@gatherthread/dsh-host 0.1.0-alpha.4 → 0.1.0-alpha.6

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.
@@ -111,7 +111,7 @@ var HttpCollaborationClient = class {
111
111
  async registerRuntime(runtime) {
112
112
  const body = requiredObject(await this.#request("/runtimes", {
113
113
  method: "POST",
114
- body: JSON.stringify(toSnakeCase(runtime))
114
+ body: JSON.stringify(toWireRuntimeRegistration(runtime))
115
115
  }));
116
116
  return fromWireRuntime(body.runtime ?? body);
117
117
  }
@@ -127,12 +127,19 @@ var HttpCollaborationClient = class {
127
127
  method: "POST",
128
128
  body: JSON.stringify({ runtime_id: runtimeId })
129
129
  }));
130
- const status = body.status === "completed" ? "completed" : "claimed";
130
+ if (body.status !== "claimed" && body.status !== "completed") {
131
+ throw new Error("Collaboration API omitted claim.status");
132
+ }
133
+ const attemptCount = body.attempt_count === void 0 ? 1 : requiredNumber(body.attempt_count, "claim.attempt_count");
134
+ if (attemptCount < 1)
135
+ throw new Error("Collaboration API omitted claim.attempt_count");
136
+ const status = body.status;
131
137
  return {
132
138
  claimed: status === "claimed",
133
139
  status,
134
140
  requestId: requiredString(body.request_event_id, "claim.request_event_id"),
135
- runtimeId: requiredString(body.runtime_id, "claim.runtime_id")
141
+ runtimeId: requiredString(body.runtime_id, "claim.runtime_id"),
142
+ attemptCount
136
143
  };
137
144
  }
138
145
  async completeAgentRequest(sessionId, requestId, input) {
@@ -140,6 +147,7 @@ var HttpCollaborationClient = class {
140
147
  method: "POST",
141
148
  body: JSON.stringify({
142
149
  runtime_id: input.runtimeId,
150
+ ...input.claimAttempt === void 0 ? {} : { claim_attempt: input.claimAttempt },
143
151
  idempotency_key: input.idempotencyKey,
144
152
  payload: truncateJsonValue(input.payload, 160 * 1024),
145
153
  ...input.observedModel === void 0 ? {} : { observed_model: input.observedModel },
@@ -153,6 +161,7 @@ var HttpCollaborationClient = class {
153
161
  method: "POST",
154
162
  body: JSON.stringify({
155
163
  runtime_id: input.runtimeId,
164
+ ...input.claimAttempt === void 0 ? {} : { claim_attempt: input.claimAttempt },
156
165
  idempotency_key: input.idempotencyKey,
157
166
  payload: truncateJsonValue(input.payload, 32 * 1024),
158
167
  ...input.observedModel === void 0 ? {} : { observed_model: input.observedModel },
@@ -191,10 +200,10 @@ var HttpCollaborationClient = class {
191
200
  const body = requiredObject(await this.#request(`/snapshot-requests/${encodeURIComponent(requestId)}`));
192
201
  return fromWireSnapshotRequest(body.snapshot_request ?? body);
193
202
  }
194
- async createSnapshotRequest(sessionId, kind = "immutable") {
203
+ async createSnapshotRequest(sessionId, kind = "immutable", targetRuntimeId) {
195
204
  const body = requiredObject(await this.#request(`/sessions/${encodeURIComponent(sessionId)}/snapshot-requests`, {
196
205
  method: "POST",
197
- body: JSON.stringify({ kind })
206
+ body: JSON.stringify({ kind, ...targetRuntimeId === void 0 ? {} : { target_runtime_id: targetRuntimeId } })
198
207
  }));
199
208
  return fromWireSnapshotRequest(body.snapshot_request ?? body);
200
209
  }
@@ -274,15 +283,34 @@ function toWireEvent(event) {
274
283
  reply_to_event_id: event.replyTo,
275
284
  visibility: event.visibility ?? "session",
276
285
  runtime_id: event.runtimeId ?? event.runtime?.runtimeId,
286
+ claim_attempt: event.claimAttempt,
277
287
  observed_model: event.observedModel,
278
288
  observed_reasoning_effort: event.observedReasoningEffort
279
289
  };
280
290
  }
281
- function toSnakeCase(value) {
282
- return Object.fromEntries(Object.entries(value).map(([key, item]) => [
283
- key.replace(/[A-Z]/g, (letter) => `_${letter.toLowerCase()}`),
284
- item
285
- ]));
291
+ function toWireRuntimeRegistration(runtime) {
292
+ return {
293
+ ...runtime.runtimeId === void 0 ? {} : { runtime_id: runtime.runtimeId },
294
+ session_id: runtime.sessionId,
295
+ device_id: runtime.deviceId,
296
+ harness: runtime.harness,
297
+ provider: runtime.provider,
298
+ model: runtime.model,
299
+ ...runtime.executionProfiles === void 0 ? {} : {
300
+ execution_profiles: runtime.executionProfiles.map((profile) => ({
301
+ provider: profile.provider,
302
+ model: profile.model,
303
+ ...profile.reasoningEfforts === void 0 ? {} : { reasoning_efforts: [...profile.reasoningEfforts] },
304
+ ...profile.defaultReasoningEffort === void 0 ? {} : {
305
+ default_reasoning_effort: profile.defaultReasoningEffort
306
+ }
307
+ }))
308
+ },
309
+ local_session_id: runtime.localSessionId,
310
+ capture_fidelity: runtime.captureFidelity,
311
+ ...runtime.capabilities === void 0 ? {} : { capabilities: [...runtime.capabilities] },
312
+ ...runtime.purpose === void 0 ? {} : { purpose: runtime.purpose }
313
+ };
286
314
  }
287
315
  function fromWireEvent(value) {
288
316
  const input = requiredObject(value);
@@ -312,10 +340,22 @@ function fromWireSnapshotRequest(value) {
312
340
  message: requiredString(failureInput.message, "snapshot_request.failure.message")
313
341
  } : void 0;
314
342
  const createdAt = optionalWireString(input.created_at) ?? optionalWireString(input.requested_at);
343
+ const kind = requiredString(input.kind, "snapshot_request.kind");
344
+ if (![
345
+ "immutable",
346
+ "visible_history_replace",
347
+ "local_sync_status",
348
+ "local_auto_upload_enable",
349
+ "local_auto_upload_disable",
350
+ "local_turn_upload"
351
+ ].includes(kind)) {
352
+ throw new Error("Collaboration API returned an invalid snapshot request kind");
353
+ }
315
354
  return {
316
355
  id: requiredString(input.id, "snapshot_request.id"),
317
356
  sessionId: requiredString(input.session_id, "snapshot_request.session_id"),
318
- kind: input.kind === "visible_history_replace" ? "visible_history_replace" : "immutable",
357
+ kind,
358
+ ...typeof input.target_runtime_id === "string" ? { targetRuntimeId: input.target_runtime_id } : {},
319
359
  throughSequence: requiredNumber(input.through_sequence, "snapshot_request.through_sequence"),
320
360
  status,
321
361
  ...createdAt === void 0 ? {} : { createdAt },
@@ -380,11 +420,61 @@ function fromWireRuntime(value) {
380
420
  harness: requiredString(input.harness, "runtime.harness"),
381
421
  provider: requiredString(input.provider, "runtime.provider"),
382
422
  model: requiredString(input.model, "runtime.model"),
423
+ ...input.execution_profiles === void 0 || input.execution_profiles === null ? {} : { executionProfiles: fromWireExecutionProfiles(input.execution_profiles) },
383
424
  localSessionId: requiredString(input.local_session_id, "runtime.local_session_id"),
384
425
  captureFidelity: requiredString(input.capture_fidelity, "runtime.capture_fidelity"),
385
426
  purpose
386
427
  };
387
428
  }
429
+ function fromWireExecutionProfiles(value) {
430
+ if (!Array.isArray(value) || value.length < 1 || value.length > 32) {
431
+ throw new Error("Collaboration API returned invalid runtime.execution_profiles");
432
+ }
433
+ const routes = /* @__PURE__ */ new Set();
434
+ return value.map((entry, index) => {
435
+ const profile = requiredObject(entry);
436
+ const allowedKeys = /* @__PURE__ */ new Set(["provider", "model", "reasoning_efforts", "default_reasoning_effort"]);
437
+ if (Object.keys(profile).some((key) => !allowedKeys.has(key))) {
438
+ throw new Error(`Collaboration API returned invalid runtime.execution_profiles[${index}]`);
439
+ }
440
+ const provider = requiredExecutionProfileString(profile.provider, `runtime.execution_profiles[${index}].provider`, 80);
441
+ const model = requiredExecutionProfileString(profile.model, `runtime.execution_profiles[${index}].model`, 160);
442
+ const route = `${provider}\0${model}`;
443
+ if (routes.has(route))
444
+ throw new Error("Collaboration API returned duplicate runtime.execution_profiles");
445
+ routes.add(route);
446
+ const rawEfforts = profile.reasoning_efforts;
447
+ let reasoningEfforts;
448
+ if (rawEfforts !== void 0) {
449
+ if (!Array.isArray(rawEfforts) || rawEfforts.length < 1 || rawEfforts.length > 16) {
450
+ throw new Error(`Collaboration API returned invalid runtime.execution_profiles[${index}].reasoning_efforts`);
451
+ }
452
+ reasoningEfforts = rawEfforts.map((effort, effortIndex) => requiredExecutionProfileString(effort, `runtime.execution_profiles[${index}].reasoning_efforts[${effortIndex}]`, 80));
453
+ if (new Set(reasoningEfforts).size !== reasoningEfforts.length) {
454
+ throw new Error(`Collaboration API returned duplicate runtime.execution_profiles[${index}].reasoning_efforts`);
455
+ }
456
+ }
457
+ const defaultReasoningEffort = profile.default_reasoning_effort === void 0 ? void 0 : requiredExecutionProfileString(profile.default_reasoning_effort, `runtime.execution_profiles[${index}].default_reasoning_effort`, 80);
458
+ if (defaultReasoningEffort !== void 0 && !reasoningEfforts?.includes(defaultReasoningEffort)) {
459
+ throw new Error(`Collaboration API returned an unadvertised runtime.execution_profiles[${index}].default_reasoning_effort`);
460
+ }
461
+ return {
462
+ provider,
463
+ model,
464
+ ...reasoningEfforts === void 0 ? {} : { reasoningEfforts },
465
+ ...defaultReasoningEffort === void 0 ? {} : { defaultReasoningEffort }
466
+ };
467
+ });
468
+ }
469
+ function requiredExecutionProfileString(value, field, maxLength) {
470
+ if (typeof value !== "string")
471
+ throw new Error(`Collaboration API omitted ${field}`);
472
+ const normalized = value.trim();
473
+ if (!normalized || normalized.length > maxLength || /[\u0000-\u001f\u007f-\u009f]/u.test(normalized)) {
474
+ throw new Error(`Collaboration API returned invalid ${field}`);
475
+ }
476
+ return normalized;
477
+ }
388
478
  function fromWireProvenance(value) {
389
479
  const input = requiredObject(value);
390
480
  return {
@@ -761,7 +851,35 @@ function isTerminalClaimConflict(error) {
761
851
  if (!error || typeof error !== "object")
762
852
  return false;
763
853
  const candidate = error;
764
- return candidate.status === 409 && (candidate.code === "agent_request_already_claimed" || candidate.code === "agent_request_already_completed");
854
+ return candidate.status === 409 && (candidate.code === "agent_request_already_claimed" || candidate.code === "agent_request_already_completed" || candidate.code === "agent_request_failed");
855
+ }
856
+
857
+ // dist/src/session-title.js
858
+ var DSH_SESSION_TITLE_MAX_BYTES = 80;
859
+ var SEPARATOR = " \xB7 ";
860
+ function managedDshSessionTitle(session) {
861
+ const marker = `${markerBrand(session.mode)}`;
862
+ const suffix = `${SEPARATOR}${marker}`;
863
+ const budget = DSH_SESSION_TITLE_MAX_BYTES - Buffer.byteLength(suffix, "utf8");
864
+ const name2 = clipToUtf8Bytes(session.name ?? session.id, budget);
865
+ return name2 === "" ? marker : `${name2}${suffix}`;
866
+ }
867
+ function markerBrand(mode) {
868
+ return mode === "solo" || mode === "multi" ? `\u5171\u5E8F \xB7 ${mode.toUpperCase()}` : "\u5171\u5E8F";
869
+ }
870
+ function clipToUtf8Bytes(value, maxBytes) {
871
+ if (maxBytes <= 0)
872
+ return "";
873
+ let kept = "";
874
+ let used = 0;
875
+ for (const codePoint of value) {
876
+ const size = Buffer.byteLength(codePoint, "utf8");
877
+ if (used + size > maxBytes)
878
+ break;
879
+ kept += codePoint;
880
+ used += size;
881
+ }
882
+ return kept;
765
883
  }
766
884
 
767
885
  // dist/src/config.js
@@ -1080,11 +1198,16 @@ function requestedDshProfile(event) {
1080
1198
  if (profile.provider !== void 0 && !provider) {
1081
1199
  throw new Error("DeepSeek Harness Agent request has an invalid provider target");
1082
1200
  }
1201
+ const reasoningEffort = profile.reasoning_effort === void 0 ? void 0 : safeProfileText(profile.reasoning_effort, 80);
1202
+ if (profile.reasoning_effort !== void 0 && !reasoningEffort) {
1203
+ throw new Error("DeepSeek Harness Agent request has an invalid reasoning effort target");
1204
+ }
1083
1205
  const runtimeId = profile.runtime_id === void 0 ? void 0 : safeRuntimeId(profile.runtime_id);
1084
1206
  return {
1085
1207
  harness,
1086
1208
  ...provider === void 0 ? {} : { provider },
1087
1209
  model,
1210
+ ...reasoningEffort === void 0 ? {} : { reasoningEffort },
1088
1211
  ...runtimeId === void 0 ? {} : { runtimeId }
1089
1212
  };
1090
1213
  }
@@ -1381,6 +1504,7 @@ function asObject2(value) {
1381
1504
  }
1382
1505
 
1383
1506
  // dist/src/connector.js
1507
+ var LIVE_PROGRESS_MIN_INTERVAL_MS = 6e4;
1384
1508
  var DshHostConnector = class {
1385
1509
  #config;
1386
1510
  #api;
@@ -1401,11 +1525,15 @@ var DshHostConnector = class {
1401
1525
  #pollPromise;
1402
1526
  #localSyncControlPromise;
1403
1527
  #heartbeatPromise;
1528
+ #liveProgressPromise = Promise.resolve();
1529
+ #lastLiveProgressKey;
1530
+ #lastLiveProgressAt = 0;
1404
1531
  #stopPromise;
1405
1532
  #backgroundFatalError;
1406
1533
  #lifecycleAbort = new AbortController();
1407
1534
  #listenerDisposers = [];
1408
1535
  #activeStatuses = [];
1536
+ #activeExecutionSelection;
1409
1537
  #liveEventSequences = /* @__PURE__ */ new Set();
1410
1538
  #session;
1411
1539
  #visibleState = "connecting";
@@ -1484,6 +1612,14 @@ var DshHostConnector = class {
1484
1612
  const active = this.#state?.activeRequest;
1485
1613
  if (active !== void 0 && event.seq >= active.dshFromSequence) {
1486
1614
  this.#liveEventSequences.add(event.seq);
1615
+ this.#queueLiveProgress(`dsh-live-${String(event.seq)}`, {
1616
+ content: "DeepSeek Harness produced durable work for the active request.",
1617
+ phase: "activity",
1618
+ status: "running",
1619
+ dsh_event_sequence: event.seq,
1620
+ capture_fidelity: "harness_transcript",
1621
+ source_harness: "deepseek-harness"
1622
+ });
1487
1623
  }
1488
1624
  if (active === void 0 && event.type === "turn/end" && turnSettlement([event]) === "completed" && this.#automaticPolling) {
1489
1625
  queueMicrotask(() => {
@@ -1498,8 +1634,9 @@ var DshHostConnector = class {
1498
1634
  this.#listenerDisposers.push(this.#host.onStatus((status) => {
1499
1635
  if (this.#state?.activeRequest === void 0)
1500
1636
  return;
1501
- if (this.#activeStatuses.at(-1) !== status)
1637
+ if (this.#activeStatuses.at(-1) !== status) {
1502
1638
  this.#activeStatuses.push(status);
1639
+ }
1503
1640
  this.#notifyLifecycle(status);
1504
1641
  }));
1505
1642
  try {
@@ -1530,16 +1667,20 @@ var DshHostConnector = class {
1530
1667
  "canonical_history_projection",
1531
1668
  "bidirectional_local_turns"
1532
1669
  ],
1670
+ ...this.#config.executionProfiles === void 0 ? {} : {
1671
+ executionProfiles: cloneExecutionProfiles(this.#config.executionProfiles)
1672
+ },
1533
1673
  purpose: "execution"
1534
1674
  });
1535
1675
  this.#assertRuntime(this.#runtime);
1536
1676
  this.#notifyLifecycle("idle");
1537
1677
  if (options.schedule !== false)
1538
1678
  this.#scheduleHeartbeat();
1539
- await this.#flushOutbox(this.#requireState().automaticUpload);
1540
- await this.#finalizeDeliveredRequest();
1541
1679
  if (this.#state.activeRequest !== void 0) {
1542
1680
  await this.#withExecutionPermit(() => this.#recoverActiveRequest());
1681
+ } else {
1682
+ await this.#flushOutbox(this.#requireState().automaticUpload);
1683
+ await this.#finalizeDeliveredRequest();
1543
1684
  }
1544
1685
  if (options.runImmediately !== false)
1545
1686
  await this.pollOnce();
@@ -1626,12 +1767,12 @@ var DshHostConnector = class {
1626
1767
  }
1627
1768
  async #poll() {
1628
1769
  const state = this.#requireState();
1629
- await this.#flushOutbox(state.automaticUpload);
1630
- await this.#finalizeDeliveredRequest();
1631
1770
  if (state.activeRequest !== void 0) {
1632
1771
  await this.#withExecutionPermit(() => this.#recoverActiveRequest());
1633
1772
  return { scanned: 0, claimed: 0, completed: 1 };
1634
1773
  }
1774
+ await this.#flushOutbox(state.automaticUpload);
1775
+ await this.#finalizeDeliveredRequest();
1635
1776
  if (state.automaticUpload) {
1636
1777
  await this.#captureLocalTurns();
1637
1778
  await this.#flushOutbox(true);
@@ -1647,7 +1788,7 @@ var DshHostConnector = class {
1647
1788
  scanCursor = Math.max(scanCursor, event.sequence);
1648
1789
  scanned += 1;
1649
1790
  const profile = requestedDshProfile(event);
1650
- if (profile === void 0 || event.actorId !== this.#requireRuntime().userId || profile.runtimeId !== void 0 && profile.runtimeId !== this.#requireRuntime().id) {
1791
+ if (profile === void 0 || event.actorId !== this.#requireRuntime().userId || !this.#profileTargetsThisRuntime(profile)) {
1651
1792
  passive.push(event);
1652
1793
  continue;
1653
1794
  }
@@ -1655,13 +1796,8 @@ var DshHostConnector = class {
1655
1796
  if (manualUploadRequired) {
1656
1797
  return { scanned, claimed: 0, completed: 0 };
1657
1798
  }
1658
- if (profile.provider !== void 0 && profile.provider !== this.#config.provider) {
1659
- throw new Error("DeepSeek Harness Agent request provider does not match the configured Host binding");
1660
- }
1661
- if (profile.model !== this.#config.model) {
1662
- throw new Error("DeepSeek Harness Agent request model does not match the configured Host binding");
1663
- }
1664
- const outcome = await this.#withExecutionPermit(() => this.#executeRequest(event));
1799
+ const selection = this.#resolveExecutionSelection(profile);
1800
+ const outcome = await this.#withExecutionPermit(() => this.#executeRequest(event, selection));
1665
1801
  return {
1666
1802
  scanned,
1667
1803
  claimed: outcome.claimed ? 1 : 0,
@@ -1679,7 +1815,7 @@ var DshHostConnector = class {
1679
1815
  }
1680
1816
  throw new Error("DSH connector stopped during event replay");
1681
1817
  }
1682
- async #executeRequest(request) {
1818
+ async #executeRequest(request, selection) {
1683
1819
  if (this.#stopped)
1684
1820
  throw new Error("DSH connector stopped before claiming an Agent request");
1685
1821
  const state = this.#requireState();
@@ -1703,17 +1839,20 @@ var DshHostConnector = class {
1703
1839
  requestId: request.id,
1704
1840
  requestSequence: request.sequence,
1705
1841
  dshFromSequence: baseline,
1706
- promptDigest: digest(prompt)
1842
+ promptDigest: digest(prompt),
1843
+ claimAttempt: claim.attemptCount ?? 1
1707
1844
  };
1708
1845
  this.#activeStatuses = [];
1846
+ this.#activeExecutionSelection = selection;
1709
1847
  this.#liveEventSequences.clear();
1710
1848
  await this.#stateStore.save(state);
1711
- const result = await this.#host.prompt(prompt);
1849
+ const result = await this.#host.prompt(prompt, selection);
1712
1850
  if (result.fromSequence !== baseline || result.toSequence < result.fromSequence) {
1713
1851
  throw new Error("DSH Host prompt returned an inconsistent durable event range");
1714
1852
  }
1853
+ await this.#liveProgressPromise;
1715
1854
  this.#assertLiveEventsDurable(result);
1716
- await this.#settleActiveRequest(result.events, result.toSequence);
1855
+ await this.#settleActiveRequest(result.events, result.toSequence, selection);
1717
1856
  return { claimed: true, completed: true };
1718
1857
  }
1719
1858
  async #recoverActiveRequest() {
@@ -1723,6 +1862,46 @@ var DshHostConnector = class {
1723
1862
  const active = state.activeRequest;
1724
1863
  if (active === void 0)
1725
1864
  return;
1865
+ let claim;
1866
+ try {
1867
+ claim = await this.#api.claimAgentRequest(this.#config.sessionId, active.requestId, this.#requireRuntime().id);
1868
+ } catch (error) {
1869
+ if (!isTerminalClaimConflict(error))
1870
+ throw error;
1871
+ state.outbox = state.outbox.filter((operation) => !outboxBelongsToRequest(operation, active.requestId));
1872
+ if (active.dshToSequence !== void 0) {
1873
+ state.publishedDshSequence = Math.max(state.publishedDshSequence, active.dshToSequence);
1874
+ }
1875
+ delete state.activeRequest;
1876
+ this.#activeStatuses = [];
1877
+ this.#activeExecutionSelection = void 0;
1878
+ this.#liveEventSequences.clear();
1879
+ await this.#stateStore.save(state);
1880
+ return;
1881
+ }
1882
+ if (claim.status === "completed" && active.dshToSequence !== void 0) {
1883
+ state.outbox = [];
1884
+ await this.#stateStore.save(state);
1885
+ await this.#finalizeDeliveredRequest();
1886
+ return;
1887
+ }
1888
+ if (!claim.claimed) {
1889
+ throw new Error("Active GatherThread request no longer has a recoverable claim");
1890
+ }
1891
+ const claimAttempt = claim.attemptCount ?? active.claimAttempt ?? 1;
1892
+ active.claimAttempt = claimAttempt;
1893
+ if (active.dshToSequence !== void 0) {
1894
+ state.outbox = state.outbox.map((operation) => {
1895
+ if ((operation.kind === "progress" || operation.kind === "complete") && operation.requestId === active.requestId) {
1896
+ return { ...operation, input: { ...operation.input, claimAttempt } };
1897
+ }
1898
+ if (operation.kind === "append" && operation.input.replyTo === active.requestId) {
1899
+ return { ...operation, input: { ...operation.input, claimAttempt } };
1900
+ }
1901
+ return operation;
1902
+ });
1903
+ }
1904
+ await this.#stateStore.save(state);
1726
1905
  if (active.dshToSequence !== void 0) {
1727
1906
  await this.#flushOutbox();
1728
1907
  await this.#finalizeDeliveredRequest();
@@ -1734,6 +1913,15 @@ var DshHostConnector = class {
1734
1913
  throw new Error("Active GatherThread request is unavailable during DSH resume");
1735
1914
  }
1736
1915
  const prompt = buildDshRequestPrompt(request);
1916
+ const profile = requestedDshProfile(request);
1917
+ if (profile === void 0) {
1918
+ throw new Error("Active GatherThread request lost its DeepSeek Harness execution profile");
1919
+ }
1920
+ if (!this.#profileTargetsThisRuntime(profile)) {
1921
+ throw new Error("Active GatherThread request no longer targets this exact DSH runtime");
1922
+ }
1923
+ const selection = this.#resolveExecutionSelection(profile);
1924
+ this.#activeExecutionSelection = selection;
1737
1925
  const legacyPrompt = buildDshCanonicalPrompt(history, request, this.#requireRuntime().id);
1738
1926
  if (digest(prompt) !== active.promptDigest && digest(legacyPrompt) !== active.promptDigest) {
1739
1927
  throw new Error("Active GatherThread request changed during DSH resume");
@@ -1741,7 +1929,7 @@ var DshHostConnector = class {
1741
1929
  const recovered = this.#host.snapshotFrom(active.dshFromSequence);
1742
1930
  const settlement = turnSettlement(recovered);
1743
1931
  if (settlement === "completed") {
1744
- await this.#settleActiveRequest(recovered, this.#host.currentSequence());
1932
+ await this.#settleActiveRequest(recovered, this.#host.currentSequence(), selection);
1745
1933
  return;
1746
1934
  }
1747
1935
  if (settlement !== void 0 && settlement !== "interrupted") {
@@ -1759,14 +1947,15 @@ var DshHostConnector = class {
1759
1947
  this.#activeStatuses = [];
1760
1948
  this.#liveEventSequences.clear();
1761
1949
  await this.#stateStore.save(state);
1762
- const result = await this.#host.prompt(continuation);
1950
+ const result = await this.#host.prompt(continuation, selection);
1763
1951
  if (result.fromSequence !== baseline || result.toSequence < result.fromSequence) {
1764
1952
  throw new Error("DSH Host recovery prompt returned an inconsistent durable event range");
1765
1953
  }
1954
+ await this.#liveProgressPromise;
1766
1955
  this.#assertLiveEventsDurable(result);
1767
- await this.#settleActiveRequest(result.events, result.toSequence);
1956
+ await this.#settleActiveRequest(result.events, result.toSequence, selection);
1768
1957
  }
1769
- async #settleActiveRequest(durableEvents, toSequence) {
1958
+ async #settleActiveRequest(durableEvents, toSequence, selection) {
1770
1959
  const state = this.#requireState();
1771
1960
  const active = state.activeRequest;
1772
1961
  if (active === void 0)
@@ -1782,11 +1971,51 @@ var DshHostConnector = class {
1782
1971
  if (state.outbox.length > 0)
1783
1972
  throw new Error("DSH connector outbox was not empty before settlement");
1784
1973
  state.activeRequest = { ...active, dshToSequence: toSequence };
1785
- state.outbox = this.#outboxFor(mapped, this.#activeStatuses, active.requestId);
1974
+ state.outbox = this.#outboxFor(mapped, this.#activeStatuses, active.requestId, active.claimAttempt ?? 1, selection);
1786
1975
  await this.#stateStore.save(state);
1787
1976
  await this.#flushOutbox();
1788
1977
  await this.#finalizeDeliveredRequest();
1789
1978
  }
1979
+ #queueLiveProgress(idSuffix, payload) {
1980
+ const active = this.#state?.activeRequest;
1981
+ const runtime = this.#runtime;
1982
+ if (active === void 0 || runtime === void 0)
1983
+ return;
1984
+ const requestId = active.requestId;
1985
+ const claimAttempt = active.claimAttempt ?? 1;
1986
+ const progressKey = `${requestId}:${String(claimAttempt)}`;
1987
+ const now = Date.now();
1988
+ if (this.#lastLiveProgressKey === progressKey && now - this.#lastLiveProgressAt < LIVE_PROGRESS_MIN_INTERVAL_MS) {
1989
+ return;
1990
+ }
1991
+ this.#lastLiveProgressKey = progressKey;
1992
+ this.#lastLiveProgressAt = now;
1993
+ const idempotencyKey = `${this.#config.deviceId}:${digest(requestId).slice(0, 24)}:${idSuffix}`;
1994
+ this.#liveProgressPromise = this.#liveProgressPromise.then(async () => {
1995
+ const current = this.#state?.activeRequest;
1996
+ if (current?.requestId !== requestId || (current.claimAttempt ?? 1) !== claimAttempt)
1997
+ return;
1998
+ const selection = this.#activeExecutionSelection;
1999
+ if (selection === void 0)
2000
+ return;
2001
+ await this.#api.appendAgentProgress(this.#config.sessionId, requestId, {
2002
+ runtimeId: runtime.id,
2003
+ claimAttempt,
2004
+ idempotencyKey,
2005
+ payload,
2006
+ observedModel: selection.model,
2007
+ ...selection.reasoningEffort === void 0 ? {} : {
2008
+ observedReasoningEffort: selection.reasoningEffort
2009
+ }
2010
+ });
2011
+ }).catch((error) => {
2012
+ if (this.#lastLiveProgressKey === progressKey) {
2013
+ this.#lastLiveProgressKey = void 0;
2014
+ this.#lastLiveProgressAt = 0;
2015
+ }
2016
+ this.#onBackgroundError?.(publicError(error));
2017
+ });
2018
+ }
1790
2019
  async #projectCanonicalBatch(events, throughSequence) {
1791
2020
  const state = this.#requireState();
1792
2021
  if (throughSequence <= state.projectionCursor)
@@ -1870,7 +2099,7 @@ var DshHostConnector = class {
1870
2099
  }
1871
2100
  await this.#stateStore.save(state);
1872
2101
  }
1873
- #outboxFor(events, statuses, requestId) {
2102
+ #outboxFor(events, statuses, requestId, claimAttempt, selection) {
1874
2103
  const runtime = this.#requireRuntime();
1875
2104
  const prefix = `${this.#config.deviceId}:${digest(requestId).slice(0, 24)}`;
1876
2105
  const operations = [];
@@ -1882,6 +2111,7 @@ var DshHostConnector = class {
1882
2111
  requestId,
1883
2112
  input: {
1884
2113
  runtimeId: runtime.id,
2114
+ claimAttempt,
1885
2115
  idempotencyKey,
1886
2116
  payload: {
1887
2117
  content: status === "running" ? "DeepSeek Harness started processing the request." : "DeepSeek Harness returned to idle.",
@@ -1890,7 +2120,10 @@ var DshHostConnector = class {
1890
2120
  capture_fidelity: "harness_transcript",
1891
2121
  source_harness: "deepseek-harness"
1892
2122
  },
1893
- observedModel: this.#config.model
2123
+ observedModel: selection.model,
2124
+ ...selection.reasoningEffort === void 0 ? {} : {
2125
+ observedReasoningEffort: selection.reasoningEffort
2126
+ }
1894
2127
  }
1895
2128
  });
1896
2129
  }
@@ -1924,7 +2157,11 @@ var DshHostConnector = class {
1924
2157
  payload: redactValue(payload),
1925
2158
  replyTo: requestId,
1926
2159
  runtimeId: runtime.id,
1927
- observedModel: this.#config.model
2160
+ claimAttempt,
2161
+ observedModel: selection.model,
2162
+ ...selection.reasoningEffort === void 0 ? {} : {
2163
+ observedReasoningEffort: selection.reasoningEffort
2164
+ }
1928
2165
  }
1929
2166
  });
1930
2167
  }
@@ -1939,6 +2176,7 @@ var DshHostConnector = class {
1939
2176
  requestId,
1940
2177
  input: {
1941
2178
  runtimeId: runtime.id,
2179
+ claimAttempt,
1942
2180
  idempotencyKey: completionKey,
1943
2181
  payload: {
1944
2182
  text: final.content,
@@ -1947,7 +2185,10 @@ var DshHostConnector = class {
1947
2185
  source_timestamp: final.timestamp,
1948
2186
  dsh_event_sequence: final.sequence
1949
2187
  },
1950
- observedModel: this.#config.model
2188
+ observedModel: selection.model,
2189
+ ...selection.reasoningEffort === void 0 ? {} : {
2190
+ observedReasoningEffort: selection.reasoningEffort
2191
+ }
1951
2192
  }
1952
2193
  });
1953
2194
  return operations;
@@ -1991,6 +2232,7 @@ var DshHostConnector = class {
1991
2232
  state.publishedDshSequence = Math.max(state.publishedDshSequence, active.dshToSequence);
1992
2233
  delete state.activeRequest;
1993
2234
  this.#activeStatuses = [];
2235
+ this.#activeExecutionSelection = void 0;
1994
2236
  this.#liveEventSequences.clear();
1995
2237
  await this.#stateStore.save(state);
1996
2238
  }
@@ -2076,10 +2318,45 @@ var DshHostConnector = class {
2076
2318
  return stored;
2077
2319
  }
2078
2320
  #assertRuntime(runtime) {
2079
- if (runtime.sessionId !== this.#config.sessionId || runtime.deviceId !== this.#config.deviceId || runtime.harness !== "deepseek-harness" || runtime.provider !== this.#config.provider || runtime.model !== this.#config.model || runtime.localSessionId !== this.#config.dshSessionId || runtime.captureFidelity !== "harness_transcript" || runtime.purpose !== "execution") {
2321
+ if (runtime.sessionId !== this.#config.sessionId || runtime.deviceId !== this.#config.deviceId || runtime.harness !== "deepseek-harness" || runtime.provider !== this.#config.provider || runtime.model !== this.#config.model || runtime.localSessionId !== this.#config.dshSessionId || runtime.captureFidelity !== "harness_transcript" || !sameExecutionProfiles(runtime.executionProfiles, this.#config.executionProfiles) || runtime.purpose !== "execution") {
2080
2322
  throw new Error("GatherThread returned an incompatible DSH runtime registration");
2081
2323
  }
2082
2324
  }
2325
+ #resolveExecutionSelection(profile) {
2326
+ const provider = profile.provider ?? this.#config.provider;
2327
+ const advertised = this.#config.executionProfiles;
2328
+ if (advertised === void 0) {
2329
+ if (provider !== this.#config.provider) {
2330
+ throw new Error("DeepSeek Harness Agent request provider does not match the configured Host binding");
2331
+ }
2332
+ if (profile.model !== this.#config.model) {
2333
+ throw new Error("DeepSeek Harness Agent request model does not match the configured Host binding");
2334
+ }
2335
+ if (profile.reasoningEffort !== void 0) {
2336
+ throw new Error("DeepSeek Harness fixed runtime did not advertise reasoning effort selection");
2337
+ }
2338
+ return { provider, model: profile.model };
2339
+ }
2340
+ const route = advertised.find((candidate) => candidate.provider === provider && candidate.model === profile.model);
2341
+ if (route === void 0) {
2342
+ throw new Error("DeepSeek Harness Agent request provider/model was not advertised by this runtime");
2343
+ }
2344
+ const reasoningEffort = profile.reasoningEffort ?? route.defaultReasoningEffort;
2345
+ if (reasoningEffort !== void 0 && !route.reasoningEfforts?.includes(reasoningEffort)) {
2346
+ throw new Error("DeepSeek Harness Agent request reasoning effort was not advertised for this model");
2347
+ }
2348
+ return {
2349
+ provider,
2350
+ model: profile.model,
2351
+ ...reasoningEffort === void 0 ? {} : { reasoningEffort }
2352
+ };
2353
+ }
2354
+ #profileTargetsThisRuntime(profile) {
2355
+ const runtimeId = profile.runtimeId;
2356
+ if (runtimeId !== void 0)
2357
+ return runtimeId === this.#requireRuntime().id;
2358
+ return this.#config.executionProfiles === void 0;
2359
+ }
2083
2360
  #validatePage(events, afterSequence) {
2084
2361
  let previous = afterSequence;
2085
2362
  for (const event of events) {
@@ -2179,6 +2456,21 @@ function turnSettlement(events) {
2179
2456
  function digest(value) {
2180
2457
  return createHash3("sha256").update(value).digest("hex");
2181
2458
  }
2459
+ function cloneExecutionProfiles(profiles) {
2460
+ return profiles.map((profile) => ({
2461
+ provider: profile.provider,
2462
+ model: profile.model,
2463
+ ...profile.reasoningEfforts === void 0 ? {} : {
2464
+ reasoningEfforts: [...profile.reasoningEfforts]
2465
+ },
2466
+ ...profile.defaultReasoningEffort === void 0 ? {} : {
2467
+ defaultReasoningEffort: profile.defaultReasoningEffort
2468
+ }
2469
+ }));
2470
+ }
2471
+ function sameExecutionProfiles(actual, expected) {
2472
+ return JSON.stringify(actual ?? null) === JSON.stringify(expected ?? null);
2473
+ }
2182
2474
  function publicError(error) {
2183
2475
  if (error instanceof Error)
2184
2476
  return error;
@@ -2281,6 +2573,12 @@ function boundedPublicText(value) {
2281
2573
  }
2282
2574
  return `${redacted.slice(0, low)}${suffix}`;
2283
2575
  }
2576
+ function outboxBelongsToRequest(operation, requestId) {
2577
+ if (operation.kind === "progress" || operation.kind === "complete") {
2578
+ return operation.requestId === requestId;
2579
+ }
2580
+ return operation.kind === "append" && operation.input.replyTo === requestId;
2581
+ }
2284
2582
  function sessionTimestamp(value) {
2285
2583
  const date = new Date(value);
2286
2584
  if (!Number.isFinite(date.getTime()))
@@ -2357,6 +2655,23 @@ function createDshHostFacade(options) {
2357
2655
  for (const subscriber of statusSubscribers)
2358
2656
  subscriber(status);
2359
2657
  }, { global: true }));
2658
+ const adoptHandle = async (acquire) => {
2659
+ const acquired = await acquire();
2660
+ handle = acquired;
2661
+ if (disposed || lifecycleAbort.signal.aborted) {
2662
+ await releaseHandle();
2663
+ throw new Error("DSH host facade was disposed during open");
2664
+ }
2665
+ if (acquired.agent.session.id !== options.sessionId) {
2666
+ await releaseHandle();
2667
+ throw new Error("DSH Host returned an agent for an unexpected Session identity");
2668
+ }
2669
+ };
2670
+ const releaseHandle = async () => {
2671
+ const owned = handle;
2672
+ handle = void 0;
2673
+ await owned?.dispose();
2674
+ };
2360
2675
  const open3 = () => {
2361
2676
  if (disposed)
2362
2677
  return Promise.reject(new Error("DSH host facade is disposed"));
@@ -2371,13 +2686,12 @@ function createDshHostFacade(options) {
2371
2686
  const stored = liveAgent === void 0 ? await hasPersistedSession(persistence, options.sessionId, lifecycleAbort.signal) : true;
2372
2687
  throwIfDisposed(disposed, lifecycleAbort.signal, "open");
2373
2688
  const mode = stored ? "resumed" : "created";
2374
- let openedHandle;
2375
2689
  try {
2376
- openedHandle = liveAgent !== void 0 ? { agent: liveAgent, dispose: async () => void 0 } : stored ? await agents.resume({
2690
+ await adoptHandle(() => liveAgent !== void 0 ? Promise.resolve({ agent: liveAgent, dispose: async () => void 0 }) : stored ? agents.resume({
2377
2691
  resumeSessionId: options.sessionId,
2378
2692
  agentOptions: { provider: options.provider, model: options.model },
2379
2693
  signal: lifecycleAbort.signal
2380
- }) : await agents.create({
2694
+ }) : agents.create({
2381
2695
  sessionId: options.sessionId,
2382
2696
  meta: {
2383
2697
  cwd: options.workspacePath,
@@ -2385,42 +2699,52 @@ function createDshHostFacade(options) {
2385
2699
  },
2386
2700
  agentOptions: { provider: options.provider, model: options.model },
2387
2701
  signal: lifecycleAbort.signal
2388
- });
2702
+ }));
2389
2703
  } catch (error) {
2390
2704
  throwIfDisposed(disposed, lifecycleAbort.signal, "open");
2391
2705
  throw error;
2392
2706
  }
2393
- if (disposed || lifecycleAbort.signal.aborted) {
2394
- await openedHandle.dispose();
2395
- throw new Error("DSH host facade was disposed during open");
2396
- }
2397
- if (openedHandle.agent.session.id !== options.sessionId) {
2398
- await openedHandle.dispose();
2399
- throw new Error("DSH Host returned an agent for an unexpected Session identity");
2400
- }
2401
2707
  if (sessionTitle !== void 0 && workspaceRegistry !== void 0 && options.sessionTitle !== void 0 && options.workspaceTitle !== void 0) {
2402
2708
  try {
2403
- await sessionTitle.rename(openedHandle.agent.session, options.sessionTitle);
2404
- ensureNativeSessionListVisibility(openedHandle.agent.session);
2405
- await sessions.flush(openedHandle.agent.session);
2709
+ const session = requireAgent(handle).session;
2710
+ if (mode === "created") {
2711
+ await sessionTitle.rename(session, options.sessionTitle);
2712
+ throwIfDisposed(disposed, lifecycleAbort.signal, "open");
2713
+ }
2714
+ const markerWritten = liveAgent === void 0 && ensureNativeSessionListVisibility(session);
2715
+ await sessions.flush(session);
2716
+ throwIfDisposed(disposed, lifecycleAbort.signal, "open");
2717
+ if (markerWritten) {
2718
+ await releaseHandle();
2719
+ throwIfDisposed(disposed, lifecycleAbort.signal, "open");
2720
+ await adoptHandle(() => agents.resume({
2721
+ resumeSessionId: options.sessionId,
2722
+ agentOptions: { provider: options.provider, model: options.model },
2723
+ signal: lifecycleAbort.signal
2724
+ }));
2725
+ }
2726
+ throwIfDisposed(disposed, lifecycleAbort.signal, "open");
2406
2727
  const workspace = await workspaceRegistry.create(options.workspacePath, options.workspaceTitle);
2407
2728
  if (workspace === null || typeof workspace !== "object" || typeof workspace.attachSession !== "function") {
2408
2729
  throw new Error("Pinned DSH workspace registry returned an incompatible Workspace");
2409
2730
  }
2731
+ throwIfDisposed(disposed, lifecycleAbort.signal, "open");
2410
2732
  await workspace.attachSession(options.sessionId);
2733
+ throwIfDisposed(disposed, lifecycleAbort.signal, "open");
2411
2734
  if (options.supersededSessionId !== void 0 && options.supersededSessionId !== options.sessionId && workspace.sessionIds.includes(options.supersededSessionId)) {
2412
2735
  if (typeof workspace.detachSession !== "function") {
2413
2736
  throw new Error("Pinned DSH Workspace detachSession API is unavailable or incompatible");
2414
2737
  }
2415
2738
  await workspace.detachSession(options.supersededSessionId);
2739
+ throwIfDisposed(disposed, lifecycleAbort.signal, "open");
2416
2740
  }
2417
2741
  } catch (error) {
2418
- await openedHandle.dispose();
2742
+ await releaseHandle();
2419
2743
  throwIfDisposed(disposed, lifecycleAbort.signal, "open");
2420
2744
  throw error;
2421
2745
  }
2422
2746
  }
2423
- handle = openedHandle;
2747
+ throwIfDisposed(disposed, lifecycleAbort.signal, "open");
2424
2748
  return mode;
2425
2749
  })();
2426
2750
  return openPromise;
@@ -2437,7 +2761,7 @@ function createDshHostFacade(options) {
2437
2761
  return parsed;
2438
2762
  });
2439
2763
  };
2440
- const prompt = async (text) => {
2764
+ const prompt = async (text, requestedSelection) => {
2441
2765
  if (disposed)
2442
2766
  throw new Error("DSH host facade is disposed");
2443
2767
  if (!text.trim())
@@ -2450,12 +2774,24 @@ function createDshHostFacade(options) {
2450
2774
  if (projectionActive)
2451
2775
  throw new Error("DSH host facade permits only one active write");
2452
2776
  promptActive = true;
2777
+ let disposeSelection;
2778
+ let selectionRef;
2453
2779
  try {
2454
2780
  await open3();
2455
2781
  throwIfDisposed(disposed, lifecycleAbort.signal, "prompt");
2456
2782
  const agent = requireAgent(handle);
2457
2783
  if (agent.status !== "idle")
2458
2784
  throw new Error("DSH Agent must be idle before a GatherThread prompt");
2785
+ if (requestedSelection !== void 0) {
2786
+ const selection = await resolveDshExecutionSelection(context, requestedSelection, lifecycleAbort.signal);
2787
+ throwIfDisposed(disposed, lifecycleAbort.signal, "prompt");
2788
+ const install = options.modelSelectionInstaller ?? await loadModelSelectionInstaller();
2789
+ selectionRef = { current: selection, assembled: void 0 };
2790
+ disposeSelection = install(agent.ctx, selectionRef);
2791
+ if (typeof disposeSelection !== "function") {
2792
+ throw new Error("Pinned DSH installModelSelection API returned an incompatible disposer");
2793
+ }
2794
+ }
2459
2795
  const fromSequence = agent.session.seq;
2460
2796
  const message = await createUserMessage(text, options);
2461
2797
  throwIfDisposed(disposed, lifecycleAbort.signal, "prompt");
@@ -2471,6 +2807,11 @@ function createDshHostFacade(options) {
2471
2807
  events: snapshotFrom(fromSequence)
2472
2808
  };
2473
2809
  } finally {
2810
+ if (selectionRef !== void 0) {
2811
+ selectionRef.current = void 0;
2812
+ selectionRef.assembled = void 0;
2813
+ }
2814
+ disposeSelection?.();
2474
2815
  promptActive = false;
2475
2816
  }
2476
2817
  };
@@ -2527,18 +2868,32 @@ function createDshHostFacade(options) {
2527
2868
  }
2528
2869
  };
2529
2870
  const dispose = () => {
2530
- disposePromise ??= (async () => {
2531
- disposed = true;
2532
- lifecycleAbort.abort(new Error("DSH host facade disposed"));
2533
- eventSubscribers.clear();
2534
- statusSubscribers.clear();
2535
- for (const stop of listenerDisposers.splice(0))
2536
- stop();
2871
+ if (disposePromise !== void 0)
2872
+ return disposePromise;
2873
+ disposed = true;
2874
+ lifecycleAbort.abort(new Error("DSH host facade disposed"));
2875
+ eventSubscribers.clear();
2876
+ statusSubscribers.clear();
2877
+ for (const stop of listenerDisposers.splice(0))
2878
+ stop();
2879
+ disposePromise = (async () => {
2880
+ let releaseError;
2881
+ try {
2882
+ await releaseHandle();
2883
+ } catch (error) {
2884
+ releaseError = error;
2885
+ }
2537
2886
  try {
2538
- await handle?.dispose();
2539
- } finally {
2540
- handle = void 0;
2887
+ await openPromise;
2888
+ } catch {
2541
2889
  }
2890
+ try {
2891
+ await releaseHandle();
2892
+ } catch (error) {
2893
+ releaseError ??= error;
2894
+ }
2895
+ if (releaseError !== void 0)
2896
+ throw releaseError;
2542
2897
  })();
2543
2898
  return disposePromise;
2544
2899
  };
@@ -2570,9 +2925,10 @@ function createDshHostFacade(options) {
2570
2925
  function ensureNativeSessionListVisibility(session) {
2571
2926
  const events = session.snapshotEvents(0);
2572
2927
  if (events.some((event) => asSessionEvent(event)?.type === "turn/start"))
2573
- return;
2928
+ return false;
2574
2929
  session.append("turn/start", { turn: 1 });
2575
2930
  session.append("turn/end", { turn: 1, reason: { kind: "completed" } });
2931
+ return true;
2576
2932
  }
2577
2933
  async function registerDshNativeWorkspace(contextValue, workspacePath, workspaceTitle) {
2578
2934
  const context = requireContext(contextValue);
@@ -2776,6 +3132,49 @@ async function createUserMessage(text, options) {
2776
3132
  source: { kind: "user" }
2777
3133
  });
2778
3134
  }
3135
+ async function loadModelSelectionInstaller() {
3136
+ const imported = asObject4(await importDshModule("@deepseek-ai/dsh-agent"));
3137
+ if (imported === void 0 || typeof imported.installModelSelection !== "function") {
3138
+ throw new Error("Pinned DSH installModelSelection API is unavailable");
3139
+ }
3140
+ return imported.installModelSelection;
3141
+ }
3142
+ async function importDshModule(specifier) {
3143
+ return import(specifier);
3144
+ }
3145
+ async function resolveDshExecutionSelection(context, requested, signal) {
3146
+ const provider = safeSelectionText(requested.provider, "provider", 80);
3147
+ const model = safeSelectionText(requested.model, "model", 160);
3148
+ const reasoningEffort = requested.reasoningEffort === void 0 ? void 0 : safeSelectionText(requested.reasoningEffort, "reasoning effort", 80);
3149
+ const llm = requireService(context, "llm", ["resolveModelInfo"]);
3150
+ const resolved = asObject4(await llm.resolveModelInfo(provider, model, signal));
3151
+ if (resolved === void 0 || resolved.provider !== provider || resolved.id !== model) {
3152
+ throw new Error("DeepSeek Harness did not resolve the requested provider/model exactly");
3153
+ }
3154
+ if (reasoningEffort !== void 0) {
3155
+ const reasoning = asObject4(resolved.reasoning);
3156
+ const efforts = Array.isArray(reasoning?.efforts) ? reasoning.efforts : [];
3157
+ const supported = efforts.some((value) => asObject4(value)?.id === reasoningEffort);
3158
+ if (!supported) {
3159
+ throw new Error(`DeepSeek Harness model ${provider}/${model} does not support reasoning effort ${reasoningEffort}`);
3160
+ }
3161
+ }
3162
+ return {
3163
+ provider,
3164
+ model,
3165
+ ...reasoningEffort === void 0 ? {} : { reasoningEffort }
3166
+ };
3167
+ }
3168
+ function safeSelectionText(value, label, maximum) {
3169
+ if (typeof value !== "string") {
3170
+ throw new Error(`DeepSeek Harness ${label} selection must be a string`);
3171
+ }
3172
+ const normalized = value.trim();
3173
+ if (!normalized || normalized.length > maximum || /[\u0000-\u001f\u007f-\u009f]/u.test(normalized)) {
3174
+ throw new Error(`DeepSeek Harness ${label} selection is invalid`);
3175
+ }
3176
+ return normalized;
3177
+ }
2779
3178
  function requireContext(value) {
2780
3179
  const context = asObject4(value);
2781
3180
  if (context === void 0 || typeof context.get !== "function" || typeof context.on !== "function" || typeof context.effect !== "function") {
@@ -3637,6 +4036,14 @@ function projectSessionConfig(config, sessionId, nativeSessionId) {
3637
4036
  statePath: path5.join(config.stateRoot, `${dshSessionId}.json`),
3638
4037
  provider: config.provider,
3639
4038
  model: config.model,
4039
+ ...config.executionProfiles === void 0 ? {} : {
4040
+ executionProfiles: config.executionProfiles.map((profile) => ({
4041
+ ...profile,
4042
+ ...profile.reasoningEfforts === void 0 ? {} : {
4043
+ reasoningEfforts: [...profile.reasoningEfforts]
4044
+ }
4045
+ }))
4046
+ },
3640
4047
  pollIntervalMs: config.pollIntervalMs,
3641
4048
  pollLimit: config.pollLimit,
3642
4049
  shareToolEvents: config.shareToolEvents,
@@ -3802,7 +4209,7 @@ function validateConnectorState(value) {
3802
4209
  }
3803
4210
  function parseActiveRequest(value) {
3804
4211
  const active = requiredObject4(value, "state.activeRequest");
3805
- exactKeys(active, /* @__PURE__ */ new Set(["requestId", "requestSequence", "dshFromSequence", "dshToSequence", "promptDigest"]), "state.activeRequest");
4212
+ exactKeys(active, /* @__PURE__ */ new Set(["requestId", "requestSequence", "dshFromSequence", "dshToSequence", "promptDigest", "claimAttempt"]), "state.activeRequest");
3806
4213
  const parsed = {
3807
4214
  requestId: safeString(active.requestId, "state.activeRequest.requestId", 128),
3808
4215
  requestSequence: positiveInteger(active.requestSequence, "state.activeRequest.requestSequence"),
@@ -3810,7 +4217,10 @@ function parseActiveRequest(value) {
3810
4217
  ...active.dshToSequence === void 0 ? {} : {
3811
4218
  dshToSequence: nonNegativeInteger(active.dshToSequence, "state.activeRequest.dshToSequence")
3812
4219
  },
3813
- promptDigest: hexDigest(active.promptDigest, "state.activeRequest.promptDigest")
4220
+ promptDigest: hexDigest(active.promptDigest, "state.activeRequest.promptDigest"),
4221
+ ...active.claimAttempt === void 0 ? {} : {
4222
+ claimAttempt: positiveInteger(active.claimAttempt, "state.activeRequest.claimAttempt")
4223
+ }
3814
4224
  };
3815
4225
  if (parsed.dshToSequence !== void 0 && parsed.dshToSequence < parsed.dshFromSequence) {
3816
4226
  throw new Error("state.activeRequest.dshToSequence cannot precede dshFromSequence");
@@ -3895,6 +4305,7 @@ function parseAppendInput(value, label) {
3895
4305
  "replyTo",
3896
4306
  "visibility",
3897
4307
  "runtimeId",
4308
+ "claimAttempt",
3898
4309
  "observedModel",
3899
4310
  "observedReasoningEffort"
3900
4311
  ]), label);
@@ -3908,6 +4319,9 @@ function parseAppendInput(value, label) {
3908
4319
  ...input.replyTo === void 0 ? {} : { replyTo: safeString(input.replyTo, `${label}.replyTo`, 128) },
3909
4320
  ...input.visibility === void 0 ? {} : { visibility: safeString(input.visibility, `${label}.visibility`, 32) },
3910
4321
  ...input.runtimeId === void 0 ? {} : { runtimeId: safeString(input.runtimeId, `${label}.runtimeId`, 128) },
4322
+ ...input.claimAttempt === void 0 ? {} : {
4323
+ claimAttempt: positiveInteger(input.claimAttempt, `${label}.claimAttempt`)
4324
+ },
3911
4325
  ...input.observedModel === void 0 ? {} : { observedModel: safeString(input.observedModel, `${label}.observedModel`, 160) },
3912
4326
  ...input.observedReasoningEffort === void 0 ? {} : {
3913
4327
  observedReasoningEffort: safeString(input.observedReasoningEffort, `${label}.observedReasoningEffort`, 80)
@@ -3916,9 +4330,12 @@ function parseAppendInput(value, label) {
3916
4330
  }
3917
4331
  function parseCompletionInput(value, label) {
3918
4332
  const input = requiredObject4(value, label);
3919
- exactKeys(input, /* @__PURE__ */ new Set(["runtimeId", "idempotencyKey", "payload", "observedModel", "observedReasoningEffort"]), label);
4333
+ exactKeys(input, /* @__PURE__ */ new Set(["runtimeId", "claimAttempt", "idempotencyKey", "payload", "observedModel", "observedReasoningEffort"]), label);
3920
4334
  return {
3921
4335
  runtimeId: safeString(input.runtimeId, `${label}.runtimeId`, 128),
4336
+ ...input.claimAttempt === void 0 ? {} : {
4337
+ claimAttempt: positiveInteger(input.claimAttempt, `${label}.claimAttempt`)
4338
+ },
3922
4339
  idempotencyKey: safeString(input.idempotencyKey, `${label}.idempotencyKey`, 200),
3923
4340
  payload: jsonValue(input.payload, `${label}.payload`),
3924
4341
  ...input.observedModel === void 0 ? {} : { observedModel: safeString(input.observedModel, `${label}.observedModel`, 160) },
@@ -4248,6 +4665,8 @@ var RPC_ENDPOINTS = /* @__PURE__ */ new Set([
4248
4665
  ]);
4249
4666
  var MAX_CATALOG_PROVIDERS = 64;
4250
4667
  var MAX_CATALOG_MODELS = 256;
4668
+ var MAX_EXECUTION_PROFILES = 32;
4669
+ var MAX_REASONING_EFFORTS = 16;
4251
4670
  var DshNativeHostController = class {
4252
4671
  #options;
4253
4672
  #credentials;
@@ -4267,6 +4686,8 @@ var DshNativeHostController = class {
4267
4686
  #projectRefreshPromise;
4268
4687
  #projectRefreshAbort;
4269
4688
  #projectRefreshTimer;
4689
+ #executionProfileRouteKey;
4690
+ #executionProfiles;
4270
4691
  constructor(options) {
4271
4692
  this.#options = options;
4272
4693
  this.#credentials = new DshNativeCredentialStore(options.context);
@@ -4423,6 +4844,8 @@ var DshNativeHostController = class {
4423
4844
  throw new Error("The single-Project DSH client is obsolete; refresh DSH and explicitly confirm all accessible Projects");
4424
4845
  }
4425
4846
  await this.#validateModel(provider, model, operationSignal);
4847
+ this.#executionProfileRouteKey = void 0;
4848
+ this.#executionProfiles = void 0;
4426
4849
  const route = { provider, model };
4427
4850
  const nextGrant = { ...grant, route };
4428
4851
  try {
@@ -4478,6 +4901,8 @@ var DshNativeHostController = class {
4478
4901
  await this.#stopOwners();
4479
4902
  await this.#credentials.clear();
4480
4903
  this.#grant = void 0;
4904
+ this.#executionProfileRouteKey = void 0;
4905
+ this.#executionProfiles = void 0;
4481
4906
  this.#recoverableError = void 0;
4482
4907
  this.#options.status.setProjectName("GatherThread / \u5171\u5E8F");
4483
4908
  this.#options.status.setConnection("stopped");
@@ -4568,11 +4993,14 @@ var DshNativeHostController = class {
4568
4993
  ...this.#options.dshHome === void 0 ? {} : { dshHome: this.#options.dshHome },
4569
4994
  signal: signal2,
4570
4995
  status,
4996
+ ...this.#executionProfiles === void 0 ? {} : {
4997
+ executionProfiles: this.#executionProfiles
4998
+ },
4571
4999
  canCreateLocalSessions: role === "owner" || role === "participant",
4572
5000
  onStatus: (update) => this.#updateProjectStatus(bindingValue.projectId, update)
4573
5001
  });
4574
5002
  });
4575
- const owner = await createOwner(grant, binding, signal, this.#options.status, workspacePath);
5003
+ const owner = await createOwner(grant, binding, signal, this.#options.status, workspacePath, this.#executionProfiles);
4576
5004
  if (this.#disposed || signal.aborted) {
4577
5005
  await owner.stop();
4578
5006
  throw signal.reason instanceof Error ? signal.reason : new Error("GatherThread native DSH Project activation was cancelled");
@@ -4608,6 +5036,8 @@ var DshNativeHostController = class {
4608
5036
  if (route === void 0)
4609
5037
  return;
4610
5038
  throwIfAborted(signal);
5039
+ await this.#refreshExecutionProfiles(route, signal);
5040
+ throwIfAborted(signal);
4611
5041
  const nextIds = new Set(projects.map((project) => project.id));
4612
5042
  this.#projects.clear();
4613
5043
  for (const project of projects)
@@ -4639,6 +5069,24 @@ var DshNativeHostController = class {
4639
5069
  this.#refreshAggregateStatus();
4640
5070
  this.#recoverableError = failures > 0 ? "connection_failed" : void 0;
4641
5071
  }
5072
+ async #refreshExecutionProfiles(route, signal) {
5073
+ const routeKey = `${route.provider}\0${route.model}`;
5074
+ if (this.#executionProfileRouteKey === routeKey)
5075
+ return;
5076
+ if (route.provider !== "deepseek-official") {
5077
+ this.#executionProfiles = void 0;
5078
+ this.#executionProfileRouteKey = routeKey;
5079
+ return;
5080
+ }
5081
+ const discovered = this.#options.listExecutionProfiles === void 0 ? await listNativeExecutionProfiles(this.#options.context, route.provider, signal) : await this.#options.listExecutionProfiles(route.provider, signal);
5082
+ throwIfAborted(signal);
5083
+ const profiles = normalizeExecutionProfiles(discovered, route.provider);
5084
+ if (!profiles.some((profile) => profile.model === route.model)) {
5085
+ throw new Error("DeepSeek Harness did not advertise the configured model as an execution profile");
5086
+ }
5087
+ this.#executionProfiles = profiles;
5088
+ this.#executionProfileRouteKey = routeKey;
5089
+ }
4642
5090
  #currentBindings(route) {
4643
5091
  return [...this.#projects.values()].map((project) => ({
4644
5092
  projectId: project.id,
@@ -4821,12 +5269,18 @@ function parseNativePluginConfig(value) {
4821
5269
  };
4822
5270
  }
4823
5271
  async function createProductionOwner(options) {
4824
- const config = createNativeProjectConfig({
5272
+ const baseConfig = createNativeProjectConfig({
4825
5273
  grant: options.grant,
4826
5274
  binding: options.binding,
4827
5275
  workspacePath: options.workspacePath,
4828
5276
  ...options.dshHome === void 0 ? {} : { dshHome: options.dshHome }
4829
5277
  });
5278
+ const config = {
5279
+ ...baseConfig,
5280
+ ...options.executionProfiles === void 0 ? {} : {
5281
+ executionProfiles: cloneExecutionProfiles2(options.executionProfiles)
5282
+ }
5283
+ };
4830
5284
  await assertSafeDshStateRoot(config);
4831
5285
  const nativeWorkspace = await registerDshNativeWorkspace(options.context, config.workspacePath, options.binding.projectName);
4832
5286
  const ownerAbort = new AbortController();
@@ -4897,7 +5351,10 @@ function createNativeManagedConnector(options) {
4897
5351
  model: options.input.config.model,
4898
5352
  agentPreset: DSH_NATIVE_AGENT_PRESET,
4899
5353
  ...supersededSessionId === void 0 ? {} : { supersededSessionId },
4900
- sessionTitle: options.input.session.name ?? options.input.session.id,
5354
+ // A newly created DSH Session receives the GatherThread marker once;
5355
+ // resumed or adopted Sessions keep their locally editable titles. The
5356
+ // published status snapshot below stays on the bare cloud name.
5357
+ sessionTitle: managedDshSessionTitle(options.input.session),
4901
5358
  workspaceTitle: options.workspaceTitle
4902
5359
  });
4903
5360
  const connector = new DshHostConnector({
@@ -4977,6 +5434,25 @@ async function listNativeLlmCatalog(contextValue, signal) {
4977
5434
  }
4978
5435
  return result;
4979
5436
  }
5437
+ async function listNativeExecutionProfiles(contextValue, provider, signal) {
5438
+ const llm = requireLlm(contextValue);
5439
+ const models = parseModels(await llm.listModels(provider), provider).slice(0, MAX_EXECUTION_PROFILES);
5440
+ const profiles = [];
5441
+ for (const model of models) {
5442
+ throwIfAborted(signal);
5443
+ const resolved = asObject6(await llm.resolveModelInfo(provider, model.id, signal));
5444
+ if (resolved === void 0 || resolved.provider !== provider || resolved.id !== model.id) {
5445
+ throw new Error("DeepSeek Harness did not resolve an advertised provider/model exactly");
5446
+ }
5447
+ const reasoning = parseNativeReasoningMetadata(resolved.reasoning, provider, model.id);
5448
+ profiles.push({
5449
+ provider,
5450
+ model: model.id,
5451
+ ...reasoning
5452
+ });
5453
+ }
5454
+ return normalizeExecutionProfiles(profiles, provider);
5455
+ }
4980
5456
  async function validateNativeLlmModel(contextValue, provider, model, signal) {
4981
5457
  const resolved = asObject6(await requireLlm(contextValue).resolveModelInfo(provider, model, signal));
4982
5458
  if (resolved === void 0 || resolved.provider !== provider || resolved.id !== model) {
@@ -5014,6 +5490,77 @@ function parseModels(values, provider) {
5014
5490
  return { id, name: nameValue };
5015
5491
  });
5016
5492
  }
5493
+ function parseNativeReasoningMetadata(value, provider, model) {
5494
+ if (value === void 0)
5495
+ return {};
5496
+ const reasoning = asObject6(value);
5497
+ if (reasoning === void 0 || !Array.isArray(reasoning.efforts)) {
5498
+ throw new Error(`DeepSeek Harness returned invalid reasoning metadata for ${provider}/${model}`);
5499
+ }
5500
+ const reasoningEfforts = reasoning.efforts.map((entry) => {
5501
+ const effort = asObject6(entry);
5502
+ return boundedPublicText2(effort?.id, "reasoning effort id", 80);
5503
+ });
5504
+ if (reasoningEfforts.length === 0 || reasoningEfforts.length > MAX_REASONING_EFFORTS || new Set(reasoningEfforts).size !== reasoningEfforts.length) {
5505
+ throw new Error(`DeepSeek Harness returned invalid reasoning efforts for ${provider}/${model}`);
5506
+ }
5507
+ const defaultReasoningEffort = reasoning.defaultEffort === void 0 ? void 0 : boundedPublicText2(reasoning.defaultEffort, "default reasoning effort", 80);
5508
+ if (defaultReasoningEffort !== void 0 && !reasoningEfforts.includes(defaultReasoningEffort)) {
5509
+ throw new Error(`DeepSeek Harness returned an unknown default reasoning effort for ${provider}/${model}`);
5510
+ }
5511
+ return {
5512
+ reasoningEfforts,
5513
+ ...defaultReasoningEffort === void 0 ? {} : { defaultReasoningEffort }
5514
+ };
5515
+ }
5516
+ function normalizeExecutionProfiles(values, expectedProvider) {
5517
+ if (!Array.isArray(values) || values.length === 0 || values.length > MAX_EXECUTION_PROFILES) {
5518
+ throw new Error("DeepSeek Harness returned an invalid execution profile catalog");
5519
+ }
5520
+ const seen = /* @__PURE__ */ new Set();
5521
+ return values.map((value) => {
5522
+ const profile = asObject6(value);
5523
+ const provider = boundedPublicText2(profile?.provider, "execution profile provider", 80);
5524
+ const model = boundedPublicText2(profile?.model, "execution profile model", 160);
5525
+ if (provider !== expectedProvider) {
5526
+ throw new Error("DeepSeek Harness returned an execution profile for an unexpected provider");
5527
+ }
5528
+ const key = `${provider}\0${model}`;
5529
+ if (seen.has(key))
5530
+ throw new Error("DeepSeek Harness returned duplicate execution profiles");
5531
+ seen.add(key);
5532
+ const rawReasoningEfforts = profile?.reasoningEfforts;
5533
+ if (rawReasoningEfforts !== void 0 && !Array.isArray(rawReasoningEfforts)) {
5534
+ throw new Error("DeepSeek Harness returned invalid execution profile reasoning efforts");
5535
+ }
5536
+ const reasoningEfforts = rawReasoningEfforts === void 0 ? void 0 : rawReasoningEfforts.map((effort) => boundedPublicText2(effort, "execution profile reasoning effort", 80));
5537
+ if (reasoningEfforts !== void 0 && (reasoningEfforts.length === 0 || reasoningEfforts.length > MAX_REASONING_EFFORTS || new Set(reasoningEfforts).size !== reasoningEfforts.length)) {
5538
+ throw new Error("DeepSeek Harness returned invalid execution profile reasoning efforts");
5539
+ }
5540
+ const defaultReasoningEffort = profile?.defaultReasoningEffort === void 0 ? void 0 : boundedPublicText2(profile.defaultReasoningEffort, "execution profile default reasoning effort", 80);
5541
+ if (defaultReasoningEffort !== void 0 && !reasoningEfforts?.includes(defaultReasoningEffort)) {
5542
+ throw new Error("DeepSeek Harness returned an invalid execution profile default reasoning effort");
5543
+ }
5544
+ return {
5545
+ provider,
5546
+ model,
5547
+ ...reasoningEfforts === void 0 ? {} : { reasoningEfforts },
5548
+ ...defaultReasoningEffort === void 0 ? {} : { defaultReasoningEffort }
5549
+ };
5550
+ });
5551
+ }
5552
+ function cloneExecutionProfiles2(values) {
5553
+ return values.map((value) => ({
5554
+ provider: value.provider,
5555
+ model: value.model,
5556
+ ...value.reasoningEfforts === void 0 ? {} : {
5557
+ reasoningEfforts: [...value.reasoningEfforts]
5558
+ },
5559
+ ...value.defaultReasoningEffort === void 0 ? {} : {
5560
+ defaultReasoningEffort: value.defaultReasoningEffort
5561
+ }
5562
+ }));
5563
+ }
5017
5564
  function requireConnection(contextValue) {
5018
5565
  const input = asObject6(contextValue);
5019
5566
  const connection = input === void 0 ? void 0 : asObject6(Reflect.get(input, "connection"));