@deepseek-ai/dsh-tool-session-query 0.1.1-rc.2 → 0.1.2-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 +2 -2
- package/README.md +122 -12
- package/README.zh.md +131 -21
- package/lib/index.js +18 -16
- package/lib/types/workspace-access.d.ts +4 -1
- package/package.json +29 -24
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/session-query/tool-session-query/README.md
|
|
5
|
-
README.md:
|
|
6
|
-
README.zh.md:
|
|
5
|
+
README.md: 6066c8466b0d161e80f96d1e667902ef30aa1d00
|
|
6
|
+
README.zh.md: e509e2e8546cc535c56ddf5a6a4a1d608276a252
|
package/README.md
CHANGED
|
@@ -1,24 +1,115 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: "Workspace-authorized model-facing session history tools for agent developers and maintainers choosing, configuring, or debugging prior-session search, tracing, and event reads."
|
|
3
|
+
kind: "package-reference"
|
|
4
|
+
---
|
|
5
|
+
|
|
1
6
|
# @deepseek-ai/dsh-tool-session-query
|
|
2
7
|
|
|
3
8
|
English | [中文](README.zh.md)
|
|
4
9
|
|
|
5
|
-
|
|
10
|
+
## Summary
|
|
11
|
+
|
|
12
|
+
`dsh-tool-session-query` gives the model five read-only tools over session history: `session_search`, `session_event_search`, `session_trace`, `session_event_trace`, and `session_event_read`. The tools are workspace-authorized — a model can only reach sessions whose `cwd` exactly matches its own caller session — and results are cursor-free plain text, so the model can search prior work and follow a useful hit into its lineage or exact event data. The package is opt-in and not mounted by shipped host compositions: mounting it adds one concise guidance section and the five schemas to every request. Configuration and usage come first; the implementation internals live in a collapsible developer section below.
|
|
13
|
+
|
|
14
|
+
## Table of Contents
|
|
15
|
+
|
|
16
|
+
- [Use this package](#use-this-package)
|
|
17
|
+
- [Understand the implementation](#understand-the-implementation)
|
|
18
|
+
- [Further Exploration](#further-exploration)
|
|
19
|
+
- [Model Experience](#model-experience)
|
|
20
|
+
- [Known Limitations and Deferred Work](#known-limitations-and-deferred-work)
|
|
21
|
+
- [Dev Note](#dev-note)
|
|
22
|
+
|
|
23
|
+
-----
|
|
6
24
|
|
|
7
|
-
|
|
25
|
+
<a id="use-this-package"></a>
|
|
26
|
+
## Use this package
|
|
8
27
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
28
|
+
Mount this package when the agent should be able to search its own prior sessions and inspect their relationships and events. The common path is explicit: mount the plugin over `ctx.sessionQuery` (backed by `dsh-session-query-sqlite`), then let the model call the tools.
|
|
29
|
+
|
|
30
|
+
### When to choose it
|
|
31
|
+
|
|
32
|
+
Choose it when a deployment wants model-driven retrieval of prior work — for example a coding agent that searches what it did in earlier sessions before starting a task. Avoid it when only programmatic retrieval is needed: `ctx.sessionQuery` itself serves code callers without the model-facing schema, prompt, and authorization layer.
|
|
33
|
+
|
|
34
|
+
### Configuration
|
|
35
|
+
|
|
36
|
+
| Field | Default | Meaning |
|
|
37
|
+
|---|---|---|
|
|
38
|
+
| `maxSearchResults` | `100` | Maximum authorized hits returned by one search call |
|
|
12
39
|
| `searchTimeoutMs` | `30000` | Cooperative deadline attached to both full-text search tools |
|
|
13
40
|
|
|
14
|
-
The
|
|
41
|
+
The generated [configuration catalog](../../../docs/config-catalog.md#deepseek-aidsh-tool-session-query) is the exhaustive source for every accepted field and its JSDoc.
|
|
42
|
+
|
|
43
|
+
### What the model can do
|
|
44
|
+
|
|
45
|
+
| Tool | What the model gets |
|
|
46
|
+
|---|---|
|
|
47
|
+
| `session_search` | Sessions matching a literal query, ranked, with title and best-match excerpt; always omits the caller session |
|
|
48
|
+
| `session_event_search` | Events matching a literal query inside one authorized session; for the current session it stops before the step that invoked it |
|
|
49
|
+
| `session_trace` | The authorized ancestor chain and descendant tree of one session; unauthorized boundaries appear as markers without hidden ids |
|
|
50
|
+
| `session_event_trace` | One event's positional replacements and cited source-event relationships |
|
|
51
|
+
| `session_event_read` | One full unabridged event as JSON, plus optional neighboring event summaries |
|
|
52
|
+
|
|
53
|
+
Workspace authority is conservative: cross-session access requires exact `cwd` equality between target and caller session, and a caller without `cwd` can inspect only itself. Requested parent ids are deduplicated and authority-checked before search; missing and cross-workspace guesses behave identically. Search results are cursor-free: a capped result asks the model to narrow its query, and never exposes provider cursors, offsets, page sizes, or a model-controlled limit. Timestamps at the tool boundary are timezone-qualified ISO 8601 and become inclusive epoch-millisecond filters.
|
|
54
|
+
|
|
55
|
+
### Failures and recovery
|
|
56
|
+
|
|
57
|
+
Every trusted query-service call crosses one error sanitizer: caller cancellation is preserved exactly, corpus and provider diagnostics go to the internal log, and unsafe or unprintable failures fall back to the fixed `SESSION_QUERY_TOOL_FAILED` code and message. Local argument-validation and authorization errors keep their precise tool-owned messages (`SESSION_QUERY_TOOL_UNAUTHORIZED` for a target outside the caller workspace). The package performs no byte or character truncation and does not import a spill backend; deployments that need bounded inline output mount `@deepseek-ai/dsh-spill-policy`, which can replace oversized rendered text while retaining the complete result.
|
|
58
|
+
|
|
59
|
+
-----
|
|
60
|
+
|
|
61
|
+
<a id="understand-the-implementation"></a>
|
|
62
|
+
## Understand the implementation
|
|
63
|
+
|
|
64
|
+
<details>
|
|
65
|
+
<summary>Implementation internals — click to expand</summary>
|
|
66
|
+
|
|
67
|
+
This section explains the design decisions behind the tools and points at the code that realizes them; the observable behavior is fully covered in [Use this package](#use-this-package).
|
|
68
|
+
|
|
69
|
+
### Design philosophy
|
|
15
70
|
|
|
16
|
-
|
|
71
|
+
The consumer is built on one separation and three commitments:
|
|
17
72
|
|
|
18
|
-
|
|
73
|
+
- **Narrow read-only tools.** Five tools with flat snake-case schemas, each teaching one follow-up step; no cursor, offset, page-size, or model-controlled limit ever reaches the model.
|
|
74
|
+
- **Authority derived from the caller, never the model.** Caller identity comes from `ToolExecution.exec.agent`; workspace is exact-string `cwd` equality, re-checked against the header observed with each result.
|
|
75
|
+
- **One model-boundary sanitizer.** Every trusted `ctx.sessionQuery` call goes through the service boundary, which preserves cancellation and contains diagnostic and classification failures.
|
|
76
|
+
- **No second truncation format.** Results stay complete; the generic spill policy owns bounded inline output.
|
|
19
77
|
|
|
20
|
-
The
|
|
78
|
+
The design history lives in the [model-facing session query tools note](../../../.agents/notes/implemented/feature/2026-07-24-model-facing-session-query-tools.md) and the [session-search-not-shipped-default note](../../../.agents/notes/implemented/feature/2026-08-02-session-search-not-shipped-default.md).
|
|
21
79
|
|
|
80
|
+
### Source map
|
|
81
|
+
|
|
82
|
+
| File | Role |
|
|
83
|
+
|---|---|
|
|
84
|
+
| [`src/index.ts`](src/index.ts) | Plugin entry: config, prompt section, five tool registrations |
|
|
85
|
+
| [`src/input.ts`](src/input.ts) | Model schemas, argument normalization, filter construction |
|
|
86
|
+
| [`src/workspace-access.ts`](src/workspace-access.ts) | Caller identity, workspace authorization, title access, lineage projection |
|
|
87
|
+
| [`src/service-boundary.ts`](src/service-boundary.ts) | Trusted calls and model-safe error translation |
|
|
88
|
+
| [`src/operations.ts`](src/operations.ts) | The five operation workflows |
|
|
89
|
+
| [`src/presentation.ts`](src/presentation.ts) | Text result rendering and tool-call cards |
|
|
90
|
+
|
|
91
|
+
### Operation flow
|
|
92
|
+
|
|
93
|
+
Each executor derives the caller, normalizes the model's arguments into service filters, authorizes the target (or the requested parent ids) against the caller workspace, and collects results through the service boundary. Both search tools page internally through provider cursors while the observed generation stays valid, stopping at `maxSearchResults`; because one search consumes generation-bound provider cursors, the two search tools execute exclusively with sibling tool calls, while the three exact trace/read tools opt into parallel execution. Lineage output replaces unauthorized ancestor and descendant boundaries with markers containing no hidden session id.
|
|
94
|
+
|
|
95
|
+
</details>
|
|
96
|
+
|
|
97
|
+
-----
|
|
98
|
+
|
|
99
|
+
<a id="further-exploration"></a>
|
|
100
|
+
## Further Exploration
|
|
101
|
+
|
|
102
|
+
Read these pages when the package-level contract is not enough. They move from the tool surface to the underlying service, the schema catalog, and the design evidence.
|
|
103
|
+
|
|
104
|
+
- [Generated tool catalog](../../../docs/tool-catalog.md#deepseek-aidsh-tool-session-query) — the five tool schemas as the model sees them.
|
|
105
|
+
- [dsh-session-query](../session-query/README.md) — the service these tools call.
|
|
106
|
+
- [dsh-session-query-sqlite](../session-query-sqlite/README.md) — the full-text backend behind the two search tools.
|
|
107
|
+
- [Session Query subsystem reference](../../../docs/subsystems/session-query.md) — the type-level contract under the tools.
|
|
108
|
+
- [Model-facing session query tools](../../../.agents/notes/implemented/feature/2026-07-24-model-facing-session-query-tools.md) — workspace authority, cursor-free results, and spill decisions.
|
|
109
|
+
|
|
110
|
+
-----
|
|
111
|
+
|
|
112
|
+
<a id="model-experience"></a>
|
|
22
113
|
## Model Experience
|
|
23
114
|
|
|
24
115
|
### System prompt
|
|
@@ -71,6 +162,25 @@ Append-only result text follows the reusable request prefix and does not invalid
|
|
|
71
162
|
|
|
72
163
|
## Known Limitations and Deferred Work
|
|
73
164
|
|
|
74
|
-
-
|
|
75
|
-
|
|
76
|
-
|
|
165
|
+
<a id="known-limitations-and-deferred-work"></a>
|
|
166
|
+
|
|
167
|
+
|
|
168
|
+
These limits define when this package is a poor fit or needs special operational care. They are current package constraints, not a task backlog.
|
|
169
|
+
|
|
170
|
+
- **Search caps without continuation** — search returns at most the deployment cap and asks the model to narrow its query when more matches exist; there is no continuation token.
|
|
171
|
+
- **Conservative workspace identity** — workspace identity is exact-string `cwd` equality, so symlink-equivalent paths do not share authority.
|
|
172
|
+
- **Inline payloads without the spill policy** — custom compositions without the generic spill policy accept complete trace and event payloads inline.
|
|
173
|
+
|
|
174
|
+
<a id="dev-note"></a>
|
|
175
|
+
### Dev Note
|
|
176
|
+
|
|
177
|
+
<details>
|
|
178
|
+
<summary>Working context for maintainers — click to expand</summary>
|
|
179
|
+
|
|
180
|
+
This Dev Note is working context for maintainers: open design questions and directions that are not decided. It is explicitly non-authoritative — shipped behavior, limits, and accepted rationale live in the sections above, the package code, and the linked Agent Notes.
|
|
181
|
+
|
|
182
|
+
#### Future: broader workspace semantics
|
|
183
|
+
|
|
184
|
+
Exact-string `cwd` equality is deliberately conservative; symlink-aware or canonical-path workspace identity would change which sessions share authority and is undecided.
|
|
185
|
+
|
|
186
|
+
</details>
|
package/README.zh.md
CHANGED
|
@@ -1,29 +1,120 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: "面向 agent 开发者与维护者的工作区授权模型会话历史工具,用于选择、配置或排查既往会话搜索、追踪与事件读取。"
|
|
3
|
+
kind: "package-reference"
|
|
4
|
+
---
|
|
5
|
+
|
|
1
6
|
# @deepseek-ai/dsh-tool-session-query
|
|
2
7
|
|
|
3
8
|
[English](README.md) | 中文
|
|
4
9
|
|
|
5
|
-
|
|
10
|
+
## 概述
|
|
11
|
+
|
|
12
|
+
`dsh-tool-session-query` 给模型提供五个会话历史只读工具:`session_search`、`session_event_search`、`session_trace`、`session_event_trace` 与 `session_event_read`。工具经工作区授权——模型只能访问 `cwd` 与其自身调用方会话完全相同的会话——结果是无游标的纯文本,因此模型可以搜索既往工作,并顺着有用命中进入其血缘或精确事件数据。本包是 opt-in,已发布宿主组合默认不挂载:挂载后每次请求都会增加一个精简指引章节与五个 schema。配置与用法在前;实现内部细节放在下方可折叠的开发者章节中。
|
|
13
|
+
|
|
14
|
+
## 目录
|
|
15
|
+
|
|
16
|
+
- [使用本包](#use-this-package)
|
|
17
|
+
- [理解实现](#understand-the-implementation)
|
|
18
|
+
- [进一步探索](#further-exploration)
|
|
19
|
+
- [模型体验](#model-experience)
|
|
20
|
+
- [已知限制与延期工作](#known-limitations-and-deferred-work)
|
|
21
|
+
- [开发备注](#dev-note)
|
|
22
|
+
|
|
23
|
+
-----
|
|
6
24
|
|
|
7
|
-
|
|
25
|
+
<a id="use-this-package"></a>
|
|
26
|
+
## 使用本包
|
|
8
27
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
28
|
+
当 agent 应该能搜索自己的既往会话并检查其关系与事件时挂载本包。常用路径是显式的:在 `ctx.sessionQuery`(由 `dsh-session-query-sqlite` 支撑)之上挂载插件,然后让模型调用这些工具。
|
|
29
|
+
|
|
30
|
+
### 何时选择
|
|
31
|
+
|
|
32
|
+
当部署需要模型驱动的既往工作检索时选择它——例如编程 agent 在开始任务前搜索更早会话中做过的事。只需要程序化检索时避免使用:`ctx.sessionQuery` 本身服务代码调用方,无需面向模型的 schema、提示词与授权层。
|
|
33
|
+
|
|
34
|
+
### 配置
|
|
35
|
+
|
|
36
|
+
| 字段 | 默认值 | 含义 |
|
|
37
|
+
|---|---|---|
|
|
38
|
+
| `maxSearchResults` | `100` | 一次搜索调用返回的最大已授权命中数 |
|
|
12
39
|
| `searchTimeoutMs` | `30000` | 附加到两个全文搜索工具的协作式截止时间 |
|
|
13
40
|
|
|
14
|
-
|
|
41
|
+
生成的[配置目录](../../../docs/config-catalog.zh.md#deepseek-aidsh-tool-session-query)是每个受支持字段及其 JSDoc 的穷尽式真源。
|
|
42
|
+
|
|
43
|
+
### 模型可以做什么
|
|
44
|
+
|
|
45
|
+
| 工具 | 模型得到什么 |
|
|
46
|
+
|---|---|
|
|
47
|
+
| `session_search` | 匹配字面查询的会话,经排序,带标题与最佳匹配摘录;始终省略调用方会话 |
|
|
48
|
+
| `session_event_search` | 一个已授权会话内匹配字面查询的事件;针对当前会话时,在调用它的步骤之前停止 |
|
|
49
|
+
| `session_trace` | 一个会话的已授权祖先链与后代树;未授权边界以不含隐藏 id 的标记出现 |
|
|
50
|
+
| `session_event_trace` | 一个事件的位置替换与被引用源事件关系 |
|
|
51
|
+
| `session_event_read` | 一个完整未删节事件(JSON),加可选的事件邻接摘要 |
|
|
52
|
+
|
|
53
|
+
工作区授权是保守的:跨会话访问要求目标与调用方会话的 `cwd` 严格相等,没有 `cwd` 的调用方只能检查自己。请求的父 id 会在搜索前去重并按权限检查;缺失与跨工作区猜测行为完全相同。搜索结果无游标:结果达到上限时请模型缩小查询,绝不暴露提供方游标、偏移、分页大小或模型可控上限。工具边界的时间戳是带时区限定的 ISO 8601,并转换为包含端点的 epoch 毫秒过滤器。
|
|
54
|
+
|
|
55
|
+
### 失败与恢复
|
|
56
|
+
|
|
57
|
+
每个可信查询服务调用都经过一个错误净化器:调用方取消被精确保留,语料库与提供方诊断进入内部日志,不安全或不可打印的失败回退到固定 `SESSION_QUERY_TOOL_FAILED` 代码与消息。本地参数校验与授权错误保留精确的工具自有消息(目标在调用方工作区之外时为 `SESSION_QUERY_TOOL_UNAUTHORIZED`)。本包不执行字节或字符截断,也不导入 spill 后端;需要限制内联输出的部署应挂载 `@deepseek-ai/dsh-spill-policy`,它可以在保留完整结果的同时替换过大的已渲染文本。
|
|
58
|
+
|
|
59
|
+
-----
|
|
60
|
+
|
|
61
|
+
<a id="understand-the-implementation"></a>
|
|
62
|
+
## 理解实现
|
|
63
|
+
|
|
64
|
+
<details>
|
|
65
|
+
<summary>实现细节——点击展开</summary>
|
|
66
|
+
|
|
67
|
+
本节解释工具背后的设计决策,并指出实现它们的代码位置;可观察行为已在[使用本包](#use-this-package)中完整说明。
|
|
68
|
+
|
|
69
|
+
### 设计理念
|
|
15
70
|
|
|
16
|
-
|
|
71
|
+
本消费方建立在一个分离与三项承诺之上:
|
|
17
72
|
|
|
18
|
-
|
|
73
|
+
- **窄而只读的工具。** 五个带扁平 snake-case schema 的工具,每个都引导一个后续步骤;游标、偏移、分页大小或模型可控上限永远不会到达模型。
|
|
74
|
+
- **授权来自调用方,绝不由模型提供。** 调用方身份来自 `ToolExecution.exec.agent`;工作区是字符串精确 `cwd` 相等,并对照每次结果观察到的 header 重新校验。
|
|
75
|
+
- **一个模型边界净化器。** 每个可信 `ctx.sessionQuery` 调用都经过服务边界,它保留取消并包含诊断与分类失败。
|
|
76
|
+
- **不引入第二种截断格式。** 结果保持完整;通用 spill 策略负责有界内联输出。
|
|
19
77
|
|
|
20
|
-
|
|
78
|
+
设计历史记录在[面向模型的会话查询工具笔记](../../../.agents/notes/implemented/feature/2026-07-24-model-facing-session-query-tools.zh.md)与 [session-search-not-shipped-default 笔记](../../../.agents/notes/implemented/feature/2026-08-02-session-search-not-shipped-default.zh.md)中。
|
|
21
79
|
|
|
80
|
+
### 源码地图
|
|
81
|
+
|
|
82
|
+
| 文件 | 职责 |
|
|
83
|
+
|---|---|
|
|
84
|
+
| [`src/index.ts`](src/index.ts) | 插件入口:配置、提示词章节、五个工具注册 |
|
|
85
|
+
| [`src/input.ts`](src/input.ts) | 模型 schema、参数规范化、过滤器构造 |
|
|
86
|
+
| [`src/workspace-access.ts`](src/workspace-access.ts) | 调用方身份、工作区授权、标题访问、血缘投影 |
|
|
87
|
+
| [`src/service-boundary.ts`](src/service-boundary.ts) | 可信调用与模型安全错误转换 |
|
|
88
|
+
| [`src/operations.ts`](src/operations.ts) | 五个操作工作流 |
|
|
89
|
+
| [`src/presentation.ts`](src/presentation.ts) | 文本结果渲染与工具调用卡片 |
|
|
90
|
+
|
|
91
|
+
### 操作流程
|
|
92
|
+
|
|
93
|
+
每个执行器先派生调用方,把模型的参数规范化为服务过滤器,对照调用方工作区授权目标(或请求的父 id),然后通过服务边界收集结果。两个搜索工具在观察世代仍有效时内部翻页消费提供方游标,停在 `maxSearchResults`;由于一次搜索会消费与世代绑定的提供方游标,两个搜索工具与同级工具调用排他执行,而三个精确追踪/读取工具选择并行执行。血缘输出用不含隐藏会话 id 的标记替换未授权祖先与后代边界。
|
|
94
|
+
|
|
95
|
+
</details>
|
|
96
|
+
|
|
97
|
+
-----
|
|
98
|
+
|
|
99
|
+
<a id="further-exploration"></a>
|
|
100
|
+
## 进一步探索
|
|
101
|
+
|
|
102
|
+
当包级约定不够用时阅读以下页面。它们从工具表面逐步进入底层服务、schema 目录与设计证据。
|
|
103
|
+
|
|
104
|
+
- [生成的工具目录](../../../docs/tool-catalog.zh.md#deepseek-aidsh-tool-session-query)——模型看到的五个工具 schema。
|
|
105
|
+
- [dsh-session-query](../session-query/README.zh.md)——这些工具调用的服务。
|
|
106
|
+
- [dsh-session-query-sqlite](../session-query-sqlite/README.zh.md)——两个搜索工具背后的全文后端。
|
|
107
|
+
- [会话查询子系统参考](../../../docs/subsystems/session-query.zh.md)——工具之下的类型级约定。
|
|
108
|
+
- [面向模型的会话查询工具](../../../.agents/notes/implemented/feature/2026-07-24-model-facing-session-query-tools.zh.md)——工作区授权、无游标结果与 spill 决策。
|
|
109
|
+
|
|
110
|
+
-----
|
|
111
|
+
|
|
112
|
+
<a id="model-experience"></a>
|
|
22
113
|
## 模型体验
|
|
23
114
|
|
|
24
115
|
### 系统提示词
|
|
25
116
|
|
|
26
|
-
####
|
|
117
|
+
#### 模型看到什么
|
|
27
118
|
|
|
28
119
|
模型会收到一个固定的既往历史指引章节。
|
|
29
120
|
|
|
@@ -39,27 +130,27 @@ Use session_search to find relevant work from prior sessions, or session_event_s
|
|
|
39
130
|
|
|
40
131
|
#### KV Cache 影响
|
|
41
132
|
|
|
42
|
-
|
|
133
|
+
插件与指引文本不变时,前缀稳定。
|
|
43
134
|
|
|
44
135
|
### 工具 schema
|
|
45
136
|
|
|
46
|
-
####
|
|
137
|
+
#### 模型看到什么
|
|
47
138
|
|
|
48
|
-
模型会看到生成的 [`session_search`、`session_event_search`、`session_trace`、`session_event_trace`
|
|
139
|
+
模型会看到生成的 [`session_search`、`session_event_search`、`session_trace`、`session_event_trace` 与 `session_event_read` schema](../../../docs/tool-catalog.zh.md#deepseek-aidsh-tool-session-query)。搜索过滤器会增加固定 schema token,而游标、工作区路径、输出分页与模型可控结果上限仍不存在。
|
|
49
140
|
|
|
50
141
|
#### Token 影响
|
|
51
142
|
|
|
52
|
-
|
|
143
|
+
可见期间,每次请求都会发送五个固定只读 schema。
|
|
53
144
|
|
|
54
145
|
#### KV Cache 影响
|
|
55
146
|
|
|
56
|
-
|
|
147
|
+
工具可见性与定义不变时,前缀稳定。
|
|
57
148
|
|
|
58
149
|
### 工具结果
|
|
59
150
|
|
|
60
|
-
####
|
|
151
|
+
#### 模型看到什么
|
|
61
152
|
|
|
62
|
-
|
|
153
|
+
每次成功调用都会发出一个纯文本块。搜索结果包含标题与最佳匹配摘录;追踪包含全部已授权关系;事件读取包含未经删节的目标 JSON。通用 spill 策略可以用其预览、不透明定位信息与取回指引替换过大的内联文本。
|
|
63
154
|
|
|
64
155
|
#### Token 影响
|
|
65
156
|
|
|
@@ -69,8 +160,27 @@ Use session_search to find relevant work from prior sessions, or session_event_s
|
|
|
69
160
|
|
|
70
161
|
仅追加的结果文本位于可重用请求前缀之后,不会使较早的缓存条目失效。
|
|
71
162
|
|
|
72
|
-
##
|
|
163
|
+
## 已知限制与延期工作
|
|
164
|
+
|
|
165
|
+
<a id="known-limitations-and-deferred-work"></a>
|
|
166
|
+
|
|
167
|
+
|
|
168
|
+
这些限制说明本包何时不合适,或何时需要特别的运维注意。它们是当前包约束,不是任务积压。
|
|
169
|
+
|
|
170
|
+
- **搜索有上限且无延续**——搜索最多返回部署上限,匹配更多时会请模型缩小查询;不提供延续 token。
|
|
171
|
+
- **保守的工作区身份**——工作区身份是字符串精确 `cwd` 相等,因此符号链接等价的路径不共享权限。
|
|
172
|
+
- **无 spill 策略时内联载荷**——未挂载通用 spill 策略的自定义组合会以内联方式接收完整追踪与事件载荷。
|
|
173
|
+
|
|
174
|
+
<a id="dev-note"></a>
|
|
175
|
+
### 开发备注
|
|
176
|
+
|
|
177
|
+
<details>
|
|
178
|
+
<summary>维护者的工作上下文——点击展开</summary>
|
|
179
|
+
|
|
180
|
+
本开发备注是维护者的工作上下文:开放设计问题与尚未决定的探索方向。它明确不具权威性——已交付的行为、限制与既定理由以上文、包代码和相关 Agent Note 为准。
|
|
181
|
+
|
|
182
|
+
#### 未来:更宽泛的工作区语义
|
|
183
|
+
|
|
184
|
+
字符串精确 `cwd` 相等是刻意保守的选择;符号链接感知或规范路径的工作区身份会改变哪些会话共享权限,尚未决定。
|
|
73
185
|
|
|
74
|
-
|
|
75
|
-
- 工作区身份使用保守的字符串精确 `cwd` 相等性,因此符号链接等价的路径不共享权限。
|
|
76
|
-
- 未挂载通用 spill 策略的自定义组合会以内联方式接收完整跟踪和事件载荷。
|
|
186
|
+
</details>
|
package/lib/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import z from "@deepseek-ai/schemastery";
|
|
2
2
|
import { MAX_TIMER_DELAY_MS } from "@deepseek-ai/dsh-timeout";
|
|
3
3
|
import { defineTool } from "@deepseek-ai/dsh-tools";
|
|
4
|
-
import {
|
|
4
|
+
import { brandString } from "@deepseek-ai/dsh-brand";
|
|
5
5
|
import { SessionQueryError, extractSessionEventText } from "@deepseek-ai/dsh-session-query";
|
|
6
6
|
import { HarnessError } from "@deepseek-ai/dsh-llm";
|
|
7
7
|
//#region lib/types/input.js
|
|
@@ -134,7 +134,7 @@ function buildSessionFilters(args) {
|
|
|
134
134
|
assertNonEmptyArray("session_ids", args.session_ids);
|
|
135
135
|
filters.push({
|
|
136
136
|
kind: "id",
|
|
137
|
-
values: args.session_ids.map(
|
|
137
|
+
values: args.session_ids.map((value) => brandString(value))
|
|
138
138
|
});
|
|
139
139
|
}
|
|
140
140
|
const created = timestampRange("created_at", args.created_at_from, args.created_at_to);
|
|
@@ -154,7 +154,7 @@ function buildSessionFilters(args) {
|
|
|
154
154
|
function materializeParentSessionIds(values) {
|
|
155
155
|
if (values === void 0) return void 0;
|
|
156
156
|
assertNonEmptyArray("parent_session_ids", values);
|
|
157
|
-
return [...new Set(values.map(
|
|
157
|
+
return [...new Set(values.map((value) => brandString(value)))];
|
|
158
158
|
}
|
|
159
159
|
function buildEventFilters(input) {
|
|
160
160
|
const filters = [];
|
|
@@ -440,17 +440,18 @@ const serviceBoundary = {
|
|
|
440
440
|
*
|
|
441
441
|
* @module @deepseek-ai/dsh-tool-session-query/workspace-access
|
|
442
442
|
*/
|
|
443
|
-
function callerOf(exec) {
|
|
443
|
+
function callerOf(exec, ctx) {
|
|
444
444
|
const agent = exec.agent;
|
|
445
445
|
if (agent === void 0) throw new HarnessError("session query tools require an agent-bound caller", "SESSION_QUERY_TOOL_MISSING_AGENT");
|
|
446
446
|
return {
|
|
447
447
|
id: agent.session.id,
|
|
448
448
|
header: agent.session.header,
|
|
449
|
-
events: agent.session.events
|
|
449
|
+
events: agent.session.events,
|
|
450
|
+
boundary: ctx.sessionProjections.stateOf(agent.session, "turnBoundary")
|
|
450
451
|
};
|
|
451
452
|
}
|
|
452
453
|
function targetId(args, caller) {
|
|
453
|
-
return args.session_id === void 0 ? caller.id :
|
|
454
|
+
return args.session_id === void 0 ? caller.id : brandString(args.session_id);
|
|
454
455
|
}
|
|
455
456
|
async function authorizeTarget(ctx, caller, target, signal) {
|
|
456
457
|
if (target === caller.id) return;
|
|
@@ -745,7 +746,7 @@ const presentation = {
|
|
|
745
746
|
* @module @deepseek-ai/dsh-tool-session-query/operations
|
|
746
747
|
*/
|
|
747
748
|
async function executeSessionSearch(ctx, args, exec, maxResults) {
|
|
748
|
-
const caller = workspaceAccess.callerOf(exec);
|
|
749
|
+
const caller = workspaceAccess.callerOf(exec, ctx);
|
|
749
750
|
const cwd = caller.header.cwd;
|
|
750
751
|
if (cwd === void 0) throw new HarnessError("cross-session search is unavailable because the caller session has no workspace", "SESSION_QUERY_TOOL_UNAUTHORIZED");
|
|
751
752
|
const query = toolInput.normalizeQuery(args.query);
|
|
@@ -785,15 +786,15 @@ async function executeSessionSearch(ctx, args, exec, maxResults) {
|
|
|
785
786
|
return presentation.formatSessionSearch(collected, titles, authorizedParents);
|
|
786
787
|
}
|
|
787
788
|
async function executeEventSearch(ctx, args, exec, maxResults) {
|
|
788
|
-
const caller = workspaceAccess.callerOf(exec);
|
|
789
|
+
const caller = workspaceAccess.callerOf(exec, ctx);
|
|
789
790
|
const sessionId = workspaceAccess.targetId(args, caller);
|
|
790
791
|
await workspaceAccess.authorizeTarget(ctx, caller, sessionId, exec.signal);
|
|
791
792
|
const query = toolInput.normalizeQuery(args.query);
|
|
792
793
|
const range = toolInput.sequenceRange(args.seq_from, args.seq_to);
|
|
793
794
|
if (sessionId === caller.id) {
|
|
794
|
-
const
|
|
795
|
-
if (
|
|
796
|
-
range.to = Math.min(range.to ?? Number.MAX_SAFE_INTEGER,
|
|
795
|
+
const stepStartSeq = caller.boundary?.lastStepStartSeq;
|
|
796
|
+
if (stepStartSeq === void 0) throw new HarnessError("current-session search requires an active step boundary", "SESSION_QUERY_TOOL_NO_CURRENT_STEP");
|
|
797
|
+
range.to = Math.min(range.to ?? Number.MAX_SAFE_INTEGER, (stepStartSeq ?? 0) - 1);
|
|
797
798
|
}
|
|
798
799
|
const title = await workspaceAccess.readTitle(ctx, caller, sessionId, exec.signal);
|
|
799
800
|
if (range.from !== void 0 && range.to !== void 0 && range.from > range.to) return presentation.formatEventSearch(sessionId, title, {
|
|
@@ -821,7 +822,7 @@ async function executeEventSearch(ctx, args, exec, maxResults) {
|
|
|
821
822
|
return presentation.formatEventSearch(sessionId, title, collected);
|
|
822
823
|
}
|
|
823
824
|
async function executeSessionTrace(ctx, args, exec) {
|
|
824
|
-
const caller = workspaceAccess.callerOf(exec);
|
|
825
|
+
const caller = workspaceAccess.callerOf(exec, ctx);
|
|
825
826
|
const sessionId = workspaceAccess.targetId(args, caller);
|
|
826
827
|
await workspaceAccess.authorizeTarget(ctx, caller, sessionId, exec.signal);
|
|
827
828
|
const trace = await serviceBoundary.call(ctx, exec.signal, "session lineage trace", () => ctx.sessionQuery.traceSession(sessionId, exec.signal));
|
|
@@ -847,7 +848,7 @@ async function executeSessionTrace(ctx, args, exec) {
|
|
|
847
848
|
}
|
|
848
849
|
async function executeEventTrace(ctx, args, exec) {
|
|
849
850
|
toolInput.assertNonNegativeSafeInteger("seq", args.seq);
|
|
850
|
-
const caller = workspaceAccess.callerOf(exec);
|
|
851
|
+
const caller = workspaceAccess.callerOf(exec, ctx);
|
|
851
852
|
const sessionId = workspaceAccess.targetId(args, caller);
|
|
852
853
|
await workspaceAccess.authorizeTarget(ctx, caller, sessionId, exec.signal);
|
|
853
854
|
const trace = await serviceBoundary.call(ctx, exec.signal, "event trace", () => ctx.sessionQuery.traceEvent({
|
|
@@ -862,7 +863,7 @@ async function executeEventRead(ctx, args, exec) {
|
|
|
862
863
|
toolInput.assertNonNegativeSafeInteger("seq", args.seq);
|
|
863
864
|
if (args.before !== void 0) toolInput.assertNonNegativeSafeInteger("before", args.before);
|
|
864
865
|
if (args.after !== void 0) toolInput.assertNonNegativeSafeInteger("after", args.after);
|
|
865
|
-
const caller = workspaceAccess.callerOf(exec);
|
|
866
|
+
const caller = workspaceAccess.callerOf(exec, ctx);
|
|
866
867
|
const sessionId = workspaceAccess.targetId(args, caller);
|
|
867
868
|
await workspaceAccess.authorizeTarget(ctx, caller, sessionId, exec.signal);
|
|
868
869
|
const window = await serviceBoundary.call(ctx, exec.signal, "event read", () => ctx.sessionQuery.readEvent({
|
|
@@ -921,7 +922,8 @@ const name = "tool-session-query";
|
|
|
921
922
|
const inject = [
|
|
922
923
|
"tools",
|
|
923
924
|
"systemPrompt",
|
|
924
|
-
"sessionQuery"
|
|
925
|
+
"sessionQuery",
|
|
926
|
+
"sessionProjections"
|
|
925
927
|
];
|
|
926
928
|
/** Default maximum number of authorized search hits returned by one call. */
|
|
927
929
|
const DEFAULT_MAX_SEARCH_RESULTS = 100;
|
|
@@ -945,7 +947,7 @@ function apply(ctx, config) {
|
|
|
945
947
|
const resolved = resolveConfig(config);
|
|
946
948
|
ctx.systemPrompt.section({
|
|
947
949
|
name: "tool:session-query",
|
|
948
|
-
order:
|
|
950
|
+
order: ctx.systemPrompt.getSectionOrder("TOOL_SESSION_QUERY"),
|
|
949
951
|
text: PROMPT_TEXT
|
|
950
952
|
});
|
|
951
953
|
ctx.tools.register(defineTool({
|
|
@@ -5,12 +5,15 @@
|
|
|
5
5
|
*/
|
|
6
6
|
import type { Context } from '@deepseek-ai/cordis';
|
|
7
7
|
import { type SessionEvent, type SessionHeader, type SessionId as SessionIdValue } from '@deepseek-ai/dsh-session';
|
|
8
|
+
import type { TurnBoundaryProjection } from '@deepseek-ai/dsh-agent';
|
|
8
9
|
import type { SessionLineageNode, SessionRecord } from '@deepseek-ai/dsh-session-query';
|
|
9
10
|
import type { ToolRunContext } from '@deepseek-ai/dsh-tools';
|
|
10
11
|
interface Caller {
|
|
11
12
|
readonly id: SessionIdValue;
|
|
12
13
|
readonly header: SessionHeader;
|
|
13
14
|
readonly events: readonly SessionEvent[];
|
|
15
|
+
/** The caller's own-session boundary fold (the `turnBoundary` projection). */
|
|
16
|
+
readonly boundary: TurnBoundaryProjection | undefined;
|
|
14
17
|
}
|
|
15
18
|
interface TitleView {
|
|
16
19
|
readonly text: string;
|
|
@@ -28,7 +31,7 @@ interface DescendantVisit {
|
|
|
28
31
|
readonly depth: number;
|
|
29
32
|
readonly next: DescendantVisit | undefined;
|
|
30
33
|
}
|
|
31
|
-
declare function callerOf(exec: ToolRunContext): Caller;
|
|
34
|
+
declare function callerOf(exec: ToolRunContext, ctx: Context): Caller;
|
|
32
35
|
declare function targetId(args: {
|
|
33
36
|
readonly session_id?: string;
|
|
34
37
|
}, caller: Caller): SessionIdValue;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@deepseek-ai/dsh-tool-session-query",
|
|
3
3
|
"description": "Workspace-authorized model-facing session history search, trace, and event read tools",
|
|
4
|
-
"version": "0.1.
|
|
4
|
+
"version": "0.1.2-alpha.2",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
7
7
|
},
|
|
@@ -32,32 +32,37 @@
|
|
|
32
32
|
],
|
|
33
33
|
"license": "MIT",
|
|
34
34
|
"peerDependencies": {
|
|
35
|
-
"@deepseek-ai/dsh-
|
|
36
|
-
"@deepseek-ai/dsh-
|
|
37
|
-
"@deepseek-ai/dsh-
|
|
38
|
-
"@deepseek-ai/
|
|
39
|
-
"@deepseek-ai/dsh-
|
|
40
|
-
"@deepseek-ai/dsh-session": "^0.1.
|
|
41
|
-
"@deepseek-ai/dsh-
|
|
42
|
-
"@deepseek-ai/
|
|
35
|
+
"@deepseek-ai/dsh-agent": "^0.1.2-alpha.2",
|
|
36
|
+
"@deepseek-ai/dsh-invariants": "^0.1.2-alpha.2",
|
|
37
|
+
"@deepseek-ai/dsh-llm": "^0.1.2-alpha.2",
|
|
38
|
+
"@deepseek-ai/cordis": "^4.0.2",
|
|
39
|
+
"@deepseek-ai/dsh-session": "^0.1.2-alpha.2",
|
|
40
|
+
"@deepseek-ai/dsh-session-query": "^0.1.2-alpha.2",
|
|
41
|
+
"@deepseek-ai/dsh-timeout": "^0.1.2-alpha.2",
|
|
42
|
+
"@deepseek-ai/dsh-tools": "^0.1.2-alpha.2",
|
|
43
|
+
"@deepseek-ai/dsh-session-projection": "^0.1.2-alpha.2",
|
|
44
|
+
"@deepseek-ai/dsh-system-prompt": "^0.1.2-alpha.2"
|
|
43
45
|
},
|
|
44
46
|
"dependencies": {
|
|
45
|
-
"@deepseek-ai/schemastery": "^3.18.
|
|
47
|
+
"@deepseek-ai/schemastery": "^3.18.2",
|
|
48
|
+
"@deepseek-ai/dsh-brand": "^0.1.2-alpha.2"
|
|
46
49
|
},
|
|
47
50
|
"devDependencies": {
|
|
48
|
-
"@deepseek-ai/
|
|
49
|
-
"@deepseek-ai/dsh-agent": "^0.1.
|
|
50
|
-
"@deepseek-ai/dsh-
|
|
51
|
-
"@deepseek-ai/dsh-
|
|
52
|
-
"@deepseek-ai/dsh-session-persistence": "^0.1.
|
|
53
|
-
"@deepseek-ai/dsh-session-persistence-jsonl": "^0.1.
|
|
54
|
-
"@deepseek-ai/dsh-session-
|
|
55
|
-
"@deepseek-ai/dsh-session-query
|
|
56
|
-
"@deepseek-ai/dsh-
|
|
57
|
-
"@deepseek-ai/dsh-
|
|
58
|
-
"@deepseek-ai/dsh-
|
|
59
|
-
"@deepseek-ai/dsh-tool-call-timeout-policy": "^0.1.
|
|
60
|
-
"@deepseek-ai/dsh-
|
|
61
|
-
"@deepseek-ai/
|
|
51
|
+
"@deepseek-ai/cordis": "^4.0.2",
|
|
52
|
+
"@deepseek-ai/dsh-agent": "^0.1.2-alpha.2",
|
|
53
|
+
"@deepseek-ai/dsh-agent-loop": "^0.1.2-alpha.2",
|
|
54
|
+
"@deepseek-ai/dsh-invariants": "^0.1.2-alpha.2",
|
|
55
|
+
"@deepseek-ai/dsh-session-persistence": "^0.1.2-alpha.2",
|
|
56
|
+
"@deepseek-ai/dsh-session-persistence-jsonl": "^0.1.2-alpha.2",
|
|
57
|
+
"@deepseek-ai/dsh-session-projection": "^0.1.2-alpha.2",
|
|
58
|
+
"@deepseek-ai/dsh-session-query": "^0.1.2-alpha.2",
|
|
59
|
+
"@deepseek-ai/dsh-session-query-sqlite": "^0.1.2-alpha.2",
|
|
60
|
+
"@deepseek-ai/dsh-system-prompt": "^0.1.2-alpha.2",
|
|
61
|
+
"@deepseek-ai/dsh-session-title": "^0.1.2-alpha.2",
|
|
62
|
+
"@deepseek-ai/dsh-tool-call-timeout-policy": "^0.1.2-alpha.2",
|
|
63
|
+
"@deepseek-ai/dsh-timeout": "^0.1.2-alpha.2",
|
|
64
|
+
"@deepseek-ai/dsh-tools": "^0.1.2-alpha.2",
|
|
65
|
+
"@deepseek-ai/dsh-session": "^0.1.2-alpha.2",
|
|
66
|
+
"@deepseek-ai/dsh-llm": "^0.1.2-alpha.2"
|
|
62
67
|
}
|
|
63
68
|
}
|