@opengeni/worker-bundle 2.0.1 → 2.0.3-canary.36199476632001
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/agent-build.d.ts +2 -0
- package/dist/activities/agent-turn/code-search.d.ts +60 -0
- package/dist/activities/agent-turn/codex-capacity.d.ts +13 -0
- package/dist/activities/agent-turn/errors.d.ts +12 -1
- package/dist/activities/agent-turn/failure-settlement.d.ts +1 -1
- package/dist/activities/agent-turn/governance-model.d.ts +2 -0
- package/dist/activities/agent-turn/history.d.ts +2 -0
- package/dist/activities/agent-turn/media-artifacts.d.ts +5 -3
- package/dist/activities/agent-turn/session-title.d.ts +32 -2
- package/dist/activities/agent-turn/tool-environment.d.ts +4 -0
- package/dist/activities/context-compaction.d.ts +10 -2
- package/dist/activities/knowledge-indexing.d.ts +19 -0
- package/dist/activities/retained-screenshots.d.ts +7 -2
- package/dist/activities/sandbox-lease.d.ts +3 -4
- package/dist/{activities-control-QA6OLRQY.js → activities-control-I72CRMAE.js} +283 -35
- package/dist/activities-control-I72CRMAE.js.map +1 -0
- package/dist/{activities-turn-YVVKCGAK.js → activities-turn-CSDKK4N3.js} +531 -77
- package/dist/activities-turn-CSDKK4N3.js.map +1 -0
- package/dist/artifact-outbox-entry.js +3 -0
- package/dist/artifact-outbox-entry.js.map +1 -1
- package/dist/{chunk-M3NVMF2V.js → chunk-7M6G2SCF.js} +172 -17
- package/dist/chunk-7M6G2SCF.js.map +1 -0
- package/dist/{chunk-I7HKKMUJ.js → chunk-DSPP6CZL.js} +48 -3
- package/dist/chunk-DSPP6CZL.js.map +1 -0
- package/dist/index.js +10 -5
- package/dist/index.js.map +1 -1
- package/dist/observability-metrics.d.ts +11 -1
- package/dist/sandbox-resume.d.ts +46 -0
- package/dist/workflow-bundle.js +80 -2
- package/dist/workflows/session.d.ts +30 -0
- package/package.json +20 -19
- package/src/activities/agent-turn/agent-build.ts +4 -0
- package/src/activities/agent-turn/code-search.ts +275 -0
- package/src/activities/agent-turn/codex-capacity.ts +37 -2
- package/src/activities/agent-turn/compaction-prep.ts +52 -16
- package/src/activities/agent-turn/errors.ts +67 -4
- package/src/activities/agent-turn/failure-settlement.ts +40 -8
- package/src/activities/agent-turn/governance-model.ts +17 -1
- package/src/activities/agent-turn/history.ts +14 -1
- package/src/activities/agent-turn/media-artifacts.ts +2 -1
- package/src/activities/agent-turn/run.ts +4 -0
- package/src/activities/agent-turn/sandbox-establish.ts +12 -1
- package/src/activities/agent-turn/sandbox-runtime.ts +25 -9
- package/src/activities/agent-turn/session-title.ts +73 -3
- package/src/activities/agent-turn/stream-attempt.ts +27 -15
- package/src/activities/agent-turn/tool-environment.ts +65 -0
- package/src/activities/context-compaction.ts +49 -14
- package/src/activities/knowledge-indexing.ts +240 -15
- package/src/activities/retained-screenshots.ts +82 -11
- package/src/activities/sandbox-lease.ts +141 -21
- package/src/activities/scheduled-tasks.ts +18 -2
- package/src/activity-services.ts +16 -4
- package/src/editable-artifact-hint-broker.ts +3 -0
- package/src/index.ts +2 -2
- package/src/observability-metrics.ts +70 -1
- package/src/personal-github-git-credentials.ts +2 -0
- package/src/sandbox-resume.ts +211 -5
- package/src/workflows/activities.ts +14 -1
- package/src/workflows/session.ts +102 -6
- package/dist/activities-control-QA6OLRQY.js.map +0 -1
- package/dist/activities-turn-YVVKCGAK.js.map +0 -1
- package/dist/chunk-I7HKKMUJ.js.map +0 -1
- package/dist/chunk-M3NVMF2V.js.map +0 -1
|
@@ -24,6 +24,7 @@ import {
|
|
|
24
24
|
compactionFailureReasonFromError,
|
|
25
25
|
compactionFailureTurnEventPayload,
|
|
26
26
|
computeIdleDelayMs,
|
|
27
|
+
createFreshSandboxReadinessReplacementBudget,
|
|
27
28
|
createKnowledgeSourceSyncActivities,
|
|
28
29
|
createModelHistoryAttachmentProjector,
|
|
29
30
|
createRuntimeBatcher,
|
|
@@ -86,13 +87,14 @@ import {
|
|
|
86
87
|
withFirstPartyTools,
|
|
87
88
|
wrapLazyTurnBoxWithRouting,
|
|
88
89
|
wrapTurnBoxWithRouting
|
|
89
|
-
} from "./chunk-
|
|
90
|
+
} from "./chunk-7M6G2SCF.js";
|
|
90
91
|
import {
|
|
91
92
|
StreamTimingMetrics,
|
|
92
93
|
makeMachineOpObserver,
|
|
93
94
|
modelCallAccountContext,
|
|
94
95
|
modelRequestLifecycleMetricsFor,
|
|
95
96
|
recordBatchFlush,
|
|
97
|
+
recordCodeSearchCall,
|
|
96
98
|
recordCompanyBrainContributions,
|
|
97
99
|
recordContextCompaction,
|
|
98
100
|
recordContextCompactionStarted,
|
|
@@ -113,7 +115,7 @@ import {
|
|
|
113
115
|
recordTurnWorkerPreparationTotal,
|
|
114
116
|
runtimeMetricsHooksForObservability,
|
|
115
117
|
turnLifecycleMetricsFor
|
|
116
|
-
} from "./chunk-
|
|
118
|
+
} from "./chunk-DSPP6CZL.js";
|
|
117
119
|
import {
|
|
118
120
|
__export
|
|
119
121
|
} from "./chunk-PZ5AY32C.js";
|
|
@@ -1445,11 +1447,13 @@ import {
|
|
|
1445
1447
|
COMPUTER_SCREENSHOT_RETENTION_MS,
|
|
1446
1448
|
COMPUTER_SCREENSHOT_WORKSPACE_QUOTA_BYTES,
|
|
1447
1449
|
RetainedArtifactMetadataSchema,
|
|
1448
|
-
retainedScreenshotReferenceFromFile
|
|
1450
|
+
retainedScreenshotReferenceFromFile,
|
|
1451
|
+
retainedSessionScreenshotKindFromObjectKey
|
|
1449
1452
|
} from "@opengeni/contracts";
|
|
1450
1453
|
import {
|
|
1451
1454
|
RetainedScreenshotQuotaExceededError,
|
|
1452
1455
|
getRetainedScreenshotArtifact,
|
|
1456
|
+
getRetainedScreenshotArtifactForToolCall,
|
|
1453
1457
|
isDatabasePersistenceFailure,
|
|
1454
1458
|
isSessionEventPersistenceError,
|
|
1455
1459
|
prepareRetainedScreenshotArtifact,
|
|
@@ -1554,13 +1558,16 @@ function toolOutputContainsInlineImage(output) {
|
|
|
1554
1558
|
return output.some((entry) => {
|
|
1555
1559
|
if (!entry || typeof entry !== "object" || Array.isArray(entry)) return false;
|
|
1556
1560
|
const record7 = entry;
|
|
1557
|
-
return record7.type === "input_image" && sdkImageSourceContainsInlineImage(record7.image ?? record7.image_url ?? record7.imageUrl) || record7.type === "image" &&
|
|
1561
|
+
return record7.type === "input_image" && sdkImageSourceContainsInlineImage(record7.image ?? record7.image_url ?? record7.imageUrl) || record7.type === "image" && isDeclaredInlineMcpImage(record7);
|
|
1558
1562
|
});
|
|
1559
1563
|
}
|
|
1560
1564
|
if (!output || typeof output !== "object") return false;
|
|
1561
1565
|
const record6 = output;
|
|
1562
1566
|
if (Array.isArray(record6.content)) return toolOutputContainsInlineImage(record6.content);
|
|
1563
|
-
return record6.type === "image" && sdkImageSourceContainsInlineImage(record6.image);
|
|
1567
|
+
return record6.type === "image" && (sdkImageSourceContainsInlineImage(record6.image) || isDeclaredInlineMcpImage(record6));
|
|
1568
|
+
}
|
|
1569
|
+
function isDeclaredInlineMcpImage(record6) {
|
|
1570
|
+
return typeof record6.data === "string" && typeof record6.mimeType === "string" && record6.mimeType.toLowerCase().startsWith("image/");
|
|
1564
1571
|
}
|
|
1565
1572
|
function decodeInlineMcpImage(data, mimeType) {
|
|
1566
1573
|
if (typeof data !== "string" || typeof mimeType !== "string" || !["image/png", "image/jpeg", "image/webp"].includes(mimeType)) {
|
|
@@ -1798,7 +1805,9 @@ function validateRetainableSessionImage(input, limits = {}) {
|
|
|
1798
1805
|
};
|
|
1799
1806
|
}
|
|
1800
1807
|
function retainedScreenshotIdentity(input) {
|
|
1801
|
-
const settlementKey = createHash3("sha256").update(
|
|
1808
|
+
const settlementKey = createHash3("sha256").update(
|
|
1809
|
+
input.kind === "browser_screenshot" ? "opengeni:browser-screenshot:v1\0" : "opengeni:computer-screenshot:v1\0"
|
|
1810
|
+
).update(input.sessionId).update("\0").update(input.turnId).update("\0").update(input.attemptId).update("\0").update(input.toolCallId).update("\0").update(input.toolOutputId).digest("hex");
|
|
1802
1811
|
const uuidBytes = Uint8Array.from(Buffer.from(settlementKey.slice(0, 32), "hex"));
|
|
1803
1812
|
uuidBytes[6] = uuidBytes[6] & 15 | 128;
|
|
1804
1813
|
uuidBytes[8] = uuidBytes[8] & 63 | 128;
|
|
@@ -1812,13 +1821,14 @@ function unavailableRetainedSessionImage(input) {
|
|
|
1812
1821
|
const identity = retainedScreenshotIdentity(input);
|
|
1813
1822
|
return unavailable(identity.artifactId, input.reason);
|
|
1814
1823
|
}
|
|
1815
|
-
async function
|
|
1824
|
+
async function retainSessionScreenshot(input) {
|
|
1816
1825
|
const identity = retainedScreenshotIdentity({
|
|
1817
1826
|
sessionId: input.sessionId,
|
|
1818
1827
|
turnId: input.turnId,
|
|
1819
1828
|
attemptId: input.attemptId,
|
|
1820
1829
|
toolCallId: input.output.callId,
|
|
1821
|
-
toolOutputId: input.output.toolOutputId
|
|
1830
|
+
toolOutputId: input.output.toolOutputId,
|
|
1831
|
+
kind: input.kind
|
|
1822
1832
|
});
|
|
1823
1833
|
let screenshot;
|
|
1824
1834
|
try {
|
|
@@ -1837,7 +1847,8 @@ async function retainComputerScreenshot(input) {
|
|
|
1837
1847
|
const retentionExpiresAt = new Date(
|
|
1838
1848
|
now.getTime() + (input.retentionMs ?? COMPUTER_SCREENSHOT_RETENTION_MS)
|
|
1839
1849
|
);
|
|
1840
|
-
const
|
|
1850
|
+
const objectName = input.kind === "browser_screenshot" ? "browser-screenshot" : "session-image";
|
|
1851
|
+
const objectKey = `workspaces/${input.workspaceId}/files/${identity.artifactId}/retained/${objectName}.${screenshot.extension}`;
|
|
1841
1852
|
let prepared;
|
|
1842
1853
|
try {
|
|
1843
1854
|
prepared = (await prepareRetainedScreenshotArtifact(input.db, {
|
|
@@ -1924,6 +1935,7 @@ async function retainComputerScreenshot(input) {
|
|
|
1924
1935
|
return unavailable(identity.artifactId, "pending");
|
|
1925
1936
|
}
|
|
1926
1937
|
}
|
|
1938
|
+
var retainComputerScreenshot = retainSessionScreenshot;
|
|
1927
1939
|
function compactRetainedScreenshotHistory(history, receiptsByCallId) {
|
|
1928
1940
|
if (receiptsByCallId.size === 0) return history;
|
|
1929
1941
|
return history.map((item) => {
|
|
@@ -2005,6 +2017,20 @@ async function materializeRetainedScreenshotHistory(input) {
|
|
|
2005
2017
|
}
|
|
2006
2018
|
async function materializeRetainedScreenshotHistoryWithCache(input, cache) {
|
|
2007
2019
|
const now = input.now ?? /* @__PURE__ */ new Date();
|
|
2020
|
+
const receiptForMarker = async (marker, callId) => {
|
|
2021
|
+
if (!isRetainedImageMarker(marker)) return null;
|
|
2022
|
+
const receipt = retainedReceipt(marker.artifact);
|
|
2023
|
+
if (receipt) return receipt;
|
|
2024
|
+
if (!callId) throw new Error("Retained screenshot receipt has no tool call identity");
|
|
2025
|
+
const artifact = await getRetainedScreenshotArtifactForToolCall(
|
|
2026
|
+
input.db,
|
|
2027
|
+
input.workspaceId,
|
|
2028
|
+
input.sessionId,
|
|
2029
|
+
callId
|
|
2030
|
+
);
|
|
2031
|
+
if (!artifact) throw new Error("Retained screenshot receipt cannot be recovered");
|
|
2032
|
+
return reference(artifact);
|
|
2033
|
+
};
|
|
2008
2034
|
const dataUrlForReceipt = async (receipt) => {
|
|
2009
2035
|
let dataUrl = cache.get(receipt.artifactId);
|
|
2010
2036
|
if (!dataUrl) {
|
|
@@ -2045,15 +2071,17 @@ async function materializeRetainedScreenshotHistoryWithCache(input, cache) {
|
|
|
2045
2071
|
}
|
|
2046
2072
|
return dataUrl;
|
|
2047
2073
|
};
|
|
2048
|
-
const materializeEntry = async (entry) => {
|
|
2049
|
-
const
|
|
2074
|
+
const materializeEntry = async (entry, callId) => {
|
|
2075
|
+
const image = entry && typeof entry === "object" && !Array.isArray(entry) ? entry.image : null;
|
|
2076
|
+
const receipt = await receiptForMarker(image, callId);
|
|
2050
2077
|
if (!receipt) return entry;
|
|
2051
2078
|
const dataUrl = await dataUrlForReceipt(receipt);
|
|
2052
2079
|
return { ...entry, image: dataUrl };
|
|
2053
2080
|
};
|
|
2054
2081
|
const materialized = [];
|
|
2055
2082
|
for (const item of input.history) {
|
|
2056
|
-
const
|
|
2083
|
+
const callId = historyCallId(item);
|
|
2084
|
+
const directReceipt = await receiptForMarker(item.output, callId);
|
|
2057
2085
|
if (directReceipt) {
|
|
2058
2086
|
materialized.push({
|
|
2059
2087
|
...item,
|
|
@@ -2070,7 +2098,7 @@ async function materializeRetainedScreenshotHistoryWithCache(input, cache) {
|
|
|
2070
2098
|
let changed = false;
|
|
2071
2099
|
const output = [];
|
|
2072
2100
|
for (const entry of outputEntries) {
|
|
2073
|
-
const next = await materializeEntry(entry);
|
|
2101
|
+
const next = await materializeEntry(entry, callId);
|
|
2074
2102
|
changed ||= next !== entry;
|
|
2075
2103
|
output.push(next);
|
|
2076
2104
|
}
|
|
@@ -2124,12 +2152,15 @@ function reference(artifact) {
|
|
|
2124
2152
|
if (!artifact.sessionId) {
|
|
2125
2153
|
throw new Error(`Ready retained screenshot is detached: ${artifact.artifactId}`);
|
|
2126
2154
|
}
|
|
2155
|
+
const kind = retainedSessionScreenshotKindFromObjectKey(artifact.file.objectKey);
|
|
2156
|
+
if (!kind) throw new Error(`Ready retained screenshot has unknown key: ${artifact.artifactId}`);
|
|
2127
2157
|
const value = retainedScreenshotReferenceFromFile({
|
|
2128
2158
|
...artifact.file,
|
|
2129
2159
|
sessionId: artifact.sessionId,
|
|
2130
2160
|
width: artifact.width,
|
|
2131
2161
|
height: artifact.height,
|
|
2132
|
-
expiresAt: artifact.retentionExpiresAt.toISOString()
|
|
2162
|
+
expiresAt: artifact.retentionExpiresAt.toISOString(),
|
|
2163
|
+
kind
|
|
2133
2164
|
});
|
|
2134
2165
|
if (!value)
|
|
2135
2166
|
throw new Error(`Ready retained screenshot receipt is invalid: ${artifact.artifactId}`);
|
|
@@ -2166,6 +2197,11 @@ function retainedReceiptFromImageContent(entry) {
|
|
|
2166
2197
|
if (marker.type !== RETAINED_IMAGE_MARKER) return null;
|
|
2167
2198
|
return retainedReceipt(marker.artifact);
|
|
2168
2199
|
}
|
|
2200
|
+
function isRetainedImageMarker(value) {
|
|
2201
|
+
return Boolean(
|
|
2202
|
+
value && typeof value === "object" && !Array.isArray(value) && value.type === RETAINED_IMAGE_MARKER
|
|
2203
|
+
);
|
|
2204
|
+
}
|
|
2169
2205
|
function retainedReceiptFromDirectOutput(output) {
|
|
2170
2206
|
if (!output || typeof output !== "object" || Array.isArray(output)) return null;
|
|
2171
2207
|
const marker = output;
|
|
@@ -2175,12 +2211,12 @@ function retainedReceiptFromDirectOutput(output) {
|
|
|
2175
2211
|
function retainedReceipt(value) {
|
|
2176
2212
|
const parsed = RetainedArtifactMetadataSchema.safeParse(value);
|
|
2177
2213
|
if (!parsed.success) return null;
|
|
2178
|
-
return parsed.data.available && parsed.data.kind !== "computer_screenshot" ? null : parsed.data;
|
|
2214
|
+
return parsed.data.available && parsed.data.kind !== "computer_screenshot" && parsed.data.kind !== "browser_screenshot" ? null : parsed.data;
|
|
2179
2215
|
}
|
|
2180
2216
|
function isInlineImageContent(entry) {
|
|
2181
2217
|
if (!entry || typeof entry !== "object" || Array.isArray(entry)) return false;
|
|
2182
2218
|
const record6 = entry;
|
|
2183
|
-
return record6.type === "input_image" && typeof record6.image === "string" && record6.image.startsWith("data:image/") || record6.type === "image" &&
|
|
2219
|
+
return record6.type === "input_image" && typeof record6.image === "string" && record6.image.startsWith("data:image/") || record6.type === "image" && isDeclaredInlineMcpImage(record6);
|
|
2184
2220
|
}
|
|
2185
2221
|
function historyCallId(item) {
|
|
2186
2222
|
const value = item.callId ?? item.call_id;
|
|
@@ -2882,6 +2918,7 @@ var TurnMediaArtifacts = class {
|
|
|
2882
2918
|
sandboxFileDownloadBackend;
|
|
2883
2919
|
nativeImageGenerationRetention = null;
|
|
2884
2920
|
retainedSessionImageCallIds = /* @__PURE__ */ new Set();
|
|
2921
|
+
retainedSessionImageKindsByCallId = /* @__PURE__ */ new Map();
|
|
2885
2922
|
rememberGeneratedImageCreatedThisTurn = (receipt) => {
|
|
2886
2923
|
this.generatedImageReceiptsCreatedThisTurn.set(receipt.artifact.artifactId, receipt);
|
|
2887
2924
|
};
|
|
@@ -3217,7 +3254,10 @@ function pendingToolCallFromSdkEvent(event) {
|
|
|
3217
3254
|
};
|
|
3218
3255
|
}
|
|
3219
3256
|
function toolCallProducesRetainableSessionImage(name) {
|
|
3220
|
-
return name === "computer_screenshot" || name === "view_image" || name === "interaction__computer_observe";
|
|
3257
|
+
return name === "computer_screenshot" || name === "view_image" || name === "interaction__computer_observe" || retainableBrowserScreenshotToolCall(name);
|
|
3258
|
+
}
|
|
3259
|
+
function retainableBrowserScreenshotToolCall(name) {
|
|
3260
|
+
return name === "browser_screenshot" || name === "interaction__browser_screenshot" || name === "browser_observe" || name === "interaction__browser_observe" || name === "browser_act" || name === "interaction__browser_act";
|
|
3221
3261
|
}
|
|
3222
3262
|
function completedToolCallFromSdkEvent(event) {
|
|
3223
3263
|
if (!event || typeof event !== "object") return null;
|
|
@@ -5110,7 +5150,8 @@ import {
|
|
|
5110
5150
|
} from "@opengeni/db";
|
|
5111
5151
|
import { publishDurableSessionEvents as publishDurableSessionEvents2 } from "@opengeni/events";
|
|
5112
5152
|
import { maxTurnsExceededRunState } from "@opengeni/runtime";
|
|
5113
|
-
import { CancelledFailure } from "@temporalio/activity";
|
|
5153
|
+
import { ApplicationFailure, CancelledFailure } from "@temporalio/activity";
|
|
5154
|
+
import { TurnExecutionPolicyDefinitionMismatchError } from "@opengeni/config";
|
|
5114
5155
|
import {
|
|
5115
5156
|
classifyCodexEncryptedArtifactRejection,
|
|
5116
5157
|
classifyCodexUsageLimitError,
|
|
@@ -6853,10 +6894,11 @@ async function settleTurnFailure(deps) {
|
|
|
6853
6894
|
return claimedResult({ status: "recovering" });
|
|
6854
6895
|
}
|
|
6855
6896
|
}
|
|
6856
|
-
|
|
6897
|
+
const earlyDefinitionMismatch = error51 instanceof TurnExecutionPolicyDefinitionMismatchError && !attempt.modelRequestStarted && !eventing.turnStartedPublished && !!attempt.turnId && !!attempt.triggerEventId && attempt.executionGeneration > 0;
|
|
6898
|
+
let failure = earlyDefinitionMismatch ? { error: error51.message, code: error51.code, retryable: true } : agentRunFailurePayload(error51, {
|
|
6857
6899
|
isCodexTurn: billingState.isCodexTurn
|
|
6858
6900
|
});
|
|
6859
|
-
if (failure.retryable && eventing.publish &&
|
|
6901
|
+
if (attempt.turnId && (earlyDefinitionMismatch || failure.retryable && eventing.publish && eventing.turnStartedPublished)) {
|
|
6860
6902
|
const nextProviderRecoveryCount = attempt.providerRecoveryCount + 1;
|
|
6861
6903
|
const recoveryResult = providerRecoveryResult({
|
|
6862
6904
|
failureCode: failure.code,
|
|
@@ -6865,8 +6907,10 @@ async function settleTurnFailure(deps) {
|
|
|
6865
6907
|
});
|
|
6866
6908
|
try {
|
|
6867
6909
|
if (recoveryResult.status === "recovering") {
|
|
6868
|
-
|
|
6869
|
-
|
|
6910
|
+
if (!earlyDefinitionMismatch) {
|
|
6911
|
+
await flushRuntimeBatcher();
|
|
6912
|
+
await historySink.reconcileConversationTruth({ requireDurable: true });
|
|
6913
|
+
}
|
|
6870
6914
|
const recovery = await requestSessionTurnRecovery(db, input.workspaceId, {
|
|
6871
6915
|
sessionId: input.sessionId,
|
|
6872
6916
|
turnId: attempt.turnId,
|
|
@@ -6894,6 +6938,16 @@ async function settleTurnFailure(deps) {
|
|
|
6894
6938
|
return claimedResult(recoveryResult);
|
|
6895
6939
|
}
|
|
6896
6940
|
failure = providerRecoveryExhaustedFailure(failure, recoveryResult);
|
|
6941
|
+
if (earlyDefinitionMismatch) {
|
|
6942
|
+
control.activityStatus = "failed";
|
|
6943
|
+
control.turnMetricOutcome = "failed";
|
|
6944
|
+
control.activityError = error51;
|
|
6945
|
+
throw ApplicationFailure.create({
|
|
6946
|
+
message: `${error51.message}. Automatic same-turn configuration recovery exhausted after ${recoveryResult.providerRecoveryCount} retries.`,
|
|
6947
|
+
type: "TurnExecutionPolicyDefinitionMismatchError",
|
|
6948
|
+
nonRetryable: true
|
|
6949
|
+
});
|
|
6950
|
+
}
|
|
6897
6951
|
} catch (recoveryError) {
|
|
6898
6952
|
const escaped = recoveryResult.status === "recovering" ? escapedMcpTimeoutRecoveryFailure({
|
|
6899
6953
|
failureCode: failure.code,
|
|
@@ -7017,7 +7071,8 @@ import {
|
|
|
7017
7071
|
import {
|
|
7018
7072
|
EmptyCompactionSummaryError,
|
|
7019
7073
|
REMOTE_COMPACTION_V2_IMPLEMENTATION,
|
|
7020
|
-
|
|
7074
|
+
compactionSummaryOutputTokens,
|
|
7075
|
+
buildSummaryItem,
|
|
7021
7076
|
buildCompactionReplacementHistory,
|
|
7022
7077
|
buildRemoteV2ReplacementHistory,
|
|
7023
7078
|
compactionThresholdTokens,
|
|
@@ -7032,7 +7087,7 @@ import {
|
|
|
7032
7087
|
} from "@opengeni/runtime";
|
|
7033
7088
|
import { contextInputBudgetTokens } from "@opengeni/config";
|
|
7034
7089
|
async function maybeCompactContext(db, settings, scope, lastInputTokens, summarize = (s, m) => summarizeForCompaction(s, m, {
|
|
7035
|
-
maxOutputTokens:
|
|
7090
|
+
maxOutputTokens: compactionSummaryOutputTokens(s.contextWindowTokens)
|
|
7036
7091
|
}), options = {}) {
|
|
7037
7092
|
if (options.codexCompactionMode === "remote_v2" && options.isCodexSubscriptionTurn !== true) {
|
|
7038
7093
|
throw new Error(
|
|
@@ -7263,12 +7318,23 @@ async function compactContextPortable(db, settings, scope, canonicalItems, items
|
|
|
7263
7318
|
const summarized = await summarizeWithCodexOverflowTrimming(summarize, settings, items);
|
|
7264
7319
|
const summaryBody = summarized.summaryBody;
|
|
7265
7320
|
const retainedTokens = await retentionTokenCounts(canonicalItems, projectForWire);
|
|
7321
|
+
const outputReserve = compactionSummaryOutputTokens(settings.contextWindowTokens);
|
|
7322
|
+
const structuralBudget = Math.min(
|
|
7323
|
+
contextInputBudgetTokens(settings) || settings.contextWindowTokens - outputReserve,
|
|
7324
|
+
settings.contextWindowTokens - outputReserve
|
|
7325
|
+
);
|
|
7326
|
+
const prefixTokens = Math.max(0, Math.ceil(summarize.estimatePrefixTokens?.() ?? 0));
|
|
7327
|
+
const summaryTokens = estimateTokens([buildSummaryItem(summaryBody)]);
|
|
7266
7328
|
const replacementHistory = buildCompactionReplacementHistory(
|
|
7267
7329
|
canonicalItems,
|
|
7268
7330
|
summaryBody,
|
|
7269
|
-
(item) => retainedTokens.get(item) ?? estimateTokens([item])
|
|
7331
|
+
(item) => retainedTokens.get(item) ?? estimateTokens([item]),
|
|
7332
|
+
Math.min(outputReserve, Math.max(0, structuralBudget - prefixTokens - summaryTokens))
|
|
7270
7333
|
);
|
|
7271
7334
|
const estimatedTokensAfter = estimateTokens(await projectForWire(replacementHistory));
|
|
7335
|
+
if (estimatedTokensAfter + prefixTokens > structuralBudget) {
|
|
7336
|
+
return await settleSkippedAfterStart(db, scope, options, "replacement_exceeds_model_budget");
|
|
7337
|
+
}
|
|
7272
7338
|
const replacementFingerprint = compactionReplacementFingerprint(replacementHistory);
|
|
7273
7339
|
const previousReplacementFingerprint = latestCompactionReplacementFingerprint(canonicalItems);
|
|
7274
7340
|
const summaryIndex = replacementHistory.length - (readReasoningConfiguration(replacementHistory.at(-1) ?? {}) ? 2 : 1);
|
|
@@ -7321,14 +7387,27 @@ async function compactContextPortable(db, settings, scope, canonicalItems, items
|
|
|
7321
7387
|
};
|
|
7322
7388
|
}
|
|
7323
7389
|
async function summarizeWithCodexOverflowTrimming(summarize, settings, activeHistory) {
|
|
7324
|
-
const summaryAwareBudget = Math.max(
|
|
7390
|
+
const summaryAwareBudget = Math.max(
|
|
7391
|
+
0,
|
|
7392
|
+
settings.contextWindowTokens - compactionSummaryOutputTokens(settings.contextWindowTokens)
|
|
7393
|
+
);
|
|
7325
7394
|
const configuredInputBudget = contextInputBudgetTokens(settings);
|
|
7326
7395
|
const structuralBudget = Math.min(
|
|
7327
7396
|
configuredInputBudget > 0 ? configuredInputBudget : summaryAwareBudget,
|
|
7328
7397
|
summaryAwareBudget
|
|
7329
7398
|
);
|
|
7330
|
-
const
|
|
7399
|
+
const prefixTokens = Math.max(0, Math.ceil(summarize.estimatePrefixTokens?.() ?? 0));
|
|
7400
|
+
const initialBudget = Math.max(0, structuralBudget - prefixTokens);
|
|
7331
7401
|
let preparation = prepareCompactionPromptInput(activeHistory, initialBudget);
|
|
7402
|
+
const requireHistory = () => {
|
|
7403
|
+
if (activeHistory.length > 0 && preparation.input.length === 1) {
|
|
7404
|
+
throw new EmptyCompactionSummaryError({
|
|
7405
|
+
stage: "portable_input_budget",
|
|
7406
|
+
reason: "no_history_fit"
|
|
7407
|
+
});
|
|
7408
|
+
}
|
|
7409
|
+
};
|
|
7410
|
+
requireHistory();
|
|
7332
7411
|
try {
|
|
7333
7412
|
return {
|
|
7334
7413
|
summaryBody: await summarize(settings, preparation.input),
|
|
@@ -7338,9 +7417,10 @@ async function summarizeWithCodexOverflowTrimming(summarize, settings, activeHis
|
|
|
7338
7417
|
} catch (error51) {
|
|
7339
7418
|
if (!isContextWindowExceeded(error51)) throw error51;
|
|
7340
7419
|
const retryBudget = Math.floor(
|
|
7341
|
-
Math.min(initialBudget * 0.
|
|
7420
|
+
Math.min(initialBudget * 0.4, preparation.estimatedInputTokens * 0.4)
|
|
7342
7421
|
);
|
|
7343
7422
|
preparation = prepareCompactionPromptInput(activeHistory, retryBudget);
|
|
7423
|
+
requireHistory();
|
|
7344
7424
|
return {
|
|
7345
7425
|
summaryBody: await summarize(settings, preparation.input),
|
|
7346
7426
|
preparation,
|
|
@@ -7708,9 +7788,11 @@ import {
|
|
|
7708
7788
|
|
|
7709
7789
|
// src/activities/agent-turn/session-title.ts
|
|
7710
7790
|
import { hasPermission } from "@opengeni/core";
|
|
7791
|
+
import { isManagedOpenRouterFreeRoute } from "@opengeni/config";
|
|
7711
7792
|
import {
|
|
7712
7793
|
AUTOMATIC_SESSION_TITLE_FALLBACK,
|
|
7713
|
-
DEFAULT_FIRST_PARTY_MCP_PERMISSIONS
|
|
7794
|
+
DEFAULT_FIRST_PARTY_MCP_PERMISSIONS,
|
|
7795
|
+
ReasoningEffort
|
|
7714
7796
|
} from "@opengeni/contracts";
|
|
7715
7797
|
var SESSION_TITLE_MODEL_TOOL_NAME = "opengeni__set_session_title";
|
|
7716
7798
|
var SESSION_TITLE_DESCRIPTION = "Set this session's display title to a concise 3-7 word topic label. Use a stable noun phrase about the actual task or subject, never a quote/prefix of a prompt, greeting, request boilerplate, URL, identifier, credential, token, or other sensitive value. Call once on a new session, then only when the topic materially changes. Never call it as routine setup after a continuation, resume, or interruption, or merely to reassert the same title. A human-set title cannot be replaced.";
|
|
@@ -7722,10 +7804,14 @@ function shouldRequestMissingSessionTitle(input) {
|
|
|
7722
7804
|
const permissions = input.firstPartyMcpPermissions ?? DEFAULT_FIRST_PARTY_MCP_PERMISSIONS;
|
|
7723
7805
|
return hasPermission([...permissions], "sessions:control");
|
|
7724
7806
|
}
|
|
7807
|
+
function routeAllowsSessionTitleRequests(resolvedModel) {
|
|
7808
|
+
return !resolvedModel || !isManagedOpenRouterFreeRoute(resolvedModel);
|
|
7809
|
+
}
|
|
7725
7810
|
function sessionTitleToolPlan(input) {
|
|
7726
7811
|
const titleToolAvailable = input.shouldRequestTitle && input.tools.some((tool) => tool.kind === "mcp" && tool.id === "opengeni");
|
|
7727
|
-
const
|
|
7728
|
-
const
|
|
7812
|
+
const titleRequestAllowed = titleToolAvailable && input.routeAllowsTitleRequests;
|
|
7813
|
+
const generateTitleInParallel = titleRequestAllowed && input.parallelGenerationAvailable;
|
|
7814
|
+
const promoteTitleTool = titleRequestAllowed && !generateTitleInParallel;
|
|
7729
7815
|
return {
|
|
7730
7816
|
promoteTitleTool,
|
|
7731
7817
|
generateTitleInParallel,
|
|
@@ -7734,6 +7820,31 @@ function sessionTitleToolPlan(input) {
|
|
|
7734
7820
|
};
|
|
7735
7821
|
}
|
|
7736
7822
|
var PARALLEL_SESSION_TITLE_TIMEOUT_MS = 15e3;
|
|
7823
|
+
function sessionTitleReasoningEffort(capabilities) {
|
|
7824
|
+
const reasoning = capabilities?.reasoning;
|
|
7825
|
+
if (!reasoning?.runnable) return void 0;
|
|
7826
|
+
const order = ReasoningEffort.options;
|
|
7827
|
+
let lowest;
|
|
7828
|
+
for (const effort of reasoning.efforts) {
|
|
7829
|
+
if (!lowest || order.indexOf(effort) < order.indexOf(lowest)) lowest = effort;
|
|
7830
|
+
}
|
|
7831
|
+
return lowest;
|
|
7832
|
+
}
|
|
7833
|
+
function sessionTitleGenerationOptions(input) {
|
|
7834
|
+
const { resolvedModel, serviceTier } = input;
|
|
7835
|
+
const reasoningEffort = sessionTitleReasoningEffort(resolvedModel?.configured.capabilities);
|
|
7836
|
+
return {
|
|
7837
|
+
...resolvedModel ? {
|
|
7838
|
+
client: resolvedModel.client,
|
|
7839
|
+
provider: resolvedModel.provider,
|
|
7840
|
+
model: resolvedModel.model
|
|
7841
|
+
} : {},
|
|
7842
|
+
modelName: input.modelName,
|
|
7843
|
+
...serviceTier ? { serviceTier } : {},
|
|
7844
|
+
...reasoningEffort ? { reasoningEffort } : {},
|
|
7845
|
+
signal: input.signal
|
|
7846
|
+
};
|
|
7847
|
+
}
|
|
7737
7848
|
function startParallelSessionTitleGeneration(input) {
|
|
7738
7849
|
const cancellationController = new AbortController();
|
|
7739
7850
|
const timeoutSignal = AbortSignal.timeout(input.timeoutMs ?? PARALLEL_SESSION_TITLE_TIMEOUT_MS);
|
|
@@ -8695,6 +8806,12 @@ async function runTurnStreamAttempt(deps) {
|
|
|
8695
8806
|
currentToolBatchCallIds.add(pendingToolCall.callId);
|
|
8696
8807
|
if (toolCallProducesRetainableSessionImage(pendingToolCall.callName)) {
|
|
8697
8808
|
media.retainedSessionImageCallIds.add(pendingToolCall.callId);
|
|
8809
|
+
if (retainableBrowserScreenshotToolCall(pendingToolCall.callName)) {
|
|
8810
|
+
media.retainedSessionImageKindsByCallId.set(
|
|
8811
|
+
pendingToolCall.callId,
|
|
8812
|
+
"browser_screenshot"
|
|
8813
|
+
);
|
|
8814
|
+
}
|
|
8698
8815
|
}
|
|
8699
8816
|
}
|
|
8700
8817
|
const completedToolCall = completedToolCallFromSdkEvent(durableSdkEvent);
|
|
@@ -8708,7 +8825,8 @@ async function runTurnStreamAttempt(deps) {
|
|
|
8708
8825
|
attemptId: input.attemptId,
|
|
8709
8826
|
toolCallId: completedToolCall.callId,
|
|
8710
8827
|
toolOutputId: completedToolCall.callId,
|
|
8711
|
-
reason: "unsupported"
|
|
8828
|
+
reason: "unsupported",
|
|
8829
|
+
kind: media.retainedSessionImageKindsByCallId.get(completedToolCall.callId)
|
|
8712
8830
|
});
|
|
8713
8831
|
media.retainedScreenshotReceiptsByCallId.set(
|
|
8714
8832
|
completedToolCall.callId,
|
|
@@ -8722,13 +8840,14 @@ async function runTurnStreamAttempt(deps) {
|
|
|
8722
8840
|
attemptId: input.attemptId,
|
|
8723
8841
|
toolCallId: typedScreenshot.callId,
|
|
8724
8842
|
toolOutputId: typedScreenshot.toolOutputId,
|
|
8725
|
-
reason: "pending"
|
|
8843
|
+
reason: "pending",
|
|
8844
|
+
kind: media.retainedSessionImageKindsByCallId.get(completedToolCall.callId)
|
|
8726
8845
|
});
|
|
8727
8846
|
media.retainedScreenshotReceiptsByCallId.set(
|
|
8728
8847
|
completedToolCall.callId,
|
|
8729
8848
|
retainedScreenshotMetadata
|
|
8730
8849
|
);
|
|
8731
|
-
retainedScreenshotMetadata = await
|
|
8850
|
+
retainedScreenshotMetadata = await retainSessionScreenshot({
|
|
8732
8851
|
db,
|
|
8733
8852
|
objectStorage,
|
|
8734
8853
|
accountId: input.accountId,
|
|
@@ -8736,7 +8855,8 @@ async function runTurnStreamAttempt(deps) {
|
|
|
8736
8855
|
sessionId: input.sessionId,
|
|
8737
8856
|
turnId: activeTurnId,
|
|
8738
8857
|
attemptId: input.attemptId,
|
|
8739
|
-
output: typedScreenshot
|
|
8858
|
+
output: typedScreenshot,
|
|
8859
|
+
kind: media.retainedSessionImageKindsByCallId.get(completedToolCall.callId)
|
|
8740
8860
|
});
|
|
8741
8861
|
media.retainedScreenshotReceiptsByCallId.set(
|
|
8742
8862
|
completedToolCall.callId,
|
|
@@ -8855,6 +8975,7 @@ async function runTurnStreamAttempt(deps) {
|
|
|
8855
8975
|
}
|
|
8856
8976
|
for (const callId of stableToolCallIdsToClear) {
|
|
8857
8977
|
media.retainedSessionImageCallIds.delete(callId);
|
|
8978
|
+
media.retainedSessionImageKindsByCallId.delete(callId);
|
|
8858
8979
|
}
|
|
8859
8980
|
}
|
|
8860
8981
|
}
|
|
@@ -9223,16 +9344,16 @@ async function runTurnStreamAttempt(deps) {
|
|
|
9223
9344
|
parallelSessionTitle = startParallelSessionTitleGeneration({
|
|
9224
9345
|
signal: runtimeCancellationSignal,
|
|
9225
9346
|
generate: async (signal) => await withSessionTitleProviderRequestContext(
|
|
9226
|
-
() => runtime.generateSessionTitle(
|
|
9227
|
-
|
|
9228
|
-
|
|
9229
|
-
|
|
9230
|
-
|
|
9231
|
-
|
|
9232
|
-
|
|
9233
|
-
|
|
9234
|
-
|
|
9235
|
-
|
|
9347
|
+
() => runtime.generateSessionTitle(
|
|
9348
|
+
runSettings,
|
|
9349
|
+
sessionTitlePrompt,
|
|
9350
|
+
sessionTitleGenerationOptions({
|
|
9351
|
+
resolvedModel,
|
|
9352
|
+
modelName: turnExecutionPolicy.upstreamModelId,
|
|
9353
|
+
serviceTier,
|
|
9354
|
+
signal
|
|
9355
|
+
})
|
|
9356
|
+
)
|
|
9236
9357
|
),
|
|
9237
9358
|
onError: (error51) => {
|
|
9238
9359
|
observability.warn("parallel session title generation failed", {
|
|
@@ -10245,6 +10366,24 @@ function safeErrorName(error51) {
|
|
|
10245
10366
|
|
|
10246
10367
|
// src/activities/agent-turn/codex-capacity.ts
|
|
10247
10368
|
import { randomUUID as randomUUID2 } from "crypto";
|
|
10369
|
+
import { createLogThrottle } from "@opengeni/observability";
|
|
10370
|
+
var CODEX_POOL_LOW_WARNING_INTERVAL_MS = 10 * 6e4;
|
|
10371
|
+
var codexPoolLowWarningThrottle = createLogThrottle({
|
|
10372
|
+
intervalMs: CODEX_POOL_LOW_WARNING_INTERVAL_MS,
|
|
10373
|
+
maxKeys: 1024
|
|
10374
|
+
});
|
|
10375
|
+
function warnCodexPoolLow(observability, input, throttle = codexPoolLowWarningThrottle) {
|
|
10376
|
+
const admission = throttle.admit(`${input.workspaceKey}:${input.depth}`);
|
|
10377
|
+
if (!admission) return;
|
|
10378
|
+
observability.warn("Codex eligible credential pool is low", {
|
|
10379
|
+
workspaceId: input.workspaceId,
|
|
10380
|
+
eligibleCount: input.eligibleCount,
|
|
10381
|
+
connectedCount: input.connectedCount,
|
|
10382
|
+
depth: input.depth,
|
|
10383
|
+
reason: input.depth === "zero" ? "eligible_pool_zero" : "eligible_pool_one",
|
|
10384
|
+
...admission.suppressedCount > 0 ? { suppressedCount: admission.suppressedCount } : {}
|
|
10385
|
+
});
|
|
10386
|
+
}
|
|
10248
10387
|
async function selectCodexTurnCapacity(deps) {
|
|
10249
10388
|
const {
|
|
10250
10389
|
input,
|
|
@@ -10510,11 +10649,12 @@ async function selectCodexTurnCapacity(deps) {
|
|
|
10510
10649
|
help: "Alert signal emitted when the eligible Codex pool is zero or one.",
|
|
10511
10650
|
labels: { workspace_key: codexWorkspaceKey, depth: poolDepth }
|
|
10512
10651
|
});
|
|
10513
|
-
observability
|
|
10652
|
+
warnCodexPoolLow(observability, {
|
|
10653
|
+
workspaceKey: codexWorkspaceKey,
|
|
10514
10654
|
workspaceId: input.workspaceId,
|
|
10515
10655
|
eligibleCount,
|
|
10516
10656
|
connectedCount: leased.accounts.length,
|
|
10517
|
-
depth: poolDepth
|
|
10657
|
+
depth: poolDepth === "zero" ? "zero" : "one"
|
|
10518
10658
|
});
|
|
10519
10659
|
}
|
|
10520
10660
|
if (providerTurn.effectiveCodexCredentialId === null && leased.accounts.length > 0 && (rotationDecision.kind === "allocatorDisabled" || leased.accounts.every((account) => !account.allocatorEnabled)) && turnId) {
|
|
@@ -10885,7 +11025,10 @@ import {
|
|
|
10885
11025
|
hasActiveWorkspaceInstructionPolicy,
|
|
10886
11026
|
renderWorkspaceGovernanceContext
|
|
10887
11027
|
} from "@opengeni/runtime";
|
|
10888
|
-
import {
|
|
11028
|
+
import {
|
|
11029
|
+
codeSearchDeploymentPolicy,
|
|
11030
|
+
settingsWithResolvedModelContext
|
|
11031
|
+
} from "@opengeni/config";
|
|
10889
11032
|
import { projectReasoningConfigurations, supportsReasoningConfiguration } from "@opengeni/codex";
|
|
10890
11033
|
import { resolveRigProviderImageForRun } from "@opengeni/core";
|
|
10891
11034
|
import { retryWhileMissing as retryWhileMissing3 } from "@opengeni/storage";
|
|
@@ -10894,6 +11037,7 @@ import {
|
|
|
10894
11037
|
evaluateWorkspaceModelPolicy,
|
|
10895
11038
|
resolveWorkspaceAgentHumanInputEnabled as resolveWorkspaceAgentHumanInputEnabled2
|
|
10896
11039
|
} from "@opengeni/contracts";
|
|
11040
|
+
import { codeSearchEnabledForTurn } from "@opengeni/contracts/code-search";
|
|
10897
11041
|
|
|
10898
11042
|
// src/activities/agent-turn/tool-policy.ts
|
|
10899
11043
|
import {
|
|
@@ -11266,6 +11410,11 @@ async function prepareGovernanceAndModel(deps) {
|
|
|
11266
11410
|
workspaceRefs.rigVersionId = session.rigVersionId ?? "";
|
|
11267
11411
|
if (!workspace) throw new Error(`Workspace not found: ${input.workspaceId}`);
|
|
11268
11412
|
const agentHumanInputEnabled = resolveWorkspaceAgentHumanInputEnabled2(workspace.settings);
|
|
11413
|
+
const codeSearchEnabled = codeSearchEnabledForTurn(
|
|
11414
|
+
session.codeSearchEnabled,
|
|
11415
|
+
workspace.settings,
|
|
11416
|
+
codeSearchDeploymentPolicy(capabilitySettings)
|
|
11417
|
+
);
|
|
11269
11418
|
const contextSelection = await resolveCompanyBrainContextSelection(db, governanceClaims);
|
|
11270
11419
|
const workspaceAgentInstructions = contextSelection.legacyWorkspaceInstructions;
|
|
11271
11420
|
const memoryPromptMode = contextSelection.receipt.memoryPromptMode;
|
|
@@ -11421,6 +11570,7 @@ async function prepareGovernanceAndModel(deps) {
|
|
|
11421
11570
|
rigVersion,
|
|
11422
11571
|
rigName,
|
|
11423
11572
|
agentHumanInputEnabled,
|
|
11573
|
+
codeSearchEnabled,
|
|
11424
11574
|
workspaceAgentInstructions,
|
|
11425
11575
|
workspaceGovernance,
|
|
11426
11576
|
structuredWorkspacePolicyActive,
|
|
@@ -11456,7 +11606,8 @@ import {
|
|
|
11456
11606
|
compactionThresholdTokens as compactionThresholdTokens2,
|
|
11457
11607
|
CompactionNeededError,
|
|
11458
11608
|
compactionProviderRejection as compactionProviderRejection2,
|
|
11459
|
-
|
|
11609
|
+
estimateSerializedValueTokens,
|
|
11610
|
+
compactionSummaryOutputTokens as compactionSummaryOutputTokens2
|
|
11460
11611
|
} from "@opengeni/runtime";
|
|
11461
11612
|
async function prepareCompaction(deps) {
|
|
11462
11613
|
const {
|
|
@@ -11495,6 +11646,11 @@ async function prepareCompaction(deps) {
|
|
|
11495
11646
|
const remotePrefix = {
|
|
11496
11647
|
agent: null
|
|
11497
11648
|
};
|
|
11649
|
+
const portableResponsesNeedsAgentPrefix = resolvedModel?.provider.api === "responses" && !(billingState.isCodexTurn && session.codexCompactionMode === "remote_v2");
|
|
11650
|
+
const preparedPortableRequest = () => {
|
|
11651
|
+
if (!remotePrefix.agent) throw new Error("Compaction agent is unavailable");
|
|
11652
|
+
return preparedCompactionRequest(remotePrefix.agent);
|
|
11653
|
+
};
|
|
11498
11654
|
const promptCacheKey = acceptsPromptCacheKeyForTurn(resolvedModel) ? input.sessionId : void 0;
|
|
11499
11655
|
const compactionUsageState = createCompactionModelUsageEventState(claimedModelUsageSourceKeys);
|
|
11500
11656
|
const recordCompactionUsage = async (usage) => {
|
|
@@ -11526,24 +11682,37 @@ async function prepareCompaction(deps) {
|
|
|
11526
11682
|
contextContributions: eventing.companyBrainContextContributions
|
|
11527
11683
|
});
|
|
11528
11684
|
};
|
|
11529
|
-
const compactionSummarizerFor = (systemInstructions) =>
|
|
11530
|
-
|
|
11531
|
-
|
|
11532
|
-
|
|
11533
|
-
|
|
11685
|
+
const compactionSummarizerFor = (systemInstructions) => {
|
|
11686
|
+
const summarize = resolvedModel ? (s, m) => withProviderRequestContext(
|
|
11687
|
+
() => summarizeContextForCompaction(s, m, {
|
|
11688
|
+
client: resolvedModel.client,
|
|
11689
|
+
provider: resolvedModel.provider,
|
|
11690
|
+
api: resolvedModel.provider.api,
|
|
11691
|
+
model: turnExecutionPolicy.upstreamModelId,
|
|
11692
|
+
maxOutputTokens: compactionSummaryOutputTokens2(s.contextWindowTokens),
|
|
11693
|
+
...cancellationSignal ? { signal: cancellationSignal } : {},
|
|
11694
|
+
onUsage: recordCompactionUsage,
|
|
11695
|
+
...systemInstructions ? { systemInstructions } : {},
|
|
11696
|
+
...promptCacheKey ? { promptCacheKey } : {},
|
|
11697
|
+
...portableResponsesNeedsAgentPrefix ? { preparedRequest: preparedPortableRequest() } : {}
|
|
11698
|
+
})
|
|
11699
|
+
) : (s, m) => summarizeContextForCompaction(s, m, {
|
|
11534
11700
|
model: turnExecutionPolicy.upstreamModelId,
|
|
11535
|
-
maxOutputTokens:
|
|
11701
|
+
maxOutputTokens: compactionSummaryOutputTokens2(s.contextWindowTokens),
|
|
11702
|
+
...cancellationSignal ? { signal: cancellationSignal } : {},
|
|
11536
11703
|
onUsage: recordCompactionUsage,
|
|
11537
11704
|
...systemInstructions ? { systemInstructions } : {},
|
|
11538
11705
|
...promptCacheKey ? { promptCacheKey } : {}
|
|
11539
|
-
})
|
|
11540
|
-
|
|
11541
|
-
|
|
11542
|
-
|
|
11543
|
-
|
|
11544
|
-
|
|
11545
|
-
|
|
11546
|
-
|
|
11706
|
+
});
|
|
11707
|
+
summarize.estimatePrefixTokens = () => {
|
|
11708
|
+
if (resolvedModel?.provider.api === "chat") {
|
|
11709
|
+
return estimateSerializedValueTokens(systemInstructions ?? "");
|
|
11710
|
+
}
|
|
11711
|
+
const prepared = portableResponsesNeedsAgentPrefix ? preparedPortableRequest() : null;
|
|
11712
|
+
return estimateSerializedValueTokens(prepared?.systemInstructions ?? systemInstructions ?? "") + (prepared ? estimateSerializedValueTokens(prepared.tools) : 0);
|
|
11713
|
+
};
|
|
11714
|
+
return summarize;
|
|
11715
|
+
};
|
|
11547
11716
|
const remoteCompactionRequester = resolvedModel && billingState.isCodexTurn ? (s, m) => withCodexRemoteCompaction(async () => {
|
|
11548
11717
|
if (!remotePrefix.agent) throw new Error("Compaction agent is unavailable");
|
|
11549
11718
|
const preparedRequest = preparedCompactionRequest(remotePrefix.agent);
|
|
@@ -11606,7 +11775,7 @@ async function prepareCompaction(deps) {
|
|
|
11606
11775
|
control.activityStatus = "idle";
|
|
11607
11776
|
return claimedResult({ status: "idle" });
|
|
11608
11777
|
};
|
|
11609
|
-
if (compactionOnlyTurn && !remoteV2CompactionNeedsAgentPrefix) {
|
|
11778
|
+
if (compactionOnlyTurn && !remoteV2CompactionNeedsAgentPrefix && !portableResponsesNeedsAgentPrefix) {
|
|
11610
11779
|
const compactionInstructions = appendWorkspaceMemory(
|
|
11611
11780
|
appendSessionInstructions(
|
|
11612
11781
|
appendWorkspaceGovernance(
|
|
@@ -11748,6 +11917,7 @@ async function runPostAgentCompaction(deps) {
|
|
|
11748
11917
|
claimedResult,
|
|
11749
11918
|
turn,
|
|
11750
11919
|
session,
|
|
11920
|
+
resolvedModel,
|
|
11751
11921
|
remotePrefix,
|
|
11752
11922
|
remoteCompactionRequester,
|
|
11753
11923
|
publishCompactionLiveEvents,
|
|
@@ -11761,16 +11931,17 @@ async function runPostAgentCompaction(deps) {
|
|
|
11761
11931
|
agent
|
|
11762
11932
|
} = deps;
|
|
11763
11933
|
const agentInstructions = typeof agent.instructions === "string" ? agent.instructions : "";
|
|
11934
|
+
const preparedPortable = resolvedModel?.provider.api === "responses" && !(remoteCompactionRequester && session.codexCompactionMode === "remote_v2");
|
|
11764
11935
|
const compactSummarizer = compactionSummarizerFor(
|
|
11765
11936
|
agentInstructions.trim() ? agentInstructions : void 0
|
|
11766
11937
|
);
|
|
11767
|
-
if (remoteCompactionRequester) {
|
|
11938
|
+
if (remoteCompactionRequester || preparedPortable) {
|
|
11768
11939
|
remotePrefix.agent = agent;
|
|
11769
11940
|
}
|
|
11770
11941
|
if (compactionOnlyTurn) {
|
|
11771
11942
|
const requested = await isSessionCompactionRequested2(db, input.workspaceId, input.sessionId);
|
|
11772
11943
|
let outcome = null;
|
|
11773
|
-
if (requested && remoteCompactionRequester && session.codexCompactionMode === "remote_v2") {
|
|
11944
|
+
if (requested && (preparedPortable || remoteCompactionRequester && session.codexCompactionMode === "remote_v2")) {
|
|
11774
11945
|
queuePreparedCompaction(
|
|
11775
11946
|
agent,
|
|
11776
11947
|
new CompactionNeededError({
|
|
@@ -11880,7 +12051,7 @@ async function runPostAgentCompaction(deps) {
|
|
|
11880
12051
|
control.activityStatus = "idle";
|
|
11881
12052
|
return { exit: claimedResult({ status: "idle" }) };
|
|
11882
12053
|
}
|
|
11883
|
-
if (remoteCompactionRequester && session.codexCompactionMode === "remote_v2") {
|
|
12054
|
+
if (preparedPortable || remoteCompactionRequester && session.codexCompactionMode === "remote_v2") {
|
|
11884
12055
|
const forced = await isSessionCompactionRequested2(db, input.workspaceId, input.sessionId);
|
|
11885
12056
|
const thresholdTokens = compactionThresholdTokens2(eventing.modelRunSettings);
|
|
11886
12057
|
if (forced || (attempt.triggerType === "user.message" || attempt.triggerType === "system.update.delivered") && (session.lastInputTokens ?? 0) >= thresholdTokens) {
|
|
@@ -12004,7 +12175,7 @@ async function runPostAgentCompaction(deps) {
|
|
|
12004
12175
|
import {
|
|
12005
12176
|
advanceWorkspaceGeneration,
|
|
12006
12177
|
verifyWorkspaceMutationSettlement,
|
|
12007
|
-
|
|
12178
|
+
heartbeatLeaseHolderStatus,
|
|
12008
12179
|
readLease as readLease2,
|
|
12009
12180
|
accrueWarmSeconds,
|
|
12010
12181
|
SandboxWorkspaceMutationFencedError
|
|
@@ -12312,21 +12483,29 @@ function createSandboxTurnRuntime(deps) {
|
|
|
12312
12483
|
const heartbeatEpoch = sandbox.leaseEpoch;
|
|
12313
12484
|
const heartbeatHolderId = sandboxState.sandboxHolderId;
|
|
12314
12485
|
const heartbeatGroupId = sandboxState.sandboxGroupId;
|
|
12315
|
-
const warmRate = sandboxWarmRateMicrosPerSecond(
|
|
12486
|
+
const warmRate = settings.sandboxWarmBillingMode === "usage_only" ? 0 : sandboxWarmRateMicrosPerSecond(
|
|
12316
12487
|
settings,
|
|
12317
12488
|
warmBackend ?? sandbox.established.backendId
|
|
12318
12489
|
);
|
|
12319
12490
|
sandboxState.leaseHeartbeatTimer = setInterval(() => {
|
|
12320
|
-
void
|
|
12491
|
+
void heartbeatLeaseHolderStatus(db, {
|
|
12321
12492
|
accountId: input.accountId,
|
|
12322
12493
|
workspaceId: input.workspaceId,
|
|
12323
12494
|
sandboxGroupId: heartbeatGroupId,
|
|
12324
12495
|
kind: "turn",
|
|
12325
12496
|
holderId: heartbeatHolderId,
|
|
12326
12497
|
leaseTtlMs: settings.sandboxLeaseTtlMs,
|
|
12327
|
-
expectedEpoch: heartbeatEpoch
|
|
12328
|
-
|
|
12329
|
-
|
|
12498
|
+
expectedEpoch: heartbeatEpoch,
|
|
12499
|
+
billingMode: settings.sandboxWarmBillingMode
|
|
12500
|
+
}).then(async (status) => {
|
|
12501
|
+
if (status.fence === "funding") {
|
|
12502
|
+
stopLeaseHeartbeat();
|
|
12503
|
+
sandboxRotationController.abort(
|
|
12504
|
+
new Error("Insufficient OpenGeni credits to extend paid sandbox compute")
|
|
12505
|
+
);
|
|
12506
|
+
return;
|
|
12507
|
+
}
|
|
12508
|
+
if (status.leaseExtended) return;
|
|
12330
12509
|
const rotation = await beginRotationPreemption(sandbox, heartbeatEpoch, heartbeatGroupId);
|
|
12331
12510
|
if (rotation === "not_rotating") {
|
|
12332
12511
|
stopLeaseHeartbeat();
|
|
@@ -12338,8 +12517,13 @@ function createSandboxTurnRuntime(deps) {
|
|
|
12338
12517
|
sandboxGroupId: heartbeatGroupId,
|
|
12339
12518
|
expectedEpoch: heartbeatEpoch,
|
|
12340
12519
|
warmRateMicrosPerSecond: warmRate,
|
|
12520
|
+
billingMode: settings.sandboxWarmBillingMode,
|
|
12341
12521
|
subjectId: input.sessionId
|
|
12342
|
-
}).then((result) =>
|
|
12522
|
+
}).then((result) => {
|
|
12523
|
+
if (settings.sandboxWarmBillingMode === "credits") {
|
|
12524
|
+
recordCreditMicros(observability, "usage", result.costMicros);
|
|
12525
|
+
}
|
|
12526
|
+
}).catch(() => void 0);
|
|
12343
12527
|
const snapshotSession = sandboxState.setupBoxSession;
|
|
12344
12528
|
const snapshotTurnId = attempt.turnId;
|
|
12345
12529
|
if (snapshotSession && snapshotTurnId && shouldStartPeriodicWorkspaceSnapshot({
|
|
@@ -12678,6 +12862,7 @@ async function resolveSandboxRoute(deps) {
|
|
|
12678
12862
|
};
|
|
12679
12863
|
}
|
|
12680
12864
|
async function establishTurnSandbox(deps) {
|
|
12865
|
+
const freshSandboxReadinessReplacementBudget = createFreshSandboxReadinessReplacementBudget();
|
|
12681
12866
|
const {
|
|
12682
12867
|
input,
|
|
12683
12868
|
settings,
|
|
@@ -12913,6 +13098,8 @@ async function establishTurnSandbox(deps) {
|
|
|
12913
13098
|
logicalFallbackSettings: logicalSandboxSettings,
|
|
12914
13099
|
cancellationSignal: sandboxResumeSignal,
|
|
12915
13100
|
sandboxMetrics: runtimeMetricsHooksForObservability(observability),
|
|
13101
|
+
observability,
|
|
13102
|
+
freshSandboxReadinessReplacementBudget,
|
|
12916
13103
|
onSandboxLost: publishSandboxLost,
|
|
12917
13104
|
objectStorage
|
|
12918
13105
|
},
|
|
@@ -12984,6 +13171,8 @@ async function establishTurnSandbox(deps) {
|
|
|
12984
13171
|
logicalFallbackSettings: logicalSandboxSettings,
|
|
12985
13172
|
cancellationSignal: sandboxResumeSignal,
|
|
12986
13173
|
sandboxMetrics: runtimeMetricsHooksForObservability(observability),
|
|
13174
|
+
observability,
|
|
13175
|
+
freshSandboxReadinessReplacementBudget,
|
|
12987
13176
|
onSandboxLost: publishSandboxLost,
|
|
12988
13177
|
objectStorage
|
|
12989
13178
|
},
|
|
@@ -14696,6 +14885,7 @@ import {
|
|
|
14696
14885
|
organizationModelProviderConnectionActiveForWorkspace,
|
|
14697
14886
|
persistAttemptToolCatalog,
|
|
14698
14887
|
prepareConnectorActionApproval,
|
|
14888
|
+
recordUsageEvent as recordUsageEvent4,
|
|
14699
14889
|
previewConnectorActionApproval,
|
|
14700
14890
|
namedSubjectHasLiveWorkspaceAuthority as namedSubjectHasLiveWorkspaceAuthority2,
|
|
14701
14891
|
updateSessionTitleWithEvent as updateSessionTitleWithEvent2,
|
|
@@ -31415,6 +31605,205 @@ function createListModelsAttemptToolDefinition(input) {
|
|
|
31415
31605
|
};
|
|
31416
31606
|
}
|
|
31417
31607
|
|
|
31608
|
+
// src/activities/agent-turn/code-search.ts
|
|
31609
|
+
import { usableJevApiKey } from "@opengeni/config";
|
|
31610
|
+
import {
|
|
31611
|
+
CODE_SEARCH_TOOL_DESCRIPTION,
|
|
31612
|
+
CODE_SEARCH_TOOL_NAME,
|
|
31613
|
+
CodeSearchArgumentError,
|
|
31614
|
+
CodeSearchRipgrepMissingError,
|
|
31615
|
+
CodeSearchWorkspaceError,
|
|
31616
|
+
JevCircuitBreaker,
|
|
31617
|
+
JevClient,
|
|
31618
|
+
JevRequestError,
|
|
31619
|
+
JevUnavailableError,
|
|
31620
|
+
codeSearchInputSchema,
|
|
31621
|
+
parseCodeSearchArguments,
|
|
31622
|
+
renderCodeSearchError,
|
|
31623
|
+
runCodeSearch
|
|
31624
|
+
} from "@opengeni/jev";
|
|
31625
|
+
import {
|
|
31626
|
+
ChannelANotFoundError,
|
|
31627
|
+
ChannelAUnavailableError,
|
|
31628
|
+
ChannelAUnsupportedError,
|
|
31629
|
+
ChannelAValidationError,
|
|
31630
|
+
isWindowsConnectedMachinePath
|
|
31631
|
+
} from "@opengeni/runtime/sandbox";
|
|
31632
|
+
var codeSearchCircuitBreaker = new JevCircuitBreaker();
|
|
31633
|
+
var CODE_SEARCH_RIPGREP_MAX_BYTES = 32 * 1024 * 1024;
|
|
31634
|
+
function codeSearchWorkspaceFromChannel(channel) {
|
|
31635
|
+
return {
|
|
31636
|
+
ripgrep: async (args, options) => {
|
|
31637
|
+
options.signal?.throwIfAborted();
|
|
31638
|
+
const outcome = await channel.codeSearchRipgrep(args, {
|
|
31639
|
+
timeoutMs: options.timeoutMs,
|
|
31640
|
+
maxBytes: CODE_SEARCH_RIPGREP_MAX_BYTES
|
|
31641
|
+
});
|
|
31642
|
+
if (!outcome.available) throw new CodeSearchRipgrepMissingError();
|
|
31643
|
+
return {
|
|
31644
|
+
stdout: outcome.stdout,
|
|
31645
|
+
exitCode: outcome.exitCode,
|
|
31646
|
+
truncated: outcome.truncated,
|
|
31647
|
+
timedOut: outcome.timedOut
|
|
31648
|
+
};
|
|
31649
|
+
},
|
|
31650
|
+
readText: async (path, options) => {
|
|
31651
|
+
options.signal?.throwIfAborted();
|
|
31652
|
+
try {
|
|
31653
|
+
const read = await channel.fsRead({ path, encoding: "utf8", maxBytes: options.maxBytes });
|
|
31654
|
+
return { text: read.content, truncated: read.truncated, binary: read.isBinary };
|
|
31655
|
+
} catch (error51) {
|
|
31656
|
+
if (error51 instanceof ChannelANotFoundError) return null;
|
|
31657
|
+
throw error51;
|
|
31658
|
+
}
|
|
31659
|
+
},
|
|
31660
|
+
pathKinds: async (paths, options) => {
|
|
31661
|
+
options.signal?.throwIfAborted();
|
|
31662
|
+
return await channel.codeSearchPathKinds(paths);
|
|
31663
|
+
}
|
|
31664
|
+
};
|
|
31665
|
+
}
|
|
31666
|
+
function textResult(text, isError) {
|
|
31667
|
+
return { isError, content: [{ type: "text", text }] };
|
|
31668
|
+
}
|
|
31669
|
+
function createCodeSearchAttemptToolDefinition(input) {
|
|
31670
|
+
const breaker = input.breaker ?? codeSearchCircuitBreaker;
|
|
31671
|
+
const jev = new JevClient({
|
|
31672
|
+
apiKey: input.apiKey,
|
|
31673
|
+
baseUrl: input.settings.jevBaseUrl,
|
|
31674
|
+
model: input.settings.jevModel,
|
|
31675
|
+
timeoutMs: input.settings.jevRequestTimeoutMs,
|
|
31676
|
+
...input.fetch ? { fetch: input.fetch } : {}
|
|
31677
|
+
});
|
|
31678
|
+
return {
|
|
31679
|
+
identity: { serverId: "opengeni", toolName: CODE_SEARCH_TOOL_NAME },
|
|
31680
|
+
modelName: CODE_SEARCH_TOOL_NAME,
|
|
31681
|
+
codemodePath: ["opengeni", CODE_SEARCH_TOOL_NAME],
|
|
31682
|
+
title: "Search code",
|
|
31683
|
+
description: CODE_SEARCH_TOOL_DESCRIPTION,
|
|
31684
|
+
inputSchema: codeSearchInputSchema,
|
|
31685
|
+
annotations: {
|
|
31686
|
+
title: "Search code",
|
|
31687
|
+
readOnlyHint: true,
|
|
31688
|
+
destructiveHint: false,
|
|
31689
|
+
idempotentHint: true,
|
|
31690
|
+
openWorldHint: false
|
|
31691
|
+
},
|
|
31692
|
+
source: "opengeni",
|
|
31693
|
+
approval: "none",
|
|
31694
|
+
execute: async (args, context) => {
|
|
31695
|
+
const startedAt = performance.now();
|
|
31696
|
+
let outcome = "failed";
|
|
31697
|
+
let jevRequests = 0;
|
|
31698
|
+
let jevCostUsd = 0;
|
|
31699
|
+
let lease = null;
|
|
31700
|
+
try {
|
|
31701
|
+
const request = parseCodeSearchArguments(args);
|
|
31702
|
+
lease = breaker.tryAcquire(Date.now());
|
|
31703
|
+
if (!lease) {
|
|
31704
|
+
outcome = "breaker_open";
|
|
31705
|
+
return textResult(
|
|
31706
|
+
renderCodeSearchError(
|
|
31707
|
+
new JevUnavailableError("Jev is not responding; calls are paused for a few minutes")
|
|
31708
|
+
),
|
|
31709
|
+
true
|
|
31710
|
+
);
|
|
31711
|
+
}
|
|
31712
|
+
const workspace = await input.workspace();
|
|
31713
|
+
const result = await runCodeSearch({
|
|
31714
|
+
...request,
|
|
31715
|
+
workspace,
|
|
31716
|
+
jev,
|
|
31717
|
+
...context.signal ? { signal: context.signal } : {}
|
|
31718
|
+
});
|
|
31719
|
+
const held = lease;
|
|
31720
|
+
lease = null;
|
|
31721
|
+
if (result.statusCheckError instanceof JevUnavailableError) {
|
|
31722
|
+
breaker.recordFailure(result.statusCheckError, Date.now(), held);
|
|
31723
|
+
} else if (result.stats.jev.requests > 0) {
|
|
31724
|
+
breaker.recordSuccess(held);
|
|
31725
|
+
} else {
|
|
31726
|
+
breaker.release(held);
|
|
31727
|
+
}
|
|
31728
|
+
outcome = "completed";
|
|
31729
|
+
jevRequests = result.stats.jev.requests;
|
|
31730
|
+
jevCostUsd = result.stats.jev.costUsd;
|
|
31731
|
+
if (input.recordUsage && jevRequests > 0) {
|
|
31732
|
+
await input.recordUsage({
|
|
31733
|
+
operationId: context.operationId,
|
|
31734
|
+
jevRequests,
|
|
31735
|
+
jevInputTokens: result.stats.jev.inputTokens,
|
|
31736
|
+
jevCostUsd
|
|
31737
|
+
}).catch((error51) => {
|
|
31738
|
+
input.observability.warn("code_search usage record failed", {
|
|
31739
|
+
error: error51 instanceof Error ? error51.message : String(error51)
|
|
31740
|
+
});
|
|
31741
|
+
});
|
|
31742
|
+
}
|
|
31743
|
+
return textResult(result.text, false);
|
|
31744
|
+
} catch (error51) {
|
|
31745
|
+
if (context.signal?.aborted) {
|
|
31746
|
+
outcome = "cancelled";
|
|
31747
|
+
throw error51;
|
|
31748
|
+
}
|
|
31749
|
+
if (error51 instanceof CodeSearchArgumentError) {
|
|
31750
|
+
outcome = "invalid_arguments";
|
|
31751
|
+
return textResult(error51.message, true);
|
|
31752
|
+
}
|
|
31753
|
+
if (error51 instanceof JevUnavailableError) {
|
|
31754
|
+
const held = lease;
|
|
31755
|
+
lease = null;
|
|
31756
|
+
breaker.recordFailure(error51, Date.now(), held);
|
|
31757
|
+
outcome = "jev_unavailable";
|
|
31758
|
+
return textResult(renderCodeSearchError(error51), true);
|
|
31759
|
+
}
|
|
31760
|
+
if (error51 instanceof JevRequestError) {
|
|
31761
|
+
outcome = "jev_rejected";
|
|
31762
|
+
return textResult(renderCodeSearchError(error51), true);
|
|
31763
|
+
}
|
|
31764
|
+
if (error51 instanceof CodeSearchWorkspaceError) {
|
|
31765
|
+
outcome = "workspace_unavailable";
|
|
31766
|
+
return textResult(renderCodeSearchError(error51), true);
|
|
31767
|
+
}
|
|
31768
|
+
if (error51 instanceof ChannelAUnavailableError || error51 instanceof ChannelAUnsupportedError || error51 instanceof ChannelAValidationError) {
|
|
31769
|
+
outcome = "workspace_unavailable";
|
|
31770
|
+
return textResult(
|
|
31771
|
+
renderCodeSearchError(new CodeSearchWorkspaceError(error51.message)),
|
|
31772
|
+
true
|
|
31773
|
+
);
|
|
31774
|
+
}
|
|
31775
|
+
throw error51;
|
|
31776
|
+
} finally {
|
|
31777
|
+
if (lease) breaker.release(lease);
|
|
31778
|
+
recordCodeSearchCall(input.observability, {
|
|
31779
|
+
outcome,
|
|
31780
|
+
durationSeconds: (performance.now() - startedAt) / 1e3,
|
|
31781
|
+
jevRequests,
|
|
31782
|
+
jevCostUsd
|
|
31783
|
+
});
|
|
31784
|
+
}
|
|
31785
|
+
}
|
|
31786
|
+
};
|
|
31787
|
+
}
|
|
31788
|
+
function codeSearchToolDefinitions(input) {
|
|
31789
|
+
const apiKey = usableJevApiKey(input.settings);
|
|
31790
|
+
const breaker = input.breaker ?? codeSearchCircuitBreaker;
|
|
31791
|
+
if (!input.enabled || !apiKey || input.backend === "none") return [];
|
|
31792
|
+
if (input.machineWorkspaceRoot && isWindowsConnectedMachinePath(input.machineWorkspaceRoot)) {
|
|
31793
|
+
return [];
|
|
31794
|
+
}
|
|
31795
|
+
return [
|
|
31796
|
+
createCodeSearchAttemptToolDefinition({
|
|
31797
|
+
settings: input.settings,
|
|
31798
|
+
apiKey,
|
|
31799
|
+
workspace: input.workspace,
|
|
31800
|
+
observability: input.observability,
|
|
31801
|
+
...input.recordUsage ? { recordUsage: input.recordUsage } : {},
|
|
31802
|
+
breaker
|
|
31803
|
+
})
|
|
31804
|
+
];
|
|
31805
|
+
}
|
|
31806
|
+
|
|
31418
31807
|
// src/activities/agent-turn/skill-tools.ts
|
|
31419
31808
|
import { createHash as createHash12 } from "crypto";
|
|
31420
31809
|
import {
|
|
@@ -32354,6 +32743,7 @@ async function prepareTurnToolRuntime(deps) {
|
|
|
32354
32743
|
turnExecutionPolicy,
|
|
32355
32744
|
trigger,
|
|
32356
32745
|
runSettings: canonicalRunSettings,
|
|
32746
|
+
resolvedModel,
|
|
32357
32747
|
lazyToolTransport,
|
|
32358
32748
|
turnTools: canonicalTurnTools,
|
|
32359
32749
|
sandboxArtifactRuntime,
|
|
@@ -32364,6 +32754,7 @@ async function prepareTurnToolRuntime(deps) {
|
|
|
32364
32754
|
credentialSubjectId,
|
|
32365
32755
|
interactionInterventionResume,
|
|
32366
32756
|
runWorkspaceMutationForSandbox,
|
|
32757
|
+
codeSearchEnabled,
|
|
32367
32758
|
throwIfWorkerShuttingDown,
|
|
32368
32759
|
throwIfTurnCancelled
|
|
32369
32760
|
} = deps;
|
|
@@ -32534,7 +32925,8 @@ async function prepareTurnToolRuntime(deps) {
|
|
|
32534
32925
|
firstPartyMcpTools: selectedFirstPartyMcpTools,
|
|
32535
32926
|
firstPartyMcpPermissions: effectiveFirstPartyPermissions
|
|
32536
32927
|
}),
|
|
32537
|
-
parallelGenerationAvailable: typeof runtime.generateSessionTitle === "function"
|
|
32928
|
+
parallelGenerationAvailable: typeof runtime.generateSessionTitle === "function",
|
|
32929
|
+
routeAllowsTitleRequests: routeAllowsSessionTitleRequests(resolvedModel)
|
|
32538
32930
|
});
|
|
32539
32931
|
const googleDrivePublicationAllowed = selectedFirstPartyMcpTools.includes("editable_artifact_export") && selectedFirstPartyMcpTools.includes("editable_artifact_export_status") && hasPermission2(
|
|
32540
32932
|
[...effectiveFirstPartyPermissions ?? DEFAULT_FIRST_PARTY_MCP_PERMISSIONS2],
|
|
@@ -32694,6 +33086,60 @@ async function prepareTurnToolRuntime(deps) {
|
|
|
32694
33086
|
return (await prepared.ready ?? prepared).attemptToolEnvironment;
|
|
32695
33087
|
}
|
|
32696
33088
|
});
|
|
33089
|
+
const codeSearchTools = codeSearchToolDefinitions({
|
|
33090
|
+
enabled: codeSearchEnabled,
|
|
33091
|
+
settings: runSettings,
|
|
33092
|
+
backend: activeSandboxBackend ?? groupBoxBackend,
|
|
33093
|
+
machineWorkspaceRoot: sandboxState.machinePrimarySession?.workspaceRoot ?? null,
|
|
33094
|
+
observability,
|
|
33095
|
+
// OpenGeni's Jev key pays for these calls whatever model billing the
|
|
33096
|
+
// workspace uses; record them per workspace so the cost stays visible.
|
|
33097
|
+
recordUsage: async (usage) => {
|
|
33098
|
+
const shared = {
|
|
33099
|
+
accountId: input.accountId,
|
|
33100
|
+
workspaceId: input.workspaceId,
|
|
33101
|
+
sourceResourceType: "code_search",
|
|
33102
|
+
sourceResourceId: usage.operationId,
|
|
33103
|
+
sessionId: input.sessionId,
|
|
33104
|
+
turnId: turn.id,
|
|
33105
|
+
turnAttemptId: input.attemptId
|
|
33106
|
+
};
|
|
33107
|
+
await recordUsageEvent4(db, {
|
|
33108
|
+
...shared,
|
|
33109
|
+
eventType: "code_search.jev_input_tokens",
|
|
33110
|
+
quantity: usage.jevInputTokens,
|
|
33111
|
+
unit: "tokens",
|
|
33112
|
+
idempotencyKey: `usage:code_search.jev_input_tokens:${input.attemptId}:${usage.operationId}`
|
|
33113
|
+
});
|
|
33114
|
+
await recordUsageEvent4(db, {
|
|
33115
|
+
...shared,
|
|
33116
|
+
eventType: "code_search.jev_cost",
|
|
33117
|
+
quantity: Math.round(usage.jevCostUsd * 1e6),
|
|
33118
|
+
unit: "usd_micros",
|
|
33119
|
+
idempotencyKey: `usage:code_search.jev_cost:${input.attemptId}:${usage.operationId}`
|
|
33120
|
+
});
|
|
33121
|
+
},
|
|
33122
|
+
workspace: async () => {
|
|
33123
|
+
throwIfWorkerShuttingDown();
|
|
33124
|
+
throwIfTurnCancelled();
|
|
33125
|
+
const access = await resolveTurnSandboxAccess(
|
|
33126
|
+
sandboxState,
|
|
33127
|
+
media.sdkOwnedSandboxSession,
|
|
33128
|
+
"code_search requires a sandbox or Connected Machine."
|
|
33129
|
+
);
|
|
33130
|
+
const machineRoot = sandboxState.machinePrimarySession?.workspaceRoot;
|
|
33131
|
+
const runAs = sandboxRunAs4(runSettings);
|
|
33132
|
+
return codeSearchWorkspaceFromChannel(
|
|
33133
|
+
new SandboxChannelAService3({
|
|
33134
|
+
session: access.session,
|
|
33135
|
+
workspaceRoot: machineRoot ?? "/workspace",
|
|
33136
|
+
...machineRoot ? { providerPathMode: "workspace-relative" } : {},
|
|
33137
|
+
leaseEpoch: access.leaseEpoch,
|
|
33138
|
+
...runAs ? { runAs } : {}
|
|
33139
|
+
})
|
|
33140
|
+
);
|
|
33141
|
+
}
|
|
33142
|
+
});
|
|
32697
33143
|
const attemptToolDefinitions = [
|
|
32698
33144
|
...operationReadStore ? [
|
|
32699
33145
|
createOperationReadAttemptToolDefinition({
|
|
@@ -32823,7 +33269,8 @@ async function prepareTurnToolRuntime(deps) {
|
|
|
32823
33269
|
subjectLabel: "OpenGeni worker",
|
|
32824
33270
|
...interactionInterventionResume ? { interventionResume: interactionInterventionResume } : {}
|
|
32825
33271
|
}),
|
|
32826
|
-
...googleDrivePublicationTool && googleDrivePublicationAllowed ? [googleDrivePublicationTool] : []
|
|
33272
|
+
...googleDrivePublicationTool && googleDrivePublicationAllowed ? [googleDrivePublicationTool] : [],
|
|
33273
|
+
...codeSearchTools
|
|
32827
33274
|
];
|
|
32828
33275
|
recordTurnStartupPhase(observability, {
|
|
32829
33276
|
phase: "tool_context_preparation",
|
|
@@ -33012,6 +33459,7 @@ async function prepareTurnToolRuntime(deps) {
|
|
|
33012
33459
|
...titleToolPlan.preparationIndependentToolNames,
|
|
33013
33460
|
"skill_read"
|
|
33014
33461
|
],
|
|
33462
|
+
codeSearchAvailable: codeSearchTools.length > 0,
|
|
33015
33463
|
skillCatalog
|
|
33016
33464
|
};
|
|
33017
33465
|
}
|
|
@@ -34430,6 +34878,7 @@ async function buildTurnAgent(deps) {
|
|
|
34430
34878
|
connectorActionPolicy,
|
|
34431
34879
|
trigger,
|
|
34432
34880
|
preparationIndependentToolNames,
|
|
34881
|
+
codeSearchAvailable,
|
|
34433
34882
|
videoGenerationAcceptancesByCallId,
|
|
34434
34883
|
activeSandboxBackend,
|
|
34435
34884
|
groupBoxBackend,
|
|
@@ -34836,6 +35285,7 @@ async function buildTurnAgent(deps) {
|
|
|
34836
35285
|
...activeSandboxBackend !== "selfhosted" && sandboxGitCredentialBindings ? { gitCredentialBindings: sandboxGitCredentialBindings } : {},
|
|
34837
35286
|
...activeSandboxBackend !== "selfhosted" && !sandboxGitTokens && sandboxGitToken ? { gitTokenSeed: sandboxGitToken } : {},
|
|
34838
35287
|
...sandboxCodemodeToken ? { codemodeAvailable: true } : {},
|
|
35288
|
+
...codeSearchAvailable ? { codeSearchAvailable: true } : {},
|
|
34839
35289
|
// Managed boxes receive the bearer through their protected per-session
|
|
34840
35290
|
// token file. Connected Machines use transient per-exec delivery above,
|
|
34841
35291
|
// so they must not run the file-seeding lifecycle hook.
|
|
@@ -35320,6 +35770,7 @@ function createRunAgentTurnActivity(services) {
|
|
|
35320
35770
|
rigVersion,
|
|
35321
35771
|
rigName,
|
|
35322
35772
|
agentHumanInputEnabled,
|
|
35773
|
+
codeSearchEnabled,
|
|
35323
35774
|
workspaceAgentInstructions,
|
|
35324
35775
|
workspaceGovernance,
|
|
35325
35776
|
structuredWorkspacePolicyActive,
|
|
@@ -35953,6 +36404,7 @@ These are publication receipts for the human's earlier answer. Do not call the r
|
|
|
35953
36404
|
turnExecutionPolicy,
|
|
35954
36405
|
trigger,
|
|
35955
36406
|
runSettings,
|
|
36407
|
+
resolvedModel,
|
|
35956
36408
|
lazyToolTransport,
|
|
35957
36409
|
turnTools,
|
|
35958
36410
|
connectionScope,
|
|
@@ -35964,6 +36416,7 @@ These are publication receipts for the human's earlier answer. Do not call the r
|
|
|
35964
36416
|
credentialSubjectId,
|
|
35965
36417
|
interactionInterventionResume,
|
|
35966
36418
|
runWorkspaceMutationForSandbox,
|
|
36419
|
+
codeSearchEnabled,
|
|
35967
36420
|
throwIfWorkerShuttingDown,
|
|
35968
36421
|
throwIfTurnCancelled
|
|
35969
36422
|
});
|
|
@@ -36026,6 +36479,7 @@ These are publication receipts for the human's earlier answer. Do not call the r
|
|
|
36026
36479
|
connectorActionPolicy,
|
|
36027
36480
|
trigger,
|
|
36028
36481
|
preparationIndependentToolNames,
|
|
36482
|
+
codeSearchAvailable: toolRuntime.codeSearchAvailable,
|
|
36029
36483
|
videoGenerationAcceptancesByCallId,
|
|
36030
36484
|
activeSandboxBackend,
|
|
36031
36485
|
groupBoxBackend,
|
|
@@ -37533,4 +37987,4 @@ export {
|
|
|
37533
37987
|
createTurnActivities,
|
|
37534
37988
|
createTurnActivitiesFromServices
|
|
37535
37989
|
};
|
|
37536
|
-
//# sourceMappingURL=activities-turn-
|
|
37990
|
+
//# sourceMappingURL=activities-turn-CSDKK4N3.js.map
|