@deepseek-ai/dsh-session-persistence-jsonl 0.1.7-alpha.2 → 0.1.7-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 CHANGED
@@ -1,6 +1,70 @@
1
- # Bilingual-pair consistency record (docs/i18n/README.md): the git blob hash of each
2
- # side as of the last confirmed-consistent state. Both languages carry equal authority;
3
- # after editing either side, bring the other along and re-record with:
1
+ # Bilingual-pair consistency record for README.md (docs/i18n/README.md): per heading
2
+ # section, a hash of its English and Chinese blocks outside code blocks and generated regions.
3
+ # After editing either side, bring the other along and re-record with:
4
4
  # pnpm run verify-translation-pairing --write packages/session/session-persistence-jsonl/README.md
5
- README.md: 5846404961caaef7a91fb4dda562655d15fd2be9
6
- README.zh.md: b7dd646e57b75fe47f3683d2b230dace628f8eee
5
+ /:
6
+ en: cc97ed79d262bf09
7
+ zh: 90a141669dc844f3
8
+ /deepseek-ai-dsh-session-persistence-jsonl:
9
+ en: 719697c849e36229
10
+ zh: 466ab1b89c10020c
11
+ /deepseek-ai-dsh-session-persistence-jsonl/summary:
12
+ en: 4821bd83813408c7
13
+ zh: 2e5c721a19f549e7
14
+ /deepseek-ai-dsh-session-persistence-jsonl/table-of-contents:
15
+ en: d152484eb41ac6b4
16
+ zh: 09388d293f9be9cb
17
+ /deepseek-ai-dsh-session-persistence-jsonl/use-this-package:
18
+ en: d6112142a705ec43
19
+ zh: f0914d9e37216f97
20
+ /deepseek-ai-dsh-session-persistence-jsonl/use-this-package/when-to-choose-it:
21
+ en: 37c10302bbbde268
22
+ zh: 3d5c027bac868efd
23
+ /deepseek-ai-dsh-session-persistence-jsonl/use-this-package/minimal-configuration:
24
+ en: 22e8c3b2da45edff
25
+ zh: d9effd892b514520
26
+ /deepseek-ai-dsh-session-persistence-jsonl/use-this-package/on-disk-layout:
27
+ en: e20cf32540d7c785
28
+ zh: 67e182529e9211ca
29
+ /deepseek-ai-dsh-session-persistence-jsonl/use-this-package/durability-and-crash-semantics:
30
+ en: 1eaa87736cac029b
31
+ zh: 26224e8889786d69
32
+ /deepseek-ai-dsh-session-persistence-jsonl/use-this-package/reading-the-logs:
33
+ en: c06983c4a73bebe1
34
+ zh: 7319f8f44223685f
35
+ /deepseek-ai-dsh-session-persistence-jsonl/understand-the-implementation:
36
+ en: a35407bb25671e7e
37
+ zh: 6a00f9510c85adcb
38
+ /deepseek-ai-dsh-session-persistence-jsonl/understand-the-implementation/design-concept:
39
+ en: b69d4565a11b6f02
40
+ zh: c8309690fc931f8d
41
+ /deepseek-ai-dsh-session-persistence-jsonl/understand-the-implementation/physical-encoding:
42
+ en: 011d56563b81acd9
43
+ zh: 69122dbade603fe9
44
+ /deepseek-ai-dsh-session-persistence-jsonl/understand-the-implementation/source-map:
45
+ en: 3bdb0f1dd4d69fba
46
+ zh: 8198d655d73d42e3
47
+ /deepseek-ai-dsh-session-persistence-jsonl/further-exploration:
48
+ en: 827c04be7cd01514
49
+ zh: 5e87603b3463db38
50
+ /deepseek-ai-dsh-session-persistence-jsonl/model-experience:
51
+ en: 215e7ba838619b7b
52
+ zh: a311da3843709f90
53
+ /deepseek-ai-dsh-session-persistence-jsonl/model-experience/resumed-conversation-history:
54
+ en: 062875aab7f3f138
55
+ zh: c7285918227e6f5c
56
+ /deepseek-ai-dsh-session-persistence-jsonl/model-experience/resumed-conversation-history/what-the-model-sees:
57
+ en: 2a3b5c6e3860eef6
58
+ zh: 82afe0f0359581b6
59
+ /deepseek-ai-dsh-session-persistence-jsonl/model-experience/resumed-conversation-history/token-effect:
60
+ en: 8fb2f7cdba1ff320
61
+ zh: e130ec2a92a53a5c
62
+ /deepseek-ai-dsh-session-persistence-jsonl/model-experience/resumed-conversation-history/kv-cache-effect:
63
+ en: 53ce4da7ce68d21c
64
+ zh: 10f40bc354100f77
65
+ /deepseek-ai-dsh-session-persistence-jsonl/known-limitations-and-deferred-work:
66
+ en: e6343e8ad3f6fb71
67
+ zh: fe632c9711e7921b
68
+ /deepseek-ai-dsh-session-persistence-jsonl/known-limitations-and-deferred-work/dev-note:
69
+ en: e67f633dc6fe7773
70
+ zh: 3bb0c20c93f16f98
package/lib/worker.cjs CHANGED
@@ -4136,6 +4136,89 @@ function projectImagesForTextModel(messages) {
4136
4136
  };
4137
4137
  });
4138
4138
  }
4139
+ function withoutDeveloperMessages(messages) {
4140
+ const retained = messages.filter((message) => message.role !== "developer");
4141
+ return retained.length === messages.length ? messages : retained;
4142
+ }
4143
+ function toolDeclarations(tools, mode, history) {
4144
+ const declarations = new Map(history.tools.map((tool) => [tool.name, tool]));
4145
+ for (const update of history.updates) for (const tool of update.additions) if (!declarations.has(tool.name)) declarations.set(tool.name, {
4146
+ ...tool,
4147
+ deferLoading: true
4148
+ });
4149
+ switch (mode) {
4150
+ case "in-history": return declarations;
4151
+ case "addition-only": {
4152
+ const activeNames = new Set(tools?.map((tool) => tool.name));
4153
+ for (const name of declarations.keys()) if (!activeNames.has(name)) declarations.delete(name);
4154
+ return declarations;
4155
+ }
4156
+ /* v8 ignore next 2 -- closed-union exhaustiveness guard */
4157
+ default: return assertNever(mode);
4158
+ }
4159
+ }
4160
+ /**
4161
+ * Construct provider declarations from session-folded history without changing logged active tools.
4162
+ * Unsupported routes and incomplete history use current declarations without developer updates.
4163
+ * Explicitly deferred baseline tools become available only after their first retained addition.
4164
+ * @param messages - complete request inputs, or the prefix selected for an auxiliary call.
4165
+ * @param tools - currently active tool schemas.
4166
+ * @param toolUpdate - the resolved route's update mode.
4167
+ * @param history - immutable state folded from committed headers and developer messages.
4168
+ * @returns provider declarations and the corresponding filtered history.
4169
+ */
4170
+ function projectToolUpdates(messages, tools, toolUpdate, history) {
4171
+ if (toolUpdate === void 0) {
4172
+ let immediateTools = tools;
4173
+ if (tools?.some((tool) => tool.deferLoading === true)) immediateTools = tools.map(({ deferLoading: _loading, ...tool }) => tool);
4174
+ return {
4175
+ messages: withoutDeveloperMessages(messages),
4176
+ tools: immediateTools
4177
+ };
4178
+ }
4179
+ if (history === void 0) return {
4180
+ messages: withoutDeveloperMessages(messages),
4181
+ tools
4182
+ };
4183
+ const messageIds = new Set(messages.flatMap((message) => message.role === "developer" ? [message.id] : []));
4184
+ if (history.updates.some((update) => !messageIds.has(update.messageId))) return {
4185
+ messages: withoutDeveloperMessages(messages),
4186
+ tools
4187
+ };
4188
+ const declarations = toolDeclarations(tools, toolUpdate, history);
4189
+ const updateIds = new Set(history.updates.map((update) => update.messageId));
4190
+ const offered = new Set(history.tools.filter((tool) => !tool.deferLoading).map((tool) => tool.name));
4191
+ const projectedMessages = [];
4192
+ for (const message of messages) {
4193
+ if (message.role !== "developer") {
4194
+ projectedMessages.push(message);
4195
+ continue;
4196
+ }
4197
+ if (!updateIds.has(message.id)) continue;
4198
+ const content = message.content.filter((block) => {
4199
+ switch (block.type) {
4200
+ case "tool-addition":
4201
+ if (!declarations.has(block.toolName) || offered.has(block.toolName)) return false;
4202
+ offered.add(block.toolName);
4203
+ return true;
4204
+ case "tool-removal":
4205
+ if (toolUpdate !== "in-history") return false;
4206
+ return offered.delete(block.toolName);
4207
+ default: return true;
4208
+ }
4209
+ });
4210
+ if (content.length === 0) continue;
4211
+ if (content.length === message.content.length) projectedMessages.push(message);
4212
+ else projectedMessages.push({
4213
+ ...message,
4214
+ content
4215
+ });
4216
+ }
4217
+ return {
4218
+ messages: projectedMessages.length === messages.length && projectedMessages.every((message, index) => message === messages[index]) ? messages : projectedMessages,
4219
+ tools: [...declarations.values()]
4220
+ };
4221
+ }
4139
4222
  //#endregion
4140
4223
  //#region ../../llm/llm/src/attribution.ts
4141
4224
  /**
@@ -4995,7 +5078,8 @@ var LlmError = class extends HarnessError {
4995
5078
  }
4996
5079
  /**
4997
5080
  * Discover models advertised by one registered provider. Catalog membership
4998
- * is advisory and never changes routing or request validation.
5081
+ * does not constrain core routing. Catalog-driven entry points may restrict
5082
+ * selection and submission to the advertised models.
4999
5083
  * @param provider - registered provider route to inspect.
5000
5084
  * @returns detached model metadata in adapter-preferred order.
5001
5085
  */
@@ -5040,6 +5124,8 @@ var LlmError = class extends HarnessError {
5040
5124
  const inputModalities = this.detachedModalities(resolved.inputModalities);
5041
5125
  const systemPromptUpdate = resolved.systemPromptUpdate;
5042
5126
  if (systemPromptUpdate !== void 0 && systemPromptUpdate !== "in-history") throw new LlmError(`adapter returned invalid system prompt update mode for provider "${provider}" model "${model}"`, "INVALID_MODEL_INFO");
5127
+ const toolUpdate = resolved.toolUpdate;
5128
+ if (toolUpdate !== void 0 && toolUpdate !== "in-history" && toolUpdate !== "addition-only") throw new LlmError(`adapter returned invalid tool update mode for provider "${provider}" model "${model}"`, "INVALID_MODEL_INFO");
5043
5129
  const defaultMaxTokens = resolved.defaultMaxTokens;
5044
5130
  if (defaultMaxTokens !== void 0 && (!Number.isSafeInteger(defaultMaxTokens) || defaultMaxTokens <= 0)) throw new LlmError(`adapter returned invalid default maxTokens for provider "${provider}" model "${model}"`, "INVALID_MODEL_MAX_TOKENS");
5045
5131
  const info = {
@@ -5050,7 +5136,8 @@ var LlmError = class extends HarnessError {
5050
5136
  ...inputModalities === void 0 ? {} : { inputModalities },
5051
5137
  ...context === void 0 ? {} : { context: { contextWindow: context.contextWindow } },
5052
5138
  ...defaultMaxTokens === void 0 ? {} : { defaultMaxTokens },
5053
- ...resolved.systemPromptUpdate === void 0 ? {} : { systemPromptUpdate: resolved.systemPromptUpdate }
5139
+ ...resolved.systemPromptUpdate === void 0 ? {} : { systemPromptUpdate: resolved.systemPromptUpdate },
5140
+ ...resolved.toolUpdate === void 0 ? {} : { toolUpdate: resolved.toolUpdate }
5054
5141
  };
5055
5142
  const reasoning = resolved.reasoning;
5056
5143
  if (reasoning === void 0) return info;
@@ -5145,6 +5232,7 @@ var LlmError = class extends HarnessError {
5145
5232
  ...context === void 0 ? {} : { context },
5146
5233
  ...modelInfo.inputModalities === void 0 ? {} : { inputModalities: Object.freeze([...modelInfo.inputModalities]) },
5147
5234
  ...modelInfo.systemPromptUpdate === void 0 ? {} : { systemPromptUpdate: modelInfo.systemPromptUpdate },
5235
+ ...modelInfo.toolUpdate === void 0 ? {} : { toolUpdate: modelInfo.toolUpdate },
5148
5236
  stream: (options) => {
5149
5237
  if (dispatched) throw new LlmError("a prepared LLM call can only be dispatched once", "INVALID_PREPARED_CALL");
5150
5238
  if (!callConfigEquals(options, resolvedConfig)) throw new LlmError("prepared LLM call config changed before adapter dispatch", "INVALID_PREPARED_CALL");
@@ -5234,13 +5322,17 @@ var LlmError = class extends HarnessError {
5234
5322
  let projectedMessages = resolvedOptions.messages;
5235
5323
  if (projectedMessages.some((message) => contentHasFile(message.content))) projectedMessages = projectFilesToText(projectedMessages, (ref) => this.fileReadPath(ref));
5236
5324
  if (modelInfo.inputModalities !== void 0 && !modelInfo.inputModalities.includes("image") && projectedMessages.some((message) => contentHasImage(message.content))) projectedMessages = projectImagesForTextModel(projectedMessages);
5237
- const projectedOptions = projectedMessages === resolvedOptions.messages ? resolvedOptions : Object.isFrozen(resolvedOptions) ? deepFreeze({
5238
- ...resolvedOptions,
5239
- messages: projectedMessages
5240
- }) : {
5241
- ...resolvedOptions,
5242
- messages: projectedMessages
5243
- };
5325
+ const projectedTools = projectToolUpdates(projectedMessages, resolvedOptions.tools, modelInfo.toolUpdate, resolvedOptions.toolHistory);
5326
+ projectedMessages = projectedTools.messages;
5327
+ let projectedOptions = resolvedOptions;
5328
+ if (projectedMessages !== resolvedOptions.messages || projectedTools.tools !== resolvedOptions.tools) {
5329
+ projectedOptions = {
5330
+ ...resolvedOptions,
5331
+ messages: projectedMessages,
5332
+ ...projectedTools.tools === void 0 ? {} : { tools: projectedTools.tools }
5333
+ };
5334
+ if (Object.isFrozen(resolvedOptions)) deepFreeze(projectedOptions);
5335
+ }
5244
5336
  iterator = dispatch(this.forAdapter(projectedOptions, adapter))[Symbol.asyncIterator]();
5245
5337
  } catch (error) {
5246
5338
  yield adapterFailureChunk(error, options.signal);
@@ -5339,6 +5431,80 @@ function foldRequestHeader(events, from) {
5339
5431
  return state;
5340
5432
  }
5341
5433
  //#endregion
5434
+ //#region ../../core/session/src/tool-history.ts
5435
+ /** Folds committed headers and developer messages independently of model capability. */
5436
+ var ToolHistoryProjection = class {
5437
+ /** Historical declarations indexed by the header sequence referenced by additions. */
5438
+ headers = /* @__PURE__ */ new Map();
5439
+ /** Definitions retained in the current declaration series, including removed tools. */
5440
+ declared = /* @__PURE__ */ new Map();
5441
+ /** Active definitions from the latest request header. */
5442
+ active = [];
5443
+ /** Active names reconstructed from the baseline and recorded updates. */
5444
+ available = /* @__PURE__ */ new Set();
5445
+ /** Header that starts the current declaration series; absent before the first header. */
5446
+ baselineSeq;
5447
+ /** Immutable request snapshot of the current baseline and resolved updates. */
5448
+ history = deepFreeze({
5449
+ tools: [],
5450
+ updates: []
5451
+ });
5452
+ /**
5453
+ * Consume the next committed event in log order.
5454
+ * @param event - a session event, including inherited events during restoration.
5455
+ */
5456
+ apply(event) {
5457
+ if (event.type === "request/header") {
5458
+ const tools = event.data.header.tools ?? [];
5459
+ this.headers.set(event.seq, tools);
5460
+ const redeclared = tools.some((tool) => {
5461
+ const before = this.declared.get(tool.name);
5462
+ return before !== void 0 && JSON.stringify(before) !== JSON.stringify(tool);
5463
+ });
5464
+ if (this.baselineSeq === void 0 || event.data.reason === "series" || event.data.startsSeries || redeclared) {
5465
+ this.baselineSeq = event.seq;
5466
+ this.declared = new Map(tools.map((tool) => [tool.name, tool]));
5467
+ this.history = deepFreeze({
5468
+ tools,
5469
+ updates: []
5470
+ });
5471
+ this.available = new Set(tools.map((tool) => tool.name));
5472
+ }
5473
+ this.active = tools;
5474
+ } else if (event.type === "developer/message") {
5475
+ const { message, headerSeq } = event.data;
5476
+ const definitions = headerSeq === void 0 ? [] : this.headers.get(headerSeq);
5477
+ const additions = message.content.flatMap((block) => {
5478
+ if (block.type !== "tool-addition") return [];
5479
+ const tool = definitions?.find((tool) => tool.name === block.toolName);
5480
+ if (tool === void 0) throw new Error(`tool history: missing definition for ${block.toolName}`);
5481
+ return [tool];
5482
+ });
5483
+ for (const tool of additions) this.declared.set(tool.name, tool);
5484
+ for (const block of message.content) if (block.type === "tool-addition") this.available.add(block.toolName);
5485
+ else if (block.type === "tool-removal") this.available.delete(block.toolName);
5486
+ this.history = deepFreeze({
5487
+ tools: this.history.tools,
5488
+ updates: [...this.history.updates, {
5489
+ messageId: message.id,
5490
+ additions
5491
+ }]
5492
+ });
5493
+ }
5494
+ }
5495
+ /**
5496
+ * Read an immutable snapshot; subsequent events do not mutate it.
5497
+ * @returns initial declarations and historically resolved additions for the current series.
5498
+ */
5499
+ snapshot() {
5500
+ if (this.active.length !== this.available.size || this.active.some((tool) => !this.available.has(tool.name))) return deepFreeze({
5501
+ tools: this.active,
5502
+ updates: []
5503
+ });
5504
+ return this.history;
5505
+ }
5506
+ };
5507
+ //#endregion
5342
5508
  //#region ../../core/session/src/index.ts
5343
5509
  /** Validate and freeze one detached creation header in place. */
5344
5510
  function validateSessionHeader(id, input) {
@@ -5812,6 +5978,20 @@ var Session = class Session {
5812
5978
  }
5813
5979
  return this.contextFold;
5814
5980
  }
5981
+ /** Cached historical tool definitions and updates for request projection. */
5982
+ toolHistoryProjection = new ToolHistoryProjection();
5983
+ /** Index of the next committed event not yet consumed by the tool-history fold. */
5984
+ toolHistorySeq = 0;
5985
+ /**
5986
+ * Fold unseen committed events into capability-independent tool history.
5987
+ * Initial access reconstructs inherited history; later reads consume only new events.
5988
+ * @returns an immutable snapshot for LLM request projection, including historical addition definitions.
5989
+ */
5990
+ toolHistory() {
5991
+ for (const event of this.log.slice(this.toolHistorySeq)) this.toolHistoryProjection.apply(event);
5992
+ this.toolHistorySeq = this.log.length;
5993
+ return this.toolHistoryProjection.snapshot();
5994
+ }
5815
5995
  /** The derived-message cache: frozen projections, extended per unseen node. */
5816
5996
  derived = [];
5817
5997
  /** Surface position (nodes projected) the cache has reached. */
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@deepseek-ai/dsh-session-persistence-jsonl",
3
3
  "description": "JSONL durable session persistence backend for the DeepSeek Harness",
4
- "version": "0.1.7-alpha.2",
4
+ "version": "0.1.7-rc.2",
5
5
  "publishConfig": {
6
6
  "access": "public"
7
7
  },
@@ -28,23 +28,23 @@
28
28
  ],
29
29
  "license": "MIT",
30
30
  "peerDependencies": {
31
- "@deepseek-ai/dsh-session": "0.1.7-alpha.2",
32
- "@deepseek-ai/dsh-session-persistence": "0.1.7-alpha.2",
31
+ "@deepseek-ai/dsh-session": "0.1.7-rc.2",
32
+ "@deepseek-ai/dsh-session-persistence": "0.1.7-rc.2",
33
33
  "@deepseek-ai/cordis": "~4.0.4"
34
34
  },
35
35
  "dependencies": {
36
36
  "koffi": "^3.1.0",
37
- "@deepseek-ai/dsh-session-format": "0.1.7-alpha.2",
38
- "@deepseek-ai/dsh-session-format-catalog": "0.1.7-alpha.2",
39
- "@deepseek-ai/dsh-session-format-v3-to-v4": "0.1.7-alpha.2",
37
+ "@deepseek-ai/dsh-session-format": "0.1.7-rc.2",
38
+ "@deepseek-ai/dsh-session-format-catalog": "0.1.7-rc.2",
39
+ "@deepseek-ai/dsh-session-format-v3-to-v4": "0.1.7-rc.2",
40
40
  "@deepseek-ai/node-addon-system": "~0.1.2",
41
41
  "@deepseek-ai/schemastery": "~3.18.4",
42
- "@deepseek-ai/dsh-llm": "0.1.7-alpha.2"
42
+ "@deepseek-ai/dsh-llm": "0.1.7-rc.2"
43
43
  },
44
44
  "devDependencies": {
45
- "@deepseek-ai/dsh-session": "0.1.7-alpha.2",
46
- "@deepseek-ai/dsh-session-persistence": "0.1.7-alpha.2",
45
+ "@deepseek-ai/dsh-session": "0.1.7-rc.2",
46
+ "@deepseek-ai/dsh-session-format-v0-to-v1": "0.1.7-rc.2",
47
47
  "@deepseek-ai/cordis": "~4.0.4",
48
- "@deepseek-ai/dsh-session-format-v0-to-v1": "0.1.7-alpha.2"
48
+ "@deepseek-ai/dsh-session-persistence": "0.1.7-rc.2"
49
49
  }
50
50
  }