mandala-computer-mcp 0.1.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.
- package/LICENSE +21 -0
- package/README.md +544 -0
- package/dist/api.d.ts +186 -0
- package/dist/api.d.ts.map +1 -0
- package/dist/api.js +932 -0
- package/dist/api.js.map +1 -0
- package/dist/cli.d.ts +55 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +292 -0
- package/dist/cli.js.map +1 -0
- package/dist/errors.d.ts +560 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +873 -0
- package/dist/errors.js.map +1 -0
- package/dist/events.d.ts +406 -0
- package/dist/events.d.ts.map +1 -0
- package/dist/events.js +1679 -0
- package/dist/events.js.map +1 -0
- package/dist/format.d.ts +125 -0
- package/dist/format.d.ts.map +1 -0
- package/dist/format.js +180 -0
- package/dist/format.js.map +1 -0
- package/dist/http.d.ts +46 -0
- package/dist/http.d.ts.map +1 -0
- package/dist/http.js +792 -0
- package/dist/http.js.map +1 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +12 -0
- package/dist/index.js.map +1 -0
- package/dist/paths.d.ts +394 -0
- package/dist/paths.d.ts.map +1 -0
- package/dist/paths.js +677 -0
- package/dist/paths.js.map +1 -0
- package/dist/server.d.ts +18 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +97 -0
- package/dist/server.js.map +1 -0
- package/dist/session.d.ts +78 -0
- package/dist/session.d.ts.map +1 -0
- package/dist/session.js +166 -0
- package/dist/session.js.map +1 -0
- package/dist/stdio.d.ts +11 -0
- package/dist/stdio.d.ts.map +1 -0
- package/dist/stdio.js +43 -0
- package/dist/stdio.js.map +1 -0
- package/dist/tools/agent.d.ts +16 -0
- package/dist/tools/agent.d.ts.map +1 -0
- package/dist/tools/agent.js +147 -0
- package/dist/tools/agent.js.map +1 -0
- package/dist/tools/computers.d.ts +3 -0
- package/dist/tools/computers.d.ts.map +1 -0
- package/dist/tools/computers.js +1037 -0
- package/dist/tools/computers.js.map +1 -0
- package/dist/tools/events.d.ts +3 -0
- package/dist/tools/events.d.ts.map +1 -0
- package/dist/tools/events.js +1077 -0
- package/dist/tools/events.js.map +1 -0
- package/dist/tools/guest.d.ts +3 -0
- package/dist/tools/guest.d.ts.map +1 -0
- package/dist/tools/guest.js +761 -0
- package/dist/tools/guest.js.map +1 -0
- package/dist/tools/input.d.ts +3 -0
- package/dist/tools/input.d.ts.map +1 -0
- package/dist/tools/input.js +240 -0
- package/dist/tools/input.js.map +1 -0
- package/dist/tools/snapshots.d.ts +3 -0
- package/dist/tools/snapshots.d.ts.map +1 -0
- package/dist/tools/snapshots.js +333 -0
- package/dist/tools/snapshots.js.map +1 -0
- package/dist/tools/templates.d.ts +3 -0
- package/dist/tools/templates.d.ts.map +1 -0
- package/dist/tools/templates.js +492 -0
- package/dist/tools/templates.js.map +1 -0
- package/dist/tools/types.d.ts +18 -0
- package/dist/tools/types.d.ts.map +1 -0
- package/dist/tools/types.js +2 -0
- package/dist/tools/types.js.map +1 -0
- package/dist/tools/webhooks.d.ts +3 -0
- package/dist/tools/webhooks.d.ts.map +1 -0
- package/dist/tools/webhooks.js +260 -0
- package/dist/tools/webhooks.js.map +1 -0
- package/package.json +59 -0
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { MODEL_KEY_HEADER } from '../api.js';
|
|
3
|
+
import { guarded, refused, said } from '../format.js';
|
|
4
|
+
import * as P from '../paths.js';
|
|
5
|
+
/**
|
|
6
|
+
* The platform's own agent loop, as one tool.
|
|
7
|
+
*
|
|
8
|
+
* Registered only when a model key is configured, and that is the point of the
|
|
9
|
+
* conditional: a tool a model can see is a tool it will try, and one that fails
|
|
10
|
+
* on every call with "no model key" costs a turn to discover. Absent is a
|
|
11
|
+
* clearer answer than present-and-broken.
|
|
12
|
+
*
|
|
13
|
+
* Worth having even though the caller is already a model with eyes. The outer
|
|
14
|
+
* agent pays for every screenshot in context; this route runs the pixel-level
|
|
15
|
+
* loop inside the platform on the caller's own Anthropic key and hands back a
|
|
16
|
+
* sentence. Ten clicks stop being ten images.
|
|
17
|
+
*/
|
|
18
|
+
export const registerAgent = (server, session) => {
|
|
19
|
+
if (!session.modelKey)
|
|
20
|
+
return;
|
|
21
|
+
server.registerTool('run_agent', {
|
|
22
|
+
title: 'Have the platform drive the computer',
|
|
23
|
+
description: 'Give the computer a task in plain language and let the platform drive it — screenshot, decide, click, type, repeat — until it is done. Runs on the Anthropic key this server was configured with, and bills that key for every step. Use it to delegate a long stretch of pixel work; drive with the individual tools when you want to see each frame yourself. The computer must already be running. A run is MINUTES, not seconds: it reports progress on every step so a client that sends a progressToken and sets resetTimeoutOnProgress can hold the request open, and a client that cannot should lower max_steps rather than watch its own default timeout cancel a run it is already paying for.',
|
|
24
|
+
inputSchema: {
|
|
25
|
+
computer_id: z
|
|
26
|
+
.string()
|
|
27
|
+
.optional()
|
|
28
|
+
.describe('Which computer. Defaults to the one selected with use_computer.'),
|
|
29
|
+
prompt: z.string().describe('The task, in plain language.'),
|
|
30
|
+
system: z.string().optional().describe('Standing instructions carried into the run.'),
|
|
31
|
+
max_steps: z
|
|
32
|
+
.number()
|
|
33
|
+
.int()
|
|
34
|
+
.min(1)
|
|
35
|
+
.max(100)
|
|
36
|
+
.default(20)
|
|
37
|
+
.describe('Each step is a model call plus a screenshot on your key, so this is a spending cap as much as a loop bound.'),
|
|
38
|
+
},
|
|
39
|
+
annotations: { openWorldHint: true },
|
|
40
|
+
}, ({ computer_id, prompt, system, max_steps }, extra) => guarded(async () => {
|
|
41
|
+
const id = session.resolve(computer_id);
|
|
42
|
+
const steps = [];
|
|
43
|
+
let done;
|
|
44
|
+
// The token the CLIENT sends when it wants progress, exactly as
|
|
45
|
+
// watch_build reads it. Without one there is nothing to address a
|
|
46
|
+
// progress notification to, and this falls back to logging alone.
|
|
47
|
+
const progressToken = extra._meta?.progressToken;
|
|
48
|
+
for await (const ev of session.api.sse('POST', P.computerAction(id, 'agent'), {
|
|
49
|
+
body: P.agentBody({ prompt, system, max_steps, stream: true }),
|
|
50
|
+
headers: { [MODEL_KEY_HEADER]: session.modelKey },
|
|
51
|
+
signal: extra.signal,
|
|
52
|
+
})) {
|
|
53
|
+
if (ev.event === 'step') {
|
|
54
|
+
if (!isRecord(ev.data))
|
|
55
|
+
continue;
|
|
56
|
+
const s = ev.data;
|
|
57
|
+
steps.push(`${s.n ?? steps.length + 1}. ${s.detail ?? s.action ?? 'step'}`);
|
|
58
|
+
// A PROGRESS notification, not only a logging one, for the reason
|
|
59
|
+
// watch_build sends one: `_onprogress` in the SDK's
|
|
60
|
+
// shared/protocol.js resets a pending request's timer, and
|
|
61
|
+
// `notifications/message` — what sendLoggingMessage emits — never
|
|
62
|
+
// touches it. This tool had only the logging half, so a run of the
|
|
63
|
+
// default 20 steps, each a model call plus a screenshot, sailed past
|
|
64
|
+
// the client's 60s default and was cancelled while the platform went
|
|
65
|
+
// on driving the desktop on the caller's own Anthropic key.
|
|
66
|
+
//
|
|
67
|
+
// Not sufficient on its own, and the same caveat applies here as
|
|
68
|
+
// there: protocol.js reads `options?.resetTimeoutOnProgress ?? false`,
|
|
69
|
+
// so a client that mints a token and leaves that option alone is
|
|
70
|
+
// still cancelled. What this does is make the keepalive AVAILABLE.
|
|
71
|
+
// The description says so, and max_steps is the lever for a client
|
|
72
|
+
// that cannot opt in.
|
|
73
|
+
if (progressToken !== undefined) {
|
|
74
|
+
await extra
|
|
75
|
+
.sendNotification({
|
|
76
|
+
method: 'notifications/progress',
|
|
77
|
+
params: {
|
|
78
|
+
progressToken,
|
|
79
|
+
// The step COUNT, which the SDK's ProgressSchema asks to
|
|
80
|
+
// increase every time. `max_steps` is a real total here —
|
|
81
|
+
// unlike a build's step count it is known before the first
|
|
82
|
+
// step and cannot change — so the bar means something.
|
|
83
|
+
progress: steps.length,
|
|
84
|
+
total: max_steps,
|
|
85
|
+
message: steps[steps.length - 1],
|
|
86
|
+
},
|
|
87
|
+
})
|
|
88
|
+
.catch(() => { });
|
|
89
|
+
}
|
|
90
|
+
// Told, not just collected. A run is minutes of clicking, and a tool
|
|
91
|
+
// that says nothing until it is over is one nobody watching can tell
|
|
92
|
+
// from a hang.
|
|
93
|
+
await server.server
|
|
94
|
+
.sendLoggingMessage({ level: 'info', data: steps[steps.length - 1] })
|
|
95
|
+
.catch(() => { });
|
|
96
|
+
}
|
|
97
|
+
else if (ev.event === 'done') {
|
|
98
|
+
// Stop at the terminal frame rather than waiting for EOF, as
|
|
99
|
+
// watch_build does. Waiting held a result that was already in hand
|
|
100
|
+
// until the generator ended, so a client that aborted in that window
|
|
101
|
+
// — or a stream the platform left open — turned a finished run into
|
|
102
|
+
// a CancelledError and threw the answer away.
|
|
103
|
+
//
|
|
104
|
+
// Terminal means it SAYS SO, which is watch_build's discipline
|
|
105
|
+
// (OPL-3835) applied to this stream's own vocabulary: `stop` is the
|
|
106
|
+
// field the platform always sends on a result — the AgentResult type
|
|
107
|
+
// in its lib/agent.ts requires it, and every `done` it yields carries
|
|
108
|
+
// one — and it is the field the verdict below reads. A record
|
|
109
|
+
// without it is not a result, so it is kept, in case nothing better
|
|
110
|
+
// arrives, but it does not end the loop and discard the frame that
|
|
111
|
+
// would have been the real one. A `done` that is not a record at all
|
|
112
|
+
// is skipped entirely: the null-done case the regression suite pins.
|
|
113
|
+
if (isRecord(ev.data)) {
|
|
114
|
+
done = ev.data;
|
|
115
|
+
if (typeof ev.data.stop === 'string' && ev.data.stop)
|
|
116
|
+
break;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
else if (ev.event === 'error') {
|
|
120
|
+
// A run that errored is a failure, and has to carry `isError` to
|
|
121
|
+
// say so. Prose alone leaves it indistinguishable at the protocol
|
|
122
|
+
// level from a run that worked — a caller checking whether the step
|
|
123
|
+
// succeeded would read this one as a success that happened to have
|
|
124
|
+
// a discouraging sentence in it.
|
|
125
|
+
return refused(`The run failed after ${steps.length} step(s).`, ev.data);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
if (!done) {
|
|
129
|
+
return refused(`The stream ended without a result after ${steps.length} step(s). What it did:\n${steps.join('\n')}`);
|
|
130
|
+
}
|
|
131
|
+
// `stop` is the field that matters and the one a caller most easily
|
|
132
|
+
// ignores: a run that hit max_steps ended without finishing, and
|
|
133
|
+
// treating every ending as success reports a failure as a result.
|
|
134
|
+
const stop = String(done.stop ?? 'unknown');
|
|
135
|
+
const verdict = stop === 'end_turn'
|
|
136
|
+
? 'finished'
|
|
137
|
+
: stop === 'max_steps'
|
|
138
|
+
? `RAN OUT OF STEPS after ${done.steps ?? max_steps} — the task is probably unfinished`
|
|
139
|
+
: stop === 'refusal'
|
|
140
|
+
? 'the model declined the task'
|
|
141
|
+
: `ended: ${stop}`;
|
|
142
|
+
const result = `${verdict}\n\n${String(done.text ?? '')}\n\nWhat it did:\n${steps.join('\n')}`;
|
|
143
|
+
return stop === 'end_turn' ? said(result, done) : refused(result, done);
|
|
144
|
+
}));
|
|
145
|
+
};
|
|
146
|
+
const isRecord = (value) => value !== null && typeof value === 'object' && !Array.isArray(value);
|
|
147
|
+
//# sourceMappingURL=agent.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent.js","sourceRoot":"","sources":["../../src/tools/agent.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"computers.d.ts","sourceRoot":"","sources":["../../src/tools/computers.ts"],"names":[],"mappings":"AAoBA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AA8P5C,eAAO,MAAM,iBAAiB,EAAE,SA6iC/B,CAAC"}
|