Merge branch 'master' into worktree/charming-swartz-83bf33

This commit is contained in:
Yichen Jiang
2026-08-07 11:37:57 +08:00
committed by GitHub
76 changed files with 1102 additions and 371 deletions

View File

@@ -30,8 +30,9 @@ export const SYSTEM_PROMPT = 'You are a coding agent. Use bash for file operatio
/** System prompt for the todo_write e2e: nudges the model to plan with the tool. */
export const TODO_SYSTEM_PROMPT = 'You are a coding agent. For multi-step work, '
+ 'use the todo_write tool to track a task list: send the WHOLE list each call, '
+ 'keep at most one task in_progress (exactly one while work remains), and mark '
+ 'a task completed as soon as it is done.'
+ 'mark every task being actively worked on in_progress (several at once when '
+ 'work runs in parallel, at least one while work remains), and mark a task '
+ 'completed as soon as it is done.'
/** Options for {@link codingHarness}. */
export interface CodingHarnessOptions {
@@ -65,7 +66,7 @@ export async function codingHarness(workdir: string, options: CodingHarnessOptio
await ctx.plugin(BashEnvPlugin)
await ctx.plugin(LocalBashExecutor, { cwd: workdir, timeoutMs: 30_000 })
await ctx.plugin(ToolBash)
await ctx.plugin(ToolTodo)
await ctx.plugin(ToolTodo, { allowParallelInProgress: true })
// Compaction is opt-in: only the compaction e2e loads the reusable meter and backend.
if (options.compact !== undefined) {
await ctx.plugin(TokenMeterService)

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -31,9 +31,10 @@ describe.skipIf(!process.env.DEEPSEEK_API_KEY)('todo_write: real model records a
agent.followup(createUserMessage({
content: [{ type: 'text', text:
'Use the todo_write tool to record a plan of exactly two steps: first '
+ '"inspect the failing test" (in_progress), then "apply the fix" (pending). '
+ 'Send both in one todo_write call, then reply with the single word DONE.' }], source: { kind: 'user' } }))
'Use the todo_write tool to record a plan of exactly three steps for work '
+ 'running in parallel: "inspect the failing test" (in_progress), '
+ '"watch the background build" (in_progress), then "apply the fix" (pending). '
+ 'Send all three in one todo_write call, then reply with the single word DONE.' }], source: { kind: 'user' } }))
await waitForIdle(ctx, agent)
const events = [...agent.session.events]
@@ -42,13 +43,15 @@ describe.skipIf(!process.env.DEEPSEEK_API_KEY)('todo_write: real model records a
const calls = events.filter(event => event.type === 'tool/call')
expect(calls.some(event => event.data.name === 'todo_write')).toBe(true)
// And the tool wrote a todo/write event to the log — verify the WORLD.
// And the tool wrote a todo/write event to the log — verify the WORLD,
// including two simultaneously in_progress tasks (the parallel contract).
const todoEvents = events.filter(event => event.type === 'todo/write')
expect(todoEvents.length).toBeGreaterThan(0)
const todos = (todoEvents.at(-1)!).data.todos
expect(todos).toEqual([
{ content: 'inspect the failing test', status: 'in_progress' },
{ content: 'watch the background build', status: 'in_progress' },
{ content: 'apply the fix', status: 'pending' },
])
}, 120_000)