@stackstackstack/dsh-agent-tool-presentation 0.1.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.i18n.yaml +6 -0
- package/README.md +31 -0
- package/README.zh.md +31 -0
- package/lib/index.js +51 -0
- package/lib/invariant.js +25 -0
- package/lib/types/index.d.ts +50 -0
- package/lib/types/invariant.d.ts +16 -0
- package/package.json +52 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 DeepSeek
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.i18n.yaml
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
# Bilingual-pair consistency record (docs/i18n/README.md): the git blob hash of each
|
|
2
|
+
# side as of the last confirmed-consistent state. Both languages carry equal authority;
|
|
3
|
+
# after editing either side, bring the other along and re-record with:
|
|
4
|
+
# pnpm run verify-translation-pairing --write packages/core/agent-tool-presentation/README.md
|
|
5
|
+
README.md: a4747d4d95a732f4eccb81ed44b68c961895d773
|
|
6
|
+
README.zh.md: 33b33c63cd61893ea68bd2ab5d7242f8cf7d7c27
|
package/README.md
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# dsh-agent-tool-presentation
|
|
2
|
+
|
|
3
|
+
English | [中文](README.zh.md)
|
|
4
|
+
|
|
5
|
+
The row an [agent preset](../../preset/agent-presets/README.md) carries to say which form of its tools the model sees: `native` (every schema), `code` (only `run_code` plus a generated TypeScript SDK), or `both`.
|
|
6
|
+
|
|
7
|
+
## Why a row rather than a registry
|
|
8
|
+
|
|
9
|
+
The tool registry cannot move into a preset. Its consumers are all host-plane — [`dsh-agent-loop`](../agent-loop/README.md) reads its scheduler, [`dsh-apiproxy`](../../host/apiproxy/README.md) reads its presenters to render tool cards, and every tool plugin registers into it — and a service only moves down when all of its consumers move with it.
|
|
10
|
+
|
|
11
|
+
What a preset can own is the **presentation** of that registry. `ctx.tools.presentAs()` declares it for the mounting agent alone, so a Code Mode session runs beside native ones in one process, each seeing its own catalog. The deployment's `mode` on the [`dsh-tools`](../tools/README.md) row remains the default that agents declaring nothing get.
|
|
12
|
+
|
|
13
|
+
## What it does
|
|
14
|
+
|
|
15
|
+
`native` applies immediately. A code mode instead waits for `ctx.codeRuntime`, which is a host-plane service ([`dsh-code-runtime-worker-thread`](../../code-runtime/code-runtime-worker-thread/README.md)): a preset selecting Code Mode against a deployment composing no runtime then holds this row pending, and `dsh-agent-presets` refuses the mount naming this id. The alternative — applying optimistically — moves the failure to the session's first request, where the operator can act on neither the preset nor the composition.
|
|
16
|
+
|
|
17
|
+
`mode` is required rather than defaulted, because a preset without this row already gets the deployment default; an omitted value would mean the row was composed for nothing.
|
|
18
|
+
|
|
19
|
+
One agent declares one presentation. A second declaration in the same composition is refused rather than merged: two answers to "which form does the model see" is a contradiction, not an override.
|
|
20
|
+
|
|
21
|
+
## Model Experience
|
|
22
|
+
|
|
23
|
+
Indirectly, through the projection it selects in `dsh-tools`: `code` presents `run_code` plus a generated SDK section and the rule that only `run_code` may be called directly, `native` presents every tool schema. The selection also decides what may EXECUTE: under `code` the registry resolves a model-direct call naming any other tool to `UNKNOWN_TOOL`, so this row is what keeps the announced surface and the callable surface the same for every agent it covers ([executor-collapse note](../../../.agents/notes/implemented/bug-fix/2026-08-07-code-mode-executor-collapse.md)).
|
|
24
|
+
|
|
25
|
+
#### KV Cache effect
|
|
26
|
+
|
|
27
|
+
No direct invalidation; the presentation is fixed when the agent is composed, so its request prefix is stable for the session's life.
|
|
28
|
+
|
|
29
|
+
## Known Limitations and Deferred Work
|
|
30
|
+
|
|
31
|
+
- **The runtime stays host-plane** — a preset can select Code Mode but cannot supply the TypeScript runtime it needs; a deployment that composes none can compose no code-mode preset.
|
package/README.zh.md
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# dsh-agent-tool-presentation
|
|
2
|
+
|
|
3
|
+
[English](README.md) | 中文
|
|
4
|
+
|
|
5
|
+
[agent preset](../../preset/agent-presets/README.md) 用来声明「模型看到的工具是哪一种形态」的那一行:`native`(全部 schema)、`code`(只有 `run_code` 加一份生成的 TypeScript SDK)或 `both`。
|
|
6
|
+
|
|
7
|
+
## 为什么是一行插件,而不是把注册表搬下来
|
|
8
|
+
|
|
9
|
+
工具注册表搬不进 preset。它的消费者全在宿主平面——[`dsh-agent-loop`](../agent-loop/README.md) 读它的调度器,[`dsh-apiproxy`](../../host/apiproxy/README.md) 读它的 presenter 来渲染工具卡,每个工具插件都往里注册——而一个服务只有在**所有**消费者一起下沉时才能下沉。
|
|
10
|
+
|
|
11
|
+
preset 能拥有的是这份注册表的**呈现方式**。`ctx.tools.presentAs()` 只为正在挂载的那个 agent 声明,于是一个 Code Mode 会话可以和多个 native 会话同进程并存,各自看到各自的清单。[`dsh-tools`](../tools/README.md) 那一行上的 `mode` 仍然是默认值,供未作声明的 agent 使用。
|
|
12
|
+
|
|
13
|
+
## 它做什么
|
|
14
|
+
|
|
15
|
+
`native` 立即生效。code 类模式则等待 `ctx.codeRuntime`——这是一个宿主平面服务([`dsh-code-runtime-worker-thread`](../../code-runtime/code-runtime-worker-thread/README.md)):若某个 preset 在未组装运行时的部署上选择 Code Mode,本行就停在 pending,`dsh-agent-presets` 会指名此 id 拒绝挂载。另一种做法——先乐观应用——会把失败推迟到该会话的第一次请求,那时操作者对 preset 和组装都已无从下手。
|
|
16
|
+
|
|
17
|
+
`mode` 是必填而非有默认值:不带这一行的 preset 本来就会拿到部署默认值,省略它等于这一行白组装了。
|
|
18
|
+
|
|
19
|
+
一个 agent 只声明一次呈现方式。同一份组装里的第二次声明会被拒绝而不是合并:对「模型看到哪种形态」给出两个答案是矛盾,不是覆盖。
|
|
20
|
+
|
|
21
|
+
## 模型体验
|
|
22
|
+
|
|
23
|
+
间接生效,取决于它在 `dsh-tools` 中选择的投影:`code` 呈现 `run_code`、一份生成的 SDK 段,以及「只有 `run_code` 可被直接调用」这条规则,`native` 呈现每个工具的 schema。该选择同时决定了**什么可以执行**:在 `code` 下,注册表会把模型直呼其他任何工具名解析为 `UNKNOWN_TOOL`,因此这一行正是让「通告面」与「可调用面」对每个被它覆盖的 agent 保持一致的东西([执行器塌缩 note](../../../.agents/notes/implemented/bug-fix/2026-08-07-code-mode-executor-collapse.md))。
|
|
24
|
+
|
|
25
|
+
#### KV Cache effect
|
|
26
|
+
|
|
27
|
+
没有直接的失效影响;呈现方式在 agent 组装时即固定,因此其请求前缀在该会话的整个生命周期内保持稳定。
|
|
28
|
+
|
|
29
|
+
## 已知限制与暂缓事项
|
|
30
|
+
|
|
31
|
+
- **运行时仍在宿主平面** —— preset 可以选择 Code Mode,却无法自带它所需的 TypeScript 运行时;未组装运行时的部署也就无法组装任何 code 模式的 preset。
|
package/lib/index.js
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import z from "@deepseek-ai/schemastery";
|
|
2
|
+
//#region lib/types/index.js
|
|
3
|
+
/**
|
|
4
|
+
* Agent-plane presentation selector: the row an agent preset carries to say
|
|
5
|
+
* which form of its tools the model sees.
|
|
6
|
+
*
|
|
7
|
+
* The tool registry itself stays on the host plane — the agent loop's
|
|
8
|
+
* scheduler, the API proxy's presenters, and every tool plugin are all its
|
|
9
|
+
* consumers, so it cannot move into a preset. What a preset CAN own is the
|
|
10
|
+
* presentation: `ctx.tools.presentAs()` declares it for the mounting SCOPE,
|
|
11
|
+
* which is the preset's standing mount, so the declaration covers every agent
|
|
12
|
+
* joined to that preset and a Code Mode preset runs beside native ones in one
|
|
13
|
+
* process. One row per composition, not one per session.
|
|
14
|
+
*
|
|
15
|
+
* A code mode needs a TypeScript code runtime, which is a host-plane service
|
|
16
|
+
* ([`dsh-code-runtime-worker-thread`](../../code-runtime/code-runtime-worker/README.md)).
|
|
17
|
+
* This row therefore waits for it rather than assuming it: a preset selecting
|
|
18
|
+
* Code Mode against a deployment that composes no runtime fails at mount, named
|
|
19
|
+
* in the preset's own activation audit, instead of at the first prompt.
|
|
20
|
+
* @module @stackstackstack/dsh-agent-tool-presentation
|
|
21
|
+
*/
|
|
22
|
+
/** Cordis plugin name. */
|
|
23
|
+
const name = "tool-presentation";
|
|
24
|
+
/**
|
|
25
|
+
* Required services. `codeRuntime` is NOT listed: a `native` row must mount in
|
|
26
|
+
* a deployment that composes no runtime, and the mode-dependent wait is
|
|
27
|
+
* declared inside {@link apply} instead.
|
|
28
|
+
*/
|
|
29
|
+
const inject = ["tools"];
|
|
30
|
+
/** Runtime schema. */
|
|
31
|
+
const Config = z.object({ mode: z.union([
|
|
32
|
+
"native",
|
|
33
|
+
"code",
|
|
34
|
+
"both"
|
|
35
|
+
]).required() });
|
|
36
|
+
/**
|
|
37
|
+
* Declare the tool presentation for every agent this composition covers.
|
|
38
|
+
* @param ctx - the mounting composition's scope context (a preset's standing scope).
|
|
39
|
+
* @param config - the selected presentation.
|
|
40
|
+
*/
|
|
41
|
+
function apply(ctx, config) {
|
|
42
|
+
if (config.mode === "native") {
|
|
43
|
+
ctx.tools.presentAs("native");
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
ctx.inject(["codeRuntime"], (runtimeCtx) => {
|
|
47
|
+
runtimeCtx.tools.presentAs(config.mode);
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
//#endregion
|
|
51
|
+
export { Config, apply, inject, name };
|
package/lib/invariant.js
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
//#region lib/types/invariant.js
|
|
2
|
+
/**
|
|
3
|
+
* Package-owned invariant companion for `@stackstackstack/dsh-agent-tool-presentation`.
|
|
4
|
+
* @module @stackstackstack/dsh-agent-tool-presentation/invariant
|
|
5
|
+
*/
|
|
6
|
+
const PACKAGE_NAME = "@stackstackstack/dsh-agent-tool-presentation";
|
|
7
|
+
/** Cordis companion plugin name. */
|
|
8
|
+
const name = "tool-presentation-invariant";
|
|
9
|
+
/** Service required before the companion can reserve package ownership. */
|
|
10
|
+
const inject = ["invariants"];
|
|
11
|
+
/**
|
|
12
|
+
* No runtime invariant: this package makes exactly one scoped call into
|
|
13
|
+
* `ctx.tools` and owns no event or snapshot of its own; the relation it
|
|
14
|
+
* establishes — which presentation one agent's assembly uses — is the tool
|
|
15
|
+
* registry's to hold, and `dsh-tools` observes it there.
|
|
16
|
+
*/
|
|
17
|
+
const install = () => {};
|
|
18
|
+
/**
|
|
19
|
+
* Register this package's invariant companion.
|
|
20
|
+
* @param ctx - Cordis context carrying the invariant service.
|
|
21
|
+
* @returns the installed registration's disposer after setup succeeds.
|
|
22
|
+
*/
|
|
23
|
+
const apply = (ctx) => Promise.resolve(ctx.invariants.register(PACKAGE_NAME, install));
|
|
24
|
+
//#endregion
|
|
25
|
+
export { apply, inject, name };
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agent-plane presentation selector: the row an agent preset carries to say
|
|
3
|
+
* which form of its tools the model sees.
|
|
4
|
+
*
|
|
5
|
+
* The tool registry itself stays on the host plane — the agent loop's
|
|
6
|
+
* scheduler, the API proxy's presenters, and every tool plugin are all its
|
|
7
|
+
* consumers, so it cannot move into a preset. What a preset CAN own is the
|
|
8
|
+
* presentation: `ctx.tools.presentAs()` declares it for the mounting SCOPE,
|
|
9
|
+
* which is the preset's standing mount, so the declaration covers every agent
|
|
10
|
+
* joined to that preset and a Code Mode preset runs beside native ones in one
|
|
11
|
+
* process. One row per composition, not one per session.
|
|
12
|
+
*
|
|
13
|
+
* A code mode needs a TypeScript code runtime, which is a host-plane service
|
|
14
|
+
* ([`dsh-code-runtime-worker-thread`](../../code-runtime/code-runtime-worker/README.md)).
|
|
15
|
+
* This row therefore waits for it rather than assuming it: a preset selecting
|
|
16
|
+
* Code Mode against a deployment that composes no runtime fails at mount, named
|
|
17
|
+
* in the preset's own activation audit, instead of at the first prompt.
|
|
18
|
+
* @module @stackstackstack/dsh-agent-tool-presentation
|
|
19
|
+
*/
|
|
20
|
+
import type { Context } from '@deepseek-ai/cordis';
|
|
21
|
+
import z from '@deepseek-ai/schemastery';
|
|
22
|
+
import type { ToolPresentationMode } from '@stackstackstack/dsh-tools';
|
|
23
|
+
/** Cordis plugin name. */
|
|
24
|
+
export declare const name = "tool-presentation";
|
|
25
|
+
/**
|
|
26
|
+
* Required services. `codeRuntime` is NOT listed: a `native` row must mount in
|
|
27
|
+
* a deployment that composes no runtime, and the mode-dependent wait is
|
|
28
|
+
* declared inside {@link apply} instead.
|
|
29
|
+
*/
|
|
30
|
+
export declare const inject: string[];
|
|
31
|
+
/** Plugin config. */
|
|
32
|
+
export interface Config {
|
|
33
|
+
/**
|
|
34
|
+
* The form this agent's model sees. `native` sends every visible schema,
|
|
35
|
+
* `code` sends only `run_code` plus a generated SDK, `both` sends both.
|
|
36
|
+
* Required rather than defaulted: the deployment default is what a preset
|
|
37
|
+
* without this row already gets, so an omitted value would mean the row was
|
|
38
|
+
* composed for nothing.
|
|
39
|
+
*/
|
|
40
|
+
mode: ToolPresentationMode;
|
|
41
|
+
}
|
|
42
|
+
/** Runtime schema. */
|
|
43
|
+
export declare const Config: z<Config>;
|
|
44
|
+
/**
|
|
45
|
+
* Declare the tool presentation for every agent this composition covers.
|
|
46
|
+
* @param ctx - the mounting composition's scope context (a preset's standing scope).
|
|
47
|
+
* @param config - the selected presentation.
|
|
48
|
+
*/
|
|
49
|
+
export declare function apply(ctx: Context, config: Config): void;
|
|
50
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Package-owned invariant companion for `@stackstackstack/dsh-agent-tool-presentation`.
|
|
3
|
+
* @module @stackstackstack/dsh-agent-tool-presentation/invariant
|
|
4
|
+
*/
|
|
5
|
+
import type { Context } from '@deepseek-ai/cordis';
|
|
6
|
+
/** Cordis companion plugin name. */
|
|
7
|
+
export declare const name = "tool-presentation-invariant";
|
|
8
|
+
/** Service required before the companion can reserve package ownership. */
|
|
9
|
+
export declare const inject: string[];
|
|
10
|
+
/**
|
|
11
|
+
* Register this package's invariant companion.
|
|
12
|
+
* @param ctx - Cordis context carrying the invariant service.
|
|
13
|
+
* @returns the installed registration's disposer after setup succeeds.
|
|
14
|
+
*/
|
|
15
|
+
export declare const apply: (ctx: Context) => Promise<() => void>;
|
|
16
|
+
//# sourceMappingURL=invariant.d.ts.map
|
package/package.json
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@stackstackstack/dsh-agent-tool-presentation",
|
|
3
|
+
"description": "Agent-plane presentation selector: composes one agent's tools as Code Mode, native, or both",
|
|
4
|
+
"version": "0.1.5",
|
|
5
|
+
"publishConfig": {
|
|
6
|
+
"access": "public"
|
|
7
|
+
},
|
|
8
|
+
"repository": {
|
|
9
|
+
"type": "git",
|
|
10
|
+
"url": "git+https://github.com/deepseek-ai/deepseek-harness.git",
|
|
11
|
+
"directory": "packages/core/agent-tool-presentation"
|
|
12
|
+
},
|
|
13
|
+
"type": "module",
|
|
14
|
+
"main": "lib/index.js",
|
|
15
|
+
"types": "lib/types/index.d.ts",
|
|
16
|
+
"exports": {
|
|
17
|
+
".": {
|
|
18
|
+
"types": "./lib/types/index.d.ts",
|
|
19
|
+
"default": "./lib/index.js"
|
|
20
|
+
},
|
|
21
|
+
"./invariant": {
|
|
22
|
+
"types": "./lib/types/invariant.d.ts",
|
|
23
|
+
"default": "./lib/invariant.js"
|
|
24
|
+
},
|
|
25
|
+
"./src/*": "./src/*",
|
|
26
|
+
"./package.json": "./package.json"
|
|
27
|
+
},
|
|
28
|
+
"files": [
|
|
29
|
+
"lib/index.js",
|
|
30
|
+
"lib/invariant.js",
|
|
31
|
+
"lib/types/**/*.d.ts"
|
|
32
|
+
],
|
|
33
|
+
"license": "MIT",
|
|
34
|
+
"dependencies": {
|
|
35
|
+
"@deepseek-ai/schemastery": "^3.18.1"
|
|
36
|
+
},
|
|
37
|
+
"peerDependencies": {
|
|
38
|
+
"@stackstackstack/dsh-invariants": "^0.1.5",
|
|
39
|
+
"@stackstackstack/dsh-tools": "^0.1.5",
|
|
40
|
+
"@deepseek-ai/cordis": "^4.0.1"
|
|
41
|
+
},
|
|
42
|
+
"devDependencies": {
|
|
43
|
+
"@stackstackstack/dsh-agent": "^0.1.5",
|
|
44
|
+
"@stackstackstack/dsh-code-runtime": "^0.1.5",
|
|
45
|
+
"@stackstackstack/dsh-scope": "^0.1.5",
|
|
46
|
+
"@stackstackstack/dsh-invariants": "^0.1.5",
|
|
47
|
+
"@stackstackstack/dsh-session": "^0.1.5",
|
|
48
|
+
"@stackstackstack/dsh-system-prompt": "^0.1.5",
|
|
49
|
+
"@stackstackstack/dsh-tools": "^0.1.5",
|
|
50
|
+
"@deepseek-ai/cordis": "^4.0.1"
|
|
51
|
+
}
|
|
52
|
+
}
|