@phnx-labs/agents-cli 1.22.102 → 1.22.104
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/CHANGELOG.md +31 -0
- package/README.md +1 -1
- package/dist/bootstrap.js +15 -0
- package/dist/commands/accounts.js +2 -2
- package/dist/commands/computer.d.ts +100 -79
- package/dist/commands/computer.js +290 -830
- package/dist/commands/setup-computer.js +20 -1
- package/dist/commands/setup-secrets.d.ts +2 -2
- package/dist/commands/setup-secrets.js +1 -1
- package/dist/commands/view.js +4 -6
- package/dist/lib/account-catalog.d.ts +22 -1
- package/dist/lib/account-catalog.js +72 -38
- package/dist/lib/accounting/usage.js +18 -14
- package/dist/lib/agent-spec/agents.d.ts +1 -0
- package/dist/lib/agent-spec/agents.js +1 -1
- package/dist/lib/browser/drivers/ssh.js +1 -1
- package/dist/lib/computer/context.d.ts +83 -0
- package/dist/lib/computer/context.js +91 -0
- package/dist/lib/computer/policy.d.ts +46 -0
- package/dist/lib/computer/policy.js +160 -0
- package/dist/lib/computer/record.d.ts +38 -0
- package/dist/lib/computer/record.js +86 -0
- package/dist/lib/computer/sessions-list.js +6 -6
- package/dist/lib/computer-client.d.ts +150 -0
- package/dist/lib/computer-client.js +222 -0
- package/dist/lib/exec.js +35 -1
- package/dist/lib/harness/adapters/claude.d.ts +37 -0
- package/dist/lib/harness/adapters/claude.js +69 -0
- package/dist/lib/helper-download.d.ts +1 -1
- package/dist/lib/helper-download.js +1 -1
- package/dist/lib/helper-versions.d.ts +9 -4
- package/dist/lib/helper-versions.js +9 -9
- package/dist/lib/installations/shims.js +8 -4
- package/dist/lib/menubar/download-menubar.d.ts +2 -1
- package/dist/lib/menubar/download-menubar.js +2 -1
- package/dist/lib/menubar/install-menubar.d.ts +56 -0
- package/dist/lib/menubar/install-menubar.js +133 -17
- package/dist/lib/menubar/resolve-version.d.ts +82 -0
- package/dist/lib/menubar/resolve-version.js +133 -0
- package/dist/lib/profiles.js +13 -2
- package/dist/lib/secrets-client.d.ts +23 -3
- package/dist/lib/secrets-client.js +57 -57
- package/dist/lib/self-heal/checks/menubar-helper.d.ts +2 -0
- package/dist/lib/self-heal/checks/menubar-helper.js +21 -0
- package/dist/lib/self-heal/registry.js +3 -0
- package/dist/lib/self-heal/types.d.ts +1 -1
- package/dist/lib/session/db.js +1 -1
- package/dist/lib/sha256-asset.d.ts +2 -1
- package/dist/lib/sha256-asset.js +2 -1
- package/dist/lib/ssh-tunnel.d.ts +61 -0
- package/dist/lib/ssh-tunnel.js +105 -0
- package/dist/lib/summarizer/summarize.d.ts +2 -2
- package/dist/lib/summarizer/summarize.js +10 -3
- package/package.json +2 -3
- package/dist/commands/computer-actions.d.ts +0 -55
- package/dist/commands/computer-actions.js +0 -594
- package/dist/computer.d.ts +0 -2
- package/dist/computer.js +0 -7
- package/dist/lib/computer/actions.d.ts +0 -36
- package/dist/lib/computer/actions.js +0 -162
- package/dist/lib/computer/computer-rpc.d.ts +0 -39
- package/dist/lib/computer/computer-rpc.js +0 -447
- package/dist/lib/computer/des.d.ts +0 -1
- package/dist/lib/computer/des.js +0 -114
- package/dist/lib/computer/dispatch.d.ts +0 -10
- package/dist/lib/computer/dispatch.js +0 -133
- package/dist/lib/computer/download.d.ts +0 -54
- package/dist/lib/computer/download.js +0 -83
- package/dist/lib/computer/loop.d.ts +0 -62
- package/dist/lib/computer/loop.js +0 -98
- package/dist/lib/computer/model.d.ts +0 -44
- package/dist/lib/computer/model.js +0 -157
- package/dist/lib/computer/rfb-client.d.ts +0 -53
- package/dist/lib/computer/rfb-client.js +0 -562
- package/dist/lib/computer/ssh-tunnel.d.ts +0 -189
- package/dist/lib/computer/ssh-tunnel.js +0 -584
|
@@ -1,157 +0,0 @@
|
|
|
1
|
-
// Default reasoning model for the `computer run` loop.
|
|
2
|
-
//
|
|
3
|
-
// This is a BOUNDARY, not loop logic. It turns the loop's LoopState into an
|
|
4
|
-
// Anthropic Messages API request (tool use), sends it to the Claude API by
|
|
5
|
-
// default OR to a configurable base URL (Ollama / vLLM / LiteLLM serving the
|
|
6
|
-
// Anthropic wire shape) for local/offline parity, and parses the reply back
|
|
7
|
-
// into a ModelDecision the loop can act on.
|
|
8
|
-
//
|
|
9
|
-
// The loop (loop.ts) never imports this — it takes a ModelResponder callback,
|
|
10
|
-
// so the unit tests inject a scripted fake instead of ever hitting a network.
|
|
11
|
-
const TARGET_PROPS = {
|
|
12
|
-
bundle: { type: 'string', description: 'Bundle id of the target app (default: frontmost allow-listed app)' },
|
|
13
|
-
pid: { type: 'number', description: 'Target pid (overrides bundle)' },
|
|
14
|
-
};
|
|
15
|
-
export const COMPUTER_TOOLS = [
|
|
16
|
-
{ name: 'apps', description: 'List allow-listed apps currently running.', input_schema: { type: 'object', properties: {} } },
|
|
17
|
-
{
|
|
18
|
-
name: 'describe',
|
|
19
|
-
description: 'Dump the accessibility tree of the target app. Element ids feed click/type via id. If the tree is opaque the loop auto-captures a screenshot for you.',
|
|
20
|
-
input_schema: { type: 'object', properties: { ...TARGET_PROPS, depth: { type: 'number' } } },
|
|
21
|
-
},
|
|
22
|
-
{
|
|
23
|
-
name: 'screenshot',
|
|
24
|
-
description: 'Capture the target app window as an image (the vision path — use coordinate clicks off it).',
|
|
25
|
-
input_schema: { type: 'object', properties: { ...TARGET_PROPS } },
|
|
26
|
-
},
|
|
27
|
-
{
|
|
28
|
-
name: 'get-text',
|
|
29
|
-
description: 'Extract visible text from the target app (or a subtree via id).',
|
|
30
|
-
input_schema: { type: 'object', properties: { ...TARGET_PROPS, id: { type: 'string' } } },
|
|
31
|
-
},
|
|
32
|
-
{
|
|
33
|
-
name: 'click',
|
|
34
|
-
description: 'Click an element (id from describe) or a screen coordinate (x,y). Use x,y after a vision screenshot.',
|
|
35
|
-
input_schema: { type: 'object', properties: { ...TARGET_PROPS, id: { type: 'string' }, x: { type: 'number' }, y: { type: 'number' } } },
|
|
36
|
-
},
|
|
37
|
-
{
|
|
38
|
-
name: 'type',
|
|
39
|
-
description: 'Set a field value (id) or paste at a coordinate. Set commit=true to submit.',
|
|
40
|
-
input_schema: { type: 'object', properties: { ...TARGET_PROPS, id: { type: 'string' }, x: { type: 'number' }, y: { type: 'number' }, text: { type: 'string' }, commit: { type: 'boolean' } }, required: ['text'] },
|
|
41
|
-
},
|
|
42
|
-
{
|
|
43
|
-
name: 'type-text',
|
|
44
|
-
description: 'Type a unicode string into the focused field. Focus it first with click or focus.',
|
|
45
|
-
input_schema: { type: 'object', properties: { ...TARGET_PROPS, text: { type: 'string' }, commit: { type: 'boolean' } }, required: ['text'] },
|
|
46
|
-
},
|
|
47
|
-
{
|
|
48
|
-
name: 'key',
|
|
49
|
-
description: 'Send a key chord, e.g. "cmd+s", "enter", "esc".',
|
|
50
|
-
input_schema: { type: 'object', properties: { ...TARGET_PROPS, keys: { type: 'string' } }, required: ['keys'] },
|
|
51
|
-
},
|
|
52
|
-
{
|
|
53
|
-
name: 'launch',
|
|
54
|
-
description: 'Launch an app by bundle id, path, or name.',
|
|
55
|
-
input_schema: { type: 'object', properties: { bundle: { type: 'string' }, path: { type: 'string' }, name: { type: 'string' } } },
|
|
56
|
-
},
|
|
57
|
-
{
|
|
58
|
-
name: 'wait',
|
|
59
|
-
description: 'Wait for a duration (ms) or for an element to appear.',
|
|
60
|
-
input_schema: { type: 'object', properties: { ...TARGET_PROPS, duration: { type: 'number' }, id: { type: 'string' }, role: { type: 'string' }, label: { type: 'string' } } },
|
|
61
|
-
},
|
|
62
|
-
];
|
|
63
|
-
export const DEFAULT_CLAUDE_BASE_URL = 'https://api.anthropic.com';
|
|
64
|
-
export const DEFAULT_CLAUDE_MODEL = 'claude-sonnet-4-6';
|
|
65
|
-
export const ANTHROPIC_VERSION = '2023-06-01';
|
|
66
|
-
// Resolve the API key: explicit config, then the standard Anthropic env var,
|
|
67
|
-
// then a computer-run-specific override. A local Anthropic-shaped endpoint
|
|
68
|
-
// (Ollama/vLLM/LiteLLM) usually ignores the key, so an empty key is allowed
|
|
69
|
-
// when a non-default base URL is set.
|
|
70
|
-
export function resolveApiKey(config, env = process.env) {
|
|
71
|
-
return config.apiKey || env.AGENTS_COMPUTER_API_KEY || env.ANTHROPIC_API_KEY || '';
|
|
72
|
-
}
|
|
73
|
-
// Build the system prompt. In vision mode we steer the model onto coordinate
|
|
74
|
-
// clicks off screenshots, because element ids from an opaque tree are useless.
|
|
75
|
-
export function buildSystemPrompt(state) {
|
|
76
|
-
const lines = [
|
|
77
|
-
'You are driving a macOS desktop through accessibility + vision tools to accomplish a task.',
|
|
78
|
-
'Loop: observe (describe / screenshot / get-text), act (click / type / key), then verify the result before the next step.',
|
|
79
|
-
'Prefer element ids from describe. When you are confident the task is complete, stop calling tools and reply with a short completion summary.',
|
|
80
|
-
`Task: ${state.task}`,
|
|
81
|
-
];
|
|
82
|
-
if (state.visionMode) {
|
|
83
|
-
lines.push('NOTE: the accessibility tree for the current surface is opaque (WebView / canvas). Work from the screenshot and click by x,y coordinates instead of element ids.');
|
|
84
|
-
}
|
|
85
|
-
return lines.join('\n');
|
|
86
|
-
}
|
|
87
|
-
// Reconstruct the Anthropic message array from the loop transcript. We rebuild
|
|
88
|
-
// from scratch each turn (the loop holds canonical state), synthesizing stable
|
|
89
|
-
// tool_use ids per step so each tool_result pairs with its call.
|
|
90
|
-
export function buildMessages(state) {
|
|
91
|
-
const messages = [
|
|
92
|
-
{ role: 'user', content: [{ type: 'text', text: `Begin. Task: ${state.task}` }] },
|
|
93
|
-
];
|
|
94
|
-
state.steps.forEach((step, i) => {
|
|
95
|
-
const id = `call_${i}`;
|
|
96
|
-
messages.push({ role: 'assistant', content: [{ type: 'tool_use', id, name: step.call.name, input: step.call.input }] });
|
|
97
|
-
const summary = step.result.ok
|
|
98
|
-
? JSON.stringify(step.result.result ?? {}).slice(0, 4000)
|
|
99
|
-
: `error: ${step.result.error ?? 'unknown'}`;
|
|
100
|
-
const note = step.visionFallback ? ' [ax tree opaque — auto-captured screenshot follows; use coordinate clicks]' : '';
|
|
101
|
-
messages.push({ role: 'user', content: [{ type: 'tool_result', tool_use_id: id, content: summary + note }] });
|
|
102
|
-
});
|
|
103
|
-
return messages;
|
|
104
|
-
}
|
|
105
|
-
// Parse the Anthropic response body into a ModelDecision. tool_use blocks
|
|
106
|
-
// become tool calls; a reply with no tool calls is treated as the model
|
|
107
|
-
// finishing, with its text as the summary.
|
|
108
|
-
export function parseDecision(body) {
|
|
109
|
-
const content = body.content;
|
|
110
|
-
const blocks = Array.isArray(content) ? content : [];
|
|
111
|
-
const toolCalls = [];
|
|
112
|
-
const texts = [];
|
|
113
|
-
for (const block of blocks) {
|
|
114
|
-
const b = block;
|
|
115
|
-
if (b.type === 'tool_use' && typeof b.name === 'string') {
|
|
116
|
-
toolCalls.push({ name: b.name, input: b.input ?? {} });
|
|
117
|
-
}
|
|
118
|
-
else if (b.type === 'text' && typeof b.text === 'string') {
|
|
119
|
-
texts.push(b.text);
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
if (toolCalls.length === 0) {
|
|
123
|
-
return { toolCalls: [], done: { text: texts.join('\n').trim() || 'no further action' } };
|
|
124
|
-
}
|
|
125
|
-
return { toolCalls };
|
|
126
|
-
}
|
|
127
|
-
// The default responder: one Anthropic Messages call per turn.
|
|
128
|
-
export function makeClaudeResponder(config = {}) {
|
|
129
|
-
const baseUrl = (config.baseUrl || DEFAULT_CLAUDE_BASE_URL).replace(/\/+$/, '');
|
|
130
|
-
const model = config.model || DEFAULT_CLAUDE_MODEL;
|
|
131
|
-
const maxTokens = config.maxTokens ?? 1024;
|
|
132
|
-
const doFetch = config.fetchImpl ?? fetch;
|
|
133
|
-
const apiKey = resolveApiKey(config);
|
|
134
|
-
return async (state) => {
|
|
135
|
-
const res = await doFetch(`${baseUrl}/v1/messages`, {
|
|
136
|
-
method: 'POST',
|
|
137
|
-
headers: {
|
|
138
|
-
'content-type': 'application/json',
|
|
139
|
-
'x-api-key': apiKey,
|
|
140
|
-
'anthropic-version': ANTHROPIC_VERSION,
|
|
141
|
-
},
|
|
142
|
-
body: JSON.stringify({
|
|
143
|
-
model,
|
|
144
|
-
max_tokens: maxTokens,
|
|
145
|
-
system: buildSystemPrompt(state),
|
|
146
|
-
tools: COMPUTER_TOOLS,
|
|
147
|
-
messages: buildMessages(state),
|
|
148
|
-
}),
|
|
149
|
-
});
|
|
150
|
-
if (!res.ok) {
|
|
151
|
-
const text = await res.text().catch(() => '');
|
|
152
|
-
throw new Error(`model request failed: ${res.status} ${res.statusText} ${text.slice(0, 500)}`);
|
|
153
|
-
}
|
|
154
|
-
const body = await res.json();
|
|
155
|
-
return parseDecision(body);
|
|
156
|
-
};
|
|
157
|
-
}
|
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
import type { ComputerClient, RPCResponse } from './computer-rpc.js';
|
|
2
|
-
export declare function mirrorByte(b: number): number;
|
|
3
|
-
export declare function vncAuthResponse(challenge: Buffer, password: string): Buffer;
|
|
4
|
-
export declare function buildPixelFormat(): Buffer;
|
|
5
|
-
export declare function encodeSetPixelFormat(pf: Buffer): Buffer;
|
|
6
|
-
export declare function encodeSetEncodings(encodings: number[]): Buffer;
|
|
7
|
-
export declare function encodeFbUpdateRequest(incremental: boolean, x: number, y: number, w: number, h: number): Buffer;
|
|
8
|
-
export declare function encodePointerEvent(buttonMask: number, x: number, y: number): Buffer;
|
|
9
|
-
export declare function encodeKeyEvent(down: boolean, keysym: number): Buffer;
|
|
10
|
-
export declare function keysymForChar(ch: string): number;
|
|
11
|
-
export declare function keysymForKeyName(name: string): number | null;
|
|
12
|
-
export declare function parseKeyCombo(combo: string): {
|
|
13
|
-
modifiers: number[];
|
|
14
|
-
key: number;
|
|
15
|
-
};
|
|
16
|
-
export declare function encodePng(rgb: Buffer, width: number, height: number): Buffer;
|
|
17
|
-
export interface ServerInit {
|
|
18
|
-
width: number;
|
|
19
|
-
height: number;
|
|
20
|
-
name: string;
|
|
21
|
-
}
|
|
22
|
-
export declare function scrollButtonsFor(dx: number, dy: number): {
|
|
23
|
-
vButton: number;
|
|
24
|
-
hButton: number;
|
|
25
|
-
};
|
|
26
|
-
export declare const MAX_RFB_STRING_LEN: number;
|
|
27
|
-
export declare function parseVncEndpoint(raw: string | undefined): {
|
|
28
|
-
host: string;
|
|
29
|
-
port: number;
|
|
30
|
-
} | null;
|
|
31
|
-
export declare class RfbClient implements ComputerClient {
|
|
32
|
-
private host;
|
|
33
|
-
private port;
|
|
34
|
-
private password;
|
|
35
|
-
private sock;
|
|
36
|
-
private reader;
|
|
37
|
-
private ready;
|
|
38
|
-
private info;
|
|
39
|
-
private closed;
|
|
40
|
-
constructor(host: string, port: number, password: string);
|
|
41
|
-
private write;
|
|
42
|
-
private readLenString;
|
|
43
|
-
private handshake;
|
|
44
|
-
private teardown;
|
|
45
|
-
private withTimeout;
|
|
46
|
-
private captureScreen;
|
|
47
|
-
private sendClick;
|
|
48
|
-
private sendScroll;
|
|
49
|
-
private typeText;
|
|
50
|
-
private pressCombo;
|
|
51
|
-
call(method: string, params?: Record<string, unknown>): Promise<RPCResponse>;
|
|
52
|
-
close(): Promise<void>;
|
|
53
|
-
}
|