@opengeni/runtime 0.3.1 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -99,7 +99,7 @@ import {
99
99
 
100
100
  // src/index.ts
101
101
  import { AGENT_INSTRUCTIONS_CORE_PLACEHOLDER, collectSandboxEnvironment as collectSandboxEnvironment2, contextInputBudgetTokens, contextServerCompactThreshold, firstPartyMcpBaseUrl, resolveContextCompactionMode, resolveModelProvider, sandboxLifecycleHookIds } from "@opengeni/config";
102
- import { CAPABILITY_DESCRIPTORS as CAPABILITY_DESCRIPTORS2, isClearedRunStateBlob, signDelegatedAccessToken } from "@opengeni/contracts";
102
+ import { CAPABILITY_DESCRIPTORS as CAPABILITY_DESCRIPTORS2, isClearedRunStateBlob, prefixedMcpToolName as sharedPrefixedMcpToolName, signDelegatedAccessToken } from "@opengeni/contracts";
103
103
  import {
104
104
  Agent,
105
105
  AgentsError,
@@ -150,7 +150,7 @@ import { fileURLToPath } from "url";
150
150
  var SCREENSHOT_FAILURE_CARD_IMAGE_URL = "data:image/png;base64,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";
151
151
 
152
152
  // src/history-sanitizer.ts
153
- var RESULT_TYPE_BY_CALL_TYPE = {
153
+ var TOOL_CALL_RESULT_TYPE_BY_CALL_TYPE = {
154
154
  function_call: "function_call_result",
155
155
  computer_call: "computer_call_result",
156
156
  shell_call: "shell_call_output",
@@ -163,6 +163,7 @@ var RESULT_TYPE_BY_CALL_TYPE = {
163
163
  // additionally ride providerData (see callIdOf).
164
164
  tool_search_call: "tool_search_output"
165
165
  };
166
+ var RESULT_TYPE_BY_CALL_TYPE = TOOL_CALL_RESULT_TYPE_BY_CALL_TYPE;
166
167
  var RESULT_TYPES = new Set(Object.values(RESULT_TYPE_BY_CALL_TYPE));
167
168
  function itemType(item) {
168
169
  if (!item || typeof item !== "object") {
@@ -795,7 +796,10 @@ function installCodexToolSearch(agent, connectorNamespaces = NO_NAMESPACES) {
795
796
  var COMPACTION_SUMMARY_MARKER = "opengeni_context_summary";
796
797
  var SUMMARY_BUFFER_TOKENS = 2e4;
797
798
  var COMPACT_USER_MESSAGE_MAX_TOKENS = 2e4;
798
- var CLIENT_COMPACTION_TRIGGER_FRACTION = 0.9;
799
+ var DEFAULT_COMPACTION_THRESHOLD_RATIO = 0.6;
800
+ var MIN_COMPACTION_THRESHOLD_RATIO = 0.3;
801
+ var MAX_COMPACTION_THRESHOLD_RATIO = 0.9;
802
+ var COMPACTION_FALLBACK_TARGET_RATIO = 0.5;
799
803
  var COMPACTION_PROMPT = [
800
804
  "You are performing a CONTEXT CHECKPOINT COMPACTION. Create a handoff summary for another LLM that will resume the task.",
801
805
  "",
@@ -809,12 +813,7 @@ var COMPACTION_PROMPT = [
809
813
  ].join("\n");
810
814
  var SUMMARY_PREFIX = "Another language model started to solve this problem and produced a summary of its thinking process. You also have access to the state of the tools that were used by that language model. Use this to build on the work that has already been done and avoid duplicating work. Here is the summary produced by the other language model, use the information in this summary to assist with your own analysis:";
811
815
  var USER_MESSAGE_TRUNCATION_MARKER = "\n[... middle truncated for context compaction ...]\n";
812
- var RESULT_TYPE_BY_CALL_TYPE2 = {
813
- function_call: "function_call_result",
814
- computer_call: "computer_call_result",
815
- shell_call: "shell_call_output",
816
- apply_patch_call: "apply_patch_call_output"
817
- };
816
+ var RESULT_TYPE_BY_CALL_TYPE2 = TOOL_CALL_RESULT_TYPE_BY_CALL_TYPE;
818
817
  var RESULT_TYPES2 = new Set(Object.values(RESULT_TYPE_BY_CALL_TYPE2));
819
818
  function itemType2(item) {
820
819
  if (!item || typeof item !== "object") {
@@ -852,12 +851,12 @@ function estimateTokens(items) {
852
851
  }
853
852
  return total;
854
853
  }
854
+ function clampCompactionThresholdRatio(value) {
855
+ const numeric = typeof value === "number" && Number.isFinite(value) ? value : DEFAULT_COMPACTION_THRESHOLD_RATIO;
856
+ return Math.min(MAX_COMPACTION_THRESHOLD_RATIO, Math.max(MIN_COMPACTION_THRESHOLD_RATIO, numeric));
857
+ }
855
858
  function clientCompactionThresholdTokens(input) {
856
- const available = Math.max(
857
- 0,
858
- input.contextWindowTokens - input.contextReservedOutputTokens - SUMMARY_BUFFER_TOKENS
859
- );
860
- return Math.floor(available * CLIENT_COMPACTION_TRIGGER_FRACTION);
859
+ return Math.floor(Math.max(0, input.contextWindowTokens) * clampCompactionThresholdRatio(input.contextCompactionThresholdRatio));
861
860
  }
862
861
  function decideClientCompaction(input) {
863
862
  const thresholdTokens = clientCompactionThresholdTokens(input);
@@ -959,6 +958,58 @@ function buildCompactionReplacementHistory(items, summaryBody) {
959
958
  history.push(buildSummaryItem(summaryBody));
960
959
  return history;
961
960
  }
961
+ function buildDeterministicFallbackCompactionHistory(input) {
962
+ const sourceTokens = Math.max(1, estimateTokens(input.items));
963
+ const requestedTarget = typeof input.targetTokens === "number" && input.targetTokens > 0 ? Math.floor(input.targetTokens) : Math.floor(sourceTokens * COMPACTION_FALLBACK_TARGET_RATIO);
964
+ const targetTokens = Math.max(1, Math.min(requestedTarget, Math.max(1, sourceTokens - 1)));
965
+ const summaryItem = buildSummaryItem([
966
+ "Non-LLM context compaction fallback.",
967
+ input.cause ? `Summarizer failure: ${input.cause}` : "Summarizer failure: unavailable.",
968
+ "Older assistant, tool, reasoning, and image history was dropped deterministically.",
969
+ "Retained context above is limited to initial instructions and the most recent user messages that fit the fallback budget; oversized retained messages may be middle-truncated."
970
+ ].join("\n"));
971
+ const summaryTokens = estimateItemTokens(summaryItem);
972
+ let remaining = Math.max(0, targetTokens - summaryTokens);
973
+ const retainedInstructions = [];
974
+ for (const item of input.items) {
975
+ if (!isInitialInstructionMessage(item)) {
976
+ if (isUserMessage(item)) {
977
+ break;
978
+ }
979
+ continue;
980
+ }
981
+ if (remaining <= 0) {
982
+ break;
983
+ }
984
+ const capped = compactMessageToEstimatedItemBudget(item, Math.min(2e3, remaining));
985
+ if (!capped) {
986
+ continue;
987
+ }
988
+ const tokens = estimateItemTokens(capped);
989
+ if (tokens <= remaining) {
990
+ retainedInstructions.push(capped);
991
+ remaining -= tokens;
992
+ }
993
+ }
994
+ const retainedUsers = [];
995
+ for (let index = input.items.length - 1; index >= 0 && remaining > 0; index -= 1) {
996
+ const item = input.items[index];
997
+ if (!isUserMessage(item) || isCompactionSummary(item)) {
998
+ continue;
999
+ }
1000
+ const capped = compactMessageToEstimatedItemBudget(item, Math.min(COMPACT_USER_MESSAGE_MAX_TOKENS, remaining));
1001
+ if (!capped) {
1002
+ continue;
1003
+ }
1004
+ const tokens = estimateItemTokens(capped);
1005
+ if (tokens <= remaining) {
1006
+ retainedUsers.push(capped);
1007
+ remaining -= tokens;
1008
+ }
1009
+ }
1010
+ retainedUsers.reverse();
1011
+ return [...retainedInstructions, ...retainedUsers, summaryItem];
1012
+ }
962
1013
  function buildSummaryItem(summaryBody) {
963
1014
  const trimmed = summaryBody.trim();
964
1015
  return {
@@ -970,15 +1021,38 @@ ${trimmed}`,
970
1021
  };
971
1022
  }
972
1023
  function compactUserMessage(item) {
1024
+ return compactMessageToTokenBudget(item, COMPACT_USER_MESSAGE_MAX_TOKENS);
1025
+ }
1026
+ function compactMessageToTokenBudget(item, maxTokens) {
973
1027
  const text = messageText(item);
974
1028
  const next = { ...item };
975
- if (estimatedTextTokens(text) > COMPACT_USER_MESSAGE_MAX_TOKENS) {
976
- next.content = truncateMiddleByEstimatedTokens(text, COMPACT_USER_MESSAGE_MAX_TOKENS);
1029
+ if (estimatedTextTokens(text) > maxTokens) {
1030
+ next.content = truncateMiddleByEstimatedTokens(text, maxTokens);
977
1031
  return next;
978
1032
  }
979
1033
  next.content = contentWithoutImages(item);
980
1034
  return next;
981
1035
  }
1036
+ function compactMessageToEstimatedItemBudget(item, maxItemTokens) {
1037
+ if (maxItemTokens <= 0) {
1038
+ return null;
1039
+ }
1040
+ const overheadTokens = estimateItemTokens({ ...item, content: "" });
1041
+ let contentBudget = Math.max(0, maxItemTokens - overheadTokens);
1042
+ for (let attempt = 0; attempt < 6; attempt += 1) {
1043
+ const capped = compactMessageToTokenBudget(item, contentBudget);
1044
+ const estimated = estimateItemTokens(capped);
1045
+ if (estimated <= maxItemTokens) {
1046
+ return capped;
1047
+ }
1048
+ const overage = estimated - maxItemTokens;
1049
+ if (contentBudget <= 0) {
1050
+ break;
1051
+ }
1052
+ contentBudget = Math.max(0, contentBudget - Math.max(1, overage));
1053
+ }
1054
+ return null;
1055
+ }
982
1056
  function estimatedTextTokens(text) {
983
1057
  return Math.ceil(text.length / 4);
984
1058
  }
@@ -1029,8 +1103,29 @@ function messageText(item) {
1029
1103
  }
1030
1104
  return "";
1031
1105
  }
1032
- function renderCompactionPromptInputForChat(input) {
1033
- return input.map(renderItem).join("\n");
1106
+ function isInitialInstructionMessage(item) {
1107
+ const type = itemType2(item);
1108
+ const role = itemRole(item);
1109
+ return type === "message" && (role === "system" || role === "developer");
1110
+ }
1111
+ function renderCompactionPromptInputForChat(input, options = {}) {
1112
+ const rendered = input.map(renderItem);
1113
+ if (typeof options.maxEstimatedTokens !== "number" || options.maxEstimatedTokens <= 0) {
1114
+ return rendered.join("\n");
1115
+ }
1116
+ const maxChars = Math.max(1, Math.floor(options.maxEstimatedTokens * 4));
1117
+ const last = rendered.at(-1);
1118
+ const prefix = rendered.slice(0, -1);
1119
+ let kept = prefix.slice();
1120
+ while (kept.length > 0 && transcriptLength([...kept, last].filter((line) => line !== void 0)) > maxChars) {
1121
+ kept.shift();
1122
+ }
1123
+ const lines = [...kept, last].filter((line) => line !== void 0);
1124
+ const joined = lines.join("\n");
1125
+ if (joined.length <= maxChars) {
1126
+ return joined;
1127
+ }
1128
+ return truncateMiddleByChars(joined, maxChars);
1034
1129
  }
1035
1130
  function renderItem(item) {
1036
1131
  const type = itemType2(item) ?? "unknown";
@@ -1076,6 +1171,24 @@ function truncateForTranscript(text, max) {
1076
1171
  }
1077
1172
  return `${text.slice(0, max)}... (${text.length - max} more chars)`;
1078
1173
  }
1174
+ function transcriptLength(lines) {
1175
+ if (lines.length === 0) {
1176
+ return 0;
1177
+ }
1178
+ return lines.reduce((sum, line) => sum + line.length, 0) + Math.max(0, lines.length - 1);
1179
+ }
1180
+ function truncateMiddleByChars(text, maxChars) {
1181
+ if (text.length <= maxChars) {
1182
+ return text;
1183
+ }
1184
+ if (maxChars <= USER_MESSAGE_TRUNCATION_MARKER.length) {
1185
+ return USER_MESSAGE_TRUNCATION_MARKER.slice(0, maxChars);
1186
+ }
1187
+ const keepChars = maxChars - USER_MESSAGE_TRUNCATION_MARKER.length;
1188
+ const headChars = Math.ceil(keepChars / 2);
1189
+ const tailChars = Math.floor(keepChars / 2);
1190
+ return `${text.slice(0, headChars)}${USER_MESSAGE_TRUNCATION_MARKER}${text.slice(text.length - tailChars)}`;
1191
+ }
1079
1192
 
1080
1193
  // src/sandbox-computer.ts
1081
1194
  import { computerTool, tool } from "@openai/agents";
@@ -1939,12 +2052,16 @@ async function summarizeForCompaction(settings, input, options = {}) {
1939
2052
  const api = options.api ?? "responses";
1940
2053
  const model = options.model ?? settings.openaiModel;
1941
2054
  const maxTokens = options.maxOutputTokens ?? SUMMARY_BUFFER_TOKENS;
2055
+ const transcript = renderCompactionPromptInputForChat(
2056
+ input,
2057
+ typeof options.maxTranscriptTokens === "number" && options.maxTranscriptTokens > 0 ? { maxEstimatedTokens: options.maxTranscriptTokens } : {}
2058
+ );
1942
2059
  try {
1943
2060
  if (api === "chat") {
1944
2061
  const completion = await client.chat.completions.create({
1945
2062
  model,
1946
2063
  max_tokens: maxTokens,
1947
- messages: [{ role: "user", content: renderCompactionPromptInputForChat(input) }]
2064
+ messages: [{ role: "user", content: transcript }]
1948
2065
  });
1949
2066
  const text2 = completion.choices?.[0]?.message?.content;
1950
2067
  const trimmed2 = typeof text2 === "string" ? text2.trim() : "";
@@ -1957,13 +2074,13 @@ async function summarizeForCompaction(settings, input, options = {}) {
1957
2074
  // built-in path (api "responses"), so gate it on the built-in provider.
1958
2075
  ...settings.openaiProvider === "azure" ? {} : { store: false },
1959
2076
  max_output_tokens: maxTokens,
1960
- input
2077
+ input: transcript
1961
2078
  });
1962
2079
  const text = extractResponseOutputText(response);
1963
2080
  const trimmed = text.trim();
1964
2081
  return trimmed.length > 0 ? trimmed : null;
1965
2082
  } catch (error) {
1966
- console.error("context compaction summarize failed (compaction skipped this turn)", error);
2083
+ console.error("context compaction summarize failed", error);
1967
2084
  return null;
1968
2085
  }
1969
2086
  }
@@ -2039,7 +2156,13 @@ function appendGenesisTitleDirective(instructions, genesisTitleHint) {
2039
2156
  var agentFileDownloads = /* @__PURE__ */ new WeakMap();
2040
2157
  var agentRepositoryCloneHooks = /* @__PURE__ */ new WeakMap();
2041
2158
  var agentGitTokenSeed = /* @__PURE__ */ new WeakMap();
2159
+ var agentToolspaceTokenSeed = /* @__PURE__ */ new WeakMap();
2042
2160
  var agentActiveSandboxBackend = /* @__PURE__ */ new WeakMap();
2161
+ function mcpToolErrorOutput(error) {
2162
+ const details = error instanceof Error ? error.message : String(error);
2163
+ return { isError: true, content: [{ type: "text", text: `An error occurred while running the tool. Please try again. Error: ${details}` }] };
2164
+ }
2165
+ var mcpToolErrorFunction = ({ error }) => mcpToolErrorOutput(error);
2043
2166
  function buildOpenGeniAgent(settings, resources, options = {}) {
2044
2167
  const compactionMode = options.compactionMode ?? resolveContextCompactionMode(settings);
2045
2168
  const hostedWebSearch = options.hostedWebSearch ?? settings.webSearchEnabled;
@@ -2098,11 +2221,19 @@ function buildOpenGeniAgent(settings, resources, options = {}) {
2098
2221
  // `new SandboxAgent({ ...baseConfig, ... })` path via the shared baseConfig
2099
2222
  // spread; the SDK concatenates these with MCP and sandbox capability tools.
2100
2223
  ...hostedTools.length ? { tools: hostedTools } : {},
2101
- ...options.mcpServers?.length ? { mcpServers: options.mcpServers } : {}
2224
+ ...options.mcpServers?.length ? { mcpServers: options.mcpServers } : {},
2225
+ // Surface FAILED MCP tool calls as `{ isError: true }` tool output (see
2226
+ // mcpToolErrorFunction / mcpToolErrorOutput) instead of the SDK's default
2227
+ // flat error string, so a thrown MCP failure (protocol error, auth, timeout,
2228
+ // tool-not-found) settles the timeline tool to "failed" rather than rendering
2229
+ // as success. Applies to every MCP server on this agent (session, first-party,
2230
+ // capability, codex_apps) since none set a server-level errorFunction.
2231
+ mcpConfig: { errorFunction: mcpToolErrorFunction }
2102
2232
  };
2103
2233
  if (settings.sandboxBackend === "none") {
2104
2234
  const agent2 = new Agent(baseConfig);
2105
2235
  maybeInstallCodexToolSearch(agent2, settings, options);
2236
+ applyMcpApprovalPolicy(agent2, settings);
2106
2237
  return agent2;
2107
2238
  }
2108
2239
  const runAs = sandboxRunAs(settings);
@@ -2125,7 +2256,11 @@ function buildOpenGeniAgent(settings, resources, options = {}) {
2125
2256
  if (options.gitTokenSeed) {
2126
2257
  agentGitTokenSeed.set(agent, options.gitTokenSeed);
2127
2258
  }
2259
+ if (options.toolspaceTokenSeed) {
2260
+ agentToolspaceTokenSeed.set(agent, options.toolspaceTokenSeed);
2261
+ }
2128
2262
  maybeInstallCodexToolSearch(agent, settings, options);
2263
+ applyMcpApprovalPolicy(agent, settings);
2129
2264
  return agent;
2130
2265
  }
2131
2266
  function maybeInstallCodexToolSearch(agent, settings, options) {
@@ -2136,6 +2271,41 @@ function maybeInstallCodexToolSearch(agent, settings, options) {
2136
2271
  );
2137
2272
  }
2138
2273
  }
2274
+ function mcpToolRequiresApproval(policy, unprefixedName) {
2275
+ return policy === true || Array.isArray(policy) && policy.includes(unprefixedName);
2276
+ }
2277
+ function installMcpApprovalPolicy(agent, policies) {
2278
+ const listMcpTools = agent.getMcpTools.bind(agent);
2279
+ agent.getMcpTools = async (runContext) => {
2280
+ const tools = await listMcpTools(runContext);
2281
+ return tools.map((tool2) => {
2282
+ if (tool2.type !== "function") {
2283
+ return tool2;
2284
+ }
2285
+ const policy = policies.find((entry) => tool2.name.startsWith(entry.prefix));
2286
+ if (!policy) {
2287
+ return tool2;
2288
+ }
2289
+ const unprefixed = tool2.name.slice(policy.prefix.length);
2290
+ return mcpToolRequiresApproval(policy.requireApproval, unprefixed) ? { ...tool2, needsApproval: async () => true } : tool2;
2291
+ });
2292
+ };
2293
+ const originalClone = agent.clone?.bind(agent);
2294
+ if (originalClone) {
2295
+ agent.clone = (config) => {
2296
+ const cloned = originalClone(config);
2297
+ installMcpApprovalPolicy(cloned, policies);
2298
+ return cloned;
2299
+ };
2300
+ }
2301
+ }
2302
+ function applyMcpApprovalPolicy(agent, settings) {
2303
+ const policies = settings.mcpServers.filter((server) => server.requireApproval === true || Array.isArray(server.requireApproval) && server.requireApproval.length > 0).map((server) => ({ prefix: prefixedMcpToolName(server.id, ""), requireApproval: server.requireApproval })).sort((a, b) => b.prefix.length - a.prefix.length);
2304
+ if (policies.length === 0) {
2305
+ return;
2306
+ }
2307
+ installMcpApprovalPolicy(agent, policies);
2308
+ }
2139
2309
  function neutralizeStructuredToolTransport(capability) {
2140
2310
  const forceFunctionTransport = function() {
2141
2311
  this._modelInstance = void 0;
@@ -2185,6 +2355,8 @@ async function prepareAgentTools(settings, tools, options = {}) {
2185
2355
  throw new Error(`Unknown MCP server id: ${tool2.id}`);
2186
2356
  }
2187
2357
  const url = firstPartyMcpServerUrlForRun(settings, config, options.workspaceId) ?? config.url;
2358
+ const baseFetch = isCodexAppsMcpServer(config) ? codexAppsSanitizingFetch(globalThis.fetch, codexConnectorNamespaces) : globalThis.fetch;
2359
+ const fetchImpl = config.connectionRef ? connectionBrokerFetch(baseFetch, config, options) : baseFetch;
2188
2360
  const server = new PrefixedMcpServer(new MCPServerStreamableHttp({
2189
2361
  url,
2190
2362
  name: config.name ?? config.id,
@@ -2193,7 +2365,7 @@ async function prepareAgentTools(settings, tools, options = {}) {
2193
2365
  // MCP SDK's strict Tool schema rejects (fails the turn during tools/list);
2194
2366
  // sanitize the response on the wire before validation. The namespace Set
2195
2367
  // also captures each tool's original connector namespace (P4 Part B.1).
2196
- ...isCodexAppsMcpServer(config) ? { fetch: codexAppsSanitizingFetch(globalThis.fetch, codexConnectorNamespaces) } : {},
2368
+ ...fetchImpl !== globalThis.fetch ? { fetch: fetchImpl } : {},
2197
2369
  ...await mcpServerRequestInit(settings, config, options),
2198
2370
  ...config.timeoutMs ? {
2199
2371
  timeout: config.timeoutMs,
@@ -2201,7 +2373,7 @@ async function prepareAgentTools(settings, tools, options = {}) {
2201
2373
  } : {}
2202
2374
  }), config.id, config.allowedTools);
2203
2375
  const optional = tool2.optional === true;
2204
- return { server, bestEffort: isCodexAppsMcpServer(config) || optional, optional };
2376
+ return { server, bestEffort: isCodexAppsMcpServer(config) || optional || !!config.connectionRef, optional };
2205
2377
  }));
2206
2378
  const requiredServers = servers.filter((entry) => !entry.bestEffort).map((entry) => entry.server);
2207
2379
  const bestEffortServers = servers.filter((entry) => entry.bestEffort).map((entry) => entry.server);
@@ -2239,6 +2411,190 @@ async function prepareAgentTools(settings, tools, options = {}) {
2239
2411
  codexConnectorNamespaces
2240
2412
  };
2241
2413
  }
2414
+ function connectionBrokerFetch(baseFetch, config, options) {
2415
+ const connectionRef = config.connectionRef;
2416
+ if (!connectionRef) {
2417
+ return baseFetch;
2418
+ }
2419
+ return async (input, init) => {
2420
+ const request = await mcpRequestInfo(input, init);
2421
+ const first = await resolveConnectionForRequest(options, config.id, connectionRef, request.toolName, false);
2422
+ if (first.status === "auth_needed") {
2423
+ return await authNeededFetchResponse(options, config.id, request, first, connectionRef);
2424
+ }
2425
+ const response = await baseFetch(fetchInputForAttempt(input), withConnectionHeaders(input, init, first.headers));
2426
+ if (response.status === 401) {
2427
+ const refreshed = await resolveConnectionForRequest(options, config.id, connectionRef, request.toolName, true);
2428
+ if (refreshed.status === "auth_needed") {
2429
+ return await authNeededFetchResponse(options, config.id, request, refreshed, connectionRef);
2430
+ }
2431
+ const retry = await baseFetch(fetchInputForAttempt(input), withConnectionHeaders(input, init, refreshed.headers));
2432
+ if (retry.status === 403) {
2433
+ const auth = insufficientScopeAuth(retry.headers, connectionRef, refreshed.connectionId);
2434
+ return auth ? await authNeededFetchResponse(options, config.id, request, auth, connectionRef) : retry;
2435
+ }
2436
+ if (retry.status === 401) {
2437
+ return await authNeededFetchResponse(options, config.id, request, {
2438
+ status: "auth_needed",
2439
+ reason: "expired",
2440
+ providerDomain: connectionRef.providerDomain,
2441
+ connectionId: refreshed.connectionId,
2442
+ ...connectionRef.scopes ? { scopes: connectionRef.scopes } : {},
2443
+ ...connectionRef.resource ? { resource: connectionRef.resource } : {}
2444
+ }, connectionRef);
2445
+ }
2446
+ return retry;
2447
+ }
2448
+ if (response.status === 403) {
2449
+ const auth = insufficientScopeAuth(response.headers, connectionRef, first.connectionId);
2450
+ return auth ? await authNeededFetchResponse(options, config.id, request, auth, connectionRef) : response;
2451
+ }
2452
+ return response;
2453
+ };
2454
+ }
2455
+ async function resolveConnectionForRequest(options, serverId, connectionRef, toolName, forceRefresh) {
2456
+ if (!options.workspaceId || !options.resolveCredential) {
2457
+ return {
2458
+ status: "auth_needed",
2459
+ reason: "missing_connection",
2460
+ providerDomain: connectionRef.providerDomain,
2461
+ ...connectionRef.connectionId ? { connectionId: connectionRef.connectionId } : {},
2462
+ ...connectionRef.scopes ? { scopes: connectionRef.scopes } : {},
2463
+ ...connectionRef.resource ? { resource: connectionRef.resource } : {}
2464
+ };
2465
+ }
2466
+ const request = {
2467
+ workspaceId: options.workspaceId,
2468
+ serverId,
2469
+ connectionRef,
2470
+ forceRefresh,
2471
+ ...toolName ? { toolName } : {},
2472
+ ...options.subjectId ? { subjectId: options.subjectId } : {}
2473
+ };
2474
+ try {
2475
+ return await options.resolveCredential(request);
2476
+ } catch {
2477
+ return {
2478
+ status: "auth_needed",
2479
+ reason: "refresh_failed",
2480
+ providerDomain: connectionRef.providerDomain,
2481
+ ...connectionRef.connectionId ? { connectionId: connectionRef.connectionId } : {},
2482
+ ...connectionRef.scopes ? { scopes: connectionRef.scopes } : {},
2483
+ ...connectionRef.resource ? { resource: connectionRef.resource } : {}
2484
+ };
2485
+ }
2486
+ }
2487
+ function insufficientScopeAuth(headers, connectionRef, connectionId) {
2488
+ const challenge = parseWwwAuthenticate(headers.get("www-authenticate"));
2489
+ if (challenge.error !== "insufficient_scope") {
2490
+ return null;
2491
+ }
2492
+ return {
2493
+ status: "auth_needed",
2494
+ reason: "insufficient_scope",
2495
+ providerDomain: connectionRef.providerDomain,
2496
+ connectionId,
2497
+ ...challenge.scope?.length ? { scopes: challenge.scope } : connectionRef.scopes ? { scopes: connectionRef.scopes } : {},
2498
+ ...challenge.resource ? { resource: challenge.resource } : connectionRef.resource ? { resource: connectionRef.resource } : {}
2499
+ };
2500
+ }
2501
+ async function authNeededFetchResponse(options, serverId, request, auth, connectionRef) {
2502
+ const connectionId = auth.connectionId ?? connectionRef.connectionId;
2503
+ await publishAuthNeeded(options, {
2504
+ serverId,
2505
+ toolName: request.toolName ?? null,
2506
+ providerDomain: auth.providerDomain,
2507
+ reason: auth.reason,
2508
+ ...connectionId ? { connectionId } : {},
2509
+ ...auth.scopes ? { scopes: auth.scopes } : connectionRef.scopes ? { scopes: connectionRef.scopes } : {},
2510
+ ...auth.resource ? { resource: auth.resource } : connectionRef.resource ? { resource: connectionRef.resource } : {},
2511
+ ...auth.authorizationUrl ? { authorizationUrl: auth.authorizationUrl } : {},
2512
+ ...options.subjectId ? { subjectId: options.subjectId } : {}
2513
+ });
2514
+ if (request.method === "tools/call") {
2515
+ return mcpToolAuthNeededResponse(request.id);
2516
+ }
2517
+ return new Response("Authentication required for MCP server connection", { status: 401 });
2518
+ }
2519
+ async function publishAuthNeeded(options, payload) {
2520
+ try {
2521
+ await options.onAuthNeeded?.(payload);
2522
+ } catch {
2523
+ }
2524
+ }
2525
+ async function mcpRequestInfo(input, init) {
2526
+ const body = typeof init?.body === "string" ? init.body : input instanceof Request && (init?.method ?? input.method).toUpperCase() === "POST" ? await input.clone().text().catch(() => "") : "";
2527
+ if (!body) {
2528
+ return {};
2529
+ }
2530
+ try {
2531
+ const parsed = JSON.parse(body);
2532
+ const method = typeof parsed.method === "string" ? parsed.method : void 0;
2533
+ const id = typeof parsed.id === "string" || typeof parsed.id === "number" || parsed.id === null ? parsed.id : void 0;
2534
+ const toolName = method === "tools/call" && typeof parsed.params?.name === "string" ? parsed.params.name : void 0;
2535
+ return {
2536
+ ...method ? { method } : {},
2537
+ ...id !== void 0 ? { id } : {},
2538
+ ...toolName ? { toolName } : {}
2539
+ };
2540
+ } catch {
2541
+ return {};
2542
+ }
2543
+ }
2544
+ function withConnectionHeaders(input, init, authHeaders) {
2545
+ const headers = new Headers(init?.headers ?? (input instanceof Request ? input.headers : void 0));
2546
+ for (const [name, value] of Object.entries(authHeaders)) {
2547
+ headers.set(name, value);
2548
+ }
2549
+ return { ...init, headers };
2550
+ }
2551
+ function fetchInputForAttempt(input) {
2552
+ return input instanceof Request ? input.clone() : input;
2553
+ }
2554
+ function parseWwwAuthenticate(header) {
2555
+ if (!header) {
2556
+ return {};
2557
+ }
2558
+ const bearerIndex = header.toLowerCase().indexOf("bearer");
2559
+ if (bearerIndex < 0) {
2560
+ return {};
2561
+ }
2562
+ const paramsText = header.slice(bearerIndex + "bearer".length);
2563
+ const params = {};
2564
+ const re = /([a-zA-Z_][a-zA-Z0-9_-]*)\s*=\s*("(?:[^"\\]|\\.)*"|[^,\s]+)/g;
2565
+ let match;
2566
+ while ((match = re.exec(paramsText)) !== null) {
2567
+ const raw = match[2];
2568
+ params[match[1].toLowerCase()] = raw.startsWith('"') ? raw.slice(1, -1).replace(/\\"/g, '"') : raw;
2569
+ }
2570
+ return {
2571
+ ...params.error ? { error: params.error } : {},
2572
+ ...params.scope ? { scope: params.scope.split(/\s+/).filter(Boolean) } : {},
2573
+ ...params.resource ? { resource: params.resource } : {}
2574
+ };
2575
+ }
2576
+ var MCP_AUTH_NEEDED_ERROR_CODE = -32001;
2577
+ var MCP_AUTH_NEEDED_MESSAGE = "Authentication required - a connection link was posted to the session.";
2578
+ function mcpToolAuthNeededResponse(id) {
2579
+ return new Response(JSON.stringify({
2580
+ jsonrpc: "2.0",
2581
+ id: id ?? null,
2582
+ error: {
2583
+ code: MCP_AUTH_NEEDED_ERROR_CODE,
2584
+ message: MCP_AUTH_NEEDED_MESSAGE
2585
+ }
2586
+ }), {
2587
+ status: 200,
2588
+ headers: { "content-type": "application/json" }
2589
+ });
2590
+ }
2591
+ function isAuthNeededMcpError(error) {
2592
+ if (!(error instanceof Error)) {
2593
+ return false;
2594
+ }
2595
+ const code = error.code;
2596
+ return code === MCP_AUTH_NEEDED_ERROR_CODE || error.message.includes(MCP_AUTH_NEEDED_MESSAGE);
2597
+ }
2242
2598
  async function mcpServerRequestInit(settings, config, options) {
2243
2599
  if (isCodexAppsMcpServer(config)) {
2244
2600
  return await codexAppsMcpRequestInit(settings);
@@ -2382,7 +2738,7 @@ function normalizeUrl(raw) {
2382
2738
  }
2383
2739
  }
2384
2740
  function prefixedMcpToolName(registryId, toolName) {
2385
- return `${registryId}__${toolName}`;
2741
+ return sharedPrefixedMcpToolName(registryId, toolName);
2386
2742
  }
2387
2743
  var PrefixedMcpServer = class {
2388
2744
  constructor(inner, registryId, allowedTools) {
@@ -2412,7 +2768,14 @@ var PrefixedMcpServer = class {
2412
2768
  if (!this.isAllowed(unprefixed)) {
2413
2769
  throw new Error(`MCP tool ${unprefixed} is not allowed for server ${this.name}`);
2414
2770
  }
2415
- return await this.inner.callTool(unprefixed, args, meta);
2771
+ try {
2772
+ return await this.inner.callTool(unprefixed, args, meta);
2773
+ } catch (error) {
2774
+ if (isAuthNeededMcpError(error)) {
2775
+ return { isError: true, content: [{ type: "text", text: MCP_AUTH_NEEDED_MESSAGE }] };
2776
+ }
2777
+ throw error;
2778
+ }
2416
2779
  }
2417
2780
  invalidateToolsCache() {
2418
2781
  return this.inner.invalidateToolsCache();
@@ -2623,15 +2986,18 @@ async function runAgentStream(agent, input, settings, overrides = {}) {
2623
2986
  ...runAs2 ? { runAs: runAs2 } : {}
2624
2987
  }) : ownedClient;
2625
2988
  const ownedGitTokenSeed = gitTokenSeedForAgent(agent);
2989
+ const ownedToolspaceTokenSeed = toolspaceTokenSeedForAgent(agent);
2626
2990
  const ownedHooks = [
2627
2991
  ...sandboxLifecycleHooksForIds(sandboxLifecycleHookIds(settings)),
2992
+ ...sandboxToolspaceTokenHooksForAgent(agent),
2628
2993
  ...sandboxRepositoryCloneHooksForAgent(agent)
2629
2994
  ];
2630
2995
  const ownedHookContext = {
2631
2996
  environment,
2632
2997
  ...overrides.onRuntimeEvent ? { onRuntimeEvent: overrides.onRuntimeEvent } : {},
2633
2998
  ...runAs2 ? { runAs: runAs2 } : {},
2634
- ...ownedGitTokenSeed ? { gitTokenSeed: ownedGitTokenSeed } : {}
2999
+ ...ownedGitTokenSeed ? { gitTokenSeed: ownedGitTokenSeed } : {},
3000
+ ...ownedToolspaceTokenSeed ? { toolspaceTokenSeed: ownedToolspaceTokenSeed } : {}
2635
3001
  };
2636
3002
  if (agentActiveSandboxBackend.get(agent) !== "selfhosted") {
2637
3003
  await runBeforeAgentStartHooks(setupSession, ownedHooks, ownedHookContext);
@@ -2675,14 +3041,17 @@ async function runAgentStream(agent, input, settings, overrides = {}) {
2675
3041
  ...runAs ? { runAs } : {}
2676
3042
  }) : refreshedClient;
2677
3043
  const gitTokenSeed = gitTokenSeedForAgent(agent);
3044
+ const toolspaceTokenSeed = toolspaceTokenSeedForAgent(agent);
2678
3045
  const client = resourceClient ? withSandboxLifecycleHooks(resourceClient, [
2679
3046
  ...sandboxLifecycleHooksForIds(sandboxLifecycleHookIds(settings)),
3047
+ ...sandboxToolspaceTokenHooksForAgent(agent),
2680
3048
  ...sandboxRepositoryCloneHooksForAgent(agent)
2681
3049
  ], {
2682
3050
  environment,
2683
3051
  ...overrides.onRuntimeEvent ? { onRuntimeEvent: overrides.onRuntimeEvent } : {},
2684
3052
  ...runAs ? { runAs } : {},
2685
- ...gitTokenSeed ? { gitTokenSeed } : {}
3053
+ ...gitTokenSeed ? { gitTokenSeed } : {},
3054
+ ...toolspaceTokenSeed ? { toolspaceTokenSeed } : {}
2686
3055
  }) : void 0;
2687
3056
  const sandboxSessionState = prepared.sandboxSessionState ?? (prepared.serializedRunStateForSandbox && client ? await restoredSandboxSessionState(await RunState.fromString(agent, prepared.serializedRunStateForSandbox), client) : void 0);
2688
3057
  const callModelInputFilter = composeCallModelInputFilters(
@@ -3356,6 +3725,16 @@ function sandboxRepositoryCloneHooksForAgent(agent) {
3356
3725
  function gitTokenSeedForAgent(agent) {
3357
3726
  return agentGitTokenSeed.get(agent);
3358
3727
  }
3728
+ function toolspaceTokenSeedForAgent(agent) {
3729
+ return agentToolspaceTokenSeed.get(agent);
3730
+ }
3731
+ function sandboxToolspaceTokenHooksForAgent(agent) {
3732
+ return toolspaceTokenSeedForAgent(agent) ? [{
3733
+ id: "toolspace-token",
3734
+ phase: "beforeAgentStart",
3735
+ run: runToolspaceTokenSeedHook
3736
+ }] : [];
3737
+ }
3359
3738
  function sandboxRepositoryCloneHooks(settings, resources, activeSandboxBackend = settings.sandboxBackend) {
3360
3739
  const repositories = resources.filter((resource) => resource.kind === "repository" && repositoryUsesSandboxClone(settings, resource, activeSandboxBackend));
3361
3740
  if (repositories.length === 0) {
@@ -3526,6 +3905,49 @@ function repositoryCloneCommand(resources) {
3526
3905
  }
3527
3906
  return commands.join("\n");
3528
3907
  }
3908
+ function toolspaceTokenSeedCommand() {
3909
+ return [
3910
+ "set -eu",
3911
+ 'export HOME="${HOME:-/workspace}"',
3912
+ 'if [ -n "${OPENGENI_TOOLSPACE_TOKEN_SEED:-}" ]; then',
3913
+ ' seed_umask="$(umask)"',
3914
+ " umask 077",
3915
+ ' token_file="${OPENGENI_TOOLSPACE_TOKEN_FILE:-$HOME/.opengeni/toolspace-token}"',
3916
+ ' mkdir -p "$(dirname "$token_file")"',
3917
+ ` printf '%s' "$OPENGENI_TOOLSPACE_TOKEN_SEED" > "$token_file.tmp.$$"`,
3918
+ ' mv -f "$token_file.tmp.$$" "$token_file"',
3919
+ ' umask "$seed_umask"',
3920
+ "fi"
3921
+ ].join("\n");
3922
+ }
3923
+ async function runToolspaceTokenSeedHook(session, context) {
3924
+ if (!context.toolspaceTokenSeed) {
3925
+ return;
3926
+ }
3927
+ const command = `export OPENGENI_TOOLSPACE_TOKEN_SEED=${shellQuote(context.toolspaceTokenSeed)}
3928
+ ${toolspaceTokenSeedCommand()}`;
3929
+ if (session.exec) {
3930
+ const result = await session.exec({
3931
+ cmd: command,
3932
+ workdir: "/workspace",
3933
+ ...context.runAs ? { runAs: context.runAs } : {},
3934
+ yieldTimeMs: SANDBOX_LIFECYCLE_COMMAND_TIMEOUT_MS,
3935
+ maxOutputTokens: 4e3
3936
+ });
3937
+ assertSandboxCommandSucceeded(result, "Toolspace token seed hook");
3938
+ } else if (session.execCommand) {
3939
+ const result = await session.execCommand({
3940
+ cmd: command,
3941
+ workdir: "/workspace",
3942
+ ...context.runAs ? { runAs: context.runAs } : {},
3943
+ yieldTimeMs: SANDBOX_LIFECYCLE_COMMAND_TIMEOUT_MS,
3944
+ maxOutputTokens: 4e3
3945
+ });
3946
+ assertSandboxCommandSucceeded(result, "Toolspace token seed hook");
3947
+ } else {
3948
+ throw new Error("Sandbox session does not support command execution");
3949
+ }
3950
+ }
3529
3951
  async function runRepositoryCloneHook(session, resources, context = { environment: {} }) {
3530
3952
  const payload = { name: "repository-clone", repositoryCount: resources.length };
3531
3953
  await context.onRuntimeEvent?.({ type: "sandbox.operation.started", payload });
@@ -3874,7 +4296,6 @@ function approvalIdentifier(item) {
3874
4296
  export {
3875
4297
  ActiveBackendUnresolvableError,
3876
4298
  CAPABILITY_DESCRIPTORS,
3877
- CLIENT_COMPACTION_TRIGGER_FRACTION,
3878
4299
  COMPACTION_PROMPT,
3879
4300
  COMPACTION_SUMMARY_MARKER,
3880
4301
  COMPACT_USER_MESSAGE_MAX_TOKENS,
@@ -3888,12 +4309,15 @@ export {
3888
4309
  ComputerReadOnlyError,
3889
4310
  ComputerUnavailableError,
3890
4311
  ComputerUseCapability,
4312
+ DEFAULT_COMPACTION_THRESHOLD_RATIO,
3891
4313
  DEFAULT_DESKTOP_GEOMETRY,
3892
4314
  DESKTOP_STREAM_PORT,
3893
4315
  DISPLAY_STACK_TIMEOUT_MS,
3894
4316
  DisplayStackError,
3895
4317
  DisplayStackUnsupportedError,
3896
4318
  GENESIS_TITLE_DIRECTIVE,
4319
+ MAX_COMPACTION_THRESHOLD_RATIO,
4320
+ MIN_COMPACTION_THRESHOLD_RATIO,
3897
4321
  MaxTurnsExceededError2 as MaxTurnsExceededError,
3898
4322
  MockAgentResponder,
3899
4323
  MultiProviderModelProvider,
@@ -3941,6 +4365,7 @@ export {
3941
4365
  buildAgentCapabilities,
3942
4366
  buildCompactionPromptInput,
3943
4367
  buildCompactionReplacementHistory,
4368
+ buildDeterministicFallbackCompactionHistory,
3944
4369
  buildDisplayStackScript,
3945
4370
  buildManifest,
3946
4371
  buildModelInstance,
@@ -3952,6 +4377,7 @@ export {
3952
4377
  buildSummaryItem,
3953
4378
  buildTerminalServerScript,
3954
4379
  callModelInputFilterForSettings,
4380
+ clampCompactionThresholdRatio,
3955
4381
  clientCompactionThresholdTokens,
3956
4382
  collectSandboxEnvironment,
3957
4383
  composeAgentInstructions,
@@ -3993,6 +4419,7 @@ export {
3993
4419
  makeActiveBackendResolver,
3994
4420
  materializeSandboxFileDownloads,
3995
4421
  maxTurnsExceededRunState,
4422
+ mcpToolErrorOutput,
3996
4423
  mintStreamToken,
3997
4424
  modalSandboxAttributionEnvironment,
3998
4425
  modalSandboxAttributionTags,
@@ -4025,6 +4452,7 @@ export {
4025
4452
  runAzureCliLoginHook,
4026
4453
  runBeforeAgentStartHooks,
4027
4454
  runRepositoryCloneHook,
4455
+ runToolspaceTokenSeedHook,
4028
4456
  sandboxCommandExitCode,
4029
4457
  sandboxCommandOutput,
4030
4458
  sandboxCommandStillRunning,
@@ -4053,6 +4481,7 @@ export {
4053
4481
  terminateModalSandboxById,
4054
4482
  timeoutAgentError,
4055
4483
  timeoutControlResponse,
4484
+ toolspaceTokenSeedCommand,
4056
4485
  verifyStreamToken,
4057
4486
  withManifestRefreshOnResume,
4058
4487
  withSandboxFileDownloads,