fix(agent): keep explicit skills out of system prompt
This commit is contained in:
+32
-13
@@ -94,7 +94,6 @@ class ContextBuilder:
|
||||
def build_system_prompt(
|
||||
self,
|
||||
*,
|
||||
active_skill_names: Sequence[str] | None = None,
|
||||
channel: str | None = None,
|
||||
session_summary: SessionSummary | None = None,
|
||||
workspace: Path | None = None,
|
||||
@@ -119,11 +118,6 @@ class ContextBuilder:
|
||||
parts.append(f"# Memory\n\n## Long-term Memory\n{memory}")
|
||||
|
||||
active_skills = self.skills.get_always_skills()
|
||||
active_skills.extend(
|
||||
name
|
||||
for name in (active_skill_names or ())
|
||||
if name not in active_skills
|
||||
)
|
||||
if active_skills:
|
||||
active_content = self.skills.load_skills_for_context(active_skills)
|
||||
if active_content:
|
||||
@@ -165,6 +159,33 @@ class ContextBuilder:
|
||||
|
||||
return "\n\n---\n\n".join(parts)
|
||||
|
||||
def build_runtime_context_blocks(
|
||||
self,
|
||||
current_message: str,
|
||||
blocks: Sequence[RuntimeContextBlock] | None = None,
|
||||
) -> list[RuntimeContextBlock]:
|
||||
"""Add explicitly invoked skill instructions to this turn's runtime context."""
|
||||
merged = list(blocks or ())
|
||||
invoked = self.skills.get_explicitly_invoked_skills(current_message)
|
||||
if not invoked:
|
||||
return merged
|
||||
always_active = set(self.skills.get_always_skills())
|
||||
skill_names = [name for name in invoked if name not in always_active]
|
||||
skill_content = self.skills.load_skills_for_context(skill_names)
|
||||
if not skill_content:
|
||||
return merged
|
||||
skill_block = RuntimeContextBlock(
|
||||
source="explicit_skills",
|
||||
content=(
|
||||
"[Active Skills — instructions for this user turn]\n"
|
||||
f"{skill_content}\n"
|
||||
"[/Active Skills]"
|
||||
),
|
||||
)
|
||||
if skill_block not in merged:
|
||||
merged.append(skill_block)
|
||||
return merged
|
||||
|
||||
@staticmethod
|
||||
def _without_duplicate_session_summary(
|
||||
entries: list[dict[str, Any]],
|
||||
@@ -279,16 +300,10 @@ class ContextBuilder:
|
||||
) -> list[dict[str, Any]]:
|
||||
"""Build the complete message list for an LLM call."""
|
||||
root = workspace or self.workspace
|
||||
active_skill_names = (
|
||||
self.skills.get_explicitly_invoked_skills(current_message)
|
||||
if current_role == "user"
|
||||
else []
|
||||
)
|
||||
messages: list[dict[str, Any]] = [
|
||||
{
|
||||
"role": "system",
|
||||
"content": self.build_system_prompt(
|
||||
active_skill_names=active_skill_names,
|
||||
channel=channel,
|
||||
session_summary=session_summary,
|
||||
workspace=root,
|
||||
@@ -332,7 +347,11 @@ class ContextBuilder:
|
||||
) -> dict[str, Any]:
|
||||
"""Build only the fresh turn message without merging it into history."""
|
||||
content = self.build_user_content(current_message, image_paths=media)
|
||||
blocks = list(runtime_context_blocks or ()) if current_role == "user" else []
|
||||
blocks = (
|
||||
self.build_runtime_context_blocks(current_message, runtime_context_blocks)
|
||||
if current_role == "user"
|
||||
else []
|
||||
)
|
||||
merged, runtime_context_meta = append_runtime_context(content, blocks)
|
||||
current: dict[str, Any] = {"role": current_role, "content": merged}
|
||||
if current_role == "user" and runtime_context_meta is not None:
|
||||
|
||||
@@ -797,7 +797,10 @@ class AgentLoop:
|
||||
]
|
||||
blocks = runtime_context_blocks_from_metadata(request.metadata)
|
||||
blocks.extend(await resolve_runtime_context(providers, request))
|
||||
return blocks
|
||||
return self.context.build_runtime_context_blocks(
|
||||
request.original_user_text or "",
|
||||
blocks,
|
||||
)
|
||||
|
||||
async def _dispatch_command_inline(
|
||||
self,
|
||||
|
||||
Reference in New Issue
Block a user