@deepseek-ai/dsh-session-reference 0.1.5-rc.2 → 0.1.6-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 +2 -2
- package/README.zh.md +14 -14
- package/lib/index.js +20 -16
- package/lib/typert.host.js +29 -21
- package/lib/typert.remote-client.js +12 -8
- package/lib/types/index.d.ts +7 -8
- package/lib/types/index.js +30 -23
- package/lib/types/types.d.ts +2 -0
- package/package.json +34 -32
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/context/session-reference/README.md
|
|
5
|
-
README.md:
|
|
6
|
-
README.zh.md:
|
|
5
|
+
README.md: e1afeef9b0e78826705ad2b3e426373b2bf0833d
|
|
6
|
+
README.zh.md: e55dab4f6403cb6aee947f80873ffe99919acc5f
|
package/README.md
CHANGED
|
@@ -39,7 +39,7 @@ For a truncated reference, an optional spill backend saves the full captured tex
|
|
|
39
39
|
|
|
40
40
|
### Finding sessions to reference
|
|
41
41
|
|
|
42
|
-
`listCandidates(agent, query?, limit?)` lists sessions other than the agent's own, filters case-insensitively by id, working directory, or
|
|
42
|
+
`listCandidates(agent, query?, limit?)` lists sessions other than the agent's own, filters case-insensitively by id, working directory, projected title, or display title, and ranks same-directory sessions first. Each candidate carries its latest title as `label`, falling back to the session id when the title is absent or unreadable. Its display title prefers a subagent's durable creation label over that title. The candidate also reports whether its working directory is the requesting agent's so a host can surface a location only when it distinguishes the row. Browser consumers call the same discovery as `ctx.remote.sessionReferenceResolver.candidates`, which labels the canonical mention with `displayTitle` when present.
|
|
43
43
|
|
|
44
44
|
### Configuration
|
|
45
45
|
|
|
@@ -68,7 +68,7 @@ This section explains the design of the service; the observable behavior is cove
|
|
|
68
68
|
|
|
69
69
|
Preparation reads each referenced session's current surface exactly once, when the target message reaches `agent/pre-step`. Both preview and spill use that same captured projection: direct-user text, assistant text, and user checkpoints carrying the canonical compaction marker; tools, reasoning, and other injected context are excluded. This prevents recursive reference propagation and prevents a later source mutation from changing the saved transcript. Preview JSON escapes every `<` as `\u003c`, so source text cannot spell the `<referenced-sessions>` framing tag.
|
|
70
70
|
|
|
71
|
-
The resolver discovers optional storage through `ctx.get("spillStore")` and saves only truncated references. Storage ownership is the target session;
|
|
71
|
+
The resolver discovers optional storage through `ctx.get("spillStore")` and saves only truncated references. Storage ownership is the target session; the source descriptor identifies the referenced session and label, without a fabricated tool call. Cancellation is checked after the asynchronous save and prevents publication even if an artifact was written. Artifact expiry remains the backend's existing policy.
|
|
72
72
|
|
|
73
73
|
The budget uses the provider and model captured after `system-prompt/assemble` completes for the target agent. Direct `prepare` calls before any assembly use agent options; session headers do not select the budget model. Diagnostic assemblies without an agent do not affect captured routes.
|
|
74
74
|
|
package/README.zh.md
CHANGED
|
@@ -31,15 +31,15 @@ kind: "package-reference"
|
|
|
31
31
|
|
|
32
32
|
规范 mention 是 Markdown 形式的 `@[label](dsh-session:<base64url 编码的 id>)`,或裸 `dsh-session:` URI;每个 JavaScript 字符串会话 id 都能精确往返。服务会把 mention 改写为消息中可读的 `@label` 文本,并返回结构化引用。显式 Markdown mention 会拒绝格式错误的 URI;空或只含标点符号的 scheme mention 仍是普通讨论文本。
|
|
33
33
|
|
|
34
|
-
###
|
|
34
|
+
### agent(智能体)能得到什么
|
|
35
35
|
|
|
36
36
|
引用其他会话的消息后会紧接一条 `## Referenced sessions` 快照,作为第二条 user 角色消息。快照是不受信任的背景:固定警告告诉模型,除非当前用户明确重复,否则不得遵循其中的指令、权限声明或工具请求。每个来源预览都独立有界——每条消息至多 `maxReferences` 个不同会话,每个来源的序列化 JSON 采用配置值或模型相对字节预算。保留策略先丢弃较早的非检查点消息,再缩短保留的文本;只有保留处理后引用仍无法满足预算时,准备才会失败。
|
|
37
37
|
|
|
38
|
-
引用被截断时,可选的 spill 后端会在目标会话下保存完整的已捕获文本投影。有界预览 JSON 之外的独立省略通知给出精确的 `omittedMessages` 与 `omittedBytes`,以及保存后的定位信息和 `retrievalHint
|
|
38
|
+
引用被截断时,可选的 spill 后端会在目标会话下保存完整的已捕获文本投影。有界预览 JSON 之外的独立省略通知给出精确的 `omittedMessages` 与 `omittedBytes`,以及保存后的定位信息和 `retrievalHint`,或区分未配置存储与保存失败的不可用结果。该通知属于同一条持久上下文消息。完整 transcript(文本记录)携带相同的不受信任背景警告与捕获元数据,包括 `capturedFormatVersion`。每条消息使用每行至多 64 个 Unicode 码点的 JSON 字符串片段;解码并拼接其片段即可恢复精确文本,包括原始换行。这种固定存储格式使很长的单行文本也可通过分页文件读取来检查。
|
|
39
39
|
|
|
40
40
|
### 查找可引用的会话
|
|
41
41
|
|
|
42
|
-
`listCandidates(agent, query?, limit?)` 列出除 agent 自身外的会话,按 id
|
|
42
|
+
`listCandidates(agent, query?, limit?)` 列出除 agent 自身外的会话,按 id、工作目录、投影标题或显示标题做不区分大小写的过滤,并把同目录会话排在前面。每个候选的 `label` 使用最新标题;标题缺失或不可读时回退到会话 id。显示标题优先使用 subagent 的持久创建 label,再回退到该标题。候选还会报告其工作目录是否就是发起方 agent 的工作目录,宿主因此可以只在位置能区分该行时才显示它。浏览器消费方通过 `ctx.remote.sessionReferenceResolver.candidates` 调用同一发现能力;该方法在 `displayTitle` 存在时用它标记规范 mention。
|
|
43
43
|
|
|
44
44
|
### 配置
|
|
45
45
|
|
|
@@ -50,7 +50,7 @@ kind: "package-reference"
|
|
|
50
50
|
| `maxReferenceBytes` | 自动 | 每个来源的最大序列化 JSON 字节数;显式设置时精确覆盖自动预算 |
|
|
51
51
|
| `referenceContextFraction` | `0.2` | 每个来源的上下文窗口比例,范围为 `0` 到 `1` |
|
|
52
52
|
|
|
53
|
-
自动预算为每个来源 `max(65536, floor(contextWindow × 4 × referenceContextFraction))` 字节。模型上下文容量以 token 计量;每个 token 四字节是容量估算,不是精确的 token 换算。缺少路由、LLM
|
|
53
|
+
自动预算为每个来源 `max(65536, floor(contextWindow × 4 × referenceContextFraction))` 字节。模型上下文容量以 token 计量;每个 token 四字节是容量估算,不是精确的 token 换算。缺少路由、LLM(大语言模型)服务、适配器或容量时使用 64 KiB;其他模型元数据查询错误与取消会使准备失败。
|
|
54
54
|
|
|
55
55
|
生成的[配置目录](../../../docs/config-catalog.zh.md#deepseek-aidsh-session-reference)是每个受支持字段及其 JSDoc 的穷尽式真源。
|
|
56
56
|
|
|
@@ -66,24 +66,24 @@ kind: "package-reference"
|
|
|
66
66
|
|
|
67
67
|
### 设计理念
|
|
68
68
|
|
|
69
|
-
准备阶段在目标消息到达 `agent/pre-step` 时,对每个被引用会话的当前表层各精确读取一次。预览与 spill 使用同一份已捕获投影:用户直接发送的文本、assistant
|
|
69
|
+
准备阶段在目标消息到达 `agent/pre-step` 时,对每个被引用会话的当前表层各精确读取一次。预览与 spill 使用同一份已捕获投影:用户直接发送的文本、assistant 文本,以及携带规范压缩(compaction)标记的 user 检查点;工具、推理(reasoning)与其他注入上下文均被排除。这既防止引用递归传播,也防止源会话后续变更影响已保存 transcript。预览 JSON 将每个 `<` 转义为 `\u003c`,因此源文本无法拼出 `<referenced-sessions>` 定界标签。
|
|
70
70
|
|
|
71
71
|
解析器通过 `ctx.get("spillStore")` 获取可选存储,只保存被截断的引用。存储归目标会话所有;来源信息标识被引用的源会话与标签,不伪造工具调用。异步保存后会检查取消,即使产物已写入,也会阻止发布。产物过期仍遵循后端既有策略。
|
|
72
72
|
|
|
73
|
-
预算使用目标 agent 的 `system-prompt/assemble`
|
|
73
|
+
预算使用目标 agent 的 `system-prompt/assemble` 完成后捕获的提供方与模型。首次组装前直接调用 `prepare` 时使用 agent 选项;会话头不决定预算模型。不带 agent 的诊断组装不会影响已捕获路由。
|
|
74
74
|
|
|
75
75
|
### 源码地图
|
|
76
76
|
|
|
77
77
|
| 文件 | 职责 |
|
|
78
78
|
|---|---|
|
|
79
79
|
| [`src/index.ts`](src/index.ts) | `SessionReferenceResolver`:pre-step 监听器、候选发现、准备 |
|
|
80
|
-
| [`src/config.ts`](src/config.ts) | `Config` schema、`SessionReferenceError`
|
|
80
|
+
| [`src/config.ts`](src/config.ts) | `Config` schema、`SessionReferenceError` 错误分类体系 |
|
|
81
81
|
| [`src/uri.ts`](src/uri.ts) | `dsh-session:` URI 编解码、mention 格式化与解析 |
|
|
82
82
|
| [`src/projection.ts`](src/projection.ts) | 当前表层投影与字节预算保留 |
|
|
83
83
|
| [`src/serialization.ts`](src/serialization.ts) | 快照载荷的标签安全 JSON 转义 |
|
|
84
|
-
| [`src/spill.ts`](src/spill.ts) |
|
|
84
|
+
| [`src/spill.ts`](src/spill.ts) | 完整 transcript 序列化与模型可见省略通知 |
|
|
85
85
|
| [`src/types.ts`](src/types.ts) | `SessionReferenceInput`/`Candidate` 与来源类型 |
|
|
86
|
-
| — |
|
|
86
|
+
| — | 不发布运行时不变式伴生入口;准备过程返回构建时已校验的不可变单次快照;持久上下文的准入、冻结与回放由 agent 层和会话层负责。 |
|
|
87
87
|
|
|
88
88
|
### 主要流程
|
|
89
89
|
|
|
@@ -98,10 +98,10 @@ kind: "package-reference"
|
|
|
98
98
|
|
|
99
99
|
包级约定不够用时阅读以下页面。它们从共享引用表面进入设计决策与其背后的读取服务。
|
|
100
100
|
|
|
101
|
-
- [会话引用子系统](../../../docs/subsystems/session-reference.zh.md)——规范 URI
|
|
101
|
+
- [会话引用子系统](../../../docs/subsystems/session-reference.zh.md)——规范 URI、投影规则与稳定的错误分类体系。
|
|
102
102
|
- [会话引用 spill 复用](../../../.agents/notes/implemented/bug-fix/2026-09-05-session-reference-spill-reuse.zh.md)——快照身份、省略通知、存储归属与替代方案。
|
|
103
103
|
- [会话查询子系统](../../../docs/subsystems/session-query.zh.md)——提供会话表层的读取服务。
|
|
104
|
-
- [
|
|
104
|
+
- [上下文组地图](../README.zh.md)——相邻的请求上下文包。
|
|
105
105
|
- [生成的配置目录](../../../docs/config-catalog.zh.md#deepseek-aidsh-session-reference)——每个受支持配置字段及其源声明。
|
|
106
106
|
|
|
107
107
|
-----
|
|
@@ -117,7 +117,7 @@ kind: "package-reference"
|
|
|
117
117
|
|
|
118
118
|
#### Token 影响
|
|
119
119
|
|
|
120
|
-
|
|
120
|
+
每条包含引用的消息都会添加固定警告和最多三个序列化预览,每个预览都受配置值或模型相对字节预算独立限制。被截断的引用会在该预算之外添加独立省略通知;已保存的完整 transcript 只有在被取回时才增加 token。精确上下文会保留在目标历史中,直到目标压缩遮蔽或摘要它;源会话变更不会添加更多 token。
|
|
121
121
|
|
|
122
122
|
#### KV Cache 影响
|
|
123
123
|
|
|
@@ -131,11 +131,11 @@ kind: "package-reference"
|
|
|
131
131
|
这些限制说明跨会话引用何时不合适。它们是当前包约束。
|
|
132
132
|
|
|
133
133
|
- **不支持消息正文检索**:候选查询会检查标题,但不搜索消息主体。
|
|
134
|
-
-
|
|
134
|
+
- **标签只来自投影**:已挂载会话的标签来自实时投影切面,冷会话的标签来自持久检查点;若会话无法提供这两者,则以其 id 作为标签,也无法按标题找到。发现过程绝不读取日志:折叠出一个标题需要处理整份日志,而这段代码会在每次补全击键时运行。在投影缓存建立前持久化的会话,会在首次打开时恢复标题并写入检查点。
|
|
135
135
|
- **受信任调用方边界**:该服务假设宿主有权读取 `ctx.sessionQuery` 公开的每个会话;它不是面向模型的搜索工具。
|
|
136
136
|
- **只投影文本**:不会在会话间传播非文本 user 与 assistant 块。
|
|
137
137
|
- **没有实时链接**:引用是快照,不是 fork、恢复、订阅或源会话变更。
|
|
138
|
-
-
|
|
138
|
+
- **transcript 搜索按行进行**:字面短语可能跨越 JSON 片段行或包含转义字符;精确文本匹配需先解码并拼接消息片段。已保存产物可能按后端策略过期。
|
|
139
139
|
|
|
140
140
|
<a id="dev-note"></a>
|
|
141
141
|
### 开发备注
|
package/lib/index.js
CHANGED
|
@@ -508,14 +508,13 @@ let SessionReferenceResolver = (() => {
|
|
|
508
508
|
/**
|
|
509
509
|
* List reference candidates, ranked by working-directory affinity.
|
|
510
510
|
*
|
|
511
|
-
* Discovery runs at keystroke rate, so
|
|
512
|
-
* projection
|
|
513
|
-
* which sessions can answer one and which fall back to their id.
|
|
511
|
+
* Discovery runs at keystroke rate, so titles and subagent labels only ever
|
|
512
|
+
* come from projection reads; sessions without either fall back to their id.
|
|
514
513
|
* @param agent - target agent; self is excluded and its cwd drives ranking.
|
|
515
|
-
* @param query - optional case-insensitive session-id/cwd/title substring.
|
|
514
|
+
* @param query - optional case-insensitive session-id/cwd/title/display-title substring.
|
|
516
515
|
* @param limit - optional positive result cap.
|
|
517
516
|
* @param signal - optional cancellation boundary for host autocomplete teardown.
|
|
518
|
-
* @returns candidates
|
|
517
|
+
* @returns candidates with canonical mention labels and presentation titles.
|
|
519
518
|
*/
|
|
520
519
|
async listCandidates(agent, query = "", limit = this.config.candidateLimit, signal) {
|
|
521
520
|
if (!Number.isSafeInteger(limit) || limit <= 0) throw new SessionReferenceError("candidate limit must be a positive safe integer", "SESSION_REFERENCE_INVALID_REFERENCE");
|
|
@@ -528,20 +527,21 @@ let SessionReferenceResolver = (() => {
|
|
|
528
527
|
})).map(({ record, index }) => ({
|
|
529
528
|
record,
|
|
530
529
|
index,
|
|
531
|
-
|
|
532
|
-
})).filter(({ record, label }) => {
|
|
530
|
+
...this.projectedLabels(record)
|
|
531
|
+
})).filter(({ record, label, displayTitle }) => {
|
|
533
532
|
if (needle === "") return true;
|
|
534
|
-
return record.header.id.toLocaleLowerCase().includes(needle) || record.header.cwd?.toLocaleLowerCase().includes(needle) === true || label.toLocaleLowerCase().includes(needle);
|
|
535
|
-
}).sort((a, b) => candidateRank(a.record.header.cwd, targetCwd) - candidateRank(b.record.header.cwd, targetCwd) || a.index - b.index).slice(0, limit).map(({ record, label }) => ({
|
|
533
|
+
return record.header.id.toLocaleLowerCase().includes(needle) || record.header.cwd?.toLocaleLowerCase().includes(needle) === true || label.toLocaleLowerCase().includes(needle) || displayTitle.toLocaleLowerCase().includes(needle);
|
|
534
|
+
}).sort((a, b) => candidateRank(a.record.header.cwd, targetCwd) - candidateRank(b.record.header.cwd, targetCwd) || a.index - b.index).slice(0, limit).map(({ record, label, displayTitle }) => ({
|
|
536
535
|
sessionId: record.header.id,
|
|
537
536
|
label,
|
|
537
|
+
displayTitle,
|
|
538
538
|
...record.header.cwd === void 0 ? {} : { cwd: record.header.cwd },
|
|
539
539
|
sameWorkspace: record.header.cwd !== void 0 && record.header.cwd === targetCwd,
|
|
540
540
|
createdAt: record.header.createdAt
|
|
541
541
|
}));
|
|
542
542
|
}
|
|
543
543
|
/**
|
|
544
|
-
* The title a
|
|
544
|
+
* The mention label and display title a Session's projections can answer without reading its log.
|
|
545
545
|
*
|
|
546
546
|
* Attachment is decided by the store at read time, not by the listing:
|
|
547
547
|
* a session that attached in between would otherwise be answered from a
|
|
@@ -560,14 +560,18 @@ let SessionReferenceResolver = (() => {
|
|
|
560
560
|
* and cannot be found by its title until it is opened once, which
|
|
561
561
|
* checkpoints it.
|
|
562
562
|
* @param record - the listed session, live or cold.
|
|
563
|
-
* @returns the
|
|
563
|
+
* @returns the title-backed mention label and the subagent-label-first display title.
|
|
564
564
|
*/
|
|
565
|
-
|
|
565
|
+
projectedLabels(record) {
|
|
566
566
|
const attached = this.ctx.get("sessions")?.get(record.header.id);
|
|
567
567
|
const projections = this.ctx.get("sessionProjections");
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
568
|
+
const snapshot = attached !== void 0 && projections !== void 0 ? projections.snapshot(attached, ["title", "subagent"]) : record.header.isSeeded ? void 0 : this.ctx.get("sessionProjectionCache")?.cachedSnapshot(record.header, SessionLogOffset(0), ["title", "subagent"]);
|
|
569
|
+
const label = titleOf(snapshot) ?? record.header.id;
|
|
570
|
+
const subagent = snapshot?.values.subagent;
|
|
571
|
+
return {
|
|
572
|
+
label,
|
|
573
|
+
displayTitle: subagent === void 0 || subagent === null ? label : subagent.label ?? label
|
|
574
|
+
};
|
|
571
575
|
}
|
|
572
576
|
/**
|
|
573
577
|
* Remote face of {@link listCandidates}: the configured candidate limit
|
|
@@ -583,7 +587,7 @@ let SessionReferenceResolver = (() => {
|
|
|
583
587
|
...candidate,
|
|
584
588
|
mention: formatSessionReferenceMention({
|
|
585
589
|
sessionId: candidate.sessionId,
|
|
586
|
-
label: candidate.label
|
|
590
|
+
label: candidate.displayTitle ?? candidate.label
|
|
587
591
|
})
|
|
588
592
|
}));
|
|
589
593
|
}
|
package/lib/typert.host.js
CHANGED
|
@@ -1,16 +1,20 @@
|
|
|
1
1
|
/* Generated by @deepseek-ai/dsh-typert-generator from FaceModel — do not edit. */
|
|
2
2
|
import { z } from 'zod'
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
const
|
|
6
|
-
|
|
4
|
+
let _deepseek_ai_dsh_session_reference_sessionReferenceResolver_candidates_parameter_0$schema$value
|
|
5
|
+
const _deepseek_ai_dsh_session_reference_sessionReferenceResolver_candidates_parameter_0$schema = () => (_deepseek_ai_dsh_session_reference_sessionReferenceResolver_candidates_parameter_0$schema$value ??= z.intersection(z.string(), z.unknown()))
|
|
6
|
+
let _deepseek_ai_dsh_session_reference_sessionReferenceResolver_candidates_parameter_1$schema$value
|
|
7
|
+
const _deepseek_ai_dsh_session_reference_sessionReferenceResolver_candidates_parameter_1$schema = () => (_deepseek_ai_dsh_session_reference_sessionReferenceResolver_candidates_parameter_1$schema$value ??= z.string())
|
|
8
|
+
let _deepseek_ai_dsh_session_reference_sessionReferenceResolver_candidates_result$schema$value
|
|
9
|
+
const _deepseek_ai_dsh_session_reference_sessionReferenceResolver_candidates_result$schema = () => (_deepseek_ai_dsh_session_reference_sessionReferenceResolver_candidates_result$schema$value ??= z.array(z.object({
|
|
7
10
|
'mention': z.string(),
|
|
8
11
|
'sessionId': z.intersection(z.string(), z.unknown()),
|
|
9
12
|
'label': z.string(),
|
|
13
|
+
'displayTitle': z.string().optional(),
|
|
10
14
|
'cwd': z.string().optional(),
|
|
11
15
|
'sameWorkspace': z.boolean(),
|
|
12
16
|
'createdAt': z.number(),
|
|
13
|
-
}))
|
|
17
|
+
})))
|
|
14
18
|
|
|
15
19
|
export const TYPERT = {
|
|
16
20
|
package: '@deepseek-ai/dsh-session-reference',
|
|
@@ -38,7 +42,7 @@ export const TYPERT = {
|
|
|
38
42
|
codec: {
|
|
39
43
|
mode: 'strict',
|
|
40
44
|
typeSymbol: '@deepseek-ai/dsh-session/types#SessionId',
|
|
41
|
-
|
|
45
|
+
create: _deepseek_ai_dsh_session_reference_sessionReferenceResolver_candidates_parameter_0$schema,
|
|
42
46
|
},
|
|
43
47
|
},
|
|
44
48
|
{
|
|
@@ -48,7 +52,7 @@ export const TYPERT = {
|
|
|
48
52
|
codec: {
|
|
49
53
|
mode: 'strict',
|
|
50
54
|
typeSymbol: '@deepseek-ai/dsh-session-reference#sessionReferenceResolver/candidates:query',
|
|
51
|
-
|
|
55
|
+
create: _deepseek_ai_dsh_session_reference_sessionReferenceResolver_candidates_parameter_1$schema,
|
|
52
56
|
},
|
|
53
57
|
},
|
|
54
58
|
],
|
|
@@ -56,9 +60,9 @@ export const TYPERT = {
|
|
|
56
60
|
result: {
|
|
57
61
|
mode: 'strict',
|
|
58
62
|
typeSymbol: '@deepseek-ai/dsh-session-reference#sessionReferenceResolver/candidates:result',
|
|
59
|
-
|
|
63
|
+
create: _deepseek_ai_dsh_session_reference_sessionReferenceResolver_candidates_result$schema,
|
|
60
64
|
},
|
|
61
|
-
sourceLocation: {"file":"packages/context/session-reference/src/index.ts","line":
|
|
65
|
+
sourceLocation: {"file":"packages/context/session-reference/src/index.ts","line":280,"column":9},
|
|
62
66
|
},
|
|
63
67
|
],
|
|
64
68
|
model: {
|
|
@@ -76,7 +80,7 @@ export const TYPERT = {
|
|
|
76
80
|
"name": "listCandidates",
|
|
77
81
|
"signature": "async listCandidates( agent: Agent, query: string = '', limit: number = this.config.candidateLimit, signal?: AbortSignal, ): Promise<SessionReferenceCandidate[]>",
|
|
78
82
|
"summary": "List reference candidates, ranked by working-directory affinity.",
|
|
79
|
-
"jsDoc": "/**\n * List reference candidates, ranked by working-directory affinity.\n *\n * Discovery runs at keystroke rate, so
|
|
83
|
+
"jsDoc": "/**\n * List reference candidates, ranked by working-directory affinity.\n *\n * Discovery runs at keystroke rate, so titles and subagent labels only ever\n * come from projection reads; sessions without either fall back to their id.\n * @param agent - target agent; self is excluded and its cwd drives ranking.\n * @param query - optional case-insensitive session-id/cwd/title/display-title substring.\n * @param limit - optional positive result cap.\n * @param signal - optional cancellation boundary for host autocomplete teardown.\n * @returns candidates with canonical mention labels and presentation titles.\n */"
|
|
80
84
|
},
|
|
81
85
|
{
|
|
82
86
|
"kind": "method",
|
|
@@ -131,8 +135,8 @@ export const TYPERT = {
|
|
|
131
135
|
"declaration": "export interface AssistantMessage extends Message {\n readonly role: 'assistant';\n readonly source: ModelMessageSource;\n}"
|
|
132
136
|
},
|
|
133
137
|
{
|
|
134
|
-
"name": "
|
|
135
|
-
"declaration": "export interface
|
|
138
|
+
"name": "AssistantProviderMetadata",
|
|
139
|
+
"declaration": "export interface AssistantProviderMetadata {\n provider: string;\n model: string;\n replayState?: unknown;\n}"
|
|
136
140
|
},
|
|
137
141
|
{
|
|
138
142
|
"name": "AssistantStreamRecord",
|
|
@@ -268,12 +272,16 @@ export const TYPERT = {
|
|
|
268
272
|
},
|
|
269
273
|
{
|
|
270
274
|
"name": "ImageBlock",
|
|
271
|
-
"declaration": "export interface ImageBlock {\n type: 'image';\n attachment: ImageAttachmentRef;\n}"
|
|
275
|
+
"declaration": "export interface ImageBlock {\n type: 'image';\n attachment: ImageAttachmentRef;\n offloaded?: true;\n}"
|
|
272
276
|
},
|
|
273
277
|
{
|
|
274
278
|
"name": "ImageMediaType",
|
|
275
279
|
"declaration": "export type ImageMediaType = 'image/png' | 'image/jpeg' | 'image/webp' | 'image/gif';"
|
|
276
280
|
},
|
|
281
|
+
{
|
|
282
|
+
"name": "ImageOffloadTarget",
|
|
283
|
+
"declaration": "export interface ImageOffloadTarget {\n seq: SessionSeq;\n imageIndexes: number[];\n}"
|
|
284
|
+
},
|
|
277
285
|
{
|
|
278
286
|
"name": "Inbox",
|
|
279
287
|
"declaration": "export interface Inbox {\n readonly nextTurn: readonly UserMessage[];\n readonly nextStep: readonly UserMessage[];\n clear(): void;\n append(target: InboxTarget, message: UserMessage): void;\n prepend(target: InboxTarget, message: UserMessage): void;\n replace(messageId: MessageId, newMessage: UserMessage): boolean;\n remove(messageId: MessageId): boolean;\n splice(target: InboxTarget, start: number, deleteCount: number, inserted: UserMessage[]): UserMessage[];\n}"
|
|
@@ -296,7 +304,7 @@ export const TYPERT = {
|
|
|
296
304
|
},
|
|
297
305
|
{
|
|
298
306
|
"name": "LlmFailure",
|
|
299
|
-
"declaration": "export interface LlmFailure {\n readonly message: string;\n readonly code: string;\n readonly status?: number;\n readonly providerRetryAfterMs?: number;\n readonly requestId?: ProviderRequestId;\n}"
|
|
307
|
+
"declaration": "export interface LlmFailure {\n readonly message: string;\n readonly code: string;\n readonly status?: number;\n readonly providerRetryAfterMs?: number;\n readonly requestId?: ProviderRequestId;\n readonly offloadImages?: number;\n}"
|
|
300
308
|
},
|
|
301
309
|
{
|
|
302
310
|
"name": "Message",
|
|
@@ -336,7 +344,7 @@ export const TYPERT = {
|
|
|
336
344
|
},
|
|
337
345
|
{
|
|
338
346
|
"name": "ModelMessageSource",
|
|
339
|
-
"declaration": "export interface ModelMessageSource extends
|
|
347
|
+
"declaration": "export interface ModelMessageSource extends AssistantProviderMetadata {\n kind: 'model';\n}"
|
|
340
348
|
},
|
|
341
349
|
{
|
|
342
350
|
"name": "ModelSelection",
|
|
@@ -360,7 +368,7 @@ export const TYPERT = {
|
|
|
360
368
|
},
|
|
361
369
|
{
|
|
362
370
|
"name": "PtcDispatchEventData",
|
|
363
|
-
"declaration": "export interface PtcDispatchEventData extends PtcDispatchStartEventData {\n isError: boolean;\n content: ContentBlock[];\n}"
|
|
371
|
+
"declaration": "export interface PtcDispatchEventData extends PtcDispatchStartEventData {\n isError: boolean;\n content: ContentBlock[];\n error?: { name: string; code: string; reason?: string; };\n}"
|
|
364
372
|
},
|
|
365
373
|
{
|
|
366
374
|
"name": "PtcDispatchStartEventData",
|
|
@@ -400,7 +408,7 @@ export const TYPERT = {
|
|
|
400
408
|
},
|
|
401
409
|
{
|
|
402
410
|
"name": "SessionEventMap",
|
|
403
|
-
"declaration": "export interface SessionEventMap {\n 'turn/start': { turn: number; };\n 'turn/end': { turn: number; reason: TurnEndReason; };\n 'step/start': { turn: number; step: number; };\n 'step/end': { turn: number; step: number; };\n 'user/message': UserMessage;\n 'system/message': { turn: number; step: number; message: SystemMessage; };\n 'assistant/message': { turn: number; step: number; message: AssistantMessage; stream: AssistantStreamRecord[]; usage?: TokenUsage; interrupted?: true; };\n 'assistant/attempt': { turn: number; step: number; stream: AssistantStreamRecord[]; };\n 'tool/call': { turn: number; step: number; callId: ToolCallId; name: string; arguments: string; };\n 'tool/result': { turn: number; step: number; message: ToolResultMessage; error?: { name: string; code: string; }; meta?: JsonValue; };\n 'request/header': { header: EpochHeader; reason: RequestHeaderReason; startsSeries?: true; };\n 'request/context': RequestContext;\n 'session/end-seed': { inherited?: true; };\n 'agent/inbox/spliced': { target: InboxTarget; start: number; removedCount?: number; inserted: UserMessage[]; outcome?: 'canceled'; };\n 'approval/asked': { id: ApprovalRequestId; toolName: string; callId?: ToolCallId; reason?: string; };\n 'approval/decided': { id: ApprovalRequestId; outcome: ApprovalOutcome; };\n 'approval/policy': { policy: ApprovalPolicy; source?: 'delegation'; };\n 'tool/ptc-dispatch-start': PtcDispatchStartEventData;\n 'tool/ptc-dispatch': PtcDispatchEventData;\n 'agent-preset/selected': { agentPreset: string; };\n 'command/run': { commandId: CommandId; name: string; args?: string; source: CommandSource; };\n 'command/done': { commandId: CommandId; kind: 'success' | 'error'; text?: string; sourceEventSeq?: import('@deepseek-ai/dsh-session/types').SessionSeq; };\n 'session/title': SessionTitleEventData;\n 'todo/write': { todos: TodoItem[]; };\n 'model/selection': ModelSelection;\n 'subagent/descriptor': SubagentDescriptorData;\n '
|
|
411
|
+
"declaration": "export interface SessionEventMap {\n 'turn/start': { turn: number; };\n 'turn/end': { turn: number; reason: TurnEndReason; };\n 'step/start': { turn: number; step: number; };\n 'step/end': { turn: number; step: number; };\n 'user/message': UserMessage;\n 'system/message': { turn: number; step: number; message: SystemMessage; };\n 'assistant/message': { turn: number; step: number; message: AssistantMessage; stream: AssistantStreamRecord[]; usage?: TokenUsage; interrupted?: true; };\n 'assistant/attempt': { turn: number; step: number; stream: AssistantStreamRecord[]; };\n 'tool/call': { turn: number; step: number; callId: ToolCallId; name: string; arguments: string; };\n 'tool/result': { turn: number; step: number; message: ToolResultMessage; error?: { name: string; code: string; reason?: string; }; meta?: JsonValue; };\n 'request/header': { header: EpochHeader; reason: RequestHeaderReason; startsSeries?: true; };\n 'request/context': RequestContext;\n 'session/end-seed': { inherited?: true; };\n 'agent/inbox/spliced': { target: InboxTarget; start: number; removedCount?: number; inserted: UserMessage[]; outcome?: 'canceled'; };\n 'sandbox/mode': { mode: SandboxMode; source?: 'delegation'; };\n 'approval/asked': { id: ApprovalRequestId; toolName: string; callId?: ToolCallId; reason?: string; };\n 'approval/decided': { id: ApprovalRequestId; outcome: ApprovalOutcome; };\n 'approval/policy': { policy: ApprovalPolicy; source?: 'delegation'; };\n 'tool/ptc-dispatch-start': PtcDispatchStartEventData;\n 'tool/ptc-dispatch': PtcDispatchEventData;\n 'agent-preset/selected': { agentPreset: string; };\n 'command/run': { commandId: CommandId; name: string; args?: string; source: CommandSource; };\n 'command/done': { commandId: CommandId; kind: 'success' | 'error'; text?: string; sourceEventSeq?: import('@deepseek-ai/dsh-session/types').SessionSeq; };\n 'image/offload': { targets: ImageOffloadTarget[]; };\n 'session/title': SessionTitleEventData;\n 'todo/write': { todos: TodoItem[]; };\n 'model/selection': ModelSelection;\n 'subagent/descriptor': SubagentDescriptorData;\n 'permission/preset': { preset: string; };\n 'subagent/catalog': SubagentCatalogEvent;\n 'feedback/record': FeedbackRecord;\n 'team/member': { version: 2; teamId: TeamId; member: TeamMemberSnapshot; };\n 'team/task': { version: 2; teamId: TeamId; task: TeamTaskSnapshot; };\n 'team/message/queued': { version: 2; teamId: TeamId; message: TeamMessageSnapshot; };\n 'team/message/delivered': { version: 2; teamId: TeamId; messageId: TeamMessageId; targetId: SessionId; };\n 'goal/change': GoalChangeMeta;\n 'feedback/message-put': MessageFeedbackPut;\n 'feedback/message-delete': MessageFeedbackDelete;\n 'compaction/start': { compactionId: CompactionId; sourceCommandId?: CommandId; turn: number | null; };\n 'compaction/summary': { compactionId: CompactionId; sourceCommandId?: CommandId; summary: ContentBlock[]; shadowedRange: { start: SessionSeq; end: SessionSeq; }; shadowedSeqs: SessionSeq[]; shadowedTokenCount: number; provider: string; model: string; maxTokens?: number; usage?: TokenUsage; } & ({ rawOutput: ContentBlock[]; llmStreamCall: true; } | { rawOutput?: ContentBlock[]; llmStreamCall?: never; });\n 'compaction/end': { compactionId: CompactionId; sourceCommandId?: CommandId; turn: number | null; error?: string; };\n 'compaction/prune': { shadowedRange: { start: SessionSeq; end: SessionSeq; }; shadowedSeqs: SessionSeq[]; shadowedTokenCount: number; };\n}"
|
|
404
412
|
},
|
|
405
413
|
{
|
|
406
414
|
"name": "SessionEventType",
|
|
@@ -420,7 +428,7 @@ export const TYPERT = {
|
|
|
420
428
|
},
|
|
421
429
|
{
|
|
422
430
|
"name": "SessionReferenceCandidate",
|
|
423
|
-
"declaration": "export interface SessionReferenceCandidate {\n sessionId: SessionId;\n label: string;\n cwd?: string;\n sameWorkspace: boolean;\n createdAt: number;\n}"
|
|
431
|
+
"declaration": "export interface SessionReferenceCandidate {\n sessionId: SessionId;\n label: string;\n displayTitle?: string;\n cwd?: string;\n sameWorkspace: boolean;\n createdAt: number;\n}"
|
|
424
432
|
},
|
|
425
433
|
{
|
|
426
434
|
"name": "SessionReferenceInput",
|
|
@@ -444,15 +452,15 @@ export const TYPERT = {
|
|
|
444
452
|
},
|
|
445
453
|
{
|
|
446
454
|
"name": "SessionSurface",
|
|
447
|
-
"declaration": "export interface SessionSurface {\n readonly nodes: readonly SessionSeq[];\n readonly replaceGeneration: number;\n}"
|
|
455
|
+
"declaration": "export interface SessionSurface {\n readonly nodes: readonly SessionSeq[];\n readonly replaceGeneration: number;\n readonly contentGeneration: number;\n}"
|
|
448
456
|
},
|
|
449
457
|
{
|
|
450
458
|
"name": "SessionTitleEventData",
|
|
451
459
|
"declaration": "export interface SessionTitleEventData {\n readonly title: string;\n readonly messageSeqs: SessionSeq[];\n readonly source: SessionTitleSource;\n}"
|
|
452
460
|
},
|
|
453
461
|
{
|
|
454
|
-
"name": "
|
|
455
|
-
"declaration": "export interface
|
|
462
|
+
"name": "SessionTitleModelIdentity",
|
|
463
|
+
"declaration": "export interface SessionTitleModelIdentity {\n readonly provider: string;\n readonly model: string;\n}"
|
|
456
464
|
},
|
|
457
465
|
{
|
|
458
466
|
"name": "SessionTitleProviderId",
|
|
@@ -460,7 +468,7 @@ export const TYPERT = {
|
|
|
460
468
|
},
|
|
461
469
|
{
|
|
462
470
|
"name": "SessionTitleSource",
|
|
463
|
-
"declaration": "export type SessionTitleSource = { readonly kind: 'fallback'; } | { readonly kind: 'provider'; readonly provider: SessionTitleProviderId; readonly model?:
|
|
471
|
+
"declaration": "export type SessionTitleSource = { readonly kind: 'fallback'; } | { readonly kind: 'provider'; readonly provider: SessionTitleProviderId; readonly model?: SessionTitleModelIdentity; } | { readonly kind: 'user'; };"
|
|
464
472
|
},
|
|
465
473
|
{
|
|
466
474
|
"name": "SkillInvocationSource",
|
|
@@ -1,16 +1,20 @@
|
|
|
1
1
|
/* Generated by @deepseek-ai/dsh-typert-generator from the Host FaceModel — do not edit. */
|
|
2
2
|
import { z } from 'zod'
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
const
|
|
6
|
-
|
|
4
|
+
let _deepseek_ai_dsh_session_reference_sessionReferenceResolver_candidates_parameter_0$schema$value
|
|
5
|
+
const _deepseek_ai_dsh_session_reference_sessionReferenceResolver_candidates_parameter_0$schema = () => (_deepseek_ai_dsh_session_reference_sessionReferenceResolver_candidates_parameter_0$schema$value ??= z.intersection(z.string(), z.unknown()))
|
|
6
|
+
let _deepseek_ai_dsh_session_reference_sessionReferenceResolver_candidates_parameter_1$schema$value
|
|
7
|
+
const _deepseek_ai_dsh_session_reference_sessionReferenceResolver_candidates_parameter_1$schema = () => (_deepseek_ai_dsh_session_reference_sessionReferenceResolver_candidates_parameter_1$schema$value ??= z.string())
|
|
8
|
+
let _deepseek_ai_dsh_session_reference_sessionReferenceResolver_candidates_result$schema$value
|
|
9
|
+
const _deepseek_ai_dsh_session_reference_sessionReferenceResolver_candidates_result$schema = () => (_deepseek_ai_dsh_session_reference_sessionReferenceResolver_candidates_result$schema$value ??= z.array(z.object({
|
|
7
10
|
'mention': z.string(),
|
|
8
11
|
'sessionId': z.intersection(z.string(), z.unknown()),
|
|
9
12
|
'label': z.string(),
|
|
13
|
+
'displayTitle': z.string().optional(),
|
|
10
14
|
'cwd': z.string().optional(),
|
|
11
15
|
'sameWorkspace': z.boolean(),
|
|
12
16
|
'createdAt': z.number(),
|
|
13
|
-
}))
|
|
17
|
+
})))
|
|
14
18
|
|
|
15
19
|
export const TYPERT_REMOTE = {
|
|
16
20
|
package: '@deepseek-ai/dsh-session-reference',
|
|
@@ -35,7 +39,7 @@ export const TYPERT_REMOTE = {
|
|
|
35
39
|
codec: {
|
|
36
40
|
mode: 'strict',
|
|
37
41
|
typeSymbol: '@deepseek-ai/dsh-session/types#SessionId',
|
|
38
|
-
|
|
42
|
+
create: _deepseek_ai_dsh_session_reference_sessionReferenceResolver_candidates_parameter_0$schema,
|
|
39
43
|
},
|
|
40
44
|
},
|
|
41
45
|
{
|
|
@@ -45,7 +49,7 @@ export const TYPERT_REMOTE = {
|
|
|
45
49
|
codec: {
|
|
46
50
|
mode: 'strict',
|
|
47
51
|
typeSymbol: '@deepseek-ai/dsh-session-reference#sessionReferenceResolver/candidates:query',
|
|
48
|
-
|
|
52
|
+
create: _deepseek_ai_dsh_session_reference_sessionReferenceResolver_candidates_parameter_1$schema,
|
|
49
53
|
},
|
|
50
54
|
},
|
|
51
55
|
],
|
|
@@ -53,9 +57,9 @@ export const TYPERT_REMOTE = {
|
|
|
53
57
|
result: {
|
|
54
58
|
mode: 'strict',
|
|
55
59
|
typeSymbol: '@deepseek-ai/dsh-session-reference#sessionReferenceResolver/candidates:result',
|
|
56
|
-
|
|
60
|
+
create: _deepseek_ai_dsh_session_reference_sessionReferenceResolver_candidates_result$schema,
|
|
57
61
|
},
|
|
58
|
-
sourceLocation: {"file":"packages/context/session-reference/src/index.ts","line":
|
|
62
|
+
sourceLocation: {"file":"packages/context/session-reference/src/index.ts","line":280,"column":9},
|
|
59
63
|
},
|
|
60
64
|
],
|
|
61
65
|
}
|
package/lib/types/index.d.ts
CHANGED
|
@@ -39,18 +39,17 @@ export declare class SessionReferenceResolver extends TypertRemoteService {
|
|
|
39
39
|
/**
|
|
40
40
|
* List reference candidates, ranked by working-directory affinity.
|
|
41
41
|
*
|
|
42
|
-
* Discovery runs at keystroke rate, so
|
|
43
|
-
* projection
|
|
44
|
-
* which sessions can answer one and which fall back to their id.
|
|
42
|
+
* Discovery runs at keystroke rate, so titles and subagent labels only ever
|
|
43
|
+
* come from projection reads; sessions without either fall back to their id.
|
|
45
44
|
* @param agent - target agent; self is excluded and its cwd drives ranking.
|
|
46
|
-
* @param query - optional case-insensitive session-id/cwd/title substring.
|
|
45
|
+
* @param query - optional case-insensitive session-id/cwd/title/display-title substring.
|
|
47
46
|
* @param limit - optional positive result cap.
|
|
48
47
|
* @param signal - optional cancellation boundary for host autocomplete teardown.
|
|
49
|
-
* @returns candidates
|
|
48
|
+
* @returns candidates with canonical mention labels and presentation titles.
|
|
50
49
|
*/
|
|
51
50
|
listCandidates(agent: Agent, query?: string, limit?: number, signal?: AbortSignal): Promise<SessionReferenceCandidate[]>;
|
|
52
51
|
/**
|
|
53
|
-
* The title a
|
|
52
|
+
* The mention label and display title a Session's projections can answer without reading its log.
|
|
54
53
|
*
|
|
55
54
|
* Attachment is decided by the store at read time, not by the listing:
|
|
56
55
|
* a session that attached in between would otherwise be answered from a
|
|
@@ -69,9 +68,9 @@ export declare class SessionReferenceResolver extends TypertRemoteService {
|
|
|
69
68
|
* and cannot be found by its title until it is opened once, which
|
|
70
69
|
* checkpoints it.
|
|
71
70
|
* @param record - the listed session, live or cold.
|
|
72
|
-
* @returns the
|
|
71
|
+
* @returns the title-backed mention label and the subagent-label-first display title.
|
|
73
72
|
*/
|
|
74
|
-
private
|
|
73
|
+
private projectedLabels;
|
|
75
74
|
/**
|
|
76
75
|
* Remote face of {@link listCandidates}: the configured candidate limit
|
|
77
76
|
* applies, and every candidate carries the canonical mention a host inserts
|
package/lib/types/index.js
CHANGED
|
@@ -153,14 +153,13 @@ let SessionReferenceResolver = (() => {
|
|
|
153
153
|
/**
|
|
154
154
|
* List reference candidates, ranked by working-directory affinity.
|
|
155
155
|
*
|
|
156
|
-
* Discovery runs at keystroke rate, so
|
|
157
|
-
* projection
|
|
158
|
-
* which sessions can answer one and which fall back to their id.
|
|
156
|
+
* Discovery runs at keystroke rate, so titles and subagent labels only ever
|
|
157
|
+
* come from projection reads; sessions without either fall back to their id.
|
|
159
158
|
* @param agent - target agent; self is excluded and its cwd drives ranking.
|
|
160
|
-
* @param query - optional case-insensitive session-id/cwd/title substring.
|
|
159
|
+
* @param query - optional case-insensitive session-id/cwd/title/display-title substring.
|
|
161
160
|
* @param limit - optional positive result cap.
|
|
162
161
|
* @param signal - optional cancellation boundary for host autocomplete teardown.
|
|
163
|
-
* @returns candidates
|
|
162
|
+
* @returns candidates with canonical mention labels and presentation titles.
|
|
164
163
|
*/
|
|
165
164
|
async listCandidates(agent, query = '', limit = this.config.candidateLimit, signal) {
|
|
166
165
|
if (!Number.isSafeInteger(limit) || limit <= 0) {
|
|
@@ -172,30 +171,28 @@ let SessionReferenceResolver = (() => {
|
|
|
172
171
|
const records = (await settleWithCancellation(this.ctx.sessionQuery.listSessions(signal), signal))
|
|
173
172
|
.filter(record => record.header.id !== agent.id)
|
|
174
173
|
.map((record, index) => ({ record, index }));
|
|
175
|
-
const labelled = records.map(({ record, index }) => ({
|
|
176
|
-
|
|
177
|
-
index,
|
|
178
|
-
label: this.projectedTitle(record) ?? record.header.id,
|
|
179
|
-
}));
|
|
180
|
-
return labelled.filter(({ record, label }) => {
|
|
174
|
+
const labelled = records.map(({ record, index }) => ({ record, index, ...this.projectedLabels(record) }));
|
|
175
|
+
return labelled.filter(({ record, label, displayTitle }) => {
|
|
181
176
|
if (needle === '')
|
|
182
177
|
return true;
|
|
183
178
|
return record.header.id.toLocaleLowerCase().includes(needle)
|
|
184
179
|
|| record.header.cwd?.toLocaleLowerCase().includes(needle) === true
|
|
185
|
-
|| label.toLocaleLowerCase().includes(needle)
|
|
180
|
+
|| label.toLocaleLowerCase().includes(needle)
|
|
181
|
+
|| displayTitle.toLocaleLowerCase().includes(needle);
|
|
186
182
|
}).sort((a, b) => candidateRank(a.record.header.cwd, targetCwd) - candidateRank(b.record.header.cwd, targetCwd)
|
|
187
183
|
|| a.index - b.index)
|
|
188
184
|
.slice(0, limit)
|
|
189
|
-
.map(({ record, label }) => ({
|
|
185
|
+
.map(({ record, label, displayTitle }) => ({
|
|
190
186
|
sessionId: record.header.id,
|
|
191
187
|
label,
|
|
188
|
+
displayTitle,
|
|
192
189
|
...record.header.cwd === undefined ? {} : { cwd: record.header.cwd },
|
|
193
190
|
sameWorkspace: record.header.cwd !== undefined && record.header.cwd === targetCwd,
|
|
194
191
|
createdAt: record.header.createdAt,
|
|
195
192
|
}));
|
|
196
193
|
}
|
|
197
194
|
/**
|
|
198
|
-
* The title a
|
|
195
|
+
* The mention label and display title a Session's projections can answer without reading its log.
|
|
199
196
|
*
|
|
200
197
|
* Attachment is decided by the store at read time, not by the listing:
|
|
201
198
|
* a session that attached in between would otherwise be answered from a
|
|
@@ -214,17 +211,24 @@ let SessionReferenceResolver = (() => {
|
|
|
214
211
|
* and cannot be found by its title until it is opened once, which
|
|
215
212
|
* checkpoints it.
|
|
216
213
|
* @param record - the listed session, live or cold.
|
|
217
|
-
* @returns the
|
|
214
|
+
* @returns the title-backed mention label and the subagent-label-first display title.
|
|
218
215
|
*/
|
|
219
|
-
|
|
216
|
+
projectedLabels(record) {
|
|
220
217
|
const attached = this.ctx.get('sessions')?.get(record.header.id);
|
|
221
218
|
const projections = this.ctx.get('sessionProjections');
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
219
|
+
const snapshot = attached !== undefined && projections !== undefined
|
|
220
|
+
? projections.snapshot(attached, ['title', 'subagent'])
|
|
221
|
+
: record.header.isSeeded
|
|
222
|
+
? undefined
|
|
223
|
+
: this.ctx.get('sessionProjectionCache')?.cachedSnapshot(record.header, SessionLogOffset(0), ['title', 'subagent']);
|
|
224
|
+
const label = titleOf(snapshot) ?? record.header.id;
|
|
225
|
+
const subagent = snapshot?.values.subagent;
|
|
226
|
+
return {
|
|
227
|
+
label,
|
|
228
|
+
displayTitle: subagent === undefined || subagent === null
|
|
229
|
+
? label
|
|
230
|
+
: subagent.label ?? label,
|
|
231
|
+
};
|
|
228
232
|
}
|
|
229
233
|
/**
|
|
230
234
|
* Remote face of {@link listCandidates}: the configured candidate limit
|
|
@@ -239,7 +243,10 @@ let SessionReferenceResolver = (() => {
|
|
|
239
243
|
const candidates = await this.listCandidates(agent, query, this.config.candidateLimit, signal);
|
|
240
244
|
return candidates.map(candidate => ({
|
|
241
245
|
...candidate,
|
|
242
|
-
mention: formatSessionReferenceMention({
|
|
246
|
+
mention: formatSessionReferenceMention({
|
|
247
|
+
sessionId: candidate.sessionId,
|
|
248
|
+
label: candidate.displayTitle ?? candidate.label,
|
|
249
|
+
}),
|
|
243
250
|
}));
|
|
244
251
|
}
|
|
245
252
|
/**
|
package/lib/types/types.d.ts
CHANGED
|
@@ -46,6 +46,8 @@ export interface SessionReferenceCandidate {
|
|
|
46
46
|
sessionId: SessionId;
|
|
47
47
|
/** Latest log-backed title, falling back to the opaque session id. */
|
|
48
48
|
label: string;
|
|
49
|
+
/** Display and canonical-mention text, preferring a subagent's durable creation label over {@link label}. */
|
|
50
|
+
displayTitle?: string;
|
|
49
51
|
/** Source session working directory, when recorded. */
|
|
50
52
|
cwd?: string;
|
|
51
53
|
/**
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@deepseek-ai/dsh-session-reference",
|
|
3
3
|
"description": "Cross-session snapshot references and durable untrusted model context (ctx.sessionReferenceResolver)",
|
|
4
|
-
"version": "0.1.
|
|
4
|
+
"version": "0.1.6-alpha.2",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
7
7
|
},
|
|
@@ -45,24 +45,25 @@
|
|
|
45
45
|
"license": "MIT",
|
|
46
46
|
"dependencies": {
|
|
47
47
|
"zod": "^4.4.3",
|
|
48
|
-
"@deepseek-ai/dsh-brand": "^0.1.
|
|
49
|
-
"@deepseek-ai/dsh-util-values": "^0.1.
|
|
48
|
+
"@deepseek-ai/dsh-brand": "^0.1.6-alpha.2",
|
|
49
|
+
"@deepseek-ai/dsh-util-values": "^0.1.6-alpha.2",
|
|
50
50
|
"@deepseek-ai/schemastery": "^3.18.2"
|
|
51
51
|
},
|
|
52
52
|
"peerDependencies": {
|
|
53
53
|
"@deepseek-ai/cordis": "^4.0.2",
|
|
54
|
-
"@deepseek-ai/dsh-agent": "^0.1.
|
|
55
|
-
"@deepseek-ai/dsh-compaction": "^0.1.
|
|
56
|
-
"@deepseek-ai/dsh-llm": "^0.1.
|
|
57
|
-
"@deepseek-ai/dsh-output-retention": "^0.1.
|
|
58
|
-
"@deepseek-ai/dsh-session": "^0.1.
|
|
59
|
-
"@deepseek-ai/dsh-session-projection": "^0.1.
|
|
60
|
-
"@deepseek-ai/dsh-session-projection-cache": "^0.1.
|
|
61
|
-
"@deepseek-ai/dsh-session-query": "^0.1.
|
|
62
|
-
"@deepseek-ai/dsh-session-title": "^0.1.
|
|
63
|
-
"@deepseek-ai/dsh-spill": "^0.1.
|
|
64
|
-
"@deepseek-ai/dsh-
|
|
65
|
-
"@deepseek-ai/dsh-
|
|
54
|
+
"@deepseek-ai/dsh-agent": "^0.1.6-alpha.2",
|
|
55
|
+
"@deepseek-ai/dsh-compaction": "^0.1.6-alpha.2",
|
|
56
|
+
"@deepseek-ai/dsh-llm": "^0.1.6-alpha.2",
|
|
57
|
+
"@deepseek-ai/dsh-output-retention": "^0.1.6-alpha.2",
|
|
58
|
+
"@deepseek-ai/dsh-session": "^0.1.6-alpha.2",
|
|
59
|
+
"@deepseek-ai/dsh-session-projection": "^0.1.6-alpha.2",
|
|
60
|
+
"@deepseek-ai/dsh-session-projection-cache": "^0.1.6-alpha.2",
|
|
61
|
+
"@deepseek-ai/dsh-session-query": "^0.1.6-alpha.2",
|
|
62
|
+
"@deepseek-ai/dsh-session-title": "^0.1.6-alpha.2",
|
|
63
|
+
"@deepseek-ai/dsh-spill": "^0.1.6-alpha.2",
|
|
64
|
+
"@deepseek-ai/dsh-subagent": "^0.1.6-alpha.2",
|
|
65
|
+
"@deepseek-ai/dsh-system-prompt": "^0.1.6-alpha.2",
|
|
66
|
+
"@deepseek-ai/dsh-typert-protocol": "^0.1.6-alpha.2"
|
|
66
67
|
},
|
|
67
68
|
"peerDependenciesMeta": {
|
|
68
69
|
"@deepseek-ai/dsh-spill": {
|
|
@@ -76,22 +77,23 @@
|
|
|
76
77
|
"@deepseek-ai/cordis": "^4.0.2",
|
|
77
78
|
"@deepseek-ai/cordis-plugin-include": "^1.0.7",
|
|
78
79
|
"@deepseek-ai/cordis-plugin-loader": "^1.0.3",
|
|
79
|
-
"@deepseek-ai/dsh-agent": "^0.1.
|
|
80
|
-
"@deepseek-ai/dsh-compaction": "^0.1.
|
|
81
|
-
"@deepseek-ai/dsh-fs-local": "^0.1.
|
|
82
|
-
"@deepseek-ai/dsh-llm": "^0.1.
|
|
83
|
-
"@deepseek-ai/dsh-
|
|
84
|
-
"@deepseek-ai/dsh-session-projection": "^0.1.
|
|
85
|
-
"@deepseek-ai/dsh-session": "^0.1.
|
|
86
|
-
"@deepseek-ai/dsh-
|
|
87
|
-
"@deepseek-ai/dsh-session-query-sqlite": "^0.1.
|
|
88
|
-
"@deepseek-ai/dsh-session-title": "^0.1.
|
|
89
|
-
"@deepseek-ai/dsh-spill": "^0.1.
|
|
90
|
-
"@deepseek-ai/dsh-
|
|
91
|
-
"@deepseek-ai/dsh-
|
|
92
|
-
"@deepseek-ai/dsh-
|
|
93
|
-
"@deepseek-ai/dsh-
|
|
94
|
-
"@deepseek-ai/dsh-
|
|
95
|
-
"@deepseek-ai/dsh-
|
|
80
|
+
"@deepseek-ai/dsh-agent": "^0.1.6-alpha.2",
|
|
81
|
+
"@deepseek-ai/dsh-compaction": "^0.1.6-alpha.2",
|
|
82
|
+
"@deepseek-ai/dsh-fs-local": "^0.1.6-alpha.2",
|
|
83
|
+
"@deepseek-ai/dsh-llm": "^0.1.6-alpha.2",
|
|
84
|
+
"@deepseek-ai/dsh-session": "^0.1.6-alpha.2",
|
|
85
|
+
"@deepseek-ai/dsh-session-projection": "^0.1.6-alpha.2",
|
|
86
|
+
"@deepseek-ai/dsh-session-projection-cache": "^0.1.6-alpha.2",
|
|
87
|
+
"@deepseek-ai/dsh-output-retention": "^0.1.6-alpha.2",
|
|
88
|
+
"@deepseek-ai/dsh-session-query-sqlite": "^0.1.6-alpha.2",
|
|
89
|
+
"@deepseek-ai/dsh-session-title": "^0.1.6-alpha.2",
|
|
90
|
+
"@deepseek-ai/dsh-spill": "^0.1.6-alpha.2",
|
|
91
|
+
"@deepseek-ai/dsh-subagent": "^0.1.6-alpha.2",
|
|
92
|
+
"@deepseek-ai/dsh-spill-local": "^0.1.6-alpha.2",
|
|
93
|
+
"@deepseek-ai/dsh-system-prompt": "^0.1.6-alpha.2",
|
|
94
|
+
"@deepseek-ai/dsh-tool-fs": "^0.1.6-alpha.2",
|
|
95
|
+
"@deepseek-ai/dsh-session-query": "^0.1.6-alpha.2",
|
|
96
|
+
"@deepseek-ai/dsh-tools": "^0.1.6-alpha.2",
|
|
97
|
+
"@deepseek-ai/dsh-typert-protocol": "^0.1.6-alpha.2"
|
|
96
98
|
}
|
|
97
99
|
}
|