@opengeni/worker-bundle 1.3.0 → 1.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/activities/agent-turn/errors.d.ts +1 -13
- package/dist/activities/agent-turn/subscription-lease.d.ts +1 -0
- package/dist/activities/agent-turn/tool-policy.d.ts +10 -1
- package/dist/activities/agent-turn/web-search.d.ts +33 -0
- package/dist/activities/programmatic-approvals.d.ts +17 -0
- package/dist/{activities-control-PEXBWKQJ.js → activities-control-D5KVEPHI.js} +3 -3
- package/dist/{activities-turn-W27A2SBO.js → activities-turn-4Z3M7Z3F.js} +288 -23
- package/dist/activities-turn-4Z3M7Z3F.js.map +1 -0
- package/dist/{chunk-QUX5LT2B.js → chunk-BMTWULF7.js} +113 -30
- package/dist/chunk-BMTWULF7.js.map +1 -0
- package/dist/{chunk-XONQEVAD.js → chunk-FF4HPY7L.js} +1 -1
- package/dist/chunk-FF4HPY7L.js.map +1 -0
- package/dist/index.js +2 -2
- package/dist/observability-metrics.d.ts +1 -1
- package/package.json +21 -21
- package/src/activities/agent-turn/agent-build.ts +4 -2
- package/src/activities/agent-turn/errors.ts +82 -3
- package/src/activities/agent-turn/governance-model.ts +8 -8
- package/src/activities/agent-turn/sandbox-runtime.ts +16 -0
- package/src/activities/agent-turn/stream-attempt.ts +40 -6
- package/src/activities/agent-turn/subscription-lease.ts +10 -1
- package/src/activities/agent-turn/tool-environment.ts +19 -0
- package/src/activities/agent-turn/tool-policy.ts +25 -0
- package/src/activities/agent-turn/web-search.ts +252 -0
- package/src/activities/connector-attachments.ts +3 -1
- package/src/activities/programmatic-approvals.ts +26 -0
- package/src/activity-services.ts +8 -0
- package/src/observability-metrics.ts +1 -0
- package/src/sandbox-routing.ts +58 -24
- package/dist/activities-turn-W27A2SBO.js.map +0 -1
- package/dist/chunk-QUX5LT2B.js.map +0 -1
- package/dist/chunk-XONQEVAD.js.map +0 -1
- /package/dist/{activities-control-PEXBWKQJ.js.map → activities-control-D5KVEPHI.js.map} +0 -0
|
@@ -131,19 +131,7 @@ export declare function modelPreparationFailureEventPayload(error: unknown, dura
|
|
|
131
131
|
failureCode?: "capture_in_progress" | "provider_recovery_in_progress" | "rotation_in_progress";
|
|
132
132
|
retryable?: boolean;
|
|
133
133
|
};
|
|
134
|
-
|
|
135
|
-
* Recognize active-route transitions that cannot finish inside their
|
|
136
|
-
* originating attempt. A Modal-home session may start on a Connected Machine
|
|
137
|
-
* without creating or leasing its managed home box. When an explicit attach
|
|
138
|
-
* clears the active pointer back to home, the pointer commit is authoritative,
|
|
139
|
-
* but this attempt has no home session to serve the next sandbox operation.
|
|
140
|
-
*
|
|
141
|
-
* The Agents SDK may retain the typed routing error directly, through `cause`,
|
|
142
|
-
* or inside an AggregateError from a parallel function-tool batch. Traverse
|
|
143
|
-
* only those structural error links with a strict bound; never classify from
|
|
144
|
-
* message text, which could originate in model or tool content.
|
|
145
|
-
*/
|
|
146
|
-
export declare function sandboxRouteTransitionCode(error: unknown): "home_unavailable_this_turn" | "workspace_root_changed_this_turn" | "native_capabilities_changed_this_attempt" | null;
|
|
134
|
+
export declare function sandboxRouteTransitionCode(error: unknown): "home_unavailable_this_turn" | "workspace_root_changed_this_turn" | "native_capabilities_changed_this_attempt" | "home_backend_recovery_pending" | null;
|
|
147
135
|
export declare function isSandboxRouteTransitionError(error: unknown): boolean;
|
|
148
136
|
/** Backward-compatible name for callers/tests that only exercised the original
|
|
149
137
|
* machine-to-home transition. */
|
|
@@ -27,6 +27,7 @@ export declare class SubscriptionTurnLease {
|
|
|
27
27
|
private heartbeatInFlight;
|
|
28
28
|
private heartbeatTimer;
|
|
29
29
|
private readonly now;
|
|
30
|
+
private readonly renewalIntervalMs;
|
|
30
31
|
constructor(leaseDeps: SubscriptionLeaseDeps);
|
|
31
32
|
private expired;
|
|
32
33
|
markLost: (reason: LeaseLossReason) => void;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { type ComputerToolMode, type LazyToolTransport } from "@opengeni/runtime";
|
|
1
|
+
import { type ComputerToolMode, type LazyToolTransport, type OpenGeniRuntime } from "@opengeni/runtime";
|
|
2
|
+
import type { TurnExecutionPolicyV1 } from "@opengeni/contracts";
|
|
2
3
|
import { type ModelProviderApi, type ResolvedModelProvider, type Settings } from "@opengeni/config";
|
|
3
4
|
import { type ModelAttachmentInputPolicy } from "../run-input.js";
|
|
4
5
|
export declare function shouldStartOnTurnRecording(params: {
|
|
@@ -112,6 +113,14 @@ export declare function shouldDeferNonEagerToolPreparation(args: {
|
|
|
112
113
|
triggerKind: "next" | "approval";
|
|
113
114
|
triggerType: string;
|
|
114
115
|
}): boolean;
|
|
116
|
+
/**
|
|
117
|
+
* Resolve the provider routing/gating shape for an accepted turn. The current
|
|
118
|
+
* definition is projected back onto the verified frozen policy: a turn
|
|
119
|
+
* accepted before hosted web search was enabled keeps its frozen tool set on
|
|
120
|
+
* every recovery attempt (stable tool prefix, exact accepted definition); the
|
|
121
|
+
* next accepted logical turn resolves the newly enabled tool.
|
|
122
|
+
*/
|
|
123
|
+
export declare function resolveAcceptedTurnModel(runtime: Pick<OpenGeniRuntime, "resolveTurnModel">, settings: Settings, policy: TurnExecutionPolicyV1): ReturnType<OpenGeniRuntime["resolveTurnModel"]>;
|
|
115
124
|
/**
|
|
116
125
|
* Native web search is a runtime capability, not part of the session's MCP
|
|
117
126
|
* allow-list. Attach it whenever the resolved provider advertises runnable
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { AttemptToolDefinition } from "@opengeni/codemode";
|
|
2
|
+
import { type WebSearchProviderToolName, type WebSearchSettings } from "@opengeni/config";
|
|
3
|
+
import { type WebSearchBilling, type WebSearchCallScope } from "@opengeni/core";
|
|
4
|
+
import type { Observability } from "@opengeni/observability";
|
|
5
|
+
/**
|
|
6
|
+
* Which web search one turn gets: the provider's hosted tool, Opengeni's
|
|
7
|
+
* provider tools, or neither. Tool preparation and agent construction both
|
|
8
|
+
* call this with the same accepted model and settings, so they agree.
|
|
9
|
+
*/
|
|
10
|
+
export declare function turnWebSearchPlan(resolvedModel: {
|
|
11
|
+
configured: {
|
|
12
|
+
hostedWebSearch: boolean;
|
|
13
|
+
};
|
|
14
|
+
provider: {
|
|
15
|
+
kind?: string;
|
|
16
|
+
};
|
|
17
|
+
} | null, settings: WebSearchSettings): {
|
|
18
|
+
hostedWebSearch: boolean;
|
|
19
|
+
providerTools: WebSearchProviderToolName[];
|
|
20
|
+
};
|
|
21
|
+
/**
|
|
22
|
+
* The `web_search` and `web_fetch` attempt tools for one turn. The caller
|
|
23
|
+
* decides which names the turn gets ({@link webSearchToolPlan}); this only
|
|
24
|
+
* builds them. Provider keys stay in the worker and never reach a sandbox.
|
|
25
|
+
*/
|
|
26
|
+
export declare function webSearchToolDefinitions(input: {
|
|
27
|
+
settings: WebSearchSettings;
|
|
28
|
+
tools: readonly WebSearchProviderToolName[];
|
|
29
|
+
scope: WebSearchCallScope;
|
|
30
|
+
billing: WebSearchBilling;
|
|
31
|
+
observability: Pick<Observability, "warn">;
|
|
32
|
+
fetch?: typeof fetch;
|
|
33
|
+
}): AttemptToolDefinition[];
|
|
@@ -8,3 +8,20 @@ export declare function programmaticApproval(operation: CodemodeOperation): {
|
|
|
8
8
|
requestId: string | undefined;
|
|
9
9
|
};
|
|
10
10
|
export declare function programmaticContinuationNote(operations: readonly CodemodeOperation[]): string | undefined;
|
|
11
|
+
/**
|
|
12
|
+
* Recover committed programmatic approval waits/results before the first model
|
|
13
|
+
* request without turning lazy MCP preparation into a first-request barrier.
|
|
14
|
+
*
|
|
15
|
+
* Only eager servers may gate the first request. Resuming a stored operation
|
|
16
|
+
* needs the prepared attempt tool environment, so this waits for full tool
|
|
17
|
+
* preparation only when there is something to resume: an approval decision
|
|
18
|
+
* trigger, or a cheap durable read showing unfinished operations for this
|
|
19
|
+
* logical turn (which covers every recovery that has stored work). Every other
|
|
20
|
+
* turn sends its first request without waiting on any lazy server.
|
|
21
|
+
*/
|
|
22
|
+
export declare function recoverProgrammaticOperationsBeforeFirstRequest(input: {
|
|
23
|
+
approvalDecisionId: string | undefined;
|
|
24
|
+
hasUnfinishedOperations: () => Promise<boolean>;
|
|
25
|
+
toolPreparationReady: Promise<void> | null;
|
|
26
|
+
resumeApproved: (decisionOperationId: string | undefined) => Promise<CodemodeOperation[]> | undefined;
|
|
27
|
+
}): Promise<CodemodeOperation[]>;
|
|
@@ -34,7 +34,7 @@ import {
|
|
|
34
34
|
warnDrainSnapshotFailure,
|
|
35
35
|
withFirstPartyTools,
|
|
36
36
|
workflowIdForSession
|
|
37
|
-
} from "./chunk-
|
|
37
|
+
} from "./chunk-BMTWULF7.js";
|
|
38
38
|
import {
|
|
39
39
|
inspectOpenSandboxKubernetesInventory,
|
|
40
40
|
recordActiveUserGauges,
|
|
@@ -62,7 +62,7 @@ import {
|
|
|
62
62
|
recordVerifiedSignupTrialSwitchGauge,
|
|
63
63
|
recordWorkerDeathRecoveryMetrics,
|
|
64
64
|
runtimeMetricsHooksForObservability
|
|
65
|
-
} from "./chunk-
|
|
65
|
+
} from "./chunk-FF4HPY7L.js";
|
|
66
66
|
import "./chunk-PZ5AY32C.js";
|
|
67
67
|
|
|
68
68
|
// src/activities/knowledge-indexing.ts
|
|
@@ -8813,4 +8813,4 @@ export {
|
|
|
8813
8813
|
createControlActivities,
|
|
8814
8814
|
createControlActivitiesFromServices
|
|
8815
8815
|
};
|
|
8816
|
-
//# sourceMappingURL=activities-control-
|
|
8816
|
+
//# sourceMappingURL=activities-control-D5KVEPHI.js.map
|
|
@@ -99,7 +99,7 @@ import {
|
|
|
99
99
|
withFirstPartyTools,
|
|
100
100
|
wrapLazyTurnBoxWithRouting,
|
|
101
101
|
wrapTurnBoxWithRouting
|
|
102
|
-
} from "./chunk-
|
|
102
|
+
} from "./chunk-BMTWULF7.js";
|
|
103
103
|
import {
|
|
104
104
|
StreamTimingMetrics,
|
|
105
105
|
makeMachineOpObserver,
|
|
@@ -132,7 +132,7 @@ import {
|
|
|
132
132
|
runtimeMetricsHooksForObservability,
|
|
133
133
|
sandboxAutomaticRecoveryOutcome,
|
|
134
134
|
turnLifecycleMetricsFor
|
|
135
|
-
} from "./chunk-
|
|
135
|
+
} from "./chunk-FF4HPY7L.js";
|
|
136
136
|
import {
|
|
137
137
|
__export
|
|
138
138
|
} from "./chunk-PZ5AY32C.js";
|
|
@@ -1193,12 +1193,14 @@ import {
|
|
|
1193
1193
|
} from "@opengeni/db";
|
|
1194
1194
|
|
|
1195
1195
|
// src/activities/agent-turn/subscription-lease.ts
|
|
1196
|
+
var HEARTBEAT_INTERVAL_MS = 6e4;
|
|
1196
1197
|
var SubscriptionTurnLease = class {
|
|
1197
1198
|
constructor(leaseDeps) {
|
|
1198
1199
|
this.leaseDeps = leaseDeps;
|
|
1199
1200
|
if (!Number.isFinite(leaseDeps.ttlMs) || leaseDeps.ttlMs <= 0)
|
|
1200
1201
|
throw new Error("Subscription lease TTL must be positive");
|
|
1201
1202
|
this.now = leaseDeps.now ?? (() => performance.now());
|
|
1203
|
+
this.renewalIntervalMs = Math.min(HEARTBEAT_INTERVAL_MS, leaseDeps.ttlMs / 5);
|
|
1202
1204
|
}
|
|
1203
1205
|
held = false;
|
|
1204
1206
|
lost = false;
|
|
@@ -1209,6 +1211,7 @@ var SubscriptionTurnLease = class {
|
|
|
1209
1211
|
heartbeatInFlight = false;
|
|
1210
1212
|
heartbeatTimer;
|
|
1211
1213
|
now;
|
|
1214
|
+
renewalIntervalMs;
|
|
1212
1215
|
expired = (deadline) => deadline === null || !Number.isFinite(deadline) || this.now() >= deadline;
|
|
1213
1216
|
markLost = (reason) => {
|
|
1214
1217
|
if (this.lost) return;
|
|
@@ -1231,6 +1234,8 @@ var SubscriptionTurnLease = class {
|
|
|
1231
1234
|
return;
|
|
1232
1235
|
}
|
|
1233
1236
|
if (this.heartbeatInFlight) return;
|
|
1237
|
+
const renewAt = this.confirmedUntilMs - this.leaseDeps.ttlMs + this.renewalIntervalMs;
|
|
1238
|
+
if (this.now() < renewAt) return;
|
|
1234
1239
|
this.heartbeatInFlight = true;
|
|
1235
1240
|
const priorDeadline = this.confirmedUntilMs;
|
|
1236
1241
|
const startedAt = this.now();
|
|
@@ -1257,7 +1262,7 @@ var SubscriptionTurnLease = class {
|
|
|
1257
1262
|
};
|
|
1258
1263
|
startHeartbeat = () => {
|
|
1259
1264
|
if (!this.leaseDeps.getTurnId() || this.heartbeatTimer) return;
|
|
1260
|
-
this.heartbeatTimer = setInterval(() => void this.renew("timer"),
|
|
1265
|
+
this.heartbeatTimer = setInterval(() => void this.renew("timer"), HEARTBEAT_INTERVAL_MS);
|
|
1261
1266
|
this.heartbeatTimer.unref?.();
|
|
1262
1267
|
};
|
|
1263
1268
|
stopHeartbeat = () => {
|
|
@@ -8101,6 +8106,13 @@ function programmaticContinuationNote(operations) {
|
|
|
8101
8106
|
"Approval resumes the stored operation, not the earlier program's JavaScript stack. Read results with the current Codemode client's status/resume handle. Do not resubmit arguments for completed, running, waiting, or uncertain operations."
|
|
8102
8107
|
].join("\n");
|
|
8103
8108
|
}
|
|
8109
|
+
async function recoverProgrammaticOperationsBeforeFirstRequest(input) {
|
|
8110
|
+
if (input.approvalDecisionId === void 0 && !await input.hasUnfinishedOperations()) {
|
|
8111
|
+
return [];
|
|
8112
|
+
}
|
|
8113
|
+
await input.toolPreparationReady;
|
|
8114
|
+
return await input.resumeApproved(input.approvalDecisionId) ?? [];
|
|
8115
|
+
}
|
|
8104
8116
|
|
|
8105
8117
|
// src/activities/agent-turn/turn-sandbox-access.ts
|
|
8106
8118
|
function ownedTurnSandboxForAgent(sandboxState) {
|
|
@@ -10251,11 +10263,33 @@ async function runTurnStreamAttempt(deps) {
|
|
|
10251
10263
|
control.activityStatus = "idle";
|
|
10252
10264
|
return claimedResult({ status: "idle" });
|
|
10253
10265
|
};
|
|
10254
|
-
|
|
10255
|
-
|
|
10256
|
-
|
|
10257
|
-
trigger.type === "user.approvalDecision" ? trigger.payload.approvalId : void 0
|
|
10258
|
-
|
|
10266
|
+
const programmaticRecoveryStartedAt = performance.now();
|
|
10267
|
+
let programmaticRecoveryOutcome = "failed";
|
|
10268
|
+
const codemodeOperations = await recoverProgrammaticOperationsBeforeFirstRequest({
|
|
10269
|
+
approvalDecisionId: trigger.type === "user.approvalDecision" ? trigger.payload.approvalId : void 0,
|
|
10270
|
+
hasUnfinishedOperations: async () => (await listTurnCodemodeApprovals(db, {
|
|
10271
|
+
accountId: input.accountId,
|
|
10272
|
+
workspaceId: input.workspaceId,
|
|
10273
|
+
sessionId: input.sessionId,
|
|
10274
|
+
turnId: activeTurnId
|
|
10275
|
+
})).length > 0,
|
|
10276
|
+
toolPreparationReady: eventing.toolPreparationReady,
|
|
10277
|
+
resumeApproved: (decisionOperationId) => eventing.codemodeDispatcher?.resumeApproved(
|
|
10278
|
+
`sandbox:${input.attemptId}`,
|
|
10279
|
+
decisionOperationId
|
|
10280
|
+
)
|
|
10281
|
+
}).then((operations) => {
|
|
10282
|
+
programmaticRecoveryOutcome = "completed";
|
|
10283
|
+
return operations;
|
|
10284
|
+
}).finally(() => {
|
|
10285
|
+
recordTurnStartupPhase(observability, {
|
|
10286
|
+
phase: "programmatic_operation_recovery",
|
|
10287
|
+
provider: turnExecutionPolicy.providerId,
|
|
10288
|
+
backend: activeSandboxBackend ?? groupBoxBackend,
|
|
10289
|
+
outcome: programmaticRecoveryOutcome,
|
|
10290
|
+
durationSeconds: (performance.now() - programmaticRecoveryStartedAt) / 1e3
|
|
10291
|
+
});
|
|
10292
|
+
});
|
|
10259
10293
|
codemodeContinuationNote = programmaticContinuationNote(codemodeOperations);
|
|
10260
10294
|
programmaticApprovalAcknowledged = trigger.type === "user.approvalDecision" && codemodeOperations.some(
|
|
10261
10295
|
(operation) => operation.operationId === trigger.payload.approvalId
|
|
@@ -12247,6 +12281,7 @@ import {
|
|
|
12247
12281
|
desktopCapableBackend
|
|
12248
12282
|
} from "@opengeni/runtime";
|
|
12249
12283
|
import {
|
|
12284
|
+
configuredModelForAcceptedTurnExecutionPolicy,
|
|
12250
12285
|
isDirectOpenAiApiBaseUrl
|
|
12251
12286
|
} from "@opengeni/config";
|
|
12252
12287
|
|
|
@@ -12523,6 +12558,16 @@ function shouldDeferNonEagerToolPreparation(args) {
|
|
|
12523
12558
|
args.lazyToolTransport && args.progressiveDisclosureEnabled && args.triggerKind === "next" && (args.triggerType === "user.message" || args.triggerType === "system.update.delivered")
|
|
12524
12559
|
);
|
|
12525
12560
|
}
|
|
12561
|
+
function resolveAcceptedTurnModel(runtime, settings, policy) {
|
|
12562
|
+
const current = runtime.resolveTurnModel(settings, policy.productModelId);
|
|
12563
|
+
if (!current) return null;
|
|
12564
|
+
const configured = configuredModelForAcceptedTurnExecutionPolicy(
|
|
12565
|
+
current.configured,
|
|
12566
|
+
current.provider,
|
|
12567
|
+
policy
|
|
12568
|
+
);
|
|
12569
|
+
return configured === current.configured ? current : { ...current, configured };
|
|
12570
|
+
}
|
|
12526
12571
|
function hostedWebSearchForTurn(resolvedModel, deploymentWebSearchEnabled) {
|
|
12527
12572
|
return resolvedModel?.configured.hostedWebSearch ?? deploymentWebSearchEnabled;
|
|
12528
12573
|
}
|
|
@@ -12713,10 +12758,7 @@ async function prepareGovernanceAndModel(deps) {
|
|
|
12713
12758
|
baseRunSettings
|
|
12714
12759
|
)
|
|
12715
12760
|
);
|
|
12716
|
-
const resolvedModel = runtime
|
|
12717
|
-
capabilitySettings,
|
|
12718
|
-
turnExecutionPolicy.productModelId
|
|
12719
|
-
);
|
|
12761
|
+
const resolvedModel = resolveAcceptedTurnModel(runtime, capabilitySettings, turnExecutionPolicy);
|
|
12720
12762
|
const providerApi = resolvedModel?.provider.api ?? "responses";
|
|
12721
12763
|
const nativeImageProviderBinding = providerApi === "responses" ? openAiHostedImageProviderBindingForTurn(capabilitySettings, resolvedModel) : null;
|
|
12722
12764
|
const lazyToolTransport = lazyToolTransportForTurn(resolvedModel);
|
|
@@ -13476,6 +13518,7 @@ import {
|
|
|
13476
13518
|
readLease as readLease2,
|
|
13477
13519
|
accrueWarmSeconds,
|
|
13478
13520
|
SandboxWorkspaceMutationFencedError,
|
|
13521
|
+
SandboxWorkspaceMutationOutputRejectedError,
|
|
13479
13522
|
retainWorkspaceMutationProcess,
|
|
13480
13523
|
retainedProviderCommandPersistence,
|
|
13481
13524
|
SandboxRetainedProcessPromotionFencedError
|
|
@@ -13483,6 +13526,7 @@ import {
|
|
|
13483
13526
|
import { createProviderCommandRetainer } from "@opengeni/db/retained-provider-commands";
|
|
13484
13527
|
import {
|
|
13485
13528
|
RoutingMutationOutcomeUnknownError,
|
|
13529
|
+
RoutingMutationOutputRejectedError,
|
|
13486
13530
|
ProviderCommandStartOutcomeUnknownError,
|
|
13487
13531
|
ProviderCommandObservationUnavailableError,
|
|
13488
13532
|
isModalCommandStartOutcomeUnknownError as isModalCommandStartOutcomeUnknownError2,
|
|
@@ -13895,6 +13939,17 @@ function createSandboxTurnRuntime(deps) {
|
|
|
13895
13939
|
try {
|
|
13896
13940
|
await settleMutation("resolved");
|
|
13897
13941
|
} catch (settlementError) {
|
|
13942
|
+
if (settlementError instanceof SandboxWorkspaceMutationOutputRejectedError && settlementError.matchesPhysicalSettlement({
|
|
13943
|
+
accountId: identity.accountId,
|
|
13944
|
+
workspaceId: identity.workspaceId,
|
|
13945
|
+
admission,
|
|
13946
|
+
operation,
|
|
13947
|
+
outcome: "resolved"
|
|
13948
|
+
})) {
|
|
13949
|
+
throw new RoutingMutationOutputRejectedError(operation, settlementError.code, {
|
|
13950
|
+
cause: settlementError
|
|
13951
|
+
});
|
|
13952
|
+
}
|
|
13898
13953
|
throw new RoutingMutationOutcomeUnknownError(
|
|
13899
13954
|
operation,
|
|
13900
13955
|
`Platform workspace mutation "${operation}" returned from the provider but lost its durable settlement fence; its outcome is unknown and it was not replayed`,
|
|
@@ -32769,7 +32824,8 @@ import {
|
|
|
32769
32824
|
} from "@opengeni/runtime";
|
|
32770
32825
|
import {
|
|
32771
32826
|
ChannelAPartialMutationError as ChannelAPartialMutationError2,
|
|
32772
|
-
RoutingMutationOutcomeUnknownError as RoutingMutationOutcomeUnknownError2
|
|
32827
|
+
RoutingMutationOutcomeUnknownError as RoutingMutationOutcomeUnknownError2,
|
|
32828
|
+
isRoutingMutationOutputRejectedError
|
|
32773
32829
|
} from "@opengeni/runtime/sandbox";
|
|
32774
32830
|
import { connectorAttachmentSandboxPath as connectorAttachmentSandboxPath2 } from "@opengeni/runtime";
|
|
32775
32831
|
var ConnectorAttachmentMaterializationError = class extends Error {
|
|
@@ -32878,7 +32934,7 @@ async function materializeConnectorAttachmentsInChannel(channel, request, option
|
|
|
32878
32934
|
attachments: receipts
|
|
32879
32935
|
});
|
|
32880
32936
|
} catch (error51) {
|
|
32881
|
-
if (error51 instanceof ChannelAPartialMutationError2 || error51 instanceof RoutingMutationOutcomeUnknownError2) {
|
|
32937
|
+
if (error51 instanceof ChannelAPartialMutationError2 || error51 instanceof RoutingMutationOutcomeUnknownError2 || isRoutingMutationOutputRejectedError(error51)) {
|
|
32882
32938
|
throw error51;
|
|
32883
32939
|
}
|
|
32884
32940
|
throw new ConnectorAttachmentMaterializationError();
|
|
@@ -33492,7 +33548,8 @@ import {
|
|
|
33492
33548
|
resolveTurnToolPolicy,
|
|
33493
33549
|
scheduledTurnMcpServerIds,
|
|
33494
33550
|
hasPermission as hasPermission2,
|
|
33495
|
-
requireExplicitPermissionDelegation
|
|
33551
|
+
requireExplicitPermissionDelegation,
|
|
33552
|
+
createWebSearchBilling
|
|
33496
33553
|
} from "@opengeni/core";
|
|
33497
33554
|
import { SandboxChannelAService as SandboxChannelAService3 } from "@opengeni/runtime/sandbox";
|
|
33498
33555
|
import { sandboxRunAs as sandboxRunAs4 } from "@opengeni/runtime";
|
|
@@ -33814,6 +33871,200 @@ function codeSearchToolDefinitions(input) {
|
|
|
33814
33871
|
];
|
|
33815
33872
|
}
|
|
33816
33873
|
|
|
33874
|
+
// src/activities/agent-turn/web-search.ts
|
|
33875
|
+
import {
|
|
33876
|
+
WEB_FETCH_TOOL_NAME,
|
|
33877
|
+
WEB_SEARCH_TOOL_NAME,
|
|
33878
|
+
webSearchCallPricing,
|
|
33879
|
+
webSearchCreditMicros,
|
|
33880
|
+
webSearchProviderConfig,
|
|
33881
|
+
webSearchToolPlan
|
|
33882
|
+
} from "@opengeni/config";
|
|
33883
|
+
import {
|
|
33884
|
+
WebSearchBillingRefusedError
|
|
33885
|
+
} from "@opengeni/core";
|
|
33886
|
+
import {
|
|
33887
|
+
WEB_FETCH_TOOL_DESCRIPTION,
|
|
33888
|
+
WEB_FETCH_RETAINED_MAX_CHARS,
|
|
33889
|
+
WEB_SEARCH_TOOL_DESCRIPTION,
|
|
33890
|
+
WebSearchProviderError,
|
|
33891
|
+
WebToolArgumentError,
|
|
33892
|
+
createWebFetchProvider,
|
|
33893
|
+
createWebSearchProvider,
|
|
33894
|
+
parseWebFetchArguments,
|
|
33895
|
+
parseWebSearchArguments,
|
|
33896
|
+
renderWebPageWindow,
|
|
33897
|
+
renderWebSearchResults,
|
|
33898
|
+
webFetchInputSchema,
|
|
33899
|
+
webSearchInputSchema
|
|
33900
|
+
} from "@opengeni/runtime/web-search";
|
|
33901
|
+
function turnWebSearchPlan(resolvedModel, settings) {
|
|
33902
|
+
return webSearchToolPlan(settings, {
|
|
33903
|
+
hostedWebSearch: hostedWebSearchForTurn(resolvedModel, settings.webSearchEnabled),
|
|
33904
|
+
// SuperGrok's native search is added by its transport, not as an agent
|
|
33905
|
+
// tool, so provider tools would only duplicate it.
|
|
33906
|
+
transportHostedSearch: resolvedModel?.provider.kind === "xai-subscription"
|
|
33907
|
+
});
|
|
33908
|
+
}
|
|
33909
|
+
var PAGE_CACHE_ENTRIES = 16;
|
|
33910
|
+
function textResult2(text, isError) {
|
|
33911
|
+
return { isError, content: [{ type: "text", text }] };
|
|
33912
|
+
}
|
|
33913
|
+
function settledCost(operationId, operation, provider, pricing, reportedCostMicros) {
|
|
33914
|
+
const basis = pricing.explicit ? "configured_price" : reportedCostMicros !== void 0 ? "provider_reported" : "list_price";
|
|
33915
|
+
const providerMicros = basis === "provider_reported" ? reportedCostMicros : pricing.providerMicros;
|
|
33916
|
+
return {
|
|
33917
|
+
operationId,
|
|
33918
|
+
operation,
|
|
33919
|
+
provider,
|
|
33920
|
+
providerMicros,
|
|
33921
|
+
creditMicros: webSearchCreditMicros(providerMicros, pricing.marginBps),
|
|
33922
|
+
marginBps: pricing.marginBps,
|
|
33923
|
+
basis
|
|
33924
|
+
};
|
|
33925
|
+
}
|
|
33926
|
+
function providerFailure(error51) {
|
|
33927
|
+
return `${error51.message}${error51.retryable ? ". You may retry shortly." : "."}`;
|
|
33928
|
+
}
|
|
33929
|
+
function webSearchToolDefinitions(input) {
|
|
33930
|
+
const config2 = webSearchProviderConfig(input.settings);
|
|
33931
|
+
if (!config2 || input.tools.length === 0) return [];
|
|
33932
|
+
const adapterInput = {
|
|
33933
|
+
timeoutMs: config2.timeoutMs,
|
|
33934
|
+
...input.fetch ? { fetch: input.fetch } : {}
|
|
33935
|
+
};
|
|
33936
|
+
const settle = async (cost) => {
|
|
33937
|
+
try {
|
|
33938
|
+
await input.billing.settle(input.scope, cost);
|
|
33939
|
+
} catch (error51) {
|
|
33940
|
+
input.observability.warn("web search usage settlement failed", {
|
|
33941
|
+
operation: cost.operation,
|
|
33942
|
+
provider: cost.provider,
|
|
33943
|
+
error: error51 instanceof Error ? error51.message : String(error51)
|
|
33944
|
+
});
|
|
33945
|
+
}
|
|
33946
|
+
};
|
|
33947
|
+
const definitions = [];
|
|
33948
|
+
if (input.tools.includes(WEB_SEARCH_TOOL_NAME)) {
|
|
33949
|
+
const provider = createWebSearchProvider({ ...adapterInput, endpoint: config2.search });
|
|
33950
|
+
const pricing = webSearchCallPricing(config2, "search");
|
|
33951
|
+
definitions.push({
|
|
33952
|
+
identity: { serverId: "opengeni", toolName: WEB_SEARCH_TOOL_NAME },
|
|
33953
|
+
modelName: WEB_SEARCH_TOOL_NAME,
|
|
33954
|
+
codemodePath: ["opengeni", WEB_SEARCH_TOOL_NAME],
|
|
33955
|
+
title: "Search the web",
|
|
33956
|
+
description: WEB_SEARCH_TOOL_DESCRIPTION,
|
|
33957
|
+
inputSchema: webSearchInputSchema,
|
|
33958
|
+
annotations: {
|
|
33959
|
+
title: "Search the web",
|
|
33960
|
+
readOnlyHint: true,
|
|
33961
|
+
destructiveHint: false,
|
|
33962
|
+
idempotentHint: true,
|
|
33963
|
+
openWorldHint: true
|
|
33964
|
+
},
|
|
33965
|
+
source: "opengeni",
|
|
33966
|
+
approval: "none",
|
|
33967
|
+
execute: async (args, context) => {
|
|
33968
|
+
let request;
|
|
33969
|
+
try {
|
|
33970
|
+
request = parseWebSearchArguments(args);
|
|
33971
|
+
await input.billing.admit(input.scope, pricing.providerMicros);
|
|
33972
|
+
} catch (error51) {
|
|
33973
|
+
if (error51 instanceof WebToolArgumentError || error51 instanceof WebSearchBillingRefusedError)
|
|
33974
|
+
return textResult2(error51.message, true);
|
|
33975
|
+
throw error51;
|
|
33976
|
+
}
|
|
33977
|
+
try {
|
|
33978
|
+
const response = await provider.search(request, { signal: context.signal });
|
|
33979
|
+
await settle(
|
|
33980
|
+
settledCost(
|
|
33981
|
+
context.operationId,
|
|
33982
|
+
"search",
|
|
33983
|
+
config2.search.provider,
|
|
33984
|
+
pricing,
|
|
33985
|
+
response.reportedCostMicros
|
|
33986
|
+
)
|
|
33987
|
+
);
|
|
33988
|
+
return textResult2(renderWebSearchResults(request.query, response.results), false);
|
|
33989
|
+
} catch (error51) {
|
|
33990
|
+
if (context.signal?.aborted) throw error51;
|
|
33991
|
+
if (error51 instanceof WebSearchProviderError) {
|
|
33992
|
+
return textResult2(`Web search failed: ${providerFailure(error51)}`, true);
|
|
33993
|
+
}
|
|
33994
|
+
throw error51;
|
|
33995
|
+
}
|
|
33996
|
+
}
|
|
33997
|
+
});
|
|
33998
|
+
}
|
|
33999
|
+
if (input.tools.includes(WEB_FETCH_TOOL_NAME) && config2.fetch) {
|
|
34000
|
+
const fetchEndpoint = config2.fetch;
|
|
34001
|
+
const provider = createWebFetchProvider({ ...adapterInput, endpoint: fetchEndpoint });
|
|
34002
|
+
const pricing = webSearchCallPricing(config2, "fetch");
|
|
34003
|
+
const pages = /* @__PURE__ */ new Map();
|
|
34004
|
+
definitions.push({
|
|
34005
|
+
identity: { serverId: "opengeni", toolName: WEB_FETCH_TOOL_NAME },
|
|
34006
|
+
modelName: WEB_FETCH_TOOL_NAME,
|
|
34007
|
+
codemodePath: ["opengeni", WEB_FETCH_TOOL_NAME],
|
|
34008
|
+
title: "Read a web page",
|
|
34009
|
+
description: WEB_FETCH_TOOL_DESCRIPTION,
|
|
34010
|
+
inputSchema: webFetchInputSchema,
|
|
34011
|
+
annotations: {
|
|
34012
|
+
title: "Read a web page",
|
|
34013
|
+
readOnlyHint: true,
|
|
34014
|
+
destructiveHint: false,
|
|
34015
|
+
idempotentHint: true,
|
|
34016
|
+
openWorldHint: true
|
|
34017
|
+
},
|
|
34018
|
+
source: "opengeni",
|
|
34019
|
+
approval: "none",
|
|
34020
|
+
execute: async (args, context) => {
|
|
34021
|
+
let request;
|
|
34022
|
+
try {
|
|
34023
|
+
request = parseWebFetchArguments(args);
|
|
34024
|
+
} catch (error51) {
|
|
34025
|
+
if (error51 instanceof WebToolArgumentError) return textResult2(error51.message, true);
|
|
34026
|
+
throw error51;
|
|
34027
|
+
}
|
|
34028
|
+
const cached2 = pages.get(request.url);
|
|
34029
|
+
if (cached2) return textResult2(renderWebPageWindow(cached2, request), false);
|
|
34030
|
+
try {
|
|
34031
|
+
await input.billing.admit(input.scope, pricing.providerMicros);
|
|
34032
|
+
} catch (error51) {
|
|
34033
|
+
if (error51 instanceof WebSearchBillingRefusedError) return textResult2(error51.message, true);
|
|
34034
|
+
throw error51;
|
|
34035
|
+
}
|
|
34036
|
+
try {
|
|
34037
|
+
const page = await provider.fetch({ url: request.url }, { signal: context.signal });
|
|
34038
|
+
await settle(
|
|
34039
|
+
settledCost(
|
|
34040
|
+
context.operationId,
|
|
34041
|
+
"fetch",
|
|
34042
|
+
fetchEndpoint.provider,
|
|
34043
|
+
pricing,
|
|
34044
|
+
page.reportedCostMicros
|
|
34045
|
+
)
|
|
34046
|
+
);
|
|
34047
|
+
if (pages.size >= PAGE_CACHE_ENTRIES) {
|
|
34048
|
+
pages.delete(pages.keys().next().value);
|
|
34049
|
+
}
|
|
34050
|
+
pages.set(request.url, {
|
|
34051
|
+
...page,
|
|
34052
|
+
content: page.content.slice(0, WEB_FETCH_RETAINED_MAX_CHARS + 1)
|
|
34053
|
+
});
|
|
34054
|
+
return textResult2(renderWebPageWindow(page, request), false);
|
|
34055
|
+
} catch (error51) {
|
|
34056
|
+
if (context.signal?.aborted) throw error51;
|
|
34057
|
+
if (error51 instanceof WebSearchProviderError) {
|
|
34058
|
+
return textResult2(`Web fetch failed: ${providerFailure(error51)}`, true);
|
|
34059
|
+
}
|
|
34060
|
+
throw error51;
|
|
34061
|
+
}
|
|
34062
|
+
}
|
|
34063
|
+
});
|
|
34064
|
+
}
|
|
34065
|
+
return definitions;
|
|
34066
|
+
}
|
|
34067
|
+
|
|
33817
34068
|
// src/activities/agent-turn/skill-tools.ts
|
|
33818
34069
|
import { createHash as createHash13 } from "crypto";
|
|
33819
34070
|
import {
|
|
@@ -33983,14 +34234,14 @@ async function readResult(files, identity, args, context, activeHistory) {
|
|
|
33983
34234
|
if (args.listFiles === true) {
|
|
33984
34235
|
return {
|
|
33985
34236
|
kind: "list",
|
|
33986
|
-
result:
|
|
34237
|
+
result: textResult3({ ...identity, ...listSkillPaths(files, PORTABLE_SKILL_MAX_FILES) })
|
|
33987
34238
|
};
|
|
33988
34239
|
}
|
|
33989
34240
|
const selected = readSkillFiles(files, args.paths);
|
|
33990
34241
|
if (args.paths === void 0 && context.caller.kind === "model" && activeHistory && await inActiveHistory(activeHistory, identity, selected.files[0])) {
|
|
33991
34242
|
return {
|
|
33992
34243
|
kind: "already_in_context",
|
|
33993
|
-
result:
|
|
34244
|
+
result: textResult3({
|
|
33994
34245
|
...identity,
|
|
33995
34246
|
alreadyInContext: true,
|
|
33996
34247
|
message: `Already in context: SKILL.md of ${JSON.stringify(args.skill)}${identity.revisionId ? ` revision ${identity.revisionId}` : ""} was returned earlier in this conversation and is unchanged. Use that copy. Re-read only if you need a fresh copy: call skill_read with paths ["SKILL.md"].`
|
|
@@ -33998,12 +34249,12 @@ async function readResult(files, identity, args, context, activeHistory) {
|
|
|
33998
34249
|
};
|
|
33999
34250
|
}
|
|
34000
34251
|
if (args.paths !== void 0) {
|
|
34001
|
-
return { kind: "files", result:
|
|
34252
|
+
return { kind: "files", result: textResult3({ ...identity, ...selected }) };
|
|
34002
34253
|
}
|
|
34003
34254
|
const scripts = skillScriptIndex(files);
|
|
34004
34255
|
return {
|
|
34005
34256
|
kind: "full",
|
|
34006
|
-
result:
|
|
34257
|
+
result: textResult3({ ...identity, ...selected, ...scripts ?? {} })
|
|
34007
34258
|
};
|
|
34008
34259
|
}
|
|
34009
34260
|
function observe(telemetry, read) {
|
|
@@ -34040,7 +34291,7 @@ function withSkillUse(read, origin, identity, telemetry) {
|
|
|
34040
34291
|
return read.result;
|
|
34041
34292
|
}
|
|
34042
34293
|
}
|
|
34043
|
-
function
|
|
34294
|
+
function textResult3(output) {
|
|
34044
34295
|
return {
|
|
34045
34296
|
isError: false,
|
|
34046
34297
|
content: [{ type: "text", text: JSON.stringify(output) }],
|
|
@@ -35504,6 +35755,19 @@ async function prepareTurnToolRuntime(deps) {
|
|
|
35504
35755
|
const attemptToolFamilies = resolveAgentToolFamilies(session.agent, {
|
|
35505
35756
|
hasSkills: skillCatalog.length > 0
|
|
35506
35757
|
});
|
|
35758
|
+
const webSearchTools = webSearchToolDefinitions({
|
|
35759
|
+
settings: runSettings,
|
|
35760
|
+
tools: turnWebSearchPlan(resolvedModel, runSettings).providerTools,
|
|
35761
|
+
scope: {
|
|
35762
|
+
accountId: input.accountId,
|
|
35763
|
+
workspaceId: input.workspaceId,
|
|
35764
|
+
sessionId: input.sessionId,
|
|
35765
|
+
turnId: turn.id,
|
|
35766
|
+
attemptId: input.attemptId
|
|
35767
|
+
},
|
|
35768
|
+
billing: createWebSearchBilling({ db, settings: runSettings }),
|
|
35769
|
+
observability
|
|
35770
|
+
});
|
|
35507
35771
|
const attemptToolDefinitions = [
|
|
35508
35772
|
...operationReadStore ? [
|
|
35509
35773
|
createOperationReadAttemptToolDefinition({
|
|
@@ -35582,7 +35846,8 @@ async function prepareTurnToolRuntime(deps) {
|
|
|
35582
35846
|
...interactionInterventionResume ? { interventionResume: interactionInterventionResume } : {}
|
|
35583
35847
|
}),
|
|
35584
35848
|
...googleDrivePublicationTool && googleDrivePublicationAllowed ? [googleDrivePublicationTool] : [],
|
|
35585
|
-
...codeSearchTools
|
|
35849
|
+
...codeSearchTools,
|
|
35850
|
+
...webSearchTools
|
|
35586
35851
|
].filter((tool) => attemptToolFamilies.allowsFunctionTool(tool.modelName));
|
|
35587
35852
|
recordTurnStartupPhase(observability, {
|
|
35588
35853
|
phase: "tool_context_preparation",
|
|
@@ -37401,7 +37666,7 @@ async function buildTurnAgent(deps) {
|
|
|
37401
37666
|
variableNames: Object.keys(workspaceVariableSet.values)
|
|
37402
37667
|
}
|
|
37403
37668
|
} : {};
|
|
37404
|
-
const hostedWebSearch =
|
|
37669
|
+
const hostedWebSearch = turnWebSearchPlan(resolvedModel, runSettings).hostedWebSearch;
|
|
37405
37670
|
const resolveImageReferences = async (references) => await resolveImageGenerationReferencesForTool({
|
|
37406
37671
|
db,
|
|
37407
37672
|
objectStorage,
|
|
@@ -40683,4 +40948,4 @@ export {
|
|
|
40683
40948
|
createTurnActivities,
|
|
40684
40949
|
createTurnActivitiesFromServices
|
|
40685
40950
|
};
|
|
40686
|
-
//# sourceMappingURL=activities-turn-
|
|
40951
|
+
//# sourceMappingURL=activities-turn-4Z3M7Z3F.js.map
|