@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
|
@@ -1,6 +1,17 @@
|
|
|
1
1
|
import { type parseModelProvidersJson, type ClaudeUsageObservation } from "@opengeni/config";
|
|
2
2
|
type Scope = "workspace" | "organization";
|
|
3
|
+
type ClaudeRequestCredential = {
|
|
4
|
+
token: string;
|
|
5
|
+
connectionId: string;
|
|
6
|
+
credentialVersion: number;
|
|
7
|
+
};
|
|
8
|
+
export declare class ClaudeSubscriptionConnectionUnavailable extends Error {
|
|
9
|
+
readonly status = 409;
|
|
10
|
+
readonly code = "claude_subscription_connection_changed";
|
|
11
|
+
constructor();
|
|
12
|
+
}
|
|
3
13
|
export type CapturedClaudeUsage = {
|
|
14
|
+
scope: Scope;
|
|
4
15
|
token: string;
|
|
5
16
|
expectedConnectionId: string;
|
|
6
17
|
expectedCredentialVersion: number;
|
|
@@ -11,16 +22,29 @@ export type CapturedClaudeUsage = {
|
|
|
11
22
|
};
|
|
12
23
|
};
|
|
13
24
|
/** Capture the exact credential before requests; replacement fences late responses. */
|
|
14
|
-
export declare function createClaudeUsageObserver(providers: ReturnType<typeof parseModelProvidersJson>, latest: Map<
|
|
25
|
+
export declare function createClaudeUsageObserver(providers: ReturnType<typeof parseModelProvidersJson>, latest: Map<string, CapturedClaudeUsage>, readCredential: (scope: Scope) => Promise<{
|
|
15
26
|
token: string;
|
|
16
27
|
connectionId: string;
|
|
17
28
|
credentialVersion: number;
|
|
18
|
-
} | null>): Promise<((providerId: string, response: Response) => void) & {
|
|
29
|
+
} | null>): Promise<((providerId: string, response: Response, upstreamModelId?: string, requestToken?: string | null) => void) & {
|
|
30
|
+
prepareRequestWithObserver: (providerId: string, headers: Headers, resolve: (binding: {
|
|
31
|
+
scope: Scope;
|
|
32
|
+
expectedConnectionId: string;
|
|
33
|
+
expectedCredentialVersion: number;
|
|
34
|
+
}) => Promise<ClaudeRequestCredential | null>) => Promise<{
|
|
35
|
+
headers: Headers;
|
|
36
|
+
observe: (providerId: string, response: Response, upstreamModelId?: string, requestToken?: string | null) => void;
|
|
37
|
+
}>;
|
|
38
|
+
prepareRequest(providerId: string, headers: Headers, resolve: (binding: {
|
|
39
|
+
scope: Scope;
|
|
40
|
+
expectedConnectionId: string;
|
|
41
|
+
expectedCredentialVersion: number;
|
|
42
|
+
}) => Promise<ClaudeRequestCredential | null>): Promise<Headers>;
|
|
19
43
|
binding(providerId: string): {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
44
|
+
scope: Scope;
|
|
45
|
+
token: string;
|
|
46
|
+
expectedConnectionId: string;
|
|
47
|
+
expectedCredentialVersion: number;
|
|
24
48
|
} | undefined;
|
|
25
49
|
renew(providerId: string, credential: {
|
|
26
50
|
token: string;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { SharedActivityServices } from "../types.js";
|
|
2
|
-
|
|
3
|
-
export type LeaseLossReason
|
|
2
|
+
import { SubscriptionTurnLease, type LeaseRenewReason, type LeaseLossReason } from "./subscription-lease.js";
|
|
3
|
+
export type { LeaseRenewReason, LeaseLossReason } from "./subscription-lease.js";
|
|
4
4
|
export declare class CodexCredentialLeaseLostError extends Error {
|
|
5
5
|
readonly reason: LeaseLossReason;
|
|
6
6
|
readonly code = "codex_credential_lease_lost";
|
|
@@ -19,40 +19,13 @@ export type TurnCredentialLeaseDeps = {
|
|
|
19
19
|
* cross-replica fairness primitive; the heartbeat here only extends its short
|
|
20
20
|
* TTL. A killed worker stops heartbeating and the holder self-expires.
|
|
21
21
|
*/
|
|
22
|
-
export declare class CodexTurnLease {
|
|
23
|
-
private readonly deps;
|
|
24
|
-
held: boolean;
|
|
25
|
-
lost: boolean;
|
|
26
|
-
lossReason: LeaseLossReason | null;
|
|
27
|
-
holderId: string | null;
|
|
28
|
-
generation: number | null;
|
|
29
|
-
confirmedUntilMs: number | null;
|
|
30
|
-
private heartbeatInFlight;
|
|
31
|
-
private heartbeatTimer;
|
|
22
|
+
export declare class CodexTurnLease extends SubscriptionTurnLease {
|
|
32
23
|
constructor(deps: TurnCredentialLeaseDeps);
|
|
33
|
-
markLost: (reason: LeaseLossReason) => void;
|
|
34
|
-
/** Fail closed at the last worker-confirmed lease deadline before dispatch. */
|
|
35
|
-
assertUsable: () => void;
|
|
36
|
-
renew: (reason: LeaseRenewReason) => Promise<void>;
|
|
37
|
-
startHeartbeat: () => void;
|
|
38
|
-
stopHeartbeat: () => void;
|
|
39
24
|
}
|
|
40
|
-
/**
|
|
41
|
-
export declare class XaiTurnLease {
|
|
42
|
-
private readonly deps;
|
|
43
|
-
held: boolean;
|
|
44
|
-
lost: boolean;
|
|
25
|
+
/** SuperGrok uses the same deadline and holder fences as Codex. */
|
|
26
|
+
export declare class XaiTurnLease extends SubscriptionTurnLease {
|
|
45
27
|
subjectId: string | null;
|
|
46
|
-
holderId: string | null;
|
|
47
|
-
generation: number | null;
|
|
48
|
-
confirmedUntilMs: number | null;
|
|
49
|
-
private heartbeatInFlight;
|
|
50
|
-
private heartbeatTimer;
|
|
51
28
|
constructor(deps: TurnCredentialLeaseDeps);
|
|
52
|
-
markLost: (reason: LeaseLossReason) => void;
|
|
53
|
-
renew: () => Promise<void>;
|
|
54
|
-
startHeartbeat: () => void;
|
|
55
|
-
stopHeartbeat: () => void;
|
|
56
29
|
}
|
|
57
30
|
/** Both serving-credential leases for one turn attempt plus their composite views. */
|
|
58
31
|
export type TurnCredentialLeases = {
|
|
@@ -90,6 +90,7 @@ export declare function postClaimDatabaseRecoveryFailure(input: {
|
|
|
90
90
|
triggerEventId: string;
|
|
91
91
|
executionGeneration: number;
|
|
92
92
|
sandboxSetupOutcomeUnknown?: true;
|
|
93
|
+
sandboxSetupRecoveryExhausted?: true;
|
|
93
94
|
providerRecovery?: {
|
|
94
95
|
failureCode: string;
|
|
95
96
|
providerRecoveryCount: number;
|
|
@@ -266,6 +267,8 @@ export declare function classifyXaiCredentialFailure(error: unknown): XaiCredent
|
|
|
266
267
|
export declare function agentRunFailurePayload(error: unknown, options?: {
|
|
267
268
|
isCodexTurn?: boolean;
|
|
268
269
|
}): ReturnType<typeof baseAgentRunFailurePayload>;
|
|
270
|
+
/** Keep Anthropic provider text on terminal failures, never recovery events. */
|
|
271
|
+
export declare function agentRunRecoveryFailurePayload(error: unknown, failure: ReturnType<typeof agentRunFailurePayload>): ReturnType<typeof agentRunFailurePayload>;
|
|
269
272
|
declare function baseAgentRunFailurePayload(error: unknown, options?: {
|
|
270
273
|
isCodexTurn?: boolean;
|
|
271
274
|
}): {
|
|
@@ -8,7 +8,7 @@ export declare function startTurnFinalizationMonitor(input: {
|
|
|
8
8
|
observability: Observability;
|
|
9
9
|
details: TurnHeartbeatDetails;
|
|
10
10
|
heartbeat: (details: TurnHeartbeatDetails) => void;
|
|
11
|
-
|
|
11
|
+
requestWorkerDrain: () => void;
|
|
12
12
|
timeoutMs?: number;
|
|
13
13
|
slowAfterMs?: number;
|
|
14
14
|
}): {
|
|
@@ -16,6 +16,8 @@ export type TurnFinalizationDeps = {
|
|
|
16
16
|
wakeSessionWorkflow: ActivityServices["wakeSessionWorkflow"];
|
|
17
17
|
signalSessionAttemptQuiesced: ActivityServices["signalSessionAttemptQuiesced"];
|
|
18
18
|
signalCodexCapacityWorkflow: ActivityServices["signalCodexCapacityWorkflow"];
|
|
19
|
+
requestWorkerDrain: ActivityServices["requestWorkerDrain"];
|
|
20
|
+
turnFinalizationTimeoutMs: ActivityServices["turnFinalizationTimeoutMs"];
|
|
19
21
|
cancellationSignal: AbortSignal | undefined;
|
|
20
22
|
sandboxResumeController: AbortController;
|
|
21
23
|
activityContext: ReturnType<typeof currentActivityContext>;
|
|
@@ -49,10 +49,9 @@ export declare const QUIESCENCE_PROOF_SIGNAL_INITIAL_RETRY_MS = 250;
|
|
|
49
49
|
export declare const QUIESCENCE_PROOF_SIGNAL_MAX_RETRY_MS = 5000;
|
|
50
50
|
export declare const TURN_QUIESCENCE_WATCHDOG_MS: number;
|
|
51
51
|
export declare const TURN_FINALIZER_STEP_TIMEOUT_MS = 30000;
|
|
52
|
-
/** A fenced activity must never heartbeat forever while
|
|
53
|
-
*
|
|
54
|
-
*
|
|
55
|
-
* then commits the exact quiescence receipt. */
|
|
52
|
+
/** A fenced activity must never heartbeat forever while physical cleanup is
|
|
53
|
+
* stuck. The callback requests host-owned containment, which drains peer turns
|
|
54
|
+
* before applying its final exit policy. A timeout is never quiescence proof. */
|
|
56
55
|
export declare function armTurnQuiescenceWatchdog(input: {
|
|
57
56
|
enabled: boolean;
|
|
58
57
|
timeoutMs?: number;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
export type LeaseRenewReason = "timer" | "runtime_event" | "model_usage";
|
|
2
|
+
export type LeaseLossReason = "deadline" | "not_found";
|
|
3
|
+
type LeaseIdentity = {
|
|
4
|
+
turnId: string;
|
|
5
|
+
holderId: string;
|
|
6
|
+
generation: number;
|
|
7
|
+
};
|
|
8
|
+
export type SubscriptionLeaseDeps = {
|
|
9
|
+
ttlMs: number;
|
|
10
|
+
getTurnId: () => string | undefined;
|
|
11
|
+
heartbeat: (identity: LeaseIdentity) => Promise<Date | null>;
|
|
12
|
+
onLost: (reason: LeaseLossReason) => void;
|
|
13
|
+
onRenewed?: (reason: LeaseRenewReason) => void;
|
|
14
|
+
onError: (error: unknown, reason: LeaseRenewReason) => void;
|
|
15
|
+
lostError: (reason: LeaseLossReason) => Error;
|
|
16
|
+
now?: () => number;
|
|
17
|
+
};
|
|
18
|
+
/** Cross-provider lease lifecycle. Only on-time DB confirmation extends ownership. */
|
|
19
|
+
export declare class SubscriptionTurnLease {
|
|
20
|
+
private readonly leaseDeps;
|
|
21
|
+
held: boolean;
|
|
22
|
+
lost: boolean;
|
|
23
|
+
lossReason: LeaseLossReason | null;
|
|
24
|
+
holderId: string | null;
|
|
25
|
+
generation: number | null;
|
|
26
|
+
confirmedUntilMs: number | null;
|
|
27
|
+
private heartbeatInFlight;
|
|
28
|
+
private heartbeatTimer;
|
|
29
|
+
private readonly now;
|
|
30
|
+
constructor(leaseDeps: SubscriptionLeaseDeps);
|
|
31
|
+
private expired;
|
|
32
|
+
markLost: (reason: LeaseLossReason) => void;
|
|
33
|
+
assertUsable: () => void;
|
|
34
|
+
renew: (reason?: LeaseRenewReason) => Promise<void>;
|
|
35
|
+
startHeartbeat: () => void;
|
|
36
|
+
stopHeartbeat: () => void;
|
|
37
|
+
}
|
|
38
|
+
export {};
|
|
@@ -146,7 +146,7 @@ export type ProviderTurnState = {
|
|
|
146
146
|
xaiCredentialQuarantined: boolean;
|
|
147
147
|
priorSessionCodexCredentialId: string | null;
|
|
148
148
|
latestCodexUsage: CodexUsageHeaderSnapshot | null;
|
|
149
|
-
latestClaudeUsage: Map<
|
|
149
|
+
latestClaudeUsage: Map<string, import("./claude-usage-observer.js").CapturedClaudeUsage>;
|
|
150
150
|
lastCodexRequestOpaqueArtifacts: readonly string[];
|
|
151
151
|
};
|
|
152
152
|
export type TurnContext = {
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { listWorkspaceIdsAfter, reconcileModelCallFacts } from "@opengeni/db";
|
|
2
|
+
import type { ControlActivityServices } from "./types.js";
|
|
3
|
+
/** Recent charged calls are rechecked on every run; older gaps use the backfill script. */
|
|
4
|
+
export declare const MODEL_CALL_FACT_RECONCILE_LOOKBACK_MS: number;
|
|
5
|
+
/** Skip the newest calls so a live fact write is not raced by its own repair. */
|
|
6
|
+
export declare const MODEL_CALL_FACT_RECONCILE_SETTLE_MS: number;
|
|
7
|
+
export declare const MODEL_CALL_FACT_RECONCILE_WORKSPACE_LIMIT = 500;
|
|
8
|
+
export declare const MODEL_CALL_FACT_RECONCILE_RUN_BUDGET_MS: number;
|
|
9
|
+
export type ReconcileRecentModelCallFactsResult = {
|
|
10
|
+
workspaces: number;
|
|
11
|
+
missing: number;
|
|
12
|
+
repaired: number;
|
|
13
|
+
unrepaired: number;
|
|
14
|
+
/** Workspaces with more missing facts than one bounded pass examines. */
|
|
15
|
+
truncatedWorkspaces: number;
|
|
16
|
+
failedWorkspaces: number;
|
|
17
|
+
budgetExhausted: boolean;
|
|
18
|
+
};
|
|
19
|
+
export type ModelCallFactReconcilerOptions = {
|
|
20
|
+
now?: () => number;
|
|
21
|
+
runBudgetMs?: number;
|
|
22
|
+
startAfterWorkspaceId?: () => string;
|
|
23
|
+
reconcile?: typeof reconcileModelCallFacts;
|
|
24
|
+
listWorkspaces?: typeof listWorkspaceIdsAfter;
|
|
25
|
+
};
|
|
26
|
+
/**
|
|
27
|
+
* Rebuild missing Insights call facts for recently charged model calls. Each
|
|
28
|
+
* workspace pass is bounded and idempotent, one failure never stops the rest,
|
|
29
|
+
* and each run starts at a random workspace so a run that exhausts its budget
|
|
30
|
+
* does not starve the same tail of workspaces every time.
|
|
31
|
+
*/
|
|
32
|
+
export declare function createModelCallFactReconcilerActivities(services: () => Promise<ControlActivityServices>, options?: ModelCallFactReconcilerOptions): {
|
|
33
|
+
reconcileRecentModelCallFacts: () => Promise<ReconcileRecentModelCallFactsResult>;
|
|
34
|
+
};
|
|
@@ -53,8 +53,8 @@ export declare function createSessionStateActivities(services: () => Promise<Con
|
|
|
53
53
|
admissionFence?: import("@opengeni/db").SessionAdmissionFence;
|
|
54
54
|
} | {
|
|
55
55
|
kind: "admission-blocked";
|
|
56
|
-
reason?: "sandbox_setup_outcome_unknown";
|
|
57
|
-
ref?: import("@opengeni/db").SandboxSetupOutcomeUnknown;
|
|
56
|
+
reason?: "sandbox_setup_outcome_unknown" | "sandbox_setup_recovery_exhausted";
|
|
57
|
+
ref?: import("@opengeni/db").SandboxSetupOutcomeUnknown | import("@opengeni/db").SandboxSetupRecoveryExhausted;
|
|
58
58
|
} | {
|
|
59
59
|
kind: "sandbox-lifecycle-wait";
|
|
60
60
|
ref: import("@opengeni/db").SandboxLifecycleWait;
|
|
@@ -87,6 +87,11 @@ export type SharedActivityServices = {
|
|
|
87
87
|
export type ControlActivityServices = SharedActivityServices;
|
|
88
88
|
/** Turn workers own the model loop and never construct document parsers. */
|
|
89
89
|
export type TurnActivityServices = SharedActivityServices & {
|
|
90
|
+
/** Host-owned containment: stop polling and checkpoint peer turns before exit.
|
|
91
|
+
* Bare activity embedders must provide their own worker lifecycle edge. */
|
|
92
|
+
requestWorkerDrain: () => void;
|
|
93
|
+
/** Deterministic test clock for the cleanup-only monitor. */
|
|
94
|
+
turnFinalizationTimeoutMs?: number | undefined;
|
|
90
95
|
runtime: OpenGeniRuntime;
|
|
91
96
|
/** Provider-free test/profiling seam; production injects the real runtime summarizer. */
|
|
92
97
|
summarizeContextForCompaction: typeof import("@opengeni/runtime").summarizeForCompaction;
|
|
@@ -237,6 +242,8 @@ export type PostClaimDatabaseRecoveryDetail = {
|
|
|
237
242
|
providerFailureCode?: string;
|
|
238
243
|
/** Persist the no-replay setup marker, not a new provider/setup attempt. */
|
|
239
244
|
sandboxSetupOutcomeUnknown?: true;
|
|
245
|
+
/** Preserve the exhausted budget for a command proven not dispatched. */
|
|
246
|
+
sandboxSetupRecoveryExhausted?: true;
|
|
240
247
|
};
|
|
241
248
|
export declare const POST_CLAIM_DATABASE_RECOVERY_FAILURE_TYPE = "OpenGeniPostClaimDatabaseRecovery";
|
|
242
249
|
export declare const POST_CLAIM_DATABASE_RECOVERY_FAILURE_MESSAGE = "Agent turn database recovery required after attempt claim.";
|