feat(aggregation): Implement sub-agent summarization pass
This commit is contained in:
@@ -2450,3 +2450,52 @@ def get_history_bleed_stats(md_content: Optional[str] = None) -> dict[str, Any]:
|
||||
"percentage": 0,
|
||||
})
|
||||
|
||||
def run_subagent_summarization(file_path: str, content: str, is_code: bool, outline: str) -> str:
|
||||
"""Performs a stateless summarization request using a sub-agent prompt."""
|
||||
prompt_tmpl = mma_prompts.TIER4_SUMMARIZE_CODE_PROMPT if is_code else mma_prompts.TIER4_SUMMARIZE_TEXT_PROMPT
|
||||
prompt = prompt_tmpl.format(file_path=file_path, outline=outline, content=content)
|
||||
if _provider == "gemini":
|
||||
_ensure_gemini_client()
|
||||
if _gemini_client:
|
||||
resp = _gemini_client.models.generate_content(
|
||||
model=_model,
|
||||
contents=prompt,
|
||||
config=types.GenerateContentConfig(
|
||||
temperature=0.0,
|
||||
max_output_tokens=1024,
|
||||
)
|
||||
)
|
||||
return resp.text or ""
|
||||
elif _provider == "anthropic":
|
||||
_ensure_anthropic_client()
|
||||
if _anthropic_client:
|
||||
resp = _anthropic_client.messages.create(
|
||||
model=_model,
|
||||
max_tokens=1024,
|
||||
messages=[{"role": "user", "content": prompt}]
|
||||
)
|
||||
return "".join([b.text for b in resp.content if hasattr(b, "text") and b.text])
|
||||
elif _provider == "deepseek":
|
||||
creds = _load_credentials()
|
||||
api_key = creds.get("deepseek", {}).get("api_key")
|
||||
if not api_key: return "ERROR: DeepSeek API key missing"
|
||||
headers = {"Authorization": f"Bearer {api_key}", "Content-Type": "application/json"}
|
||||
payload = {
|
||||
"model": _model,
|
||||
"messages": [{"role": "user", "content": prompt}],
|
||||
"temperature": 0.0,
|
||||
}
|
||||
try:
|
||||
r = requests.post("https://api.deepseek.com/chat/completions", headers=headers, json=payload, timeout=60)
|
||||
r.raise_for_status()
|
||||
return r.json()["choices"][0]["message"]["content"]
|
||||
except Exception as e:
|
||||
return f"ERROR: DeepSeek summarization failed: {e}"
|
||||
elif _provider == "gemini_cli":
|
||||
# Using the adapter for a one-off call
|
||||
from src.gemini_cli_adapter import GeminiCliAdapter
|
||||
adapter = GeminiCliAdapter(binary_path="gemini")
|
||||
resp_data = adapter.send(prompt, model=_model)
|
||||
return resp_data.get("text", "")
|
||||
return "ERROR: Unsupported provider for sub-agent summarization"
|
||||
|
||||
|
||||
@@ -179,3 +179,32 @@ RULES:
|
||||
Analyze this error and generate the patch:
|
||||
"""
|
||||
|
||||
TIER4_SUMMARIZE_CODE_PROMPT: str = """You are a Tier 4 QA Agent specializing in code summarization.
|
||||
Your goal is to provide a concise, high-signal summary of the provided code file.
|
||||
Focus on the primary responsibility of the module and its key architectural components.
|
||||
|
||||
INPUT:
|
||||
- File Path: {file_path}
|
||||
- Heuristic Outline: {outline}
|
||||
- Raw Content:
|
||||
{content}
|
||||
|
||||
OUTPUT REQUIREMENT:
|
||||
Provide a 1-2 sentence high-level summary followed by a brief bulleted list of key features or responsibilities.
|
||||
Keep it extremely concise. Do NOT repeat the outline.
|
||||
"""
|
||||
|
||||
TIER4_SUMMARIZE_TEXT_PROMPT: str = """You are a Tier 4 QA Agent specializing in document summarization.
|
||||
Your goal is to provide a concise, high-signal summary of the provided text/markdown file.
|
||||
|
||||
INPUT:
|
||||
- File Path: {file_path}
|
||||
- Heuristic Outline: {outline}
|
||||
- Raw Content:
|
||||
{content}
|
||||
|
||||
OUTPUT REQUIREMENT:
|
||||
Provide a 1-2 sentence high-level summary of the document's purpose and key takeaways.
|
||||
Keep it extremely concise.
|
||||
"""
|
||||
|
||||
|
||||
+22
-4
@@ -153,9 +153,9 @@ _SUMMARISERS: dict[str, Callable[[Path, str], str]] = {
|
||||
|
||||
def summarise_file(path: Path, content: str) -> str:
|
||||
"""
|
||||
Return a compact markdown summary string for a single file.
|
||||
`content` is the already-read file text (or an error string).
|
||||
"""
|
||||
Return a compact markdown summary string for a single file.
|
||||
`content` is the already-read file text (or an error string).
|
||||
"""
|
||||
content_hash = get_file_hash(content)
|
||||
cached = _summary_cache.get_summary(str(path), content_hash)
|
||||
if cached:
|
||||
@@ -164,7 +164,25 @@ def summarise_file(path: Path, content: str) -> str:
|
||||
suffix = path.suffix.lower() if hasattr(path, "suffix") else ""
|
||||
fn = _SUMMARISERS.get(suffix, _summarise_generic)
|
||||
try:
|
||||
summary = fn(path, content)
|
||||
heuristic_outline = fn(path, content)
|
||||
|
||||
# Smart AI Summarization
|
||||
is_code = suffix in [".py", ".ps1", ".js", ".ts", ".cpp", ".c", ".h", ".cs", ".go", ".rs", ".lua"]
|
||||
try:
|
||||
from src import ai_client
|
||||
smart_summary = ai_client.run_subagent_summarization(
|
||||
file_path=str(path),
|
||||
content=content[:10000], # Cap content to 10k chars for summarization
|
||||
is_code=is_code,
|
||||
outline=heuristic_outline
|
||||
)
|
||||
if smart_summary and not smart_summary.startswith("ERROR:"):
|
||||
summary = f"{smart_summary}\n\n**Outline:**\n{heuristic_outline}"
|
||||
else:
|
||||
summary = heuristic_outline
|
||||
except Exception:
|
||||
summary = heuristic_outline # Fallback
|
||||
|
||||
_summary_cache.set_summary(str(path), content_hash, summary)
|
||||
return summary
|
||||
except Exception as e:
|
||||
|
||||
Reference in New Issue
Block a user