@opengeni/worker-bundle 2.3.1 → 2.3.2-canary.37090756480001
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/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-TTNAVGKN.js} +263 -308
- package/dist/activities-turn-TTNAVGKN.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/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";
|
|
@@ -10079,6 +10007,10 @@ async function runTurnStreamAttempt(deps) {
|
|
|
10079
10007
|
}
|
|
10080
10008
|
}
|
|
10081
10009
|
|
|
10010
|
+
// src/activities/agent-turn/claim.ts
|
|
10011
|
+
import { withDirectModelProviders } from "@opengeni/config";
|
|
10012
|
+
import { loadDirectModelProviderConnection } from "@opengeni/db";
|
|
10013
|
+
|
|
10082
10014
|
// src/activities/agent-turn/recovery-warning.ts
|
|
10083
10015
|
import { getSandboxRecoveryDiscontinuity } from "@opengeni/db";
|
|
10084
10016
|
var FILESYSTEM_DISCONTINUITY_PROTOCOL = 3;
|
|
@@ -10511,6 +10443,15 @@ async function claimTurnAttempt(deps) {
|
|
|
10511
10443
|
workspaceProviderSettings,
|
|
10512
10444
|
claimedPolicy.kind === "valid" ? claimedPolicy.policy.productModelId : turn.model
|
|
10513
10445
|
);
|
|
10446
|
+
const selectedDirectConnection = await loadDirectModelProviderConnection(
|
|
10447
|
+
db,
|
|
10448
|
+
capabilitySettings,
|
|
10449
|
+
input.workspaceId,
|
|
10450
|
+
claimedPolicy.kind === "valid" ? claimedPolicy.policy.productModelId : turn.model ?? ""
|
|
10451
|
+
);
|
|
10452
|
+
if (selectedDirectConnection) {
|
|
10453
|
+
capabilitySettings = withDirectModelProviders(capabilitySettings, [selectedDirectConnection]);
|
|
10454
|
+
}
|
|
10514
10455
|
const codexAppsCredentialId = capabilitySettings.codexConnectedAppsEnabled ? await resolveCodexAppsCredentialIdForRun(db, input.workspaceId) : null;
|
|
10515
10456
|
const candidatePolicy = claimedPolicy.kind === "valid" ? claimedPolicy.policy : resolveTurnExecutionPolicyV12(capabilitySettings, legacyTurnExecutionPolicyInput(turn));
|
|
10516
10457
|
const credentialRestriction = claimedPolicy.kind === "absent" ? turn.initiatorContext?.credentialRestriction === "developer_setup" ? "developer_setup" : turnCredentialRestriction(candidatePolicy, session.metadata) : void 0;
|
|
@@ -13001,6 +12942,7 @@ import { createProviderCommandRetainer } from "@opengeni/db/retained-provider-co
|
|
|
13001
12942
|
import {
|
|
13002
12943
|
RoutingMutationOutcomeUnknownError,
|
|
13003
12944
|
ProviderCommandStartOutcomeUnknownError,
|
|
12945
|
+
ProviderCommandObservationUnavailableError,
|
|
13004
12946
|
isModalCommandStartOutcomeUnknownError as isModalCommandStartOutcomeUnknownError2,
|
|
13005
12947
|
withModalCommandStartSignal,
|
|
13006
12948
|
resolveModalCheckpointProviderBindingForSession,
|
|
@@ -13028,7 +12970,7 @@ function internalMutationUnknownCommand(error51, instanceId) {
|
|
|
13028
12970
|
if (!value || typeof value !== "object" || seen.has(value)) continue;
|
|
13029
12971
|
seen.add(value);
|
|
13030
12972
|
try {
|
|
13031
|
-
if (value instanceof ProviderCommandStartOutcomeUnknownError) {
|
|
12973
|
+
if (value instanceof ProviderCommandStartOutcomeUnknownError || value instanceof ProviderCommandObservationUnavailableError) {
|
|
13032
12974
|
unknown2 = true;
|
|
13033
12975
|
let remaining = 64;
|
|
13034
12976
|
const copyCommandData = (candidate, descriptorDepth = 0) => {
|
|
@@ -14161,7 +14103,8 @@ async function establishTurnSandbox(deps) {
|
|
|
14161
14103
|
observability,
|
|
14162
14104
|
freshSandboxReadinessReplacementBudget,
|
|
14163
14105
|
onSandboxLost: publishSandboxLost,
|
|
14164
|
-
objectStorage
|
|
14106
|
+
objectStorage,
|
|
14107
|
+
bus
|
|
14165
14108
|
},
|
|
14166
14109
|
{
|
|
14167
14110
|
accountId: input.accountId,
|
|
@@ -14236,7 +14179,8 @@ async function establishTurnSandbox(deps) {
|
|
|
14236
14179
|
observability,
|
|
14237
14180
|
freshSandboxReadinessReplacementBudget,
|
|
14238
14181
|
onSandboxLost: publishSandboxLost,
|
|
14239
|
-
objectStorage
|
|
14182
|
+
objectStorage,
|
|
14183
|
+
bus
|
|
14240
14184
|
},
|
|
14241
14185
|
{
|
|
14242
14186
|
accountId: input.accountId,
|
|
@@ -34291,6 +34235,7 @@ function configuredBundledSkillNames(context) {
|
|
|
34291
34235
|
{ name: "document-parsing", include: () => true },
|
|
34292
34236
|
{ name: "opengeni-skills", include: () => true },
|
|
34293
34237
|
{ name: "opengeni-projects", include: () => true },
|
|
34238
|
+
{ name: "opengeni-schedules", include: () => tools.has("scheduled_tasks_create") },
|
|
34294
34239
|
{ name: "opengeni-documents", include: artifacts },
|
|
34295
34240
|
{ name: "opengeni-spreadsheets", include: artifacts },
|
|
34296
34241
|
{ name: "opengeni-presentations", include: artifacts },
|
|
@@ -34308,6 +34253,7 @@ function loadConfiguredBundledSkills(context) {
|
|
|
34308
34253
|
const names = new Set(configuredBundledSkillNames(context));
|
|
34309
34254
|
const artifacts = loadNativeToolSkillArtifacts({
|
|
34310
34255
|
projects: names.has("opengeni-projects"),
|
|
34256
|
+
schedules: names.has("opengeni-schedules"),
|
|
34311
34257
|
editableArtifacts: [
|
|
34312
34258
|
"opengeni-documents",
|
|
34313
34259
|
"opengeni-spreadsheets",
|
|
@@ -37388,6 +37334,8 @@ function createRunAgentTurnActivity(services) {
|
|
|
37388
37334
|
bus,
|
|
37389
37335
|
runtime,
|
|
37390
37336
|
summarizeContextForCompaction,
|
|
37337
|
+
requestWorkerDrain,
|
|
37338
|
+
turnFinalizationTimeoutMs,
|
|
37391
37339
|
objectStorage,
|
|
37392
37340
|
observability,
|
|
37393
37341
|
wakeSessionWorkflow,
|
|
@@ -38011,28 +37959,28 @@ function createRunAgentTurnActivity(services) {
|
|
|
38011
37959
|
})
|
|
38012
37960
|
);
|
|
38013
37961
|
const withClaudeUsage = (fn) => withClaudeUsageObserver(claudeUsageObserver, fn, async (providerId, headers) => {
|
|
38014
|
-
|
|
38015
|
-
|
|
38016
|
-
|
|
38017
|
-
|
|
38018
|
-
|
|
38019
|
-
|
|
38020
|
-
|
|
38021
|
-
|
|
38022
|
-
|
|
38023
|
-
|
|
38024
|
-
|
|
38025
|
-
|
|
38026
|
-
|
|
37962
|
+
return claudeUsageObserver.prepareRequestWithObserver(
|
|
37963
|
+
providerId,
|
|
37964
|
+
headers,
|
|
37965
|
+
async (binding) => {
|
|
37966
|
+
const credential = await resolveClaudeSubscriptionCredential(
|
|
37967
|
+
db,
|
|
37968
|
+
settings,
|
|
37969
|
+
{
|
|
37970
|
+
accountId: input.accountId,
|
|
37971
|
+
workspaceId: input.workspaceId,
|
|
37972
|
+
scope: binding.scope
|
|
37973
|
+
},
|
|
37974
|
+
{
|
|
37975
|
+
expectedConnectionId: binding.expectedConnectionId,
|
|
37976
|
+
expectedCredentialVersion: binding.expectedCredentialVersion
|
|
37977
|
+
}
|
|
37978
|
+
);
|
|
37979
|
+
if (credential && "reconnectRequired" in credential)
|
|
37980
|
+
throw new ClaudeSubscriptionReconnectRequired();
|
|
37981
|
+
return credential;
|
|
38027
37982
|
}
|
|
38028
37983
|
);
|
|
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
37984
|
});
|
|
38037
37985
|
const withCodex = (fn) => codexContext ? codexRequestStorage.run(codexContext, fn) : fn();
|
|
38038
37986
|
const withProviderRequestContext = (fn) => withClaudeUsage(
|
|
@@ -38842,6 +38790,8 @@ These are publication receipts for the human's earlier answer. Do not call the r
|
|
|
38842
38790
|
});
|
|
38843
38791
|
} finally {
|
|
38844
38792
|
await finalizeTurnAttempt({
|
|
38793
|
+
turnFinalizationTimeoutMs,
|
|
38794
|
+
requestWorkerDrain,
|
|
38845
38795
|
input,
|
|
38846
38796
|
settings,
|
|
38847
38797
|
db,
|
|
@@ -39982,12 +39932,17 @@ function createTurnActivityServices(dependencies) {
|
|
|
39982
39932
|
let servicesPromise = null;
|
|
39983
39933
|
return async () => {
|
|
39984
39934
|
servicesPromise ??= (async () => {
|
|
39935
|
+
if (!dependencies.requestWorkerDrain) {
|
|
39936
|
+
throw new Error("Turn activities require a host requestWorkerDrain lifecycle edge");
|
|
39937
|
+
}
|
|
39985
39938
|
const services = await shared();
|
|
39986
39939
|
return {
|
|
39987
39940
|
...services,
|
|
39988
39941
|
runtime: dependencies.runtime ?? createProductionAgentRuntime({
|
|
39989
39942
|
metrics: runtimeMetricsHooksForObservability(services.observability)
|
|
39990
39943
|
}),
|
|
39944
|
+
requestWorkerDrain: dependencies.requestWorkerDrain,
|
|
39945
|
+
turnFinalizationTimeoutMs: dependencies.turnFinalizationTimeoutMs,
|
|
39991
39946
|
summarizeContextForCompaction: dependencies.summarizeContextForCompaction ?? summarizeForCompaction2
|
|
39992
39947
|
};
|
|
39993
39948
|
})();
|
|
@@ -40007,4 +39962,4 @@ export {
|
|
|
40007
39962
|
createTurnActivities,
|
|
40008
39963
|
createTurnActivitiesFromServices
|
|
40009
39964
|
};
|
|
40010
|
-
//# sourceMappingURL=activities-turn-
|
|
39965
|
+
//# sourceMappingURL=activities-turn-TTNAVGKN.js.map
|