@opengeni/worker-bundle 2.2.0 → 2.2.1-canary.36919050519001
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/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 +2 -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/types.d.ts +1 -1
- package/dist/{activities-control-MHNA3CYV.js → activities-control-55ECL47G.js} +403 -116
- package/dist/activities-control-55ECL47G.js.map +1 -0
- package/dist/activities-control.d.ts +30 -0
- package/dist/{activities-turn-FQ5OO2WW.js → activities-turn-T7Y3BWYO.js} +678 -246
- package/dist/activities-turn-T7Y3BWYO.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-OWNLATJL.js} +189 -80
- package/dist/chunk-OWNLATJL.js.map +1 -0
- package/dist/index.d.ts +15 -0
- package/dist/index.js +45 -23
- package/dist/index.js.map +1 -1
- package/dist/sandbox-resume.d.ts +4 -1
- package/dist/workflow-bundle.js +72 -10
- package/dist/workflows/browser-deadline-checkpoint.d.ts +9 -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 +56 -14
- 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/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 +15 -3
- package/src/activities/agent-turn/run.ts +43 -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 +51 -39
- package/src/activities/agent-turn/turn-context.ts +1 -0
- package/src/activities/automations.ts +55 -3
- package/src/activities/browser-deadline-checkpoint.ts +279 -0
- package/src/activities/capabilities.ts +52 -14
- package/src/activities/goals.ts +67 -95
- 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/scheduled-tasks.ts +83 -13
- package/src/activities/types.ts +1 -0
- 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/sandbox-resume.ts +23 -8
- package/src/sandbox-routing.ts +4 -2
- package/src/workflows/browser-deadline-checkpoint.ts +50 -0
- 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-RZAAGRFQ.js.map +0 -1
|
@@ -94,7 +94,7 @@ import {
|
|
|
94
94
|
withFirstPartyTools,
|
|
95
95
|
wrapLazyTurnBoxWithRouting,
|
|
96
96
|
wrapTurnBoxWithRouting
|
|
97
|
-
} from "./chunk-
|
|
97
|
+
} from "./chunk-OWNLATJL.js";
|
|
98
98
|
import {
|
|
99
99
|
StreamTimingMetrics,
|
|
100
100
|
makeMachineOpObserver,
|
|
@@ -139,10 +139,13 @@ import {
|
|
|
139
139
|
getSessionAuthorityProjection,
|
|
140
140
|
readActiveSandbox as readActiveSandbox3,
|
|
141
141
|
getWorkspaceCredentialProvider,
|
|
142
|
-
loadClaudeSubscriptionUsageCredential
|
|
142
|
+
loadClaudeSubscriptionUsageCredential as loadClaudeSubscriptionUsageCredential2,
|
|
143
|
+
resolveClaudeSubscriptionCredential,
|
|
144
|
+
ClaudeSubscriptionReconnectRequired
|
|
143
145
|
} from "@opengeni/db";
|
|
146
|
+
import { resolveAgentToolFamilies as resolveAgentToolFamilies3 } from "@opengeni/contracts";
|
|
144
147
|
import {
|
|
145
|
-
assertModelConnectionAllowsTurn,
|
|
148
|
+
assertModelConnectionAllowsTurn as assertModelConnectionAllowsTurn2,
|
|
146
149
|
freezeAgentLearningPolicy as freezeAgentLearningPolicy2,
|
|
147
150
|
recoverLegacyKnowledgeConfirmations,
|
|
148
151
|
withSessionRlsActorContext
|
|
@@ -161,6 +164,7 @@ import {
|
|
|
161
164
|
import {
|
|
162
165
|
REMOTE_COMPACTION_V2_BETA_FEATURE,
|
|
163
166
|
REMOTE_COMPACTION_V2_IMPLEMENTATION as REMOTE_COMPACTION_V2_IMPLEMENTATION2,
|
|
167
|
+
awaitModelCallAdmission,
|
|
164
168
|
materializeSandboxFileDownloads as materializeSandboxFileDownloads3,
|
|
165
169
|
sandboxFileDownloadFailureNote
|
|
166
170
|
} from "@opengeni/runtime";
|
|
@@ -191,6 +195,17 @@ async function createClaudeUsageObserver(providers, latest, readCredential) {
|
|
|
191
195
|
(provider) => provider.kind === "claude-subscription-workspace" || provider.kind === "claude-subscription-organization"
|
|
192
196
|
).map(async (provider) => {
|
|
193
197
|
const scope = provider.kind === "claude-subscription-workspace" ? "workspace" : "organization";
|
|
198
|
+
const binding = provider.anthropic?.credentialBinding;
|
|
199
|
+
if (binding && provider.apiKey)
|
|
200
|
+
return [
|
|
201
|
+
provider.id,
|
|
202
|
+
{
|
|
203
|
+
scope,
|
|
204
|
+
token: provider.apiKey,
|
|
205
|
+
expectedConnectionId: binding.connectionId,
|
|
206
|
+
expectedCredentialVersion: binding.credentialVersion
|
|
207
|
+
}
|
|
208
|
+
];
|
|
194
209
|
const credential = await readCredential(scope).catch(() => null);
|
|
195
210
|
if (!credential || credential.token !== provider.apiKey) return null;
|
|
196
211
|
return [
|
|
@@ -205,7 +220,7 @@ async function createClaudeUsageObserver(providers, latest, readCredential) {
|
|
|
205
220
|
})
|
|
206
221
|
);
|
|
207
222
|
const captured = new Map(bindings.filter((binding) => binding !== null));
|
|
208
|
-
|
|
223
|
+
const observe2 = (providerId, response) => {
|
|
209
224
|
const binding = captured.get(providerId);
|
|
210
225
|
if (!binding) return;
|
|
211
226
|
const { scope, ...identity } = binding;
|
|
@@ -230,6 +245,16 @@ async function createClaudeUsageObserver(providers, latest, readCredential) {
|
|
|
230
245
|
...response.status === 401 ? { refresh: { status: "reconnect", checkedAt: (/* @__PURE__ */ new Date()).toISOString() } } : {}
|
|
231
246
|
});
|
|
232
247
|
};
|
|
248
|
+
return Object.assign(observe2, {
|
|
249
|
+
binding(providerId) {
|
|
250
|
+
return captured.get(providerId);
|
|
251
|
+
},
|
|
252
|
+
renew(providerId, credential) {
|
|
253
|
+
const binding = captured.get(providerId);
|
|
254
|
+
if (binding && binding.expectedConnectionId === credential.connectionId && binding.expectedCredentialVersion === credential.credentialVersion)
|
|
255
|
+
captured.set(providerId, { ...binding, token: credential.token });
|
|
256
|
+
}
|
|
257
|
+
});
|
|
233
258
|
}
|
|
234
259
|
|
|
235
260
|
// src/activities/agent-turn/run.ts
|
|
@@ -5245,7 +5270,10 @@ import {
|
|
|
5245
5270
|
isSessionEventPersistenceError as isSessionEventPersistenceError2
|
|
5246
5271
|
} from "@opengeni/db";
|
|
5247
5272
|
import { publishDurableSessionEvents as publishDurableSessionEvents2 } from "@opengeni/events";
|
|
5248
|
-
import {
|
|
5273
|
+
import {
|
|
5274
|
+
maxTurnsExceededRunState,
|
|
5275
|
+
isModalTaskExecStartPreDispatchUnavailableError
|
|
5276
|
+
} from "@opengeni/runtime";
|
|
5249
5277
|
import { ApplicationFailure, CancelledFailure } from "@temporalio/activity";
|
|
5250
5278
|
import { TurnExecutionPolicyDefinitionMismatchError } from "@opengeni/config";
|
|
5251
5279
|
import {
|
|
@@ -5256,7 +5284,7 @@ import {
|
|
|
5256
5284
|
} from "@opengeni/codex";
|
|
5257
5285
|
|
|
5258
5286
|
// src/activities/agent-turn/admission.ts
|
|
5259
|
-
import { getBillingBalance, sumUsageQuantity } from "@opengeni/db";
|
|
5287
|
+
import { checkWorkspaceAllowance, getBillingBalance, sumUsageQuantity } from "@opengeni/db";
|
|
5260
5288
|
import {
|
|
5261
5289
|
configuredStaticUsageLimits
|
|
5262
5290
|
} from "@opengeni/config";
|
|
@@ -5901,13 +5929,48 @@ function stableInteractionInterventionUuid(namespace, sessionId, turnId, toolCal
|
|
|
5901
5929
|
return `${value.slice(0, 8)}-${value.slice(8, 12)}-${value.slice(12, 16)}-${value.slice(16, 20)}-${value.slice(20)}`;
|
|
5902
5930
|
}
|
|
5903
5931
|
var BudgetExhaustedError = class extends Error {
|
|
5904
|
-
constructor(message, serializedRunState) {
|
|
5932
|
+
constructor(message, serializedRunState, allowance = null) {
|
|
5905
5933
|
super(message);
|
|
5906
5934
|
this.serializedRunState = serializedRunState;
|
|
5935
|
+
this.allowance = allowance;
|
|
5907
5936
|
this.name = "BudgetExhaustedError";
|
|
5908
5937
|
}
|
|
5909
5938
|
};
|
|
5910
|
-
|
|
5939
|
+
var AllowanceExhaustedError = class extends Error {
|
|
5940
|
+
constructor(refusal) {
|
|
5941
|
+
super(refusal.message);
|
|
5942
|
+
this.refusal = refusal;
|
|
5943
|
+
this.name = "AllowanceExhaustedError";
|
|
5944
|
+
}
|
|
5945
|
+
code = "allowance_exhausted";
|
|
5946
|
+
};
|
|
5947
|
+
async function ensureRunAllowedBetweenModelCalls(input) {
|
|
5948
|
+
try {
|
|
5949
|
+
await ensureRunAllowed(
|
|
5950
|
+
input.settings,
|
|
5951
|
+
input.db,
|
|
5952
|
+
input.accountId,
|
|
5953
|
+
input.workspaceId,
|
|
5954
|
+
input.isExternallyBilledTurn,
|
|
5955
|
+
input.entitlements,
|
|
5956
|
+
input.chargesOpenGeniCredits,
|
|
5957
|
+
input.countsTowardTokenCap,
|
|
5958
|
+
input.initiatingHumanSubjectId
|
|
5959
|
+
);
|
|
5960
|
+
} catch (limitError) {
|
|
5961
|
+
let serializedRunState = null;
|
|
5962
|
+
try {
|
|
5963
|
+
serializedRunState = input.serializedRunState?.() ?? null;
|
|
5964
|
+
} catch {
|
|
5965
|
+
}
|
|
5966
|
+
throw new BudgetExhaustedError(
|
|
5967
|
+
limitError instanceof Error ? limitError.message : String(limitError),
|
|
5968
|
+
serializedRunState,
|
|
5969
|
+
limitError instanceof AllowanceExhaustedError ? limitError.refusal : null
|
|
5970
|
+
);
|
|
5971
|
+
}
|
|
5972
|
+
}
|
|
5973
|
+
async function ensureRunAllowed(settings, db, accountId, workspaceId, isExternallyBilledTurn, entitlements, chargesOpenGeniCredits = !isExternallyBilledTurn, countsTowardTokenCap = !isExternallyBilledTurn, initiatingHumanSubjectId = null) {
|
|
5911
5974
|
if (chargesOpenGeniCredits && entitlements && (settings.billingMode === "stripe" || settings.usageLimitsMode === "managed")) {
|
|
5912
5975
|
const decision = await entitlements.admitRun({
|
|
5913
5976
|
accountId,
|
|
@@ -5924,6 +5987,14 @@ async function ensureRunAllowed(settings, db, accountId, workspaceId, isExternal
|
|
|
5924
5987
|
throw new Error("insufficient OpenGeni credits");
|
|
5925
5988
|
}
|
|
5926
5989
|
}
|
|
5990
|
+
if (chargesOpenGeniCredits) {
|
|
5991
|
+
const refusal = await checkWorkspaceAllowance(db, {
|
|
5992
|
+
accountId,
|
|
5993
|
+
workspaceId,
|
|
5994
|
+
subjectId: initiatingHumanSubjectId
|
|
5995
|
+
});
|
|
5996
|
+
if (refusal) throw new AllowanceExhaustedError(refusal);
|
|
5997
|
+
}
|
|
5927
5998
|
if (settings.usageLimitsMode === "static" || settings.usageLimitsMode === "managed") {
|
|
5928
5999
|
const limits = configuredStaticUsageLimits(settings);
|
|
5929
6000
|
if (limits.maxMonthlyAgentRunsPerWorkspace) {
|
|
@@ -6998,19 +7069,22 @@ async function settleTurnFailure(deps) {
|
|
|
6998
7069
|
await historySink.reconcileConversationTruth();
|
|
6999
7070
|
if (!await eventing.settle({
|
|
7000
7071
|
events: [
|
|
7072
|
+
...error51.allowance ? [{ type: "usage.exhausted", payload: error51.allowance }] : [],
|
|
7001
7073
|
{
|
|
7002
7074
|
type: "turn.completed",
|
|
7003
7075
|
payload: {
|
|
7004
7076
|
output: "",
|
|
7005
7077
|
segmentLimit: "budget_exhausted",
|
|
7006
|
-
detail: error51.message
|
|
7078
|
+
detail: error51.message,
|
|
7079
|
+
...error51.allowance ?? {}
|
|
7007
7080
|
}
|
|
7008
7081
|
},
|
|
7009
7082
|
{ type: "session.status.changed", payload: { status: "idle" } }
|
|
7010
7083
|
],
|
|
7011
7084
|
turnStatus: "completed",
|
|
7012
7085
|
sessionStatus: "idle",
|
|
7013
|
-
activeTurnId: null
|
|
7086
|
+
activeTurnId: null,
|
|
7087
|
+
...error51.allowance ? { allowanceGoalPause: { rationale: error51.allowance.message } } : {}
|
|
7014
7088
|
})) {
|
|
7015
7089
|
return claimedResult({ status: "cancelled" });
|
|
7016
7090
|
}
|
|
@@ -7078,10 +7152,12 @@ async function settleTurnFailure(deps) {
|
|
|
7078
7152
|
}
|
|
7079
7153
|
}
|
|
7080
7154
|
const earlyDefinitionMismatch = error51 instanceof TurnExecutionPolicyDefinitionMismatchError && !attempt.modelRequestStarted && !eventing.turnStartedPublished && !!attempt.turnId && !!attempt.triggerEventId && attempt.executionGeneration > 0;
|
|
7155
|
+
const earlyCommandStartUnavailable = isModalTaskExecStartPreDispatchUnavailableError(error51) && !attempt.modelRequestStarted && !eventing.turnStartedPublished && !!attempt.turnId && !!attempt.triggerEventId && attempt.executionGeneration > 0;
|
|
7156
|
+
const earlyRecoverableSetup = earlyDefinitionMismatch || earlyCommandStartUnavailable;
|
|
7081
7157
|
let failure2 = earlyDefinitionMismatch ? { error: error51.message, code: error51.code, retryable: true } : codexTerminalFailure ?? agentRunFailurePayload(error51, {
|
|
7082
7158
|
isCodexTurn: billingState.isCodexTurn
|
|
7083
7159
|
});
|
|
7084
|
-
if (attempt.turnId && (
|
|
7160
|
+
if (attempt.turnId && (earlyRecoverableSetup || failure2.retryable && eventing.publish && eventing.turnStartedPublished)) {
|
|
7085
7161
|
const nextProviderRecoveryCount = attempt.providerRecoveryCount + 1;
|
|
7086
7162
|
const recoveryResult = providerRecoveryResult({
|
|
7087
7163
|
failureCode: failure2.code,
|
|
@@ -7090,7 +7166,7 @@ async function settleTurnFailure(deps) {
|
|
|
7090
7166
|
});
|
|
7091
7167
|
try {
|
|
7092
7168
|
if (recoveryResult.status === "recovering") {
|
|
7093
|
-
if (!
|
|
7169
|
+
if (!earlyRecoverableSetup) {
|
|
7094
7170
|
await flushRuntimeBatcher();
|
|
7095
7171
|
await historySink.reconcileConversationTruth({ requireDurable: true });
|
|
7096
7172
|
}
|
|
@@ -7121,13 +7197,13 @@ async function settleTurnFailure(deps) {
|
|
|
7121
7197
|
return claimedResult(recoveryResult);
|
|
7122
7198
|
}
|
|
7123
7199
|
failure2 = providerRecoveryExhaustedFailure(failure2, recoveryResult);
|
|
7124
|
-
if (
|
|
7200
|
+
if (earlyRecoverableSetup) {
|
|
7125
7201
|
control.activityStatus = "failed";
|
|
7126
7202
|
control.turnMetricOutcome = "failed";
|
|
7127
7203
|
control.activityError = error51;
|
|
7128
7204
|
throw ApplicationFailure.create({
|
|
7129
|
-
message: `${error51.message}. Automatic same-turn configuration recovery exhausted after ${recoveryResult.providerRecoveryCount} retries
|
|
7130
|
-
type: "TurnExecutionPolicyDefinitionMismatchError",
|
|
7205
|
+
message: earlyDefinitionMismatch ? `${error51.message}. Automatic same-turn configuration recovery exhausted after ${recoveryResult.providerRecoveryCount} retries.` : failure2.error,
|
|
7206
|
+
type: earlyDefinitionMismatch ? "TurnExecutionPolicyDefinitionMismatchError" : "SandboxCommandStartUnavailableError",
|
|
7131
7207
|
nonRetryable: true
|
|
7132
7208
|
});
|
|
7133
7209
|
}
|
|
@@ -7216,6 +7292,9 @@ async function settleTurnFailure(deps) {
|
|
|
7216
7292
|
// src/activities/agent-turn/stream-attempt.ts
|
|
7217
7293
|
import { measureMcpPhase, withMcpCallIdentity } from "@opengeni/observability";
|
|
7218
7294
|
import {
|
|
7295
|
+
appendSessionHistoryItems as appendSessionHistoryItems3,
|
|
7296
|
+
sessionTurnFinalReplyFacts,
|
|
7297
|
+
sessionTurnHasFinalReplyNudge,
|
|
7219
7298
|
getSessionHumanInputRequest,
|
|
7220
7299
|
getWorkspace,
|
|
7221
7300
|
recordUsageEvent as recordUsageEvent3,
|
|
@@ -7665,7 +7744,8 @@ async function resolveTurnSandboxAccess(sandboxState, sdkOwnedSandboxSession, un
|
|
|
7665
7744
|
// src/activities/open-suffix-resume.ts
|
|
7666
7745
|
import {
|
|
7667
7746
|
OPEN_SUFFIX_RUN_STATE_BLOB,
|
|
7668
|
-
approvalIdentifier
|
|
7747
|
+
approvalIdentifier,
|
|
7748
|
+
withPublicApprovalFields
|
|
7669
7749
|
} from "@opengeni/contracts";
|
|
7670
7750
|
import {
|
|
7671
7751
|
appendSessionHistoryItems as appendSessionHistoryItems2,
|
|
@@ -7931,7 +8011,7 @@ async function settleOpenSuffixResumeIfNeeded(input) {
|
|
|
7931
8011
|
...requiresActionApprovals.length > 0 ? [
|
|
7932
8012
|
{
|
|
7933
8013
|
type: "session.requiresAction",
|
|
7934
|
-
payload: { approvals: requiresActionApprovals }
|
|
8014
|
+
payload: { approvals: requiresActionApprovals.map(withPublicApprovalFields) }
|
|
7935
8015
|
}
|
|
7936
8016
|
] : [],
|
|
7937
8017
|
{
|
|
@@ -7969,9 +8049,85 @@ function interruptionCallIdsFromPause(input) {
|
|
|
7969
8049
|
// src/activities/agent-turn/stream-attempt.ts
|
|
7970
8050
|
import {
|
|
7971
8051
|
OPEN_SUFFIX_RUN_STATE_BLOB as OPEN_SUFFIX_RUN_STATE_BLOB2,
|
|
7972
|
-
resolveWorkspaceAgentHumanInputEnabled
|
|
8052
|
+
resolveWorkspaceAgentHumanInputEnabled,
|
|
8053
|
+
withPublicApprovalFields as withPublicApprovalFields2
|
|
7973
8054
|
} from "@opengeni/contracts";
|
|
7974
8055
|
|
|
8056
|
+
// src/activities/agent-turn/model-call-admission.ts
|
|
8057
|
+
function createModelCallAdmission(input) {
|
|
8058
|
+
const receipts = /* @__PURE__ */ new WeakMap();
|
|
8059
|
+
const responseReceipts = /* @__PURE__ */ new Map();
|
|
8060
|
+
const pending = /* @__PURE__ */ new Set();
|
|
8061
|
+
const responseId = (event) => {
|
|
8062
|
+
const id = event?.response?.id;
|
|
8063
|
+
return typeof id === "string" && id.length > 0 ? id : null;
|
|
8064
|
+
};
|
|
8065
|
+
let latest = Promise.resolve();
|
|
8066
|
+
let failure2;
|
|
8067
|
+
let failed = false;
|
|
8068
|
+
let rejectHalted;
|
|
8069
|
+
const halted = new Promise((_, reject) => {
|
|
8070
|
+
rejectHalted = reject;
|
|
8071
|
+
});
|
|
8072
|
+
void halted.catch(() => void 0);
|
|
8073
|
+
const fail = (error51) => {
|
|
8074
|
+
if (failed) return;
|
|
8075
|
+
failed = true;
|
|
8076
|
+
failure2 = error51;
|
|
8077
|
+
rejectHalted(error51);
|
|
8078
|
+
for (const receipt of pending) receipt.reject(error51);
|
|
8079
|
+
pending.clear();
|
|
8080
|
+
responseReceipts.clear();
|
|
8081
|
+
};
|
|
8082
|
+
const abort = () => fail(input.signal.reason ?? new Error("Model stream cancelled"));
|
|
8083
|
+
input.signal.addEventListener("abort", abort, { once: true });
|
|
8084
|
+
if (input.signal.aborted) abort();
|
|
8085
|
+
return {
|
|
8086
|
+
beforeModelRequest: async () => {
|
|
8087
|
+
await Promise.race([latest, halted]);
|
|
8088
|
+
if (failed) throw failure2;
|
|
8089
|
+
await Promise.race([input.admit(), halted]);
|
|
8090
|
+
if (failed) throw failure2;
|
|
8091
|
+
},
|
|
8092
|
+
onModelResponse: (event) => {
|
|
8093
|
+
if (failed) return Promise.reject(failure2);
|
|
8094
|
+
const id = responseId(event);
|
|
8095
|
+
const existing = receipts.get(event) ?? (id ? responseReceipts.get(id) : void 0) ?? (!id && pending.size === 1 ? pending.values().next().value : void 0);
|
|
8096
|
+
if (existing) return existing.promise;
|
|
8097
|
+
let resolve;
|
|
8098
|
+
let reject;
|
|
8099
|
+
const promise2 = new Promise((yes, no) => {
|
|
8100
|
+
resolve = yes;
|
|
8101
|
+
reject = no;
|
|
8102
|
+
});
|
|
8103
|
+
void promise2.catch(() => void 0);
|
|
8104
|
+
const receipt = { promise: promise2, resolve, reject };
|
|
8105
|
+
receipts.set(event, receipt);
|
|
8106
|
+
if (id) responseReceipts.set(id, receipt);
|
|
8107
|
+
pending.add(receipt);
|
|
8108
|
+
latest = promise2;
|
|
8109
|
+
return promise2;
|
|
8110
|
+
},
|
|
8111
|
+
settle: (event) => {
|
|
8112
|
+
if (event.type !== "raw_model_stream_event" || !event.data || typeof event.data !== "object")
|
|
8113
|
+
return;
|
|
8114
|
+
if (event.data.type !== "response_done") return;
|
|
8115
|
+
const id = responseId(event.data);
|
|
8116
|
+
const receipt = receipts.get(event.data) ?? (id ? responseReceipts.get(id) : void 0) ?? (pending.size === 1 ? pending.values().next().value : void 0);
|
|
8117
|
+
if (!receipt) return;
|
|
8118
|
+
pending.delete(receipt);
|
|
8119
|
+
if (id) responseReceipts.delete(id);
|
|
8120
|
+
receipt.resolve();
|
|
8121
|
+
},
|
|
8122
|
+
fail,
|
|
8123
|
+
close: () => {
|
|
8124
|
+
input.signal.removeEventListener("abort", abort);
|
|
8125
|
+
if (pending.size > 0) fail(new Error("Model stream closed before response settlement"));
|
|
8126
|
+
responseReceipts.clear();
|
|
8127
|
+
}
|
|
8128
|
+
};
|
|
8129
|
+
}
|
|
8130
|
+
|
|
7975
8131
|
// src/activities/agent-turn/session-title.ts
|
|
7976
8132
|
import { hasPermission } from "@opengeni/core";
|
|
7977
8133
|
import { isManagedOpenRouterFreeRoute } from "@opengeni/config";
|
|
@@ -7986,7 +8142,7 @@ function shouldRequestMissingSessionTitle(input) {
|
|
|
7986
8142
|
const title = input.title?.trim() ?? "";
|
|
7987
8143
|
const needsSemanticTitle = input.titleSource !== "user" && (!title || title === AUTOMATIC_SESSION_TITLE_FALLBACK);
|
|
7988
8144
|
if (!needsSemanticTitle) return false;
|
|
7989
|
-
if (!input.firstPartyMcpTools.includes("set_session_title")) return false;
|
|
8145
|
+
if (!input.agentConfig && !input.firstPartyMcpTools.includes("set_session_title")) return false;
|
|
7990
8146
|
const permissions = input.firstPartyMcpPermissions ?? DEFAULT_FIRST_PARTY_MCP_PERMISSIONS;
|
|
7991
8147
|
return hasPermission([...permissions], "sessions:control");
|
|
7992
8148
|
}
|
|
@@ -7994,7 +8150,7 @@ function routeAllowsSessionTitleRequests(resolvedModel) {
|
|
|
7994
8150
|
return !resolvedModel || !isManagedOpenRouterFreeRoute(resolvedModel);
|
|
7995
8151
|
}
|
|
7996
8152
|
function sessionTitleToolPlan(input) {
|
|
7997
|
-
const titleToolAvailable = input.shouldRequestTitle && input.tools.some((tool) => tool.kind === "mcp" && tool.id === "opengeni");
|
|
8153
|
+
const titleToolAvailable = input.shouldRequestTitle && (input.agentConfig != null || input.tools.some((tool) => tool.kind === "mcp" && tool.id === "opengeni"));
|
|
7998
8154
|
const titleRequestAllowed = titleToolAvailable && input.routeAllowsTitleRequests;
|
|
7999
8155
|
const generateTitleInParallel = titleRequestAllowed && input.parallelGenerationAvailable;
|
|
8000
8156
|
const promoteTitleTool = titleRequestAllowed && !generateTitleInParallel;
|
|
@@ -8301,6 +8457,24 @@ function createSharedRigSetupCoordinator(options) {
|
|
|
8301
8457
|
};
|
|
8302
8458
|
}
|
|
8303
8459
|
|
|
8460
|
+
// src/activities/agent-turn/final-reply.ts
|
|
8461
|
+
function finalReplyNudge(turnId) {
|
|
8462
|
+
return {
|
|
8463
|
+
type: "message",
|
|
8464
|
+
role: "developer",
|
|
8465
|
+
content: [
|
|
8466
|
+
{
|
|
8467
|
+
type: "input_text",
|
|
8468
|
+
text: `[Runtime final-reply handoff for turn ${turnId}]
|
|
8469
|
+
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.`
|
|
8470
|
+
}
|
|
8471
|
+
]
|
|
8472
|
+
};
|
|
8473
|
+
}
|
|
8474
|
+
function needsFinalReply(input) {
|
|
8475
|
+
return typeof input.output === "string" && input.output.trim().length === 0 && !input.inputWaitYielded && !input.interrupted && !input.maintenance && (input.toolsExecuted || input.completedGoal);
|
|
8476
|
+
}
|
|
8477
|
+
|
|
8304
8478
|
// src/activities/agent-turn/stream-attempt.ts
|
|
8305
8479
|
async function attachPendingUpdatesBeforePreparingModelInput(input) {
|
|
8306
8480
|
if (input.shouldAttach && !await input.attachPendingUpdates()) return false;
|
|
@@ -8567,12 +8741,33 @@ async function runTurnStreamAttempt(deps) {
|
|
|
8567
8741
|
const modelResponseState = createModelResponseEventState(claimedModelUsageSourceKeys);
|
|
8568
8742
|
let latestAssistantMessageText = null;
|
|
8569
8743
|
let workerPreparationTotalRecorded = false;
|
|
8744
|
+
let toolsExecuted = false;
|
|
8745
|
+
let finalReplyNudged = false;
|
|
8746
|
+
const revalidateModelCallAdmission = async () => {
|
|
8747
|
+
await historySink.reconcileConversationTruth({ requireDurable: true });
|
|
8748
|
+
await ensureRunAllowedBetweenModelCalls({
|
|
8749
|
+
settings,
|
|
8750
|
+
db,
|
|
8751
|
+
accountId: input.accountId,
|
|
8752
|
+
workspaceId: input.workspaceId,
|
|
8753
|
+
isExternallyBilledTurn: billingState.isExternallyBilledTurn,
|
|
8754
|
+
entitlements,
|
|
8755
|
+
chargesOpenGeniCredits: billingState.chargesOpenGeniCredits,
|
|
8756
|
+
countsTowardTokenCap: billingState.countsTowardTokenCap,
|
|
8757
|
+
initiatingHumanSubjectId: turn.initiatingHumanSubjectId
|
|
8758
|
+
});
|
|
8759
|
+
};
|
|
8570
8760
|
const runStreamAttempt = async (options) => {
|
|
8571
8761
|
if (!runInput) {
|
|
8572
8762
|
throw new Error("Run input was not prepared");
|
|
8573
8763
|
}
|
|
8574
|
-
const responseCountBeforeStream = modelResponseState.responseCount;
|
|
8575
8764
|
eventing.stream = void 0;
|
|
8765
|
+
if (options.requireTerminalModelResponse) await revalidateModelCallAdmission();
|
|
8766
|
+
const modelCallAdmission = createModelCallAdmission({
|
|
8767
|
+
signal: runtimeCancellationSignal,
|
|
8768
|
+
admit: revalidateModelCallAdmission
|
|
8769
|
+
});
|
|
8770
|
+
const responseCountBeforeStream = modelResponseState.responseCount;
|
|
8576
8771
|
eventing.batcher = null;
|
|
8577
8772
|
let currentToolBatchCallIds = /* @__PURE__ */ new Set();
|
|
8578
8773
|
let currentToolBatchCompletedCallIds = /* @__PURE__ */ new Set();
|
|
@@ -8740,6 +8935,8 @@ async function runTurnStreamAttempt(deps) {
|
|
|
8740
8935
|
}
|
|
8741
8936
|
attempt.modelRequestStarted = true;
|
|
8742
8937
|
return await runtime.runStream(agent, runInput, eventing.modelRunSettings, {
|
|
8938
|
+
beforeModelRequest: modelCallAdmission.beforeModelRequest,
|
|
8939
|
+
onModelResponse: modelCallAdmission.onModelResponse,
|
|
8743
8940
|
signal: runtimeCancellationSignal,
|
|
8744
8941
|
sandboxEnvironment,
|
|
8745
8942
|
onModelVisibleContext: async (snapshot) => {
|
|
@@ -8846,7 +9043,13 @@ async function runTurnStreamAttempt(deps) {
|
|
|
8846
9043
|
if (leases.xai.lost) {
|
|
8847
9044
|
throw new Error("xAI credential lease expired before the model run");
|
|
8848
9045
|
}
|
|
8849
|
-
|
|
9046
|
+
try {
|
|
9047
|
+
eventing.stream = await withProviderRequestContext(runStreamOnce);
|
|
9048
|
+
} catch (error51) {
|
|
9049
|
+
modelCallAdmission.fail(error51);
|
|
9050
|
+
modelCallAdmission.close();
|
|
9051
|
+
throw error51;
|
|
9052
|
+
}
|
|
8850
9053
|
const streamTiming = new StreamTimingMetrics(observability, {
|
|
8851
9054
|
provider: streamProvider
|
|
8852
9055
|
});
|
|
@@ -8985,32 +9188,20 @@ async function runTurnStreamAttempt(deps) {
|
|
|
8985
9188
|
await historySink.reconcileConversationTruth();
|
|
8986
9189
|
turnLifecycleMetricsFor(observability).progress({ attemptId: input.attemptId });
|
|
8987
9190
|
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
|
-
}
|
|
9191
|
+
await ensureRunAllowedBetweenModelCalls({
|
|
9192
|
+
settings,
|
|
9193
|
+
db,
|
|
9194
|
+
accountId: input.accountId,
|
|
9195
|
+
workspaceId: input.workspaceId,
|
|
9196
|
+
isExternallyBilledTurn: billingState.isExternallyBilledTurn,
|
|
9197
|
+
entitlements,
|
|
9198
|
+
chargesOpenGeniCredits: billingState.chargesOpenGeniCredits,
|
|
9199
|
+
countsTowardTokenCap: billingState.countsTowardTokenCap,
|
|
9200
|
+
initiatingHumanSubjectId: turn.initiatingHumanSubjectId,
|
|
9201
|
+
serializedRunState: () => media.compactMediaRunState(String(eventing.stream.state.toString()))
|
|
9202
|
+
});
|
|
9013
9203
|
}
|
|
9204
|
+
modelCallAdmission.settle(next.value);
|
|
9014
9205
|
const durableSdkEvent = generatedImageReceipt ? compactGeneratedImageSdkEvent(next.value, generatedImageReceipt) : next.value;
|
|
9015
9206
|
const pendingToolCall = pendingToolCallFromSdkEvent(durableSdkEvent);
|
|
9016
9207
|
if (pendingToolCall) {
|
|
@@ -9044,6 +9235,7 @@ async function runTurnStreamAttempt(deps) {
|
|
|
9044
9235
|
}
|
|
9045
9236
|
const completedToolCall = completedToolCallFromSdkEvent(durableSdkEvent);
|
|
9046
9237
|
if (completedToolCall) {
|
|
9238
|
+
toolsExecuted = true;
|
|
9047
9239
|
retainedScreenshotMetadata = media.retainedScreenshotReceiptsByCallId.get(completedToolCall.callId) ?? null;
|
|
9048
9240
|
const typedScreenshot = retainedScreenshotMetadata ? null : typedScreenshotFromSdkEvent(durableSdkEvent);
|
|
9049
9241
|
if (!retainedScreenshotMetadata && media.retainedSessionImageCallIds.has(completedToolCall.callId) && sdkEventContainsInlineImage(durableSdkEvent) && !typedScreenshot) {
|
|
@@ -9225,6 +9417,7 @@ async function runTurnStreamAttempt(deps) {
|
|
|
9225
9417
|
}
|
|
9226
9418
|
}
|
|
9227
9419
|
} catch (error51) {
|
|
9420
|
+
modelCallAdmission.fail(error51);
|
|
9228
9421
|
closeStreamWaitAdmission?.();
|
|
9229
9422
|
if (fallbackProviderRequestLifecycleStartedAt !== null) {
|
|
9230
9423
|
const durationMs = Math.max(
|
|
@@ -9274,6 +9467,7 @@ async function runTurnStreamAttempt(deps) {
|
|
|
9274
9467
|
}
|
|
9275
9468
|
throw error51;
|
|
9276
9469
|
} finally {
|
|
9470
|
+
modelCallAdmission.close();
|
|
9277
9471
|
if (!streamDone) {
|
|
9278
9472
|
void iterator.return?.().catch(() => void 0);
|
|
9279
9473
|
}
|
|
@@ -9284,7 +9478,7 @@ async function runTurnStreamAttempt(deps) {
|
|
|
9284
9478
|
temporalCancellationSignal: cancellationSignal,
|
|
9285
9479
|
runtimeCancellationSignal
|
|
9286
9480
|
});
|
|
9287
|
-
await eventing.preparedTools?.inputWaitYield?.
|
|
9481
|
+
await eventing.preparedTools?.inputWaitYield?.drainForHandoff(runtimeCancellationSignal);
|
|
9288
9482
|
if (options.requireTerminalModelResponse && !eventing.preparedTools?.inputWaitYield?.yielded && eventing.stream.interruptions.length === 0 && modelResponseState.responseCount === responseCountBeforeStream) {
|
|
9289
9483
|
throwIfWorkerShuttingDown();
|
|
9290
9484
|
throwIfTurnCancelled();
|
|
@@ -9380,6 +9574,7 @@ async function runTurnStreamAttempt(deps) {
|
|
|
9380
9574
|
}
|
|
9381
9575
|
}
|
|
9382
9576
|
if (eventing.stream.interruptions.length > 0) {
|
|
9577
|
+
await eventing.preparedTools?.inputWaitYield?.sealForSettlement(runtimeCancellationSignal);
|
|
9383
9578
|
await historySink.reconcileConversationTruth({ requireDurable: true });
|
|
9384
9579
|
const approvals = runtime.serializeApprovals(eventing.stream.interruptions);
|
|
9385
9580
|
const humanInputInterruptions = runtime.serializeHumanInputRequests?.(eventing.stream.interruptions) ?? [];
|
|
@@ -9487,9 +9682,11 @@ async function runTurnStreamAttempt(deps) {
|
|
|
9487
9682
|
type: "session.requiresAction",
|
|
9488
9683
|
payload: {
|
|
9489
9684
|
approvals: approvals.map(
|
|
9490
|
-
(approval) =>
|
|
9491
|
-
|
|
9492
|
-
|
|
9685
|
+
(approval) => withPublicApprovalFields2(
|
|
9686
|
+
withMcpToolDisplayMetadata(
|
|
9687
|
+
eventing.preparedTools?.mcpServers ?? [],
|
|
9688
|
+
approval
|
|
9689
|
+
)
|
|
9493
9690
|
)
|
|
9494
9691
|
)
|
|
9495
9692
|
}
|
|
@@ -9520,6 +9717,48 @@ async function runTurnStreamAttempt(deps) {
|
|
|
9520
9717
|
const finalOutput = String(
|
|
9521
9718
|
requireAgentStreamFinalOutput(eventing.stream.finalOutput, inputWaitYielded)
|
|
9522
9719
|
);
|
|
9720
|
+
const durableReplyFacts = !inputWaitYielded && finalOutput.trim().length === 0 ? await sessionTurnFinalReplyFacts(db, input.workspaceId, input.sessionId, activeTurnId) : { toolsExecuted: false, completedGoal: false };
|
|
9721
|
+
let emptyFinalReply = false;
|
|
9722
|
+
if (needsFinalReply({
|
|
9723
|
+
output: finalOutput,
|
|
9724
|
+
inputWaitYielded: inputWaitYielded || eventing.preparedTools?.inputWaitYield?.requested === true,
|
|
9725
|
+
interrupted: false,
|
|
9726
|
+
// interruption settlement returned above
|
|
9727
|
+
maintenance: turn.source === "compaction",
|
|
9728
|
+
toolsExecuted: toolsExecuted || finalReplyNudged || durableReplyFacts.toolsExecuted,
|
|
9729
|
+
completedGoal: durableReplyFacts.completedGoal
|
|
9730
|
+
})) {
|
|
9731
|
+
await historySink.reconcileConversationTruth({ requireDurable: true });
|
|
9732
|
+
if (finalReplyNudged || await sessionTurnHasFinalReplyNudge(
|
|
9733
|
+
db,
|
|
9734
|
+
input.workspaceId,
|
|
9735
|
+
input.sessionId,
|
|
9736
|
+
activeTurnId,
|
|
9737
|
+
finalReplyNudge(activeTurnId).content[0].text
|
|
9738
|
+
)) {
|
|
9739
|
+
emptyFinalReply = true;
|
|
9740
|
+
} else {
|
|
9741
|
+
const appended = await appendSessionHistoryItems3(db, {
|
|
9742
|
+
accountId: input.accountId,
|
|
9743
|
+
workspaceId: input.workspaceId,
|
|
9744
|
+
sessionId: input.sessionId,
|
|
9745
|
+
turnId: activeTurnId,
|
|
9746
|
+
expectedExecutionGeneration: attempt.executionGeneration,
|
|
9747
|
+
expectedAttemptId: input.attemptId,
|
|
9748
|
+
items: [
|
|
9749
|
+
{
|
|
9750
|
+
position: await nextSessionHistoryPosition2(db, input.workspaceId, input.sessionId),
|
|
9751
|
+
item: finalReplyNudge(activeTurnId)
|
|
9752
|
+
}
|
|
9753
|
+
]
|
|
9754
|
+
});
|
|
9755
|
+
if (!appended) throw new TurnAttemptFencedError("turn ended before final reply handoff");
|
|
9756
|
+
finalReplyNudged = true;
|
|
9757
|
+
await prepareRunAttemptInput();
|
|
9758
|
+
return "reply_nudge";
|
|
9759
|
+
}
|
|
9760
|
+
}
|
|
9761
|
+
await eventing.preparedTools?.inputWaitYield?.sealForSettlement(runtimeCancellationSignal);
|
|
9523
9762
|
const finalOutputAlreadyCompleted = latestStreamedAssistantText === finalOutput;
|
|
9524
9763
|
const reply = await inputWaitReply({
|
|
9525
9764
|
inputWaitYielded,
|
|
@@ -9539,7 +9778,11 @@ async function runTurnStreamAttempt(deps) {
|
|
|
9539
9778
|
...inputWaitYielded || finalOutputAlreadyCompleted ? [] : [{ type: "agent.message.completed", payload: { text: finalOutput } }],
|
|
9540
9779
|
{
|
|
9541
9780
|
type: "turn.completed",
|
|
9542
|
-
payload: {
|
|
9781
|
+
payload: {
|
|
9782
|
+
output: finalOutput,
|
|
9783
|
+
...reply === null ? {} : { reply },
|
|
9784
|
+
...emptyFinalReply ? { emptyFinalReply: true } : {}
|
|
9785
|
+
}
|
|
9543
9786
|
},
|
|
9544
9787
|
{ type: "session.status.changed", payload: { status: "idle" } }
|
|
9545
9788
|
],
|
|
@@ -9595,6 +9838,7 @@ async function runTurnStreamAttempt(deps) {
|
|
|
9595
9838
|
})) {
|
|
9596
9839
|
return claimedResult({ status: "cancelled" });
|
|
9597
9840
|
}
|
|
9841
|
+
await revalidateModelCallAdmission();
|
|
9598
9842
|
if (turn.source !== "compaction" && generateSessionTitleInParallel && runtime.generateSessionTitle && !runtimeCancellationSignal.aborted) {
|
|
9599
9843
|
const serviceTier = serviceTierForLatencyMode(
|
|
9600
9844
|
turnExecutionPolicy.providerId,
|
|
@@ -9626,11 +9870,19 @@ async function runTurnStreamAttempt(deps) {
|
|
|
9626
9870
|
}
|
|
9627
9871
|
try {
|
|
9628
9872
|
let retriedAfterCompaction = false;
|
|
9873
|
+
finalReplyNudged = await sessionTurnHasFinalReplyNudge(
|
|
9874
|
+
db,
|
|
9875
|
+
input.workspaceId,
|
|
9876
|
+
input.sessionId,
|
|
9877
|
+
activeTurnId,
|
|
9878
|
+
finalReplyNudge(activeTurnId).content[0].text
|
|
9879
|
+
);
|
|
9629
9880
|
while (true) {
|
|
9630
9881
|
try {
|
|
9631
9882
|
const result = await runStreamAttempt({
|
|
9632
9883
|
requireTerminalModelResponse: retriedAfterCompaction
|
|
9633
9884
|
});
|
|
9885
|
+
if (result === "reply_nudge") continue;
|
|
9634
9886
|
if (retriedAfterCompaction) {
|
|
9635
9887
|
observability.info("context compaction recovery succeeded after in-activity retry", {
|
|
9636
9888
|
sessionId: input.sessionId,
|
|
@@ -9841,7 +10093,9 @@ import {
|
|
|
9841
10093
|
loadOrganizationModelProviderApiKey,
|
|
9842
10094
|
listWorkspaceProviderCustomModels,
|
|
9843
10095
|
getWorkspaceProviderCustomModelForExecution,
|
|
9844
|
-
loadWorkspaceProviderApiKey
|
|
10096
|
+
loadWorkspaceProviderApiKey,
|
|
10097
|
+
loadClaudeSubscriptionUsageCredential,
|
|
10098
|
+
assertModelConnectionAllowsTurn
|
|
9845
10099
|
} from "@opengeni/db";
|
|
9846
10100
|
async function settingsWithSessionMcpServersForRun(db, workspaceId, sessionId, attemptId, settings, options) {
|
|
9847
10101
|
const encryptionKey = environmentsEncryptionKeyBytes(settings);
|
|
@@ -9999,12 +10253,24 @@ async function settingsWithOrganizationProviderCredentials(db, accountId, worksp
|
|
|
9999
10253
|
if (kind === "claude_subscription" && !settings.claudeSubscriptionEnabled) continue;
|
|
10000
10254
|
const models = await buildModels(kind, claudeProviderId(kind) + "/");
|
|
10001
10255
|
result = withClaudeConnectionCatalog(result, { [kind]: { models } });
|
|
10002
|
-
const
|
|
10256
|
+
const binding = kind === "claude_subscription" ? await loadClaudeSubscriptionUsageCredential(db, settings, {
|
|
10257
|
+
accountId,
|
|
10258
|
+
workspaceId,
|
|
10259
|
+
scope: "organization"
|
|
10260
|
+
}) : null;
|
|
10261
|
+
const credential = kind === "claude_subscription" ? binding?.serializedCredential : await loadOrganizationModelProviderApiKey(db, settings, {
|
|
10003
10262
|
accountId,
|
|
10004
10263
|
workspaceId,
|
|
10005
10264
|
providerKind: kind
|
|
10006
10265
|
});
|
|
10007
|
-
if (credential)
|
|
10266
|
+
if (credential)
|
|
10267
|
+
result = withClaudeConnectionCredential(
|
|
10268
|
+
result,
|
|
10269
|
+
kind,
|
|
10270
|
+
credential,
|
|
10271
|
+
"organization",
|
|
10272
|
+
binding ?? void 0
|
|
10273
|
+
);
|
|
10008
10274
|
const workspaceModels = await listWorkspaceProviderCustomModels(db, {
|
|
10009
10275
|
accountId,
|
|
10010
10276
|
workspaceId,
|
|
@@ -10027,15 +10293,27 @@ async function settingsWithOrganizationProviderCredentials(db, accountId, worksp
|
|
|
10027
10293
|
{ [kind]: { models: workspaceModels } },
|
|
10028
10294
|
"workspace"
|
|
10029
10295
|
);
|
|
10030
|
-
const
|
|
10031
|
-
|
|
10032
|
-
settings,
|
|
10296
|
+
const workspaceBinding = kind === "claude_subscription" ? await loadClaudeSubscriptionUsageCredential(db, settings, {
|
|
10297
|
+
accountId,
|
|
10033
10298
|
workspaceId,
|
|
10034
|
-
|
|
10035
|
-
|
|
10036
|
-
)
|
|
10299
|
+
scope: "workspace"
|
|
10300
|
+
}) : null;
|
|
10301
|
+
if (workspaceBinding && workspaceModelId)
|
|
10302
|
+
await assertModelConnectionAllowsTurn(db, {
|
|
10303
|
+
workspaceId,
|
|
10304
|
+
subjectId: "worker:model-access",
|
|
10305
|
+
modelId: workspaceModelId,
|
|
10306
|
+
workspaceProviderConnectionId: workspaceBinding.connectionId
|
|
10307
|
+
});
|
|
10308
|
+
const workspaceCredential = kind === "claude_subscription" ? workspaceBinding?.serializedCredential : await loadWorkspaceProviderApiKey(db, settings, workspaceId, kind, workspaceModelId);
|
|
10037
10309
|
if (workspaceCredential)
|
|
10038
|
-
result = withClaudeConnectionCredential(
|
|
10310
|
+
result = withClaudeConnectionCredential(
|
|
10311
|
+
result,
|
|
10312
|
+
kind,
|
|
10313
|
+
workspaceCredential,
|
|
10314
|
+
"workspace",
|
|
10315
|
+
workspaceBinding ?? void 0
|
|
10316
|
+
);
|
|
10039
10317
|
}
|
|
10040
10318
|
return result;
|
|
10041
10319
|
}
|
|
@@ -10253,20 +10531,27 @@ async function claimTurnAttempt(deps) {
|
|
|
10253
10531
|
return attached.action === "claimed" && attached.turn.id === turn.id;
|
|
10254
10532
|
};
|
|
10255
10533
|
turnLifecycleMetricsFor(observability).start({ attemptId: input.attemptId });
|
|
10256
|
-
|
|
10257
|
-
|
|
10258
|
-
|
|
10259
|
-
|
|
10260
|
-
|
|
10261
|
-
|
|
10262
|
-
|
|
10263
|
-
|
|
10264
|
-
|
|
10265
|
-
|
|
10266
|
-
|
|
10267
|
-
|
|
10268
|
-
|
|
10269
|
-
|
|
10534
|
+
let allowanceRefusal = null;
|
|
10535
|
+
try {
|
|
10536
|
+
await waitForTurnOperation(
|
|
10537
|
+
ensureRunAllowed(
|
|
10538
|
+
capabilitySettings,
|
|
10539
|
+
db,
|
|
10540
|
+
input.accountId,
|
|
10541
|
+
input.workspaceId,
|
|
10542
|
+
billingState.isExternallyBilledTurn,
|
|
10543
|
+
entitlements,
|
|
10544
|
+
billingState.chargesOpenGeniCredits,
|
|
10545
|
+
billingState.countsTowardTokenCap,
|
|
10546
|
+
turn.initiatingHumanSubjectId
|
|
10547
|
+
),
|
|
10548
|
+
cancellationSignal,
|
|
10549
|
+
void 0
|
|
10550
|
+
);
|
|
10551
|
+
} catch (error51) {
|
|
10552
|
+
if (!(error51 instanceof AllowanceExhaustedError)) throw error51;
|
|
10553
|
+
allowanceRefusal = error51.refusal;
|
|
10554
|
+
}
|
|
10270
10555
|
const throwIfWorkerShuttingDown = () => {
|
|
10271
10556
|
const reason = activityContext?.cancellationSignal.reason;
|
|
10272
10557
|
if (isWorkerShutdownCancellation(reason)) {
|
|
@@ -10371,6 +10656,7 @@ async function claimTurnAttempt(deps) {
|
|
|
10371
10656
|
sessionStatus: inputSettlement.sessionStatus,
|
|
10372
10657
|
activeTurnId: inputSettlement.activeTurnId,
|
|
10373
10658
|
...inputSettlement.suppressGoalContinuation !== void 0 ? { suppressGoalContinuation: inputSettlement.suppressGoalContinuation } : {},
|
|
10659
|
+
...inputSettlement.allowanceGoalPause ? { allowanceGoalPause: inputSettlement.allowanceGoalPause } : {},
|
|
10374
10660
|
events: inputs,
|
|
10375
10661
|
...runState ? { runState } : {},
|
|
10376
10662
|
...compactionRequestFailure ? { compactionRequestFailure } : {}
|
|
@@ -10418,6 +10704,31 @@ async function claimTurnAttempt(deps) {
|
|
|
10418
10704
|
durationSeconds: (performance.now() - activityStarted) / 1e3
|
|
10419
10705
|
});
|
|
10420
10706
|
const turnStartSettlementStartedAt = performance.now();
|
|
10707
|
+
if (allowanceRefusal) {
|
|
10708
|
+
if (!await eventing.settle({
|
|
10709
|
+
events: [
|
|
10710
|
+
{ type: "usage.exhausted", payload: allowanceRefusal },
|
|
10711
|
+
{
|
|
10712
|
+
type: "turn.completed",
|
|
10713
|
+
payload: {
|
|
10714
|
+
output: "",
|
|
10715
|
+
segmentLimit: "budget_exhausted",
|
|
10716
|
+
...allowanceRefusal
|
|
10717
|
+
}
|
|
10718
|
+
},
|
|
10719
|
+
{ type: "session.status.changed", payload: { status: "idle" } }
|
|
10720
|
+
],
|
|
10721
|
+
turnStatus: "completed",
|
|
10722
|
+
sessionStatus: "idle",
|
|
10723
|
+
activeTurnId: null,
|
|
10724
|
+
allowanceGoalPause: { rationale: allowanceRefusal.message }
|
|
10725
|
+
})) {
|
|
10726
|
+
return { exit: claimedResult({ status: "cancelled" }) };
|
|
10727
|
+
}
|
|
10728
|
+
control.turnMetricOutcome = "completed";
|
|
10729
|
+
control.activityStatus = "idle";
|
|
10730
|
+
return { exit: claimedResult({ status: "idle" }) };
|
|
10731
|
+
}
|
|
10421
10732
|
if (!await eventing.settle({
|
|
10422
10733
|
events: [
|
|
10423
10734
|
{ type: "session.status.changed", payload: { status: "running" } },
|
|
@@ -11431,7 +11742,8 @@ import { retryWhileMissing as retryWhileMissing3 } from "@opengeni/storage";
|
|
|
11431
11742
|
import { WorkspaceModelPolicyBlockedError } from "@opengeni/runtime";
|
|
11432
11743
|
import {
|
|
11433
11744
|
evaluateWorkspaceModelPolicy,
|
|
11434
|
-
resolveWorkspaceAgentHumanInputEnabled as resolveWorkspaceAgentHumanInputEnabled2
|
|
11745
|
+
resolveWorkspaceAgentHumanInputEnabled as resolveWorkspaceAgentHumanInputEnabled2,
|
|
11746
|
+
resolveWorkspaceDefaultAgentIdentity
|
|
11435
11747
|
} from "@opengeni/contracts";
|
|
11436
11748
|
import { codeSearchEnabledForTurn } from "@opengeni/contracts/code-search";
|
|
11437
11749
|
|
|
@@ -11822,6 +12134,10 @@ async function prepareGovernanceAndModel(deps) {
|
|
|
11822
12134
|
);
|
|
11823
12135
|
const contextSelection = await resolveCompanyBrainContextSelection(db, governanceClaims);
|
|
11824
12136
|
const workspaceAgentInstructions = contextSelection.legacyWorkspaceInstructions;
|
|
12137
|
+
const workspaceAgentIdentity = resolveWorkspaceDefaultAgentIdentity(
|
|
12138
|
+
workspace.settings,
|
|
12139
|
+
workspaceAgentInstructions
|
|
12140
|
+
).identity;
|
|
11825
12141
|
const memoryPromptMode = contextSelection.receipt.memoryPromptMode;
|
|
11826
12142
|
assertWorkspaceHumanInputAllowed(agentHumanInputEnabled, "resume", humanInputResume !== null);
|
|
11827
12143
|
const companyProfileIncluded = contextSelection.receipt.companyProfileIncluded;
|
|
@@ -11981,6 +12297,7 @@ async function prepareGovernanceAndModel(deps) {
|
|
|
11981
12297
|
agentHumanInputEnabled,
|
|
11982
12298
|
codeSearchEnabled,
|
|
11983
12299
|
workspaceAgentInstructions,
|
|
12300
|
+
workspaceAgentIdentity,
|
|
11984
12301
|
workspaceGovernance,
|
|
11985
12302
|
structuredWorkspacePolicyActive,
|
|
11986
12303
|
workspaceMemory,
|
|
@@ -12008,7 +12325,9 @@ import {
|
|
|
12008
12325
|
appendSessionInstructions,
|
|
12009
12326
|
appendWorkspaceGovernance,
|
|
12010
12327
|
appendWorkspaceMemory,
|
|
12328
|
+
agentPromptResourcesFor,
|
|
12011
12329
|
composeAgentInstructions,
|
|
12330
|
+
inspectPersistentAgentInstructions,
|
|
12012
12331
|
requestRemoteCompactionV2,
|
|
12013
12332
|
preparedCompactionRequest,
|
|
12014
12333
|
queuePreparedCompaction,
|
|
@@ -12018,6 +12337,39 @@ import {
|
|
|
12018
12337
|
estimateSerializedValueTokens,
|
|
12019
12338
|
compactionSummaryOutputTokens as compactionSummaryOutputTokens2
|
|
12020
12339
|
} from "@opengeni/runtime";
|
|
12340
|
+
function standaloneCompactionInstructions(input) {
|
|
12341
|
+
if (input.session.agent) {
|
|
12342
|
+
return inspectPersistentAgentInstructions(input.settings, {
|
|
12343
|
+
agentConfig: input.session.agent,
|
|
12344
|
+
...input.workspaceAgentIdentity ? { workspaceAgentIdentity: input.workspaceAgentIdentity } : {},
|
|
12345
|
+
...input.workspaceGovernance ? { workspaceGovernance: input.workspaceGovernance } : {},
|
|
12346
|
+
...input.workspaceMemory ? { workspaceMemory: input.workspaceMemory } : {},
|
|
12347
|
+
...input.session.instructions ? { sessionInstructions: input.session.instructions } : {},
|
|
12348
|
+
...input.rig ? { rig: input.rig } : {},
|
|
12349
|
+
// Session-level facts only: per-turn attachments do not apply to a
|
|
12350
|
+
// standalone compaction request.
|
|
12351
|
+
agentPromptResources: agentPromptResourcesFor(
|
|
12352
|
+
input.settings,
|
|
12353
|
+
input.session.resources.filter((resource) => resource.kind !== "file"),
|
|
12354
|
+
input.rig ? { rig: input.rig } : {}
|
|
12355
|
+
)
|
|
12356
|
+
}).composed;
|
|
12357
|
+
}
|
|
12358
|
+
return appendWorkspaceMemory(
|
|
12359
|
+
appendSessionInstructions(
|
|
12360
|
+
appendWorkspaceGovernance(
|
|
12361
|
+
composeAgentInstructions(
|
|
12362
|
+
input.structuredWorkspacePolicyActive ? input.settings.agentInstructionsTemplate : input.workspaceAgentInstructions ?? input.settings.agentInstructionsTemplate,
|
|
12363
|
+
void 0,
|
|
12364
|
+
input.rig
|
|
12365
|
+
),
|
|
12366
|
+
input.workspaceGovernance ?? void 0
|
|
12367
|
+
),
|
|
12368
|
+
input.session.instructions ?? void 0
|
|
12369
|
+
),
|
|
12370
|
+
input.workspaceMemory ?? void 0
|
|
12371
|
+
);
|
|
12372
|
+
}
|
|
12021
12373
|
async function prepareCompaction(deps) {
|
|
12022
12374
|
const {
|
|
12023
12375
|
input,
|
|
@@ -12042,6 +12394,7 @@ async function prepareCompaction(deps) {
|
|
|
12042
12394
|
turnExecutionPolicy,
|
|
12043
12395
|
resolvedModel,
|
|
12044
12396
|
workspaceAgentInstructions,
|
|
12397
|
+
workspaceAgentIdentity,
|
|
12045
12398
|
workspaceGovernance,
|
|
12046
12399
|
structuredWorkspacePolicyActive,
|
|
12047
12400
|
workspaceMemory,
|
|
@@ -12185,20 +12538,16 @@ async function prepareCompaction(deps) {
|
|
|
12185
12538
|
return claimedResult({ status: "idle" });
|
|
12186
12539
|
};
|
|
12187
12540
|
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
|
-
);
|
|
12541
|
+
const compactionInstructions = standaloneCompactionInstructions({
|
|
12542
|
+
settings: eventing.modelRunSettings,
|
|
12543
|
+
session,
|
|
12544
|
+
workspaceAgentInstructions,
|
|
12545
|
+
workspaceAgentIdentity,
|
|
12546
|
+
workspaceGovernance,
|
|
12547
|
+
structuredWorkspacePolicyActive,
|
|
12548
|
+
workspaceMemory,
|
|
12549
|
+
rig: rigVersion && rigName ? { name: rigName, version: rigVersion.version } : void 0
|
|
12550
|
+
});
|
|
12202
12551
|
const requested = await isSessionCompactionRequested2(db, input.workspaceId, input.sessionId);
|
|
12203
12552
|
let outcome = null;
|
|
12204
12553
|
if (requested) {
|
|
@@ -13267,6 +13616,7 @@ async function resolveSandboxRoute(deps) {
|
|
|
13267
13616
|
machinePrimary,
|
|
13268
13617
|
groupBoxBackend,
|
|
13269
13618
|
groupBoxImage,
|
|
13619
|
+
groupBoxImagePolicy: "new_creates_only",
|
|
13270
13620
|
sandboxCreationBackend,
|
|
13271
13621
|
effectiveRunCredentialBackend
|
|
13272
13622
|
};
|
|
@@ -13306,6 +13656,7 @@ async function establishTurnSandbox(deps) {
|
|
|
13306
13656
|
machinePrimary,
|
|
13307
13657
|
groupBoxBackend,
|
|
13308
13658
|
groupBoxImage,
|
|
13659
|
+
groupBoxImagePolicy,
|
|
13309
13660
|
rigVersion,
|
|
13310
13661
|
turnResources
|
|
13311
13662
|
} = deps;
|
|
@@ -13560,7 +13911,8 @@ async function establishTurnSandbox(deps) {
|
|
|
13560
13911
|
os: groupBoxOs,
|
|
13561
13912
|
environment: sandboxEnvironment,
|
|
13562
13913
|
...groupBoxImage ? {
|
|
13563
|
-
image: groupBoxImage
|
|
13914
|
+
image: groupBoxImage,
|
|
13915
|
+
imagePolicy: groupBoxImagePolicy
|
|
13564
13916
|
} : {},
|
|
13565
13917
|
// The lazy acquire must enforce the same frozen rig authority
|
|
13566
13918
|
// as the eager acquire; otherwise a warm box for another rig
|
|
@@ -13637,16 +13989,16 @@ async function establishTurnSandbox(deps) {
|
|
|
13637
13989
|
backend: groupBoxBackend,
|
|
13638
13990
|
os: groupBoxOs,
|
|
13639
13991
|
environment: sandboxEnvironment,
|
|
13640
|
-
//
|
|
13641
|
-
//
|
|
13642
|
-
//
|
|
13643
|
-
//
|
|
13644
|
-
// the image for the actual group-box backend; a configured Modal image must
|
|
13992
|
+
// Deployment/workspace pins select NEW creates only. The lease
|
|
13993
|
+
// retains a live group's image through between-turn repins, even
|
|
13994
|
+
// with other holders; only rotation/reaping elects a new image.
|
|
13995
|
+
// Select the image for the actual group-box backend; a configured Modal image must
|
|
13645
13996
|
// never override a Docker run. The selfhosted branch
|
|
13646
13997
|
// (establishSelfhostedTurnSession) NEVER passes
|
|
13647
13998
|
// an image — B3 lives only on this managed-box branch.
|
|
13648
13999
|
...groupBoxImage ? {
|
|
13649
|
-
image: groupBoxImage
|
|
14000
|
+
image: groupBoxImage,
|
|
14001
|
+
imagePolicy: groupBoxImagePolicy
|
|
13650
14002
|
} : {},
|
|
13651
14003
|
// RIG IS SHARED STATE (M3): stamp the frozen rig version so the lease
|
|
13652
14004
|
// conflicts on a live shared box set up under a different rig (solo
|
|
@@ -14342,6 +14694,100 @@ import {
|
|
|
14342
14694
|
} from "@opengeni/runtime";
|
|
14343
14695
|
import { codemodeWorkspaceUrl as codemodeWorkspaceUrl2 } from "@opengeni/config";
|
|
14344
14696
|
|
|
14697
|
+
// src/activities/mcp-account-routes.ts
|
|
14698
|
+
function accountRouteAuthNeededPayload(payload, bindings) {
|
|
14699
|
+
const binding = bindings?.find((candidate) => candidate.serverId === payload.serverId);
|
|
14700
|
+
return binding ? {
|
|
14701
|
+
...payload,
|
|
14702
|
+
canonicalServerId: binding.canonicalServerId,
|
|
14703
|
+
connectionSubjectScope: binding.subjectScope
|
|
14704
|
+
} : payload;
|
|
14705
|
+
}
|
|
14706
|
+
function expandMcpAccountRoutes(input) {
|
|
14707
|
+
if (input.bindings == null) {
|
|
14708
|
+
return { settings: input.settings, tools: input.tools, accountLabels: /* @__PURE__ */ new Map() };
|
|
14709
|
+
}
|
|
14710
|
+
const configured = new Map(input.settings.mcpServers.map((server) => [server.id, server]));
|
|
14711
|
+
const byCanonical = /* @__PURE__ */ new Map();
|
|
14712
|
+
const routes = /* @__PURE__ */ new Set();
|
|
14713
|
+
const accounts = /* @__PURE__ */ new Set();
|
|
14714
|
+
for (const binding of input.bindings) {
|
|
14715
|
+
const account = JSON.stringify([binding.canonicalServerId, binding.connectionId]);
|
|
14716
|
+
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) {
|
|
14717
|
+
throw new Error("Invalid accepted MCP account route");
|
|
14718
|
+
}
|
|
14719
|
+
routes.add(binding.serverId);
|
|
14720
|
+
accounts.add(account);
|
|
14721
|
+
const siblings = byCanonical.get(binding.canonicalServerId) ?? [];
|
|
14722
|
+
siblings.push(binding);
|
|
14723
|
+
byCanonical.set(binding.canonicalServerId, siblings);
|
|
14724
|
+
}
|
|
14725
|
+
const servers = [];
|
|
14726
|
+
const tools = [];
|
|
14727
|
+
const accountLabels = /* @__PURE__ */ new Map();
|
|
14728
|
+
for (const tool of input.tools) {
|
|
14729
|
+
const bindings = byCanonical.get(tool.id);
|
|
14730
|
+
if (!bindings) {
|
|
14731
|
+
if (!configured.get(tool.id)?.connectionRef) tools.push(tool);
|
|
14732
|
+
continue;
|
|
14733
|
+
}
|
|
14734
|
+
const canonical = configured.get(tool.id);
|
|
14735
|
+
if (!canonical?.connectionRef) {
|
|
14736
|
+
throw new Error("Accepted MCP account route has no canonical connection configuration");
|
|
14737
|
+
}
|
|
14738
|
+
for (const binding of bindings) {
|
|
14739
|
+
if (canonical.connectionRef.authoritySource === "host" || canonical.connectionRef.providerDomain !== binding.providerDomain || canonical.connectionRef.kind && canonical.connectionRef.kind !== binding.kind) {
|
|
14740
|
+
throw new Error("Accepted MCP account route does not match canonical provider");
|
|
14741
|
+
}
|
|
14742
|
+
const { headers: _headers, ...config2 } = canonical;
|
|
14743
|
+
const label = `${canonical.name ?? canonical.id} \u2014 ${binding.subjectScope === "subject" ? "Personal" : "Workspace"}: ${binding.accountLabel}`;
|
|
14744
|
+
servers.push({
|
|
14745
|
+
...config2,
|
|
14746
|
+
id: binding.serverId,
|
|
14747
|
+
name: label,
|
|
14748
|
+
connectionRef: structuredClone(binding.connectionRef)
|
|
14749
|
+
});
|
|
14750
|
+
tools.push({ ...tool, id: binding.serverId });
|
|
14751
|
+
accountLabels.set(binding.serverId, label);
|
|
14752
|
+
}
|
|
14753
|
+
}
|
|
14754
|
+
return {
|
|
14755
|
+
settings: {
|
|
14756
|
+
...input.settings,
|
|
14757
|
+
mcpServers: [
|
|
14758
|
+
...input.settings.mcpServers.filter((server) => !server.connectionRef),
|
|
14759
|
+
...servers
|
|
14760
|
+
]
|
|
14761
|
+
},
|
|
14762
|
+
tools,
|
|
14763
|
+
accountLabels
|
|
14764
|
+
};
|
|
14765
|
+
}
|
|
14766
|
+
function expandApiIntegrationAccountRoutes(input) {
|
|
14767
|
+
const selected = new Set(input.tools.map((tool) => tool.id));
|
|
14768
|
+
if (input.bindings == null)
|
|
14769
|
+
return input.integrations.filter((item) => selected.has(item.serverId));
|
|
14770
|
+
const acceptedBindings = input.bindings;
|
|
14771
|
+
return input.integrations.flatMap((integration) => {
|
|
14772
|
+
const bindings = acceptedBindings.filter(
|
|
14773
|
+
(binding) => binding.canonicalServerId === integration.serverId
|
|
14774
|
+
);
|
|
14775
|
+
if (bindings.length === 0)
|
|
14776
|
+
return !integration.connectionRef && selected.has(integration.serverId) ? [integration] : [];
|
|
14777
|
+
return bindings.filter((binding) => selected.has(binding.serverId)).map((binding) => {
|
|
14778
|
+
if (binding.connectionAuthorityGeneration === void 0) {
|
|
14779
|
+
throw new Error("Accepted API integration account route has no authority generation");
|
|
14780
|
+
}
|
|
14781
|
+
return {
|
|
14782
|
+
...integration,
|
|
14783
|
+
serverId: binding.serverId,
|
|
14784
|
+
connectionRef: structuredClone(binding.connectionRef),
|
|
14785
|
+
connectionAuthorityGeneration: binding.connectionAuthorityGeneration
|
|
14786
|
+
};
|
|
14787
|
+
});
|
|
14788
|
+
});
|
|
14789
|
+
}
|
|
14790
|
+
|
|
14345
14791
|
// src/activities/git-credential-renewal.ts
|
|
14346
14792
|
var GIT_CREDENTIAL_DEFAULT_REFRESH_MS = 30 * 6e4;
|
|
14347
14793
|
var GIT_CREDENTIAL_EXPIRY_LEAD_MS = 5 * 6e4;
|
|
@@ -14700,6 +15146,8 @@ function credentialProviderRequestBody(input, initiatingHumanSubjectId, initiati
|
|
|
14700
15146
|
lane: "workspace",
|
|
14701
15147
|
mcpServers: []
|
|
14702
15148
|
}) {
|
|
15149
|
+
const via = input.initiatorContext.via;
|
|
15150
|
+
const latestHop = Array.isArray(via) ? via.at(-1) : null;
|
|
14703
15151
|
return {
|
|
14704
15152
|
type: "credentials.request",
|
|
14705
15153
|
lane: selection.lane,
|
|
@@ -14714,6 +15162,11 @@ function credentialProviderRequestBody(input, initiatingHumanSubjectId, initiati
|
|
|
14714
15162
|
turnId: input.turnId,
|
|
14715
15163
|
attemptId: input.attemptId,
|
|
14716
15164
|
initiator: { kind: input.initiator.kind, subjectId: input.initiator.subjectId },
|
|
15165
|
+
initiatorContext: {
|
|
15166
|
+
kind: latestHop?.kind === "agent" ? "agent" : input.initiator.kind === "subject" ? "human" : "service",
|
|
15167
|
+
initiator: input.initiator,
|
|
15168
|
+
context: input.initiatorContext
|
|
15169
|
+
},
|
|
14717
15170
|
initiatingHumanSubjectId,
|
|
14718
15171
|
initiatingHuman,
|
|
14719
15172
|
sandboxBackend: input.effectiveSandboxBackend,
|
|
@@ -14905,7 +15358,7 @@ async function bindRunCredentialResolver(input) {
|
|
|
14905
15358
|
mcpServers: selectedSessionRemoteMcpTargets(
|
|
14906
15359
|
input.settings,
|
|
14907
15360
|
input.session.mcpServers ?? [],
|
|
14908
|
-
input.
|
|
15361
|
+
input.effectiveTools,
|
|
14909
15362
|
(input.localMcpServerIds ?? []).map((id) => ({ id }))
|
|
14910
15363
|
)
|
|
14911
15364
|
}
|
|
@@ -14921,22 +15374,23 @@ async function bindRunCredentialResolver(input) {
|
|
|
14921
15374
|
workspaceId: input.workspaceId,
|
|
14922
15375
|
sessionId: input.session.id
|
|
14923
15376
|
};
|
|
15377
|
+
const frozenRequest = structuredClone(
|
|
15378
|
+
buildRunCredentialsRequest({
|
|
15379
|
+
accountId: input.accountId,
|
|
15380
|
+
workspaceId: input.workspaceId,
|
|
15381
|
+
session: input.session,
|
|
15382
|
+
turn: input.turn,
|
|
15383
|
+
attemptId: input.attemptId,
|
|
15384
|
+
effectiveSandboxBackend: input.effectiveSandboxBackend,
|
|
15385
|
+
variableSet: input.variableSet,
|
|
15386
|
+
rootSessionId,
|
|
15387
|
+
purpose: "provision",
|
|
15388
|
+
forceRefresh: false
|
|
15389
|
+
})
|
|
15390
|
+
);
|
|
14924
15391
|
return {
|
|
14925
15392
|
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
|
-
);
|
|
15393
|
+
const resolution = await resolver({ ...frozenRequest, purpose, forceRefresh });
|
|
14940
15394
|
return normalizeRunCredentialsResolution(resolution, scope);
|
|
14941
15395
|
}
|
|
14942
15396
|
};
|
|
@@ -14981,13 +15435,19 @@ async function prepareRunCredentials(deps) {
|
|
|
14981
15435
|
const platformGitResources = turnResources.filter(
|
|
14982
15436
|
(resource) => resource.kind !== "repository" || repositoryHasExplicitGitConnection(resource)
|
|
14983
15437
|
);
|
|
15438
|
+
const accountRoutes = expandMcpAccountRoutes({
|
|
15439
|
+
settings: runSettings,
|
|
15440
|
+
tools: deps.turnTools,
|
|
15441
|
+
bindings: turn.mcpAccountBindings
|
|
15442
|
+
});
|
|
14984
15443
|
const runCredentialResolver = effectiveRunCredentialBackend === "none" || effectiveRunCredentialBackend === "selfhosted" ? null : await waitForTurnOperation(
|
|
14985
15444
|
bindRunCredentialResolver({
|
|
14986
15445
|
db,
|
|
14987
|
-
settings:
|
|
15446
|
+
settings: accountRoutes.settings,
|
|
14988
15447
|
initiatingHumanSubjectId: turn.initiatingHumanSubjectId ?? null,
|
|
14989
15448
|
connectionCredentials: connectionCredentials ?? null,
|
|
14990
15449
|
localMcpServerIds: deps.localMcpServerIds ?? [],
|
|
15450
|
+
effectiveTools: accountRoutes.tools,
|
|
14991
15451
|
accountId: input.accountId,
|
|
14992
15452
|
workspaceId: input.workspaceId,
|
|
14993
15453
|
session,
|
|
@@ -15026,9 +15486,9 @@ async function prepareRunCredentials(deps) {
|
|
|
15026
15486
|
) : null;
|
|
15027
15487
|
const runMcpCredentials = new RunMcpCredentials(
|
|
15028
15488
|
selectedSessionRemoteMcpTargets2(
|
|
15029
|
-
|
|
15489
|
+
accountRoutes.settings,
|
|
15030
15490
|
session.mcpServers ?? [],
|
|
15031
|
-
|
|
15491
|
+
accountRoutes.tools,
|
|
15032
15492
|
(deps.localMcpServerIds ?? []).map((id) => ({ id }))
|
|
15033
15493
|
),
|
|
15034
15494
|
{
|
|
@@ -16410,100 +16870,6 @@ function isGitHubApiDestination(value) {
|
|
|
16410
16870
|
}
|
|
16411
16871
|
}
|
|
16412
16872
|
|
|
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
16873
|
// src/activities/agent-turn/tool-environment.ts
|
|
16508
16874
|
import { createMcpOperationPersistence } from "@opengeni/db/mcp-operations";
|
|
16509
16875
|
|
|
@@ -32257,14 +32623,17 @@ import {
|
|
|
32257
32623
|
buildApiIntegrationMcpServers,
|
|
32258
32624
|
resolveCatalogSettings as resolveCatalogSettings2,
|
|
32259
32625
|
resolveWorkspaceModelSelection,
|
|
32626
|
+
loadWorkspaceCodexModelAvailability,
|
|
32260
32627
|
withFrozenPersonalConnectionDelegations,
|
|
32261
|
-
|
|
32628
|
+
resolveTurnToolPolicy,
|
|
32629
|
+
scheduledTurnMcpServerIds,
|
|
32262
32630
|
hasPermission as hasPermission2
|
|
32263
32631
|
} from "@opengeni/core";
|
|
32264
32632
|
import { SandboxChannelAService as SandboxChannelAService3 } from "@opengeni/runtime/sandbox";
|
|
32265
32633
|
import { sandboxRunAs as sandboxRunAs4 } from "@opengeni/runtime";
|
|
32266
32634
|
import {
|
|
32267
|
-
DEFAULT_FIRST_PARTY_MCP_PERMISSIONS as DEFAULT_FIRST_PARTY_MCP_PERMISSIONS2
|
|
32635
|
+
DEFAULT_FIRST_PARTY_MCP_PERMISSIONS as DEFAULT_FIRST_PARTY_MCP_PERMISSIONS2,
|
|
32636
|
+
resolveAgentToolFamilies
|
|
32268
32637
|
} from "@opengeni/contracts";
|
|
32269
32638
|
|
|
32270
32639
|
// src/activities/agent-turn/list-models.ts
|
|
@@ -33703,27 +34072,31 @@ async function prepareTurnToolPolicy(deps) {
|
|
|
33703
34072
|
} = deps;
|
|
33704
34073
|
const turnResources = mergeResourceRefs(session.resources, turn.resources);
|
|
33705
34074
|
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({
|
|
34075
|
+
const resolvedToolPolicy = resolveTurnToolPolicy({
|
|
33712
34076
|
toolPolicy: session.toolPolicy,
|
|
33713
|
-
|
|
33714
|
-
|
|
33715
|
-
|
|
34077
|
+
session,
|
|
34078
|
+
turn,
|
|
34079
|
+
availableMcpServerIds: runSettings.mcpServers.map((server) => server.id),
|
|
34080
|
+
defaultMcpServerIds: scheduledTurnMcpServerIds(turn) === null && session.toolPolicy.mode === "workspace_default" ? await workspaceSessionToolPolicyDefaultServerIds(
|
|
33716
34081
|
db,
|
|
33717
34082
|
input.workspaceId,
|
|
33718
34083
|
capabilitySettings,
|
|
33719
34084
|
fileAuthoritySubjectId ?? void 0
|
|
33720
|
-
) : []
|
|
34085
|
+
) : []
|
|
33721
34086
|
});
|
|
33722
34087
|
const mcpAvailabilityNote = unavailableMcpOperationalContext({
|
|
33723
34088
|
droppedIds: resolvedToolPolicy.effectivePolicy.droppedIds,
|
|
33724
34089
|
droppedCount: resolvedToolPolicy.effectivePolicy.counts.dropped
|
|
33725
34090
|
});
|
|
33726
|
-
const
|
|
34091
|
+
const families = resolveAgentToolFamilies(session.agent, {
|
|
34092
|
+
productServerIds: /* @__PURE__ */ new Set([
|
|
34093
|
+
...session.mcpServers.map((server) => server.id),
|
|
34094
|
+
...session.toolPolicy.mode !== "workspace_default" ? session.tools.map((tool) => tool.id) : []
|
|
34095
|
+
])
|
|
34096
|
+
});
|
|
34097
|
+
const effectivePolicyTools = resolvedToolPolicy.toolRefs.filter(
|
|
34098
|
+
(tool) => tool.kind !== "mcp" || families.allowsMcpServer(tool.id)
|
|
34099
|
+
);
|
|
33727
34100
|
const turnTools = withFirstPartyTools(runSettings, effectivePolicyTools);
|
|
33728
34101
|
const connectionScope = {
|
|
33729
34102
|
accountId: input.accountId,
|
|
@@ -34003,14 +34376,16 @@ async function prepareTurnToolRuntime(deps) {
|
|
|
34003
34376
|
const effectiveFirstPartyPermissions = linkedAuthority ? (session.firstPartyMcpPermissions ?? DEFAULT_FIRST_PARTY_MCP_PERMISSIONS2).filter(
|
|
34004
34377
|
(permission) => hasPermission2(linkedAuthority.permissions, permission)
|
|
34005
34378
|
) : session.firstPartyMcpPermissions;
|
|
34006
|
-
const
|
|
34007
|
-
|
|
34008
|
-
session.firstPartyMcpTools
|
|
34379
|
+
const toolFamilies = resolveAgentToolFamilies(session.agent);
|
|
34380
|
+
const selectedFirstPartyMcpTools = toolFamilies.firstPartyTools(
|
|
34381
|
+
allowedFirstPartyMcpToolsForSession(runSettings, session.firstPartyMcpTools)
|
|
34009
34382
|
);
|
|
34010
34383
|
const titleToolPlan = sessionTitleToolPlan({
|
|
34384
|
+
agentConfig: session.agent,
|
|
34011
34385
|
tools: turnTools,
|
|
34012
34386
|
selectedFirstPartyMcpTools,
|
|
34013
34387
|
shouldRequestTitle: shouldRequestMissingSessionTitle({
|
|
34388
|
+
agentConfig: session.agent,
|
|
34014
34389
|
title: session.title,
|
|
34015
34390
|
titleSource: session.titleSource,
|
|
34016
34391
|
firstPartyMcpTools: selectedFirstPartyMcpTools,
|
|
@@ -34070,7 +34445,7 @@ async function prepareTurnToolRuntime(deps) {
|
|
|
34070
34445
|
workspaceId: input.workspaceId,
|
|
34071
34446
|
...deps.fileAuthoritySubjectId ? { subjectId: deps.fileAuthoritySubjectId } : {}
|
|
34072
34447
|
});
|
|
34073
|
-
const skillCatalog = [
|
|
34448
|
+
const skillCatalog = toolFamilies.skills === false ? [] : [
|
|
34074
34449
|
...sharedSkillDescriptors.filter((entry) => entry.activationMode === "workspace_managed").map((entry) => ({
|
|
34075
34450
|
id: entry.id,
|
|
34076
34451
|
name: entry.title,
|
|
@@ -34242,6 +34617,9 @@ async function prepareTurnToolRuntime(deps) {
|
|
|
34242
34617
|
);
|
|
34243
34618
|
}
|
|
34244
34619
|
});
|
|
34620
|
+
const attemptToolFamilies = resolveAgentToolFamilies(session.agent, {
|
|
34621
|
+
hasSkills: skillCatalog.length > 0
|
|
34622
|
+
});
|
|
34245
34623
|
const attemptToolDefinitions = [
|
|
34246
34624
|
...operationReadStore ? [
|
|
34247
34625
|
createOperationReadAttemptToolDefinition({
|
|
@@ -34283,7 +34661,8 @@ async function prepareTurnToolRuntime(deps) {
|
|
|
34283
34661
|
organizationGatewayConnectionActive,
|
|
34284
34662
|
organizationGatewayCustomModels,
|
|
34285
34663
|
organizationOpenRouterConnectionActive,
|
|
34286
|
-
organizationOpenRouterCustomModels
|
|
34664
|
+
organizationOpenRouterCustomModels,
|
|
34665
|
+
codexModelAvailability
|
|
34287
34666
|
] = await Promise.all([
|
|
34288
34667
|
getWorkspaceConnectionModelRestrictions(
|
|
34289
34668
|
db,
|
|
@@ -34326,10 +34705,12 @@ async function prepareTurnToolRuntime(deps) {
|
|
|
34326
34705
|
accountId: input.accountId,
|
|
34327
34706
|
workspaceId: input.workspaceId,
|
|
34328
34707
|
providerKind: "openrouter"
|
|
34329
|
-
})
|
|
34708
|
+
}),
|
|
34709
|
+
loadWorkspaceCodexModelAvailability(db, currentSettings, input.workspaceId)
|
|
34330
34710
|
]);
|
|
34331
34711
|
return {
|
|
34332
34712
|
selections: resolveWorkspaceModelSelection({
|
|
34713
|
+
observations: codexModelAvailability,
|
|
34333
34714
|
connectionModelRestrictions,
|
|
34334
34715
|
settings: currentSettings,
|
|
34335
34716
|
policy,
|
|
@@ -34385,7 +34766,7 @@ async function prepareTurnToolRuntime(deps) {
|
|
|
34385
34766
|
}),
|
|
34386
34767
|
...googleDrivePublicationTool && googleDrivePublicationAllowed ? [googleDrivePublicationTool] : [],
|
|
34387
34768
|
...codeSearchTools
|
|
34388
|
-
];
|
|
34769
|
+
].filter((tool) => attemptToolFamilies.allowsFunctionTool(tool.modelName));
|
|
34389
34770
|
recordTurnStartupPhase(observability, {
|
|
34390
34771
|
phase: "tool_context_preparation",
|
|
34391
34772
|
provider: turnExecutionPolicy.providerId,
|
|
@@ -34473,7 +34854,7 @@ async function prepareTurnToolRuntime(deps) {
|
|
|
34473
34854
|
sessionAttachedRemoteMcpTargets: selectedSessionRemoteMcpTargets3(
|
|
34474
34855
|
githubRestMcp.settings,
|
|
34475
34856
|
session.mcpServers ?? [],
|
|
34476
|
-
|
|
34857
|
+
githubRestMcp.tools,
|
|
34477
34858
|
localMcpServers
|
|
34478
34859
|
),
|
|
34479
34860
|
...deps.runMcpCredentials ? { runMcpCredentials: deps.runMcpCredentials } : {},
|
|
@@ -34917,7 +35298,8 @@ import {
|
|
|
34917
35298
|
getExternalLinkTurnAuthorization as getExternalLinkTurnAuthorization2,
|
|
34918
35299
|
getSessionTurnForAttempt as getSessionTurnForAttempt2,
|
|
34919
35300
|
ensureSessionReasoningConfiguration,
|
|
34920
|
-
ensureSessionSkillCatalog
|
|
35301
|
+
ensureSessionSkillCatalog,
|
|
35302
|
+
sessionHasToolRouterHistory
|
|
34921
35303
|
} from "@opengeni/db";
|
|
34922
35304
|
import {
|
|
34923
35305
|
formatSkillCatalog,
|
|
@@ -36073,7 +36455,7 @@ function validateReferenceImage(bytes) {
|
|
|
36073
36455
|
// src/activities/agent-turn/agent-build.ts
|
|
36074
36456
|
import { SandboxChannelAService as SandboxChannelAService4 } from "@opengeni/runtime/sandbox";
|
|
36075
36457
|
import { sandboxRunAs as sandboxRunAs5 } from "@opengeni/runtime";
|
|
36076
|
-
import { VideoGenerationRejectedResult } from "@opengeni/contracts";
|
|
36458
|
+
import { VideoGenerationRejectedResult, resolveAgentToolFamilies as resolveAgentToolFamilies2 } from "@opengeni/contracts";
|
|
36077
36459
|
|
|
36078
36460
|
// src/activities/agent-turn/video-reference-sandbox.ts
|
|
36079
36461
|
async function resolveVideoReferenceSandboxAccess(request, sandboxState, sdkOwnedSandboxSession) {
|
|
@@ -36117,6 +36499,7 @@ async function buildTurnAgent(deps) {
|
|
|
36117
36499
|
supportsImageInput,
|
|
36118
36500
|
agentHumanInputEnabled,
|
|
36119
36501
|
workspaceAgentInstructions,
|
|
36502
|
+
workspaceAgentIdentity,
|
|
36120
36503
|
workspaceGovernance,
|
|
36121
36504
|
structuredWorkspacePolicyActive,
|
|
36122
36505
|
workspaceMemory,
|
|
@@ -36197,7 +36580,7 @@ async function buildTurnAgent(deps) {
|
|
|
36197
36580
|
}
|
|
36198
36581
|
});
|
|
36199
36582
|
const imageGenerationOption = (() => {
|
|
36200
|
-
if (!objectStorage) return {};
|
|
36583
|
+
if (!objectStorage || !resolveAgentToolFamilies2(session.agent).media) return {};
|
|
36201
36584
|
if (nativeImageProviderBinding) {
|
|
36202
36585
|
media.nativeImageGenerationRetention = {
|
|
36203
36586
|
...nativeImageProviderBinding,
|
|
@@ -36313,7 +36696,7 @@ async function buildTurnAgent(deps) {
|
|
|
36313
36696
|
const videoGenerationPolicy = await getWorkspaceVideoGenerationPolicy2(db, input.workspaceId);
|
|
36314
36697
|
const videoGenerationEnabled = videoGenerationPolicy.defaultModelId !== null && videoGenerationPolicy.enabledModelIds.length > 0;
|
|
36315
36698
|
let videoGenerationCredential = null;
|
|
36316
|
-
if (objectStorage && videoGenerationEnabled) {
|
|
36699
|
+
if (objectStorage && videoGenerationEnabled && resolveAgentToolFamilies2(session.agent).media) {
|
|
36317
36700
|
if (videoGenerationPolicy.fundingSource === "opengeni_credits") {
|
|
36318
36701
|
videoGenerationCredential = managedVideoGenerationCredentialLease(eventing.modelRunSettings);
|
|
36319
36702
|
} else if (videoGenerationPolicy.fundingSource === "workspace_gateway") {
|
|
@@ -36505,6 +36888,11 @@ async function buildTurnAgent(deps) {
|
|
|
36505
36888
|
expectedAttemptId: input.attemptId,
|
|
36506
36889
|
effort: turn.reasoningEffort
|
|
36507
36890
|
}) : turn.reasoningEffort;
|
|
36891
|
+
const toolRouterInHistory = session.agent ? await sessionHasToolRouterHistory(db, {
|
|
36892
|
+
accountId: input.accountId,
|
|
36893
|
+
workspaceId: input.workspaceId,
|
|
36894
|
+
sessionId: input.sessionId
|
|
36895
|
+
}) : false;
|
|
36508
36896
|
const agent = (() => {
|
|
36509
36897
|
const agentConstructionStartedAt = performance.now();
|
|
36510
36898
|
let agentConstructionOutcome = "completed";
|
|
@@ -36523,6 +36911,7 @@ async function buildTurnAgent(deps) {
|
|
|
36523
36911
|
}
|
|
36524
36912
|
} : {},
|
|
36525
36913
|
...preparedTools.inputWaitYield ? { inputWaitYield: preparedTools.inputWaitYield } : {},
|
|
36914
|
+
...session.agent ? { agentConfig: session.agent, toolRouterInHistory } : {},
|
|
36526
36915
|
reasoningEffort: requestReasoningEffort,
|
|
36527
36916
|
latencyMode: turnExecutionPolicy.latencyMode,
|
|
36528
36917
|
...serviceTier ? { serviceTier } : {},
|
|
@@ -36611,6 +37000,14 @@ async function buildTurnAgent(deps) {
|
|
|
36611
37000
|
onRetainableSessionImageOutput: media.retainSessionImageAtToolBoundary,
|
|
36612
37001
|
skillCatalog: deps.skillCatalog,
|
|
36613
37002
|
skillCatalogInHistory: true,
|
|
37003
|
+
// A session with an agent configuration composes the modular prompt
|
|
37004
|
+
// (identity, base behavior, runtime mechanics, capability modules);
|
|
37005
|
+
// its workspace identity survives instruction policies. Null keeps
|
|
37006
|
+
// the legacy composition below byte-for-byte.
|
|
37007
|
+
...session.agent ? {
|
|
37008
|
+
agentConfig: session.agent,
|
|
37009
|
+
...workspaceAgentIdentity ? { workspaceAgentIdentity } : {}
|
|
37010
|
+
} : {},
|
|
36614
37011
|
...!structuredWorkspacePolicyActive && workspaceAgentInstructions ? { instructionsTemplate: workspaceAgentInstructions } : {},
|
|
36615
37012
|
...workspaceGovernance ? { workspaceGovernance } : {},
|
|
36616
37013
|
...workspaceMemory ? { workspaceMemory } : {},
|
|
@@ -36878,11 +37275,14 @@ function createRunAgentTurnActivity(services) {
|
|
|
36878
37275
|
getModelRunSettings: () => eventing.modelRunSettings,
|
|
36879
37276
|
getExecutionGeneration: () => attempt.executionGeneration
|
|
36880
37277
|
});
|
|
36881
|
-
const checkpointBeforeProviderDispatch = () =>
|
|
36882
|
-
|
|
36883
|
-
|
|
36884
|
-
|
|
36885
|
-
|
|
37278
|
+
const checkpointBeforeProviderDispatch = async () => {
|
|
37279
|
+
await awaitModelCallAdmission();
|
|
37280
|
+
await checkpointHistoryBeforeProviderDispatch(historySink, {
|
|
37281
|
+
effectiveSandboxBackend: eventing.modelRunSettings.sandboxBackend,
|
|
37282
|
+
routingEnabled: routingEnabled(settings),
|
|
37283
|
+
readActiveSandbox: () => readActiveSandbox3(db, input.workspaceId, input.sessionId)
|
|
37284
|
+
});
|
|
37285
|
+
};
|
|
36886
37286
|
try {
|
|
36887
37287
|
const claimed = await claimTurnAttempt({
|
|
36888
37288
|
input,
|
|
@@ -37025,7 +37425,7 @@ function createRunAgentTurnActivity(services) {
|
|
|
37025
37425
|
requiredGeneratedVideoFiles
|
|
37026
37426
|
});
|
|
37027
37427
|
if ("exit" in governance) return governance.exit;
|
|
37028
|
-
await
|
|
37428
|
+
await assertModelConnectionAllowsTurn2(db, {
|
|
37029
37429
|
workspaceId: input.workspaceId,
|
|
37030
37430
|
subjectId: turn.initiatingHumanSubjectId ?? "worker:model-access",
|
|
37031
37431
|
modelId: turnExecutionPolicy.productModelId,
|
|
@@ -37039,6 +37439,7 @@ function createRunAgentTurnActivity(services) {
|
|
|
37039
37439
|
agentHumanInputEnabled,
|
|
37040
37440
|
codeSearchEnabled,
|
|
37041
37441
|
workspaceAgentInstructions,
|
|
37442
|
+
workspaceAgentIdentity,
|
|
37042
37443
|
workspaceGovernance,
|
|
37043
37444
|
structuredWorkspacePolicyActive,
|
|
37044
37445
|
workspaceMemory,
|
|
@@ -37221,8 +37622,12 @@ function createRunAgentTurnActivity(services) {
|
|
|
37221
37622
|
credentialId: providerTurn.effectiveXaiCredentialId,
|
|
37222
37623
|
authoritySnapshot: turn.xaiProviderAccountAuthoritySnapshot,
|
|
37223
37624
|
hostedSearch: {
|
|
37224
|
-
webSearch:
|
|
37225
|
-
|
|
37625
|
+
webSearch: resolveAgentToolFamilies3(session.agent, {
|
|
37626
|
+
webSearch: runSettings.webSearchEnabled
|
|
37627
|
+
}).webSearch,
|
|
37628
|
+
xSearch: resolveAgentToolFamilies3(session.agent, {
|
|
37629
|
+
webSearch: runSettings.webSearchEnabled
|
|
37630
|
+
}).webSearch
|
|
37226
37631
|
},
|
|
37227
37632
|
streamIdleTimeoutMs: runSettings.supergrokResponseStreamIdleTimeoutMs,
|
|
37228
37633
|
nextRequestId: () => `${dispatchId}:xai:${++xaiModelRequestSequence}`,
|
|
@@ -37332,13 +37737,36 @@ function createRunAgentTurnActivity(services) {
|
|
|
37332
37737
|
const claudeUsageObserver = await createClaudeUsageObserver(
|
|
37333
37738
|
parseModelProvidersJson(runSettings.modelProvidersJson),
|
|
37334
37739
|
providerTurn.latestClaudeUsage,
|
|
37335
|
-
(scope) =>
|
|
37740
|
+
(scope) => loadClaudeSubscriptionUsageCredential2(db, settings, {
|
|
37336
37741
|
accountId: input.accountId,
|
|
37337
37742
|
workspaceId: input.workspaceId,
|
|
37338
37743
|
scope
|
|
37339
37744
|
})
|
|
37340
37745
|
);
|
|
37341
|
-
const withClaudeUsage = (fn) => withClaudeUsageObserver(claudeUsageObserver, fn)
|
|
37746
|
+
const withClaudeUsage = (fn) => withClaudeUsageObserver(claudeUsageObserver, fn, async (providerId, headers) => {
|
|
37747
|
+
const binding = claudeUsageObserver.binding(providerId);
|
|
37748
|
+
if (!binding) return headers;
|
|
37749
|
+
const credential = await resolveClaudeSubscriptionCredential(
|
|
37750
|
+
db,
|
|
37751
|
+
settings,
|
|
37752
|
+
{
|
|
37753
|
+
accountId: input.accountId,
|
|
37754
|
+
workspaceId: input.workspaceId,
|
|
37755
|
+
scope: binding.scope
|
|
37756
|
+
},
|
|
37757
|
+
{
|
|
37758
|
+
expectedConnectionId: binding.expectedConnectionId,
|
|
37759
|
+
expectedCredentialVersion: binding.expectedCredentialVersion
|
|
37760
|
+
}
|
|
37761
|
+
);
|
|
37762
|
+
if (!credential) return headers;
|
|
37763
|
+
if ("reconnectRequired" in credential)
|
|
37764
|
+
throw new ClaudeSubscriptionReconnectRequired();
|
|
37765
|
+
claudeUsageObserver.renew(providerId, credential);
|
|
37766
|
+
headers.set("authorization", `Bearer ${credential.token}`);
|
|
37767
|
+
headers.delete("x-api-key");
|
|
37768
|
+
return headers;
|
|
37769
|
+
});
|
|
37342
37770
|
const withCodex = (fn) => codexContext ? codexRequestStorage.run(codexContext, fn) : fn();
|
|
37343
37771
|
const withProviderRequestContext = (fn) => withClaudeUsage(
|
|
37344
37772
|
() => providerTurn.xaiRequestContext ? xaiSubscriptionRequestStorage.run(providerTurn.xaiRequestContext, fn) : withCodex(fn)
|
|
@@ -37396,6 +37824,7 @@ function createRunAgentTurnActivity(services) {
|
|
|
37396
37824
|
turnExecutionPolicy,
|
|
37397
37825
|
resolvedModel,
|
|
37398
37826
|
workspaceAgentInstructions,
|
|
37827
|
+
workspaceAgentIdentity,
|
|
37399
37828
|
workspaceGovernance,
|
|
37400
37829
|
structuredWorkspacePolicyActive,
|
|
37401
37830
|
workspaceMemory,
|
|
@@ -37542,6 +37971,7 @@ These are publication receipts for the human's earlier answer. Do not call the r
|
|
|
37542
37971
|
void 0
|
|
37543
37972
|
);
|
|
37544
37973
|
const runCredentials = await prepareRunCredentials({
|
|
37974
|
+
turnTools,
|
|
37545
37975
|
localMcpServerIds: installedApiIntegrations.map((integration) => integration.serverId),
|
|
37546
37976
|
input,
|
|
37547
37977
|
settings,
|
|
@@ -37774,6 +38204,7 @@ These are publication receipts for the human's earlier answer. Do not call the r
|
|
|
37774
38204
|
supportsImageInput,
|
|
37775
38205
|
agentHumanInputEnabled,
|
|
37776
38206
|
workspaceAgentInstructions,
|
|
38207
|
+
workspaceAgentIdentity,
|
|
37777
38208
|
workspaceGovernance,
|
|
37778
38209
|
structuredWorkspacePolicyActive,
|
|
37779
38210
|
workspaceMemory,
|
|
@@ -37898,6 +38329,7 @@ These are publication receipts for the human's earlier answer. Do not call the r
|
|
|
37898
38329
|
turnExecutionPolicy,
|
|
37899
38330
|
resolvedModel,
|
|
37900
38331
|
workspaceAgentInstructions,
|
|
38332
|
+
workspaceAgentIdentity,
|
|
37901
38333
|
workspaceGovernance,
|
|
37902
38334
|
structuredWorkspacePolicyActive,
|
|
37903
38335
|
workspaceMemory,
|
|
@@ -39307,4 +39739,4 @@ export {
|
|
|
39307
39739
|
createTurnActivities,
|
|
39308
39740
|
createTurnActivitiesFromServices
|
|
39309
39741
|
};
|
|
39310
|
-
//# sourceMappingURL=activities-turn-
|
|
39742
|
+
//# sourceMappingURL=activities-turn-T7Y3BWYO.js.map
|