@oharness/engine 0.9.2 → 0.10.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 (119) hide show
  1. package/dist/agent/agent.d.ts +207 -1
  2. package/dist/agent/agent.js +691 -55
  3. package/dist/agent/agent.js.map +1 -1
  4. package/dist/agent/background.d.ts +135 -0
  5. package/dist/agent/background.js +307 -0
  6. package/dist/agent/background.js.map +1 -0
  7. package/dist/agent/compaction.d.ts +7 -0
  8. package/dist/agent/compaction.js +11 -3
  9. package/dist/agent/compaction.js.map +1 -1
  10. package/dist/agent/goal.d.ts +36 -0
  11. package/dist/agent/goal.js +71 -0
  12. package/dist/agent/goal.js.map +1 -0
  13. package/dist/agent/permissions.d.ts +6 -0
  14. package/dist/agent/permissions.js +2 -1
  15. package/dist/agent/permissions.js.map +1 -1
  16. package/dist/agent/session.d.ts +36 -0
  17. package/dist/agent/session.js +72 -0
  18. package/dist/agent/session.js.map +1 -1
  19. package/dist/agent/store.d.ts +25 -0
  20. package/dist/agent/store.js +21 -0
  21. package/dist/agent/store.js.map +1 -1
  22. package/dist/agent/subagent.d.ts +12 -0
  23. package/dist/agent/subagent.js +11 -1
  24. package/dist/agent/subagent.js.map +1 -1
  25. package/dist/agent/workspace.d.ts +9 -0
  26. package/dist/agent/workspace.js +59 -5
  27. package/dist/agent/workspace.js.map +1 -1
  28. package/dist/auth/manager.d.ts +9 -0
  29. package/dist/auth/manager.js +67 -6
  30. package/dist/auth/manager.js.map +1 -1
  31. package/dist/auth/providers/account.js +5 -4
  32. package/dist/auth/providers/account.js.map +1 -1
  33. package/dist/browser/tools.js +3 -0
  34. package/dist/browser/tools.js.map +1 -1
  35. package/dist/computer/arbiter.d.ts +69 -0
  36. package/dist/computer/arbiter.js +128 -0
  37. package/dist/computer/arbiter.js.map +1 -0
  38. package/dist/computer/cua-driver.d.ts +115 -0
  39. package/dist/computer/cua-driver.js +453 -0
  40. package/dist/computer/cua-driver.js.map +1 -0
  41. package/dist/computer/helper-client.d.ts +78 -0
  42. package/dist/computer/helper-client.js +163 -0
  43. package/dist/computer/helper-client.js.map +1 -0
  44. package/dist/computer/index.d.ts +15 -0
  45. package/dist/computer/index.js +9 -0
  46. package/dist/computer/index.js.map +1 -0
  47. package/dist/computer/mode.d.ts +19 -0
  48. package/dist/computer/mode.js +42 -0
  49. package/dist/computer/mode.js.map +1 -0
  50. package/dist/computer/plugin.d.ts +24 -0
  51. package/dist/computer/plugin.js +17 -0
  52. package/dist/computer/plugin.js.map +1 -0
  53. package/dist/computer/policy.d.ts +29 -0
  54. package/dist/computer/policy.js +127 -0
  55. package/dist/computer/policy.js.map +1 -0
  56. package/dist/computer/session.d.ts +199 -0
  57. package/dist/computer/session.js +392 -0
  58. package/dist/computer/session.js.map +1 -0
  59. package/dist/computer/target.d.ts +187 -0
  60. package/dist/computer/target.js +31 -0
  61. package/dist/computer/target.js.map +1 -0
  62. package/dist/computer/tools.d.ts +8 -0
  63. package/dist/computer/tools.js +537 -0
  64. package/dist/computer/tools.js.map +1 -0
  65. package/dist/core/tokens.js +4 -0
  66. package/dist/core/tokens.js.map +1 -1
  67. package/dist/core/types.d.ts +16 -1
  68. package/dist/core/types.js.map +1 -1
  69. package/dist/harness.d.ts +76 -1
  70. package/dist/harness.js +178 -22
  71. package/dist/harness.js.map +1 -1
  72. package/dist/index.d.ts +3 -0
  73. package/dist/index.js +2 -0
  74. package/dist/index.js.map +1 -1
  75. package/dist/mcp/transport.js +3 -0
  76. package/dist/mcp/transport.js.map +1 -1
  77. package/dist/providers/catalog.js +6 -0
  78. package/dist/providers/catalog.js.map +1 -1
  79. package/dist/providers/discovery.js +10 -2
  80. package/dist/providers/discovery.js.map +1 -1
  81. package/dist/providers/models-dev.js +1 -0
  82. package/dist/providers/models-dev.js.map +1 -1
  83. package/dist/providers/models-dev.json +114 -102
  84. package/dist/providers/piai.d.ts +16 -1
  85. package/dist/providers/piai.js +84 -7
  86. package/dist/providers/piai.js.map +1 -1
  87. package/dist/providers/types.d.ts +6 -0
  88. package/dist/providers/types.js.map +1 -1
  89. package/dist/runtime-plugins/cloud-connector.js +5 -0
  90. package/dist/runtime-plugins/cloud-connector.js.map +1 -1
  91. package/dist/schedule/scheduler.d.ts +38 -0
  92. package/dist/schedule/scheduler.js +101 -1
  93. package/dist/schedule/scheduler.js.map +1 -1
  94. package/dist/tools/builtin/bash.d.ts +6 -0
  95. package/dist/tools/builtin/bash.js +2 -1
  96. package/dist/tools/builtin/bash.js.map +1 -1
  97. package/dist/tools/builtin/recall.js +4 -0
  98. package/dist/tools/builtin/recall.js.map +1 -1
  99. package/dist/tools/builtin/routine.d.ts +9 -0
  100. package/dist/tools/builtin/routine.js +23 -2
  101. package/dist/tools/builtin/routine.js.map +1 -1
  102. package/dist/tools/builtin/task-control.d.ts +21 -0
  103. package/dist/tools/builtin/task-control.js +120 -0
  104. package/dist/tools/builtin/task-control.js.map +1 -0
  105. package/dist/tools/builtin/task.js +50 -9
  106. package/dist/tools/builtin/task.js.map +1 -1
  107. package/dist/tools/builtin/todo.d.ts +1 -1
  108. package/dist/tools/builtin/worktree.d.ts +10 -0
  109. package/dist/tools/builtin/worktree.js +52 -0
  110. package/dist/tools/builtin/worktree.js.map +1 -0
  111. package/dist/tools/define.d.ts +4 -1
  112. package/dist/tools/define.js +2 -0
  113. package/dist/tools/define.js.map +1 -1
  114. package/dist/tools/types.d.ts +112 -0
  115. package/dist/tools/types.js.map +1 -1
  116. package/dist/worktree/index.d.ts +109 -0
  117. package/dist/worktree/index.js +463 -0
  118. package/dist/worktree/index.js.map +1 -0
  119. package/package.json +3 -3
@@ -0,0 +1,199 @@
1
+ import type { Logger } from "../util/logger.ts";
2
+ import { ComputerArbiter } from "./arbiter.ts";
3
+ import type { LeaseHolder } from "./arbiter.ts";
4
+ import type { ActionKind, ComputerTier, PolicyOptions } from "./policy.ts";
5
+ import type { AppInfo, AxNode, ComputerPermissions, ComputerTarget, ComputerTargetFactory, HelperInfo, Rect, Shot, WindowInfo } from "./target.ts";
6
+ /**
7
+ * What the page and the overlay are told about each action, so the person can
8
+ * see where the agent is working without reading the transcript. Presentation
9
+ * only: nothing here goes to the model.
10
+ */
11
+ export interface ComputerActionEvent {
12
+ sessionId: string;
13
+ label: string;
14
+ kind: "look" | "click" | "type" | "scroll" | "drag" | "key" | "control" | "release" | "idle";
15
+ window?: string;
16
+ app?: string;
17
+ /** Screen point the action lands on, when it has one. */
18
+ point?: {
19
+ x: number;
20
+ y: number;
21
+ };
22
+ /** Whether that point is on screen and uncovered: the overlay draws the cursor only then. */
23
+ visible?: boolean;
24
+ /** Frame of the element acted on, for a ref action. */
25
+ frame?: Rect;
26
+ /** Where the window is on screen, so a live view can place the point inside it. */
27
+ windowFrame?: Rect;
28
+ /** The window's title, for the live view's heading. */
29
+ title?: string;
30
+ }
31
+ /**
32
+ * What the windows a turn worked in looked like when it ended, for the person
33
+ * reading the conversation back. Never model input: the agent works from the
34
+ * accessibility tree and takes its own screenshots when it needs one.
35
+ */
36
+ export interface ComputerSnapshotEvent {
37
+ sessionId: string;
38
+ shots: {
39
+ window: string;
40
+ app: string;
41
+ title?: string;
42
+ mimeType: string;
43
+ data: string;
44
+ }[];
45
+ }
46
+ export interface ComputerRuntimeOptions {
47
+ target: ComputerTargetFactory;
48
+ /**
49
+ * Capture one window for the person, outside the platform layer. The host
50
+ * does this, not the target: a target screenshot replaces the snapshot the
51
+ * agent's element refs belong to, and a picture for the transcript must not
52
+ * cost the agent its refs. Without it, turns end with no snapshot.
53
+ */
54
+ snapshot?: (window: string) => Promise<{
55
+ mimeType: string;
56
+ data: string;
57
+ } | undefined>;
58
+ /** Pids of the host app itself; its windows are never listed or driven. */
59
+ selfPids?: () => number[];
60
+ policy?: () => PolicyOptions;
61
+ /** `never` keeps the agent in the background: take_control is refused. */
62
+ takeover?: () => "ask" | "never";
63
+ arbiter?: ComputerArbiter;
64
+ logger?: Logger;
65
+ /**
66
+ * Read the OS grants from the host app itself, live. Preferred over asking
67
+ * the helper: macOS caches a process's Accessibility answer, so a helper
68
+ * started before the grant keeps saying no after the person said yes.
69
+ */
70
+ permissions?: () => Promise<ComputerPermissions>;
71
+ }
72
+ /**
73
+ * What every conversation shares: one helper process, one arbiter.
74
+ *
75
+ * The helper starts on the first call that needs it — registered eagerly,
76
+ * launched lazily, the same rule as the browser — and is restarted on the next
77
+ * call if it dies.
78
+ */
79
+ export declare class ComputerRuntime {
80
+ readonly arbiter: ComputerArbiter;
81
+ private readonly opts;
82
+ private starting?;
83
+ private helperInfo?;
84
+ private readonly observers;
85
+ private readonly snapshotObservers;
86
+ constructor(opts: ComputerRuntimeOptions);
87
+ target(): Promise<ComputerTarget>;
88
+ /** Forget a dead helper so the next call starts a fresh one. */
89
+ reset(): void;
90
+ info(): Promise<HelperInfo>;
91
+ private granted?;
92
+ permissions(): Promise<ComputerPermissions>;
93
+ requestPermissions(grant?: keyof ComputerPermissions): Promise<void>;
94
+ selfPids(): Set<number>;
95
+ policy(): PolicyOptions;
96
+ takeover(): "ask" | "never";
97
+ onAction(listener: (event: ComputerActionEvent) => void): () => void;
98
+ emit(event: ComputerActionEvent): void;
99
+ canSnapshot(): boolean;
100
+ snapshot(window: string): Promise<{
101
+ mimeType: string;
102
+ data: string;
103
+ } | undefined>;
104
+ onSnapshot(listener: (event: ComputerSnapshotEvent) => void): () => void;
105
+ emitSnapshot(event: ComputerSnapshotEvent): void;
106
+ close(): Promise<void>;
107
+ }
108
+ /**
109
+ * One conversation's view of the computer.
110
+ *
111
+ * Holds what only makes sense per conversation: the apps and windows it has
112
+ * seen (so a permission prompt can name an app synchronously), the geometry of
113
+ * the screenshots it was shown (so its coordinates can be mapped back), and
114
+ * the window it last worked in.
115
+ */
116
+ export declare class ComputerUseSession {
117
+ readonly runtime: ComputerRuntime;
118
+ private sessionId;
119
+ private label;
120
+ private readonly apps;
121
+ private readonly windowsById;
122
+ private readonly shots;
123
+ private readonly secureRefs;
124
+ /**
125
+ * Windows this turn worked in whose last state the agent has not seen in a
126
+ * screenshot of its own. Each gets one picture when the turn ends; one the
127
+ * agent screenshotted after its last action already has its picture in the
128
+ * transcript.
129
+ */
130
+ private readonly unseen;
131
+ private readonly refFrames;
132
+ private currentWindow?;
133
+ constructor(runtime: ComputerRuntime, sessionId?: string);
134
+ bind(sessionId: string): void;
135
+ setLabel(label: () => string | undefined): void;
136
+ holder(): LeaseHolder;
137
+ get id(): string;
138
+ listApps(): Promise<AppInfo[]>;
139
+ listWindows(pid?: number): Promise<WindowInfo[]>;
140
+ private rememberApp;
141
+ /**
142
+ * The app a call names, synchronously, for the permission prompt.
143
+ *
144
+ * From what this conversation has already seen; an app it has not listed
145
+ * yet is named as the model wrote it, which still scopes the approval to
146
+ * one app.
147
+ */
148
+ appIdFor(input: {
149
+ app?: string;
150
+ window?: string;
151
+ ref?: string;
152
+ }): string | undefined;
153
+ /** Find the window a call means: by ref, by id, by app, or the last one used. */
154
+ resolveWindow(input: {
155
+ app?: string;
156
+ window?: string;
157
+ ref?: string;
158
+ }): Promise<WindowInfo>;
159
+ tierOf(window: WindowInfo): ComputerTier;
160
+ /**
161
+ * Everything that has to hold before touching a window: it is not ours,
162
+ * its tier allows this kind of action, and no other conversation has it.
163
+ */
164
+ guard(window: WindowInfo, kind: ActionKind): void;
165
+ /**
166
+ * Stay off a window the person is using right now.
167
+ *
168
+ * Their front window with input in the last few seconds is theirs: the
169
+ * lease on it lapses and the call is refused. Pointer-free actions on other
170
+ * windows go ahead regardless.
171
+ */
172
+ respectUser(window: WindowInfo, target: ComputerTarget): Promise<void>;
173
+ /** Keys wait until the person has stopped typing, up to a limit. */
174
+ waitForQuiet(target: ComputerTarget, signal?: AbortSignal, quietMs?: number, maxMs?: number): Promise<void>;
175
+ rememberShot(key: string, shot: Shot): void;
176
+ /**
177
+ * Map a point in the last screenshot of `window` back to the screen.
178
+ *
179
+ * The model only ever sees image pixels. Retina, per-monitor DPI and the
180
+ * downscale to fit the image budget are all folded into the screenshot's own
181
+ * frame, so none of them reach the model.
182
+ */
183
+ toScreen(window: WindowInfo, x: number, y: number): {
184
+ x: number;
185
+ y: number;
186
+ };
187
+ rememberTree(nodes: AxNode[]): void;
188
+ isSecure(ref: string): boolean;
189
+ frameOf(ref: string): Rect | undefined;
190
+ announce(event: Omit<ComputerActionEvent, "sessionId" | "label">, target?: ComputerTarget): Promise<void>;
191
+ /** The agent's own screenshot of this window: the transcript already shows its state. */
192
+ sawWindow(window: string): void;
193
+ /** The turn ended: let go of windows and control, so others need not wait out the lease. */
194
+ endTurn(): void;
195
+ private snapshotTurn;
196
+ close(): Promise<void>;
197
+ }
198
+ /** Refs look like `w<window>.<n>`; the window id is everything between. */
199
+ export declare function windowOfRef(ref: string): string | undefined;
@@ -0,0 +1,392 @@
1
+ import { ComputerArbiter } from "./arbiter.js";
2
+ import { tierAllows, tierFor, tierRefusal } from "./policy.js";
3
+ import { ComputerError } from "./target.js";
4
+ /**
5
+ * What every conversation shares: one helper process, one arbiter.
6
+ *
7
+ * The helper starts on the first call that needs it — registered eagerly,
8
+ * launched lazily, the same rule as the browser — and is restarted on the next
9
+ * call if it dies.
10
+ */
11
+ export class ComputerRuntime {
12
+ arbiter;
13
+ opts;
14
+ starting;
15
+ helperInfo;
16
+ observers = new Set();
17
+ snapshotObservers = new Set();
18
+ constructor(opts) {
19
+ this.opts = opts;
20
+ this.arbiter = opts.arbiter ?? new ComputerArbiter();
21
+ }
22
+ async target() {
23
+ if (!this.starting) {
24
+ this.starting = this.opts.target().catch((err) => {
25
+ this.starting = undefined;
26
+ throw err;
27
+ });
28
+ }
29
+ return this.starting;
30
+ }
31
+ /** Forget a dead helper so the next call starts a fresh one. */
32
+ reset() {
33
+ const old = this.starting;
34
+ this.starting = undefined;
35
+ this.helperInfo = undefined;
36
+ void old?.then((target) => target.close()).catch(() => { });
37
+ }
38
+ async info() {
39
+ if (!this.helperInfo)
40
+ this.helperInfo = await (await this.target()).info();
41
+ return this.helperInfo;
42
+ }
43
+ granted;
44
+ async permissions() {
45
+ const now = this.opts.permissions ? await this.opts.permissions() : await (await this.target()).permissions();
46
+ // A grant that just arrived is invisible to a helper started before it:
47
+ // start a fresh one, which asks the OS again.
48
+ const before = this.granted;
49
+ if (before && ((now.accessibility && !before.accessibility) || (now.screen && !before.screen))) {
50
+ this.reset();
51
+ }
52
+ this.granted = now;
53
+ return now;
54
+ }
55
+ async requestPermissions(grant) {
56
+ await (await this.target()).requestPermissions(grant);
57
+ }
58
+ selfPids() {
59
+ return new Set(this.opts.selfPids?.() ?? [process.pid]);
60
+ }
61
+ policy() {
62
+ return this.opts.policy?.() ?? {};
63
+ }
64
+ takeover() {
65
+ return this.opts.takeover?.() ?? "ask";
66
+ }
67
+ onAction(listener) {
68
+ this.observers.add(listener);
69
+ return () => this.observers.delete(listener);
70
+ }
71
+ emit(event) {
72
+ for (const listener of this.observers) {
73
+ try {
74
+ listener(event);
75
+ }
76
+ catch {
77
+ // An overlay that throws must not fail the action it was drawing.
78
+ }
79
+ }
80
+ }
81
+ canSnapshot() {
82
+ return Boolean(this.opts.snapshot);
83
+ }
84
+ async snapshot(window) {
85
+ return this.opts.snapshot?.(window).catch(() => undefined);
86
+ }
87
+ onSnapshot(listener) {
88
+ this.snapshotObservers.add(listener);
89
+ return () => this.snapshotObservers.delete(listener);
90
+ }
91
+ emitSnapshot(event) {
92
+ for (const listener of this.snapshotObservers) {
93
+ try {
94
+ listener(event);
95
+ }
96
+ catch {
97
+ // A transcript that cannot take the picture must not fail the turn.
98
+ }
99
+ }
100
+ }
101
+ async close() {
102
+ const target = this.starting;
103
+ this.starting = undefined;
104
+ await target?.then((t) => t.close()).catch(() => { });
105
+ }
106
+ }
107
+ /**
108
+ * One conversation's view of the computer.
109
+ *
110
+ * Holds what only makes sense per conversation: the apps and windows it has
111
+ * seen (so a permission prompt can name an app synchronously), the geometry of
112
+ * the screenshots it was shown (so its coordinates can be mapped back), and
113
+ * the window it last worked in.
114
+ */
115
+ export class ComputerUseSession {
116
+ runtime;
117
+ sessionId = "";
118
+ label = () => undefined;
119
+ apps = new Map();
120
+ windowsById = new Map();
121
+ shots = new Map();
122
+ secureRefs = new Set();
123
+ /**
124
+ * Windows this turn worked in whose last state the agent has not seen in a
125
+ * screenshot of its own. Each gets one picture when the turn ends; one the
126
+ * agent screenshotted after its last action already has its picture in the
127
+ * transcript.
128
+ */
129
+ unseen = new Map();
130
+ refFrames = new Map();
131
+ currentWindow;
132
+ constructor(runtime, sessionId) {
133
+ this.runtime = runtime;
134
+ if (sessionId)
135
+ this.sessionId = sessionId;
136
+ }
137
+ bind(sessionId) {
138
+ if (!this.sessionId)
139
+ this.sessionId = sessionId;
140
+ }
141
+ setLabel(label) {
142
+ this.label = label;
143
+ }
144
+ holder() {
145
+ return { sessionId: this.sessionId, label: this.label() ?? "another conversation" };
146
+ }
147
+ get id() {
148
+ return this.sessionId;
149
+ }
150
+ // ---- lookups -----------------------------------------------------------
151
+ async listApps() {
152
+ const target = await this.runtime.target();
153
+ const self = this.runtime.selfPids();
154
+ const apps = (await target.apps()).filter((app) => !self.has(app.pid));
155
+ for (const app of apps)
156
+ this.rememberApp(app);
157
+ return apps;
158
+ }
159
+ async listWindows(pid) {
160
+ const target = await this.runtime.target();
161
+ const self = this.runtime.selfPids();
162
+ const windows = (await target.windows(pid === undefined ? {} : { pid })).filter((w) => !self.has(w.pid));
163
+ for (const window of windows)
164
+ this.windowsById.set(window.id, window);
165
+ return windows;
166
+ }
167
+ rememberApp(app) {
168
+ this.apps.set(app.id.toLowerCase(), app);
169
+ this.apps.set(app.name.toLowerCase(), app);
170
+ }
171
+ /**
172
+ * The app a call names, synchronously, for the permission prompt.
173
+ *
174
+ * From what this conversation has already seen; an app it has not listed
175
+ * yet is named as the model wrote it, which still scopes the approval to
176
+ * one app.
177
+ */
178
+ appIdFor(input) {
179
+ const window = input.ref ? windowOfRef(input.ref) : input.window;
180
+ if (window) {
181
+ const known = this.windowsById.get(window);
182
+ if (known)
183
+ return known.appId;
184
+ }
185
+ if (input.app)
186
+ return this.apps.get(input.app.toLowerCase())?.id ?? input.app.toLowerCase();
187
+ if (!window && this.currentWindow)
188
+ return this.windowsById.get(this.currentWindow)?.appId;
189
+ return undefined;
190
+ }
191
+ /** Find the window a call means: by ref, by id, by app, or the last one used. */
192
+ async resolveWindow(input) {
193
+ const wanted = input.ref ? windowOfRef(input.ref) : input.window;
194
+ if (wanted) {
195
+ let window = this.windowsById.get(wanted);
196
+ if (!window)
197
+ window = (await this.listWindows()).find((w) => w.id === wanted);
198
+ if (!window)
199
+ throw new ComputerError("not_found", `No window ${wanted}. Call computer_list_apps to see what is open.`);
200
+ return window;
201
+ }
202
+ if (input.app) {
203
+ const key = input.app.toLowerCase();
204
+ let app = this.apps.get(key);
205
+ if (!app) {
206
+ await this.listApps();
207
+ app = this.apps.get(key) ?? [...new Set(this.apps.values())].find((a) => a.name.toLowerCase().includes(key));
208
+ }
209
+ if (!app)
210
+ throw new ComputerError("not_found", `${input.app} is not running. Use computer_open_app to start it.`);
211
+ const windows = (await this.listWindows(app.pid)).filter((w) => !w.minimized);
212
+ const window = windows.find((w) => w.focused) ?? windows[0];
213
+ if (!window)
214
+ throw new ComputerError("not_found", `${app.name} has no open window.`);
215
+ return window;
216
+ }
217
+ if (this.currentWindow) {
218
+ const window = this.windowsById.get(this.currentWindow);
219
+ if (window)
220
+ return window;
221
+ }
222
+ throw new ComputerError("not_found", "Name an app or a window. Call computer_list_apps to see what is open.");
223
+ }
224
+ // ---- guards ------------------------------------------------------------
225
+ tierOf(window) {
226
+ return tierFor(window.appId, window.app, this.runtime.policy());
227
+ }
228
+ /**
229
+ * Everything that has to hold before touching a window: it is not ours,
230
+ * its tier allows this kind of action, and no other conversation has it.
231
+ */
232
+ guard(window, kind) {
233
+ if (this.runtime.selfPids().has(window.pid)) {
234
+ throw new ComputerError("refused", "That window belongs to OHarness itself, which cannot be controlled by the agent.");
235
+ }
236
+ const tier = this.tierOf(window);
237
+ if (!tierAllows(tier, kind))
238
+ throw new ComputerError("refused", tierRefusal(tier, window.app, kind));
239
+ if (kind !== "look") {
240
+ this.runtime.arbiter.claimWindow(this.holder(), window.id);
241
+ if (kind === "type")
242
+ this.runtime.arbiter.claimApp(this.holder(), window.pid);
243
+ }
244
+ this.currentWindow = window.id;
245
+ }
246
+ /**
247
+ * Stay off a window the person is using right now.
248
+ *
249
+ * Their front window with input in the last few seconds is theirs: the
250
+ * lease on it lapses and the call is refused. Pointer-free actions on other
251
+ * windows go ahead regardless.
252
+ */
253
+ async respectUser(window, target) {
254
+ if (this.runtime.arbiter.holdsControl(this.sessionId))
255
+ return;
256
+ const [front, idle] = await Promise.all([target.frontmost().catch(() => undefined), target.idle().catch(() => Infinity)]);
257
+ if (front && idle < 3_000 && (front.window === window.id || (!front.window && front.pid === window.pid))) {
258
+ this.runtime.arbiter.yieldWindow(window.id);
259
+ throw new ComputerError("busy", `The user is working in ${window.app} right now. Wait, or work on something else.`);
260
+ }
261
+ }
262
+ /** Keys wait until the person has stopped typing, up to a limit. */
263
+ async waitForQuiet(target, signal, quietMs = 1_500, maxMs = 10_000) {
264
+ if (this.runtime.arbiter.holdsControl(this.sessionId))
265
+ return;
266
+ const started = Date.now();
267
+ for (;;) {
268
+ const idle = await target.idle().catch(() => Infinity);
269
+ if (idle >= quietMs)
270
+ return;
271
+ if (Date.now() - started > maxMs) {
272
+ throw new ComputerError("busy", "The user has been typing continuously; try again when they pause.");
273
+ }
274
+ if (signal?.aborted)
275
+ throw new ComputerError("refused", "stopped");
276
+ await new Promise((resolve) => setTimeout(resolve, Math.min(500, quietMs - idle + 50)));
277
+ }
278
+ }
279
+ // ---- screenshots and coordinates ---------------------------------------
280
+ rememberShot(key, shot) {
281
+ this.shots.set(key, { width: shot.width, height: shot.height, frame: shot.frame });
282
+ }
283
+ /**
284
+ * Map a point in the last screenshot of `window` back to the screen.
285
+ *
286
+ * The model only ever sees image pixels. Retina, per-monitor DPI and the
287
+ * downscale to fit the image budget are all folded into the screenshot's own
288
+ * frame, so none of them reach the model.
289
+ */
290
+ toScreen(window, x, y) {
291
+ const shot = this.shots.get(window.id);
292
+ if (!shot) {
293
+ throw new ComputerError("refused", `Take a computer_screenshot of ${window.app} first; x/y are pixels in that screenshot. Or act on a ref from computer_read_app.`);
294
+ }
295
+ if (x < 0 || y < 0 || x > shot.width || y > shot.height) {
296
+ throw new ComputerError("refused", `(${x}, ${y}) is outside the ${shot.width}x${shot.height} screenshot.`);
297
+ }
298
+ return {
299
+ x: shot.frame.x + (x * shot.frame.w) / shot.width,
300
+ y: shot.frame.y + (y * shot.frame.h) / shot.height,
301
+ };
302
+ }
303
+ // ---- accessibility refs ------------------------------------------------
304
+ rememberTree(nodes) {
305
+ for (const node of nodes) {
306
+ if (node.secure)
307
+ this.secureRefs.add(node.ref);
308
+ if (node.frame)
309
+ this.refFrames.set(node.ref, node.frame);
310
+ }
311
+ }
312
+ isSecure(ref) {
313
+ return this.secureRefs.has(ref);
314
+ }
315
+ frameOf(ref) {
316
+ return this.refFrames.get(ref);
317
+ }
318
+ // ---- presentation ------------------------------------------------------
319
+ async announce(event, target) {
320
+ const known = event.window ? this.windowsById.get(event.window) : undefined;
321
+ // Opening or reading a window has no point of its own, and without one the
322
+ // cursor stayed wherever the last click was — or nowhere — while the agent
323
+ // had moved on to another app. The window's middle says where it is now.
324
+ if (event.kind === "look" && !event.point && known?.frame) {
325
+ event = { ...event, point: { x: known.frame.x + known.frame.w / 2, y: known.frame.y + known.frame.h / 2 } };
326
+ }
327
+ let visible = event.visible;
328
+ if (visible === undefined && event.point && event.window && target) {
329
+ visible = await target.pointVisible(event.window, event.point.x, event.point.y).catch(() => false);
330
+ }
331
+ if (event.window && event.kind !== "control" && event.kind !== "release") {
332
+ // Re-inserted, so the order is the order the windows were last used in.
333
+ this.unseen.delete(event.window);
334
+ this.unseen.set(event.window, event.app ?? known?.app ?? "");
335
+ }
336
+ this.runtime.emit({
337
+ ...event,
338
+ ...(visible === undefined ? {} : { visible }),
339
+ ...(known ? { windowFrame: known.frame, ...(known.title ? { title: known.title } : {}) } : {}),
340
+ sessionId: this.sessionId,
341
+ label: this.holder().label,
342
+ });
343
+ }
344
+ /** The agent's own screenshot of this window: the transcript already shows its state. */
345
+ sawWindow(window) {
346
+ this.unseen.delete(window);
347
+ }
348
+ /** The turn ended: let go of windows and control, so others need not wait out the lease. */
349
+ endTurn() {
350
+ this.runtime.arbiter.releaseAll(this.sessionId);
351
+ // The idle event first, synchronously: the host marks where in the
352
+ // conversation this turn ended on it, before a queued message can start
353
+ // the next one. The pictures follow when they are taken.
354
+ this.runtime.emit({ sessionId: this.sessionId, label: this.holder().label, kind: "idle" });
355
+ const windows = [...this.unseen].slice(-SNAPSHOT_MAX_WINDOWS);
356
+ this.unseen.clear();
357
+ if (windows.length && this.runtime.canSnapshot())
358
+ void this.snapshotTurn(windows);
359
+ }
360
+ async snapshotTurn(windows) {
361
+ const shots = [];
362
+ for (const [window, app] of windows) {
363
+ const image = await this.runtime.snapshot(window);
364
+ if (!image)
365
+ continue;
366
+ const title = this.windowsById.get(window)?.title;
367
+ shots.push({ window, app, ...(title ? { title } : {}), ...image });
368
+ }
369
+ if (shots.length)
370
+ this.runtime.emitSnapshot({ sessionId: this.sessionId, shots });
371
+ }
372
+ async close() {
373
+ // Closing is not the end of a turn anyone will read back.
374
+ this.unseen.clear();
375
+ this.endTurn();
376
+ this.shots.clear();
377
+ this.windowsById.clear();
378
+ this.apps.clear();
379
+ }
380
+ }
381
+ /**
382
+ * At most this many windows get a picture per turn: a turn that went through
383
+ * six apps is read back by its last few, and each picture is a capture and a
384
+ * file.
385
+ */
386
+ const SNAPSHOT_MAX_WINDOWS = 3;
387
+ /** Refs look like `w<window>.<n>`; the window id is everything between. */
388
+ export function windowOfRef(ref) {
389
+ const match = /^w(.+)\.\d+$/.exec(ref);
390
+ return match?.[1];
391
+ }
392
+ //# sourceMappingURL=session.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session.js","sourceRoot":"","sources":["../../src/computer/session.ts"],"names":[],"mappings":"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"}