Improve line sampling deduplication and add robust tests for message digest and prompt construction in router logic

This commit is contained in:
2026-06-15 22:05:04 +02:00
parent 13cfd7518b
commit 8616c077cc
2 changed files with 58 additions and 2 deletions

View File

@@ -236,12 +236,14 @@ def _short_line(line: str, limit: int = MESSAGE_DIGEST_SAMPLE_LINE_CHARS) -> str
def _sample_representative_lines(text: str, *, max_lines: int = MESSAGE_DIGEST_MAX_SAMPLE_LINES) -> List[str]:
candidates = []
seen = set()
for line_number, line in enumerate(text.splitlines(), 1):
compact = _short_line(line)
if not compact:
continue
if compact in {item[1] for item in candidates}:
if compact in seen:
continue
seen.add(compact)
candidates.append((line_number, compact))
if len(candidates) <= max_lines:
return [f"L{line_number}: {compact}" for line_number, compact in candidates]

View File

@@ -9,7 +9,7 @@ from sqlalchemy.orm import sessionmaker
from backend.agent.models import WorkflowDefinition
from backend.agent.registry import NativeToolProvider
from backend.agent.router import select_workflow
from backend.agent.router import _format_message_for_router, _router_prompt, select_workflow
from backend.agent.tools import register_native_tools
from backend.agent.validation import validate_workflow_graph
from backend.agent.workflows.builtins import BUILTIN_WORKFLOWS, seed_builtin_workflows
@@ -183,6 +183,60 @@ class RouterAndBuiltinTests(unittest.IsolatedAsyncioTestCase):
self.assertNotIn("Selected knowledge database:", prompt)
db.close()
async def test_long_message_digest_preserves_request_boundaries(self):
message = (
"Please summarize the pasted material and keep the answer short.\n"
+ ("A" * 3600)
+ "\nMiddle note: focus on the security implications.\n"
+ ("B" * 3600)
+ "\nActually, compare the risks and benefits instead."
)
digest = _format_message_for_router(message)
self.assertLess(len(digest), len(message))
self.assertIn("<long_user_message_digest>", digest)
self.assertIn("Please summarize the pasted material", digest)
self.assertIn("Middle note: focus on the security implications", digest)
self.assertIn("Actually, compare the risks and benefits instead.", digest)
self.assertIn("Original length:", digest)
async def test_router_prompt_uses_bounded_digest_and_attachment_summary(self):
message = (
"Instruction before payload: analyze this local document.\n"
+ "\n".join(f"payload line {index} " + ("x" * 80) for index in range(400))
+ "\nInstruction after payload: do not search the web unless needed."
)
manifest = {
"workflow_id": "direct",
"slug": "input-output",
"name": "Input -> Output",
"routing_description": "Use when no external tool is needed.",
"examples": [],
"required_capabilities": ["chat"],
}
prompt = _router_prompt(
message=message,
recent_messages=[{"role": "assistant", "content": "previous " + ("y" * 2000)}],
attachments=[{
"kind": "file",
"name": "large-report.pdf",
"mime_type": "application/pdf",
"size": 12345,
"text": "attachment text " * 1000,
}],
manifests=[manifest],
)
self.assertLess(len(prompt), 9000)
self.assertIn("Current user message or routing digest:", prompt)
self.assertIn("Instruction before payload", prompt)
self.assertIn("Instruction after payload", prompt)
self.assertIn("large-report.pdf", prompt)
self.assertIn("text_chars=", prompt)
self.assertNotIn("attachment text attachment text attachment text", prompt)
async def test_all_builtins_validate(self):
registry = NativeToolProvider(); register_native_tools(registry)
for item in BUILTIN_WORKFLOWS: