@agimon-ai/doompi-computer-use 0.0.1-alpha.49 → 0.0.1-alpha.51
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/dist/apiContracts.cjs +49 -3
- package/dist/apiContracts.cjs.map +1 -1
- package/dist/apiContracts.d.mts.map +1 -1
- package/dist/apiContracts.mjs +49 -3
- package/dist/apiContracts.mjs.map +1 -1
- package/dist/{computerUseMode-KnoOWve4.cjs → computerUseMode-C1Cj1ZlK.cjs} +2 -1
- package/dist/computerUseMode-C1Cj1ZlK.cjs.map +1 -0
- package/dist/{computerUseMode-C1r5mG7K.mjs → computerUseMode-QSRNQAYf.mjs} +2 -1
- package/dist/computerUseMode-QSRNQAYf.mjs.map +1 -0
- package/dist/extensions/mcp.cjs.map +1 -1
- package/dist/extensions/mcp.mjs.map +1 -1
- package/dist/extensions/pi.cjs +1 -1
- package/dist/extensions/pi.d.mts +1 -1
- package/dist/extensions/pi.mjs +1 -1
- package/dist/extensions/server.cjs +57 -12
- package/dist/extensions/server.cjs.map +1 -1
- package/dist/extensions/server.mjs +57 -12
- package/dist/extensions/server.mjs.map +1 -1
- package/dist/extensions/web.mjs +160 -22
- package/dist/extensions/web.mjs.map +1 -1
- package/dist/{index-DoKasntC.d.mts → index-B059zxHp.d.mts} +4 -2
- package/dist/index-B059zxHp.d.mts.map +1 -0
- package/dist/index.d.mts +1 -1
- package/package.json +10 -10
- package/src/types/computerUseApi.ts +3 -1
- package/dist/computerUseMode-C1r5mG7K.mjs.map +0 -1
- package/dist/computerUseMode-KnoOWve4.cjs.map +0 -1
- package/dist/index-DoKasntC.d.mts.map +0 -1
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { a as COMMAND_NAME, i as COMMAND_DESCRIPTION, r as ComputerScriptRunner, t as DefaultComputerUseExtensionService } from "../extensionService-BSqhP2uB.mjs";
|
|
2
|
-
import { a as computerScriptOutput, d as COMPUTER_USE_ROUTES, f as COMPUTER_USE_STATUS_KEY, i as computerScriptFailure, l as COMPUTER_USE_MODE_ID, m as computerUseChannelType, n as modeState, o as API_BASE_PATH, p as COMPUTER_USE_WAKE_LIMIT, r as computerObservationOutput, s as COMPUTER_USE_CONFIRMATION_WINDOW_MS } from "../computerUseMode-
|
|
2
|
+
import { a as computerScriptOutput, d as COMPUTER_USE_ROUTES, f as COMPUTER_USE_STATUS_KEY, i as computerScriptFailure, l as COMPUTER_USE_MODE_ID, m as computerUseChannelType, n as modeState, o as API_BASE_PATH, p as COMPUTER_USE_WAKE_LIMIT, r as computerObservationOutput, s as COMPUTER_USE_CONFIRMATION_WINDOW_MS } from "../computerUseMode-QSRNQAYf.mjs";
|
|
3
3
|
import path from "node:path";
|
|
4
4
|
import { composeRootHooks, defineChannel, defineRoot, defineRoutedContribution } from "@agimon-ai/doompi-core/extensionFile";
|
|
5
5
|
import { defineMinorMode, serverMinorModes } from "@agimon-ai/doompi-minor-mode";
|
|
6
6
|
import { defineServerPlugin } from "@agimon-ai/doompi-core/serverFacet";
|
|
7
7
|
import { randomUUID } from "node:crypto";
|
|
8
|
+
import { doomApiCallerFrom } from "@agimon-ai/doompi-core/packageApi";
|
|
8
9
|
import { apiResponse, defineApiRoutes } from "@agimon-ai/doompi-core/web";
|
|
9
10
|
//#region src/services/mcpTools/index.ts
|
|
10
11
|
const COMPUTER_USE_MCP_TOOLS_SERVICE = "doom/computer-use-mcp-tools";
|
|
@@ -33,12 +34,28 @@ function mountMcpTools(tools) {
|
|
|
33
34
|
* disagreement this file exists to prevent. The dispatcher now reads this
|
|
34
35
|
* table, so the page, the broker and the hub all resolve one set of strings.
|
|
35
36
|
*
|
|
36
|
-
*
|
|
37
|
+
* Activation, status, cancellation and recording reads are reachable from a browser. The `/agent/` and `/hub/` routes
|
|
37
38
|
* each demand a host-issued bearer token and answer 404 without one; they are
|
|
38
39
|
* declared here because they are this API's surface, not because a page calls
|
|
39
40
|
* them.
|
|
40
41
|
*/
|
|
41
42
|
var apiRoutes_default = defineApiRoutes({
|
|
43
|
+
artifact: {
|
|
44
|
+
method: "GET",
|
|
45
|
+
path: COMPUTER_USE_ROUTES.artifact,
|
|
46
|
+
query: ["artifactId", "offset"],
|
|
47
|
+
raw: true
|
|
48
|
+
},
|
|
49
|
+
activationState: {
|
|
50
|
+
method: "GET",
|
|
51
|
+
path: COMPUTER_USE_ROUTES.activate,
|
|
52
|
+
response: apiResponse()
|
|
53
|
+
},
|
|
54
|
+
cancelActivation: {
|
|
55
|
+
method: "DELETE",
|
|
56
|
+
path: COMPUTER_USE_ROUTES.activate,
|
|
57
|
+
response: apiResponse()
|
|
58
|
+
},
|
|
42
59
|
activate: {
|
|
43
60
|
method: "POST",
|
|
44
61
|
path: COMPUTER_USE_ROUTES.activate,
|
|
@@ -154,6 +171,7 @@ function artifactView(value) {
|
|
|
154
171
|
return {
|
|
155
172
|
artifactId: input.artifactId,
|
|
156
173
|
status: input.status,
|
|
174
|
+
...typeof input.sizeBytes === "number" && Number.isSafeInteger(input.sizeBytes) && input.sizeBytes > 0 ? { sizeBytes: input.sizeBytes } : {},
|
|
157
175
|
...downloadUrl === void 0 ? {} : { downloadUrl },
|
|
158
176
|
...previewUrl === void 0 ? {} : { previewUrl },
|
|
159
177
|
...typeof input.actionCount === "number" ? { actionCount: input.actionCount } : {},
|
|
@@ -274,9 +292,10 @@ var ComputerUseRequestBroker = class ComputerUseRequestBroker {
|
|
|
274
292
|
return token !== void 0 && request.headers.get("authorization") === `Bearer ${token}`;
|
|
275
293
|
}
|
|
276
294
|
async requestActivation(request) {
|
|
277
|
-
if (!this.desktop?.available || !this.desktop.authorize(request.headers)) return jsonError("Not found.", 404);
|
|
295
|
+
if (!this.desktop?.available || !(this.desktop.authorizeActivation?.(request.headers) ?? this.desktop.authorize(request.headers))) return jsonError("Not found.", 404);
|
|
278
296
|
if (this.desktop.enabled === false) return jsonError("Enable computer use in global Desktop settings first.", 409);
|
|
279
|
-
const
|
|
297
|
+
const stamped = doomApiCallerFrom(request.headers);
|
|
298
|
+
const caller = stamped?.locality === "remote" ? stamped : {
|
|
280
299
|
locality: "local",
|
|
281
300
|
stepUp: "not-required"
|
|
282
301
|
};
|
|
@@ -284,10 +303,10 @@ var ComputerUseRequestBroker = class ComputerUseRequestBroker {
|
|
|
284
303
|
const input = await body(request);
|
|
285
304
|
const target = record$1(input.target);
|
|
286
305
|
const durationMs = input.durationMs;
|
|
287
|
-
if (target === void 0 || typeof target.windowId !== "string" || typeof target.bundleId !== "string") return jsonError("A Desktop target is required.", 400);
|
|
306
|
+
if (target === void 0 && (input.target !== void 0 || caller.locality !== "remote") || target !== void 0 && (typeof target.windowId !== "string" || typeof target.bundleId !== "string")) return jsonError("A Desktop target is required, or a remote request must leave selection to the Mac.", 400);
|
|
288
307
|
if (typeof durationMs !== "number" || !Number.isInteger(durationMs) || durationMs < 1e3 || durationMs > 18e5) return jsonError("The requested duration is invalid.", 400);
|
|
289
|
-
this.desktop.claim();
|
|
290
308
|
try {
|
|
309
|
+
this.desktop.claim(request.headers);
|
|
291
310
|
await this.beforeActivate?.();
|
|
292
311
|
} catch (error) {
|
|
293
312
|
return jsonError(error instanceof Error ? error.message : String(error), 409);
|
|
@@ -296,7 +315,7 @@ var ComputerUseRequestBroker = class ComputerUseRequestBroker {
|
|
|
296
315
|
const createdAt = Date.now();
|
|
297
316
|
this.activation = Object.freeze({
|
|
298
317
|
requestId: randomUUID(),
|
|
299
|
-
target: Object.freeze({ ...target }),
|
|
318
|
+
...target === void 0 ? {} : { target: Object.freeze({ ...target }) },
|
|
300
319
|
durationSeconds: durationMs / 1e3,
|
|
301
320
|
createdAt,
|
|
302
321
|
confirmationExpiresAt: createdAt + COMPUTER_USE_CONFIRMATION_WINDOW_MS,
|
|
@@ -358,7 +377,28 @@ var ComputerUseRequestBroker = class ComputerUseRequestBroker {
|
|
|
358
377
|
}
|
|
359
378
|
async fetch(request) {
|
|
360
379
|
if (this.closed) return jsonError("Computer-use broker is closed.", 503);
|
|
361
|
-
const
|
|
380
|
+
const url = new URL(request.url);
|
|
381
|
+
const path = url.pathname;
|
|
382
|
+
if (request.method === "GET" && path === apiRoutes_default.artifact.path) {
|
|
383
|
+
if (!(this.desktop?.authorizeRecording?.(request.headers) ?? this.desktop?.authorize(request.headers)) || !this.desktop?.fetchRecording) return jsonError("Not found.", 404);
|
|
384
|
+
const artifactId = url.searchParams.get("artifactId") ?? "";
|
|
385
|
+
const offsetText = url.searchParams.get("offset") ?? "";
|
|
386
|
+
const offset = Number(offsetText);
|
|
387
|
+
if (!/^[0-9]+$/u.test(offsetText) || !Number.isSafeInteger(offset) || offset < 0 || offset > 134217728) return jsonError("Invalid recording offset.", 400);
|
|
388
|
+
return this.desktop.fetchRecording(artifactId, `bytes=${offset}-${offset + 1048576 - 1}`);
|
|
389
|
+
}
|
|
390
|
+
if (path === apiRoutes_default.activate.path && request.method === "GET") {
|
|
391
|
+
if (!this.desktop?.authorizePending?.(request.headers) && !(this.desktop?.authorizeRecording?.(request.headers) ?? this.desktop?.authorize(request.headers))) return jsonError("Not found.", 404);
|
|
392
|
+
return Response.json(this.state());
|
|
393
|
+
}
|
|
394
|
+
if (path === apiRoutes_default.activate.path && request.method === "DELETE") {
|
|
395
|
+
if (!this.desktop?.authorizePending?.(request.headers)) return jsonError("Not found.", 404);
|
|
396
|
+
if (this.phase !== "awaiting_confirmation" && this.phase !== "activating") return jsonError("No activation is pending.", 409);
|
|
397
|
+
this.phase = "stopping";
|
|
398
|
+
this.rejectPending("The activation was cancelled.");
|
|
399
|
+
this.changed();
|
|
400
|
+
return Response.json(this.state(), { status: 202 });
|
|
401
|
+
}
|
|
362
402
|
if (request.method === "POST" && path === apiRoutes_default.activate.path) return this.requestActivation(request);
|
|
363
403
|
const agent = path.startsWith("/agent/");
|
|
364
404
|
const hub = path.startsWith("/hub/");
|
|
@@ -415,6 +455,11 @@ var ComputerUseRequestBroker = class ComputerUseRequestBroker {
|
|
|
415
455
|
} else {
|
|
416
456
|
const host = record$1(input.host);
|
|
417
457
|
if (typeof host?.grantId !== "string" || !Number.isFinite(host.expiresAt) || host.expiresAt <= Date.now()) return jsonError("Desktop did not issue a complete grant.", 502);
|
|
458
|
+
const selectedTarget = record$1(host.target);
|
|
459
|
+
if (this.activation !== void 0 && selectedTarget !== void 0) this.activation = Object.freeze({
|
|
460
|
+
...this.activation,
|
|
461
|
+
target: Object.freeze({ ...selectedTarget })
|
|
462
|
+
});
|
|
418
463
|
this.grantId = host.grantId;
|
|
419
464
|
this.expiresAt = host.expiresAt;
|
|
420
465
|
this.actionSequence = 0;
|
|
@@ -435,7 +480,7 @@ var ComputerUseRequestBroker = class ComputerUseRequestBroker {
|
|
|
435
480
|
this.grantId = void 0;
|
|
436
481
|
this.expiresAt = void 0;
|
|
437
482
|
this.activation = void 0;
|
|
438
|
-
this.artifact = artifactView(input.artifact);
|
|
483
|
+
this.artifact = artifactView(input.artifact) ?? this.artifact;
|
|
439
484
|
}
|
|
440
485
|
this.changed();
|
|
441
486
|
return Response.json(this.state());
|
|
@@ -965,10 +1010,10 @@ function createComputerUseChannel() {
|
|
|
965
1010
|
const authorization = await responseJson(await sessionRequest(scope, COMPUTER_USE_ROUTES.hubAuthorization));
|
|
966
1011
|
let artifact;
|
|
967
1012
|
if (authorization !== null && host.computerUse?.available) try {
|
|
968
|
-
artifact = await host.computerUse.request(scope, {
|
|
1013
|
+
artifact = record(await host.computerUse.request(scope, {
|
|
969
1014
|
operation: "stop",
|
|
970
1015
|
payload: { grantId: authorization.grantId }
|
|
971
|
-
});
|
|
1016
|
+
}))?.artifact;
|
|
972
1017
|
} catch (error) {
|
|
973
1018
|
const message = error instanceof Error ? error.message : String(error);
|
|
974
1019
|
artifact = {
|
|
@@ -1134,7 +1179,7 @@ function createComputerUseChannel() {
|
|
|
1134
1179
|
};
|
|
1135
1180
|
},
|
|
1136
1181
|
receive(scope, payload, connection) {
|
|
1137
|
-
if (connection.desktopAuthorized !== true) return;
|
|
1182
|
+
if (connection.desktopAuthorized !== true && connection.computerUseAuthorized !== true) return;
|
|
1138
1183
|
receiveCommand?.(scope, payload);
|
|
1139
1184
|
}
|
|
1140
1185
|
};
|