@opengeni/runtime 3.2.2 → 3.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (69) hide show
  1. package/dist/agent-LJT5NPWT.js +9 -0
  2. package/dist/assets/codemode-client.json +1 -1
  3. package/dist/browser-current-tab.d.ts +46 -0
  4. package/dist/browser-model-text.d.ts +126 -0
  5. package/dist/{chunk-2AUDDDO2.js → chunk-3DFH3ZHU.js} +784 -121
  6. package/dist/chunk-3DFH3ZHU.js.map +1 -0
  7. package/dist/{chunk-HJSIPTFA.js → chunk-4XDJ4TJA.js} +2 -2
  8. package/dist/{chunk-XQ23VCZ4.js → chunk-6FQ6KEII.js} +3 -3
  9. package/dist/{chunk-7LJ7KDPI.js → chunk-ERD4ICVB.js} +4 -3
  10. package/dist/{chunk-462CH77G.js → chunk-ETTCGPBT.js} +400 -9
  11. package/dist/chunk-ETTCGPBT.js.map +1 -0
  12. package/dist/{chunk-7OUG7WBV.js → chunk-GWRBALGQ.js} +181 -13
  13. package/dist/chunk-GWRBALGQ.js.map +1 -0
  14. package/dist/{chunk-YG26XE7B.js → chunk-JYDG2A7H.js} +2 -2
  15. package/dist/{chunk-RSHQSLEJ.js → chunk-KIL4FGX5.js} +3 -3
  16. package/dist/{chunk-NWS4HPB7.js → chunk-MIAL5I4O.js} +2 -2
  17. package/dist/{chunk-Z5U6WE22.js → chunk-PRZPGRIK.js} +2 -2
  18. package/dist/{chunk-KCPW4K7L.js → chunk-PZQUUBEB.js} +2 -2
  19. package/dist/{chunk-5WJOPANS.js → chunk-Y5THZH5N.js} +7 -7
  20. package/dist/codex-tool-search.d.ts +9 -0
  21. package/dist/gmail-rest-mcp.js +8 -8
  22. package/dist/index.d.ts +3 -0
  23. package/dist/index.js +14 -12
  24. package/dist/interaction-tool-json-schema.d.ts +27 -0
  25. package/dist/{lazy-manifest-AJ6XPJ4F.js → lazy-manifest-BLZ3UZLX.js} +4 -4
  26. package/dist/lazy-tool-transport.d.ts +10 -0
  27. package/dist/{localSources-SSIEH5F5.js → localSources-I6SIQ6CX.js} +6 -6
  28. package/dist/model-call.js +3 -3
  29. package/dist/sandbox/browser-control-client.d.ts +87 -0
  30. package/dist/sandbox/browser-control-http.d.ts +33 -0
  31. package/dist/sandbox/index.d.ts +1 -1
  32. package/dist/sandbox/index.js +7 -7
  33. package/dist/sandbox/routing/backend-resolver.d.ts +1 -0
  34. package/dist/sandbox/selfhosted/session.d.ts +22 -0
  35. package/dist/slack-rest-mcp.js +8 -8
  36. package/dist/workspace-tool-gateway.js +12 -12
  37. package/package.json +14 -14
  38. package/src/browser-current-tab.ts +139 -0
  39. package/src/browser-model-text.ts +378 -0
  40. package/src/bundled_site_skills/opengeni-sites/SKILL.md +46 -12
  41. package/src/codex-tool-search.ts +53 -0
  42. package/src/index.ts +39 -1
  43. package/src/interaction-tool-json-schema.ts +281 -0
  44. package/src/interaction-tools.ts +425 -235
  45. package/src/lazy-tool-transport.ts +229 -10
  46. package/src/model-input.ts +12 -1
  47. package/src/sandbox/browser-control-client.ts +425 -0
  48. package/src/sandbox/browser-control-http.ts +32 -0
  49. package/src/sandbox/index.ts +4 -0
  50. package/src/sandbox/routing/backend-resolver.ts +2 -0
  51. package/src/sandbox/selfhosted/session.ts +154 -0
  52. package/dist/agent-CTPLA3HP.js +0 -9
  53. package/dist/browser-action-json-schema.d.ts +0 -4
  54. package/dist/chunk-2AUDDDO2.js.map +0 -1
  55. package/dist/chunk-462CH77G.js.map +0 -1
  56. package/dist/chunk-7OUG7WBV.js.map +0 -1
  57. package/src/browser-action-json-schema.ts +0 -10
  58. /package/dist/{agent-CTPLA3HP.js.map → agent-LJT5NPWT.js.map} +0 -0
  59. /package/dist/{chunk-HJSIPTFA.js.map → chunk-4XDJ4TJA.js.map} +0 -0
  60. /package/dist/{chunk-XQ23VCZ4.js.map → chunk-6FQ6KEII.js.map} +0 -0
  61. /package/dist/{chunk-7LJ7KDPI.js.map → chunk-ERD4ICVB.js.map} +0 -0
  62. /package/dist/{chunk-YG26XE7B.js.map → chunk-JYDG2A7H.js.map} +0 -0
  63. /package/dist/{chunk-RSHQSLEJ.js.map → chunk-KIL4FGX5.js.map} +0 -0
  64. /package/dist/{chunk-NWS4HPB7.js.map → chunk-MIAL5I4O.js.map} +0 -0
  65. /package/dist/{chunk-Z5U6WE22.js.map → chunk-PRZPGRIK.js.map} +0 -0
  66. /package/dist/{chunk-KCPW4K7L.js.map → chunk-PZQUUBEB.js.map} +0 -0
  67. /package/dist/{chunk-5WJOPANS.js.map → chunk-Y5THZH5N.js.map} +0 -0
  68. /package/dist/{lazy-manifest-AJ6XPJ4F.js.map → lazy-manifest-BLZ3UZLX.js.map} +0 -0
  69. /package/dist/{localSources-SSIEH5F5.js.map → localSources-I6SIQ6CX.js.map} +0 -0
@@ -1,6 +1,7 @@
1
1
  import { ControlResponse, type BrowserControlEnsureRequest, type BrowserControlEnsureResponse, type BrowserFramesOpenRequest, type ComputerFramesOpenRequest, type StreamChannel } from "@opengeni/agent-proto";
2
2
  import { Manifest } from "@openai/agents/sandbox";
3
3
  import type { ExposedPortEndpoint } from "../stream-port.js";
4
+ import { type BrowserControlHttpCall, type BrowserControlHttpOutcome } from "../browser-control-http.js";
4
5
  import { type ControlRpc } from "./control-rpc.js";
5
6
  import { type SelfhostedRetryClock } from "./retry-policy.js";
6
7
  import type { SelfhostedOpObserver } from "./op-observer.js";
@@ -95,11 +96,16 @@ export interface SelfhostedBackgroundCommandAdoption {
95
96
  connectionInstanceId: string;
96
97
  opId: string;
97
98
  command: string;
99
+ /** The exec already failed because the machine stopped answering. Record it
100
+ * with a stop request instead of as a running background command. */
101
+ abandoned?: boolean;
98
102
  }
99
103
  /** Exact command-admission snapshot. A worker resolves this immediately before
100
104
  * every exec/Git admission; retries and already-started operations retain it. */
101
105
  export interface SelfhostedOperationAdmission {
102
106
  transactionalFsWriteSupported?: boolean;
107
+ /** The live runner serves in-process browser/computer controller requests. */
108
+ browserControlHttpSupported?: boolean;
103
109
  /** Workspace segment of the physical agent/relay route. Personal machines may
104
110
  * originate in a different same-organization workspace than the session. */
105
111
  workspaceId?: string;
@@ -123,6 +129,9 @@ export interface SelfhostedOperationAdmission {
123
129
  export interface SelfhostedSessionDeps {
124
130
  /** Exact live daemon capability; absent preserves legacy small-file writes. */
125
131
  transactionalFsWriteSupported?: boolean;
132
+ /** Exact live daemon capability; absent keeps controller requests on the
133
+ * command transport. */
134
+ browserControlHttpSupported?: boolean;
126
135
  /** Authorization/session workspace. */
127
136
  workspaceId: string;
128
137
  /** Physical control-plane workspace. Defaults to workspaceId for legacy and
@@ -303,6 +312,7 @@ export declare class SelfhostedSession {
303
312
  private readonly resourcePolicySupported;
304
313
  private readonly operationCpuQuotaSupported;
305
314
  private readonly transactionalFsWriteSupported;
315
+ private readonly browserControlHttpSupported;
306
316
  private readonly defaultOpStream;
307
317
  private readonly connectionInstanceId;
308
318
  private readonly resolveOperationAdmission;
@@ -524,6 +534,14 @@ export declare class SelfhostedSession {
524
534
  /** Ensure the loopback browser controller sidecar owned by this connected
525
535
  * machine. The authority scope is supplied by the caller and remains local. */
526
536
  ensureBrowserControl(request: BrowserControlEnsureRequest): Promise<BrowserControlEnsureResponse>;
537
+ /** Send one request to the agent-owned controller of an exact authority
538
+ * scope, served inside the runner over loopback without starting a process.
539
+ * `unsupported` means this connection's runner does not serve it and nothing
540
+ * was sent. `controller_absent` means no controller for that scope and
541
+ * generation accepted the request, so it was not delivered and the caller may
542
+ * ensure the controller and send again. A body too large for one reply is
543
+ * drained from the runner's spool; the request is never repeated. */
544
+ browserControlHttp(request: BrowserControlHttpCall): Promise<BrowserControlHttpOutcome>;
527
545
  /** Open one browser-native frame producer and return its canonical relay
528
546
  * endpoint. This does not route through `resolveExposedPort`: that legacy
529
547
  * method allocates PTY/desktop resources based on fixed ports, while this op
@@ -597,6 +615,7 @@ export declare class SelfhostedSandboxClient {
597
615
  private readonly operationResourcePolicySupported;
598
616
  private readonly operationCpuQuotaSupported;
599
617
  private readonly transactionalFsWriteSupported;
618
+ private readonly browserControlHttpSupported;
600
619
  private readonly resolveOperationAdmission;
601
620
  private readonly adoptBackgroundCommand;
602
621
  private readonly settleBackgroundCommand;
@@ -631,6 +650,7 @@ export declare class SelfhostedSandboxClient {
631
650
  operationResourcePolicySupported?: boolean;
632
651
  operationCpuQuotaSupported?: boolean;
633
652
  transactionalFsWriteSupported?: boolean;
653
+ browserControlHttpSupported?: boolean;
634
654
  resolveOperationAdmission?: () => Promise<SelfhostedOperationAdmission | null>;
635
655
  adoptBackgroundCommand?: SelfhostedSessionDeps["adoptBackgroundCommand"];
636
656
  settleBackgroundCommand?: SelfhostedSessionDeps["settleBackgroundCommand"];
@@ -711,6 +731,8 @@ export interface SelfhostedSessionBuild {
711
731
  /** Exact live CPU enforcement capability paired with the initial snapshot. */
712
732
  operationCpuQuotaSupported?: boolean;
713
733
  transactionalFsWriteSupported?: boolean;
734
+ /** Exact live runner capability for in-process controller requests. */
735
+ browserControlHttpSupported?: boolean;
714
736
  /** Live last-boundary operation admission resolver; see SelfhostedSessionDeps. */
715
737
  resolveOperationAdmission?: () => Promise<SelfhostedOperationAdmission | null>;
716
738
  adoptBackgroundCommand?: SelfhostedSessionDeps["adoptBackgroundCommand"];
@@ -8,15 +8,15 @@ import {
8
8
  SlackRestMcpServer,
9
9
  isOfficialSlackMcpConfig,
10
10
  slackRestToolIsMutation
11
- } from "./chunk-RSHQSLEJ.js";
12
- import "./chunk-Z5U6WE22.js";
13
- import "./chunk-5WJOPANS.js";
11
+ } from "./chunk-KIL4FGX5.js";
12
+ import "./chunk-PRZPGRIK.js";
13
+ import "./chunk-Y5THZH5N.js";
14
14
  import "./chunk-4A4XTKKX.js";
15
- import "./chunk-YG26XE7B.js";
16
- import "./chunk-NWS4HPB7.js";
17
- import "./chunk-HJSIPTFA.js";
18
- import "./chunk-KCPW4K7L.js";
19
- import "./chunk-7LJ7KDPI.js";
15
+ import "./chunk-JYDG2A7H.js";
16
+ import "./chunk-MIAL5I4O.js";
17
+ import "./chunk-4XDJ4TJA.js";
18
+ import "./chunk-PZQUUBEB.js";
19
+ import "./chunk-ERD4ICVB.js";
20
20
  import "./chunk-LJNCGUMB.js";
21
21
  import "./chunk-PLDDJCW6.js";
22
22
  export {
@@ -3,21 +3,21 @@ import {
3
3
  prepareAgentTools,
4
4
  secretArgumentMode,
5
5
  sessionMcpApprovalConnectionId
6
- } from "./chunk-2AUDDDO2.js";
7
- import "./chunk-462CH77G.js";
6
+ } from "./chunk-3DFH3ZHU.js";
7
+ import "./chunk-ETTCGPBT.js";
8
8
  import "./chunk-4KFT2G3W.js";
9
- import "./chunk-7OUG7WBV.js";
9
+ import "./chunk-GWRBALGQ.js";
10
10
  import "./chunk-5ULGMFKR.js";
11
- import "./chunk-XQ23VCZ4.js";
12
- import "./chunk-RSHQSLEJ.js";
13
- import "./chunk-Z5U6WE22.js";
14
- import "./chunk-5WJOPANS.js";
11
+ import "./chunk-6FQ6KEII.js";
12
+ import "./chunk-KIL4FGX5.js";
13
+ import "./chunk-PRZPGRIK.js";
14
+ import "./chunk-Y5THZH5N.js";
15
15
  import "./chunk-4A4XTKKX.js";
16
- import "./chunk-YG26XE7B.js";
17
- import "./chunk-NWS4HPB7.js";
18
- import "./chunk-HJSIPTFA.js";
19
- import "./chunk-KCPW4K7L.js";
20
- import "./chunk-7LJ7KDPI.js";
16
+ import "./chunk-JYDG2A7H.js";
17
+ import "./chunk-MIAL5I4O.js";
18
+ import "./chunk-4XDJ4TJA.js";
19
+ import "./chunk-PZQUUBEB.js";
20
+ import "./chunk-ERD4ICVB.js";
21
21
  import "./chunk-LJNCGUMB.js";
22
22
  import "./chunk-PLDDJCW6.js";
23
23
  export {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@opengeni/runtime",
3
- "version": "3.2.2",
3
+ "version": "3.4.0",
4
4
  "license": "Apache-2.0",
5
5
  "repository": {
6
6
  "type": "git",
@@ -75,19 +75,19 @@
75
75
  "@openai/agents": "0.14.3",
76
76
  "@openai/agents-core": "0.14.3",
77
77
  "@openai/agents-extensions": "0.14.3",
78
- "@opengeni/agent-proto": "3.2.2",
79
- "@opengeni/capabilities": "3.2.2",
80
- "@opengeni/codemode": "3.2.2",
81
- "@opengeni/codex": "3.2.2",
82
- "@opengeni/config": "3.2.2",
83
- "@opengeni/contracts": "3.2.2",
84
- "@opengeni/interaction": "3.2.2",
85
- "@opengeni/network": "3.2.2",
86
- "@opengeni/observability": "3.2.2",
87
- "@opengeni/sdk": "3.2.2",
88
- "@opengeni/tool-gateway": "3.2.2",
89
- "@opengeni/vaults": "3.2.2",
90
- "@opengeni/xai-subscription": "3.2.2",
78
+ "@opengeni/agent-proto": "3.4.0",
79
+ "@opengeni/capabilities": "3.4.0",
80
+ "@opengeni/codemode": "3.4.0",
81
+ "@opengeni/codex": "3.4.0",
82
+ "@opengeni/config": "3.4.0",
83
+ "@opengeni/contracts": "3.4.0",
84
+ "@opengeni/interaction": "3.4.0",
85
+ "@opengeni/network": "3.4.0",
86
+ "@opengeni/observability": "3.4.0",
87
+ "@opengeni/sdk": "3.4.0",
88
+ "@opengeni/tool-gateway": "3.4.0",
89
+ "@opengeni/vaults": "3.4.0",
90
+ "@opengeni/xai-subscription": "3.4.0",
91
91
  "debug": "4.4.3",
92
92
  "modal": "0.9.0",
93
93
  "openai": "6.47.0",
@@ -0,0 +1,139 @@
1
+ // The browser tab an agent is working in.
2
+ //
3
+ // Browser tools may omit browserSessionId and targetId to keep working in the
4
+ // tab the agent used last, the way a person keeps using the tab in front of
5
+ // them. A step then costs a few output tokens instead of two identifiers, and
6
+ // output tokens dominate a browser step's model latency. The remembered tab
7
+ // lives for one turn attempt; a call that omits identifiers before any browser
8
+ // call in that attempt resolves this session's most recently used live
9
+ // browser and its selected tab.
10
+
11
+ export class BrowserTargetResolutionError extends Error {
12
+ constructor(
13
+ readonly code: "browser_session_required" | "browser_target_required",
14
+ message: string,
15
+ ) {
16
+ super(message);
17
+ this.name = "BrowserTargetResolutionError";
18
+ }
19
+ }
20
+
21
+ export type CurrentBrowserTabDeps = {
22
+ /** This agent session's live BrowserSessions. */
23
+ listLiveSessions: () => Promise<ReadonlyArray<{ id: string; lastUsedAt: string }>>;
24
+ /** The tabs of one BrowserSession. */
25
+ listTargets: (
26
+ browserSessionId: string,
27
+ ) => Promise<ReadonlyArray<{ id: string; kind: string; selected: boolean }>>;
28
+ };
29
+
30
+ export type ResolvedBrowserSession = {
31
+ browserSessionId: string;
32
+ /** True when the identifier came from memory or lookup, not the caller. */
33
+ implicit: boolean;
34
+ };
35
+
36
+ export type ResolvedBrowserTarget = ResolvedBrowserSession & {
37
+ targetId: string;
38
+ implicitTarget: boolean;
39
+ };
40
+
41
+ export class CurrentBrowserTab {
42
+ private current: { browserSessionId: string; targetId: string | null } | null = null;
43
+
44
+ constructor(private readonly deps: CurrentBrowserTabDeps) {}
45
+
46
+ /** Record the session and, when known, the tab a successful call used. */
47
+ use(browserSessionId: string, targetId?: string | null): void {
48
+ if (targetId === undefined) {
49
+ if (this.current?.browserSessionId !== browserSessionId) {
50
+ this.current = { browserSessionId, targetId: null };
51
+ }
52
+ return;
53
+ }
54
+ this.current = { browserSessionId, targetId };
55
+ }
56
+
57
+ forgetTarget(browserSessionId: string, targetId: string): void {
58
+ if (this.current?.browserSessionId === browserSessionId && this.current.targetId === targetId) {
59
+ this.current = { browserSessionId, targetId: null };
60
+ }
61
+ }
62
+
63
+ forgetSession(browserSessionId: string): void {
64
+ if (this.current?.browserSessionId === browserSessionId) this.current = null;
65
+ }
66
+
67
+ /** A call that relied on remembered identifiers failed: resolve afresh next time. */
68
+ failed(resolved: ResolvedBrowserSession & { implicitTarget?: boolean }): void {
69
+ if (resolved.implicit) this.forgetSession(resolved.browserSessionId);
70
+ else if (
71
+ resolved.implicitTarget &&
72
+ this.current?.browserSessionId === resolved.browserSessionId
73
+ ) {
74
+ this.current = { browserSessionId: resolved.browserSessionId, targetId: null };
75
+ }
76
+ }
77
+
78
+ async session(browserSessionId: string | undefined): Promise<ResolvedBrowserSession> {
79
+ if (browserSessionId !== undefined) return { browserSessionId, implicit: false };
80
+ if (this.current) return { browserSessionId: this.current.browserSessionId, implicit: true };
81
+ const sessions = [...(await this.deps.listLiveSessions())].sort((left, right) =>
82
+ right.lastUsedAt.localeCompare(left.lastUsedAt),
83
+ );
84
+ const latest = sessions[0];
85
+ if (!latest) {
86
+ throw new BrowserTargetResolutionError(
87
+ "browser_session_required",
88
+ "This session has no open browser. Call browser_open first, or pass browserSessionId.",
89
+ );
90
+ }
91
+ return { browserSessionId: latest.id, implicit: true };
92
+ }
93
+
94
+ async target(value: {
95
+ browserSessionId?: string | undefined;
96
+ targetId?: string | undefined;
97
+ }): Promise<ResolvedBrowserTarget> {
98
+ const session = await this.session(value.browserSessionId);
99
+ if (value.targetId !== undefined) {
100
+ return { ...session, targetId: value.targetId, implicitTarget: false };
101
+ }
102
+ if (this.current?.browserSessionId === session.browserSessionId && this.current.targetId) {
103
+ return { ...session, targetId: this.current.targetId, implicitTarget: true };
104
+ }
105
+ const pages = (await this.deps.listTargets(session.browserSessionId)).filter(
106
+ (target) => target.kind === "page" || target.kind === "popup",
107
+ );
108
+ const chosen =
109
+ pages.find((target) => target.selected) ?? (pages.length === 1 ? pages[0] : null);
110
+ if (!chosen) {
111
+ throw new BrowserTargetResolutionError(
112
+ "browser_target_required",
113
+ pages.length === 0
114
+ ? "This browser has no open tab. Open one with browser_tabs operation=open."
115
+ : `This browser has ${pages.length} tabs and none is selected. Pass targetId from browser_tabs operation=list.`,
116
+ );
117
+ }
118
+ return { ...session, targetId: chosen.id, implicitTarget: true };
119
+ }
120
+ }
121
+
122
+ /** An element ref passed where a locator is expected, as a bare string. */
123
+ export function expandRefShorthand(action: unknown): unknown {
124
+ if (!action || typeof action !== "object" || Array.isArray(action)) return action;
125
+ const record = action as Record<string, unknown>;
126
+ let expanded: Record<string, unknown> | null = null;
127
+ for (const field of ["locator", "from", "to"] as const) {
128
+ const value = record[field];
129
+ if (typeof value === "string") {
130
+ expanded ??= { ...record };
131
+ expanded[field] = { kind: "ref", ref: value };
132
+ }
133
+ }
134
+ if (Array.isArray(record.actions)) {
135
+ expanded ??= { ...record };
136
+ expanded.actions = record.actions.map(expandRefShorthand);
137
+ }
138
+ return expanded ?? action;
139
+ }