Fix project instructions review findings

This commit is contained in:
Yichen Jiang
2026-07-06 18:22:28 +08:00
parent a3b0da0255
commit 15c7a27f39
4 changed files with 38 additions and 8 deletions

View File

@@ -526,19 +526,25 @@ function instructionDisplayPathsFromContextContent(content: readonly { type: str
return paths
}
function visibleInstructionDisplayPaths(agent: Agent): { visible: Set<string>; logged: Set<string> } {
function visibleInstructionDisplayPaths(agent: Agent): { visible: Set<string>; logged: Set<string>; visibleTexts: Set<string> } {
const visibleSeqs = new Set(agent.session.surface.nodes.map(node => node.seq))
const visible = new Set<string>()
const logged = new Set<string>()
const visibleTexts = new Set<string>()
for (const [seq, event] of agent.session.events.entries()) {
if (event.type !== 'context/message' || !isProjectInstructionContextSource(event.data.source)) continue
if (visibleSeqs.has(seq)) {
for (const block of event.data.content) {
if (block.type === 'text') visibleTexts.add(block.text)
}
}
const displayPaths = instructionDisplayPathsFromContextContent(event.data.content)
for (const displayPath of displayPaths) {
logged.add(displayPath)
if (visibleSeqs.has(seq)) visible.add(displayPath)
}
}
return { visible, logged }
return { visible, logged, visibleTexts }
}
function loadedNestedInstructionDisplayPaths(agent: Agent, pendingDisplayPaths: Set<string>): Set<string> {
@@ -606,9 +612,10 @@ export function apply(ctx: Context, config: Config): void {
cache,
}, fileSystem)
if (instructions === undefined) return
const visibleDisplayPaths = visibleInstructionDisplayPaths(agent).visible
const visibleInstructions = visibleInstructionDisplayPaths(agent)
const baselineDisplayPaths = instructionDisplayPathsFromText(instructions.text)
if (baselineDisplayPaths.length > 0 && baselineDisplayPaths.every(path => visibleDisplayPaths.has(path))) return
if (baselineDisplayPaths.length > 0 && baselineDisplayPaths.every(path => visibleInstructions.visible.has(path))) return
if (baselineDisplayPaths.length === 0 && visibleInstructions.visibleTexts.has(instructions.text)) return
agent.inject(workspaceContextHook(instructions.text).content, { source: PLUGIN_SOURCE })
})
ctx.on('tools/post-execute', async (exec: ToolExecution, result: ToolExecutionResult, next): Promise<PostToolDecision> => {

View File

@@ -719,6 +719,29 @@ describe('project instruction request injection', () => {
}
})
it('does not duplicate markerless baseline workspace context on later pre-step checks', async () => {
const root = await tempRepo()
const home = await tempRepo()
try {
await mkdir(join(root, '.git'), { recursive: true })
await write(join(root, 'AGENTS.md'), 'repo rule')
const ctx = new Context()
await mountProjectInstructions(ctx, { dshHome: home, baselineMaxBytes: 10 })
const agent = stubAgent(root)
await runBaselinePreStep(ctx, agent)
await runBaselinePreStep(ctx, agent)
const messages = agent.session.events.filter(event => event.type === 'context/message')
expect(messages).toHaveLength(1)
expect(blocksText(messages[0]?.type === 'context/message' ? messages[0].data.content : undefined))
.not.toContain('project-instruction-files:path=')
} finally {
await rm(root, { recursive: true, force: true })
await rm(home, { recursive: true, force: true })
}
})
it('loads instruction file content through ctx.fs instead of direct node reads', async () => {
const root = await tempRepo()
const home = await tempRepo()

View File

@@ -40,9 +40,9 @@ const acpBin = join(repoRoot, 'packages/ui/acp-agent/lib/bin.js')
const dshPackages = [
'core/agent-core', 'core/agent', 'core/session', 'core/system-prompt',
'core/tools', 'core/agent-loop', 'llm/llm', 'llm/llm-deepseek', 'bash/bash',
'bash/bash-local', 'bash/tool-bash', 'support/invariants', 'ui/app-boot',
'bash/bash-local', 'bash/tool-bash', 'prompt/project-instructions', 'support/invariants', 'ui/app-boot',
'session-persistence/session-persistence',
'session-persistence/session-persistence-jsonl', 'ui/acp', 'ui/acp-agent',
'session-persistence/session-persistence-jsonl', 'ui/acp', 'ui/acp-agent', 'util/paths',
]
const vendorPackages = [
'cordis', 'loader', 'include', 'timer', 'hmr', 'logger-console',

View File

@@ -35,9 +35,9 @@ const stdioBin = join(repoRoot, 'packages/ui/stdio-agent/lib/bin.js')
const dshPackages = [
'core/agent-core', 'core/agent', 'core/session', 'core/system-prompt',
'core/tools', 'core/agent-loop', 'llm/llm', 'bash/bash', 'bash/bash-local',
'bash/tool-bash', 'support/invariants', 'ui/app-boot',
'bash/tool-bash', 'prompt/project-instructions', 'support/invariants', 'ui/app-boot',
'session-persistence/session-persistence',
'session-persistence/session-persistence-jsonl', 'ui/stdio-agent',
'session-persistence/session-persistence-jsonl', 'ui/stdio-agent', 'util/paths',
]
const vendorPackages = [
'cordis', 'loader', 'include', 'timer', 'hmr', 'logger-console',