@deepseek-ai/dsh-session 0.0.1-rc.1 → 0.0.1-rc.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 +3 -2
- package/README.zh.md +3 -2
- package/lib/index.js +86 -23
- package/lib/types/index.d.ts +1 -7
- package/lib/types/index.js +4 -20
- package/lib/types/known-event-types.d.ts +19 -0
- package/lib/types/known-event-types.js +64 -0
- package/lib/types/types.d.ts +29 -2
- package/lib/types/types.js +17 -2
- package/package.json +12 -12
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/core/session/README.md
|
|
5
|
-
README.md:
|
|
6
|
-
README.zh.md:
|
|
5
|
+
README.md: 57569e9c0dbfa7cb696e3a561a9ff108c2ac981f
|
|
6
|
+
README.zh.md: 16629dc70c79ca838ba7088aeafcc5b38b124f87
|
package/README.md
CHANGED
|
@@ -76,10 +76,11 @@ Also defines `TurnEndReasonMap`, the merge-extensible `kind`-tagged sum type for
|
|
|
76
76
|
|
|
77
77
|
An interrupted live turn ends with `{ kind: 'aborted', reason: AgentCancelCause }`, preserving the typed cancellation cause in the durable transcript. Persistence imports the coarse aborted outcome from the supported older format as `{ kind: 'aborted', reason: { kind: 'legacy' } }`, because that record did not retain its caller. A turn failure carries `{ kind: 'error', error }`; crash recovery alone synthesizes `{ kind: 'interrupted' }`.
|
|
78
78
|
|
|
79
|
-
Every `SessionEvent` carries
|
|
79
|
+
Every `SessionEvent` carries three optional top-level fields (structural metadata):
|
|
80
80
|
|
|
81
81
|
- `sourceEventSeqs?: number[]` — seq numbers of earlier events cited as sources (e.g., the `assistant/chunk` seqs behind an `assistant/message`, or the shadowed entries behind a compaction replacement entry). On `assistant/message`, a present `[]` records a known empty provider stream, while omission means a legacy or foreign event did not record the source stream; other surface events require a non-empty list when this field is present.
|
|
82
82
|
- `surfaceOp?: SurfaceOp` — how this event entered the surface. Absent for non-surface events (boundaries, chunks, usage, errors).
|
|
83
|
+
- `ignorable?: true` — marks an event a reader may safely skip when it does not recognize the type; absent means required, so an unknown-type event refuses session reconstruction ([mechanism](../../../.agents/notes/implemented/architecture/2026-08-10-session-log-version-mechanism.md)).
|
|
83
84
|
|
|
84
85
|
### Metadata types (`types.ts`)
|
|
85
86
|
|
|
@@ -139,5 +140,5 @@ Logging causes no invalidation, and exact reconstruction preserves request-prefi
|
|
|
139
140
|
|
|
140
141
|
- **Session branching/tree** (pi-style entry tree) — deferred unless needed beyond boundary-based `fork()`.
|
|
141
142
|
- **`fork()` cuts only at stable boundaries of live sessions** — the selected prefix must end outside an open turn and the source must be in the store; forking a persisted-but-unloaded session is excluded from the [fork API](../../../.agents/notes/implemented/feature/2026-06-30-session-store-fork-api.md).
|
|
142
|
-
- **`SESSION_FORMAT_VERSION` stays pinned at `0`** — pre-release, no broad compatibility implied: `Session` accepts only current seed shapes and a backend
|
|
143
|
+
- **`SESSION_FORMAT_VERSION` stays pinned at `0`** — pre-release, no broad compatibility implied: `Session` accepts only current seed shapes, and a backend refuses any other version naming the direction (newer: "written by a newer harness — upgrade"; older: no upgrade path ships yet). Unknown event types refuse the same way unless marked `ignorable` in the envelope; the versioning mechanism is the [session-log-version-mechanism note](../../../.agents/notes/implemented/architecture/2026-08-10-session-log-version-mechanism.md). Narrow storage import upgrades belong to the persistence boundary ([policy](../../../AGENTS.md), [pre-identity message recovery](../../../.agents/notes/implemented/bug-fix/2026-07-28-load-pre-identity-session-messages.md)).
|
|
143
144
|
- **`TurnEndReasonMap` omits the ACP-named `refusal` / `max_turn_requests` variants** — producer-gated: they land when an adapter or the loop first emits them.
|
package/README.zh.md
CHANGED
|
@@ -76,10 +76,11 @@
|
|
|
76
76
|
|
|
77
77
|
被中断的实时轮次以 `{ kind: 'aborted', reason: AgentCancelCause }` 结束,在持久 transcript(文本记录)中保留类型化取消原因。持久化会将受支持旧格式中的粗粒度中止结果导入为 `{ kind: 'aborted', reason: { kind: 'legacy' } }`,因为该记录没有保留调用方。轮次失败携带 `{ kind: 'error', error }`;只有崩溃恢复会合成 `{ kind: 'interrupted' }`。
|
|
78
78
|
|
|
79
|
-
每个 `SessionEvent`
|
|
79
|
+
每个 `SessionEvent` 都有三个可选顶层字段(结构元数据):
|
|
80
80
|
|
|
81
81
|
- `sourceEventSeqs?: number[]`:被引用为来源的较早事件 seq(例如 `assistant/message` 引用的 `assistant/chunk` seq,或压缩替换条目引用的已遮蔽条目)。对于 `assistant/message`,存在的 `[]` 表示已知提供方流为空;省略则表示旧版或外部事件没有记录源流。其他 surface 事件若有此字段,则要求非空列表。
|
|
82
82
|
- `surfaceOp?: SurfaceOp`:事件进入 surface 的方式。非 surface 事件(边界、分片、用量、错误)不含该字段。
|
|
83
|
+
- `ignorable?: true`:标记读取器在不认识事件类型时可以安全跳过该事件;缺失表示必需,不认识的事件类型会使会话重建被拒绝([机制](../../../.agents/notes/implemented/architecture/2026-08-10-session-log-version-mechanism.md))。
|
|
83
84
|
|
|
84
85
|
### 元数据类型(`types.ts`)
|
|
85
86
|
|
|
@@ -139,5 +140,5 @@
|
|
|
139
140
|
|
|
140
141
|
- **会话分支/树**(pi 风格条目树):除非需要超越基于边界的 `fork()` 能力,否则暂缓。
|
|
141
142
|
- **`fork()` 仅在实时会话的稳定边界处切分**:所选前缀结束时不得有开放轮次,且源会话必须位于存储中;[fork API](../../../.agents/notes/implemented/feature/2026-06-30-session-store-fork-api.md) 不支持对已持久化但未加载的会话进行 fork。
|
|
142
|
-
- **`SESSION_FORMAT_VERSION` 固定为 `0`**:预发布阶段不承诺广泛兼容性;`Session` 只接受当前 seed
|
|
143
|
+
- **`SESSION_FORMAT_VERSION` 固定为 `0`**:预发布阶段不承诺广泛兼容性;`Session` 只接受当前 seed 形状,后端拒绝其他任何版本并说明方向(更新的版本提示"由更新的 harness 写入,请升级";更旧的版本说明尚无升级路径)。不认识的事件类型同样被拒绝,除非信封带 `ignorable` 标记;版本机制见 [session-log 版本机制 Agent Note](../../../.agents/notes/implemented/architecture/2026-08-10-session-log-version-mechanism.md)。范围受限的存储导入升级应由持久化边界负责([政策](../../../AGENTS.md)、[消息标识机制引入前的消息恢复](../../../.agents/notes/implemented/bug-fix/2026-07-28-load-pre-identity-session-messages.md))。
|
|
143
144
|
- **`TurnEndReasonMap` 不含 ACP(Agent Client Protocol)命名的 `refusal`/`max_turn_requests` 变体**:受生产方约束;只有当适配器或循环首次产生这些变体时才加入。
|
package/lib/index.js
CHANGED
|
@@ -16,8 +16,23 @@ function SessionId(id) {
|
|
|
16
16
|
* and enforced by every persistence backend on load. The single source of truth for the
|
|
17
17
|
* version — write sites and the load-time check all read it.
|
|
18
18
|
* While the harness is unreleased it is pinned at `0`: no compatibility is
|
|
19
|
-
* implied, incompatible logs are rejected, and no migration is provided.
|
|
20
|
-
*
|
|
19
|
+
* implied, incompatible logs are rejected, and no migration is provided.
|
|
20
|
+
*
|
|
21
|
+
* The version is a single monotonic integer with no major/minor split. Whether
|
|
22
|
+
* a bump is needed is decided by what the WRITER emits, never by what a newer
|
|
23
|
+
* reader can accept: bump exactly when an older runtime could no longer handle
|
|
24
|
+
* a new log with full semantic correctness ("parses without error" is not
|
|
25
|
+
* correctness — silently skipping content that shapes reconstruction is a
|
|
26
|
+
* wrong read). Only structural changes reach that bar: the header shape, the
|
|
27
|
+
* {@link SessionEvent} envelope, core event semantics, or the surface
|
|
28
|
+
* mechanism (the {@link SurfaceEventType} set and {@link SurfaceOp} variants).
|
|
29
|
+
* Adding an ordinary event type does not bump — the per-event
|
|
30
|
+
* {@link SessionEvent.ignorable} guard covers vocabulary growth instead. When
|
|
31
|
+
* in doubt, bump: a near-identity upgrade step is almost free, a missed bump
|
|
32
|
+
* makes older runtimes read new logs wrong silently. The full mechanism
|
|
33
|
+
* (upgrade-step chain, in-memory view conversion, migrate-on-continue) is
|
|
34
|
+
* recorded in the session-log-version-mechanism Agent Note
|
|
35
|
+
* (`.agents/notes/implemented/architecture/2026-08-10-session-log-version-mechanism.md`).
|
|
21
36
|
*/
|
|
22
37
|
const SESSION_FORMAT_VERSION = 0;
|
|
23
38
|
//#endregion
|
|
@@ -1036,6 +1051,71 @@ function decodeStorageRecord(value) {
|
|
|
1036
1051
|
return expandRow(validateRow(value, tag));
|
|
1037
1052
|
}
|
|
1038
1053
|
//#endregion
|
|
1054
|
+
//#region lib/types/known-event-types.js
|
|
1055
|
+
/**
|
|
1056
|
+
* GENERATED by `scripts/gen-persistence-catalog.ts` — do not edit by hand; run
|
|
1057
|
+
* `pnpm run gen-persistence-catalog` to regenerate (verified fresh by
|
|
1058
|
+
* `pnpm run verify-persistence-catalog`, part of `doc-sync`).
|
|
1059
|
+
* @module @deepseek-ai/dsh-session/known-event-types
|
|
1060
|
+
*/
|
|
1061
|
+
/**
|
|
1062
|
+
* Every `SessionEventMap` member declared in this repository — the event
|
|
1063
|
+
* vocabulary this build understands. The persistence read path refuses to
|
|
1064
|
+
* interpret a log containing a type outside this set unless the event
|
|
1065
|
+
* carries the envelope's `ignorable` marker (see `SessionEvent.ignorable`
|
|
1066
|
+
* in `./types.ts`): such a log was likely written by a newer harness, and
|
|
1067
|
+
* silently skipping a required event would reconstruct a wrong session.
|
|
1068
|
+
* Downstream (out-of-repo) plugin events are outside this list by
|
|
1069
|
+
* construction; a registration surface for them is deferred until such a
|
|
1070
|
+
* consumer exists.
|
|
1071
|
+
*/
|
|
1072
|
+
const KNOWN_SESSION_EVENT_TYPES = new Set([
|
|
1073
|
+
"agent-preset/selected",
|
|
1074
|
+
"agent/inbox/spliced",
|
|
1075
|
+
"approval/asked",
|
|
1076
|
+
"approval/decided",
|
|
1077
|
+
"approval/policy",
|
|
1078
|
+
"assistant/chunk",
|
|
1079
|
+
"assistant/message",
|
|
1080
|
+
"command/done",
|
|
1081
|
+
"command/run",
|
|
1082
|
+
"compact/end",
|
|
1083
|
+
"compact/prune",
|
|
1084
|
+
"compact/start",
|
|
1085
|
+
"compact/summary",
|
|
1086
|
+
"feedback/record",
|
|
1087
|
+
"goal/change",
|
|
1088
|
+
"hook/invoked",
|
|
1089
|
+
"hook/result",
|
|
1090
|
+
"llm/retry",
|
|
1091
|
+
"llm/retry-started",
|
|
1092
|
+
"permission/preset",
|
|
1093
|
+
"plan/mode",
|
|
1094
|
+
"request/context",
|
|
1095
|
+
"request/header",
|
|
1096
|
+
"sandbox/mode",
|
|
1097
|
+
"schedule/change",
|
|
1098
|
+
"session/end-seed",
|
|
1099
|
+
"session/title",
|
|
1100
|
+
"session/title-llm-request",
|
|
1101
|
+
"step/end",
|
|
1102
|
+
"step/start",
|
|
1103
|
+
"subagent/descriptor",
|
|
1104
|
+
"todo/write",
|
|
1105
|
+
"tool-workflow/agent-end",
|
|
1106
|
+
"tool-workflow/agent-start",
|
|
1107
|
+
"tool-workflow/run-end",
|
|
1108
|
+
"tool-workflow/run-start",
|
|
1109
|
+
"tool/call",
|
|
1110
|
+
"tool/code-dispatch",
|
|
1111
|
+
"tool/code-dispatch-start",
|
|
1112
|
+
"tool/result",
|
|
1113
|
+
"turn/end",
|
|
1114
|
+
"turn/start",
|
|
1115
|
+
"user/message",
|
|
1116
|
+
"web/deepseek-search-llm-request"
|
|
1117
|
+
]);
|
|
1118
|
+
//#endregion
|
|
1039
1119
|
//#region lib/types/index.js
|
|
1040
1120
|
/**
|
|
1041
1121
|
* Event-sourced session service: append-only session log, in-memory store, and
|
|
@@ -1044,24 +1124,6 @@ function decodeStorageRecord(value) {
|
|
|
1044
1124
|
*
|
|
1045
1125
|
* @module @deepseek-ai/dsh-session
|
|
1046
1126
|
*/
|
|
1047
|
-
/**
|
|
1048
|
-
* Find the latest closed turn that entered at least one model step, ignoring
|
|
1049
|
-
* balanced no-step turns produced by rejection, empty input, or cancellation.
|
|
1050
|
-
* @param events - session events, or an owned suffix, to inspect.
|
|
1051
|
-
* @returns the latest matching turn end, or `undefined`.
|
|
1052
|
-
*/
|
|
1053
|
-
function findLastMessageTurnEnd(events) {
|
|
1054
|
-
const steppedTurns = /* @__PURE__ */ new Set();
|
|
1055
|
-
let latest;
|
|
1056
|
-
for (const event of events) {
|
|
1057
|
-
if (event.type === "step/start") {
|
|
1058
|
-
steppedTurns.add(event.data.turn);
|
|
1059
|
-
continue;
|
|
1060
|
-
}
|
|
1061
|
-
if (event.type === "turn/end" && steppedTurns.delete(event.data.turn)) latest = event;
|
|
1062
|
-
}
|
|
1063
|
-
return latest;
|
|
1064
|
-
}
|
|
1065
1127
|
/** Validate and freeze one detached creation header in place. */
|
|
1066
1128
|
function validateSessionHeader(id, input) {
|
|
1067
1129
|
if (input === null || typeof input !== "object" || Array.isArray(input)) throw new Error("session header is not a plain JSON record");
|
|
@@ -1151,13 +1213,14 @@ function assertSessionEventEnvelope(value, index) {
|
|
|
1151
1213
|
case "time":
|
|
1152
1214
|
case "data":
|
|
1153
1215
|
case "surfaceOp":
|
|
1154
|
-
case "sourceEventSeqs":
|
|
1216
|
+
case "sourceEventSeqs":
|
|
1217
|
+
case "ignorable": break;
|
|
1155
1218
|
default: throw new Error(`seed event at index ${index} has an invalid event envelope`);
|
|
1156
1219
|
}
|
|
1157
1220
|
const type = event["type"];
|
|
1158
1221
|
const seq = event["seq"];
|
|
1159
1222
|
const time = event["time"];
|
|
1160
|
-
if (typeof type !== "string" || typeof seq !== "number" || !Number.isSafeInteger(seq) || seq < 0 || typeof time !== "number" || !Number.isSafeInteger(time) || event["data"] === void 0) throw new Error(`seed event at index ${index} has an invalid event envelope`);
|
|
1223
|
+
if (typeof type !== "string" || typeof seq !== "number" || !Number.isSafeInteger(seq) || seq < 0 || typeof time !== "number" || !Number.isSafeInteger(time) || event["data"] === void 0 || event["ignorable"] !== void 0 && event["ignorable"] !== true) throw new Error(`seed event at index ${index} has an invalid event envelope`);
|
|
1161
1224
|
switch (type) {
|
|
1162
1225
|
case "request/header":
|
|
1163
1226
|
case "user/message":
|
|
@@ -1838,4 +1901,4 @@ var SessionStore = class extends Service {
|
|
|
1838
1901
|
}
|
|
1839
1902
|
};
|
|
1840
1903
|
//#endregion
|
|
1841
|
-
export { SESSION_FORMAT_VERSION, Session, SessionForkError, SessionId, SessionPreparation, SessionStore, SessionStore as default, TOOL_NOT_STARTED, TOOL_OUTCOME_UNKNOWN, adoptSessionEvent, canonicalHeader, decodeStorageRecord, deriveEventMessage,
|
|
1904
|
+
export { KNOWN_SESSION_EVENT_TYPES, SESSION_FORMAT_VERSION, Session, SessionForkError, SessionId, SessionPreparation, SessionStore, SessionStore as default, TOOL_NOT_STARTED, TOOL_OUTCOME_UNKNOWN, adoptSessionEvent, canonicalHeader, decodeStorageRecord, deriveEventMessage, foldRequestHeader, foldSurface, headerEquals, interruptedTurnClosers, isAppendSurfaceEvent, isJsonValue, isReplacementSurfaceEvent, isSurfaceEligibleType, isSurfaceEvent, lastActivityTime, packChunkRuns, snapshotJsonValue, snapshotSessionEvent };
|
package/lib/types/index.d.ts
CHANGED
|
@@ -24,13 +24,7 @@ export type { ChunkRow, StorageRecord } from './chunk-rows.ts';
|
|
|
24
24
|
export type { SessionSurface, SurfaceFoldReplacement, SurfaceFoldResult } from './surface.ts';
|
|
25
25
|
export { deriveEventMessage, foldSurface, isAppendSurfaceEvent, isReplacementSurfaceEvent, isSurfaceEvent, isSurfaceEligibleType } from './surface.ts';
|
|
26
26
|
export { canonicalHeader, foldRequestHeader, headerEquals } from './request-header.ts';
|
|
27
|
-
|
|
28
|
-
* Find the latest closed turn that entered at least one model step, ignoring
|
|
29
|
-
* balanced no-step turns produced by rejection, empty input, or cancellation.
|
|
30
|
-
* @param events - session events, or an owned suffix, to inspect.
|
|
31
|
-
* @returns the latest matching turn end, or `undefined`.
|
|
32
|
-
*/
|
|
33
|
-
export declare function findLastMessageTurnEnd(events: readonly SessionEvent[]): SessionEvent<'turn/end'> | undefined;
|
|
27
|
+
export { KNOWN_SESSION_EVENT_TYPES } from './known-event-types.ts';
|
|
34
28
|
declare module '@deepseek-ai/cordis' {
|
|
35
29
|
interface Context {
|
|
36
30
|
sessions: SessionStore;
|
package/lib/types/index.js
CHANGED
|
@@ -20,25 +20,7 @@ export { interruptedTurnClosers, lastActivityTime, TOOL_NOT_STARTED, TOOL_OUTCOM
|
|
|
20
20
|
export { decodeStorageRecord, packChunkRuns } from "./chunk-rows.js";
|
|
21
21
|
export { deriveEventMessage, foldSurface, isAppendSurfaceEvent, isReplacementSurfaceEvent, isSurfaceEvent, isSurfaceEligibleType } from "./surface.js";
|
|
22
22
|
export { canonicalHeader, foldRequestHeader, headerEquals } from "./request-header.js";
|
|
23
|
-
|
|
24
|
-
* Find the latest closed turn that entered at least one model step, ignoring
|
|
25
|
-
* balanced no-step turns produced by rejection, empty input, or cancellation.
|
|
26
|
-
* @param events - session events, or an owned suffix, to inspect.
|
|
27
|
-
* @returns the latest matching turn end, or `undefined`.
|
|
28
|
-
*/
|
|
29
|
-
export function findLastMessageTurnEnd(events) {
|
|
30
|
-
const steppedTurns = new Set();
|
|
31
|
-
let latest;
|
|
32
|
-
for (const event of events) {
|
|
33
|
-
if (event.type === 'step/start') {
|
|
34
|
-
steppedTurns.add(event.data.turn);
|
|
35
|
-
continue;
|
|
36
|
-
}
|
|
37
|
-
if (event.type === 'turn/end' && steppedTurns.delete(event.data.turn))
|
|
38
|
-
latest = event;
|
|
39
|
-
}
|
|
40
|
-
return latest;
|
|
41
|
-
}
|
|
23
|
+
export { KNOWN_SESSION_EVENT_TYPES } from "./known-event-types.js";
|
|
42
24
|
/** Validate and freeze one detached creation header in place. */
|
|
43
25
|
function validateSessionHeader(id, input) {
|
|
44
26
|
if (input === null || typeof input !== 'object' || Array.isArray(input)) {
|
|
@@ -164,6 +146,7 @@ function assertSessionEventEnvelope(value, index) {
|
|
|
164
146
|
case 'data':
|
|
165
147
|
case 'surfaceOp':
|
|
166
148
|
case 'sourceEventSeqs':
|
|
149
|
+
case 'ignorable':
|
|
167
150
|
break;
|
|
168
151
|
default:
|
|
169
152
|
throw new Error(`seed event at index ${index} has an invalid event envelope`);
|
|
@@ -175,7 +158,8 @@ function assertSessionEventEnvelope(value, index) {
|
|
|
175
158
|
if (typeof type !== 'string'
|
|
176
159
|
|| typeof seq !== 'number' || !Number.isSafeInteger(seq) || seq < 0
|
|
177
160
|
|| typeof time !== 'number' || !Number.isSafeInteger(time)
|
|
178
|
-
|| event['data'] === undefined
|
|
161
|
+
|| event['data'] === undefined
|
|
162
|
+
|| (event['ignorable'] !== undefined && event['ignorable'] !== true)) {
|
|
179
163
|
throw new Error(`seed event at index ${index} has an invalid event envelope`);
|
|
180
164
|
}
|
|
181
165
|
switch (type) {
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GENERATED by `scripts/gen-persistence-catalog.ts` — do not edit by hand; run
|
|
3
|
+
* `pnpm run gen-persistence-catalog` to regenerate (verified fresh by
|
|
4
|
+
* `pnpm run verify-persistence-catalog`, part of `doc-sync`).
|
|
5
|
+
* @module @deepseek-ai/dsh-session/known-event-types
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Every `SessionEventMap` member declared in this repository — the event
|
|
9
|
+
* vocabulary this build understands. The persistence read path refuses to
|
|
10
|
+
* interpret a log containing a type outside this set unless the event
|
|
11
|
+
* carries the envelope's `ignorable` marker (see `SessionEvent.ignorable`
|
|
12
|
+
* in `./types.ts`): such a log was likely written by a newer harness, and
|
|
13
|
+
* silently skipping a required event would reconstruct a wrong session.
|
|
14
|
+
* Downstream (out-of-repo) plugin events are outside this list by
|
|
15
|
+
* construction; a registration surface for them is deferred until such a
|
|
16
|
+
* consumer exists.
|
|
17
|
+
*/
|
|
18
|
+
export declare const KNOWN_SESSION_EVENT_TYPES: ReadonlySet<string>;
|
|
19
|
+
//# sourceMappingURL=known-event-types.d.ts.map
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GENERATED by `scripts/gen-persistence-catalog.ts` — do not edit by hand; run
|
|
3
|
+
* `pnpm run gen-persistence-catalog` to regenerate (verified fresh by
|
|
4
|
+
* `pnpm run verify-persistence-catalog`, part of `doc-sync`).
|
|
5
|
+
* @module @deepseek-ai/dsh-session/known-event-types
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Every `SessionEventMap` member declared in this repository — the event
|
|
9
|
+
* vocabulary this build understands. The persistence read path refuses to
|
|
10
|
+
* interpret a log containing a type outside this set unless the event
|
|
11
|
+
* carries the envelope's `ignorable` marker (see `SessionEvent.ignorable`
|
|
12
|
+
* in `./types.ts`): such a log was likely written by a newer harness, and
|
|
13
|
+
* silently skipping a required event would reconstruct a wrong session.
|
|
14
|
+
* Downstream (out-of-repo) plugin events are outside this list by
|
|
15
|
+
* construction; a registration surface for them is deferred until such a
|
|
16
|
+
* consumer exists.
|
|
17
|
+
*/
|
|
18
|
+
export const KNOWN_SESSION_EVENT_TYPES = new Set([
|
|
19
|
+
'agent-preset/selected',
|
|
20
|
+
'agent/inbox/spliced',
|
|
21
|
+
'approval/asked',
|
|
22
|
+
'approval/decided',
|
|
23
|
+
'approval/policy',
|
|
24
|
+
'assistant/chunk',
|
|
25
|
+
'assistant/message',
|
|
26
|
+
'command/done',
|
|
27
|
+
'command/run',
|
|
28
|
+
'compact/end',
|
|
29
|
+
'compact/prune',
|
|
30
|
+
'compact/start',
|
|
31
|
+
'compact/summary',
|
|
32
|
+
'feedback/record',
|
|
33
|
+
'goal/change',
|
|
34
|
+
'hook/invoked',
|
|
35
|
+
'hook/result',
|
|
36
|
+
'llm/retry',
|
|
37
|
+
'llm/retry-started',
|
|
38
|
+
'permission/preset',
|
|
39
|
+
'plan/mode',
|
|
40
|
+
'request/context',
|
|
41
|
+
'request/header',
|
|
42
|
+
'sandbox/mode',
|
|
43
|
+
'schedule/change',
|
|
44
|
+
'session/end-seed',
|
|
45
|
+
'session/title',
|
|
46
|
+
'session/title-llm-request',
|
|
47
|
+
'step/end',
|
|
48
|
+
'step/start',
|
|
49
|
+
'subagent/descriptor',
|
|
50
|
+
'todo/write',
|
|
51
|
+
'tool-workflow/agent-end',
|
|
52
|
+
'tool-workflow/agent-start',
|
|
53
|
+
'tool-workflow/run-end',
|
|
54
|
+
'tool-workflow/run-start',
|
|
55
|
+
'tool/call',
|
|
56
|
+
'tool/code-dispatch',
|
|
57
|
+
'tool/code-dispatch-start',
|
|
58
|
+
'tool/result',
|
|
59
|
+
'turn/end',
|
|
60
|
+
'turn/start',
|
|
61
|
+
'user/message',
|
|
62
|
+
'web/deepseek-search-llm-request',
|
|
63
|
+
]);
|
|
64
|
+
//# sourceMappingURL=known-event-types.js.map
|
package/lib/types/types.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { Branded } from '@deepseek-ai/dsh-brand';
|
|
2
2
|
import type { AssistantMessage, CallId, LlmCallConfig, LlmCallConfigAdapterDefaults, LlmFailure, StreamChunk, TokenUsage, ToolResultMessage, ToolSchema, UserMessage } from '@deepseek-ai/dsh-llm';
|
|
3
3
|
import type { JsonValue } from './json.ts';
|
|
4
|
+
export type { JsonValue } from './json.ts';
|
|
4
5
|
/** Identifies one session in the store (and its persistence artifacts). */
|
|
5
6
|
export type SessionId = Branded<'SessionId'>;
|
|
6
7
|
/**
|
|
@@ -14,8 +15,23 @@ export declare function SessionId(id: string): SessionId;
|
|
|
14
15
|
* and enforced by every persistence backend on load. The single source of truth for the
|
|
15
16
|
* version — write sites and the load-time check all read it.
|
|
16
17
|
* While the harness is unreleased it is pinned at `0`: no compatibility is
|
|
17
|
-
* implied, incompatible logs are rejected, and no migration is provided.
|
|
18
|
-
*
|
|
18
|
+
* implied, incompatible logs are rejected, and no migration is provided.
|
|
19
|
+
*
|
|
20
|
+
* The version is a single monotonic integer with no major/minor split. Whether
|
|
21
|
+
* a bump is needed is decided by what the WRITER emits, never by what a newer
|
|
22
|
+
* reader can accept: bump exactly when an older runtime could no longer handle
|
|
23
|
+
* a new log with full semantic correctness ("parses without error" is not
|
|
24
|
+
* correctness — silently skipping content that shapes reconstruction is a
|
|
25
|
+
* wrong read). Only structural changes reach that bar: the header shape, the
|
|
26
|
+
* {@link SessionEvent} envelope, core event semantics, or the surface
|
|
27
|
+
* mechanism (the {@link SurfaceEventType} set and {@link SurfaceOp} variants).
|
|
28
|
+
* Adding an ordinary event type does not bump — the per-event
|
|
29
|
+
* {@link SessionEvent.ignorable} guard covers vocabulary growth instead. When
|
|
30
|
+
* in doubt, bump: a near-identity upgrade step is almost free, a missed bump
|
|
31
|
+
* makes older runtimes read new logs wrong silently. The full mechanism
|
|
32
|
+
* (upgrade-step chain, in-memory view conversion, migrate-on-continue) is
|
|
33
|
+
* recorded in the session-log-version-mechanism Agent Note
|
|
34
|
+
* (`.agents/notes/implemented/architecture/2026-08-10-session-log-version-mechanism.md`).
|
|
19
35
|
*/
|
|
20
36
|
export declare const SESSION_FORMAT_VERSION = 0;
|
|
21
37
|
/**
|
|
@@ -409,6 +425,17 @@ export type SessionEvent<T extends SessionEventType = SessionEventType> = {
|
|
|
409
425
|
/** Unix epoch milliseconds. */
|
|
410
426
|
time: number;
|
|
411
427
|
data: SessionEventMap[K];
|
|
428
|
+
/**
|
|
429
|
+
* Marks an event a reader may safely skip when it does not recognize
|
|
430
|
+
* `type`. Absent means required: a reader meeting an unrecognized type
|
|
431
|
+
* without this marker MUST refuse to reconstruct the session instead of
|
|
432
|
+
* silently dropping the event, because an unrecognized required event may
|
|
433
|
+
* change how the rest of the log is interpreted. A writer sets `true` only
|
|
434
|
+
* on purely informational records whose loss cannot affect reconstruction;
|
|
435
|
+
* defaulting to required means a forgotten marker over-refuses (an
|
|
436
|
+
* inconvenience) rather than silently resuming a gutted session.
|
|
437
|
+
*/
|
|
438
|
+
ignorable?: true;
|
|
412
439
|
} & (K extends SurfaceEventType ? {
|
|
413
440
|
/**
|
|
414
441
|
* Seq numbers of earlier events that this event cites as sources
|
package/lib/types/types.js
CHANGED
|
@@ -11,8 +11,23 @@ export function SessionId(id) {
|
|
|
11
11
|
* and enforced by every persistence backend on load. The single source of truth for the
|
|
12
12
|
* version — write sites and the load-time check all read it.
|
|
13
13
|
* While the harness is unreleased it is pinned at `0`: no compatibility is
|
|
14
|
-
* implied, incompatible logs are rejected, and no migration is provided.
|
|
15
|
-
*
|
|
14
|
+
* implied, incompatible logs are rejected, and no migration is provided.
|
|
15
|
+
*
|
|
16
|
+
* The version is a single monotonic integer with no major/minor split. Whether
|
|
17
|
+
* a bump is needed is decided by what the WRITER emits, never by what a newer
|
|
18
|
+
* reader can accept: bump exactly when an older runtime could no longer handle
|
|
19
|
+
* a new log with full semantic correctness ("parses without error" is not
|
|
20
|
+
* correctness — silently skipping content that shapes reconstruction is a
|
|
21
|
+
* wrong read). Only structural changes reach that bar: the header shape, the
|
|
22
|
+
* {@link SessionEvent} envelope, core event semantics, or the surface
|
|
23
|
+
* mechanism (the {@link SurfaceEventType} set and {@link SurfaceOp} variants).
|
|
24
|
+
* Adding an ordinary event type does not bump — the per-event
|
|
25
|
+
* {@link SessionEvent.ignorable} guard covers vocabulary growth instead. When
|
|
26
|
+
* in doubt, bump: a near-identity upgrade step is almost free, a missed bump
|
|
27
|
+
* makes older runtimes read new logs wrong silently. The full mechanism
|
|
28
|
+
* (upgrade-step chain, in-memory view conversion, migrate-on-continue) is
|
|
29
|
+
* recorded in the session-log-version-mechanism Agent Note
|
|
30
|
+
* (`.agents/notes/implemented/architecture/2026-08-10-session-log-version-mechanism.md`).
|
|
16
31
|
*/
|
|
17
32
|
export const SESSION_FORMAT_VERSION = 0;
|
|
18
33
|
//# sourceMappingURL=types.js.map
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@deepseek-ai/dsh-session",
|
|
3
3
|
"description": "Event-sourced session store for the DeepSeek Harness",
|
|
4
|
-
"version": "0.0.1-rc.
|
|
4
|
+
"version": "0.0.1-rc.2",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "restricted"
|
|
7
7
|
},
|
|
@@ -41,20 +41,20 @@
|
|
|
41
41
|
],
|
|
42
42
|
"license": "BSD-3-Clause",
|
|
43
43
|
"peerDependencies": {
|
|
44
|
-
"@deepseek-ai/dsh-brand": "^0.0.1-rc.
|
|
45
|
-
"@deepseek-ai/dsh-
|
|
46
|
-
"@deepseek-ai/dsh-
|
|
47
|
-
"@deepseek-ai/dsh-scope": "^0.0.1-rc.
|
|
48
|
-
"@deepseek-ai/dsh-type-meta": "^0.0.1-rc.
|
|
44
|
+
"@deepseek-ai/dsh-brand": "^0.0.1-rc.2",
|
|
45
|
+
"@deepseek-ai/dsh-invariants": "^0.0.1-rc.2",
|
|
46
|
+
"@deepseek-ai/dsh-llm": "^0.0.1-rc.2",
|
|
47
|
+
"@deepseek-ai/dsh-scope": "^0.0.1-rc.2",
|
|
48
|
+
"@deepseek-ai/dsh-type-meta": "^0.0.1-rc.2",
|
|
49
49
|
"@deepseek-ai/cordis": "^4.0.1-rc.1"
|
|
50
50
|
},
|
|
51
51
|
"devDependencies": {
|
|
52
|
-
"@deepseek-ai/dsh-brand": "^0.0.1-rc.
|
|
53
|
-
"@deepseek-ai/dsh-invariants": "^0.0.1-rc.
|
|
54
|
-
"@deepseek-ai/dsh-llm": "^0.0.1-rc.
|
|
55
|
-
"@deepseek-ai/dsh-
|
|
56
|
-
"@deepseek-ai/dsh-
|
|
57
|
-
"@deepseek-ai/dsh-
|
|
52
|
+
"@deepseek-ai/dsh-brand": "^0.0.1-rc.2",
|
|
53
|
+
"@deepseek-ai/dsh-invariants": "^0.0.1-rc.2",
|
|
54
|
+
"@deepseek-ai/dsh-llm": "^0.0.1-rc.2",
|
|
55
|
+
"@deepseek-ai/dsh-scope": "^0.0.1-rc.2",
|
|
56
|
+
"@deepseek-ai/dsh-type-meta": "^0.0.1-rc.2",
|
|
57
|
+
"@deepseek-ai/dsh-typert-registry": "^0.0.1-rc.2",
|
|
58
58
|
"@deepseek-ai/cordis": "^4.0.1-rc.1"
|
|
59
59
|
}
|
|
60
60
|
}
|