pilotswarm-sdk 0.5.19 → 0.5.21
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/api/src/http-api-transport.js +4 -0
- package/api/src/protocol.js +2 -0
- package/dist/blob-store.d.ts +42 -11
- package/dist/blob-store.d.ts.map +1 -1
- package/dist/blob-store.js +163 -53
- package/dist/blob-store.js.map +1 -1
- package/dist/cms-migrations.d.ts.map +1 -1
- package/dist/cms-migrations.js +231 -0
- package/dist/cms-migrations.js.map +1 -1
- package/dist/cms.d.ts +62 -0
- package/dist/cms.d.ts.map +1 -1
- package/dist/cms.js +81 -4
- package/dist/cms.js.map +1 -1
- package/dist/distiller-tools.d.ts +9 -0
- package/dist/distiller-tools.d.ts.map +1 -0
- package/dist/distiller-tools.js +102 -0
- package/dist/distiller-tools.js.map +1 -0
- package/dist/footprint.d.ts +129 -0
- package/dist/footprint.d.ts.map +1 -0
- package/dist/footprint.js +254 -0
- package/dist/footprint.js.map +1 -0
- package/dist/inspect-tools.d.ts.map +1 -1
- package/dist/inspect-tools.js +63 -2
- package/dist/inspect-tools.js.map +1 -1
- package/dist/managed-session.d.ts.map +1 -1
- package/dist/managed-session.js +140 -14
- package/dist/managed-session.js.map +1 -1
- package/dist/management-client.d.ts +32 -0
- package/dist/management-client.d.ts.map +1 -1
- package/dist/management-client.js +93 -0
- package/dist/management-client.js.map +1 -1
- package/dist/orchestration/agents.d.ts +18 -0
- package/dist/orchestration/agents.d.ts.map +1 -1
- package/dist/orchestration/agents.js +63 -3
- package/dist/orchestration/agents.js.map +1 -1
- package/dist/orchestration/index.d.ts +2 -2
- package/dist/orchestration/index.js +1 -1
- package/dist/orchestration/lifecycle.d.ts +1 -0
- package/dist/orchestration/lifecycle.d.ts.map +1 -1
- package/dist/orchestration/lifecycle.js +349 -1
- package/dist/orchestration/lifecycle.js.map +1 -1
- package/dist/orchestration/queue.d.ts.map +1 -1
- package/dist/orchestration/queue.js +61 -2
- package/dist/orchestration/queue.js.map +1 -1
- package/dist/orchestration/runtime.d.ts +1 -1
- package/dist/orchestration/runtime.d.ts.map +1 -1
- package/dist/orchestration/runtime.js +31 -1
- package/dist/orchestration/runtime.js.map +1 -1
- package/dist/orchestration/state.d.ts +29 -0
- package/dist/orchestration/state.d.ts.map +1 -1
- package/dist/orchestration/state.js +11 -0
- package/dist/orchestration/state.js.map +1 -1
- package/dist/orchestration/turn.d.ts.map +1 -1
- package/dist/orchestration/turn.js +68 -1
- package/dist/orchestration/turn.js.map +1 -1
- package/dist/orchestration-registry.d.ts.map +1 -1
- package/dist/orchestration-registry.js +8 -2
- package/dist/orchestration-registry.js.map +1 -1
- package/dist/orchestration-version.d.ts +1 -1
- package/dist/orchestration-version.js +1 -1
- package/dist/orchestration.d.ts +2 -2
- package/dist/orchestration.js +1 -1
- package/dist/orchestration_1_0_46.d.ts +1 -1
- package/dist/orchestration_1_0_47.d.ts +1 -1
- package/dist/orchestration_1_0_48.d.ts +1 -1
- package/dist/orchestration_1_0_49.d.ts +1 -1
- package/dist/orchestration_1_0_50.d.ts +1 -1
- package/dist/orchestration_1_0_65/agents.d.ts +43 -0
- package/dist/orchestration_1_0_65/agents.d.ts.map +1 -0
- package/dist/orchestration_1_0_65/agents.js +780 -0
- package/dist/orchestration_1_0_65/agents.js.map +1 -0
- package/dist/orchestration_1_0_65/index.d.ts +24 -0
- package/dist/orchestration_1_0_65/index.d.ts.map +1 -0
- package/dist/orchestration_1_0_65/index.js +13 -0
- package/dist/orchestration_1_0_65/index.js.map +1 -0
- package/dist/orchestration_1_0_65/lifecycle.d.ts +48 -0
- package/dist/orchestration_1_0_65/lifecycle.d.ts.map +1 -0
- package/dist/orchestration_1_0_65/lifecycle.js +572 -0
- package/dist/orchestration_1_0_65/lifecycle.js.map +1 -0
- package/dist/orchestration_1_0_65/queue.d.ts +7 -0
- package/dist/orchestration_1_0_65/queue.d.ts.map +1 -0
- package/dist/orchestration_1_0_65/queue.js +745 -0
- package/dist/orchestration_1_0_65/queue.js.map +1 -0
- package/dist/orchestration_1_0_65/runtime.d.ts +29 -0
- package/dist/orchestration_1_0_65/runtime.d.ts.map +1 -0
- package/dist/orchestration_1_0_65/runtime.js +195 -0
- package/dist/orchestration_1_0_65/runtime.js.map +1 -0
- package/dist/orchestration_1_0_65/state.d.ts +147 -0
- package/dist/orchestration_1_0_65/state.d.ts.map +1 -0
- package/dist/orchestration_1_0_65/state.js +147 -0
- package/dist/orchestration_1_0_65/state.js.map +1 -0
- package/dist/orchestration_1_0_65/turn.d.ts +34 -0
- package/dist/orchestration_1_0_65/turn.d.ts.map +1 -0
- package/dist/orchestration_1_0_65/turn.js +1144 -0
- package/dist/orchestration_1_0_65/turn.js.map +1 -0
- package/dist/orchestration_1_0_65/utils.d.ts +39 -0
- package/dist/orchestration_1_0_65/utils.d.ts.map +1 -0
- package/dist/orchestration_1_0_65/utils.js +316 -0
- package/dist/orchestration_1_0_65/utils.js.map +1 -0
- package/dist/orchestration_1_0_66/agents.d.ts +52 -0
- package/dist/orchestration_1_0_66/agents.d.ts.map +1 -0
- package/dist/orchestration_1_0_66/agents.js +825 -0
- package/dist/orchestration_1_0_66/agents.js.map +1 -0
- package/dist/orchestration_1_0_66/index.d.ts +24 -0
- package/dist/orchestration_1_0_66/index.d.ts.map +1 -0
- package/dist/orchestration_1_0_66/index.js +13 -0
- package/dist/orchestration_1_0_66/index.js.map +1 -0
- package/dist/orchestration_1_0_66/lifecycle.d.ts +48 -0
- package/dist/orchestration_1_0_66/lifecycle.d.ts.map +1 -0
- package/dist/orchestration_1_0_66/lifecycle.js +573 -0
- package/dist/orchestration_1_0_66/lifecycle.js.map +1 -0
- package/dist/orchestration_1_0_66/queue.d.ts +7 -0
- package/dist/orchestration_1_0_66/queue.d.ts.map +1 -0
- package/dist/orchestration_1_0_66/queue.js +776 -0
- package/dist/orchestration_1_0_66/queue.js.map +1 -0
- package/dist/orchestration_1_0_66/runtime.d.ts +29 -0
- package/dist/orchestration_1_0_66/runtime.d.ts.map +1 -0
- package/dist/orchestration_1_0_66/runtime.js +198 -0
- package/dist/orchestration_1_0_66/runtime.js.map +1 -0
- package/dist/orchestration_1_0_66/state.d.ts +149 -0
- package/dist/orchestration_1_0_66/state.d.ts.map +1 -0
- package/dist/orchestration_1_0_66/state.js +148 -0
- package/dist/orchestration_1_0_66/state.js.map +1 -0
- package/dist/orchestration_1_0_66/turn.d.ts +34 -0
- package/dist/orchestration_1_0_66/turn.d.ts.map +1 -0
- package/dist/orchestration_1_0_66/turn.js +1169 -0
- package/dist/orchestration_1_0_66/turn.js.map +1 -0
- package/dist/orchestration_1_0_66/utils.d.ts +39 -0
- package/dist/orchestration_1_0_66/utils.d.ts.map +1 -0
- package/dist/orchestration_1_0_66/utils.js +316 -0
- package/dist/orchestration_1_0_66/utils.js.map +1 -0
- package/dist/orchestration_1_0_67/agents.d.ts +52 -0
- package/dist/orchestration_1_0_67/agents.d.ts.map +1 -0
- package/dist/orchestration_1_0_67/agents.js +825 -0
- package/dist/orchestration_1_0_67/agents.js.map +1 -0
- package/dist/orchestration_1_0_67/index.d.ts +28 -0
- package/dist/orchestration_1_0_67/index.d.ts.map +1 -0
- package/dist/orchestration_1_0_67/index.js +13 -0
- package/dist/orchestration_1_0_67/index.js.map +1 -0
- package/dist/orchestration_1_0_67/lifecycle.d.ts +49 -0
- package/dist/orchestration_1_0_67/lifecycle.d.ts.map +1 -0
- package/dist/orchestration_1_0_67/lifecycle.js +807 -0
- package/dist/orchestration_1_0_67/lifecycle.js.map +1 -0
- package/dist/orchestration_1_0_67/queue.d.ts +7 -0
- package/dist/orchestration_1_0_67/queue.d.ts.map +1 -0
- package/dist/orchestration_1_0_67/queue.js +804 -0
- package/dist/orchestration_1_0_67/queue.js.map +1 -0
- package/dist/orchestration_1_0_67/runtime.d.ts +29 -0
- package/dist/orchestration_1_0_67/runtime.d.ts.map +1 -0
- package/dist/orchestration_1_0_67/runtime.js +228 -0
- package/dist/orchestration_1_0_67/runtime.js.map +1 -0
- package/dist/orchestration_1_0_67/state.d.ts +176 -0
- package/dist/orchestration_1_0_67/state.d.ts.map +1 -0
- package/dist/orchestration_1_0_67/state.js +158 -0
- package/dist/orchestration_1_0_67/state.js.map +1 -0
- package/dist/orchestration_1_0_67/turn.d.ts +34 -0
- package/dist/orchestration_1_0_67/turn.d.ts.map +1 -0
- package/dist/orchestration_1_0_67/turn.js +1208 -0
- package/dist/orchestration_1_0_67/turn.js.map +1 -0
- package/dist/orchestration_1_0_67/utils.d.ts +39 -0
- package/dist/orchestration_1_0_67/utils.d.ts.map +1 -0
- package/dist/orchestration_1_0_67/utils.js +316 -0
- package/dist/orchestration_1_0_67/utils.js.map +1 -0
- package/dist/regen-worker.d.ts +167 -0
- package/dist/regen-worker.d.ts.map +1 -0
- package/dist/regen-worker.js +512 -0
- package/dist/regen-worker.js.map +1 -0
- package/dist/resourcemgr-tools.d.ts.map +1 -1
- package/dist/resourcemgr-tools.js +33 -2
- package/dist/resourcemgr-tools.js.map +1 -1
- package/dist/session-lifecycle.d.ts +8 -0
- package/dist/session-lifecycle.d.ts.map +1 -1
- package/dist/session-lifecycle.js +35 -17
- package/dist/session-lifecycle.js.map +1 -1
- package/dist/session-manager.d.ts +21 -0
- package/dist/session-manager.d.ts.map +1 -1
- package/dist/session-manager.js +104 -11
- package/dist/session-manager.js.map +1 -1
- package/dist/session-proxy.d.ts +34 -0
- package/dist/session-proxy.d.ts.map +1 -1
- package/dist/session-proxy.js +407 -5
- package/dist/session-proxy.js.map +1 -1
- package/dist/session-store.d.ts +50 -15
- package/dist/session-store.d.ts.map +1 -1
- package/dist/session-store.js +143 -30
- package/dist/session-store.js.map +1 -1
- package/dist/snapshot-protocol.d.ts +34 -3
- package/dist/snapshot-protocol.d.ts.map +1 -1
- package/dist/snapshot-protocol.js +25 -0
- package/dist/snapshot-protocol.js.map +1 -1
- package/dist/types.d.ts +101 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/dist/web/web-management-client.d.ts +11 -0
- package/dist/web/web-management-client.d.ts.map +1 -1
- package/dist/web/web-management-client.js +8 -0
- package/dist/web/web-management-client.js.map +1 -1
- package/dist/worker.d.ts.map +1 -1
- package/dist/worker.js +7 -0
- package/dist/worker.js.map +1 -1
- package/package.json +1 -1
package/dist/session-proxy.js
CHANGED
|
@@ -10,12 +10,14 @@ import { mergePromptSections } from "./prompt-layering.js";
|
|
|
10
10
|
import { approvePermissionForSession } from "./permissions.js";
|
|
11
11
|
import { formatSessionOwnerLabel, getSessionOwnerKind, matchesSessionOwnerFilters } from "./session-owner-utils.js";
|
|
12
12
|
import { cmsRetryBestEffort, cmsRetryCritical } from "./cms-retry.js";
|
|
13
|
+
import { archiveName, artifactExists, assembleRegenClosure, buildMapReduceSeedPrompt, deterministicPackage, DISTILLER_SYSTEM_MESSAGE, distillInputName, distillOutputName, packageName, parseDistillerResponse, renderBootstrap, runRegenArchive, runRegenDistill, } from "./regen-worker.js";
|
|
14
|
+
import { REGEN_DISTILLER_SERVICE_KIND } from "./distiller-tools.js";
|
|
13
15
|
import { computeCronAtNextFire } from "./cron-at.js";
|
|
14
16
|
import { SpanStatusCode, trace as otelTrace } from "@opentelemetry/api";
|
|
15
17
|
import os from "node:os";
|
|
16
18
|
import fs from "node:fs";
|
|
17
19
|
import path from "node:path";
|
|
18
|
-
import { randomUUID } from "node:crypto";
|
|
20
|
+
import { createHash, randomUUID } from "node:crypto";
|
|
19
21
|
import { attemptStoreRecovery, runTurnCommit, runTurnPreamble } from "./session-lifecycle.js";
|
|
20
22
|
import { supportsVersionedSnapshots, writeTurnSentinel } from "./snapshot-protocol.js";
|
|
21
23
|
const SYSTEM_AGENT_IDS = new Set(["pilotswarm", "sweeper", "resourcemgr", "facts-manager", "agent-tuner"]);
|
|
@@ -439,7 +441,12 @@ async function tryReadSnapshotSizeBytes(sessionStore, sessionId) {
|
|
|
439
441
|
export function createSessionProxy(ctx, sessionId, affinityKey, config) {
|
|
440
442
|
return {
|
|
441
443
|
runTurn(prompt, bootstrap, turnIndex, turnMeta) {
|
|
442
|
-
return ctx.scheduleActivityOnSession(
|
|
444
|
+
return ctx.scheduleActivityOnSession(
|
|
445
|
+
// The epoch-start turn is a distinct activity name (runTurn2):
|
|
446
|
+
// pre-1.0.67 workers don't register it, so a rolling deploy can
|
|
447
|
+
// never hand the fresh-epoch create to a worker that would
|
|
448
|
+
// silently resume the dead transcript instead.
|
|
449
|
+
turnMeta?.epochStart ? "runTurn2" : "runTurn", {
|
|
443
450
|
sessionId,
|
|
444
451
|
prompt,
|
|
445
452
|
config,
|
|
@@ -463,6 +470,8 @@ export function createSessionProxy(ctx, sessionId, affinityKey, config) {
|
|
|
463
470
|
...(turnMeta?.attachments && turnMeta.attachments.length > 0
|
|
464
471
|
? { attachments: turnMeta.attachments }
|
|
465
472
|
: {}),
|
|
473
|
+
...(turnMeta?.transcriptEpoch ? { transcriptEpoch: turnMeta.transcriptEpoch } : {}),
|
|
474
|
+
...(turnMeta?.epochStart ? { epochStart: true } : {}),
|
|
466
475
|
}, affinityKey);
|
|
467
476
|
},
|
|
468
477
|
dehydrate(reason, eventData) {
|
|
@@ -656,6 +665,40 @@ export function createSessionManagerProxy(ctx) {
|
|
|
656
665
|
computeCronAtNextFire(schedule, afterUtcMs, lastOccurrenceKey) {
|
|
657
666
|
return ctx.scheduleActivity("computeCronAtNextFire", { schedule, afterUtcMs, lastOccurrenceKey });
|
|
658
667
|
},
|
|
668
|
+
// ── Session regeneration (1.0.67) ──────────────────────
|
|
669
|
+
/** ARCHIVE stage: transcript slice → attempt-scoped artifact. Idempotent per attempt. */
|
|
670
|
+
runRegenArchive(sessionId, epoch, attemptId) {
|
|
671
|
+
return ctx.scheduleActivity("runRegenArchive", { sessionId, epoch, attemptId });
|
|
672
|
+
},
|
|
673
|
+
/** DISTILL (deterministic): closure package in-activity → ResumePackage artifact + bootstrap. */
|
|
674
|
+
runRegenDistill(sessionId, epoch, attemptId, opts) {
|
|
675
|
+
return ctx.scheduleActivity("runRegenDistill", { sessionId, epoch, attemptId, ...(opts ?? {}) });
|
|
676
|
+
},
|
|
677
|
+
/** Post-flip boundary: epoch_committed event + transcript_epoch + regen_count, one CMS transaction. */
|
|
678
|
+
commitEpochBoundary(sessionId, commit) {
|
|
679
|
+
return ctx.scheduleActivity("commitEpochBoundary", { sessionId, commit });
|
|
680
|
+
},
|
|
681
|
+
/** Proven rebirth: session.regenerated event + last_regen_stats. */
|
|
682
|
+
recordRegenerated(sessionId, payload) {
|
|
683
|
+
return ctx.scheduleActivity("recordRegenerated", { sessionId, payload });
|
|
684
|
+
},
|
|
685
|
+
// ── Service-session distiller (1.0.68) ─────────────────
|
|
686
|
+
/** Spawn the regen-distiller service session under the tree root (idempotent per attempt). */
|
|
687
|
+
runRegenSpawnDistiller(sessionId, epoch, attemptId, opts) {
|
|
688
|
+
return ctx.scheduleActivity("runRegenSpawnDistiller", { sessionId, epoch, attemptId, ...(opts ?? {}) });
|
|
689
|
+
},
|
|
690
|
+
/** Poll the distiller service session: running | completed (with response) | failed. */
|
|
691
|
+
runRegenCheckDistiller(distillerSessionId) {
|
|
692
|
+
return ctx.scheduleActivity("runRegenCheckDistiller", { distillerSessionId });
|
|
693
|
+
},
|
|
694
|
+
/** Parse/validate the distiller's final message into the package (+dumps); deterministic fallback on junk. */
|
|
695
|
+
runRegenCollectDistiller(sessionId, epoch, attemptId, distillerSessionId, opts) {
|
|
696
|
+
return ctx.scheduleActivity("runRegenCollectDistiller", { sessionId, epoch, attemptId, distillerSessionId, ...(opts ?? {}) });
|
|
697
|
+
},
|
|
698
|
+
/** Best-effort cancel of a timed-out/failed distiller service session. */
|
|
699
|
+
runRegenCancelDistiller(distillerSessionId) {
|
|
700
|
+
return ctx.scheduleActivity("runRegenCancelDistiller", { distillerSessionId });
|
|
701
|
+
},
|
|
659
702
|
};
|
|
660
703
|
}
|
|
661
704
|
// ─── Activity Registration ───────────────────────────────────────
|
|
@@ -695,7 +738,7 @@ artifactStore) {
|
|
|
695
738
|
...(clientConfig?.aadDbUser != null && { aadDbUser: clientConfig.aadDbUser }),
|
|
696
739
|
});
|
|
697
740
|
// ── runTurn ──────────────────────────────────────────────
|
|
698
|
-
|
|
741
|
+
const runTurnHandler = async (activityCtx, input) => {
|
|
699
742
|
// Attachment count is traced unconditionally: a 2026-07-21 incident
|
|
700
743
|
// showed turns whose ActivityScheduled input carried refs executing
|
|
701
744
|
// WITHOUT them (suspected work-item redelivery after eviction/lock
|
|
@@ -786,12 +829,17 @@ artifactStore) {
|
|
|
786
829
|
// observability-only reads (lossy flag, snapshot_store_empty).
|
|
787
830
|
expectedVersion: input.snapshot.expectedVersion ?? 0,
|
|
788
831
|
turnKey: input.snapshot.turnKey,
|
|
832
|
+
// Session regeneration: epoch scopes every store call to
|
|
833
|
+
// the current chain and gates local-dir trust. Absent on
|
|
834
|
+
// pre-1.0.67 inputs → 0 (legacy chain, today's behavior).
|
|
835
|
+
transcriptEpoch: input.transcriptEpoch ?? 0,
|
|
789
836
|
dropWarmSession: () => sessionManager.dropWarmSession(input.sessionId),
|
|
790
837
|
trace,
|
|
791
838
|
}
|
|
792
839
|
: null;
|
|
793
840
|
let lifecycleBaseVersion = 0;
|
|
794
841
|
let lifecycleRehydrated = false;
|
|
842
|
+
let lifecyclePreambleFresh = false;
|
|
795
843
|
// Protocol-native persistence stats: the legacy dehydrate/hydrate
|
|
796
844
|
// activities no longer run, so the preamble/commit paths feed the
|
|
797
845
|
// same CMS summary + events the Stats pane reads. Best-effort only.
|
|
@@ -819,6 +867,7 @@ artifactStore) {
|
|
|
819
867
|
}
|
|
820
868
|
lifecycleBaseVersion = pre.baseVersion;
|
|
821
869
|
lifecycleRehydrated = pre.kind === "hydrated";
|
|
870
|
+
lifecyclePreambleFresh = pre.kind === "fresh";
|
|
822
871
|
if (lifecycleRehydrated) {
|
|
823
872
|
await recordLifecycleHydration(pre.baseVersion);
|
|
824
873
|
}
|
|
@@ -837,7 +886,7 @@ artifactStore) {
|
|
|
837
886
|
},
|
|
838
887
|
}], workerNodeId), (msg) => activityCtx.traceInfo(msg));
|
|
839
888
|
}
|
|
840
|
-
if (pre.kind === "fresh" && pre.lossy && catalog) {
|
|
889
|
+
if (pre.kind === "fresh" && pre.lossy && !input.epochStart && catalog) {
|
|
841
890
|
await cmsRetryBestEffort(`runTurn.recordEvent snapshot-store-empty session=${input.sessionId}`, () => catalog.recordEvents(input.sessionId, [{
|
|
842
891
|
eventType: "session.snapshot_store_empty",
|
|
843
892
|
data: {
|
|
@@ -850,9 +899,17 @@ artifactStore) {
|
|
|
850
899
|
const executeTurnBody = async () => {
|
|
851
900
|
let session = null;
|
|
852
901
|
let effectivePrompt = input.prompt;
|
|
902
|
+
// Conditional epoch init (runTurn2): create a brand-new SDK session
|
|
903
|
+
// ONLY when the epoch's chain is empty (preamble "fresh"). A committed
|
|
904
|
+
// grounding turn recovers via already-committed above; a non-empty
|
|
905
|
+
// chain resumes — an unconditional reset would erase a committed
|
|
906
|
+
// grounding turn on activity retry.
|
|
907
|
+
const epochCreate = input.epochStart === true && (!lifecycle || lifecyclePreambleFresh);
|
|
853
908
|
try {
|
|
854
909
|
session = await sessionManager.getOrCreate(input.sessionId, runConfig, {
|
|
855
910
|
turnIndex: input.turnIndex,
|
|
911
|
+
transcriptEpoch: input.transcriptEpoch ?? 0,
|
|
912
|
+
...(epochCreate ? { epochStart: true } : {}),
|
|
856
913
|
trace,
|
|
857
914
|
lockHeld: true,
|
|
858
915
|
});
|
|
@@ -1279,6 +1336,62 @@ artifactStore) {
|
|
|
1279
1336
|
return `[SYSTEM: set_session_model failed: ${err?.message || String(err)}]`;
|
|
1280
1337
|
}
|
|
1281
1338
|
},
|
|
1339
|
+
regenerateContext: async (args) => {
|
|
1340
|
+
try {
|
|
1341
|
+
if (!storeUrl)
|
|
1342
|
+
return "[SYSTEM: regenerate_context failed: no storeUrl is configured.]";
|
|
1343
|
+
const sdkClient = new PilotSwarmClient(internalClientConfig());
|
|
1344
|
+
try {
|
|
1345
|
+
await sdkClient.start();
|
|
1346
|
+
await sdkClient.duroxideClient.enqueueEvent(`session-${input.sessionId}`, "messages", JSON.stringify({
|
|
1347
|
+
type: "cmd",
|
|
1348
|
+
cmd: "regenerate",
|
|
1349
|
+
id: `regenerate-tool-${randomUUID()}`,
|
|
1350
|
+
args: {
|
|
1351
|
+
...(args.handoff ? { handoff: String(args.handoff).slice(0, 4_000) } : {}),
|
|
1352
|
+
...(args.instructions ? { instructions: String(args.instructions).slice(0, 4_000) } : {}),
|
|
1353
|
+
source: "tool",
|
|
1354
|
+
},
|
|
1355
|
+
// Owner-gate evidence: the runTurn activity input's
|
|
1356
|
+
// authoritative sender, stamped server-side — the
|
|
1357
|
+
// cmd handler refuses non-owner turns on shared
|
|
1358
|
+
// sessions. Never an LLM-supplied value.
|
|
1359
|
+
...(input.sender ? { sender: input.sender } : {}),
|
|
1360
|
+
}));
|
|
1361
|
+
}
|
|
1362
|
+
finally {
|
|
1363
|
+
await sdkClient.stop().catch(() => { });
|
|
1364
|
+
}
|
|
1365
|
+
return "[SYSTEM: Regeneration accepted. Finish this turn cleanly NOW — at the next boundary the runtime archives your transcript, distills a resume package, and rebuilds your context. Durable state (facts, artifacts, children, schedule) is untouched.]";
|
|
1366
|
+
}
|
|
1367
|
+
catch (err) {
|
|
1368
|
+
return `[SYSTEM: regenerate_context failed: ${err?.message || String(err)}]`;
|
|
1369
|
+
}
|
|
1370
|
+
},
|
|
1371
|
+
regenerateAgent: async (args) => {
|
|
1372
|
+
try {
|
|
1373
|
+
const child = await resolveManagedChild(args.agent_id);
|
|
1374
|
+
const sdkClient = await getInlineClient();
|
|
1375
|
+
await sdkClient._getDuroxideClient().enqueueEvent(child.orchId, "messages", JSON.stringify({
|
|
1376
|
+
type: "cmd",
|
|
1377
|
+
cmd: "regenerate",
|
|
1378
|
+
id: `regenerate-parent-${randomUUID()}`,
|
|
1379
|
+
args: {
|
|
1380
|
+
...(args.handoff ? { handoff: String(args.handoff).slice(0, 4_000) } : {}),
|
|
1381
|
+
...(args.instructions ? { instructions: String(args.instructions).slice(0, 4_000) } : {}),
|
|
1382
|
+
source: "parent",
|
|
1383
|
+
},
|
|
1384
|
+
// Parent-of gate evidence: the child's handler accepts
|
|
1385
|
+
// source "parent" only when this id equals its own
|
|
1386
|
+
// carried parentSessionId.
|
|
1387
|
+
requestedBy: input.sessionId,
|
|
1388
|
+
}));
|
|
1389
|
+
return `[SYSTEM: Regeneration requested for sub-agent ${child.orchId}. It applies at the child's next turn boundary; check_agents will reflect the rebirth. Continue your work in this SAME turn.]`;
|
|
1390
|
+
}
|
|
1391
|
+
catch (err) {
|
|
1392
|
+
return `[SYSTEM: regenerate_agent failed: ${err?.message || String(err)}]`;
|
|
1393
|
+
}
|
|
1394
|
+
},
|
|
1282
1395
|
messageAgent: async (args) => {
|
|
1283
1396
|
try {
|
|
1284
1397
|
const child = await resolveManagedChild(args.agent_id);
|
|
@@ -2165,7 +2278,12 @@ artifactStore) {
|
|
|
2165
2278
|
catch { }
|
|
2166
2279
|
}
|
|
2167
2280
|
}
|
|
2168
|
-
}
|
|
2281
|
+
};
|
|
2282
|
+
runtime.registerActivity("runTurn", runTurnHandler);
|
|
2283
|
+
// Session regeneration: the epoch-start turn dispatches under a NEW
|
|
2284
|
+
// activity name so pre-1.0.67 workers — which would silently resume the
|
|
2285
|
+
// dead transcript — structurally cannot receive it (deployment gate §4).
|
|
2286
|
+
runtime.registerActivity("runTurn2", runTurnHandler);
|
|
2169
2287
|
// ── abortTurn ────────────────────────────────────────────
|
|
2170
2288
|
// Stop-turn fast-path interrupt. Routed on the session affinity key so it
|
|
2171
2289
|
// lands on the worker owning the warm ManagedSession and runs CONCURRENTLY
|
|
@@ -2997,5 +3115,289 @@ artifactStore) {
|
|
|
2997
3115
|
activityCtx.traceInfo(`[computeCronAtNextFire] tz=${input.schedule?.tz} after=${input.afterUtcMs}`);
|
|
2998
3116
|
return computeCronAtNextFire(input.schedule, input.afterUtcMs, input.lastOccurrenceKey);
|
|
2999
3117
|
});
|
|
3118
|
+
// ── Session regeneration activities (1.0.67) ──────────────
|
|
3119
|
+
const regenDeps = (activityCtx) => {
|
|
3120
|
+
if (!catalog)
|
|
3121
|
+
throw new Error("session regeneration requires the CMS catalog");
|
|
3122
|
+
return {
|
|
3123
|
+
catalog,
|
|
3124
|
+
artifactStore: artifactStore ?? null,
|
|
3125
|
+
resolveModelOptions: (ref) => sessionManager.resolveModelSessionOptions(ref),
|
|
3126
|
+
fallbackDistillerModel: process.env.PILOTSWARM_DISTILLER_FALLBACK_MODEL || undefined,
|
|
3127
|
+
trace: (message) => activityCtx.traceInfo(`[regen] ${message}`),
|
|
3128
|
+
};
|
|
3129
|
+
};
|
|
3130
|
+
runtime.registerActivity("runRegenArchive", async (activityCtx, input) => {
|
|
3131
|
+
activityCtx.traceInfo(`[runRegenArchive] session=${input.sessionId} epoch=${input.epoch} attempt=${input.attemptId}`);
|
|
3132
|
+
return runRegenArchive(regenDeps(activityCtx), input);
|
|
3133
|
+
});
|
|
3134
|
+
runtime.registerActivity("runRegenDistill", async (activityCtx, input) => {
|
|
3135
|
+
activityCtx.traceInfo(`[runRegenDistill] session=${input.sessionId} epoch=${input.epoch} attempt=${input.attemptId}`);
|
|
3136
|
+
return runRegenDistill(regenDeps(activityCtx), input);
|
|
3137
|
+
});
|
|
3138
|
+
runtime.registerActivity("commitEpochBoundary", async (activityCtx, input) => {
|
|
3139
|
+
if (!catalog)
|
|
3140
|
+
throw new Error("session regeneration requires the CMS catalog");
|
|
3141
|
+
activityCtx.traceInfo(`[commitEpochBoundary] session=${input.sessionId} toEpoch=${input.commit?.toEpoch}`);
|
|
3142
|
+
return catalog.recordEpochCommitted(input.sessionId, input.commit);
|
|
3143
|
+
});
|
|
3144
|
+
runtime.registerActivity("recordRegenerated", async (activityCtx, input) => {
|
|
3145
|
+
if (!catalog)
|
|
3146
|
+
throw new Error("session regeneration requires the CMS catalog");
|
|
3147
|
+
activityCtx.traceInfo(`[recordRegenerated] session=${input.sessionId} epoch=${input.payload?.epoch}`);
|
|
3148
|
+
return catalog.recordRegenerated(input.sessionId, input.payload);
|
|
3149
|
+
});
|
|
3150
|
+
// ── Service-session distiller activities (1.0.68) ──────────
|
|
3151
|
+
// The distiller is a REAL session (service_kind="regen-distiller") under
|
|
3152
|
+
// the served tree's ROOT: lifecycle events, metrics, and normal sweeper
|
|
3153
|
+
// cleanup apply because nothing is special-cased. Its id is deterministic
|
|
3154
|
+
// per attempt so activity retries reuse the same session.
|
|
3155
|
+
const distillerSessionIdFor = (sessionId, epoch, attemptId) => {
|
|
3156
|
+
const digest = createHash("sha1")
|
|
3157
|
+
.update(`ps-regen-distiller:${sessionId}:e${epoch}:${attemptId}`)
|
|
3158
|
+
.digest();
|
|
3159
|
+
const b = Buffer.from(digest.subarray(0, 16));
|
|
3160
|
+
b[6] = (b[6] & 0x0f) | 0x50; // UUIDv5 version bits
|
|
3161
|
+
b[8] = (b[8] & 0x3f) | 0x80; // RFC 4122 variant
|
|
3162
|
+
const h = b.toString("hex");
|
|
3163
|
+
return `${h.slice(0, 8)}-${h.slice(8, 12)}-${h.slice(12, 16)}-${h.slice(16, 20)}-${h.slice(20, 32)}`;
|
|
3164
|
+
};
|
|
3165
|
+
const enqueueDistillerCmd = async (distillerSessionId, cmd, idPrefix) => {
|
|
3166
|
+
const sdkClient = new PilotSwarmClient(internalClientConfig());
|
|
3167
|
+
try {
|
|
3168
|
+
await sdkClient.start();
|
|
3169
|
+
await sdkClient.duroxideClient.enqueueEvent(`session-${distillerSessionId}`, "messages", JSON.stringify({ type: "cmd", cmd, id: `${idPrefix}-${randomUUID()}` }));
|
|
3170
|
+
}
|
|
3171
|
+
finally {
|
|
3172
|
+
await sdkClient.stop().catch(() => { });
|
|
3173
|
+
}
|
|
3174
|
+
};
|
|
3175
|
+
runtime.registerActivity("runRegenSpawnDistiller", async (activityCtx, input) => {
|
|
3176
|
+
if (!catalog)
|
|
3177
|
+
throw new Error("distiller spawn requires the CMS catalog");
|
|
3178
|
+
if (!artifactStore)
|
|
3179
|
+
throw new Error("distiller spawn requires an artifact store");
|
|
3180
|
+
if (!storeUrl)
|
|
3181
|
+
throw new Error("distiller spawn requires a storeUrl");
|
|
3182
|
+
// Deployment kill switch: force the deterministic package fleet-wide.
|
|
3183
|
+
// Read in the ACTIVITY (recorded in history) — never in the orchestration.
|
|
3184
|
+
if (process.env.PILOTSWARM_REGEN_DETERMINISTIC_ONLY === "1") {
|
|
3185
|
+
return { fallback: "deterministic-only" };
|
|
3186
|
+
}
|
|
3187
|
+
const deps = regenDeps(activityCtx);
|
|
3188
|
+
const distillerSessionId = distillerSessionIdFor(input.sessionId, input.epoch, input.attemptId);
|
|
3189
|
+
// Build the seed once — reused by the fresh spawn and by the re-seed
|
|
3190
|
+
// path below so a create-then-crash-before-send retry still delivers it.
|
|
3191
|
+
const buildSeed = async () => {
|
|
3192
|
+
const closure = await assembleRegenClosure({ catalog, artifactStore: artifactStore }, input.sessionId);
|
|
3193
|
+
const seed = buildMapReduceSeedPrompt({
|
|
3194
|
+
servedSessionId: input.sessionId,
|
|
3195
|
+
epoch: input.epoch,
|
|
3196
|
+
attemptId: input.attemptId,
|
|
3197
|
+
archiveArtifactId: input.archiveArtifactId || archiveName(input.epoch, input.attemptId),
|
|
3198
|
+
closure,
|
|
3199
|
+
...(input.handoff ? { handoff: input.handoff } : {}),
|
|
3200
|
+
...(input.instructions ? { instructions: input.instructions } : {}),
|
|
3201
|
+
});
|
|
3202
|
+
// Dump the EXACT distiller input (§9 dumps) on the served session.
|
|
3203
|
+
await artifactStore.uploadArtifact(input.sessionId, distillInputName(input.epoch, input.attemptId), Buffer.from(seed, "utf8"), "text/markdown");
|
|
3204
|
+
return seed;
|
|
3205
|
+
};
|
|
3206
|
+
const existing = await catalog.getSession(distillerSessionId).catch(() => null);
|
|
3207
|
+
if (existing) {
|
|
3208
|
+
// Only reuse a row that is ACTUALLY our distiller for THIS session —
|
|
3209
|
+
// re-verify the service columns before trusting its output as this
|
|
3210
|
+
// regen's package. The id is per-attempt and unguessable, so a
|
|
3211
|
+
// mismatch is not a real attack, but defense-in-depth: never collect
|
|
3212
|
+
// a foreign/mislabelled session as the distiller (adversarial-review
|
|
3213
|
+
// finding). A mismatch throws → the pipeline falls back deterministically.
|
|
3214
|
+
if (existing.serviceKind !== REGEN_DISTILLER_SERVICE_KIND || existing.serviceOf !== input.sessionId) {
|
|
3215
|
+
throw new Error(`distiller id collision: ${distillerSessionId} exists but is not this session's distiller `
|
|
3216
|
+
+ `(serviceKind=${existing.serviceKind ?? "null"}, serviceOf=${existing.serviceOf ?? "null"})`);
|
|
3217
|
+
}
|
|
3218
|
+
// Re-seed if the seed never landed (activity retried after
|
|
3219
|
+
// createSession but before send): otherwise the distiller sits with
|
|
3220
|
+
// no orchestration/work and the regen burns the whole 5-min deadline
|
|
3221
|
+
// before falling back (adversarial-review finding). Idempotent —
|
|
3222
|
+
// _startTurn ensures the orchestration then enqueues the prompt.
|
|
3223
|
+
const seeded = (await catalog.getSessionEventsBefore(distillerSessionId, Number.MAX_SAFE_INTEGER, 1, ["user.message"]).catch(() => [])).length > 0;
|
|
3224
|
+
if (!seeded) {
|
|
3225
|
+
activityCtx.traceInfo(`[runRegenSpawnDistiller] ${distillerSessionId} exists but was never seeded — re-seeding`);
|
|
3226
|
+
const seed = await buildSeed();
|
|
3227
|
+
const reseedClient = new PilotSwarmClient(internalClientConfig());
|
|
3228
|
+
try {
|
|
3229
|
+
await reseedClient.start();
|
|
3230
|
+
await catalog.markSessionService(distillerSessionId, REGEN_DISTILLER_SERVICE_KIND, input.sessionId);
|
|
3231
|
+
await reseedClient._startTurn(distillerSessionId, seed, { bootstrap: true });
|
|
3232
|
+
}
|
|
3233
|
+
finally {
|
|
3234
|
+
await reseedClient.stop().catch(() => { });
|
|
3235
|
+
}
|
|
3236
|
+
}
|
|
3237
|
+
else {
|
|
3238
|
+
activityCtx.traceInfo(`[runRegenSpawnDistiller] reusing ${distillerSessionId} (attempt retry)`);
|
|
3239
|
+
}
|
|
3240
|
+
return { distillerSessionId, distillerModel: existing.model ?? "(existing)", reused: true };
|
|
3241
|
+
}
|
|
3242
|
+
// Model policy (§9): per-call override → CLUSTER DEFAULT → configured
|
|
3243
|
+
// fallback. The served session's model is deliberately not in the chain.
|
|
3244
|
+
const candidates = [input.distillerModel, undefined, deps.fallbackDistillerModel];
|
|
3245
|
+
let resolvedRef;
|
|
3246
|
+
let resolvedAny = false;
|
|
3247
|
+
for (const ref of candidates) {
|
|
3248
|
+
if (deps.resolveModelOptions(ref)) {
|
|
3249
|
+
resolvedRef = ref;
|
|
3250
|
+
resolvedAny = true;
|
|
3251
|
+
break;
|
|
3252
|
+
}
|
|
3253
|
+
}
|
|
3254
|
+
if (!resolvedAny) {
|
|
3255
|
+
activityCtx.traceInfo(`[runRegenSpawnDistiller] no distiller model resolvable — caller falls back deterministically`);
|
|
3256
|
+
return { fallback: "no-model" };
|
|
3257
|
+
}
|
|
3258
|
+
// Root ancestor: service sessions collect under the tree root so a
|
|
3259
|
+
// sub-agent's distiller is still visible at the top (§9.1).
|
|
3260
|
+
let rootId = input.sessionId;
|
|
3261
|
+
for (let hop = 0; hop < 16; hop++) {
|
|
3262
|
+
const row = await catalog.getSession(rootId).catch(() => null);
|
|
3263
|
+
if (!row?.parentSessionId)
|
|
3264
|
+
break;
|
|
3265
|
+
rootId = row.parentSessionId;
|
|
3266
|
+
}
|
|
3267
|
+
const seed = await buildSeed();
|
|
3268
|
+
const owner = await resolveEffectiveSpawnOwner((id) => catalog.getSession(id), rootId).catch(() => null);
|
|
3269
|
+
const sdkClient = new PilotSwarmClient(internalClientConfig());
|
|
3270
|
+
try {
|
|
3271
|
+
await sdkClient.start();
|
|
3272
|
+
const session = await sdkClient.createSession({
|
|
3273
|
+
sessionId: distillerSessionId,
|
|
3274
|
+
parentSessionId: rootId,
|
|
3275
|
+
nestingLevel: 1,
|
|
3276
|
+
agentId: REGEN_DISTILLER_SERVICE_KIND,
|
|
3277
|
+
...(resolvedRef ? { model: resolvedRef } : {}),
|
|
3278
|
+
systemMessage: DISTILLER_SYSTEM_MESSAGE,
|
|
3279
|
+
toolNames: ["read_transcript_page"],
|
|
3280
|
+
...(owner ? { owner } : {}),
|
|
3281
|
+
});
|
|
3282
|
+
await catalog.markSessionService(distillerSessionId, REGEN_DISTILLER_SERVICE_KIND, input.sessionId);
|
|
3283
|
+
await cmsRetryBestEffort(`runRegenSpawnDistiller.updateSession meta session=${distillerSessionId}`, () => catalog.updateSession(distillerSessionId, {
|
|
3284
|
+
title: `Regen Distiller — ${input.sessionId.slice(0, 8)} e${input.epoch}→e${input.epoch + 1}`,
|
|
3285
|
+
agentId: REGEN_DISTILLER_SERVICE_KIND,
|
|
3286
|
+
}), (msg) => activityCtx.traceInfo(msg));
|
|
3287
|
+
await session.send(seed, { bootstrap: true });
|
|
3288
|
+
}
|
|
3289
|
+
finally {
|
|
3290
|
+
await sdkClient.stop().catch(() => { });
|
|
3291
|
+
}
|
|
3292
|
+
activityCtx.traceInfo(`[runRegenSpawnDistiller] spawned ${distillerSessionId} under root ${rootId} model=${resolvedRef ?? "(default)"}`);
|
|
3293
|
+
return { distillerSessionId, distillerModel: resolvedRef ?? "(default)" };
|
|
3294
|
+
});
|
|
3295
|
+
runtime.registerActivity("runRegenCheckDistiller", async (_activityCtx, input) => {
|
|
3296
|
+
if (!catalog)
|
|
3297
|
+
throw new Error("distiller check requires the CMS catalog");
|
|
3298
|
+
const row = await catalog.getSession(input.distillerSessionId).catch(() => null);
|
|
3299
|
+
if (!row)
|
|
3300
|
+
return { status: "failed", reason: "missing" };
|
|
3301
|
+
const rows = await catalog.getSessionEventsBefore(input.distillerSessionId, Number.MAX_SAFE_INTEGER, 1, ["assistant.message"]);
|
|
3302
|
+
if (rows.length > 0)
|
|
3303
|
+
return { status: "completed" };
|
|
3304
|
+
if (row.state === "failed" || row.state === "cancelled" || row.state === "completed") {
|
|
3305
|
+
return { status: "failed", reason: row.state };
|
|
3306
|
+
}
|
|
3307
|
+
return { status: "running" };
|
|
3308
|
+
});
|
|
3309
|
+
runtime.registerActivity("runRegenCollectDistiller", async (activityCtx, input) => {
|
|
3310
|
+
if (!catalog)
|
|
3311
|
+
throw new Error("distiller collect requires the CMS catalog");
|
|
3312
|
+
if (!artifactStore)
|
|
3313
|
+
throw new Error("distiller collect requires an artifact store");
|
|
3314
|
+
const { sessionId, epoch, attemptId, distillerSessionId } = input;
|
|
3315
|
+
const filename = packageName(epoch, attemptId);
|
|
3316
|
+
const bootstrapMeta = {
|
|
3317
|
+
epoch,
|
|
3318
|
+
...(input.archiveArtifactId ? { archiveArtifactId: input.archiveArtifactId } : {}),
|
|
3319
|
+
packageArtifactId: filename,
|
|
3320
|
+
};
|
|
3321
|
+
// Attempt idempotency: a retry after the package landed re-renders from it.
|
|
3322
|
+
if (await artifactExists(artifactStore, sessionId, filename)) {
|
|
3323
|
+
const stored = await artifactStore.downloadArtifact(sessionId, filename);
|
|
3324
|
+
const pkg = parseDistillerResponse(stored.body.toString("utf8"));
|
|
3325
|
+
return {
|
|
3326
|
+
packageArtifactId: filename,
|
|
3327
|
+
bootstrap: renderBootstrap(pkg, bootstrapMeta),
|
|
3328
|
+
distillerModel: "(reused)",
|
|
3329
|
+
distillMode: "llm",
|
|
3330
|
+
packageBytes: stored.body.length,
|
|
3331
|
+
};
|
|
3332
|
+
}
|
|
3333
|
+
// Scan the last few assistant messages (newest first), not just the
|
|
3334
|
+
// latest: a distiller that emits the JSON and THEN narrates ("done!")
|
|
3335
|
+
// would otherwise be misread as junk (adversarial-review finding). The
|
|
3336
|
+
// latest message is still dumped as the raw output of record.
|
|
3337
|
+
const rows = await catalog.getSessionEventsBefore(distillerSessionId, Number.MAX_SAFE_INTEGER, 5, ["assistant.message"]);
|
|
3338
|
+
const candidates = rows
|
|
3339
|
+
.slice()
|
|
3340
|
+
.sort((a, b) => Number(b.seq) - Number(a.seq))
|
|
3341
|
+
.map((r) => String(r.data?.content ?? ""))
|
|
3342
|
+
.filter((t) => t.trim());
|
|
3343
|
+
const responseText = candidates[0] ?? "";
|
|
3344
|
+
// Dump the RAW pre-parse output (§9 dumps) — junk that triggers the
|
|
3345
|
+
// fallback stays inspectable.
|
|
3346
|
+
await artifactStore.uploadArtifact(sessionId, distillOutputName(epoch, attemptId), Buffer.from(responseText, "utf8"), "text/plain");
|
|
3347
|
+
let pkg;
|
|
3348
|
+
let distillMode = "llm";
|
|
3349
|
+
let modelLabel = input.distillerModel ?? "(default)";
|
|
3350
|
+
try {
|
|
3351
|
+
if (candidates.length === 0)
|
|
3352
|
+
throw new Error("distiller produced no response");
|
|
3353
|
+
// Take the newest message that parses as a valid ResumePackage.
|
|
3354
|
+
let parsed;
|
|
3355
|
+
for (const text of candidates) {
|
|
3356
|
+
try {
|
|
3357
|
+
parsed = parseDistillerResponse(text);
|
|
3358
|
+
break;
|
|
3359
|
+
}
|
|
3360
|
+
catch { /* try older */ }
|
|
3361
|
+
}
|
|
3362
|
+
if (!parsed)
|
|
3363
|
+
throw new Error("no assistant message parsed as a ResumePackage");
|
|
3364
|
+
pkg = parsed;
|
|
3365
|
+
}
|
|
3366
|
+
catch (err) {
|
|
3367
|
+
activityCtx.traceInfo(`[runRegenCollectDistiller] parse failed (${err?.message || err}) — deterministic fallback`);
|
|
3368
|
+
const closure = await assembleRegenClosure({ catalog, artifactStore }, sessionId);
|
|
3369
|
+
pkg = deterministicPackage(closure, { ...(input.instructions ? { instructions: input.instructions } : {}) });
|
|
3370
|
+
distillMode = "deterministic";
|
|
3371
|
+
modelLabel = `(fallback:${modelLabel}:invalid)`;
|
|
3372
|
+
}
|
|
3373
|
+
const body = Buffer.from(JSON.stringify(pkg, null, 2), "utf8");
|
|
3374
|
+
await artifactStore.uploadArtifact(sessionId, filename, body, "application/json");
|
|
3375
|
+
// The distiller delivered — complete it so the sweeper's normal
|
|
3376
|
+
// stale-terminal scan reclaims it. Best-effort: an already-terminal or
|
|
3377
|
+
// unreachable distiller must never fail the collect.
|
|
3378
|
+
try {
|
|
3379
|
+
await enqueueDistillerCmd(distillerSessionId, "done", "distiller-complete");
|
|
3380
|
+
}
|
|
3381
|
+
catch (err) {
|
|
3382
|
+
activityCtx.traceInfo(`[runRegenCollectDistiller] complete enqueue failed (${err?.message || err})`);
|
|
3383
|
+
}
|
|
3384
|
+
return {
|
|
3385
|
+
packageArtifactId: filename,
|
|
3386
|
+
bootstrap: renderBootstrap(pkg, bootstrapMeta),
|
|
3387
|
+
distillerModel: modelLabel,
|
|
3388
|
+
distillMode,
|
|
3389
|
+
packageBytes: body.length,
|
|
3390
|
+
};
|
|
3391
|
+
});
|
|
3392
|
+
runtime.registerActivity("runRegenCancelDistiller", async (activityCtx, input) => {
|
|
3393
|
+
try {
|
|
3394
|
+
await enqueueDistillerCmd(input.distillerSessionId, "cancel", "distiller-cancel");
|
|
3395
|
+
return { ok: true };
|
|
3396
|
+
}
|
|
3397
|
+
catch (err) {
|
|
3398
|
+
activityCtx.traceInfo(`[runRegenCancelDistiller] cancel enqueue failed (${err?.message || err})`);
|
|
3399
|
+
return { ok: false };
|
|
3400
|
+
}
|
|
3401
|
+
});
|
|
3000
3402
|
}
|
|
3001
3403
|
//# sourceMappingURL=session-proxy.js.map
|