@deepseek-ai/dsh-spill 0.1.2-rc.1 → 0.1.3-alpha.2

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/README.i18n.yaml CHANGED
@@ -2,5 +2,5 @@
2
2
  # side as of the last confirmed-consistent state. Both languages carry equal authority;
3
3
  # after editing either side, bring the other along and re-record with:
4
4
  # pnpm run verify-translation-pairing --write packages/spill/spill/README.md
5
- README.md: 260407b49681183569416d5a9b820a7014479107
6
- README.zh.md: 85bf20fc0a50dd3f224c67e245ed3b4dfb692c4f
5
+ README.md: 27fef4a17aabf2eb9b55bd804ecdbf252353f539
6
+ README.zh.md: 98c27ee70899fb1703284559c0056175420615b5
package/README.md CHANGED
@@ -1,5 +1,5 @@
1
1
  ---
2
- description: "The spill storage service: how deployments and plugin authors save oversized tool text and get back a retrievable locator."
2
+ description: "The spill storage service: save oversized tool text or captured session references and return a retrievable locator."
3
3
  kind: "package-reference"
4
4
  ---
5
5
 
@@ -9,7 +9,7 @@ English | [中文](README.zh.md)
9
9
 
10
10
  ## Summary
11
11
 
12
- `dsh-spill` lets any plugin or tool save oversized text through `ctx.spillStore` and receive an opaque locator, the exact byte count, and retrieval guidance the model can act on. It defines what a spill backend does, not how it stores — a deployment mounts a backend such as `dsh-spill-local` for real persistence, and the `dsh-spill-policy` plugin decides when a tool result is too large. Choose it when a deployment must keep oversized tool output retrievable without flooding the model's context. The service owns storage only: no retention policy, no tool-result replacement, and no retrieval or search API. A real storage failure rejects loudly, so the caller decides how to degrade.
12
+ `dsh-spill` lets any plugin or tool save oversized text through `ctx.spillStore` and receive an opaque locator, the exact byte count, and retrieval guidance the model can act on. It defines what a spill backend does, not how it stores — a deployment mounts a backend such as `dsh-spill-local` for real persistence, and the `dsh-spill-policy` plugin decides when a tool result is too large. Choose it when a deployment must keep oversized text retrievable without flooding the model's context. The service owns storage only: no retention policy, no tool-result replacement, and no retrieval or search API. A real storage failure rejects loudly, so the caller decides how to degrade.
13
13
 
14
14
  ## Table of Contents
15
15
 
@@ -25,11 +25,11 @@ English | [中文](README.zh.md)
25
25
  <a id="use-this-package"></a>
26
26
  ## Use this package
27
27
 
28
- A composition that spills tool output mounts one spill backend — this package alone stores nothing — and the `dsh-spill-policy` plugin decides when to spill. Plugin and tool authors call `ctx.spillStore.saveText()` directly to persist text under the current session.
28
+ A composition that saves spill artifacts mounts one backend — this package alone stores nothing. `dsh-spill-policy` decides when tool results spill; `dsh-session-reference` directly saves truncated reference transcripts without requiring that policy. Callers use `ctx.spillStore.saveText()` with an explicit owner; optional consumers discover the backend with `ctx.get("spillStore")`.
29
29
 
30
30
  ### When to choose it
31
31
 
32
- Choose spill storage when a deployment needs to keep oversized tool output retrievable after the model has only seen a bounded preview for example a fetched page body the model may want to read or grep later. You do not need this package when no tool in the composition produces results large enough to matter, or when the deployment has no local filesystem the model's tools can read; a backend whose locator is meaningful in that environment is a prerequisite.
32
+ Choose spill storage when a deployment needs to keep full text retrievable after the model sees a bounded preview, such as a fetched page body or a captured session-reference transcript. A backend whose locator and retrieval hint are usable in the deployment is a prerequisite; local filesystem access is not a service requirement.
33
33
 
34
34
  ### Smallest working composition
35
35
 
@@ -49,7 +49,7 @@ With a backend mounted, call `ctx.spillStore.saveText()` with the owning session
49
49
  ```text
50
50
  const ref = await ctx.spillStore.saveText({
51
51
  owner: { sessionId: 'session-1' },
52
- source: { toolName: 'web_fetch', callId: 'call-1', label: 'result' },
52
+ source: { kind: 'tool', toolName: 'web_fetch', callId: 'call-1', label: 'result' },
53
53
  suggestedName: 'web_fetch.txt',
54
54
  content: fullText,
55
55
  })
@@ -59,7 +59,7 @@ The returned `SpillRef` carries three fields: `locator`, an opaque model-facing
59
59
 
60
60
  ### Ownership and boundaries
61
61
 
62
- Storage is grouped by the owning session: forked sessions inherit existing locators from the seeded log without copying or re-owning them, and new spills after a fork use the child session id. `suggestedName` is only a hint — backends sanitize it to one safe segment and never trust it as a path. The service deliberately excludes what other packages own: retention and preview decisions (`dsh-output-retention`), when to spill (`dsh-spill-policy`), and retrieval or search (the backend's `retrievalHint` tells the model what to do with the locator).
62
+ Storage is grouped by the owning session: forked sessions inherit existing locators from the seeded log without copying or re-owning them, and new spills after a fork use the child session id. A session-reference artifact belongs to the target session receiving the context, not the referenced source session. `suggestedName` is only a hint — backends sanitize it to one safe segment and never trust it as a path. Consumers own preview and spill decisions; the backend owns storage and artifact expiry.
63
63
 
64
64
  ### Failures and recovery
65
65
 
@@ -93,7 +93,7 @@ The package is built on one separation and a deliberate minimum:
93
93
 
94
94
  ### Data model
95
95
 
96
- `SaveTextSpill` (owner, source, suggestedName, content) is the request; `SpillRef` (locator, bytes, retrievalHint) is the result. `SpillLocator` is a branded string so consumers cannot treat it as a path without the backend's intent; `SpillOwner.sessionId` is the save-time storage namespace, and `SpillSource` records the producing tool, call id, and label for readable filenames descriptive only, never access control.
96
+ `SaveTextSpill` separates storage ownership from descriptive provenance. `SpillSource` accepts either the tool source `{ kind: "tool", toolName, callId, label }` or `{ kind: "session-reference", sessionId, label }`, whose id names the captured source session. Session references never fabricate tool call ids. Neither provenance nor the owner namespace grants read access. Consumers treat the returned locator as opaque and present it with its retrieval hint.
97
97
 
98
98
  ### Lifecycle
99
99
 
@@ -150,6 +150,6 @@ The seam has only `saveText`; a save-file or link/copy path for existing executo
150
150
 
151
151
  #### Future: non-local backends and cleanup
152
152
 
153
- Remote or database backends for ACP or remote environments, and a cleanup or retention policy for old spill files (likely tied to session cleanup), remain open. A predictable, world-readable spill root would let other local users read spilled tool output, which is why the shipped backend keeps files private.
153
+ Remote or database backends remain open. The local backend applies its [startup-cleanup policy](../spill-local/README.md#startup-cleanup); the service defines no per-session cleanup or locator-refresh API.
154
154
 
155
155
  </details>
package/README.zh.md CHANGED
@@ -1,5 +1,5 @@
1
1
  ---
2
- description: "spill 存储服务:部署方与插件作者如何保存过大的工具文本并取回可检索的定位信息。"
2
+ description: "spill 存储服务:保存超大工具文本或已捕获的会话引用,并返回可检索的定位信息。"
3
3
  kind: "package-reference"
4
4
  ---
5
5
 
@@ -9,7 +9,7 @@ kind: "package-reference"
9
9
 
10
10
  ## 概述
11
11
 
12
- `dsh-spill` 让任何插件或工具都能通过 `ctx.spillStore` 保存过大的文本,并拿到一个不透明定位信息、精确的字节数与模型可以直接依据的取回指引。它定义 spill 后端做什么,而不规定如何存储——部署需要挂载 `dsh-spill-local` 之类的后端才能真正持久化,由 `dsh-spill-policy` 插件决定工具结果何时过大。当部署必须在不让模型上下文泛滥的前提下保留超大工具输出时,选择它。该服务只负责存储:没有保留策略、没有工具结果替换,也没有取回或搜索 API。真实存储故障会以拒绝结束,由调用方决定如何降级。
12
+ `dsh-spill` 让任何插件或工具都能通过 `ctx.spillStore` 保存过大的文本,并拿到一个不透明定位信息、精确的字节数与模型可以直接依据的取回指引。它定义 spill 后端做什么,而不规定如何存储——部署需要挂载 `dsh-spill-local` 之类的后端才能真正持久化,由 `dsh-spill-policy` 插件决定工具结果何时过大。当部署必须在不让模型上下文泛滥的前提下保留超大文本时,选择它。该服务只负责存储:没有保留策略、没有工具结果替换,也没有取回或搜索 API。真实存储故障会以拒绝结束,由调用方决定如何降级。
13
13
 
14
14
  ## 目录
15
15
 
@@ -25,11 +25,11 @@ kind: "package-reference"
25
25
  <a id="use-this-package"></a>
26
26
  ## 使用本包
27
27
 
28
- 需要 spill 工具输出的组合会挂载一个 spill 后端——仅本包本身不存储任何内容——并由 `dsh-spill-policy` 插件决定何时 spill。插件与工具作者直接调用 `ctx.spillStore.saveText()`,在当前会话下持久化文本。
28
+ 保存 spill 产物的组合需要挂载一个后端——仅本包本身不存储任何内容。`dsh-spill-policy` 决定工具结果何时 spill;`dsh-session-reference` 直接保存被截断引用的转录,不需要该策略。调用方使用 `ctx.spillStore.saveText()` 并明确指定归属;可选消费方通过 `ctx.get("spillStore")` 获取后端。
29
29
 
30
30
  ### 何时选择
31
31
 
32
- 当部署需要在模型只看到有界预览之后仍可检索超大的工具输出时,选择 spill 存储——例如模型稍后可能想读取或搜索的抓取页面正文。当组合中没有工具会产生大到值得处理的输出,或部署没有模型工具可读取的本地文件系统时,你不需要本包;此时需要的是一个在该环境中定位信息有明确含义的后端。
32
+ 当部署需要在模型看到有界预览后仍能取回全文时,选择 spill 存储,例如抓取的页面正文或已捕获的会话引用转录。前提是后端的定位信息与取回指引在部署环境中可用;该服务不要求本地文件系统访问。
33
33
 
34
34
  ### 最小可用组合
35
35
 
@@ -49,7 +49,7 @@ kind: "package-reference"
49
49
  ```text
50
50
  const ref = await ctx.spillStore.saveText({
51
51
  owner: { sessionId: 'session-1' },
52
- source: { toolName: 'web_fetch', callId: 'call-1', label: 'result' },
52
+ source: { kind: 'tool', toolName: 'web_fetch', callId: 'call-1', label: 'result' },
53
53
  suggestedName: 'web_fetch.txt',
54
54
  content: fullText,
55
55
  })
@@ -59,7 +59,7 @@ const ref = await ctx.spillStore.saveText({
59
59
 
60
60
  ### 归属与边界
61
61
 
62
- 存储按所属会话分组:fork 后的会话从种子日志继承既有定位信息,无需复制或更改归属,fork 后新产生的 spill 使用子会话 id。`suggestedName` 只是提示——后端会把它清理成单个安全路径段,绝不把它当作可信路径。该服务刻意排除其他包负责的内容:保留与预览决策(`dsh-output-retention`)、何时 spill(`dsh-spill-policy`),以及取回或搜索(后端的 `retrievalHint` 会告诉模型如何处理定位信息)。
62
+ 存储按所属会话分组:fork 后的会话从种子日志继承既有定位信息,无需复制或更改归属,fork 后新产生的 spill 使用子会话 id。会话引用产物归接收上下文的目标会话所有,而不是被引用的源会话。`suggestedName` 只是提示——后端会把它清理成单个安全路径段,绝不把它当作可信路径。预览与 spill 决策由消费方负责;存储与产物过期由后端负责。
63
63
 
64
64
  ### 故障与恢复
65
65
 
@@ -93,7 +93,7 @@ const ref = await ctx.spillStore.saveText({
93
93
 
94
94
  ### 数据模型
95
95
 
96
- `SaveTextSpill`(owner、source、suggestedName、content)是请求;`SpillRef`(locator、bytes、retrievalHint)是结果。`SpillLocator` 是带品牌类型的字符串,消费方无法在未获后端意图的情况下把它当作路径;`SpillOwner.sessionId` 是保存时存储命名空间,`SpillSource` 记录产生 spill 的工具、调用 id 与标签,用于可读文件名——仅作描述,绝非访问控制。
96
+ `SaveTextSpill` 将存储归属与描述性来源信息分开。`SpillSource` 接受工具来源 `{ kind: "tool", toolName, callId, label }` 或 `{ kind: "session-reference", sessionId, label }`,后者的 id 标识被捕获的源会话。会话引用绝不伪造工具调用 id。来源信息与归属命名空间都不授予读取权限。消费方把返回的定位信息视为不透明值,并与取回指引一同展示。
97
97
 
98
98
  ### 生命周期
99
99
 
@@ -150,6 +150,6 @@ const ref = await ctx.spillStore.saveText({
150
150
 
151
151
  #### 未来:非本地后端与清理
152
152
 
153
- 面向 ACP 或远程环境的远程或数据库后端,以及旧 spill 文件的清理或保留策略(很可能与会话清理挂钩),仍是开放问题。可预测且任何用户均可读取的 spill 根目录会让其他本地用户读到 spill 工具输出,这正是已交付后端把文件保持私有的原因。
153
+ 远程或数据库后端仍是开放方向。本地后端执行其[启动清理策略](../spill-local/README.zh.md#startup-cleanup);该服务未定义按会话清理或刷新定位信息的 API。
154
154
 
155
155
  </details>
package/lib/index.js CHANGED
@@ -20,7 +20,7 @@ function SpillLocator(locator) {
20
20
  //#region lib/types/index.js
21
21
  /**
22
22
  * Service Definition for the spill storage capability seam (`ctx.spillStore`): an abstract service defining WHAT a
23
- * spill backend does — persist a tool's oversized text and return a model-facing
23
+ * spill backend does — persist oversized text and return a model-facing
24
24
  * locator plus retrieval guidance — without saying HOW. Implementations
25
25
  * subclass {@link SpillStore} and register as the `spillStore` service;
26
26
  * `@deepseek-ai/dsh-spill-local` (host filesystem) is the first.
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Service Definition for the spill storage capability seam (`ctx.spillStore`): an abstract service defining WHAT a
3
- * spill backend does — persist a tool's oversized text and return a model-facing
3
+ * spill backend does — persist oversized text and return a model-facing
4
4
  * locator plus retrieval guidance — without saying HOW. Implementations
5
5
  * subclass {@link SpillStore} and register as the `spillStore` service;
6
6
  * `@deepseek-ai/dsh-spill-local` (host filesystem) is the first.
@@ -32,18 +32,25 @@ export interface SpillOwner {
32
32
  sessionId: SessionId;
33
33
  }
34
34
  /**
35
- * Tool and call that produced one spilled artifact recorded by the backend for a readable
36
- * filename and inspection. Not interpreted for access control; purely
37
- * descriptive.
35
+ * Producer of a spilled artifact. Tool results carry their model-issued call id;
36
+ * session references identify the captured source session instead. Descriptive
37
+ * provenance only, never access control.
38
38
  */
39
- export interface SpillSource {
39
+ export type SpillSource = {
40
+ kind: 'tool';
40
41
  /** The tool whose result was spilled (e.g. `web_fetch`). */
41
42
  toolName: string;
42
43
  /** The model-issued call id the result belongs to. */
43
44
  callId: ToolCallId;
44
45
  /** A short human label for the artifact (e.g. `result`). */
45
46
  label: string;
46
- }
47
+ } | {
48
+ kind: 'session-reference';
49
+ /** Session whose projected conversation was captured. */
50
+ sessionId: SessionId;
51
+ /** Host-provided label for the referenced session. */
52
+ label: string;
53
+ };
47
54
  /** One request to persist text to a spill artifact. */
48
55
  export interface SaveTextSpill {
49
56
  owner: SpillOwner;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@deepseek-ai/dsh-spill",
3
3
  "description": "Abstract spill storage seam (ctx.spillStore) for the DeepSeek Harness — save oversized tool text and return a retrieval locator",
4
- "version": "0.1.2-rc.1",
4
+ "version": "0.1.3-alpha.2",
5
5
  "publishConfig": {
6
6
  "access": "public"
7
7
  },
@@ -27,15 +27,15 @@
27
27
  ],
28
28
  "license": "MIT",
29
29
  "peerDependencies": {
30
- "@deepseek-ai/dsh-brand": "^0.1.2-rc.1",
31
- "@deepseek-ai/dsh-llm": "^0.1.2-rc.1",
32
- "@deepseek-ai/dsh-session": "^0.1.2-rc.1",
33
- "@deepseek-ai/cordis": "^4.0.2"
30
+ "@deepseek-ai/dsh-brand": "^0.1.3-alpha.2",
31
+ "@deepseek-ai/dsh-llm": "^0.1.3-alpha.2",
32
+ "@deepseek-ai/cordis": "^4.0.2",
33
+ "@deepseek-ai/dsh-session": "^0.1.3-alpha.2"
34
34
  },
35
35
  "devDependencies": {
36
- "@deepseek-ai/dsh-brand": "^0.1.2-rc.1",
37
- "@deepseek-ai/dsh-llm": "^0.1.2-rc.1",
38
- "@deepseek-ai/dsh-session": "^0.1.2-rc.1",
36
+ "@deepseek-ai/dsh-llm": "^0.1.3-alpha.2",
37
+ "@deepseek-ai/dsh-session": "^0.1.3-alpha.2",
38
+ "@deepseek-ai/dsh-brand": "^0.1.3-alpha.2",
39
39
  "@deepseek-ai/cordis": "^4.0.2"
40
40
  }
41
41
  }