fix(tools): keep executor changes out of registry notifications

This commit is contained in:
_Kerman committed 2026-10-21 12:13:57 +08:00
1 parent 6c1ae74d16
commit e727a3b161
9 files changed
+19 -15

No files matched your search

+2 -2
View File
@@ -676,11 +676,11 @@ Source: [`packages/core/tools/src/index.ts`](../../packages/core/tools/src/index
#### `tools/change` — emit
A tool or executor was registered or unregistered, or a scoped restriction changed. Unfiltered registry notification: scoped listeners receive changes from every scope because a global contribution can affect every agent's next assembly.
A tool was registered or unregistered, or a scoped restriction changed. Unfiltered registry notification: scoped listeners receive changes from every scope because a global contribution can affect every agent's next assembly.
```ts cordis-catalog
/**
* A tool or executor was registered or unregistered, or a scoped restriction changed.
* A tool was registered or unregistered, or a scoped restriction changed.
* Unfiltered registry notification: scoped listeners receive changes from every
* scope because a global contribution can affect every agent's next assembly.
* @mode emit
+2 -2
View File
@@ -676,11 +676,11 @@ Source: [`packages/core/tools/src/index.ts`](../../packages/core/tools/src/index
#### `tools/change` — emit
A tool or executor was registered or unregistered, or a scoped restriction changed. Unfiltered registry notification: scoped listeners receive changes from every scope because a global contribution can affect every agent's next assembly.
A tool was registered or unregistered, or a scoped restriction changed. Unfiltered registry notification: scoped listeners receive changes from every scope because a global contribution can affect every agent's next assembly.
```ts cordis-catalog
/**
* A tool or executor was registered or unregistered, or a scoped restriction changed.
* A tool was registered or unregistered, or a scoped restriction changed.
* Unfiltered registry notification: scoped listeners receive changes from every
* scope because a global contribution can affect every agent's next assembly.
* @mode emit
@@ -191,14 +191,20 @@ it('rejects new batches after unload while an accepted batch settles on its orig
expect(trace).toEqual(['old_eval:execute', 'replacement_eval:execute'])
})
it('refreshes the selected projection when the same assembly context is reused', async () => {
it('refreshes executor projections without emitting tool registry changes', async () => {
const ctx = await setup()
let registryChanges = 0
ctx.on('tools/change', () => { registryChanges++ })
const key = { preset: 'refresh' }
const scope = await scoped(ctx, key)
const context: AssembleContext = { scope: key }
expect((await ctx.systemPrompt.assemble(context)).tools.map(tool => tool.name)).toEqual(['echo'])
scope.ctx.tools.setExecutor(independent(scope.ctx, 'new_eval', []))
const dispose = scope.ctx.tools.setExecutor(independent(scope.ctx, 'new_eval', []))
expect((await ctx.systemPrompt.assemble(context)).tools.map(tool => tool.name)).toEqual(['new_eval'])
expect(registryChanges).toBe(0)
dispose()
await expect(ctx.systemPrompt.assemble(context)).rejects.toThrow('selected tool executor is unavailable')
expect(registryChanges).toBe(0)
})
it.each([
+2 -2
View File
@@ -21,8 +21,8 @@
en: 9d2e6caa39c53d62
zh: 096a777f828c7565
/deepseek-ai-dsh-tools/use-this-package/select-an-executor:
en: 1ddfa584f9280cb7
zh: b0899fcb8163569e
en: bdf27b6f339ea866
zh: b89205eedea1db0a
/deepseek-ai-dsh-tools/use-this-package/restrict-tools-per-agent:
en: c6f98b2283cc2e47
zh: c2cdce5d13473f15
+1 -1
View File
@@ -65,7 +65,7 @@ The unified schema DSL supports `string`, `number`, `integer`, `boolean`, `null`
### Select an executor
Mount one executor in the deployment, preset, or Agent scope. The nearest scope selects the provider; duplicate providers in one scope fail. Native exposes visible capabilities directly; PTC exposes `run_code` and a generated SDK.
Mount one executor in the deployment, preset, or Agent scope. The nearest scope selects the provider; duplicate providers in one scope fail. Native exposes visible capabilities directly; PTC exposes `run_code` and a generated SDK. Executor registration and disposal do not emit `tools/change`; prompt assemblies and batches resolve the current executor when they run.
```yaml
- name: '@deepseek-ai/dsh-tools'
+1 -1
View File
@@ -65,7 +65,7 @@ ctx.tools.register(defineTool({
### 选择执行器
在部署、预设或 Agent 作用域中挂载一个执行器。最近的作用域决定提供者,同一作用域的重复提供者会报错。原生执行器直接公开可见能力;PTC 执行器公开 `run_code` 和生成的 SDK。
在部署、预设或 Agent 作用域中挂载一个执行器。最近的作用域决定提供者,同一作用域的重复提供者会报错。原生执行器直接公开可见能力;PTC 执行器公开 `run_code` 和生成的 SDK。执行器注册和卸载不触发 `tools/change`;提示词组装和批次执行在运行时解析当前执行器。
```yaml
- name: '@deepseek-ai/dsh-tools'
+1 -1
View File
@@ -48,7 +48,7 @@ declare module '@deepseek-ai/cordis' {
*/
'tools/result'(this: Scoped<ToolsService>, exec: Readonly<ToolExecution>, result: Readonly<ToolExecutionResult>): undefined
/**
* A tool or executor was registered or unregistered, or a scoped restriction changed.
* A tool was registered or unregistered, or a scoped restriction changed.
* Unfiltered registry notification: scoped listeners receive changes from every
* scope because a global contribution can affect every agent's next assembly.
* @mode emit
-2
View File
@@ -260,11 +260,9 @@ export class ToolsService extends Service {
}
if (scope === undefined) this.root = record
else this.scoped.set(scope, record)
this.ctx.emit('tools/change')
yield () => {
// Keep an unavailable selection so a program cannot fall through to a different executor.
record.executor = undefined
this.ctx.emit('tools/change')
}
}.bind(this), 'tools.setExecutor()')
}
@@ -4691,8 +4691,8 @@ export const EVENT_API: readonly EventApiEntry[] = [
name: 'tools/change',
mode: 'emit',
signature: '\'tools/change\'(): void',
summary: 'A tool or executor was registered or unregistered, or a scoped restriction changed.',
description: 'A tool or executor was registered or unregistered, or a scoped restriction changed. Unfiltered registry notification: scoped listeners receive changes from every scope because a global contribution can affect every agent\'s next assembly.',
summary: 'A tool was registered or unregistered, or a scoped restriction changed.',
description: 'A tool was registered or unregistered, or a scoped restriction changed. Unfiltered registry notification: scoped listeners receive changes from every scope because a global contribution can affect every agent\'s next assembly.',
parameters: [],
},
{