Merge remote-tracking branch 'origin/master' into codex/session-scoped-sandbox-roots

# Conflicts:
#	examples/acp-agent/tests/acp.snapshot.ts
#	packages/examples/agent-spine-demo/package.json
#	pnpm-lock.yaml
This commit is contained in:
Tianyi Cui
2026-07-21 20:00:55 +08:00
635 changed files with 21527 additions and 3332 deletions

View File

@@ -12,6 +12,10 @@ import LocalFileSystem from '@deepseek-ai/dsh-fs-local'
import { MockAdapter, textResponse } from '../../../core/agent-loop/tests/mock-adapter.ts'
import { CallId, LlmAdapter, LlmError, type GenerateOptions, type Message, type StreamChunk } from '@deepseek-ai/dsh-llm'
import type { ToolExecution } from '@deepseek-ai/dsh-tools'
import * as sessionInvariant from '@deepseek-ai/dsh-session/invariant'
import * as agentInvariant from '@deepseek-ai/dsh-agent/invariant'
import * as scopeInvariant from '@deepseek-ai/dsh-scope/invariant'
import * as agentLoopInvariant from '@deepseek-ai/dsh-agent-loop/invariant'
declare module '@deepseek-ai/dsh-tasks' {
interface TaskKindMap {
@@ -44,7 +48,14 @@ async function mount(config: agentCore.Config, withBash = false): Promise<Contex
process.env.DSH_HOME = await mkdtemp(join(tmpdir(), 'dsh-agent-spine-demo-home-'))
process.env.DSH_AGENTS_HOME = await mkdtemp(join(tmpdir(), 'dsh-agent-spine-demo-agents-'))
const ctx = new Context()
if (withBash) ctx.provide('bash', { sandboxMode: undefined })
if (withBash) {
ctx.provide('bash', {
sandboxMode: undefined,
resolve() { throw new Error('composition test does not execute bash') },
run() { throw new Error('composition test does not execute bash') },
start() { throw new Error('composition test does not execute bash') },
})
}
try {
await ctx.plugin(agentCore, config)
// The bundle mounts its children inside apply() (not awaited there); let their
@@ -123,6 +134,7 @@ describe('dsh-agent-spine-demo bundle', () => {
expect(ctx.get('skills')).toBeDefined()
expect(ctx.get('agents')).toBeDefined()
expect(ctx.get('tasks')).toBeDefined()
expect(ctx.get('invariants')).toBeDefined()
expect(ctx.get('agentLoop')).toBeDefined()
expect(ctx.get('goals')).toBeUndefined()
await ctx.fiber.dispose()
@@ -156,6 +168,28 @@ describe('dsh-agent-spine-demo bundle', () => {
await ctx.fiber.dispose()
})
it('mounts package companions and forwards invariant selection config', async () => {
const nestedTurn = (ctx: Context): void => {
const session = ctx.sessions.create()
session.append('turn/start', { turn: 1, trigger: { kind: 'message', source: { kind: 'user' } } })
session.append('turn/start', { turn: 2, trigger: { kind: 'message', source: { kind: 'user' } } })
}
const enabled = await mount({ workspaceContext: false })
expect(() => { nestedTurn(enabled) }).toThrow(/turn 1 is still open/)
await enabled.fiber.dispose()
for (const invariants of [
{ enabled: false },
{ package_allowlist: ['^@deepseek-ai/dsh-agent$'] },
{ package_blocklist: ['^@deepseek-ai/dsh-session$'] },
]) {
const filtered = await mount({ workspaceContext: false, invariants })
expect(() => { nestedTurn(filtered) }).not.toThrow()
await filtered.fiber.dispose()
}
})
it('loads and configures bounded request recovery for every bundled front door', async () => {
const adapter = new TransientOnceAdapter()
const ctx = await mount({
@@ -457,6 +491,7 @@ describe('dsh-agent-spine-demo bundle', () => {
skills: { enabled: false },
toolBash: { enableRunInBackground: false },
toolTasks: false as const,
invariants: { enabled: false },
llmRetry: { maxTransientRetries: 1, jitterRatio: 0 },
}
@@ -469,6 +504,7 @@ describe('dsh-agent-spine-demo bundle', () => {
skills: appConfig.skills,
toolBash: appConfig.toolBash,
toolTasks: appConfig.toolTasks,
invariants: appConfig.invariants,
llmRetry: appConfig.llmRetry,
})
expect(agentCore.pickSpineConfig({ workspaceContext: false })).toEqual({ workspaceContext: false })
@@ -530,4 +566,16 @@ describe('dsh-agent-spine-demo bundle', () => {
expect(unwrapped.Config).toBeDefined()
expect(typeof unwrapped.apply).toBe('function')
})
it('keeps each standard-spine invariant companion loadable through the real Loader unwrap path', () => {
const loader = Object.create(Loader.prototype) as Loader
for (const companion of [sessionInvariant, agentInvariant, scopeInvariant, agentLoopInvariant]) {
expect('default' in companion).toBe(false)
const unwrapped = loader.unwrapExports(companion) as Record<string, unknown>
expect(unwrapped).toBe(companion)
expect(typeof unwrapped.name).toBe('string')
expect(unwrapped.inject).toContain('invariants')
expect(typeof unwrapped.apply).toBe('function')
}
})
})