@opengeni/worker-bundle 2.2.0-canary.36855269964001 → 2.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/activities/agent-run-admission.d.ts +1 -3
- package/dist/activities/agent-turn/admission.d.ts +3 -24
- package/dist/activities/agent-turn/claude-usage-observer.d.ts +1 -13
- package/dist/activities/agent-turn/run-credentials.d.ts +0 -2
- package/dist/activities/agent-turn/stream-attempt.d.ts +0 -1
- package/dist/activities/agent-turn/turn-context.d.ts +0 -1
- package/dist/activities/goals.d.ts +0 -8
- package/dist/activities/run-credentials.d.ts +2 -4
- package/dist/activities/types.d.ts +1 -1
- package/dist/{activities-control-YKXRDVMB.js → activities-control-MHNA3CYV.js} +66 -28
- package/dist/activities-control-MHNA3CYV.js.map +1 -0
- package/dist/{activities-turn-V37B7CQY.js → activities-turn-FQ5OO2WW.js} +197 -540
- package/dist/activities-turn-FQ5OO2WW.js.map +1 -0
- package/dist/{chunk-ZCCLJK3V.js → chunk-RZAAGRFQ.js} +65 -145
- package/dist/chunk-RZAAGRFQ.js.map +1 -0
- package/dist/index.js +1 -1
- package/dist/workflow-bundle.js +1 -1
- package/package.json +20 -20
- package/src/activities/agent-run-admission.ts +1 -17
- package/src/activities/agent-turn/admission.ts +1 -64
- package/src/activities/agent-turn/claim.ts +14 -56
- package/src/activities/agent-turn/claude-usage-observer.ts +1 -33
- package/src/activities/agent-turn/errors.ts +0 -46
- package/src/activities/agent-turn/failure-settlement.ts +0 -5
- package/src/activities/agent-turn/run-credentials.ts +3 -15
- package/src/activities/agent-turn/run.ts +3 -32
- package/src/activities/agent-turn/stream-attempt.ts +35 -138
- package/src/activities/agent-turn/tool-environment.ts +20 -13
- package/src/activities/agent-turn/turn-context.ts +0 -1
- package/src/activities/capabilities.ts +14 -52
- package/src/activities/goals.ts +78 -38
- package/src/activities/knowledge-indexing.ts +0 -29
- package/src/activities/run-credentials.ts +16 -22
- package/src/activities/scheduled-tasks.ts +0 -1
- package/src/activities/types.ts +0 -1
- package/src/activities/workspace-credential-provider.ts +0 -12
- package/src/sandbox-routing.ts +2 -4
- package/dist/activities/agent-turn/final-reply.d.ts +0 -18
- package/dist/activities/agent-turn/model-call-admission.d.ts +0 -15
- package/dist/activities-control-YKXRDVMB.js.map +0 -1
- package/dist/activities-turn-V37B7CQY.js.map +0 -1
- package/dist/chunk-ZCCLJK3V.js.map +0 -1
- package/src/activities/agent-turn/final-reply.ts +0 -46
- package/src/activities/agent-turn/model-call-admission.ts +0 -94
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@opengeni/worker-bundle",
|
|
3
|
-
"version": "2.2.0
|
|
3
|
+
"version": "2.2.0",
|
|
4
4
|
"description": "OpenGeni worker entry and reusable embedded lifecycle, shipped with a release-coherent pre-bundled Temporal workflow artifact.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"repository": {
|
|
@@ -54,25 +54,25 @@
|
|
|
54
54
|
},
|
|
55
55
|
"dependencies": {
|
|
56
56
|
"@llamaindex/liteparse": "2.14.2",
|
|
57
|
-
"@opengeni/agent-proto": "^0.6.0
|
|
58
|
-
"@opengeni/capabilities": "^0.3.4
|
|
59
|
-
"@opengeni/codemode": "^0.6.5
|
|
60
|
-
"@opengeni/codex": "^0.2.29
|
|
61
|
-
"@opengeni/config": "^3.1.1
|
|
62
|
-
"@opengeni/contracts": "^5.4.0
|
|
63
|
-
"@opengeni/core": "^5.0.0
|
|
64
|
-
"@opengeni/db": "^6.2.0
|
|
65
|
-
"@opengeni/documents": "^0.8.37
|
|
66
|
-
"@opengeni/events": "^0.4.35
|
|
67
|
-
"@opengeni/github": "^0.8.0
|
|
68
|
-
"@opengeni/jev": "^0.2.0
|
|
69
|
-
"@opengeni/network": "^0.3.1
|
|
70
|
-
"@opengeni/observability": "^0.8.35
|
|
71
|
-
"@opengeni/runtime": "^4.3.0
|
|
72
|
-
"@opengeni/sdk": "^7.4.0
|
|
73
|
-
"@opengeni/storage": "^0.2.136
|
|
74
|
-
"@opengeni/tool-gateway": "^0.1.16
|
|
75
|
-
"@opengeni/xai-subscription": "^0.1.4
|
|
57
|
+
"@opengeni/agent-proto": "^0.6.0",
|
|
58
|
+
"@opengeni/capabilities": "^0.3.4",
|
|
59
|
+
"@opengeni/codemode": "^0.6.5",
|
|
60
|
+
"@opengeni/codex": "^0.2.29",
|
|
61
|
+
"@opengeni/config": "^3.1.1",
|
|
62
|
+
"@opengeni/contracts": "^5.4.0",
|
|
63
|
+
"@opengeni/core": "^5.0.0",
|
|
64
|
+
"@opengeni/db": "^6.2.0",
|
|
65
|
+
"@opengeni/documents": "^0.8.37",
|
|
66
|
+
"@opengeni/events": "^0.4.35",
|
|
67
|
+
"@opengeni/github": "^0.8.0",
|
|
68
|
+
"@opengeni/jev": "^0.2.0",
|
|
69
|
+
"@opengeni/network": "^0.3.1",
|
|
70
|
+
"@opengeni/observability": "^0.8.35",
|
|
71
|
+
"@opengeni/runtime": "^4.3.0",
|
|
72
|
+
"@opengeni/sdk": "^7.4.0",
|
|
73
|
+
"@opengeni/storage": "^0.2.136",
|
|
74
|
+
"@opengeni/tool-gateway": "^0.1.16",
|
|
75
|
+
"@opengeni/xai-subscription": "^0.1.4",
|
|
76
76
|
"@temporalio/activity": "^1.17.0",
|
|
77
77
|
"@temporalio/client": "^1.17.0",
|
|
78
78
|
"@temporalio/worker": "^1.17.0",
|
|
@@ -1,16 +1,10 @@
|
|
|
1
1
|
import { configuredStaticUsageLimits, type Settings } from "@opengeni/config";
|
|
2
2
|
import { modelFundingForAdmission } from "@opengeni/core";
|
|
3
|
-
import {
|
|
4
|
-
checkWorkspaceAllowance,
|
|
5
|
-
getBillingBalance,
|
|
6
|
-
isCodexBilledTurn,
|
|
7
|
-
sumUsageQuantity,
|
|
8
|
-
} from "@opengeni/db";
|
|
3
|
+
import { getBillingBalance, isCodexBilledTurn, sumUsageQuantity } from "@opengeni/db";
|
|
9
4
|
import type { ControlActivityServices } from "./types";
|
|
10
5
|
|
|
11
6
|
export type AgentRunAdmissionDenial =
|
|
12
7
|
| "insufficient_credits"
|
|
13
|
-
| "allowance_exhausted"
|
|
14
8
|
| "monthly_model_cost_limit"
|
|
15
9
|
| "monthly_agent_run_limit";
|
|
16
10
|
|
|
@@ -22,8 +16,6 @@ export async function agentRunAdmissionDenial(
|
|
|
22
16
|
workspaceId: string;
|
|
23
17
|
model: string;
|
|
24
18
|
requestedAgentRuns: number;
|
|
25
|
-
/** The accepted work's causal human, not the scheduler/service caller. */
|
|
26
|
-
initiatingHumanSubjectId?: string | null;
|
|
27
19
|
},
|
|
28
20
|
): Promise<AgentRunAdmissionDenial | null> {
|
|
29
21
|
const codexBilled = await isCodexBilledTurn({
|
|
@@ -54,14 +46,6 @@ export async function agentRunAdmissionDenial(
|
|
|
54
46
|
if (balance.balanceMicros <= 0) return "insufficient_credits";
|
|
55
47
|
}
|
|
56
48
|
}
|
|
57
|
-
if (!externallyBilled) {
|
|
58
|
-
const refusal = await checkWorkspaceAllowance(services.db, {
|
|
59
|
-
accountId: input.accountId,
|
|
60
|
-
workspaceId: input.workspaceId,
|
|
61
|
-
subjectId: input.initiatingHumanSubjectId ?? null,
|
|
62
|
-
});
|
|
63
|
-
if (refusal) return refusal.code;
|
|
64
|
-
}
|
|
65
49
|
if (
|
|
66
50
|
services.settings.usageLimitsMode !== "static" &&
|
|
67
51
|
services.settings.usageLimitsMode !== "managed"
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { getBillingBalance, sumUsageQuantity } from "@opengeni/db";
|
|
2
2
|
import {
|
|
3
3
|
configuredStaticUsageLimits,
|
|
4
4
|
resolveTurnExecutionPolicyV1,
|
|
@@ -8,7 +8,6 @@ import { selectCodexCredentialId } from "@opengeni/codex";
|
|
|
8
8
|
import { directPersonalConnectionSubjectId } from "@opengeni/core";
|
|
9
9
|
import type { TurnActivityServices as ActivityServices } from "../types";
|
|
10
10
|
import {
|
|
11
|
-
type AllowanceExhaustedRefusal,
|
|
12
11
|
type SessionEvent,
|
|
13
12
|
type SessionTurn,
|
|
14
13
|
type ToolAuthNeededPayload,
|
|
@@ -244,65 +243,12 @@ export class BudgetExhaustedError extends Error {
|
|
|
244
243
|
constructor(
|
|
245
244
|
message: string,
|
|
246
245
|
readonly serializedRunState: string | null,
|
|
247
|
-
readonly allowance: AllowanceRefusal | null = null,
|
|
248
246
|
) {
|
|
249
247
|
super(message);
|
|
250
248
|
this.name = "BudgetExhaustedError";
|
|
251
249
|
}
|
|
252
250
|
}
|
|
253
251
|
|
|
254
|
-
export type AllowanceRefusal = AllowanceExhaustedRefusal;
|
|
255
|
-
|
|
256
|
-
/** Account allowance exhaustion is recoverable state, never a provider failure. */
|
|
257
|
-
export class AllowanceExhaustedError extends Error {
|
|
258
|
-
readonly code = "allowance_exhausted";
|
|
259
|
-
|
|
260
|
-
constructor(readonly refusal: AllowanceRefusal) {
|
|
261
|
-
super(refusal.message);
|
|
262
|
-
this.name = "AllowanceExhaustedError";
|
|
263
|
-
}
|
|
264
|
-
}
|
|
265
|
-
|
|
266
|
-
/** Revalidate between paid calls without replaying provider work or reserving credits. */
|
|
267
|
-
export async function ensureRunAllowedBetweenModelCalls(input: {
|
|
268
|
-
settings: Settings;
|
|
269
|
-
db: ActivityServices["db"];
|
|
270
|
-
accountId: string;
|
|
271
|
-
workspaceId: string;
|
|
272
|
-
isExternallyBilledTurn: boolean;
|
|
273
|
-
entitlements?: ActivityServices["entitlements"];
|
|
274
|
-
chargesOpenGeniCredits: boolean;
|
|
275
|
-
countsTowardTokenCap: boolean;
|
|
276
|
-
initiatingHumanSubjectId: string | null;
|
|
277
|
-
serializedRunState?: () => string | null;
|
|
278
|
-
}): Promise<void> {
|
|
279
|
-
try {
|
|
280
|
-
await ensureRunAllowed(
|
|
281
|
-
input.settings,
|
|
282
|
-
input.db,
|
|
283
|
-
input.accountId,
|
|
284
|
-
input.workspaceId,
|
|
285
|
-
input.isExternallyBilledTurn,
|
|
286
|
-
input.entitlements,
|
|
287
|
-
input.chargesOpenGeniCredits,
|
|
288
|
-
input.countsTowardTokenCap,
|
|
289
|
-
input.initiatingHumanSubjectId,
|
|
290
|
-
);
|
|
291
|
-
} catch (limitError) {
|
|
292
|
-
let serializedRunState: string | null = null;
|
|
293
|
-
try {
|
|
294
|
-
serializedRunState = input.serializedRunState?.() ?? null;
|
|
295
|
-
} catch {
|
|
296
|
-
// Durable history remains authoritative when the SDK state cannot serialize.
|
|
297
|
-
}
|
|
298
|
-
throw new BudgetExhaustedError(
|
|
299
|
-
limitError instanceof Error ? limitError.message : String(limitError),
|
|
300
|
-
serializedRunState,
|
|
301
|
-
limitError instanceof AllowanceExhaustedError ? limitError.refusal : null,
|
|
302
|
-
);
|
|
303
|
-
}
|
|
304
|
-
}
|
|
305
|
-
|
|
306
252
|
// Exported for unit testing the external-billing bypass (codex-billing.test.ts); not
|
|
307
253
|
// part of the activity surface. Takes the accepted policy's billing attribution and
|
|
308
254
|
// the optional §7.5 P3 host `entitlements` port (when bound, its `admitRun` REPLACES
|
|
@@ -316,7 +262,6 @@ export async function ensureRunAllowed(
|
|
|
316
262
|
entitlements?: ActivityServices["entitlements"],
|
|
317
263
|
chargesOpenGeniCredits = !isExternallyBilledTurn,
|
|
318
264
|
countsTowardTokenCap = !isExternallyBilledTurn,
|
|
319
|
-
initiatingHumanSubjectId: string | null = null,
|
|
320
265
|
): Promise<void> {
|
|
321
266
|
// Upstream settlement and workspace-facing cost are independent. External
|
|
322
267
|
// metering skips the token cap; free/subscription/workspace cost skips the
|
|
@@ -357,14 +302,6 @@ export async function ensureRunAllowed(
|
|
|
357
302
|
throw new Error("insufficient OpenGeni credits");
|
|
358
303
|
}
|
|
359
304
|
}
|
|
360
|
-
if (chargesOpenGeniCredits) {
|
|
361
|
-
const refusal = await checkWorkspaceAllowance(db, {
|
|
362
|
-
accountId,
|
|
363
|
-
workspaceId,
|
|
364
|
-
subjectId: initiatingHumanSubjectId,
|
|
365
|
-
});
|
|
366
|
-
if (refusal) throw new AllowanceExhaustedError(refusal);
|
|
367
|
-
}
|
|
368
305
|
if (settings.usageLimitsMode === "static" || settings.usageLimitsMode === "managed") {
|
|
369
306
|
const limits = configuredStaticUsageLimits(settings);
|
|
370
307
|
if (limits.maxMonthlyAgentRunsPerWorkspace) {
|
|
@@ -62,8 +62,6 @@ import {
|
|
|
62
62
|
turnExecutionPolicyBillingIdentity,
|
|
63
63
|
legacyTurnExecutionPolicyInput,
|
|
64
64
|
ensureRunAllowed,
|
|
65
|
-
AllowanceExhaustedError,
|
|
66
|
-
type AllowanceRefusal,
|
|
67
65
|
} from "./admission";
|
|
68
66
|
import { providerRecoveryCountFromMetadata, isWorkerShutdownCancellation } from "./errors";
|
|
69
67
|
import { throwIfTurnOperationCancelled, waitForTurnOperation } from "./sandbox-provision";
|
|
@@ -370,27 +368,20 @@ export async function claimTurnAttempt(deps: ClaimTurnDeps): Promise<ClaimTurnOu
|
|
|
370
368
|
// bypass OpenGeni credit/token gates)
|
|
371
369
|
// AND the optional host `entitlements` port (when bound, its admitRun replaces
|
|
372
370
|
// the local credit read). Unset port → today's local-ledger path.
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
cancellationSignal,
|
|
388
|
-
undefined,
|
|
389
|
-
);
|
|
390
|
-
} catch (error) {
|
|
391
|
-
if (!(error instanceof AllowanceExhaustedError)) throw error;
|
|
392
|
-
allowanceRefusal = error.refusal;
|
|
393
|
-
}
|
|
371
|
+
await waitForTurnOperation(
|
|
372
|
+
ensureRunAllowed(
|
|
373
|
+
capabilitySettings,
|
|
374
|
+
db,
|
|
375
|
+
input.accountId,
|
|
376
|
+
input.workspaceId,
|
|
377
|
+
billingState.isExternallyBilledTurn,
|
|
378
|
+
entitlements,
|
|
379
|
+
billingState.chargesOpenGeniCredits,
|
|
380
|
+
billingState.countsTowardTokenCap,
|
|
381
|
+
),
|
|
382
|
+
cancellationSignal,
|
|
383
|
+
undefined,
|
|
384
|
+
);
|
|
394
385
|
// Setup (variableSet load, MCP connects, sandbox restore) does not
|
|
395
386
|
// stream and so never observes cancellation on its own; these explicit
|
|
396
387
|
// checks let a graceful shutdown checkpoint the turn before the worker is
|
|
@@ -523,9 +514,6 @@ export async function claimTurnAttempt(deps: ClaimTurnDeps): Promise<ClaimTurnOu
|
|
|
523
514
|
...(inputSettlement.suppressGoalContinuation !== undefined
|
|
524
515
|
? { suppressGoalContinuation: inputSettlement.suppressGoalContinuation }
|
|
525
516
|
: {}),
|
|
526
|
-
...(inputSettlement.allowanceGoalPause
|
|
527
|
-
? { allowanceGoalPause: inputSettlement.allowanceGoalPause }
|
|
528
|
-
: {}),
|
|
529
517
|
events: inputs,
|
|
530
518
|
...(runState ? { runState } : {}),
|
|
531
519
|
...(compactionRequestFailure ? { compactionRequestFailure } : {}),
|
|
@@ -587,36 +575,6 @@ export async function claimTurnAttempt(deps: ClaimTurnDeps): Promise<ClaimTurnOu
|
|
|
587
575
|
durationSeconds: (performance.now() - activityStarted) / 1_000,
|
|
588
576
|
});
|
|
589
577
|
const turnStartSettlementStartedAt = performance.now();
|
|
590
|
-
if (allowanceRefusal) {
|
|
591
|
-
// Claim has frozen the exact human, but no provider or sandbox has started.
|
|
592
|
-
// Use the same terminal valve as a post-response stop, retaining a usable
|
|
593
|
-
// session and a visible typed refusal instead of manufacturing a failure.
|
|
594
|
-
if (
|
|
595
|
-
!(await eventing.settle({
|
|
596
|
-
events: [
|
|
597
|
-
{ type: "usage.exhausted", payload: allowanceRefusal },
|
|
598
|
-
{
|
|
599
|
-
type: "turn.completed",
|
|
600
|
-
payload: {
|
|
601
|
-
output: "",
|
|
602
|
-
segmentLimit: "budget_exhausted",
|
|
603
|
-
...allowanceRefusal,
|
|
604
|
-
},
|
|
605
|
-
},
|
|
606
|
-
{ type: "session.status.changed", payload: { status: "idle" } },
|
|
607
|
-
],
|
|
608
|
-
turnStatus: "completed",
|
|
609
|
-
sessionStatus: "idle",
|
|
610
|
-
activeTurnId: null,
|
|
611
|
-
allowanceGoalPause: { rationale: allowanceRefusal.message },
|
|
612
|
-
}))
|
|
613
|
-
) {
|
|
614
|
-
return { exit: claimedResult({ status: "cancelled" }) };
|
|
615
|
-
}
|
|
616
|
-
control.turnMetricOutcome = "completed";
|
|
617
|
-
control.activityStatus = "idle";
|
|
618
|
-
return { exit: claimedResult({ status: "idle" }) };
|
|
619
|
-
}
|
|
620
578
|
if (
|
|
621
579
|
!(await eventing.settle({
|
|
622
580
|
events: [
|
|
@@ -35,17 +35,6 @@ export async function createClaudeUsageObserver(
|
|
|
35
35
|
.map(async (provider) => {
|
|
36
36
|
const scope: Scope =
|
|
37
37
|
provider.kind === "claude-subscription-workspace" ? "workspace" : "organization";
|
|
38
|
-
const binding = provider.anthropic?.credentialBinding;
|
|
39
|
-
if (binding && provider.apiKey)
|
|
40
|
-
return [
|
|
41
|
-
provider.id,
|
|
42
|
-
{
|
|
43
|
-
scope,
|
|
44
|
-
token: provider.apiKey,
|
|
45
|
-
expectedConnectionId: binding.connectionId,
|
|
46
|
-
expectedCredentialVersion: binding.credentialVersion,
|
|
47
|
-
},
|
|
48
|
-
] as const;
|
|
49
38
|
const credential = await readCredential(scope).catch(() => null);
|
|
50
39
|
if (!credential || credential.token !== provider.apiKey) return null;
|
|
51
40
|
return [
|
|
@@ -60,7 +49,7 @@ export async function createClaudeUsageObserver(
|
|
|
60
49
|
}),
|
|
61
50
|
);
|
|
62
51
|
const captured = new Map(bindings.filter((binding) => binding !== null));
|
|
63
|
-
|
|
52
|
+
return (providerId: string, response: Response) => {
|
|
64
53
|
const binding = captured.get(providerId);
|
|
65
54
|
if (!binding) return;
|
|
66
55
|
const { scope, ...identity } = binding;
|
|
@@ -87,25 +76,4 @@ export async function createClaudeUsageObserver(
|
|
|
87
76
|
: {}),
|
|
88
77
|
});
|
|
89
78
|
};
|
|
90
|
-
return Object.assign(observe, {
|
|
91
|
-
binding(providerId: string) {
|
|
92
|
-
return captured.get(providerId);
|
|
93
|
-
},
|
|
94
|
-
renew(
|
|
95
|
-
providerId: string,
|
|
96
|
-
credential: {
|
|
97
|
-
token: string;
|
|
98
|
-
connectionId: string;
|
|
99
|
-
credentialVersion: number;
|
|
100
|
-
},
|
|
101
|
-
) {
|
|
102
|
-
const binding = captured.get(providerId);
|
|
103
|
-
if (
|
|
104
|
-
binding &&
|
|
105
|
-
binding.expectedConnectionId === credential.connectionId &&
|
|
106
|
-
binding.expectedCredentialVersion === credential.credentialVersion
|
|
107
|
-
)
|
|
108
|
-
captured.set(providerId, { ...binding, token: credential.token });
|
|
109
|
-
},
|
|
110
|
-
});
|
|
111
79
|
}
|
|
@@ -20,7 +20,6 @@ import {
|
|
|
20
20
|
isModalTaskExecStartPreDispatchUnavailableError,
|
|
21
21
|
isRoutingMutationOutcomeUnknownError,
|
|
22
22
|
RoutingWorkspaceRootChangedError,
|
|
23
|
-
ResponsesStreamingTerminalError,
|
|
24
23
|
SandboxMaterializationVerificationError,
|
|
25
24
|
materializationVerificationDiagnostic,
|
|
26
25
|
type MaterializationVerificationDiagnostic,
|
|
@@ -730,7 +729,6 @@ export function shouldRecoverCompactionProviderFailure(error: unknown): boolean
|
|
|
730
729
|
export function classifyContextWindowOverflowError(
|
|
731
730
|
error: unknown,
|
|
732
731
|
): { message: string; code?: string; detail?: string } | null {
|
|
733
|
-
if (isProviderSafetyRefusal(error)) return null;
|
|
734
732
|
const fields = collectErrorStrings(error);
|
|
735
733
|
const matched = fields.find(
|
|
736
734
|
(value) =>
|
|
@@ -797,9 +795,6 @@ export function collectErrorStrings(value: unknown, seen = new WeakSet<object>()
|
|
|
797
795
|
}
|
|
798
796
|
seen.add(value);
|
|
799
797
|
const out: string[] = [];
|
|
800
|
-
// This diagnostic is already provider-owned and byte-bounded. Do not widen
|
|
801
|
-
// generic detail traversal to arbitrary application payloads.
|
|
802
|
-
if (value instanceof ResponsesStreamingTerminalError) out.push(value.detail);
|
|
803
798
|
const record = value as Record<string, unknown>;
|
|
804
799
|
for (const key of ["message", "code", "type", "name", "param"]) {
|
|
805
800
|
const field = record[key];
|
|
@@ -862,9 +857,6 @@ export function isExactStatuslessUpstreamConnectivityMessage(message: string): b
|
|
|
862
857
|
}
|
|
863
858
|
|
|
864
859
|
function providerSafetyRefusalDiagnostic(error: unknown): string | undefined {
|
|
865
|
-
if (error instanceof ResponsesStreamingTerminalError) {
|
|
866
|
-
return error.category === "safety" ? error.detail : undefined;
|
|
867
|
-
}
|
|
868
860
|
return collectErrorStrings(error).find(
|
|
869
861
|
(value) =>
|
|
870
862
|
/^(?:content_policy_violation|content_filter|safety_violation|bio_policy|cyber_policy)$/.test(
|
|
@@ -878,9 +870,6 @@ function isProviderSafetyRefusal(error: unknown): boolean {
|
|
|
878
870
|
}
|
|
879
871
|
|
|
880
872
|
export function isTransientProviderError(error: unknown): boolean {
|
|
881
|
-
if (error instanceof ResponsesStreamingTerminalError) {
|
|
882
|
-
return error.category === "unavailable";
|
|
883
|
-
}
|
|
884
873
|
// A semantic refusal can arrive inside a 5xx transport envelope.
|
|
885
874
|
if (isProviderSafetyRefusal(error)) return false;
|
|
886
875
|
const status =
|
|
@@ -1079,41 +1068,6 @@ function baseAgentRunFailurePayload(
|
|
|
1079
1068
|
detail: safetyRefusalDiagnostic,
|
|
1080
1069
|
};
|
|
1081
1070
|
}
|
|
1082
|
-
if (error instanceof ResponsesStreamingTerminalError) {
|
|
1083
|
-
const quota =
|
|
1084
|
-
error.category === "unknown" || error.category === "rate_limit"
|
|
1085
|
-
? classifyProviderQuotaExhaustionError({
|
|
1086
|
-
code: error.code,
|
|
1087
|
-
error: { code: error.code, type: error.type, message: error.detail },
|
|
1088
|
-
retryAfterSeconds: error.retryAfterSeconds,
|
|
1089
|
-
})
|
|
1090
|
-
: null;
|
|
1091
|
-
if (quota) {
|
|
1092
|
-
return {
|
|
1093
|
-
error: providerQuotaExhaustedMessage(quota.scope),
|
|
1094
|
-
code: PROVIDER_QUOTA_EXHAUSTED_CODE,
|
|
1095
|
-
retryable: false,
|
|
1096
|
-
quotaScope: quota.scope,
|
|
1097
|
-
detail: error.detail,
|
|
1098
|
-
};
|
|
1099
|
-
}
|
|
1100
|
-
return {
|
|
1101
|
-
error:
|
|
1102
|
-
error.category === "rate_limit"
|
|
1103
|
-
? "Model provider rate limit hit. Try again in a minute or lower the reasoning effort."
|
|
1104
|
-
: error.category === "unavailable"
|
|
1105
|
-
? "The model provider is temporarily unavailable. The same turn will retry after a short delay."
|
|
1106
|
-
: "The model provider rejected the response. Automatic retries stopped.",
|
|
1107
|
-
code:
|
|
1108
|
-
error.category === "rate_limit"
|
|
1109
|
-
? "provider_rate_limited"
|
|
1110
|
-
: error.category === "unavailable"
|
|
1111
|
-
? "provider_unavailable"
|
|
1112
|
-
: "provider_request_rejected",
|
|
1113
|
-
retryable: error.category === "rate_limit" || error.category === "unavailable",
|
|
1114
|
-
detail: error.detail,
|
|
1115
|
-
};
|
|
1116
|
-
}
|
|
1117
1071
|
const message = error instanceof Error ? error.message : String(error);
|
|
1118
1072
|
const status =
|
|
1119
1073
|
typeof error === "object" && error !== null
|
|
@@ -1536,16 +1536,12 @@ export async function settleTurnFailure(deps: TurnFailureDeps): Promise<RunAgent
|
|
|
1536
1536
|
if (
|
|
1537
1537
|
!(await eventing.settle!({
|
|
1538
1538
|
events: [
|
|
1539
|
-
...(error.allowance
|
|
1540
|
-
? [{ type: "usage.exhausted" as const, payload: error.allowance }]
|
|
1541
|
-
: []),
|
|
1542
1539
|
{
|
|
1543
1540
|
type: "turn.completed",
|
|
1544
1541
|
payload: {
|
|
1545
1542
|
output: "",
|
|
1546
1543
|
segmentLimit: "budget_exhausted",
|
|
1547
1544
|
detail: error.message,
|
|
1548
|
-
...(error.allowance ?? {}),
|
|
1549
1545
|
},
|
|
1550
1546
|
},
|
|
1551
1547
|
{ type: "session.status.changed", payload: { status: "idle" } },
|
|
@@ -1553,7 +1549,6 @@ export async function settleTurnFailure(deps: TurnFailureDeps): Promise<RunAgent
|
|
|
1553
1549
|
turnStatus: "completed",
|
|
1554
1550
|
sessionStatus: "idle",
|
|
1555
1551
|
activeTurnId: null,
|
|
1556
|
-
...(error.allowance ? { allowanceGoalPause: { rationale: error.allowance.message } } : {}),
|
|
1557
1552
|
}))
|
|
1558
1553
|
) {
|
|
1559
1554
|
return claimedResult({ status: "cancelled" });
|
|
@@ -28,8 +28,6 @@ import {
|
|
|
28
28
|
type loadWorkspaceEnvironmentForRunWithCredentials,
|
|
29
29
|
} from "../environment";
|
|
30
30
|
import type { mergeResourceRefs } from "../common";
|
|
31
|
-
import type { withFirstPartyTools } from "../goals";
|
|
32
|
-
import { expandMcpAccountRoutes } from "../mcp-account-routes";
|
|
33
31
|
import { startGitCredentialRenewalLoop } from "../git-credential-renewal";
|
|
34
32
|
import {
|
|
35
33
|
RUN_CREDENTIAL_EXPIRY_LEAD_MS,
|
|
@@ -76,7 +74,6 @@ import type {
|
|
|
76
74
|
|
|
77
75
|
export type PrepareRunCredentialsDeps = {
|
|
78
76
|
localMcpServerIds?: readonly string[];
|
|
79
|
-
turnTools: ReturnType<typeof withFirstPartyTools>;
|
|
80
77
|
input: RunAgentTurnInput;
|
|
81
78
|
settings: Settings;
|
|
82
79
|
db: ActivityServices["db"];
|
|
@@ -156,14 +153,6 @@ export async function prepareRunCredentials(deps: PrepareRunCredentialsDeps) {
|
|
|
156
153
|
const platformGitResources = turnResources.filter(
|
|
157
154
|
(resource) => resource.kind !== "repository" || repositoryHasExplicitGitConnection(resource),
|
|
158
155
|
);
|
|
159
|
-
// Credential targets follow the same accepted-account narrowing as execution.
|
|
160
|
-
// A canonical connection without an accepted account does not execute, and
|
|
161
|
-
// account-qualified aliases never inherit an attachment's product headers.
|
|
162
|
-
const accountRoutes = expandMcpAccountRoutes({
|
|
163
|
-
settings: runSettings,
|
|
164
|
-
tools: deps.turnTools,
|
|
165
|
-
bindings: turn.mcpAccountBindings,
|
|
166
|
-
});
|
|
167
156
|
|
|
168
157
|
const runCredentialResolver =
|
|
169
158
|
effectiveRunCredentialBackend === "none" || effectiveRunCredentialBackend === "selfhosted"
|
|
@@ -171,11 +160,10 @@ export async function prepareRunCredentials(deps: PrepareRunCredentialsDeps) {
|
|
|
171
160
|
: await waitForTurnOperation(
|
|
172
161
|
bindRunCredentialResolver({
|
|
173
162
|
db,
|
|
174
|
-
settings:
|
|
163
|
+
settings: runSettings,
|
|
175
164
|
initiatingHumanSubjectId: turn.initiatingHumanSubjectId ?? null,
|
|
176
165
|
connectionCredentials: connectionCredentials ?? null,
|
|
177
166
|
localMcpServerIds: deps.localMcpServerIds ?? [],
|
|
178
|
-
effectiveTools: accountRoutes.tools,
|
|
179
167
|
accountId: input.accountId,
|
|
180
168
|
workspaceId: input.workspaceId,
|
|
181
169
|
session,
|
|
@@ -226,9 +214,9 @@ export async function prepareRunCredentials(deps: PrepareRunCredentialsDeps) {
|
|
|
226
214
|
: null;
|
|
227
215
|
const runMcpCredentials = new RunMcpCredentials(
|
|
228
216
|
selectedSessionRemoteMcpTargets(
|
|
229
|
-
|
|
217
|
+
runSettings,
|
|
230
218
|
session.mcpServers ?? [],
|
|
231
|
-
|
|
219
|
+
turn.tools ?? [],
|
|
232
220
|
(deps.localMcpServerIds ?? []).map((id) => ({ id })),
|
|
233
221
|
),
|
|
234
222
|
{
|
|
@@ -3,8 +3,6 @@ import {
|
|
|
3
3
|
readActiveSandbox,
|
|
4
4
|
getWorkspaceCredentialProvider,
|
|
5
5
|
loadClaudeSubscriptionUsageCredential,
|
|
6
|
-
resolveClaudeSubscriptionCredential,
|
|
7
|
-
ClaudeSubscriptionReconnectRequired,
|
|
8
6
|
} from "@opengeni/db";
|
|
9
7
|
import { routingEnabled } from "../../sandbox-routing";
|
|
10
8
|
import { createKnowledgeSourceSyncActivities } from "../knowledge-source-sync";
|
|
@@ -28,7 +26,6 @@ import {
|
|
|
28
26
|
import {
|
|
29
27
|
REMOTE_COMPACTION_V2_BETA_FEATURE,
|
|
30
28
|
REMOTE_COMPACTION_V2_IMPLEMENTATION,
|
|
31
|
-
awaitModelCallAdmission,
|
|
32
29
|
materializeSandboxFileDownloads,
|
|
33
30
|
sandboxFileDownloadFailureNote,
|
|
34
31
|
type SandboxFileDownload,
|
|
@@ -381,14 +378,12 @@ export function createRunAgentTurnActivity(services: () => Promise<ActivityServi
|
|
|
381
378
|
getModelRunSettings: () => eventing.modelRunSettings,
|
|
382
379
|
getExecutionGeneration: () => attempt.executionGeneration,
|
|
383
380
|
});
|
|
384
|
-
const checkpointBeforeProviderDispatch =
|
|
385
|
-
|
|
386
|
-
await checkpointHistoryBeforeProviderDispatch(historySink, {
|
|
381
|
+
const checkpointBeforeProviderDispatch = () =>
|
|
382
|
+
checkpointHistoryBeforeProviderDispatch(historySink, {
|
|
387
383
|
effectiveSandboxBackend: eventing.modelRunSettings.sandboxBackend,
|
|
388
384
|
routingEnabled: routingEnabled(settings),
|
|
389
385
|
readActiveSandbox: () => readActiveSandbox(db, input.workspaceId, input.sessionId),
|
|
390
386
|
});
|
|
391
|
-
};
|
|
392
387
|
|
|
393
388
|
try {
|
|
394
389
|
const claimed = await claimTurnAttempt({
|
|
@@ -937,30 +932,7 @@ export function createRunAgentTurnActivity(services: () => Promise<ActivityServi
|
|
|
937
932
|
}),
|
|
938
933
|
);
|
|
939
934
|
const withClaudeUsage = <T>(fn: () => Promise<T>): Promise<T> =>
|
|
940
|
-
withClaudeUsageObserver(claudeUsageObserver, fn
|
|
941
|
-
const binding = claudeUsageObserver.binding(providerId);
|
|
942
|
-
if (!binding) return headers;
|
|
943
|
-
const credential = await resolveClaudeSubscriptionCredential(
|
|
944
|
-
db,
|
|
945
|
-
settings,
|
|
946
|
-
{
|
|
947
|
-
accountId: input.accountId,
|
|
948
|
-
workspaceId: input.workspaceId,
|
|
949
|
-
scope: binding.scope,
|
|
950
|
-
},
|
|
951
|
-
{
|
|
952
|
-
expectedConnectionId: binding.expectedConnectionId,
|
|
953
|
-
expectedCredentialVersion: binding.expectedCredentialVersion,
|
|
954
|
-
},
|
|
955
|
-
);
|
|
956
|
-
if (!credential) return headers; // A replaced connection never lends its new token to this turn.
|
|
957
|
-
if ("reconnectRequired" in credential)
|
|
958
|
-
throw new ClaudeSubscriptionReconnectRequired();
|
|
959
|
-
claudeUsageObserver.renew(providerId, credential);
|
|
960
|
-
headers.set("authorization", `Bearer ${credential.token}`);
|
|
961
|
-
headers.delete("x-api-key");
|
|
962
|
-
return headers;
|
|
963
|
-
});
|
|
935
|
+
withClaudeUsageObserver(claudeUsageObserver, fn);
|
|
964
936
|
const withCodex = <T>(fn: () => Promise<T>): Promise<T> =>
|
|
965
937
|
codexContext ? codexRequestStorage.run(codexContext, fn) : fn();
|
|
966
938
|
const withProviderRequestContext = <T>(fn: () => Promise<T>): Promise<T> =>
|
|
@@ -1203,7 +1175,6 @@ export function createRunAgentTurnActivity(services: () => Promise<ActivityServi
|
|
|
1203
1175
|
);
|
|
1204
1176
|
|
|
1205
1177
|
const runCredentials = await prepareRunCredentials({
|
|
1206
|
-
turnTools,
|
|
1207
1178
|
localMcpServerIds: installedApiIntegrations.map((integration) => integration.serverId),
|
|
1208
1179
|
input,
|
|
1209
1180
|
settings,
|