Преглед изворни кода

test(subagent): align DSH SDK route evidence with profiles

pku-xht пре 1 месец
родитељ
комит
0aafe0f8f8

+ 2 - 2
docs/config-catalog.i18n.yaml

@@ -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 docs/config-catalog.md
-config-catalog.md: 9230b8de99a2e1d084a29a2fc92b3d445f59e5e7
-config-catalog.zh.md: d89fee530dec759a429ccf39f6972272955f2865
+config-catalog.md: a54f0ff7068bdb0149c0ae98c90ae8079695287f
+config-catalog.zh.md: aa3dbc5c5f4653f76287a746e36b7801441b6522

+ 1 - 1
docs/config-catalog.md

@@ -2385,7 +2385,7 @@ export interface Config {
 }
 ```
 
-Source: [`packages/subagent/subagent-dsh-sdk/src/index.ts:31`](../packages/subagent/subagent-dsh-sdk/src/index.ts)
+Source: [`packages/subagent/subagent-dsh-sdk/src/index.ts:33`](../packages/subagent/subagent-dsh-sdk/src/index.ts)
 
 <a id="deepseek-aidsh-subagent-fork-in-process"></a>
 

+ 1 - 1
docs/config-catalog.zh.md

@@ -2387,7 +2387,7 @@ export interface Config {
 }
 ```
 
-来源:[`packages/subagent/subagent-dsh-sdk/src/index.ts:31`](../packages/subagent/subagent-dsh-sdk/src/index.ts)
+来源:[`packages/subagent/subagent-dsh-sdk/src/index.ts:33`](../packages/subagent/subagent-dsh-sdk/src/index.ts)
 
 <a id="deepseek-aidsh-subagent-fork-in-process"></a>
 

+ 1 - 0
examples/python-sdk-agent/tests/fixtures/subagent/subagent-dsh-sdk/cordis.yml

@@ -29,6 +29,7 @@
   config:
     provider: dsh-sdk
     toolName: subagent
+    enableModelSelection: true
     agentOptions:
       maxTokens: 777
     # The SDK backend advertises no depthLimit: the child harness owns its own

+ 4 - 1
examples/python-sdk-agent/tests/fixtures/subagent/subagent-dsh-sdk/mock-delegating-llm.ts

@@ -66,5 +66,8 @@ export const inject = ['llm']
  * @param ctx - the plugin context supplying `ctx.llm`.
  */
 export function apply(ctx: Context): void {
-  ctx.llm.registerAdapter(['mock'], new MockDelegatingAdapter())
+  const providers = process.env.DSH_TEST_PARENT_PROVIDER === 'deepseek-official'
+    ? ['deepseek-official', 'mock']
+    : ['mock']
+  ctx.llm.registerAdapter(providers, new MockDelegatingAdapter())
 }

+ 46 - 43
examples/python-sdk-agent/tests/fixtures/subagent/subagent-dsh-sdk/snapshot.cordis.yml

@@ -1,51 +1,54 @@
-# JSON-RPC snapshot root: a deterministic parent model selects a route for a
-# separate SDK child runtime. Both runtimes persist their own request headers.
-- id: sdk-jsonrpc-server
-  name: '@deepseek-ai/dsh-sdk-jsonrpc-server'
+# SDK-profile patch for a deterministic parent model that selects a route for
+# a separate SDK child runtime. Both runtimes persist their request headers.
 
-- id: mock-llm
-  name: './mock-delegating-llm.ts'
-
-- id: subagent
-  name: '@deepseek-ai/dsh-subagent'
-
-- id: subagent-dsh-sdk
-  name: '@deepseek-ai/dsh-subagent-dsh-sdk'
-  config:
-    profile: sdk
-    patches: !!js JSON.parse(process.env.DSH_TEST_CHILD_PATCHES ?? '[]')
-    dshHome: !!js process.env.DSH_TEST_CHILD_HOME
-    provider: unavailable-default
-    model: unavailable-default
-    env:
-      DSH_TELEMETRY_DISABLED: '1'
+- id: llm-deepseek
+  name: '@deepseek-ai/dsh-llm-deepseek'
+  disabled: true
 
 - id: tool-subagent
   name: '@deepseek-ai/dsh-tool-subagent'
-  config:
-    provider: dsh-sdk
-    toolName: subagent
-    enableRunInBackground: false
-    agentOptions:
-      maxTokens: 777
-    maxDepth: 'provider-managed'
-
-- id: agent-spine
-  name: '@deepseek-ai/dsh-agent-spine-demo'
-  config:
-    persona: 'Test SDK subagent dynamic routing.'
-    workspaceContext: false
-    skills:
-      enabled: false
-    toolBash:
-      enableRunInBackground: false
-    toolJobs: false
-
-- id: sessions
+  disabled: true
+
+- id: sdk-jsonrpc-server
+  name: '@deepseek-ai/dsh-sdk-jsonrpc-server'
+  disabled: true
+
+- id: session-persistence-jsonl
   name: '@deepseek-ai/dsh-session-persistence-jsonl'
   config:
-    root: !!js process.env.DSH_SESSION_ROOT
+    root: !!js dshHomePath('sessions')
     compression: none
 
-- id: session-checkpoints
-  name: '@deepseek-ai/dsh-session-checkpoint-policy'
+- insert:
+    - id: mock-llm
+      name: './mock-delegating-llm.ts'
+      disabled: !!js process.env.DSH_SNAPSHOT !== 'record'
+
+    - id: subagent-dsh-sdk
+      name: '@deepseek-ai/dsh-subagent-dsh-sdk'
+      config:
+        profile: sdk
+        patches: !!js JSON.parse(process.env.DSH_TEST_CHILD_PATCHES ?? '[]')
+        dshHome: !!js process.env.DSH_TEST_CHILD_HOME
+        provider: mock
+        model: mock-routed
+        env:
+          DSH_TELEMETRY_DISABLED: '1'
+
+    - id: tool-subagent-dsh-sdk
+      name: '@deepseek-ai/dsh-tool-subagent'
+      config:
+        provider: dsh-sdk
+        toolName: subagent
+        enableModelSelection: true
+        enableRunInBackground: false
+        agentOptions:
+          maxTokens: 777
+        maxDepth: 'provider-managed'
+
+    - id: sdk-jsonrpc-server-dynamic-live
+      name: '@deepseek-ai/dsh-sdk-jsonrpc-server'
+      inject: [sdkAppStartup, loader]
+      disabled: !!js process.env.DSH_SNAPSHOT !== 'record'
+      config:
+        maxTokensAsSuccess: true

+ 22 - 0
examples/python-sdk-agent/tests/fixtures/subagent/subagent-dsh-sdk/snapshot.replay.cordis.yml

@@ -0,0 +1,22 @@
+# Keyless replay layer for the DSH SDK dynamic-route snapshot.
+
+- insert:
+    - id: llm-replay
+      name: '@deepseek-ai/dsh-llm-replay'
+      config:
+        providers:
+          - id: deepseek-official
+            name: DeepSeek
+            models:
+              - id: mock-delegate
+          - id: mock
+            name: Mock
+            models:
+              - id: mock-routed
+                reasoningEfforts: [max]
+
+    - id: sdk-jsonrpc-server-dynamic-replay
+      name: '@deepseek-ai/dsh-sdk-jsonrpc-server'
+      inject: [sdkAppStartup, loader]
+      config:
+        maxTokensAsSuccess: true

+ 25 - 3
examples/python-sdk-agent/tests/sdk.snapshot.ts

@@ -47,8 +47,16 @@ const replayPlugin = fileURLToPath(new URL(
 ))
 const dshSdkFixtureDir = join(testsDir, 'fixtures', 'subagent', 'subagent-dsh-sdk')
 const dshSdkSnapshotConfig = join(dshSdkFixtureDir, 'snapshot.cordis.yml')
+const dshSdkSnapshotReplayConfig = join(dshSdkFixtureDir, 'snapshot.replay.cordis.yml')
 const dshSdkChildConfig = join(dshSdkFixtureDir, 'child.cordis.yml')
 const dshSdkChildMockPath = join(dshSdkFixtureDir, 'child-mock-llm.ts')
+const dshSdkParentMockPath = join(dshSdkFixtureDir, 'mock-delegating-llm.ts')
+const dshSdkProviderPlugin = fileURLToPath(new URL(
+  exampleMode === 'lib'
+    ? '../../../packages/subagent/subagent-dsh-sdk/lib/index.js'
+    : '../../../packages/subagent/subagent-dsh-sdk/src/index.ts',
+  import.meta.url,
+))
 
 const MINIMAL_SYSTEM_PROMPT = 'You are the environment-selected minimal software engineer.'
 const MINIMAL_BASH_DESCRIPTION = `Run commands in a bash shell
@@ -127,8 +135,9 @@ const SCENARIOS: SdkScenario[] = [
     prompt: 'Delegate once using the requested child route.',
     sessionId: 'sdk-snapshot-dsh-sdk',
     children: 1,
-    configs: { live: dshSdkSnapshotConfig, replay: dshSdkSnapshotConfig },
-    sdkRoute: { provider: 'mock', model: 'mock-delegate' },
+    configs: { live: dshSdkSnapshotConfig, replay: dshSdkSnapshotReplayConfig },
+    environment: { DSH_TEST_PARENT_PROVIDER: 'deepseek-official' },
+    sdkRoute: { provider: 'deepseek-official', model: 'mock-delegate' },
     dshSdkChild: {
       config: dshSdkChildConfig,
       sessionRoot: '.child-dsh/sessions',
@@ -272,6 +281,16 @@ async function materializeReplayPatch(source: string, cwd: string): Promise<stri
   return target
 }
 
+/** Materialize the DSH SDK scenario patch with absolute test and provider modules. */
+async function materializeDshSdkPatch(source: string, cwd: string): Promise<string> {
+  const target = join(cwd, `.sdk-${basename(source)}`)
+  const content = (await readFile(source, 'utf8'))
+    .replaceAll("'@deepseek-ai/dsh-subagent-dsh-sdk'", JSON.stringify(pathToFileURL(dshSdkProviderPlugin).href))
+    .replaceAll("'./mock-delegating-llm.ts'", JSON.stringify(pathToFileURL(dshSdkParentMockPath).href))
+  await writeFile(target, content)
+  return target
+}
+
 /**
  * Normalize the SDK-visible notification stream: embedded `session.event`
  * envelopes get the session-log treatment (times zeroed, headers tokenized),
@@ -317,6 +336,9 @@ async function runScenario(scenario: SdkScenario): Promise<{
   const sessionsRoot = join(dshHome, 'sessions')
   const replayFixtures = recording ? [] : await hydrateReplayFixtures(scenario, cwd)
   const livePatch = scenario.configs?.live ?? liveConfig
+  const resolvedLivePatch = scenario.dshSdkChild === undefined
+    ? livePatch
+    : await materializeDshSdkPatch(livePatch, cwd)
   const replayPatch = scenario.configs?.replay ?? replayConfig
   const resolvedReplayPatch = recording ? undefined : await materializeReplayPatch(replayPatch, cwd)
   const additionalPatches = recording
@@ -351,7 +373,7 @@ async function runScenario(scenario: SdkScenario): Promise<{
   const harness = new DeepSeekHarness({
     profile: 'sdk',
     patches: [
-      livePatch,
+      resolvedLivePatch,
       ...resolvedReplayPatch === undefined ? [] : [resolvedReplayPatch],
       ...additionalPatches,
     ],

Разлика између датотеке није приказан због своје велике величине
+ 6 - 26
examples/python-sdk-agent/tests/snapshots/subagent-dsh-sdk-dynamic-route/notifications.expected.jsonl


Разлика између датотеке није приказан због своје велике величине
+ 9 - 16
examples/python-sdk-agent/tests/snapshots/subagent-dsh-sdk-dynamic-route/session.1.jsonl


Разлика између датотеке није приказан због своје велике величине
+ 9 - 26
examples/python-sdk-agent/tests/snapshots/subagent-dsh-sdk-dynamic-route/session.jsonl


+ 11 - 2
packages/subagent/tool-subagent/tests/tool-subagent.spec.ts

@@ -247,6 +247,7 @@ describe('dsh-tool-subagent', () => {
     }))
     await ctx.plugin(tool, {
       provider: 'capture',
+      enableModelSelection: true,
       agentOptions: { reasoningEffort: ReasoningEffortId('high'), maxTokens: 321 },
       maxDepth: 'provider-managed',
     })
@@ -290,7 +291,11 @@ describe('dsh-tool-subagent', () => {
       },
     })
     ctx.llm.registerAdapter(['alpha'], new MockAdapter([]))
-    await ctx.plugin(tool, { provider: 'provider-defaults', maxDepth: 'provider-managed' })
+    await ctx.plugin(tool, {
+      provider: 'provider-defaults',
+      enableModelSelection: true,
+      maxDepth: 'provider-managed',
+    })
     const parent = {
       ...fakeAgent('same-route-parent'),
       options: {
@@ -1002,7 +1007,11 @@ describe('dsh-tool-subagent background mode', () => {
       agentRouteDefaults: { provider: 'alpha', model: 'selected-model' },
       start: oldStart,
     })
-    await ctx.plugin(tool, { provider: 'swapped', maxDepth: 'provider-managed' })
+    await ctx.plugin(tool, {
+      provider: 'swapped',
+      enableModelSelection: true,
+      maxDepth: 'provider-managed',
+    })
     const adapter = new MockAdapter([])
     let releasePreflight!: () => void
     const preflightGate = new Promise<void>((resolve) => { releasePreflight = resolve })

Неке датотеке нису приказане због велике количине промена