@opengeni/worker-bundle 2.0.1 → 2.0.3-canary.36079201993001
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/failure-settlement.d.ts +1 -1
- package/dist/activities/agent-turn/history.d.ts +2 -0
- package/dist/activities/agent-turn/media-artifacts.d.ts +5 -3
- package/dist/activities/context-compaction.d.ts +10 -2
- 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-IVTL723D.js} +204 -23
- package/dist/activities-control-IVTL723D.js.map +1 -0
- package/dist/{activities-turn-YVVKCGAK.js → activities-turn-AJHDYNZU.js} +180 -58
- package/dist/activities-turn-AJHDYNZU.js.map +1 -0
- package/dist/{chunk-M3NVMF2V.js → chunk-JMO5ZUW3.js} +14 -7
- package/dist/{chunk-M3NVMF2V.js.map → chunk-JMO5ZUW3.js.map} +1 -1
- package/dist/index.js +7 -2
- package/dist/index.js.map +1 -1
- package/dist/workflow-bundle.js +4 -1
- package/package.json +19 -19
- package/src/activities/agent-turn/compaction-prep.ts +52 -16
- package/src/activities/agent-turn/errors.ts +8 -3
- package/src/activities/agent-turn/failure-settlement.ts +40 -8
- package/src/activities/agent-turn/history.ts +14 -1
- package/src/activities/agent-turn/media-artifacts.ts +2 -1
- package/src/activities/agent-turn/sandbox-runtime.ts +25 -9
- package/src/activities/agent-turn/stream-attempt.ts +13 -2
- package/src/activities/context-compaction.ts +49 -14
- package/src/activities/knowledge-indexing.ts +133 -6
- package/src/activities/retained-screenshots.ts +82 -11
- package/src/activities/sandbox-lease.ts +141 -21
- package/src/sandbox-resume.ts +6 -0
- package/src/workflows/activities.ts +14 -1
- package/dist/activities-control-QA6OLRQY.js.map +0 -1
- package/dist/activities-turn-YVVKCGAK.js.map +0 -1
|
@@ -86,7 +86,7 @@ import {
|
|
|
86
86
|
withFirstPartyTools,
|
|
87
87
|
wrapLazyTurnBoxWithRouting,
|
|
88
88
|
wrapTurnBoxWithRouting
|
|
89
|
-
} from "./chunk-
|
|
89
|
+
} from "./chunk-JMO5ZUW3.js";
|
|
90
90
|
import {
|
|
91
91
|
StreamTimingMetrics,
|
|
92
92
|
makeMachineOpObserver,
|
|
@@ -1445,11 +1445,13 @@ import {
|
|
|
1445
1445
|
COMPUTER_SCREENSHOT_RETENTION_MS,
|
|
1446
1446
|
COMPUTER_SCREENSHOT_WORKSPACE_QUOTA_BYTES,
|
|
1447
1447
|
RetainedArtifactMetadataSchema,
|
|
1448
|
-
retainedScreenshotReferenceFromFile
|
|
1448
|
+
retainedScreenshotReferenceFromFile,
|
|
1449
|
+
retainedSessionScreenshotKindFromObjectKey
|
|
1449
1450
|
} from "@opengeni/contracts";
|
|
1450
1451
|
import {
|
|
1451
1452
|
RetainedScreenshotQuotaExceededError,
|
|
1452
1453
|
getRetainedScreenshotArtifact,
|
|
1454
|
+
getRetainedScreenshotArtifactForToolCall,
|
|
1453
1455
|
isDatabasePersistenceFailure,
|
|
1454
1456
|
isSessionEventPersistenceError,
|
|
1455
1457
|
prepareRetainedScreenshotArtifact,
|
|
@@ -1554,13 +1556,16 @@ function toolOutputContainsInlineImage(output) {
|
|
|
1554
1556
|
return output.some((entry) => {
|
|
1555
1557
|
if (!entry || typeof entry !== "object" || Array.isArray(entry)) return false;
|
|
1556
1558
|
const record7 = entry;
|
|
1557
|
-
return record7.type === "input_image" && sdkImageSourceContainsInlineImage(record7.image ?? record7.image_url ?? record7.imageUrl) || record7.type === "image" &&
|
|
1559
|
+
return record7.type === "input_image" && sdkImageSourceContainsInlineImage(record7.image ?? record7.image_url ?? record7.imageUrl) || record7.type === "image" && isDeclaredInlineMcpImage(record7);
|
|
1558
1560
|
});
|
|
1559
1561
|
}
|
|
1560
1562
|
if (!output || typeof output !== "object") return false;
|
|
1561
1563
|
const record6 = output;
|
|
1562
1564
|
if (Array.isArray(record6.content)) return toolOutputContainsInlineImage(record6.content);
|
|
1563
|
-
return record6.type === "image" && sdkImageSourceContainsInlineImage(record6.image);
|
|
1565
|
+
return record6.type === "image" && (sdkImageSourceContainsInlineImage(record6.image) || isDeclaredInlineMcpImage(record6));
|
|
1566
|
+
}
|
|
1567
|
+
function isDeclaredInlineMcpImage(record6) {
|
|
1568
|
+
return typeof record6.data === "string" && typeof record6.mimeType === "string" && record6.mimeType.toLowerCase().startsWith("image/");
|
|
1564
1569
|
}
|
|
1565
1570
|
function decodeInlineMcpImage(data, mimeType) {
|
|
1566
1571
|
if (typeof data !== "string" || typeof mimeType !== "string" || !["image/png", "image/jpeg", "image/webp"].includes(mimeType)) {
|
|
@@ -1798,7 +1803,9 @@ function validateRetainableSessionImage(input, limits = {}) {
|
|
|
1798
1803
|
};
|
|
1799
1804
|
}
|
|
1800
1805
|
function retainedScreenshotIdentity(input) {
|
|
1801
|
-
const settlementKey = createHash3("sha256").update(
|
|
1806
|
+
const settlementKey = createHash3("sha256").update(
|
|
1807
|
+
input.kind === "browser_screenshot" ? "opengeni:browser-screenshot:v1\0" : "opengeni:computer-screenshot:v1\0"
|
|
1808
|
+
).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
1809
|
const uuidBytes = Uint8Array.from(Buffer.from(settlementKey.slice(0, 32), "hex"));
|
|
1803
1810
|
uuidBytes[6] = uuidBytes[6] & 15 | 128;
|
|
1804
1811
|
uuidBytes[8] = uuidBytes[8] & 63 | 128;
|
|
@@ -1812,13 +1819,14 @@ function unavailableRetainedSessionImage(input) {
|
|
|
1812
1819
|
const identity = retainedScreenshotIdentity(input);
|
|
1813
1820
|
return unavailable(identity.artifactId, input.reason);
|
|
1814
1821
|
}
|
|
1815
|
-
async function
|
|
1822
|
+
async function retainSessionScreenshot(input) {
|
|
1816
1823
|
const identity = retainedScreenshotIdentity({
|
|
1817
1824
|
sessionId: input.sessionId,
|
|
1818
1825
|
turnId: input.turnId,
|
|
1819
1826
|
attemptId: input.attemptId,
|
|
1820
1827
|
toolCallId: input.output.callId,
|
|
1821
|
-
toolOutputId: input.output.toolOutputId
|
|
1828
|
+
toolOutputId: input.output.toolOutputId,
|
|
1829
|
+
kind: input.kind
|
|
1822
1830
|
});
|
|
1823
1831
|
let screenshot;
|
|
1824
1832
|
try {
|
|
@@ -1837,7 +1845,8 @@ async function retainComputerScreenshot(input) {
|
|
|
1837
1845
|
const retentionExpiresAt = new Date(
|
|
1838
1846
|
now.getTime() + (input.retentionMs ?? COMPUTER_SCREENSHOT_RETENTION_MS)
|
|
1839
1847
|
);
|
|
1840
|
-
const
|
|
1848
|
+
const objectName = input.kind === "browser_screenshot" ? "browser-screenshot" : "session-image";
|
|
1849
|
+
const objectKey = `workspaces/${input.workspaceId}/files/${identity.artifactId}/retained/${objectName}.${screenshot.extension}`;
|
|
1841
1850
|
let prepared;
|
|
1842
1851
|
try {
|
|
1843
1852
|
prepared = (await prepareRetainedScreenshotArtifact(input.db, {
|
|
@@ -1924,6 +1933,7 @@ async function retainComputerScreenshot(input) {
|
|
|
1924
1933
|
return unavailable(identity.artifactId, "pending");
|
|
1925
1934
|
}
|
|
1926
1935
|
}
|
|
1936
|
+
var retainComputerScreenshot = retainSessionScreenshot;
|
|
1927
1937
|
function compactRetainedScreenshotHistory(history, receiptsByCallId) {
|
|
1928
1938
|
if (receiptsByCallId.size === 0) return history;
|
|
1929
1939
|
return history.map((item) => {
|
|
@@ -2005,6 +2015,20 @@ async function materializeRetainedScreenshotHistory(input) {
|
|
|
2005
2015
|
}
|
|
2006
2016
|
async function materializeRetainedScreenshotHistoryWithCache(input, cache) {
|
|
2007
2017
|
const now = input.now ?? /* @__PURE__ */ new Date();
|
|
2018
|
+
const receiptForMarker = async (marker, callId) => {
|
|
2019
|
+
if (!isRetainedImageMarker(marker)) return null;
|
|
2020
|
+
const receipt = retainedReceipt(marker.artifact);
|
|
2021
|
+
if (receipt) return receipt;
|
|
2022
|
+
if (!callId) throw new Error("Retained screenshot receipt has no tool call identity");
|
|
2023
|
+
const artifact = await getRetainedScreenshotArtifactForToolCall(
|
|
2024
|
+
input.db,
|
|
2025
|
+
input.workspaceId,
|
|
2026
|
+
input.sessionId,
|
|
2027
|
+
callId
|
|
2028
|
+
);
|
|
2029
|
+
if (!artifact) throw new Error("Retained screenshot receipt cannot be recovered");
|
|
2030
|
+
return reference(artifact);
|
|
2031
|
+
};
|
|
2008
2032
|
const dataUrlForReceipt = async (receipt) => {
|
|
2009
2033
|
let dataUrl = cache.get(receipt.artifactId);
|
|
2010
2034
|
if (!dataUrl) {
|
|
@@ -2045,15 +2069,17 @@ async function materializeRetainedScreenshotHistoryWithCache(input, cache) {
|
|
|
2045
2069
|
}
|
|
2046
2070
|
return dataUrl;
|
|
2047
2071
|
};
|
|
2048
|
-
const materializeEntry = async (entry) => {
|
|
2049
|
-
const
|
|
2072
|
+
const materializeEntry = async (entry, callId) => {
|
|
2073
|
+
const image = entry && typeof entry === "object" && !Array.isArray(entry) ? entry.image : null;
|
|
2074
|
+
const receipt = await receiptForMarker(image, callId);
|
|
2050
2075
|
if (!receipt) return entry;
|
|
2051
2076
|
const dataUrl = await dataUrlForReceipt(receipt);
|
|
2052
2077
|
return { ...entry, image: dataUrl };
|
|
2053
2078
|
};
|
|
2054
2079
|
const materialized = [];
|
|
2055
2080
|
for (const item of input.history) {
|
|
2056
|
-
const
|
|
2081
|
+
const callId = historyCallId(item);
|
|
2082
|
+
const directReceipt = await receiptForMarker(item.output, callId);
|
|
2057
2083
|
if (directReceipt) {
|
|
2058
2084
|
materialized.push({
|
|
2059
2085
|
...item,
|
|
@@ -2070,7 +2096,7 @@ async function materializeRetainedScreenshotHistoryWithCache(input, cache) {
|
|
|
2070
2096
|
let changed = false;
|
|
2071
2097
|
const output = [];
|
|
2072
2098
|
for (const entry of outputEntries) {
|
|
2073
|
-
const next = await materializeEntry(entry);
|
|
2099
|
+
const next = await materializeEntry(entry, callId);
|
|
2074
2100
|
changed ||= next !== entry;
|
|
2075
2101
|
output.push(next);
|
|
2076
2102
|
}
|
|
@@ -2124,12 +2150,15 @@ function reference(artifact) {
|
|
|
2124
2150
|
if (!artifact.sessionId) {
|
|
2125
2151
|
throw new Error(`Ready retained screenshot is detached: ${artifact.artifactId}`);
|
|
2126
2152
|
}
|
|
2153
|
+
const kind = retainedSessionScreenshotKindFromObjectKey(artifact.file.objectKey);
|
|
2154
|
+
if (!kind) throw new Error(`Ready retained screenshot has unknown key: ${artifact.artifactId}`);
|
|
2127
2155
|
const value = retainedScreenshotReferenceFromFile({
|
|
2128
2156
|
...artifact.file,
|
|
2129
2157
|
sessionId: artifact.sessionId,
|
|
2130
2158
|
width: artifact.width,
|
|
2131
2159
|
height: artifact.height,
|
|
2132
|
-
expiresAt: artifact.retentionExpiresAt.toISOString()
|
|
2160
|
+
expiresAt: artifact.retentionExpiresAt.toISOString(),
|
|
2161
|
+
kind
|
|
2133
2162
|
});
|
|
2134
2163
|
if (!value)
|
|
2135
2164
|
throw new Error(`Ready retained screenshot receipt is invalid: ${artifact.artifactId}`);
|
|
@@ -2166,6 +2195,11 @@ function retainedReceiptFromImageContent(entry) {
|
|
|
2166
2195
|
if (marker.type !== RETAINED_IMAGE_MARKER) return null;
|
|
2167
2196
|
return retainedReceipt(marker.artifact);
|
|
2168
2197
|
}
|
|
2198
|
+
function isRetainedImageMarker(value) {
|
|
2199
|
+
return Boolean(
|
|
2200
|
+
value && typeof value === "object" && !Array.isArray(value) && value.type === RETAINED_IMAGE_MARKER
|
|
2201
|
+
);
|
|
2202
|
+
}
|
|
2169
2203
|
function retainedReceiptFromDirectOutput(output) {
|
|
2170
2204
|
if (!output || typeof output !== "object" || Array.isArray(output)) return null;
|
|
2171
2205
|
const marker = output;
|
|
@@ -2175,12 +2209,12 @@ function retainedReceiptFromDirectOutput(output) {
|
|
|
2175
2209
|
function retainedReceipt(value) {
|
|
2176
2210
|
const parsed = RetainedArtifactMetadataSchema.safeParse(value);
|
|
2177
2211
|
if (!parsed.success) return null;
|
|
2178
|
-
return parsed.data.available && parsed.data.kind !== "computer_screenshot" ? null : parsed.data;
|
|
2212
|
+
return parsed.data.available && parsed.data.kind !== "computer_screenshot" && parsed.data.kind !== "browser_screenshot" ? null : parsed.data;
|
|
2179
2213
|
}
|
|
2180
2214
|
function isInlineImageContent(entry) {
|
|
2181
2215
|
if (!entry || typeof entry !== "object" || Array.isArray(entry)) return false;
|
|
2182
2216
|
const record6 = entry;
|
|
2183
|
-
return record6.type === "input_image" && typeof record6.image === "string" && record6.image.startsWith("data:image/") || record6.type === "image" &&
|
|
2217
|
+
return record6.type === "input_image" && typeof record6.image === "string" && record6.image.startsWith("data:image/") || record6.type === "image" && isDeclaredInlineMcpImage(record6);
|
|
2184
2218
|
}
|
|
2185
2219
|
function historyCallId(item) {
|
|
2186
2220
|
const value = item.callId ?? item.call_id;
|
|
@@ -2882,6 +2916,7 @@ var TurnMediaArtifacts = class {
|
|
|
2882
2916
|
sandboxFileDownloadBackend;
|
|
2883
2917
|
nativeImageGenerationRetention = null;
|
|
2884
2918
|
retainedSessionImageCallIds = /* @__PURE__ */ new Set();
|
|
2919
|
+
retainedSessionImageKindsByCallId = /* @__PURE__ */ new Map();
|
|
2885
2920
|
rememberGeneratedImageCreatedThisTurn = (receipt) => {
|
|
2886
2921
|
this.generatedImageReceiptsCreatedThisTurn.set(receipt.artifact.artifactId, receipt);
|
|
2887
2922
|
};
|
|
@@ -3217,7 +3252,10 @@ function pendingToolCallFromSdkEvent(event) {
|
|
|
3217
3252
|
};
|
|
3218
3253
|
}
|
|
3219
3254
|
function toolCallProducesRetainableSessionImage(name) {
|
|
3220
|
-
return name === "computer_screenshot" || name === "view_image" || name === "interaction__computer_observe";
|
|
3255
|
+
return name === "computer_screenshot" || name === "view_image" || name === "interaction__computer_observe" || retainableBrowserScreenshotToolCall(name);
|
|
3256
|
+
}
|
|
3257
|
+
function retainableBrowserScreenshotToolCall(name) {
|
|
3258
|
+
return name === "browser_screenshot" || name === "interaction__browser_screenshot" || name === "browser_observe" || name === "interaction__browser_observe" || name === "browser_act" || name === "interaction__browser_act";
|
|
3221
3259
|
}
|
|
3222
3260
|
function completedToolCallFromSdkEvent(event) {
|
|
3223
3261
|
if (!event || typeof event !== "object") return null;
|
|
@@ -5110,7 +5148,8 @@ import {
|
|
|
5110
5148
|
} from "@opengeni/db";
|
|
5111
5149
|
import { publishDurableSessionEvents as publishDurableSessionEvents2 } from "@opengeni/events";
|
|
5112
5150
|
import { maxTurnsExceededRunState } from "@opengeni/runtime";
|
|
5113
|
-
import { CancelledFailure } from "@temporalio/activity";
|
|
5151
|
+
import { ApplicationFailure, CancelledFailure } from "@temporalio/activity";
|
|
5152
|
+
import { TurnExecutionPolicyDefinitionMismatchError } from "@opengeni/config";
|
|
5114
5153
|
import {
|
|
5115
5154
|
classifyCodexEncryptedArtifactRejection,
|
|
5116
5155
|
classifyCodexUsageLimitError,
|
|
@@ -6853,10 +6892,11 @@ async function settleTurnFailure(deps) {
|
|
|
6853
6892
|
return claimedResult({ status: "recovering" });
|
|
6854
6893
|
}
|
|
6855
6894
|
}
|
|
6856
|
-
|
|
6895
|
+
const earlyDefinitionMismatch = error51 instanceof TurnExecutionPolicyDefinitionMismatchError && !attempt.modelRequestStarted && !eventing.turnStartedPublished && !!attempt.turnId && !!attempt.triggerEventId && attempt.executionGeneration > 0;
|
|
6896
|
+
let failure = earlyDefinitionMismatch ? { error: error51.message, code: error51.code, retryable: true } : agentRunFailurePayload(error51, {
|
|
6857
6897
|
isCodexTurn: billingState.isCodexTurn
|
|
6858
6898
|
});
|
|
6859
|
-
if (failure.retryable && eventing.publish &&
|
|
6899
|
+
if (attempt.turnId && (earlyDefinitionMismatch || failure.retryable && eventing.publish && eventing.turnStartedPublished)) {
|
|
6860
6900
|
const nextProviderRecoveryCount = attempt.providerRecoveryCount + 1;
|
|
6861
6901
|
const recoveryResult = providerRecoveryResult({
|
|
6862
6902
|
failureCode: failure.code,
|
|
@@ -6865,8 +6905,10 @@ async function settleTurnFailure(deps) {
|
|
|
6865
6905
|
});
|
|
6866
6906
|
try {
|
|
6867
6907
|
if (recoveryResult.status === "recovering") {
|
|
6868
|
-
|
|
6869
|
-
|
|
6908
|
+
if (!earlyDefinitionMismatch) {
|
|
6909
|
+
await flushRuntimeBatcher();
|
|
6910
|
+
await historySink.reconcileConversationTruth({ requireDurable: true });
|
|
6911
|
+
}
|
|
6870
6912
|
const recovery = await requestSessionTurnRecovery(db, input.workspaceId, {
|
|
6871
6913
|
sessionId: input.sessionId,
|
|
6872
6914
|
turnId: attempt.turnId,
|
|
@@ -6894,6 +6936,16 @@ async function settleTurnFailure(deps) {
|
|
|
6894
6936
|
return claimedResult(recoveryResult);
|
|
6895
6937
|
}
|
|
6896
6938
|
failure = providerRecoveryExhaustedFailure(failure, recoveryResult);
|
|
6939
|
+
if (earlyDefinitionMismatch) {
|
|
6940
|
+
control.activityStatus = "failed";
|
|
6941
|
+
control.turnMetricOutcome = "failed";
|
|
6942
|
+
control.activityError = error51;
|
|
6943
|
+
throw ApplicationFailure.create({
|
|
6944
|
+
message: `${error51.message}. Automatic same-turn configuration recovery exhausted after ${recoveryResult.providerRecoveryCount} retries.`,
|
|
6945
|
+
type: "TurnExecutionPolicyDefinitionMismatchError",
|
|
6946
|
+
nonRetryable: true
|
|
6947
|
+
});
|
|
6948
|
+
}
|
|
6897
6949
|
} catch (recoveryError) {
|
|
6898
6950
|
const escaped = recoveryResult.status === "recovering" ? escapedMcpTimeoutRecoveryFailure({
|
|
6899
6951
|
failureCode: failure.code,
|
|
@@ -7017,7 +7069,8 @@ import {
|
|
|
7017
7069
|
import {
|
|
7018
7070
|
EmptyCompactionSummaryError,
|
|
7019
7071
|
REMOTE_COMPACTION_V2_IMPLEMENTATION,
|
|
7020
|
-
|
|
7072
|
+
compactionSummaryOutputTokens,
|
|
7073
|
+
buildSummaryItem,
|
|
7021
7074
|
buildCompactionReplacementHistory,
|
|
7022
7075
|
buildRemoteV2ReplacementHistory,
|
|
7023
7076
|
compactionThresholdTokens,
|
|
@@ -7032,7 +7085,7 @@ import {
|
|
|
7032
7085
|
} from "@opengeni/runtime";
|
|
7033
7086
|
import { contextInputBudgetTokens } from "@opengeni/config";
|
|
7034
7087
|
async function maybeCompactContext(db, settings, scope, lastInputTokens, summarize = (s, m) => summarizeForCompaction(s, m, {
|
|
7035
|
-
maxOutputTokens:
|
|
7088
|
+
maxOutputTokens: compactionSummaryOutputTokens(s.contextWindowTokens)
|
|
7036
7089
|
}), options = {}) {
|
|
7037
7090
|
if (options.codexCompactionMode === "remote_v2" && options.isCodexSubscriptionTurn !== true) {
|
|
7038
7091
|
throw new Error(
|
|
@@ -7263,12 +7316,23 @@ async function compactContextPortable(db, settings, scope, canonicalItems, items
|
|
|
7263
7316
|
const summarized = await summarizeWithCodexOverflowTrimming(summarize, settings, items);
|
|
7264
7317
|
const summaryBody = summarized.summaryBody;
|
|
7265
7318
|
const retainedTokens = await retentionTokenCounts(canonicalItems, projectForWire);
|
|
7319
|
+
const outputReserve = compactionSummaryOutputTokens(settings.contextWindowTokens);
|
|
7320
|
+
const structuralBudget = Math.min(
|
|
7321
|
+
contextInputBudgetTokens(settings) || settings.contextWindowTokens - outputReserve,
|
|
7322
|
+
settings.contextWindowTokens - outputReserve
|
|
7323
|
+
);
|
|
7324
|
+
const prefixTokens = Math.max(0, Math.ceil(summarize.estimatePrefixTokens?.() ?? 0));
|
|
7325
|
+
const summaryTokens = estimateTokens([buildSummaryItem(summaryBody)]);
|
|
7266
7326
|
const replacementHistory = buildCompactionReplacementHistory(
|
|
7267
7327
|
canonicalItems,
|
|
7268
7328
|
summaryBody,
|
|
7269
|
-
(item) => retainedTokens.get(item) ?? estimateTokens([item])
|
|
7329
|
+
(item) => retainedTokens.get(item) ?? estimateTokens([item]),
|
|
7330
|
+
Math.min(outputReserve, Math.max(0, structuralBudget - prefixTokens - summaryTokens))
|
|
7270
7331
|
);
|
|
7271
7332
|
const estimatedTokensAfter = estimateTokens(await projectForWire(replacementHistory));
|
|
7333
|
+
if (estimatedTokensAfter + prefixTokens > structuralBudget) {
|
|
7334
|
+
return await settleSkippedAfterStart(db, scope, options, "replacement_exceeds_model_budget");
|
|
7335
|
+
}
|
|
7272
7336
|
const replacementFingerprint = compactionReplacementFingerprint(replacementHistory);
|
|
7273
7337
|
const previousReplacementFingerprint = latestCompactionReplacementFingerprint(canonicalItems);
|
|
7274
7338
|
const summaryIndex = replacementHistory.length - (readReasoningConfiguration(replacementHistory.at(-1) ?? {}) ? 2 : 1);
|
|
@@ -7321,14 +7385,27 @@ async function compactContextPortable(db, settings, scope, canonicalItems, items
|
|
|
7321
7385
|
};
|
|
7322
7386
|
}
|
|
7323
7387
|
async function summarizeWithCodexOverflowTrimming(summarize, settings, activeHistory) {
|
|
7324
|
-
const summaryAwareBudget = Math.max(
|
|
7388
|
+
const summaryAwareBudget = Math.max(
|
|
7389
|
+
0,
|
|
7390
|
+
settings.contextWindowTokens - compactionSummaryOutputTokens(settings.contextWindowTokens)
|
|
7391
|
+
);
|
|
7325
7392
|
const configuredInputBudget = contextInputBudgetTokens(settings);
|
|
7326
7393
|
const structuralBudget = Math.min(
|
|
7327
7394
|
configuredInputBudget > 0 ? configuredInputBudget : summaryAwareBudget,
|
|
7328
7395
|
summaryAwareBudget
|
|
7329
7396
|
);
|
|
7330
|
-
const
|
|
7397
|
+
const prefixTokens = Math.max(0, Math.ceil(summarize.estimatePrefixTokens?.() ?? 0));
|
|
7398
|
+
const initialBudget = Math.max(0, structuralBudget - prefixTokens);
|
|
7331
7399
|
let preparation = prepareCompactionPromptInput(activeHistory, initialBudget);
|
|
7400
|
+
const requireHistory = () => {
|
|
7401
|
+
if (activeHistory.length > 0 && preparation.input.length === 1) {
|
|
7402
|
+
throw new EmptyCompactionSummaryError({
|
|
7403
|
+
stage: "portable_input_budget",
|
|
7404
|
+
reason: "no_history_fit"
|
|
7405
|
+
});
|
|
7406
|
+
}
|
|
7407
|
+
};
|
|
7408
|
+
requireHistory();
|
|
7332
7409
|
try {
|
|
7333
7410
|
return {
|
|
7334
7411
|
summaryBody: await summarize(settings, preparation.input),
|
|
@@ -7338,9 +7415,10 @@ async function summarizeWithCodexOverflowTrimming(summarize, settings, activeHis
|
|
|
7338
7415
|
} catch (error51) {
|
|
7339
7416
|
if (!isContextWindowExceeded(error51)) throw error51;
|
|
7340
7417
|
const retryBudget = Math.floor(
|
|
7341
|
-
Math.min(initialBudget * 0.
|
|
7418
|
+
Math.min(initialBudget * 0.4, preparation.estimatedInputTokens * 0.4)
|
|
7342
7419
|
);
|
|
7343
7420
|
preparation = prepareCompactionPromptInput(activeHistory, retryBudget);
|
|
7421
|
+
requireHistory();
|
|
7344
7422
|
return {
|
|
7345
7423
|
summaryBody: await summarize(settings, preparation.input),
|
|
7346
7424
|
preparation,
|
|
@@ -8695,6 +8773,12 @@ async function runTurnStreamAttempt(deps) {
|
|
|
8695
8773
|
currentToolBatchCallIds.add(pendingToolCall.callId);
|
|
8696
8774
|
if (toolCallProducesRetainableSessionImage(pendingToolCall.callName)) {
|
|
8697
8775
|
media.retainedSessionImageCallIds.add(pendingToolCall.callId);
|
|
8776
|
+
if (retainableBrowserScreenshotToolCall(pendingToolCall.callName)) {
|
|
8777
|
+
media.retainedSessionImageKindsByCallId.set(
|
|
8778
|
+
pendingToolCall.callId,
|
|
8779
|
+
"browser_screenshot"
|
|
8780
|
+
);
|
|
8781
|
+
}
|
|
8698
8782
|
}
|
|
8699
8783
|
}
|
|
8700
8784
|
const completedToolCall = completedToolCallFromSdkEvent(durableSdkEvent);
|
|
@@ -8708,7 +8792,8 @@ async function runTurnStreamAttempt(deps) {
|
|
|
8708
8792
|
attemptId: input.attemptId,
|
|
8709
8793
|
toolCallId: completedToolCall.callId,
|
|
8710
8794
|
toolOutputId: completedToolCall.callId,
|
|
8711
|
-
reason: "unsupported"
|
|
8795
|
+
reason: "unsupported",
|
|
8796
|
+
kind: media.retainedSessionImageKindsByCallId.get(completedToolCall.callId)
|
|
8712
8797
|
});
|
|
8713
8798
|
media.retainedScreenshotReceiptsByCallId.set(
|
|
8714
8799
|
completedToolCall.callId,
|
|
@@ -8722,13 +8807,14 @@ async function runTurnStreamAttempt(deps) {
|
|
|
8722
8807
|
attemptId: input.attemptId,
|
|
8723
8808
|
toolCallId: typedScreenshot.callId,
|
|
8724
8809
|
toolOutputId: typedScreenshot.toolOutputId,
|
|
8725
|
-
reason: "pending"
|
|
8810
|
+
reason: "pending",
|
|
8811
|
+
kind: media.retainedSessionImageKindsByCallId.get(completedToolCall.callId)
|
|
8726
8812
|
});
|
|
8727
8813
|
media.retainedScreenshotReceiptsByCallId.set(
|
|
8728
8814
|
completedToolCall.callId,
|
|
8729
8815
|
retainedScreenshotMetadata
|
|
8730
8816
|
);
|
|
8731
|
-
retainedScreenshotMetadata = await
|
|
8817
|
+
retainedScreenshotMetadata = await retainSessionScreenshot({
|
|
8732
8818
|
db,
|
|
8733
8819
|
objectStorage,
|
|
8734
8820
|
accountId: input.accountId,
|
|
@@ -8736,7 +8822,8 @@ async function runTurnStreamAttempt(deps) {
|
|
|
8736
8822
|
sessionId: input.sessionId,
|
|
8737
8823
|
turnId: activeTurnId,
|
|
8738
8824
|
attemptId: input.attemptId,
|
|
8739
|
-
output: typedScreenshot
|
|
8825
|
+
output: typedScreenshot,
|
|
8826
|
+
kind: media.retainedSessionImageKindsByCallId.get(completedToolCall.callId)
|
|
8740
8827
|
});
|
|
8741
8828
|
media.retainedScreenshotReceiptsByCallId.set(
|
|
8742
8829
|
completedToolCall.callId,
|
|
@@ -8855,6 +8942,7 @@ async function runTurnStreamAttempt(deps) {
|
|
|
8855
8942
|
}
|
|
8856
8943
|
for (const callId of stableToolCallIdsToClear) {
|
|
8857
8944
|
media.retainedSessionImageCallIds.delete(callId);
|
|
8945
|
+
media.retainedSessionImageKindsByCallId.delete(callId);
|
|
8858
8946
|
}
|
|
8859
8947
|
}
|
|
8860
8948
|
}
|
|
@@ -11456,7 +11544,8 @@ import {
|
|
|
11456
11544
|
compactionThresholdTokens as compactionThresholdTokens2,
|
|
11457
11545
|
CompactionNeededError,
|
|
11458
11546
|
compactionProviderRejection as compactionProviderRejection2,
|
|
11459
|
-
|
|
11547
|
+
estimateSerializedValueTokens,
|
|
11548
|
+
compactionSummaryOutputTokens as compactionSummaryOutputTokens2
|
|
11460
11549
|
} from "@opengeni/runtime";
|
|
11461
11550
|
async function prepareCompaction(deps) {
|
|
11462
11551
|
const {
|
|
@@ -11495,6 +11584,11 @@ async function prepareCompaction(deps) {
|
|
|
11495
11584
|
const remotePrefix = {
|
|
11496
11585
|
agent: null
|
|
11497
11586
|
};
|
|
11587
|
+
const portableResponsesNeedsAgentPrefix = resolvedModel?.provider.api === "responses" && !(billingState.isCodexTurn && session.codexCompactionMode === "remote_v2");
|
|
11588
|
+
const preparedPortableRequest = () => {
|
|
11589
|
+
if (!remotePrefix.agent) throw new Error("Compaction agent is unavailable");
|
|
11590
|
+
return preparedCompactionRequest(remotePrefix.agent);
|
|
11591
|
+
};
|
|
11498
11592
|
const promptCacheKey = acceptsPromptCacheKeyForTurn(resolvedModel) ? input.sessionId : void 0;
|
|
11499
11593
|
const compactionUsageState = createCompactionModelUsageEventState(claimedModelUsageSourceKeys);
|
|
11500
11594
|
const recordCompactionUsage = async (usage) => {
|
|
@@ -11526,24 +11620,37 @@ async function prepareCompaction(deps) {
|
|
|
11526
11620
|
contextContributions: eventing.companyBrainContextContributions
|
|
11527
11621
|
});
|
|
11528
11622
|
};
|
|
11529
|
-
const compactionSummarizerFor = (systemInstructions) =>
|
|
11530
|
-
|
|
11531
|
-
|
|
11532
|
-
|
|
11533
|
-
|
|
11623
|
+
const compactionSummarizerFor = (systemInstructions) => {
|
|
11624
|
+
const summarize = resolvedModel ? (s, m) => withProviderRequestContext(
|
|
11625
|
+
() => summarizeContextForCompaction(s, m, {
|
|
11626
|
+
client: resolvedModel.client,
|
|
11627
|
+
provider: resolvedModel.provider,
|
|
11628
|
+
api: resolvedModel.provider.api,
|
|
11629
|
+
model: turnExecutionPolicy.upstreamModelId,
|
|
11630
|
+
maxOutputTokens: compactionSummaryOutputTokens2(s.contextWindowTokens),
|
|
11631
|
+
...cancellationSignal ? { signal: cancellationSignal } : {},
|
|
11632
|
+
onUsage: recordCompactionUsage,
|
|
11633
|
+
...systemInstructions ? { systemInstructions } : {},
|
|
11634
|
+
...promptCacheKey ? { promptCacheKey } : {},
|
|
11635
|
+
...portableResponsesNeedsAgentPrefix ? { preparedRequest: preparedPortableRequest() } : {}
|
|
11636
|
+
})
|
|
11637
|
+
) : (s, m) => summarizeContextForCompaction(s, m, {
|
|
11534
11638
|
model: turnExecutionPolicy.upstreamModelId,
|
|
11535
|
-
maxOutputTokens:
|
|
11639
|
+
maxOutputTokens: compactionSummaryOutputTokens2(s.contextWindowTokens),
|
|
11640
|
+
...cancellationSignal ? { signal: cancellationSignal } : {},
|
|
11536
11641
|
onUsage: recordCompactionUsage,
|
|
11537
11642
|
...systemInstructions ? { systemInstructions } : {},
|
|
11538
11643
|
...promptCacheKey ? { promptCacheKey } : {}
|
|
11539
|
-
})
|
|
11540
|
-
|
|
11541
|
-
|
|
11542
|
-
|
|
11543
|
-
|
|
11544
|
-
|
|
11545
|
-
|
|
11546
|
-
|
|
11644
|
+
});
|
|
11645
|
+
summarize.estimatePrefixTokens = () => {
|
|
11646
|
+
if (resolvedModel?.provider.api === "chat") {
|
|
11647
|
+
return estimateSerializedValueTokens(systemInstructions ?? "");
|
|
11648
|
+
}
|
|
11649
|
+
const prepared = portableResponsesNeedsAgentPrefix ? preparedPortableRequest() : null;
|
|
11650
|
+
return estimateSerializedValueTokens(prepared?.systemInstructions ?? systemInstructions ?? "") + (prepared ? estimateSerializedValueTokens(prepared.tools) : 0);
|
|
11651
|
+
};
|
|
11652
|
+
return summarize;
|
|
11653
|
+
};
|
|
11547
11654
|
const remoteCompactionRequester = resolvedModel && billingState.isCodexTurn ? (s, m) => withCodexRemoteCompaction(async () => {
|
|
11548
11655
|
if (!remotePrefix.agent) throw new Error("Compaction agent is unavailable");
|
|
11549
11656
|
const preparedRequest = preparedCompactionRequest(remotePrefix.agent);
|
|
@@ -11606,7 +11713,7 @@ async function prepareCompaction(deps) {
|
|
|
11606
11713
|
control.activityStatus = "idle";
|
|
11607
11714
|
return claimedResult({ status: "idle" });
|
|
11608
11715
|
};
|
|
11609
|
-
if (compactionOnlyTurn && !remoteV2CompactionNeedsAgentPrefix) {
|
|
11716
|
+
if (compactionOnlyTurn && !remoteV2CompactionNeedsAgentPrefix && !portableResponsesNeedsAgentPrefix) {
|
|
11610
11717
|
const compactionInstructions = appendWorkspaceMemory(
|
|
11611
11718
|
appendSessionInstructions(
|
|
11612
11719
|
appendWorkspaceGovernance(
|
|
@@ -11748,6 +11855,7 @@ async function runPostAgentCompaction(deps) {
|
|
|
11748
11855
|
claimedResult,
|
|
11749
11856
|
turn,
|
|
11750
11857
|
session,
|
|
11858
|
+
resolvedModel,
|
|
11751
11859
|
remotePrefix,
|
|
11752
11860
|
remoteCompactionRequester,
|
|
11753
11861
|
publishCompactionLiveEvents,
|
|
@@ -11761,16 +11869,17 @@ async function runPostAgentCompaction(deps) {
|
|
|
11761
11869
|
agent
|
|
11762
11870
|
} = deps;
|
|
11763
11871
|
const agentInstructions = typeof agent.instructions === "string" ? agent.instructions : "";
|
|
11872
|
+
const preparedPortable = resolvedModel?.provider.api === "responses" && !(remoteCompactionRequester && session.codexCompactionMode === "remote_v2");
|
|
11764
11873
|
const compactSummarizer = compactionSummarizerFor(
|
|
11765
11874
|
agentInstructions.trim() ? agentInstructions : void 0
|
|
11766
11875
|
);
|
|
11767
|
-
if (remoteCompactionRequester) {
|
|
11876
|
+
if (remoteCompactionRequester || preparedPortable) {
|
|
11768
11877
|
remotePrefix.agent = agent;
|
|
11769
11878
|
}
|
|
11770
11879
|
if (compactionOnlyTurn) {
|
|
11771
11880
|
const requested = await isSessionCompactionRequested2(db, input.workspaceId, input.sessionId);
|
|
11772
11881
|
let outcome = null;
|
|
11773
|
-
if (requested && remoteCompactionRequester && session.codexCompactionMode === "remote_v2") {
|
|
11882
|
+
if (requested && (preparedPortable || remoteCompactionRequester && session.codexCompactionMode === "remote_v2")) {
|
|
11774
11883
|
queuePreparedCompaction(
|
|
11775
11884
|
agent,
|
|
11776
11885
|
new CompactionNeededError({
|
|
@@ -11880,7 +11989,7 @@ async function runPostAgentCompaction(deps) {
|
|
|
11880
11989
|
control.activityStatus = "idle";
|
|
11881
11990
|
return { exit: claimedResult({ status: "idle" }) };
|
|
11882
11991
|
}
|
|
11883
|
-
if (remoteCompactionRequester && session.codexCompactionMode === "remote_v2") {
|
|
11992
|
+
if (preparedPortable || remoteCompactionRequester && session.codexCompactionMode === "remote_v2") {
|
|
11884
11993
|
const forced = await isSessionCompactionRequested2(db, input.workspaceId, input.sessionId);
|
|
11885
11994
|
const thresholdTokens = compactionThresholdTokens2(eventing.modelRunSettings);
|
|
11886
11995
|
if (forced || (attempt.triggerType === "user.message" || attempt.triggerType === "system.update.delivered") && (session.lastInputTokens ?? 0) >= thresholdTokens) {
|
|
@@ -12004,7 +12113,7 @@ async function runPostAgentCompaction(deps) {
|
|
|
12004
12113
|
import {
|
|
12005
12114
|
advanceWorkspaceGeneration,
|
|
12006
12115
|
verifyWorkspaceMutationSettlement,
|
|
12007
|
-
|
|
12116
|
+
heartbeatLeaseHolderStatus,
|
|
12008
12117
|
readLease as readLease2,
|
|
12009
12118
|
accrueWarmSeconds,
|
|
12010
12119
|
SandboxWorkspaceMutationFencedError
|
|
@@ -12312,21 +12421,29 @@ function createSandboxTurnRuntime(deps) {
|
|
|
12312
12421
|
const heartbeatEpoch = sandbox.leaseEpoch;
|
|
12313
12422
|
const heartbeatHolderId = sandboxState.sandboxHolderId;
|
|
12314
12423
|
const heartbeatGroupId = sandboxState.sandboxGroupId;
|
|
12315
|
-
const warmRate = sandboxWarmRateMicrosPerSecond(
|
|
12424
|
+
const warmRate = settings.sandboxWarmBillingMode === "usage_only" ? 0 : sandboxWarmRateMicrosPerSecond(
|
|
12316
12425
|
settings,
|
|
12317
12426
|
warmBackend ?? sandbox.established.backendId
|
|
12318
12427
|
);
|
|
12319
12428
|
sandboxState.leaseHeartbeatTimer = setInterval(() => {
|
|
12320
|
-
void
|
|
12429
|
+
void heartbeatLeaseHolderStatus(db, {
|
|
12321
12430
|
accountId: input.accountId,
|
|
12322
12431
|
workspaceId: input.workspaceId,
|
|
12323
12432
|
sandboxGroupId: heartbeatGroupId,
|
|
12324
12433
|
kind: "turn",
|
|
12325
12434
|
holderId: heartbeatHolderId,
|
|
12326
12435
|
leaseTtlMs: settings.sandboxLeaseTtlMs,
|
|
12327
|
-
expectedEpoch: heartbeatEpoch
|
|
12328
|
-
|
|
12329
|
-
|
|
12436
|
+
expectedEpoch: heartbeatEpoch,
|
|
12437
|
+
billingMode: settings.sandboxWarmBillingMode
|
|
12438
|
+
}).then(async (status) => {
|
|
12439
|
+
if (status.fence === "funding") {
|
|
12440
|
+
stopLeaseHeartbeat();
|
|
12441
|
+
sandboxRotationController.abort(
|
|
12442
|
+
new Error("Insufficient OpenGeni credits to extend paid sandbox compute")
|
|
12443
|
+
);
|
|
12444
|
+
return;
|
|
12445
|
+
}
|
|
12446
|
+
if (status.leaseExtended) return;
|
|
12330
12447
|
const rotation = await beginRotationPreemption(sandbox, heartbeatEpoch, heartbeatGroupId);
|
|
12331
12448
|
if (rotation === "not_rotating") {
|
|
12332
12449
|
stopLeaseHeartbeat();
|
|
@@ -12338,8 +12455,13 @@ function createSandboxTurnRuntime(deps) {
|
|
|
12338
12455
|
sandboxGroupId: heartbeatGroupId,
|
|
12339
12456
|
expectedEpoch: heartbeatEpoch,
|
|
12340
12457
|
warmRateMicrosPerSecond: warmRate,
|
|
12458
|
+
billingMode: settings.sandboxWarmBillingMode,
|
|
12341
12459
|
subjectId: input.sessionId
|
|
12342
|
-
}).then((result) =>
|
|
12460
|
+
}).then((result) => {
|
|
12461
|
+
if (settings.sandboxWarmBillingMode === "credits") {
|
|
12462
|
+
recordCreditMicros(observability, "usage", result.costMicros);
|
|
12463
|
+
}
|
|
12464
|
+
}).catch(() => void 0);
|
|
12343
12465
|
const snapshotSession = sandboxState.setupBoxSession;
|
|
12344
12466
|
const snapshotTurnId = attempt.turnId;
|
|
12345
12467
|
if (snapshotSession && snapshotTurnId && shouldStartPeriodicWorkspaceSnapshot({
|
|
@@ -37533,4 +37655,4 @@ export {
|
|
|
37533
37655
|
createTurnActivities,
|
|
37534
37656
|
createTurnActivitiesFromServices
|
|
37535
37657
|
};
|
|
37536
|
-
//# sourceMappingURL=activities-turn-
|
|
37658
|
+
//# sourceMappingURL=activities-turn-AJHDYNZU.js.map
|