diff --git a/apps/cli/config/agent-presets/core-web/agent.cordis.yml b/apps/cli/config/agent-presets/core-web/agent.cordis.yml index 48f7b5b3a0..9a251461c5 100644 --- a/apps/cli/config/agent-presets/core-web/agent.cordis.yml +++ b/apps/cli/config/agent-presets/core-web/agent.cordis.yml @@ -22,6 +22,11 @@ isolate: bashEnv: true config: + # The registry and its consumer share the realm: a consumer left outside + # would resolve the host's `bashEnv`, which this plane no longer provides. + - id: bash-env + name: '@deepseek-ai/dsh-bash-env' + - id: tool-bash name: '@deepseek-ai/dsh-tool-bash' diff --git a/apps/cli/config/agent-presets/standard/agent.cordis.yml b/apps/cli/config/agent-presets/standard/agent.cordis.yml index ccf0d92360..407e4d7d27 100644 --- a/apps/cli/config/agent-presets/standard/agent.cordis.yml +++ b/apps/cli/config/agent-presets/standard/agent.cordis.yml @@ -40,6 +40,11 @@ isolate: bashEnv: true config: + # The registry and its consumer share the realm: a consumer left outside + # would resolve the host's `bashEnv`, which this plane no longer provides. + - id: bash-env + name: '@deepseek-ai/dsh-bash-env' + - id: tool-bash name: '@deepseek-ai/dsh-tool-bash' diff --git a/apps/cli/tests/web-agent-presets.spec.ts b/apps/cli/tests/web-agent-presets.spec.ts index 87123dde36..4b854697ff 100644 --- a/apps/cli/tests/web-agent-presets.spec.ts +++ b/apps/cli/tests/web-agent-presets.spec.ts @@ -154,6 +154,36 @@ describe('the shipped Web composition', () => { }) }) +describe('a forked session', () => { + it('inherits the composition its seeded history was produced under', async () => { + const parent = await ctx.agents.create({ + sessionId: SessionId('preset-fork-parent'), + meta: { agentPreset: 'core-web' }, + setup: agentCtx => ctx.agentPresets.mount(agentCtx, 'core-web').then(() => undefined), + }) + const inherited = parent.agent.session.header.agentPreset + const child = await ctx.agents.create({ + sessionId: SessionId('preset-fork-child'), + meta: { + parentSession: SessionId('preset-fork-parent'), + seedLength: 0, + ...inherited === undefined ? {} : { agentPreset: inherited }, + }, + setup: agentCtx => ctx.agentPresets.mount(agentCtx, inherited).then(() => undefined), + }) + try { + // Composing nothing would leave the child empty: this layer moved every + // model-facing row out of the host plane, so there is nothing to inherit + // for free any more. + expect(toolNames(ctx, child.agent)).toEqual(toolNames(ctx, parent.agent)) + expect(toolNames(ctx, child.agent).length).toBeGreaterThan(0) + } finally { + await child.dispose() + await parent.dispose() + } + }) +}) + describe('a session keeps the preset it was created with', () => { it('refuses to adopt a live session under a different preset', async () => { const handle = await ctx.agents.create({ diff --git a/packages/bundle/web-app/cordis.patch.yml b/packages/bundle/web-app/cordis.patch.yml index 50b8d7f94e..ca28e5552a 100644 --- a/packages/bundle/web-app/cordis.patch.yml +++ b/packages/bundle/web-app/cordis.patch.yml @@ -201,6 +201,9 @@ # absent from a surface overlay would silently reappear the day someone reorders # the composition. +- id: bash-env + disabled: true + - id: tool-bash disabled: true diff --git a/packages/host/apiproxy/src/api-proxy.ts b/packages/host/apiproxy/src/api-proxy.ts index d465f1056c..8eefd9ac2f 100644 --- a/packages/host/apiproxy/src/api-proxy.ts +++ b/packages/host/apiproxy/src/api-proxy.ts @@ -1898,6 +1898,12 @@ export function createApiProxy(ctx: Context, defaults: ApiProxyDefaults): ApiPro }) } const childId = `session-${randomUUID()}` as SessionId + // The child inherits the parent's composition for the same reason a + // resumed session keeps its own: the seeded history was produced under + // those tools, and composing anything else would strand the tool calls + // it already carries. Now that no model-facing row sits in the host + // plane, composing nothing would leave the child with no tools at all. + const forkComposition = await composeAgent(source.header.agentPreset) try { await ctx.agents.create({ sessionId: childId, @@ -1906,9 +1912,12 @@ export function createApiProxy(ctx: Context, defaults: ApiProxyDefaults): ApiPro ...source.header.cwd === undefined ? {} : { cwd: source.header.cwd }, parentSession: source.id, seedLength: cut, + ...forkComposition.agentPreset === undefined + ? {} + : { agentPreset: forkComposition.agentPreset }, }, agentOptions, - setup: installTarget, + setup: forkComposition.setup, }) } catch (error: unknown) { return err(request, {