@opengeni/runtime 3.0.2-canary.38894290271001 → 3.1.2

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.
@@ -101,7 +101,7 @@ import {
101
101
  withModelRequestCapture,
102
102
  withModelTransportStartedObserver,
103
103
  withPreparedCompactionRequest
104
- } from "./chunk-EQQ3YOKR.js";
104
+ } from "./chunk-7OUG7WBV.js";
105
105
  import {
106
106
  GMAIL_REST_MCP_BRIDGE_ADAPTER,
107
107
  gmailRestResultOutcome,
@@ -317,8 +317,6 @@ import {
317
317
  } from "@opengeni/contracts";
318
318
  import { boundComputerNativeReceipt } from "@opengeni/interaction";
319
319
  import {
320
- AttachedBrowserBridge,
321
- AttachedBrowserDevice,
322
320
  AuthRun,
323
321
  AuthRunListResponse,
324
322
  AuthRunMutationResponse,
@@ -339,12 +337,18 @@ import {
339
337
  BrowserIdentityListResponse,
340
338
  BrowserIdentityMutationResponse,
341
339
  BrowserObservation,
340
+ BrowserActionResolvedTarget,
341
+ BrowserDialog,
342
+ InteractionDiagnosticSummary,
343
+ InteractionError,
344
+ InteractionOperationState,
345
+ InteractionRect,
346
+ RetainedArtifactReferenceSchema,
342
347
  BrowserRevisionListResponse,
343
348
  BrowserSession,
344
349
  BrowserStorageMode,
345
350
  browserSessionStorageMode,
346
351
  BrowserSessionMutationResponse,
347
- BrowserTarget,
348
352
  BrowserTargetListResponse,
349
353
  ComputerAction,
350
354
  ComputerActionReceipt,
@@ -411,28 +415,53 @@ var BrowserAgentNode = external_exports.object({
411
415
  external_exports.string().max(BROWSER_AGENT_MAX_FIELD_LENGTH),
412
416
  external_exports.object({ redacted: external_exports.literal(true), reason: external_exports.string().max(32) }).strict()
413
417
  ]).optional(),
414
- states: external_exports.array(external_exports.string().max(BROWSER_AGENT_MAX_FIELD_LENGTH)).max(6),
415
- actions: external_exports.array(external_exports.string().max(BROWSER_AGENT_MAX_FIELD_LENGTH)).max(6)
418
+ // Omitted when empty: most nodes have no states or actions, and repeating
419
+ // empty arrays on every node only costs the model tokens.
420
+ states: external_exports.array(external_exports.string().max(BROWSER_AGENT_MAX_FIELD_LENGTH)).min(1).max(6).optional(),
421
+ actions: external_exports.array(external_exports.string().max(BROWSER_AGENT_MAX_FIELD_LENGTH)).min(1).max(6).optional()
416
422
  }).strict();
417
423
  var BrowserAgentView = external_exports.object({
418
- kind: external_exports.literal("compact"),
419
424
  sourceKind: external_exports.enum(["snapshot", "diff", "none"]),
420
425
  nodes: external_exports.array(BrowserAgentNode).max(BROWSER_AGENT_MAX_NODES),
421
- sourceNodeCount: external_exports.number().int().nonnegative(),
422
- omittedNodeCount: external_exports.number().int().nonnegative(),
423
- removedRefCount: external_exports.number().int().nonnegative(),
424
- clippedFieldCount: external_exports.number().int().nonnegative(),
425
- maxNodes: external_exports.number().int().positive(),
426
- maxNodeBytes: external_exports.number().int().positive()
426
+ omittedNodeCount: external_exports.number().int().positive().optional(),
427
+ removedRefCount: external_exports.number().int().positive().optional(),
428
+ clippedFieldCount: external_exports.number().int().positive().optional()
429
+ }).strict();
430
+ var AgentBrowserTarget = external_exports.object({
431
+ id: external_exports.string().max(512),
432
+ kind: external_exports.enum(["page", "popup", "background_page", "worker"]),
433
+ title: external_exports.string().max(4096),
434
+ url: external_exports.string().max(16384),
435
+ selected: external_exports.boolean(),
436
+ controllerGeneration: external_exports.string().max(256),
437
+ targetGeneration: external_exports.string().max(256),
438
+ documentGeneration: external_exports.string().max(256).nullable()
427
439
  }).strict();
428
- var CompactBrowserObservation = BrowserObservation.safeExtend({
429
- semantic: external_exports.null(),
440
+ var CompactBrowserObservation = external_exports.object({
441
+ target: AgentBrowserTarget,
442
+ frameId: external_exports.string().max(256).optional(),
443
+ viewport: external_exports.object({
444
+ width: external_exports.number().int().positive(),
445
+ height: external_exports.number().int().positive(),
446
+ deviceScaleFactor: external_exports.number().positive().optional(),
447
+ maxTouchPoints: external_exports.number().int().positive().optional()
448
+ }).strict().optional(),
449
+ focusedRef: external_exports.string().max(512).optional(),
450
+ changedRegions: external_exports.array(InteractionRect).min(1).optional(),
451
+ diagnostics: InteractionDiagnosticSummary.optional(),
452
+ dialog: BrowserDialog.optional(),
453
+ screenshot: RetainedArtifactReferenceSchema.optional(),
430
454
  agentView: BrowserAgentView
431
- });
455
+ }).strict();
432
456
  var BrowserAgentObservation = external_exports.union([BrowserObservation, CompactBrowserObservation]);
433
- var BrowserAgentActionReceipt = BrowserActionReceipt.safeExtend({
434
- observation: BrowserAgentObservation.nullable()
435
- });
457
+ var CompactBrowserActionReceipt = external_exports.object({
458
+ targetId: external_exports.string().max(512),
459
+ state: InteractionOperationState,
460
+ error: InteractionError.optional(),
461
+ targets: external_exports.array(BrowserActionResolvedTarget).optional(),
462
+ observation: CompactBrowserObservation.optional()
463
+ }).strict();
464
+ var BrowserAgentActionReceipt = external_exports.union([BrowserActionReceipt, CompactBrowserActionReceipt]);
436
465
  var BrowserScreenshotInput = external_exports.object({
437
466
  browserSessionId: external_exports.string().uuid(),
438
467
  targetId: external_exports.string().min(1).max(512),
@@ -574,6 +603,20 @@ var DiscoveryInput = external_exports.object({
574
603
  includeArchivedIdentities: external_exports.boolean().optional(),
575
604
  includeDisconnectedDevices: external_exports.boolean().optional()
576
605
  }).strict();
606
+ var AgentAttachedBrowser = external_exports.object({
607
+ id: external_exports.string().uuid(),
608
+ name: external_exports.string().max(200),
609
+ profileLabel: external_exports.string().max(200).optional(),
610
+ browserName: external_exports.string().max(100),
611
+ platform: external_exports.enum(["linux", "macos", "windows"]),
612
+ state: external_exports.enum(["connected", "disconnected"]),
613
+ tabCount: external_exports.number().int().nonnegative(),
614
+ unsupported: external_exports.array(external_exports.string().max(64)).min(1).optional()
615
+ }).strict();
616
+ var AgentAttachedBrowserBridge = external_exports.object({
617
+ enrollmentId: external_exports.string().uuid(),
618
+ connectedProfileCount: external_exports.number().int().nonnegative()
619
+ }).strict();
577
620
  var DiscoveryOutput = external_exports.object({
578
621
  browserRevision: external_exports.number().int().nonnegative(),
579
622
  computerRevision: external_exports.number().int().nonnegative(),
@@ -582,8 +625,17 @@ var DiscoveryOutput = external_exports.object({
582
625
  browsers: external_exports.array(BrowserSession),
583
626
  computers: external_exports.array(ComputerSession),
584
627
  identities: external_exports.array(BrowserIdentity),
585
- attachedBrowserBridges: external_exports.array(AttachedBrowserBridge),
586
- attachedBrowsers: external_exports.array(AttachedBrowserDevice)
628
+ attachedBrowserBridges: external_exports.array(AgentAttachedBrowserBridge),
629
+ attachedBrowsers: external_exports.array(AgentAttachedBrowser)
630
+ }).strict();
631
+ var BrowserOpenPlacement = external_exports.union([
632
+ InteractionPlacement,
633
+ external_exports.object({ kind: external_exports.literal("attached_device") }).strict()
634
+ ]);
635
+ var AgentAttachedProfile = external_exports.object({
636
+ id: external_exports.string().uuid(),
637
+ name: external_exports.string(),
638
+ profileLabel: external_exports.string().optional()
587
639
  }).strict();
588
640
  var BrowserOpenInput = external_exports.object({
589
641
  browserSessionId: external_exports.string().uuid().optional(),
@@ -592,7 +644,7 @@ var BrowserOpenInput = external_exports.object({
592
644
  initialUrl: external_exports.string().url().max(16384).optional(),
593
645
  headless: external_exports.boolean().optional(),
594
646
  storageMode: BrowserStorageMode.optional(),
595
- placement: InteractionPlacement.optional(),
647
+ placement: BrowserOpenPlacement.optional(),
596
648
  identityId: external_exports.string().uuid().optional(),
597
649
  baseRevisionId: external_exports.string().uuid().optional(),
598
650
  networkRouteId: external_exports.string().uuid().optional(),
@@ -620,7 +672,14 @@ var BrowserOpenInput = external_exports.object({
620
672
  });
621
673
  }
622
674
  });
623
- var BrowserOpenOutput = external_exports.object({ session: BrowserSession, targets: external_exports.array(BrowserTarget) }).strict();
675
+ var BrowserOpenOutput = external_exports.object({
676
+ session: BrowserSession,
677
+ targets: external_exports.array(AgentBrowserTarget),
678
+ otherTabCount: external_exports.number().int().nonnegative().optional(),
679
+ observation: CompactBrowserObservation.optional(),
680
+ attachedProfile: AgentAttachedProfile.optional(),
681
+ otherAttachedProfiles: external_exports.array(AgentAttachedProfile).optional()
682
+ }).strict();
624
683
  var BrowserTabsInput = external_exports.discriminatedUnion("operation", [
625
684
  external_exports.object({ operation: external_exports.literal("list"), browserSessionId: external_exports.string().uuid() }).strict(),
626
685
  external_exports.object({
@@ -639,9 +698,11 @@ var BrowserTabsInput = external_exports.discriminatedUnion("operation", [
639
698
  targetId: external_exports.string().min(1).max(512)
640
699
  }).strict()
641
700
  ]);
642
- var BrowserTabsOutput = BrowserTargetListResponse.safeExtend({
701
+ var BrowserTabsOutput = external_exports.object({
702
+ browserSessionId: external_exports.string().uuid(),
703
+ targets: external_exports.array(AgentBrowserTarget),
643
704
  mutationObservation: CompactBrowserObservation.optional()
644
- });
705
+ }).strict();
645
706
  var BrowserObserveInput = external_exports.object({
646
707
  browserSessionId: external_exports.string().uuid(),
647
708
  targetId: external_exports.string().min(1).max(512),
@@ -846,7 +907,7 @@ function createInteractionAttemptToolDefinitions(input) {
846
907
  name: "interaction_discover",
847
908
  codemodePath: ["interaction", "discover"],
848
909
  title: "Discover browsers and computers",
849
- description: `Discover browsers and computers. For the user's existing/current/personal Chrome, use scope=attached_browsers before browser_open and select an actual attachedBrowsers device. This reads only Chrome profiles and extension bridges, avoiding unrelated sessions and saved identities. The default current_session scope lists this agent session's BrowserSessions and ComputerSessions. Use scope=workspace only for reusable identities or peer/child resources; that inventory can be large. An attachedBrowserBridge only means the machine is ready for the extension; only attachedBrowsers are real user Chrome profiles/tabs. If none exist, the person needs a Connected Machine first (post the Connected Machine card with capability_authorization_request api:connected-machine) and then the Opengeni Browser Chrome extension: ${OPENGENI_BROWSER_EXTENSION_URL}. Leave includeTerminal=false unless ended history is specifically required.`,
910
+ description: `Discover browsers and computers. To use the user's existing/current/personal Chrome, call browser_open with placement={kind:'attached_device'} directly; use scope=attached_browsers only to pick a specific Chrome profile or to see why none is connected. That scope reads only Chrome profiles and extension bridges, avoiding unrelated sessions and saved identities. The default current_session scope lists this agent session's BrowserSessions and ComputerSessions. Use scope=workspace only for reusable identities or peer/child resources; that inventory can be large. An attachedBrowserBridge only means the machine is ready for the extension; only attachedBrowsers are real user Chrome profiles/tabs. If none exist, the person needs a Connected Machine first (post the Connected Machine card with capability_authorization_request api:connected-machine) and then the Opengeni Browser Chrome extension: ${OPENGENI_BROWSER_EXTENSION_URL}. Leave includeTerminal=false unless ended history is specifically required.`,
850
911
  input: DiscoveryInput,
851
912
  output: DiscoveryOutput,
852
913
  readOnly: true,
@@ -865,8 +926,7 @@ function createInteractionAttemptToolDefinitions(input) {
865
926
  browsers: [],
866
927
  computers: [],
867
928
  identities: [],
868
- attachedBrowserBridges: attached2.bridges,
869
- attachedBrowsers: attached2.devices
929
+ ...agentAttachedInventory(attached2)
870
930
  };
871
931
  }
872
932
  const listFilter = {
@@ -901,8 +961,7 @@ function createInteractionAttemptToolDefinitions(input) {
901
961
  value.includeTerminal ?? false
902
962
  ),
903
963
  identities: scope === "workspace" ? identities.identities : [],
904
- attachedBrowserBridges: scope === "workspace" ? attached.bridges : [],
905
- attachedBrowsers: scope === "workspace" ? attached.devices : []
964
+ ...scope === "workspace" ? agentAttachedInventory(attached) : { attachedBrowserBridges: [], attachedBrowsers: [] }
906
965
  };
907
966
  }
908
967
  });
@@ -910,7 +969,7 @@ function createInteractionAttemptToolDefinitions(input) {
910
969
  name: "browser_open",
911
970
  codemodePath: ["interaction", "browser", "open"],
912
971
  title: "Open or reuse browser",
913
- description: `Open a managed BrowserSession on the current agent placement, reuse a relevant compatible live session by default, attach to an explicit workspace BrowserSession, or open an attached Chrome profile by passing placement={kind:'attached_device',deviceId}. This does not infer or attach the user's existing Chrome: for requests about 'my browser', 'my tabs', or current Chrome, call interaction_discover first and select an actual attachedBrowsers device; if none exists, explain that the Chrome extension must be connected instead of silently creating a blank managed browser (it needs a Connected Machine, then the Opengeni Browser extension: ${OPENGENI_BROWSER_EXTENSION_URL}). BrowserSessions persist across tool calls; shell-launched browser daemons do not survive remote-command cleanup. Never switch to the user's attached Chrome as a fallback for a failed managed browser unless the user requested that profile. A new attached session opens a dedicated tab. Managed Chromium defaults to headed so OAuth and later human interaction use a supported browser; request headless=true only for agent-only work that will not require sign-in or human control. Operator-enabled disposable sandbox verification may explicitly request storageMode=ephemeral_context with headless=true: no saved identity, route, Computer, checkpoint or resume; process loss ends the session. Default private_profile storage is unchanged. Returns exact session and tab state.`,
972
+ description: `Open a managed BrowserSession on the current agent placement, reuse a relevant compatible live session by default, attach to an explicit workspace BrowserSession, or open the user's own Chrome with placement={kind:'attached_device'}. Use that directly for requests about 'my browser', 'my tabs', or current Chrome: it opens the only Chrome profile connected through the Opengeni Browser extension, or else the most recently active one (reported as attachedProfile, the rest as otherAttachedProfiles). Add deviceId (from interaction_discover scope=attached_browsers or otherAttachedProfiles) only when the user wants a different profile. Omitting placement never uses the user's Chrome. If no profile is connected, explain that the Chrome extension must be connected instead of silently creating a blank managed browser (it needs a Connected Machine, then the Opengeni Browser extension: ${OPENGENI_BROWSER_EXTENSION_URL}). BrowserSessions persist across tool calls; shell-launched browser daemons do not survive remote-command cleanup. Never switch to the user's attached Chrome as a fallback for a failed managed browser unless the user requested that profile. A new attached session opens a dedicated tab. Managed Chromium defaults to headed so OAuth and later human interaction use a supported browser; request headless=true only for agent-only work that will not require sign-in or human control. Operator-enabled disposable sandbox verification may explicitly request storageMode=ephemeral_context with headless=true: no saved identity, route, Computer, checkpoint or resume; process loss ends the session. Default private_profile storage is unchanged. Returns exact session and tab state, plus observation: a compact snapshot of the opened (or selected) tab when one is available. With initialUrl, targets holds only the opened tab and otherTabCount counts the rest (browser_tabs list shows them). Reuse its refs and generations for the first action instead of observing again.`,
914
973
  input: BrowserOpenInput,
915
974
  output: BrowserOpenOutput,
916
975
  readOnly: false,
@@ -941,10 +1000,12 @@ function createInteractionAttemptToolDefinitions(input) {
941
1000
  value.targetId
942
1001
  );
943
1002
  } else if (value.operation === "close") {
944
- return await input.transport.closeBrowserTarget(
945
- input.workspaceId,
946
- value.browserSessionId,
947
- value.targetId
1003
+ return agentTargetList(
1004
+ await input.transport.closeBrowserTarget(
1005
+ input.workspaceId,
1006
+ value.browserSessionId,
1007
+ value.targetId
1008
+ )
948
1009
  );
949
1010
  }
950
1011
  const tabs = await input.transport.listBrowserTargets(
@@ -952,16 +1013,16 @@ function createInteractionAttemptToolDefinitions(input) {
952
1013
  value.browserSessionId
953
1014
  );
954
1015
  return mutationObservation ? {
955
- ...tabs,
1016
+ ...agentTargetList(tabs),
956
1017
  mutationObservation: projectBrowserObservation(mutationObservation, "compact")
957
- } : tabs;
1018
+ } : agentTargetList(tabs);
958
1019
  }
959
1020
  });
960
1021
  add({
961
1022
  name: "browser_observe",
962
1023
  codemodePath: ["interaction", "browser", "observe"],
963
1024
  title: "Observe browser tab",
964
- description: "Read one tab's URL, title, viewport, causal generations, and a bounded accessibility view. Compact view is the default: agentView lists selected refs and reports omitted nodes and clipped fields; it is not a complete page tree. Set view=full for the complete accessibility snapshot. Set includeScreenshot=true to add a current still image as tool image content; browser_screenshot is faster when only pixels are needed.",
1025
+ description: "Read one tab's URL, title, viewport, causal generations, and a bounded accessibility view. Compact view is the default: agentView lists selected refs, and omittedNodeCount or clippedFieldCount appear only when something was left out; it is not a complete page tree. Empty and default fields are omitted. Set view=full for the complete accessibility snapshot. Set includeScreenshot=true to add a current still image as tool image content; browser_screenshot is faster when only pixels are needed.",
965
1026
  input: BrowserObserveInput,
966
1027
  output: BrowserAgentObservation,
967
1028
  readOnly: true,
@@ -1108,7 +1169,7 @@ function createInteractionAttemptToolDefinitions(input) {
1108
1169
  name: "browser_act",
1109
1170
  codemodePath: ["interaction", "browser", "act"],
1110
1171
  title: "Act in browser tab",
1111
- description: "Perform one semantic-first browser action or bounded batch. Prefer action={type:'batch',actions:[...],fenceEachAction:true} for predictable edits in the same observed document, such as filling known form fields before one authorized submit. Pause for new page state, a dialog, or a decision instead of batching steps that depend on an unseen result. Reuse a page observation, when present, from tab open/select or a prior action; browser_open returns only session/tab metadata, so observe when page content is needed. Observe again after page changes or when needed content was omitted. If an action reports outcome_unknown, inspect the outcome and do not replay the batch. Use viewport to set page width, height, desktop/mobile layout and touch emulation, then check the measured viewport in the returned observation; emulation does not prove physical mobile-browser behavior. Use history back/forward for tab navigation; keypress shortcuts are page input and may not navigate browser history. A press key is one character or a key name (Enter, Tab, Escape, Backspace, Delete, Insert, Home, End, PageUp, PageDown, ArrowUp/Down/Left/Right, Space, F1-F24), optionally prefixed by Ctrl+, Alt+, Shift+, Meta+ or Mod+. The explicit activate action foregrounds the target in the user's desktop browser; use only when that is intended. Permission actions set a managed browser's web permission for this tab's exact current top-level origin. Omit generation fences to fetch fresh generation metadata without scanning accessibility; supplying all three fences skips that state read while preserving controller validation. The default receipt includes a compact accessibility view with explicit omissions; set view=full for the complete observation, or view=none when no post-action tree is needed. An upload action takes workspace File IDs; the artifact.artifactId returned by sandbox_file_publish is one. Text in fill, type and clipboard write may contain {{secret:\u2026}} references; the value (or the current TOTP code for /otp) is typed at dispatch and never shown to you. Use type with mode:'keys' for split one-time-code boxes or inputs that ignore pasted text.",
1172
+ description: "Perform one semantic-first browser action or bounded batch. Prefer action={type:'batch',actions:[...],fenceEachAction:true} for predictable edits in the same observed document, such as filling known form fields before one authorized submit. Pause for new page state, a dialog, or a decision instead of batching steps that depend on an unseen result. Reuse a page observation, when present, from browser_open, tab open/select or a prior action; observe only when none is present or it lacks needed content. Observe again after page changes or when needed content was omitted. If an action reports outcome_unknown, inspect the outcome and do not replay the batch. Use viewport to set page width, height, desktop/mobile layout and touch emulation, then check the measured viewport in the returned observation; emulation does not prove physical mobile-browser behavior. Use history back/forward for tab navigation; keypress shortcuts are page input and may not navigate browser history. A press key is one character or a key name (Enter, Tab, Escape, Backspace, Delete, Insert, Home, End, PageUp, PageDown, ArrowUp/Down/Left/Right, Space, F1-F24), optionally prefixed by Ctrl+, Alt+, Shift+, Meta+ or Mod+. The explicit activate action foregrounds the target in the user's desktop browser; use only when that is intended. Permission actions set a managed browser's web permission for this tab's exact current top-level origin. Omit generation fences to fetch fresh generation metadata without scanning accessibility; supplying all three fences skips that state read while preserving controller validation. The default receipt includes a compact accessibility view with explicit omissions; set view=full for the complete observation, or view=none when no post-action tree is needed. An upload action takes workspace File IDs; the artifact.artifactId returned by sandbox_file_publish is one. Text in fill, type and clipboard write may contain {{secret:\u2026}} references; the value (or the current TOTP code for /otp) is typed at dispatch and never shown to you. Use type with mode:'keys' for split one-time-code boxes or inputs that ignore pasted text.",
1112
1173
  input: BrowserActInput,
1113
1174
  output: BrowserAgentActionReceipt,
1114
1175
  readOnly: false,
@@ -1127,7 +1188,7 @@ function createInteractionAttemptToolDefinitions(input) {
1127
1188
  action: value.action
1128
1189
  }
1129
1190
  );
1130
- return receipt.observation && (value.view ?? "compact") === "compact" ? { ...receipt, observation: projectBrowserObservation(receipt.observation, "compact") } : receipt;
1191
+ return value.view === "full" ? receipt : compactActionReceipt(receipt);
1131
1192
  }
1132
1193
  });
1133
1194
  add({
@@ -1646,7 +1707,43 @@ function createInteractionAttemptToolDefinitions(input) {
1646
1707
  }
1647
1708
  function nativeCuaSchema(variants) {
1648
1709
  const unique = [...new Map(variants.map((schema) => [JSON.stringify(schema), schema])).values()];
1649
- return unique.length === 1 ? unique[0] : { type: "object", anyOf: unique };
1710
+ if (unique.length === 1) return unique[0];
1711
+ const properties = {};
1712
+ const names = [...new Set(unique.flatMap((schema) => Object.keys(objectProperties(schema))))];
1713
+ for (const name of names) {
1714
+ const alternatives = unique.map((schema) => objectProperties(schema)[name]).filter((value) => isJsonObject(value));
1715
+ const distinct = /* @__PURE__ */ new Map();
1716
+ for (const schema of alternatives) {
1717
+ const key = JSON.stringify(withoutWording(schema));
1718
+ if (!distinct.has(key)) distinct.set(key, schema);
1719
+ }
1720
+ const options = [...distinct.values()];
1721
+ properties[name] = options.length === 1 ? options[0] : { anyOf: options };
1722
+ }
1723
+ const required = names.filter(
1724
+ (name) => unique.every(
1725
+ (schema) => Array.isArray(schema.required) ? schema.required.includes(name) : false
1726
+ )
1727
+ );
1728
+ return {
1729
+ type: "object",
1730
+ properties,
1731
+ ...required.length > 0 ? { required } : {},
1732
+ ...unique.every((schema) => schema.additionalProperties === false) ? { additionalProperties: false } : {}
1733
+ };
1734
+ }
1735
+ function objectProperties(schema) {
1736
+ return isJsonObject(schema.properties) ? schema.properties : {};
1737
+ }
1738
+ function isJsonObject(value) {
1739
+ return typeof value === "object" && value !== null && !Array.isArray(value);
1740
+ }
1741
+ function withoutWording(value) {
1742
+ if (Array.isArray(value)) return value.map(withoutWording);
1743
+ if (!isJsonObject(value)) return value;
1744
+ return Object.fromEntries(
1745
+ Object.entries(value).filter(([key]) => key !== "description" && key !== "title" && key !== "default").sort(([a], [b]) => a.localeCompare(b)).map(([key, entry]) => [key, withoutWording(entry)])
1746
+ );
1650
1747
  }
1651
1748
  function filterDiscoveredSessions(sessions, sessionId, scope, includeTerminal) {
1652
1749
  return sessions.filter(
@@ -1703,15 +1800,20 @@ function createFirstPartyInteractionAttemptToolDefinitions(input) {
1703
1800
  async function openBrowser(transport, workspaceId, sourceSessionId, value, context) {
1704
1801
  let session;
1705
1802
  let created = false;
1803
+ let profileChoice;
1706
1804
  if (value.browserSessionId) {
1707
1805
  session = await transport.getBrowserSession(workspaceId, value.browserSessionId);
1708
1806
  if (value.storageMode && browserSessionStorageMode(session) !== value.storageMode)
1709
1807
  throw new Error("existing BrowserSession storage mode does not match request");
1710
1808
  } else {
1711
- const listed = value.mode === "new" ? { sessions: [] } : await transport.listBrowserSessions(workspaceId, {
1712
- associatedSessionId: sourceSessionId,
1713
- includeTerminal: false
1714
- });
1809
+ const resolveProfile = value.placement?.kind === "attached_device" && !("deviceId" in value.placement);
1810
+ const [listed, attachedInventory] = await Promise.all([
1811
+ value.mode === "new" ? { sessions: [] } : transport.listBrowserSessions(workspaceId, {
1812
+ associatedSessionId: sourceSessionId,
1813
+ includeTerminal: false
1814
+ }),
1815
+ resolveProfile ? transport.listAttachedBrowsers(workspaceId, { includeDisconnected: false }) : null
1816
+ ]);
1715
1817
  const requestedHeadless = value.headless ?? false;
1716
1818
  const reusable = value.mode === "new" ? null : newestRelevant(
1717
1819
  listed.sessions.filter(
@@ -1723,6 +1825,8 @@ async function openBrowser(transport, workspaceId, sourceSessionId, value, conte
1723
1825
  session = reusable;
1724
1826
  } else {
1725
1827
  created = true;
1828
+ if (attachedInventory) profileChoice = chooseAttachedProfile(attachedInventory);
1829
+ const placement = profileChoice ? { kind: "attached_device", deviceId: profileChoice.chosen.id } : value.placement;
1726
1830
  session = (await transport.createBrowserSession(workspaceId, {
1727
1831
  operationId: context.operationId,
1728
1832
  sessionId: sourceSessionId,
@@ -1730,7 +1834,7 @@ async function openBrowser(transport, workspaceId, sourceSessionId, value, conte
1730
1834
  ...value.initialUrl ? { initialUrl: value.initialUrl } : {},
1731
1835
  headless: requestedHeadless,
1732
1836
  ...value.storageMode ? { storageMode: value.storageMode } : {},
1733
- ...value.placement ? { placement: value.placement } : {},
1837
+ ...placement ? { placement } : {},
1734
1838
  ...value.identityId ? { identityId: value.identityId } : {},
1735
1839
  ...value.baseRevisionId ? { baseRevisionId: value.baseRevisionId } : {},
1736
1840
  ...value.networkRouteId ? { networkRouteId: value.networkRouteId } : {},
@@ -1743,7 +1847,11 @@ async function openBrowser(transport, workspaceId, sourceSessionId, value, conte
1743
1847
  operationId: context.operationId
1744
1848
  })).session;
1745
1849
  }
1746
- if (session.lifecycle !== "active") return { session, targets: [] };
1850
+ const chosenProfile = profileChoice ? {
1851
+ attachedProfile: agentAttachedProfile(profileChoice.chosen),
1852
+ ...profileChoice.others.length > 0 ? { otherAttachedProfiles: profileChoice.others.map(agentAttachedProfile) } : {}
1853
+ } : {};
1854
+ if (session.lifecycle !== "active") return { session, targets: [], ...chosenProfile };
1747
1855
  let targets = (await transport.listBrowserTargets(workspaceId, session.id)).targets;
1748
1856
  if (value.initialUrl && !created && !targets.some((target) => sameBrowserUrl(target.url, value.initialUrl))) {
1749
1857
  if (!transport.openBrowserTargetWithInventory) {
@@ -1762,7 +1870,50 @@ async function openBrowser(transport, workspaceId, sourceSessionId, value, conte
1762
1870
  }
1763
1871
  targets = inventory.targets;
1764
1872
  }
1765
- return { session, targets };
1873
+ const primary = openedBrowserTarget(targets, value.initialUrl);
1874
+ const observation = primary ? await observeOpenedBrowserTarget(transport, workspaceId, session.id, primary) : void 0;
1875
+ const opened = value.initialUrl && primary && sameBrowserUrl(primary.url, value.initialUrl) ? primary : void 0;
1876
+ const shown = opened && targets.length > 1 ? [opened] : targets;
1877
+ return {
1878
+ session,
1879
+ targets: shown.map(agentBrowserTarget),
1880
+ ...shown.length < targets.length ? { otherTabCount: targets.length - shown.length } : {},
1881
+ ...observation ? { observation } : {},
1882
+ ...chosenProfile
1883
+ };
1884
+ }
1885
+ function chooseAttachedProfile(inventory) {
1886
+ const usable = inventory.devices.filter((device) => device.state === "connected" && device.capabilities.debuggerAttachment).sort((left, right) => Date.parse(right.updatedAt) - Date.parse(left.updatedAt));
1887
+ const [chosen, ...others] = usable;
1888
+ if (!chosen) {
1889
+ throw new OpenGeniApiError(
1890
+ 409,
1891
+ `No Chrome profile is connected through the Opengeni Browser extension. The person needs a Connected Machine, then the extension: ${OPENGENI_BROWSER_EXTENSION_URL}`,
1892
+ { code: "attached_browser_unavailable", retryable: false }
1893
+ );
1894
+ }
1895
+ return { chosen, others };
1896
+ }
1897
+ function agentAttachedProfile(device) {
1898
+ return {
1899
+ id: device.id,
1900
+ name: device.name,
1901
+ ...device.profileLabel && device.profileLabel !== device.name ? { profileLabel: device.profileLabel } : {}
1902
+ };
1903
+ }
1904
+ function openedBrowserTarget(targets, initialUrl) {
1905
+ const pages = targets.filter((target) => target.kind === "page");
1906
+ return (initialUrl ? pages.find((target) => sameBrowserUrl(target.url, initialUrl)) : void 0) ?? pages.find((target) => target.selected) ?? (pages.length === 1 ? pages[0] : void 0);
1907
+ }
1908
+ async function observeOpenedBrowserTarget(transport, workspaceId, browserSessionId, primary) {
1909
+ try {
1910
+ return projectBrowserObservation(
1911
+ await transport.observeBrowserTarget(workspaceId, browserSessionId, primary.id),
1912
+ "compact"
1913
+ );
1914
+ } catch {
1915
+ return void 0;
1916
+ }
1766
1917
  }
1767
1918
  function sameBrowserUrl(left, right) {
1768
1919
  try {
@@ -1830,14 +1981,47 @@ function flattenBrowserNodes(roots, scopeRef) {
1830
1981
  node: next.node,
1831
1982
  depth: next.depth,
1832
1983
  index: flattened.length,
1833
- withinScope
1984
+ withinScope,
1985
+ ...next.parentName !== void 0 ? { parentName: next.parentName } : {}
1834
1986
  });
1835
1987
  for (const child of [...next.node.children ?? []].reverse()) {
1836
- stack.push({ node: child, depth: next.depth + 1, withinScope });
1988
+ stack.push({
1989
+ node: child,
1990
+ depth: next.depth + 1,
1991
+ withinScope,
1992
+ ...next.node.name !== void 0 ? { parentName: next.node.name } : {}
1993
+ });
1837
1994
  }
1838
1995
  }
1839
1996
  return flattened;
1840
1997
  }
1998
+ var BROWSER_AGENT_STRUCTURAL_ROLES = /* @__PURE__ */ new Set([
1999
+ "dialog",
2000
+ "alertdialog",
2001
+ "alert",
2002
+ "status",
2003
+ "navigation",
2004
+ "main",
2005
+ "form",
2006
+ "table",
2007
+ "grid",
2008
+ "list",
2009
+ "listbox",
2010
+ "menu",
2011
+ "menubar",
2012
+ "tablist",
2013
+ "radiogroup"
2014
+ ]);
2015
+ function redundantAgentNode(flat) {
2016
+ const { node } = flat;
2017
+ if (node.actions.length > 0 || node.states.length > 0) return false;
2018
+ const hasValue = node.value !== void 0 && node.value !== null && node.value !== "";
2019
+ if (node.role === "text" || node.role === "StaticText") {
2020
+ return !hasValue && !node.description && (!node.name || node.name === flat.parentName);
2021
+ }
2022
+ if (BROWSER_AGENT_STRUCTURAL_ROLES.has(node.role)) return false;
2023
+ return !node.name && !node.description && !hasValue;
2024
+ }
1841
2025
  function boundedAgentField(value, onClip) {
1842
2026
  if (value.length <= BROWSER_AGENT_MAX_FIELD_LENGTH) return value;
1843
2027
  onClip();
@@ -1858,8 +2042,8 @@ function projectAgentNode(flat) {
1858
2042
  ...source.value !== void 0 ? {
1859
2043
  value: typeof source.value === "string" ? boundedAgentField(source.value, clip) : source.value
1860
2044
  } : {},
1861
- states: source.states.slice(0, 6).map((state) => boundedAgentField(state, clip)),
1862
- actions: source.actions.slice(0, 6).map((action) => boundedAgentField(action, clip))
2045
+ ...source.states.length > 0 ? { states: source.states.slice(0, 6).map((state) => boundedAgentField(state, clip)) } : {},
2046
+ ...source.actions.length > 0 ? { actions: source.actions.slice(0, 6).map((action) => boundedAgentField(action, clip)) } : {}
1863
2047
  };
1864
2048
  if (source.states.length > 6) clippedFieldCount += source.states.length - 6;
1865
2049
  if (source.actions.length > 6) clippedFieldCount += source.actions.length - 6;
@@ -1897,28 +2081,90 @@ function projectBrowserObservation(observation, view) {
1897
2081
  if (view === "full") return observation;
1898
2082
  const semantic = observation.semantic;
1899
2083
  const roots = semantic?.kind === "snapshot" ? semantic.roots : semantic?.kind === "diff" ? semantic.changed : [];
1900
- const flattened = flattenBrowserNodes(roots);
2084
+ const flattened = flattenBrowserNodes(roots).filter((flat) => !redundantAgentNode(flat));
1901
2085
  const projected = selectAgentNodes(
1902
2086
  flattened,
1903
2087
  BROWSER_AGENT_MAX_NODES,
1904
2088
  BROWSER_AGENT_MAX_NODE_BYTES
1905
2089
  );
2090
+ const omittedNodeCount = flattened.length - projected.nodes.length;
2091
+ const removedRefCount = semantic?.kind === "diff" ? semantic.removedRefs.length : 0;
2092
+ const viewport = observation.viewport;
2093
+ const diagnostics = observation.diagnostics;
2094
+ const hasDiagnostics = diagnostics.consoleErrorCount > 0 || diagnostics.failedRequestCount > 0 || diagnostics.downloadCount > 0 || diagnostics.pageErrorCount > 0;
1906
2095
  return {
1907
- ...observation,
1908
- semantic: null,
2096
+ target: agentBrowserTarget(observation.target),
2097
+ ...observation.frameId ? { frameId: observation.frameId } : {},
2098
+ ...viewport ? {
2099
+ viewport: {
2100
+ width: viewport.width,
2101
+ height: viewport.height,
2102
+ ...viewport.deviceScaleFactor !== 1 ? { deviceScaleFactor: viewport.deviceScaleFactor } : {},
2103
+ ...viewport.maxTouchPoints > 0 ? { maxTouchPoints: viewport.maxTouchPoints } : {}
2104
+ }
2105
+ } : {},
2106
+ ...observation.focusedRef ? { focusedRef: observation.focusedRef } : {},
2107
+ ...observation.changedRegions.length > 0 ? { changedRegions: observation.changedRegions } : {},
2108
+ ...hasDiagnostics ? { diagnostics } : {},
2109
+ ...observation.dialog ? { dialog: observation.dialog } : {},
2110
+ ...observation.screenshot ? { screenshot: observation.screenshot } : {},
1909
2111
  agentView: {
1910
- kind: "compact",
1911
2112
  sourceKind: semantic?.kind ?? "none",
1912
2113
  nodes: projected.nodes,
1913
- sourceNodeCount: flattened.length,
1914
- omittedNodeCount: flattened.length - projected.nodes.length,
1915
- removedRefCount: semantic?.kind === "diff" ? semantic.removedRefs.length : 0,
1916
- clippedFieldCount: projected.clippedFieldCount,
1917
- maxNodes: BROWSER_AGENT_MAX_NODES,
1918
- maxNodeBytes: BROWSER_AGENT_MAX_NODE_BYTES
2114
+ ...omittedNodeCount > 0 ? { omittedNodeCount } : {},
2115
+ ...removedRefCount > 0 ? { removedRefCount } : {},
2116
+ ...projected.clippedFieldCount > 0 ? { clippedFieldCount: projected.clippedFieldCount } : {}
1919
2117
  }
1920
2118
  };
1921
2119
  }
2120
+ function agentBrowserTarget(target) {
2121
+ return {
2122
+ id: target.id,
2123
+ kind: target.kind,
2124
+ title: target.title,
2125
+ url: target.url,
2126
+ selected: target.selected,
2127
+ controllerGeneration: target.controllerGeneration,
2128
+ targetGeneration: target.targetGeneration,
2129
+ documentGeneration: target.documentGeneration
2130
+ };
2131
+ }
2132
+ function agentAttachedInventory(inventory) {
2133
+ const attachedBrowsers = inventory.devices.map((device) => {
2134
+ const unsupported = Object.entries(device.capabilities).filter(([, supported]) => !supported).map(([capability]) => capability);
2135
+ return {
2136
+ id: device.id,
2137
+ name: device.name,
2138
+ ...device.profileLabel ? { profileLabel: device.profileLabel } : {},
2139
+ browserName: device.browserName,
2140
+ platform: device.platform,
2141
+ state: device.state,
2142
+ tabCount: device.tabCount,
2143
+ ...unsupported.length > 0 ? { unsupported } : {}
2144
+ };
2145
+ });
2146
+ const anyConnected = inventory.devices.some((device) => device.state === "connected");
2147
+ const attachedBrowserBridges = anyConnected ? [] : inventory.bridges.filter((bridge) => bridge.state === "online").map((bridge) => ({
2148
+ enrollmentId: bridge.enrollmentId,
2149
+ connectedProfileCount: bridge.connectedProfileCount
2150
+ }));
2151
+ return { attachedBrowserBridges, attachedBrowsers };
2152
+ }
2153
+ function agentTargetList(list) {
2154
+ return {
2155
+ browserSessionId: list.browserSessionId,
2156
+ targets: list.targets.map(agentBrowserTarget)
2157
+ };
2158
+ }
2159
+ function compactActionReceipt(receipt) {
2160
+ return {
2161
+ targetId: receipt.targetId,
2162
+ state: receipt.state,
2163
+ ...receipt.error ? { error: receipt.error } : {},
2164
+ ...receipt.targets && receipt.targets.length > 0 ? { targets: receipt.targets } : {},
2165
+ ...receipt.observation ? { observation: projectBrowserObservation(receipt.observation, "compact") } : {}
2166
+ };
2167
+ }
1922
2168
  function readBrowserObservation(observation, input) {
1923
2169
  if (observation.semantic?.kind !== "snapshot") {
1924
2170
  throw new Error("browser focused read requires a complete accessibility snapshot");
@@ -2413,6 +2659,7 @@ function normalizedUrl(value) {
2413
2659
 
2414
2660
  // src/index.ts
2415
2661
  import {
2662
+ mcpToolRecommendsApproval,
2416
2663
  normalizeCredentialProviderMcpUrl as normalizeCredentialProviderMcpUrl2,
2417
2664
  toolPolicyActionName,
2418
2665
  toolReviewContextFromSchema
@@ -4864,7 +5111,7 @@ import { existsSync, readdirSync } from "fs";
4864
5111
  // ../sdk/package.json
4865
5112
  var package_default = {
4866
5113
  name: "@opengeni/sdk",
4867
- version: "3.0.2-canary.38894290271001",
5114
+ version: "3.1.2",
4868
5115
  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.",
4869
5116
  license: "Apache-2.0",
4870
5117
  repository: {
@@ -5082,7 +5329,7 @@ var package_default = {
5082
5329
  // ../react/package.json
5083
5330
  var package_default2 = {
5084
5331
  name: "@opengeni/react",
5085
- version: "3.0.2-canary.38894290271001",
5332
+ version: "3.1.2",
5086
5333
  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.",
5087
5334
  license: "Apache-2.0",
5088
5335
  repository: {
@@ -5257,6 +5504,10 @@ var package_default2 = {
5257
5504
  types: "./src/session-agents-model.ts",
5258
5505
  default: "./src/session-agents-model.ts"
5259
5506
  },
5507
+ "./scrollbars": {
5508
+ types: "./src/scrollbars.ts",
5509
+ default: "./src/scrollbars.ts"
5510
+ },
5260
5511
  "./session-list-model": {
5261
5512
  types: "./src/session-list-model.ts",
5262
5513
  default: "./src/session-list-model.ts"
@@ -5415,7 +5666,7 @@ var package_default2 = {
5415
5666
  // ../codemode/package.json
5416
5667
  var package_default3 = {
5417
5668
  name: "@opengeni/codemode",
5418
- version: "3.0.2-canary.38894290271001",
5669
+ version: "3.1.2",
5419
5670
  description: "Attempt-frozen programmatic tool catalog and execution authority for Opengeni.",
5420
5671
  license: "Apache-2.0",
5421
5672
  repository: {
@@ -5465,7 +5716,7 @@ var package_default3 = {
5465
5716
  // ../ogtool/package.json
5466
5717
  var package_default4 = {
5467
5718
  name: "@opengeni/ogtool",
5468
- version: "3.0.2-canary.38894290271001",
5719
+ version: "3.1.2",
5469
5720
  description: "Codemode CLI and typed client entrypoint for an Opengeni execution attempt.",
5470
5721
  license: "Apache-2.0",
5471
5722
  repository: {
@@ -8898,6 +9149,7 @@ function installMcpApprovalPolicy(agent, policies, connectorActionPolicy, approv
8898
9149
  serverId: server.registryId,
8899
9150
  toolName: await server.unprefixedToolName(descriptor.name),
8900
9151
  inputSchema: descriptor.inputSchema,
9152
+ recommendsApproval: mcpToolRecommendsApproval(descriptor),
8901
9153
  readReview: (name, args) => server.reviewContext(name, args),
8902
9154
  ...descriptor.title ? { title: descriptor.title } : {},
8903
9155
  ...accountLabel ? { accountLabel } : {}
@@ -8916,7 +9168,8 @@ function installMcpApprovalPolicy(agent, policies, connectorActionPolicy, approv
8916
9168
  const unprefixed = identity2?.toolName ?? tool2.name.slice(policy.prefix.length);
8917
9169
  const originalNeedsApproval = tool2.needsApproval.bind(tool2);
8918
9170
  const originalInvoke = tool2.invoke.bind(tool2);
8919
- const legacyApproval = !policy.connectorBacked && mcpToolRequiresApproval(policy.requireApproval, unprefixed);
9171
+ const recommendsApproval = mcpToolRequiresApproval(policy.requireApproval, unprefixed) || identity2?.recommendsApproval === true;
9172
+ const legacyApproval = !policy.connectorBacked && recommendsApproval;
8920
9173
  if (!policy.connectorBacked && !legacyApproval && !connectorActionPolicy) {
8921
9174
  return tool2;
8922
9175
  }
@@ -8938,14 +9191,14 @@ function installMcpApprovalPolicy(agent, policies, connectorActionPolicy, approv
8938
9191
  }),
8939
9192
  actionName: toolPolicyActionName(unprefixed, identity2?.inputSchema, args),
8940
9193
  ...legacyApproval ? { approvalMode: "session_mcp" } : {},
8941
- defaultDecision: mcpToolRequiresApproval(policy.requireApproval, unprefixed) ? "ask" : "allow"
9194
+ defaultDecision: recommendsApproval ? "ask" : "allow"
8942
9195
  };
8943
9196
  };
8944
9197
  return {
8945
9198
  ...tool2,
8946
9199
  needsApproval: async (runContext, parsedInput, callId) => {
8947
9200
  if (!connectorActionPolicy) {
8948
- return mcpToolRequiresApproval(policy.requireApproval, unprefixed) || await originalNeedsApproval(runContext, parsedInput, callId);
9201
+ return recommendsApproval || await originalNeedsApproval(runContext, parsedInput, callId);
8949
9202
  }
8950
9203
  if (!callId) {
8951
9204
  throw new Error("Connector action is missing its durable approval identity");
@@ -8960,7 +9213,7 @@ function installMcpApprovalPolicy(agent, policies, connectorActionPolicy, approv
8960
9213
  approvalRequiredCallIds.delete(callId);
8961
9214
  return false;
8962
9215
  }
8963
- const requiresApproval = preparation.managed ? preparation.decision === "ask" : mcpToolRequiresApproval(policy.requireApproval, unprefixed);
9216
+ const requiresApproval = preparation.managed ? preparation.decision === "ask" : recommendsApproval;
8964
9217
  if (requiresApproval) approvalRequiredCallIds.add(callId);
8965
9218
  else approvalRequiredCallIds.delete(callId);
8966
9219
  return requiresApproval;
@@ -9159,7 +9412,7 @@ function installInteractionInterventionPolicy(agent, approvedToolCallId) {
9159
9412
  }
9160
9413
  function applyMcpApprovalPolicy(agent, settings, connectorActionPolicy, resolvedMcpConnectionIds, approvedToolCallId) {
9161
9414
  const policies = settings.mcpServers.filter(
9162
- (server) => Boolean(server.connectionRef) || Boolean(connectorActionPolicy && attemptToolSource(server.id) === "mcp") || server.requireApproval === true || Array.isArray(server.requireApproval) && server.requireApproval.length > 0
9415
+ (server) => Boolean(server.connectionRef) || attemptToolSource(server.id) === "mcp" || server.requireApproval === true || Array.isArray(server.requireApproval) && server.requireApproval.length > 0
9163
9416
  ).map((server) => {
9164
9417
  const connectionId = () => {
9165
9418
  return resolvedMcpConnectionId(server, resolvedMcpConnectionIds) ?? (server.connectionRef ? null : sessionMcpApprovalConnectionId(server.id, server.url));
@@ -10324,7 +10577,7 @@ function installAttemptConnectorActionGatewayLifecycle(definitions, registry, re
10324
10577
  definition.inputSchema,
10325
10578
  arguments_
10326
10579
  ),
10327
- defaultDecision: attemptToolApproval(config, definition.identity.toolName) === "human" ? "ask" : "allow"
10580
+ defaultDecision: definition.approval === "human" ? "ask" : "allow"
10328
10581
  };
10329
10582
  } : (approvalId, arguments_) => ({
10330
10583
  approvalId,
@@ -10515,7 +10768,7 @@ async function prepareToolGatewayDefinitionsFromServers(servers, registry, callI
10515
10768
  ...tool2.annotations ? { annotations: tool2.annotations } : {},
10516
10769
  ...tool2.icons ? { icons: tool2.icons } : {},
10517
10770
  source: attemptToolSource(server.registryId),
10518
- approval: attemptToolApproval(config, toolName),
10771
+ approval: attemptToolApproval(config, toolName, tool2),
10519
10772
  effectAuthorityDigest: digestCanonicalJson({
10520
10773
  version: 1,
10521
10774
  serverId: server.registryId,
@@ -10630,8 +10883,8 @@ function attemptToolSource(serverId) {
10630
10883
  if (serverId === CODEX_APPS_MCP_SERVER_ID) return "codex_apps";
10631
10884
  return "mcp";
10632
10885
  }
10633
- function attemptToolApproval(config, toolName) {
10634
- if (config.requireApproval === true || Array.isArray(config.requireApproval) && config.requireApproval.includes(toolName)) {
10886
+ function attemptToolApproval(config, toolName, tool2) {
10887
+ if (config.requireApproval === true || Array.isArray(config.requireApproval) && config.requireApproval.includes(toolName) || attemptToolSource(config.id) === "mcp" && mcpToolRecommendsApproval(tool2)) {
10635
10888
  return "human";
10636
10889
  }
10637
10890
  return config.connectionRef ? "policy" : "none";
@@ -15562,6 +15815,7 @@ function sortJson(value) {
15562
15815
  export {
15563
15816
  INTERACTION_ATTEMPT_TOOL_NAMES,
15564
15817
  createInteractionAttemptToolDefinitions,
15818
+ nativeCuaSchema,
15565
15819
  createFirstPartyInteractionAttemptToolDefinitions,
15566
15820
  interactionToolErrorOutput,
15567
15821
  secretReferenceToolResult,
@@ -15748,4 +16002,4 @@ export {
15748
16002
  runAzureCliLoginHook,
15749
16003
  renderSessionGoalContext2 as renderSessionGoalContext
15750
16004
  };
15751
- //# sourceMappingURL=chunk-JDNBDSQV.js.map
16005
+ //# sourceMappingURL=chunk-TE3JIUL6.js.map