@opengeni/runtime 4.6.0 → 4.7.0-canary.37090756480001

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.
Files changed (72) hide show
  1. package/dist/agent-instructions/modules/media.d.ts +3 -0
  2. package/dist/anthropic-messages.d.ts +13 -3
  3. package/dist/anthropic-request-error.d.ts +10 -0
  4. package/dist/assets/codemode-client.json +1 -1
  5. package/dist/{chunk-A22BKN4P.js → chunk-LJNCGUMB.js} +3 -3
  6. package/dist/chunk-LJNCGUMB.js.map +1 -0
  7. package/dist/{chunk-GTWKWJ67.js → chunk-P2OVGKDG.js} +505 -100
  8. package/dist/chunk-P2OVGKDG.js.map +1 -0
  9. package/dist/{chunk-D5DPVA2C.js → chunk-R25L27T3.js} +2047 -1275
  10. package/dist/chunk-R25L27T3.js.map +1 -0
  11. package/dist/claude-subscription-usage.d.ts +14 -4
  12. package/dist/context-compaction.d.ts +7 -7
  13. package/dist/index.d.ts +2 -0
  14. package/dist/index.js +13 -3
  15. package/dist/interaction-tools.d.ts +1 -1
  16. package/dist/mcp-network.js +1 -1
  17. package/dist/runtime-skills.d.ts +1 -0
  18. package/dist/sandbox/channel-a.d.ts +3 -0
  19. package/dist/sandbox/index.d.ts +3 -1
  20. package/dist/sandbox/index.js +7 -1
  21. package/dist/sandbox/provider-command-session.d.ts +21 -0
  22. package/dist/sandbox/providers/modal-command-argv.d.ts +4 -0
  23. package/dist/sandbox/providers/modal-command-control.d.ts +17 -5
  24. package/dist/sandbox/providers/modal-command-observation-errors.d.ts +3 -0
  25. package/dist/sandbox/providers/modal-command-raw-page.d.ts +100 -0
  26. package/dist/sandbox/providers/modal-command-router-wire.d.ts +17 -0
  27. package/dist/sandbox/routing/routing-session.d.ts +10 -0
  28. package/dist/sandbox/turn-tool-cancellation.d.ts +4 -0
  29. package/dist/workspace-tool-gateway.js +3 -3
  30. package/package.json +12 -12
  31. package/src/agent-instructions/PROMPT_CHANGELOG.md +23 -1
  32. package/src/agent-instructions/compose.ts +2 -0
  33. package/src/agent-instructions/modules/media.ts +20 -0
  34. package/src/agent-instructions/runtime-mechanics.ts +8 -0
  35. package/src/anthropic-messages.ts +223 -31
  36. package/src/anthropic-request-error.ts +45 -0
  37. package/src/bundled_default_skills/opengeni-client/SKILL.md +9 -7
  38. package/src/bundled_default_skills/opengeni-client/references/agent-recipes.md +1 -1
  39. package/src/bundled_default_skills/opengeni-client/references/api-workflows.md +61 -0
  40. package/src/bundled_default_skills/opengeni-client/references/compatibility-and-troubleshooting.md +86 -0
  41. package/src/bundled_default_skills/opengeni-client/references/data-tools-and-credentials.md +82 -0
  42. package/src/bundled_default_skills/opengeni-client/references/discovery-and-autonomy.md +32 -25
  43. package/src/bundled_default_skills/opengeni-client/references/external-users-and-connect.md +17 -0
  44. package/src/bundled_default_skills/opengeni-client/references/product-shapes-and-ui.md +156 -0
  45. package/src/bundled_schedule_skills/opengeni-schedules/SKILL.md +56 -0
  46. package/src/claude-subscription-usage.ts +55 -9
  47. package/src/context-compaction.ts +16 -9
  48. package/src/index.ts +85 -18
  49. package/src/interaction-tools.ts +113 -3
  50. package/src/lazy-tool-transport.ts +26 -10
  51. package/src/mcp-network.ts +4 -2
  52. package/src/model-provider-client.ts +11 -3
  53. package/src/model-provider-routing.ts +4 -0
  54. package/src/runtime-skills.ts +8 -0
  55. package/src/sandbox/channel-a.ts +3 -0
  56. package/src/sandbox/index.ts +11 -1
  57. package/src/sandbox/provider-command-session.ts +58 -0
  58. package/src/sandbox/provider-errors.ts +43 -9
  59. package/src/sandbox/providers/modal-command-argv.ts +20 -0
  60. package/src/sandbox/providers/modal-command-control.ts +422 -116
  61. package/src/sandbox/providers/modal-command-observation-errors.ts +65 -0
  62. package/src/sandbox/providers/modal-command-raw-page.ts +147 -0
  63. package/src/sandbox/providers/modal-command-router-wire.ts +104 -12
  64. package/src/sandbox/providers/modal-command-session.ts +26 -4
  65. package/src/sandbox/providers/modal-legacy-command-control.ts +2 -9
  66. package/src/sandbox/providers/modal-materialization-verification.ts +70 -6
  67. package/src/sandbox/routing/routing-session.ts +140 -41
  68. package/src/sandbox/run-credentials.ts +62 -19
  69. package/src/sandbox/turn-tool-cancellation.ts +159 -42
  70. package/dist/chunk-A22BKN4P.js.map +0 -1
  71. package/dist/chunk-D5DPVA2C.js.map +0 -1
  72. package/dist/chunk-GTWKWJ67.js.map +0 -1
@@ -10,6 +10,7 @@ import {
10
10
  isDefinitePathNotFoundError,
11
11
  isModalCommandStartOutcomeUnknownError,
12
12
  isModalTaskExecStartPreDispatchUnavailableError,
13
+ isProviderCommandObservationUnavailableError,
13
14
  isRoutingMutationOutcomeUnknownError,
14
15
  loadManagedCodemodeClient,
15
16
  managedCodemodeClientDirectory,
@@ -29,7 +30,7 @@ import {
29
30
  withRunCredentialsClient,
30
31
  withRunCredentialsSession,
31
32
  wrapCapabilityToolsForTurnCancellation
32
- } from "./chunk-D5DPVA2C.js";
33
+ } from "./chunk-R25L27T3.js";
33
34
  import {
34
35
  MemorySession,
35
36
  connectMcpServers
@@ -62,7 +63,7 @@ import {
62
63
  mcpRequestReplayInfo,
63
64
  mcpSerializedSizeBytes,
64
65
  undiciFetch
65
- } from "./chunk-A22BKN4P.js";
66
+ } from "./chunk-LJNCGUMB.js";
66
67
  import {
67
68
  GMAIL_REST_MCP_BRIDGE_ADAPTER
68
69
  } from "./chunk-YU4VRTR4.js";
@@ -681,6 +682,9 @@ function itemRole(item) {
681
682
  function isUserMessage(item) {
682
683
  return itemType2(item) === "message" && itemRole(item) === "user";
683
684
  }
685
+ function isPortableInputMessage(item) {
686
+ return isUserMessage(item) || itemType2(item) === "message" && itemRole(item) === "system";
687
+ }
684
688
  function isCompactionSummary(item) {
685
689
  return isUserMessage(item) && item[COMPACTION_SUMMARY_MARKER] === true;
686
690
  }
@@ -1612,7 +1616,7 @@ function buildCompactionReplacementHistory(items, summaryBody, retainedItemToken
1612
1616
  );
1613
1617
  for (let index = items.length - 1; index >= 0 && remaining > 0; index -= 1) {
1614
1618
  const item = items[index];
1615
- if (!isUserMessage(item) || isCompactionSummary(item) || isAttachmentCatalog(item)) {
1619
+ if (!isPortableInputMessage(item) || isCompactionSummary(item) || isAttachmentCatalog(item)) {
1616
1620
  continue;
1617
1621
  }
1618
1622
  const textTokens = estimateTextTokens(messageText(item));
@@ -1644,7 +1648,7 @@ function isRetainedRemoteV2Message(item) {
1644
1648
  return false;
1645
1649
  }
1646
1650
  const role = itemRole(item);
1647
- return itemType2(item) === "message" && (role === "user" || role === "developer");
1651
+ return itemType2(item) === "message" && (role === "user" || role === "system" || role === "developer");
1648
1652
  }
1649
1653
  function buildRemoteV2ReplacementHistory(items, compactionItem, retainedItemTokens = (item) => estimateTokens([item])) {
1650
1654
  if (!isRemoteCompactionItem(compactionItem)) {
@@ -2031,6 +2035,39 @@ function applyClaudeCodeIdentity(body, headers, url, request, account, identity2
2031
2035
  body.system = [{ type: "text", text: billing }, ...body.system ?? []];
2032
2036
  }
2033
2037
 
2038
+ // src/anthropic-request-error.ts
2039
+ import { Buffer as Buffer2 } from "buffer";
2040
+ function bounded(value, maxBytes) {
2041
+ if (typeof value !== "string" || !value) return void 0;
2042
+ const bytes = Buffer2.from(value);
2043
+ if (bytes.length <= maxBytes) return value;
2044
+ const marker = "\u2026 [truncated]";
2045
+ let end = maxBytes - Buffer2.byteLength(marker);
2046
+ while (end > 0 && (bytes[end] & 192) === 128) end -= 1;
2047
+ return bytes.subarray(0, end).toString("utf8") + marker;
2048
+ }
2049
+ var AnthropicRequestError = class extends Error {
2050
+ constructor(message, status, code, source, headers) {
2051
+ super(message);
2052
+ this.status = status;
2053
+ this.code = code;
2054
+ this.name = "AnthropicRequestError";
2055
+ const error = source && typeof source === "object" && !Array.isArray(source) ? source : void 0;
2056
+ const type = bounded(error?.type, 256);
2057
+ const detail = bounded(error?.message, 4096);
2058
+ this.#detail = bounded([type, detail].filter(Boolean).join(": "), 4096);
2059
+ this.request_id = bounded(headers.get("request-id"), 256) ?? null;
2060
+ const retryAfter = bounded(headers.get("retry-after"), 256);
2061
+ this.headers = retryAfter ? { "retry-after": retryAfter } : {};
2062
+ }
2063
+ request_id;
2064
+ headers;
2065
+ #detail;
2066
+ get detail() {
2067
+ return this.#detail;
2068
+ }
2069
+ };
2070
+
2034
2071
  // ../../node_modules/.bun/@openai+agents-openai@0.14.3+933c5e7db4cd33c2/node_modules/@openai/agents-openai/dist/openaiProvider.mjs
2035
2072
  import OpenAI3 from "openai";
2036
2073
 
@@ -8592,10 +8629,97 @@ var BACKGROUND_RESULT_SYMBOL = Symbol("backgroundResult");
8592
8629
  setDefaultModelProvider(new OpenAIProvider({ cacheResponsesWebSocketModels: false }));
8593
8630
  setDefaultOpenAITracingExporter();
8594
8631
 
8632
+ // src/anthropic-messages.ts
8633
+ import { claudeNativeModelProfile } from "@opengeni/config";
8634
+
8635
+ // src/claude-subscription-usage.ts
8636
+ import { AsyncLocalStorage as AsyncLocalStorage2 } from "async_hooks";
8637
+ var observers = new AsyncLocalStorage2();
8638
+ var modelRequests = new AsyncLocalStorage2();
8639
+ function withClaudeModelRequest(upstreamModelId, run2) {
8640
+ return modelRequests.run(upstreamModelId, run2);
8641
+ }
8642
+ function withClaudeUsageObserver(observer, run2, prepare) {
8643
+ return observers.run({ observe: observer, ...prepare ? { prepare } : {} }, run2);
8644
+ }
8645
+ async function prepareClaudeSubscriptionRequest(providerId, input, init) {
8646
+ const context = observers.getStore();
8647
+ const upstreamModelId = modelRequests.getStore();
8648
+ let observe = context?.observe;
8649
+ if (context?.prepare) {
8650
+ const headers = new Headers(input instanceof Request ? input.headers : void 0);
8651
+ new Headers(init?.headers).forEach((value, key) => headers.set(key, value));
8652
+ const prepared = await context.prepare(providerId, headers);
8653
+ init = { ...init, headers: prepared instanceof Headers ? prepared : prepared.headers };
8654
+ if (!(prepared instanceof Headers)) observe = prepared.observe;
8655
+ }
8656
+ return {
8657
+ init,
8658
+ observe(response, requestToken) {
8659
+ try {
8660
+ observe?.(providerId, response, upstreamModelId, requestToken);
8661
+ } catch {
8662
+ }
8663
+ }
8664
+ };
8665
+ }
8666
+ function captureClaudeRequestToken(input, init) {
8667
+ if (!observers.getStore()) return void 0;
8668
+ const headers = new Headers(
8669
+ init?.headers !== void 0 ? init.headers : input instanceof Request ? input.headers : void 0
8670
+ );
8671
+ return headers.get("authorization")?.match(/^Bearer (.+)$/i)?.[1] ?? null;
8672
+ }
8673
+
8595
8674
  // src/anthropic-messages.ts
8596
8675
  var AnthropicProtocolError = class extends Error {
8597
8676
  code = "anthropic_protocol_error";
8598
8677
  };
8678
+ var AnthropicProviderRejection = class extends Error {
8679
+ constructor(code, status, request_id, suspendedUntil, headers = {}) {
8680
+ super(
8681
+ code === "anthropic_model_access_suspended" ? suspendedUntil ? `Claude suspended access to this model for the connected account until ${suspendedUntil.replace("T", " ").replace(/(?:\.000)?Z$/, " UTC")}. Try again after that time.` : "Claude suspended access to this model for the connected account. Signing in again will not lift this restriction." : code === "content_policy_violation" ? "Claude blocked this request through its safety systems. Automatic retries stopped." : "Claude denied this request (HTTP 403). Check the connected account's permissions."
8682
+ );
8683
+ this.code = code;
8684
+ this.status = status;
8685
+ this.request_id = request_id;
8686
+ this.suspendedUntil = suspendedUntil;
8687
+ this.headers = headers;
8688
+ }
8689
+ name = "AnthropicProviderRejection";
8690
+ };
8691
+ function suspensionDeadline(error) {
8692
+ if (typeof error.message !== "string") return void 0;
8693
+ const raw = /^model: "[A-Za-z0-9._:/-]{1,128}" is suspended for this organization until (\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d{3})?Z)$/.exec(
8694
+ error.message
8695
+ )?.[1];
8696
+ if (!raw) return void 0;
8697
+ const date = new Date(raw);
8698
+ if (!Number.isFinite(date.getTime())) return void 0;
8699
+ const normalized = date.toISOString();
8700
+ return normalized.replace(/\.000Z$/, "Z") === raw.replace(/\.000Z$/, "Z") ? normalized : void 0;
8701
+ }
8702
+ function providerRejection(status, detail, responseHeaders) {
8703
+ if (status !== 403) return void 0;
8704
+ const requestId = responseHeaders.get("request-id") ?? void 0;
8705
+ const headers = responseHeaders.has("retry-after") ? { "retry-after": responseHeaders.get("retry-after") } : {};
8706
+ const error = detail && typeof detail === "object" && !Array.isArray(detail) ? detail : {};
8707
+ if (error.type === "permission_error" && error.details?.error_code === "model_access_suspended")
8708
+ return new AnthropicProviderRejection(
8709
+ "anthropic_model_access_suspended",
8710
+ status,
8711
+ requestId,
8712
+ suspensionDeadline(error),
8713
+ headers
8714
+ );
8715
+ return new AnthropicProviderRejection(
8716
+ "anthropic_permission_denied",
8717
+ status,
8718
+ requestId,
8719
+ void 0,
8720
+ headers
8721
+ );
8722
+ }
8599
8723
  function object(value) {
8600
8724
  if (!value || typeof value !== "object" || Array.isArray(value)) {
8601
8725
  throw new AnthropicProtocolError("Expected an object in the Claude protocol");
@@ -8791,6 +8915,37 @@ ${JSON.stringify(item)}`
8791
8915
  if (pending.size) throw new AnthropicProtocolError("Claude tool results are missing");
8792
8916
  return messages;
8793
8917
  }
8918
+ function placeConversationSystems(messages) {
8919
+ const result = [];
8920
+ let systems = [];
8921
+ const flush = () => {
8922
+ if (!systems.length) return;
8923
+ if (result.at(-1)?.role !== "user")
8924
+ result.push({
8925
+ role: "user",
8926
+ content: [
8927
+ {
8928
+ type: "text",
8929
+ text: "OpenGeni continuation (machine-origin input; no new human message)."
8930
+ }
8931
+ ]
8932
+ });
8933
+ result.push({ role: "system", content: systems });
8934
+ systems = [];
8935
+ };
8936
+ for (const message of messages) {
8937
+ if (message.role === "system") {
8938
+ systems.push(...message.content);
8939
+ continue;
8940
+ }
8941
+ if (message.role === "assistant") flush();
8942
+ const previous = result.at(-1);
8943
+ if (previous?.role === message.role) previous.content.push(...message.content);
8944
+ else result.push(message);
8945
+ }
8946
+ flush();
8947
+ return result;
8948
+ }
8794
8949
  function buildAnthropicRequest(request, model, provider, stream) {
8795
8950
  if (request.previousResponseId || request.conversationId)
8796
8951
  throw new AnthropicProtocolError(
@@ -8799,6 +8954,9 @@ function buildAnthropicRequest(request, model, provider, stream) {
8799
8954
  if (request.prompt)
8800
8955
  throw new AnthropicProtocolError("OpenAI prompt templates cannot be used with Claude");
8801
8956
  const settings = request.modelSettings;
8957
+ const profile = claudeNativeModelProfile(model);
8958
+ const managed = provider.kind === "anthropic-workspace" || provider.kind === "anthropic-organization" || provider.kind === "claude-subscription-workspace" || provider.kind === "claude-subscription-organization";
8959
+ const outputLimit = profile?.maxOutputTokens ?? (managed ? 32e3 : void 0);
8802
8960
  const names = toolNames(request);
8803
8961
  const forcedName = (name) => {
8804
8962
  const matches = [...names].filter(([, identity2]) => identity2.name === name);
@@ -8808,11 +8966,12 @@ function buildAnthropicRequest(request, model, provider, stream) {
8808
8966
  );
8809
8967
  return matches[0][0];
8810
8968
  };
8811
- const messages = anthropicMessages(request.input);
8969
+ let messages = anthropicMessages(request.input);
8812
8970
  if (!messages.length) throw new AnthropicProtocolError("Claude requires at least one message");
8813
8971
  const system = request.systemInstructions ? [{ type: "text", text: request.systemInstructions }] : [];
8814
8972
  while (messages[0]?.role === "system") system.push(...messages.shift().content);
8815
8973
  if (!messages.length) throw new AnthropicProtocolError("Claude requires a conversation message");
8974
+ messages = placeConversationSystems(messages);
8816
8975
  const tools = request.tools.map((tool2) => {
8817
8976
  if (tool2.type !== "function")
8818
8977
  throw new AnthropicProtocolError(`Claude does not support the ${tool2.type} tool transport`);
@@ -8846,7 +9005,10 @@ function buildAnthropicRequest(request, model, provider, stream) {
8846
9005
  }
8847
9006
  const body = {
8848
9007
  model,
8849
- max_tokens: settings.maxTokens ?? provider.anthropic?.maxOutputTokens ?? 32e3,
9008
+ max_tokens: Math.min(
9009
+ settings.maxTokens ?? provider.anthropic?.maxOutputTokens ?? profile?.maxOutputTokens ?? 32e3,
9010
+ outputLimit ?? Infinity
9011
+ ),
8850
9012
  messages,
8851
9013
  stream
8852
9014
  };
@@ -8859,12 +9021,18 @@ function buildAnthropicRequest(request, model, provider, stream) {
8859
9021
  ...body.tool_choice ?? { type: "auto" },
8860
9022
  disable_parallel_tool_use: true
8861
9023
  };
8862
- const effort = settings.reasoning?.effort;
9024
+ const requestedEffort = settings.reasoning?.effort;
9025
+ const effort = requestedEffort === "minimal" ? "low" : requestedEffort;
9026
+ const supportsThinking = profile ? profile.efforts.length > 0 : !managed;
8863
9027
  const forcedTool = body.tool_choice?.type === "any" || body.tool_choice?.type === "tool";
8864
- if (effort && effort !== "none" && !forcedTool) {
9028
+ if (supportsThinking && effort && effort !== "none" && !forcedTool) {
9029
+ if (profile && !profile.efforts.includes(effort))
9030
+ throw new AnthropicProtocolError(
9031
+ "The selected Claude model does not support this reasoning effort"
9032
+ );
8865
9033
  body.thinking = { type: "adaptive" };
8866
9034
  body.output_config = {
8867
- effort: effort === "minimal" ? "low" : effort === "xhigh" ? "high" : effort
9035
+ effort
8868
9036
  };
8869
9037
  } else if (settings.temperature !== void 0) body.temperature = settings.temperature;
8870
9038
  if (settings.topP !== void 0 && !body.thinking) body.top_p = settings.topP;
@@ -8896,9 +9064,9 @@ function normalizeUsage(raw) {
8896
9064
  });
8897
9065
  }
8898
9066
  function anthropicResponse(message, requestId, names = /* @__PURE__ */ new Map()) {
8899
- if (!["end_turn", "tool_use", "stop_sequence", "max_tokens", "refusal"].includes(
8900
- message.stop_reason
8901
- ))
9067
+ if (message.stop_reason === "refusal")
9068
+ throw new AnthropicProviderRejection("content_policy_violation", 200, requestId);
9069
+ if (!["end_turn", "tool_use", "stop_sequence", "max_tokens"].includes(message.stop_reason))
8902
9070
  throw new AnthropicProtocolError(`Claude response did not finish: ${message.stop_reason}`);
8903
9071
  text(message.id, "message ID");
8904
9072
  if (!Array.isArray(message.content))
@@ -8973,6 +9141,7 @@ var AnthropicMessagesModel = class {
8973
9141
  promptId = randomUUID2();
8974
9142
  previousRequestId;
8975
9143
  async send(request, stream) {
9144
+ request.signal?.throwIfAborted();
8976
9145
  const body = buildAnthropicRequest(request, this.model, this.provider, stream);
8977
9146
  const base = this.provider.baseUrl ?? "https://api.anthropic.com/v1";
8978
9147
  const url = new URL(`${base.replace(/\/$/, "")}/messages`);
@@ -8982,6 +9151,11 @@ var AnthropicMessagesModel = class {
8982
9151
  headers.set("content-type", "application/json");
8983
9152
  headers.set("accept", stream ? "text/event-stream" : "application/json");
8984
9153
  headers.set("anthropic-version", "2023-06-01");
9154
+ if ((claudeNativeModelProfile(this.model)?.contextWindowTokens ?? 0) > 2e5) {
9155
+ const betas = new Set((headers.get("anthropic-beta") ?? "").split(",").filter(Boolean));
9156
+ betas.add("context-1m-2025-08-07");
9157
+ headers.set("anthropic-beta", [...betas].join(","));
9158
+ }
8985
9159
  if (body.messages.some((message) => message.role === "system")) {
8986
9160
  const betas = new Set((headers.get("anthropic-beta") ?? "").split(",").filter(Boolean));
8987
9161
  betas.add("mid-conversation-system-2026-04-07");
@@ -9015,12 +9189,19 @@ var AnthropicMessagesModel = class {
9015
9189
  previousRequestId: this.previousRequestId
9016
9190
  });
9017
9191
  }
9018
- const response = await this.fetch(url, {
9019
- method: "POST",
9020
- headers,
9021
- body: JSON.stringify(body),
9022
- ...request.signal ? { signal: request.signal } : {}
9023
- });
9192
+ const response = await withClaudeModelRequest(
9193
+ this.model,
9194
+ () => this.fetch(url, {
9195
+ method: "POST",
9196
+ headers,
9197
+ body: JSON.stringify(body),
9198
+ ...request.signal ? { signal: request.signal } : {}
9199
+ })
9200
+ );
9201
+ if (request.signal?.aborted) {
9202
+ void response.body?.cancel().catch(() => void 0);
9203
+ request.signal.throwIfAborted();
9204
+ }
9024
9205
  if (!response.ok) {
9025
9206
  const detail = await readErrorDetail(
9026
9207
  response.body,
@@ -9028,13 +9209,26 @@ var AnthropicMessagesModel = class {
9028
9209
  request.signal
9029
9210
  );
9030
9211
  const contextExceeded = response.status === 400 && /prompt is too long|context_length_exceeded|exceeds.*context window/i.test(detail);
9212
+ let providerError;
9213
+ try {
9214
+ providerError = JSON.parse(detail).error;
9215
+ } catch {
9216
+ }
9217
+ const rejection = providerRejection(response.status, providerError, response.headers);
9218
+ if (rejection) throw rejection;
9031
9219
  const message = contextExceeded ? "Claude context window exceeded" : response.status === 401 ? "Claude credentials expired or were revoked. Replace the key or setup token in Models." : "Claude request failed (HTTP " + response.status + ")";
9032
- throw Object.assign(new Error(message), {
9033
- status: response.status,
9034
- request_id: response.headers.get("request-id"),
9035
- headers: response.headers.has("retry-after") ? { "retry-after": response.headers.get("retry-after") } : {},
9036
- code: contextExceeded ? "context_length_exceeded" : "anthropic_http_error"
9037
- });
9220
+ let source;
9221
+ try {
9222
+ source = JSON.parse(detail)?.error;
9223
+ } catch {
9224
+ }
9225
+ throw new AnthropicRequestError(
9226
+ message,
9227
+ response.status,
9228
+ contextExceeded ? "context_length_exceeded" : "anthropic_http_error",
9229
+ source,
9230
+ response.headers
9231
+ );
9038
9232
  }
9039
9233
  this.previousRequestId = response.headers.get("request-id") ?? void 0;
9040
9234
  return response;
@@ -9055,7 +9249,8 @@ var AnthropicMessagesModel = class {
9055
9249
  let finalDelta = false;
9056
9250
  for await (const event of anthropicSse(
9057
9251
  response.body,
9058
- this.provider.anthropic?.streamIdleTimeoutMs ?? 6e5
9252
+ this.provider.anthropic?.streamIdleTimeoutMs ?? 6e5,
9253
+ request.signal
9059
9254
  )) {
9060
9255
  request.signal?.throwIfAborted();
9061
9256
  if (event.type === "error") {
@@ -9071,11 +9266,22 @@ var AnthropicMessagesModel = class {
9071
9266
  overloaded_error: 529
9072
9267
  };
9073
9268
  const status = typeof kind === "string" ? statuses[kind] ?? 502 : 502;
9269
+ const rejection = providerRejection(status, event.error, response.headers);
9270
+ if (rejection) throw rejection;
9074
9271
  throw Object.assign(new Error(`Claude stream failed (HTTP ${status})`), {
9075
9272
  status,
9076
9273
  code: status === 429 ? "rate_limit_exceeded" : "anthropic_stream_error",
9077
9274
  request_id: response.headers.get("request-id"),
9078
- headers: response.headers.has("retry-after") ? { "retry-after": response.headers.get("retry-after") } : {}
9275
+ headers: response.headers.has("retry-after") ? { "retry-after": response.headers.get("retry-after") } : {},
9276
+ // Keep the structural stream wrapper stable for provider rejection
9277
+ // guards while the typed cause keeps provider text private.
9278
+ cause: new AnthropicRequestError(
9279
+ `Claude stream failed (HTTP ${status})`,
9280
+ status,
9281
+ status === 429 ? "rate_limit_exceeded" : "anthropic_stream_error",
9282
+ event.error,
9283
+ response.headers
9284
+ )
9079
9285
  });
9080
9286
  }
9081
9287
  switch (event.type) {
@@ -9135,6 +9341,12 @@ var AnthropicMessagesModel = class {
9135
9341
  if (!message) throw new AnthropicProtocolError("Claude message_delta without a message");
9136
9342
  Object.assign(message, event.delta);
9137
9343
  message.usage = { ...message.usage, ...event.usage };
9344
+ if (message.stop_reason === "refusal")
9345
+ throw new AnthropicProviderRejection(
9346
+ "content_policy_violation",
9347
+ 200,
9348
+ response.headers.get("request-id") ?? void 0
9349
+ );
9138
9350
  finalDelta = true;
9139
9351
  break;
9140
9352
  case "message_stop": {
@@ -9157,23 +9369,38 @@ var AnthropicMessagesModel = class {
9157
9369
  throw new AnthropicProtocolError("Claude stream ended without message_stop");
9158
9370
  }
9159
9371
  };
9160
- async function* anthropicSse(body, idleTimeoutMs = 6e5) {
9372
+ async function* anthropicSse(body, idleTimeoutMs = 6e5, signal) {
9373
+ if (signal?.aborted) void body.cancel().catch(() => void 0);
9374
+ signal?.throwIfAborted();
9161
9375
  const reader = body.getReader();
9162
9376
  const decoder = new TextDecoder();
9163
9377
  let buffer = "";
9164
9378
  let data = [];
9165
9379
  try {
9166
9380
  while (true) {
9381
+ signal?.throwIfAborted();
9167
9382
  let timer;
9383
+ let onAbort;
9384
+ const aborted = new Promise((_, reject) => {
9385
+ if (signal) {
9386
+ onAbort = () => reject(signal.reason);
9387
+ signal.addEventListener("abort", onAbort, { once: true });
9388
+ if (signal.aborted) onAbort();
9389
+ }
9390
+ });
9168
9391
  const chunk = await Promise.race([
9169
9392
  reader.read(),
9393
+ aborted,
9170
9394
  new Promise((_, reject) => {
9171
9395
  timer = setTimeout(
9172
9396
  () => reject(new AnthropicProtocolError("Claude stream timed out waiting for data")),
9173
9397
  idleTimeoutMs
9174
9398
  );
9175
9399
  })
9176
- ]).finally(() => clearTimeout(timer));
9400
+ ]).finally(() => {
9401
+ clearTimeout(timer);
9402
+ if (signal && onAbort) signal.removeEventListener("abort", onAbort);
9403
+ });
9177
9404
  buffer += decoder.decode(chunk.value, { stream: !chunk.done });
9178
9405
  let newline;
9179
9406
  while ((newline = buffer.indexOf("\n")) >= 0) {
@@ -9187,7 +9414,7 @@ async function* anthropicSse(body, idleTimeoutMs = 6e5) {
9187
9414
  if (chunk.done) break;
9188
9415
  }
9189
9416
  } finally {
9190
- await reader.cancel().catch(() => void 0);
9417
+ void reader.cancel().catch(() => void 0);
9191
9418
  reader.releaseLock();
9192
9419
  }
9193
9420
  }
@@ -9516,13 +9743,13 @@ import OpenAI6 from "openai";
9516
9743
  import { types as utilTypes } from "util";
9517
9744
 
9518
9745
  // src/model-preparation-diagnostics.ts
9519
- import { AsyncLocalStorage as AsyncLocalStorage3 } from "async_hooks";
9746
+ import { AsyncLocalStorage as AsyncLocalStorage4 } from "async_hooks";
9520
9747
 
9521
9748
  // src/model-request-capture.ts
9522
- import { AsyncLocalStorage as AsyncLocalStorage2 } from "async_hooks";
9523
- var modelRequestCapture = new AsyncLocalStorage2();
9749
+ import { AsyncLocalStorage as AsyncLocalStorage3 } from "async_hooks";
9750
+ var modelRequestCapture = new AsyncLocalStorage3();
9524
9751
  var captureIndices = /* @__PURE__ */ new WeakMap();
9525
- var modelCallLifecycle = new AsyncLocalStorage2();
9752
+ var modelCallLifecycle = new AsyncLocalStorage3();
9526
9753
  function withModelCallLifecycle(lifecycle, fn) {
9527
9754
  return modelCallLifecycle.run(lifecycle, fn);
9528
9755
  }
@@ -9665,9 +9892,9 @@ var ModelRequestCaptureProvider = class {
9665
9892
  };
9666
9893
 
9667
9894
  // src/model-preparation-diagnostics.ts
9668
- var modelPreparationObserver = new AsyncLocalStorage3();
9669
- var modelTransportStartedObserver = new AsyncLocalStorage3();
9670
- var modelTransportAdmission = new AsyncLocalStorage3();
9895
+ var modelPreparationObserver = new AsyncLocalStorage4();
9896
+ var modelTransportStartedObserver = new AsyncLocalStorage4();
9897
+ var modelTransportAdmission = new AsyncLocalStorage4();
9671
9898
  var modelTransportRefusals = /* @__PURE__ */ new WeakMap();
9672
9899
  var ModelPreparationTraceProcessor = class {
9673
9900
  async onTraceStart(_trace) {
@@ -10447,26 +10674,6 @@ function withoutQuotaExhaustedRetries(inner) {
10447
10674
  };
10448
10675
  }
10449
10676
 
10450
- // src/claude-subscription-usage.ts
10451
- import { AsyncLocalStorage as AsyncLocalStorage4 } from "async_hooks";
10452
- var observers = new AsyncLocalStorage4();
10453
- function withClaudeUsageObserver(observer, run2, prepare) {
10454
- return observers.run({ observe: observer, ...prepare ? { prepare } : {} }, run2);
10455
- }
10456
- async function prepareClaudeSubscriptionRequest(providerId, input, init) {
10457
- const prepare = observers.getStore()?.prepare;
10458
- if (!prepare) return init;
10459
- const headers = new Headers(input instanceof Request ? input.headers : void 0);
10460
- new Headers(init?.headers).forEach((value, key) => headers.set(key, value));
10461
- return { ...init, headers: await prepare(providerId, headers) };
10462
- }
10463
- function observeClaudeUsageResponse(providerId, response) {
10464
- try {
10465
- observers.getStore()?.observe(providerId, response);
10466
- } catch {
10467
- }
10468
- }
10469
-
10470
10677
  // src/model-provider-client.ts
10471
10678
  var runtimeMetricsHooks = null;
10472
10679
  function configureRuntimeMetricsHooks(hooks) {
@@ -10623,6 +10830,9 @@ function withoutAuthenticationHeaders(inner) {
10623
10830
  };
10624
10831
  }
10625
10832
  function buildProviderClient(provider, settings) {
10833
+ if ((provider.kind === "direct-openai-workspace" || provider.kind === "direct-azure-workspace") && !provider.apiKey?.trim()) {
10834
+ throw new Error("OpenAI or Azure OpenAI workspace key is unavailable");
10835
+ }
10626
10836
  const workspaceGateway = provider.kind === "vercel-gateway-workspace";
10627
10837
  const scopedCredentialProvider = provider.credentialSource?.kind === "workspace_connection" || provider.credentialSource?.kind === "organization_connection";
10628
10838
  const gatewayProvider = workspaceGateway || provider.kind === "vercel-gateway-organization" || provider.kind === "vercel-gateway-managed";
@@ -10735,13 +10945,15 @@ function instrumentedModelFetch(provider, inner) {
10735
10945
  if (!isModelCallFetch(input)) {
10736
10946
  return await inner(input, init);
10737
10947
  }
10738
- init = await prepareClaudeSubscriptionRequest(provider, input, init);
10948
+ const prepared = await prepareClaudeSubscriptionRequest(provider, input, init);
10949
+ init = prepared.init;
10950
+ const claudeRequestToken = captureClaudeRequestToken(input, init);
10739
10951
  await recordModelTransportStarted();
10740
10952
  const capture = captureProviderRequestBody(provider, input, init);
10741
10953
  const started = performance.now();
10742
10954
  try {
10743
10955
  const response = await inner(input, capture.init);
10744
- observeClaudeUsageResponse(provider, response);
10956
+ prepared.observe(response, claudeRequestToken);
10745
10957
  recordModelCallMetric(provider, response.ok ? "completed" : "failed", started);
10746
10958
  return response;
10747
10959
  } catch (error) {
@@ -11520,7 +11732,7 @@ function searchToolPool(availableTools, rawArguments) {
11520
11732
  ];
11521
11733
  limit = Math.min(MAX_SEARCH_LIMIT, Math.max(requestedLimit, named.length));
11522
11734
  }
11523
- const bounded = [];
11735
+ const bounded2 = [];
11524
11736
  let disclosedBytes = 0;
11525
11737
  for (const tool2 of ranked) {
11526
11738
  const toolBytes = mcpSerializedSizeBytes(tool2);
@@ -11531,10 +11743,10 @@ function searchToolPool(availableTools, rawArguments) {
11531
11743
  continue;
11532
11744
  }
11533
11745
  disclosedBytes += toolBytes;
11534
- bounded.push(tool2);
11535
- if (bounded.length >= limit) break;
11746
+ bounded2.push(tool2);
11747
+ if (bounded2.length >= limit) break;
11536
11748
  }
11537
- return bounded;
11749
+ return bounded2;
11538
11750
  }
11539
11751
 
11540
11752
  // src/lazy-tool-transport.ts
@@ -11848,7 +12060,8 @@ var LazyToolRuntime = class {
11848
12060
  const prefix = typeof args.namePrefix === "string" ? args.namePrefix : "";
11849
12061
  const cursor = typeof args.cursor === "string" ? args.cursor : void 0;
11850
12062
  const limit = typeof args.limit === "number" && Number.isFinite(args.limit) ? Math.max(1, Math.min(40, Math.floor(args.limit))) : 20;
11851
- const tools = [...new Set(this.searchableTools(this.currentTools))].filter(isFunctionTool).filter((tool2) => tool2.name.startsWith(prefix)).sort((a, b) => a.name < b.name ? -1 : a.name > b.name ? 1 : 0);
12063
+ const authorizedTools = [...new Set(this.searchableTools(this.currentTools))].filter(isFunctionTool).sort((a, b) => a.name < b.name ? -1 : a.name > b.name ? 1 : 0);
12064
+ const tools = authorizedTools.filter((tool2) => tool2.name.startsWith(prefix));
11852
12065
  const cursorIndex = cursor === void 0 ? -1 : tools.findIndex((tool2) => tool2.name === cursor);
11853
12066
  if (cursor !== void 0 && cursorIndex === -1) {
11854
12067
  return JSON.stringify({
@@ -11880,14 +12093,29 @@ var LazyToolRuntime = class {
11880
12093
  }
11881
12094
  descriptors.push(descriptor);
11882
12095
  }
11883
- return JSON.stringify({
12096
+ const result = {
11884
12097
  tools: descriptors,
11885
12098
  total: tools.length,
11886
- nextCursor: index < tools.length ? descriptors.at(-1).name : null,
11887
- ...prefix && tools.length === 0 ? {
11888
- message: "No tool names match this literal prefix. Retry tool_list without namePrefix to browse the authorized catalog; tool names can include a server namespace."
11889
- } : {}
11890
- });
12099
+ nextCursor: index < tools.length ? descriptors.at(-1).name : null
12100
+ };
12101
+ if (!prefix || tools.length > 0) return JSON.stringify(result);
12102
+ const recovery = {
12103
+ ...result,
12104
+ message: "No tool names match this literal prefix. This does not establish capability absence. Load any suggested exact names with tool_search, or retry tool_list without namePrefix to browse the authorized catalog.",
12105
+ suggestions: []
12106
+ };
12107
+ for (const candidate of authorizedTools) {
12108
+ if (!candidate.name.includes(prefix)) continue;
12109
+ const suggestion = {
12110
+ name: candidate.name,
12111
+ description: Array.from(candidate.description).slice(0, 160).join("")
12112
+ };
12113
+ const next = { ...recovery, suggestions: [...recovery.suggestions, suggestion] };
12114
+ if (Buffer.byteLength(JSON.stringify(next)) > 16 * 1024) continue;
12115
+ recovery.suggestions.push(suggestion);
12116
+ if (recovery.suggestions.length >= Math.min(limit, 8)) break;
12117
+ }
12118
+ return JSON.stringify(recovery);
11891
12119
  }
11892
12120
  });
11893
12121
  }
@@ -12800,6 +13028,7 @@ import {
12800
13028
  import { AsyncLocalStorage as AsyncLocalStorage7 } from "async_hooks";
12801
13029
  import { createHash as createHash7, randomUUID as randomUUID5 } from "crypto";
12802
13030
  import { dirname as dirname2, isAbsolute, join as join2, posix as posixPath2 } from "path";
13031
+ import { gzipSync } from "zlib";
12803
13032
 
12804
13033
  // src/operational-instructions.ts
12805
13034
  var OPENGENI_OPERATIONAL_INSTRUCTIONS = `You are an agent for the current workspace. You and the user share one workspace, and your job is to collaborate with them until their goal is genuinely handled.
@@ -13116,6 +13345,14 @@ Command completion alone resumes you only while you have an explicit \`wait_for_
13116
13345
  function renderRuntimeMechanics(context) {
13117
13346
  return blocks(
13118
13347
  "# Runtime mechanics",
13348
+ "## Tool discovery",
13349
+ sentences(
13350
+ "Deferred tool schemas are omitted from the first request; absence there does not prove a tool is unavailable.",
13351
+ "When deferred tools are attached, use `tool_search` for one focused capability at a time; broad searches with small limits can omit a relevant tool.",
13352
+ "If a search misses, use `tool_list` and follow `nextCursor` until the relevant authorized names are covered, then load exact names with `tool_search`.",
13353
+ "`namePrefix` is a literal tool-name prefix, not a capability keyword; an empty filtered page does not prove the capability is unavailable.",
13354
+ "Discovery never grants authority, and remembered tool names must still resolve against the current authorized catalog."
13355
+ ),
13119
13356
  "## New messages while you work",
13120
13357
  newMessages(context),
13121
13358
  "## Waiting",
@@ -13281,6 +13518,24 @@ var connectedMachineModule = {
13281
13518
  )
13282
13519
  };
13283
13520
 
13521
+ // src/agent-instructions/modules/media.ts
13522
+ var mediaModule = {
13523
+ id: "media",
13524
+ applies: (context) => context.capabilities.media,
13525
+ render: () => blocks(
13526
+ "# Images and video",
13527
+ sentences(
13528
+ "Use an attached image-generation tool when the user requests generated images or edits.",
13529
+ "If it is deferred, use a focused image-generation query with `tool_search`, or request the exact `generate_image` name before concluding no image tool exists.",
13530
+ "`generate_image` is a runtime tool; integration catalogs and sandbox CLI lists do not enumerate it.",
13531
+ "A hosted `image_generation` tool may instead be visible directly on supported provider routes.",
13532
+ "The media capability permits discovery, but does not prove a provider adapter is attached; establish availability from the current authorized tool catalog.",
13533
+ "Use the returned tool schema for references and output controls; do not invent model names or provider-specific options.",
13534
+ "For video, discover `get_video_generation_capabilities` and `generate_video`, read current capabilities before selecting a model, and follow the available video-generation Skill."
13535
+ )
13536
+ )
13537
+ };
13538
+
13284
13539
  // src/agent-instructions/modules/renderer-markdown.ts
13285
13540
  var rendererMarkdownModule = {
13286
13541
  id: "renderer_markdown",
@@ -13421,6 +13676,7 @@ var AGENT_PROMPT_MODULES = [
13421
13676
  workspaceEnvironmentModule,
13422
13677
  rigModule,
13423
13678
  artifactsModule,
13679
+ mediaModule,
13424
13680
  goalsModule,
13425
13681
  subagentsModule,
13426
13682
  knowledgeModule,
@@ -13774,6 +14030,7 @@ function withRetainableSessionImageOutputHook(tools, hook) {
13774
14030
  }
13775
14031
 
13776
14032
  // src/model-provider-routing.ts
14033
+ import { isDirectModelId } from "@opengeni/contracts";
13777
14034
  import { configuredProviders, resolveModelProvider } from "@opengeni/config";
13778
14035
  import { APIError as APIError2 } from "openai";
13779
14036
  import { CODEX_MODEL_ID_PREFIX } from "@opengeni/codex";
@@ -14114,6 +14371,9 @@ var MultiProviderModelProvider = class {
14114
14371
  throw new XaiSubscriptionUnavailableError(modelName);
14115
14372
  }
14116
14373
  }
14374
+ if (modelName && isDirectModelId(modelName)) {
14375
+ throw new Error("The selected OpenAI or Azure OpenAI connection is unavailable");
14376
+ }
14117
14377
  const builtin = configuredProviders(this.settings)[0];
14118
14378
  if (!builtin) throw new Error("Built-in model provider is unavailable");
14119
14379
  const client = buildProviderClient(builtin, this.settings);
@@ -14520,7 +14780,7 @@ import { existsSync, readdirSync } from "fs";
14520
14780
  // ../sdk/package.json
14521
14781
  var package_default = {
14522
14782
  name: "@opengeni/sdk",
14523
- version: "7.6.1",
14783
+ version: "7.7.0-canary.37090756480001",
14524
14784
  description: "Framework-agnostic TypeScript SDK for the OpenGeni API: typed client, session lifecycle, SSE event streaming with reconnect + replay-by-sequence, and proxy re-streaming helpers.",
14525
14785
  license: "Apache-2.0",
14526
14786
  repository: {
@@ -14673,6 +14933,10 @@ var package_default = {
14673
14933
  "./hono": {
14674
14934
  types: "./src/adapters/hono.ts",
14675
14935
  default: "./src/adapters/hono.ts"
14936
+ },
14937
+ "./session-list-entries": {
14938
+ types: "./src/session-list-entries.ts",
14939
+ default: "./src/session-list-entries.ts"
14676
14940
  }
14677
14941
  },
14678
14942
  publishConfig: {
@@ -14708,7 +14972,7 @@ var package_default = {
14708
14972
  // ../react/package.json
14709
14973
  var package_default2 = {
14710
14974
  name: "@opengeni/react",
14711
- version: "7.6.1",
14975
+ version: "7.7.0-canary.37090756480001",
14712
14976
  description: "React hooks and styled components for OpenGeni: live session streaming, chat composer, message timeline, session status, and fleet views \u2014 token-themed (CSS variables), dark-first, built on Tailwind v4 + Radix + Motion.",
14713
14977
  license: "Apache-2.0",
14714
14978
  repository: {
@@ -14981,7 +15245,7 @@ var package_default2 = {
14981
15245
  // ../codemode/package.json
14982
15246
  var package_default3 = {
14983
15247
  name: "@opengeni/codemode",
14984
- version: "0.6.8",
15248
+ version: "0.7.0-canary.37090756480001",
14985
15249
  description: "Attempt-frozen programmatic tool catalog and execution authority for OpenGeni.",
14986
15250
  license: "Apache-2.0",
14987
15251
  repository: {
@@ -15031,7 +15295,7 @@ var package_default3 = {
15031
15295
  // ../ogtool/package.json
15032
15296
  var package_default4 = {
15033
15297
  name: "@opengeni/ogtool",
15034
- version: "0.3.50",
15298
+ version: "0.3.51-canary.37090756480001",
15035
15299
  description: "Codemode CLI and typed client entrypoint for an OpenGeni execution attempt.",
15036
15300
  license: "Apache-2.0",
15037
15301
  repository: {
@@ -15112,6 +15376,7 @@ var emptyNativeToolSkillSet = Object.freeze({
15112
15376
  function loadNativeToolSkillArtifacts(nativeTools) {
15113
15377
  const directories = nativeTools.defaults === false ? [] : ["bundled_default_skills"];
15114
15378
  if (nativeTools.projects) directories.push("bundled_project_skills");
15379
+ if (nativeTools.schedules) directories.push("bundled_schedule_skills");
15115
15380
  if (nativeTools.editableArtifacts) directories.push("bundled_artifact_skills");
15116
15381
  if (nativeTools.sites) directories.push("bundled_site_skills");
15117
15382
  if (nativeTools.videoGeneration) directories.push("bundled_video_skills");
@@ -15343,6 +15608,12 @@ function nativeToolSkillSources(nativeTools) {
15343
15608
  reason: "bundled Site authoring skill"
15344
15609
  });
15345
15610
  }
15611
+ if (nativeTools.schedules) {
15612
+ sources.push({
15613
+ names: skillDirNames(packagedSkillDirectory("bundled_schedule_skills")),
15614
+ reason: "native scheduled-task tool surface"
15615
+ });
15616
+ }
15346
15617
  if (nativeTools.videoGeneration) {
15347
15618
  sources.push({
15348
15619
  names: skillDirNames(packagedSkillDirectory("bundled_video_skills")),
@@ -17427,6 +17698,10 @@ import {
17427
17698
  BrowserActionReceipt,
17428
17699
  BrowserClipboard,
17429
17700
  BrowserDiagnosticBatch,
17701
+ BrowserDownload,
17702
+ BrowserDownloadListResponse,
17703
+ BrowserDownloadSaveRequest,
17704
+ BrowserDownloadSaveResponse,
17430
17705
  BrowserDomReadResponse,
17431
17706
  BrowserDomReadLocator,
17432
17707
  BrowserDomReadSelector,
@@ -17648,6 +17923,8 @@ var TOOL_PERMISSION = {
17648
17923
  browser_act: "sessions:control",
17649
17924
  browser_clipboard: "sessions:read",
17650
17925
  browser_debug: "sessions:read",
17926
+ browser_downloads: "sessions:read",
17927
+ browser_download_save: ["sessions:control", "files:upload"],
17651
17928
  browser_auth: "sessions:control",
17652
17929
  interaction_request_human: "sessions:control",
17653
17930
  browser_identity: "sessions:control",
@@ -17888,6 +18165,20 @@ var ComputerLifecycleInput = external_exports.object({
17888
18165
  action: external_exports.literal("end")
17889
18166
  }).strict();
17890
18167
  var TERMINAL_LIFECYCLES = /* @__PURE__ */ new Set(["ended", "failed"]);
18168
+ var BrowserDownloadsInput = external_exports.object({
18169
+ browserSessionId: external_exports.string().uuid(),
18170
+ operation: external_exports.enum(["list", "get"]).default("list"),
18171
+ downloadId: external_exports.string().uuid().optional()
18172
+ }).strict().superRefine((value, context) => {
18173
+ if (value.operation === "get" !== (value.downloadId !== void 0)) {
18174
+ context.addIssue({
18175
+ code: "custom",
18176
+ path: ["downloadId"],
18177
+ message: "downloadId is required only for operation=get"
18178
+ });
18179
+ }
18180
+ });
18181
+ var BrowserDownloadSaveInput = BrowserDownloadSaveRequest.omit({ operationId: true }).extend({ browserSessionId: external_exports.string().uuid(), downloadId: external_exports.string().uuid() }).strict();
17891
18182
  function createInteractionAttemptToolDefinitions(input) {
17892
18183
  const selected = new Set(input.selectedTools ?? DEFAULT_FIRST_PARTY_MCP_TOOLS);
17893
18184
  const permissions = input.permissions ?? DEFAULT_FIRST_PARTY_MCP_PERMISSIONS;
@@ -18224,6 +18515,65 @@ function createInteractionAttemptToolDefinitions(input) {
18224
18515
  }
18225
18516
  )
18226
18517
  });
18518
+ add({
18519
+ name: "browser_downloads",
18520
+ codemodePath: ["interaction", "browser", "downloads"],
18521
+ title: "Inspect browser downloads",
18522
+ description: "List browser-produced files or get one exact download by id. Metadata identifies completed bytes and their SHA-256; diagnostics alone do not expose a download id or file bytes. Use browser_download_save to materialize a completed download in its source session's workspace. Attached browsers and Lightpanda do not expose managed downloads.",
18523
+ input: BrowserDownloadsInput,
18524
+ output: external_exports.union([BrowserDownloadListResponse, BrowserDownload]),
18525
+ readOnly: true,
18526
+ idempotent: true,
18527
+ execute: async (value) => {
18528
+ if (value.operation === "get") {
18529
+ const download = await input.transport.getBrowserDownload(
18530
+ input.workspaceId,
18531
+ value.browserSessionId,
18532
+ value.downloadId
18533
+ );
18534
+ if (download.browserSessionId !== value.browserSessionId || download.id !== value.downloadId) {
18535
+ throw new Error("Browser download belongs to another resource");
18536
+ }
18537
+ return download;
18538
+ }
18539
+ const response = await input.transport.listBrowserDownloads(
18540
+ input.workspaceId,
18541
+ value.browserSessionId
18542
+ );
18543
+ if (response.browserSessionId !== value.browserSessionId || response.downloads.some(
18544
+ (download) => download.browserSessionId !== value.browserSessionId || download.controllerGeneration !== response.controllerGeneration
18545
+ )) {
18546
+ throw new Error("Browser downloads belong to another session binding");
18547
+ }
18548
+ return response;
18549
+ }
18550
+ });
18551
+ add({
18552
+ name: "browser_download_save",
18553
+ codemodePath: ["interaction", "browser", "downloadSave"],
18554
+ title: "Save browser download to workspace",
18555
+ description: "Save one exact completed managed browser download to a portable relative path in the browser's source session workspace. Requires sessions:control and files:upload. Returns the materialized destinationPath, fileId and integrity metadata; read the saved bytes with ordinary workspace file tools. Existing files are protected unless overwrite=true. The attempt operation id fences retries; uncertain outcomes must reconcile that same operation. Attached browsers and Lightpanda cannot publish managed downloads.",
18556
+ input: BrowserDownloadSaveInput,
18557
+ output: BrowserDownloadSaveResponse,
18558
+ readOnly: false,
18559
+ idempotent: true,
18560
+ execute: async (value, context) => {
18561
+ const response = await input.transport.saveBrowserDownload(
18562
+ input.workspaceId,
18563
+ value.browserSessionId,
18564
+ value.downloadId,
18565
+ {
18566
+ operationId: context.operationId,
18567
+ destinationPath: value.destinationPath,
18568
+ overwrite: value.overwrite
18569
+ }
18570
+ );
18571
+ if (response.download.browserSessionId !== value.browserSessionId || response.download.id !== value.downloadId || response.operationId !== context.operationId || response.destinationPath !== value.destinationPath) {
18572
+ throw new Error("Browser download save returned another operation binding");
18573
+ }
18574
+ return response;
18575
+ }
18576
+ });
18227
18577
  add({
18228
18578
  name: "browser_auth",
18229
18579
  codemodePath: ["interaction", "browser", "auth"],
@@ -18929,7 +19279,9 @@ function jsonSchema(schema) {
18929
19279
  return external_exports.toJSONSchema(schema, { target: "draft-2020-12" });
18930
19280
  }
18931
19281
  function hasToolPermission(permissions, required) {
18932
- return permissions.includes(required) || permissions.includes("workspace:admin");
19282
+ return permissions.includes("workspace:admin") || (typeof required === "string" ? [required] : required).every(
19283
+ (permission) => permissions.includes(permission)
19284
+ );
18933
19285
  }
18934
19286
  function firstPartyApiBaseUrl(settings, workspaceId) {
18935
19287
  const url = new URL(firstPartyMcpInternalWorkspaceUrl(settings, workspaceId));
@@ -21364,6 +21716,9 @@ function buildAgentCapabilitiesFromComposition(settings, skillComposition, optio
21364
21716
  // Preserve that behavior except for client-side, pre-dispatch Modal
21365
21717
  // readiness proof, which reaches bounded same-turn recovery.
21366
21718
  execCommandErrorFunction: (_context, error) => {
21719
+ if (isProviderCommandObservationUnavailableError(error)) {
21720
+ return "Managed sandbox command observation unavailable. Outcome unknown. Do not replay the command or resend stdin; observe the existing invocation.";
21721
+ }
21367
21722
  if (isModalTaskExecStartPreDispatchUnavailableError(error)) throw error;
21368
21723
  if (isRoutingMutationOutcomeUnknownError(error)) {
21369
21724
  if (toolCancellation) throw error;
@@ -23823,9 +24178,9 @@ ${tool2.description ?? ""}`.trimEnd()
23823
24178
  } : {}
23824
24179
  };
23825
24180
  });
23826
- const bounded = this.aggregateToolBudget?.replace(this.aggregateSourceId, exposed) ?? assertMcpToolListWithinBounds(exposed);
23827
- this.listedToolSchemaTokens = estimateSerializedValueTokens(bounded);
23828
- return bounded;
24181
+ const bounded2 = this.aggregateToolBudget?.replace(this.aggregateSourceId, exposed) ?? assertMcpToolListWithinBounds(exposed);
24182
+ this.listedToolSchemaTokens = estimateSerializedValueTokens(bounded2);
24183
+ return bounded2;
23829
24184
  } catch (error) {
23830
24185
  if (!this.bestEffort) {
23831
24186
  throw mcpTransportErrorWithRetryMetadata(error, {
@@ -26640,8 +26995,9 @@ var RIG_SETUP_SKIPPED_SENTINEL = "__OPENGENI_RIG_SETUP_SKIPPED__";
26640
26995
  var RIG_SETUP_RUNTIME_MARKER_ROOT = "/tmp/opengeni/rig-setup";
26641
26996
  var RIG_SETUP_PROVIDER_IMAGE_MARKER_ROOT = "/var/opengeni";
26642
26997
  var RIG_SETUP_INLINE_COMMAND_MAX_BYTES = 4 * 1024;
26643
- var RIG_SETUP_PAYLOAD_CHUNK_CHARS = 7 * 1024;
26998
+ var RIG_SETUP_PAYLOAD_CHUNK_CHARS = 2 * 1024;
26644
26999
  var RIG_SETUP_PAYLOAD_ROOT = "/tmp/opengeni/rig-setup-payloads";
27000
+ var RIG_SETUP_GZIP_SENTINEL = "__OPENGENI_SETUP_GZIP__";
26645
27001
  function rigSetupHeredocDelimiter(script) {
26646
27002
  const occupied = new Set(script.split(/\r?\n/u));
26647
27003
  const digest = createHash7("sha256").update(script, "utf8").digest("hex").slice(0, 16);
@@ -26735,28 +27091,51 @@ function rigSetupScriptCommand(script, versionId, options = {}) {
26735
27091
  "done"
26736
27092
  ].join("\n");
26737
27093
  }
26738
- async function stageRigSetupScript(session, script, context) {
26739
- const payloadPath = `${RIG_SETUP_PAYLOAD_ROOT}/${randomUUID5()}.sh`;
27094
+ async function stageRigSetupScript(session, script, context, options = {}) {
27095
+ const payloadRoot = options.payloadRoot ?? RIG_SETUP_PAYLOAD_ROOT;
27096
+ const payloadPath = `${payloadRoot}/${randomUUID5()}.sh`;
26740
27097
  const encodedPath = `${payloadPath}.b64`;
26741
- const encoded = Buffer.from(script, "utf8").toString("base64");
26742
- const commands = [
26743
- `set -eu
26744
- umask 077
26745
- mkdir -p ${shellQuote(RIG_SETUP_PAYLOAD_ROOT)}
26746
- : > ${shellQuote(encodedPath)}`
26747
- ];
26748
- for (let offset = 0; offset < encoded.length; offset += RIG_SETUP_PAYLOAD_CHUNK_CHARS) {
26749
- commands.push(
26750
- `printf '%s' ${shellQuote(encoded.slice(offset, offset + RIG_SETUP_PAYLOAD_CHUNK_CHARS))} >> ${shellQuote(encodedPath)}`
27098
+ const bytes = Buffer.from(script, "utf8");
27099
+ const compressed = gzipSync(bytes);
27100
+ const compressionUseful = compressed.length < bytes.length;
27101
+ try {
27102
+ const bootstrap = await runSandboxLifecycleCommand(
27103
+ session,
27104
+ {
27105
+ cmd: [
27106
+ "set -eu",
27107
+ "umask 077",
27108
+ `mkdir -p ${shellQuote(payloadRoot)}`,
27109
+ `: > ${shellQuote(encodedPath)}`,
27110
+ ...compressionUseful ? [
27111
+ `if command -v gzip >/dev/null 2>&1; then printf '%s\\n' ${shellQuote(RIG_SETUP_GZIP_SENTINEL)}; fi`
27112
+ ] : []
27113
+ ].join("\n"),
27114
+ workdir: "/workspace",
27115
+ ...context.runAs ? { runAs: context.runAs } : {},
27116
+ yieldTimeMs: SANDBOX_LIFECYCLE_COMMAND_TIMEOUT_MS,
27117
+ maxOutputTokens: 4e3
27118
+ },
27119
+ context.commandRunner
26751
27120
  );
26752
- }
26753
- commands.push(
26754
- `set -eu
26755
- base64 -d ${shellQuote(encodedPath)} > ${shellQuote(payloadPath)}
27121
+ assertSandboxCommandSucceeded(
27122
+ bootstrap,
27123
+ options.label ?? "Sandbox Environment setup payload staging"
27124
+ );
27125
+ const useCompression = compressionUseful && sandboxCommandOutput(bootstrap).split(/\r?\n/u).includes(RIG_SETUP_GZIP_SENTINEL);
27126
+ const encoded = (useCompression ? compressed : bytes).toString("base64");
27127
+ const commands = [];
27128
+ for (let offset = 0; offset < encoded.length; offset += RIG_SETUP_PAYLOAD_CHUNK_CHARS) {
27129
+ commands.push(
27130
+ `printf '%s' ${shellQuote(encoded.slice(offset, offset + RIG_SETUP_PAYLOAD_CHUNK_CHARS))} >> ${shellQuote(encodedPath)}`
27131
+ );
27132
+ }
27133
+ commands.push(
27134
+ `set -eu
27135
+ base64 -d < ${shellQuote(encodedPath)}${useCompression ? " | gzip -dc" : ""} > ${shellQuote(payloadPath)}
26756
27136
  chmod 0700 ${shellQuote(payloadPath)}
26757
27137
  rm -f ${shellQuote(encodedPath)}`
26758
- );
26759
- try {
27138
+ );
26760
27139
  for (const command of commands) {
26761
27140
  const result = await runSandboxLifecycleCommand(
26762
27141
  session,
@@ -26769,7 +27148,10 @@ rm -f ${shellQuote(encodedPath)}`
26769
27148
  },
26770
27149
  context.commandRunner
26771
27150
  );
26772
- assertSandboxCommandSucceeded(result, "Sandbox Environment setup payload staging");
27151
+ assertSandboxCommandSucceeded(
27152
+ result,
27153
+ options.label ?? "Sandbox Environment setup payload staging"
27154
+ );
26773
27155
  }
26774
27156
  return payloadPath;
26775
27157
  } catch (error) {
@@ -26944,6 +27326,7 @@ async function runRepositoryCloneHook(session, resources, context = { environmen
26944
27326
  editor: null,
26945
27327
  staged: []
26946
27328
  };
27329
+ let stagedCloneScript = null;
26947
27330
  try {
26948
27331
  const gitTokenSeeds = {
26949
27332
  ...context.gitTokenSeeds ?? {},
@@ -26965,10 +27348,17 @@ async function runRepositoryCloneHook(session, resources, context = { environmen
26965
27348
  stagedBrokerSeeds.staged,
26966
27349
  options
26967
27350
  );
26968
- const command = sandboxGitProvisioningCommand(
27351
+ let command = sandboxGitProvisioningCommand(
26969
27352
  seedPrefix ? `${seedPrefix}
26970
27353
  ${cloneCommand}` : cloneCommand
26971
27354
  );
27355
+ if (Buffer.byteLength(command, "utf8") > RIG_SETUP_INLINE_COMMAND_MAX_BYTES) {
27356
+ stagedCloneScript = await stageRigSetupScript(session, command, context, {
27357
+ payloadRoot: "/tmp/opengeni/repository-setup-payloads",
27358
+ label: "Repository setup payload staging"
27359
+ });
27360
+ command = `exec /bin/sh ${shellQuote(stagedCloneScript)}`;
27361
+ }
26972
27362
  const result = await runSandboxLifecycleCommand(
26973
27363
  session,
26974
27364
  {
@@ -27008,6 +27398,19 @@ ${cloneCommand}` : cloneCommand
27008
27398
  });
27009
27399
  throw error;
27010
27400
  } finally {
27401
+ if (stagedCloneScript) {
27402
+ await runSandboxLifecycleCommand(
27403
+ session,
27404
+ {
27405
+ cmd: `rm -f ${shellQuote(stagedCloneScript)} ${shellQuote(`${stagedCloneScript}.b64`)}`,
27406
+ workdir: "/workspace",
27407
+ ...context.runAs ? { runAs: context.runAs } : {},
27408
+ yieldTimeMs: SANDBOX_LIFECYCLE_COMMAND_TIMEOUT_MS,
27409
+ maxOutputTokens: 1e3
27410
+ },
27411
+ context.commandRunner
27412
+ ).catch(() => void 0);
27413
+ }
27011
27414
  if (stagedBrokerSeeds.editor) {
27012
27415
  await cleanupStagedGitCredentialSeeds(stagedBrokerSeeds.editor, stagedBrokerSeeds.staged);
27013
27416
  }
@@ -27179,8 +27582,11 @@ export {
27179
27582
  renderCompactionPromptInputForChat,
27180
27583
  queuePreparedCompaction,
27181
27584
  preparedCompactionRequest,
27585
+ AnthropicRequestError,
27182
27586
  OpenAIResponsesModel,
27183
27587
  OpenAIChatCompletionsModel,
27588
+ withClaudeUsageObserver,
27589
+ AnthropicProviderRejection,
27184
27590
  WorkspaceGatewayUnavailableError,
27185
27591
  WorkspaceOpenRouterUnavailableError,
27186
27592
  OrganizationGatewayUnavailableError,
@@ -27199,7 +27605,6 @@ export {
27199
27605
  PROVIDER_QUOTA_EXHAUSTED_CODE,
27200
27606
  providerQuotaExhaustedMessage,
27201
27607
  classifyProviderQuotaError,
27202
- withClaudeUsageObserver,
27203
27608
  configureRuntimeMetricsHooks,
27204
27609
  buildOpenAIClientFromSettings,
27205
27610
  buildProviderClient,
@@ -27410,4 +27815,4 @@ export {
27410
27815
  runAzureCliLoginHook,
27411
27816
  renderSessionGoalContext2 as renderSessionGoalContext
27412
27817
  };
27413
- //# sourceMappingURL=chunk-GTWKWJ67.js.map
27818
+ //# sourceMappingURL=chunk-P2OVGKDG.js.map