@opengeni/worker-bundle 1.0.1 → 2.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-turn/codex.d.ts +1 -1
- package/dist/activities/agent-turn/compaction-prep.d.ts +1 -5
- package/dist/activities/agent-turn/errors.d.ts +31 -5
- package/dist/activities/agent-turn/finalization-monitor.d.ts +17 -0
- package/dist/activities/agent-turn/finalization.d.ts +1 -1
- package/dist/activities/agent-turn/governance-model.d.ts +0 -2
- package/dist/activities/agent-turn/quiescence.d.ts +1 -0
- package/dist/activities/agent-turn/recovery-warning.d.ts +8 -0
- package/dist/activities/agent-turn/run-credentials.d.ts +0 -1
- package/dist/activities/agent-turn/sandbox-establish.d.ts +1 -1
- package/dist/activities/agent-turn/sandbox-route.d.ts +0 -20
- package/dist/activities/agent-turn/sandbox-runtime.d.ts +1 -1
- package/dist/activities/agent-turn/skill-remove.d.ts +14 -0
- package/dist/activities/agent-turn/skill-search.d.ts +1 -1
- package/dist/activities/agent-turn/stream-attempt.d.ts +1 -0
- package/dist/activities/agent-turn/tool-environment.d.ts +0 -4
- package/dist/activities/agent-turn/turn-context.d.ts +2 -0
- package/dist/activities/agent-turn/turn-sandbox-access.d.ts +3 -0
- package/dist/activities/codex-capacity.d.ts +6 -1
- package/dist/activities/codex-rotation.d.ts +1 -1
- package/dist/activities/context-compaction.d.ts +7 -1
- package/dist/activities/mcp-account-routes.d.ts +22 -0
- package/dist/activities/mcp-credentials.d.ts +12 -13
- package/dist/activities/mcp-operation-authority.d.ts +0 -5
- package/dist/activities/rig-verification.d.ts +2 -3
- package/dist/activities/sandbox-images.d.ts +1 -1
- package/dist/activities/sandbox-lease.d.ts +4 -3
- package/dist/activities/session-state.d.ts +57 -2
- package/dist/activities/types.d.ts +12 -3
- package/dist/{activities-control-HMFGSKC5.js → activities-control-BOLIY3H4.js} +366 -187
- package/dist/activities-control-BOLIY3H4.js.map +1 -0
- package/dist/activities-control.d.ts +110 -2
- package/dist/{activities-turn-AP67JADS.js → activities-turn-2B3WMHBB.js} +767 -471
- package/dist/activities-turn-2B3WMHBB.js.map +1 -0
- package/dist/activities.d.ts +110 -2
- package/dist/artifact-materializer-entry.js +5 -2
- package/dist/artifact-materializer-entry.js.map +1 -1
- package/dist/artifact-outbox-entry.js +2 -2
- package/dist/artifact-outbox-entry.js.map +1 -1
- package/dist/{chunk-A4XQWVZK.js → chunk-I7HKKMUJ.js} +77 -1
- package/dist/chunk-I7HKKMUJ.js.map +1 -0
- package/dist/{chunk-CYITU5UH.js → chunk-TVEE2UUC.js} +275 -146
- package/dist/chunk-TVEE2UUC.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/index.d.ts +55 -1
- package/dist/index.js +4 -3
- package/dist/index.js.map +1 -1
- package/dist/observability-metrics.d.ts +11 -3
- package/dist/retained-process-diagnostics.d.ts +4 -0
- package/dist/sandbox-resume.d.ts +2 -12
- package/dist/sandbox-routing.d.ts +5 -3
- package/dist/sandbox-snapshot-diagnostics.d.ts +20 -0
- package/dist/warm-capture-holder.d.ts +3 -0
- package/dist/workflow-bundle.js +51 -11
- package/package.json +15 -15
- package/src/activities/agent-turn/agent-build.ts +42 -5
- package/src/activities/agent-turn/claim.ts +12 -0
- package/src/activities/agent-turn/codex-capacity.ts +26 -4
- package/src/activities/agent-turn/codex.ts +6 -2
- package/src/activities/agent-turn/compaction-prep.ts +53 -72
- package/src/activities/agent-turn/errors.ts +98 -10
- package/src/activities/agent-turn/failure-settlement.ts +49 -28
- package/src/activities/agent-turn/finalization-monitor.ts +121 -0
- package/src/activities/agent-turn/finalization.ts +79 -21
- package/src/activities/agent-turn/governance-model.ts +15 -19
- package/src/activities/agent-turn/history.ts +24 -10
- package/src/activities/agent-turn/quiescence.ts +3 -0
- package/src/activities/agent-turn/recovery-warning.ts +18 -0
- package/src/activities/agent-turn/run-credentials.ts +3 -7
- package/src/activities/agent-turn/run.ts +68 -52
- package/src/activities/agent-turn/sandbox-establish.ts +10 -2
- package/src/activities/agent-turn/sandbox-route.ts +0 -20
- package/src/activities/agent-turn/sandbox-runtime.ts +40 -7
- 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 +1 -1
- package/src/activities/agent-turn/skill-selection.ts +2 -0
- package/src/activities/agent-turn/skill-tools.ts +10 -5
- package/src/activities/agent-turn/stream-attempt.ts +38 -15
- package/src/activities/agent-turn/tool-environment.ts +44 -29
- package/src/activities/agent-turn/turn-context.ts +3 -0
- package/src/activities/agent-turn/turn-sandbox-access.ts +7 -1
- package/src/activities/capabilities.ts +17 -2
- package/src/activities/codex-capacity.ts +38 -9
- package/src/activities/codex-rotation.ts +18 -5
- package/src/activities/context-compaction.ts +26 -4
- package/src/activities/goals.ts +1 -0
- package/src/activities/google-drive-publication.ts +1 -3
- package/src/activities/mcp-account-routes.ts +139 -0
- package/src/activities/mcp-credentials.ts +83 -194
- package/src/activities/mcp-operation-authority.ts +16 -41
- package/src/activities/parent-wake.ts +8 -0
- package/src/activities/rig-verification.ts +38 -37
- package/src/activities/run-input.ts +25 -16
- package/src/activities/sandbox-images.ts +0 -1
- package/src/activities/sandbox-lease.ts +177 -44
- package/src/activities/scheduled-tasks.ts +118 -93
- package/src/activities/session-state.ts +83 -3
- package/src/activities/types.ts +18 -2
- package/src/activities/workflow-wake.ts +2 -17
- package/src/editable-artifact-materializer-service.ts +7 -3
- package/src/editable-artifact-outbox-service.ts +4 -4
- package/src/github-rest-mcp.ts +0 -1
- package/src/index.ts +2 -1
- package/src/observability-metrics.ts +105 -2
- package/src/personal-github-git-credentials.ts +0 -1
- package/src/pr-review-credentials.ts +0 -2
- package/src/retained-process-diagnostics.ts +50 -0
- package/src/sandbox-resume.ts +58 -73
- package/src/sandbox-routing.ts +44 -19
- package/src/sandbox-snapshot-diagnostics.ts +112 -0
- package/src/warm-capture-holder.ts +15 -0
- package/src/workflows/session.ts +64 -2
- 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/src/activities/agent-turn/knowledge-sources.ts +0 -86
- package/src/activities/packs.ts +0 -166
|
@@ -1,23 +1,18 @@
|
|
|
1
1
|
import { createHash } from "node:crypto";
|
|
2
2
|
import { stableJson } from "@opengeni/contracts";
|
|
3
3
|
import type { ConnectionUseAttribution } from "@opengeni/contracts/connection-authority";
|
|
4
|
-
import type { HostMcpAcceptedAuthority } from "@opengeni/contracts/host-mcp-bindings";
|
|
5
4
|
import type { ResolveConnectionCredentialInput } from "@opengeni/db";
|
|
6
5
|
|
|
7
6
|
/** Metadata only. Callers must obtain authority from a current live fence.
|
|
8
7
|
* This equality key is never authorization and never replaces physical-use checks. */
|
|
9
8
|
export function mcpOperationAuthorityDigest(
|
|
10
9
|
request: ResolveConnectionCredentialInput,
|
|
11
|
-
authority:
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
principal?: { kind: string; subjectId?: string };
|
|
16
|
-
}
|
|
17
|
-
| { host: HostMcpAcceptedAuthority; native?: never },
|
|
10
|
+
authority: {
|
|
11
|
+
native: ConnectionUseAttribution;
|
|
12
|
+
principal?: { kind: string; subjectId?: string };
|
|
13
|
+
},
|
|
18
14
|
): string {
|
|
19
15
|
const n = authority.native;
|
|
20
|
-
const h = authority.host;
|
|
21
16
|
const ref = request.connectionRef;
|
|
22
17
|
const metadata = {
|
|
23
18
|
version: 1,
|
|
@@ -31,7 +26,6 @@ export function mcpOperationAuthorityDigest(
|
|
|
31
26
|
providerDomain: ref.providerDomain,
|
|
32
27
|
kind: ref.kind,
|
|
33
28
|
subjectScope: ref.subjectScope,
|
|
34
|
-
hostBinding: ref.hostBinding,
|
|
35
29
|
scopes: ref.scopes ? [...ref.scopes].sort() : undefined,
|
|
36
30
|
resource: ref.resource,
|
|
37
31
|
selectedResources: ref.selectedResources
|
|
@@ -40,37 +34,18 @@ export function mcpOperationAuthorityDigest(
|
|
|
40
34
|
)
|
|
41
35
|
: undefined,
|
|
42
36
|
},
|
|
43
|
-
native:
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
}
|
|
56
|
-
: undefined,
|
|
57
|
-
host: h
|
|
58
|
-
? {
|
|
59
|
-
accountId: h.accountId,
|
|
60
|
-
workspaceId: h.workspaceId,
|
|
61
|
-
targetSessionId: h.targetSessionId,
|
|
62
|
-
targetSessionVisibility: h.targetSessionVisibility,
|
|
63
|
-
targetSessionAuthorityEpoch: h.targetSessionAuthorityEpoch,
|
|
64
|
-
ownerSubjectId: h.ownerSubjectId,
|
|
65
|
-
ownerOrganizationMembershipId: h.ownerOrganizationMembershipId,
|
|
66
|
-
ownerMembershipAuthorizationRevision: h.ownerMembershipAuthorizationRevision,
|
|
67
|
-
bindingId: h.bindingId,
|
|
68
|
-
bindingGeneration: h.bindingGeneration,
|
|
69
|
-
definition: h.definition,
|
|
70
|
-
delegationId: h.delegationId,
|
|
71
|
-
delegationGeneration: h.delegationGeneration,
|
|
72
|
-
}
|
|
73
|
-
: undefined,
|
|
37
|
+
native: {
|
|
38
|
+
organizationId: n.organizationId,
|
|
39
|
+
workspaceId: n.workspaceId,
|
|
40
|
+
sessionId: n.sessionId,
|
|
41
|
+
connectionId: n.connectionId,
|
|
42
|
+
connectionGeneration: n.connectionGeneration,
|
|
43
|
+
scope: n.scope,
|
|
44
|
+
ownerSubjectId: n.ownerSubjectId,
|
|
45
|
+
authorityId: n.authorityId,
|
|
46
|
+
grantId: n.grantId,
|
|
47
|
+
principal: authority.principal,
|
|
48
|
+
},
|
|
74
49
|
};
|
|
75
50
|
return createHash("sha256").update(stableJson(metadata)).digest("hex");
|
|
76
51
|
}
|
|
@@ -4,6 +4,7 @@ import {
|
|
|
4
4
|
getSession,
|
|
5
5
|
getSessionGoal,
|
|
6
6
|
getSessionParentPersonalConnectionDelegations,
|
|
7
|
+
getSessionParentMcpAccountBindings,
|
|
7
8
|
getSessionParentXaiProviderAccountAuthority,
|
|
8
9
|
addSessionSystemUpdateWithSourceMutation,
|
|
9
10
|
claimPendingSessionSystemUpdateOutbox,
|
|
@@ -75,6 +76,11 @@ export async function notifyParentOfChildIdle(
|
|
|
75
76
|
workspaceId,
|
|
76
77
|
childSessionId,
|
|
77
78
|
);
|
|
79
|
+
const mcpAccountBindings = await getSessionParentMcpAccountBindings(
|
|
80
|
+
svc.db,
|
|
81
|
+
workspaceId,
|
|
82
|
+
childSessionId,
|
|
83
|
+
);
|
|
78
84
|
const xaiAuthority = await getSessionParentXaiProviderAccountAuthority(
|
|
79
85
|
svc.db,
|
|
80
86
|
workspaceId,
|
|
@@ -97,6 +103,7 @@ export async function notifyParentOfChildIdle(
|
|
|
97
103
|
...(xaiAuthority.subjectId ? { xaiAuthoritySubjectId: xaiAuthority.subjectId } : {}),
|
|
98
104
|
},
|
|
99
105
|
personalConnectionDelegations,
|
|
106
|
+
mcpAccountBindings,
|
|
100
107
|
xaiProviderAccountAuthoritySnapshot: xaiAuthority.snapshot,
|
|
101
108
|
});
|
|
102
109
|
if (outbox.status === "delivered") {
|
|
@@ -214,6 +221,7 @@ async function deliverParentSystemUpdateOutbox(
|
|
|
214
221
|
summary: outbox.summary,
|
|
215
222
|
lineage: outbox.lineage,
|
|
216
223
|
personalConnectionDelegations: outbox.personalConnectionDelegations,
|
|
224
|
+
mcpAccountBindings: outbox.mcpAccountBindings,
|
|
217
225
|
xaiProviderAccountAuthoritySnapshot: outbox.xaiProviderAccountAuthoritySnapshot,
|
|
218
226
|
},
|
|
219
227
|
async (tx) => {
|
|
@@ -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(
|
|
@@ -304,19 +304,13 @@ function attachmentRefsFromItem(item: Record<string, unknown>): FileResourceRef[
|
|
|
304
304
|
return refs;
|
|
305
305
|
}
|
|
306
306
|
|
|
307
|
-
function attachmentReceiptText(ref: FileResourceRef
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
`[Earlier attachment: fileId=${ref.fileId}; mountDirectory=${resourceMountPath(ref)}. ` +
|
|
311
|
-
`Use the existing file there, or call files__files_get_download_url with this fileId and ` +
|
|
312
|
-
`download it with the shell.]`
|
|
313
|
-
);
|
|
314
|
-
}
|
|
315
|
-
const path = sandboxFilePath(ref, file);
|
|
307
|
+
function attachmentReceiptText(ref: FileResourceRef): string {
|
|
308
|
+
// The durable reference is immutable; live metadata/authority must not rewrite
|
|
309
|
+
// old receipt text. Pixel delivery remains subject to current file authority.
|
|
316
310
|
return (
|
|
317
|
-
`[Attachment:
|
|
318
|
-
`
|
|
319
|
-
`
|
|
311
|
+
`[Attachment: fileId=${ref.fileId}; mountDirectory=${resourceMountPath(ref)}. ` +
|
|
312
|
+
`Use the existing file there, or call files__files_get_download_url with this fileId and ` +
|
|
313
|
+
`download it with the shell.]`
|
|
320
314
|
);
|
|
321
315
|
}
|
|
322
316
|
|
|
@@ -434,7 +428,7 @@ export function createModelHistoryAttachmentProjector(
|
|
|
434
428
|
const attachment = currentFile ? contentById.get(ref.fileId) : undefined;
|
|
435
429
|
const receipt = {
|
|
436
430
|
type: "input_text",
|
|
437
|
-
text: attachmentReceiptText(ref
|
|
431
|
+
text: attachmentReceiptText(ref),
|
|
438
432
|
};
|
|
439
433
|
if (!attachment || attachment.kind !== "image") {
|
|
440
434
|
return [receipt];
|
|
@@ -458,12 +452,21 @@ export function withCurrentUserAttachmentRefs(
|
|
|
458
452
|
refs: FileResourceRef[],
|
|
459
453
|
): Array<Record<string, unknown>> {
|
|
460
454
|
if (refs.length === 0) return historyItems;
|
|
455
|
+
// Compaction can put a catalog after the triggering user message. A ref
|
|
456
|
+
// already retained anywhere in canonical history must not be copied onto
|
|
457
|
+
// that older catalog (and then disappear when the next turn replays it).
|
|
458
|
+
const retainedIds = new Set(
|
|
459
|
+
historyItems.flatMap((item) => attachmentRefsFromItem(item).map((ref) => ref.fileId)),
|
|
460
|
+
);
|
|
461
|
+
const missing = refs.filter((ref) => !retainedIds.has(ref.fileId));
|
|
462
|
+
if (missing.length === 0) return historyItems;
|
|
461
463
|
for (let index = historyItems.length - 1; index >= 0; index -= 1) {
|
|
462
464
|
const item = historyItems[index]!;
|
|
465
|
+
if (item[MODEL_ATTACHMENT_CATALOG_MARKER] === true) continue;
|
|
463
466
|
if (item.type !== "message" || item.role !== "user") continue;
|
|
464
467
|
const existing = attachmentRefsFromItem(item);
|
|
465
468
|
const existingIds = new Set(existing.map((ref) => ref.fileId));
|
|
466
|
-
const additions =
|
|
469
|
+
const additions = missing.filter((ref) => !existingIds.has(ref.fileId));
|
|
467
470
|
if (additions.length === 0) return historyItems;
|
|
468
471
|
const projected = [...historyItems];
|
|
469
472
|
projected[index] = { ...item, [MODEL_ATTACHMENT_REFS_FIELD]: [...existing, ...additions] };
|
|
@@ -552,8 +555,14 @@ export async function turnInput(
|
|
|
552
555
|
options,
|
|
553
556
|
);
|
|
554
557
|
}
|
|
555
|
-
|
|
556
|
-
|
|
558
|
+
// Maintenance has no user message or delivered-update batch. It still needs
|
|
559
|
+
// the ordinary history/projection path so SDK preparation can capture the
|
|
560
|
+
// same model request prefix before the queued compaction stops inference.
|
|
561
|
+
if (
|
|
562
|
+
trigger.type === "system.update.delivered" ||
|
|
563
|
+
trigger.type === "session.context.compaction.requested"
|
|
564
|
+
) {
|
|
565
|
+
if (trigger.type === "system.update.delivered" && updates.length === 0) {
|
|
557
566
|
throw new Error("Internal update inference has no delivered updates");
|
|
558
567
|
}
|
|
559
568
|
return await messageInput(
|