Merge branch 'codex/simp-ui-identity-residue' into codex/simp-hide-concrete-agent-loop

# Conflicts:
#	docs/event-producer-consumer.md
#	examples/coding-agent/tests/code-mode.e2e.ts
#	examples/coding-agent/tests/harness.ts
#	examples/coding-agent/tests/resume.e2e.ts
#	examples/cordis-agent/tests/harness.ts
#	packages/bash/tool-bash/tests/integration.spec.ts
#	packages/compact/compact-basic/tests/compact-loop-repro.spec.ts
#	packages/cordis/tool-cordis/tests/integration.spec.ts
#	packages/core/agent-loop/tests/contract-regressions.spec.ts
#	packages/guard/repeat-tool-guard/tests/repeat-tool-guard.spec.ts
#	packages/hooks/hooks-claude/tests/bridge.spec.ts
#	packages/hooks/hooks-claude/tests/coverage.spec.ts
#	packages/hooks/hooks-codex/tests/bridge.spec.ts
#	packages/hooks/hooks-codex/tests/coverage.spec.ts
#	packages/todo/tool-todo/tests/integration.spec.ts
This commit is contained in:
Tianyi Cui
2026-07-18 12:33:49 +08:00
657 changed files with 36714 additions and 7631 deletions

View File

@@ -1,4 +1,4 @@
import { mkdtemp, readFile, rm } from 'node:fs/promises'
import { mkdtemp, mkdir, readFile, rm, writeFile } from 'node:fs/promises'
import { tmpdir } from 'node:os'
import { join } from 'node:path'
import { afterEach, describe, expect, it } from 'vitest'
@@ -15,6 +15,9 @@ import { LocalBashExecutor } from '@deepseek-ai/dsh-bash-local'
import * as ToolBash from '@deepseek-ai/dsh-tool-bash'
import * as LlmDeepSeek from '@deepseek-ai/dsh-llm-deepseek'
import { WorkerCodeRuntime } from '@deepseek-ai/dsh-code-runtime-worker'
import LocalFileSystem from '@deepseek-ai/dsh-fs-local'
import * as ToolFs from '@deepseek-ai/dsh-tool-fs'
import * as WorkspaceContext from '@deepseek-ai/dsh-workspace-context'
/**
* With-key Code Mode proof: a real model receives only `run_code`, composes two
@@ -24,6 +27,7 @@ import { WorkerCodeRuntime } from '@deepseek-ai/dsh-code-runtime-worker'
const PERSONA = 'You are coding-agent. You work by writing TypeScript programs for run_code: '
+ 'batch related tool work into one program and print or return ONLY the findings that matter.'
const WORKSPACE_PROBE = 'dragonfruit-8675309'
let ctx: Context | undefined
let workdir: string | undefined
@@ -46,13 +50,29 @@ async function codeModeHarness(cwd: string): Promise<Context> {
await harness.plugin(ToolRegistry, { mode: 'code' })
await harness.plugin(AgentRegistry)
await harness.plugin(AgentLoop, { agents: [] })
await harness.plugin(LlmDeepSeek, { models: ['deepseek-v4-flash'] })
await harness.plugin(LlmDeepSeek)
await harness.plugin(LocalBashExecutor, { cwd, timeoutMs: 30_000 })
await harness.plugin(ToolBash)
await harness.plugin(WorkerCodeRuntime, {})
return harness
}
async function workspaceCodeModeHarness(): Promise<Context> {
const harness = new Context()
await harness.plugin(LlmService)
await harness.plugin(SessionStore)
await harness.plugin(SystemPrompt, { persona: PERSONA })
await harness.plugin(ToolRegistry, { mode: 'code' })
await harness.plugin(AgentRegistry)
await harness.plugin(LocalFileSystem, { cwd: '/' })
await harness.plugin(ToolFs)
await harness.plugin(WorkspaceContext, { maxBytes: 65536 })
await harness.plugin(AgentLoop, { agents: [] })
await harness.plugin(LlmDeepSeek, { models: [{ id: 'deepseek-v4-flash' }] })
await harness.plugin(WorkerCodeRuntime, {})
return harness
}
function waitForIdle(harness: Context, agent: Agent): Promise<void> {
return new Promise((resolve) => {
const dispose = harness.on('agent/status', (subject, status) => {
@@ -68,7 +88,7 @@ describe.skipIf(!process.env.DEEPSEEK_API_KEY)('Code Mode: real model writes a p
it('collapses the wire tool list to [run_code], bridges sub-calls, and returns curated output', async () => {
workdir = await mkdtemp(join(tmpdir(), 'dsh-code-mode-e2e-'))
ctx = await codeModeHarness(workdir)
const agent = ctx.agentLoop.create(SessionId('e2e-code-mode'), { model: 'deepseek-v4-flash' })
const agent = ctx.agentLoop.create(SessionId('e2e-code-mode'), { provider: 'deepseek', model: 'deepseek-v4-flash' })
agent.send([{
type: 'text',
@@ -108,4 +128,42 @@ describe.skipIf(!process.env.DEEPSEEK_API_KEY)('Code Mode: real model writes a p
expect(finalText).toContain('alpha-7')
expect(finalText).toContain('beta-9')
}, 180_000)
it('delivers nested workspace instructions discovered by an fs sub-call after the outer result', async () => {
workdir = await mkdtemp(join(tmpdir(), 'dsh-code-mode-workspace-e2e-'))
await mkdir(join(workdir, '.git'), { recursive: true })
await mkdir(join(workdir, 'pkg/deep'), { recursive: true })
await writeFile(join(workdir, 'pkg/AGENTS.md'), `If asked for the Code Mode workspace handshake, reply with exactly ${WORKSPACE_PROBE} and nothing else.\n`)
await writeFile(join(workdir, 'pkg/deep/task.txt'), 'Touch this file to discover the nested instructions.\n')
ctx = await workspaceCodeModeHarness()
const handle = await ctx.agents.create({
sessionId: SessionId('e2e-code-mode-workspace-session'),
meta: { cwd: workdir },
agentOptions: { provider: 'deepseek', model: 'deepseek-v4-flash' },
})
handle.agent.send([{
type: 'text',
text: 'Use one run_code program to call tools.read on pkg/deep/task.txt. After it finishes, answer: Code Mode workspace handshake?',
}])
await waitForIdle(ctx, handle.agent)
const events: SessionEvent[] = [...handle.agent.session.events]
const dispatch = events.find(event => event.type === 'tool/code-dispatch' && event.data.name === 'read')
const outerResult = events.find(event => event.type === 'tool/result')
const workspaceContext = events.find(event => event.type === 'context/message'
&& typeof event.data.meta === 'object'
&& event.data.meta !== null
&& !Array.isArray(event.data.meta)
&& event.data.meta.kind === 'workspace-instructions')
expect(dispatch).toBeDefined()
expect(outerResult).toBeDefined()
expect(workspaceContext).toBeDefined()
expect(workspaceContext!.seq).toBeGreaterThan(outerResult!.seq)
const finalMessage = events.findLast(event => event.type === 'assistant/message')
const answer = finalMessage?.type === 'assistant/message'
? finalMessage.data.content.filter(block => block.type === 'text').map(block => block.text).join('')
: ''
expect(answer).toContain(WORKSPACE_PROBE)
}, 180_000)
})