Merge commit '0b307c4ea80ba603dee91b46731e4d14644d84d2' into codex/workflow-runs-chat-node-f6

This commit is contained in:
pku-xht
2026-08-10 21:08:32 +08:00
49 changed files with 909 additions and 92 deletions

View File

@@ -77,6 +77,7 @@
"@deepseek-ai/dsh-loader-smoke": "workspace:^",
"@deepseek-ai/dsh-session": "workspace:^",
"@deepseek-ai/dsh-settings": "workspace:^",
"@deepseek-ai/dsh-subagent": "workspace:^",
"@deepseek-ai/dsh-system-prompt": "workspace:^",
"@deepseek-ai/dsh-tools": "workspace:^",
"@types/js-yaml": "^4.0.9",

View File

@@ -11,6 +11,7 @@ import type { PatchOptions } from '@cordisjs/plugin-include'
import { beforeAll, describe, expect, it } from 'vitest'
import { settingsNamespace } from '@deepseek-ai/dsh-settings'
import { resolveSessionPreset, SETTINGS_NAMESPACE } from '@deepseek-ai/dsh-agent-presets'
import { applyChildComposition, childSessionMeta } from '@deepseek-ai/dsh-subagent'
import { CallId } from '@deepseek-ai/dsh-llm'
import type {} from '@deepseek-ai/dsh-skill'
import type {} from '@deepseek-ai/dsh-tools'
@@ -422,6 +423,59 @@ describe('a forked session', () => {
})
})
describe('a delegated child', () => {
it('runs on the composition its parent runs on', async () => {
const parent = await ctx.agents.create({
sessionId: SessionId('preset-child-parent'),
meta: { agentPreset: 'standard' },
setup: agentCtx => ctx.agentPresets.mount(agentCtx, 'standard').then(() => undefined),
})
// Exactly what an in-process subagent driver's creation window does.
const child = await parent.agent.ctx.agents.create({
sessionId: SessionId('preset-child'),
meta: childSessionMeta(parent.agent, 1, 0),
setup: (agentCtx) => {
applyChildComposition(agentCtx, parent.agent, {})
},
})
try {
expect(toolNames(ctx, child.agent)).toEqual(toolNames(ctx, parent.agent))
// The shipped `standard` preset is the whole coding agent; an empty
// child here is the defect, and equality alone would not catch it.
expect(toolNames(ctx, child.agent)).toContain('bash')
expect(child.agent.session.header.agentPreset).toBe('standard')
} finally {
await child.dispose()
await parent.dispose()
}
})
it('follows a parent that switched preset while blank', async () => {
const parent = await ctx.agents.create({
sessionId: SessionId('preset-child-switch-parent'),
meta: { agentPreset: 'standard' },
setup: agentCtx => ctx.agentPresets.mount(agentCtx, 'standard').then(() => undefined),
})
await ctx.agentPresets.recompose(parent.agent.ctx, 'minimal')
const child = await parent.agent.ctx.agents.create({
sessionId: SessionId('preset-child-switch'),
meta: childSessionMeta(parent.agent, 1, 0),
setup: (agentCtx) => {
applyChildComposition(agentCtx, parent.agent, {})
},
})
try {
// The live scope chain is the authority, not the parent's creation
// header — which still names `standard`.
expect(toolNames(ctx, child.agent)).toEqual(toolNames(ctx, parent.agent))
expect(child.agent.session.header.agentPreset).toBe('minimal')
} finally {
await child.dispose()
await parent.dispose()
}
})
})
describe('authoring a preset on the shipped composition', () => {
let authorCtx: Context
let userRoot: string

View File

@@ -3,6 +3,8 @@
- button "Ask a research subagent to"
- text: /
- button "event-sourcing researcher" [disabled]
- img
- text: Standard mode
- button "1 subagent":
- text: 1 subagent
- img

View File

@@ -3,6 +3,8 @@
- button "Ask a research subagent to"
- text: /
- button "event-sourcing researcher" [disabled]
- img
- text: Standard mode
- tablist:
- tab "Chat" [selected]
- tab "Trajectory"