askvireo 0.0.0-stage → 0.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.
Files changed (186) hide show
  1. package/dist/access.js +33 -0
  2. package/dist/access.js.map +1 -0
  3. package/dist/acp.js +257 -0
  4. package/dist/acp.js.map +1 -0
  5. package/dist/actions.js +141 -0
  6. package/dist/actions.js.map +1 -0
  7. package/dist/address.js +32 -0
  8. package/dist/address.js.map +1 -0
  9. package/dist/aftercare.js +51 -0
  10. package/dist/aftercare.js.map +1 -0
  11. package/dist/agents.js +164 -0
  12. package/dist/agents.js.map +1 -0
  13. package/dist/app.js +67 -0
  14. package/dist/app.js.map +1 -0
  15. package/dist/audit.js +40 -0
  16. package/dist/audit.js.map +1 -0
  17. package/dist/browser.js +559 -0
  18. package/dist/browser.js.map +1 -0
  19. package/dist/bus.js +27 -0
  20. package/dist/bus.js.map +1 -0
  21. package/dist/cards/blocks.js +80 -0
  22. package/dist/cards/blocks.js.map +1 -0
  23. package/dist/cards/diff.js +48 -0
  24. package/dist/cards/diff.js.map +1 -0
  25. package/dist/cards/kinds.js +139 -0
  26. package/dist/cards/kinds.js.map +1 -0
  27. package/dist/cards/store.js +177 -0
  28. package/dist/cards/store.js.map +1 -0
  29. package/dist/cli.js +245 -0
  30. package/dist/cli.js.map +1 -0
  31. package/dist/config.js +33 -0
  32. package/dist/config.js.map +1 -0
  33. package/dist/connect.js +97 -0
  34. package/dist/connect.js.map +1 -0
  35. package/dist/db.js +288 -0
  36. package/dist/db.js.map +1 -0
  37. package/dist/extract.js +75 -0
  38. package/dist/extract.js.map +1 -0
  39. package/dist/fake-llm-server.js +118 -0
  40. package/dist/fake-llm-server.js.map +1 -0
  41. package/dist/fake-model.js +517 -0
  42. package/dist/fake-model.js.map +1 -0
  43. package/dist/files.js +70 -0
  44. package/dist/files.js.map +1 -0
  45. package/dist/hook.js +146 -0
  46. package/dist/hook.js.map +1 -0
  47. package/dist/http/browser.js +91 -0
  48. package/dist/http/browser.js.map +1 -0
  49. package/dist/http/events.js +54 -0
  50. package/dist/http/events.js.map +1 -0
  51. package/dist/http/index.js +91 -0
  52. package/dist/http/index.js.map +1 -0
  53. package/dist/http/memory.js +40 -0
  54. package/dist/http/memory.js.map +1 -0
  55. package/dist/http/settings.js +69 -0
  56. package/dist/http/settings.js.map +1 -0
  57. package/dist/http/test.js +38 -0
  58. package/dist/http/test.js.map +1 -0
  59. package/dist/http/threads.js +109 -0
  60. package/dist/http/threads.js.map +1 -0
  61. package/dist/http/views.js +43 -0
  62. package/dist/http/views.js.map +1 -0
  63. package/dist/http/work.js +27 -0
  64. package/dist/http/work.js.map +1 -0
  65. package/dist/identity.js +26 -0
  66. package/dist/identity.js.map +1 -0
  67. package/dist/index.js +23 -0
  68. package/dist/index.js.map +1 -0
  69. package/dist/integrations/index.js +44 -0
  70. package/dist/integrations/index.js.map +1 -0
  71. package/dist/integrations/local.js +144 -0
  72. package/dist/integrations/local.js.map +1 -0
  73. package/dist/integrations/types.js +2 -0
  74. package/dist/integrations/types.js.map +1 -0
  75. package/dist/lifecycle.js +74 -0
  76. package/dist/lifecycle.js.map +1 -0
  77. package/dist/link.js +33 -0
  78. package/dist/link.js.map +1 -0
  79. package/dist/memory-sync.js +93 -0
  80. package/dist/memory-sync.js.map +1 -0
  81. package/dist/memory-worker.js +146 -0
  82. package/dist/memory-worker.js.map +1 -0
  83. package/dist/memory.js +217 -0
  84. package/dist/memory.js.map +1 -0
  85. package/dist/messages.js +13 -0
  86. package/dist/messages.js.map +1 -0
  87. package/dist/models.js +275 -0
  88. package/dist/models.js.map +1 -0
  89. package/dist/net.js +28 -0
  90. package/dist/net.js.map +1 -0
  91. package/dist/peers.js +82 -0
  92. package/dist/peers.js.map +1 -0
  93. package/dist/plugins/agents/index.js +357 -0
  94. package/dist/plugins/agents/index.js.map +1 -0
  95. package/dist/plugins/chat.js +258 -0
  96. package/dist/plugins/chat.js.map +1 -0
  97. package/dist/plugins/endpoint/index.js +436 -0
  98. package/dist/plugins/endpoint/index.js.map +1 -0
  99. package/dist/plugins/feishu/index.js +256 -0
  100. package/dist/plugins/feishu/index.js.map +1 -0
  101. package/dist/plugins/google/api.js +347 -0
  102. package/dist/plugins/google/api.js.map +1 -0
  103. package/dist/plugins/google/index.js +138 -0
  104. package/dist/plugins/google/index.js.map +1 -0
  105. package/dist/plugins/index.js +518 -0
  106. package/dist/plugins/index.js.map +1 -0
  107. package/dist/plugins/mcp/index.js +218 -0
  108. package/dist/plugins/mcp/index.js.map +1 -0
  109. package/dist/plugins/nodes/index.js +232 -0
  110. package/dist/plugins/nodes/index.js.map +1 -0
  111. package/dist/plugins/search/index.js +122 -0
  112. package/dist/plugins/search/index.js.map +1 -0
  113. package/dist/plugins/tailscale/api.js +52 -0
  114. package/dist/plugins/tailscale/api.js.map +1 -0
  115. package/dist/plugins/tailscale/daemon.js +203 -0
  116. package/dist/plugins/tailscale/daemon.js.map +1 -0
  117. package/dist/plugins/tailscale/index.js +504 -0
  118. package/dist/plugins/tailscale/index.js.map +1 -0
  119. package/dist/plugins/telegram/index.js +174 -0
  120. package/dist/plugins/telegram/index.js.map +1 -0
  121. package/dist/plugins/types.js +2 -0
  122. package/dist/plugins/types.js.map +1 -0
  123. package/dist/pricing.js +113 -0
  124. package/dist/pricing.js.map +1 -0
  125. package/dist/procedures.js +57 -0
  126. package/dist/procedures.js.map +1 -0
  127. package/dist/prompt.js +106 -0
  128. package/dist/prompt.js.map +1 -0
  129. package/dist/push.js +48 -0
  130. package/dist/push.js.map +1 -0
  131. package/dist/relay-client.js +176 -0
  132. package/dist/relay-client.js.map +1 -0
  133. package/dist/reminders.js +40 -0
  134. package/dist/reminders.js.map +1 -0
  135. package/dist/runner.js +350 -0
  136. package/dist/runner.js.map +1 -0
  137. package/dist/scheduler.js +182 -0
  138. package/dist/scheduler.js.map +1 -0
  139. package/dist/server.js +105 -0
  140. package/dist/server.js.map +1 -0
  141. package/dist/service.js +196 -0
  142. package/dist/service.js.map +1 -0
  143. package/dist/settings.js +28 -0
  144. package/dist/settings.js.map +1 -0
  145. package/dist/threads.js +197 -0
  146. package/dist/threads.js.map +1 -0
  147. package/dist/time.js +85 -0
  148. package/dist/time.js.map +1 -0
  149. package/dist/tool-gate.js +70 -0
  150. package/dist/tool-gate.js.map +1 -0
  151. package/dist/tools/approval.js +22 -0
  152. package/dist/tools/approval.js.map +1 -0
  153. package/dist/tools/browser.js +291 -0
  154. package/dist/tools/browser.js.map +1 -0
  155. package/dist/tools/calendar.js +153 -0
  156. package/dist/tools/calendar.js.map +1 -0
  157. package/dist/tools/cards.js +176 -0
  158. package/dist/tools/cards.js.map +1 -0
  159. package/dist/tools/email.js +76 -0
  160. package/dist/tools/email.js.map +1 -0
  161. package/dist/tools/files.js +57 -0
  162. package/dist/tools/files.js.map +1 -0
  163. package/dist/tools/index.js +16 -0
  164. package/dist/tools/index.js.map +1 -0
  165. package/dist/tools/memory.js +90 -0
  166. package/dist/tools/memory.js.map +1 -0
  167. package/dist/tools/research.js +163 -0
  168. package/dist/tools/research.js.map +1 -0
  169. package/dist/tools/setup.js +96 -0
  170. package/dist/tools/setup.js.map +1 -0
  171. package/dist/tools/threads.js +132 -0
  172. package/dist/tools/threads.js.map +1 -0
  173. package/dist/tools/types.js +16 -0
  174. package/dist/tools/types.js.map +1 -0
  175. package/dist/usage.js +75 -0
  176. package/dist/usage.js.map +1 -0
  177. package/dist/util.js +71 -0
  178. package/dist/util.js.map +1 -0
  179. package/dist/vault.js +81 -0
  180. package/dist/vault.js.map +1 -0
  181. package/dist/version.js +4 -0
  182. package/dist/version.js.map +1 -0
  183. package/dist/watch.js +104 -0
  184. package/dist/watch.js.map +1 -0
  185. package/package.json +45 -4
  186. package/README.md +0 -3
@@ -0,0 +1,559 @@
1
+ import { join } from "node:path";
2
+ import { normaliseProxy, PROXY_BYPASS } from "./net.js";
3
+ import { normaliseDomain } from "./vault.js";
4
+ const RISKY_TEXT = /\b(submit|send|pay|purchase|buy|order|checkout|check out|book|reserve|confirm|place order|sign up|register|delete|remove|transfer)\b|提交|支付|付款|购买|下单|预订|预定|确认|发送|删除|注册/i;
5
+ /** Navigations shortly after an agent action (clicks, sign-in redirects, SSO) may leave the opened sites. */
6
+ const ACTION_WINDOW_MS = 15_000;
7
+ const TREE_LIMIT = 24_000;
8
+ export class BrowserService {
9
+ app;
10
+ context;
11
+ launchedProxy = "";
12
+ threads = new Map();
13
+ screencasts = new WeakMap();
14
+ /** Latest frame per thread, kept after the tab closes so the owner can still see where the browser ended up. */
15
+ frames = new Map();
16
+ /** Threads whose browser the owner has taken over; the agent's browser tools wait until it is handed back. */
17
+ control = new Map();
18
+ constructor(app) {
19
+ this.app = app;
20
+ }
21
+ proxy() {
22
+ return normaliseProxy(this.app.settings.get().proxyUrl);
23
+ }
24
+ async ctx() {
25
+ // A changed proxy takes effect once no thread is using the browser.
26
+ if (this.context && this.launchedProxy !== this.proxy() && !this.anyOpen())
27
+ await this.shutdown();
28
+ if (!this.context) {
29
+ const proxy = this.proxy();
30
+ this.launchedProxy = proxy;
31
+ this.context = (async () => {
32
+ const { chromium } = await import("playwright");
33
+ const ctx = await chromium.launchPersistentContext(join(this.app.config.dataDir, "browser-profile"), {
34
+ headless: this.app.config.browserHeadless,
35
+ executablePath: this.app.config.chromiumPath,
36
+ viewport: { width: 1280, height: 900 },
37
+ acceptDownloads: false,
38
+ proxy: proxy ? { server: proxy, bypass: PROXY_BYPASS } : undefined,
39
+ args: ["--disable-blink-features=AutomationControlled"],
40
+ });
41
+ ctx.on("close", () => {
42
+ this.context = undefined;
43
+ this.threads.clear();
44
+ });
45
+ return ctx;
46
+ })().catch((err) => {
47
+ this.context = undefined;
48
+ throw new Error(`The browser could not start: ${err instanceof Error ? err.message : String(err)}`);
49
+ });
50
+ }
51
+ return this.context;
52
+ }
53
+ anyOpen() {
54
+ for (const t of this.threads.values())
55
+ if (t.pages.some((p) => !p.isClosed()))
56
+ return true;
57
+ return false;
58
+ }
59
+ tabs(threadId) {
60
+ let t = this.threads.get(threadId);
61
+ if (!t) {
62
+ t = { pages: [], allowed: new Set(), lastAction: 0 };
63
+ this.threads.set(threadId, t);
64
+ }
65
+ t.pages = t.pages.filter((p) => !p.isClosed());
66
+ if (t.current?.isClosed())
67
+ t.current = t.pages.at(-1);
68
+ return t;
69
+ }
70
+ allowedHosts(threadId) {
71
+ return [...(this.threads.get(threadId)?.allowed ?? [])];
72
+ }
73
+ isAllowed(threadId, url) {
74
+ if (/^(about|data|blob|chrome-error):/.test(url))
75
+ return true;
76
+ let host;
77
+ try {
78
+ host = normaliseDomain(new URL(url).hostname);
79
+ }
80
+ catch {
81
+ return true;
82
+ }
83
+ const t = this.tabs(threadId);
84
+ // Wherever the owner goes by hand is theirs to choose.
85
+ if (this.control.has(threadId)) {
86
+ t.allowed.add(host);
87
+ return true;
88
+ }
89
+ for (const h of t.allowed)
90
+ if (host === h || host.endsWith(`.${h}`) || h.endsWith(`.${host}`))
91
+ return true;
92
+ if (Date.now() - t.lastAction < ACTION_WINDOW_MS) {
93
+ t.allowed.add(host);
94
+ return true;
95
+ }
96
+ return false;
97
+ }
98
+ /** Marks that the agent just acted, so the navigation it causes is allowed. */
99
+ acted(threadId) {
100
+ this.tabs(threadId).lastAction = Date.now();
101
+ }
102
+ async adopt(threadId, page) {
103
+ const t = this.tabs(threadId);
104
+ if (t.pages.includes(page))
105
+ return;
106
+ t.pages.push(page);
107
+ t.current = page;
108
+ await page.route("**/*", async (route) => {
109
+ const req = route.request();
110
+ if (req.isNavigationRequest() && req.frame() === page.mainFrame() && !this.isAllowed(threadId, req.url())) {
111
+ await route.abort("blockedbyclient");
112
+ return;
113
+ }
114
+ await route.continue();
115
+ });
116
+ // Links with target=_blank and window.open land in a new tab; follow it.
117
+ page.on("popup", (popup) => void this.adopt(threadId, popup).catch(() => undefined));
118
+ page.on("close", () => {
119
+ const tt = this.threads.get(threadId);
120
+ if (!tt)
121
+ return;
122
+ tt.pages = tt.pages.filter((p) => p !== page);
123
+ if (tt.current === page)
124
+ tt.current = tt.pages.at(-1);
125
+ if (tt.current)
126
+ void this.screencast(threadId, tt.current);
127
+ });
128
+ await this.screencast(threadId, page);
129
+ }
130
+ /** Streams frames of the thread's current tab into the live view. */
131
+ async screencast(threadId, page) {
132
+ if (this.screencasts.has(page) || page.isClosed())
133
+ return;
134
+ try {
135
+ const cdp = await page.context().newCDPSession(page);
136
+ this.screencasts.set(page, cdp);
137
+ cdp.on("Page.screencastFrame", (f) => {
138
+ if (this.threads.get(threadId)?.current === page)
139
+ this.frames.set(threadId, Buffer.from(f.data, "base64"));
140
+ void cdp.send("Page.screencastFrameAck", { sessionId: f.sessionId }).catch(() => undefined);
141
+ });
142
+ await cdp.send("Page.startScreencast", { format: "jpeg", quality: 60, maxWidth: 1280, maxHeight: 900 });
143
+ }
144
+ catch {
145
+ // The live view falls back to screenshots.
146
+ }
147
+ }
148
+ async page(threadId) {
149
+ const t = this.tabs(threadId);
150
+ if (t.current)
151
+ return t.current;
152
+ const ctx = await this.ctx();
153
+ const page = await ctx.newPage();
154
+ await this.adopt(threadId, page);
155
+ return page;
156
+ }
157
+ hasPage(threadId) {
158
+ return Boolean(this.tabs(threadId).current);
159
+ }
160
+ async open(threadId, url, newTab = false) {
161
+ const t = this.tabs(threadId);
162
+ t.allowed.add(normaliseDomain(new URL(url).hostname));
163
+ let page;
164
+ if (newTab && t.current) {
165
+ page = await (await this.ctx()).newPage();
166
+ await this.adopt(threadId, page);
167
+ }
168
+ else {
169
+ page = await this.page(threadId);
170
+ }
171
+ this.acted(threadId);
172
+ await page.goto(url, { waitUntil: "domcontentloaded", timeout: 30000 });
173
+ await this.settle(page);
174
+ return this.snapshot(threadId);
175
+ }
176
+ nextPopup(page) {
177
+ return page.waitForEvent("popup", { timeout: 1500 }).catch(() => null);
178
+ }
179
+ /** Lets the page settle and switches the thread to a tab the action opened, if any. */
180
+ async afterAction(threadId, page, popup) {
181
+ const [p] = await Promise.all([popup, this.settle(page)]);
182
+ if (!p)
183
+ return;
184
+ await this.adopt(threadId, p);
185
+ this.tabs(threadId).current = p;
186
+ await this.settle(p);
187
+ }
188
+ /** Waits for the page to stop changing after an action, without hanging on long-polling sites. */
189
+ async settle(page) {
190
+ await page.waitForLoadState("domcontentloaded", { timeout: 10000 }).catch(() => undefined);
191
+ await page.waitForLoadState("networkidle", { timeout: 2500 }).catch(() => undefined);
192
+ }
193
+ async snapshot(threadId) {
194
+ const t = this.tabs(threadId);
195
+ const page = await this.page(threadId);
196
+ await page.waitForLoadState("domcontentloaded").catch(() => undefined);
197
+ // Keys a plugin recognises (one the agent just created, say) never reach the model.
198
+ let tree = this.app.plugins.redact(await page._snapshotForAI({ timeout: 10000 }));
199
+ if (tree.length > TREE_LIMIT)
200
+ tree = `${tree.slice(0, TREE_LIMIT)}\n- … (truncated; scroll or use browser_read for the rest)`;
201
+ const tabs = await Promise.all(t.pages.map(async (p, index) => ({ index, title: await p.title().catch(() => ""), url: p.url(), current: p === page })));
202
+ return { url: page.url(), title: await page.title().catch(() => ""), tabs, tree };
203
+ }
204
+ /** The page's readable text, for long articles and result lists. */
205
+ async read(threadId) {
206
+ const page = await this.page(threadId);
207
+ const text = await page.evaluate(() => (document.body?.innerText ?? "").replace(/\n{3,}/g, "\n\n"));
208
+ return { url: page.url(), title: await page.title().catch(() => ""), text: this.app.plugins.redact(text).slice(0, 20000) };
209
+ }
210
+ /**
211
+ * Text of an element (an input's value, or what it shows), or of the whole
212
+ * page with the values of its fields, for plugin_save_from_page. Only
213
+ * server code reads it; it is never returned to the model.
214
+ */
215
+ async rawText(threadId, ref) {
216
+ if (ref) {
217
+ const { loc } = await this.element(threadId, ref);
218
+ return loc.evaluate((el) => {
219
+ const v = el.value;
220
+ const fields = [...el.querySelectorAll("input, textarea")].map((f) => f.value);
221
+ return [typeof v === "string" ? v : "", el.innerText ?? el.textContent ?? "", ...fields].join("\n");
222
+ });
223
+ }
224
+ const page = await this.page(threadId);
225
+ const frames = await Promise.all(page.frames().map((f) => f
226
+ .evaluate(() => [document.body?.innerText ?? "", ...[...document.querySelectorAll("input, textarea")].map((el) => el.value)].join("\n"))
227
+ .catch(() => "")));
228
+ return frames.join("\n");
229
+ }
230
+ async element(threadId, ref) {
231
+ const page = await this.page(threadId);
232
+ const clean = ref.trim().replace(/^\[?ref=/, "").replace(/\]$/, "");
233
+ const loc = page.locator(`aria-ref=${clean}`);
234
+ const n = await loc.count().catch(() => 0);
235
+ if (n === 0)
236
+ throw new Error(`Element ${ref} is not on the page any more; call browser_snapshot for fresh refs`);
237
+ return { page, loc: loc.first() };
238
+ }
239
+ async describe(threadId, ref) {
240
+ const { loc } = await this.element(threadId, ref);
241
+ return loc.evaluate((el) => {
242
+ const form = el.closest("form");
243
+ const action = form?.getAttribute("action") ?? "";
244
+ return {
245
+ tag: el.tagName.toLowerCase(),
246
+ type: (el.getAttribute("type") ?? "").toLowerCase(),
247
+ text: (el.innerText || el.value || el.getAttribute("aria-label") || "").trim().slice(0, 80),
248
+ inForm: Boolean(form),
249
+ formHasPassword: Boolean(form?.querySelector("input[type=password]")),
250
+ formIsSearch: Boolean(form &&
251
+ (form.getAttribute("role") === "search" ||
252
+ el.closest("[role=search]") ||
253
+ /search|query|\/s\b|\/find/i.test(action) ||
254
+ form.querySelector("input[type=search],input[name=q],input[name=query],input[name=wd],input[name=keyword]"))),
255
+ formAction: action || undefined,
256
+ };
257
+ });
258
+ }
259
+ /** Whether clicking this element would submit, buy or otherwise act outward. */
260
+ async isConsequentialClick(threadId, ref) {
261
+ const info = await this.describe(threadId, ref);
262
+ // Signing in with stored credentials and searching are part of getting the task done, not outward actions.
263
+ if (info.formHasPassword && /^(sign ?in|log ?in|continue|next|登录|登入|下一步)$/i.test(info.text))
264
+ return false;
265
+ if (info.formIsSearch && !RISKY_TEXT.test(info.text))
266
+ return false;
267
+ if (info.tag === "input" && ["submit", "image"].includes(info.type))
268
+ return true;
269
+ if (info.tag === "button" && info.inForm && (info.type === "" || info.type === "submit"))
270
+ return true;
271
+ return RISKY_TEXT.test(info.text);
272
+ }
273
+ /** Whether pressing Enter in this field would submit a form that acts outward. */
274
+ async isConsequentialSubmit(threadId, ref) {
275
+ if (!ref) {
276
+ const page = await this.page(threadId);
277
+ const inForm = await page.evaluate(() => Boolean(document.activeElement?.closest("form"))).catch(() => false);
278
+ return inForm;
279
+ }
280
+ const info = await this.describe(threadId, ref);
281
+ if (!info.inForm)
282
+ return false;
283
+ return !info.formIsSearch && !info.formHasPassword;
284
+ }
285
+ async click(threadId, ref, double = false) {
286
+ const { page, loc } = await this.element(threadId, ref);
287
+ this.acted(threadId);
288
+ const popup = this.nextPopup(page);
289
+ if (double)
290
+ await loc.dblclick({ timeout: 10000 });
291
+ else
292
+ await loc.click({ timeout: 10000 });
293
+ await this.afterAction(threadId, page, popup);
294
+ return this.snapshot(threadId);
295
+ }
296
+ async hover(threadId, ref) {
297
+ const { page, loc } = await this.element(threadId, ref);
298
+ await loc.hover({ timeout: 10000 });
299
+ await page.waitForTimeout(400);
300
+ return this.snapshot(threadId);
301
+ }
302
+ /** Types text; {{username}} / {{password}} are filled from the vault for the current site. */
303
+ async type(threadId, ref, text, submit, slowly = false) {
304
+ const { page, loc } = await this.element(threadId, ref);
305
+ let value = text;
306
+ if (/\{\{(username|password)\}\}/.test(text)) {
307
+ const cred = this.app.vault.forHost(new URL(page.url()).hostname);
308
+ if (!cred)
309
+ throw new Error(`No stored credentials for ${new URL(page.url()).hostname}. Ask the owner to add them in Settings.`);
310
+ value = text.replace(/\{\{username\}\}/g, cred.username).replace(/\{\{password\}\}/g, cred.password);
311
+ }
312
+ if (slowly) {
313
+ // Key by key, for fields whose autocomplete only reacts to real key presses.
314
+ await loc.click({ timeout: 10000 });
315
+ await loc.press("ControlOrMeta+a");
316
+ await loc.press("Backspace");
317
+ await loc.pressSequentially(value, { delay: 40 });
318
+ }
319
+ else {
320
+ await loc.fill(value, { timeout: 10000 });
321
+ }
322
+ if (submit) {
323
+ this.acted(threadId);
324
+ await loc.press("Enter");
325
+ await this.settle(page);
326
+ }
327
+ else {
328
+ await page.waitForTimeout(300);
329
+ }
330
+ return this.snapshot(threadId);
331
+ }
332
+ async press(threadId, key, ref) {
333
+ this.acted(threadId);
334
+ const page = await this.page(threadId);
335
+ const popup = this.nextPopup(page);
336
+ if (ref)
337
+ await (await this.element(threadId, ref)).loc.press(key, { timeout: 10000 });
338
+ else
339
+ await page.keyboard.press(key);
340
+ await this.afterAction(threadId, page, popup);
341
+ return this.snapshot(threadId);
342
+ }
343
+ async select(threadId, ref, values) {
344
+ const { page, loc } = await this.element(threadId, ref);
345
+ await loc.selectOption(values.map((label) => ({ label }))).catch(() => loc.selectOption(values));
346
+ await page.waitForTimeout(300);
347
+ return this.snapshot(threadId);
348
+ }
349
+ async check(threadId, ref, checked) {
350
+ const { page, loc } = await this.element(threadId, ref);
351
+ await loc.setChecked(checked, { timeout: 10000 });
352
+ await page.waitForTimeout(300);
353
+ return this.snapshot(threadId);
354
+ }
355
+ async scroll(threadId, direction, ref) {
356
+ const page = await this.page(threadId);
357
+ if (ref) {
358
+ const { loc } = await this.element(threadId, ref);
359
+ await loc.scrollIntoViewIfNeeded({ timeout: 10000 });
360
+ }
361
+ else {
362
+ await page.mouse.move(640, 450);
363
+ await page.mouse.wheel(0, direction === "down" ? 800 : -800);
364
+ }
365
+ // Lazy lists load more items once scrolled.
366
+ await page.waitForTimeout(700);
367
+ return this.snapshot(threadId);
368
+ }
369
+ async wait(threadId, opts) {
370
+ const page = await this.page(threadId);
371
+ if (opts.text)
372
+ await page.getByText(opts.text).first().waitFor({ state: "visible", timeout: 20000 });
373
+ else
374
+ await page.waitForTimeout(Math.min(Math.max(opts.seconds ?? 2, 0.5), 20) * 1000);
375
+ return this.snapshot(threadId);
376
+ }
377
+ async history(threadId, direction) {
378
+ const page = await this.page(threadId);
379
+ this.acted(threadId);
380
+ if (direction === "back")
381
+ await page.goBack({ waitUntil: "domcontentloaded", timeout: 15000 });
382
+ else
383
+ await page.goForward({ waitUntil: "domcontentloaded", timeout: 15000 });
384
+ await this.settle(page);
385
+ return this.snapshot(threadId);
386
+ }
387
+ async selectTab(threadId, index) {
388
+ const t = this.tabs(threadId);
389
+ const page = t.pages[index];
390
+ if (!page)
391
+ throw new Error(`There is no tab ${index}; this thread has ${t.pages.length}`);
392
+ t.current = page;
393
+ await page.bringToFront().catch(() => undefined);
394
+ await this.screencast(threadId, page);
395
+ return this.snapshot(threadId);
396
+ }
397
+ async closeTab(threadId, index) {
398
+ const t = this.tabs(threadId);
399
+ const page = index === undefined ? t.current : t.pages[index];
400
+ if (!page)
401
+ throw new Error(`There is no tab ${index}`);
402
+ await page.close();
403
+ return this.snapshot(threadId);
404
+ }
405
+ async screenshot(threadId) {
406
+ const page = await this.page(threadId);
407
+ return page.screenshot({ type: "png", fullPage: false });
408
+ }
409
+ /** The latest JPEG of the thread's current tab for the live view; the last frame once the tab is gone. */
410
+ async frame(threadId) {
411
+ const t = this.threads.get(threadId);
412
+ const page = t?.current && !t.current.isClosed() ? t.current : undefined;
413
+ if (page && (!this.screencasts.has(page) || !this.frames.has(threadId))) {
414
+ const shot = await page.screenshot({ type: "jpeg", quality: 60, fullPage: false, timeout: 5000 }).catch(() => null);
415
+ if (shot)
416
+ this.frames.set(threadId, shot);
417
+ }
418
+ return this.frames.get(threadId) ?? null;
419
+ }
420
+ isControlled(threadId) {
421
+ return this.control.has(threadId);
422
+ }
423
+ /** The owner takes the thread's browser; returns false when there is no open tab to take. */
424
+ takeOver(threadId, request) {
425
+ if (!this.hasPage(threadId))
426
+ return false;
427
+ if (!this.control.has(threadId)) {
428
+ let release = () => { };
429
+ const released = new Promise((r) => (release = r));
430
+ this.control.set(threadId, { released, release, queue: Promise.resolve(), request, since: Date.now() });
431
+ }
432
+ else if (request) {
433
+ this.control.get(threadId).request = request;
434
+ }
435
+ return true;
436
+ }
437
+ /** What the agent asked the owner to do in the browser, while it waits for them. */
438
+ request(threadId) {
439
+ return this.control.get(threadId)?.request;
440
+ }
441
+ /** Every request Vireo is waiting on the owner for, oldest first. */
442
+ requests() {
443
+ return [...this.control.entries()].flatMap(([threadId, c]) => (c.request ? [{ threadId, request: c.request, since: c.since }] : [])).sort((a, b) => a.since - b.since);
444
+ }
445
+ /**
446
+ * The agent hands the browser to the owner for something only they should
447
+ * do (signing in, a captcha, a passkey) and waits until it is handed back.
448
+ * Returns false when the owner did not hand it back in time.
449
+ */
450
+ async askOwner(threadId, request, timeoutMs, signal) {
451
+ if (!this.takeOver(threadId, request))
452
+ throw new Error("Open the page with browser_open first, then ask the owner.");
453
+ const c = this.control.get(threadId);
454
+ let timer;
455
+ const timedOut = new Promise((r) => (timer = setTimeout(() => r(true), timeoutMs)));
456
+ try {
457
+ const late = await Promise.race([
458
+ c.released.then(() => false),
459
+ timedOut,
460
+ new Promise((_, reject) => {
461
+ if (signal?.aborted)
462
+ reject(new Error("Stopped"));
463
+ signal?.addEventListener("abort", () => reject(new Error("Stopped")), { once: true });
464
+ }),
465
+ ]);
466
+ if (late)
467
+ this.handBack(threadId);
468
+ return !late;
469
+ }
470
+ catch (err) {
471
+ this.handBack(threadId);
472
+ throw err;
473
+ }
474
+ finally {
475
+ clearTimeout(timer);
476
+ }
477
+ }
478
+ handBack(threadId) {
479
+ this.control.get(threadId)?.release();
480
+ this.control.delete(threadId);
481
+ }
482
+ /** Resolves once the owner hands the browser back; true when the agent had to wait. */
483
+ async waitForOwner(threadId, signal) {
484
+ const c = this.control.get(threadId);
485
+ if (!c)
486
+ return false;
487
+ await new Promise((resolve, reject) => {
488
+ if (signal?.aborted)
489
+ return reject(new Error("Stopped"));
490
+ signal?.addEventListener("abort", () => reject(new Error("Stopped")), { once: true });
491
+ void c.released.then(resolve);
492
+ });
493
+ return true;
494
+ }
495
+ /** Replays the owner's mouse and keyboard on the current tab, in order. */
496
+ input(threadId, ev) {
497
+ const c = this.control.get(threadId);
498
+ if (!c)
499
+ return Promise.reject(new Error("Take over the browser first"));
500
+ const run = async () => {
501
+ const t = this.tabs(threadId);
502
+ const page = t.current;
503
+ if (!page)
504
+ return;
505
+ const vp = page.viewportSize() ?? { width: 1280, height: 900 };
506
+ const at = (e) => [Math.round(clamp01(e.x) * vp.width), Math.round(clamp01(e.y) * vp.height)];
507
+ switch (ev.type) {
508
+ case "move":
509
+ await page.mouse.move(...at(ev));
510
+ break;
511
+ case "down":
512
+ await page.mouse.move(...at(ev));
513
+ await page.mouse.down({ button: ev.button ?? "left" });
514
+ break;
515
+ case "up":
516
+ await page.mouse.move(...at(ev));
517
+ await page.mouse.up({ button: ev.button ?? "left" });
518
+ break;
519
+ case "wheel":
520
+ await page.mouse.move(...at(ev));
521
+ await page.mouse.wheel(ev.dx, ev.dy);
522
+ break;
523
+ case "key":
524
+ await page.keyboard.press(ev.key);
525
+ break;
526
+ case "text":
527
+ await page.keyboard.insertText(ev.text);
528
+ break;
529
+ }
530
+ };
531
+ const next = c.queue.then(run);
532
+ c.queue = next.catch(() => undefined);
533
+ return next;
534
+ }
535
+ async closeThread(threadId) {
536
+ this.handBack(threadId);
537
+ const t = this.threads.get(threadId);
538
+ this.threads.delete(threadId);
539
+ for (const p of t?.pages ?? [])
540
+ await p.close().catch(() => undefined);
541
+ }
542
+ async shutdown() {
543
+ for (const id of [...this.control.keys()])
544
+ this.handBack(id);
545
+ const ctx = this.context;
546
+ this.context = undefined;
547
+ this.threads.clear();
548
+ if (ctx)
549
+ await (await ctx).close().catch(() => undefined);
550
+ }
551
+ }
552
+ function clamp01(n) {
553
+ return Number.isFinite(n) ? Math.min(1, Math.max(0, n)) : 0;
554
+ }
555
+ export function formatSnapshot(s) {
556
+ const tabs = s.tabs.length > 1 ? `\nTabs:\n${s.tabs.map((t) => `${t.current ? "*" : " "} [${t.index}] ${t.title || "(untitled)"} — ${t.url}`).join("\n")}\n` : "";
557
+ return `URL: ${s.url}\nTitle: ${s.title}\n${tabs}\nPage (act on elements by their ref, e.g. e12):\n${s.tree || "(empty page)"}`;
558
+ }
559
+ //# sourceMappingURL=browser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"browser.js","sourceRoot":"","sources":["../src/browser.ts"],"names":[],"mappings":"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"}
package/dist/bus.js ADDED
@@ -0,0 +1,27 @@
1
+ import { EventEmitter } from "node:events";
2
+ /**
3
+ * One per app: services announce what changed, and SSE clients, chat apps and
4
+ * follow-up work subscribe. A failing subscriber is logged and never stops the
5
+ * others.
6
+ */
7
+ export class Bus extends EventEmitter {
8
+ constructor() {
9
+ super();
10
+ this.setMaxListeners(1000);
11
+ }
12
+ publish(event) {
13
+ for (const fn of this.listeners("event")) {
14
+ try {
15
+ fn(event);
16
+ }
17
+ catch (err) {
18
+ console.error(`[bus] ${event.type} subscriber failed:`, err);
19
+ }
20
+ }
21
+ }
22
+ subscribe(fn) {
23
+ this.on("event", fn);
24
+ return () => this.off("event", fn);
25
+ }
26
+ }
27
+ //# sourceMappingURL=bus.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bus.js","sourceRoot":"","sources":["../src/bus.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAQ3C;;;;GAIG;AACH,MAAM,OAAO,GAAI,SAAQ,YAAY;IACnC;QACE,KAAK,EAAE,CAAC;QACR,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC;IAC7B,CAAC;IAED,OAAO,CAAC,KAAe;QACrB,KAAK,MAAM,EAAE,IAAI,IAAI,CAAC,SAAS,CAAC,OAAO,CAA8B,EAAE,CAAC;YACtE,IAAI,CAAC;gBACH,EAAE,CAAC,KAAK,CAAC,CAAC;YACZ,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,OAAO,CAAC,KAAK,CAAC,SAAS,KAAK,CAAC,IAAI,qBAAqB,EAAE,GAAG,CAAC,CAAC;YAC/D,CAAC;QACH,CAAC;IACH,CAAC;IACD,SAAS,CAAC,EAA6B;QACrC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;QACrB,OAAO,GAAG,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;IACrC,CAAC;CACF"}