@opengeni/worker-bundle 2.2.0 → 2.2.1-canary.36927100590001
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 +3 -1
- package/dist/activities/agent-turn/admission.d.ts +24 -3
- package/dist/activities/agent-turn/agent-build.d.ts +1 -0
- package/dist/activities/agent-turn/claude-usage-observer.d.ts +13 -1
- package/dist/activities/agent-turn/compaction-prep.d.ts +20 -0
- package/dist/activities/agent-turn/credential-restriction.d.ts +3 -0
- package/dist/activities/agent-turn/final-reply.d.ts +18 -0
- package/dist/activities/agent-turn/governance-model.d.ts +6 -0
- package/dist/activities/agent-turn/model-call-admission.d.ts +15 -0
- package/dist/activities/agent-turn/run-credentials.d.ts +4 -0
- package/dist/activities/agent-turn/sandbox-establish.d.ts +1 -0
- package/dist/activities/agent-turn/session-title.d.ts +3 -1
- package/dist/activities/agent-turn/stream-attempt.d.ts +1 -0
- package/dist/activities/agent-turn/turn-context.d.ts +1 -0
- package/dist/activities/automations.d.ts +3 -1
- package/dist/activities/browser-deadline-checkpoint.d.ts +29 -0
- package/dist/activities/goals.d.ts +8 -0
- package/dist/activities/run-credentials.d.ts +4 -2
- package/dist/activities/scheduled-tasks.d.ts +4 -35
- package/dist/activities/types.d.ts +4 -1
- package/dist/activities/workspace-capture.d.ts +2 -0
- package/dist/{activities-control-MHNA3CYV.js → activities-control-4F2A734B.js} +502 -133
- package/dist/activities-control-4F2A734B.js.map +1 -0
- package/dist/activities-control.d.ts +30 -0
- package/dist/{activities-turn-FQ5OO2WW.js → activities-turn-TESOIOEX.js} +696 -251
- package/dist/activities-turn-TESOIOEX.js.map +1 -0
- package/dist/activities.d.ts +30 -0
- package/dist/browser-deadline-checkpoint-contract.d.ts +2 -0
- package/dist/{chunk-RZAAGRFQ.js → chunk-4PJTUBWQ.js} +220 -88
- package/dist/chunk-4PJTUBWQ.js.map +1 -0
- package/dist/{chunk-IJZU752L.js → chunk-YG27NEMX.js} +34 -1
- package/dist/chunk-YG27NEMX.js.map +1 -0
- package/dist/index.d.ts +15 -0
- package/dist/index.js +46 -24
- package/dist/index.js.map +1 -1
- package/dist/observability-metrics.d.ts +16 -1
- package/dist/sandbox-resume.d.ts +4 -1
- package/dist/workflow-bundle.js +89 -21
- package/dist/workflows/browser-deadline-checkpoint.d.ts +9 -0
- package/dist/workflows/scheduled-tasks.d.ts +4 -0
- package/dist/workflows.d.ts +1 -0
- package/package.json +21 -20
- package/src/activities/agent-run-admission.ts +17 -1
- package/src/activities/agent-turn/admission.ts +64 -1
- package/src/activities/agent-turn/agent-build.ts +24 -3
- package/src/activities/agent-turn/claim.ts +69 -15
- package/src/activities/agent-turn/claude-usage-observer.ts +33 -1
- package/src/activities/agent-turn/compaction-prep.ts +67 -16
- package/src/activities/agent-turn/credential-restriction.ts +14 -0
- package/src/activities/agent-turn/errors.ts +55 -0
- package/src/activities/agent-turn/failure-settlement.ts +26 -6
- package/src/activities/agent-turn/final-reply.ts +46 -0
- package/src/activities/agent-turn/governance-model.ts +12 -0
- package/src/activities/agent-turn/model-call-admission.ts +94 -0
- package/src/activities/agent-turn/run-credentials.ts +20 -3
- package/src/activities/agent-turn/run.ts +44 -5
- package/src/activities/agent-turn/sandbox-establish.ts +9 -5
- package/src/activities/agent-turn/session-title.ts +8 -2
- package/src/activities/agent-turn/stream-attempt.ts +144 -38
- package/src/activities/agent-turn/tool-environment.ts +55 -39
- package/src/activities/agent-turn/turn-context.ts +1 -0
- package/src/activities/automations.ts +78 -4
- package/src/activities/browser-deadline-checkpoint.ts +279 -0
- package/src/activities/capabilities.ts +52 -14
- package/src/activities/goals.ts +95 -98
- package/src/activities/knowledge-indexing.ts +29 -0
- package/src/activities/open-suffix-resume.ts +2 -1
- package/src/activities/run-credentials.ts +22 -16
- package/src/activities/sandbox-lease.ts +22 -0
- package/src/activities/scheduled-tasks.ts +172 -38
- package/src/activities/site-auth-maintenance.ts +1 -0
- package/src/activities/types.ts +4 -0
- package/src/activities/workspace-capture.ts +13 -2
- package/src/activities/workspace-credential-provider.ts +12 -0
- package/src/activities-control.ts +2 -0
- package/src/activities.ts +3 -0
- package/src/browser-deadline-checkpoint-contract.ts +5 -0
- package/src/index.ts +53 -25
- package/src/observability-metrics.ts +55 -1
- package/src/sandbox-resume.ts +23 -8
- package/src/sandbox-routing.ts +4 -2
- package/src/workflows/browser-deadline-checkpoint.ts +50 -0
- package/src/workflows/scheduled-tasks.ts +26 -13
- package/src/workflows.ts +4 -0
- package/dist/activities-control-MHNA3CYV.js.map +0 -1
- package/dist/activities-turn-FQ5OO2WW.js.map +0 -1
- package/dist/chunk-IJZU752L.js.map +0 -1
- package/dist/chunk-RZAAGRFQ.js.map +0 -1
|
@@ -83,6 +83,7 @@ import {
|
|
|
83
83
|
signalPendingCodexCapacityWakeTargets,
|
|
84
84
|
startActivityHeartbeat,
|
|
85
85
|
throwIfTurnOperationCancelled,
|
|
86
|
+
turnCredentialRestriction,
|
|
86
87
|
turnFinalizerCancellationSignal,
|
|
87
88
|
turnInput,
|
|
88
89
|
turnOperationCancellationFailure,
|
|
@@ -94,7 +95,7 @@ import {
|
|
|
94
95
|
withFirstPartyTools,
|
|
95
96
|
wrapLazyTurnBoxWithRouting,
|
|
96
97
|
wrapTurnBoxWithRouting
|
|
97
|
-
} from "./chunk-
|
|
98
|
+
} from "./chunk-4PJTUBWQ.js";
|
|
98
99
|
import {
|
|
99
100
|
StreamTimingMetrics,
|
|
100
101
|
makeMachineOpObserver,
|
|
@@ -126,7 +127,7 @@ import {
|
|
|
126
127
|
runtimeMetricsHooksForObservability,
|
|
127
128
|
sandboxAutomaticRecoveryOutcome,
|
|
128
129
|
turnLifecycleMetricsFor
|
|
129
|
-
} from "./chunk-
|
|
130
|
+
} from "./chunk-YG27NEMX.js";
|
|
130
131
|
import {
|
|
131
132
|
__export
|
|
132
133
|
} from "./chunk-PZ5AY32C.js";
|
|
@@ -139,10 +140,13 @@ import {
|
|
|
139
140
|
getSessionAuthorityProjection,
|
|
140
141
|
readActiveSandbox as readActiveSandbox3,
|
|
141
142
|
getWorkspaceCredentialProvider,
|
|
142
|
-
loadClaudeSubscriptionUsageCredential
|
|
143
|
+
loadClaudeSubscriptionUsageCredential as loadClaudeSubscriptionUsageCredential2,
|
|
144
|
+
resolveClaudeSubscriptionCredential,
|
|
145
|
+
ClaudeSubscriptionReconnectRequired
|
|
143
146
|
} from "@opengeni/db";
|
|
147
|
+
import { resolveAgentToolFamilies as resolveAgentToolFamilies3 } from "@opengeni/contracts";
|
|
144
148
|
import {
|
|
145
|
-
assertModelConnectionAllowsTurn,
|
|
149
|
+
assertModelConnectionAllowsTurn as assertModelConnectionAllowsTurn2,
|
|
146
150
|
freezeAgentLearningPolicy as freezeAgentLearningPolicy2,
|
|
147
151
|
recoverLegacyKnowledgeConfirmations,
|
|
148
152
|
withSessionRlsActorContext
|
|
@@ -161,6 +165,7 @@ import {
|
|
|
161
165
|
import {
|
|
162
166
|
REMOTE_COMPACTION_V2_BETA_FEATURE,
|
|
163
167
|
REMOTE_COMPACTION_V2_IMPLEMENTATION as REMOTE_COMPACTION_V2_IMPLEMENTATION2,
|
|
168
|
+
awaitModelCallAdmission,
|
|
164
169
|
materializeSandboxFileDownloads as materializeSandboxFileDownloads3,
|
|
165
170
|
sandboxFileDownloadFailureNote
|
|
166
171
|
} from "@opengeni/runtime";
|
|
@@ -191,6 +196,17 @@ async function createClaudeUsageObserver(providers, latest, readCredential) {
|
|
|
191
196
|
(provider) => provider.kind === "claude-subscription-workspace" || provider.kind === "claude-subscription-organization"
|
|
192
197
|
).map(async (provider) => {
|
|
193
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
|
+
];
|
|
194
210
|
const credential = await readCredential(scope).catch(() => null);
|
|
195
211
|
if (!credential || credential.token !== provider.apiKey) return null;
|
|
196
212
|
return [
|
|
@@ -205,7 +221,7 @@ async function createClaudeUsageObserver(providers, latest, readCredential) {
|
|
|
205
221
|
})
|
|
206
222
|
);
|
|
207
223
|
const captured = new Map(bindings.filter((binding) => binding !== null));
|
|
208
|
-
|
|
224
|
+
const observe2 = (providerId, response) => {
|
|
209
225
|
const binding = captured.get(providerId);
|
|
210
226
|
if (!binding) return;
|
|
211
227
|
const { scope, ...identity } = binding;
|
|
@@ -230,6 +246,16 @@ async function createClaudeUsageObserver(providers, latest, readCredential) {
|
|
|
230
246
|
...response.status === 401 ? { refresh: { status: "reconnect", checkedAt: (/* @__PURE__ */ new Date()).toISOString() } } : {}
|
|
231
247
|
});
|
|
232
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
|
+
});
|
|
233
259
|
}
|
|
234
260
|
|
|
235
261
|
// src/activities/agent-turn/run.ts
|
|
@@ -4435,13 +4461,16 @@ async function runCapture(input, ctx, startedAt, signal, stage, ownership) {
|
|
|
4435
4461
|
"error.message": gcError instanceof Error ? gcError.message : String(gcError)
|
|
4436
4462
|
});
|
|
4437
4463
|
}
|
|
4438
|
-
|
|
4464
|
+
recordWorkspaceCaptureCompleted(observability, Date.now() - startedAt);
|
|
4465
|
+
}
|
|
4466
|
+
function recordWorkspaceCaptureCompleted(observability, durationMs) {
|
|
4439
4467
|
observability.incrementCounter({
|
|
4440
4468
|
name: "opengeni_workspace_capture_total",
|
|
4441
4469
|
labels: { result: "ok" }
|
|
4442
4470
|
});
|
|
4443
4471
|
observability.observeHistogram({
|
|
4444
|
-
name: "
|
|
4472
|
+
name: "opengeni_workspace_capture_revision_duration_seconds",
|
|
4473
|
+
help: "Turn-end logical workspace revision capture duration for committed revisions.",
|
|
4445
4474
|
value: durationMs / 1e3
|
|
4446
4475
|
});
|
|
4447
4476
|
}
|
|
@@ -5245,7 +5274,10 @@ import {
|
|
|
5245
5274
|
isSessionEventPersistenceError as isSessionEventPersistenceError2
|
|
5246
5275
|
} from "@opengeni/db";
|
|
5247
5276
|
import { publishDurableSessionEvents as publishDurableSessionEvents2 } from "@opengeni/events";
|
|
5248
|
-
import {
|
|
5277
|
+
import {
|
|
5278
|
+
maxTurnsExceededRunState,
|
|
5279
|
+
isModalTaskExecStartPreDispatchUnavailableError
|
|
5280
|
+
} from "@opengeni/runtime";
|
|
5249
5281
|
import { ApplicationFailure, CancelledFailure } from "@temporalio/activity";
|
|
5250
5282
|
import { TurnExecutionPolicyDefinitionMismatchError } from "@opengeni/config";
|
|
5251
5283
|
import {
|
|
@@ -5256,7 +5288,7 @@ import {
|
|
|
5256
5288
|
} from "@opengeni/codex";
|
|
5257
5289
|
|
|
5258
5290
|
// src/activities/agent-turn/admission.ts
|
|
5259
|
-
import { getBillingBalance, sumUsageQuantity } from "@opengeni/db";
|
|
5291
|
+
import { checkWorkspaceAllowance, getBillingBalance, sumUsageQuantity } from "@opengeni/db";
|
|
5260
5292
|
import {
|
|
5261
5293
|
configuredStaticUsageLimits
|
|
5262
5294
|
} from "@opengeni/config";
|
|
@@ -5901,13 +5933,48 @@ function stableInteractionInterventionUuid(namespace, sessionId, turnId, toolCal
|
|
|
5901
5933
|
return `${value.slice(0, 8)}-${value.slice(8, 12)}-${value.slice(12, 16)}-${value.slice(16, 20)}-${value.slice(20)}`;
|
|
5902
5934
|
}
|
|
5903
5935
|
var BudgetExhaustedError = class extends Error {
|
|
5904
|
-
constructor(message, serializedRunState) {
|
|
5936
|
+
constructor(message, serializedRunState, allowance = null) {
|
|
5905
5937
|
super(message);
|
|
5906
5938
|
this.serializedRunState = serializedRunState;
|
|
5939
|
+
this.allowance = allowance;
|
|
5907
5940
|
this.name = "BudgetExhaustedError";
|
|
5908
5941
|
}
|
|
5909
5942
|
};
|
|
5910
|
-
|
|
5943
|
+
var AllowanceExhaustedError = class extends Error {
|
|
5944
|
+
constructor(refusal) {
|
|
5945
|
+
super(refusal.message);
|
|
5946
|
+
this.refusal = refusal;
|
|
5947
|
+
this.name = "AllowanceExhaustedError";
|
|
5948
|
+
}
|
|
5949
|
+
code = "allowance_exhausted";
|
|
5950
|
+
};
|
|
5951
|
+
async function ensureRunAllowedBetweenModelCalls(input) {
|
|
5952
|
+
try {
|
|
5953
|
+
await ensureRunAllowed(
|
|
5954
|
+
input.settings,
|
|
5955
|
+
input.db,
|
|
5956
|
+
input.accountId,
|
|
5957
|
+
input.workspaceId,
|
|
5958
|
+
input.isExternallyBilledTurn,
|
|
5959
|
+
input.entitlements,
|
|
5960
|
+
input.chargesOpenGeniCredits,
|
|
5961
|
+
input.countsTowardTokenCap,
|
|
5962
|
+
input.initiatingHumanSubjectId
|
|
5963
|
+
);
|
|
5964
|
+
} catch (limitError) {
|
|
5965
|
+
let serializedRunState = null;
|
|
5966
|
+
try {
|
|
5967
|
+
serializedRunState = input.serializedRunState?.() ?? null;
|
|
5968
|
+
} catch {
|
|
5969
|
+
}
|
|
5970
|
+
throw new BudgetExhaustedError(
|
|
5971
|
+
limitError instanceof Error ? limitError.message : String(limitError),
|
|
5972
|
+
serializedRunState,
|
|
5973
|
+
limitError instanceof AllowanceExhaustedError ? limitError.refusal : null
|
|
5974
|
+
);
|
|
5975
|
+
}
|
|
5976
|
+
}
|
|
5977
|
+
async function ensureRunAllowed(settings, db, accountId, workspaceId, isExternallyBilledTurn, entitlements, chargesOpenGeniCredits = !isExternallyBilledTurn, countsTowardTokenCap = !isExternallyBilledTurn, initiatingHumanSubjectId = null) {
|
|
5911
5978
|
if (chargesOpenGeniCredits && entitlements && (settings.billingMode === "stripe" || settings.usageLimitsMode === "managed")) {
|
|
5912
5979
|
const decision = await entitlements.admitRun({
|
|
5913
5980
|
accountId,
|
|
@@ -5924,6 +5991,14 @@ async function ensureRunAllowed(settings, db, accountId, workspaceId, isExternal
|
|
|
5924
5991
|
throw new Error("insufficient OpenGeni credits");
|
|
5925
5992
|
}
|
|
5926
5993
|
}
|
|
5994
|
+
if (chargesOpenGeniCredits) {
|
|
5995
|
+
const refusal = await checkWorkspaceAllowance(db, {
|
|
5996
|
+
accountId,
|
|
5997
|
+
workspaceId,
|
|
5998
|
+
subjectId: initiatingHumanSubjectId
|
|
5999
|
+
});
|
|
6000
|
+
if (refusal) throw new AllowanceExhaustedError(refusal);
|
|
6001
|
+
}
|
|
5927
6002
|
if (settings.usageLimitsMode === "static" || settings.usageLimitsMode === "managed") {
|
|
5928
6003
|
const limits = configuredStaticUsageLimits(settings);
|
|
5929
6004
|
if (limits.maxMonthlyAgentRunsPerWorkspace) {
|
|
@@ -6998,19 +7073,22 @@ async function settleTurnFailure(deps) {
|
|
|
6998
7073
|
await historySink.reconcileConversationTruth();
|
|
6999
7074
|
if (!await eventing.settle({
|
|
7000
7075
|
events: [
|
|
7076
|
+
...error51.allowance ? [{ type: "usage.exhausted", payload: error51.allowance }] : [],
|
|
7001
7077
|
{
|
|
7002
7078
|
type: "turn.completed",
|
|
7003
7079
|
payload: {
|
|
7004
7080
|
output: "",
|
|
7005
7081
|
segmentLimit: "budget_exhausted",
|
|
7006
|
-
detail: error51.message
|
|
7082
|
+
detail: error51.message,
|
|
7083
|
+
...error51.allowance ?? {}
|
|
7007
7084
|
}
|
|
7008
7085
|
},
|
|
7009
7086
|
{ type: "session.status.changed", payload: { status: "idle" } }
|
|
7010
7087
|
],
|
|
7011
7088
|
turnStatus: "completed",
|
|
7012
7089
|
sessionStatus: "idle",
|
|
7013
|
-
activeTurnId: null
|
|
7090
|
+
activeTurnId: null,
|
|
7091
|
+
...error51.allowance ? { allowanceGoalPause: { rationale: error51.allowance.message } } : {}
|
|
7014
7092
|
})) {
|
|
7015
7093
|
return claimedResult({ status: "cancelled" });
|
|
7016
7094
|
}
|
|
@@ -7078,10 +7156,12 @@ async function settleTurnFailure(deps) {
|
|
|
7078
7156
|
}
|
|
7079
7157
|
}
|
|
7080
7158
|
const earlyDefinitionMismatch = error51 instanceof TurnExecutionPolicyDefinitionMismatchError && !attempt.modelRequestStarted && !eventing.turnStartedPublished && !!attempt.turnId && !!attempt.triggerEventId && attempt.executionGeneration > 0;
|
|
7159
|
+
const earlyCommandStartUnavailable = isModalTaskExecStartPreDispatchUnavailableError(error51) && !attempt.modelRequestStarted && !eventing.turnStartedPublished && !!attempt.turnId && !!attempt.triggerEventId && attempt.executionGeneration > 0;
|
|
7160
|
+
const earlyRecoverableSetup = earlyDefinitionMismatch || earlyCommandStartUnavailable;
|
|
7081
7161
|
let failure2 = earlyDefinitionMismatch ? { error: error51.message, code: error51.code, retryable: true } : codexTerminalFailure ?? agentRunFailurePayload(error51, {
|
|
7082
7162
|
isCodexTurn: billingState.isCodexTurn
|
|
7083
7163
|
});
|
|
7084
|
-
if (attempt.turnId && (
|
|
7164
|
+
if (attempt.turnId && (earlyRecoverableSetup || failure2.retryable && eventing.publish && eventing.turnStartedPublished)) {
|
|
7085
7165
|
const nextProviderRecoveryCount = attempt.providerRecoveryCount + 1;
|
|
7086
7166
|
const recoveryResult = providerRecoveryResult({
|
|
7087
7167
|
failureCode: failure2.code,
|
|
@@ -7090,7 +7170,7 @@ async function settleTurnFailure(deps) {
|
|
|
7090
7170
|
});
|
|
7091
7171
|
try {
|
|
7092
7172
|
if (recoveryResult.status === "recovering") {
|
|
7093
|
-
if (!
|
|
7173
|
+
if (!earlyRecoverableSetup) {
|
|
7094
7174
|
await flushRuntimeBatcher();
|
|
7095
7175
|
await historySink.reconcileConversationTruth({ requireDurable: true });
|
|
7096
7176
|
}
|
|
@@ -7121,13 +7201,13 @@ async function settleTurnFailure(deps) {
|
|
|
7121
7201
|
return claimedResult(recoveryResult);
|
|
7122
7202
|
}
|
|
7123
7203
|
failure2 = providerRecoveryExhaustedFailure(failure2, recoveryResult);
|
|
7124
|
-
if (
|
|
7204
|
+
if (earlyRecoverableSetup) {
|
|
7125
7205
|
control.activityStatus = "failed";
|
|
7126
7206
|
control.turnMetricOutcome = "failed";
|
|
7127
7207
|
control.activityError = error51;
|
|
7128
7208
|
throw ApplicationFailure.create({
|
|
7129
|
-
message: `${error51.message}. Automatic same-turn configuration recovery exhausted after ${recoveryResult.providerRecoveryCount} retries
|
|
7130
|
-
type: "TurnExecutionPolicyDefinitionMismatchError",
|
|
7209
|
+
message: earlyDefinitionMismatch ? `${error51.message}. Automatic same-turn configuration recovery exhausted after ${recoveryResult.providerRecoveryCount} retries.` : failure2.error,
|
|
7210
|
+
type: earlyDefinitionMismatch ? "TurnExecutionPolicyDefinitionMismatchError" : "SandboxCommandStartUnavailableError",
|
|
7131
7211
|
nonRetryable: true
|
|
7132
7212
|
});
|
|
7133
7213
|
}
|
|
@@ -7216,6 +7296,9 @@ async function settleTurnFailure(deps) {
|
|
|
7216
7296
|
// src/activities/agent-turn/stream-attempt.ts
|
|
7217
7297
|
import { measureMcpPhase, withMcpCallIdentity } from "@opengeni/observability";
|
|
7218
7298
|
import {
|
|
7299
|
+
appendSessionHistoryItems as appendSessionHistoryItems3,
|
|
7300
|
+
sessionTurnFinalReplyFacts,
|
|
7301
|
+
sessionTurnHasFinalReplyNudge,
|
|
7219
7302
|
getSessionHumanInputRequest,
|
|
7220
7303
|
getWorkspace,
|
|
7221
7304
|
recordUsageEvent as recordUsageEvent3,
|
|
@@ -7665,7 +7748,8 @@ async function resolveTurnSandboxAccess(sandboxState, sdkOwnedSandboxSession, un
|
|
|
7665
7748
|
// src/activities/open-suffix-resume.ts
|
|
7666
7749
|
import {
|
|
7667
7750
|
OPEN_SUFFIX_RUN_STATE_BLOB,
|
|
7668
|
-
approvalIdentifier
|
|
7751
|
+
approvalIdentifier,
|
|
7752
|
+
withPublicApprovalFields
|
|
7669
7753
|
} from "@opengeni/contracts";
|
|
7670
7754
|
import {
|
|
7671
7755
|
appendSessionHistoryItems as appendSessionHistoryItems2,
|
|
@@ -7931,7 +8015,7 @@ async function settleOpenSuffixResumeIfNeeded(input) {
|
|
|
7931
8015
|
...requiresActionApprovals.length > 0 ? [
|
|
7932
8016
|
{
|
|
7933
8017
|
type: "session.requiresAction",
|
|
7934
|
-
payload: { approvals: requiresActionApprovals }
|
|
8018
|
+
payload: { approvals: requiresActionApprovals.map(withPublicApprovalFields) }
|
|
7935
8019
|
}
|
|
7936
8020
|
] : [],
|
|
7937
8021
|
{
|
|
@@ -7969,9 +8053,85 @@ function interruptionCallIdsFromPause(input) {
|
|
|
7969
8053
|
// src/activities/agent-turn/stream-attempt.ts
|
|
7970
8054
|
import {
|
|
7971
8055
|
OPEN_SUFFIX_RUN_STATE_BLOB as OPEN_SUFFIX_RUN_STATE_BLOB2,
|
|
7972
|
-
resolveWorkspaceAgentHumanInputEnabled
|
|
8056
|
+
resolveWorkspaceAgentHumanInputEnabled,
|
|
8057
|
+
withPublicApprovalFields as withPublicApprovalFields2
|
|
7973
8058
|
} from "@opengeni/contracts";
|
|
7974
8059
|
|
|
8060
|
+
// src/activities/agent-turn/model-call-admission.ts
|
|
8061
|
+
function createModelCallAdmission(input) {
|
|
8062
|
+
const receipts = /* @__PURE__ */ new WeakMap();
|
|
8063
|
+
const responseReceipts = /* @__PURE__ */ new Map();
|
|
8064
|
+
const pending = /* @__PURE__ */ new Set();
|
|
8065
|
+
const responseId = (event) => {
|
|
8066
|
+
const id = event?.response?.id;
|
|
8067
|
+
return typeof id === "string" && id.length > 0 ? id : null;
|
|
8068
|
+
};
|
|
8069
|
+
let latest = Promise.resolve();
|
|
8070
|
+
let failure2;
|
|
8071
|
+
let failed = false;
|
|
8072
|
+
let rejectHalted;
|
|
8073
|
+
const halted = new Promise((_, reject) => {
|
|
8074
|
+
rejectHalted = reject;
|
|
8075
|
+
});
|
|
8076
|
+
void halted.catch(() => void 0);
|
|
8077
|
+
const fail = (error51) => {
|
|
8078
|
+
if (failed) return;
|
|
8079
|
+
failed = true;
|
|
8080
|
+
failure2 = error51;
|
|
8081
|
+
rejectHalted(error51);
|
|
8082
|
+
for (const receipt of pending) receipt.reject(error51);
|
|
8083
|
+
pending.clear();
|
|
8084
|
+
responseReceipts.clear();
|
|
8085
|
+
};
|
|
8086
|
+
const abort = () => fail(input.signal.reason ?? new Error("Model stream cancelled"));
|
|
8087
|
+
input.signal.addEventListener("abort", abort, { once: true });
|
|
8088
|
+
if (input.signal.aborted) abort();
|
|
8089
|
+
return {
|
|
8090
|
+
beforeModelRequest: async () => {
|
|
8091
|
+
await Promise.race([latest, halted]);
|
|
8092
|
+
if (failed) throw failure2;
|
|
8093
|
+
await Promise.race([input.admit(), halted]);
|
|
8094
|
+
if (failed) throw failure2;
|
|
8095
|
+
},
|
|
8096
|
+
onModelResponse: (event) => {
|
|
8097
|
+
if (failed) return Promise.reject(failure2);
|
|
8098
|
+
const id = responseId(event);
|
|
8099
|
+
const existing = receipts.get(event) ?? (id ? responseReceipts.get(id) : void 0) ?? (!id && pending.size === 1 ? pending.values().next().value : void 0);
|
|
8100
|
+
if (existing) return existing.promise;
|
|
8101
|
+
let resolve;
|
|
8102
|
+
let reject;
|
|
8103
|
+
const promise2 = new Promise((yes, no) => {
|
|
8104
|
+
resolve = yes;
|
|
8105
|
+
reject = no;
|
|
8106
|
+
});
|
|
8107
|
+
void promise2.catch(() => void 0);
|
|
8108
|
+
const receipt = { promise: promise2, resolve, reject };
|
|
8109
|
+
receipts.set(event, receipt);
|
|
8110
|
+
if (id) responseReceipts.set(id, receipt);
|
|
8111
|
+
pending.add(receipt);
|
|
8112
|
+
latest = promise2;
|
|
8113
|
+
return promise2;
|
|
8114
|
+
},
|
|
8115
|
+
settle: (event) => {
|
|
8116
|
+
if (event.type !== "raw_model_stream_event" || !event.data || typeof event.data !== "object")
|
|
8117
|
+
return;
|
|
8118
|
+
if (event.data.type !== "response_done") return;
|
|
8119
|
+
const id = responseId(event.data);
|
|
8120
|
+
const receipt = receipts.get(event.data) ?? (id ? responseReceipts.get(id) : void 0) ?? (pending.size === 1 ? pending.values().next().value : void 0);
|
|
8121
|
+
if (!receipt) return;
|
|
8122
|
+
pending.delete(receipt);
|
|
8123
|
+
if (id) responseReceipts.delete(id);
|
|
8124
|
+
receipt.resolve();
|
|
8125
|
+
},
|
|
8126
|
+
fail,
|
|
8127
|
+
close: () => {
|
|
8128
|
+
input.signal.removeEventListener("abort", abort);
|
|
8129
|
+
if (pending.size > 0) fail(new Error("Model stream closed before response settlement"));
|
|
8130
|
+
responseReceipts.clear();
|
|
8131
|
+
}
|
|
8132
|
+
};
|
|
8133
|
+
}
|
|
8134
|
+
|
|
7975
8135
|
// src/activities/agent-turn/session-title.ts
|
|
7976
8136
|
import { hasPermission } from "@opengeni/core";
|
|
7977
8137
|
import { isManagedOpenRouterFreeRoute } from "@opengeni/config";
|
|
@@ -7986,7 +8146,7 @@ function shouldRequestMissingSessionTitle(input) {
|
|
|
7986
8146
|
const title = input.title?.trim() ?? "";
|
|
7987
8147
|
const needsSemanticTitle = input.titleSource !== "user" && (!title || title === AUTOMATIC_SESSION_TITLE_FALLBACK);
|
|
7988
8148
|
if (!needsSemanticTitle) return false;
|
|
7989
|
-
if (!input.firstPartyMcpTools.includes("set_session_title")) return false;
|
|
8149
|
+
if (!input.agentConfig && !input.firstPartyMcpTools.includes("set_session_title")) return false;
|
|
7990
8150
|
const permissions = input.firstPartyMcpPermissions ?? DEFAULT_FIRST_PARTY_MCP_PERMISSIONS;
|
|
7991
8151
|
return hasPermission([...permissions], "sessions:control");
|
|
7992
8152
|
}
|
|
@@ -7994,7 +8154,7 @@ function routeAllowsSessionTitleRequests(resolvedModel) {
|
|
|
7994
8154
|
return !resolvedModel || !isManagedOpenRouterFreeRoute(resolvedModel);
|
|
7995
8155
|
}
|
|
7996
8156
|
function sessionTitleToolPlan(input) {
|
|
7997
|
-
const titleToolAvailable = input.shouldRequestTitle && input.tools.some((tool) => tool.kind === "mcp" && tool.id === "opengeni");
|
|
8157
|
+
const titleToolAvailable = input.shouldRequestTitle && (input.agentConfig != null || input.tools.some((tool) => tool.kind === "mcp" && tool.id === "opengeni"));
|
|
7998
8158
|
const titleRequestAllowed = titleToolAvailable && input.routeAllowsTitleRequests;
|
|
7999
8159
|
const generateTitleInParallel = titleRequestAllowed && input.parallelGenerationAvailable;
|
|
8000
8160
|
const promoteTitleTool = titleRequestAllowed && !generateTitleInParallel;
|
|
@@ -8301,6 +8461,24 @@ function createSharedRigSetupCoordinator(options) {
|
|
|
8301
8461
|
};
|
|
8302
8462
|
}
|
|
8303
8463
|
|
|
8464
|
+
// src/activities/agent-turn/final-reply.ts
|
|
8465
|
+
function finalReplyNudge(turnId) {
|
|
8466
|
+
return {
|
|
8467
|
+
type: "message",
|
|
8468
|
+
role: "developer",
|
|
8469
|
+
content: [
|
|
8470
|
+
{
|
|
8471
|
+
type: "input_text",
|
|
8472
|
+
text: `[Runtime final-reply handoff for turn ${turnId}]
|
|
8473
|
+
Your final user-facing answer was empty. Reply to the user now with the requested deliverable or a concise outcome and its retained artifact link. Goal evidence is a short ledger proof, not the answer, and goal_complete does not deliver a chat reply. Use the completed work and tool results already in history; do not repeat completed tools or restart the task. If this is a late child result after goal completion, integrate material new findings and deliver any still-missing handoff. Do not change the completed goal or invent a result.`
|
|
8474
|
+
}
|
|
8475
|
+
]
|
|
8476
|
+
};
|
|
8477
|
+
}
|
|
8478
|
+
function needsFinalReply(input) {
|
|
8479
|
+
return typeof input.output === "string" && input.output.trim().length === 0 && !input.inputWaitYielded && !input.interrupted && !input.maintenance && (input.toolsExecuted || input.completedGoal);
|
|
8480
|
+
}
|
|
8481
|
+
|
|
8304
8482
|
// src/activities/agent-turn/stream-attempt.ts
|
|
8305
8483
|
async function attachPendingUpdatesBeforePreparingModelInput(input) {
|
|
8306
8484
|
if (input.shouldAttach && !await input.attachPendingUpdates()) return false;
|
|
@@ -8567,12 +8745,33 @@ async function runTurnStreamAttempt(deps) {
|
|
|
8567
8745
|
const modelResponseState = createModelResponseEventState(claimedModelUsageSourceKeys);
|
|
8568
8746
|
let latestAssistantMessageText = null;
|
|
8569
8747
|
let workerPreparationTotalRecorded = false;
|
|
8748
|
+
let toolsExecuted = false;
|
|
8749
|
+
let finalReplyNudged = false;
|
|
8750
|
+
const revalidateModelCallAdmission = async () => {
|
|
8751
|
+
await historySink.reconcileConversationTruth({ requireDurable: true });
|
|
8752
|
+
await ensureRunAllowedBetweenModelCalls({
|
|
8753
|
+
settings,
|
|
8754
|
+
db,
|
|
8755
|
+
accountId: input.accountId,
|
|
8756
|
+
workspaceId: input.workspaceId,
|
|
8757
|
+
isExternallyBilledTurn: billingState.isExternallyBilledTurn,
|
|
8758
|
+
entitlements,
|
|
8759
|
+
chargesOpenGeniCredits: billingState.chargesOpenGeniCredits,
|
|
8760
|
+
countsTowardTokenCap: billingState.countsTowardTokenCap,
|
|
8761
|
+
initiatingHumanSubjectId: turn.initiatingHumanSubjectId
|
|
8762
|
+
});
|
|
8763
|
+
};
|
|
8570
8764
|
const runStreamAttempt = async (options) => {
|
|
8571
8765
|
if (!runInput) {
|
|
8572
8766
|
throw new Error("Run input was not prepared");
|
|
8573
8767
|
}
|
|
8574
|
-
const responseCountBeforeStream = modelResponseState.responseCount;
|
|
8575
8768
|
eventing.stream = void 0;
|
|
8769
|
+
if (options.requireTerminalModelResponse) await revalidateModelCallAdmission();
|
|
8770
|
+
const modelCallAdmission = createModelCallAdmission({
|
|
8771
|
+
signal: runtimeCancellationSignal,
|
|
8772
|
+
admit: revalidateModelCallAdmission
|
|
8773
|
+
});
|
|
8774
|
+
const responseCountBeforeStream = modelResponseState.responseCount;
|
|
8576
8775
|
eventing.batcher = null;
|
|
8577
8776
|
let currentToolBatchCallIds = /* @__PURE__ */ new Set();
|
|
8578
8777
|
let currentToolBatchCompletedCallIds = /* @__PURE__ */ new Set();
|
|
@@ -8740,6 +8939,8 @@ async function runTurnStreamAttempt(deps) {
|
|
|
8740
8939
|
}
|
|
8741
8940
|
attempt.modelRequestStarted = true;
|
|
8742
8941
|
return await runtime.runStream(agent, runInput, eventing.modelRunSettings, {
|
|
8942
|
+
beforeModelRequest: modelCallAdmission.beforeModelRequest,
|
|
8943
|
+
onModelResponse: modelCallAdmission.onModelResponse,
|
|
8743
8944
|
signal: runtimeCancellationSignal,
|
|
8744
8945
|
sandboxEnvironment,
|
|
8745
8946
|
onModelVisibleContext: async (snapshot) => {
|
|
@@ -8846,7 +9047,13 @@ async function runTurnStreamAttempt(deps) {
|
|
|
8846
9047
|
if (leases.xai.lost) {
|
|
8847
9048
|
throw new Error("xAI credential lease expired before the model run");
|
|
8848
9049
|
}
|
|
8849
|
-
|
|
9050
|
+
try {
|
|
9051
|
+
eventing.stream = await withProviderRequestContext(runStreamOnce);
|
|
9052
|
+
} catch (error51) {
|
|
9053
|
+
modelCallAdmission.fail(error51);
|
|
9054
|
+
modelCallAdmission.close();
|
|
9055
|
+
throw error51;
|
|
9056
|
+
}
|
|
8850
9057
|
const streamTiming = new StreamTimingMetrics(observability, {
|
|
8851
9058
|
provider: streamProvider
|
|
8852
9059
|
});
|
|
@@ -8985,32 +9192,20 @@ async function runTurnStreamAttempt(deps) {
|
|
|
8985
9192
|
await historySink.reconcileConversationTruth();
|
|
8986
9193
|
turnLifecycleMetricsFor(observability).progress({ attemptId: input.attemptId });
|
|
8987
9194
|
modelCheckpointMemoryCollector.schedule(observability);
|
|
8988
|
-
|
|
8989
|
-
|
|
8990
|
-
|
|
8991
|
-
|
|
8992
|
-
|
|
8993
|
-
|
|
8994
|
-
|
|
8995
|
-
|
|
8996
|
-
|
|
8997
|
-
|
|
8998
|
-
)
|
|
8999
|
-
}
|
|
9000
|
-
let serializedRunState = null;
|
|
9001
|
-
try {
|
|
9002
|
-
serializedRunState = media.compactMediaRunState(
|
|
9003
|
-
String(eventing.stream.state.toString())
|
|
9004
|
-
);
|
|
9005
|
-
} catch {
|
|
9006
|
-
serializedRunState = null;
|
|
9007
|
-
}
|
|
9008
|
-
throw new BudgetExhaustedError(
|
|
9009
|
-
limitError instanceof Error ? limitError.message : String(limitError),
|
|
9010
|
-
serializedRunState
|
|
9011
|
-
);
|
|
9012
|
-
}
|
|
9195
|
+
await ensureRunAllowedBetweenModelCalls({
|
|
9196
|
+
settings,
|
|
9197
|
+
db,
|
|
9198
|
+
accountId: input.accountId,
|
|
9199
|
+
workspaceId: input.workspaceId,
|
|
9200
|
+
isExternallyBilledTurn: billingState.isExternallyBilledTurn,
|
|
9201
|
+
entitlements,
|
|
9202
|
+
chargesOpenGeniCredits: billingState.chargesOpenGeniCredits,
|
|
9203
|
+
countsTowardTokenCap: billingState.countsTowardTokenCap,
|
|
9204
|
+
initiatingHumanSubjectId: turn.initiatingHumanSubjectId,
|
|
9205
|
+
serializedRunState: () => media.compactMediaRunState(String(eventing.stream.state.toString()))
|
|
9206
|
+
});
|
|
9013
9207
|
}
|
|
9208
|
+
modelCallAdmission.settle(next.value);
|
|
9014
9209
|
const durableSdkEvent = generatedImageReceipt ? compactGeneratedImageSdkEvent(next.value, generatedImageReceipt) : next.value;
|
|
9015
9210
|
const pendingToolCall = pendingToolCallFromSdkEvent(durableSdkEvent);
|
|
9016
9211
|
if (pendingToolCall) {
|
|
@@ -9044,6 +9239,7 @@ async function runTurnStreamAttempt(deps) {
|
|
|
9044
9239
|
}
|
|
9045
9240
|
const completedToolCall = completedToolCallFromSdkEvent(durableSdkEvent);
|
|
9046
9241
|
if (completedToolCall) {
|
|
9242
|
+
toolsExecuted = true;
|
|
9047
9243
|
retainedScreenshotMetadata = media.retainedScreenshotReceiptsByCallId.get(completedToolCall.callId) ?? null;
|
|
9048
9244
|
const typedScreenshot = retainedScreenshotMetadata ? null : typedScreenshotFromSdkEvent(durableSdkEvent);
|
|
9049
9245
|
if (!retainedScreenshotMetadata && media.retainedSessionImageCallIds.has(completedToolCall.callId) && sdkEventContainsInlineImage(durableSdkEvent) && !typedScreenshot) {
|
|
@@ -9225,6 +9421,7 @@ async function runTurnStreamAttempt(deps) {
|
|
|
9225
9421
|
}
|
|
9226
9422
|
}
|
|
9227
9423
|
} catch (error51) {
|
|
9424
|
+
modelCallAdmission.fail(error51);
|
|
9228
9425
|
closeStreamWaitAdmission?.();
|
|
9229
9426
|
if (fallbackProviderRequestLifecycleStartedAt !== null) {
|
|
9230
9427
|
const durationMs = Math.max(
|
|
@@ -9274,6 +9471,7 @@ async function runTurnStreamAttempt(deps) {
|
|
|
9274
9471
|
}
|
|
9275
9472
|
throw error51;
|
|
9276
9473
|
} finally {
|
|
9474
|
+
modelCallAdmission.close();
|
|
9277
9475
|
if (!streamDone) {
|
|
9278
9476
|
void iterator.return?.().catch(() => void 0);
|
|
9279
9477
|
}
|
|
@@ -9284,7 +9482,7 @@ async function runTurnStreamAttempt(deps) {
|
|
|
9284
9482
|
temporalCancellationSignal: cancellationSignal,
|
|
9285
9483
|
runtimeCancellationSignal
|
|
9286
9484
|
});
|
|
9287
|
-
await eventing.preparedTools?.inputWaitYield?.
|
|
9485
|
+
await eventing.preparedTools?.inputWaitYield?.drainForHandoff(runtimeCancellationSignal);
|
|
9288
9486
|
if (options.requireTerminalModelResponse && !eventing.preparedTools?.inputWaitYield?.yielded && eventing.stream.interruptions.length === 0 && modelResponseState.responseCount === responseCountBeforeStream) {
|
|
9289
9487
|
throwIfWorkerShuttingDown();
|
|
9290
9488
|
throwIfTurnCancelled();
|
|
@@ -9380,6 +9578,7 @@ async function runTurnStreamAttempt(deps) {
|
|
|
9380
9578
|
}
|
|
9381
9579
|
}
|
|
9382
9580
|
if (eventing.stream.interruptions.length > 0) {
|
|
9581
|
+
await eventing.preparedTools?.inputWaitYield?.sealForSettlement(runtimeCancellationSignal);
|
|
9383
9582
|
await historySink.reconcileConversationTruth({ requireDurable: true });
|
|
9384
9583
|
const approvals = runtime.serializeApprovals(eventing.stream.interruptions);
|
|
9385
9584
|
const humanInputInterruptions = runtime.serializeHumanInputRequests?.(eventing.stream.interruptions) ?? [];
|
|
@@ -9487,9 +9686,11 @@ async function runTurnStreamAttempt(deps) {
|
|
|
9487
9686
|
type: "session.requiresAction",
|
|
9488
9687
|
payload: {
|
|
9489
9688
|
approvals: approvals.map(
|
|
9490
|
-
(approval) =>
|
|
9491
|
-
|
|
9492
|
-
|
|
9689
|
+
(approval) => withPublicApprovalFields2(
|
|
9690
|
+
withMcpToolDisplayMetadata(
|
|
9691
|
+
eventing.preparedTools?.mcpServers ?? [],
|
|
9692
|
+
approval
|
|
9693
|
+
)
|
|
9493
9694
|
)
|
|
9494
9695
|
)
|
|
9495
9696
|
}
|
|
@@ -9520,6 +9721,48 @@ async function runTurnStreamAttempt(deps) {
|
|
|
9520
9721
|
const finalOutput = String(
|
|
9521
9722
|
requireAgentStreamFinalOutput(eventing.stream.finalOutput, inputWaitYielded)
|
|
9522
9723
|
);
|
|
9724
|
+
const durableReplyFacts = !inputWaitYielded && finalOutput.trim().length === 0 ? await sessionTurnFinalReplyFacts(db, input.workspaceId, input.sessionId, activeTurnId) : { toolsExecuted: false, completedGoal: false };
|
|
9725
|
+
let emptyFinalReply = false;
|
|
9726
|
+
if (needsFinalReply({
|
|
9727
|
+
output: finalOutput,
|
|
9728
|
+
inputWaitYielded: inputWaitYielded || eventing.preparedTools?.inputWaitYield?.requested === true,
|
|
9729
|
+
interrupted: false,
|
|
9730
|
+
// interruption settlement returned above
|
|
9731
|
+
maintenance: turn.source === "compaction",
|
|
9732
|
+
toolsExecuted: toolsExecuted || finalReplyNudged || durableReplyFacts.toolsExecuted,
|
|
9733
|
+
completedGoal: durableReplyFacts.completedGoal
|
|
9734
|
+
})) {
|
|
9735
|
+
await historySink.reconcileConversationTruth({ requireDurable: true });
|
|
9736
|
+
if (finalReplyNudged || await sessionTurnHasFinalReplyNudge(
|
|
9737
|
+
db,
|
|
9738
|
+
input.workspaceId,
|
|
9739
|
+
input.sessionId,
|
|
9740
|
+
activeTurnId,
|
|
9741
|
+
finalReplyNudge(activeTurnId).content[0].text
|
|
9742
|
+
)) {
|
|
9743
|
+
emptyFinalReply = true;
|
|
9744
|
+
} else {
|
|
9745
|
+
const appended = await appendSessionHistoryItems3(db, {
|
|
9746
|
+
accountId: input.accountId,
|
|
9747
|
+
workspaceId: input.workspaceId,
|
|
9748
|
+
sessionId: input.sessionId,
|
|
9749
|
+
turnId: activeTurnId,
|
|
9750
|
+
expectedExecutionGeneration: attempt.executionGeneration,
|
|
9751
|
+
expectedAttemptId: input.attemptId,
|
|
9752
|
+
items: [
|
|
9753
|
+
{
|
|
9754
|
+
position: await nextSessionHistoryPosition2(db, input.workspaceId, input.sessionId),
|
|
9755
|
+
item: finalReplyNudge(activeTurnId)
|
|
9756
|
+
}
|
|
9757
|
+
]
|
|
9758
|
+
});
|
|
9759
|
+
if (!appended) throw new TurnAttemptFencedError("turn ended before final reply handoff");
|
|
9760
|
+
finalReplyNudged = true;
|
|
9761
|
+
await prepareRunAttemptInput();
|
|
9762
|
+
return "reply_nudge";
|
|
9763
|
+
}
|
|
9764
|
+
}
|
|
9765
|
+
await eventing.preparedTools?.inputWaitYield?.sealForSettlement(runtimeCancellationSignal);
|
|
9523
9766
|
const finalOutputAlreadyCompleted = latestStreamedAssistantText === finalOutput;
|
|
9524
9767
|
const reply = await inputWaitReply({
|
|
9525
9768
|
inputWaitYielded,
|
|
@@ -9539,7 +9782,11 @@ async function runTurnStreamAttempt(deps) {
|
|
|
9539
9782
|
...inputWaitYielded || finalOutputAlreadyCompleted ? [] : [{ type: "agent.message.completed", payload: { text: finalOutput } }],
|
|
9540
9783
|
{
|
|
9541
9784
|
type: "turn.completed",
|
|
9542
|
-
payload: {
|
|
9785
|
+
payload: {
|
|
9786
|
+
output: finalOutput,
|
|
9787
|
+
...reply === null ? {} : { reply },
|
|
9788
|
+
...emptyFinalReply ? { emptyFinalReply: true } : {}
|
|
9789
|
+
}
|
|
9543
9790
|
},
|
|
9544
9791
|
{ type: "session.status.changed", payload: { status: "idle" } }
|
|
9545
9792
|
],
|
|
@@ -9595,6 +9842,7 @@ async function runTurnStreamAttempt(deps) {
|
|
|
9595
9842
|
})) {
|
|
9596
9843
|
return claimedResult({ status: "cancelled" });
|
|
9597
9844
|
}
|
|
9845
|
+
await revalidateModelCallAdmission();
|
|
9598
9846
|
if (turn.source !== "compaction" && generateSessionTitleInParallel && runtime.generateSessionTitle && !runtimeCancellationSignal.aborted) {
|
|
9599
9847
|
const serviceTier = serviceTierForLatencyMode(
|
|
9600
9848
|
turnExecutionPolicy.providerId,
|
|
@@ -9626,11 +9874,19 @@ async function runTurnStreamAttempt(deps) {
|
|
|
9626
9874
|
}
|
|
9627
9875
|
try {
|
|
9628
9876
|
let retriedAfterCompaction = false;
|
|
9877
|
+
finalReplyNudged = await sessionTurnHasFinalReplyNudge(
|
|
9878
|
+
db,
|
|
9879
|
+
input.workspaceId,
|
|
9880
|
+
input.sessionId,
|
|
9881
|
+
activeTurnId,
|
|
9882
|
+
finalReplyNudge(activeTurnId).content[0].text
|
|
9883
|
+
);
|
|
9629
9884
|
while (true) {
|
|
9630
9885
|
try {
|
|
9631
9886
|
const result = await runStreamAttempt({
|
|
9632
9887
|
requireTerminalModelResponse: retriedAfterCompaction
|
|
9633
9888
|
});
|
|
9889
|
+
if (result === "reply_nudge") continue;
|
|
9634
9890
|
if (retriedAfterCompaction) {
|
|
9635
9891
|
observability.info("context compaction recovery succeeded after in-activity retry", {
|
|
9636
9892
|
sessionId: input.sessionId,
|
|
@@ -9841,7 +10097,9 @@ import {
|
|
|
9841
10097
|
loadOrganizationModelProviderApiKey,
|
|
9842
10098
|
listWorkspaceProviderCustomModels,
|
|
9843
10099
|
getWorkspaceProviderCustomModelForExecution,
|
|
9844
|
-
loadWorkspaceProviderApiKey
|
|
10100
|
+
loadWorkspaceProviderApiKey,
|
|
10101
|
+
loadClaudeSubscriptionUsageCredential,
|
|
10102
|
+
assertModelConnectionAllowsTurn
|
|
9845
10103
|
} from "@opengeni/db";
|
|
9846
10104
|
async function settingsWithSessionMcpServersForRun(db, workspaceId, sessionId, attemptId, settings, options) {
|
|
9847
10105
|
const encryptionKey = environmentsEncryptionKeyBytes(settings);
|
|
@@ -9999,12 +10257,24 @@ async function settingsWithOrganizationProviderCredentials(db, accountId, worksp
|
|
|
9999
10257
|
if (kind === "claude_subscription" && !settings.claudeSubscriptionEnabled) continue;
|
|
10000
10258
|
const models = await buildModels(kind, claudeProviderId(kind) + "/");
|
|
10001
10259
|
result = withClaudeConnectionCatalog(result, { [kind]: { models } });
|
|
10002
|
-
const
|
|
10260
|
+
const binding = kind === "claude_subscription" ? await loadClaudeSubscriptionUsageCredential(db, settings, {
|
|
10261
|
+
accountId,
|
|
10262
|
+
workspaceId,
|
|
10263
|
+
scope: "organization"
|
|
10264
|
+
}) : null;
|
|
10265
|
+
const credential = kind === "claude_subscription" ? binding?.serializedCredential : await loadOrganizationModelProviderApiKey(db, settings, {
|
|
10003
10266
|
accountId,
|
|
10004
10267
|
workspaceId,
|
|
10005
10268
|
providerKind: kind
|
|
10006
10269
|
});
|
|
10007
|
-
if (credential)
|
|
10270
|
+
if (credential)
|
|
10271
|
+
result = withClaudeConnectionCredential(
|
|
10272
|
+
result,
|
|
10273
|
+
kind,
|
|
10274
|
+
credential,
|
|
10275
|
+
"organization",
|
|
10276
|
+
binding ?? void 0
|
|
10277
|
+
);
|
|
10008
10278
|
const workspaceModels = await listWorkspaceProviderCustomModels(db, {
|
|
10009
10279
|
accountId,
|
|
10010
10280
|
workspaceId,
|
|
@@ -10027,15 +10297,27 @@ async function settingsWithOrganizationProviderCredentials(db, accountId, worksp
|
|
|
10027
10297
|
{ [kind]: { models: workspaceModels } },
|
|
10028
10298
|
"workspace"
|
|
10029
10299
|
);
|
|
10030
|
-
const
|
|
10031
|
-
|
|
10032
|
-
settings,
|
|
10300
|
+
const workspaceBinding = kind === "claude_subscription" ? await loadClaudeSubscriptionUsageCredential(db, settings, {
|
|
10301
|
+
accountId,
|
|
10033
10302
|
workspaceId,
|
|
10034
|
-
|
|
10035
|
-
|
|
10036
|
-
)
|
|
10303
|
+
scope: "workspace"
|
|
10304
|
+
}) : null;
|
|
10305
|
+
if (workspaceBinding && workspaceModelId)
|
|
10306
|
+
await assertModelConnectionAllowsTurn(db, {
|
|
10307
|
+
workspaceId,
|
|
10308
|
+
subjectId: "worker:model-access",
|
|
10309
|
+
modelId: workspaceModelId,
|
|
10310
|
+
workspaceProviderConnectionId: workspaceBinding.connectionId
|
|
10311
|
+
});
|
|
10312
|
+
const workspaceCredential = kind === "claude_subscription" ? workspaceBinding?.serializedCredential : await loadWorkspaceProviderApiKey(db, settings, workspaceId, kind, workspaceModelId);
|
|
10037
10313
|
if (workspaceCredential)
|
|
10038
|
-
result = withClaudeConnectionCredential(
|
|
10314
|
+
result = withClaudeConnectionCredential(
|
|
10315
|
+
result,
|
|
10316
|
+
kind,
|
|
10317
|
+
workspaceCredential,
|
|
10318
|
+
"workspace",
|
|
10319
|
+
workspaceBinding ?? void 0
|
|
10320
|
+
);
|
|
10039
10321
|
}
|
|
10040
10322
|
return result;
|
|
10041
10323
|
}
|
|
@@ -10180,7 +10462,9 @@ async function claimTurnAttempt(deps) {
|
|
|
10180
10462
|
claimedPolicy.kind === "valid" ? claimedPolicy.policy.productModelId : turn.model
|
|
10181
10463
|
);
|
|
10182
10464
|
const codexAppsCredentialId = capabilitySettings.codexConnectedAppsEnabled ? await resolveCodexAppsCredentialIdForRun(db, input.workspaceId) : null;
|
|
10183
|
-
const
|
|
10465
|
+
const candidatePolicy = claimedPolicy.kind === "valid" ? claimedPolicy.policy : resolveTurnExecutionPolicyV12(capabilitySettings, legacyTurnExecutionPolicyInput(turn));
|
|
10466
|
+
const credentialRestriction = claimedPolicy.kind === "absent" ? turn.initiatorContext?.credentialRestriction === "developer_setup" ? "developer_setup" : turnCredentialRestriction(candidatePolicy, session.metadata) : void 0;
|
|
10467
|
+
const policyForAbsent = credentialRestriction ? { ...candidatePolicy, credentialRestriction } : candidatePolicy;
|
|
10184
10468
|
const installedPolicy = await installOrReadTurnExecutionPolicyForAttempt(db, {
|
|
10185
10469
|
accountId: input.accountId,
|
|
10186
10470
|
workspaceId: input.workspaceId,
|
|
@@ -10253,20 +10537,27 @@ async function claimTurnAttempt(deps) {
|
|
|
10253
10537
|
return attached.action === "claimed" && attached.turn.id === turn.id;
|
|
10254
10538
|
};
|
|
10255
10539
|
turnLifecycleMetricsFor(observability).start({ attemptId: input.attemptId });
|
|
10256
|
-
|
|
10257
|
-
|
|
10258
|
-
|
|
10259
|
-
|
|
10260
|
-
|
|
10261
|
-
|
|
10262
|
-
|
|
10263
|
-
|
|
10264
|
-
|
|
10265
|
-
|
|
10266
|
-
|
|
10267
|
-
|
|
10268
|
-
|
|
10269
|
-
|
|
10540
|
+
let allowanceRefusal = null;
|
|
10541
|
+
try {
|
|
10542
|
+
await waitForTurnOperation(
|
|
10543
|
+
ensureRunAllowed(
|
|
10544
|
+
capabilitySettings,
|
|
10545
|
+
db,
|
|
10546
|
+
input.accountId,
|
|
10547
|
+
input.workspaceId,
|
|
10548
|
+
billingState.isExternallyBilledTurn,
|
|
10549
|
+
entitlements,
|
|
10550
|
+
billingState.chargesOpenGeniCredits,
|
|
10551
|
+
billingState.countsTowardTokenCap,
|
|
10552
|
+
turn.initiatingHumanSubjectId
|
|
10553
|
+
),
|
|
10554
|
+
cancellationSignal,
|
|
10555
|
+
void 0
|
|
10556
|
+
);
|
|
10557
|
+
} catch (error51) {
|
|
10558
|
+
if (!(error51 instanceof AllowanceExhaustedError)) throw error51;
|
|
10559
|
+
allowanceRefusal = error51.refusal;
|
|
10560
|
+
}
|
|
10270
10561
|
const throwIfWorkerShuttingDown = () => {
|
|
10271
10562
|
const reason = activityContext?.cancellationSignal.reason;
|
|
10272
10563
|
if (isWorkerShutdownCancellation(reason)) {
|
|
@@ -10371,6 +10662,7 @@ async function claimTurnAttempt(deps) {
|
|
|
10371
10662
|
sessionStatus: inputSettlement.sessionStatus,
|
|
10372
10663
|
activeTurnId: inputSettlement.activeTurnId,
|
|
10373
10664
|
...inputSettlement.suppressGoalContinuation !== void 0 ? { suppressGoalContinuation: inputSettlement.suppressGoalContinuation } : {},
|
|
10665
|
+
...inputSettlement.allowanceGoalPause ? { allowanceGoalPause: inputSettlement.allowanceGoalPause } : {},
|
|
10374
10666
|
events: inputs,
|
|
10375
10667
|
...runState ? { runState } : {},
|
|
10376
10668
|
...compactionRequestFailure ? { compactionRequestFailure } : {}
|
|
@@ -10418,6 +10710,31 @@ async function claimTurnAttempt(deps) {
|
|
|
10418
10710
|
durationSeconds: (performance.now() - activityStarted) / 1e3
|
|
10419
10711
|
});
|
|
10420
10712
|
const turnStartSettlementStartedAt = performance.now();
|
|
10713
|
+
if (allowanceRefusal) {
|
|
10714
|
+
if (!await eventing.settle({
|
|
10715
|
+
events: [
|
|
10716
|
+
{ type: "usage.exhausted", payload: allowanceRefusal },
|
|
10717
|
+
{
|
|
10718
|
+
type: "turn.completed",
|
|
10719
|
+
payload: {
|
|
10720
|
+
output: "",
|
|
10721
|
+
segmentLimit: "budget_exhausted",
|
|
10722
|
+
...allowanceRefusal
|
|
10723
|
+
}
|
|
10724
|
+
},
|
|
10725
|
+
{ type: "session.status.changed", payload: { status: "idle" } }
|
|
10726
|
+
],
|
|
10727
|
+
turnStatus: "completed",
|
|
10728
|
+
sessionStatus: "idle",
|
|
10729
|
+
activeTurnId: null,
|
|
10730
|
+
allowanceGoalPause: { rationale: allowanceRefusal.message }
|
|
10731
|
+
})) {
|
|
10732
|
+
return { exit: claimedResult({ status: "cancelled" }) };
|
|
10733
|
+
}
|
|
10734
|
+
control.turnMetricOutcome = "completed";
|
|
10735
|
+
control.activityStatus = "idle";
|
|
10736
|
+
return { exit: claimedResult({ status: "idle" }) };
|
|
10737
|
+
}
|
|
10421
10738
|
if (!await eventing.settle({
|
|
10422
10739
|
events: [
|
|
10423
10740
|
{ type: "session.status.changed", payload: { status: "running" } },
|
|
@@ -11431,7 +11748,8 @@ import { retryWhileMissing as retryWhileMissing3 } from "@opengeni/storage";
|
|
|
11431
11748
|
import { WorkspaceModelPolicyBlockedError } from "@opengeni/runtime";
|
|
11432
11749
|
import {
|
|
11433
11750
|
evaluateWorkspaceModelPolicy,
|
|
11434
|
-
resolveWorkspaceAgentHumanInputEnabled as resolveWorkspaceAgentHumanInputEnabled2
|
|
11751
|
+
resolveWorkspaceAgentHumanInputEnabled as resolveWorkspaceAgentHumanInputEnabled2,
|
|
11752
|
+
resolveWorkspaceDefaultAgentIdentity
|
|
11435
11753
|
} from "@opengeni/contracts";
|
|
11436
11754
|
import { codeSearchEnabledForTurn } from "@opengeni/contracts/code-search";
|
|
11437
11755
|
|
|
@@ -11822,6 +12140,10 @@ async function prepareGovernanceAndModel(deps) {
|
|
|
11822
12140
|
);
|
|
11823
12141
|
const contextSelection = await resolveCompanyBrainContextSelection(db, governanceClaims);
|
|
11824
12142
|
const workspaceAgentInstructions = contextSelection.legacyWorkspaceInstructions;
|
|
12143
|
+
const workspaceAgentIdentity = resolveWorkspaceDefaultAgentIdentity(
|
|
12144
|
+
workspace.settings,
|
|
12145
|
+
workspaceAgentInstructions
|
|
12146
|
+
).identity;
|
|
11825
12147
|
const memoryPromptMode = contextSelection.receipt.memoryPromptMode;
|
|
11826
12148
|
assertWorkspaceHumanInputAllowed(agentHumanInputEnabled, "resume", humanInputResume !== null);
|
|
11827
12149
|
const companyProfileIncluded = contextSelection.receipt.companyProfileIncluded;
|
|
@@ -11981,6 +12303,7 @@ async function prepareGovernanceAndModel(deps) {
|
|
|
11981
12303
|
agentHumanInputEnabled,
|
|
11982
12304
|
codeSearchEnabled,
|
|
11983
12305
|
workspaceAgentInstructions,
|
|
12306
|
+
workspaceAgentIdentity,
|
|
11984
12307
|
workspaceGovernance,
|
|
11985
12308
|
structuredWorkspacePolicyActive,
|
|
11986
12309
|
workspaceMemory,
|
|
@@ -12008,7 +12331,9 @@ import {
|
|
|
12008
12331
|
appendSessionInstructions,
|
|
12009
12332
|
appendWorkspaceGovernance,
|
|
12010
12333
|
appendWorkspaceMemory,
|
|
12334
|
+
agentPromptResourcesFor,
|
|
12011
12335
|
composeAgentInstructions,
|
|
12336
|
+
inspectPersistentAgentInstructions,
|
|
12012
12337
|
requestRemoteCompactionV2,
|
|
12013
12338
|
preparedCompactionRequest,
|
|
12014
12339
|
queuePreparedCompaction,
|
|
@@ -12018,6 +12343,39 @@ import {
|
|
|
12018
12343
|
estimateSerializedValueTokens,
|
|
12019
12344
|
compactionSummaryOutputTokens as compactionSummaryOutputTokens2
|
|
12020
12345
|
} from "@opengeni/runtime";
|
|
12346
|
+
function standaloneCompactionInstructions(input) {
|
|
12347
|
+
if (input.session.agent) {
|
|
12348
|
+
return inspectPersistentAgentInstructions(input.settings, {
|
|
12349
|
+
agentConfig: input.session.agent,
|
|
12350
|
+
...input.workspaceAgentIdentity ? { workspaceAgentIdentity: input.workspaceAgentIdentity } : {},
|
|
12351
|
+
...input.workspaceGovernance ? { workspaceGovernance: input.workspaceGovernance } : {},
|
|
12352
|
+
...input.workspaceMemory ? { workspaceMemory: input.workspaceMemory } : {},
|
|
12353
|
+
...input.session.instructions ? { sessionInstructions: input.session.instructions } : {},
|
|
12354
|
+
...input.rig ? { rig: input.rig } : {},
|
|
12355
|
+
// Session-level facts only: per-turn attachments do not apply to a
|
|
12356
|
+
// standalone compaction request.
|
|
12357
|
+
agentPromptResources: agentPromptResourcesFor(
|
|
12358
|
+
input.settings,
|
|
12359
|
+
input.session.resources.filter((resource) => resource.kind !== "file"),
|
|
12360
|
+
input.rig ? { rig: input.rig } : {}
|
|
12361
|
+
)
|
|
12362
|
+
}).composed;
|
|
12363
|
+
}
|
|
12364
|
+
return appendWorkspaceMemory(
|
|
12365
|
+
appendSessionInstructions(
|
|
12366
|
+
appendWorkspaceGovernance(
|
|
12367
|
+
composeAgentInstructions(
|
|
12368
|
+
input.structuredWorkspacePolicyActive ? input.settings.agentInstructionsTemplate : input.workspaceAgentInstructions ?? input.settings.agentInstructionsTemplate,
|
|
12369
|
+
void 0,
|
|
12370
|
+
input.rig
|
|
12371
|
+
),
|
|
12372
|
+
input.workspaceGovernance ?? void 0
|
|
12373
|
+
),
|
|
12374
|
+
input.session.instructions ?? void 0
|
|
12375
|
+
),
|
|
12376
|
+
input.workspaceMemory ?? void 0
|
|
12377
|
+
);
|
|
12378
|
+
}
|
|
12021
12379
|
async function prepareCompaction(deps) {
|
|
12022
12380
|
const {
|
|
12023
12381
|
input,
|
|
@@ -12042,6 +12400,7 @@ async function prepareCompaction(deps) {
|
|
|
12042
12400
|
turnExecutionPolicy,
|
|
12043
12401
|
resolvedModel,
|
|
12044
12402
|
workspaceAgentInstructions,
|
|
12403
|
+
workspaceAgentIdentity,
|
|
12045
12404
|
workspaceGovernance,
|
|
12046
12405
|
structuredWorkspacePolicyActive,
|
|
12047
12406
|
workspaceMemory,
|
|
@@ -12185,20 +12544,16 @@ async function prepareCompaction(deps) {
|
|
|
12185
12544
|
return claimedResult({ status: "idle" });
|
|
12186
12545
|
};
|
|
12187
12546
|
if (compactionOnlyTurn && !remoteV2CompactionNeedsAgentPrefix && !portableResponsesNeedsAgentPrefix) {
|
|
12188
|
-
const compactionInstructions =
|
|
12189
|
-
|
|
12190
|
-
|
|
12191
|
-
|
|
12192
|
-
|
|
12193
|
-
|
|
12194
|
-
|
|
12195
|
-
|
|
12196
|
-
|
|
12197
|
-
|
|
12198
|
-
session.instructions ?? void 0
|
|
12199
|
-
),
|
|
12200
|
-
workspaceMemory ?? void 0
|
|
12201
|
-
);
|
|
12547
|
+
const compactionInstructions = standaloneCompactionInstructions({
|
|
12548
|
+
settings: eventing.modelRunSettings,
|
|
12549
|
+
session,
|
|
12550
|
+
workspaceAgentInstructions,
|
|
12551
|
+
workspaceAgentIdentity,
|
|
12552
|
+
workspaceGovernance,
|
|
12553
|
+
structuredWorkspacePolicyActive,
|
|
12554
|
+
workspaceMemory,
|
|
12555
|
+
rig: rigVersion && rigName ? { name: rigName, version: rigVersion.version } : void 0
|
|
12556
|
+
});
|
|
12202
12557
|
const requested = await isSessionCompactionRequested2(db, input.workspaceId, input.sessionId);
|
|
12203
12558
|
let outcome = null;
|
|
12204
12559
|
if (requested) {
|
|
@@ -13267,6 +13622,7 @@ async function resolveSandboxRoute(deps) {
|
|
|
13267
13622
|
machinePrimary,
|
|
13268
13623
|
groupBoxBackend,
|
|
13269
13624
|
groupBoxImage,
|
|
13625
|
+
groupBoxImagePolicy: "new_creates_only",
|
|
13270
13626
|
sandboxCreationBackend,
|
|
13271
13627
|
effectiveRunCredentialBackend
|
|
13272
13628
|
};
|
|
@@ -13306,6 +13662,7 @@ async function establishTurnSandbox(deps) {
|
|
|
13306
13662
|
machinePrimary,
|
|
13307
13663
|
groupBoxBackend,
|
|
13308
13664
|
groupBoxImage,
|
|
13665
|
+
groupBoxImagePolicy,
|
|
13309
13666
|
rigVersion,
|
|
13310
13667
|
turnResources
|
|
13311
13668
|
} = deps;
|
|
@@ -13560,7 +13917,8 @@ async function establishTurnSandbox(deps) {
|
|
|
13560
13917
|
os: groupBoxOs,
|
|
13561
13918
|
environment: sandboxEnvironment,
|
|
13562
13919
|
...groupBoxImage ? {
|
|
13563
|
-
image: groupBoxImage
|
|
13920
|
+
image: groupBoxImage,
|
|
13921
|
+
imagePolicy: groupBoxImagePolicy
|
|
13564
13922
|
} : {},
|
|
13565
13923
|
// The lazy acquire must enforce the same frozen rig authority
|
|
13566
13924
|
// as the eager acquire; otherwise a warm box for another rig
|
|
@@ -13637,16 +13995,16 @@ async function establishTurnSandbox(deps) {
|
|
|
13637
13995
|
backend: groupBoxBackend,
|
|
13638
13996
|
os: groupBoxOs,
|
|
13639
13997
|
environment: sandboxEnvironment,
|
|
13640
|
-
//
|
|
13641
|
-
//
|
|
13642
|
-
//
|
|
13643
|
-
//
|
|
13644
|
-
// the image for the actual group-box backend; a configured Modal image must
|
|
13998
|
+
// Deployment/workspace pins select NEW creates only. The lease
|
|
13999
|
+
// retains a live group's image through between-turn repins, even
|
|
14000
|
+
// with other holders; only rotation/reaping elects a new image.
|
|
14001
|
+
// Select the image for the actual group-box backend; a configured Modal image must
|
|
13645
14002
|
// never override a Docker run. The selfhosted branch
|
|
13646
14003
|
// (establishSelfhostedTurnSession) NEVER passes
|
|
13647
14004
|
// an image — B3 lives only on this managed-box branch.
|
|
13648
14005
|
...groupBoxImage ? {
|
|
13649
|
-
image: groupBoxImage
|
|
14006
|
+
image: groupBoxImage,
|
|
14007
|
+
imagePolicy: groupBoxImagePolicy
|
|
13650
14008
|
} : {},
|
|
13651
14009
|
// RIG IS SHARED STATE (M3): stamp the frozen rig version so the lease
|
|
13652
14010
|
// conflicts on a live shared box set up under a different rig (solo
|
|
@@ -14342,6 +14700,100 @@ import {
|
|
|
14342
14700
|
} from "@opengeni/runtime";
|
|
14343
14701
|
import { codemodeWorkspaceUrl as codemodeWorkspaceUrl2 } from "@opengeni/config";
|
|
14344
14702
|
|
|
14703
|
+
// src/activities/mcp-account-routes.ts
|
|
14704
|
+
function accountRouteAuthNeededPayload(payload, bindings) {
|
|
14705
|
+
const binding = bindings?.find((candidate) => candidate.serverId === payload.serverId);
|
|
14706
|
+
return binding ? {
|
|
14707
|
+
...payload,
|
|
14708
|
+
canonicalServerId: binding.canonicalServerId,
|
|
14709
|
+
connectionSubjectScope: binding.subjectScope
|
|
14710
|
+
} : payload;
|
|
14711
|
+
}
|
|
14712
|
+
function expandMcpAccountRoutes(input) {
|
|
14713
|
+
if (input.bindings == null) {
|
|
14714
|
+
return { settings: input.settings, tools: input.tools, accountLabels: /* @__PURE__ */ new Map() };
|
|
14715
|
+
}
|
|
14716
|
+
const configured = new Map(input.settings.mcpServers.map((server) => [server.id, server]));
|
|
14717
|
+
const byCanonical = /* @__PURE__ */ new Map();
|
|
14718
|
+
const routes = /* @__PURE__ */ new Set();
|
|
14719
|
+
const accounts = /* @__PURE__ */ new Set();
|
|
14720
|
+
for (const binding of input.bindings) {
|
|
14721
|
+
const account = JSON.stringify([binding.canonicalServerId, binding.connectionId]);
|
|
14722
|
+
if (routes.has(binding.serverId) || accounts.has(account) || configured.has(binding.serverId) || binding.subjectScope === "subject" !== (binding.ownerSubjectId !== null) || binding.connectionRef.authoritySource === "host" || binding.connectionRef.connectionId !== binding.connectionId || binding.connectionRef.subjectScope !== binding.subjectScope || binding.connectionRef.providerDomain !== binding.providerDomain || binding.connectionRef.kind !== binding.kind) {
|
|
14723
|
+
throw new Error("Invalid accepted MCP account route");
|
|
14724
|
+
}
|
|
14725
|
+
routes.add(binding.serverId);
|
|
14726
|
+
accounts.add(account);
|
|
14727
|
+
const siblings = byCanonical.get(binding.canonicalServerId) ?? [];
|
|
14728
|
+
siblings.push(binding);
|
|
14729
|
+
byCanonical.set(binding.canonicalServerId, siblings);
|
|
14730
|
+
}
|
|
14731
|
+
const servers = [];
|
|
14732
|
+
const tools = [];
|
|
14733
|
+
const accountLabels = /* @__PURE__ */ new Map();
|
|
14734
|
+
for (const tool of input.tools) {
|
|
14735
|
+
const bindings = byCanonical.get(tool.id);
|
|
14736
|
+
if (!bindings) {
|
|
14737
|
+
if (!configured.get(tool.id)?.connectionRef) tools.push(tool);
|
|
14738
|
+
continue;
|
|
14739
|
+
}
|
|
14740
|
+
const canonical = configured.get(tool.id);
|
|
14741
|
+
if (!canonical?.connectionRef) {
|
|
14742
|
+
throw new Error("Accepted MCP account route has no canonical connection configuration");
|
|
14743
|
+
}
|
|
14744
|
+
for (const binding of bindings) {
|
|
14745
|
+
if (canonical.connectionRef.authoritySource === "host" || canonical.connectionRef.providerDomain !== binding.providerDomain || canonical.connectionRef.kind && canonical.connectionRef.kind !== binding.kind) {
|
|
14746
|
+
throw new Error("Accepted MCP account route does not match canonical provider");
|
|
14747
|
+
}
|
|
14748
|
+
const { headers: _headers, ...config2 } = canonical;
|
|
14749
|
+
const label = `${canonical.name ?? canonical.id} \u2014 ${binding.subjectScope === "subject" ? "Personal" : "Workspace"}: ${binding.accountLabel}`;
|
|
14750
|
+
servers.push({
|
|
14751
|
+
...config2,
|
|
14752
|
+
id: binding.serverId,
|
|
14753
|
+
name: label,
|
|
14754
|
+
connectionRef: structuredClone(binding.connectionRef)
|
|
14755
|
+
});
|
|
14756
|
+
tools.push({ ...tool, id: binding.serverId });
|
|
14757
|
+
accountLabels.set(binding.serverId, label);
|
|
14758
|
+
}
|
|
14759
|
+
}
|
|
14760
|
+
return {
|
|
14761
|
+
settings: {
|
|
14762
|
+
...input.settings,
|
|
14763
|
+
mcpServers: [
|
|
14764
|
+
...input.settings.mcpServers.filter((server) => !server.connectionRef),
|
|
14765
|
+
...servers
|
|
14766
|
+
]
|
|
14767
|
+
},
|
|
14768
|
+
tools,
|
|
14769
|
+
accountLabels
|
|
14770
|
+
};
|
|
14771
|
+
}
|
|
14772
|
+
function expandApiIntegrationAccountRoutes(input) {
|
|
14773
|
+
const selected = new Set(input.tools.map((tool) => tool.id));
|
|
14774
|
+
if (input.bindings == null)
|
|
14775
|
+
return input.integrations.filter((item) => selected.has(item.serverId));
|
|
14776
|
+
const acceptedBindings = input.bindings;
|
|
14777
|
+
return input.integrations.flatMap((integration) => {
|
|
14778
|
+
const bindings = acceptedBindings.filter(
|
|
14779
|
+
(binding) => binding.canonicalServerId === integration.serverId
|
|
14780
|
+
);
|
|
14781
|
+
if (bindings.length === 0)
|
|
14782
|
+
return !integration.connectionRef && selected.has(integration.serverId) ? [integration] : [];
|
|
14783
|
+
return bindings.filter((binding) => selected.has(binding.serverId)).map((binding) => {
|
|
14784
|
+
if (binding.connectionAuthorityGeneration === void 0) {
|
|
14785
|
+
throw new Error("Accepted API integration account route has no authority generation");
|
|
14786
|
+
}
|
|
14787
|
+
return {
|
|
14788
|
+
...integration,
|
|
14789
|
+
serverId: binding.serverId,
|
|
14790
|
+
connectionRef: structuredClone(binding.connectionRef),
|
|
14791
|
+
connectionAuthorityGeneration: binding.connectionAuthorityGeneration
|
|
14792
|
+
};
|
|
14793
|
+
});
|
|
14794
|
+
});
|
|
14795
|
+
}
|
|
14796
|
+
|
|
14345
14797
|
// src/activities/git-credential-renewal.ts
|
|
14346
14798
|
var GIT_CREDENTIAL_DEFAULT_REFRESH_MS = 30 * 6e4;
|
|
14347
14799
|
var GIT_CREDENTIAL_EXPIRY_LEAD_MS = 5 * 6e4;
|
|
@@ -14700,6 +15152,8 @@ function credentialProviderRequestBody(input, initiatingHumanSubjectId, initiati
|
|
|
14700
15152
|
lane: "workspace",
|
|
14701
15153
|
mcpServers: []
|
|
14702
15154
|
}) {
|
|
15155
|
+
const via = input.initiatorContext.via;
|
|
15156
|
+
const latestHop = Array.isArray(via) ? via.at(-1) : null;
|
|
14703
15157
|
return {
|
|
14704
15158
|
type: "credentials.request",
|
|
14705
15159
|
lane: selection.lane,
|
|
@@ -14714,6 +15168,11 @@ function credentialProviderRequestBody(input, initiatingHumanSubjectId, initiati
|
|
|
14714
15168
|
turnId: input.turnId,
|
|
14715
15169
|
attemptId: input.attemptId,
|
|
14716
15170
|
initiator: { kind: input.initiator.kind, subjectId: input.initiator.subjectId },
|
|
15171
|
+
initiatorContext: {
|
|
15172
|
+
kind: latestHop?.kind === "agent" ? "agent" : input.initiator.kind === "subject" ? "human" : "service",
|
|
15173
|
+
initiator: input.initiator,
|
|
15174
|
+
context: input.initiatorContext
|
|
15175
|
+
},
|
|
14717
15176
|
initiatingHumanSubjectId,
|
|
14718
15177
|
initiatingHuman,
|
|
14719
15178
|
sandboxBackend: input.effectiveSandboxBackend,
|
|
@@ -14905,7 +15364,7 @@ async function bindRunCredentialResolver(input) {
|
|
|
14905
15364
|
mcpServers: selectedSessionRemoteMcpTargets(
|
|
14906
15365
|
input.settings,
|
|
14907
15366
|
input.session.mcpServers ?? [],
|
|
14908
|
-
input.
|
|
15367
|
+
input.effectiveTools,
|
|
14909
15368
|
(input.localMcpServerIds ?? []).map((id) => ({ id }))
|
|
14910
15369
|
)
|
|
14911
15370
|
}
|
|
@@ -14921,22 +15380,23 @@ async function bindRunCredentialResolver(input) {
|
|
|
14921
15380
|
workspaceId: input.workspaceId,
|
|
14922
15381
|
sessionId: input.session.id
|
|
14923
15382
|
};
|
|
15383
|
+
const frozenRequest = structuredClone(
|
|
15384
|
+
buildRunCredentialsRequest({
|
|
15385
|
+
accountId: input.accountId,
|
|
15386
|
+
workspaceId: input.workspaceId,
|
|
15387
|
+
session: input.session,
|
|
15388
|
+
turn: input.turn,
|
|
15389
|
+
attemptId: input.attemptId,
|
|
15390
|
+
effectiveSandboxBackend: input.effectiveSandboxBackend,
|
|
15391
|
+
variableSet: input.variableSet,
|
|
15392
|
+
rootSessionId,
|
|
15393
|
+
purpose: "provision",
|
|
15394
|
+
forceRefresh: false
|
|
15395
|
+
})
|
|
15396
|
+
);
|
|
14924
15397
|
return {
|
|
14925
15398
|
resolve: async ({ purpose, forceRefresh }) => {
|
|
14926
|
-
const resolution = await resolver(
|
|
14927
|
-
buildRunCredentialsRequest({
|
|
14928
|
-
accountId: input.accountId,
|
|
14929
|
-
workspaceId: input.workspaceId,
|
|
14930
|
-
session: input.session,
|
|
14931
|
-
turn: input.turn,
|
|
14932
|
-
attemptId: input.attemptId,
|
|
14933
|
-
effectiveSandboxBackend: input.effectiveSandboxBackend,
|
|
14934
|
-
variableSet: input.variableSet,
|
|
14935
|
-
rootSessionId,
|
|
14936
|
-
purpose,
|
|
14937
|
-
forceRefresh
|
|
14938
|
-
})
|
|
14939
|
-
);
|
|
15399
|
+
const resolution = await resolver({ ...frozenRequest, purpose, forceRefresh });
|
|
14940
15400
|
return normalizeRunCredentialsResolution(resolution, scope);
|
|
14941
15401
|
}
|
|
14942
15402
|
};
|
|
@@ -14959,6 +15419,7 @@ async function prepareRunCredentials(deps) {
|
|
|
14959
15419
|
sandboxState,
|
|
14960
15420
|
turn,
|
|
14961
15421
|
session,
|
|
15422
|
+
turnExecutionPolicy,
|
|
14962
15423
|
fileAuthoritySubjectId,
|
|
14963
15424
|
runSettings,
|
|
14964
15425
|
workspaceVariableSet,
|
|
@@ -14981,13 +15442,19 @@ async function prepareRunCredentials(deps) {
|
|
|
14981
15442
|
const platformGitResources = turnResources.filter(
|
|
14982
15443
|
(resource) => resource.kind !== "repository" || repositoryHasExplicitGitConnection(resource)
|
|
14983
15444
|
);
|
|
15445
|
+
const accountRoutes = expandMcpAccountRoutes({
|
|
15446
|
+
settings: runSettings,
|
|
15447
|
+
tools: deps.turnTools,
|
|
15448
|
+
bindings: turn.mcpAccountBindings
|
|
15449
|
+
});
|
|
14984
15450
|
const runCredentialResolver = effectiveRunCredentialBackend === "none" || effectiveRunCredentialBackend === "selfhosted" ? null : await waitForTurnOperation(
|
|
14985
15451
|
bindRunCredentialResolver({
|
|
14986
15452
|
db,
|
|
14987
|
-
settings:
|
|
15453
|
+
settings: accountRoutes.settings,
|
|
14988
15454
|
initiatingHumanSubjectId: turn.initiatingHumanSubjectId ?? null,
|
|
14989
15455
|
connectionCredentials: connectionCredentials ?? null,
|
|
14990
15456
|
localMcpServerIds: deps.localMcpServerIds ?? [],
|
|
15457
|
+
effectiveTools: accountRoutes.tools,
|
|
14991
15458
|
accountId: input.accountId,
|
|
14992
15459
|
workspaceId: input.workspaceId,
|
|
14993
15460
|
session,
|
|
@@ -15026,9 +15493,9 @@ async function prepareRunCredentials(deps) {
|
|
|
15026
15493
|
) : null;
|
|
15027
15494
|
const runMcpCredentials = new RunMcpCredentials(
|
|
15028
15495
|
selectedSessionRemoteMcpTargets2(
|
|
15029
|
-
|
|
15496
|
+
accountRoutes.settings,
|
|
15030
15497
|
session.mcpServers ?? [],
|
|
15031
|
-
|
|
15498
|
+
accountRoutes.tools,
|
|
15032
15499
|
(deps.localMcpServerIds ?? []).map((id) => ({ id }))
|
|
15033
15500
|
),
|
|
15034
15501
|
{
|
|
@@ -15111,11 +15578,13 @@ async function prepareRunCredentials(deps) {
|
|
|
15111
15578
|
attemptId: input.attemptId,
|
|
15112
15579
|
turn
|
|
15113
15580
|
}) : void 0;
|
|
15581
|
+
const credentialRestriction = turnCredentialRestriction(turnExecutionPolicy, session.metadata);
|
|
15114
15582
|
const codemodeAuthority = {
|
|
15115
15583
|
sessionId: input.sessionId,
|
|
15116
15584
|
turnId: turn.id,
|
|
15117
15585
|
attemptId: input.attemptId,
|
|
15118
|
-
executionGeneration: turn.executionGeneration
|
|
15586
|
+
executionGeneration: turn.executionGeneration,
|
|
15587
|
+
...credentialRestriction ? { credentialRestriction } : {}
|
|
15119
15588
|
};
|
|
15120
15589
|
const sandboxArtifactRuntime = sandboxArtifactRuntimeAdmission(
|
|
15121
15590
|
settings,
|
|
@@ -16410,100 +16879,6 @@ function isGitHubApiDestination(value) {
|
|
|
16410
16879
|
}
|
|
16411
16880
|
}
|
|
16412
16881
|
|
|
16413
|
-
// src/activities/mcp-account-routes.ts
|
|
16414
|
-
function accountRouteAuthNeededPayload(payload, bindings) {
|
|
16415
|
-
const binding = bindings?.find((candidate) => candidate.serverId === payload.serverId);
|
|
16416
|
-
return binding ? {
|
|
16417
|
-
...payload,
|
|
16418
|
-
canonicalServerId: binding.canonicalServerId,
|
|
16419
|
-
connectionSubjectScope: binding.subjectScope
|
|
16420
|
-
} : payload;
|
|
16421
|
-
}
|
|
16422
|
-
function expandMcpAccountRoutes(input) {
|
|
16423
|
-
if (input.bindings == null) {
|
|
16424
|
-
return { settings: input.settings, tools: input.tools, accountLabels: /* @__PURE__ */ new Map() };
|
|
16425
|
-
}
|
|
16426
|
-
const configured = new Map(input.settings.mcpServers.map((server) => [server.id, server]));
|
|
16427
|
-
const byCanonical = /* @__PURE__ */ new Map();
|
|
16428
|
-
const routes = /* @__PURE__ */ new Set();
|
|
16429
|
-
const accounts = /* @__PURE__ */ new Set();
|
|
16430
|
-
for (const binding of input.bindings) {
|
|
16431
|
-
const account = JSON.stringify([binding.canonicalServerId, binding.connectionId]);
|
|
16432
|
-
if (routes.has(binding.serverId) || accounts.has(account) || configured.has(binding.serverId) || binding.subjectScope === "subject" !== (binding.ownerSubjectId !== null) || binding.connectionRef.authoritySource === "host" || binding.connectionRef.connectionId !== binding.connectionId || binding.connectionRef.subjectScope !== binding.subjectScope || binding.connectionRef.providerDomain !== binding.providerDomain || binding.connectionRef.kind !== binding.kind) {
|
|
16433
|
-
throw new Error("Invalid accepted MCP account route");
|
|
16434
|
-
}
|
|
16435
|
-
routes.add(binding.serverId);
|
|
16436
|
-
accounts.add(account);
|
|
16437
|
-
const siblings = byCanonical.get(binding.canonicalServerId) ?? [];
|
|
16438
|
-
siblings.push(binding);
|
|
16439
|
-
byCanonical.set(binding.canonicalServerId, siblings);
|
|
16440
|
-
}
|
|
16441
|
-
const servers = [];
|
|
16442
|
-
const tools = [];
|
|
16443
|
-
const accountLabels = /* @__PURE__ */ new Map();
|
|
16444
|
-
for (const tool of input.tools) {
|
|
16445
|
-
const bindings = byCanonical.get(tool.id);
|
|
16446
|
-
if (!bindings) {
|
|
16447
|
-
if (!configured.get(tool.id)?.connectionRef) tools.push(tool);
|
|
16448
|
-
continue;
|
|
16449
|
-
}
|
|
16450
|
-
const canonical = configured.get(tool.id);
|
|
16451
|
-
if (!canonical?.connectionRef) {
|
|
16452
|
-
throw new Error("Accepted MCP account route has no canonical connection configuration");
|
|
16453
|
-
}
|
|
16454
|
-
for (const binding of bindings) {
|
|
16455
|
-
if (canonical.connectionRef.authoritySource === "host" || canonical.connectionRef.providerDomain !== binding.providerDomain || canonical.connectionRef.kind && canonical.connectionRef.kind !== binding.kind) {
|
|
16456
|
-
throw new Error("Accepted MCP account route does not match canonical provider");
|
|
16457
|
-
}
|
|
16458
|
-
const { headers: _headers, ...config2 } = canonical;
|
|
16459
|
-
const label = `${canonical.name ?? canonical.id} \u2014 ${binding.subjectScope === "subject" ? "Personal" : "Workspace"}: ${binding.accountLabel}`;
|
|
16460
|
-
servers.push({
|
|
16461
|
-
...config2,
|
|
16462
|
-
id: binding.serverId,
|
|
16463
|
-
name: label,
|
|
16464
|
-
connectionRef: structuredClone(binding.connectionRef)
|
|
16465
|
-
});
|
|
16466
|
-
tools.push({ ...tool, id: binding.serverId });
|
|
16467
|
-
accountLabels.set(binding.serverId, label);
|
|
16468
|
-
}
|
|
16469
|
-
}
|
|
16470
|
-
return {
|
|
16471
|
-
settings: {
|
|
16472
|
-
...input.settings,
|
|
16473
|
-
mcpServers: [
|
|
16474
|
-
...input.settings.mcpServers.filter((server) => !server.connectionRef),
|
|
16475
|
-
...servers
|
|
16476
|
-
]
|
|
16477
|
-
},
|
|
16478
|
-
tools,
|
|
16479
|
-
accountLabels
|
|
16480
|
-
};
|
|
16481
|
-
}
|
|
16482
|
-
function expandApiIntegrationAccountRoutes(input) {
|
|
16483
|
-
const selected = new Set(input.tools.map((tool) => tool.id));
|
|
16484
|
-
if (input.bindings == null)
|
|
16485
|
-
return input.integrations.filter((item) => selected.has(item.serverId));
|
|
16486
|
-
const acceptedBindings = input.bindings;
|
|
16487
|
-
return input.integrations.flatMap((integration) => {
|
|
16488
|
-
const bindings = acceptedBindings.filter(
|
|
16489
|
-
(binding) => binding.canonicalServerId === integration.serverId
|
|
16490
|
-
);
|
|
16491
|
-
if (bindings.length === 0)
|
|
16492
|
-
return !integration.connectionRef && selected.has(integration.serverId) ? [integration] : [];
|
|
16493
|
-
return bindings.filter((binding) => selected.has(binding.serverId)).map((binding) => {
|
|
16494
|
-
if (binding.connectionAuthorityGeneration === void 0) {
|
|
16495
|
-
throw new Error("Accepted API integration account route has no authority generation");
|
|
16496
|
-
}
|
|
16497
|
-
return {
|
|
16498
|
-
...integration,
|
|
16499
|
-
serverId: binding.serverId,
|
|
16500
|
-
connectionRef: structuredClone(binding.connectionRef),
|
|
16501
|
-
connectionAuthorityGeneration: binding.connectionAuthorityGeneration
|
|
16502
|
-
};
|
|
16503
|
-
});
|
|
16504
|
-
});
|
|
16505
|
-
}
|
|
16506
|
-
|
|
16507
16882
|
// src/activities/agent-turn/tool-environment.ts
|
|
16508
16883
|
import { createMcpOperationPersistence } from "@opengeni/db/mcp-operations";
|
|
16509
16884
|
|
|
@@ -32257,14 +32632,17 @@ import {
|
|
|
32257
32632
|
buildApiIntegrationMcpServers,
|
|
32258
32633
|
resolveCatalogSettings as resolveCatalogSettings2,
|
|
32259
32634
|
resolveWorkspaceModelSelection,
|
|
32635
|
+
loadWorkspaceCodexModelAvailability,
|
|
32260
32636
|
withFrozenPersonalConnectionDelegations,
|
|
32261
|
-
|
|
32637
|
+
resolveTurnToolPolicy,
|
|
32638
|
+
scheduledTurnMcpServerIds,
|
|
32262
32639
|
hasPermission as hasPermission2
|
|
32263
32640
|
} from "@opengeni/core";
|
|
32264
32641
|
import { SandboxChannelAService as SandboxChannelAService3 } from "@opengeni/runtime/sandbox";
|
|
32265
32642
|
import { sandboxRunAs as sandboxRunAs4 } from "@opengeni/runtime";
|
|
32266
32643
|
import {
|
|
32267
|
-
DEFAULT_FIRST_PARTY_MCP_PERMISSIONS as DEFAULT_FIRST_PARTY_MCP_PERMISSIONS2
|
|
32644
|
+
DEFAULT_FIRST_PARTY_MCP_PERMISSIONS as DEFAULT_FIRST_PARTY_MCP_PERMISSIONS2,
|
|
32645
|
+
resolveAgentToolFamilies
|
|
32268
32646
|
} from "@opengeni/contracts";
|
|
32269
32647
|
|
|
32270
32648
|
// src/activities/agent-turn/list-models.ts
|
|
@@ -33703,27 +34081,31 @@ async function prepareTurnToolPolicy(deps) {
|
|
|
33703
34081
|
} = deps;
|
|
33704
34082
|
const turnResources = mergeResourceRefs(session.resources, turn.resources);
|
|
33705
34083
|
const runtimeResources = runtimeResourcesForTurn(session.resources, turn.resources);
|
|
33706
|
-
const
|
|
33707
|
-
const value = turn.metadata && typeof turn.metadata === "object" && !Array.isArray(turn.metadata) ? turn.metadata.scheduledEffectiveMcpServerIds : null;
|
|
33708
|
-
return Array.isArray(value) && value.every((id) => typeof id === "string") ? [...new Set(value)].sort() : null;
|
|
33709
|
-
})();
|
|
33710
|
-
const currentMcpServerIds = new Set(runSettings.mcpServers.map((server) => server.id));
|
|
33711
|
-
const resolvedToolPolicy = resolveSessionToolPolicy({
|
|
34084
|
+
const resolvedToolPolicy = resolveTurnToolPolicy({
|
|
33712
34085
|
toolPolicy: session.toolPolicy,
|
|
33713
|
-
|
|
33714
|
-
|
|
33715
|
-
|
|
34086
|
+
session,
|
|
34087
|
+
turn,
|
|
34088
|
+
availableMcpServerIds: runSettings.mcpServers.map((server) => server.id),
|
|
34089
|
+
defaultMcpServerIds: scheduledTurnMcpServerIds(turn) === null && session.toolPolicy.mode === "workspace_default" ? await workspaceSessionToolPolicyDefaultServerIds(
|
|
33716
34090
|
db,
|
|
33717
34091
|
input.workspaceId,
|
|
33718
34092
|
capabilitySettings,
|
|
33719
34093
|
fileAuthoritySubjectId ?? void 0
|
|
33720
|
-
) : []
|
|
34094
|
+
) : []
|
|
33721
34095
|
});
|
|
33722
34096
|
const mcpAvailabilityNote = unavailableMcpOperationalContext({
|
|
33723
34097
|
droppedIds: resolvedToolPolicy.effectivePolicy.droppedIds,
|
|
33724
34098
|
droppedCount: resolvedToolPolicy.effectivePolicy.counts.dropped
|
|
33725
34099
|
});
|
|
33726
|
-
const
|
|
34100
|
+
const families = resolveAgentToolFamilies(session.agent, {
|
|
34101
|
+
productServerIds: /* @__PURE__ */ new Set([
|
|
34102
|
+
...session.mcpServers.map((server) => server.id),
|
|
34103
|
+
...session.toolPolicy.mode !== "workspace_default" ? session.tools.map((tool) => tool.id) : []
|
|
34104
|
+
])
|
|
34105
|
+
});
|
|
34106
|
+
const effectivePolicyTools = resolvedToolPolicy.toolRefs.filter(
|
|
34107
|
+
(tool) => tool.kind !== "mcp" || families.allowsMcpServer(tool.id)
|
|
34108
|
+
);
|
|
33727
34109
|
const turnTools = withFirstPartyTools(runSettings, effectivePolicyTools);
|
|
33728
34110
|
const connectionScope = {
|
|
33729
34111
|
accountId: input.accountId,
|
|
@@ -33854,6 +34236,7 @@ async function prepareTurnToolRuntime(deps) {
|
|
|
33854
34236
|
});
|
|
33855
34237
|
const runSettings = accountRoutes.settings;
|
|
33856
34238
|
const turnTools = accountRoutes.tools;
|
|
34239
|
+
const credentialRestriction = turnCredentialRestriction(turnExecutionPolicy, session.metadata);
|
|
33857
34240
|
const toolContextPreparationStartedAt = performance.now();
|
|
33858
34241
|
throwIfWorkerShuttingDown();
|
|
33859
34242
|
throwIfTurnCancelled();
|
|
@@ -34003,14 +34386,16 @@ async function prepareTurnToolRuntime(deps) {
|
|
|
34003
34386
|
const effectiveFirstPartyPermissions = linkedAuthority ? (session.firstPartyMcpPermissions ?? DEFAULT_FIRST_PARTY_MCP_PERMISSIONS2).filter(
|
|
34004
34387
|
(permission) => hasPermission2(linkedAuthority.permissions, permission)
|
|
34005
34388
|
) : session.firstPartyMcpPermissions;
|
|
34006
|
-
const
|
|
34007
|
-
|
|
34008
|
-
session.firstPartyMcpTools
|
|
34389
|
+
const toolFamilies = resolveAgentToolFamilies(session.agent);
|
|
34390
|
+
const selectedFirstPartyMcpTools = toolFamilies.firstPartyTools(
|
|
34391
|
+
allowedFirstPartyMcpToolsForSession(runSettings, session.firstPartyMcpTools)
|
|
34009
34392
|
);
|
|
34010
34393
|
const titleToolPlan = sessionTitleToolPlan({
|
|
34394
|
+
agentConfig: session.agent,
|
|
34011
34395
|
tools: turnTools,
|
|
34012
34396
|
selectedFirstPartyMcpTools,
|
|
34013
34397
|
shouldRequestTitle: shouldRequestMissingSessionTitle({
|
|
34398
|
+
agentConfig: session.agent,
|
|
34014
34399
|
title: session.title,
|
|
34015
34400
|
titleSource: session.titleSource,
|
|
34016
34401
|
firstPartyMcpTools: selectedFirstPartyMcpTools,
|
|
@@ -34070,7 +34455,7 @@ async function prepareTurnToolRuntime(deps) {
|
|
|
34070
34455
|
workspaceId: input.workspaceId,
|
|
34071
34456
|
...deps.fileAuthoritySubjectId ? { subjectId: deps.fileAuthoritySubjectId } : {}
|
|
34072
34457
|
});
|
|
34073
|
-
const skillCatalog = [
|
|
34458
|
+
const skillCatalog = toolFamilies.skills === false ? [] : [
|
|
34074
34459
|
...sharedSkillDescriptors.filter((entry) => entry.activationMode === "workspace_managed").map((entry) => ({
|
|
34075
34460
|
id: entry.id,
|
|
34076
34461
|
name: entry.title,
|
|
@@ -34242,6 +34627,9 @@ async function prepareTurnToolRuntime(deps) {
|
|
|
34242
34627
|
);
|
|
34243
34628
|
}
|
|
34244
34629
|
});
|
|
34630
|
+
const attemptToolFamilies = resolveAgentToolFamilies(session.agent, {
|
|
34631
|
+
hasSkills: skillCatalog.length > 0
|
|
34632
|
+
});
|
|
34245
34633
|
const attemptToolDefinitions = [
|
|
34246
34634
|
...operationReadStore ? [
|
|
34247
34635
|
createOperationReadAttemptToolDefinition({
|
|
@@ -34283,7 +34671,8 @@ async function prepareTurnToolRuntime(deps) {
|
|
|
34283
34671
|
organizationGatewayConnectionActive,
|
|
34284
34672
|
organizationGatewayCustomModels,
|
|
34285
34673
|
organizationOpenRouterConnectionActive,
|
|
34286
|
-
organizationOpenRouterCustomModels
|
|
34674
|
+
organizationOpenRouterCustomModels,
|
|
34675
|
+
codexModelAvailability
|
|
34287
34676
|
] = await Promise.all([
|
|
34288
34677
|
getWorkspaceConnectionModelRestrictions(
|
|
34289
34678
|
db,
|
|
@@ -34326,10 +34715,12 @@ async function prepareTurnToolRuntime(deps) {
|
|
|
34326
34715
|
accountId: input.accountId,
|
|
34327
34716
|
workspaceId: input.workspaceId,
|
|
34328
34717
|
providerKind: "openrouter"
|
|
34329
|
-
})
|
|
34718
|
+
}),
|
|
34719
|
+
loadWorkspaceCodexModelAvailability(db, currentSettings, input.workspaceId)
|
|
34330
34720
|
]);
|
|
34331
34721
|
return {
|
|
34332
34722
|
selections: resolveWorkspaceModelSelection({
|
|
34723
|
+
observations: codexModelAvailability,
|
|
34333
34724
|
connectionModelRestrictions,
|
|
34334
34725
|
settings: currentSettings,
|
|
34335
34726
|
policy,
|
|
@@ -34369,6 +34760,7 @@ async function prepareTurnToolRuntime(deps) {
|
|
|
34369
34760
|
] : [],
|
|
34370
34761
|
...createFirstPartyInteractionAttemptToolDefinitions({
|
|
34371
34762
|
settings: runSettings,
|
|
34763
|
+
...credentialRestriction ? { credentialRestriction } : {},
|
|
34372
34764
|
scope: {
|
|
34373
34765
|
accountId: input.accountId,
|
|
34374
34766
|
workspaceId: input.workspaceId,
|
|
@@ -34385,7 +34777,7 @@ async function prepareTurnToolRuntime(deps) {
|
|
|
34385
34777
|
}),
|
|
34386
34778
|
...googleDrivePublicationTool && googleDrivePublicationAllowed ? [googleDrivePublicationTool] : [],
|
|
34387
34779
|
...codeSearchTools
|
|
34388
|
-
];
|
|
34780
|
+
].filter((tool) => attemptToolFamilies.allowsFunctionTool(tool.modelName));
|
|
34389
34781
|
recordTurnStartupPhase(observability, {
|
|
34390
34782
|
phase: "tool_context_preparation",
|
|
34391
34783
|
provider: turnExecutionPolicy.providerId,
|
|
@@ -34455,6 +34847,7 @@ async function prepareTurnToolRuntime(deps) {
|
|
|
34455
34847
|
try {
|
|
34456
34848
|
eventing.preparedTools = await waitForTurnOperation(
|
|
34457
34849
|
runtime.prepareTools(githubRestMcp.settings, githubRestMcp.tools, {
|
|
34850
|
+
...credentialRestriction ? { credentialRestriction } : {},
|
|
34458
34851
|
mcpAccountLabels: accountRoutes.accountLabels,
|
|
34459
34852
|
accountId: input.accountId,
|
|
34460
34853
|
workspaceId: input.workspaceId,
|
|
@@ -34473,7 +34866,7 @@ async function prepareTurnToolRuntime(deps) {
|
|
|
34473
34866
|
sessionAttachedRemoteMcpTargets: selectedSessionRemoteMcpTargets3(
|
|
34474
34867
|
githubRestMcp.settings,
|
|
34475
34868
|
session.mcpServers ?? [],
|
|
34476
|
-
|
|
34869
|
+
githubRestMcp.tools,
|
|
34477
34870
|
localMcpServers
|
|
34478
34871
|
),
|
|
34479
34872
|
...deps.runMcpCredentials ? { runMcpCredentials: deps.runMcpCredentials } : {},
|
|
@@ -34917,7 +35310,8 @@ import {
|
|
|
34917
35310
|
getExternalLinkTurnAuthorization as getExternalLinkTurnAuthorization2,
|
|
34918
35311
|
getSessionTurnForAttempt as getSessionTurnForAttempt2,
|
|
34919
35312
|
ensureSessionReasoningConfiguration,
|
|
34920
|
-
ensureSessionSkillCatalog
|
|
35313
|
+
ensureSessionSkillCatalog,
|
|
35314
|
+
sessionHasToolRouterHistory
|
|
34921
35315
|
} from "@opengeni/db";
|
|
34922
35316
|
import {
|
|
34923
35317
|
formatSkillCatalog,
|
|
@@ -36073,7 +36467,7 @@ function validateReferenceImage(bytes) {
|
|
|
36073
36467
|
// src/activities/agent-turn/agent-build.ts
|
|
36074
36468
|
import { SandboxChannelAService as SandboxChannelAService4 } from "@opengeni/runtime/sandbox";
|
|
36075
36469
|
import { sandboxRunAs as sandboxRunAs5 } from "@opengeni/runtime";
|
|
36076
|
-
import { VideoGenerationRejectedResult } from "@opengeni/contracts";
|
|
36470
|
+
import { VideoGenerationRejectedResult, resolveAgentToolFamilies as resolveAgentToolFamilies2 } from "@opengeni/contracts";
|
|
36077
36471
|
|
|
36078
36472
|
// src/activities/agent-turn/video-reference-sandbox.ts
|
|
36079
36473
|
async function resolveVideoReferenceSandboxAccess(request, sandboxState, sdkOwnedSandboxSession) {
|
|
@@ -36117,6 +36511,7 @@ async function buildTurnAgent(deps) {
|
|
|
36117
36511
|
supportsImageInput,
|
|
36118
36512
|
agentHumanInputEnabled,
|
|
36119
36513
|
workspaceAgentInstructions,
|
|
36514
|
+
workspaceAgentIdentity,
|
|
36120
36515
|
workspaceGovernance,
|
|
36121
36516
|
structuredWorkspacePolicyActive,
|
|
36122
36517
|
workspaceMemory,
|
|
@@ -36197,7 +36592,7 @@ async function buildTurnAgent(deps) {
|
|
|
36197
36592
|
}
|
|
36198
36593
|
});
|
|
36199
36594
|
const imageGenerationOption = (() => {
|
|
36200
|
-
if (!objectStorage) return {};
|
|
36595
|
+
if (!objectStorage || !resolveAgentToolFamilies2(session.agent).media) return {};
|
|
36201
36596
|
if (nativeImageProviderBinding) {
|
|
36202
36597
|
media.nativeImageGenerationRetention = {
|
|
36203
36598
|
...nativeImageProviderBinding,
|
|
@@ -36313,7 +36708,7 @@ async function buildTurnAgent(deps) {
|
|
|
36313
36708
|
const videoGenerationPolicy = await getWorkspaceVideoGenerationPolicy2(db, input.workspaceId);
|
|
36314
36709
|
const videoGenerationEnabled = videoGenerationPolicy.defaultModelId !== null && videoGenerationPolicy.enabledModelIds.length > 0;
|
|
36315
36710
|
let videoGenerationCredential = null;
|
|
36316
|
-
if (objectStorage && videoGenerationEnabled) {
|
|
36711
|
+
if (objectStorage && videoGenerationEnabled && resolveAgentToolFamilies2(session.agent).media) {
|
|
36317
36712
|
if (videoGenerationPolicy.fundingSource === "opengeni_credits") {
|
|
36318
36713
|
videoGenerationCredential = managedVideoGenerationCredentialLease(eventing.modelRunSettings);
|
|
36319
36714
|
} else if (videoGenerationPolicy.fundingSource === "workspace_gateway") {
|
|
@@ -36505,6 +36900,11 @@ async function buildTurnAgent(deps) {
|
|
|
36505
36900
|
expectedAttemptId: input.attemptId,
|
|
36506
36901
|
effort: turn.reasoningEffort
|
|
36507
36902
|
}) : turn.reasoningEffort;
|
|
36903
|
+
const toolRouterInHistory = session.agent ? await sessionHasToolRouterHistory(db, {
|
|
36904
|
+
accountId: input.accountId,
|
|
36905
|
+
workspaceId: input.workspaceId,
|
|
36906
|
+
sessionId: input.sessionId
|
|
36907
|
+
}) : false;
|
|
36508
36908
|
const agent = (() => {
|
|
36509
36909
|
const agentConstructionStartedAt = performance.now();
|
|
36510
36910
|
let agentConstructionOutcome = "completed";
|
|
@@ -36523,6 +36923,7 @@ async function buildTurnAgent(deps) {
|
|
|
36523
36923
|
}
|
|
36524
36924
|
} : {},
|
|
36525
36925
|
...preparedTools.inputWaitYield ? { inputWaitYield: preparedTools.inputWaitYield } : {},
|
|
36926
|
+
...session.agent ? { agentConfig: session.agent, toolRouterInHistory } : {},
|
|
36526
36927
|
reasoningEffort: requestReasoningEffort,
|
|
36527
36928
|
latencyMode: turnExecutionPolicy.latencyMode,
|
|
36528
36929
|
...serviceTier ? { serviceTier } : {},
|
|
@@ -36611,6 +37012,14 @@ async function buildTurnAgent(deps) {
|
|
|
36611
37012
|
onRetainableSessionImageOutput: media.retainSessionImageAtToolBoundary,
|
|
36612
37013
|
skillCatalog: deps.skillCatalog,
|
|
36613
37014
|
skillCatalogInHistory: true,
|
|
37015
|
+
// A session with an agent configuration composes the modular prompt
|
|
37016
|
+
// (identity, base behavior, runtime mechanics, capability modules);
|
|
37017
|
+
// its workspace identity survives instruction policies. Null keeps
|
|
37018
|
+
// the legacy composition below byte-for-byte.
|
|
37019
|
+
...session.agent ? {
|
|
37020
|
+
agentConfig: session.agent,
|
|
37021
|
+
...workspaceAgentIdentity ? { workspaceAgentIdentity } : {}
|
|
37022
|
+
} : {},
|
|
36614
37023
|
...!structuredWorkspacePolicyActive && workspaceAgentInstructions ? { instructionsTemplate: workspaceAgentInstructions } : {},
|
|
36615
37024
|
...workspaceGovernance ? { workspaceGovernance } : {},
|
|
36616
37025
|
...workspaceMemory ? { workspaceMemory } : {},
|
|
@@ -36878,11 +37287,14 @@ function createRunAgentTurnActivity(services) {
|
|
|
36878
37287
|
getModelRunSettings: () => eventing.modelRunSettings,
|
|
36879
37288
|
getExecutionGeneration: () => attempt.executionGeneration
|
|
36880
37289
|
});
|
|
36881
|
-
const checkpointBeforeProviderDispatch = () =>
|
|
36882
|
-
|
|
36883
|
-
|
|
36884
|
-
|
|
36885
|
-
|
|
37290
|
+
const checkpointBeforeProviderDispatch = async () => {
|
|
37291
|
+
await awaitModelCallAdmission();
|
|
37292
|
+
await checkpointHistoryBeforeProviderDispatch(historySink, {
|
|
37293
|
+
effectiveSandboxBackend: eventing.modelRunSettings.sandboxBackend,
|
|
37294
|
+
routingEnabled: routingEnabled(settings),
|
|
37295
|
+
readActiveSandbox: () => readActiveSandbox3(db, input.workspaceId, input.sessionId)
|
|
37296
|
+
});
|
|
37297
|
+
};
|
|
36886
37298
|
try {
|
|
36887
37299
|
const claimed = await claimTurnAttempt({
|
|
36888
37300
|
input,
|
|
@@ -37025,7 +37437,7 @@ function createRunAgentTurnActivity(services) {
|
|
|
37025
37437
|
requiredGeneratedVideoFiles
|
|
37026
37438
|
});
|
|
37027
37439
|
if ("exit" in governance) return governance.exit;
|
|
37028
|
-
await
|
|
37440
|
+
await assertModelConnectionAllowsTurn2(db, {
|
|
37029
37441
|
workspaceId: input.workspaceId,
|
|
37030
37442
|
subjectId: turn.initiatingHumanSubjectId ?? "worker:model-access",
|
|
37031
37443
|
modelId: turnExecutionPolicy.productModelId,
|
|
@@ -37039,6 +37451,7 @@ function createRunAgentTurnActivity(services) {
|
|
|
37039
37451
|
agentHumanInputEnabled,
|
|
37040
37452
|
codeSearchEnabled,
|
|
37041
37453
|
workspaceAgentInstructions,
|
|
37454
|
+
workspaceAgentIdentity,
|
|
37042
37455
|
workspaceGovernance,
|
|
37043
37456
|
structuredWorkspacePolicyActive,
|
|
37044
37457
|
workspaceMemory,
|
|
@@ -37221,8 +37634,12 @@ function createRunAgentTurnActivity(services) {
|
|
|
37221
37634
|
credentialId: providerTurn.effectiveXaiCredentialId,
|
|
37222
37635
|
authoritySnapshot: turn.xaiProviderAccountAuthoritySnapshot,
|
|
37223
37636
|
hostedSearch: {
|
|
37224
|
-
webSearch:
|
|
37225
|
-
|
|
37637
|
+
webSearch: resolveAgentToolFamilies3(session.agent, {
|
|
37638
|
+
webSearch: runSettings.webSearchEnabled
|
|
37639
|
+
}).webSearch,
|
|
37640
|
+
xSearch: resolveAgentToolFamilies3(session.agent, {
|
|
37641
|
+
webSearch: runSettings.webSearchEnabled
|
|
37642
|
+
}).webSearch
|
|
37226
37643
|
},
|
|
37227
37644
|
streamIdleTimeoutMs: runSettings.supergrokResponseStreamIdleTimeoutMs,
|
|
37228
37645
|
nextRequestId: () => `${dispatchId}:xai:${++xaiModelRequestSequence}`,
|
|
@@ -37332,13 +37749,36 @@ function createRunAgentTurnActivity(services) {
|
|
|
37332
37749
|
const claudeUsageObserver = await createClaudeUsageObserver(
|
|
37333
37750
|
parseModelProvidersJson(runSettings.modelProvidersJson),
|
|
37334
37751
|
providerTurn.latestClaudeUsage,
|
|
37335
|
-
(scope) =>
|
|
37752
|
+
(scope) => loadClaudeSubscriptionUsageCredential2(db, settings, {
|
|
37336
37753
|
accountId: input.accountId,
|
|
37337
37754
|
workspaceId: input.workspaceId,
|
|
37338
37755
|
scope
|
|
37339
37756
|
})
|
|
37340
37757
|
);
|
|
37341
|
-
const withClaudeUsage = (fn) => withClaudeUsageObserver(claudeUsageObserver, fn)
|
|
37758
|
+
const withClaudeUsage = (fn) => withClaudeUsageObserver(claudeUsageObserver, fn, async (providerId, headers) => {
|
|
37759
|
+
const binding = claudeUsageObserver.binding(providerId);
|
|
37760
|
+
if (!binding) return headers;
|
|
37761
|
+
const credential = await resolveClaudeSubscriptionCredential(
|
|
37762
|
+
db,
|
|
37763
|
+
settings,
|
|
37764
|
+
{
|
|
37765
|
+
accountId: input.accountId,
|
|
37766
|
+
workspaceId: input.workspaceId,
|
|
37767
|
+
scope: binding.scope
|
|
37768
|
+
},
|
|
37769
|
+
{
|
|
37770
|
+
expectedConnectionId: binding.expectedConnectionId,
|
|
37771
|
+
expectedCredentialVersion: binding.expectedCredentialVersion
|
|
37772
|
+
}
|
|
37773
|
+
);
|
|
37774
|
+
if (!credential) return headers;
|
|
37775
|
+
if ("reconnectRequired" in credential)
|
|
37776
|
+
throw new ClaudeSubscriptionReconnectRequired();
|
|
37777
|
+
claudeUsageObserver.renew(providerId, credential);
|
|
37778
|
+
headers.set("authorization", `Bearer ${credential.token}`);
|
|
37779
|
+
headers.delete("x-api-key");
|
|
37780
|
+
return headers;
|
|
37781
|
+
});
|
|
37342
37782
|
const withCodex = (fn) => codexContext ? codexRequestStorage.run(codexContext, fn) : fn();
|
|
37343
37783
|
const withProviderRequestContext = (fn) => withClaudeUsage(
|
|
37344
37784
|
() => providerTurn.xaiRequestContext ? xaiSubscriptionRequestStorage.run(providerTurn.xaiRequestContext, fn) : withCodex(fn)
|
|
@@ -37396,6 +37836,7 @@ function createRunAgentTurnActivity(services) {
|
|
|
37396
37836
|
turnExecutionPolicy,
|
|
37397
37837
|
resolvedModel,
|
|
37398
37838
|
workspaceAgentInstructions,
|
|
37839
|
+
workspaceAgentIdentity,
|
|
37399
37840
|
workspaceGovernance,
|
|
37400
37841
|
structuredWorkspacePolicyActive,
|
|
37401
37842
|
workspaceMemory,
|
|
@@ -37542,6 +37983,7 @@ These are publication receipts for the human's earlier answer. Do not call the r
|
|
|
37542
37983
|
void 0
|
|
37543
37984
|
);
|
|
37544
37985
|
const runCredentials = await prepareRunCredentials({
|
|
37986
|
+
turnTools,
|
|
37545
37987
|
localMcpServerIds: installedApiIntegrations.map((integration) => integration.serverId),
|
|
37546
37988
|
input,
|
|
37547
37989
|
settings,
|
|
@@ -37557,6 +37999,7 @@ These are publication receipts for the human's earlier answer. Do not call the r
|
|
|
37557
37999
|
sandboxRuntime,
|
|
37558
38000
|
turn,
|
|
37559
38001
|
session,
|
|
38002
|
+
turnExecutionPolicy,
|
|
37560
38003
|
fileAuthoritySubjectId,
|
|
37561
38004
|
runSettings,
|
|
37562
38005
|
workspaceVariableSet,
|
|
@@ -37774,6 +38217,7 @@ These are publication receipts for the human's earlier answer. Do not call the r
|
|
|
37774
38217
|
supportsImageInput,
|
|
37775
38218
|
agentHumanInputEnabled,
|
|
37776
38219
|
workspaceAgentInstructions,
|
|
38220
|
+
workspaceAgentIdentity,
|
|
37777
38221
|
workspaceGovernance,
|
|
37778
38222
|
structuredWorkspacePolicyActive,
|
|
37779
38223
|
workspaceMemory,
|
|
@@ -37898,6 +38342,7 @@ These are publication receipts for the human's earlier answer. Do not call the r
|
|
|
37898
38342
|
turnExecutionPolicy,
|
|
37899
38343
|
resolvedModel,
|
|
37900
38344
|
workspaceAgentInstructions,
|
|
38345
|
+
workspaceAgentIdentity,
|
|
37901
38346
|
workspaceGovernance,
|
|
37902
38347
|
structuredWorkspacePolicyActive,
|
|
37903
38348
|
workspaceMemory,
|
|
@@ -39307,4 +39752,4 @@ export {
|
|
|
39307
39752
|
createTurnActivities,
|
|
39308
39753
|
createTurnActivitiesFromServices
|
|
39309
39754
|
};
|
|
39310
|
-
//# sourceMappingURL=activities-turn-
|
|
39755
|
+
//# sourceMappingURL=activities-turn-TESOIOEX.js.map
|