@opengeni/worker-bundle 1.0.0-canary.1 → 1.0.0
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/dist/activities/agent-run-admission.d.ts +3 -1
- package/dist/activities/agent-turn/admission.d.ts +24 -3
- package/dist/activities/agent-turn/agent-build.d.ts +4 -0
- package/dist/activities/agent-turn/claude-usage-observer.d.ts +58 -0
- package/dist/activities/agent-turn/code-search.d.ts +60 -0
- package/dist/activities/agent-turn/codex-capacity.d.ts +13 -0
- package/dist/activities/agent-turn/codex-plan-entitlement.d.ts +105 -0
- package/dist/activities/agent-turn/codex.d.ts +3 -2
- package/dist/activities/agent-turn/compaction-prep.d.ts +21 -5
- package/dist/activities/agent-turn/credential-leases.d.ts +19 -33
- package/dist/activities/agent-turn/credential-restriction.d.ts +3 -0
- package/dist/activities/agent-turn/errors.d.ts +82 -11
- package/dist/activities/agent-turn/failure-settlement.d.ts +6 -3
- package/dist/activities/agent-turn/final-reply.d.ts +18 -0
- package/dist/activities/agent-turn/finalization-monitor.d.ts +17 -0
- package/dist/activities/agent-turn/finalization.d.ts +4 -2
- package/dist/activities/agent-turn/github-repository-bindings.d.ts +2 -0
- package/dist/activities/agent-turn/governance-model.d.ts +9 -2
- package/dist/activities/agent-turn/history-sink.d.ts +2 -0
- package/dist/activities/agent-turn/history.d.ts +2 -0
- package/dist/activities/agent-turn/input-wait-reply.d.ts +41 -0
- package/dist/activities/agent-turn/media-artifacts.d.ts +5 -3
- package/dist/activities/agent-turn/model-call-admission.d.ts +15 -0
- package/dist/activities/agent-turn/model-usage.d.ts +6 -0
- package/dist/activities/agent-turn/model-wire-dispatch.d.ts +15 -0
- package/dist/activities/agent-turn/optional-repositories.d.ts +59 -0
- package/dist/activities/agent-turn/provider-dispatch-barrier.d.ts +12 -1
- package/dist/activities/agent-turn/quiescence.d.ts +7 -7
- package/dist/activities/agent-turn/recovery-warning.d.ts +9 -0
- package/dist/activities/agent-turn/refresh-credentials.d.ts +6 -0
- package/dist/activities/agent-turn/run-credentials.d.ts +8 -3
- package/dist/activities/agent-turn/sandbox-establish.d.ts +2 -1
- package/dist/activities/agent-turn/sandbox-provision.d.ts +3 -1
- package/dist/activities/agent-turn/sandbox-route.d.ts +3 -20
- package/dist/activities/agent-turn/sandbox-runtime.d.ts +2 -2
- package/dist/activities/agent-turn/session-title.d.ts +34 -2
- package/dist/activities/agent-turn/skill-checkout.d.ts +25 -6
- package/dist/activities/agent-turn/skill-read.d.ts +70 -2
- package/dist/activities/agent-turn/skill-remove.d.ts +14 -0
- package/dist/activities/agent-turn/skill-search.d.ts +3 -1
- package/dist/activities/agent-turn/skill-tools.d.ts +15 -2
- package/dist/activities/agent-turn/skill-transfer.d.ts +18 -6
- package/dist/activities/agent-turn/stream-attempt.d.ts +7 -3
- package/dist/activities/agent-turn/subscription-lease.d.ts +38 -0
- package/dist/activities/agent-turn/tool-environment.d.ts +56 -6
- package/dist/activities/agent-turn/tool-policy.d.ts +43 -0
- package/dist/activities/agent-turn/turn-context.d.ts +29 -0
- package/dist/activities/agent-turn/turn-sandbox-access.d.ts +3 -0
- package/dist/activities/agent-turn/xai-capacity.d.ts +2 -1
- package/dist/activities/automations.d.ts +3 -1
- package/dist/activities/browser-deadline-checkpoint.d.ts +29 -0
- package/dist/activities/codemode-dispatcher.d.ts +9 -2
- package/dist/activities/codex-capacity.d.ts +18 -2
- package/dist/activities/codex-rotation.d.ts +7 -1
- package/dist/activities/context-compaction.d.ts +16 -2
- package/dist/activities/gmail-files.d.ts +32 -0
- package/dist/activities/goals.d.ts +8 -0
- package/dist/activities/knowledge-indexing.d.ts +19 -0
- package/dist/activities/mcp-account-routes.d.ts +3 -0
- package/dist/activities/mcp-credentials.d.ts +12 -13
- package/dist/activities/mcp-operation-authority.d.ts +0 -5
- package/dist/activities/model-call-fact-reconciler.d.ts +34 -0
- package/dist/activities/open-suffix-resume.d.ts +13 -0
- package/dist/activities/parent-wake.d.ts +6 -12
- package/dist/activities/retained-screenshots.d.ts +7 -2
- package/dist/activities/rig-verification.d.ts +2 -3
- package/dist/activities/run-credential-renewal.d.ts +1 -0
- package/dist/activities/run-credentials.d.ts +15 -3
- package/dist/activities/sandbox-images.d.ts +1 -1
- package/dist/activities/sandbox-lease.d.ts +47 -9
- package/dist/activities/scheduled-tasks.d.ts +4 -35
- package/dist/activities/session-state.d.ts +70 -3
- package/dist/activities/types.d.ts +55 -6
- package/dist/activities/workspace-capture.d.ts +2 -0
- package/dist/activities/workspace-credential-provider.d.ts +46 -0
- package/dist/{activities-control-HMFGSKC5.js → activities-control-BNPTRTOE.js} +1896 -418
- package/dist/activities-control-BNPTRTOE.js.map +1 -0
- package/dist/activities-control.d.ts +182 -4
- package/dist/{activities-turn-AP67JADS.js → activities-turn-5LGZOSVU.js} +4476 -1327
- package/dist/activities-turn-5LGZOSVU.js.map +1 -0
- package/dist/activities.d.ts +182 -4
- package/dist/artifact-materializer-entry.js +5 -2
- package/dist/artifact-materializer-entry.js.map +1 -1
- package/dist/artifact-outbox-entry.js +5 -2
- package/dist/artifact-outbox-entry.js.map +1 -1
- package/dist/browser-deadline-checkpoint-contract.d.ts +2 -0
- package/dist/{chunk-A4XQWVZK.js → chunk-3ZTRWDMN.js} +307 -4
- package/dist/chunk-3ZTRWDMN.js.map +1 -0
- package/dist/{chunk-RAMNYSAW.js → chunk-4ER3YXOT.js} +22 -4
- package/dist/chunk-4ER3YXOT.js.map +1 -0
- package/dist/{chunk-CYITU5UH.js → chunk-LJX7Z2KP.js} +1445 -343
- package/dist/chunk-LJX7Z2KP.js.map +1 -0
- package/dist/editable-artifact-materializer-service.d.ts +2 -2
- package/dist/editable-artifact-outbox-service.d.ts +2 -2
- package/dist/host-export-pump.d.ts +3 -1
- package/dist/host-export.d.ts +1 -1
- package/dist/host-export.js +1 -1
- package/dist/http.d.ts +1 -1
- package/dist/index.d.ts +95 -3
- package/dist/index.js +137 -43
- package/dist/index.js.map +1 -1
- package/dist/observability-metrics.d.ts +118 -8
- package/dist/retained-process-diagnostics.d.ts +4 -0
- package/dist/retained-process-retry.d.ts +7 -0
- package/dist/sandbox-resume.d.ts +55 -13
- package/dist/sandbox-routing.d.ts +5 -3
- package/dist/sandbox-snapshot-diagnostics.d.ts +20 -0
- package/dist/session-event-fanout.d.ts +6 -0
- package/dist/warm-capture-holder.d.ts +3 -0
- package/dist/worker-service-lifecycle.d.ts +12 -0
- package/dist/workflow-bundle.js +273 -41
- package/dist/workflows/activities.d.ts +1 -1
- package/dist/workflows/browser-deadline-checkpoint.d.ts +9 -0
- package/dist/workflows/scheduled-tasks.d.ts +4 -0
- package/dist/workflows/session.d.ts +36 -0
- package/dist/workflows.d.ts +1 -0
- package/package.json +21 -19
- package/src/activities/agent-run-admission.ts +17 -1
- package/src/activities/agent-turn/admission.ts +66 -3
- package/src/activities/agent-turn/agent-build.ts +84 -10
- package/src/activities/agent-turn/claim.ts +186 -43
- package/src/activities/agent-turn/claude-usage-observer.ts +221 -0
- package/src/activities/agent-turn/code-search.ts +275 -0
- package/src/activities/agent-turn/codex-capacity.ts +172 -8
- package/src/activities/agent-turn/codex-plan-entitlement.ts +254 -0
- package/src/activities/agent-turn/codex.ts +13 -5
- package/src/activities/agent-turn/compaction-prep.ts +170 -102
- package/src/activities/agent-turn/credential-leases.ts +122 -216
- package/src/activities/agent-turn/credential-restriction.ts +14 -0
- package/src/activities/agent-turn/errors.ts +647 -48
- package/src/activities/agent-turn/failure-settlement.ts +682 -130
- package/src/activities/agent-turn/final-reply.ts +46 -0
- package/src/activities/agent-turn/finalization-monitor.ts +120 -0
- package/src/activities/agent-turn/finalization.ts +146 -43
- package/src/activities/agent-turn/github-repository-bindings.ts +3 -1
- package/src/activities/agent-turn/governance-model.ts +69 -28
- package/src/activities/agent-turn/history-sink.ts +16 -2
- package/src/activities/agent-turn/history.ts +38 -11
- package/src/activities/agent-turn/input-wait-reply.ts +103 -0
- package/src/activities/agent-turn/knowledge-source-tools.ts +2 -0
- package/src/activities/agent-turn/media-artifacts.ts +2 -1
- package/src/activities/agent-turn/model-call-admission.ts +94 -0
- package/src/activities/agent-turn/model-usage.ts +64 -3
- package/src/activities/agent-turn/model-wire-dispatch.ts +27 -0
- package/src/activities/agent-turn/optional-repositories.ts +224 -0
- package/src/activities/agent-turn/provider-dispatch-barrier.ts +22 -0
- package/src/activities/agent-turn/quiescence.ts +10 -7
- package/src/activities/agent-turn/recovery-warning.ts +16 -0
- package/src/activities/agent-turn/refresh-credentials.ts +44 -0
- package/src/activities/agent-turn/run-credentials.ts +116 -55
- package/src/activities/agent-turn/run.ts +320 -93
- package/src/activities/agent-turn/sandbox-establish.ts +84 -8
- package/src/activities/agent-turn/sandbox-provision.ts +3 -1
- package/src/activities/agent-turn/sandbox-route.ts +4 -21
- package/src/activities/agent-turn/sandbox-runtime.ts +343 -18
- package/src/activities/agent-turn/session-title.ts +81 -5
- package/src/activities/agent-turn/skill-checkout.ts +111 -24
- package/src/activities/agent-turn/skill-install.ts +1 -1
- package/src/activities/agent-turn/skill-read.ts +374 -28
- package/src/activities/agent-turn/skill-remove.ts +46 -0
- package/src/activities/agent-turn/skill-save.ts +1 -1
- package/src/activities/agent-turn/skill-search.ts +10 -1
- package/src/activities/agent-turn/skill-selection.ts +4 -0
- package/src/activities/agent-turn/skill-tools.ts +112 -18
- package/src/activities/agent-turn/skill-transfer.ts +68 -23
- package/src/activities/agent-turn/stream-attempt.ts +313 -77
- package/src/activities/agent-turn/subscription-lease.ts +115 -0
- package/src/activities/agent-turn/tool-environment.ts +316 -167
- package/src/activities/agent-turn/tool-policy.ts +80 -1
- package/src/activities/agent-turn/turn-context.ts +35 -0
- package/src/activities/agent-turn/turn-sandbox-access.ts +7 -1
- package/src/activities/agent-turn/xai-capacity.ts +94 -51
- package/src/activities/automations.ts +76 -4
- package/src/activities/browser-deadline-checkpoint.ts +279 -0
- package/src/activities/capabilities.ts +108 -11
- package/src/activities/codemode-dispatcher.ts +36 -8
- package/src/activities/codex-capacity.ts +60 -25
- package/src/activities/codex-rotation.ts +39 -17
- package/src/activities/context-compaction.ts +75 -18
- package/src/activities/gmail-files.ts +88 -0
- package/src/activities/goals.ts +116 -121
- package/src/activities/google-drive-publication.ts +1 -3
- package/src/activities/image-generation-operation.ts +1 -1
- package/src/activities/knowledge-indexing.ts +269 -15
- package/src/activities/knowledge-source-sync.ts +10 -0
- package/src/activities/mcp-account-routes.ts +17 -0
- package/src/activities/mcp-credentials.ts +83 -194
- package/src/activities/mcp-operation-authority.ts +16 -41
- package/src/activities/model-call-fact-reconciler.ts +112 -0
- package/src/activities/open-suffix-resume.ts +15 -2
- package/src/activities/parent-wake.ts +46 -21
- package/src/activities/retained-screenshots.ts +82 -11
- package/src/activities/rig-verification.ts +38 -37
- package/src/activities/run-credential-renewal.ts +13 -1
- package/src/activities/run-credentials.ts +59 -17
- package/src/activities/run-input.ts +25 -16
- package/src/activities/sandbox-images.ts +0 -1
- package/src/activities/sandbox-lease.ts +798 -82
- package/src/activities/scheduled-tasks.ts +550 -178
- package/src/activities/session-state.ts +245 -6
- package/src/activities/site-auth-maintenance.ts +3 -0
- package/src/activities/types.ts +72 -5
- package/src/activities/workflow-wake.ts +2 -17
- package/src/activities/workspace-capture.ts +13 -2
- package/src/activities/workspace-credential-provider.ts +283 -0
- package/src/activities-control.ts +4 -0
- package/src/activities-turn.ts +5 -0
- package/src/activities.ts +13 -0
- package/src/activity-services.ts +16 -4
- package/src/browser-deadline-checkpoint-contract.ts +5 -0
- package/src/editable-artifact-hint-broker.ts +3 -0
- package/src/editable-artifact-materializer-service.ts +7 -3
- package/src/editable-artifact-outbox-service.ts +4 -4
- package/src/github-rest-mcp.ts +1 -2
- package/src/host-export-pump.ts +26 -4
- package/src/host-export.ts +3 -0
- package/src/http.ts +4 -2
- package/src/index.ts +99 -37
- package/src/observability-metrics.ts +510 -5
- package/src/personal-github-git-credentials.ts +2 -1
- package/src/pr-review-credentials.ts +1 -3
- package/src/retained-process-diagnostics.ts +50 -0
- package/src/retained-process-retry.ts +36 -0
- package/src/sandbox-resume.ts +388 -101
- package/src/sandbox-routing.ts +150 -25
- package/src/sandbox-snapshot-diagnostics.ts +112 -0
- package/src/session-event-fanout.ts +23 -0
- package/src/warm-capture-holder.ts +15 -0
- package/src/worker-service-lifecycle.ts +53 -0
- package/src/workflows/activities.ts +16 -1
- package/src/workflows/browser-deadline-checkpoint.ts +50 -0
- package/src/workflows/file-upload-reaper.ts +2 -0
- package/src/workflows/scheduled-tasks.ts +26 -13
- package/src/workflows/session.ts +242 -22
- package/src/workflows.ts +4 -0
- package/dist/activities/agent-turn/knowledge-sources.d.ts +0 -20
- package/dist/activities/packs.d.ts +0 -55
- package/dist/activities-control-HMFGSKC5.js.map +0 -1
- package/dist/activities-turn-AP67JADS.js.map +0 -1
- package/dist/chunk-A4XQWVZK.js.map +0 -1
- package/dist/chunk-CYITU5UH.js.map +0 -1
- package/dist/chunk-RAMNYSAW.js.map +0 -1
- package/src/activities/agent-turn/knowledge-sources.ts +0 -86
- package/src/activities/packs.ts +0 -166
|
@@ -1,13 +1,17 @@
|
|
|
1
|
+
import { getSessionParentClaudeProviderAccountAuthority } from "@opengeni/db";
|
|
1
2
|
import type { Settings } from "@opengeni/config";
|
|
2
3
|
import type { Session, SessionGoal, SessionSystemUpdatePayload } from "@opengeni/contracts";
|
|
3
4
|
import {
|
|
4
5
|
getSession,
|
|
5
6
|
getSessionGoal,
|
|
6
7
|
getSessionParentPersonalConnectionDelegations,
|
|
8
|
+
getSessionParentMcpAccountBindings,
|
|
7
9
|
getSessionParentXaiProviderAccountAuthority,
|
|
8
10
|
addSessionSystemUpdateWithSourceMutation,
|
|
9
11
|
claimPendingSessionSystemUpdateOutbox,
|
|
10
12
|
claimPendingSessionWorkflowWakes,
|
|
13
|
+
repairPendingChildTerminalResultWakes,
|
|
14
|
+
type ChildTerminalWakeRepairCursor,
|
|
11
15
|
childRequiresActionDedupeKey,
|
|
12
16
|
getSessionSystemUpdateOutboxByDedupeKey,
|
|
13
17
|
getOrCreateSessionSystemUpdateOutbox,
|
|
@@ -38,8 +42,11 @@ export type ReconcileParentSystemUpdateOverrides = Partial<{
|
|
|
38
42
|
|
|
39
43
|
export type ReconcileSessionWorkflowWakeOverrides = Partial<{
|
|
40
44
|
claimPendingSessionWorkflowWakes: typeof claimPendingSessionWorkflowWakes;
|
|
45
|
+
repairPendingChildTerminalResultWakes: typeof repairPendingChildTerminalResultWakes;
|
|
41
46
|
}>;
|
|
42
47
|
|
|
48
|
+
const childTerminalRepairCursors = new WeakMap<Database, ChildTerminalWakeRepairCursor>();
|
|
49
|
+
|
|
43
50
|
export type ReconcileAutomaticSessionTitleFanoutOverrides = Partial<{
|
|
44
51
|
claimAutomaticSessionTitleFanout: typeof claimAutomaticSessionTitleFanout;
|
|
45
52
|
markAutomaticSessionTitleFanoutDelivered: typeof markAutomaticSessionTitleFanoutDelivered;
|
|
@@ -63,23 +70,30 @@ export async function notifyParentOfChildIdle(
|
|
|
63
70
|
return;
|
|
64
71
|
}
|
|
65
72
|
const goal = await getSessionGoal(svc.db, workspaceId, childSessionId);
|
|
66
|
-
// Sacred user pause: if the MANAGER's own goal was paused by the user, the
|
|
67
|
-
// wake must not tell it to "resume it now" — that instruction is exactly
|
|
68
|
-
// what re-arms the loop the user just stopped. Suppress the resume nudge and
|
|
69
|
-
// tell the agent to stay paused. Paired with the goal_set reactivation
|
|
70
|
-
// guard so a nudge that slips through still cannot revive the goal.
|
|
71
73
|
const clientEventId = `child-completion:${childSessionId}:${episodeKey}`;
|
|
74
|
+
// The idle settlement committed this row with the child's frozen final
|
|
75
|
+
// answer. This adds the goal facts; the upsert keeps the frozen content.
|
|
72
76
|
const payload = childCompletionPayload(child, goal);
|
|
73
77
|
const personalConnectionDelegations = await getSessionParentPersonalConnectionDelegations(
|
|
74
78
|
svc.db,
|
|
75
79
|
workspaceId,
|
|
76
80
|
childSessionId,
|
|
77
81
|
);
|
|
82
|
+
const mcpAccountBindings = await getSessionParentMcpAccountBindings(
|
|
83
|
+
svc.db,
|
|
84
|
+
workspaceId,
|
|
85
|
+
childSessionId,
|
|
86
|
+
);
|
|
78
87
|
const xaiAuthority = await getSessionParentXaiProviderAccountAuthority(
|
|
79
88
|
svc.db,
|
|
80
89
|
workspaceId,
|
|
81
90
|
childSessionId,
|
|
82
91
|
);
|
|
92
|
+
const claudeAuthority = await getSessionParentClaudeProviderAccountAuthority(
|
|
93
|
+
svc.db,
|
|
94
|
+
workspaceId,
|
|
95
|
+
childSessionId,
|
|
96
|
+
);
|
|
83
97
|
const outbox = await getOrCreateSessionSystemUpdateOutbox(svc.db, {
|
|
84
98
|
accountId: child.accountId,
|
|
85
99
|
workspaceId,
|
|
@@ -92,12 +106,17 @@ export async function notifyParentOfChildIdle(
|
|
|
92
106
|
summary: childCompletionSummary(child, goal, "idle"),
|
|
93
107
|
payload,
|
|
94
108
|
lineage: {
|
|
109
|
+
...(claudeAuthority.subjectId
|
|
110
|
+
? { claudeAuthoritySubjectId: claudeAuthority.subjectId }
|
|
111
|
+
: {}),
|
|
95
112
|
childSessionId: child.id,
|
|
96
113
|
parentSessionId: child.parentSessionId,
|
|
97
114
|
...(xaiAuthority.subjectId ? { xaiAuthoritySubjectId: xaiAuthority.subjectId } : {}),
|
|
98
115
|
},
|
|
99
116
|
personalConnectionDelegations,
|
|
117
|
+
mcpAccountBindings,
|
|
100
118
|
xaiProviderAccountAuthoritySnapshot: xaiAuthority.snapshot,
|
|
119
|
+
claudeProviderAccountAuthoritySnapshot: claudeAuthority.snapshot,
|
|
101
120
|
});
|
|
102
121
|
if (outbox.status === "delivered") {
|
|
103
122
|
return;
|
|
@@ -214,7 +233,9 @@ async function deliverParentSystemUpdateOutbox(
|
|
|
214
233
|
summary: outbox.summary,
|
|
215
234
|
lineage: outbox.lineage,
|
|
216
235
|
personalConnectionDelegations: outbox.personalConnectionDelegations,
|
|
236
|
+
mcpAccountBindings: outbox.mcpAccountBindings,
|
|
217
237
|
xaiProviderAccountAuthoritySnapshot: outbox.xaiProviderAccountAuthoritySnapshot,
|
|
238
|
+
claudeProviderAccountAuthoritySnapshot: outbox.claudeProviderAccountAuthoritySnapshot,
|
|
218
239
|
},
|
|
219
240
|
async (tx) => {
|
|
220
241
|
await markSessionSystemUpdateOutboxDeliveredInTransaction(tx, outbox);
|
|
@@ -370,6 +391,22 @@ export async function reconcilePendingSessionWorkflowWakes(
|
|
|
370
391
|
pendingAdmissionBlockers: {},
|
|
371
392
|
};
|
|
372
393
|
}
|
|
394
|
+
const repairChildren =
|
|
395
|
+
overrides.repairPendingChildTerminalResultWakes ?? repairPendingChildTerminalResultWakes;
|
|
396
|
+
const inventory = await repairChildren(
|
|
397
|
+
svc.db,
|
|
398
|
+
Math.min(100, limit),
|
|
399
|
+
childTerminalRepairCursors.get(svc.db) ?? null,
|
|
400
|
+
);
|
|
401
|
+
if (inventory.cursor) childTerminalRepairCursors.set(svc.db, inventory.cursor);
|
|
402
|
+
else childTerminalRepairCursors.delete(svc.db);
|
|
403
|
+
if (inventory.failed > 0) {
|
|
404
|
+
svc.observability.error("Pending child-result wake repair failed", {
|
|
405
|
+
examined: inventory.examined,
|
|
406
|
+
registered: inventory.registered,
|
|
407
|
+
failed: inventory.failed,
|
|
408
|
+
});
|
|
409
|
+
}
|
|
373
410
|
const repairs = await claimPendingSessionWorkflowWakesFn(svc.db, limit);
|
|
374
411
|
let signaled = 0;
|
|
375
412
|
let pendingAdmission = 0;
|
|
@@ -457,11 +494,10 @@ function childCompletionPayload(
|
|
|
457
494
|
}
|
|
458
495
|
|
|
459
496
|
/**
|
|
460
|
-
* The
|
|
461
|
-
* the
|
|
462
|
-
*
|
|
463
|
-
*
|
|
464
|
-
* shared trailing instruction instead of running N model calls.
|
|
497
|
+
* The short status line for one child (what happened + its goal). It is also
|
|
498
|
+
* the timeline preview, so it carries no instructions: the parent reads the
|
|
499
|
+
* child's answer from the typed payload, and the operational contract says how
|
|
500
|
+
* to use it. N completions coalesce into one internal-update inference.
|
|
465
501
|
*/
|
|
466
502
|
export function childCompletionSummary(
|
|
467
503
|
child: Session,
|
|
@@ -495,14 +531,3 @@ export function childCompletionSummary(
|
|
|
495
531
|
}
|
|
496
532
|
return lines.join("\n");
|
|
497
533
|
}
|
|
498
|
-
|
|
499
|
-
/**
|
|
500
|
-
* The single trailing instruction appended to a child-completion (or digest)
|
|
501
|
-
* inference. Suppresses the "resume it now" nudge when the manager's own goal
|
|
502
|
-
* was paused by the user (paired with the goal_set reactivation guard).
|
|
503
|
-
*/
|
|
504
|
-
export function childCompletionTrailing(parentGoalUserPaused: boolean): string {
|
|
505
|
-
return parentGoalUserPaused
|
|
506
|
-
? "Read each worker's session events/notebook output for its result. This session was paused by the user — do NOT resume or replace your goal; summarize the result for the user and remain paused."
|
|
507
|
-
: "Read each worker's session events/notebook output for its result, then continue. If your own goal was paused awaiting these workers, resume it now.";
|
|
508
|
-
}
|
|
@@ -6,13 +6,16 @@ import {
|
|
|
6
6
|
COMPUTER_SCREENSHOT_WORKSPACE_QUOTA_BYTES,
|
|
7
7
|
RetainedArtifactMetadataSchema,
|
|
8
8
|
retainedScreenshotReferenceFromFile,
|
|
9
|
+
retainedSessionScreenshotKindFromObjectKey,
|
|
9
10
|
type RetainedArtifactMetadata,
|
|
10
11
|
type RetainedArtifactReference,
|
|
11
12
|
type RetainedOutputUnavailableReason,
|
|
13
|
+
type RetainedSessionScreenshotKind,
|
|
12
14
|
} from "@opengeni/contracts";
|
|
13
15
|
import {
|
|
14
16
|
RetainedScreenshotQuotaExceededError,
|
|
15
17
|
getRetainedScreenshotArtifact,
|
|
18
|
+
getRetainedScreenshotArtifactForToolCall,
|
|
16
19
|
isDatabasePersistenceFailure,
|
|
17
20
|
isSessionEventPersistenceError,
|
|
18
21
|
prepareRetainedScreenshotArtifact,
|
|
@@ -209,14 +212,26 @@ export function toolOutputContainsInlineImage(output: unknown): boolean {
|
|
|
209
212
|
return (
|
|
210
213
|
(record.type === "input_image" &&
|
|
211
214
|
sdkImageSourceContainsInlineImage(record.image ?? record.image_url ?? record.imageUrl)) ||
|
|
212
|
-
(record.type === "image" &&
|
|
215
|
+
(record.type === "image" && isDeclaredInlineMcpImage(record))
|
|
213
216
|
);
|
|
214
217
|
});
|
|
215
218
|
}
|
|
216
219
|
if (!output || typeof output !== "object") return false;
|
|
217
220
|
const record = output as Record<string, unknown>;
|
|
218
221
|
if (Array.isArray(record.content)) return toolOutputContainsInlineImage(record.content);
|
|
219
|
-
return
|
|
222
|
+
return (
|
|
223
|
+
record.type === "image" &&
|
|
224
|
+
(sdkImageSourceContainsInlineImage(record.image) || isDeclaredInlineMcpImage(record))
|
|
225
|
+
);
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
/** Detect image-bearing MCP blocks even when decoding rejects oversized or malformed bytes. */
|
|
229
|
+
function isDeclaredInlineMcpImage(record: Record<string, unknown>): boolean {
|
|
230
|
+
return (
|
|
231
|
+
typeof record.data === "string" &&
|
|
232
|
+
typeof record.mimeType === "string" &&
|
|
233
|
+
record.mimeType.toLowerCase().startsWith("image/")
|
|
234
|
+
);
|
|
220
235
|
}
|
|
221
236
|
|
|
222
237
|
function decodeInlineMcpImage(
|
|
@@ -520,9 +535,14 @@ export function retainedScreenshotIdentity(input: {
|
|
|
520
535
|
attemptId: string;
|
|
521
536
|
toolCallId: string;
|
|
522
537
|
toolOutputId: string;
|
|
538
|
+
kind?: RetainedSessionScreenshotKind | undefined;
|
|
523
539
|
}): { artifactId: string; settlementKey: string } {
|
|
524
540
|
const settlementKey = createHash("sha256")
|
|
525
|
-
.update(
|
|
541
|
+
.update(
|
|
542
|
+
input.kind === "browser_screenshot"
|
|
543
|
+
? "opengeni:browser-screenshot:v1\0"
|
|
544
|
+
: "opengeni:computer-screenshot:v1\0",
|
|
545
|
+
)
|
|
526
546
|
.update(input.sessionId)
|
|
527
547
|
.update("\0")
|
|
528
548
|
.update(input.turnId)
|
|
@@ -551,12 +571,13 @@ export function unavailableRetainedSessionImage(input: {
|
|
|
551
571
|
toolCallId: string;
|
|
552
572
|
toolOutputId: string;
|
|
553
573
|
reason: RetainedOutputUnavailableReason;
|
|
574
|
+
kind?: RetainedSessionScreenshotKind | undefined;
|
|
554
575
|
}): RetainedArtifactMetadata {
|
|
555
576
|
const identity = retainedScreenshotIdentity(input);
|
|
556
577
|
return unavailable(identity.artifactId, input.reason);
|
|
557
578
|
}
|
|
558
579
|
|
|
559
|
-
export async function
|
|
580
|
+
export async function retainSessionScreenshot(input: {
|
|
560
581
|
db: Database;
|
|
561
582
|
objectStorage: ObjectStorage | null;
|
|
562
583
|
accountId: string;
|
|
@@ -565,6 +586,7 @@ export async function retainComputerScreenshot(input: {
|
|
|
565
586
|
turnId: string;
|
|
566
587
|
attemptId: string;
|
|
567
588
|
output: TypedScreenshotToolOutput;
|
|
589
|
+
kind?: RetainedSessionScreenshotKind | undefined;
|
|
568
590
|
now?: Date;
|
|
569
591
|
retentionMs?: number;
|
|
570
592
|
workspaceQuotaBytes?: number;
|
|
@@ -575,6 +597,7 @@ export async function retainComputerScreenshot(input: {
|
|
|
575
597
|
attemptId: input.attemptId,
|
|
576
598
|
toolCallId: input.output.callId,
|
|
577
599
|
toolOutputId: input.output.toolOutputId,
|
|
600
|
+
kind: input.kind,
|
|
578
601
|
});
|
|
579
602
|
let screenshot: ValidatedSessionImage;
|
|
580
603
|
try {
|
|
@@ -594,7 +617,8 @@ export async function retainComputerScreenshot(input: {
|
|
|
594
617
|
const retentionExpiresAt = new Date(
|
|
595
618
|
now.getTime() + (input.retentionMs ?? COMPUTER_SCREENSHOT_RETENTION_MS),
|
|
596
619
|
);
|
|
597
|
-
const
|
|
620
|
+
const objectName = input.kind === "browser_screenshot" ? "browser-screenshot" : "session-image";
|
|
621
|
+
const objectKey = `workspaces/${input.workspaceId}/files/${identity.artifactId}/retained/${objectName}.${screenshot.extension}`;
|
|
598
622
|
let prepared: RetainedScreenshotArtifact;
|
|
599
623
|
try {
|
|
600
624
|
prepared = (
|
|
@@ -697,6 +721,9 @@ export async function retainComputerScreenshot(input: {
|
|
|
697
721
|
}
|
|
698
722
|
}
|
|
699
723
|
|
|
724
|
+
/** Existing computer callers keep their stable entry point. */
|
|
725
|
+
export const retainComputerScreenshot = retainSessionScreenshot;
|
|
726
|
+
|
|
700
727
|
/** Replace only new screenshot bytes with a compact receipt before first persistence. */
|
|
701
728
|
export function compactRetainedScreenshotHistory(
|
|
702
729
|
history: Array<Record<string, unknown>>,
|
|
@@ -874,6 +901,26 @@ async function materializeRetainedScreenshotHistoryWithCache(
|
|
|
874
901
|
cache: Map<string, string>,
|
|
875
902
|
): Promise<Array<Record<string, unknown>>> {
|
|
876
903
|
const now = input.now ?? new Date();
|
|
904
|
+
const receiptForMarker = async (
|
|
905
|
+
marker: unknown,
|
|
906
|
+
callId: string | null,
|
|
907
|
+
): Promise<RetainedArtifactMetadata | null> => {
|
|
908
|
+
if (!isRetainedImageMarker(marker)) return null;
|
|
909
|
+
const receipt = retainedReceipt(marker.artifact);
|
|
910
|
+
if (receipt) return receipt;
|
|
911
|
+
// Older canonical history could truncate the artifact UUID and reason as
|
|
912
|
+
// ordinary text. Recover only from this exact session and an unambiguous
|
|
913
|
+
// tool call; otherwise fail before constructing a malformed model image.
|
|
914
|
+
if (!callId) throw new Error("Retained screenshot receipt has no tool call identity");
|
|
915
|
+
const artifact = await getRetainedScreenshotArtifactForToolCall(
|
|
916
|
+
input.db,
|
|
917
|
+
input.workspaceId,
|
|
918
|
+
input.sessionId,
|
|
919
|
+
callId,
|
|
920
|
+
);
|
|
921
|
+
if (!artifact) throw new Error("Retained screenshot receipt cannot be recovered");
|
|
922
|
+
return reference(artifact);
|
|
923
|
+
};
|
|
877
924
|
const dataUrlForReceipt = async (receipt: RetainedArtifactMetadata): Promise<string> => {
|
|
878
925
|
let dataUrl = cache.get(receipt.artifactId);
|
|
879
926
|
if (!dataUrl) {
|
|
@@ -921,8 +968,12 @@ async function materializeRetainedScreenshotHistoryWithCache(
|
|
|
921
968
|
}
|
|
922
969
|
return dataUrl;
|
|
923
970
|
};
|
|
924
|
-
const materializeEntry = async (entry: unknown): Promise<unknown> => {
|
|
925
|
-
const
|
|
971
|
+
const materializeEntry = async (entry: unknown, callId: string | null): Promise<unknown> => {
|
|
972
|
+
const image =
|
|
973
|
+
entry && typeof entry === "object" && !Array.isArray(entry)
|
|
974
|
+
? (entry as Record<string, unknown>).image
|
|
975
|
+
: null;
|
|
976
|
+
const receipt = await receiptForMarker(image, callId);
|
|
926
977
|
if (!receipt) return entry;
|
|
927
978
|
const dataUrl = await dataUrlForReceipt(receipt);
|
|
928
979
|
return { ...(entry as Record<string, unknown>), image: dataUrl };
|
|
@@ -930,7 +981,8 @@ async function materializeRetainedScreenshotHistoryWithCache(
|
|
|
930
981
|
|
|
931
982
|
const materialized: Array<Record<string, unknown>> = [];
|
|
932
983
|
for (const item of input.history) {
|
|
933
|
-
const
|
|
984
|
+
const callId = historyCallId(item);
|
|
985
|
+
const directReceipt = await receiptForMarker(item.output, callId);
|
|
934
986
|
if (directReceipt) {
|
|
935
987
|
materialized.push({
|
|
936
988
|
...item,
|
|
@@ -954,7 +1006,7 @@ async function materializeRetainedScreenshotHistoryWithCache(
|
|
|
954
1006
|
let changed = false;
|
|
955
1007
|
const output: unknown[] = [];
|
|
956
1008
|
for (const entry of outputEntries) {
|
|
957
|
-
const next = await materializeEntry(entry);
|
|
1009
|
+
const next = await materializeEntry(entry, callId);
|
|
958
1010
|
changed ||= next !== entry;
|
|
959
1011
|
output.push(next);
|
|
960
1012
|
}
|
|
@@ -1059,12 +1111,15 @@ function reference(artifact: RetainedScreenshotArtifact): RetainedArtifactRefere
|
|
|
1059
1111
|
if (!artifact.sessionId) {
|
|
1060
1112
|
throw new Error(`Ready retained screenshot is detached: ${artifact.artifactId}`);
|
|
1061
1113
|
}
|
|
1114
|
+
const kind = retainedSessionScreenshotKindFromObjectKey(artifact.file.objectKey);
|
|
1115
|
+
if (!kind) throw new Error(`Ready retained screenshot has unknown key: ${artifact.artifactId}`);
|
|
1062
1116
|
const value = retainedScreenshotReferenceFromFile({
|
|
1063
1117
|
...artifact.file,
|
|
1064
1118
|
sessionId: artifact.sessionId,
|
|
1065
1119
|
width: artifact.width,
|
|
1066
1120
|
height: artifact.height,
|
|
1067
1121
|
expiresAt: artifact.retentionExpiresAt.toISOString(),
|
|
1122
|
+
kind,
|
|
1068
1123
|
});
|
|
1069
1124
|
if (!value)
|
|
1070
1125
|
throw new Error(`Ready retained screenshot receipt is invalid: ${artifact.artifactId}`);
|
|
@@ -1110,6 +1165,18 @@ function retainedReceiptFromImageContent(entry: unknown): RetainedArtifactMetada
|
|
|
1110
1165
|
return retainedReceipt(marker.artifact);
|
|
1111
1166
|
}
|
|
1112
1167
|
|
|
1168
|
+
function isRetainedImageMarker(value: unknown): value is {
|
|
1169
|
+
type: "retained_artifact";
|
|
1170
|
+
artifact: unknown;
|
|
1171
|
+
} {
|
|
1172
|
+
return Boolean(
|
|
1173
|
+
value &&
|
|
1174
|
+
typeof value === "object" &&
|
|
1175
|
+
!Array.isArray(value) &&
|
|
1176
|
+
(value as Record<string, unknown>).type === RETAINED_IMAGE_MARKER,
|
|
1177
|
+
);
|
|
1178
|
+
}
|
|
1179
|
+
|
|
1113
1180
|
function retainedReceiptFromDirectOutput(output: unknown): RetainedArtifactMetadata | null {
|
|
1114
1181
|
if (!output || typeof output !== "object" || Array.isArray(output)) return null;
|
|
1115
1182
|
const marker = output as Record<string, unknown>;
|
|
@@ -1120,7 +1187,11 @@ function retainedReceiptFromDirectOutput(output: unknown): RetainedArtifactMetad
|
|
|
1120
1187
|
function retainedReceipt(value: unknown): RetainedArtifactMetadata | null {
|
|
1121
1188
|
const parsed = RetainedArtifactMetadataSchema.safeParse(value);
|
|
1122
1189
|
if (!parsed.success) return null;
|
|
1123
|
-
return parsed.data.available &&
|
|
1190
|
+
return parsed.data.available &&
|
|
1191
|
+
parsed.data.kind !== "computer_screenshot" &&
|
|
1192
|
+
parsed.data.kind !== "browser_screenshot"
|
|
1193
|
+
? null
|
|
1194
|
+
: parsed.data;
|
|
1124
1195
|
}
|
|
1125
1196
|
|
|
1126
1197
|
function isInlineImageContent(entry: unknown): boolean {
|
|
@@ -1130,7 +1201,7 @@ function isInlineImageContent(entry: unknown): boolean {
|
|
|
1130
1201
|
(record.type === "input_image" &&
|
|
1131
1202
|
typeof record.image === "string" &&
|
|
1132
1203
|
record.image.startsWith("data:image/")) ||
|
|
1133
|
-
(record.type === "image" &&
|
|
1204
|
+
(record.type === "image" && isDeclaredInlineMcpImage(record))
|
|
1134
1205
|
);
|
|
1135
1206
|
}
|
|
1136
1207
|
|
|
@@ -60,7 +60,6 @@ import {
|
|
|
60
60
|
import type { Context } from "@temporalio/activity";
|
|
61
61
|
import type { ControlActivityServices } from "./types";
|
|
62
62
|
import { rigProviderImageSourceImage } from "./sandbox-images";
|
|
63
|
-
import { resolveWorkspacePackRuntime, type WorkspacePackRuntime } from "./packs";
|
|
64
63
|
import { currentActivityContext } from "./streaming";
|
|
65
64
|
|
|
66
65
|
type RigSetupHook = typeof import("@opengeni/runtime").runRigSetupHook;
|
|
@@ -175,7 +174,7 @@ const RIG_VERIFICATION_HEARTBEAT_MIN_INTERVAL_MS = 250;
|
|
|
175
174
|
// lease-holder fiction or manual recovery.
|
|
176
175
|
export const RIG_VERIFICATION_OWNER_TTL_MS = 20 * 60_000;
|
|
177
176
|
export const RIG_VERIFICATION_OWNERS_DISABLED_MESSAGE =
|
|
178
|
-
"
|
|
177
|
+
"Sandbox Environment verification lease ownership is disabled; refusing to create an unowned verifier sandbox";
|
|
179
178
|
const RIG_VERIFICATION_HOLDER_TOUCH_INTERVAL_MS = 10_000;
|
|
180
179
|
const RIG_VERIFICATION_RELEASE_GRACE_MS = 1;
|
|
181
180
|
|
|
@@ -187,7 +186,7 @@ export class RigVerificationActivityDeadlineError extends Error {
|
|
|
187
186
|
readonly cleanupReserveMs: number,
|
|
188
187
|
) {
|
|
189
188
|
super(
|
|
190
|
-
`
|
|
189
|
+
`Sandbox Environment verification activity-local deadline reached with ${cleanupReserveMs}ms reserved for cleanup before the ${startToCloseTimeoutMs}ms Temporal start-to-close timeout`,
|
|
191
190
|
);
|
|
192
191
|
}
|
|
193
192
|
}
|
|
@@ -223,7 +222,9 @@ export function createRigVerificationActivityLifecycle(
|
|
|
223
222
|
const temporalSignal = context?.cancellationSignal;
|
|
224
223
|
const forwardTemporalCancellation = (): void => {
|
|
225
224
|
if (!controller.signal.aborted) {
|
|
226
|
-
controller.abort(
|
|
225
|
+
controller.abort(
|
|
226
|
+
temporalSignal?.reason ?? new Error("Sandbox Environment verification cancelled"),
|
|
227
|
+
);
|
|
227
228
|
}
|
|
228
229
|
};
|
|
229
230
|
if (temporalSignal?.aborted) {
|
|
@@ -308,7 +309,7 @@ export function createRigVerificationActivityLifecycle(
|
|
|
308
309
|
}
|
|
309
310
|
|
|
310
311
|
function abortReason(signal: AbortSignal): unknown {
|
|
311
|
-
return signal.reason ?? new Error("
|
|
312
|
+
return signal.reason ?? new Error("Sandbox Environment verification cancelled");
|
|
312
313
|
}
|
|
313
314
|
|
|
314
315
|
function throwIfAborted(signal: AbortSignal): void {
|
|
@@ -433,7 +434,9 @@ export class RigVerificationLeaseUnavailableError extends Error {
|
|
|
433
434
|
readonly sandboxGroupId: string,
|
|
434
435
|
readonly role: "attached" | "blocked" | "rearmed" | "fenced",
|
|
435
436
|
) {
|
|
436
|
-
super(
|
|
437
|
+
super(
|
|
438
|
+
`Sandbox Environment verification requires a new clean sandbox, but lease ${sandboxGroupId} was ${role}`,
|
|
439
|
+
);
|
|
437
440
|
}
|
|
438
441
|
}
|
|
439
442
|
|
|
@@ -490,7 +493,7 @@ export async function runWithOwnedRigVerificationSandbox<T>(
|
|
|
490
493
|
let establishmentPromise: Promise<EstablishedSandboxSession> | null = null;
|
|
491
494
|
|
|
492
495
|
const warnCleanupTimeout = (operation: string, instanceId: string | null): void => {
|
|
493
|
-
input.observability.warn("
|
|
496
|
+
input.observability.warn("sandbox environment verifier: ownership cleanup timed out", {
|
|
494
497
|
holderId,
|
|
495
498
|
instanceId,
|
|
496
499
|
operation,
|
|
@@ -504,7 +507,7 @@ export async function runWithOwnedRigVerificationSandbox<T>(
|
|
|
504
507
|
instanceId: string | null,
|
|
505
508
|
error: unknown,
|
|
506
509
|
): void => {
|
|
507
|
-
input.observability.warn("
|
|
510
|
+
input.observability.warn("sandbox environment verifier: ownership cleanup failed", {
|
|
508
511
|
holderId,
|
|
509
512
|
instanceId,
|
|
510
513
|
operation,
|
|
@@ -643,11 +646,14 @@ export async function runWithOwnedRigVerificationSandbox<T>(
|
|
|
643
646
|
);
|
|
644
647
|
} catch (error) {
|
|
645
648
|
if (!signal.aborted) {
|
|
646
|
-
input.observability.warn(
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
649
|
+
input.observability.warn(
|
|
650
|
+
"sandbox environment verifier: Modal ownership tag failed",
|
|
651
|
+
{
|
|
652
|
+
holderId,
|
|
653
|
+
instanceId: created.instanceId,
|
|
654
|
+
error: error instanceof Error ? error.message : String(error),
|
|
655
|
+
},
|
|
656
|
+
);
|
|
651
657
|
}
|
|
652
658
|
}
|
|
653
659
|
}
|
|
@@ -913,10 +919,12 @@ function rigProviderImageContentMarker(
|
|
|
913
919
|
markerRoot = "/var/opengeni",
|
|
914
920
|
): { marker: string; normalizedRoot: string } {
|
|
915
921
|
if (!/^sha256:[0-9a-f]{64}$/u.test(contentHash)) {
|
|
916
|
-
throw new Error(
|
|
922
|
+
throw new Error(
|
|
923
|
+
"Sandbox Environment provider image content marker requires a canonical SHA-256 value",
|
|
924
|
+
);
|
|
917
925
|
}
|
|
918
926
|
if (!/^\/[A-Za-z0-9._/-]+$/u.test(markerRoot)) {
|
|
919
|
-
throw new Error("
|
|
927
|
+
throw new Error("Sandbox Environment provider image marker root must be a safe absolute path");
|
|
920
928
|
}
|
|
921
929
|
const normalizedRoot = markerRoot.replace(/\/+$/u, "") || "/";
|
|
922
930
|
const marker = `${normalizedRoot === "/" ? "" : normalizedRoot}/rig-setup-content-${contentHash.slice("sha256:".length)}.done`;
|
|
@@ -978,7 +986,9 @@ export async function verifyRigProviderImageColdBoot(
|
|
|
978
986
|
runContext.commandRunner,
|
|
979
987
|
);
|
|
980
988
|
if (markerResult.exitCode !== 0) {
|
|
981
|
-
throw new Error(
|
|
989
|
+
throw new Error(
|
|
990
|
+
"built provider image is missing its exact sandbox environment-content marker",
|
|
991
|
+
);
|
|
982
992
|
}
|
|
983
993
|
for (const check of rigPlatformChecksForSettings(input.settings)) {
|
|
984
994
|
const result = await runCommand(
|
|
@@ -1083,7 +1093,7 @@ export async function buildVerifiedRigProviderImage(input: {
|
|
|
1083
1093
|
error: {
|
|
1084
1094
|
code: "provider_image_content_conflict",
|
|
1085
1095
|
message:
|
|
1086
|
-
"this exact
|
|
1096
|
+
"this exact sandbox environment version already records a provider image for different effective content; mint and verify a new version",
|
|
1087
1097
|
retryable: false,
|
|
1088
1098
|
},
|
|
1089
1099
|
};
|
|
@@ -1276,13 +1286,10 @@ export async function buildVerifiedRigProviderImage(input: {
|
|
|
1276
1286
|
|
|
1277
1287
|
export function settingsForRigVerification(
|
|
1278
1288
|
settings: ControlActivityServices["settings"],
|
|
1279
|
-
packRuntime: WorkspacePackRuntime,
|
|
1280
1289
|
rigImage: string | null,
|
|
1281
1290
|
): ControlActivityServices["settings"] {
|
|
1282
1291
|
// Rig verification must prove setup and provider-image materialization on
|
|
1283
|
-
// the deployment-owned platform base.
|
|
1284
|
-
// values are intentionally ignored here.
|
|
1285
|
-
void packRuntime;
|
|
1292
|
+
// the deployment-owned platform base. Historical Rig image values are ignored.
|
|
1286
1293
|
void rigImage;
|
|
1287
1294
|
return settings;
|
|
1288
1295
|
}
|
|
@@ -1294,18 +1301,18 @@ async function loadChangeTarget(
|
|
|
1294
1301
|
): Promise<{ rig: Rig; baseVersion: RigVersion; change: RigChange }> {
|
|
1295
1302
|
const change = await getRigChange(db, workspaceId, changeId);
|
|
1296
1303
|
if (!change) {
|
|
1297
|
-
throw new Error(`
|
|
1304
|
+
throw new Error(`Sandbox Environment change not found: ${changeId}`);
|
|
1298
1305
|
}
|
|
1299
1306
|
const rig = await getRig(db, workspaceId, change.rigId);
|
|
1300
1307
|
if (!rig) {
|
|
1301
|
-
throw new Error(`
|
|
1308
|
+
throw new Error(`Sandbox Environment not found for change: ${change.rigId}`);
|
|
1302
1309
|
}
|
|
1303
1310
|
if (!change.baseVersionId) {
|
|
1304
|
-
throw new Error(`
|
|
1311
|
+
throw new Error(`Sandbox Environment change ${change.id} has no base version`);
|
|
1305
1312
|
}
|
|
1306
1313
|
const baseVersion = await getRigVersionById(db, workspaceId, change.baseVersionId);
|
|
1307
1314
|
if (!baseVersion || baseVersion.rigId !== rig.id) {
|
|
1308
|
-
throw new Error(`Base
|
|
1315
|
+
throw new Error(`Base sandbox environment version not found: ${change.baseVersionId}`);
|
|
1309
1316
|
}
|
|
1310
1317
|
return { rig, baseVersion, change };
|
|
1311
1318
|
}
|
|
@@ -1317,11 +1324,11 @@ async function loadVersionTarget(
|
|
|
1317
1324
|
): Promise<{ rig: Rig; version: RigVersion }> {
|
|
1318
1325
|
const version = await getRigVersionById(db, workspaceId, versionId);
|
|
1319
1326
|
if (!version) {
|
|
1320
|
-
throw new Error(`
|
|
1327
|
+
throw new Error(`Sandbox Environment version not found: ${versionId}`);
|
|
1321
1328
|
}
|
|
1322
1329
|
const rig = await getRig(db, workspaceId, version.rigId);
|
|
1323
1330
|
if (!rig) {
|
|
1324
|
-
throw new Error(`
|
|
1331
|
+
throw new Error(`Sandbox Environment not found for version: ${version.rigId}`);
|
|
1325
1332
|
}
|
|
1326
1333
|
return { rig, version };
|
|
1327
1334
|
}
|
|
@@ -1373,12 +1380,7 @@ export function createRigVerificationActivities(services: () => Promise<ControlA
|
|
|
1373
1380
|
change,
|
|
1374
1381
|
candidateVersion,
|
|
1375
1382
|
);
|
|
1376
|
-
const
|
|
1377
|
-
const runSettings = settingsForRigVerification(
|
|
1378
|
-
settings,
|
|
1379
|
-
packRuntime,
|
|
1380
|
-
candidateVersion.image,
|
|
1381
|
-
);
|
|
1383
|
+
const runSettings = settingsForRigVerification(settings, candidateVersion.image);
|
|
1382
1384
|
const providerImageContentHash = rigProviderImageContentHash({
|
|
1383
1385
|
backend: runSettings.sandboxBackend,
|
|
1384
1386
|
sourceImage: rigProviderImageSourceImage(runSettings, runSettings.sandboxBackend),
|
|
@@ -1452,7 +1454,7 @@ export function createRigVerificationActivities(services: () => Promise<ControlA
|
|
|
1452
1454
|
);
|
|
1453
1455
|
if (markerResult.exitCode !== 0) {
|
|
1454
1456
|
throw new Error(
|
|
1455
|
-
`Failed to seal
|
|
1457
|
+
`Failed to seal sandbox environment provider image content marker: ${markerResult.output.slice(-2000)}`,
|
|
1456
1458
|
);
|
|
1457
1459
|
}
|
|
1458
1460
|
const platformCheckResults = await runRigChecks(
|
|
@@ -1572,8 +1574,7 @@ export function createRigVerificationActivities(services: () => Promise<ControlA
|
|
|
1572
1574
|
metadata: { versionId: version.id },
|
|
1573
1575
|
});
|
|
1574
1576
|
try {
|
|
1575
|
-
const
|
|
1576
|
-
const runSettings = settingsForRigVerification(settings, packRuntime, version.image);
|
|
1577
|
+
const runSettings = settingsForRigVerification(settings, version.image);
|
|
1577
1578
|
const providerImageContentHash = rigProviderImageContentHash({
|
|
1578
1579
|
backend: runSettings.sandboxBackend,
|
|
1579
1580
|
sourceImage: rigProviderImageSourceImage(runSettings, runSettings.sandboxBackend),
|
|
@@ -1615,7 +1616,7 @@ export function createRigVerificationActivities(services: () => Promise<ControlA
|
|
|
1615
1616
|
);
|
|
1616
1617
|
if (markerResult.exitCode !== 0) {
|
|
1617
1618
|
throw new Error(
|
|
1618
|
-
`Failed to seal
|
|
1619
|
+
`Failed to seal sandbox environment provider image content marker: ${markerResult.output.slice(-2000)}`,
|
|
1619
1620
|
);
|
|
1620
1621
|
}
|
|
1621
1622
|
const platformCheckResults = await runRigChecks(
|
|
@@ -28,6 +28,18 @@ export type RunCredentialRenewalOptions = {
|
|
|
28
28
|
}) => void;
|
|
29
29
|
};
|
|
30
30
|
|
|
31
|
+
export function runCredentialRenewalExpiry(
|
|
32
|
+
material: NormalizedRunCredentialMaterial | null,
|
|
33
|
+
): Date | null {
|
|
34
|
+
const expiries = [
|
|
35
|
+
...(material?.expiresAt ? [material.expiresAt.getTime()] : []),
|
|
36
|
+
...(material?.mcp ?? []).flatMap((entry) =>
|
|
37
|
+
entry.expiresAt ? [Date.parse(entry.expiresAt)] : [],
|
|
38
|
+
),
|
|
39
|
+
];
|
|
40
|
+
return expiries.length ? new Date(Math.min(...expiries)) : null;
|
|
41
|
+
}
|
|
42
|
+
|
|
31
43
|
export function nextRunCredentialRenewalDelay(expiresAt: Date | null, nowMs = Date.now()): number {
|
|
32
44
|
return nextExpiringMaterialRenewalDelay(
|
|
33
45
|
expiresAt,
|
|
@@ -52,7 +64,7 @@ export function startRunCredentialRenewalLoop(
|
|
|
52
64
|
initialExpiresAt: options.initialExpiresAt,
|
|
53
65
|
resolve: options.resolve,
|
|
54
66
|
write: options.write,
|
|
55
|
-
expiresAt:
|
|
67
|
+
expiresAt: runCredentialRenewalExpiry,
|
|
56
68
|
publicErrorClass: "RunCredentialRenewalOperationError",
|
|
57
69
|
policy: {
|
|
58
70
|
defaultRefreshMs: RUN_CREDENTIAL_DEFAULT_REFRESH_MS,
|