@deepseek-ai/dsh-session-reference 0.1.6-alpha.1 → 0.1.7-alpha.1
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 +1 -1
- package/README.zh.md +1 -1
- package/lib/index.js +24 -20
- package/lib/typert.host.js +60 -28
- package/lib/typert.remote-client.js +12 -8
- package/lib/types/index.d.ts +9 -11
- package/lib/types/index.js +30 -27
- package/lib/types/projection.js +1 -0
- package/lib/types/types.d.ts +2 -0
- package/package.json +39 -37
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
|
|
package/README.zh.md
CHANGED
|
@@ -39,7 +39,7 @@ kind: "package-reference"
|
|
|
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
|
|
package/lib/index.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import z from "@deepseek-ai/schemastery";
|
|
2
2
|
import { Remote, TypertRemoteService } from "@deepseek-ai/dsh-typert-protocol";
|
|
3
3
|
import { LlmError, createUserMessage, freezeMessage } from "@deepseek-ai/dsh-llm";
|
|
4
|
-
import { SessionLogOffset, SessionSeq } from "@deepseek-ai/dsh-session";
|
|
5
4
|
import { isCompactCheckpointSource } from "@deepseek-ai/dsh-compaction";
|
|
6
5
|
import { TextRetainer } from "@deepseek-ai/dsh-output-retention";
|
|
7
6
|
import { assertNever } from "@deepseek-ai/dsh-util-values";
|
|
7
|
+
import { SessionSeq } from "@deepseek-ai/dsh-session";
|
|
8
8
|
import { brandString } from "@deepseek-ai/dsh-brand";
|
|
9
9
|
//#region lib/types/spill.js
|
|
10
10
|
/** Full projected transcripts and model-visible spill outcomes for bounded reference previews. */
|
|
@@ -150,6 +150,7 @@ function projectSessionConversation(snapshot) {
|
|
|
150
150
|
});
|
|
151
151
|
break;
|
|
152
152
|
}
|
|
153
|
+
case "developer/message":
|
|
153
154
|
case "system/message":
|
|
154
155
|
case "tool/result": break;
|
|
155
156
|
/* v8 ignore next 2 -- SurfaceEventType is closed and every variant is handled above. */
|
|
@@ -508,14 +509,13 @@ let SessionReferenceResolver = (() => {
|
|
|
508
509
|
/**
|
|
509
510
|
* List reference candidates, ranked by working-directory affinity.
|
|
510
511
|
*
|
|
511
|
-
* Discovery runs at keystroke rate, so
|
|
512
|
-
* projection
|
|
513
|
-
* which sessions can answer one and which fall back to their id.
|
|
512
|
+
* Discovery runs at keystroke rate, so titles and subagent labels only ever
|
|
513
|
+
* come from projection reads; sessions without either fall back to their id.
|
|
514
514
|
* @param agent - target agent; self is excluded and its cwd drives ranking.
|
|
515
|
-
* @param query - optional case-insensitive session-id/cwd/title substring.
|
|
515
|
+
* @param query - optional case-insensitive session-id/cwd/title/display-title substring.
|
|
516
516
|
* @param limit - optional positive result cap.
|
|
517
517
|
* @param signal - optional cancellation boundary for host autocomplete teardown.
|
|
518
|
-
* @returns candidates
|
|
518
|
+
* @returns candidates with canonical mention labels and presentation titles.
|
|
519
519
|
*/
|
|
520
520
|
async listCandidates(agent, query = "", limit = this.config.candidateLimit, signal) {
|
|
521
521
|
if (!Number.isSafeInteger(limit) || limit <= 0) throw new SessionReferenceError("candidate limit must be a positive safe integer", "SESSION_REFERENCE_INVALID_REFERENCE");
|
|
@@ -528,20 +528,21 @@ let SessionReferenceResolver = (() => {
|
|
|
528
528
|
})).map(({ record, index }) => ({
|
|
529
529
|
record,
|
|
530
530
|
index,
|
|
531
|
-
|
|
532
|
-
})).filter(({ record, label }) => {
|
|
531
|
+
...this.projectedLabels(record)
|
|
532
|
+
})).filter(({ record, label, displayTitle }) => {
|
|
533
533
|
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 }) => ({
|
|
534
|
+
return record.header.id.toLocaleLowerCase().includes(needle) || record.header.cwd?.toLocaleLowerCase().includes(needle) === true || label.toLocaleLowerCase().includes(needle) || displayTitle.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, displayTitle }) => ({
|
|
536
536
|
sessionId: record.header.id,
|
|
537
537
|
label,
|
|
538
|
+
displayTitle,
|
|
538
539
|
...record.header.cwd === void 0 ? {} : { cwd: record.header.cwd },
|
|
539
540
|
sameWorkspace: record.header.cwd !== void 0 && record.header.cwd === targetCwd,
|
|
540
541
|
createdAt: record.header.createdAt
|
|
541
542
|
}));
|
|
542
543
|
}
|
|
543
544
|
/**
|
|
544
|
-
* The title a
|
|
545
|
+
* The mention label and display title a Session's projections can answer without reading its log.
|
|
545
546
|
*
|
|
546
547
|
* Attachment is decided by the store at read time, not by the listing:
|
|
547
548
|
* a session that attached in between would otherwise be answered from a
|
|
@@ -556,18 +557,21 @@ let SessionReferenceResolver = (() => {
|
|
|
556
557
|
* Nothing else is attempted. Folding a title from a log costs the whole
|
|
557
558
|
* log, and this call sits under every keystroke of `@` completion. A
|
|
558
559
|
* session that no projection can answer for — one persisted before the
|
|
559
|
-
* cache was composed
|
|
560
|
-
*
|
|
561
|
-
* checkpoints it.
|
|
560
|
+
* cache was composed — is labeled by its id and cannot be found by its
|
|
561
|
+
* title until it is opened once, which 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"]) : this.ctx.get("sessionProjectionCache")?.cachedSnapshot(record.header, ["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":272,"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",
|
|
@@ -128,7 +132,7 @@ export const TYPERT = {
|
|
|
128
132
|
},
|
|
129
133
|
{
|
|
130
134
|
"name": "AssistantMessage",
|
|
131
|
-
"declaration": "export interface AssistantMessage extends
|
|
135
|
+
"declaration": "export interface AssistantMessage extends MessageBase {\n readonly role: 'assistant';\n readonly source: ModelMessageSource;\n}"
|
|
132
136
|
},
|
|
133
137
|
{
|
|
134
138
|
"name": "AssistantProviderMetadata",
|
|
@@ -166,6 +170,10 @@ export const TYPERT = {
|
|
|
166
170
|
"name": "CommandSourceMap",
|
|
167
171
|
"declaration": "export interface CommandSourceMap {\n user: { kind: 'user'; };\n}"
|
|
168
172
|
},
|
|
173
|
+
{
|
|
174
|
+
"name": "CompactionCheckpointSource",
|
|
175
|
+
"declaration": "export type CompactionCheckpointSource = typeof COMPACT_CHECKPOINT_MARKER & { readonly compactionId: CompactionId; readonly sourceCommandId?: CommandId; };"
|
|
176
|
+
},
|
|
169
177
|
{
|
|
170
178
|
"name": "CompactionId",
|
|
171
179
|
"declaration": "export type CompactionId = Branded<'CompactionId'>;"
|
|
@@ -176,7 +184,7 @@ export const TYPERT = {
|
|
|
176
184
|
},
|
|
177
185
|
{
|
|
178
186
|
"name": "ContentBlockMap",
|
|
179
|
-
"declaration": "export interface ContentBlockMap {\n text: TextBlock;\n reasoning: ReasoningBlock;\n image: ImageBlock;\n file: FileBlock;\n 'tool-call': ToolCallBlock;\n 'tool-
|
|
187
|
+
"declaration": "export interface ContentBlockMap {\n text: TextBlock;\n reasoning: ReasoningBlock;\n image: ImageBlock;\n file: FileBlock;\n 'tool-call': ToolCallBlock;\n 'tool-addition': ToolAdditionBlock;\n 'tool-removal': ToolRemovalBlock;\n}"
|
|
180
188
|
},
|
|
181
189
|
{
|
|
182
190
|
"name": "ContentBlockType",
|
|
@@ -194,9 +202,13 @@ export const TYPERT = {
|
|
|
194
202
|
"name": "ContinuableSubagentDescriptorData",
|
|
195
203
|
"declaration": "export interface ContinuableSubagentDescriptorData extends SubagentDescriptorBase {\n readonly mode: 'continuable';\n readonly label: string;\n readonly agentProvider?: string;\n readonly agentModel?: string;\n readonly agentReasoningEffort?: ReasoningEffortId;\n readonly persona?: string;\n readonly toolFilter?: ToolRestriction;\n}"
|
|
196
204
|
},
|
|
205
|
+
{
|
|
206
|
+
"name": "DeveloperMessage",
|
|
207
|
+
"declaration": "export interface DeveloperMessage extends MessageBase {\n readonly role: 'developer';\n}"
|
|
208
|
+
},
|
|
197
209
|
{
|
|
198
210
|
"name": "EpochHeader",
|
|
199
|
-
"declaration": "export interface EpochHeader {\n config: LlmCallConfig;\n adapterDefaults?: LlmCallConfigAdapterDefaults;\n tools?: ToolSchema[];\n}"
|
|
211
|
+
"declaration": "export interface EpochHeader {\n config: LlmCallConfig;\n adapterDefaults?: LlmCallConfigAdapterDefaults;\n tools?: ToolSchema[];\n system?: never;\n}"
|
|
200
212
|
},
|
|
201
213
|
{
|
|
202
214
|
"name": "FeedbackCategory",
|
|
@@ -290,6 +302,10 @@ export const TYPERT = {
|
|
|
290
302
|
"name": "JsonValue",
|
|
291
303
|
"declaration": "export type JsonValue = null | boolean | number | string | JsonValue[] | { [key: string]: JsonValue; };"
|
|
292
304
|
},
|
|
305
|
+
{
|
|
306
|
+
"name": "KnownCatalogMode",
|
|
307
|
+
"declaration": "export type KnownCatalogMode = { readonly mode: 'one-shot'; readonly label?: string; } | { readonly mode: 'continuable'; readonly label: string; };"
|
|
308
|
+
},
|
|
293
309
|
{
|
|
294
310
|
"name": "LlmCallConfig",
|
|
295
311
|
"declaration": "export interface LlmCallConfig {\n provider: string;\n model: string;\n reasoningEffort?: ReasoningEffortId;\n temperature?: number;\n maxTokens?: number;\n stop?: string[];\n}"
|
|
@@ -304,7 +320,11 @@ export const TYPERT = {
|
|
|
304
320
|
},
|
|
305
321
|
{
|
|
306
322
|
"name": "Message",
|
|
307
|
-
"declaration": "export
|
|
323
|
+
"declaration": "export type Message = MessageRoleMap[keyof MessageRoleMap];"
|
|
324
|
+
},
|
|
325
|
+
{
|
|
326
|
+
"name": "MessageBase",
|
|
327
|
+
"declaration": "export interface MessageBase {\n readonly id: MessageId;\n readonly content: readonly ContentBlock[];\n readonly source: MessageSource;\n}"
|
|
308
328
|
},
|
|
309
329
|
{
|
|
310
330
|
"name": "MessageFeedbackDelete",
|
|
@@ -330,13 +350,17 @@ export const TYPERT = {
|
|
|
330
350
|
"name": "MessageId",
|
|
331
351
|
"declaration": "export type MessageId = Branded<'MessageId'>;"
|
|
332
352
|
},
|
|
353
|
+
{
|
|
354
|
+
"name": "MessageRoleMap",
|
|
355
|
+
"declaration": "export interface MessageRoleMap {\n system: SystemMessage;\n developer: DeveloperMessage;\n user: UserMessage;\n assistant: AssistantMessage;\n tool: ToolResultMessage;\n}"
|
|
356
|
+
},
|
|
333
357
|
{
|
|
334
358
|
"name": "MessageSource",
|
|
335
359
|
"declaration": "export type MessageSource = MessageSourceMap[keyof MessageSourceMap];"
|
|
336
360
|
},
|
|
337
361
|
{
|
|
338
362
|
"name": "MessageSourceMap",
|
|
339
|
-
"declaration": "export interface MessageSourceMap {\n user: { kind: 'user'; };\n
|
|
363
|
+
"declaration": "export interface MessageSourceMap {\n user: { kind: 'user'; };\n model: ModelMessageSource;\n tool: ToolMessageSource;\n 'system-prompt': SystemPromptMessageSource;\n 'model-selection': { kind: 'model-selection'; } & ContextFormed;\n 'user-approval': { kind: 'user-approval'; } & ContextFormed;\n 'ptc-mode': { kind: 'ptc-mode'; };\n 'tool-registry': { kind: 'tool-registry'; };\n 'user-rpc': { kind: 'user'; rpcId: SessionRequestId; clientTimeZone?: string; };\n 'agent-message': AgentMessageSource;\n 'subagent-settled': SubagentSettledMessageSource;\n 'skill-invocation': SkillInvocationSource;\n 'cordis-host-runner': { kind: 'cordis-host-runner'; };\n 'team-message': TeamMessageSource;\n goal: GoalMessageSource;\n 'compact-checkpoint': CompactionCheckpointSource;\n 'session-reference': SessionReferenceSource;\n}"
|
|
340
364
|
},
|
|
341
365
|
{
|
|
342
366
|
"name": "ModelMessageSource",
|
|
@@ -396,7 +420,7 @@ export const TYPERT = {
|
|
|
396
420
|
},
|
|
397
421
|
{
|
|
398
422
|
"name": "Session",
|
|
399
|
-
"declaration": "export class Session {\n get surface(): SessionSurface;\n readonly header: SessionHeader;\n readonly inheritedEventCount: SessionLogOffset;\n get id(): SessionId;\n readonly firstLiveSeq: SessionLogOffset;\n eventAt(seq: SessionSeq): SessionEvent | undefined;\n snapshotEvents(fromSeq: SessionLogOffset = SessionLogOffset(0), toSeqExclusive: SessionLogOffset = this.seq): readonly SessionEvent[];\n ownEvents(): readonly SessionEvent[];\n isOwnSeq(seq: SessionSeq): boolean;\n get seq(): SessionLogOffset;\n append<T extends SessionEventType>(type: T, data: SessionEventMap[T], ...opts: T extends SurfaceEventType ? [opts: SurfaceIntent<T>] : []): SessionEvent<T>;\n requestHeader(): EpochHeader | undefined;\n requestContext(): RequestContext | undefined;\n deriveMessages(): Message[];\n deriveEventMessage(event: SessionEvent): Message | null;\n}"
|
|
423
|
+
"declaration": "export class Session {\n get surface(): SessionSurface;\n readonly header: SessionHeader;\n readonly inheritedEventCount: SessionLogOffset;\n get id(): SessionId;\n readonly firstLiveSeq: SessionLogOffset;\n readonly firstLifecycleSeq: SessionLogOffset;\n eventAt(seq: SessionSeq): SessionEvent | undefined;\n snapshotEvents(fromSeq: SessionLogOffset = SessionLogOffset(0), toSeqExclusive: SessionLogOffset = this.seq): readonly SessionEvent[];\n ownEvents(): readonly SessionEvent[];\n isOwnSeq(seq: SessionSeq): boolean;\n get seq(): SessionLogOffset;\n append<T extends SessionEventType>(type: T, data: SessionEventMap[T], ...opts: T extends SurfaceEventType ? [opts: SurfaceIntent<T>] : []): SessionEvent<T>;\n requestHeader(): EpochHeader | undefined;\n requestContext(): RequestContext | undefined;\n deriveMessages(): Message[];\n deriveEventMessage(event: SessionEvent): Message | null;\n}"
|
|
400
424
|
},
|
|
401
425
|
{
|
|
402
426
|
"name": "SessionEvent",
|
|
@@ -404,7 +428,7 @@ export const TYPERT = {
|
|
|
404
428
|
},
|
|
405
429
|
{
|
|
406
430
|
"name": "SessionEventMap",
|
|
407
|
-
"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}"
|
|
431
|
+
"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 'developer/message': { turn: number; step: number; message: DeveloperMessage; headerSeq?: SessionSeq; };\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}"
|
|
408
432
|
},
|
|
409
433
|
{
|
|
410
434
|
"name": "SessionEventType",
|
|
@@ -424,7 +448,7 @@ export const TYPERT = {
|
|
|
424
448
|
},
|
|
425
449
|
{
|
|
426
450
|
"name": "SessionReferenceCandidate",
|
|
427
|
-
"declaration": "export interface SessionReferenceCandidate {\n sessionId: SessionId;\n label: string;\n cwd?: string;\n sameWorkspace: boolean;\n createdAt: number;\n}"
|
|
451
|
+
"declaration": "export interface SessionReferenceCandidate {\n sessionId: SessionId;\n label: string;\n displayTitle?: string;\n cwd?: string;\n sameWorkspace: boolean;\n createdAt: number;\n}"
|
|
428
452
|
},
|
|
429
453
|
{
|
|
430
454
|
"name": "SessionReferenceInput",
|
|
@@ -476,7 +500,7 @@ export const TYPERT = {
|
|
|
476
500
|
},
|
|
477
501
|
{
|
|
478
502
|
"name": "SubagentCatalogEvent",
|
|
479
|
-
"declaration": "export type SubagentCatalogEvent = { readonly
|
|
503
|
+
"declaration": "export type SubagentCatalogEvent = { readonly childId: SessionId; readonly childCreatedAt: number; } & (({ readonly version: 0; } & KnownCatalogMode) | ({ readonly version: 1; } & (KnownCatalogMode | { readonly mode: 'unknown'; readonly label?: string; })));"
|
|
480
504
|
},
|
|
481
505
|
{
|
|
482
506
|
"name": "SubagentDescriptorBase",
|
|
@@ -492,7 +516,7 @@ export const TYPERT = {
|
|
|
492
516
|
},
|
|
493
517
|
{
|
|
494
518
|
"name": "SurfaceEventType",
|
|
495
|
-
"declaration": "export type SurfaceEventType = 'system/message' | 'user/message' | 'assistant/message' | 'tool/result';"
|
|
519
|
+
"declaration": "export type SurfaceEventType = 'system/message' | 'developer/message' | 'user/message' | 'assistant/message' | 'tool/result';"
|
|
496
520
|
},
|
|
497
521
|
{
|
|
498
522
|
"name": "SurfaceIntent",
|
|
@@ -504,7 +528,11 @@ export const TYPERT = {
|
|
|
504
528
|
},
|
|
505
529
|
{
|
|
506
530
|
"name": "SystemMessage",
|
|
507
|
-
"declaration": "export interface SystemMessage extends
|
|
531
|
+
"declaration": "export interface SystemMessage extends MessageBase {\n readonly role: 'system';\n readonly source: MessageSourceMap['system-prompt'];\n}"
|
|
532
|
+
},
|
|
533
|
+
{
|
|
534
|
+
"name": "SystemPromptMessageSource",
|
|
535
|
+
"declaration": "export interface SystemPromptMessageSource {\n kind: 'system-prompt';\n}"
|
|
508
536
|
},
|
|
509
537
|
{
|
|
510
538
|
"name": "SystemPromptUpdate",
|
|
@@ -558,6 +586,10 @@ export const TYPERT = {
|
|
|
558
586
|
"name": "TokenUsage",
|
|
559
587
|
"declaration": "export interface TokenUsage {\n inputTokens: number;\n outputTokens: number;\n totalTokens?: number;\n cacheReadTokens?: number;\n cacheWriteTokens?: number;\n reasoningTokens?: number;\n}"
|
|
560
588
|
},
|
|
589
|
+
{
|
|
590
|
+
"name": "ToolAdditionBlock",
|
|
591
|
+
"declaration": "export interface ToolAdditionBlock {\n type: 'tool-addition';\n toolName: string;\n tool?: never;\n}"
|
|
592
|
+
},
|
|
561
593
|
{
|
|
562
594
|
"name": "ToolCallBlock",
|
|
563
595
|
"declaration": "export interface ToolCallBlock {\n type: 'tool-call';\n id: ToolCallId;\n name: string;\n arguments: string;\n}"
|
|
@@ -571,20 +603,20 @@ export const TYPERT = {
|
|
|
571
603
|
"declaration": "export interface ToolMessageSource {\n kind: 'tool';\n callId: ToolCallId;\n}"
|
|
572
604
|
},
|
|
573
605
|
{
|
|
574
|
-
"name": "
|
|
575
|
-
"declaration": "export interface
|
|
606
|
+
"name": "ToolRemovalBlock",
|
|
607
|
+
"declaration": "export interface ToolRemovalBlock {\n type: 'tool-removal';\n toolName: string;\n}"
|
|
576
608
|
},
|
|
577
609
|
{
|
|
578
|
-
"name": "
|
|
579
|
-
"declaration": "export interface
|
|
610
|
+
"name": "ToolRestriction",
|
|
611
|
+
"declaration": "export interface ToolRestriction {\n readonly allow?: readonly string[];\n readonly deny?: readonly string[];\n}"
|
|
580
612
|
},
|
|
581
613
|
{
|
|
582
614
|
"name": "ToolResultMessage",
|
|
583
|
-
"declaration": "export interface ToolResultMessage extends
|
|
615
|
+
"declaration": "export interface ToolResultMessage extends MessageBase {\n readonly role: 'tool';\n readonly source: ToolMessageSource;\n readonly toolCallId: ToolCallId;\n readonly isError?: boolean;\n}"
|
|
584
616
|
},
|
|
585
617
|
{
|
|
586
618
|
"name": "ToolSchema",
|
|
587
|
-
"declaration": "export interface ToolSchema {\n name: string;\n description: string;\n parameters: Record<string, unknown>;\n}"
|
|
619
|
+
"declaration": "export interface ToolSchema {\n deferLoading?: true;\n name: string;\n description: string;\n parameters: Record<string, unknown>;\n}"
|
|
588
620
|
},
|
|
589
621
|
{
|
|
590
622
|
"name": "TurnEndCancelCause",
|
|
@@ -596,11 +628,11 @@ export const TYPERT = {
|
|
|
596
628
|
},
|
|
597
629
|
{
|
|
598
630
|
"name": "TurnEndReasonMap",
|
|
599
|
-
"declaration": "export interface TurnEndReasonMap {\n completed: { kind: 'completed'; };\n aborted: { kind: 'aborted'; reason: TurnEndCancelCause; };\n blocked: { kind: 'blocked'; };\n error: { kind: 'error'; error: LlmFailure; };\n 'max-tokens': { kind: 'max-tokens'; };\n interrupted: { kind: 'interrupted'; };\n}"
|
|
631
|
+
"declaration": "export interface TurnEndReasonMap {\n completed: { kind: 'completed'; };\n aborted: { kind: 'aborted'; reason: TurnEndCancelCause; };\n blocked: { kind: 'blocked'; };\n error: { kind: 'error'; error: LlmFailure; };\n 'max-tokens': { kind: 'max-tokens'; };\n interrupted: { kind: 'interrupted'; };\n forked: { kind: 'forked'; };\n}"
|
|
600
632
|
},
|
|
601
633
|
{
|
|
602
634
|
"name": "UserMessage",
|
|
603
|
-
"declaration": "export interface UserMessage extends
|
|
635
|
+
"declaration": "export interface UserMessage extends MessageBase {\n readonly role: 'user';\n}"
|
|
604
636
|
}
|
|
605
637
|
]
|
|
606
638
|
}
|
|
@@ -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":272,"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
|
|
@@ -65,13 +64,12 @@ export declare class SessionReferenceResolver extends TypertRemoteService {
|
|
|
65
64
|
* Nothing else is attempted. Folding a title from a log costs the whole
|
|
66
65
|
* log, and this call sits under every keystroke of `@` completion. A
|
|
67
66
|
* session that no projection can answer for — one persisted before the
|
|
68
|
-
* cache was composed
|
|
69
|
-
*
|
|
70
|
-
* checkpoints it.
|
|
67
|
+
* cache was composed — is labeled by its id and cannot be found by its
|
|
68
|
+
* title until it is opened once, which checkpoints it.
|
|
71
69
|
* @param record - the listed session, live or cold.
|
|
72
|
-
* @returns the
|
|
70
|
+
* @returns the title-backed mention label and the subagent-label-first display title.
|
|
73
71
|
*/
|
|
74
|
-
private
|
|
72
|
+
private projectedLabels;
|
|
75
73
|
/**
|
|
76
74
|
* Remote face of {@link listCandidates}: the configured candidate limit
|
|
77
75
|
* applies, and every candidate carries the canonical mention a host inserts
|
package/lib/types/index.js
CHANGED
|
@@ -41,7 +41,6 @@ var __esDecorate = (this && this.__esDecorate) || function (ctor, descriptorIn,
|
|
|
41
41
|
import z from '@deepseek-ai/schemastery';
|
|
42
42
|
import { Remote, TypertRemoteService } from '@deepseek-ai/dsh-typert-protocol';
|
|
43
43
|
import { createUserMessage, freezeMessage, LlmError } from '@deepseek-ai/dsh-llm';
|
|
44
|
-
import { SessionLogOffset } from '@deepseek-ai/dsh-session';
|
|
45
44
|
import { prepareReferenceOmission, REFERENCE_WARNING } from "./spill.js";
|
|
46
45
|
import { DEFAULT_CANDIDATE_LIMIT, DEFAULT_MAX_REFERENCE_BYTES, MAX_REFERENCES, SessionReferenceError, } from "./config.js";
|
|
47
46
|
import { retainReferencedSession } from "./projection.js";
|
|
@@ -153,14 +152,13 @@ let SessionReferenceResolver = (() => {
|
|
|
153
152
|
/**
|
|
154
153
|
* List reference candidates, ranked by working-directory affinity.
|
|
155
154
|
*
|
|
156
|
-
* Discovery runs at keystroke rate, so
|
|
157
|
-
* projection
|
|
158
|
-
* which sessions can answer one and which fall back to their id.
|
|
155
|
+
* Discovery runs at keystroke rate, so titles and subagent labels only ever
|
|
156
|
+
* come from projection reads; sessions without either fall back to their id.
|
|
159
157
|
* @param agent - target agent; self is excluded and its cwd drives ranking.
|
|
160
|
-
* @param query - optional case-insensitive session-id/cwd/title substring.
|
|
158
|
+
* @param query - optional case-insensitive session-id/cwd/title/display-title substring.
|
|
161
159
|
* @param limit - optional positive result cap.
|
|
162
160
|
* @param signal - optional cancellation boundary for host autocomplete teardown.
|
|
163
|
-
* @returns candidates
|
|
161
|
+
* @returns candidates with canonical mention labels and presentation titles.
|
|
164
162
|
*/
|
|
165
163
|
async listCandidates(agent, query = '', limit = this.config.candidateLimit, signal) {
|
|
166
164
|
if (!Number.isSafeInteger(limit) || limit <= 0) {
|
|
@@ -172,30 +170,28 @@ let SessionReferenceResolver = (() => {
|
|
|
172
170
|
const records = (await settleWithCancellation(this.ctx.sessionQuery.listSessions(signal), signal))
|
|
173
171
|
.filter(record => record.header.id !== agent.id)
|
|
174
172
|
.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 }) => {
|
|
173
|
+
const labelled = records.map(({ record, index }) => ({ record, index, ...this.projectedLabels(record) }));
|
|
174
|
+
return labelled.filter(({ record, label, displayTitle }) => {
|
|
181
175
|
if (needle === '')
|
|
182
176
|
return true;
|
|
183
177
|
return record.header.id.toLocaleLowerCase().includes(needle)
|
|
184
178
|
|| record.header.cwd?.toLocaleLowerCase().includes(needle) === true
|
|
185
|
-
|| label.toLocaleLowerCase().includes(needle)
|
|
179
|
+
|| label.toLocaleLowerCase().includes(needle)
|
|
180
|
+
|| displayTitle.toLocaleLowerCase().includes(needle);
|
|
186
181
|
}).sort((a, b) => candidateRank(a.record.header.cwd, targetCwd) - candidateRank(b.record.header.cwd, targetCwd)
|
|
187
182
|
|| a.index - b.index)
|
|
188
183
|
.slice(0, limit)
|
|
189
|
-
.map(({ record, label }) => ({
|
|
184
|
+
.map(({ record, label, displayTitle }) => ({
|
|
190
185
|
sessionId: record.header.id,
|
|
191
186
|
label,
|
|
187
|
+
displayTitle,
|
|
192
188
|
...record.header.cwd === undefined ? {} : { cwd: record.header.cwd },
|
|
193
189
|
sameWorkspace: record.header.cwd !== undefined && record.header.cwd === targetCwd,
|
|
194
190
|
createdAt: record.header.createdAt,
|
|
195
191
|
}));
|
|
196
192
|
}
|
|
197
193
|
/**
|
|
198
|
-
* The title a
|
|
194
|
+
* The mention label and display title a Session's projections can answer without reading its log.
|
|
199
195
|
*
|
|
200
196
|
* Attachment is decided by the store at read time, not by the listing:
|
|
201
197
|
* a session that attached in between would otherwise be answered from a
|
|
@@ -210,21 +206,25 @@ let SessionReferenceResolver = (() => {
|
|
|
210
206
|
* Nothing else is attempted. Folding a title from a log costs the whole
|
|
211
207
|
* log, and this call sits under every keystroke of `@` completion. A
|
|
212
208
|
* session that no projection can answer for — one persisted before the
|
|
213
|
-
* cache was composed
|
|
214
|
-
*
|
|
215
|
-
* checkpoints it.
|
|
209
|
+
* cache was composed — is labeled by its id and cannot be found by its
|
|
210
|
+
* title until it is opened once, which checkpoints it.
|
|
216
211
|
* @param record - the listed session, live or cold.
|
|
217
|
-
* @returns the
|
|
212
|
+
* @returns the title-backed mention label and the subagent-label-first display title.
|
|
218
213
|
*/
|
|
219
|
-
|
|
214
|
+
projectedLabels(record) {
|
|
220
215
|
const attached = this.ctx.get('sessions')?.get(record.header.id);
|
|
221
216
|
const projections = this.ctx.get('sessionProjections');
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
return
|
|
217
|
+
const snapshot = attached !== undefined && projections !== undefined
|
|
218
|
+
? projections.snapshot(attached, ['title', 'subagent'])
|
|
219
|
+
: this.ctx.get('sessionProjectionCache')?.cachedSnapshot(record.header, ['title', 'subagent']);
|
|
220
|
+
const label = titleOf(snapshot) ?? record.header.id;
|
|
221
|
+
const subagent = snapshot?.values.subagent;
|
|
222
|
+
return {
|
|
223
|
+
label,
|
|
224
|
+
displayTitle: subagent === undefined || subagent === null
|
|
225
|
+
? label
|
|
226
|
+
: subagent.label ?? label,
|
|
227
|
+
};
|
|
228
228
|
}
|
|
229
229
|
/**
|
|
230
230
|
* Remote face of {@link listCandidates}: the configured candidate limit
|
|
@@ -239,7 +239,10 @@ let SessionReferenceResolver = (() => {
|
|
|
239
239
|
const candidates = await this.listCandidates(agent, query, this.config.candidateLimit, signal);
|
|
240
240
|
return candidates.map(candidate => ({
|
|
241
241
|
...candidate,
|
|
242
|
-
mention: formatSessionReferenceMention({
|
|
242
|
+
mention: formatSessionReferenceMention({
|
|
243
|
+
sessionId: candidate.sessionId,
|
|
244
|
+
label: candidate.displayTitle ?? candidate.label,
|
|
245
|
+
}),
|
|
243
246
|
}));
|
|
244
247
|
}
|
|
245
248
|
/**
|
package/lib/types/projection.js
CHANGED
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.7-alpha.1",
|
|
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-
|
|
49
|
-
"@deepseek-ai/
|
|
50
|
-
"@deepseek-ai/
|
|
48
|
+
"@deepseek-ai/dsh-brand": "^0.1.7-alpha.1",
|
|
49
|
+
"@deepseek-ai/dsh-util-values": "^0.1.7-alpha.1",
|
|
50
|
+
"@deepseek-ai/schemastery": "^3.18.3"
|
|
51
51
|
},
|
|
52
52
|
"peerDependencies": {
|
|
53
|
-
"@deepseek-ai/
|
|
54
|
-
"@deepseek-ai/dsh-
|
|
55
|
-
"@deepseek-ai/
|
|
56
|
-
"@deepseek-ai/dsh-
|
|
57
|
-
"@deepseek-ai/dsh-
|
|
58
|
-
"@deepseek-ai/dsh-session
|
|
59
|
-
"@deepseek-ai/dsh-
|
|
60
|
-
"@deepseek-ai/dsh-session-
|
|
61
|
-
"@deepseek-ai/dsh-
|
|
62
|
-
"@deepseek-ai/dsh-
|
|
63
|
-
"@deepseek-ai/dsh-
|
|
64
|
-
"@deepseek-ai/dsh-spill": "^0.1.
|
|
65
|
-
"@deepseek-ai/dsh-
|
|
53
|
+
"@deepseek-ai/dsh-agent": "^0.1.7-alpha.1",
|
|
54
|
+
"@deepseek-ai/dsh-compaction": "^0.1.7-alpha.1",
|
|
55
|
+
"@deepseek-ai/cordis": "^4.0.3",
|
|
56
|
+
"@deepseek-ai/dsh-llm": "^0.1.7-alpha.1",
|
|
57
|
+
"@deepseek-ai/dsh-output-retention": "^0.1.7-alpha.1",
|
|
58
|
+
"@deepseek-ai/dsh-session": "^0.1.7-alpha.1",
|
|
59
|
+
"@deepseek-ai/dsh-session-query": "^0.1.7-alpha.1",
|
|
60
|
+
"@deepseek-ai/dsh-session-title": "^0.1.7-alpha.1",
|
|
61
|
+
"@deepseek-ai/dsh-system-prompt": "^0.1.7-alpha.1",
|
|
62
|
+
"@deepseek-ai/dsh-typert-protocol": "^0.1.7-alpha.1",
|
|
63
|
+
"@deepseek-ai/dsh-session-projection-cache": "^0.1.7-alpha.1",
|
|
64
|
+
"@deepseek-ai/dsh-spill": "^0.1.7-alpha.1",
|
|
65
|
+
"@deepseek-ai/dsh-session-projection": "^0.1.7-alpha.1",
|
|
66
|
+
"@deepseek-ai/dsh-subagent": "^0.1.7-alpha.1"
|
|
66
67
|
},
|
|
67
68
|
"peerDependenciesMeta": {
|
|
68
69
|
"@deepseek-ai/dsh-spill": {
|
|
@@ -73,25 +74,26 @@
|
|
|
73
74
|
}
|
|
74
75
|
},
|
|
75
76
|
"devDependencies": {
|
|
76
|
-
"@deepseek-ai/cordis": "^4.0.
|
|
77
|
-
"@deepseek-ai/cordis-plugin-include": "^1.0.
|
|
78
|
-
"@deepseek-ai/cordis-plugin-loader": "^1.0.
|
|
79
|
-
"@deepseek-ai/dsh-compaction": "^0.1.
|
|
80
|
-
"@deepseek-ai/dsh-
|
|
81
|
-
"@deepseek-ai/dsh-llm": "^0.1.
|
|
82
|
-
"@deepseek-ai/dsh-
|
|
83
|
-
"@deepseek-ai/dsh-
|
|
84
|
-
"@deepseek-ai/dsh-
|
|
85
|
-
"@deepseek-ai/dsh-session-projection": "^0.1.
|
|
86
|
-
"@deepseek-ai/dsh-session-projection
|
|
87
|
-
"@deepseek-ai/dsh-session-query": "^0.1.
|
|
88
|
-
"@deepseek-ai/dsh-session-query-sqlite": "^0.1.
|
|
89
|
-
"@deepseek-ai/dsh-session-title": "^0.1.
|
|
90
|
-
"@deepseek-ai/dsh-spill": "^0.1.
|
|
91
|
-
"@deepseek-ai/dsh-
|
|
92
|
-
"@deepseek-ai/dsh-
|
|
93
|
-
"@deepseek-ai/dsh-
|
|
94
|
-
"@deepseek-ai/dsh-
|
|
95
|
-
"@deepseek-ai/dsh-
|
|
77
|
+
"@deepseek-ai/cordis": "^4.0.3",
|
|
78
|
+
"@deepseek-ai/cordis-plugin-include": "^1.0.8",
|
|
79
|
+
"@deepseek-ai/cordis-plugin-loader": "^1.0.4",
|
|
80
|
+
"@deepseek-ai/dsh-compaction": "^0.1.7-alpha.1",
|
|
81
|
+
"@deepseek-ai/dsh-fs-local": "^0.1.7-alpha.1",
|
|
82
|
+
"@deepseek-ai/dsh-llm": "^0.1.7-alpha.1",
|
|
83
|
+
"@deepseek-ai/dsh-agent": "^0.1.7-alpha.1",
|
|
84
|
+
"@deepseek-ai/dsh-output-retention": "^0.1.7-alpha.1",
|
|
85
|
+
"@deepseek-ai/dsh-session": "^0.1.7-alpha.1",
|
|
86
|
+
"@deepseek-ai/dsh-session-projection-cache": "^0.1.7-alpha.1",
|
|
87
|
+
"@deepseek-ai/dsh-session-projection": "^0.1.7-alpha.1",
|
|
88
|
+
"@deepseek-ai/dsh-session-query": "^0.1.7-alpha.1",
|
|
89
|
+
"@deepseek-ai/dsh-session-query-sqlite": "^0.1.7-alpha.1",
|
|
90
|
+
"@deepseek-ai/dsh-session-title": "^0.1.7-alpha.1",
|
|
91
|
+
"@deepseek-ai/dsh-spill": "^0.1.7-alpha.1",
|
|
92
|
+
"@deepseek-ai/dsh-subagent": "^0.1.7-alpha.1",
|
|
93
|
+
"@deepseek-ai/dsh-spill-local": "^0.1.7-alpha.1",
|
|
94
|
+
"@deepseek-ai/dsh-system-prompt": "^0.1.7-alpha.1",
|
|
95
|
+
"@deepseek-ai/dsh-tool-fs": "^0.1.7-alpha.1",
|
|
96
|
+
"@deepseek-ai/dsh-tools": "^0.1.7-alpha.1",
|
|
97
|
+
"@deepseek-ai/dsh-typert-protocol": "^0.1.7-alpha.1"
|
|
96
98
|
}
|
|
97
99
|
}
|