183 lines
6.9 KiB
Python
183 lines
6.9 KiB
Python
"""Bundle build and capability summary methods."""
|
|
|
|
from __future__ import annotations
|
|
|
|
from .shared import (
|
|
Any,
|
|
AsyncSession,
|
|
CONTEXT_BUNDLE_KEYS,
|
|
CONTEXT_BUNDLE_MARKER,
|
|
ModelRoutingService,
|
|
TARGET_FUNCTION_CONTEXT,
|
|
TaskBriefService,
|
|
datetime,
|
|
timezone,
|
|
)
|
|
from ...project_knowledge_graph_service import ProjectKnowledgeGraphService
|
|
|
|
|
|
class ModelContextBundleBuildMixin:
|
|
"""Build context bundles and capability summaries."""
|
|
|
|
@classmethod
|
|
async def build_context_bundle(
|
|
cls,
|
|
db: AsyncSession,
|
|
*,
|
|
tenant_id: int,
|
|
function_name: str,
|
|
) -> dict[str, Any] | None:
|
|
fn = cls._normalize_function_name(function_name)
|
|
target = TARGET_FUNCTION_CONTEXT.get(fn)
|
|
if target is None:
|
|
return None
|
|
|
|
kg_service = ProjectKnowledgeGraphService(db, tenant_id=int(tenant_id))
|
|
overview = await kg_service.get_overview()
|
|
templates = await TaskBriefService.list_templates(db, tenant_id=int(tenant_id))
|
|
template_map = {
|
|
str(item.get("id") or ""): item
|
|
for item in templates
|
|
if isinstance(item, dict) and str(item.get("id") or "").strip()
|
|
}
|
|
configured_template_ids = [
|
|
str(x or "").strip()
|
|
for x in target.get("template_ids", [])
|
|
if str(x or "").strip()
|
|
]
|
|
primary_template_id = configured_template_ids[0] if configured_template_ids else ""
|
|
additional_ids = configured_template_ids[1:] if len(configured_template_ids) > 1 else []
|
|
missing_template_ids = [tid for tid in configured_template_ids if tid not in template_map]
|
|
contract_sync = await TaskBriefService.get_contract_sync_status(db, tenant_id=int(tenant_id))
|
|
|
|
bundle = {
|
|
"marker": CONTEXT_BUNDLE_MARKER,
|
|
"function_name": fn,
|
|
"tier": str(target.get("tier") or ""),
|
|
"knowledge_graph": cls._kg_snapshot(overview),
|
|
"task_template": {
|
|
"primary": cls._template_snapshot(
|
|
template_map.get(primary_template_id),
|
|
include_content=True,
|
|
),
|
|
"additional": [
|
|
snap
|
|
for snap in (
|
|
cls._template_snapshot(template_map.get(template_id), include_content=False)
|
|
for template_id in additional_ids
|
|
)
|
|
if snap is not None
|
|
],
|
|
"template_ids": configured_template_ids,
|
|
"missing_template_ids": missing_template_ids,
|
|
},
|
|
"contract_sync": cls._contract_snapshot(contract_sync),
|
|
}
|
|
return bundle
|
|
|
|
@classmethod
|
|
async def inject_prompt_with_bundle(
|
|
cls,
|
|
db: AsyncSession,
|
|
*,
|
|
tenant_id: int,
|
|
function_name: str,
|
|
prompt: str,
|
|
) -> str:
|
|
raw_prompt = str(prompt or "")
|
|
if not cls.should_inject_context(function_name):
|
|
return raw_prompt
|
|
marker = f"[{CONTEXT_BUNDLE_MARKER}]"
|
|
if marker in raw_prompt:
|
|
return raw_prompt
|
|
bundle = await cls.build_context_bundle(
|
|
db,
|
|
tenant_id=int(tenant_id),
|
|
function_name=function_name,
|
|
)
|
|
if bundle is None:
|
|
return raw_prompt
|
|
bundle_text = cls.render_bundle_marker_text(bundle)
|
|
return f"{bundle_text}\n\n{raw_prompt}".strip()
|
|
|
|
@classmethod
|
|
async def build_capability_summary(cls, db: AsyncSession, *, tenant_id: int) -> dict[str, Any]:
|
|
kg_service = ProjectKnowledgeGraphService(db, tenant_id=int(tenant_id))
|
|
overview = await kg_service.get_overview()
|
|
templates = await TaskBriefService.list_templates(db, tenant_id=int(tenant_id))
|
|
template_map = {
|
|
str(item.get("id") or ""): item
|
|
for item in templates
|
|
if isinstance(item, dict) and str(item.get("id") or "").strip()
|
|
}
|
|
required_template_ids = sorted(
|
|
{
|
|
template_id
|
|
for spec in TARGET_FUNCTION_CONTEXT.values()
|
|
for template_id in spec.get("template_ids", [])
|
|
if str(template_id or "").strip()
|
|
}
|
|
)
|
|
present_template_ids = sorted(template_map.keys())
|
|
missing_template_ids = [
|
|
template_id
|
|
for template_id in required_template_ids
|
|
if template_id not in template_map
|
|
]
|
|
contract_sync_raw = await TaskBriefService.get_contract_sync_status(db, tenant_id=int(tenant_id))
|
|
contract_sync = cls._contract_snapshot(contract_sync_raw)
|
|
|
|
function_matrix: list[dict[str, Any]] = []
|
|
for function_name in cls.target_functions():
|
|
spec = TARGET_FUNCTION_CONTEXT[function_name]
|
|
routing = await ModelRoutingService.get_effective_routing(
|
|
db,
|
|
tenant_id=int(tenant_id),
|
|
function_name=function_name,
|
|
)
|
|
function_matrix.append(
|
|
{
|
|
"function_name": function_name,
|
|
"tier": str(spec.get("tier") or ""),
|
|
"context_sections": list(CONTEXT_BUNDLE_KEYS),
|
|
"template_ids": [
|
|
str(tid)
|
|
for tid in spec.get("template_ids", [])
|
|
if str(tid or "").strip()
|
|
],
|
|
"model_routing": {
|
|
"provider": str(routing.get("provider") or ""),
|
|
"model": str(routing.get("model") or ""),
|
|
"tier": str(routing.get("tier") or ""),
|
|
"source": str(routing.get("source") or ""),
|
|
"api_env": str(routing.get("api_env") or ""),
|
|
},
|
|
}
|
|
)
|
|
|
|
required_templates = [
|
|
cls._template_snapshot(template_map.get(template_id), include_content=False)
|
|
or {"id": template_id}
|
|
for template_id in required_template_ids
|
|
]
|
|
|
|
return {
|
|
"marker": CONTEXT_BUNDLE_MARKER,
|
|
"knowledge_graph": cls._kg_snapshot(overview),
|
|
"task_templates": {
|
|
"total": len(templates),
|
|
"required_template_ids": required_template_ids,
|
|
"present_template_ids": present_template_ids,
|
|
"missing_template_ids": missing_template_ids,
|
|
"required_templates": required_templates,
|
|
},
|
|
"contract_sync": contract_sync,
|
|
"function_model_template_matrix": function_matrix,
|
|
"coverage": {
|
|
"template_ready": len(missing_template_ids) == 0,
|
|
"contract_ready": bool(contract_sync.get("all_synced")),
|
|
"target_function_count": len(function_matrix),
|
|
},
|
|
"generated_at": datetime.now(timezone.utc).isoformat(),
|
|
}
|