tesseract-agent 0.9.15 → 0.9.20

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 (2) hide show
  1. package/dist-bundle/cli.js +78 -0
  2. package/package.json +1 -1
@@ -22277,6 +22277,54 @@ ${r?.url ?? ""}`);
22277
22277
  tool3("browser_type", `Type text into an input/textarea by CSS selector (fires input + change events). ${REAL}`, { selector: external_exports.string().describe("CSS selector of the field."), text: external_exports.string().describe("Text to set as the field value.") }, async (a) => {
22278
22278
  const r = await drive("type", { selector: a.selector, text: a.text });
22279
22279
  return text2(r?.typed ? `Typed into ${a.selector}` : `No element matched ${a.selector}`, !r?.typed);
22280
+ }),
22281
+ // ── FULL CONTROL / runtime-debugger tools (need the Companion extension; the built-in engine
22282
+ // supports the structured verbs above). Powerful — gated by the user's opt-in + indicator. ──
22283
+ tool3("browser_eval", `Run ARBITRARY JavaScript in the page and return its result. Executes in the real page context via the DevTools protocol (bypasses page CSP for the top-level expression) \u2014 use for anything the structured tools don't cover: read variables & site functions, walk the DOM, compute values, mutate state, await async work. The last expression value (or an awaited promise) is returned, serialized by value. ${REAL}`, { expression: external_exports.string().describe("JS expression or statements to evaluate in the page."), awaitPromise: external_exports.boolean().optional().describe("Await a returned promise (default true).") }, async (a) => {
22284
+ const r = await drive("eval", { expression: a.expression, awaitPromise: a.awaitPromise });
22285
+ if (r?.exceptionDetails)
22286
+ return text2(`Exception: ${JSON.stringify(r.exceptionDetails)}`, true);
22287
+ return text2(typeof r?.value === "string" ? r.value : JSON.stringify(r?.value ?? null, null, 2));
22288
+ }),
22289
+ tool3("browser_cdp", `Send a RAW Chrome DevTools Protocol command to the driven tab and return the result \u2014 full runtime-debugger access to ANY CDP domain: DOM, CSS, Runtime, Debugger (breakpoints / pause / step / evaluateOnCallFrame), Network (enable, then getResponseBody), Page, Input, Emulation, Storage, Performance, Accessibility, \u2026 Enable a domain (e.g. Network.enable) then read its async notifications with browser_events. ${REAL}`, { method: external_exports.string().describe('CDP method, e.g. "DOM.getDocument", "Debugger.setBreakpointByUrl", "Network.enable", "Emulation.setDeviceMetricsOverride".'), params: external_exports.record(external_exports.string(), external_exports.unknown()).optional().describe("Params object for the CDP method.") }, async (a) => {
22290
+ const r = await drive("cdp", { method: a.method, params: a.params ?? {} });
22291
+ return text2(JSON.stringify(r ?? null, null, 2));
22292
+ }),
22293
+ tool3("browser_events", `Drain buffered CDP notifications from the driven tab \u2014 console messages (Runtime.consoleAPICalled), uncaught errors, Network.* traffic, Debugger.paused, Log.entryAdded, etc. Enable the relevant domain first with browser_cdp (Runtime.enable / Network.enable / Log.enable / Debugger.enable), then poll this. ${REAL}`, { filter: external_exports.string().optional().describe('Only return events whose CDP method starts with this prefix, e.g. "Network." or "Runtime.consoleAPICalled".'), keep: external_exports.boolean().optional().describe("Keep events in the buffer instead of draining (default false = drain).") }, async (a) => {
22294
+ const r = await drive("pullEvents", { method: a.filter, text: a.keep ? "keep" : "" });
22295
+ return text2(JSON.stringify(r?.events ?? [], null, 2));
22296
+ }),
22297
+ tool3("browser_wait_for", `Wait until a CSS selector appears OR a JS expression becomes truthy (polls up to timeout ms). ${REAL}`, { selector: external_exports.string().optional().describe("CSS selector to wait for."), expression: external_exports.string().optional().describe("JS expression to poll until truthy (used when no selector is given)."), timeout: external_exports.number().optional().describe("Max wait in ms (default 10000).") }, async (a) => {
22298
+ const r = await drive("waitFor", { selector: a.selector, expression: a.expression, timeout: a.timeout });
22299
+ return text2(r?.ok ? `Ready after ${r.waitedMs}ms` : "Timed out waiting", !r?.ok);
22300
+ }),
22301
+ tool3("browser_get_html", `Return the full outer HTML of the current page (document.documentElement.outerHTML). ${REAL}`, {}, async () => {
22302
+ const r = await drive("html");
22303
+ return text2(r?.html ?? "");
22304
+ }),
22305
+ tool3("browser_real_click", `Click an element with a REAL, trusted mouse event dispatched at its center via the DevTools protocol (isTrusted=true) \u2014 use when a site ignores the synthetic browser_click (OAuth buttons, some SPAs, drag handles). ${REAL}`, { selector: external_exports.string().describe("CSS selector of the element to click.") }, async (a) => {
22306
+ const r = await drive("realClick", { selector: a.selector });
22307
+ return text2(r?.clicked ? `Trusted-clicked ${a.selector}` : `No element matched ${a.selector}`, !r?.clicked);
22308
+ }),
22309
+ tool3("browser_real_type", `Type text as REAL, trusted keyboard input via the DevTools protocol (optionally focusing a selector first) \u2014 use when a site ignores the synthetic browser_type. ${REAL}`, { selector: external_exports.string().optional().describe("CSS selector to focus first (optional; types into the already-focused element otherwise)."), text: external_exports.string().describe("Text to type.") }, async (a) => {
22310
+ await drive("realType", { selector: a.selector, text: a.text });
22311
+ return text2(`Typed${a.selector ? ` into ${a.selector}` : ""}`);
22312
+ }),
22313
+ tool3("browser_key", `Press a single trusted key in the driven tab \u2014 "Enter" / "Tab" / "Escape" / "Backspace" or a character. ${REAL}`, { key: external_exports.string().describe('Key to press, e.g. "Enter".') }, async (a) => {
22314
+ await drive("key", { text: a.key });
22315
+ return text2(`Pressed ${a.key}`);
22316
+ }),
22317
+ tool3("browser_cookies", `Read cookies for the driven tab (includes httpOnly) via the DevTools protocol. ${REAL}`, { url: external_exports.string().optional().describe("Restrict to cookies for this URL (optional).") }, async (a) => {
22318
+ const r = await drive("cookies", { url: a.url });
22319
+ return text2(JSON.stringify(r ?? {}, null, 2));
22320
+ }),
22321
+ tool3("browser_screenshot_full", `Capture a full-page PNG (beyond the visible viewport) via the DevTools protocol. ${REAL}`, {}, async () => {
22322
+ const r = await drive("screenshotFull");
22323
+ const dataUrl = r?.dataUrl ?? "";
22324
+ const b642 = dataUrl.startsWith("data:") ? dataUrl.slice(dataUrl.indexOf(",") + 1) : dataUrl;
22325
+ if (!b642)
22326
+ return text2("No screenshot data returned.", true);
22327
+ return { content: [{ type: "image", data: b642, mimeType: "image/png" }] };
22280
22328
  })
22281
22329
  ];
22282
22330
  }
@@ -73864,11 +73912,35 @@ async function replayTurn(turn) {
73864
73912
  var extensionBrowserConn = null;
73865
73913
  function setExtensionBrowserConn(send3) {
73866
73914
  extensionBrowserConn = send3;
73915
+ if (send3) {
73916
+ browserPushActive = false;
73917
+ browserEventBuf.length = 0;
73918
+ }
73867
73919
  }
73868
73920
  function clearExtensionBrowserConnIf(send3) {
73869
73921
  if (extensionBrowserConn === send3)
73870
73922
  extensionBrowserConn = null;
73871
73923
  }
73924
+ var browserEventBuf = [];
73925
+ var browserPushActive = false;
73926
+ var MAX_BROWSER_EVENTS = 1e3;
73927
+ function pushBrowserEvent(e) {
73928
+ browserPushActive = true;
73929
+ browserEventBuf.push(e ?? {});
73930
+ if (browserEventBuf.length > MAX_BROWSER_EVENTS)
73931
+ browserEventBuf.splice(0, browserEventBuf.length - MAX_BROWSER_EVENTS);
73932
+ }
73933
+ function drainBrowserEvents(params) {
73934
+ const prefix = typeof params.method === "string" ? params.method : "";
73935
+ const match = (e) => !prefix || (e.method ?? "").startsWith(prefix);
73936
+ const events = browserEventBuf.filter(match);
73937
+ if (params.text !== "keep") {
73938
+ for (let i = browserEventBuf.length - 1; i >= 0; i--)
73939
+ if (match(browserEventBuf[i]))
73940
+ browserEventBuf.splice(i, 1);
73941
+ }
73942
+ return events;
73943
+ }
73872
73944
  setBrowserExtensionProbe(() => extensionBrowserConn != null);
73873
73945
  function registerAgentSink(sink) {
73874
73946
  sinks.add(sink);
@@ -73957,6 +74029,10 @@ function buildSharedBackend(engineId) {
73957
74029
  },
73958
74030
  (requestId, action, params, browserId) => {
73959
74031
  if (extensionBrowserConn) {
74032
+ if (action === "pullEvents" && browserPushActive && backend) {
74033
+ backend.sendBrowserResponse?.(requestId, { events: drainBrowserEvents(params ?? {}) });
74034
+ return;
74035
+ }
73960
74036
  extensionBrowserConn("browser", { id: requestId, op: action, ...params ?? {} });
73961
74037
  return;
73962
74038
  }
@@ -83651,6 +83727,8 @@ async function startLocalServer(opts) {
83651
83727
  setExtensionBrowserConn(send3);
83652
83728
  } else if (p?.id)
83653
83729
  peekSharedBackend()?.sendBrowserResponse?.(p.id, p.result, p.error);
83730
+ } else if (env.channel === "browser:event") {
83731
+ pushBrowserEvent(env.payload);
83654
83732
  } else if (env.channel === "rdesk") {
83655
83733
  const rd = opts.getRdesk?.();
83656
83734
  if (rd && env.sessionId) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tesseract-agent",
3
- "version": "0.9.15",
3
+ "version": "0.9.20",
4
4
  "license": "UNLICENSED",
5
5
  "publishConfig": {
6
6
  "access": "public",