@deepseek-ai/dsh-session-title 0.2.1-alpha.1 → 0.2.1-alpha.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.i18n.yaml CHANGED
@@ -24,8 +24,8 @@
24
24
  en: f72239b38a91783b
25
25
  zh: 07e22375c09906a6
26
26
  /deepseek-ai-dsh-session-title/use-this-package/adding-a-provider:
27
- en: 2e1e7b56a1f26478
28
- zh: 750800b2d9e73595
27
+ en: cda41e431e48f914
28
+ zh: c6347ef731b0036e
29
29
  /deepseek-ai-dsh-session-title/use-this-package/reading-titles:
30
30
  en: 34148c23c20ee6f4
31
31
  zh: b0d10677722f3f63
@@ -48,8 +48,8 @@
48
48
  en: 0fa22531683cc824
49
49
  zh: c6379873eb809e76
50
50
  /deepseek-ai-dsh-session-title/further-exploration:
51
- en: 8b405b3bb2abf7cd
52
- zh: 71e8a58bfae99a36
51
+ en: 80d2f64367af8bda
52
+ zh: cfdd94b628fc4d8d
53
53
  /deepseek-ai-dsh-session-title/model-experience:
54
54
  en: 215e7ba838619b7b
55
55
  zh: a311da3843709f90
package/README.md CHANGED
@@ -54,7 +54,7 @@ The generated [configuration catalog](../../../docs/config-catalog.md#deepseek-a
54
54
 
55
55
  ### Adding a provider
56
56
 
57
- One optional asynchronous provider may be registered through `ctx.sessionTitle.register(provider)`; a second registration throws. The shipped model-backed providers are [first-prompt](../session-title-first-prompt-llm/README.md) and [all-prompts](../session-title-all-prompts-llm/README.md), both using the shared [LLM generation policy](../session-title-llm/README.md). A provider starts only after a marked loop-built request's exact route matches the logged `request/header`, and a newer revision supersedes and aborts older work.
57
+ One optional asynchronous provider may be registered through `ctx.sessionTitle.register(provider)`; a second registration throws until the first provider's disposal starts, so a replacement can activate while the previous provider drains, and the previous provider's late results never commit. The shipped model-backed providers are [first-prompt](../session-title-first-prompt-llm/README.md) and [all-prompts](../../experimental/session-title-all-prompts-llm/README.md), both using the shared [LLM execution module](../session-title-llm/README.md). Immediately before each call the service captures the latest accepted title snapshot, including the fallback it just ensured, and passes it as `request.currentTitle`; the provider owns whether and how to use it. A provider starts only after a marked loop-built request's exact route matches the logged `request/header`, and a newer revision supersedes and aborts older work. For unchanged routes, an active marked request starts pending automatic generation without a new header event; accepted human messages may follow the current `step/start`.
58
58
 
59
59
  ### Reading titles
60
60
 
@@ -104,9 +104,9 @@ Accepted titles are cleaned of terminal control sequences, directional and invis
104
104
  Read these pages when the service contract is not enough. They move from the subsystem reference to the model-backed providers that plug in here.
105
105
 
106
106
  - [Session title subsystem](../../../docs/subsystems/session-title.md) — durable title state and the provider vocabulary types.
107
- - [Shared LLM title policy](../session-title-llm/README.md) — the model-backed generation helper both shipped providers use.
107
+ - [Shared LLM execution module](../session-title-llm/README.md) — the model-backed execution module both shipped providers use.
108
108
  - [First-message title provider](../session-title-first-prompt-llm/README.md) — titles from the first eligible human message.
109
- - [All-messages title provider](../session-title-all-prompts-llm/README.md) — titles from every eligible human message.
109
+ - [All-messages title provider](../../experimental/session-title-all-prompts-llm/README.md) — titles from every eligible human message.
110
110
  - [Session package map](../README.md) — adjacent persistence, projection, title, and telemetry packages.
111
111
 
112
112
  -----
package/README.zh.md CHANGED
@@ -54,7 +54,7 @@ kind: "package-reference"
54
54
 
55
55
  ### 添加提供方
56
56
 
57
- 可选异步提供方可通过 `ctx.sessionTitle.register(provider)` 注册一个;第二次注册会立即抛出。随附的模型支持提供方是[首消息](../session-title-first-prompt-llm/README.zh.md)与[全消息](../session-title-all-prompts-llm/README.zh.md),两者都使用共享的 [LLM(大语言模型)生成策略](../session-title-llm/README.zh.md)。提供方只有在带标记、由循环构建的请求的确切路由与已记录 `request/header` 匹配时才启动,较新的修订会取代并中止旧工作。
57
+ 可选异步提供方可通过 `ctx.sessionTitle.register(provider)` 注册一个;在前一个提供方开始释放之前,第二次注册会立即抛出。因此替代提供方可以在前一个提供方排空期间激活,前一个提供方迟到的结果不会提交。随附的模型支持提供方是[首消息](../session-title-first-prompt-llm/README.zh.md)与[全消息](../../experimental/session-title-all-prompts-llm/README.zh.md),两者都使用共享的 [LLM(大语言模型)执行模块](../session-title-llm/README.zh.md)。每次调用前,服务会捕获最新已接纳标题快照(包括它刚刚确保的回退),并作为 `request.currentTitle` 传入;提供方自行决定是否以及如何使用。提供方只有在带标记、由循环构建的请求的确切路由与已记录 `request/header` 匹配时才启动,较新的修订会取代并中止旧工作。路由不变时,活跃步骤中带标记的请求会启动待处理的自动生成,无需新的 header 事件;已接受的人类消息可以位于当前 `step/start` 之后。
58
58
 
59
59
  ### 读取标题
60
60
 
@@ -104,9 +104,9 @@ kind: "package-reference"
104
104
  当服务约定不够用时阅读以下页面。它们从子系统参考逐步进入在此插拔的模型支持提供方。
105
105
 
106
106
  - [会话标题子系统](../../../docs/subsystems/session-title.zh.md)——持久标题状态与提供方词汇类型。
107
- - [共享 LLM 标题策略](../session-title-llm/README.zh.md)——两个随附提供方共用的模型生成辅助模块。
107
+ - [共享 LLM 执行模块](../session-title-llm/README.zh.md)——两个随附提供方共用的模型执行模块。
108
108
  - [首消息标题提供方](../session-title-first-prompt-llm/README.zh.md)——根据第一条符合条件的用户消息生成标题。
109
- - [全消息标题提供方](../session-title-all-prompts-llm/README.zh.md)——根据所有符合条件的用户消息生成标题。
109
+ - [全消息标题提供方](../../experimental/session-title-all-prompts-llm/README.zh.md)——根据所有符合条件的用户消息生成标题。
110
110
  - [会话包映射](../README.zh.md)——相邻的持久化、投影、标题与遥测包。
111
111
 
112
112
  -----
package/lib/index.js CHANGED
@@ -350,13 +350,14 @@ var SessionTitleService = class extends Service {
350
350
  }
351
351
  /**
352
352
  * Register the sole optional title provider. Disposal aborts its pending and
353
- * active work before another provider may register.
353
+ * active work; a replacement may register once disposal has started, and the
354
+ * closing provider's late results never commit.
354
355
  * @param provider - provider identity, cadence, and generation function.
355
356
  * @returns exact Cordis effect disposer, which settles after active calls quiesce.
356
357
  */
357
358
  register(provider) {
358
359
  this.validateProvider(provider);
359
- if (this.registration !== void 0) throw new Error(`session-title provider "${this.registration.provider.id}" is already registered`);
360
+ if (this.registration !== void 0 && !this.registration.closing) throw new Error(`session-title provider "${this.registration.provider.id}" is already registered`);
360
361
  const registration = {
361
362
  provider,
362
363
  active: /* @__PURE__ */ new Set(),
@@ -422,7 +423,7 @@ var SessionTitleService = class extends Service {
422
423
  if (session === void 0 || state === void 0 || pending === void 0) return;
423
424
  const boundary = this.ctx.sessionProjections.stateOf(session, "turnBoundary")?.lastStepBoundary;
424
425
  const route = session.requestHeader()?.config;
425
- if (boundary?.kind !== "start" || boundary.seq <= pending.throughSeq || route?.provider !== options.provider || route.model !== options.model) return;
426
+ if (boundary?.kind !== "start" || route?.provider !== options.provider || route.model !== options.model) return;
426
427
  this.startPending(session, state, pending, {
427
428
  provider: options.provider,
428
429
  model: options.model
@@ -453,11 +454,14 @@ var SessionTitleService = class extends Service {
453
454
  this.assertCurrent(session, work);
454
455
  await this.ensureFallback(session);
455
456
  this.assertCurrent(session, work);
456
- const messages = collectSessionTitleMessages(session.snapshotEvents(), work.throughSeq);
457
+ const events = session.snapshotEvents();
458
+ const messages = collectSessionTitleMessages(events, work.throughSeq);
459
+ const currentTitle = foldSessionTitle(events);
457
460
  const result = await work.registration.provider.generate({
458
461
  session,
459
462
  messages,
460
463
  ...route === void 0 ? {} : { route },
464
+ ...currentTitle === void 0 ? {} : { currentTitle },
461
465
  signal: work.signal
462
466
  });
463
467
  this.assertCurrent(session, work);
@@ -61,6 +61,12 @@ export interface SessionTitleProviderRequest {
61
61
  readonly messages: readonly SessionTitleUserMessage[];
62
62
  /** Exact current logged main-request route, when one has been recorded. */
63
63
  readonly route?: SessionTitleModelIdentity;
64
+ /**
65
+ * Latest accepted title captured at invocation, including an accepted
66
+ * fallback whose event may follow the last eligible message. Absent before
67
+ * any title is accepted. The provider decides whether and how to use it.
68
+ */
69
+ readonly currentTitle?: SessionTitleSnapshot;
64
70
  /** Cancellation for supersession, disposal, timeout composition, or the explicit caller. */
65
71
  readonly signal: AbortSignal;
66
72
  }
@@ -81,7 +87,7 @@ export interface SessionTitleProvider {
81
87
  readonly automatic: SessionTitleAutomaticMode;
82
88
  /**
83
89
  * Produce one title revision.
84
- * @param request - message snapshot, current route, session, and cancellation.
90
+ * @param request - message snapshot, current title, current route, session, and cancellation.
85
91
  * @returns proposed title plus exact input seqs and the optional provider/model route used to generate it.
86
92
  */
87
93
  generate(request: SessionTitleProviderRequest): Promise<SessionTitleProviderResult>;
@@ -143,7 +149,8 @@ export declare class SessionTitleService extends Service {
143
149
  refresh(session: Session, signal?: AbortSignal): Promise<SessionTitleSnapshot | undefined>;
144
150
  /**
145
151
  * Register the sole optional title provider. Disposal aborts its pending and
146
- * active work before another provider may register.
152
+ * active work; a replacement may register once disposal has started, and the
153
+ * closing provider's late results never commit.
147
154
  * @param provider - provider identity, cadence, and generation function.
148
155
  * @returns exact Cordis effect disposer, which settles after active calls quiesce.
149
156
  */
@@ -315,13 +315,14 @@ export class SessionTitleService extends Service {
315
315
  }
316
316
  /**
317
317
  * Register the sole optional title provider. Disposal aborts its pending and
318
- * active work before another provider may register.
318
+ * active work; a replacement may register once disposal has started, and the
319
+ * closing provider's late results never commit.
319
320
  * @param provider - provider identity, cadence, and generation function.
320
321
  * @returns exact Cordis effect disposer, which settles after active calls quiesce.
321
322
  */
322
323
  register(provider) {
323
324
  this.validateProvider(provider);
324
- if (this.registration !== undefined) {
325
+ if (this.registration !== undefined && !this.registration.closing) {
325
326
  throw new Error(`session-title provider "${this.registration.provider.id}" is already registered`);
326
327
  }
327
328
  const registration = {
@@ -404,7 +405,6 @@ export class SessionTitleService extends Service {
404
405
  const boundary = this.ctx.sessionProjections.stateOf(session, 'turnBoundary')?.lastStepBoundary;
405
406
  const route = session.requestHeader()?.config;
406
407
  if (boundary?.kind !== 'start'
407
- || boundary.seq <= pending.throughSeq
408
408
  || route?.provider !== options.provider
409
409
  || route.model !== options.model)
410
410
  return;
@@ -441,12 +441,17 @@ export class SessionTitleService extends Service {
441
441
  this.assertCurrent(session, work);
442
442
  await this.ensureFallback(session);
443
443
  this.assertCurrent(session, work);
444
+ // One snapshot supplies both inputs: messages stop at the scheduled
445
+ // watermark, while the current title is not bounded by that watermark.
444
446
  // oxlint-disable-next-line typescript/no-deprecated -- Existing Session history read; migration deferred.
445
- const messages = collectSessionTitleMessages(session.snapshotEvents(), work.throughSeq);
447
+ const events = session.snapshotEvents();
448
+ const messages = collectSessionTitleMessages(events, work.throughSeq);
449
+ const currentTitle = foldSessionTitle(events);
446
450
  const result = await work.registration.provider.generate({
447
451
  session,
448
452
  messages,
449
453
  ...route === undefined ? {} : { route },
454
+ ...currentTitle === undefined ? {} : { currentTitle },
450
455
  signal: work.signal,
451
456
  });
452
457
  this.assertCurrent(session, work);
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@deepseek-ai/dsh-session-title",
3
3
  "description": "Log-backed session title service and provider registry for the DeepSeek Harness",
4
- "version": "0.2.1-alpha.1",
4
+ "version": "0.2.1-alpha.2",
5
5
  "publishConfig": {
6
6
  "access": "public"
7
7
  },
@@ -37,25 +37,25 @@
37
37
  "license": "MIT",
38
38
  "peerDependencies": {
39
39
  "@deepseek-ai/cordis": "~4.0.5-alpha.1",
40
- "@deepseek-ai/dsh-agent": "0.2.1-alpha.1",
41
- "@deepseek-ai/dsh-brand": "0.2.1-alpha.1",
42
- "@deepseek-ai/dsh-llm": "0.2.1-alpha.1",
43
- "@deepseek-ai/dsh-session": "0.2.1-alpha.1",
44
- "@deepseek-ai/dsh-session-projection": "0.2.1-alpha.1"
40
+ "@deepseek-ai/dsh-agent": "0.2.1-alpha.2",
41
+ "@deepseek-ai/dsh-brand": "0.2.1-alpha.2",
42
+ "@deepseek-ai/dsh-llm": "0.2.1-alpha.2",
43
+ "@deepseek-ai/dsh-session": "0.2.1-alpha.2",
44
+ "@deepseek-ai/dsh-session-projection": "0.2.1-alpha.2"
45
45
  },
46
46
  "dependencies": {
47
- "zod": "^4.4.3",
48
- "@deepseek-ai/dsh-util-values": "0.2.1-alpha.1",
49
- "@deepseek-ai/schemastery": "~3.18.5-alpha.1"
47
+ "@deepseek-ai/dsh-util-values": "0.2.1-alpha.2",
48
+ "@deepseek-ai/schemastery": "~3.18.5-alpha.1",
49
+ "zod": "^4.4.3"
50
50
  },
51
51
  "devDependencies": {
52
52
  "@deepseek-ai/cordis": "~4.0.5-alpha.1",
53
- "@deepseek-ai/dsh-agent": "0.2.1-alpha.1",
54
- "@deepseek-ai/dsh-agent-loop": "0.2.1-alpha.1",
55
- "@deepseek-ai/dsh-brand": "0.2.1-alpha.1",
56
- "@deepseek-ai/dsh-session": "0.2.1-alpha.1",
57
- "@deepseek-ai/dsh-session-persistence-jsonl": "0.2.1-alpha.1",
58
- "@deepseek-ai/dsh-llm": "0.2.1-alpha.1",
59
- "@deepseek-ai/dsh-session-projection": "0.2.1-alpha.1"
53
+ "@deepseek-ai/dsh-agent": "0.2.1-alpha.2",
54
+ "@deepseek-ai/dsh-agent-loop": "0.2.1-alpha.2",
55
+ "@deepseek-ai/dsh-brand": "0.2.1-alpha.2",
56
+ "@deepseek-ai/dsh-llm": "0.2.1-alpha.2",
57
+ "@deepseek-ai/dsh-session": "0.2.1-alpha.2",
58
+ "@deepseek-ai/dsh-session-persistence-jsonl": "0.2.1-alpha.2",
59
+ "@deepseek-ai/dsh-session-projection": "0.2.1-alpha.2"
60
60
  }
61
61
  }