@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.
- package/dist/assets/codemode-client.json +1 -1
- package/dist/{chunk-EQQ3YOKR.js → chunk-7OUG7WBV.js} +165 -121
- package/dist/chunk-7OUG7WBV.js.map +1 -0
- package/dist/{chunk-JDNBDSQV.js → chunk-TE3JIUL6.js} +330 -76
- package/dist/chunk-TE3JIUL6.js.map +1 -0
- package/dist/context-compaction.d.ts +6 -4
- package/dist/index.d.ts +1 -0
- package/dist/index.js +6 -2
- package/dist/interaction-tools.d.ts +11 -1
- package/dist/model-call.js +1 -1
- package/dist/model-image-sizing.d.ts +10 -4
- package/dist/workspace-tool-gateway.js +2 -2
- package/package.json +14 -14
- package/src/bundled_site_skills/opengeni-sites/SKILL.md +41 -0
- package/src/codex-tool-search.ts +48 -0
- package/src/context-compaction.ts +51 -31
- package/src/history-sanitizer.ts +3 -0
- package/src/index.ts +26 -16
- package/src/interaction-tools.ts +478 -68
- package/src/model-image-sizing.ts +30 -5
- package/dist/chunk-EQQ3YOKR.js.map +0 -1
- package/dist/chunk-JDNBDSQV.js.map +0 -1
|
@@ -101,7 +101,7 @@ import {
|
|
|
101
101
|
withModelRequestCapture,
|
|
102
102
|
withModelTransportStartedObserver,
|
|
103
103
|
withPreparedCompactionRequest
|
|
104
|
-
} from "./chunk-
|
|
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
|
-
|
|
415
|
-
|
|
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
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
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 =
|
|
429
|
-
|
|
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
|
|
434
|
-
|
|
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(
|
|
586
|
-
attachedBrowsers: external_exports.array(
|
|
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:
|
|
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({
|
|
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 =
|
|
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.
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
|
945
|
-
input.
|
|
946
|
-
|
|
947
|
-
|
|
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
|
|
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;
|
|
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
|
|
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
|
-
|
|
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
|
|
1712
|
-
|
|
1713
|
-
|
|
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
|
-
...
|
|
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
|
-
|
|
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
|
-
|
|
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({
|
|
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
|
-
|
|
1908
|
-
|
|
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
|
-
|
|
1914
|
-
|
|
1915
|
-
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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
|
|
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:
|
|
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
|
|
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" :
|
|
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) ||
|
|
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:
|
|
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-
|
|
16005
|
+
//# sourceMappingURL=chunk-TE3JIUL6.js.map
|