fix(workspace): inject subagents and skills summary into workspace co…#1665
fix(workspace): inject subagents and skills summary into workspace co…#1665hangweizhang wants to merge 1 commit into
Conversation
…ntext The WorkspaceContextMiddleware previously only injected AGENTS.md, MEMORY.md, and knowledge/ content into the system prompt. Subagent declarations and skill directories were not included in the injected workspace context, causing the LLM to be unaware of available subagents and skills defined in the workspace. This change adds: - SUBAGENTS_DIR constant to WorkspaceConstants - getSubagentsDir(), listSubagentFiles(), listSkillDirs() methods to WorkspaceManager - buildSubagentsBlock() and buildSkillsBlock() in WorkspaceContextMiddleware to inject subagent and skill summaries (name + description from YAML frontmatter) into <loaded_context> - extractDescriptionFromFrontmatter() utility for parsing YAML frontmatter description fields - Unit tests for extractDescriptionFromFrontmatter() Closes agentscope-ai#1650
Codecov Report❌ Patch coverage is 📢 Thoughts on this report? Let us know! |
AgentScopeJavaBot
left a comment
There was a problem hiding this comment.
🤖 AI Review
This PR adds subagent and skill directory summaries to the workspace context injected into the system prompt, closing issue #1650. The implementation follows existing patterns in WorkspaceContextMiddleware (mirroring buildKnowledgeBlock) and adds new listing methods to WorkspaceManager. The overall approach is sound and the token budget accounting is correctly updated. However, there are two notable issues: (1) YAML-quoted description values (e.g. description: "foo") are not unquoted, leaking literal " characters into the LLM prompt, and (2) the new XML blocks use a different indentation strategy from the existing buildXmlContext helper, producing inconsistent output.
| if (trimmed.startsWith("description:")) { | ||
| return trimmed.substring("description:".length()).strip(); | ||
| } | ||
| if (trimmed.startsWith("description :")) { |
There was a problem hiding this comment.
[major] Quoted YAML description values are not unquoted. If frontmatter contains description: "Code review specialist", this line returns the literal string "Code review specialist" (with quote characters), which leaks into the LLM prompt. The test extractDescriptionFromFrontmatter_quotedDescription even asserts this incorrect behavior.
Suggested fix — strip matching surrounding quotes:
String value = trimmed.substring("description:".length()).strip();
if (value.length() >= 2
&& ((value.startsWith("\"") && value.endsWith("\""))
|| (value.startsWith("'") && value.endsWith("'")))) {
value = value.substring(1, value.length() - 1);
}
return value;Also update the test expectation to assertEquals("A long description with special chars: @#$", desc);.
| sb.append(buildXmlContext("agents_context", agentsContent)); | ||
| sb.append(buildXmlContext("memory_context", memoryContent)); | ||
| sb.append(buildXmlContext("domain_knowledge_context", knowledgeBlock)); | ||
| if (!subagentsBlock.isBlank()) { |
There was a problem hiding this comment.
[minor] Indentation inconsistency: buildSubagentsBlock / buildSkillsBlock produce XML blocks whose inner content is not indented, yet buildLoadedContextSection prepends only " " (2 spaces) to the whole block. This yields output like:
<subagents_context>
Available subagents:
- foo
</subagents_context>While buildXmlContext (used for agents/memory/knowledge) correctly indents every inner line by 2 spaces.
Suggested fix: apply indentByTwo inside buildSubagentsBlock / buildSkillsBlock (similar to how buildAdditionalContextBlock works), or wrap them via buildXmlContext for consistency.
| + "\n" | ||
| + "Body text."; | ||
| String desc = WorkspaceContextMiddleware.extractDescriptionFromFrontmatter(content); | ||
| assertNotNull(desc); |
There was a problem hiding this comment.
[major] This assertion codifies the buggy behavior: the expected value still includes the literal quote characters (\"A long description...\"). After fixing extractDescriptionFromFrontmatter to strip YAML quotes, update this to:
assertEquals("A long description with special chars: @#$", desc);| return trimmed.substring("description:".length()).strip(); | ||
| } | ||
| if (trimmed.startsWith("description :")) { | ||
| return trimmed.substring("description :".length()).strip(); |
There was a problem hiding this comment.
[nit] The second branch description : (with a space before the colon) is non-standard YAML and unlikely to appear in real frontmatter. While harmless, consider removing it to keep the parser minimal, or document that it's intentional leniency.
…ntext
The WorkspaceContextMiddleware previously only injected AGENTS.md, MEMORY.md, and knowledge/ content into the system prompt. Subagent declarations and skill directories were not included in the injected workspace context, causing the LLM to be unaware of available subagents and skills defined in the workspace.
This change adds:
Closes #1650
AgentScope-Java Version
[The version of AgentScope-Java you are working on, e.g. 1.0.12, check your pom.xml dependency version or run
mvn dependency:tree | grep agentscope-parent:pom(only mac/linux)]Description
[Please describe the background, purpose, changes made, and how to test this PR]
Checklist
Please check the following items before code is ready to be reviewed.
mvn spotless:applymvn test)