@opengeni/worker-bundle 2.3.1 → 2.3.2-canary.37111190284001
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/claude-usage-observer.d.ts +30 -6
- package/dist/activities/agent-turn/credential-leases.d.ts +5 -32
- package/dist/activities/agent-turn/errors.d.ts +3 -0
- package/dist/activities/agent-turn/finalization-monitor.d.ts +1 -1
- package/dist/activities/agent-turn/finalization.d.ts +2 -0
- package/dist/activities/agent-turn/quiescence.d.ts +3 -4
- package/dist/activities/agent-turn/subscription-lease.d.ts +38 -0
- package/dist/activities/agent-turn/turn-context.d.ts +1 -1
- package/dist/activities/model-call-fact-reconciler.d.ts +34 -0
- package/dist/activities/open-suffix-resume.d.ts +13 -0
- package/dist/activities/session-state.d.ts +2 -2
- package/dist/activities/types.d.ts +7 -0
- package/dist/{activities-control-3HAH4FMG.js → activities-control-3BY4IJKL.js} +166 -35
- package/dist/activities-control-3BY4IJKL.js.map +1 -0
- package/dist/activities-control.d.ts +6 -4
- package/dist/{activities-turn-KU25J3VQ.js → activities-turn-E3EA7FPS.js} +270 -308
- package/dist/activities-turn-E3EA7FPS.js.map +1 -0
- package/dist/activities.d.ts +6 -4
- package/dist/{chunk-3K3ULWEE.js → chunk-PA7Z55P4.js} +242 -17
- package/dist/chunk-PA7Z55P4.js.map +1 -0
- package/dist/{chunk-YG27NEMX.js → chunk-YOI3Z3GF.js} +9 -1
- package/dist/chunk-YOI3Z3GF.js.map +1 -0
- package/dist/http.d.ts +1 -1
- package/dist/index.d.ts +6 -2
- package/dist/index.js +82 -16
- package/dist/index.js.map +1 -1
- package/dist/observability-metrics.d.ts +6 -1
- package/dist/sandbox-resume.d.ts +3 -0
- package/dist/session-event-fanout.d.ts +6 -0
- package/dist/worker-service-lifecycle.d.ts +12 -0
- package/dist/workflow-bundle.js +3 -2
- package/package.json +21 -21
- package/src/activities/agent-turn/claim.ts +13 -0
- package/src/activities/agent-turn/claude-usage-observer.ts +99 -8
- package/src/activities/agent-turn/credential-leases.ts +86 -213
- package/src/activities/agent-turn/errors.ts +61 -1
- package/src/activities/agent-turn/failure-settlement.ts +59 -5
- package/src/activities/agent-turn/finalization-monitor.ts +3 -4
- package/src/activities/agent-turn/finalization.ts +8 -3
- package/src/activities/agent-turn/quiescence.ts +3 -4
- package/src/activities/agent-turn/run.ts +24 -20
- package/src/activities/agent-turn/sandbox-establish.ts +2 -0
- package/src/activities/agent-turn/sandbox-runtime.ts +5 -1
- package/src/activities/agent-turn/skill-selection.ts +2 -0
- package/src/activities/agent-turn/subscription-lease.ts +115 -0
- package/src/activities/agent-turn/turn-context.ts +1 -4
- package/src/activities/codex-rotation.ts +2 -12
- package/src/activities/model-call-fact-reconciler.ts +112 -0
- package/src/activities/open-suffix-resume.ts +13 -1
- package/src/activities/sandbox-lease.ts +59 -8
- package/src/activities/session-state.ts +29 -4
- package/src/activities/types.ts +7 -0
- package/src/activities-control.ts +2 -0
- package/src/activities-turn.ts +5 -0
- package/src/activities.ts +7 -0
- package/src/http.ts +4 -2
- package/src/index.ts +39 -9
- package/src/observability-metrics.ts +27 -0
- package/src/sandbox-resume.ts +9 -0
- package/src/sandbox-routing.ts +77 -0
- package/src/session-event-fanout.ts +23 -0
- package/src/worker-service-lifecycle.ts +53 -0
- package/src/workflows/file-upload-reaper.ts +2 -0
- package/src/workflows/session.ts +6 -1
- package/dist/activities-control-3HAH4FMG.js.map +0 -1
- package/dist/activities-turn-KU25J3VQ.js.map +0 -1
- package/dist/chunk-3K3ULWEE.js.map +0 -1
- package/dist/chunk-YG27NEMX.js.map +0 -1
|
@@ -4,6 +4,7 @@ import {
|
|
|
4
4
|
PostCompactionContinuationEmptyError,
|
|
5
5
|
SandboxDeadlineRotationError,
|
|
6
6
|
agentRunFailurePayload,
|
|
7
|
+
agentRunRecoveryFailurePayload,
|
|
7
8
|
armAndReconcileCodexCapacityWait,
|
|
8
9
|
armTurnQuiescenceWatchdog,
|
|
9
10
|
assertAgentStreamNotCancelled,
|
|
@@ -31,6 +32,7 @@ import {
|
|
|
31
32
|
compactionFailureReasonFromError,
|
|
32
33
|
compactionFailureTurnEventPayload,
|
|
33
34
|
computeIdleDelayMs,
|
|
35
|
+
createClaudeUsageObserver,
|
|
34
36
|
createFreshSandboxReadinessReplacementBudget,
|
|
35
37
|
createKnowledgeSourceSyncActivities,
|
|
36
38
|
createModelHistoryAttachmentProjector,
|
|
@@ -95,7 +97,7 @@ import {
|
|
|
95
97
|
withFirstPartyTools,
|
|
96
98
|
wrapLazyTurnBoxWithRouting,
|
|
97
99
|
wrapTurnBoxWithRouting
|
|
98
|
-
} from "./chunk-
|
|
100
|
+
} from "./chunk-PA7Z55P4.js";
|
|
99
101
|
import {
|
|
100
102
|
StreamTimingMetrics,
|
|
101
103
|
makeMachineOpObserver,
|
|
@@ -127,7 +129,7 @@ import {
|
|
|
127
129
|
runtimeMetricsHooksForObservability,
|
|
128
130
|
sandboxAutomaticRecoveryOutcome,
|
|
129
131
|
turnLifecycleMetricsFor
|
|
130
|
-
} from "./chunk-
|
|
132
|
+
} from "./chunk-YOI3Z3GF.js";
|
|
131
133
|
import {
|
|
132
134
|
__export
|
|
133
135
|
} from "./chunk-PZ5AY32C.js";
|
|
@@ -183,82 +185,6 @@ import {
|
|
|
183
185
|
import { codexUpstreamModelSlugs } from "@opengeni/config";
|
|
184
186
|
import { parseModelProvidersJson } from "@opengeni/config";
|
|
185
187
|
import { withClaudeUsageObserver } from "@opengeni/runtime";
|
|
186
|
-
|
|
187
|
-
// src/activities/agent-turn/claude-usage-observer.ts
|
|
188
|
-
import {
|
|
189
|
-
emptyClaudeUsage,
|
|
190
|
-
mergeClaudeUsage,
|
|
191
|
-
parseClaudeUsageHeaders
|
|
192
|
-
} from "@opengeni/config";
|
|
193
|
-
async function createClaudeUsageObserver(providers, latest, readCredential) {
|
|
194
|
-
const bindings = await Promise.all(
|
|
195
|
-
providers.filter(
|
|
196
|
-
(provider) => provider.kind === "claude-subscription-workspace" || provider.kind === "claude-subscription-organization"
|
|
197
|
-
).map(async (provider) => {
|
|
198
|
-
const scope = provider.kind === "claude-subscription-workspace" ? "workspace" : "organization";
|
|
199
|
-
const binding = provider.anthropic?.credentialBinding;
|
|
200
|
-
if (binding && provider.apiKey)
|
|
201
|
-
return [
|
|
202
|
-
provider.id,
|
|
203
|
-
{
|
|
204
|
-
scope,
|
|
205
|
-
token: provider.apiKey,
|
|
206
|
-
expectedConnectionId: binding.connectionId,
|
|
207
|
-
expectedCredentialVersion: binding.credentialVersion
|
|
208
|
-
}
|
|
209
|
-
];
|
|
210
|
-
const credential = await readCredential(scope).catch(() => null);
|
|
211
|
-
if (!credential || credential.token !== provider.apiKey) return null;
|
|
212
|
-
return [
|
|
213
|
-
provider.id,
|
|
214
|
-
{
|
|
215
|
-
scope,
|
|
216
|
-
token: credential.token,
|
|
217
|
-
expectedConnectionId: credential.connectionId,
|
|
218
|
-
expectedCredentialVersion: credential.credentialVersion
|
|
219
|
-
}
|
|
220
|
-
];
|
|
221
|
-
})
|
|
222
|
-
);
|
|
223
|
-
const captured = new Map(bindings.filter((binding) => binding !== null));
|
|
224
|
-
const observe2 = (providerId, response) => {
|
|
225
|
-
const binding = captured.get(providerId);
|
|
226
|
-
if (!binding) return;
|
|
227
|
-
const { scope, ...identity } = binding;
|
|
228
|
-
const previous = latest.get(scope);
|
|
229
|
-
let observation = parseClaudeUsageHeaders(response.headers);
|
|
230
|
-
if (observation && previous?.observation) {
|
|
231
|
-
const merged = mergeClaudeUsage(
|
|
232
|
-
mergeClaudeUsage(emptyClaudeUsage(binding.expectedCredentialVersion), previous.observation),
|
|
233
|
-
observation
|
|
234
|
-
);
|
|
235
|
-
observation = {
|
|
236
|
-
windows: merged.windows,
|
|
237
|
-
observedAt: merged.observedAt,
|
|
238
|
-
source: merged.source
|
|
239
|
-
};
|
|
240
|
-
}
|
|
241
|
-
if (observation || response.status === 401)
|
|
242
|
-
latest.set(scope, {
|
|
243
|
-
...identity,
|
|
244
|
-
...previous?.observation && !observation ? { observation: previous.observation } : {},
|
|
245
|
-
...observation ? { observation } : {},
|
|
246
|
-
...response.status === 401 ? { refresh: { status: "reconnect", checkedAt: (/* @__PURE__ */ new Date()).toISOString() } } : {}
|
|
247
|
-
});
|
|
248
|
-
};
|
|
249
|
-
return Object.assign(observe2, {
|
|
250
|
-
binding(providerId) {
|
|
251
|
-
return captured.get(providerId);
|
|
252
|
-
},
|
|
253
|
-
renew(providerId, credential) {
|
|
254
|
-
const binding = captured.get(providerId);
|
|
255
|
-
if (binding && binding.expectedConnectionId === credential.connectionId && binding.expectedCredentialVersion === credential.credentialVersion)
|
|
256
|
-
captured.set(providerId, { ...binding, token: credential.token });
|
|
257
|
-
}
|
|
258
|
-
});
|
|
259
|
-
}
|
|
260
|
-
|
|
261
|
-
// src/activities/agent-turn/run.ts
|
|
262
188
|
import {
|
|
263
189
|
xaiSubscriptionRequestStorage
|
|
264
190
|
} from "@opengeni/xai-subscription";
|
|
@@ -1261,161 +1187,72 @@ import {
|
|
|
1261
1187
|
heartbeatXaiCredentialLeaseUntil
|
|
1262
1188
|
} from "@opengeni/db";
|
|
1263
1189
|
|
|
1264
|
-
// src/activities/agent-turn/
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
return createHash2("sha256").update(workspaceId).digest("hex").slice(0, 12);
|
|
1272
|
-
}
|
|
1273
|
-
function acceptsPromptCacheKeyForTurn(resolvedModel) {
|
|
1274
|
-
if (!resolvedModel) {
|
|
1275
|
-
return true;
|
|
1276
|
-
}
|
|
1277
|
-
return resolvedModel.provider.builtin === true || resolvedModel.provider.kind === "codex-subscription" || // Native Claude consumes this internal key as session identity; it never
|
|
1278
|
-
// sends OpenAI's prompt_cache_key field to the Messages endpoint.
|
|
1279
|
-
resolvedModel.provider.api === "anthropic-messages";
|
|
1280
|
-
}
|
|
1281
|
-
async function refreshCappedCodexUsageRows(db, settings, workspaceId, accounts, capacitySignals, acceptedTurnId) {
|
|
1282
|
-
const now = /* @__PURE__ */ new Date();
|
|
1283
|
-
const stale = accounts.filter(
|
|
1284
|
-
(account) => account.status === "active" && codexAccountNeedsLiveCapacityRefresh(account, now)
|
|
1285
|
-
);
|
|
1286
|
-
if (stale.length === 0) {
|
|
1287
|
-
return accounts;
|
|
1288
|
-
}
|
|
1289
|
-
await refreshCodexUsageAndRepairCapacityWaiters(
|
|
1290
|
-
stale.map(
|
|
1291
|
-
(account) => () => fetchCodexUsageForAccount(db, settings, workspaceId, account.id, void 0, acceptedTurnId)
|
|
1292
|
-
),
|
|
1293
|
-
() => signalPendingCodexCapacityWakeTargets({ db, ...capacitySignals }, workspaceId)
|
|
1294
|
-
);
|
|
1295
|
-
return listCodexAccountStatuses(db, workspaceId, acceptedTurnId).catch(() => accounts);
|
|
1296
|
-
}
|
|
1297
|
-
function codexCredentialLeaseDeadlineExpired(confirmedUntilMs, nowMs = performance.now()) {
|
|
1298
|
-
return confirmedUntilMs === null || !Number.isFinite(confirmedUntilMs) || confirmedUntilMs <= nowMs;
|
|
1299
|
-
}
|
|
1300
|
-
|
|
1301
|
-
// src/activities/agent-turn/credential-leases.ts
|
|
1302
|
-
var CodexCredentialLeaseLostError = class extends Error {
|
|
1303
|
-
constructor(reason) {
|
|
1304
|
-
super("Codex credential lease is not usable for provider dispatch");
|
|
1305
|
-
this.reason = reason;
|
|
1306
|
-
this.name = "CodexCredentialLeaseLostError";
|
|
1307
|
-
}
|
|
1308
|
-
code = "codex_credential_lease_lost";
|
|
1309
|
-
};
|
|
1310
|
-
var CodexTurnLease = class {
|
|
1311
|
-
constructor(deps) {
|
|
1312
|
-
this.deps = deps;
|
|
1190
|
+
// src/activities/agent-turn/subscription-lease.ts
|
|
1191
|
+
var SubscriptionTurnLease = class {
|
|
1192
|
+
constructor(leaseDeps) {
|
|
1193
|
+
this.leaseDeps = leaseDeps;
|
|
1194
|
+
if (!Number.isFinite(leaseDeps.ttlMs) || leaseDeps.ttlMs <= 0)
|
|
1195
|
+
throw new Error("Subscription lease TTL must be positive");
|
|
1196
|
+
this.now = leaseDeps.now ?? (() => performance.now());
|
|
1313
1197
|
}
|
|
1314
1198
|
held = false;
|
|
1315
1199
|
lost = false;
|
|
1316
1200
|
lossReason = null;
|
|
1317
1201
|
holderId = null;
|
|
1318
1202
|
generation = null;
|
|
1319
|
-
// Monotonic worker deadline, not a comparison between the Postgres and
|
|
1320
|
-
// worker wall clocks. It is advanced only after a database renewal confirms,
|
|
1321
|
-
// from the request START + TTL; slow queries therefore shorten (never extend)
|
|
1322
|
-
// the conservative ownership window.
|
|
1323
1203
|
confirmedUntilMs = null;
|
|
1324
1204
|
heartbeatInFlight = false;
|
|
1325
1205
|
heartbeatTimer;
|
|
1206
|
+
now;
|
|
1207
|
+
expired = (deadline) => deadline === null || !Number.isFinite(deadline) || this.now() >= deadline;
|
|
1326
1208
|
markLost = (reason) => {
|
|
1327
1209
|
if (this.lost) return;
|
|
1328
1210
|
this.lost = true;
|
|
1329
1211
|
this.lossReason = reason;
|
|
1330
|
-
this.
|
|
1331
|
-
name: "opengeni_codex_lease_renewals_total",
|
|
1332
|
-
help: "Codex lease renewal checkpoints by outcome and reason.",
|
|
1333
|
-
labels: { workspace_key: this.deps.codexWorkspaceKey, outcome: "lost", reason }
|
|
1334
|
-
});
|
|
1335
|
-
this.deps.observability.warn("Codex credential lease was lost during an active turn", {
|
|
1336
|
-
workspaceId: this.deps.workspaceId,
|
|
1337
|
-
turnId: this.deps.getTurnId(),
|
|
1338
|
-
reason
|
|
1339
|
-
});
|
|
1212
|
+
this.leaseDeps.onLost(reason);
|
|
1340
1213
|
};
|
|
1341
|
-
/** Fail closed at the last worker-confirmed lease deadline before dispatch. */
|
|
1342
1214
|
assertUsable = () => {
|
|
1343
|
-
if (this.lost)
|
|
1344
|
-
|
|
1345
|
-
}
|
|
1346
|
-
if (!this.held || this.holderId === null || this.generation === null || codexCredentialLeaseDeadlineExpired(this.confirmedUntilMs)) {
|
|
1215
|
+
if (this.lost) throw this.leaseDeps.lostError(this.lossReason ?? "not_found");
|
|
1216
|
+
if (!this.held || this.holderId === null || this.generation === null || this.expired(this.confirmedUntilMs)) {
|
|
1347
1217
|
this.markLost("deadline");
|
|
1348
|
-
throw
|
|
1218
|
+
throw this.leaseDeps.lostError("deadline");
|
|
1349
1219
|
}
|
|
1350
1220
|
};
|
|
1351
|
-
renew = async (reason) => {
|
|
1352
|
-
const turnId = this.
|
|
1353
|
-
if (!turnId || !this.held || !this.holderId || this.generation === null || this.lost)
|
|
1354
|
-
|
|
1355
|
-
}
|
|
1356
|
-
if (codexCredentialLeaseDeadlineExpired(this.confirmedUntilMs)) {
|
|
1221
|
+
renew = async (reason = "timer") => {
|
|
1222
|
+
const turnId = this.leaseDeps.getTurnId();
|
|
1223
|
+
if (!turnId || !this.held || !this.holderId || this.generation === null || this.lost) return;
|
|
1224
|
+
if (this.expired(this.confirmedUntilMs)) {
|
|
1357
1225
|
this.markLost("deadline");
|
|
1358
1226
|
return;
|
|
1359
1227
|
}
|
|
1360
1228
|
if (this.heartbeatInFlight) return;
|
|
1361
1229
|
this.heartbeatInFlight = true;
|
|
1362
|
-
const
|
|
1363
|
-
const
|
|
1230
|
+
const priorDeadline = this.confirmedUntilMs;
|
|
1231
|
+
const startedAt = this.now();
|
|
1232
|
+
const identity = { turnId, holderId: this.holderId, generation: this.generation };
|
|
1364
1233
|
try {
|
|
1365
|
-
const renewedUntil = await
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
this.holderId,
|
|
1371
|
-
this.generation,
|
|
1372
|
-
CODEX_CREDENTIAL_LEASE_TTL_MS
|
|
1373
|
-
);
|
|
1374
|
-
if (!renewedUntil) {
|
|
1375
|
-
this.markLost("not_found");
|
|
1376
|
-
} else if (codexCredentialLeaseDeadlineExpired(priorConfirmedUntilMs) || codexCredentialLeaseDeadlineExpired(renewalStartedAtMs + CODEX_CREDENTIAL_LEASE_TTL_MS)) {
|
|
1234
|
+
const renewedUntil = await this.leaseDeps.heartbeat(identity);
|
|
1235
|
+
if (!this.held || this.lost || this.leaseDeps.getTurnId() !== identity.turnId || this.holderId !== identity.holderId || this.generation !== identity.generation)
|
|
1236
|
+
return;
|
|
1237
|
+
if (!renewedUntil) this.markLost("not_found");
|
|
1238
|
+
else if (this.expired(priorDeadline) || this.expired(startedAt + this.leaseDeps.ttlMs))
|
|
1377
1239
|
this.markLost("deadline");
|
|
1378
|
-
|
|
1379
|
-
this.confirmedUntilMs =
|
|
1380
|
-
this.
|
|
1381
|
-
name: "opengeni_codex_lease_renewals_total",
|
|
1382
|
-
help: "Codex lease renewal checkpoints by outcome and reason.",
|
|
1383
|
-
labels: {
|
|
1384
|
-
workspace_key: this.deps.codexWorkspaceKey,
|
|
1385
|
-
outcome: "completed",
|
|
1386
|
-
reason
|
|
1387
|
-
}
|
|
1388
|
-
});
|
|
1240
|
+
else {
|
|
1241
|
+
this.confirmedUntilMs = startedAt + this.leaseDeps.ttlMs;
|
|
1242
|
+
this.leaseDeps.onRenewed?.(reason);
|
|
1389
1243
|
}
|
|
1390
1244
|
} catch (error51) {
|
|
1391
|
-
if (
|
|
1392
|
-
this.markLost("deadline");
|
|
1245
|
+
if (!this.held || this.lost || this.leaseDeps.getTurnId() !== identity.turnId || this.holderId !== identity.holderId || this.generation !== identity.generation)
|
|
1393
1246
|
return;
|
|
1394
|
-
|
|
1395
|
-
this.
|
|
1396
|
-
workspaceId: this.deps.workspaceId,
|
|
1397
|
-
turnId,
|
|
1398
|
-
reason,
|
|
1399
|
-
...safeErrorDiagnostic(error51)
|
|
1400
|
-
});
|
|
1401
|
-
this.deps.observability.incrementCounter({
|
|
1402
|
-
name: "opengeni_codex_lease_renewals_total",
|
|
1403
|
-
help: "Codex lease renewal checkpoints by outcome and reason.",
|
|
1404
|
-
labels: {
|
|
1405
|
-
workspace_key: this.deps.codexWorkspaceKey,
|
|
1406
|
-
outcome: "error",
|
|
1407
|
-
reason
|
|
1408
|
-
}
|
|
1409
|
-
});
|
|
1247
|
+
if (this.expired(this.confirmedUntilMs)) this.markLost("deadline");
|
|
1248
|
+
else this.leaseDeps.onError(error51, reason);
|
|
1410
1249
|
} finally {
|
|
1411
1250
|
this.heartbeatInFlight = false;
|
|
1412
1251
|
}
|
|
1413
1252
|
};
|
|
1414
1253
|
startHeartbeat = () => {
|
|
1415
|
-
if (!this.
|
|
1416
|
-
this.heartbeatTimer = setInterval(() =>
|
|
1417
|
-
void this.renew("timer");
|
|
1418
|
-
}, 6e4);
|
|
1254
|
+
if (!this.leaseDeps.getTurnId() || this.heartbeatTimer) return;
|
|
1255
|
+
this.heartbeatTimer = setInterval(() => void this.renew("timer"), 6e4);
|
|
1419
1256
|
this.heartbeatTimer.unref?.();
|
|
1420
1257
|
};
|
|
1421
1258
|
stopHeartbeat = () => {
|
|
@@ -1424,79 +1261,94 @@ var CodexTurnLease = class {
|
|
|
1424
1261
|
this.heartbeatTimer = void 0;
|
|
1425
1262
|
};
|
|
1426
1263
|
};
|
|
1427
|
-
|
|
1264
|
+
|
|
1265
|
+
// src/activities/agent-turn/credential-leases.ts
|
|
1266
|
+
var CodexCredentialLeaseLostError = class extends Error {
|
|
1267
|
+
constructor(reason) {
|
|
1268
|
+
super("Codex credential lease is not usable for provider dispatch");
|
|
1269
|
+
this.reason = reason;
|
|
1270
|
+
this.name = "CodexCredentialLeaseLostError";
|
|
1271
|
+
}
|
|
1272
|
+
code = "codex_credential_lease_lost";
|
|
1273
|
+
};
|
|
1274
|
+
var CodexTurnLease = class extends SubscriptionTurnLease {
|
|
1428
1275
|
constructor(deps) {
|
|
1429
|
-
|
|
1276
|
+
super({
|
|
1277
|
+
ttlMs: CODEX_CREDENTIAL_LEASE_TTL_MS,
|
|
1278
|
+
getTurnId: deps.getTurnId,
|
|
1279
|
+
heartbeat: ({ turnId, holderId, generation }) => heartbeatCodexCredentialLeaseUntil(
|
|
1280
|
+
deps.db,
|
|
1281
|
+
deps.accountId,
|
|
1282
|
+
deps.workspaceId,
|
|
1283
|
+
turnId,
|
|
1284
|
+
holderId,
|
|
1285
|
+
generation,
|
|
1286
|
+
CODEX_CREDENTIAL_LEASE_TTL_MS
|
|
1287
|
+
),
|
|
1288
|
+
lostError: (reason) => new CodexCredentialLeaseLostError(reason),
|
|
1289
|
+
onLost: (reason) => {
|
|
1290
|
+
deps.observability.incrementCounter({
|
|
1291
|
+
name: "opengeni_codex_lease_renewals_total",
|
|
1292
|
+
help: "Codex lease renewal checkpoints by outcome and reason.",
|
|
1293
|
+
labels: { workspace_key: deps.codexWorkspaceKey, outcome: "lost", reason }
|
|
1294
|
+
});
|
|
1295
|
+
deps.observability.warn("Codex credential lease was lost during an active turn", {
|
|
1296
|
+
workspaceId: deps.workspaceId,
|
|
1297
|
+
turnId: deps.getTurnId(),
|
|
1298
|
+
reason
|
|
1299
|
+
});
|
|
1300
|
+
},
|
|
1301
|
+
onRenewed: (reason) => deps.observability.incrementCounter({
|
|
1302
|
+
name: "opengeni_codex_lease_renewals_total",
|
|
1303
|
+
help: "Codex lease renewal checkpoints by outcome and reason.",
|
|
1304
|
+
labels: { workspace_key: deps.codexWorkspaceKey, outcome: "completed", reason }
|
|
1305
|
+
}),
|
|
1306
|
+
onError: (error51, reason) => {
|
|
1307
|
+
deps.observability.warn("Codex credential lease heartbeat failed", {
|
|
1308
|
+
workspaceId: deps.workspaceId,
|
|
1309
|
+
turnId: deps.getTurnId(),
|
|
1310
|
+
reason,
|
|
1311
|
+
...safeErrorDiagnostic(error51)
|
|
1312
|
+
});
|
|
1313
|
+
deps.observability.incrementCounter({
|
|
1314
|
+
name: "opengeni_codex_lease_renewals_total",
|
|
1315
|
+
help: "Codex lease renewal checkpoints by outcome and reason.",
|
|
1316
|
+
labels: { workspace_key: deps.codexWorkspaceKey, outcome: "error", reason }
|
|
1317
|
+
});
|
|
1318
|
+
}
|
|
1319
|
+
});
|
|
1430
1320
|
}
|
|
1431
|
-
|
|
1432
|
-
|
|
1321
|
+
};
|
|
1322
|
+
var XaiTurnLease = class extends SubscriptionTurnLease {
|
|
1433
1323
|
subjectId = null;
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
if (this.lost) return;
|
|
1441
|
-
this.lost = true;
|
|
1442
|
-
this.deps.observability.warn("xAI credential lease was lost during an active turn", {
|
|
1443
|
-
workspaceId: this.deps.workspaceId,
|
|
1444
|
-
turnId: this.deps.getTurnId(),
|
|
1445
|
-
reason
|
|
1446
|
-
});
|
|
1447
|
-
};
|
|
1448
|
-
renew = async () => {
|
|
1449
|
-
const turnId = this.deps.getTurnId();
|
|
1450
|
-
if (!turnId || !this.held || !this.subjectId || !this.holderId || this.generation === null || this.lost) {
|
|
1451
|
-
return;
|
|
1452
|
-
}
|
|
1453
|
-
if (codexCredentialLeaseDeadlineExpired(this.confirmedUntilMs)) {
|
|
1454
|
-
this.markLost("deadline");
|
|
1455
|
-
return;
|
|
1456
|
-
}
|
|
1457
|
-
if (this.heartbeatInFlight) return;
|
|
1458
|
-
this.heartbeatInFlight = true;
|
|
1459
|
-
const renewalStartedAtMs = performance.now();
|
|
1460
|
-
try {
|
|
1461
|
-
const renewedUntil = await heartbeatXaiCredentialLeaseUntil(this.deps.db, {
|
|
1462
|
-
workspaceId: this.deps.workspaceId,
|
|
1324
|
+
constructor(deps) {
|
|
1325
|
+
super({
|
|
1326
|
+
ttlMs: XAI_CREDENTIAL_LEASE_TTL_MS,
|
|
1327
|
+
getTurnId: deps.getTurnId,
|
|
1328
|
+
heartbeat: ({ turnId, holderId, generation }) => this.subjectId ? heartbeatXaiCredentialLeaseUntil(deps.db, {
|
|
1329
|
+
workspaceId: deps.workspaceId,
|
|
1463
1330
|
subjectId: this.subjectId,
|
|
1464
1331
|
turnId,
|
|
1465
|
-
holderId
|
|
1466
|
-
generation
|
|
1332
|
+
holderId,
|
|
1333
|
+
generation,
|
|
1467
1334
|
leaseTtlMs: XAI_CREDENTIAL_LEASE_TTL_MS
|
|
1468
|
-
})
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
turnId,
|
|
1335
|
+
}) : Promise.resolve(null),
|
|
1336
|
+
lostError: (reason) => Object.assign(new Error("SuperGrok credential lease is not usable for provider dispatch"), {
|
|
1337
|
+
code: "xai_credential_lease_lost",
|
|
1338
|
+
reason
|
|
1339
|
+
}),
|
|
1340
|
+
onLost: (reason) => deps.observability.warn("xAI credential lease was lost during an active turn", {
|
|
1341
|
+
workspaceId: deps.workspaceId,
|
|
1342
|
+
turnId: deps.getTurnId(),
|
|
1343
|
+
reason
|
|
1344
|
+
}),
|
|
1345
|
+
onError: (error51) => deps.observability.warn("xAI credential lease heartbeat failed", {
|
|
1346
|
+
workspaceId: deps.workspaceId,
|
|
1347
|
+
turnId: deps.getTurnId(),
|
|
1482
1348
|
...safeErrorDiagnostic(error51)
|
|
1483
|
-
})
|
|
1484
|
-
}
|
|
1485
|
-
|
|
1486
|
-
}
|
|
1487
|
-
};
|
|
1488
|
-
startHeartbeat = () => {
|
|
1489
|
-
if (!this.deps.getTurnId() || this.heartbeatTimer) return;
|
|
1490
|
-
this.heartbeatTimer = setInterval(() => {
|
|
1491
|
-
void this.renew();
|
|
1492
|
-
}, 6e4);
|
|
1493
|
-
this.heartbeatTimer.unref?.();
|
|
1494
|
-
};
|
|
1495
|
-
stopHeartbeat = () => {
|
|
1496
|
-
if (!this.heartbeatTimer) return;
|
|
1497
|
-
clearInterval(this.heartbeatTimer);
|
|
1498
|
-
this.heartbeatTimer = void 0;
|
|
1499
|
-
};
|
|
1349
|
+
})
|
|
1350
|
+
});
|
|
1351
|
+
}
|
|
1500
1352
|
};
|
|
1501
1353
|
function createTurnCredentialLeases(deps) {
|
|
1502
1354
|
const codex = new CodexTurnLease(deps);
|
|
@@ -1539,7 +1391,7 @@ import {
|
|
|
1539
1391
|
settleGeneratedImageArtifactReady
|
|
1540
1392
|
} from "@opengeni/db";
|
|
1541
1393
|
import { retryWhileMissing as retryWhileMissing2 } from "@opengeni/storage";
|
|
1542
|
-
import { createHash as
|
|
1394
|
+
import { createHash as createHash3 } from "crypto";
|
|
1543
1395
|
|
|
1544
1396
|
// src/activities/retained-screenshots.ts
|
|
1545
1397
|
import {
|
|
@@ -1563,7 +1415,7 @@ import {
|
|
|
1563
1415
|
settleRetainedScreenshotArtifactReady
|
|
1564
1416
|
} from "@opengeni/db";
|
|
1565
1417
|
import { retryWhileMissing } from "@opengeni/storage";
|
|
1566
|
-
import { createHash as
|
|
1418
|
+
import { createHash as createHash2 } from "crypto";
|
|
1567
1419
|
var PNG_SIGNATURE = Uint8Array.of(137, 80, 78, 71, 13, 10, 26, 10);
|
|
1568
1420
|
var PNG_ALLOWED_CRITICAL_CHUNKS = /* @__PURE__ */ new Set(["IHDR", "PLTE", "IDAT", "IEND"]);
|
|
1569
1421
|
var PNG_MAX_CHUNKS = 16384;
|
|
@@ -1847,7 +1699,7 @@ function validateComputerScreenshot(input, limits = {}) {
|
|
|
1847
1699
|
bytes: input.bytes,
|
|
1848
1700
|
mediaType: "image/png",
|
|
1849
1701
|
sizeBytes: input.bytes.byteLength,
|
|
1850
|
-
sha256:
|
|
1702
|
+
sha256: createHash2("sha256").update(input.bytes).digest("hex"),
|
|
1851
1703
|
width,
|
|
1852
1704
|
height
|
|
1853
1705
|
};
|
|
@@ -1903,11 +1755,11 @@ function validateRetainableSessionImage(input, limits = {}) {
|
|
|
1903
1755
|
bytes: input.bytes,
|
|
1904
1756
|
...identity,
|
|
1905
1757
|
sizeBytes: input.bytes.byteLength,
|
|
1906
|
-
sha256:
|
|
1758
|
+
sha256: createHash2("sha256").update(input.bytes).digest("hex")
|
|
1907
1759
|
};
|
|
1908
1760
|
}
|
|
1909
1761
|
function retainedScreenshotIdentity(input) {
|
|
1910
|
-
const settlementKey =
|
|
1762
|
+
const settlementKey = createHash2("sha256").update(
|
|
1911
1763
|
input.kind === "browser_screenshot" ? "opengeni:browser-screenshot:v1\0" : "opengeni:computer-screenshot:v1\0"
|
|
1912
1764
|
).update(input.sessionId).update("\0").update(input.turnId).update("\0").update(input.attemptId).update("\0").update(input.toolCallId).update("\0").update(input.toolOutputId).digest("hex");
|
|
1913
1765
|
const uuidBytes = Uint8Array.from(Buffer.from(settlementKey.slice(0, 32), "hex"));
|
|
@@ -2621,7 +2473,7 @@ function validateGeneratedImage(input) {
|
|
|
2621
2473
|
}
|
|
2622
2474
|
}
|
|
2623
2475
|
function generatedImageIdentity(input) {
|
|
2624
|
-
const hash2 =
|
|
2476
|
+
const hash2 = createHash3("sha256").update("opengeni:generated-image:v2\0").update(input.workspaceId).update("\0").update(input.sourceStrategy).update("\0").update(input.providerId).update("\0").update(input.providerBindingHash).update("\0");
|
|
2625
2477
|
if (input.sourceStrategy === "native_hosted") {
|
|
2626
2478
|
hash2.update(input.providerItemId);
|
|
2627
2479
|
} else {
|
|
@@ -3378,7 +3230,7 @@ function completedToolCallFromSdkEvent(event) {
|
|
|
3378
3230
|
}
|
|
3379
3231
|
|
|
3380
3232
|
// src/activities/agent-turn/history-prefix.ts
|
|
3381
|
-
import { createHash as
|
|
3233
|
+
import { createHash as createHash4 } from "crypto";
|
|
3382
3234
|
import { normalizeProtocolJsonValue as normalizeProtocolJsonValue2, sanitizeHistoryItemsForModel as sanitizeHistoryItemsForModel2 } from "@opengeni/runtime";
|
|
3383
3235
|
var HistoryPrefixGuard = class {
|
|
3384
3236
|
persisted = [];
|
|
@@ -3404,7 +3256,7 @@ var HistoryPrefixGuard = class {
|
|
|
3404
3256
|
}
|
|
3405
3257
|
keys(items, truncationTokens) {
|
|
3406
3258
|
return sanitizeHistoryItemsForModel2(items, truncationTokens).map(
|
|
3407
|
-
(item) =>
|
|
3259
|
+
(item) => createHash4("sha256").update(JSON.stringify(sorted(normalizeProtocolJsonValue2(item)))).digest("hex")
|
|
3408
3260
|
);
|
|
3409
3261
|
}
|
|
3410
3262
|
};
|
|
@@ -3611,6 +3463,40 @@ function safeObserveHistogram(observability, input) {
|
|
|
3611
3463
|
}
|
|
3612
3464
|
}
|
|
3613
3465
|
|
|
3466
|
+
// src/activities/agent-turn/codex.ts
|
|
3467
|
+
import {
|
|
3468
|
+
listCodexAccountStatuses,
|
|
3469
|
+
fetchCodexUsageForAccount
|
|
3470
|
+
} from "@opengeni/db";
|
|
3471
|
+
import { createHash as createHash5 } from "crypto";
|
|
3472
|
+
function codexWorkspaceMetricKey(workspaceId) {
|
|
3473
|
+
return createHash5("sha256").update(workspaceId).digest("hex").slice(0, 12);
|
|
3474
|
+
}
|
|
3475
|
+
function acceptsPromptCacheKeyForTurn(resolvedModel) {
|
|
3476
|
+
if (!resolvedModel) {
|
|
3477
|
+
return true;
|
|
3478
|
+
}
|
|
3479
|
+
return resolvedModel.provider.builtin === true || resolvedModel.provider.kind === "codex-subscription" || // Native Claude consumes this internal key as session identity; it never
|
|
3480
|
+
// sends OpenAI's prompt_cache_key field to the Messages endpoint.
|
|
3481
|
+
resolvedModel.provider.api === "anthropic-messages";
|
|
3482
|
+
}
|
|
3483
|
+
async function refreshCappedCodexUsageRows(db, settings, workspaceId, accounts, capacitySignals, acceptedTurnId) {
|
|
3484
|
+
const now = /* @__PURE__ */ new Date();
|
|
3485
|
+
const stale = accounts.filter(
|
|
3486
|
+
(account) => account.status === "active" && codexAccountNeedsLiveCapacityRefresh(account, now)
|
|
3487
|
+
);
|
|
3488
|
+
if (stale.length === 0) {
|
|
3489
|
+
return accounts;
|
|
3490
|
+
}
|
|
3491
|
+
await refreshCodexUsageAndRepairCapacityWaiters(
|
|
3492
|
+
stale.map(
|
|
3493
|
+
(account) => () => fetchCodexUsageForAccount(db, settings, workspaceId, account.id, void 0, acceptedTurnId)
|
|
3494
|
+
),
|
|
3495
|
+
() => signalPendingCodexCapacityWakeTargets({ db, ...capacitySignals }, workspaceId)
|
|
3496
|
+
);
|
|
3497
|
+
return listCodexAccountStatuses(db, workspaceId, acceptedTurnId).catch(() => accounts);
|
|
3498
|
+
}
|
|
3499
|
+
|
|
3614
3500
|
// src/activities/agent-turn/turn-context.ts
|
|
3615
3501
|
function createTurnContext(input) {
|
|
3616
3502
|
return {
|
|
@@ -3809,7 +3695,7 @@ function startTurnFinalizationMonitor(input) {
|
|
|
3809
3695
|
} catch {
|
|
3810
3696
|
}
|
|
3811
3697
|
},
|
|
3812
|
-
terminateWorker: input.
|
|
3698
|
+
terminateWorker: input.requestWorkerDrain
|
|
3813
3699
|
});
|
|
3814
3700
|
slowTimer = setTimeout(
|
|
3815
3701
|
() => diagnose(() => {
|
|
@@ -4671,6 +4557,7 @@ async function finalizeTurnAttempt(deps) {
|
|
|
4671
4557
|
deps.eventing.heartbeatTimer = startActivityHeartbeat(deps.activityContext, details);
|
|
4672
4558
|
const monitor = startTurnFinalizationMonitor({
|
|
4673
4559
|
observability: deps.observability,
|
|
4560
|
+
...deps.turnFinalizationTimeoutMs === void 0 ? {} : { timeoutMs: deps.turnFinalizationTimeoutMs },
|
|
4674
4561
|
details,
|
|
4675
4562
|
heartbeat: (value) => {
|
|
4676
4563
|
try {
|
|
@@ -4678,7 +4565,7 @@ async function finalizeTurnAttempt(deps) {
|
|
|
4678
4565
|
} catch {
|
|
4679
4566
|
}
|
|
4680
4567
|
},
|
|
4681
|
-
|
|
4568
|
+
requestWorkerDrain: deps.requestWorkerDrain
|
|
4682
4569
|
});
|
|
4683
4570
|
try {
|
|
4684
4571
|
monitor.enter("tool_writers");
|
|
@@ -4912,12 +4799,12 @@ async function finalizeTurnAttemptSteps(deps, monitor) {
|
|
|
4912
4799
|
);
|
|
4913
4800
|
}
|
|
4914
4801
|
monitor.enter("provider_leases");
|
|
4915
|
-
for (const
|
|
4802
|
+
for (const snapshot of providerTurn.latestClaudeUsage.values()) {
|
|
4916
4803
|
await waitForTurnFinalizerStep(
|
|
4917
4804
|
recordClaudeSubscriptionUsage(
|
|
4918
4805
|
db,
|
|
4919
4806
|
settings,
|
|
4920
|
-
{ accountId: input.accountId, workspaceId: input.workspaceId, scope },
|
|
4807
|
+
{ accountId: input.accountId, workspaceId: input.workspaceId, scope: snapshot.scope },
|
|
4921
4808
|
snapshot
|
|
4922
4809
|
).catch(() => null),
|
|
4923
4810
|
finalizerSignal
|
|
@@ -5271,13 +5158,15 @@ import {
|
|
|
5271
5158
|
settleCodexCredentialFailover,
|
|
5272
5159
|
readLease,
|
|
5273
5160
|
SandboxLeaseSupersededError,
|
|
5274
|
-
isSessionEventPersistenceError as isSessionEventPersistenceError2
|
|
5161
|
+
isSessionEventPersistenceError as isSessionEventPersistenceError2,
|
|
5162
|
+
SANDBOX_SETUP_RECOVERY_LIMIT
|
|
5275
5163
|
} from "@opengeni/db";
|
|
5276
5164
|
import { publishDurableSessionEvents as publishDurableSessionEvents2 } from "@opengeni/events";
|
|
5277
5165
|
import {
|
|
5278
5166
|
maxTurnsExceededRunState,
|
|
5279
5167
|
isModalTaskExecStartPreDispatchUnavailableError,
|
|
5280
|
-
isModalCommandStartOutcomeUnknownError
|
|
5168
|
+
isModalCommandStartOutcomeUnknownError,
|
|
5169
|
+
isProviderCommandObservationUnavailableError
|
|
5281
5170
|
} from "@opengeni/runtime";
|
|
5282
5171
|
import { ApplicationFailure, CancelledFailure } from "@temporalio/activity";
|
|
5283
5172
|
import { TurnExecutionPolicyDefinitionMismatchError } from "@opengeni/config";
|
|
@@ -6141,7 +6030,8 @@ async function settleTurnFailure(deps) {
|
|
|
6141
6030
|
}
|
|
6142
6031
|
}
|
|
6143
6032
|
const recoveryTurnId = attempt.turnId;
|
|
6144
|
-
|
|
6033
|
+
const observationUnavailable = isProviderCommandObservationUnavailableError(error51);
|
|
6034
|
+
if ((isModalCommandStartOutcomeUnknownError(error51) || observationUnavailable) && recoveryTurnId && attempt.triggerEventId && attempt.executionGeneration > 0) {
|
|
6145
6035
|
let recovery;
|
|
6146
6036
|
try {
|
|
6147
6037
|
if (eventing.turnStartedPublished) {
|
|
@@ -6153,10 +6043,10 @@ async function settleTurnFailure(deps) {
|
|
|
6153
6043
|
turnId: recoveryTurnId,
|
|
6154
6044
|
triggerEventId: attempt.triggerEventId,
|
|
6155
6045
|
attemptId: input.attemptId,
|
|
6156
|
-
reason: "sandbox_command_start_outcome_unknown",
|
|
6046
|
+
reason: observationUnavailable ? "sandbox_command_observation_unavailable" : "sandbox_command_start_outcome_unknown",
|
|
6157
6047
|
sandboxSetupOutcomeUnknown: true,
|
|
6158
6048
|
detail: {
|
|
6159
|
-
code: "sandbox_command_start_outcome_unknown",
|
|
6049
|
+
code: observationUnavailable ? "sandbox_command_observation_unavailable" : "sandbox_command_start_outcome_unknown",
|
|
6160
6050
|
retryable: false,
|
|
6161
6051
|
setupOutcome: "unknown",
|
|
6162
6052
|
replay: "blocked",
|
|
@@ -7218,7 +7108,39 @@ async function settleTurnFailure(deps) {
|
|
|
7218
7108
|
attemptNumber: nextProviderRecoveryCount,
|
|
7219
7109
|
retryAfterMs: providerRetryAfterMs(error51)
|
|
7220
7110
|
});
|
|
7111
|
+
const setupRecoveryExhausted = earlyCommandStartUnavailable && recoveryResult.status === "exhausted" && attempt.providerRecoveryCount === SANDBOX_SETUP_RECOVERY_LIMIT;
|
|
7221
7112
|
try {
|
|
7113
|
+
if (setupRecoveryExhausted) {
|
|
7114
|
+
const recovery = await requestSessionTurnRecovery(db, input.workspaceId, {
|
|
7115
|
+
sessionId: input.sessionId,
|
|
7116
|
+
turnId: attempt.turnId,
|
|
7117
|
+
triggerEventId: attempt.triggerEventId,
|
|
7118
|
+
attemptId: input.attemptId,
|
|
7119
|
+
reason: "sandbox_command_start_recovery_exhausted",
|
|
7120
|
+
sandboxSetupRecoveryExhausted: true,
|
|
7121
|
+
detail: {
|
|
7122
|
+
code: failure2.code,
|
|
7123
|
+
error: "Automatic sandbox setup recovery exhausted after five retries; the accepted turn remains parked without starting a command.",
|
|
7124
|
+
retryable: false,
|
|
7125
|
+
setupOutcome: "not_started",
|
|
7126
|
+
replay: "blocked",
|
|
7127
|
+
recoveryExhausted: true,
|
|
7128
|
+
providerRecoveryCount: SANDBOX_SETUP_RECOVERY_LIMIT
|
|
7129
|
+
}
|
|
7130
|
+
});
|
|
7131
|
+
if (recovery.action === "stale") {
|
|
7132
|
+
acknowledgeLostAttemptOwnership();
|
|
7133
|
+
control.activityStatus = "cancelled";
|
|
7134
|
+
control.turnMetricOutcome = "cancelled";
|
|
7135
|
+
return claimedResult({ status: "cancelled" });
|
|
7136
|
+
}
|
|
7137
|
+
acknowledgeRecoveryQuiescence();
|
|
7138
|
+
await publishDurableSessionEvents2(bus, input.workspaceId, input.sessionId, recovery.events);
|
|
7139
|
+
control.turnMetricOutcome = "recovering";
|
|
7140
|
+
control.activityStatus = "recovering";
|
|
7141
|
+
control.activityError = error51;
|
|
7142
|
+
return claimedResult({ status: "recovering" });
|
|
7143
|
+
}
|
|
7222
7144
|
if (recoveryResult.status === "recovering") {
|
|
7223
7145
|
if (!earlyRecoverableSetup) {
|
|
7224
7146
|
await flushRuntimeBatcher();
|
|
@@ -7232,7 +7154,7 @@ async function settleTurnFailure(deps) {
|
|
|
7232
7154
|
reason: failure2.code ?? "provider_unavailable",
|
|
7233
7155
|
providerRecoveryCount: nextProviderRecoveryCount,
|
|
7234
7156
|
detail: {
|
|
7235
|
-
...failure2,
|
|
7157
|
+
...agentRunRecoveryFailurePayload(error51, failure2),
|
|
7236
7158
|
continueDelayMs: recoveryResult.continueDelayMs,
|
|
7237
7159
|
providerRecoveryCount: nextProviderRecoveryCount
|
|
7238
7160
|
}
|
|
@@ -7288,6 +7210,12 @@ async function settleTurnFailure(deps) {
|
|
|
7288
7210
|
failureCode: failure2.code ?? "provider_unavailable",
|
|
7289
7211
|
providerRecoveryCount: nextProviderRecoveryCount
|
|
7290
7212
|
}
|
|
7213
|
+
}) : setupRecoveryExhausted ? postClaimDatabaseRecoveryFailure({
|
|
7214
|
+
error: recoveryError,
|
|
7215
|
+
turnId: attempt.turnId,
|
|
7216
|
+
triggerEventId: attempt.triggerEventId,
|
|
7217
|
+
executionGeneration: attempt.executionGeneration,
|
|
7218
|
+
sandboxSetupRecoveryExhausted: true
|
|
7291
7219
|
}) : null;
|
|
7292
7220
|
if (postClaimRecovery) {
|
|
7293
7221
|
control.activityStatus = "recovering";
|
|
@@ -7899,6 +7827,13 @@ async function resultItemForOpenSuffixMember(input) {
|
|
|
7899
7827
|
const name = toolNameFromCallItem(input.row.callItem);
|
|
7900
7828
|
const rejected = () => {
|
|
7901
7829
|
const payload2 = input.trigger.payload;
|
|
7830
|
+
if (input.row.interruptionKind === "approval" && payload2.decision === "reject" && !(typeof payload2.message === "string" && payload2.message.trim().length > 0)) {
|
|
7831
|
+
return memberResult({
|
|
7832
|
+
callId: input.row.callId,
|
|
7833
|
+
name,
|
|
7834
|
+
output: "Tool approval was rejected. This proposed tool call was not executed."
|
|
7835
|
+
});
|
|
7836
|
+
}
|
|
7902
7837
|
const message = typeof payload2.message === "string" && payload2.message.trim().length > 0 ? payload2.message : "Tool approval was rejected.";
|
|
7903
7838
|
const interrupted = interruptedToolCallResult({
|
|
7904
7839
|
callType: input.row.callType,
|
|
@@ -10079,6 +10014,10 @@ async function runTurnStreamAttempt(deps) {
|
|
|
10079
10014
|
}
|
|
10080
10015
|
}
|
|
10081
10016
|
|
|
10017
|
+
// src/activities/agent-turn/claim.ts
|
|
10018
|
+
import { withDirectModelProviders } from "@opengeni/config";
|
|
10019
|
+
import { loadDirectModelProviderConnection } from "@opengeni/db";
|
|
10020
|
+
|
|
10082
10021
|
// src/activities/agent-turn/recovery-warning.ts
|
|
10083
10022
|
import { getSandboxRecoveryDiscontinuity } from "@opengeni/db";
|
|
10084
10023
|
var FILESYSTEM_DISCONTINUITY_PROTOCOL = 3;
|
|
@@ -10511,6 +10450,15 @@ async function claimTurnAttempt(deps) {
|
|
|
10511
10450
|
workspaceProviderSettings,
|
|
10512
10451
|
claimedPolicy.kind === "valid" ? claimedPolicy.policy.productModelId : turn.model
|
|
10513
10452
|
);
|
|
10453
|
+
const selectedDirectConnection = await loadDirectModelProviderConnection(
|
|
10454
|
+
db,
|
|
10455
|
+
capabilitySettings,
|
|
10456
|
+
input.workspaceId,
|
|
10457
|
+
claimedPolicy.kind === "valid" ? claimedPolicy.policy.productModelId : turn.model ?? ""
|
|
10458
|
+
);
|
|
10459
|
+
if (selectedDirectConnection) {
|
|
10460
|
+
capabilitySettings = withDirectModelProviders(capabilitySettings, [selectedDirectConnection]);
|
|
10461
|
+
}
|
|
10514
10462
|
const codexAppsCredentialId = capabilitySettings.codexConnectedAppsEnabled ? await resolveCodexAppsCredentialIdForRun(db, input.workspaceId) : null;
|
|
10515
10463
|
const candidatePolicy = claimedPolicy.kind === "valid" ? claimedPolicy.policy : resolveTurnExecutionPolicyV12(capabilitySettings, legacyTurnExecutionPolicyInput(turn));
|
|
10516
10464
|
const credentialRestriction = claimedPolicy.kind === "absent" ? turn.initiatorContext?.credentialRestriction === "developer_setup" ? "developer_setup" : turnCredentialRestriction(candidatePolicy, session.metadata) : void 0;
|
|
@@ -13001,6 +12949,7 @@ import { createProviderCommandRetainer } from "@opengeni/db/retained-provider-co
|
|
|
13001
12949
|
import {
|
|
13002
12950
|
RoutingMutationOutcomeUnknownError,
|
|
13003
12951
|
ProviderCommandStartOutcomeUnknownError,
|
|
12952
|
+
ProviderCommandObservationUnavailableError,
|
|
13004
12953
|
isModalCommandStartOutcomeUnknownError as isModalCommandStartOutcomeUnknownError2,
|
|
13005
12954
|
withModalCommandStartSignal,
|
|
13006
12955
|
resolveModalCheckpointProviderBindingForSession,
|
|
@@ -13028,7 +12977,7 @@ function internalMutationUnknownCommand(error51, instanceId) {
|
|
|
13028
12977
|
if (!value || typeof value !== "object" || seen.has(value)) continue;
|
|
13029
12978
|
seen.add(value);
|
|
13030
12979
|
try {
|
|
13031
|
-
if (value instanceof ProviderCommandStartOutcomeUnknownError) {
|
|
12980
|
+
if (value instanceof ProviderCommandStartOutcomeUnknownError || value instanceof ProviderCommandObservationUnavailableError) {
|
|
13032
12981
|
unknown2 = true;
|
|
13033
12982
|
let remaining = 64;
|
|
13034
12983
|
const copyCommandData = (candidate, descriptorDepth = 0) => {
|
|
@@ -14161,7 +14110,8 @@ async function establishTurnSandbox(deps) {
|
|
|
14161
14110
|
observability,
|
|
14162
14111
|
freshSandboxReadinessReplacementBudget,
|
|
14163
14112
|
onSandboxLost: publishSandboxLost,
|
|
14164
|
-
objectStorage
|
|
14113
|
+
objectStorage,
|
|
14114
|
+
bus
|
|
14165
14115
|
},
|
|
14166
14116
|
{
|
|
14167
14117
|
accountId: input.accountId,
|
|
@@ -14236,7 +14186,8 @@ async function establishTurnSandbox(deps) {
|
|
|
14236
14186
|
observability,
|
|
14237
14187
|
freshSandboxReadinessReplacementBudget,
|
|
14238
14188
|
onSandboxLost: publishSandboxLost,
|
|
14239
|
-
objectStorage
|
|
14189
|
+
objectStorage,
|
|
14190
|
+
bus
|
|
14240
14191
|
},
|
|
14241
14192
|
{
|
|
14242
14193
|
accountId: input.accountId,
|
|
@@ -34291,6 +34242,7 @@ function configuredBundledSkillNames(context) {
|
|
|
34291
34242
|
{ name: "document-parsing", include: () => true },
|
|
34292
34243
|
{ name: "opengeni-skills", include: () => true },
|
|
34293
34244
|
{ name: "opengeni-projects", include: () => true },
|
|
34245
|
+
{ name: "opengeni-schedules", include: () => tools.has("scheduled_tasks_create") },
|
|
34294
34246
|
{ name: "opengeni-documents", include: artifacts },
|
|
34295
34247
|
{ name: "opengeni-spreadsheets", include: artifacts },
|
|
34296
34248
|
{ name: "opengeni-presentations", include: artifacts },
|
|
@@ -34308,6 +34260,7 @@ function loadConfiguredBundledSkills(context) {
|
|
|
34308
34260
|
const names = new Set(configuredBundledSkillNames(context));
|
|
34309
34261
|
const artifacts = loadNativeToolSkillArtifacts({
|
|
34310
34262
|
projects: names.has("opengeni-projects"),
|
|
34263
|
+
schedules: names.has("opengeni-schedules"),
|
|
34311
34264
|
editableArtifacts: [
|
|
34312
34265
|
"opengeni-documents",
|
|
34313
34266
|
"opengeni-spreadsheets",
|
|
@@ -37388,6 +37341,8 @@ function createRunAgentTurnActivity(services) {
|
|
|
37388
37341
|
bus,
|
|
37389
37342
|
runtime,
|
|
37390
37343
|
summarizeContextForCompaction,
|
|
37344
|
+
requestWorkerDrain,
|
|
37345
|
+
turnFinalizationTimeoutMs,
|
|
37391
37346
|
objectStorage,
|
|
37392
37347
|
observability,
|
|
37393
37348
|
wakeSessionWorkflow,
|
|
@@ -38011,28 +37966,28 @@ function createRunAgentTurnActivity(services) {
|
|
|
38011
37966
|
})
|
|
38012
37967
|
);
|
|
38013
37968
|
const withClaudeUsage = (fn) => withClaudeUsageObserver(claudeUsageObserver, fn, async (providerId, headers) => {
|
|
38014
|
-
|
|
38015
|
-
|
|
38016
|
-
|
|
38017
|
-
|
|
38018
|
-
|
|
38019
|
-
|
|
38020
|
-
|
|
38021
|
-
|
|
38022
|
-
|
|
38023
|
-
|
|
38024
|
-
|
|
38025
|
-
|
|
38026
|
-
|
|
37969
|
+
return claudeUsageObserver.prepareRequestWithObserver(
|
|
37970
|
+
providerId,
|
|
37971
|
+
headers,
|
|
37972
|
+
async (binding) => {
|
|
37973
|
+
const credential = await resolveClaudeSubscriptionCredential(
|
|
37974
|
+
db,
|
|
37975
|
+
settings,
|
|
37976
|
+
{
|
|
37977
|
+
accountId: input.accountId,
|
|
37978
|
+
workspaceId: input.workspaceId,
|
|
37979
|
+
scope: binding.scope
|
|
37980
|
+
},
|
|
37981
|
+
{
|
|
37982
|
+
expectedConnectionId: binding.expectedConnectionId,
|
|
37983
|
+
expectedCredentialVersion: binding.expectedCredentialVersion
|
|
37984
|
+
}
|
|
37985
|
+
);
|
|
37986
|
+
if (credential && "reconnectRequired" in credential)
|
|
37987
|
+
throw new ClaudeSubscriptionReconnectRequired();
|
|
37988
|
+
return credential;
|
|
38027
37989
|
}
|
|
38028
37990
|
);
|
|
38029
|
-
if (!credential) return headers;
|
|
38030
|
-
if ("reconnectRequired" in credential)
|
|
38031
|
-
throw new ClaudeSubscriptionReconnectRequired();
|
|
38032
|
-
claudeUsageObserver.renew(providerId, credential);
|
|
38033
|
-
headers.set("authorization", `Bearer ${credential.token}`);
|
|
38034
|
-
headers.delete("x-api-key");
|
|
38035
|
-
return headers;
|
|
38036
37991
|
});
|
|
38037
37992
|
const withCodex = (fn) => codexContext ? codexRequestStorage.run(codexContext, fn) : fn();
|
|
38038
37993
|
const withProviderRequestContext = (fn) => withClaudeUsage(
|
|
@@ -38842,6 +38797,8 @@ These are publication receipts for the human's earlier answer. Do not call the r
|
|
|
38842
38797
|
});
|
|
38843
38798
|
} finally {
|
|
38844
38799
|
await finalizeTurnAttempt({
|
|
38800
|
+
turnFinalizationTimeoutMs,
|
|
38801
|
+
requestWorkerDrain,
|
|
38845
38802
|
input,
|
|
38846
38803
|
settings,
|
|
38847
38804
|
db,
|
|
@@ -39982,12 +39939,17 @@ function createTurnActivityServices(dependencies) {
|
|
|
39982
39939
|
let servicesPromise = null;
|
|
39983
39940
|
return async () => {
|
|
39984
39941
|
servicesPromise ??= (async () => {
|
|
39942
|
+
if (!dependencies.requestWorkerDrain) {
|
|
39943
|
+
throw new Error("Turn activities require a host requestWorkerDrain lifecycle edge");
|
|
39944
|
+
}
|
|
39985
39945
|
const services = await shared();
|
|
39986
39946
|
return {
|
|
39987
39947
|
...services,
|
|
39988
39948
|
runtime: dependencies.runtime ?? createProductionAgentRuntime({
|
|
39989
39949
|
metrics: runtimeMetricsHooksForObservability(services.observability)
|
|
39990
39950
|
}),
|
|
39951
|
+
requestWorkerDrain: dependencies.requestWorkerDrain,
|
|
39952
|
+
turnFinalizationTimeoutMs: dependencies.turnFinalizationTimeoutMs,
|
|
39991
39953
|
summarizeContextForCompaction: dependencies.summarizeContextForCompaction ?? summarizeForCompaction2
|
|
39992
39954
|
};
|
|
39993
39955
|
})();
|
|
@@ -40007,4 +39969,4 @@ export {
|
|
|
40007
39969
|
createTurnActivities,
|
|
40008
39970
|
createTurnActivitiesFromServices
|
|
40009
39971
|
};
|
|
40010
|
-
//# sourceMappingURL=activities-turn-
|
|
39972
|
+
//# sourceMappingURL=activities-turn-E3EA7FPS.js.map
|