mirror of
https://github.com/deepseek-ai/deepseek-harness
synced 2026-08-15 21:04:50 +00:00
fix(tool-goal): scope the wrap-up no-more-tools clause to the current run
The injected instruction persists as a durable user message, so an unscoped 'Do not call any more tools.' stays in every later request's history. Scope it: '...in this run; further work waits for the user's next instruction.' A/B probes on deepseek-v4-pro show the scoped wording is non-inferior in-turn (4/4 zero tool calls, closing quality unchanged) and next-turn tool use is unaffected under both wordings; the scoped form states the instruction's actual lifetime.
This commit is contained in:
@@ -37,7 +37,7 @@
|
||||
{"type":"tool/call","seq":35,"time":0,"data":{"turn":2,"step":1,"callId":"call_goal_complete","name":"update_goal","arguments":"{\"goal_id\":\"goal-{{sessionId}}\",\"revision\":1,\"action\":\"complete\"}"}}
|
||||
{"type":"tool/result","seq":36,"time":0,"data":{"turn":2,"step":1,"message":{"source":{"kind":"tool","callId":"call_goal_complete"},"content":[{"type":"tool-result","toolCallId":"call_goal_complete","content":[{"type":"text","text":"{\"goal\":{\"id\":\"goal-{{sessionId}}\",\"revision\":2,\"objective\":\"Finish the ACP goal wrap-up snapshot proof\",\"phase\":\"complete\",\"roundsStarted\":1,\"maxGoalRounds\":2},\"activation\":\"disarmed\"}"}],"isError":false}],"role":"user","id":"{{sessionId}}"}},"sourceEventSeqs":[35],"surfaceOp":"append"}
|
||||
{"type":"user/message","seq":37,"time":0,"data":{"content":[{"type":"text","text":"<goal_state>{\"goal\":{\"id\":\"goal-{{sessionId}}\",\"revision\":2,\"objective\":\"Finish the ACP goal wrap-up snapshot proof\",\"phase\":\"complete\",\"maxGoalRounds\":2},\"roundsStarted\":1,\"createdAt\":0,\"updatedAt\":0}</goal_state>"}],"source":{"kind":"goal","goalId":"goal-{{sessionId}}","revision":2,"round":0,"change":{"kind":"goal/change","version":1,"operation":"complete","goal":{"id":"goal-{{sessionId}}","revision":2,"objective":"Finish the ACP goal wrap-up snapshot proof","phase":"complete","maxGoalRounds":2},"roundsStarted":1,"createdAt":0,"updatedAt":0}},"role":"user","id":"{{sessionId}}"},"surfaceOp":"append"}
|
||||
{"type":"user/message","seq":38,"time":0,"data":{"content":[{"type":"text","text":"<goal_complete>\nObjective: \"Finish the ACP goal wrap-up snapshot proof\"\nThe goal is marked complete and this autonomous run is ending. Write the closing message to the user now: state the outcome, summarize what was done and how it was verified, and point to the concrete results (files, commits, or other artifacts). Report only what earlier rounds and tool results in this session actually establish; when a detail is not in the session, say so instead of inventing it. Note anything the user should review or do next. Address the user directly. Do not call any more tools.\n</goal_complete>"}],"source":{"kind":"plugin","plugin":"tool-goal"},"role":"user","id":"{{sessionId}}"},"surfaceOp":"append"}
|
||||
{"type":"user/message","seq":38,"time":0,"data":{"content":[{"type":"text","text":"<goal_complete>\nObjective: \"Finish the ACP goal wrap-up snapshot proof\"\nThe goal is marked complete and this autonomous run is ending. Write the closing message to the user now: state the outcome, summarize what was done and how it was verified, and point to the concrete results (files, commits, or other artifacts). Report only what earlier rounds and tool results in this session actually establish; when a detail is not in the session, say so instead of inventing it. Note anything the user should review or do next. Address the user directly. Do not call any more tools in this run; further work waits for the user's next instruction.\n</goal_complete>"}],"source":{"kind":"plugin","plugin":"tool-goal"},"role":"user","id":"{{sessionId}}"},"surfaceOp":"append"}
|
||||
{"type":"step/end","seq":39,"time":0,"data":{"turn":2,"step":1}}
|
||||
{"type":"step/start","seq":40,"time":0,"data":{"turn":2,"step":2}}
|
||||
{"type":"assistant/chunk","seq":41,"time":0,"data":{"turn":2,"step":2,"chunk":{"type":"block-start","index":0,"blockType":"text"}}}
|
||||
|
||||
@@ -24,7 +24,7 @@ export function renderWrapupContext(objective: string, blockedReason?: string):
|
||||
+ 'verified, and point to the concrete results (files, commits, or other artifacts). '
|
||||
+ GROUNDING
|
||||
+ 'Note anything the user should review or do next. Address the user directly. Do not '
|
||||
+ 'call any more tools.\n'
|
||||
+ "call any more tools in this run; further work waits for the user's next instruction.\n"
|
||||
+ '</goal_complete>'
|
||||
: '<goal_blocked>\n'
|
||||
+ heading
|
||||
@@ -34,7 +34,8 @@ export function renderWrapupContext(objective: string, blockedReason?: string):
|
||||
+ 'blocking condition and what you tried, and say exactly what you need from the user to '
|
||||
+ 'continue. '
|
||||
+ GROUNDING
|
||||
+ 'Address the user directly. Do not call any more tools.\n'
|
||||
+ 'Address the user directly. Do not call any more tools in this run; further work '
|
||||
+ "waits for the user's next instruction.\n"
|
||||
+ '</goal_blocked>'
|
||||
return [{ type: 'text', text }]
|
||||
}
|
||||
|
||||
@@ -377,7 +377,7 @@ describe('goal tool state transitions', () => {
|
||||
if (block?.type !== 'text') throw new Error('expected one text wrap-up block')
|
||||
expect(block.text).toContain('<goal_complete>')
|
||||
expect(block.text).toContain('"pause cleanly"')
|
||||
expect(block.text).toContain('Do not call any more tools.')
|
||||
expect(block.text).toContain("Do not call any more tools in this run; further work waits for the user's next instruction.")
|
||||
})
|
||||
|
||||
it('completes without a wrap-up instruction under direct human authority', async () => {
|
||||
@@ -578,7 +578,7 @@ describe('goal tool state transitions', () => {
|
||||
if (block?.type !== 'text') throw new Error('expected one text wrap-up block')
|
||||
expect(block.text).toContain('<goal_blocked>')
|
||||
expect(block.text).toContain('The required credential is still unavailable.')
|
||||
expect(block.text).toContain('Do not call any more tools.')
|
||||
expect(block.text).toContain("Do not call any more tools in this run; further work waits for the user's next instruction.")
|
||||
})
|
||||
|
||||
it('lets direct human authority block before the model threshold', async () => {
|
||||
|
||||
Reference in New Issue
Block a user