@gatherthread/dsh-host 0.1.0-beta.1 → 0.1.0-beta.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.
@@ -1050,9 +1050,9 @@ function floatSafeRemainder(val, step) {
1050
1050
  return ratio - roundedRatio;
1051
1051
  }
1052
1052
  var EVALUATING = /* @__PURE__ */ Symbol("evaluating");
1053
- function defineLazy(object2, key, getter) {
1053
+ function defineLazy(object3, key, getter) {
1054
1054
  let value = void 0;
1055
- Object.defineProperty(object2, key, {
1055
+ Object.defineProperty(object3, key, {
1056
1056
  get() {
1057
1057
  if (value === EVALUATING) {
1058
1058
  return void 0;
@@ -1064,7 +1064,7 @@ function defineLazy(object2, key, getter) {
1064
1064
  return value;
1065
1065
  },
1066
1066
  set(v) {
1067
- Object.defineProperty(object2, key, {
1067
+ Object.defineProperty(object3, key, {
1068
1068
  value: v
1069
1069
  // configurable: true,
1070
1070
  });
@@ -16131,8 +16131,8 @@ function foldObjects(members2) {
16131
16131
  }
16132
16132
  const properties = {};
16133
16133
  const required2 = /* @__PURE__ */ new Set();
16134
- for (const object2 of objects) {
16135
- for (const key in object2.properties) {
16134
+ for (const object3 of objects) {
16135
+ for (const key in object3.properties) {
16136
16136
  if (Object.prototype.hasOwnProperty.call(properties, key))
16137
16137
  continue;
16138
16138
  const parts = [];
@@ -16146,18 +16146,18 @@ function foldObjects(members2) {
16146
16146
  const merged = parts.length === 1 ? parts[0] : foldObjects(parts) ?? { allOf: parts };
16147
16147
  assignProp(properties, key, merged);
16148
16148
  }
16149
- for (const key of object2.required ?? [])
16149
+ for (const key of object3.required ?? [])
16150
16150
  required2.add(key);
16151
16151
  }
16152
16152
  const folded = { type: "object", properties };
16153
16153
  if (required2.size)
16154
16154
  folded.required = [...required2];
16155
- if (objects.every((object2) => object2.additionalProperties === false)) {
16155
+ if (objects.every((object3) => object3.additionalProperties === false)) {
16156
16156
  folded.additionalProperties = false;
16157
16157
  } else {
16158
16158
  const constraints = [];
16159
- for (const object2 of objects) {
16160
- const constraint = undeclaredConstraint(object2);
16159
+ for (const object3 of objects) {
16160
+ const constraint = undeclaredConstraint(object3);
16161
16161
  if (constraint && !constraints.some((seen) => JSON.stringify(seen) === JSON.stringify(constraint)))
16162
16162
  constraints.push(constraint);
16163
16163
  }
@@ -19996,6 +19996,28 @@ function date4(params) {
19996
19996
  return _coercedDate(ZodDate, params);
19997
19997
  }
19998
19998
 
19999
+ // ../protocol/dist/src/live-output.js
20000
+ var utf8 = (maximum) => external_exports.string().refine((value) => new TextEncoder().encode(value).length <= maximum, "Live output is too large");
20001
+ var LiveOutputPayloadSchema = external_exports.object({
20002
+ content: utf8(24 * 1024),
20003
+ phase: external_exports.literal("stream"),
20004
+ stream_id: external_exports.string().uuid(),
20005
+ stream_mode: external_exports.literal("snapshot"),
20006
+ stream_kind: external_exports.enum(["answer", "reasoning", "tool", "plan"]),
20007
+ stream_revision: external_exports.number().int().min(1).max(1200),
20008
+ stream_state: external_exports.enum(["running", "completed", "failed"]),
20009
+ title: utf8(256).optional(),
20010
+ plan: external_exports.array(external_exports.object({ step: utf8(512), status: external_exports.enum(["pending", "in_progress", "completed"]) }).strict()).max(64).optional(),
20011
+ status: external_exports.enum(["thinking", "running"]).optional(),
20012
+ occurred_at: external_exports.string().datetime().optional(),
20013
+ capture_fidelity: external_exports.literal("harness_transcript").optional(),
20014
+ source_harness: external_exports.string().min(1).max(80).optional()
20015
+ }).strict().superRefine((value, context) => {
20016
+ if (value.stream_kind === "plan" !== (value.plan !== void 0)) {
20017
+ context.addIssue({ code: "custom", message: "Only plan snapshots carry plan steps" });
20018
+ }
20019
+ });
20020
+
19999
20021
  // ../protocol/dist/src/code-sync.js
20000
20022
  var CODE_SYNC_MAX_FILES = 1e3;
20001
20023
  var CODE_SYNC_MAX_FILE_BYTES = 2 * 1024 * 1024;
@@ -20170,6 +20192,118 @@ var githubCodeSyncRequestKinds = [
20170
20192
  "github_code_update"
20171
20193
  ];
20172
20194
 
20195
+ // ../protocol/dist/src/registration.js
20196
+ var RegistrationEmailSchema = external_exports.string().max(254).trim().toLowerCase().regex(/^[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@[a-z0-9](?:[a-z0-9-]*[a-z0-9])?(?:\.[a-z0-9](?:[a-z0-9-]*[a-z0-9])?)+$/).refine((value) => value.split("@")[0].length <= 64 && value.split("@")[1].split(".").every((part) => part.length <= 63));
20197
+ var Label = external_exports.string().regex(/^[^\u0000-\u001f\u007f-\u009f]*$/u).trim().min(1).max(120);
20198
+ var SendRegistrationInputSchema = external_exports.object({
20199
+ email: RegistrationEmailSchema,
20200
+ challenge_token: external_exports.string().min(1).max(2048),
20201
+ idempotency_key: external_exports.string().uuid(),
20202
+ locale: external_exports.enum(["en", "zh-CN"])
20203
+ }).strict();
20204
+ var AccountPasswordSchema = external_exports.string().min(8).max(128).refine((value) => new TextEncoder().encode(value).byteLength <= 512);
20205
+ var EmailLoginInputSchema = external_exports.object({
20206
+ email: RegistrationEmailSchema,
20207
+ password: AccountPasswordSchema,
20208
+ device_name: Label,
20209
+ remember_device: external_exports.boolean().default(false)
20210
+ }).strict();
20211
+ var LauncherProjectId = external_exports.string().min(1).max(128).refine((value) => /^[A-Za-z0-9]/u.test(value) && !/[^A-Za-z0-9._:-]/u.test(value));
20212
+ var CreateCodexLauncherAuthorizationInputSchema = external_exports.object({
20213
+ project_id: LauncherProjectId,
20214
+ email: RegistrationEmailSchema
20215
+ }).strict();
20216
+ var ClaimCodexLauncherAuthorizationInputSchema = external_exports.object({
20217
+ authorization_id: external_exports.string().uuid().toLowerCase(),
20218
+ project_id: LauncherProjectId,
20219
+ email: RegistrationEmailSchema,
20220
+ password: AccountPasswordSchema,
20221
+ device_name: Label
20222
+ }).strict();
20223
+ var VerifyRegistrationInputSchema = external_exports.object({
20224
+ registration_id: external_exports.string().uuid(),
20225
+ code: external_exports.string().regex(/^\d{8}$/),
20226
+ display_name: Label,
20227
+ device_name: Label,
20228
+ remember_device: external_exports.boolean().default(false),
20229
+ privacy_acknowledged: external_exports.literal(true),
20230
+ password: AccountPasswordSchema
20231
+ }).strict();
20232
+ var RegistrationStatusSchema = external_exports.object({
20233
+ enabled: external_exports.boolean(),
20234
+ site_key: external_exports.string().nullable(),
20235
+ challenge_binding: external_exports.string().nullable()
20236
+ }).strict();
20237
+ var RegistrationSentSchema = external_exports.object({
20238
+ registration_id: external_exports.string().uuid(),
20239
+ expires_in_seconds: external_exports.literal(600),
20240
+ resend_after_seconds: external_exports.literal(60)
20241
+ }).strict();
20242
+ var PasswordResetSentSchema = external_exports.object({
20243
+ reset_id: external_exports.string().uuid(),
20244
+ expires_in_seconds: external_exports.literal(600),
20245
+ resend_after_seconds: external_exports.literal(60)
20246
+ }).strict();
20247
+ var VerifyPasswordResetInputSchema = external_exports.object({
20248
+ reset_id: external_exports.string().uuid(),
20249
+ email: RegistrationEmailSchema,
20250
+ code: external_exports.string().regex(/^\d{8}$/),
20251
+ password: AccountPasswordSchema,
20252
+ password_confirmation: AccountPasswordSchema,
20253
+ locale: external_exports.enum(["en", "zh-CN"])
20254
+ }).strict().refine((value) => value.password === value.password_confirmation);
20255
+ var EmailAccountSessionSchema = external_exports.object({
20256
+ actor: external_exports.object({ user_id: external_exports.string(), display_name: external_exports.string(), device_id: external_exports.string(), can_create_projects: external_exports.literal(true) }).strict(),
20257
+ expires_at: external_exports.string().datetime()
20258
+ }).strict();
20259
+
20260
+ // ../protocol/dist/src/cloud-api.js
20261
+ var CloudApiProviderIdSchema = external_exports.enum(["openai", "anthropic", "deepseek", "siliconflow-cn", "siliconflow-global", "openrouter", "qwen", "glm", "doubao"]);
20262
+ var CloudApiModelSchema = external_exports.string().trim().min(1).max(160).regex(/^[^\u0000-\u0020\u007f-\u009f]+$/u);
20263
+ var Label2 = external_exports.string().trim().min(1).max(80).regex(/^[^\u0000-\u001f\u007f-\u009f]+$/u);
20264
+ var CloudApiPutInputSchema = external_exports.object({
20265
+ expected_revision: external_exports.string().uuid().nullable(),
20266
+ provider_id: CloudApiProviderIdSchema,
20267
+ label: Label2,
20268
+ model: CloudApiModelSchema,
20269
+ enabled: external_exports.boolean(),
20270
+ api_key: external_exports.string().min(8).max(4096).regex(/^[\x21-\x7e]+$/u).optional()
20271
+ }).strict();
20272
+ var CloudApiDeleteInputSchema = external_exports.object({ expected_revision: external_exports.string().uuid() }).strict();
20273
+ var CloudApiConfigurationSchema = external_exports.object({
20274
+ id: external_exports.string().uuid(),
20275
+ revision: external_exports.string().uuid(),
20276
+ provider_id: CloudApiProviderIdSchema,
20277
+ profile_id: external_exports.string().regex(/^api-[0-9a-f-]{36}$/u),
20278
+ label: Label2,
20279
+ model: CloudApiModelSchema,
20280
+ enabled: external_exports.boolean(),
20281
+ has_key: external_exports.literal(true),
20282
+ updated_at: external_exports.string().datetime()
20283
+ }).strict();
20284
+ var CloudApiProviderSchema = external_exports.object({
20285
+ id: CloudApiProviderIdSchema,
20286
+ label: external_exports.string().max(80),
20287
+ transport: external_exports.enum(["openai-chat", "anthropic-messages"]),
20288
+ base_url: external_exports.string().url().max(200),
20289
+ docs_url: external_exports.string().url().max(300),
20290
+ default_model: CloudApiModelSchema.optional()
20291
+ }).strict();
20292
+ var CloudApiStatusSchema = external_exports.object({
20293
+ enabled: external_exports.boolean(),
20294
+ providers: external_exports.array(CloudApiProviderSchema).max(16),
20295
+ configurations: external_exports.array(CloudApiConfigurationSchema).max(8)
20296
+ }).strict();
20297
+ var CloudApiSavedSchema = external_exports.object({ configuration: CloudApiConfigurationSchema }).strict();
20298
+ var PersonalCloudRevisionSchema = external_exports.string().uuid().optional();
20299
+ function hasValidPersonalCloudRevision(value) {
20300
+ return value.profile_id.startsWith("api-") ? /^api-[0-9a-f-]{36}$/u.test(value.profile_id) && value.api_config_revision !== void 0 : value.api_config_revision === void 0;
20301
+ }
20302
+ var HostedAgentSelectionSchema = external_exports.object({
20303
+ profile_id: external_exports.string().min(1).max(64),
20304
+ api_config_revision: PersonalCloudRevisionSchema
20305
+ }).strict().refine(hasValidPersonalCloudRevision, "Personal Cloud Agent selection requires its exact revision");
20306
+
20173
20307
  // ../protocol/dist/src/history-summary.js
20174
20308
  var HISTORY_SUMMARY_MAX_SOURCE_BYTES = 20 * 1024;
20175
20309
  var HISTORY_SUMMARY_MAX_PROMPT_BYTES = 30 * 1024;
@@ -20185,7 +20319,7 @@ function record2(value) {
20185
20319
  return value !== null && typeof value === "object" && !Array.isArray(value) ? value : void 0;
20186
20320
  }
20187
20321
  function historySummaryMarker(event) {
20188
- if (event.type !== "agent_request")
20322
+ if (event.deleted || event.type !== "agent_request")
20189
20323
  return void 0;
20190
20324
  const marker = record2(record2(event.payload)?.history_summary);
20191
20325
  const ids = marker?.source_event_ids;
@@ -20215,8 +20349,10 @@ var HostedGithubTaskInputSchema = external_exports.object({
20215
20349
  profile_id: external_exports.string().regex(/^[a-zA-Z0-9][a-zA-Z0-9_-]{0,63}$/u),
20216
20350
  idempotency_key: Key2,
20217
20351
  continue_task_id: external_exports.string().regex(/^gh-task-[a-f0-9]{32}$/u).optional(),
20218
- reply_to_event_id: external_exports.string().min(1).max(128).nullable().optional()
20219
- }).strict();
20352
+ reply_to_event_id: external_exports.string().min(1).max(128).nullable().optional(),
20353
+ api_config_revision: PersonalCloudRevisionSchema,
20354
+ content_revision: external_exports.number().int().nonnegative().optional()
20355
+ }).strict().refine(hasValidPersonalCloudRevision, { message: "Personal cloud profiles require their exact configuration revision" });
20220
20356
  var HostedGithubCompleteInputSchema = external_exports.object({
20221
20357
  state: external_exports.string().regex(/^[A-Za-z0-9_-]{43}$/u),
20222
20358
  code: external_exports.string().min(1).max(500)
@@ -20264,7 +20400,8 @@ var HostedGithubTaskSummarySchema = external_exports.object({
20264
20400
  revision: Revision,
20265
20401
  error_code: external_exports.string().regex(/^[a-z][a-z0-9_]{0,63}$/u).nullable(),
20266
20402
  pull_request_url: PullUrl,
20267
- expires_at: external_exports.number().int().positive().max(Number.MAX_SAFE_INTEGER)
20403
+ expires_at: external_exports.number().int().positive().max(Number.MAX_SAFE_INTEGER),
20404
+ api_config_revision: external_exports.string().uuid().optional()
20268
20405
  }).strict();
20269
20406
  var bytes = (value) => value.length / 4 * 3 - (value.endsWith("==") ? 2 : value.endsWith("=") ? 1 : 0);
20270
20407
  var Source = external_exports.string().max(2796204).regex(/^[A-Za-z0-9+/]*={0,2}$/u).refine((value) => value.length % 4 === 0 && bytes(value) <= 2 * 1024 * 1024).nullable();
@@ -20290,59 +20427,6 @@ var HostedGithubTaskSchema = HostedGithubTaskSummarySchema.extend({
20290
20427
  });
20291
20428
  var HostedGithubTaskListSchema = external_exports.object({ tasks: external_exports.array(HostedGithubTaskSummarySchema).max(10) }).strict();
20292
20429
 
20293
- // ../protocol/dist/src/registration.js
20294
- var RegistrationEmailSchema = external_exports.string().max(254).trim().toLowerCase().regex(/^[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@[a-z0-9](?:[a-z0-9-]*[a-z0-9])?(?:\.[a-z0-9](?:[a-z0-9-]*[a-z0-9])?)+$/).refine((value) => value.split("@")[0].length <= 64 && value.split("@")[1].split(".").every((part) => part.length <= 63));
20295
- var Label = external_exports.string().regex(/^[^\u0000-\u001f\u007f-\u009f]*$/u).trim().min(1).max(120);
20296
- var SendRegistrationInputSchema = external_exports.object({
20297
- email: RegistrationEmailSchema,
20298
- challenge_token: external_exports.string().min(1).max(2048),
20299
- idempotency_key: external_exports.string().uuid(),
20300
- locale: external_exports.enum(["en", "zh-CN"])
20301
- }).strict();
20302
- var AccountPasswordSchema = external_exports.string().min(12).max(128).refine((value) => new TextEncoder().encode(value).byteLength <= 512);
20303
- var EmailLoginInputSchema = external_exports.object({
20304
- email: RegistrationEmailSchema,
20305
- password: AccountPasswordSchema,
20306
- device_name: Label,
20307
- remember_device: external_exports.boolean().default(false)
20308
- }).strict();
20309
- var VerifyRegistrationInputSchema = external_exports.object({
20310
- registration_id: external_exports.string().uuid(),
20311
- code: external_exports.string().regex(/^\d{8}$/),
20312
- display_name: Label,
20313
- device_name: Label,
20314
- remember_device: external_exports.boolean().default(false),
20315
- privacy_acknowledged: external_exports.literal(true),
20316
- password: AccountPasswordSchema
20317
- }).strict();
20318
- var RegistrationStatusSchema = external_exports.object({
20319
- enabled: external_exports.boolean(),
20320
- site_key: external_exports.string().nullable(),
20321
- challenge_binding: external_exports.string().nullable()
20322
- }).strict();
20323
- var RegistrationSentSchema = external_exports.object({
20324
- registration_id: external_exports.string().uuid(),
20325
- expires_in_seconds: external_exports.literal(600),
20326
- resend_after_seconds: external_exports.literal(60)
20327
- }).strict();
20328
- var PasswordResetSentSchema = external_exports.object({
20329
- reset_id: external_exports.string().uuid(),
20330
- expires_in_seconds: external_exports.literal(600),
20331
- resend_after_seconds: external_exports.literal(60)
20332
- }).strict();
20333
- var VerifyPasswordResetInputSchema = external_exports.object({
20334
- reset_id: external_exports.string().uuid(),
20335
- email: RegistrationEmailSchema,
20336
- code: external_exports.string().regex(/^\d{8}$/),
20337
- password: AccountPasswordSchema,
20338
- password_confirmation: AccountPasswordSchema,
20339
- locale: external_exports.enum(["en", "zh-CN"])
20340
- }).strict().refine((value) => value.password === value.password_confirmation);
20341
- var EmailAccountSessionSchema = external_exports.object({
20342
- actor: external_exports.object({ user_id: external_exports.string(), display_name: external_exports.string(), device_id: external_exports.string(), can_create_projects: external_exports.literal(true) }).strict(),
20343
- expires_at: external_exports.string().datetime()
20344
- }).strict();
20345
-
20346
20430
  // ../protocol/dist/src/index.js
20347
20431
  var sessionModes = ["solo", "multi"];
20348
20432
  var membershipRoles = ["owner", "participant", "viewer"];
@@ -20357,7 +20441,8 @@ var eventTypes = [
20357
20441
  "attachment",
20358
20442
  "context_snapshot",
20359
20443
  "membership_change",
20360
- "session_state_change"
20444
+ "session_state_change",
20445
+ "message_deleted"
20361
20446
  ];
20362
20447
  var eventVisibilities = ["session", "owner_only"];
20363
20448
  var captureFidelities = [
@@ -20454,8 +20539,18 @@ var CanonicalEventSchema = external_exports.object({
20454
20539
  visibility: EventVisibilitySchema,
20455
20540
  reply_to_event_id: IdSchema.nullable(),
20456
20541
  payload: JsonValueSchema,
20457
- runtime_provenance: RuntimeProvenanceSchema.nullable()
20542
+ runtime_provenance: RuntimeProvenanceSchema.nullable(),
20543
+ content_revision: external_exports.number().int().nonnegative().optional(),
20544
+ deleted: external_exports.object({ deleted_at: external_exports.string().datetime(), reason: external_exports.enum(["author", "request", "summary_invalidated"]) }).strict().optional()
20458
20545
  });
20546
+ var DeleteMessageInputSchema = external_exports.object({ idempotency_key: IdempotencyKeySchema }).strict();
20547
+ var DeleteMessageResultSchema = external_exports.object({
20548
+ event: CanonicalEventSchema,
20549
+ target_event_id: IdSchema,
20550
+ content_revision: external_exports.number().int().nonnegative(),
20551
+ affected_event_ids: external_exports.array(IdSchema).max(256),
20552
+ affected_truncated: external_exports.boolean()
20553
+ }).strict();
20459
20554
  var MessageMentionsSchema = external_exports.array(external_exports.object({
20460
20555
  user_id: IdSchema,
20461
20556
  start: external_exports.number().int().nonnegative().max(1e6),
@@ -20484,6 +20579,7 @@ var AppendEventInputSchema = external_exports.object({
20484
20579
  payload: JsonValueSchema,
20485
20580
  runtime_id: IdSchema.optional(),
20486
20581
  claim_attempt: external_exports.number().int().positive().optional(),
20582
+ content_revision: external_exports.number().int().nonnegative().optional(),
20487
20583
  observed_model: external_exports.string().trim().min(1).max(160).regex(/^[^\u0000-\u001f\u007f-\u009f]+$/u).optional(),
20488
20584
  observed_reasoning_effort: external_exports.string().trim().min(1).max(80).regex(/^[^\u0000-\u001f\u007f-\u009f]+$/u).optional()
20489
20585
  });
@@ -20493,7 +20589,28 @@ var HostedAgentRequestInputSchema = external_exports.object({
20493
20589
  include_code: external_exports.boolean().default(false),
20494
20590
  idempotency_key: IdempotencyKeySchema,
20495
20591
  reply_to_event_id: IdSchema.nullable().optional(),
20496
- github_task_id: external_exports.string().regex(/^gh-task-[a-f0-9]{32}$/u).optional()
20592
+ github_task_id: external_exports.string().regex(/^gh-task-[a-f0-9]{32}$/u).optional(),
20593
+ continue_from_event_id: IdSchema.optional(),
20594
+ api_config_revision: PersonalCloudRevisionSchema,
20595
+ content_revision: external_exports.number().int().nonnegative().optional()
20596
+ }).strict().refine(hasValidPersonalCloudRevision, { message: "Personal cloud profiles require their exact configuration revision" });
20597
+ var HostedAgentFailurePayloadSchema = external_exports.object({
20598
+ content: external_exports.string().min(1).max(512),
20599
+ status: external_exports.literal("failed"),
20600
+ outcome: external_exports.enum(["timed_out", "failed"]),
20601
+ error: external_exports.object({
20602
+ code: external_exports.string().regex(/^[a-z][a-z0-9_]{0,63}$/u),
20603
+ provider_attempts: external_exports.number().int().min(0).max(64).optional()
20604
+ }).strict()
20605
+ }).strict();
20606
+ var HostedHistorySummaryInputSchema = CreateHistorySummaryInputSchema.omit({ execution_profile: true }).extend({ profile_id: HostedAgentRequestInputSchema.shape.profile_id.unwrap(), api_config_revision: PersonalCloudRevisionSchema, continue_from_event_id: IdSchema.optional() }).strict().refine(hasValidPersonalCloudRevision, { message: "Personal cloud profiles require their exact configuration revision" });
20607
+ var HostedAgentAcceptedSchema = external_exports.object({
20608
+ request_event: CanonicalEventSchema,
20609
+ replayed: external_exports.boolean()
20610
+ }).strict();
20611
+ var HostedAgentPausedSchema = external_exports.object({
20612
+ request_event_id: IdSchema,
20613
+ status: external_exports.literal("paused")
20497
20614
  }).strict();
20498
20615
  var HostedAgentStatusSchema = external_exports.discriminatedUnion("enabled", [
20499
20616
  external_exports.object({ enabled: external_exports.literal(false) }).strict(),
@@ -20518,7 +20635,9 @@ var HostedAgentStatusSchema = external_exports.discriminatedUnion("enabled", [
20518
20635
  model: external_exports.string(),
20519
20636
  available: external_exports.boolean(),
20520
20637
  capacity: external_exports.number().int().nonnegative(),
20521
- status: external_exports.enum(["available", "busy", "daily_limit", "cooldown", "user_busy", "rate_limit"])
20638
+ status: external_exports.enum(["available", "busy", "daily_limit", "cooldown", "user_busy", "rate_limit"]),
20639
+ source: external_exports.enum(["service", "personal"]).optional(),
20640
+ api_config_revision: external_exports.string().uuid().optional()
20522
20641
  }).strict()),
20523
20642
  capabilities: external_exports.array(external_exports.string()),
20524
20643
  privacy: external_exports.string()
@@ -20630,6 +20749,17 @@ var ClaimInvitationInputSchema = external_exports.object({
20630
20749
  var AcceptInvitationInputSchema = external_exports.object({
20631
20750
  invite_token: external_exports.string().min(32).max(512)
20632
20751
  });
20752
+ var PreviewProjectInvitationInputSchema = external_exports.object({
20753
+ invite_token: external_exports.string().regex(/^gti_[A-Za-z0-9_-]{32,508}$/)
20754
+ }).strict();
20755
+ var ProjectInvitationPreviewSchema = external_exports.object({
20756
+ project: external_exports.object({ id: IdSchema, title: external_exports.string().min(1).max(200) }).strict(),
20757
+ inviter_display_name: external_exports.string().min(1).max(120),
20758
+ role: InvitationRoleSchema,
20759
+ created_at: external_exports.string().datetime(),
20760
+ expires_at: external_exports.string().datetime(),
20761
+ already_member: external_exports.boolean()
20762
+ }).strict();
20633
20763
  var InvitationRecordSchema = external_exports.object({
20634
20764
  id: IdSchema,
20635
20765
  session_id: IdSchema,
@@ -20704,6 +20834,10 @@ var DeviceAuthorizationRecordSchema = external_exports.object({
20704
20834
  claimed_at: external_exports.string().datetime().nullable(),
20705
20835
  claimed_by_device_id: IdSchema.nullable()
20706
20836
  });
20837
+ var CodexLauncherAuthorizationSchema = external_exports.object({
20838
+ authorization: DeviceAuthorizationRecordSchema.strict(),
20839
+ email: RegistrationEmailSchema
20840
+ }).strict();
20707
20841
  var RotateDeviceTokenInputSchema = external_exports.object({
20708
20842
  expires_at: external_exports.string().datetime().nullable().optional()
20709
20843
  });
@@ -20738,6 +20872,7 @@ var RegisterRuntimeInputSchema = external_exports.object({
20738
20872
  provider: external_exports.string().trim().min(1).max(80),
20739
20873
  model: external_exports.string().trim().min(1).max(160),
20740
20874
  execution_profiles: RuntimeExecutionProfilesSchema.optional(),
20875
+ context_deletion_version: external_exports.literal(1).optional(),
20741
20876
  local_session_id: external_exports.string().trim().min(1).max(512),
20742
20877
  capture_fidelity: CaptureFidelitySchema
20743
20878
  });
@@ -20751,11 +20886,13 @@ var AgentRequestClaimSchema = external_exports.object({
20751
20886
  // `paused` is a decision by the requester, not a claim a runtime can execute.
20752
20887
  // It is reported so a connector can skip the request without advancing past it.
20753
20888
  status: external_exports.enum(["claimed", "completed", "paused"]),
20754
- attempt_count: external_exports.number().int().positive().optional()
20889
+ attempt_count: external_exports.number().int().positive().optional(),
20890
+ content_revision: external_exports.number().int().nonnegative().optional()
20755
20891
  }).strict();
20756
20892
  var CompleteAgentRequestInputSchema = external_exports.object({
20757
20893
  runtime_id: IdSchema,
20758
20894
  claim_attempt: external_exports.number().int().positive().optional(),
20895
+ content_revision: external_exports.number().int().nonnegative().optional(),
20759
20896
  idempotency_key: IdempotencyKeySchema,
20760
20897
  payload: JsonValueSchema,
20761
20898
  observed_model: external_exports.string().trim().min(1).max(160).regex(/^[^\u0000-\u001f\u007f-\u009f]+$/u).optional(),
@@ -20770,6 +20907,7 @@ var CommitLocalTurnInputSchema = external_exports.object({
20770
20907
  local_turn_id: IdSchema,
20771
20908
  runtime_id: IdSchema,
20772
20909
  based_on_sequence: external_exports.number().int().nonnegative(),
20910
+ content_revision: external_exports.number().int().nonnegative().optional(),
20773
20911
  occurred_at: external_exports.string().datetime(),
20774
20912
  observed_model: external_exports.string().trim().min(1).max(160).regex(/^[^\u0000-\u001f\u007f-\u009f]+$/u).optional(),
20775
20913
  observed_reasoning_effort: external_exports.string().trim().min(1).max(80).regex(/^[^\u0000-\u001f\u007f-\u009f]+$/u).optional(),
@@ -20823,6 +20961,7 @@ var SnapshotRequestRecordSchema = external_exports.object({
20823
20961
  kind: SnapshotRequestKindSchema,
20824
20962
  through_sequence: external_exports.number().int().nonnegative(),
20825
20963
  status: SnapshotRequestStatusSchema,
20964
+ content_revision: external_exports.number().int().nonnegative().optional(),
20826
20965
  target_runtime_id: IdSchema.nullable(),
20827
20966
  claimed_by_runtime_id: IdSchema.nullable(),
20828
20967
  created_at: external_exports.string().datetime(),
@@ -20848,7 +20987,8 @@ var SubscribeMessageSchema = external_exports.object({
20848
20987
  var ReplayResponseSchema = external_exports.object({
20849
20988
  events: external_exports.array(CanonicalEventSchema),
20850
20989
  cursor: external_exports.number().int().nonnegative(),
20851
- has_more: external_exports.boolean()
20990
+ has_more: external_exports.boolean(),
20991
+ content_revision: external_exports.number().int().nonnegative().optional()
20852
20992
  });
20853
20993
  var SessionListItemSchema = external_exports.object({
20854
20994
  id: IdSchema,
@@ -20859,6 +20999,7 @@ var SessionListItemSchema = external_exports.object({
20859
20999
  state: external_exports.enum(["active", "archived"]),
20860
21000
  role: MembershipRoleSchema,
20861
21001
  current_sequence: external_exports.number().int().nonnegative(),
21002
+ content_revision: external_exports.number().int().nonnegative().optional(),
20862
21003
  member_count: external_exports.number().int().nonnegative().optional(),
20863
21004
  updated_at: external_exports.string().datetime()
20864
21005
  });
@@ -20962,7 +21103,8 @@ var HttpCollaborationClient = class {
20962
21103
  return {
20963
21104
  events,
20964
21105
  nextSequence: requiredNumber(body.cursor, "cursor"),
20965
- hasMore: body.has_more === true
21106
+ hasMore: body.has_more === true,
21107
+ ...body.content_revision === void 0 ? {} : { contentRevision: requiredRevision(body.content_revision, "events.content_revision") }
20966
21108
  };
20967
21109
  }
20968
21110
  async readContext(sessionId, view, throughSequence) {
@@ -21020,7 +21162,8 @@ var HttpCollaborationClient = class {
21020
21162
  status,
21021
21163
  requestId: requiredString2(body.request_event_id, "claim.request_event_id"),
21022
21164
  runtimeId: requiredString2(body.runtime_id, "claim.runtime_id"),
21023
- attemptCount
21165
+ attemptCount,
21166
+ ...body.content_revision === void 0 ? {} : { contentRevision: requiredRevision(body.content_revision, "claim.content_revision") }
21024
21167
  };
21025
21168
  }
21026
21169
  async completeAgentRequest(sessionId, requestId, input2) {
@@ -21029,6 +21172,7 @@ var HttpCollaborationClient = class {
21029
21172
  body: JSON.stringify({
21030
21173
  runtime_id: input2.runtimeId,
21031
21174
  ...input2.claimAttempt === void 0 ? {} : { claim_attempt: input2.claimAttempt },
21175
+ ...input2.contentRevision === void 0 ? {} : { content_revision: input2.contentRevision },
21032
21176
  idempotency_key: input2.idempotencyKey,
21033
21177
  payload: truncateJsonValue(input2.payload, 160 * 1024),
21034
21178
  ...input2.observedModel === void 0 ? {} : { observed_model: input2.observedModel },
@@ -21043,6 +21187,7 @@ var HttpCollaborationClient = class {
21043
21187
  body: JSON.stringify({
21044
21188
  runtime_id: input2.runtimeId,
21045
21189
  ...input2.claimAttempt === void 0 ? {} : { claim_attempt: input2.claimAttempt },
21190
+ ...input2.contentRevision === void 0 ? {} : { content_revision: input2.contentRevision },
21046
21191
  idempotency_key: input2.idempotencyKey,
21047
21192
  payload: truncateJsonValue(input2.payload, 32 * 1024),
21048
21193
  ...input2.observedModel === void 0 ? {} : { observed_model: input2.observedModel },
@@ -21059,6 +21204,7 @@ var HttpCollaborationClient = class {
21059
21204
  local_turn_id: input2.localTurnId,
21060
21205
  runtime_id: input2.runtimeId,
21061
21206
  based_on_sequence: input2.basedOnSequence,
21207
+ ...input2.contentRevision === void 0 ? {} : { content_revision: input2.contentRevision },
21062
21208
  occurred_at: input2.occurredAt,
21063
21209
  ...input2.observedModel === void 0 ? {} : { observed_model: input2.observedModel },
21064
21210
  ...input2.observedReasoningEffort === void 0 ? {} : { observed_reasoning_effort: input2.observedReasoningEffort },
@@ -21165,6 +21311,7 @@ function toWireEvent(event) {
21165
21311
  visibility: event.visibility ?? "session",
21166
21312
  runtime_id: event.runtimeId ?? event.runtime?.runtimeId,
21167
21313
  claim_attempt: event.claimAttempt,
21314
+ ...event.contentRevision === void 0 ? {} : { content_revision: event.contentRevision },
21168
21315
  observed_model: event.observedModel,
21169
21316
  observed_reasoning_effort: event.observedReasoningEffort
21170
21317
  };
@@ -21190,7 +21337,8 @@ function toWireRuntimeRegistration(runtime) {
21190
21337
  local_session_id: runtime.localSessionId,
21191
21338
  capture_fidelity: runtime.captureFidelity,
21192
21339
  ...runtime.capabilities === void 0 ? {} : { capabilities: [...runtime.capabilities] },
21193
- ...runtime.purpose === void 0 ? {} : { purpose: runtime.purpose }
21340
+ ...runtime.purpose === void 0 ? {} : { purpose: runtime.purpose },
21341
+ ...runtime.contextDeletionVersion === void 0 ? {} : { context_deletion_version: runtime.contextDeletionVersion }
21194
21342
  };
21195
21343
  }
21196
21344
  function validateContextReadInput(sessionId, view, throughSequence) {
@@ -21251,7 +21399,17 @@ function parseHistoryContext(value, expectedView, throughSequence) {
21251
21399
  if (items.some((item) => sourceIds.has(item.event_id))) {
21252
21400
  throw new Error("Collaboration API context repeats summarized sources");
21253
21401
  }
21254
- return { view: value.view, through_sequence: Number(value.through_sequence), items };
21402
+ return {
21403
+ view: value.view,
21404
+ through_sequence: Number(value.through_sequence),
21405
+ items,
21406
+ ...value.content_revision === void 0 ? {} : { content_revision: requiredRevision(value.content_revision, "context.content_revision") }
21407
+ };
21408
+ }
21409
+ function requiredRevision(value, label) {
21410
+ if (!Number.isSafeInteger(value) || Number(value) < 0)
21411
+ throw new Error(`Collaboration API returned invalid ${label}`);
21412
+ return Number(value);
21255
21413
  }
21256
21414
  function isContextId(value) {
21257
21415
  return typeof value === "string" && /^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$/.test(value);
@@ -21270,9 +21428,17 @@ function fromWireEvent(value) {
21270
21428
  ...typeof input2.reply_to_event_id === "string" ? { replyTo: input2.reply_to_event_id } : {},
21271
21429
  timestamp: requiredString2(input2.created_at, "event.created_at"),
21272
21430
  payload: input2.payload,
21431
+ ...input2.content_revision === void 0 ? {} : { contentRevision: requiredRevision(input2.content_revision, "event.content_revision") },
21432
+ ...input2.deleted === void 0 ? {} : { deleted: fromWireDeletion(input2.deleted) },
21273
21433
  ...runtime === void 0 ? {} : { runtime }
21274
21434
  };
21275
21435
  }
21436
+ function fromWireDeletion(value) {
21437
+ const input2 = requiredObject2(value);
21438
+ if (input2.reason !== "author" && input2.reason !== "request" && input2.reason !== "summary_invalidated")
21439
+ throw new Error("Collaboration API returned invalid event.deleted reason");
21440
+ return { deletedAt: requiredString2(input2.deleted_at, "event.deleted.deleted_at"), reason: input2.reason };
21441
+ }
21276
21442
  function fromWireSnapshotRequest(value) {
21277
21443
  const input2 = requiredObject2(value);
21278
21444
  const status = requiredString2(input2.status, "snapshot_request.status");
@@ -21308,6 +21474,7 @@ function fromWireSnapshotRequest(value) {
21308
21474
  kind,
21309
21475
  ...typeof input2.target_runtime_id === "string" ? { targetRuntimeId: input2.target_runtime_id } : {},
21310
21476
  throughSequence: requiredNumber(input2.through_sequence, "snapshot_request.through_sequence"),
21477
+ ...input2.content_revision === void 0 ? {} : { contentRevision: requiredRevision(input2.content_revision, "snapshot_request.content_revision") },
21311
21478
  status,
21312
21479
  ...createdAt === void 0 ? {} : { createdAt },
21313
21480
  ..."result" in input2 ? { result: input2.result } : {},
@@ -21327,7 +21494,8 @@ function fromWireSession(value) {
21327
21494
  ...input2.state === "active" || input2.state === "archived" ? { state: input2.state } : {},
21328
21495
  ...name2 === void 0 ? {} : { name: name2 },
21329
21496
  ...role === void 0 ? {} : { role },
21330
- ...latestSequence === void 0 ? {} : { latestSequence }
21497
+ ...latestSequence === void 0 ? {} : { latestSequence },
21498
+ ...input2.content_revision === void 0 ? {} : { contentRevision: requiredRevision(input2.content_revision, "session.content_revision") }
21331
21499
  };
21332
21500
  }
21333
21501
  function fromWireProject(value) {
@@ -21374,7 +21542,8 @@ function fromWireRuntime(value) {
21374
21542
  ...input2.execution_profiles === void 0 || input2.execution_profiles === null ? {} : { executionProfiles: fromWireExecutionProfiles(input2.execution_profiles) },
21375
21543
  localSessionId: requiredString2(input2.local_session_id, "runtime.local_session_id"),
21376
21544
  captureFidelity: requiredString2(input2.capture_fidelity, "runtime.capture_fidelity"),
21377
- purpose
21545
+ purpose,
21546
+ ...input2.context_deletion_version === 1 ? { contextDeletionVersion: 1 } : {}
21378
21547
  };
21379
21548
  }
21380
21549
  function fromWireExecutionProfiles(value) {
@@ -21505,8 +21674,8 @@ function isObject2(value) {
21505
21674
 
21506
21675
  // ../adapters/dist/src/redaction.js
21507
21676
  var REDACTED = "[REDACTED]";
21677
+ var PRIVATE_KEY_PATTERN = /-----BEGIN (?:ENCRYPTED |RSA |EC |OPENSSH |DSA )?PRIVATE KEY-----[\s\S]*?(?:-----END (?:ENCRYPTED |RSA |EC |OPENSSH |DSA )?PRIVATE KEY-----|$)/g;
21508
21678
  var DEFAULT_SECRET_PATTERNS = [
21509
- /-----BEGIN (?:RSA |EC |OPENSSH |DSA )?PRIVATE KEY-----[\s\S]*?-----END (?:RSA |EC |OPENSSH |DSA )?PRIVATE KEY-----/g,
21510
21679
  /\bAKIA[0-9A-Z]{16}\b/g,
21511
21680
  /\b(?:ghp|github_pat|glpat|sk|xox[baprs])[-_][A-Za-z0-9_-]{16,}\b/g,
21512
21681
  /\bBearer\s+[A-Za-z0-9._~+/=-]{8,}\b/gi,
@@ -21519,6 +21688,8 @@ var SENSITIVE_KEY_NAMES = /* @__PURE__ */ new Set([
21519
21688
  "accesstoken",
21520
21689
  "authtoken",
21521
21690
  "authorization",
21691
+ "cookie",
21692
+ "setcookie",
21522
21693
  "bearer",
21523
21694
  "clientsecret",
21524
21695
  "password",
@@ -21535,7 +21706,83 @@ var SENSITIVE_KEY_NAMES = /* @__PURE__ */ new Set([
21535
21706
  ]);
21536
21707
  function redactText(value, options = {}) {
21537
21708
  const replacement = options.replacement ?? REDACTED;
21538
- return [...DEFAULT_SECRET_PATTERNS, ...options.extraPatterns ?? []].reduce((redacted, pattern) => redacted.replace(cloneGlobal(pattern), (match, prefix) => typeof prefix === "string" && prefix.length < match.length ? `${prefix}${replacement}` : replacement), value);
21709
+ return [...DEFAULT_SECRET_PATTERNS, ...options.extraPatterns ?? []].reduce(
21710
+ (redacted, pattern) => redacted.replace(cloneGlobal(pattern), (match, prefix) => typeof prefix === "string" && prefix.length < match.length ? `${prefix}${replacement}` : replacement),
21711
+ // Mask PEM first: scanning `private_key: -----BEGIN ...` as an ordinary
21712
+ // assignment must not break its header and leave the following body public.
21713
+ redactSensitiveFields(value.replace(cloneGlobal(PRIVATE_KEY_PATTERN), () => replacement), replacement)
21714
+ );
21715
+ }
21716
+ function redactSensitiveFields(text, replacement) {
21717
+ const fields = /("(?:\\.|[^"\\\r\n])*"|'(?:\\.|[^'\\\r\n])*'|\b[A-Za-z_][A-Za-z0-9_.-]*)(\s*[:=]\s*)/gu;
21718
+ const parts = [];
21719
+ let retainedFrom = 0;
21720
+ let match;
21721
+ while ((match = fields.exec(text)) !== null) {
21722
+ const encodedKey = match[1];
21723
+ let key = encodedKey;
21724
+ if (encodedKey.startsWith('"')) {
21725
+ try {
21726
+ key = JSON.parse(encodedKey);
21727
+ } catch {
21728
+ continue;
21729
+ }
21730
+ } else if (encodedKey.startsWith("'"))
21731
+ key = encodedKey.slice(1, -1);
21732
+ if (!isSensitiveKey(key))
21733
+ continue;
21734
+ const start = fields.lastIndex;
21735
+ const end = sensitiveValueEnd(text, start, encodedKey[0] !== '"' && encodedKey[0] !== "'" && /^(?:authorization|cookie|set-cookie)$/iu.test(key));
21736
+ const quote = text[start];
21737
+ const masked = quote === "'" ? `'${replacement.replace(/\\/gu, "\\\\").replace(/'/gu, "\\'")}'` : quote === '"' || encodedKey.startsWith('"') ? JSON.stringify(replacement) : replacement;
21738
+ parts.push(text.slice(retainedFrom, start), masked);
21739
+ retainedFrom = end;
21740
+ fields.lastIndex = end;
21741
+ }
21742
+ return parts.length === 0 ? text : parts.join("") + text.slice(retainedFrom);
21743
+ }
21744
+ function sensitiveValueEnd(text, start, header) {
21745
+ if (header) {
21746
+ const end = text.indexOf("\n", start);
21747
+ return end < 0 ? text.length : end;
21748
+ }
21749
+ const first = text[start];
21750
+ if (first === '"' || first === "'") {
21751
+ for (let index2 = start + 1; index2 < text.length; index2++) {
21752
+ if (text[index2] === "\\")
21753
+ index2++;
21754
+ else if (text[index2] === first)
21755
+ return index2 + 1;
21756
+ }
21757
+ return text.length;
21758
+ }
21759
+ if (first === "{" || first === "[") {
21760
+ const closing = [first === "{" ? "}" : "]"];
21761
+ let quote;
21762
+ for (let index2 = start + 1; index2 < text.length; index2++) {
21763
+ const character = text[index2];
21764
+ if (quote !== void 0) {
21765
+ if (character === "\\")
21766
+ index2++;
21767
+ else if (character === quote)
21768
+ quote = void 0;
21769
+ } else if (character === '"' || character === "'")
21770
+ quote = character;
21771
+ else if (character === "{" || character === "[")
21772
+ closing.push(character === "{" ? "}" : "]");
21773
+ else if (character === "}" || character === "]") {
21774
+ if (character !== closing.pop())
21775
+ return text.length;
21776
+ if (closing.length === 0)
21777
+ return index2 + 1;
21778
+ }
21779
+ }
21780
+ return text.length;
21781
+ }
21782
+ let index = start;
21783
+ while (index < text.length && !/[\s,;}\]]/u.test(text[index]))
21784
+ index++;
21785
+ return index;
21539
21786
  }
21540
21787
  function redactValue(value, options = {}) {
21541
21788
  if (typeof value === "string")
@@ -21557,6 +21804,208 @@ function cloneGlobal(pattern) {
21557
21804
  return new RegExp(pattern.source, pattern.flags.includes("g") ? pattern.flags : `${pattern.flags}g`);
21558
21805
  }
21559
21806
 
21807
+ // ../adapters/dist/src/live-output.js
21808
+ import { randomUUID } from "node:crypto";
21809
+ var MAX_ITEMS = 128;
21810
+ var MAX_INPUT_BYTES = 96 * 1024;
21811
+ var MAX_PUBLIC_BYTES = 24 * 1024;
21812
+ var MAX_PUBLICATIONS = 1200;
21813
+ function createLiveOutputPublisher(options) {
21814
+ const items = /* @__PURE__ */ new Map();
21815
+ const now = options.now ?? Date.now;
21816
+ const intervalMs = options.intervalMs ?? 1500;
21817
+ let lastPublished, publications = 0, closed = false;
21818
+ let timer;
21819
+ let queue = Promise.resolve();
21820
+ let lastVisited;
21821
+ const serial = (operation) => {
21822
+ queue = queue.then(operation, operation);
21823
+ return queue;
21824
+ };
21825
+ const itemFor = (key, kind, title) => {
21826
+ let item = items.get(key);
21827
+ if (!item && items.size < MAX_ITEMS) {
21828
+ item = {
21829
+ streamId: randomUUID(),
21830
+ raw: "",
21831
+ kind,
21832
+ state: "running",
21833
+ revision: 0,
21834
+ acknowledged: "",
21835
+ dirty: true,
21836
+ truncated: false
21837
+ };
21838
+ items.set(key, item);
21839
+ }
21840
+ if (item && title !== void 0)
21841
+ item.title = bound(redactText(title, options.redaction), 256);
21842
+ return item;
21843
+ };
21844
+ const safe = (item) => {
21845
+ let content = item.raw;
21846
+ if (item.state === "running") {
21847
+ content = content.replace(/(?:\bBearer\s+|\b(?:api[_-]?key|access[_-]?token|auth[_-]?token|client[_-]?secret|password|passwd|secret|token)["']?\s*[=:]\s*["']?)[^\n,;]*$/giu, "");
21848
+ let end = content.length;
21849
+ while (end > 0 && /[A-Za-z0-9_./~+=:@%\-]/u.test(content[end - 1]))
21850
+ end--;
21851
+ content = content.slice(0, end);
21852
+ }
21853
+ content = redactText(content, options.redaction);
21854
+ return bound(content, MAX_PUBLIC_BYTES, item.truncated);
21855
+ };
21856
+ const signatureFor = (item) => JSON.stringify([safe(item), item.state, item.title, item.plan]);
21857
+ const schedule = () => {
21858
+ if (closed || options.schedule === false || timer || ![...items.values()].some((x) => x.dirty))
21859
+ return;
21860
+ timer = setTimeout(() => {
21861
+ timer = void 0;
21862
+ void flush().catch(() => void 0);
21863
+ }, intervalMs);
21864
+ timer.unref();
21865
+ };
21866
+ const publishOne = async (item) => {
21867
+ if (!item.dirty || publications >= MAX_PUBLICATIONS)
21868
+ return;
21869
+ const content = safe(item);
21870
+ const signature = JSON.stringify([content, item.state, item.title, item.plan]);
21871
+ if (!item.pending && signature === item.acknowledged) {
21872
+ item.dirty = false;
21873
+ return;
21874
+ }
21875
+ if (!item.pending && !content.trim() && item.plan === void 0)
21876
+ return;
21877
+ const revision = item.revision + 1;
21878
+ const update = {
21879
+ id: `${item.streamId}:${revision}`,
21880
+ content,
21881
+ phase: "stream",
21882
+ streamId: item.streamId,
21883
+ streamMode: "snapshot",
21884
+ streamKind: item.kind,
21885
+ streamRevision: revision,
21886
+ streamState: item.state,
21887
+ ...item.title === void 0 ? {} : { title: item.title },
21888
+ ...item.plan === void 0 ? {} : { plan: item.plan }
21889
+ };
21890
+ item.pending ??= { update, signature };
21891
+ const pending = item.pending;
21892
+ try {
21893
+ if (await options.publish(pending.update) === false)
21894
+ return;
21895
+ item.revision = pending.update.streamRevision;
21896
+ item.acknowledged = pending.signature;
21897
+ delete item.pending;
21898
+ item.dirty = signatureFor(item) !== item.acknowledged;
21899
+ lastPublished = now();
21900
+ publications++;
21901
+ } catch {
21902
+ }
21903
+ };
21904
+ const flush = () => serial(async () => {
21905
+ if (closed || lastPublished !== void 0 && now() - lastPublished < intervalMs) {
21906
+ schedule();
21907
+ return;
21908
+ }
21909
+ const ordered = [...items.values()];
21910
+ const start = lastVisited === void 0 ? 0 : (ordered.indexOf(lastVisited) + 1) % ordered.length;
21911
+ for (let offset = 0; offset < ordered.length; offset++) {
21912
+ const item = ordered[(start + offset) % ordered.length];
21913
+ if (!item.dirty)
21914
+ continue;
21915
+ lastVisited = item;
21916
+ await publishOne(item);
21917
+ if (lastPublished !== void 0 && now() - lastPublished < intervalMs)
21918
+ break;
21919
+ }
21920
+ schedule();
21921
+ });
21922
+ return {
21923
+ async onDelta(key, delta, kind = "answer", title) {
21924
+ if (closed || !delta)
21925
+ return;
21926
+ const item = itemFor(key, kind, title);
21927
+ if (!item || item.state !== "running" || item.truncated)
21928
+ return;
21929
+ const raw = item.raw + delta;
21930
+ item.raw = bound(raw, MAX_INPUT_BYTES);
21931
+ item.truncated = Buffer.byteLength(raw) > MAX_INPUT_BYTES;
21932
+ item.dirty = true;
21933
+ await flush();
21934
+ },
21935
+ async onSnapshot(key, text, kind = "answer", title, state = "running") {
21936
+ if (closed)
21937
+ return;
21938
+ const item = itemFor(key, kind, title);
21939
+ if (!item)
21940
+ return;
21941
+ item.raw = bound(text, MAX_INPUT_BYTES);
21942
+ item.truncated = Buffer.byteLength(text) > MAX_INPUT_BYTES;
21943
+ item.state = state;
21944
+ item.dirty = true;
21945
+ await flush();
21946
+ },
21947
+ async onPlan(key, steps) {
21948
+ if (closed)
21949
+ return;
21950
+ const item = itemFor(key, "plan");
21951
+ if (!item)
21952
+ return;
21953
+ item.plan = steps.slice(0, 64).map((step) => ({ step: bound(redactText(step.step, options.redaction), 512), status: step.status }));
21954
+ item.raw = item.plan.map((step) => `${step.status}: ${step.step}`).join("\n");
21955
+ item.dirty = true;
21956
+ await flush();
21957
+ },
21958
+ flush,
21959
+ async finish(success2 = true) {
21960
+ if (timer) {
21961
+ clearTimeout(timer);
21962
+ timer = void 0;
21963
+ }
21964
+ await serial(async () => {
21965
+ if (closed)
21966
+ return;
21967
+ for (const item of [...items.values()].slice(0, 64)) {
21968
+ if (item.state === "running") {
21969
+ item.state = success2 ? "completed" : "failed";
21970
+ item.dirty = true;
21971
+ }
21972
+ await publishOne(item);
21973
+ if (item.dirty && !item.pending)
21974
+ await publishOne(item);
21975
+ }
21976
+ closed = true;
21977
+ items.clear();
21978
+ });
21979
+ },
21980
+ lastPublishedAt: () => lastPublished
21981
+ };
21982
+ }
21983
+ function liveOutputPayload(update) {
21984
+ return {
21985
+ content: update.content,
21986
+ phase: update.phase,
21987
+ stream_id: update.streamId,
21988
+ stream_mode: update.streamMode,
21989
+ stream_kind: update.streamKind,
21990
+ stream_revision: update.streamRevision,
21991
+ stream_state: update.streamState,
21992
+ ...update.title === void 0 ? {} : { title: update.title },
21993
+ ...update.plan === void 0 ? {} : { plan: update.plan.map((step) => ({ step: step.step, status: step.status })) }
21994
+ };
21995
+ }
21996
+ function bound(text, maxBytes, alreadyTruncated = false) {
21997
+ if (!alreadyTruncated && Buffer.byteLength(text) <= maxBytes)
21998
+ return text;
21999
+ const suffix = "\n[TRUNCATED]";
22000
+ const bytes2 = Buffer.from(text).subarray(0, maxBytes - Buffer.byteLength(suffix));
22001
+ let end = bytes2.length;
22002
+ while (end > 0 && (bytes2[end - 1] & 192) === 128)
22003
+ end--;
22004
+ if (end < bytes2.length || (bytes2[end - 1] & 128) !== 0)
22005
+ end = Math.max(0, end - 1);
22006
+ return bytes2.subarray(0, end).toString("utf8") + suffix;
22007
+ }
22008
+
21560
22009
  // ../adapters/dist/src/jsonl.js
21561
22010
  var DEFAULT_MAX_READ_BYTES = 4 * 1024 * 1024;
21562
22011
 
@@ -22033,6 +22482,255 @@ function asObject2(value) {
22033
22482
  return value !== null && typeof value === "object" && !Array.isArray(value) ? value : void 0;
22034
22483
  }
22035
22484
 
22485
+ // dist/src/live-event-mapper.js
22486
+ var MAX_ATTEMPTS = 64;
22487
+ var MAX_BLOCKS = 128;
22488
+ var MAX_TEXT = 96 * 1024;
22489
+ function createDshLiveEventMapper(publisher) {
22490
+ const attempts = /* @__PURE__ */ new Map();
22491
+ const steps = /* @__PURE__ */ new Map();
22492
+ const tools = /* @__PURE__ */ new Map();
22493
+ let revision = 0;
22494
+ const deliver = (operation) => {
22495
+ void operation.catch(() => void 0);
22496
+ };
22497
+ const snapshot = (block, state) => deliver(publisher.onSnapshot(block.key, block.text, block.kind, block.title, state));
22498
+ const toolFor = (id, fallbackKey) => {
22499
+ let tool = tools.get(id);
22500
+ if (tool === void 0 && tools.size < MAX_BLOCKS) {
22501
+ tool = { key: fallbackKey, arguments: "" };
22502
+ tools.set(id, tool);
22503
+ }
22504
+ return tool;
22505
+ };
22506
+ const settle2 = (attempt, state) => {
22507
+ if (state === "failed")
22508
+ attempt.failed = true;
22509
+ for (const block of attempt.blocks.values()) {
22510
+ if (block.kind !== "tool")
22511
+ snapshot(block, state);
22512
+ else if (state === "failed") {
22513
+ const argumentsText = block.callId === void 0 ? void 0 : tools.get(block.callId)?.arguments;
22514
+ deliver(publisher.onSnapshot(block.key, `Arguments:
22515
+ ${argumentsText || "[Unparseable tool arguments]"}`, "tool", block.title, state));
22516
+ }
22517
+ }
22518
+ };
22519
+ const onFrame = (frame) => {
22520
+ if (frame.revision <= revision)
22521
+ return;
22522
+ const identity = frame.attemptId;
22523
+ if (frame.type === "start") {
22524
+ if (attempts.has(identity) || attempts.size >= MAX_ATTEMPTS)
22525
+ return;
22526
+ revision = frame.revision;
22527
+ const attempt2 = { turn: frame.turn, step: frame.step, nextIndex: 0, closed: false, failed: false, blocks: /* @__PURE__ */ new Map() };
22528
+ attempts.set(identity, attempt2);
22529
+ steps.set(`${frame.turn}:${frame.step}`, attempt2);
22530
+ return;
22531
+ }
22532
+ const attempt = attempts.get(identity);
22533
+ if (attempt === void 0 || attempt.closed || frame.index !== attempt.nextIndex)
22534
+ return;
22535
+ revision = frame.revision;
22536
+ if (frame.type === "end") {
22537
+ attempt.closed = true;
22538
+ settle2(attempt, attempt.failed || frame.outcome.kind === "abandoned" || frame.outcome.eventType === "assistant/attempt" ? "failed" : "completed");
22539
+ return;
22540
+ }
22541
+ attempt.nextIndex++;
22542
+ const chunk = object2(frame.chunk);
22543
+ if (chunk?.type === "finish") {
22544
+ const reason = object2(chunk.reason)?.kind ?? chunk.reason;
22545
+ if (reason === "error" || reason === "aborted")
22546
+ settle2(attempt, "failed");
22547
+ return;
22548
+ }
22549
+ if (!integer2(chunk?.index) || Number(chunk.index) >= MAX_BLOCKS)
22550
+ return;
22551
+ const index = Number(chunk.index);
22552
+ if (chunk.type === "block-start") {
22553
+ const kind = chunk.blockType === "text" ? "answer" : chunk.blockType === "reasoning" ? "reasoning" : chunk.blockType === "tool-call" ? "tool" : void 0;
22554
+ if (kind !== void 0 && !attempt.blocks.has(index)) {
22555
+ attempt.blocks.set(index, { key: `${identity}:${index}`, kind, text: "" });
22556
+ }
22557
+ return;
22558
+ }
22559
+ const block = attempt.blocks.get(index);
22560
+ if (block === void 0)
22561
+ return;
22562
+ if (chunk.type === "text-delta" && block.kind === "answer" || chunk.type === "reasoning-delta" && block.kind === "reasoning") {
22563
+ if (typeof chunk.text !== "string")
22564
+ return;
22565
+ block.text = bound2(block.text + chunk.text);
22566
+ deliver(publisher.onDelta(block.key, chunk.text, block.kind));
22567
+ } else if (chunk.type === "tool-call-delta" && block.kind === "tool") {
22568
+ if (!identifier(chunk.id) || typeof chunk.argumentsDelta !== "string" || block.callId !== void 0 && block.callId !== chunk.id)
22569
+ return;
22570
+ block.callId = chunk.id;
22571
+ if (typeof chunk.name === "string")
22572
+ block.title = bound2(chunk.name).slice(0, 256);
22573
+ const tool = toolFor(block.callId, block.key);
22574
+ if (tool === void 0)
22575
+ return;
22576
+ block.key = tool.key;
22577
+ block.text = bound2(block.text + chunk.argumentsDelta);
22578
+ if (block.title !== void 0)
22579
+ tool.title = block.title;
22580
+ const argumentsText = parsedArguments(block.text);
22581
+ if (argumentsText !== void 0)
22582
+ tool.arguments = argumentsText;
22583
+ deliver(publisher.onSnapshot(block.key, argumentsText === void 0 ? "Preparing tool arguments.\n" : `Arguments:
22584
+ ${argumentsText}`, "tool", block.title));
22585
+ } else if (chunk.type === "block-end") {
22586
+ const content = object2(chunk.block);
22587
+ if ((content?.type === "text" && block.kind === "answer" || content?.type === "reasoning" && block.kind === "reasoning") && typeof content.text === "string") {
22588
+ block.text = bound2(content.text);
22589
+ snapshot(block, "completed");
22590
+ } else if (content?.type === "tool-call" && block.kind === "tool" && identifier(content.id) && typeof content.arguments === "string" && (block.callId === void 0 || content.id === block.callId)) {
22591
+ const tool = toolFor(content.id, block.key);
22592
+ if (tool === void 0)
22593
+ return;
22594
+ block.callId = content.id;
22595
+ block.key = tool.key;
22596
+ block.text = publicArguments(content.arguments);
22597
+ if (typeof content.name === "string")
22598
+ block.title = content.name.slice(0, 256);
22599
+ tool.arguments = block.text;
22600
+ if (block.title !== void 0)
22601
+ tool.title = block.title;
22602
+ snapshot(block, "running");
22603
+ }
22604
+ }
22605
+ };
22606
+ const onDurable = (event) => {
22607
+ const data = object2(event.data);
22608
+ if (data === void 0)
22609
+ return;
22610
+ if (event.type === "assistant/message" && integer2(data.turn) && integer2(data.step)) {
22611
+ const attempt = steps.get(`${data.turn}:${data.step}`);
22612
+ if (attempt !== void 0 && data.interrupted === true)
22613
+ attempt.failed = true;
22614
+ const message = object2(data.message);
22615
+ if (!Array.isArray(message?.content))
22616
+ return;
22617
+ const nativeBlocks = [...attempt?.blocks.values() ?? []];
22618
+ for (const [index, value] of message.content.slice(0, MAX_BLOCKS).entries()) {
22619
+ const content = object2(value);
22620
+ const kind = content?.type === "text" ? "answer" : content?.type === "reasoning" ? "reasoning" : void 0;
22621
+ if (kind !== void 0 && typeof content.text === "string") {
22622
+ const candidate = nativeBlocks[index];
22623
+ const key = candidate?.kind === kind ? candidate.key : `assistant:${event.seq}:${index}`;
22624
+ if (candidate?.kind === kind)
22625
+ candidate.text = bound2(content.text);
22626
+ deliver(publisher.onSnapshot(key, content.text, kind, void 0, data.interrupted === true ? "failed" : "completed"));
22627
+ }
22628
+ }
22629
+ } else if (event.type === "assistant/attempt" && integer2(data.turn) && integer2(data.step)) {
22630
+ const attempt = steps.get(`${data.turn}:${data.step}`);
22631
+ if (attempt !== void 0)
22632
+ settle2(attempt, "failed");
22633
+ } else if (event.type === "tool/call" && identifier(data.callId) && typeof data.name === "string" && typeof data.arguments === "string") {
22634
+ const tool = toolFor(data.callId, `tool:${event.seq}`);
22635
+ if (tool === void 0)
22636
+ return;
22637
+ tool.arguments = publicArguments(data.arguments);
22638
+ tool.title = data.name.slice(0, 256);
22639
+ deliver(publisher.onSnapshot(tool.key, `Arguments:
22640
+ ${tool.arguments}`, "tool", tool.title));
22641
+ } else if (event.type === "tool/result") {
22642
+ const message = object2(data.message);
22643
+ const content = Array.isArray(message?.content) ? message.content : [];
22644
+ const wrapped = content.map(object2).find((block) => block?.type === "tool-result");
22645
+ const id = wrapped?.toolCallId ?? message?.toolCallId;
22646
+ if (!identifier(id))
22647
+ return;
22648
+ const tool = tools.get(id);
22649
+ if (tool === void 0)
22650
+ return;
22651
+ const blocks = wrapped === void 0 ? content : wrapped.content;
22652
+ if (!Array.isArray(blocks))
22653
+ return;
22654
+ const text = blocks.slice(0, MAX_BLOCKS).flatMap((value) => {
22655
+ const block = object2(value);
22656
+ return block?.type === "text" && typeof block.text === "string" ? [bound2(block.text)] : [];
22657
+ }).join("");
22658
+ const failed = wrapped?.isError === true || message?.isError === true || data.error !== void 0;
22659
+ deliver(publisher.onSnapshot(tool.key, `Arguments:
22660
+ ${tool.arguments}
22661
+
22662
+ Result:
22663
+ ${bound2(text)}`, "tool", tool.title, failed ? "failed" : "completed"));
22664
+ } else if (event.type === "todo/write" && Array.isArray(data.todos) && data.todos.length <= 64) {
22665
+ const plan = [];
22666
+ for (const value of data.todos) {
22667
+ const item = object2(value);
22668
+ if (typeof item?.content !== "string" || !["pending", "in_progress", "completed"].includes(String(item.status)))
22669
+ return;
22670
+ plan.push({ step: item.content, status: item.status });
22671
+ }
22672
+ deliver(publisher.onPlan("plan", plan));
22673
+ }
22674
+ };
22675
+ return {
22676
+ onEvent(event) {
22677
+ if (event.kind === "assistant-stream")
22678
+ onFrame(event.frame);
22679
+ else
22680
+ onDurable(event.event);
22681
+ },
22682
+ async finish(success2 = true) {
22683
+ await publisher.finish(success2);
22684
+ }
22685
+ };
22686
+ }
22687
+ function parseDshAssistantStreamFrame(value) {
22688
+ const frame = object2(value);
22689
+ if (!identifier(frame?.attemptId) || !integer2(frame?.revision) || Number(frame.revision) < 1)
22690
+ return void 0;
22691
+ const shared = { attemptId: frame.attemptId, revision: Number(frame.revision) };
22692
+ if (frame.type === "start" && integer2(frame.turn) && integer2(frame.step)) {
22693
+ return { type: "start", ...shared, turn: Number(frame.turn), step: Number(frame.step) };
22694
+ }
22695
+ if (frame.type === "chunk" && integer2(frame.index) && integer2(frame.time) && object2(frame.chunk) !== void 0) {
22696
+ return { type: "chunk", ...shared, index: Number(frame.index), time: Number(frame.time), chunk: frame.chunk };
22697
+ }
22698
+ const outcome = object2(frame.outcome);
22699
+ if (frame.type === "end" && integer2(frame.index)) {
22700
+ if (outcome?.kind === "abandoned")
22701
+ return { type: "end", ...shared, index: Number(frame.index), outcome: { kind: "abandoned" } };
22702
+ if (outcome?.kind === "committed" && integer2(outcome.seq) && (outcome.eventType === "assistant/message" || outcome.eventType === "assistant/attempt")) {
22703
+ return { type: "end", ...shared, index: Number(frame.index), outcome: { kind: "committed", eventType: outcome.eventType, seq: Number(outcome.seq) } };
22704
+ }
22705
+ }
22706
+ return void 0;
22707
+ }
22708
+ function publicArguments(text) {
22709
+ return parsedArguments(text) ?? "[Unparseable tool arguments]";
22710
+ }
22711
+ function parsedArguments(text) {
22712
+ if (text.length > MAX_TEXT)
22713
+ return void 0;
22714
+ try {
22715
+ return JSON.stringify(redactValue(JSON.parse(text)));
22716
+ } catch {
22717
+ return void 0;
22718
+ }
22719
+ }
22720
+ function bound2(text) {
22721
+ return text.length > MAX_TEXT ? `${text.slice(0, MAX_TEXT)}
22722
+ [TRUNCATED]` : text;
22723
+ }
22724
+ function integer2(value) {
22725
+ return Number.isSafeInteger(value) && Number(value) >= 0;
22726
+ }
22727
+ function identifier(value) {
22728
+ return typeof value === "string" && value.length > 0 && value.length <= 512;
22729
+ }
22730
+ function object2(value) {
22731
+ return value !== null && typeof value === "object" && !Array.isArray(value) ? value : void 0;
22732
+ }
22733
+
22036
22734
  // dist/src/connector.js
22037
22735
  var INTERRUPTED_REQUEST_CONTINUATION = "Continue the interrupted GatherThread request using the DSH Session context already restored by the Host. Return only the public final answer.";
22038
22736
  var LIVE_PROGRESS_MIN_INTERVAL_MS = 6e4;
@@ -22060,6 +22758,7 @@ var DshHostConnector = class {
22060
22758
  #publicationPromise;
22061
22759
  #heartbeatOffline = false;
22062
22760
  #liveProgressPromise = Promise.resolve();
22761
+ #activeLiveOutput;
22063
22762
  #lastLiveProgressKey;
22064
22763
  #lastLiveProgressAt = 0;
22065
22764
  #stopPromise;
@@ -22070,6 +22769,8 @@ var DshHostConnector = class {
22070
22769
  #activeExecutionSelection;
22071
22770
  #summaryScanSequence = 0;
22072
22771
  #hasSummaryHistory = false;
22772
+ #revisionPollPromise;
22773
+ #revisionSupported = false;
22073
22774
  #liveEventSequences = /* @__PURE__ */ new Set();
22074
22775
  #session;
22075
22776
  #visibleState = "connecting";
@@ -22174,7 +22875,8 @@ var DshHostConnector = class {
22174
22875
  ...executionProfiles === void 0 ? {} : {
22175
22876
  executionProfiles: cloneExecutionProfiles(executionProfiles)
22176
22877
  },
22177
- purpose: "execution"
22878
+ purpose: "execution",
22879
+ ...this.#host.contextDeletionVersion === 1 ? { contextDeletionVersion: 1 } : {}
22178
22880
  };
22179
22881
  }
22180
22882
  get executionRuntimeId() {
@@ -22207,6 +22909,7 @@ var DshHostConnector = class {
22207
22909
  }
22208
22910
  uploadLocalTurns() {
22209
22911
  return this.#withLocalSyncControl(async () => {
22912
+ await this.#refreshContentRevision();
22210
22913
  const before = this.localSyncStatus();
22211
22914
  await this.#flushOutbox(true);
22212
22915
  await this.#captureLocalTurns(0);
@@ -22229,6 +22932,15 @@ var DshHostConnector = class {
22229
22932
  this.#started = true;
22230
22933
  this.#automaticPolling = options.schedule !== false;
22231
22934
  this.#notifyLifecycle("connecting");
22935
+ if (this.#host.onLiveOutput !== void 0) {
22936
+ this.#listenerDisposers.push(this.#host.onLiveOutput((event) => {
22937
+ const active = this.#state?.activeRequest;
22938
+ const output2 = this.#activeLiveOutput;
22939
+ if (this.#stopped || active === void 0 || output2 === void 0 || event.sourceSessionId !== output2.sourceSessionId || event.sourceSessionId !== (active.contextExecution?.sessionId ?? this.#host.sessionId))
22940
+ return;
22941
+ output2.mapper.onEvent(event);
22942
+ }));
22943
+ }
22232
22944
  this.#listenerDisposers.push(this.#host.onSessionEvent((event) => {
22233
22945
  const active = this.#state?.activeRequest;
22234
22946
  if (active?.contextExecution !== void 0 && event.sourceSessionId !== active.contextExecution.sessionId)
@@ -22274,6 +22986,7 @@ var DshHostConnector = class {
22274
22986
  }));
22275
22987
  try {
22276
22988
  const session = await this.#verifySessionBinding();
22989
+ this.#revisionSupported = session.contentRevision !== void 0;
22277
22990
  this.#session = session;
22278
22991
  this.#notifyLifecycle("connecting");
22279
22992
  const storedState = await this.#stateStore.load();
@@ -22281,8 +22994,16 @@ var DshHostConnector = class {
22281
22994
  throw new Error("GatherThread Session head precedes the persisted DSH cursor; refusing identity reuse");
22282
22995
  }
22283
22996
  const mode = await this.#host.open();
22997
+ if (storedState?.projectionSessionId && (storedState.contentRevision ?? 0) > 0) {
22998
+ if (!this.#host.resetCanonicalContext)
22999
+ throw new Error("DSH deletion-safe projection requires an updated native facade");
23000
+ const restored = await this.#host.resetCanonicalContext(storedState.contentRevision);
23001
+ if (restored.sessionId !== storedState.projectionSessionId)
23002
+ throw new Error("DSH restored another native projection");
23003
+ }
22284
23004
  this.#state = this.#reconcileState(storedState, mode);
22285
23005
  await this.#stateStore.save(this.#state);
23006
+ await this.#refreshContentRevision();
22286
23007
  this.#runtime = await this.#api.registerRuntime(this.#runtimeRegistration());
22287
23008
  this.#assertRuntime(this.#runtime);
22288
23009
  this.#notifyLifecycle("idle");
@@ -22354,6 +23075,8 @@ var DshHostConnector = class {
22354
23075
  stop() {
22355
23076
  this.#stopPromise ??= (async () => {
22356
23077
  this.#stopped = true;
23078
+ const liveOutput = this.#activeLiveOutput;
23079
+ this.#activeLiveOutput = void 0;
22357
23080
  this.#notifyLifecycle("stopped");
22358
23081
  this.#lifecycleAbort.abort(new Error("DSH connector stopped"));
22359
23082
  if (this.#timer !== void 0) {
@@ -22367,6 +23090,7 @@ var DshHostConnector = class {
22367
23090
  for (const dispose of this.#listenerDisposers.splice(0))
22368
23091
  dispose();
22369
23092
  await this.#host.dispose();
23093
+ void liveOutput?.mapper.finish(false).catch(() => void 0);
22370
23094
  try {
22371
23095
  await this.#pollPromise;
22372
23096
  } catch {
@@ -22379,6 +23103,7 @@ var DshHostConnector = class {
22379
23103
  return this.#stopPromise;
22380
23104
  }
22381
23105
  async #poll() {
23106
+ await this.#refreshContentRevision();
22382
23107
  const state = this.#requireState();
22383
23108
  if (state.activeRequest !== void 0) {
22384
23109
  await this.#withExecutionPermit(() => this.#recoverActiveRequest());
@@ -22395,6 +23120,12 @@ var DshHostConnector = class {
22395
23120
  let scanned = 0;
22396
23121
  while (!this.#stopped) {
22397
23122
  const page = await this.#api.readEvents(this.#config.sessionId, scanCursor, this.#config.pollLimit);
23123
+ if (page.contentRevision !== void 0)
23124
+ this.#revisionSupported = true;
23125
+ if ((page.contentRevision ?? 0) !== (state.contentRevision ?? 0)) {
23126
+ await this.#refreshContentRevision();
23127
+ return this.#poll();
23128
+ }
22398
23129
  this.#validatePage(page.events, scanCursor);
22399
23130
  const passive = [];
22400
23131
  for (const event of page.events) {
@@ -22428,6 +23159,39 @@ var DshHostConnector = class {
22428
23159
  }
22429
23160
  throw new Error("DSH connector stopped during event replay");
22430
23161
  }
23162
+ async #refreshContentRevision() {
23163
+ const state = this.#requireState();
23164
+ if (!this.#revisionSupported && (state.contentRevision ?? 0) === 0)
23165
+ return;
23166
+ const page = await this.#api.readEvents(this.#config.sessionId, 0, 1);
23167
+ const revision = page.contentRevision ?? 0;
23168
+ if (!Number.isSafeInteger(revision) || revision < (state.contentRevision ?? 0))
23169
+ throw new Error("Stale DSH shared context revision");
23170
+ if (revision === (state.contentRevision ?? 0)) {
23171
+ if (revision > 0 && state.projectionSessionId && this.#host.resetCanonicalContext) {
23172
+ const restored = await this.#host.resetCanonicalContext(revision);
23173
+ if (restored.sessionId !== state.projectionSessionId)
23174
+ throw new Error("DSH clean projection binding changed on reconnect");
23175
+ }
23176
+ return;
23177
+ }
23178
+ state.localOnlySessionIds = [.../* @__PURE__ */ new Set([...state.localOnlySessionIds ?? [], this.#config.dshSessionId, this.#host.sessionId])];
23179
+ state.outbox = [];
23180
+ delete state.activeRequest;
23181
+ this.#activeStatuses = [];
23182
+ this.#activeExecutionSelection = void 0;
23183
+ this.#summaryScanSequence = 0;
23184
+ this.#hasSummaryHistory = false;
23185
+ await this.#stateStore.save(state);
23186
+ if (this.#host.resetCanonicalContext) {
23187
+ const replacement = await this.#host.resetCanonicalContext(revision);
23188
+ state.projectionSessionId = replacement.sessionId;
23189
+ state.projectionCursor = 0;
23190
+ state.publishedDshSequence = this.#host.currentSequence();
23191
+ }
23192
+ state.contentRevision = revision;
23193
+ await this.#stateStore.save(state);
23194
+ }
22431
23195
  async #executeRequest(request, selection) {
22432
23196
  if (this.#stopped)
22433
23197
  throw new Error("DSH connector stopped before claiming an Agent request");
@@ -22446,6 +23210,8 @@ var DshHostConnector = class {
22446
23210
  await this.#projectCanonicalBatch([request], request.sequence);
22447
23211
  return { claimed: false, completed: false };
22448
23212
  }
23213
+ if ((claim2.contentRevision ?? state.contentRevision ?? 0) !== (state.contentRevision ?? 0))
23214
+ throw new Error("context_changed");
22449
23215
  const quotedEvent = request.replyTo ? (await this.#readThroughRequest(request.id, request.sequence)).find((event) => event.id === request.replyTo) : void 0;
22450
23216
  const prompt = buildDshRequestPrompt(request, quotedEvent);
22451
23217
  const context = await this.#contextForRequest(request);
@@ -22458,6 +23224,7 @@ var DshHostConnector = class {
22458
23224
  if (prepared !== void 0 && prepared.fromSequence !== baseline)
22459
23225
  throw new Error("DSH context preparation returned an inconsistent sequence");
22460
23226
  state.activeRequest = {
23227
+ contentRevision: state.contentRevision ?? 0,
22461
23228
  requestId: request.id,
22462
23229
  requestSequence: request.sequence,
22463
23230
  dshFromSequence: baseline,
@@ -22471,7 +23238,7 @@ var DshHostConnector = class {
22471
23238
  this.#activeExecutionSelection = selection;
22472
23239
  this.#liveEventSequences.clear();
22473
23240
  await this.#stateStore.save(state);
22474
- const result = await this.#host.prompt(prompt, selection, prepared?.sessionId);
23241
+ const result = await this.#promptWithLiveOutput(prompt, selection, prepared?.sessionId);
22475
23242
  if (result.fromSequence !== baseline || result.toSequence < result.fromSequence) {
22476
23243
  throw new Error("DSH Host prompt returned an inconsistent durable event range");
22477
23244
  }
@@ -22493,7 +23260,7 @@ var DshHostConnector = class {
22493
23260
  throw new Error("GatherThread history summary request has invalid source metadata");
22494
23261
  if (selectedOnly)
22495
23262
  this.#hasSummaryHistory = true;
22496
- if (!selectedOnly && !await this.#sessionHasSummaryBefore(request.sequence))
23263
+ if (!selectedOnly && (this.#requireState().contentRevision ?? 0) === 0 && !await this.#sessionHasSummaryBefore(request.sequence))
22497
23264
  return void 0;
22498
23265
  if (!selectedOnly && this.#api.readContext === void 0) {
22499
23266
  throw new Error("GatherThread summarized context is unavailable; update the connector before continuing");
@@ -22501,7 +23268,9 @@ var DshHostConnector = class {
22501
23268
  if (this.#host.prepareContextExecution === void 0) {
22502
23269
  throw new Error("DSH isolated context execution is unavailable; refusing to run a summary-aware request in native history");
22503
23270
  }
22504
- const received = selectedOnly ? { view: "original", through_sequence: request.sequence - 1, items: [] } : parseHistoryContext(await this.#api.readContext(this.#config.sessionId, void 0, request.sequence - 1), void 0, request.sequence - 1);
23271
+ const received = selectedOnly ? { view: "original", content_revision: this.#requireState().contentRevision ?? 0, through_sequence: request.sequence - 1, items: [] } : parseHistoryContext(await this.#api.readContext(this.#config.sessionId, void 0, request.sequence - 1), void 0, request.sequence - 1);
23272
+ if ((received.content_revision ?? 0) !== (this.#requireState().contentRevision ?? 0))
23273
+ throw new Error("context_changed");
22505
23274
  const historyContext = { ...received, items: received.items.map((item) => ({ ...item, content: redactText(item.content) })) };
22506
23275
  return { historyContext, selectedOnly };
22507
23276
  }
@@ -22599,6 +23368,10 @@ var DshHostConnector = class {
22599
23368
  throw new Error("Active GatherThread request no longer has a recoverable claim");
22600
23369
  }
22601
23370
  const claimAttempt = claim2.attemptCount ?? active.claimAttempt ?? 1;
23371
+ if ((active.contentRevision ?? 0) !== (state.contentRevision ?? 0) || (claim2.contentRevision ?? active.contentRevision ?? 0) !== (active.contentRevision ?? 0)) {
23372
+ await this.#retireFencedActiveRequest(state, active);
23373
+ return;
23374
+ }
22602
23375
  active.claimAttempt = claimAttempt;
22603
23376
  if (active.dshToSequence !== void 0) {
22604
23377
  state.outbox = state.outbox.map((operation) => {
@@ -22671,7 +23444,7 @@ var DshHostConnector = class {
22671
23444
  this.#activeStatuses = [];
22672
23445
  this.#liveEventSequences.clear();
22673
23446
  await this.#stateStore.save(state);
22674
- const result = await this.#host.prompt(continuation, selection, execution?.sessionId);
23447
+ const result = await this.#promptWithLiveOutput(continuation, selection, execution?.sessionId);
22675
23448
  if (result.fromSequence !== baseline || result.toSequence < result.fromSequence) {
22676
23449
  throw new Error("DSH Host recovery prompt returned an inconsistent durable event range");
22677
23450
  }
@@ -22700,6 +23473,94 @@ var DshHostConnector = class {
22700
23473
  await this.#flushOutbox();
22701
23474
  await this.#finalizeDeliveredRequest();
22702
23475
  }
23476
+ async #promptWithLiveOutput(text, selection, executionSessionId) {
23477
+ const active = this.#requireState().activeRequest;
23478
+ if (active === void 0)
23479
+ throw new Error("No claimed DSH request owns live output");
23480
+ const requestId = active.requestId;
23481
+ const claimAttempt = active.claimAttempt ?? 1;
23482
+ const fromSequence = active.dshFromSequence;
23483
+ const runtime = this.#requireRuntime();
23484
+ const sourceSessionId = executionSessionId ?? this.#host.sessionId;
23485
+ const publisher = createLiveOutputPublisher({
23486
+ publish: async (update) => {
23487
+ const publication = this.#liveProgressPromise.then(async () => {
23488
+ const current = this.#state?.activeRequest;
23489
+ if (this.#stopped || this.#activeLiveOutput?.publisher !== publisher || current?.requestId !== requestId || (current.claimAttempt ?? 1) !== claimAttempt || current.dshFromSequence !== fromSequence || (current.contextExecution?.sessionId ?? this.#host.sessionId) !== sourceSessionId || this.#runtime?.id !== runtime.id || this.#activeExecutionSelection !== selection)
23490
+ return false;
23491
+ await this.#api.appendAgentProgress(this.#config.sessionId, requestId, {
23492
+ runtimeId: runtime.id,
23493
+ claimAttempt,
23494
+ contentRevision: active.contentRevision ?? 0,
23495
+ idempotencyKey: `${this.#config.deviceId}:${digest(requestId).slice(0, 24)}:${claimAttempt}:live-${update.id}`,
23496
+ payload: { ...liveOutputPayload(update), capture_fidelity: "harness_transcript", source_harness: "deepseek-harness" },
23497
+ observedModel: selection.model,
23498
+ ...selection.reasoningEffort === void 0 ? {} : { observedReasoningEffort: selection.reasoningEffort }
23499
+ });
23500
+ return true;
23501
+ });
23502
+ this.#liveProgressPromise = publication.then(() => void 0).catch((error62) => {
23503
+ this.#onBackgroundError?.(publicError(error62));
23504
+ });
23505
+ return publication.catch(() => false);
23506
+ }
23507
+ });
23508
+ const output2 = { publisher, mapper: createDshLiveEventMapper(publisher), sourceSessionId };
23509
+ this.#activeLiveOutput = output2;
23510
+ const abort = new AbortController();
23511
+ const abortLifecycle = () => abort.abort(this.#lifecycleAbort.signal.reason);
23512
+ this.#lifecycleAbort.signal.addEventListener("abort", abortLifecycle, { once: true });
23513
+ const verifyRevision = async () => {
23514
+ if (!this.#revisionSupported && (active.contentRevision ?? 0) === 0)
23515
+ return;
23516
+ try {
23517
+ const page = await this.#api.readEvents(this.#config.sessionId, 0, 1);
23518
+ if ((page.contentRevision ?? 0) !== (active.contentRevision ?? 0))
23519
+ abort.abort(new Error("context_changed"));
23520
+ } catch (error62) {
23521
+ abort.abort(error62);
23522
+ }
23523
+ };
23524
+ const timer = setInterval(() => {
23525
+ if (this.#revisionPollPromise)
23526
+ return;
23527
+ const poll = verifyRevision();
23528
+ this.#revisionPollPromise = poll;
23529
+ void poll.finally(() => {
23530
+ if (this.#revisionPollPromise === poll)
23531
+ this.#revisionPollPromise = void 0;
23532
+ });
23533
+ }, 1e3);
23534
+ timer.unref();
23535
+ try {
23536
+ await verifyRevision();
23537
+ abort.signal.throwIfAborted();
23538
+ const result = await this.#host.prompt(text, selection, executionSessionId, abort.signal);
23539
+ await verifyRevision();
23540
+ abort.signal.throwIfAborted();
23541
+ await output2.mapper.finish();
23542
+ return result;
23543
+ } catch (error62) {
23544
+ if (abort.signal.aborted) {
23545
+ const state = this.#requireState();
23546
+ state.outbox = state.outbox.filter((operation) => !outboxBelongsToRequest(operation, requestId));
23547
+ delete state.activeRequest;
23548
+ this.#activeExecutionSelection = void 0;
23549
+ await this.#stateStore.save(state);
23550
+ }
23551
+ throw error62;
23552
+ } finally {
23553
+ clearInterval(timer);
23554
+ this.#lifecycleAbort.signal.removeEventListener("abort", abortLifecycle);
23555
+ await this.#revisionPollPromise;
23556
+ if (this.#activeLiveOutput === output2)
23557
+ this.#activeLiveOutput = void 0;
23558
+ if (this.#stopped)
23559
+ void output2.mapper.finish(false).catch(() => void 0);
23560
+ else
23561
+ await output2.mapper.finish(false);
23562
+ }
23563
+ }
22703
23564
  #queueLiveProgress(idSuffix, payload, throttle = true) {
22704
23565
  const active = this.#state?.activeRequest;
22705
23566
  const runtime = this.#runtime;
@@ -22709,6 +23570,9 @@ var DshHostConnector = class {
22709
23570
  const claimAttempt = active.claimAttempt ?? 1;
22710
23571
  const progressKey = `${requestId}:${String(claimAttempt)}`;
22711
23572
  const now = Date.now();
23573
+ const streamedAt = this.#activeLiveOutput?.publisher.lastPublishedAt();
23574
+ if (throttle && streamedAt !== void 0 && now - streamedAt < LIVE_PROGRESS_MIN_INTERVAL_MS)
23575
+ return;
22712
23576
  if (throttle && this.#lastLiveProgressKey === progressKey && now - this.#lastLiveProgressAt < LIVE_PROGRESS_MIN_INTERVAL_MS) {
22713
23577
  return;
22714
23578
  }
@@ -22719,7 +23583,7 @@ var DshHostConnector = class {
22719
23583
  const idempotencyKey = `${this.#config.deviceId}:${digest(requestId).slice(0, 24)}:${String(claimAttempt)}:${idSuffix}`;
22720
23584
  this.#liveProgressPromise = this.#liveProgressPromise.then(async () => {
22721
23585
  const current = this.#state?.activeRequest;
22722
- if (current?.requestId !== requestId || (current.claimAttempt ?? 1) !== claimAttempt)
23586
+ if (this.#stopped || current?.requestId !== requestId || (current.claimAttempt ?? 1) !== claimAttempt || this.#runtime?.id !== runtime.id)
22723
23587
  return;
22724
23588
  const selection = this.#activeExecutionSelection;
22725
23589
  if (selection === void 0)
@@ -22727,6 +23591,7 @@ var DshHostConnector = class {
22727
23591
  await this.#api.appendAgentProgress(this.#config.sessionId, requestId, {
22728
23592
  runtimeId: runtime.id,
22729
23593
  claimAttempt,
23594
+ contentRevision: active.contentRevision ?? 0,
22730
23595
  idempotencyKey,
22731
23596
  payload,
22732
23597
  observedModel: selection.model,
@@ -22744,11 +23609,15 @@ var DshHostConnector = class {
22744
23609
  }
22745
23610
  async #projectCanonicalBatch(events, throughSequence) {
22746
23611
  const state = this.#requireState();
23612
+ if (state.localOnlySessionIds?.includes(this.#host.sessionId))
23613
+ return;
22747
23614
  if (throughSequence <= state.projectionCursor)
22748
23615
  return;
22749
23616
  const runtime = this.#requireRuntime();
22750
23617
  const projections = [];
22751
23618
  for (const event of events) {
23619
+ if (event.deleted)
23620
+ continue;
22752
23621
  if (event.type === "agent_request" && asObject3(event.payload)?.history_summary !== void 0) {
22753
23622
  this.#hasSummaryHistory = true;
22754
23623
  continue;
@@ -22793,6 +23662,8 @@ var DshHostConnector = class {
22793
23662
  }
22794
23663
  async #captureLocalTurns(basedOnSequence) {
22795
23664
  const state = this.#requireState();
23665
+ if (state.localOnlySessionIds?.includes(this.#host.sessionId))
23666
+ return;
22796
23667
  if (state.activeRequest !== void 0 || state.outbox.length > 0)
22797
23668
  return;
22798
23669
  const current = this.#host.currentSequence();
@@ -22809,6 +23680,7 @@ var DshHostConnector = class {
22809
23680
  input: {
22810
23681
  localTurnId: turn.localTurnId,
22811
23682
  runtimeId: runtime.id,
23683
+ contentRevision: state.contentRevision ?? 0,
22812
23684
  basedOnSequence: basedOnSequence ?? state.serverCursor,
22813
23685
  occurredAt: turn.occurredAt,
22814
23686
  observedModel: this.#config.model,
@@ -22922,7 +23794,10 @@ var DshHostConnector = class {
22922
23794
  }
22923
23795
  }
22924
23796
  });
22925
- return operations;
23797
+ return operations.map((operation) => ({
23798
+ ...operation,
23799
+ input: { ...operation.input, contentRevision: this.#requireState().activeRequest?.contentRevision ?? 0 }
23800
+ }));
22926
23801
  }
22927
23802
  async #flushOutbox(includeLocalTurns = true) {
22928
23803
  const state = this.#requireState();
@@ -22931,6 +23806,11 @@ var DshHostConnector = class {
22931
23806
  const operation = state.outbox[0];
22932
23807
  if (operation === void 0)
22933
23808
  break;
23809
+ if ((operation.input.contentRevision ?? 0) !== (state.contentRevision ?? 0) || operation.kind === "local_turn" && state.localOnlySessionIds?.includes(this.#host.sessionId)) {
23810
+ state.outbox.shift();
23811
+ await this.#stateStore.save(state);
23812
+ continue;
23813
+ }
22934
23814
  if (operation.kind === "local_turn" && !includeLocalTurns)
22935
23815
  break;
22936
23816
  if (operation.input.runtimeId !== runtime.id) {
@@ -23332,16 +24212,16 @@ function asObject3(value) {
23332
24212
  }
23333
24213
 
23334
24214
  // dist/src/dsh-compat.js
23335
- import { createHash as createHash4 } from "node:crypto";
24215
+ import { createHash as createHash4, randomUUID as randomUUID2 } from "node:crypto";
23336
24216
  var DSH_COMPATIBILITY = Object.freeze({
23337
- tag: "dsh-v0.1.3-alpha.1",
23338
- version: "0.1.3-alpha.1",
23339
- commit: "d347e703908d0406b7a7ef80e3a0e594d86b2215",
24217
+ tag: "dsh-v0.1.7-rc.2",
24218
+ version: "0.1.7-rc.2",
24219
+ commit: "477b4f420553e8a52c2fbccc464d7561b239c443",
23340
24220
  profile: "headless"
23341
24221
  });
23342
24222
  var DSH_NPM_COMPATIBILITY = Object.freeze({
23343
24223
  package: "@deepseek-ai/dsh",
23344
- version: "0.1.2-rc.1",
24224
+ version: "0.1.7-rc.2",
23345
24225
  profile: "web",
23346
24226
  persistenceProbe: "list"
23347
24227
  });
@@ -23371,16 +24251,19 @@ function createDshHostFacade(options) {
23371
24251
  const sessionTitle = options.sessionTitle === void 0 ? void 0 : requireService(context, "sessionTitle", ["rename"]);
23372
24252
  const workspaceRegistry = options.workspaceTitle === void 0 ? void 0 : requireService(context, "workspaceRegistry", ["create"]);
23373
24253
  const eventSubscribers = /* @__PURE__ */ new Set();
24254
+ const liveSubscribers = /* @__PURE__ */ new Set();
23374
24255
  const statusSubscribers = /* @__PURE__ */ new Set();
23375
24256
  const listenerDisposers = [];
23376
24257
  const lifecycleAbort = new AbortController();
23377
24258
  let handle;
23378
24259
  let executionHandle;
23379
- let contextPreparationPromise;
24260
+ let nativeSessionId = options.sessionId;
24261
+ let contentRevision = 0;
24262
+ let contextOperationPromise;
23380
24263
  const executionBinding = JSON.stringify({ nativeSessionId: options.sessionId, ...options.contextBinding });
23381
- const executionSessionId = `gatherthread-execution-${createHash4("sha256").update(executionBinding).digest("hex").slice(0, 32)}`;
23382
- const executionOwnerId = `gatherthread-execution-owner:${createHash4("sha256").update(executionBinding).digest("hex")}`;
23383
- const executionOwnerText = JSON.stringify({
24264
+ let executionSessionId = `gatherthread-execution-${createHash4("sha256").update(executionBinding).digest("hex").slice(0, 32)}`;
24265
+ let executionOwnerId = `gatherthread-execution-owner:${createHash4("sha256").update(executionBinding).digest("hex")}`;
24266
+ let executionOwnerText = JSON.stringify({
23384
24267
  version: 1,
23385
24268
  owner: "gatherthread",
23386
24269
  native_session_id: options.sessionId,
@@ -23393,19 +24276,76 @@ function createDshHostFacade(options) {
23393
24276
  let knownProjectionMessageIds;
23394
24277
  let disposePromise;
23395
24278
  let disposed = false;
24279
+ let livePrompt;
24280
+ const emitLive = (owner, event) => {
24281
+ if (disposed || livePrompt !== owner || owner.closed)
24282
+ return;
24283
+ for (const subscriber of liveSubscribers)
24284
+ subscriber(event);
24285
+ };
23396
24286
  listenerDisposers.push(context.on("session/event", (...args) => {
23397
24287
  const session = asSession(args[0]);
23398
24288
  const event = asSessionEvent(args[1]);
23399
- if (session === void 0 || session.id !== options.sessionId && session.id !== executionHandle?.agent.session.id || event === void 0)
24289
+ if (session === void 0 || session.id !== nativeSessionId && session.id !== executionHandle?.agent.session.id || event === void 0)
23400
24290
  return;
23401
24291
  for (const subscriber of eventSubscribers)
23402
24292
  subscriber({ ...event, sourceSessionId: session.id });
24293
+ const owner = livePrompt;
24294
+ if (owner === void 0 || owner.closed || session !== owner.agent.session)
24295
+ return;
24296
+ const data = asObject4(event.data);
24297
+ if (event.type === "turn/start" && owner.turn === void 0 && Number.isSafeInteger(data?.turn)) {
24298
+ owner.turn = Number(data.turn);
24299
+ }
24300
+ if (owner.turn === void 0 || data?.turn !== void 0 && data.turn !== owner.turn)
24301
+ return;
24302
+ if (event.type === "step/start" && Number.isSafeInteger(data?.step))
24303
+ owner.step = Number(data.step);
24304
+ if (["assistant/message", "assistant/attempt", "tool/call", "tool/result", "todo/write"].includes(event.type)) {
24305
+ emitLive(owner, { kind: "session-event", sourceSessionId: session.id, event });
24306
+ }
24307
+ if (event.type === "turn/end")
24308
+ owner.closed = true;
24309
+ }, { global: true }));
24310
+ listenerDisposers.push(context.on("agent/assistant-stream", (...args) => {
24311
+ const owner = livePrompt;
24312
+ const payload = asObject4(args[0]);
24313
+ if (owner === void 0 || !owner.nativeFrames || owner.turn === void 0 || payload?.agent !== owner.agent)
24314
+ return;
24315
+ const frame = parseDshAssistantStreamFrame(payload.frame);
24316
+ if (frame === void 0 || frame.type === "start" && frame.turn !== owner.turn)
24317
+ return;
24318
+ emitLive(owner, { kind: "assistant-stream", sourceSessionId: owner.agent.session.id, frame });
24319
+ }, { global: true }));
24320
+ listenerDisposers.push(context.on("llm/stream", (...args) => {
24321
+ const request = asObject4(args[0]);
24322
+ const next = args[1];
24323
+ if (typeof next !== "function")
24324
+ return;
24325
+ const stream = next();
24326
+ const owner = livePrompt;
24327
+ if (owner === void 0 || owner.nativeFrames || owner.closed || owner.turn === void 0 || owner.step === void 0 || owner.isLoopRequest === void 0 || request === void 0 || !Object.isFrozen(args[0]) || request.sessionId !== owner.agent.session.id || request.provider !== owner.provider || request.model !== owner.model || typeof agents.get !== "function" || agents.get(owner.agent.session.id) !== owner.agent || !owner.isLoopRequest(args[0]))
24328
+ return stream;
24329
+ const attemptId = randomUUID2();
24330
+ const publish = (frame) => emitLive(owner, {
24331
+ kind: "assistant-stream",
24332
+ sourceSessionId: owner.agent.session.id,
24333
+ frame
24334
+ });
24335
+ return (async function* () {
24336
+ let index = 0;
24337
+ publish({ type: "start", attemptId, revision: ++owner.revision, turn: owner.turn, step: owner.step });
24338
+ for await (const chunk of stream) {
24339
+ publish({ type: "chunk", attemptId, revision: ++owner.revision, index: index++, time: Date.now(), chunk });
24340
+ yield chunk;
24341
+ }
24342
+ })();
23403
24343
  }, { global: true }));
23404
24344
  listenerDisposers.push(context.on("agent/status", (...args) => {
23405
24345
  const payload = asObject4(args[0]);
23406
24346
  const agent = payload ? asAgent(payload.agent) : void 0;
23407
24347
  const status = payload?.status;
23408
- if (agent === void 0 || agent.session.id !== options.sessionId && agent.session.id !== executionHandle?.agent.session.id || status !== "running" && status !== "idle")
24348
+ if (agent === void 0 || agent.session.id !== nativeSessionId && agent.session.id !== executionHandle?.agent.session.id || status !== "running" && status !== "idle")
23409
24349
  return;
23410
24350
  for (const subscriber of statusSubscribers)
23411
24351
  subscriber(status, agent.session.id);
@@ -23417,7 +24357,7 @@ function createDshHostFacade(options) {
23417
24357
  await releaseHandle();
23418
24358
  throw new Error("DSH host facade was disposed during open");
23419
24359
  }
23420
- if (acquired.agent.session.id !== options.sessionId) {
24360
+ if (acquired.agent.session.id !== nativeSessionId) {
23421
24361
  await releaseHandle();
23422
24362
  throw new Error("DSH Host returned an agent for an unexpected Session identity");
23423
24363
  }
@@ -23444,13 +24384,13 @@ function createDshHostFacade(options) {
23444
24384
  const parent = requireAgent(handle);
23445
24385
  if (parent.status !== "idle")
23446
24386
  throw new Error("Native DSH Agent must be idle before isolated context execution");
23447
- if (parent.session.header?.cwd !== options.workspacePath || agents.get?.(options.sessionId) !== parent) {
24387
+ if (parent.session.header?.cwd !== options.workspacePath || agents.get?.(nativeSessionId) !== parent) {
23448
24388
  throw new Error("Native DSH workspace or live owner does not match the isolated context binding");
23449
24389
  }
23450
24390
  };
23451
24391
  const assertExecutionOwnership = (agent) => {
23452
24392
  const session = agent.session;
23453
- if (session.id !== executionSessionId || session.header?.cwd !== options.workspacePath || session.header.parentSession !== options.sessionId || session.header.origin !== "subagent") {
24393
+ if (session.id !== executionSessionId || session.header?.cwd !== options.workspacePath || session.header.parentSession !== nativeSessionId || session.header.origin !== "subagent") {
23454
24394
  throw new Error("DSH isolated execution Session ownership does not match this native binding");
23455
24395
  }
23456
24396
  if (agents.get !== void 0 && agents.get(executionSessionId) !== agent) {
@@ -23471,6 +24411,118 @@ function createDshHostFacade(options) {
23471
24411
  throw new Error("DSH isolated execution Session contains local manual input; refusing to replace or execute it");
23472
24412
  }
23473
24413
  };
24414
+ const recordedRevision = (session) => session.snapshotEvents(0).reduce((highest, value) => {
24415
+ const event = asObject4(value), data = asObject4(event?.data);
24416
+ const id = data?.id;
24417
+ if (event?.type !== "user/message" || typeof id !== "string" || !/^gatherthread-retired:[0-9]+$/.test(id) || asObject4(data?.source)?.kind !== "plugin" || asObject4(data?.source)?.plugin !== "gatherthread")
24418
+ return highest;
24419
+ const revision = Number(id.slice("gatherthread-retired:".length));
24420
+ return Number.isSafeInteger(revision) ? Math.max(highest, revision) : highest;
24421
+ }, 0);
24422
+ const resetCanonicalContext = async (revision) => {
24423
+ if (!Number.isSafeInteger(revision) || revision < 1 || revision < contentRevision)
24424
+ throw new Error("Stale DSH content revision");
24425
+ if (options.contextBinding === void 0 || Object.values(options.contextBinding).some((value) => !value) || typeof agents.get !== "function")
24426
+ throw new Error("DSH context reset requires an explicit owned GatherThread binding");
24427
+ throwIfDisposed(disposed, lifecycleAbort.signal, "projection");
24428
+ await open3();
24429
+ throwIfDisposed(disposed, lifecycleAbort.signal, "projection");
24430
+ if (promptActive || projectionActive)
24431
+ throw new Error("Wait for the active DSH turn before replacing its projection");
24432
+ const parent = requireAgent(handle);
24433
+ if (revision < recordedRevision(parent.session))
24434
+ throw new Error("Retired DSH revision cannot resume");
24435
+ assertExecutionParentIdle();
24436
+ const targetId = `gatherthread-projection-${createHash4("sha256").update(`${executionBinding}:${revision}`).digest("hex").slice(0, 32)}`;
24437
+ if (nativeSessionId === targetId && contentRevision === revision)
24438
+ return { sessionId: targetId };
24439
+ const ownerId = `gatherthread-projection-owner:${createHash4("sha256").update(`${executionBinding}:${revision}`).digest("hex")}`;
24440
+ const ownerText = JSON.stringify({ version: 1, binding: options.contextBinding, native_session_id: options.sessionId, content_revision: revision });
24441
+ projectionActive = true;
24442
+ let candidate;
24443
+ try {
24444
+ const retired = await createIsolatedMessage(`gatherthread-retired:${revision}`, "GatherThread retired this context. Continue here locally only.", options);
24445
+ throwIfDisposed(disposed, lifecycleAbort.signal, "projection");
24446
+ if (recordedRevision(parent.session) < revision) {
24447
+ parent.session.append("user/message", retired, { surfaceOp: "append" });
24448
+ await sessions.flush(parent.session);
24449
+ throwIfDisposed(disposed, lifecycleAbort.signal, "projection");
24450
+ }
24451
+ if (agents.get?.(targetId) !== void 0)
24452
+ throw new Error("DSH clean projection already has another live owner");
24453
+ const stored = await hasPersistedSession(persistence, targetId, lifecycleAbort.signal);
24454
+ throwIfDisposed(disposed, lifecycleAbort.signal, "projection");
24455
+ const presets = asObject4(context.get("agentPresets"));
24456
+ const setup = (ctx) => {
24457
+ if (presets !== void 0) {
24458
+ if (typeof presets.composeFrom !== "function" || typeof presets.composedPreset !== "function")
24459
+ throw new Error("Native DSH tool inheritance unavailable");
24460
+ const expected = presets.composedPreset(parent.ctx);
24461
+ if (presets.composeFrom(ctx, parent.ctx) !== expected)
24462
+ throw new Error("DSH clean projection did not inherit native tools");
24463
+ }
24464
+ };
24465
+ candidate = await (stored ? agents.resume({
24466
+ resumeSessionId: targetId,
24467
+ agentOptions: { provider: options.provider, model: options.model },
24468
+ signal: lifecycleAbort.signal,
24469
+ setup
24470
+ }) : agents.create({
24471
+ sessionId: targetId,
24472
+ meta: { cwd: options.workspacePath, parentSession: options.sessionId, origin: "subagent" },
24473
+ agentOptions: { provider: options.provider, model: options.model },
24474
+ signal: lifecycleAbort.signal,
24475
+ setup
24476
+ }));
24477
+ throwIfDisposed(disposed, lifecycleAbort.signal, "projection");
24478
+ const agent = candidate.agent;
24479
+ if (agent.session.id !== targetId || agent.session.header?.cwd !== options.workspacePath || agent.status !== "idle" || agent.session.header.parentSession !== options.sessionId || agent.session.header.origin !== "subagent" || agents.get?.(targetId) !== agent)
24480
+ throw new Error("DSH clean projection ownership is invalid");
24481
+ if (!stored) {
24482
+ if (agent.session.seq !== 0)
24483
+ throw new Error("DSH clean projection is not fresh");
24484
+ const owner = await createIsolatedMessage(ownerId, ownerText, options);
24485
+ throwIfDisposed(disposed, lifecycleAbort.signal, "projection");
24486
+ agent.session.append("user/message", owner, { surfaceOp: "append" });
24487
+ }
24488
+ const events = agent.session.snapshotEvents(0).map(asObject4);
24489
+ if (!events.some((event) => {
24490
+ const data = asObject4(event?.data), source = asObject4(data?.source);
24491
+ return event?.type === "user/message" && data?.id === ownerId && source?.kind === "plugin" && source.plugin === "gatherthread" && Array.isArray(data?.content) && data.content.length === 1 && asObject4(data.content[0])?.text === ownerText;
24492
+ })) {
24493
+ throw new Error("DSH clean projection is missing its durable owner marker");
24494
+ }
24495
+ await sessions.flush(agent.session);
24496
+ throwIfDisposed(disposed, lifecycleAbort.signal, "projection");
24497
+ if (sessionTitle && options.sessionTitle) {
24498
+ await sessionTitle.rename(agent.session, options.sessionTitle);
24499
+ throwIfDisposed(disposed, lifecycleAbort.signal, "projection");
24500
+ }
24501
+ if (workspaceRegistry && options.workspaceTitle) {
24502
+ const workspace = await workspaceRegistry.create(options.workspacePath, options.workspaceTitle);
24503
+ throwIfDisposed(disposed, lifecycleAbort.signal, "projection");
24504
+ await workspace.attachSession(targetId);
24505
+ throwIfDisposed(disposed, lifecycleAbort.signal, "projection");
24506
+ }
24507
+ throwIfDisposed(disposed, lifecycleAbort.signal, "projection");
24508
+ await releaseExecutionHandle();
24509
+ throwIfDisposed(disposed, lifecycleAbort.signal, "projection");
24510
+ await releaseHandle();
24511
+ throwIfDisposed(disposed, lifecycleAbort.signal, "projection");
24512
+ handle = candidate;
24513
+ candidate = void 0;
24514
+ nativeSessionId = targetId;
24515
+ contentRevision = revision;
24516
+ knownProjectionMessageIds = void 0;
24517
+ return { sessionId: targetId };
24518
+ } finally {
24519
+ try {
24520
+ await candidate?.dispose();
24521
+ } finally {
24522
+ projectionActive = false;
24523
+ }
24524
+ }
24525
+ };
23474
24526
  const prepareContextExecution = async (input2) => {
23475
24527
  if (disposed)
23476
24528
  throw new Error("DSH host facade is disposed");
@@ -23491,6 +24543,30 @@ function createDshHostFacade(options) {
23491
24543
  if (disposed || promptActive || projectionActive)
23492
24544
  throw new Error("DSH host facade permits only one active write");
23493
24545
  const parent = requireAgent(handle);
24546
+ const revision = historyContext.content_revision ?? 0;
24547
+ if (revision < Math.max(contentRevision, recordedRevision(parent.session)))
24548
+ throw new Error("Stale retired DSH context revision");
24549
+ if (revision !== contentRevision || revision > 0 && !executionSessionId.endsWith(createHash4("sha256").update(`${executionBinding}:${revision}`).digest("hex").slice(0, 32))) {
24550
+ await releaseExecutionHandle();
24551
+ throwIfDisposed(disposed, lifecycleAbort.signal, "projection");
24552
+ contentRevision = revision;
24553
+ const binding = `${executionBinding}:${revision}`;
24554
+ executionSessionId = `gatherthread-execution-${createHash4("sha256").update(binding).digest("hex").slice(0, 32)}`;
24555
+ executionOwnerId = `gatherthread-execution-owner:${createHash4("sha256").update(binding).digest("hex")}`;
24556
+ executionOwnerText = JSON.stringify({
24557
+ version: 1,
24558
+ owner: "gatherthread",
24559
+ native_session_id: options.sessionId,
24560
+ execution_session_id: executionSessionId,
24561
+ binding: options.contextBinding,
24562
+ content_revision: revision
24563
+ });
24564
+ const marker = await createIsolatedMessage(`gatherthread-retired:${revision}`, "GatherThread previous execution context is local only.", options);
24565
+ throwIfDisposed(disposed, lifecycleAbort.signal, "projection");
24566
+ parent.session.append("user/message", marker, { surfaceOp: "append" });
24567
+ await sessions.flush(parent.session);
24568
+ throwIfDisposed(disposed, lifecycleAbort.signal, "projection");
24569
+ }
23494
24570
  assertExecutionParentIdle();
23495
24571
  const presets = asObject4(context.get("agentPresets"));
23496
24572
  let parentPreset;
@@ -23499,7 +24575,8 @@ function createDshHostFacade(options) {
23499
24575
  throw new Error("Pinned DSH public preset inheritance API is unavailable; refusing an isolated Agent without native tools");
23500
24576
  }
23501
24577
  parentPreset = presets.composedPreset(parent.ctx);
23502
- if (parentPreset === void 0 && (!Array.isArray(presets.roots) || presets.roots.length > 0)) {
24578
+ const roots = Array.isArray(presets.roots) ? presets.roots : void 0;
24579
+ if (parentPreset === void 0 && roots !== void 0 && roots.length > 0) {
23503
24580
  throw new Error("Native DSH Agent has no composed preset; restore its tool composition before using summarized context");
23504
24581
  }
23505
24582
  }
@@ -23533,7 +24610,7 @@ function createDshHostFacade(options) {
23533
24610
  sessionId: executionSessionId,
23534
24611
  meta: {
23535
24612
  cwd: options.workspacePath,
23536
- parentSession: options.sessionId,
24613
+ parentSession: nativeSessionId,
23537
24614
  origin: "subagent",
23538
24615
  ...parentPreset === void 0 ? {} : { agentPreset: parentPreset }
23539
24616
  },
@@ -23547,7 +24624,7 @@ function createDshHostFacade(options) {
23547
24624
  }
23548
24625
  const agent2 = operationAgent(executionSessionId);
23549
24626
  if (!stored) {
23550
- if (agent2.session.id !== executionSessionId || agent2.session.seq !== 0 || agent2.session.header?.parentSession !== options.sessionId || agent2.session.header.origin !== "subagent" || agent2.session.header.cwd !== options.workspacePath || agent2.status !== "idle") {
24627
+ if (agent2.session.id !== executionSessionId || agent2.session.seq !== 0 || agent2.session.header?.parentSession !== nativeSessionId || agent2.session.header.origin !== "subagent" || agent2.session.header.cwd !== options.workspacePath || agent2.status !== "idle") {
23551
24628
  throw new Error("DSH did not create a fresh, owned isolated execution Session");
23552
24629
  }
23553
24630
  const ownerMessage = await createIsolatedMessage(executionOwnerId, executionOwnerText, options);
@@ -23583,7 +24660,7 @@ ${JSON.stringify(historyContext.items)}`;
23583
24660
  const nodes = agent.session.surface?.nodes;
23584
24661
  if (!Array.isArray(nodes) || nodes.some((seq) => !Number.isSafeInteger(seq) || seq < 0 || seq >= agent.session.seq) || new Set(nodes).size !== nodes.length)
23585
24662
  throw new Error("Pinned DSH public Session surface API is unavailable or invalid");
23586
- agent.session.append("user/message", message, nodes.length === 0 ? { surfaceOp: "append" } : { surfaceOp: { op: "replace", start: nodes[0], end: nodes.at(-1) }, sourceEventSeqs: [...nodes] });
24663
+ agent.session.append("user/message", message, nodes.length === 0 ? { surfaceOp: "append" } : { surfaceOp: { op: "replace", startSeq: nodes[0], endSeq: nodes.at(-1) }, sourceEventSeqs: [...nodes] });
23587
24664
  }
23588
24665
  await sessions.flush(agent.session);
23589
24666
  throwIfDisposed(disposed, lifecycleAbort.signal, "projection");
@@ -23592,11 +24669,11 @@ ${JSON.stringify(historyContext.items)}`;
23592
24669
  projectionActive = false;
23593
24670
  }
23594
24671
  };
23595
- const setupNativeAgent = async (agentContext) => {
24672
+ const setupNativeAgent = async (agentContext, agentValue) => {
23596
24673
  const presets = asObject4(context.get("agentPresets"));
23597
24674
  if (presets === void 0 || Array.isArray(presets.roots) && presets.roots.length === 0)
23598
24675
  return;
23599
- const agent = asAgent(asObject4(agentContext)?.agent);
24676
+ const agent = asAgent(agentValue);
23600
24677
  const projections = asObject4(context.get("sessionProjections"));
23601
24678
  if (agent === void 0 || typeof presets.mount !== "function" || typeof projections?.stateOf !== "function") {
23602
24679
  throw new Error("Pinned DSH public native preset composition API is unavailable");
@@ -23699,7 +24776,8 @@ ${JSON.stringify(historyContext.items)}`;
23699
24776
  return parsed;
23700
24777
  });
23701
24778
  };
23702
- const prompt = async (text, requestedSelection, requestedExecutionId) => {
24779
+ const prompt = async (text, requestedSelection, requestedExecutionId, signal) => {
24780
+ signal?.throwIfAborted();
23703
24781
  if (disposed)
23704
24782
  throw new Error("DSH host facade is disposed");
23705
24783
  if (!text.trim())
@@ -23714,11 +24792,15 @@ ${JSON.stringify(historyContext.items)}`;
23714
24792
  promptActive = true;
23715
24793
  let disposeSelection;
23716
24794
  let selectionRef;
24795
+ let abortPrompt;
23717
24796
  try {
23718
24797
  if (requestedExecutionId === void 0)
23719
24798
  await open3();
23720
24799
  throwIfDisposed(disposed, lifecycleAbort.signal, "prompt");
23721
24800
  const agent = operationAgent(requestedExecutionId);
24801
+ signal?.throwIfAborted();
24802
+ if (signal && typeof agent.cancel !== "function")
24803
+ throw new Error("DSH public cancel API is required for deletion-safe execution");
23722
24804
  if (requestedExecutionId !== void 0) {
23723
24805
  assertExecutionParentIdle();
23724
24806
  assertExecutionOwnership(agent);
@@ -23744,8 +24826,41 @@ ${JSON.stringify(historyContext.items)}`;
23744
24826
  assertExecutionParentIdle();
23745
24827
  assertExecutionOwnership(agent);
23746
24828
  }
24829
+ if (liveSubscribers.size > 0) {
24830
+ let imported;
24831
+ try {
24832
+ imported = asObject4(await (options.moduleImporter ?? importDshModule)(USER_MESSAGE_MODULE));
24833
+ } catch {
24834
+ }
24835
+ throwIfDisposed(disposed, lifecycleAbort.signal, "prompt");
24836
+ if (agent.status !== "idle" || agent.session.seq !== fromSequence)
24837
+ throw new Error("DSH Agent changed while preparing live output");
24838
+ livePrompt = {
24839
+ agent,
24840
+ closed: false,
24841
+ revision: 0,
24842
+ nativeFrames: typeof imported?.expandAssistantStream === "function",
24843
+ ...typeof imported?.isAgentLoopRequest === "function" ? { isLoopRequest: imported.isAgentLoopRequest } : {},
24844
+ provider: requestedSelection?.provider ?? options.provider,
24845
+ model: requestedSelection?.model ?? options.model
24846
+ };
24847
+ }
24848
+ signal?.throwIfAborted();
23747
24849
  agent.followup(message);
24850
+ abortPrompt = () => {
24851
+ livePrompt = void 0;
24852
+ if (typeof agent.cancel === "function")
24853
+ agent.cancel({ kind: "user" });
24854
+ else if (requestedExecutionId !== void 0)
24855
+ void releaseExecutionHandle();
24856
+ else
24857
+ void releaseHandle();
24858
+ };
24859
+ signal?.addEventListener("abort", abortPrompt, { once: true });
24860
+ if (signal?.aborted)
24861
+ abortPrompt();
23748
24862
  await agent.whenIdle();
24863
+ signal?.throwIfAborted();
23749
24864
  throwIfDisposed(disposed, lifecycleAbort.signal, "prompt");
23750
24865
  await sessions.flush(agent.session);
23751
24866
  throwIfDisposed(disposed, lifecycleAbort.signal, "prompt");
@@ -23756,11 +24871,14 @@ ${JSON.stringify(historyContext.items)}`;
23756
24871
  events: snapshotFrom(fromSequence, requestedExecutionId)
23757
24872
  };
23758
24873
  } finally {
24874
+ if (abortPrompt)
24875
+ signal?.removeEventListener("abort", abortPrompt);
23759
24876
  if (selectionRef !== void 0) {
23760
24877
  selectionRef.current = void 0;
23761
24878
  selectionRef.assembled = void 0;
23762
24879
  }
23763
24880
  disposeSelection?.();
24881
+ livePrompt = void 0;
23764
24882
  promptActive = false;
23765
24883
  }
23766
24884
  };
@@ -23824,7 +24942,7 @@ ${JSON.stringify(historyContext.items)}`;
23824
24942
  } catch {
23825
24943
  }
23826
24944
  try {
23827
- await contextPreparationPromise;
24945
+ await contextOperationPromise;
23828
24946
  } catch {
23829
24947
  }
23830
24948
  try {
@@ -23839,20 +24957,33 @@ ${JSON.stringify(historyContext.items)}`;
23839
24957
  return disposePromise;
23840
24958
  };
23841
24959
  return {
23842
- sessionId: options.sessionId,
24960
+ get sessionId() {
24961
+ return nativeSessionId;
24962
+ },
24963
+ ...options.contextBinding === void 0 ? {} : { contextDeletionVersion: 1 },
24964
+ resetCanonicalContext(revision) {
24965
+ if (contextOperationPromise !== void 0)
24966
+ return Promise.reject(new Error("DSH host facade permits only one active context operation"));
24967
+ const operation = resetCanonicalContext(revision);
24968
+ contextOperationPromise = operation;
24969
+ return operation.finally(() => {
24970
+ if (contextOperationPromise === operation)
24971
+ contextOperationPromise = void 0;
24972
+ });
24973
+ },
23843
24974
  open: open3,
23844
24975
  currentSequence(requestedExecutionId) {
23845
24976
  return operationAgent(requestedExecutionId).session.seq;
23846
24977
  },
23847
24978
  snapshotFrom,
23848
24979
  prepareContextExecution(input2) {
23849
- if (contextPreparationPromise !== void 0)
24980
+ if (contextOperationPromise !== void 0)
23850
24981
  return Promise.reject(new Error("DSH host facade permits only one active context preparation"));
23851
24982
  const operation = prepareContextExecution(input2);
23852
- contextPreparationPromise = operation;
24983
+ contextOperationPromise = operation;
23853
24984
  return operation.finally(() => {
23854
- if (contextPreparationPromise === operation)
23855
- contextPreparationPromise = void 0;
24985
+ if (contextOperationPromise === operation)
24986
+ contextOperationPromise = void 0;
23856
24987
  });
23857
24988
  },
23858
24989
  projectCanonicalEvents,
@@ -23864,6 +24995,12 @@ ${JSON.stringify(historyContext.items)}`;
23864
24995
  eventSubscribers.add(listener);
23865
24996
  return () => eventSubscribers.delete(listener);
23866
24997
  },
24998
+ onLiveOutput(listener) {
24999
+ if (disposed)
25000
+ throw new Error("DSH host facade is disposed");
25001
+ liveSubscribers.add(listener);
25002
+ return () => liveSubscribers.delete(listener);
25003
+ },
23867
25004
  onStatus(listener) {
23868
25005
  if (disposed)
23869
25006
  throw new Error("DSH host facade is disposed");
@@ -24082,7 +25219,7 @@ function asObject4(value) {
24082
25219
  }
24083
25220
 
24084
25221
  // dist/src/state-store.js
24085
- import { randomUUID } from "node:crypto";
25222
+ import { randomUUID as randomUUID3 } from "node:crypto";
24086
25223
  import { constants } from "node:fs";
24087
25224
  import { lstat as lstat3, mkdir, open as open2, rename, unlink } from "node:fs/promises";
24088
25225
  import path3 from "node:path";
@@ -24137,7 +25274,7 @@ var FileConnectorStateStore = class {
24137
25274
  const targetBefore = await optionalLstat(this.#path);
24138
25275
  if (targetBefore !== void 0)
24139
25276
  assertPrivateRegularFile(targetBefore, "DSH connector state");
24140
- const temporaryPath = `${this.#path}.tmp-${process.pid}-${randomUUID()}`;
25277
+ const temporaryPath = `${this.#path}.tmp-${process.pid}-${randomUUID3()}`;
24141
25278
  const handle = await open2(temporaryPath, "wx", 384);
24142
25279
  try {
24143
25280
  await handle.writeFile(`${JSON.stringify(validated, null, 2)}
@@ -24177,7 +25314,10 @@ function validateConnectorState(value) {
24177
25314
  "publishedDshSequence",
24178
25315
  ...legacyUploadPolicy ? [] : ["automaticUpload"],
24179
25316
  "activeRequest",
24180
- "outbox"
25317
+ "outbox",
25318
+ "contentRevision",
25319
+ "projectionSessionId",
25320
+ "localOnlySessionIds"
24181
25321
  ]), "state");
24182
25322
  if (state.version !== 1 && state.version !== 2 && state.version !== 3) {
24183
25323
  throw new Error("Unsupported DSH connector state version");
@@ -24192,6 +25332,9 @@ function validateConnectorState(value) {
24192
25332
  throw new Error("state.outbox must be an array");
24193
25333
  const outbox = state.outbox.map(parseOutboxOperation);
24194
25334
  const validated = {
25335
+ ...state.contentRevision === void 0 ? {} : { contentRevision: nonNegativeInteger(state.contentRevision, "state.contentRevision") },
25336
+ ...state.projectionSessionId === void 0 ? {} : { projectionSessionId: safeString(state.projectionSessionId, "state.projectionSessionId", 128) },
25337
+ ...state.localOnlySessionIds === void 0 ? {} : { localOnlySessionIds: parseRetiredSessionIds(state.localOnlySessionIds) },
24195
25338
  version: 3,
24196
25339
  binding: {
24197
25340
  projectId: safeString(binding.projectId, "state.binding.projectId", 128),
@@ -24210,8 +25353,9 @@ function validateConnectorState(value) {
24210
25353
  }
24211
25354
  function parseActiveRequest(value) {
24212
25355
  const active = requiredObject3(value, "state.activeRequest");
24213
- exactKeys(active, /* @__PURE__ */ new Set(["requestId", "requestSequence", "dshFromSequence", "dshToSequence", "promptDigest", "claimAttempt", "contextExecution"]), "state.activeRequest");
25356
+ exactKeys(active, /* @__PURE__ */ new Set(["requestId", "requestSequence", "dshFromSequence", "dshToSequence", "promptDigest", "claimAttempt", "contextExecution", "contentRevision"]), "state.activeRequest");
24214
25357
  const parsed = {
25358
+ ...active.contentRevision === void 0 ? {} : { contentRevision: nonNegativeInteger(active.contentRevision, "state.activeRequest.contentRevision") },
24215
25359
  requestId: safeString(active.requestId, "state.activeRequest.requestId", 128),
24216
25360
  requestSequence: positiveInteger(active.requestSequence, "state.activeRequest.requestSequence"),
24217
25361
  dshFromSequence: nonNegativeInteger(active.dshFromSequence, "state.activeRequest.dshFromSequence"),
@@ -24287,7 +25431,8 @@ function parseLocalTurnInput(value, label) {
24287
25431
  "observedReasoningEffort",
24288
25432
  "requestPayload",
24289
25433
  "responsePayload",
24290
- "toolEvents"
25434
+ "toolEvents",
25435
+ "contentRevision"
24291
25436
  ]), label);
24292
25437
  const occurredAt = safeString(input2.occurredAt, `${label}.occurredAt`, 64);
24293
25438
  if (!Number.isFinite(Date.parse(occurredAt)))
@@ -24297,6 +25442,7 @@ function parseLocalTurnInput(value, label) {
24297
25442
  }
24298
25443
  return {
24299
25444
  localTurnId: safeString(input2.localTurnId, `${label}.localTurnId`, 200),
25445
+ ...input2.contentRevision === void 0 ? {} : { contentRevision: nonNegativeInteger(input2.contentRevision, `${label}.contentRevision`) },
24300
25446
  runtimeId: safeString(input2.runtimeId, `${label}.runtimeId`, 128),
24301
25447
  basedOnSequence: nonNegativeInteger(input2.basedOnSequence, `${label}.basedOnSequence`),
24302
25448
  occurredAt,
@@ -24324,13 +25470,15 @@ function parseAppendInput(value, label) {
24324
25470
  "runtimeId",
24325
25471
  "claimAttempt",
24326
25472
  "observedModel",
24327
- "observedReasoningEffort"
25473
+ "observedReasoningEffort",
25474
+ "contentRevision"
24328
25475
  ]), label);
24329
25476
  if (input2.type !== "tool_call" && input2.type !== "tool_result") {
24330
25477
  throw new Error(`${label}.type must be tool_call or tool_result`);
24331
25478
  }
24332
25479
  return {
24333
25480
  type: input2.type,
25481
+ ...input2.contentRevision === void 0 ? {} : { contentRevision: nonNegativeInteger(input2.contentRevision, `${label}.contentRevision`) },
24334
25482
  idempotencyKey: safeString(input2.idempotencyKey, `${label}.idempotencyKey`, 200),
24335
25483
  payload: jsonValue(input2.payload, `${label}.payload`),
24336
25484
  ...input2.replyTo === void 0 ? {} : { replyTo: safeString(input2.replyTo, `${label}.replyTo`, 128) },
@@ -24347,9 +25495,10 @@ function parseAppendInput(value, label) {
24347
25495
  }
24348
25496
  function parseCompletionInput(value, label) {
24349
25497
  const input2 = requiredObject3(value, label);
24350
- exactKeys(input2, /* @__PURE__ */ new Set(["runtimeId", "claimAttempt", "idempotencyKey", "payload", "observedModel", "observedReasoningEffort"]), label);
25498
+ exactKeys(input2, /* @__PURE__ */ new Set(["runtimeId", "claimAttempt", "idempotencyKey", "payload", "observedModel", "observedReasoningEffort", "contentRevision"]), label);
24351
25499
  return {
24352
25500
  runtimeId: safeString(input2.runtimeId, `${label}.runtimeId`, 128),
25501
+ ...input2.contentRevision === void 0 ? {} : { contentRevision: nonNegativeInteger(input2.contentRevision, `${label}.contentRevision`) },
24353
25502
  ...input2.claimAttempt === void 0 ? {} : {
24354
25503
  claimAttempt: positiveInteger(input2.claimAttempt, `${label}.claimAttempt`)
24355
25504
  },
@@ -24361,6 +25510,11 @@ function parseCompletionInput(value, label) {
24361
25510
  }
24362
25511
  };
24363
25512
  }
25513
+ function parseRetiredSessionIds(value) {
25514
+ if (!Array.isArray(value) || value.length > 4096 || new Set(value).size !== value.length)
25515
+ throw new Error("Invalid DSH retired Session identities");
25516
+ return value.map((id, index) => safeString(id, `state.localOnlySessionIds[${index}]`, 128));
25517
+ }
24364
25518
  function assertAlreadyRedacted(state) {
24365
25519
  const encoded = JSON.stringify(state);
24366
25520
  const redacted = JSON.stringify(redactValue(state));