@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.
- package/README.md +20 -5
- package/bundle/manifest.json +1 -1
- package/client/client.js +7 -0
- package/cordis.patch.yml +18 -0
- package/dist/bundle/native-plugin.js +621 -74
- package/dist/bundle/plugin.js +460 -71
- package/package.json +1 -1
package/dist/bundle/plugin.js
CHANGED
|
@@ -432,7 +432,7 @@ var HttpCollaborationClient = class {
|
|
|
432
432
|
async registerRuntime(runtime) {
|
|
433
433
|
const body = requiredObject2(await this.#request("/runtimes", {
|
|
434
434
|
method: "POST",
|
|
435
|
-
body: JSON.stringify(
|
|
435
|
+
body: JSON.stringify(toWireRuntimeRegistration(runtime))
|
|
436
436
|
}));
|
|
437
437
|
return fromWireRuntime(body.runtime ?? body);
|
|
438
438
|
}
|
|
@@ -448,12 +448,19 @@ var HttpCollaborationClient = class {
|
|
|
448
448
|
method: "POST",
|
|
449
449
|
body: JSON.stringify({ runtime_id: runtimeId })
|
|
450
450
|
}));
|
|
451
|
-
|
|
451
|
+
if (body.status !== "claimed" && body.status !== "completed") {
|
|
452
|
+
throw new Error("Collaboration API omitted claim.status");
|
|
453
|
+
}
|
|
454
|
+
const attemptCount = body.attempt_count === void 0 ? 1 : requiredNumber(body.attempt_count, "claim.attempt_count");
|
|
455
|
+
if (attemptCount < 1)
|
|
456
|
+
throw new Error("Collaboration API omitted claim.attempt_count");
|
|
457
|
+
const status = body.status;
|
|
452
458
|
return {
|
|
453
459
|
claimed: status === "claimed",
|
|
454
460
|
status,
|
|
455
461
|
requestId: requiredString2(body.request_event_id, "claim.request_event_id"),
|
|
456
|
-
runtimeId: requiredString2(body.runtime_id, "claim.runtime_id")
|
|
462
|
+
runtimeId: requiredString2(body.runtime_id, "claim.runtime_id"),
|
|
463
|
+
attemptCount
|
|
457
464
|
};
|
|
458
465
|
}
|
|
459
466
|
async completeAgentRequest(sessionId, requestId, input) {
|
|
@@ -461,6 +468,7 @@ var HttpCollaborationClient = class {
|
|
|
461
468
|
method: "POST",
|
|
462
469
|
body: JSON.stringify({
|
|
463
470
|
runtime_id: input.runtimeId,
|
|
471
|
+
...input.claimAttempt === void 0 ? {} : { claim_attempt: input.claimAttempt },
|
|
464
472
|
idempotency_key: input.idempotencyKey,
|
|
465
473
|
payload: truncateJsonValue(input.payload, 160 * 1024),
|
|
466
474
|
...input.observedModel === void 0 ? {} : { observed_model: input.observedModel },
|
|
@@ -474,6 +482,7 @@ var HttpCollaborationClient = class {
|
|
|
474
482
|
method: "POST",
|
|
475
483
|
body: JSON.stringify({
|
|
476
484
|
runtime_id: input.runtimeId,
|
|
485
|
+
...input.claimAttempt === void 0 ? {} : { claim_attempt: input.claimAttempt },
|
|
477
486
|
idempotency_key: input.idempotencyKey,
|
|
478
487
|
payload: truncateJsonValue(input.payload, 32 * 1024),
|
|
479
488
|
...input.observedModel === void 0 ? {} : { observed_model: input.observedModel },
|
|
@@ -512,10 +521,10 @@ var HttpCollaborationClient = class {
|
|
|
512
521
|
const body = requiredObject2(await this.#request(`/snapshot-requests/${encodeURIComponent(requestId)}`));
|
|
513
522
|
return fromWireSnapshotRequest(body.snapshot_request ?? body);
|
|
514
523
|
}
|
|
515
|
-
async createSnapshotRequest(sessionId, kind = "immutable") {
|
|
524
|
+
async createSnapshotRequest(sessionId, kind = "immutable", targetRuntimeId) {
|
|
516
525
|
const body = requiredObject2(await this.#request(`/sessions/${encodeURIComponent(sessionId)}/snapshot-requests`, {
|
|
517
526
|
method: "POST",
|
|
518
|
-
body: JSON.stringify({ kind })
|
|
527
|
+
body: JSON.stringify({ kind, ...targetRuntimeId === void 0 ? {} : { target_runtime_id: targetRuntimeId } })
|
|
519
528
|
}));
|
|
520
529
|
return fromWireSnapshotRequest(body.snapshot_request ?? body);
|
|
521
530
|
}
|
|
@@ -595,15 +604,34 @@ function toWireEvent(event) {
|
|
|
595
604
|
reply_to_event_id: event.replyTo,
|
|
596
605
|
visibility: event.visibility ?? "session",
|
|
597
606
|
runtime_id: event.runtimeId ?? event.runtime?.runtimeId,
|
|
607
|
+
claim_attempt: event.claimAttempt,
|
|
598
608
|
observed_model: event.observedModel,
|
|
599
609
|
observed_reasoning_effort: event.observedReasoningEffort
|
|
600
610
|
};
|
|
601
611
|
}
|
|
602
|
-
function
|
|
603
|
-
return
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
612
|
+
function toWireRuntimeRegistration(runtime) {
|
|
613
|
+
return {
|
|
614
|
+
...runtime.runtimeId === void 0 ? {} : { runtime_id: runtime.runtimeId },
|
|
615
|
+
session_id: runtime.sessionId,
|
|
616
|
+
device_id: runtime.deviceId,
|
|
617
|
+
harness: runtime.harness,
|
|
618
|
+
provider: runtime.provider,
|
|
619
|
+
model: runtime.model,
|
|
620
|
+
...runtime.executionProfiles === void 0 ? {} : {
|
|
621
|
+
execution_profiles: runtime.executionProfiles.map((profile) => ({
|
|
622
|
+
provider: profile.provider,
|
|
623
|
+
model: profile.model,
|
|
624
|
+
...profile.reasoningEfforts === void 0 ? {} : { reasoning_efforts: [...profile.reasoningEfforts] },
|
|
625
|
+
...profile.defaultReasoningEffort === void 0 ? {} : {
|
|
626
|
+
default_reasoning_effort: profile.defaultReasoningEffort
|
|
627
|
+
}
|
|
628
|
+
}))
|
|
629
|
+
},
|
|
630
|
+
local_session_id: runtime.localSessionId,
|
|
631
|
+
capture_fidelity: runtime.captureFidelity,
|
|
632
|
+
...runtime.capabilities === void 0 ? {} : { capabilities: [...runtime.capabilities] },
|
|
633
|
+
...runtime.purpose === void 0 ? {} : { purpose: runtime.purpose }
|
|
634
|
+
};
|
|
607
635
|
}
|
|
608
636
|
function fromWireEvent(value) {
|
|
609
637
|
const input = requiredObject2(value);
|
|
@@ -633,10 +661,22 @@ function fromWireSnapshotRequest(value) {
|
|
|
633
661
|
message: requiredString2(failureInput.message, "snapshot_request.failure.message")
|
|
634
662
|
} : void 0;
|
|
635
663
|
const createdAt = optionalWireString(input.created_at) ?? optionalWireString(input.requested_at);
|
|
664
|
+
const kind = requiredString2(input.kind, "snapshot_request.kind");
|
|
665
|
+
if (![
|
|
666
|
+
"immutable",
|
|
667
|
+
"visible_history_replace",
|
|
668
|
+
"local_sync_status",
|
|
669
|
+
"local_auto_upload_enable",
|
|
670
|
+
"local_auto_upload_disable",
|
|
671
|
+
"local_turn_upload"
|
|
672
|
+
].includes(kind)) {
|
|
673
|
+
throw new Error("Collaboration API returned an invalid snapshot request kind");
|
|
674
|
+
}
|
|
636
675
|
return {
|
|
637
676
|
id: requiredString2(input.id, "snapshot_request.id"),
|
|
638
677
|
sessionId: requiredString2(input.session_id, "snapshot_request.session_id"),
|
|
639
|
-
kind
|
|
678
|
+
kind,
|
|
679
|
+
...typeof input.target_runtime_id === "string" ? { targetRuntimeId: input.target_runtime_id } : {},
|
|
640
680
|
throughSequence: requiredNumber(input.through_sequence, "snapshot_request.through_sequence"),
|
|
641
681
|
status,
|
|
642
682
|
...createdAt === void 0 ? {} : { createdAt },
|
|
@@ -701,11 +741,61 @@ function fromWireRuntime(value) {
|
|
|
701
741
|
harness: requiredString2(input.harness, "runtime.harness"),
|
|
702
742
|
provider: requiredString2(input.provider, "runtime.provider"),
|
|
703
743
|
model: requiredString2(input.model, "runtime.model"),
|
|
744
|
+
...input.execution_profiles === void 0 || input.execution_profiles === null ? {} : { executionProfiles: fromWireExecutionProfiles(input.execution_profiles) },
|
|
704
745
|
localSessionId: requiredString2(input.local_session_id, "runtime.local_session_id"),
|
|
705
746
|
captureFidelity: requiredString2(input.capture_fidelity, "runtime.capture_fidelity"),
|
|
706
747
|
purpose
|
|
707
748
|
};
|
|
708
749
|
}
|
|
750
|
+
function fromWireExecutionProfiles(value) {
|
|
751
|
+
if (!Array.isArray(value) || value.length < 1 || value.length > 32) {
|
|
752
|
+
throw new Error("Collaboration API returned invalid runtime.execution_profiles");
|
|
753
|
+
}
|
|
754
|
+
const routes = /* @__PURE__ */ new Set();
|
|
755
|
+
return value.map((entry, index) => {
|
|
756
|
+
const profile = requiredObject2(entry);
|
|
757
|
+
const allowedKeys = /* @__PURE__ */ new Set(["provider", "model", "reasoning_efforts", "default_reasoning_effort"]);
|
|
758
|
+
if (Object.keys(profile).some((key) => !allowedKeys.has(key))) {
|
|
759
|
+
throw new Error(`Collaboration API returned invalid runtime.execution_profiles[${index}]`);
|
|
760
|
+
}
|
|
761
|
+
const provider = requiredExecutionProfileString(profile.provider, `runtime.execution_profiles[${index}].provider`, 80);
|
|
762
|
+
const model = requiredExecutionProfileString(profile.model, `runtime.execution_profiles[${index}].model`, 160);
|
|
763
|
+
const route = `${provider}\0${model}`;
|
|
764
|
+
if (routes.has(route))
|
|
765
|
+
throw new Error("Collaboration API returned duplicate runtime.execution_profiles");
|
|
766
|
+
routes.add(route);
|
|
767
|
+
const rawEfforts = profile.reasoning_efforts;
|
|
768
|
+
let reasoningEfforts;
|
|
769
|
+
if (rawEfforts !== void 0) {
|
|
770
|
+
if (!Array.isArray(rawEfforts) || rawEfforts.length < 1 || rawEfforts.length > 16) {
|
|
771
|
+
throw new Error(`Collaboration API returned invalid runtime.execution_profiles[${index}].reasoning_efforts`);
|
|
772
|
+
}
|
|
773
|
+
reasoningEfforts = rawEfforts.map((effort, effortIndex) => requiredExecutionProfileString(effort, `runtime.execution_profiles[${index}].reasoning_efforts[${effortIndex}]`, 80));
|
|
774
|
+
if (new Set(reasoningEfforts).size !== reasoningEfforts.length) {
|
|
775
|
+
throw new Error(`Collaboration API returned duplicate runtime.execution_profiles[${index}].reasoning_efforts`);
|
|
776
|
+
}
|
|
777
|
+
}
|
|
778
|
+
const defaultReasoningEffort = profile.default_reasoning_effort === void 0 ? void 0 : requiredExecutionProfileString(profile.default_reasoning_effort, `runtime.execution_profiles[${index}].default_reasoning_effort`, 80);
|
|
779
|
+
if (defaultReasoningEffort !== void 0 && !reasoningEfforts?.includes(defaultReasoningEffort)) {
|
|
780
|
+
throw new Error(`Collaboration API returned an unadvertised runtime.execution_profiles[${index}].default_reasoning_effort`);
|
|
781
|
+
}
|
|
782
|
+
return {
|
|
783
|
+
provider,
|
|
784
|
+
model,
|
|
785
|
+
...reasoningEfforts === void 0 ? {} : { reasoningEfforts },
|
|
786
|
+
...defaultReasoningEffort === void 0 ? {} : { defaultReasoningEffort }
|
|
787
|
+
};
|
|
788
|
+
});
|
|
789
|
+
}
|
|
790
|
+
function requiredExecutionProfileString(value, field, maxLength) {
|
|
791
|
+
if (typeof value !== "string")
|
|
792
|
+
throw new Error(`Collaboration API omitted ${field}`);
|
|
793
|
+
const normalized = value.trim();
|
|
794
|
+
if (!normalized || normalized.length > maxLength || /[\u0000-\u001f\u007f-\u009f]/u.test(normalized)) {
|
|
795
|
+
throw new Error(`Collaboration API returned invalid ${field}`);
|
|
796
|
+
}
|
|
797
|
+
return normalized;
|
|
798
|
+
}
|
|
709
799
|
function fromWireProvenance(value) {
|
|
710
800
|
const input = requiredObject2(value);
|
|
711
801
|
return {
|
|
@@ -964,7 +1054,7 @@ function isTerminalClaimConflict(error) {
|
|
|
964
1054
|
if (!error || typeof error !== "object")
|
|
965
1055
|
return false;
|
|
966
1056
|
const candidate = error;
|
|
967
|
-
return candidate.status === 409 && (candidate.code === "agent_request_already_claimed" || candidate.code === "agent_request_already_completed");
|
|
1057
|
+
return candidate.status === 409 && (candidate.code === "agent_request_already_claimed" || candidate.code === "agent_request_already_completed" || candidate.code === "agent_request_failed");
|
|
968
1058
|
}
|
|
969
1059
|
|
|
970
1060
|
// dist/src/connector.js
|
|
@@ -991,11 +1081,16 @@ function requestedDshProfile(event) {
|
|
|
991
1081
|
if (profile.provider !== void 0 && !provider) {
|
|
992
1082
|
throw new Error("DeepSeek Harness Agent request has an invalid provider target");
|
|
993
1083
|
}
|
|
1084
|
+
const reasoningEffort = profile.reasoning_effort === void 0 ? void 0 : safeProfileText(profile.reasoning_effort, 80);
|
|
1085
|
+
if (profile.reasoning_effort !== void 0 && !reasoningEffort) {
|
|
1086
|
+
throw new Error("DeepSeek Harness Agent request has an invalid reasoning effort target");
|
|
1087
|
+
}
|
|
994
1088
|
const runtimeId = profile.runtime_id === void 0 ? void 0 : safeRuntimeId(profile.runtime_id);
|
|
995
1089
|
return {
|
|
996
1090
|
harness,
|
|
997
1091
|
...provider === void 0 ? {} : { provider },
|
|
998
1092
|
model,
|
|
1093
|
+
...reasoningEffort === void 0 ? {} : { reasoningEffort },
|
|
999
1094
|
...runtimeId === void 0 ? {} : { runtimeId }
|
|
1000
1095
|
};
|
|
1001
1096
|
}
|
|
@@ -1292,6 +1387,7 @@ function asObject2(value) {
|
|
|
1292
1387
|
}
|
|
1293
1388
|
|
|
1294
1389
|
// dist/src/connector.js
|
|
1390
|
+
var LIVE_PROGRESS_MIN_INTERVAL_MS = 6e4;
|
|
1295
1391
|
var DshHostConnector = class {
|
|
1296
1392
|
#config;
|
|
1297
1393
|
#api;
|
|
@@ -1312,11 +1408,15 @@ var DshHostConnector = class {
|
|
|
1312
1408
|
#pollPromise;
|
|
1313
1409
|
#localSyncControlPromise;
|
|
1314
1410
|
#heartbeatPromise;
|
|
1411
|
+
#liveProgressPromise = Promise.resolve();
|
|
1412
|
+
#lastLiveProgressKey;
|
|
1413
|
+
#lastLiveProgressAt = 0;
|
|
1315
1414
|
#stopPromise;
|
|
1316
1415
|
#backgroundFatalError;
|
|
1317
1416
|
#lifecycleAbort = new AbortController();
|
|
1318
1417
|
#listenerDisposers = [];
|
|
1319
1418
|
#activeStatuses = [];
|
|
1419
|
+
#activeExecutionSelection;
|
|
1320
1420
|
#liveEventSequences = /* @__PURE__ */ new Set();
|
|
1321
1421
|
#session;
|
|
1322
1422
|
#visibleState = "connecting";
|
|
@@ -1395,6 +1495,14 @@ var DshHostConnector = class {
|
|
|
1395
1495
|
const active = this.#state?.activeRequest;
|
|
1396
1496
|
if (active !== void 0 && event.seq >= active.dshFromSequence) {
|
|
1397
1497
|
this.#liveEventSequences.add(event.seq);
|
|
1498
|
+
this.#queueLiveProgress(`dsh-live-${String(event.seq)}`, {
|
|
1499
|
+
content: "DeepSeek Harness produced durable work for the active request.",
|
|
1500
|
+
phase: "activity",
|
|
1501
|
+
status: "running",
|
|
1502
|
+
dsh_event_sequence: event.seq,
|
|
1503
|
+
capture_fidelity: "harness_transcript",
|
|
1504
|
+
source_harness: "deepseek-harness"
|
|
1505
|
+
});
|
|
1398
1506
|
}
|
|
1399
1507
|
if (active === void 0 && event.type === "turn/end" && turnSettlement([event]) === "completed" && this.#automaticPolling) {
|
|
1400
1508
|
queueMicrotask(() => {
|
|
@@ -1409,8 +1517,9 @@ var DshHostConnector = class {
|
|
|
1409
1517
|
this.#listenerDisposers.push(this.#host.onStatus((status) => {
|
|
1410
1518
|
if (this.#state?.activeRequest === void 0)
|
|
1411
1519
|
return;
|
|
1412
|
-
if (this.#activeStatuses.at(-1) !== status)
|
|
1520
|
+
if (this.#activeStatuses.at(-1) !== status) {
|
|
1413
1521
|
this.#activeStatuses.push(status);
|
|
1522
|
+
}
|
|
1414
1523
|
this.#notifyLifecycle(status);
|
|
1415
1524
|
}));
|
|
1416
1525
|
try {
|
|
@@ -1441,16 +1550,20 @@ var DshHostConnector = class {
|
|
|
1441
1550
|
"canonical_history_projection",
|
|
1442
1551
|
"bidirectional_local_turns"
|
|
1443
1552
|
],
|
|
1553
|
+
...this.#config.executionProfiles === void 0 ? {} : {
|
|
1554
|
+
executionProfiles: cloneExecutionProfiles(this.#config.executionProfiles)
|
|
1555
|
+
},
|
|
1444
1556
|
purpose: "execution"
|
|
1445
1557
|
});
|
|
1446
1558
|
this.#assertRuntime(this.#runtime);
|
|
1447
1559
|
this.#notifyLifecycle("idle");
|
|
1448
1560
|
if (options.schedule !== false)
|
|
1449
1561
|
this.#scheduleHeartbeat();
|
|
1450
|
-
await this.#flushOutbox(this.#requireState().automaticUpload);
|
|
1451
|
-
await this.#finalizeDeliveredRequest();
|
|
1452
1562
|
if (this.#state.activeRequest !== void 0) {
|
|
1453
1563
|
await this.#withExecutionPermit(() => this.#recoverActiveRequest());
|
|
1564
|
+
} else {
|
|
1565
|
+
await this.#flushOutbox(this.#requireState().automaticUpload);
|
|
1566
|
+
await this.#finalizeDeliveredRequest();
|
|
1454
1567
|
}
|
|
1455
1568
|
if (options.runImmediately !== false)
|
|
1456
1569
|
await this.pollOnce();
|
|
@@ -1537,12 +1650,12 @@ var DshHostConnector = class {
|
|
|
1537
1650
|
}
|
|
1538
1651
|
async #poll() {
|
|
1539
1652
|
const state = this.#requireState();
|
|
1540
|
-
await this.#flushOutbox(state.automaticUpload);
|
|
1541
|
-
await this.#finalizeDeliveredRequest();
|
|
1542
1653
|
if (state.activeRequest !== void 0) {
|
|
1543
1654
|
await this.#withExecutionPermit(() => this.#recoverActiveRequest());
|
|
1544
1655
|
return { scanned: 0, claimed: 0, completed: 1 };
|
|
1545
1656
|
}
|
|
1657
|
+
await this.#flushOutbox(state.automaticUpload);
|
|
1658
|
+
await this.#finalizeDeliveredRequest();
|
|
1546
1659
|
if (state.automaticUpload) {
|
|
1547
1660
|
await this.#captureLocalTurns();
|
|
1548
1661
|
await this.#flushOutbox(true);
|
|
@@ -1558,7 +1671,7 @@ var DshHostConnector = class {
|
|
|
1558
1671
|
scanCursor = Math.max(scanCursor, event.sequence);
|
|
1559
1672
|
scanned += 1;
|
|
1560
1673
|
const profile = requestedDshProfile(event);
|
|
1561
|
-
if (profile === void 0 || event.actorId !== this.#requireRuntime().userId ||
|
|
1674
|
+
if (profile === void 0 || event.actorId !== this.#requireRuntime().userId || !this.#profileTargetsThisRuntime(profile)) {
|
|
1562
1675
|
passive.push(event);
|
|
1563
1676
|
continue;
|
|
1564
1677
|
}
|
|
@@ -1566,13 +1679,8 @@ var DshHostConnector = class {
|
|
|
1566
1679
|
if (manualUploadRequired) {
|
|
1567
1680
|
return { scanned, claimed: 0, completed: 0 };
|
|
1568
1681
|
}
|
|
1569
|
-
|
|
1570
|
-
|
|
1571
|
-
}
|
|
1572
|
-
if (profile.model !== this.#config.model) {
|
|
1573
|
-
throw new Error("DeepSeek Harness Agent request model does not match the configured Host binding");
|
|
1574
|
-
}
|
|
1575
|
-
const outcome = await this.#withExecutionPermit(() => this.#executeRequest(event));
|
|
1682
|
+
const selection = this.#resolveExecutionSelection(profile);
|
|
1683
|
+
const outcome = await this.#withExecutionPermit(() => this.#executeRequest(event, selection));
|
|
1576
1684
|
return {
|
|
1577
1685
|
scanned,
|
|
1578
1686
|
claimed: outcome.claimed ? 1 : 0,
|
|
@@ -1590,7 +1698,7 @@ var DshHostConnector = class {
|
|
|
1590
1698
|
}
|
|
1591
1699
|
throw new Error("DSH connector stopped during event replay");
|
|
1592
1700
|
}
|
|
1593
|
-
async #executeRequest(request) {
|
|
1701
|
+
async #executeRequest(request, selection) {
|
|
1594
1702
|
if (this.#stopped)
|
|
1595
1703
|
throw new Error("DSH connector stopped before claiming an Agent request");
|
|
1596
1704
|
const state = this.#requireState();
|
|
@@ -1614,17 +1722,20 @@ var DshHostConnector = class {
|
|
|
1614
1722
|
requestId: request.id,
|
|
1615
1723
|
requestSequence: request.sequence,
|
|
1616
1724
|
dshFromSequence: baseline,
|
|
1617
|
-
promptDigest: digest(prompt)
|
|
1725
|
+
promptDigest: digest(prompt),
|
|
1726
|
+
claimAttempt: claim.attemptCount ?? 1
|
|
1618
1727
|
};
|
|
1619
1728
|
this.#activeStatuses = [];
|
|
1729
|
+
this.#activeExecutionSelection = selection;
|
|
1620
1730
|
this.#liveEventSequences.clear();
|
|
1621
1731
|
await this.#stateStore.save(state);
|
|
1622
|
-
const result = await this.#host.prompt(prompt);
|
|
1732
|
+
const result = await this.#host.prompt(prompt, selection);
|
|
1623
1733
|
if (result.fromSequence !== baseline || result.toSequence < result.fromSequence) {
|
|
1624
1734
|
throw new Error("DSH Host prompt returned an inconsistent durable event range");
|
|
1625
1735
|
}
|
|
1736
|
+
await this.#liveProgressPromise;
|
|
1626
1737
|
this.#assertLiveEventsDurable(result);
|
|
1627
|
-
await this.#settleActiveRequest(result.events, result.toSequence);
|
|
1738
|
+
await this.#settleActiveRequest(result.events, result.toSequence, selection);
|
|
1628
1739
|
return { claimed: true, completed: true };
|
|
1629
1740
|
}
|
|
1630
1741
|
async #recoverActiveRequest() {
|
|
@@ -1634,6 +1745,46 @@ var DshHostConnector = class {
|
|
|
1634
1745
|
const active = state.activeRequest;
|
|
1635
1746
|
if (active === void 0)
|
|
1636
1747
|
return;
|
|
1748
|
+
let claim;
|
|
1749
|
+
try {
|
|
1750
|
+
claim = await this.#api.claimAgentRequest(this.#config.sessionId, active.requestId, this.#requireRuntime().id);
|
|
1751
|
+
} catch (error) {
|
|
1752
|
+
if (!isTerminalClaimConflict(error))
|
|
1753
|
+
throw error;
|
|
1754
|
+
state.outbox = state.outbox.filter((operation) => !outboxBelongsToRequest(operation, active.requestId));
|
|
1755
|
+
if (active.dshToSequence !== void 0) {
|
|
1756
|
+
state.publishedDshSequence = Math.max(state.publishedDshSequence, active.dshToSequence);
|
|
1757
|
+
}
|
|
1758
|
+
delete state.activeRequest;
|
|
1759
|
+
this.#activeStatuses = [];
|
|
1760
|
+
this.#activeExecutionSelection = void 0;
|
|
1761
|
+
this.#liveEventSequences.clear();
|
|
1762
|
+
await this.#stateStore.save(state);
|
|
1763
|
+
return;
|
|
1764
|
+
}
|
|
1765
|
+
if (claim.status === "completed" && active.dshToSequence !== void 0) {
|
|
1766
|
+
state.outbox = [];
|
|
1767
|
+
await this.#stateStore.save(state);
|
|
1768
|
+
await this.#finalizeDeliveredRequest();
|
|
1769
|
+
return;
|
|
1770
|
+
}
|
|
1771
|
+
if (!claim.claimed) {
|
|
1772
|
+
throw new Error("Active GatherThread request no longer has a recoverable claim");
|
|
1773
|
+
}
|
|
1774
|
+
const claimAttempt = claim.attemptCount ?? active.claimAttempt ?? 1;
|
|
1775
|
+
active.claimAttempt = claimAttempt;
|
|
1776
|
+
if (active.dshToSequence !== void 0) {
|
|
1777
|
+
state.outbox = state.outbox.map((operation) => {
|
|
1778
|
+
if ((operation.kind === "progress" || operation.kind === "complete") && operation.requestId === active.requestId) {
|
|
1779
|
+
return { ...operation, input: { ...operation.input, claimAttempt } };
|
|
1780
|
+
}
|
|
1781
|
+
if (operation.kind === "append" && operation.input.replyTo === active.requestId) {
|
|
1782
|
+
return { ...operation, input: { ...operation.input, claimAttempt } };
|
|
1783
|
+
}
|
|
1784
|
+
return operation;
|
|
1785
|
+
});
|
|
1786
|
+
}
|
|
1787
|
+
await this.#stateStore.save(state);
|
|
1637
1788
|
if (active.dshToSequence !== void 0) {
|
|
1638
1789
|
await this.#flushOutbox();
|
|
1639
1790
|
await this.#finalizeDeliveredRequest();
|
|
@@ -1645,6 +1796,15 @@ var DshHostConnector = class {
|
|
|
1645
1796
|
throw new Error("Active GatherThread request is unavailable during DSH resume");
|
|
1646
1797
|
}
|
|
1647
1798
|
const prompt = buildDshRequestPrompt(request);
|
|
1799
|
+
const profile = requestedDshProfile(request);
|
|
1800
|
+
if (profile === void 0) {
|
|
1801
|
+
throw new Error("Active GatherThread request lost its DeepSeek Harness execution profile");
|
|
1802
|
+
}
|
|
1803
|
+
if (!this.#profileTargetsThisRuntime(profile)) {
|
|
1804
|
+
throw new Error("Active GatherThread request no longer targets this exact DSH runtime");
|
|
1805
|
+
}
|
|
1806
|
+
const selection = this.#resolveExecutionSelection(profile);
|
|
1807
|
+
this.#activeExecutionSelection = selection;
|
|
1648
1808
|
const legacyPrompt = buildDshCanonicalPrompt(history, request, this.#requireRuntime().id);
|
|
1649
1809
|
if (digest(prompt) !== active.promptDigest && digest(legacyPrompt) !== active.promptDigest) {
|
|
1650
1810
|
throw new Error("Active GatherThread request changed during DSH resume");
|
|
@@ -1652,7 +1812,7 @@ var DshHostConnector = class {
|
|
|
1652
1812
|
const recovered = this.#host.snapshotFrom(active.dshFromSequence);
|
|
1653
1813
|
const settlement = turnSettlement(recovered);
|
|
1654
1814
|
if (settlement === "completed") {
|
|
1655
|
-
await this.#settleActiveRequest(recovered, this.#host.currentSequence());
|
|
1815
|
+
await this.#settleActiveRequest(recovered, this.#host.currentSequence(), selection);
|
|
1656
1816
|
return;
|
|
1657
1817
|
}
|
|
1658
1818
|
if (settlement !== void 0 && settlement !== "interrupted") {
|
|
@@ -1670,14 +1830,15 @@ var DshHostConnector = class {
|
|
|
1670
1830
|
this.#activeStatuses = [];
|
|
1671
1831
|
this.#liveEventSequences.clear();
|
|
1672
1832
|
await this.#stateStore.save(state);
|
|
1673
|
-
const result = await this.#host.prompt(continuation);
|
|
1833
|
+
const result = await this.#host.prompt(continuation, selection);
|
|
1674
1834
|
if (result.fromSequence !== baseline || result.toSequence < result.fromSequence) {
|
|
1675
1835
|
throw new Error("DSH Host recovery prompt returned an inconsistent durable event range");
|
|
1676
1836
|
}
|
|
1837
|
+
await this.#liveProgressPromise;
|
|
1677
1838
|
this.#assertLiveEventsDurable(result);
|
|
1678
|
-
await this.#settleActiveRequest(result.events, result.toSequence);
|
|
1839
|
+
await this.#settleActiveRequest(result.events, result.toSequence, selection);
|
|
1679
1840
|
}
|
|
1680
|
-
async #settleActiveRequest(durableEvents, toSequence) {
|
|
1841
|
+
async #settleActiveRequest(durableEvents, toSequence, selection) {
|
|
1681
1842
|
const state = this.#requireState();
|
|
1682
1843
|
const active = state.activeRequest;
|
|
1683
1844
|
if (active === void 0)
|
|
@@ -1693,11 +1854,51 @@ var DshHostConnector = class {
|
|
|
1693
1854
|
if (state.outbox.length > 0)
|
|
1694
1855
|
throw new Error("DSH connector outbox was not empty before settlement");
|
|
1695
1856
|
state.activeRequest = { ...active, dshToSequence: toSequence };
|
|
1696
|
-
state.outbox = this.#outboxFor(mapped, this.#activeStatuses, active.requestId);
|
|
1857
|
+
state.outbox = this.#outboxFor(mapped, this.#activeStatuses, active.requestId, active.claimAttempt ?? 1, selection);
|
|
1697
1858
|
await this.#stateStore.save(state);
|
|
1698
1859
|
await this.#flushOutbox();
|
|
1699
1860
|
await this.#finalizeDeliveredRequest();
|
|
1700
1861
|
}
|
|
1862
|
+
#queueLiveProgress(idSuffix, payload) {
|
|
1863
|
+
const active = this.#state?.activeRequest;
|
|
1864
|
+
const runtime = this.#runtime;
|
|
1865
|
+
if (active === void 0 || runtime === void 0)
|
|
1866
|
+
return;
|
|
1867
|
+
const requestId = active.requestId;
|
|
1868
|
+
const claimAttempt = active.claimAttempt ?? 1;
|
|
1869
|
+
const progressKey = `${requestId}:${String(claimAttempt)}`;
|
|
1870
|
+
const now = Date.now();
|
|
1871
|
+
if (this.#lastLiveProgressKey === progressKey && now - this.#lastLiveProgressAt < LIVE_PROGRESS_MIN_INTERVAL_MS) {
|
|
1872
|
+
return;
|
|
1873
|
+
}
|
|
1874
|
+
this.#lastLiveProgressKey = progressKey;
|
|
1875
|
+
this.#lastLiveProgressAt = now;
|
|
1876
|
+
const idempotencyKey = `${this.#config.deviceId}:${digest(requestId).slice(0, 24)}:${idSuffix}`;
|
|
1877
|
+
this.#liveProgressPromise = this.#liveProgressPromise.then(async () => {
|
|
1878
|
+
const current = this.#state?.activeRequest;
|
|
1879
|
+
if (current?.requestId !== requestId || (current.claimAttempt ?? 1) !== claimAttempt)
|
|
1880
|
+
return;
|
|
1881
|
+
const selection = this.#activeExecutionSelection;
|
|
1882
|
+
if (selection === void 0)
|
|
1883
|
+
return;
|
|
1884
|
+
await this.#api.appendAgentProgress(this.#config.sessionId, requestId, {
|
|
1885
|
+
runtimeId: runtime.id,
|
|
1886
|
+
claimAttempt,
|
|
1887
|
+
idempotencyKey,
|
|
1888
|
+
payload,
|
|
1889
|
+
observedModel: selection.model,
|
|
1890
|
+
...selection.reasoningEffort === void 0 ? {} : {
|
|
1891
|
+
observedReasoningEffort: selection.reasoningEffort
|
|
1892
|
+
}
|
|
1893
|
+
});
|
|
1894
|
+
}).catch((error) => {
|
|
1895
|
+
if (this.#lastLiveProgressKey === progressKey) {
|
|
1896
|
+
this.#lastLiveProgressKey = void 0;
|
|
1897
|
+
this.#lastLiveProgressAt = 0;
|
|
1898
|
+
}
|
|
1899
|
+
this.#onBackgroundError?.(publicError(error));
|
|
1900
|
+
});
|
|
1901
|
+
}
|
|
1701
1902
|
async #projectCanonicalBatch(events, throughSequence) {
|
|
1702
1903
|
const state = this.#requireState();
|
|
1703
1904
|
if (throughSequence <= state.projectionCursor)
|
|
@@ -1781,7 +1982,7 @@ var DshHostConnector = class {
|
|
|
1781
1982
|
}
|
|
1782
1983
|
await this.#stateStore.save(state);
|
|
1783
1984
|
}
|
|
1784
|
-
#outboxFor(events, statuses, requestId) {
|
|
1985
|
+
#outboxFor(events, statuses, requestId, claimAttempt, selection) {
|
|
1785
1986
|
const runtime = this.#requireRuntime();
|
|
1786
1987
|
const prefix = `${this.#config.deviceId}:${digest(requestId).slice(0, 24)}`;
|
|
1787
1988
|
const operations = [];
|
|
@@ -1793,6 +1994,7 @@ var DshHostConnector = class {
|
|
|
1793
1994
|
requestId,
|
|
1794
1995
|
input: {
|
|
1795
1996
|
runtimeId: runtime.id,
|
|
1997
|
+
claimAttempt,
|
|
1796
1998
|
idempotencyKey,
|
|
1797
1999
|
payload: {
|
|
1798
2000
|
content: status === "running" ? "DeepSeek Harness started processing the request." : "DeepSeek Harness returned to idle.",
|
|
@@ -1801,7 +2003,10 @@ var DshHostConnector = class {
|
|
|
1801
2003
|
capture_fidelity: "harness_transcript",
|
|
1802
2004
|
source_harness: "deepseek-harness"
|
|
1803
2005
|
},
|
|
1804
|
-
observedModel:
|
|
2006
|
+
observedModel: selection.model,
|
|
2007
|
+
...selection.reasoningEffort === void 0 ? {} : {
|
|
2008
|
+
observedReasoningEffort: selection.reasoningEffort
|
|
2009
|
+
}
|
|
1805
2010
|
}
|
|
1806
2011
|
});
|
|
1807
2012
|
}
|
|
@@ -1835,7 +2040,11 @@ var DshHostConnector = class {
|
|
|
1835
2040
|
payload: redactValue(payload),
|
|
1836
2041
|
replyTo: requestId,
|
|
1837
2042
|
runtimeId: runtime.id,
|
|
1838
|
-
|
|
2043
|
+
claimAttempt,
|
|
2044
|
+
observedModel: selection.model,
|
|
2045
|
+
...selection.reasoningEffort === void 0 ? {} : {
|
|
2046
|
+
observedReasoningEffort: selection.reasoningEffort
|
|
2047
|
+
}
|
|
1839
2048
|
}
|
|
1840
2049
|
});
|
|
1841
2050
|
}
|
|
@@ -1850,6 +2059,7 @@ var DshHostConnector = class {
|
|
|
1850
2059
|
requestId,
|
|
1851
2060
|
input: {
|
|
1852
2061
|
runtimeId: runtime.id,
|
|
2062
|
+
claimAttempt,
|
|
1853
2063
|
idempotencyKey: completionKey,
|
|
1854
2064
|
payload: {
|
|
1855
2065
|
text: final.content,
|
|
@@ -1858,7 +2068,10 @@ var DshHostConnector = class {
|
|
|
1858
2068
|
source_timestamp: final.timestamp,
|
|
1859
2069
|
dsh_event_sequence: final.sequence
|
|
1860
2070
|
},
|
|
1861
|
-
observedModel:
|
|
2071
|
+
observedModel: selection.model,
|
|
2072
|
+
...selection.reasoningEffort === void 0 ? {} : {
|
|
2073
|
+
observedReasoningEffort: selection.reasoningEffort
|
|
2074
|
+
}
|
|
1862
2075
|
}
|
|
1863
2076
|
});
|
|
1864
2077
|
return operations;
|
|
@@ -1902,6 +2115,7 @@ var DshHostConnector = class {
|
|
|
1902
2115
|
state.publishedDshSequence = Math.max(state.publishedDshSequence, active.dshToSequence);
|
|
1903
2116
|
delete state.activeRequest;
|
|
1904
2117
|
this.#activeStatuses = [];
|
|
2118
|
+
this.#activeExecutionSelection = void 0;
|
|
1905
2119
|
this.#liveEventSequences.clear();
|
|
1906
2120
|
await this.#stateStore.save(state);
|
|
1907
2121
|
}
|
|
@@ -1987,10 +2201,45 @@ var DshHostConnector = class {
|
|
|
1987
2201
|
return stored;
|
|
1988
2202
|
}
|
|
1989
2203
|
#assertRuntime(runtime) {
|
|
1990
|
-
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") {
|
|
2204
|
+
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") {
|
|
1991
2205
|
throw new Error("GatherThread returned an incompatible DSH runtime registration");
|
|
1992
2206
|
}
|
|
1993
2207
|
}
|
|
2208
|
+
#resolveExecutionSelection(profile) {
|
|
2209
|
+
const provider = profile.provider ?? this.#config.provider;
|
|
2210
|
+
const advertised = this.#config.executionProfiles;
|
|
2211
|
+
if (advertised === void 0) {
|
|
2212
|
+
if (provider !== this.#config.provider) {
|
|
2213
|
+
throw new Error("DeepSeek Harness Agent request provider does not match the configured Host binding");
|
|
2214
|
+
}
|
|
2215
|
+
if (profile.model !== this.#config.model) {
|
|
2216
|
+
throw new Error("DeepSeek Harness Agent request model does not match the configured Host binding");
|
|
2217
|
+
}
|
|
2218
|
+
if (profile.reasoningEffort !== void 0) {
|
|
2219
|
+
throw new Error("DeepSeek Harness fixed runtime did not advertise reasoning effort selection");
|
|
2220
|
+
}
|
|
2221
|
+
return { provider, model: profile.model };
|
|
2222
|
+
}
|
|
2223
|
+
const route = advertised.find((candidate) => candidate.provider === provider && candidate.model === profile.model);
|
|
2224
|
+
if (route === void 0) {
|
|
2225
|
+
throw new Error("DeepSeek Harness Agent request provider/model was not advertised by this runtime");
|
|
2226
|
+
}
|
|
2227
|
+
const reasoningEffort = profile.reasoningEffort ?? route.defaultReasoningEffort;
|
|
2228
|
+
if (reasoningEffort !== void 0 && !route.reasoningEfforts?.includes(reasoningEffort)) {
|
|
2229
|
+
throw new Error("DeepSeek Harness Agent request reasoning effort was not advertised for this model");
|
|
2230
|
+
}
|
|
2231
|
+
return {
|
|
2232
|
+
provider,
|
|
2233
|
+
model: profile.model,
|
|
2234
|
+
...reasoningEffort === void 0 ? {} : { reasoningEffort }
|
|
2235
|
+
};
|
|
2236
|
+
}
|
|
2237
|
+
#profileTargetsThisRuntime(profile) {
|
|
2238
|
+
const runtimeId = profile.runtimeId;
|
|
2239
|
+
if (runtimeId !== void 0)
|
|
2240
|
+
return runtimeId === this.#requireRuntime().id;
|
|
2241
|
+
return this.#config.executionProfiles === void 0;
|
|
2242
|
+
}
|
|
1994
2243
|
#validatePage(events, afterSequence) {
|
|
1995
2244
|
let previous = afterSequence;
|
|
1996
2245
|
for (const event of events) {
|
|
@@ -2090,6 +2339,21 @@ function turnSettlement(events) {
|
|
|
2090
2339
|
function digest(value) {
|
|
2091
2340
|
return createHash3("sha256").update(value).digest("hex");
|
|
2092
2341
|
}
|
|
2342
|
+
function cloneExecutionProfiles(profiles) {
|
|
2343
|
+
return profiles.map((profile) => ({
|
|
2344
|
+
provider: profile.provider,
|
|
2345
|
+
model: profile.model,
|
|
2346
|
+
...profile.reasoningEfforts === void 0 ? {} : {
|
|
2347
|
+
reasoningEfforts: [...profile.reasoningEfforts]
|
|
2348
|
+
},
|
|
2349
|
+
...profile.defaultReasoningEffort === void 0 ? {} : {
|
|
2350
|
+
defaultReasoningEffort: profile.defaultReasoningEffort
|
|
2351
|
+
}
|
|
2352
|
+
}));
|
|
2353
|
+
}
|
|
2354
|
+
function sameExecutionProfiles(actual, expected) {
|
|
2355
|
+
return JSON.stringify(actual ?? null) === JSON.stringify(expected ?? null);
|
|
2356
|
+
}
|
|
2093
2357
|
function publicError(error) {
|
|
2094
2358
|
if (error instanceof Error)
|
|
2095
2359
|
return error;
|
|
@@ -2189,6 +2453,12 @@ function boundedPublicText(value) {
|
|
|
2189
2453
|
}
|
|
2190
2454
|
return `${redacted.slice(0, low)}${suffix}`;
|
|
2191
2455
|
}
|
|
2456
|
+
function outboxBelongsToRequest(operation, requestId) {
|
|
2457
|
+
if (operation.kind === "progress" || operation.kind === "complete") {
|
|
2458
|
+
return operation.requestId === requestId;
|
|
2459
|
+
}
|
|
2460
|
+
return operation.kind === "append" && operation.input.replyTo === requestId;
|
|
2461
|
+
}
|
|
2192
2462
|
function sessionTimestamp(value) {
|
|
2193
2463
|
const date = new Date(value);
|
|
2194
2464
|
if (!Number.isFinite(date.getTime()))
|
|
@@ -2265,6 +2535,23 @@ function createDshHostFacade(options) {
|
|
|
2265
2535
|
for (const subscriber of statusSubscribers)
|
|
2266
2536
|
subscriber(status);
|
|
2267
2537
|
}, { global: true }));
|
|
2538
|
+
const adoptHandle = async (acquire) => {
|
|
2539
|
+
const acquired = await acquire();
|
|
2540
|
+
handle = acquired;
|
|
2541
|
+
if (disposed || lifecycleAbort.signal.aborted) {
|
|
2542
|
+
await releaseHandle();
|
|
2543
|
+
throw new Error("DSH host facade was disposed during open");
|
|
2544
|
+
}
|
|
2545
|
+
if (acquired.agent.session.id !== options.sessionId) {
|
|
2546
|
+
await releaseHandle();
|
|
2547
|
+
throw new Error("DSH Host returned an agent for an unexpected Session identity");
|
|
2548
|
+
}
|
|
2549
|
+
};
|
|
2550
|
+
const releaseHandle = async () => {
|
|
2551
|
+
const owned = handle;
|
|
2552
|
+
handle = void 0;
|
|
2553
|
+
await owned?.dispose();
|
|
2554
|
+
};
|
|
2268
2555
|
const open2 = () => {
|
|
2269
2556
|
if (disposed)
|
|
2270
2557
|
return Promise.reject(new Error("DSH host facade is disposed"));
|
|
@@ -2279,13 +2566,12 @@ function createDshHostFacade(options) {
|
|
|
2279
2566
|
const stored = liveAgent === void 0 ? await hasPersistedSession(persistence, options.sessionId, lifecycleAbort.signal) : true;
|
|
2280
2567
|
throwIfDisposed(disposed, lifecycleAbort.signal, "open");
|
|
2281
2568
|
const mode = stored ? "resumed" : "created";
|
|
2282
|
-
let openedHandle;
|
|
2283
2569
|
try {
|
|
2284
|
-
|
|
2570
|
+
await adoptHandle(() => liveAgent !== void 0 ? Promise.resolve({ agent: liveAgent, dispose: async () => void 0 }) : stored ? agents.resume({
|
|
2285
2571
|
resumeSessionId: options.sessionId,
|
|
2286
2572
|
agentOptions: { provider: options.provider, model: options.model },
|
|
2287
2573
|
signal: lifecycleAbort.signal
|
|
2288
|
-
}) :
|
|
2574
|
+
}) : agents.create({
|
|
2289
2575
|
sessionId: options.sessionId,
|
|
2290
2576
|
meta: {
|
|
2291
2577
|
cwd: options.workspacePath,
|
|
@@ -2293,42 +2579,52 @@ function createDshHostFacade(options) {
|
|
|
2293
2579
|
},
|
|
2294
2580
|
agentOptions: { provider: options.provider, model: options.model },
|
|
2295
2581
|
signal: lifecycleAbort.signal
|
|
2296
|
-
});
|
|
2582
|
+
}));
|
|
2297
2583
|
} catch (error) {
|
|
2298
2584
|
throwIfDisposed(disposed, lifecycleAbort.signal, "open");
|
|
2299
2585
|
throw error;
|
|
2300
2586
|
}
|
|
2301
|
-
if (disposed || lifecycleAbort.signal.aborted) {
|
|
2302
|
-
await openedHandle.dispose();
|
|
2303
|
-
throw new Error("DSH host facade was disposed during open");
|
|
2304
|
-
}
|
|
2305
|
-
if (openedHandle.agent.session.id !== options.sessionId) {
|
|
2306
|
-
await openedHandle.dispose();
|
|
2307
|
-
throw new Error("DSH Host returned an agent for an unexpected Session identity");
|
|
2308
|
-
}
|
|
2309
2587
|
if (sessionTitle !== void 0 && workspaceRegistry !== void 0 && options.sessionTitle !== void 0 && options.workspaceTitle !== void 0) {
|
|
2310
2588
|
try {
|
|
2311
|
-
|
|
2312
|
-
|
|
2313
|
-
|
|
2589
|
+
const session = requireAgent(handle).session;
|
|
2590
|
+
if (mode === "created") {
|
|
2591
|
+
await sessionTitle.rename(session, options.sessionTitle);
|
|
2592
|
+
throwIfDisposed(disposed, lifecycleAbort.signal, "open");
|
|
2593
|
+
}
|
|
2594
|
+
const markerWritten = liveAgent === void 0 && ensureNativeSessionListVisibility(session);
|
|
2595
|
+
await sessions.flush(session);
|
|
2596
|
+
throwIfDisposed(disposed, lifecycleAbort.signal, "open");
|
|
2597
|
+
if (markerWritten) {
|
|
2598
|
+
await releaseHandle();
|
|
2599
|
+
throwIfDisposed(disposed, lifecycleAbort.signal, "open");
|
|
2600
|
+
await adoptHandle(() => agents.resume({
|
|
2601
|
+
resumeSessionId: options.sessionId,
|
|
2602
|
+
agentOptions: { provider: options.provider, model: options.model },
|
|
2603
|
+
signal: lifecycleAbort.signal
|
|
2604
|
+
}));
|
|
2605
|
+
}
|
|
2606
|
+
throwIfDisposed(disposed, lifecycleAbort.signal, "open");
|
|
2314
2607
|
const workspace = await workspaceRegistry.create(options.workspacePath, options.workspaceTitle);
|
|
2315
2608
|
if (workspace === null || typeof workspace !== "object" || typeof workspace.attachSession !== "function") {
|
|
2316
2609
|
throw new Error("Pinned DSH workspace registry returned an incompatible Workspace");
|
|
2317
2610
|
}
|
|
2611
|
+
throwIfDisposed(disposed, lifecycleAbort.signal, "open");
|
|
2318
2612
|
await workspace.attachSession(options.sessionId);
|
|
2613
|
+
throwIfDisposed(disposed, lifecycleAbort.signal, "open");
|
|
2319
2614
|
if (options.supersededSessionId !== void 0 && options.supersededSessionId !== options.sessionId && workspace.sessionIds.includes(options.supersededSessionId)) {
|
|
2320
2615
|
if (typeof workspace.detachSession !== "function") {
|
|
2321
2616
|
throw new Error("Pinned DSH Workspace detachSession API is unavailable or incompatible");
|
|
2322
2617
|
}
|
|
2323
2618
|
await workspace.detachSession(options.supersededSessionId);
|
|
2619
|
+
throwIfDisposed(disposed, lifecycleAbort.signal, "open");
|
|
2324
2620
|
}
|
|
2325
2621
|
} catch (error) {
|
|
2326
|
-
await
|
|
2622
|
+
await releaseHandle();
|
|
2327
2623
|
throwIfDisposed(disposed, lifecycleAbort.signal, "open");
|
|
2328
2624
|
throw error;
|
|
2329
2625
|
}
|
|
2330
2626
|
}
|
|
2331
|
-
|
|
2627
|
+
throwIfDisposed(disposed, lifecycleAbort.signal, "open");
|
|
2332
2628
|
return mode;
|
|
2333
2629
|
})();
|
|
2334
2630
|
return openPromise;
|
|
@@ -2345,7 +2641,7 @@ function createDshHostFacade(options) {
|
|
|
2345
2641
|
return parsed;
|
|
2346
2642
|
});
|
|
2347
2643
|
};
|
|
2348
|
-
const prompt = async (text) => {
|
|
2644
|
+
const prompt = async (text, requestedSelection) => {
|
|
2349
2645
|
if (disposed)
|
|
2350
2646
|
throw new Error("DSH host facade is disposed");
|
|
2351
2647
|
if (!text.trim())
|
|
@@ -2358,12 +2654,24 @@ function createDshHostFacade(options) {
|
|
|
2358
2654
|
if (projectionActive)
|
|
2359
2655
|
throw new Error("DSH host facade permits only one active write");
|
|
2360
2656
|
promptActive = true;
|
|
2657
|
+
let disposeSelection;
|
|
2658
|
+
let selectionRef;
|
|
2361
2659
|
try {
|
|
2362
2660
|
await open2();
|
|
2363
2661
|
throwIfDisposed(disposed, lifecycleAbort.signal, "prompt");
|
|
2364
2662
|
const agent = requireAgent(handle);
|
|
2365
2663
|
if (agent.status !== "idle")
|
|
2366
2664
|
throw new Error("DSH Agent must be idle before a GatherThread prompt");
|
|
2665
|
+
if (requestedSelection !== void 0) {
|
|
2666
|
+
const selection = await resolveDshExecutionSelection(context, requestedSelection, lifecycleAbort.signal);
|
|
2667
|
+
throwIfDisposed(disposed, lifecycleAbort.signal, "prompt");
|
|
2668
|
+
const install = options.modelSelectionInstaller ?? await loadModelSelectionInstaller();
|
|
2669
|
+
selectionRef = { current: selection, assembled: void 0 };
|
|
2670
|
+
disposeSelection = install(agent.ctx, selectionRef);
|
|
2671
|
+
if (typeof disposeSelection !== "function") {
|
|
2672
|
+
throw new Error("Pinned DSH installModelSelection API returned an incompatible disposer");
|
|
2673
|
+
}
|
|
2674
|
+
}
|
|
2367
2675
|
const fromSequence = agent.session.seq;
|
|
2368
2676
|
const message = await createUserMessage(text, options);
|
|
2369
2677
|
throwIfDisposed(disposed, lifecycleAbort.signal, "prompt");
|
|
@@ -2379,6 +2687,11 @@ function createDshHostFacade(options) {
|
|
|
2379
2687
|
events: snapshotFrom(fromSequence)
|
|
2380
2688
|
};
|
|
2381
2689
|
} finally {
|
|
2690
|
+
if (selectionRef !== void 0) {
|
|
2691
|
+
selectionRef.current = void 0;
|
|
2692
|
+
selectionRef.assembled = void 0;
|
|
2693
|
+
}
|
|
2694
|
+
disposeSelection?.();
|
|
2382
2695
|
promptActive = false;
|
|
2383
2696
|
}
|
|
2384
2697
|
};
|
|
@@ -2435,18 +2748,32 @@ function createDshHostFacade(options) {
|
|
|
2435
2748
|
}
|
|
2436
2749
|
};
|
|
2437
2750
|
const dispose = () => {
|
|
2438
|
-
disposePromise
|
|
2439
|
-
|
|
2440
|
-
|
|
2441
|
-
|
|
2442
|
-
|
|
2443
|
-
|
|
2444
|
-
|
|
2751
|
+
if (disposePromise !== void 0)
|
|
2752
|
+
return disposePromise;
|
|
2753
|
+
disposed = true;
|
|
2754
|
+
lifecycleAbort.abort(new Error("DSH host facade disposed"));
|
|
2755
|
+
eventSubscribers.clear();
|
|
2756
|
+
statusSubscribers.clear();
|
|
2757
|
+
for (const stop of listenerDisposers.splice(0))
|
|
2758
|
+
stop();
|
|
2759
|
+
disposePromise = (async () => {
|
|
2760
|
+
let releaseError;
|
|
2445
2761
|
try {
|
|
2446
|
-
await
|
|
2447
|
-
}
|
|
2448
|
-
|
|
2762
|
+
await releaseHandle();
|
|
2763
|
+
} catch (error) {
|
|
2764
|
+
releaseError = error;
|
|
2765
|
+
}
|
|
2766
|
+
try {
|
|
2767
|
+
await openPromise;
|
|
2768
|
+
} catch {
|
|
2449
2769
|
}
|
|
2770
|
+
try {
|
|
2771
|
+
await releaseHandle();
|
|
2772
|
+
} catch (error) {
|
|
2773
|
+
releaseError ??= error;
|
|
2774
|
+
}
|
|
2775
|
+
if (releaseError !== void 0)
|
|
2776
|
+
throw releaseError;
|
|
2450
2777
|
})();
|
|
2451
2778
|
return disposePromise;
|
|
2452
2779
|
};
|
|
@@ -2478,9 +2805,10 @@ function createDshHostFacade(options) {
|
|
|
2478
2805
|
function ensureNativeSessionListVisibility(session) {
|
|
2479
2806
|
const events = session.snapshotEvents(0);
|
|
2480
2807
|
if (events.some((event) => asSessionEvent(event)?.type === "turn/start"))
|
|
2481
|
-
return;
|
|
2808
|
+
return false;
|
|
2482
2809
|
session.append("turn/start", { turn: 1 });
|
|
2483
2810
|
session.append("turn/end", { turn: 1, reason: { kind: "completed" } });
|
|
2811
|
+
return true;
|
|
2484
2812
|
}
|
|
2485
2813
|
function throwIfDisposed(disposed, signal, operation) {
|
|
2486
2814
|
if (disposed || signal.aborted) {
|
|
@@ -2560,6 +2888,49 @@ async function createUserMessage(text, options) {
|
|
|
2560
2888
|
source: { kind: "user" }
|
|
2561
2889
|
});
|
|
2562
2890
|
}
|
|
2891
|
+
async function loadModelSelectionInstaller() {
|
|
2892
|
+
const imported = asObject4(await importDshModule("@deepseek-ai/dsh-agent"));
|
|
2893
|
+
if (imported === void 0 || typeof imported.installModelSelection !== "function") {
|
|
2894
|
+
throw new Error("Pinned DSH installModelSelection API is unavailable");
|
|
2895
|
+
}
|
|
2896
|
+
return imported.installModelSelection;
|
|
2897
|
+
}
|
|
2898
|
+
async function importDshModule(specifier) {
|
|
2899
|
+
return import(specifier);
|
|
2900
|
+
}
|
|
2901
|
+
async function resolveDshExecutionSelection(context, requested, signal) {
|
|
2902
|
+
const provider = safeSelectionText(requested.provider, "provider", 80);
|
|
2903
|
+
const model = safeSelectionText(requested.model, "model", 160);
|
|
2904
|
+
const reasoningEffort = requested.reasoningEffort === void 0 ? void 0 : safeSelectionText(requested.reasoningEffort, "reasoning effort", 80);
|
|
2905
|
+
const llm = requireService(context, "llm", ["resolveModelInfo"]);
|
|
2906
|
+
const resolved = asObject4(await llm.resolveModelInfo(provider, model, signal));
|
|
2907
|
+
if (resolved === void 0 || resolved.provider !== provider || resolved.id !== model) {
|
|
2908
|
+
throw new Error("DeepSeek Harness did not resolve the requested provider/model exactly");
|
|
2909
|
+
}
|
|
2910
|
+
if (reasoningEffort !== void 0) {
|
|
2911
|
+
const reasoning = asObject4(resolved.reasoning);
|
|
2912
|
+
const efforts = Array.isArray(reasoning?.efforts) ? reasoning.efforts : [];
|
|
2913
|
+
const supported = efforts.some((value) => asObject4(value)?.id === reasoningEffort);
|
|
2914
|
+
if (!supported) {
|
|
2915
|
+
throw new Error(`DeepSeek Harness model ${provider}/${model} does not support reasoning effort ${reasoningEffort}`);
|
|
2916
|
+
}
|
|
2917
|
+
}
|
|
2918
|
+
return {
|
|
2919
|
+
provider,
|
|
2920
|
+
model,
|
|
2921
|
+
...reasoningEffort === void 0 ? {} : { reasoningEffort }
|
|
2922
|
+
};
|
|
2923
|
+
}
|
|
2924
|
+
function safeSelectionText(value, label, maximum) {
|
|
2925
|
+
if (typeof value !== "string") {
|
|
2926
|
+
throw new Error(`DeepSeek Harness ${label} selection must be a string`);
|
|
2927
|
+
}
|
|
2928
|
+
const normalized = value.trim();
|
|
2929
|
+
if (!normalized || normalized.length > maximum || /[\u0000-\u001f\u007f-\u009f]/u.test(normalized)) {
|
|
2930
|
+
throw new Error(`DeepSeek Harness ${label} selection is invalid`);
|
|
2931
|
+
}
|
|
2932
|
+
return normalized;
|
|
2933
|
+
}
|
|
2563
2934
|
function requireContext(value) {
|
|
2564
2935
|
const context = asObject4(value);
|
|
2565
2936
|
if (context === void 0 || typeof context.get !== "function" || typeof context.on !== "function" || typeof context.effect !== "function") {
|
|
@@ -2768,7 +3139,7 @@ function validateConnectorState(value) {
|
|
|
2768
3139
|
}
|
|
2769
3140
|
function parseActiveRequest(value) {
|
|
2770
3141
|
const active = requiredObject3(value, "state.activeRequest");
|
|
2771
|
-
exactKeys(active, /* @__PURE__ */ new Set(["requestId", "requestSequence", "dshFromSequence", "dshToSequence", "promptDigest"]), "state.activeRequest");
|
|
3142
|
+
exactKeys(active, /* @__PURE__ */ new Set(["requestId", "requestSequence", "dshFromSequence", "dshToSequence", "promptDigest", "claimAttempt"]), "state.activeRequest");
|
|
2772
3143
|
const parsed = {
|
|
2773
3144
|
requestId: safeString(active.requestId, "state.activeRequest.requestId", 128),
|
|
2774
3145
|
requestSequence: positiveInteger(active.requestSequence, "state.activeRequest.requestSequence"),
|
|
@@ -2776,7 +3147,10 @@ function parseActiveRequest(value) {
|
|
|
2776
3147
|
...active.dshToSequence === void 0 ? {} : {
|
|
2777
3148
|
dshToSequence: nonNegativeInteger(active.dshToSequence, "state.activeRequest.dshToSequence")
|
|
2778
3149
|
},
|
|
2779
|
-
promptDigest: hexDigest(active.promptDigest, "state.activeRequest.promptDigest")
|
|
3150
|
+
promptDigest: hexDigest(active.promptDigest, "state.activeRequest.promptDigest"),
|
|
3151
|
+
...active.claimAttempt === void 0 ? {} : {
|
|
3152
|
+
claimAttempt: positiveInteger(active.claimAttempt, "state.activeRequest.claimAttempt")
|
|
3153
|
+
}
|
|
2780
3154
|
};
|
|
2781
3155
|
if (parsed.dshToSequence !== void 0 && parsed.dshToSequence < parsed.dshFromSequence) {
|
|
2782
3156
|
throw new Error("state.activeRequest.dshToSequence cannot precede dshFromSequence");
|
|
@@ -2861,6 +3235,7 @@ function parseAppendInput(value, label) {
|
|
|
2861
3235
|
"replyTo",
|
|
2862
3236
|
"visibility",
|
|
2863
3237
|
"runtimeId",
|
|
3238
|
+
"claimAttempt",
|
|
2864
3239
|
"observedModel",
|
|
2865
3240
|
"observedReasoningEffort"
|
|
2866
3241
|
]), label);
|
|
@@ -2874,6 +3249,9 @@ function parseAppendInput(value, label) {
|
|
|
2874
3249
|
...input.replyTo === void 0 ? {} : { replyTo: safeString(input.replyTo, `${label}.replyTo`, 128) },
|
|
2875
3250
|
...input.visibility === void 0 ? {} : { visibility: safeString(input.visibility, `${label}.visibility`, 32) },
|
|
2876
3251
|
...input.runtimeId === void 0 ? {} : { runtimeId: safeString(input.runtimeId, `${label}.runtimeId`, 128) },
|
|
3252
|
+
...input.claimAttempt === void 0 ? {} : {
|
|
3253
|
+
claimAttempt: positiveInteger(input.claimAttempt, `${label}.claimAttempt`)
|
|
3254
|
+
},
|
|
2877
3255
|
...input.observedModel === void 0 ? {} : { observedModel: safeString(input.observedModel, `${label}.observedModel`, 160) },
|
|
2878
3256
|
...input.observedReasoningEffort === void 0 ? {} : {
|
|
2879
3257
|
observedReasoningEffort: safeString(input.observedReasoningEffort, `${label}.observedReasoningEffort`, 80)
|
|
@@ -2882,9 +3260,12 @@ function parseAppendInput(value, label) {
|
|
|
2882
3260
|
}
|
|
2883
3261
|
function parseCompletionInput(value, label) {
|
|
2884
3262
|
const input = requiredObject3(value, label);
|
|
2885
|
-
exactKeys(input, /* @__PURE__ */ new Set(["runtimeId", "idempotencyKey", "payload", "observedModel", "observedReasoningEffort"]), label);
|
|
3263
|
+
exactKeys(input, /* @__PURE__ */ new Set(["runtimeId", "claimAttempt", "idempotencyKey", "payload", "observedModel", "observedReasoningEffort"]), label);
|
|
2886
3264
|
return {
|
|
2887
3265
|
runtimeId: safeString(input.runtimeId, `${label}.runtimeId`, 128),
|
|
3266
|
+
...input.claimAttempt === void 0 ? {} : {
|
|
3267
|
+
claimAttempt: positiveInteger(input.claimAttempt, `${label}.claimAttempt`)
|
|
3268
|
+
},
|
|
2888
3269
|
idempotencyKey: safeString(input.idempotencyKey, `${label}.idempotencyKey`, 200),
|
|
2889
3270
|
payload: jsonValue(input.payload, `${label}.payload`),
|
|
2890
3271
|
...input.observedModel === void 0 ? {} : { observedModel: safeString(input.observedModel, `${label}.observedModel`, 160) },
|
|
@@ -3393,6 +3774,14 @@ function projectSessionConfig(config, sessionId, nativeSessionId) {
|
|
|
3393
3774
|
statePath: path4.join(config.stateRoot, `${dshSessionId}.json`),
|
|
3394
3775
|
provider: config.provider,
|
|
3395
3776
|
model: config.model,
|
|
3777
|
+
...config.executionProfiles === void 0 ? {} : {
|
|
3778
|
+
executionProfiles: config.executionProfiles.map((profile) => ({
|
|
3779
|
+
...profile,
|
|
3780
|
+
...profile.reasoningEfforts === void 0 ? {} : {
|
|
3781
|
+
reasoningEfforts: [...profile.reasoningEfforts]
|
|
3782
|
+
}
|
|
3783
|
+
}))
|
|
3784
|
+
},
|
|
3396
3785
|
pollIntervalMs: config.pollIntervalMs,
|
|
3397
3786
|
pollLimit: config.pollLimit,
|
|
3398
3787
|
shareToolEvents: config.shareToolEvents,
|