fix(subagent): tighten named Claude instance evidence

This commit is contained in:
pku-xht committed 2026-08-18 02:50:42 +08:00
1 parent 49351cbf0e
commit 044f65e46b
7 files changed
+20 -36

No files matched your search

@@ -2,5 +2,5 @@
# side as of the last confirmed-consistent state. Both languages carry equal authority;
# after editing either side, bring the other along and re-record with:
# pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-08-10-product-subagent-providers-in-shared-host.md
2026-08-10-product-subagent-providers-in-shared-host.md: 2798431709307e50a1ee16c7fc595bcead223f59
2026-08-10-product-subagent-providers-in-shared-host.md: 34c286821a245a659b668a8ba6676c4e3b1ba5e9
2026-08-10-product-subagent-providers-in-shared-host.zh.md: 981b1e2cd305c1410dcd744e3aea5028eb283806
@@ -26,7 +26,7 @@ The base bundle test proves production `dsh-base` contains neither product provi
## Alternatives considered
**Keep product providers opt-in at the Profile layer.** This preserves a smaller default dependency closure but requires the user to edit both a Profile and a Preset. The production-install exclusion decision accepts that installation trade-off; this note retains the requirement that any selected provider is mounted once on the host plane rather than inside the preset.
**Keep product providers opt-in at the Profile layer.** This preserves a smaller default dependency closure but requires the user to edit both a Profile and a Preset. The production-install exclusion decision accepts that installation trade-off; this note retains the requirement that selected provider instances are mounted on the host plane rather than inside the preset.
**Store global or per-Profile product enable switches.** A process switch competes with the Preset as owner of model-visible tools and cannot express two sessions using different combinations. Availability and authentication are deployment facts, not another persisted product state.
@@ -12,21 +12,15 @@
- id: subagent-codex
name: '@deepseek-ai/dsh-subagent-codex'
- id: subagent-claude-safe
- id: subagent-claude-primary
name: '@deepseek-ai/dsh-subagent-claude-code'
config:
providerName: claude-safe
permissionMode: dontAsk
env:
DSH_CLAUDE_INSTANCE: safe
providerName: claude-primary
- id: subagent-claude-bypass
- id: subagent-claude-secondary
name: '@deepseek-ai/dsh-subagent-claude-code'
config:
providerName: claude-bypass
permissionMode: bypassPermissions
env:
DSH_CLAUDE_INSTANCE: bypass
providerName: claude-secondary
- id: tool-subagent-codex
name: '@deepseek-ai/dsh-tool-subagent'
@@ -36,19 +30,19 @@
backgroundMode: one-shot
maxDepth: 'provider-managed'
- id: tool-subagent-claude-safe
- id: tool-subagent-claude-primary
name: '@deepseek-ai/dsh-tool-subagent'
config:
provider: claude-safe
toolName: subagent_claude_safe
provider: claude-primary
toolName: subagent_claude_primary
backgroundMode: one-shot
maxDepth: 'provider-managed'
- id: tool-subagent-claude-bypass
- id: tool-subagent-claude-secondary
name: '@deepseek-ai/dsh-tool-subagent'
config:
provider: claude-bypass
toolName: subagent_claude_bypass
provider: claude-secondary
toolName: subagent_claude_secondary
backgroundMode: one-shot
maxDepth: 'provider-managed'
@@ -23,11 +23,11 @@ const ctx = await boot(
)
try {
const providerNames = ['codex', 'claude-safe', 'claude-bypass'] as const
const providerNames = ['codex', 'claude-primary', 'claude-secondary'] as const
const toolNames = [
'subagent_codex',
'subagent_claude_safe',
'subagent_claude_bypass',
'subagent_claude_primary',
'subagent_claude_secondary',
] as const
const providers = providerNames.map((providerName) => {
const provider = ctx.subagents.getProvider(providerName)
@@ -131,9 +131,6 @@ export function apply(ctx: Context, config: Config): void {
`subagent-claude-code: disposeGraceMs must be no greater than ${MAX_TIMER_DELAY_MS}`,
)
}
if (resolved.providerName.length === 0) {
throw new TypeError('subagent-claude-code providerName must be non-empty')
}
ctx.subagents.registerProvider(new ClaudeCodeProvider(
resolved.providerName,
ctx,
@@ -31,7 +31,7 @@ describe('product-provider public Loader composition', () => {
expect(stderr).toBe('')
expect(JSON.parse(stdout)).toEqual({
registeredProviders: ['codex', 'claude-safe', 'claude-bypass'],
registeredProviders: ['codex', 'claude-primary', 'claude-secondary'],
providers: [
{
name: 'codex',
@@ -44,7 +44,7 @@ describe('product-provider public Loader composition', () => {
inheritsParentContext: false,
},
{
name: 'claude-safe',
name: 'claude-primary',
capabilities: {
outputSchema: false,
depthLimit: false,
@@ -54,7 +54,7 @@ describe('product-provider public Loader composition', () => {
inheritsParentContext: false,
},
{
name: 'claude-bypass',
name: 'claude-secondary',
capabilities: {
outputSchema: false,
depthLimit: false,
@@ -71,12 +71,12 @@ describe('product-provider public Loader composition', () => {
required: ['description', 'prompt'],
},
{
name: 'subagent_claude_safe',
name: 'subagent_claude_primary',
parameterNames: ['description', 'prompt', 'run_in_background'],
required: ['description', 'prompt'],
},
{
name: 'subagent_claude_bypass',
name: 'subagent_claude_secondary',
parameterNames: ['description', 'prompt', 'run_in_background'],
required: ['description', 'prompt'],
},
@@ -480,13 +480,6 @@ describe('task admission and package contracts', () => {
await ctx.plugin(LocalSubprocessRuntime)
claudeCode.apply(ctx, { env: {}, disposeGraceMs: 3_000 })
expect(ctx.subagents.getProvider('claude-code')).toBeDefined()
expect(() => {
claudeCode.apply(ctx, {
providerName: '',
env: {},
disposeGraceMs: 3_000,
})
}).toThrow('providerName must be non-empty')
await ctx.fiber.dispose()
})