@agentorg/computer 0.0.5 → 0.0.7
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/README.md +1 -1
- package/dist/agentcomputer.js +42 -15
- package/dist/types/generated/schema.d.ts +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -139,7 +139,7 @@ A computer at `--access terminal` has two surfaces you can open live, as a WebSo
|
|
|
139
139
|
|
|
140
140
|
A computer with `--browser` has a third:
|
|
141
141
|
|
|
142
|
-
- **`browser`** (protocol `screencast@1`): its browser, on the same page the agent works on. Binary messages are JPEG frames of the page shown. Text messages are JSON: the service sends `tabs`, `viewport`, `dialog`, `file-chooser`, `choice` and `driver`, and an `operate` socket sends `mouse`, `key`, `text`, `dialog`, `files`, `choice`, `tab`, `navigate` and `release`. `openapi.yaml` has each one's fields. A page's own dialogs, file choosers and select lists aren't in the frames, so they arrive as events for you to show and answer.
|
|
142
|
+
- **`browser`** (protocol `screencast@1`): its browser, on the same page the agent works on. Binary messages are JPEG frames of the page shown. Text messages are JSON: the service sends `tabs`, `viewport`, `dialog`, `file-chooser`, `choice` and `driver`, and an `operate` socket sends `mouse`, `key`, `text`, `dialog`, `files`, `choice`, `tab`, `navigate` and `release`. `openapi.yaml` has each one's fields. A page's own dialogs, file choosers and select lists aren't in the frames, so they arrive as events for you to show and answer. Opening it to operate makes you the driver: the agent's browser calls wait up to 25 seconds while you are, then answer that a person has or had the browser. You stop being the driver when you send `release`, close the socket, or send nothing for 60 seconds, and sending input takes it again.
|
|
143
143
|
|
|
144
144
|
`POST /v1/computers/{computerID}/live` with `{ "surface": "terminal", "mode": "operate" }` gives a ticket: a `url` to open once within a minute, which needs no token. A request with an `Origin` header is refused unless `serve --allow-origin` names that origin, so a page can't open one. The SDK does the same with `computer.pty.connect({ onData })` and `computer.commands.watch(onEvent)`, and the CLI with `agentcomputer live <id> --surface terminal --mode operate`.
|
|
145
145
|
|
package/dist/agentcomputer.js
CHANGED
|
@@ -3759,7 +3759,6 @@ import { isMainThread as isMainThread2 } from "node:worker_threads";
|
|
|
3759
3759
|
|
|
3760
3760
|
// src/browser-host.ts
|
|
3761
3761
|
import { mkdtempSync, rmSync } from "node:fs";
|
|
3762
|
-
import { tmpdir } from "node:os";
|
|
3763
3762
|
import { join, sep } from "node:path";
|
|
3764
3763
|
|
|
3765
3764
|
// src/playwright.ts
|
|
@@ -3773,8 +3772,9 @@ var playwright = () => {
|
|
|
3773
3772
|
// src/browser-host.ts
|
|
3774
3773
|
var sandboxFor = (options) => options.sandbox ?? (process.platform !== "linux" || !options.executable && !["chromium", "chrome-for-testing"].includes(options.channel ?? "chrome"));
|
|
3775
3774
|
async function hostBrowser(options) {
|
|
3776
|
-
const run3 = mkdtempSync(join(
|
|
3775
|
+
const run3 = mkdtempSync(join("/tmp", "agentcomputer-"));
|
|
3777
3776
|
process.env.XDG_RUNTIME_DIR = run3;
|
|
3777
|
+
process.env.TMPDIR = run3;
|
|
3778
3778
|
const context = await playwright().chromium.launchPersistentContext(options.profile, {
|
|
3779
3779
|
headless: true,
|
|
3780
3780
|
chromiumSandbox: sandboxFor(options),
|
|
@@ -66315,6 +66315,7 @@ async function startScreencast(page, onFrame) {
|
|
|
66315
66315
|
// src/browser-live.ts
|
|
66316
66316
|
var WAIT_MS = 25e3;
|
|
66317
66317
|
var IDLE_MS = 6e4;
|
|
66318
|
+
var TITLE_CHECK_MS = 1e3;
|
|
66318
66319
|
var STEP_MS = 2e3;
|
|
66319
66320
|
var MAX_BUFFERED = 4 * 1024 * 1024;
|
|
66320
66321
|
var sleep3 = (ms) => new Promise((done) => setTimeout(done, ms));
|
|
@@ -66337,6 +66338,10 @@ var BrowserLive = class {
|
|
|
66337
66338
|
#lastInput = 0;
|
|
66338
66339
|
#agentWaiting = 0;
|
|
66339
66340
|
#answeredChooser = false;
|
|
66341
|
+
/** The tabs last sent, to send them again only when something about them changed. */
|
|
66342
|
+
#lastTabs = "";
|
|
66343
|
+
#titles;
|
|
66344
|
+
#checking = false;
|
|
66340
66345
|
#steps = Promise.resolve();
|
|
66341
66346
|
constructor(endpoint) {
|
|
66342
66347
|
this.#endpoint = endpoint;
|
|
@@ -66369,6 +66374,10 @@ var BrowserLive = class {
|
|
|
66369
66374
|
// ---- The person's side
|
|
66370
66375
|
open(ws, mode) {
|
|
66371
66376
|
this.#sockets.set(ws, mode);
|
|
66377
|
+
if (mode === "operate") {
|
|
66378
|
+
this.#driver = ws;
|
|
66379
|
+
this.#lastInput = Date.now();
|
|
66380
|
+
}
|
|
66372
66381
|
ws.on("close", () => this.#left(ws));
|
|
66373
66382
|
ws.on("message", (data, binary) => {
|
|
66374
66383
|
if (binary || this.#sockets.get(ws) !== "operate") return;
|
|
@@ -66418,6 +66427,7 @@ var BrowserLive = class {
|
|
|
66418
66427
|
void this.#show(page);
|
|
66419
66428
|
});
|
|
66420
66429
|
await this.#show(context.pages().at(-1) ?? await context.newPage());
|
|
66430
|
+
this.#titles = setInterval(() => void this.#checkTabs(), TITLE_CHECK_MS);
|
|
66421
66431
|
return viewer;
|
|
66422
66432
|
})();
|
|
66423
66433
|
await this.#viewer;
|
|
@@ -66425,6 +66435,9 @@ var BrowserLive = class {
|
|
|
66425
66435
|
async #end() {
|
|
66426
66436
|
const viewer = this.#viewer;
|
|
66427
66437
|
this.#viewer = void 0;
|
|
66438
|
+
clearInterval(this.#titles);
|
|
66439
|
+
this.#titles = void 0;
|
|
66440
|
+
this.#lastTabs = "";
|
|
66428
66441
|
await this.#stopCast?.();
|
|
66429
66442
|
this.#stopCast = void 0;
|
|
66430
66443
|
this.#shown = void 0;
|
|
@@ -66499,7 +66512,7 @@ var BrowserLive = class {
|
|
|
66499
66512
|
}
|
|
66500
66513
|
await this.#tabs();
|
|
66501
66514
|
}
|
|
66502
|
-
async #
|
|
66515
|
+
async #tabList() {
|
|
66503
66516
|
const tabs = await Promise.all(
|
|
66504
66517
|
[...this.#ids].map(async ([page, id]) => ({
|
|
66505
66518
|
id,
|
|
@@ -66507,14 +66520,28 @@ var BrowserLive = class {
|
|
|
66507
66520
|
title: await within(page.title(), STEP_MS).catch(() => void 0) ?? ""
|
|
66508
66521
|
}))
|
|
66509
66522
|
);
|
|
66510
|
-
|
|
66511
|
-
|
|
66512
|
-
|
|
66513
|
-
|
|
66514
|
-
|
|
66523
|
+
return { type: "tabs", tabs, shown: (this.#shown && this.#ids.get(this.#shown)) ?? null };
|
|
66524
|
+
}
|
|
66525
|
+
async #tabs(only) {
|
|
66526
|
+
const message = await this.#tabList();
|
|
66527
|
+
this.#lastTabs = JSON.stringify(message);
|
|
66515
66528
|
if (only) this.#send(only, message);
|
|
66516
66529
|
else this.#broadcast(message);
|
|
66517
66530
|
}
|
|
66531
|
+
/** Send the tabs again if anything about them changed, such as a title. */
|
|
66532
|
+
async #checkTabs() {
|
|
66533
|
+
if (this.#checking) return;
|
|
66534
|
+
this.#checking = true;
|
|
66535
|
+
try {
|
|
66536
|
+
const message = await this.#tabList();
|
|
66537
|
+
const text2 = JSON.stringify(message);
|
|
66538
|
+
if (text2 === this.#lastTabs) return;
|
|
66539
|
+
this.#lastTabs = text2;
|
|
66540
|
+
this.#broadcast(message);
|
|
66541
|
+
} finally {
|
|
66542
|
+
this.#checking = false;
|
|
66543
|
+
}
|
|
66544
|
+
}
|
|
66518
66545
|
/** Each step in order, none waiting on another for long: a dialog blocks the page's input. */
|
|
66519
66546
|
#step(work) {
|
|
66520
66547
|
this.#steps = this.#steps.then(() => within(work(), STEP_MS)).catch(() => {
|
|
@@ -67185,7 +67212,7 @@ async function forward(url3, authorization, request, response) {
|
|
|
67185
67212
|
}
|
|
67186
67213
|
|
|
67187
67214
|
// src/handlers.ts
|
|
67188
|
-
var VERSION2 = "0.0.
|
|
67215
|
+
var VERSION2 = "0.0.7";
|
|
67189
67216
|
function createHandlers(computers) {
|
|
67190
67217
|
return {
|
|
67191
67218
|
getInfo: async () => ({ version: VERSION2, isolation: computers.isolation }),
|
|
@@ -84160,7 +84187,7 @@ var OPENAPI = {
|
|
|
84160
84187
|
"openapi": "3.1.0",
|
|
84161
84188
|
"info": {
|
|
84162
84189
|
"title": "AgentComputer",
|
|
84163
|
-
"version": "0.0.
|
|
84190
|
+
"version": "0.0.7",
|
|
84164
84191
|
"description": "Computers for agents. This file is the source of truth: the HTTP API, the MCP control tools and the SDK are all generated from it. An operation with `x-mcp-tool` is also an MCP tool of that name.",
|
|
84165
84192
|
"license": {
|
|
84166
84193
|
"name": "Apache-2.0",
|
|
@@ -84824,7 +84851,7 @@ var OPENAPI = {
|
|
|
84824
84851
|
"terminal",
|
|
84825
84852
|
"browser"
|
|
84826
84853
|
],
|
|
84827
|
-
"description": "commands: the agent's commands as they run, read-only, in commands@1. terminal: a shell of your own in its workspace, as its user, in pty@1. browser: its browser, in screencast@1: binary messages are JPEG frames of the page shown, text messages are ScreencastEvent one way and ScreencastInput the other.
|
|
84854
|
+
"description": "commands: the agent's commands as they run, read-only, in commands@1. terminal: a shell of your own in its workspace, as its user, in pty@1. browser: its browser, in screencast@1: binary messages are JPEG frames of the page shown, text messages are ScreencastEvent one way and ScreencastInput the other. Opening it to operate makes you the driver: the agent's browser calls wait up to 25 seconds while you are, then answer that a person has or had it. You stop being the driver when you send release, close the socket, or send nothing for 60 seconds, and sending input takes it again."
|
|
84828
84855
|
},
|
|
84829
84856
|
"LiveMode": {
|
|
84830
84857
|
"type": "string",
|
|
@@ -84915,7 +84942,7 @@ var OPENAPI = {
|
|
|
84915
84942
|
"oneOf": [
|
|
84916
84943
|
{
|
|
84917
84944
|
"type": "object",
|
|
84918
|
-
"description": "The open tabs, and which one the frames are of.",
|
|
84945
|
+
"description": "The open tabs, and which one the frames are of, sent again whenever a tab opens, closes, navigates or changes its title.",
|
|
84919
84946
|
"required": [
|
|
84920
84947
|
"type",
|
|
84921
84948
|
"tabs",
|
|
@@ -85846,7 +85873,7 @@ var OPERATIONS = [
|
|
|
85846
85873
|
"terminal",
|
|
85847
85874
|
"browser"
|
|
85848
85875
|
],
|
|
85849
|
-
"description": "commands: the agent's commands as they run, read-only, in commands@1. terminal: a shell of your own in its workspace, as its user, in pty@1. browser: its browser, in screencast@1: binary messages are JPEG frames of the page shown, text messages are ScreencastEvent one way and ScreencastInput the other.
|
|
85876
|
+
"description": "commands: the agent's commands as they run, read-only, in commands@1. terminal: a shell of your own in its workspace, as its user, in pty@1. browser: its browser, in screencast@1: binary messages are JPEG frames of the page shown, text messages are ScreencastEvent one way and ScreencastInput the other. Opening it to operate makes you the driver: the agent's browser calls wait up to 25 seconds while you are, then answer that a person has or had it. You stop being the driver when you send release, close the socket, or send nothing for 60 seconds, and sending input takes it again."
|
|
85850
85877
|
},
|
|
85851
85878
|
"protocol": {
|
|
85852
85879
|
"type": "string"
|
|
@@ -86386,7 +86413,7 @@ var OPERATIONS = [
|
|
|
86386
86413
|
"terminal",
|
|
86387
86414
|
"browser"
|
|
86388
86415
|
],
|
|
86389
|
-
"description": "commands: the agent's commands as they run, read-only, in commands@1. terminal: a shell of your own in its workspace, as its user, in pty@1. browser: its browser, in screencast@1: binary messages are JPEG frames of the page shown, text messages are ScreencastEvent one way and ScreencastInput the other.
|
|
86416
|
+
"description": "commands: the agent's commands as they run, read-only, in commands@1. terminal: a shell of your own in its workspace, as its user, in pty@1. browser: its browser, in screencast@1: binary messages are JPEG frames of the page shown, text messages are ScreencastEvent one way and ScreencastInput the other. Opening it to operate makes you the driver: the agent's browser calls wait up to 25 seconds while you are, then answer that a person has or had it. You stop being the driver when you send release, close the socket, or send nothing for 60 seconds, and sending input takes it again."
|
|
86390
86417
|
},
|
|
86391
86418
|
"mode": {
|
|
86392
86419
|
"allOf": [
|
|
@@ -86432,7 +86459,7 @@ var OPERATIONS = [
|
|
|
86432
86459
|
"terminal",
|
|
86433
86460
|
"browser"
|
|
86434
86461
|
],
|
|
86435
|
-
"description": "commands: the agent's commands as they run, read-only, in commands@1. terminal: a shell of your own in its workspace, as its user, in pty@1. browser: its browser, in screencast@1: binary messages are JPEG frames of the page shown, text messages are ScreencastEvent one way and ScreencastInput the other.
|
|
86462
|
+
"description": "commands: the agent's commands as they run, read-only, in commands@1. terminal: a shell of your own in its workspace, as its user, in pty@1. browser: its browser, in screencast@1: binary messages are JPEG frames of the page shown, text messages are ScreencastEvent one way and ScreencastInput the other. Opening it to operate makes you the driver: the agent's browser calls wait up to 25 seconds while you are, then answer that a person has or had it. You stop being the driver when you send release, close the socket, or send nothing for 60 seconds, and sending input takes it again."
|
|
86436
86463
|
},
|
|
86437
86464
|
"mode": {
|
|
86438
86465
|
"type": "string",
|
|
@@ -248,7 +248,7 @@ export interface components {
|
|
|
248
248
|
};
|
|
249
249
|
};
|
|
250
250
|
/**
|
|
251
|
-
* @description commands: the agent's commands as they run, read-only, in commands@1. terminal: a shell of your own in its workspace, as its user, in pty@1. browser: its browser, in screencast@1: binary messages are JPEG frames of the page shown, text messages are ScreencastEvent one way and ScreencastInput the other.
|
|
251
|
+
* @description commands: the agent's commands as they run, read-only, in commands@1. terminal: a shell of your own in its workspace, as its user, in pty@1. browser: its browser, in screencast@1: binary messages are JPEG frames of the page shown, text messages are ScreencastEvent one way and ScreencastInput the other. Opening it to operate makes you the driver: the agent's browser calls wait up to 25 seconds while you are, then answer that a person has or had it. You stop being the driver when you send release, close the socket, or send nothing for 60 seconds, and sending input takes it again.
|
|
252
252
|
* @enum {string}
|
|
253
253
|
*/
|
|
254
254
|
Surface: "commands" | "terminal" | "browser";
|