@leverageaiapps/locus 2.2.2 → 2.2.4

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.
@@ -0,0 +1,217 @@
1
+ "use strict";
2
+ /**
3
+ * Tool Definitions for PC Agent — adapted from container-agent/src/tool-defs.ts
4
+ *
5
+ * Differences from sandbox tools:
6
+ * - Removed: browser_action (no browser automation on Mac)
7
+ * - Removed: request_human_help (no VNC desktop)
8
+ * - Updated descriptions: "user's computer" instead of "sandbox"
9
+ */
10
+ Object.defineProperty(exports, "__esModule", { value: true });
11
+ exports.WEB_FETCH_SERVER_TOOL = exports.WEB_SEARCH_SERVER_TOOL = exports.PC_TOOLS = void 0;
12
+ exports.buildToolList = buildToolList;
13
+ // ─── Client-Side Tools (executed locally on user's Mac) ───────────
14
+ exports.PC_TOOLS = [
15
+ {
16
+ name: 'bash',
17
+ description: "Execute a bash command on the user's computer terminal. Has full access to installed tools, packages, and the filesystem.",
18
+ input_schema: {
19
+ type: 'object',
20
+ properties: {
21
+ command: { type: 'string', description: 'The bash command to execute' },
22
+ },
23
+ required: ['command'],
24
+ },
25
+ },
26
+ {
27
+ name: 'write_file',
28
+ description: 'Write content to a file (create or overwrite). Prefer this over bash heredoc/echo for reliability.',
29
+ input_schema: {
30
+ type: 'object',
31
+ properties: {
32
+ path: { type: 'string', description: 'Absolute file path (e.g., /Users/username/Desktop/report.html)' },
33
+ content: { type: 'string', description: 'The complete file content to write' },
34
+ },
35
+ required: ['path', 'content'],
36
+ },
37
+ },
38
+ {
39
+ name: 'read_file',
40
+ description: 'Read the contents of a file.',
41
+ input_schema: {
42
+ type: 'object',
43
+ properties: {
44
+ path: { type: 'string', description: 'Absolute file path to read' },
45
+ },
46
+ required: ['path'],
47
+ },
48
+ },
49
+ {
50
+ name: 'show_file',
51
+ description: "Send a file to the user's phone for preview/download.",
52
+ input_schema: {
53
+ type: 'object',
54
+ properties: {
55
+ path: { type: 'string', description: 'Absolute file path to show' },
56
+ },
57
+ required: ['path'],
58
+ },
59
+ },
60
+ {
61
+ name: 'search_files',
62
+ description: 'Search for files by name or pattern in a directory.',
63
+ input_schema: {
64
+ type: 'object',
65
+ properties: {
66
+ directory: { type: 'string', description: 'Directory to search in' },
67
+ pattern: { type: 'string', description: 'File name pattern (glob or regex)' },
68
+ },
69
+ required: ['directory', 'pattern'],
70
+ },
71
+ },
72
+ // ── Memory Tools ──
73
+ {
74
+ name: 'save_memory',
75
+ description: "Save information to today's daily memory log (memory/YYYY-MM-DD.md). Use for user preferences, project details, decisions, or any info that should persist.",
76
+ input_schema: {
77
+ type: 'object',
78
+ properties: {
79
+ content: { type: 'string', description: 'The information to save' },
80
+ category: { type: 'string', description: 'Memory category: "preference", "project", "workflow", "decision", "person", "general"' },
81
+ section: { type: 'string', description: 'Alias for category (backward compatible)' },
82
+ },
83
+ required: ['content'],
84
+ },
85
+ },
86
+ {
87
+ name: 'search_memory',
88
+ description: 'Search long-term memory (MEMORY.md) and daily logs by keyword matching. Returns snippets with file:line references.',
89
+ input_schema: {
90
+ type: 'object',
91
+ properties: {
92
+ query: { type: 'string', description: 'Search query (keywords)' },
93
+ category: { type: 'string', description: 'Optional: limit search to a specific category' },
94
+ max_results: { type: 'number', description: 'Max results to return (default: 5, max: 10)' },
95
+ },
96
+ required: ['query'],
97
+ },
98
+ },
99
+ {
100
+ name: 'read_memory',
101
+ description: 'Read a specific section of a memory file. Use after search_memory to get full context.',
102
+ input_schema: {
103
+ type: 'object',
104
+ properties: {
105
+ file: { type: 'string', description: 'File name: "MEMORY.md" or "2026-02-20.md"' },
106
+ from_line: { type: 'number', description: 'Starting line number (1-indexed, default: 1)' },
107
+ lines: { type: 'number', description: 'Number of lines to read (default: 50, max: 200)' },
108
+ },
109
+ required: ['file'],
110
+ },
111
+ },
112
+ {
113
+ name: 'update_memory',
114
+ description: 'Rewrite the curated long-term memory file (MEMORY.md). Provide the COMPLETE new content.',
115
+ input_schema: {
116
+ type: 'object',
117
+ properties: {
118
+ content: { type: 'string', description: 'Complete new content for MEMORY.md (replaces entire file)' },
119
+ },
120
+ required: ['content'],
121
+ },
122
+ },
123
+ // ── Schedule Tool ──
124
+ {
125
+ name: 'manage_schedule',
126
+ description: 'Manage scheduled tasks (create, list, update, delete, pause, resume).',
127
+ input_schema: {
128
+ type: 'object',
129
+ properties: {
130
+ action: { type: 'string', enum: ['create', 'list', 'update', 'delete', 'pause', 'resume'] },
131
+ job_id: { type: 'string', description: 'Job ID (for update/delete/pause/resume)' },
132
+ name: { type: 'string', description: 'Task name (for create)' },
133
+ schedule: { type: 'string', description: 'Cron expression or natural language (for create)' },
134
+ command: { type: 'string', description: 'Task instruction for the AI agent (for create)' },
135
+ notify: { type: 'boolean', description: 'Notify user on completion (default: true)' },
136
+ },
137
+ required: ['action'],
138
+ },
139
+ },
140
+ // ── Skill Tools ──
141
+ {
142
+ name: 'get_skill',
143
+ description: "Load detailed instructions for a specific skill. Call only when the user's task matches an available skill.",
144
+ input_schema: {
145
+ type: 'object',
146
+ properties: {
147
+ skill_id: { type: 'string', description: 'The skill_id to load' },
148
+ },
149
+ required: ['skill_id'],
150
+ },
151
+ },
152
+ {
153
+ name: 'create_skill',
154
+ description: 'Create a new custom skill.',
155
+ input_schema: {
156
+ type: 'object',
157
+ properties: {
158
+ skill_id: { type: 'string', description: 'Unique identifier (lowercase, hyphens)' },
159
+ name: { type: 'string', description: 'Human-readable skill name' },
160
+ description: { type: 'string', description: 'What this skill does' },
161
+ full_prompt: { type: 'string', description: 'Detailed AI instructions' },
162
+ category: { type: 'string', enum: ['productivity', 'development', 'system', 'lifestyle', 'custom'] },
163
+ },
164
+ required: ['skill_id', 'name', 'full_prompt'],
165
+ },
166
+ },
167
+ {
168
+ name: 'upload_skill_resource',
169
+ description: 'Upload a resource file (script, template, etc.) for a skill.',
170
+ input_schema: {
171
+ type: 'object',
172
+ properties: {
173
+ skill_id: { type: 'string', description: 'Which skill this resource belongs to' },
174
+ filename: { type: 'string', description: 'Resource filename' },
175
+ content: { type: 'string', description: 'File content (text)' },
176
+ content_type: { type: 'string', description: 'MIME type (default: text/plain)' },
177
+ },
178
+ required: ['skill_id', 'filename', 'content'],
179
+ },
180
+ },
181
+ {
182
+ name: 'install_skill',
183
+ description: 'Install a skill from a URL (e.g., clawhub.ai/user/skill-name).',
184
+ input_schema: {
185
+ type: 'object',
186
+ properties: {
187
+ url: { type: 'string', description: 'URL to install the skill from' },
188
+ skill_id: { type: 'string', description: 'Override skill_id (optional)' },
189
+ },
190
+ required: ['url'],
191
+ },
192
+ },
193
+ ];
194
+ // ─── Server-Side Tools (executed by Anthropic API) ────────────────
195
+ exports.WEB_SEARCH_SERVER_TOOL = {
196
+ type: 'web_search_20250305',
197
+ name: 'web_search',
198
+ max_uses: 5,
199
+ };
200
+ exports.WEB_FETCH_SERVER_TOOL = {
201
+ type: 'web_fetch_20250910',
202
+ name: 'web_fetch',
203
+ max_uses: 5,
204
+ };
205
+ /**
206
+ * Build the full tools array, excluding specified tool names.
207
+ */
208
+ function buildToolList(excludeTools = []) {
209
+ const excludeSet = new Set(excludeTools);
210
+ const clientTools = exports.PC_TOOLS.filter(t => !excludeSet.has(t.name));
211
+ return [
212
+ ...clientTools,
213
+ exports.WEB_SEARCH_SERVER_TOOL,
214
+ exports.WEB_FETCH_SERVER_TOOL,
215
+ ];
216
+ }
217
+ //# sourceMappingURL=tool-defs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tool-defs.js","sourceRoot":"","sources":["../../src/agent/tool-defs.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,80 @@
1
+ export interface Message {
2
+ role: 'user' | 'assistant';
3
+ content: string | ContentBlock[];
4
+ }
5
+ export interface ContentBlock {
6
+ type: string;
7
+ text?: string;
8
+ id?: string;
9
+ name?: string;
10
+ input?: Record<string, any>;
11
+ tool_use_id?: string;
12
+ content?: string | ContentBlock[];
13
+ is_error?: boolean;
14
+ }
15
+ export interface ToolResult {
16
+ type: 'tool_result';
17
+ tool_use_id: string;
18
+ content: string;
19
+ is_error?: boolean;
20
+ }
21
+ export interface ChatResponse {
22
+ content: ContentBlock[];
23
+ stop_reason: string;
24
+ usage: {
25
+ input_tokens: number;
26
+ output_tokens: number;
27
+ };
28
+ model: string;
29
+ }
30
+ export interface ToolDef {
31
+ name: string;
32
+ description: string;
33
+ input_schema: Record<string, any>;
34
+ }
35
+ export interface ServerTool {
36
+ type: string;
37
+ name: string;
38
+ [key: string]: any;
39
+ }
40
+ export interface AgentRunRequest {
41
+ taskId: string;
42
+ userId: string;
43
+ sandboxId: string;
44
+ message: string;
45
+ images?: string[];
46
+ model?: string;
47
+ sessionId: string;
48
+ workerUrl: string;
49
+ token: string;
50
+ enableContext?: boolean;
51
+ workingDirectory?: string;
52
+ connectionId?: string;
53
+ cronJobId?: string;
54
+ cronRunId?: string;
55
+ }
56
+ export interface EmitEventPayload {
57
+ taskId: string;
58
+ userId: string;
59
+ conversationId: string;
60
+ sequence: number;
61
+ eventType: string;
62
+ data: Record<string, any>;
63
+ }
64
+ export interface ContextResponse {
65
+ conversationHistory: Message[];
66
+ systemPrompt: string;
67
+ enabledSkills: {
68
+ skill_id: string;
69
+ name: string;
70
+ }[];
71
+ hasSkills: boolean;
72
+ }
73
+ export interface ToolExecResult {
74
+ output: string;
75
+ isError: boolean;
76
+ }
77
+ export declare const MAX_AGENT_TURNS = 50;
78
+ export declare const LOOP_TIMEOUT: number;
79
+ export declare const TOOL_OUTPUT_LIMIT = 10000;
80
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/agent/types.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,OAAO;IACtB,IAAI,EAAE,MAAM,GAAG,WAAW,CAAC;IAC3B,OAAO,EAAE,MAAM,GAAG,YAAY,EAAE,CAAC;CAClC;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAE5B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,GAAG,YAAY,EAAE,CAAC;IAClC,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,aAAa,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,YAAY,EAAE,CAAC;IACxB,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE;QAAE,YAAY,EAAE,MAAM,CAAC;QAAC,aAAa,EAAE,MAAM,CAAA;KAAE,CAAC;IACvD,KAAK,EAAE,MAAM,CAAC;CACf;AAID,MAAM,WAAW,OAAO;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;CACnC;AAED,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IAEb,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;CACpB;AAID,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAID,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,cAAc,EAAE,MAAM,CAAC;IACvB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;CAC3B;AAED,MAAM,WAAW,eAAe;IAC9B,mBAAmB,EAAE,OAAO,EAAE,CAAC;IAC/B,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IACpD,SAAS,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,OAAO,CAAC;CAClB;AAID,eAAO,MAAM,eAAe,KAAK,CAAC;AAClC,eAAO,MAAM,YAAY,QAAiB,CAAC;AAC3C,eAAO,MAAM,iBAAiB,QAAQ,CAAC"}
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ // ─── Shared Types ────────────────────────────────────────────────
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.TOOL_OUTPUT_LIMIT = exports.LOOP_TIMEOUT = exports.MAX_AGENT_TURNS = void 0;
5
+ // ─── Constants ───────────────────────────────────────────────────
6
+ exports.MAX_AGENT_TURNS = 50;
7
+ exports.LOOP_TIMEOUT = 15 * 60 * 1000; // 15 minutes
8
+ exports.TOOL_OUTPUT_LIMIT = 10000; // chars
9
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/agent/types.ts"],"names":[],"mappings":";AAAA,oEAAoE;;;AA0FpE,oEAAoE;AAEvD,QAAA,eAAe,GAAG,EAAE,CAAC;AACrB,QAAA,YAAY,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC,aAAa;AAC5C,QAAA,iBAAiB,GAAG,KAAK,CAAC,CAAC,QAAQ"}
@@ -0,0 +1,39 @@
1
+ /**
2
+ * Worker Proxy Client — Locus agent calls back to the Worker
3
+ * for D1/R2 operations, event emission, and Claude API calls.
4
+ *
5
+ * Claude API calls are proxied through the Worker so API keys
6
+ * never leave Cloudflare (keys stay in Worker env secrets).
7
+ */
8
+ import type { Message, ChatResponse, EmitEventPayload, ContextResponse } from './types';
9
+ export declare class WorkerProxy {
10
+ private workerUrl;
11
+ private token;
12
+ private taskId;
13
+ private userId;
14
+ constructor(workerUrl: string, token: string, taskId: string, userId: string);
15
+ private post;
16
+ emitEvents(events: EmitEventPayload[]): Promise<void>;
17
+ updateTaskStatus(status: 'running' | 'completed' | 'failed', errorMessage?: string): Promise<void>;
18
+ finalizeCronRun(cronRunId: string, cronJobId: string, sandboxId: string, status: 'completed' | 'failed', output?: string, error?: string): Promise<void>;
19
+ loadContext(sandboxId: string, sessionId: string, isCronTask: boolean, memoryContent?: string, recentNotes?: string, workingDirectory?: string): Promise<ContextResponse>;
20
+ saveTurn(sandboxId: string, sessionId: string, userMessage: string, assistantSummary: string): Promise<void>;
21
+ memoryOp(tool: 'backup_memory' | 'restore_memory', filePath: string, content?: string): Promise<string>;
22
+ skillOp(tool: 'get_skill' | 'create_skill' | 'upload_skill_resource', input: Record<string, any>): Promise<string>;
23
+ scheduleOp(sandboxId: string, input: Record<string, any>): Promise<string>;
24
+ uploadToR2(sandboxId: string, filePath: string, contentBase64: string, fileSize: number): Promise<{
25
+ downloadUrl: string;
26
+ }>;
27
+ claudeChat(messages: Message[], options: {
28
+ model?: string;
29
+ maxTokens?: number;
30
+ temperature?: number;
31
+ systemPrompt?: string;
32
+ tools?: any[];
33
+ toolChoice?: {
34
+ type: string;
35
+ name?: string;
36
+ };
37
+ }): Promise<ChatResponse>;
38
+ }
39
+ //# sourceMappingURL=worker-proxy.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"worker-proxy.d.ts","sourceRoot":"","sources":["../../src/agent/worker-proxy.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EACV,OAAO,EAAE,YAAY,EAAE,gBAAgB,EAAE,eAAe,EACzD,MAAM,SAAS,CAAC;AAEjB,qBAAa,WAAW;IACtB,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,MAAM,CAAS;gBAEX,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;YAQ9D,IAAI;IAqBZ,UAAU,CAAC,MAAM,EAAE,gBAAgB,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAMrD,gBAAgB,CACpB,MAAM,EAAE,SAAS,GAAG,WAAW,GAAG,QAAQ,EAC1C,YAAY,CAAC,EAAE,MAAM,GACpB,OAAO,CAAC,IAAI,CAAC;IAWV,eAAe,CACnB,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,WAAW,GAAG,QAAQ,EAC9B,MAAM,GAAE,MAAW,EACnB,KAAK,CAAC,EAAE,MAAM,GACb,OAAO,CAAC,IAAI,CAAC;IAaV,WAAW,CACf,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,OAAO,EACnB,aAAa,CAAC,EAAE,MAAM,EACtB,WAAW,CAAC,EAAE,MAAM,EACpB,gBAAgB,CAAC,EAAE,MAAM,GACxB,OAAO,CAAC,eAAe,CAAC;IAcrB,QAAQ,CACZ,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,EACjB,WAAW,EAAE,MAAM,EACnB,gBAAgB,EAAE,MAAM,GACvB,OAAO,CAAC,IAAI,CAAC;IAYV,QAAQ,CACZ,IAAI,EAAE,eAAe,GAAG,gBAAgB,EACxC,QAAQ,EAAE,MAAM,EAChB,OAAO,CAAC,EAAE,MAAM,GACf,OAAO,CAAC,MAAM,CAAC;IAYZ,OAAO,CACX,IAAI,EAAE,WAAW,GAAG,cAAc,GAAG,uBAAuB,EAC5D,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GACzB,OAAO,CAAC,MAAM,CAAC;IAWZ,UAAU,CACd,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GACzB,OAAO,CAAC,MAAM,CAAC;IAWZ,UAAU,CACd,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,EAChB,aAAa,EAAE,MAAM,EACrB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC;QAAE,WAAW,EAAE,MAAM,CAAA;KAAE,CAAC;IAY7B,UAAU,CACd,QAAQ,EAAE,OAAO,EAAE,EACnB,OAAO,EAAE;QACP,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB,KAAK,CAAC,EAAE,GAAG,EAAE,CAAC;QACd,UAAU,CAAC,EAAE;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,IAAI,CAAC,EAAE,MAAM,CAAA;SAAE,CAAC;KAC9C,GACA,OAAO,CAAC,YAAY,CAAC;CAWzB"}
@@ -0,0 +1,135 @@
1
+ "use strict";
2
+ /**
3
+ * Worker Proxy Client — Locus agent calls back to the Worker
4
+ * for D1/R2 operations, event emission, and Claude API calls.
5
+ *
6
+ * Claude API calls are proxied through the Worker so API keys
7
+ * never leave Cloudflare (keys stay in Worker env secrets).
8
+ */
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ exports.WorkerProxy = void 0;
11
+ class WorkerProxy {
12
+ constructor(workerUrl, token, taskId, userId) {
13
+ // Remove trailing slash
14
+ this.workerUrl = workerUrl.replace(/\/$/, '');
15
+ this.token = token;
16
+ this.taskId = taskId;
17
+ this.userId = userId;
18
+ }
19
+ async post(path, body) {
20
+ const url = `${this.workerUrl}/api/internal/agent${path}`;
21
+ const res = await fetch(url, {
22
+ method: 'POST',
23
+ headers: {
24
+ 'Content-Type': 'application/json',
25
+ 'Authorization': `Bearer ${this.token}`,
26
+ 'X-Task-Id': this.taskId,
27
+ 'X-User-Id': this.userId,
28
+ },
29
+ body: JSON.stringify(body),
30
+ });
31
+ if (!res.ok) {
32
+ const errText = await res.text().catch(() => '');
33
+ throw new Error(`Worker proxy ${path} failed (${res.status}): ${errText}`);
34
+ }
35
+ return res.json();
36
+ }
37
+ // ─── Event Emission ───────────────────────────────────────────
38
+ async emitEvents(events) {
39
+ await this.post('/emit-events', { events });
40
+ }
41
+ // ─── Task Status ──────────────────────────────────────────────
42
+ async updateTaskStatus(status, errorMessage) {
43
+ await this.post('/task-status', {
44
+ taskId: this.taskId,
45
+ userId: this.userId,
46
+ status,
47
+ errorMessage,
48
+ });
49
+ }
50
+ // ─── Cron Finalization ───────────────────────────────────────
51
+ async finalizeCronRun(cronRunId, cronJobId, sandboxId, status, output = '', error) {
52
+ await this.post('/finalize-cron', {
53
+ cronRunId,
54
+ cronJobId,
55
+ sandboxId,
56
+ status,
57
+ output,
58
+ error,
59
+ });
60
+ }
61
+ // ─── Context Loading ──────────────────────────────────────────
62
+ async loadContext(sandboxId, sessionId, isCronTask, memoryContent, recentNotes, workingDirectory) {
63
+ return await this.post('/context', {
64
+ userId: this.userId,
65
+ sandboxId,
66
+ sessionId,
67
+ isCronTask,
68
+ memoryContent,
69
+ recentNotes,
70
+ workingDirectory,
71
+ });
72
+ }
73
+ // ─── Conversation History ─────────────────────────────────────
74
+ async saveTurn(sandboxId, sessionId, userMessage, assistantSummary) {
75
+ await this.post('/save-turn', {
76
+ userId: this.userId,
77
+ sandboxId,
78
+ sessionId,
79
+ userMessage,
80
+ assistantSummary,
81
+ });
82
+ }
83
+ // ─── Memory Tools (R2 backup) ─────────────────────────────────
84
+ async memoryOp(tool, filePath, content) {
85
+ const result = await this.post('/memory', {
86
+ userId: this.userId,
87
+ tool,
88
+ filePath,
89
+ content,
90
+ });
91
+ return result.output || '';
92
+ }
93
+ // ─── Skill Tools (D1 + R2) ────────────────────────────────────
94
+ async skillOp(tool, input) {
95
+ const result = await this.post('/skill', {
96
+ userId: this.userId,
97
+ tool,
98
+ input,
99
+ });
100
+ return result.output || '';
101
+ }
102
+ // ─── Schedule Tool (D1) ───────────────────────────────────────
103
+ async scheduleOp(sandboxId, input) {
104
+ const result = await this.post('/schedule', {
105
+ userId: this.userId,
106
+ sandboxId,
107
+ input,
108
+ });
109
+ return result.output || '';
110
+ }
111
+ // ─── R2 File Upload ───────────────────────────────────────────
112
+ async uploadToR2(sandboxId, filePath, contentBase64, fileSize) {
113
+ return await this.post('/r2-upload', {
114
+ userId: this.userId,
115
+ sandboxId,
116
+ filePath,
117
+ contentBase64,
118
+ fileSize,
119
+ });
120
+ }
121
+ // ─── Claude Chat Proxy (API keys stay on Cloudflare) ──────────
122
+ async claudeChat(messages, options) {
123
+ return await this.post('/claude-chat', {
124
+ messages: messages.map(m => ({ role: m.role, content: m.content })),
125
+ model: options.model,
126
+ maxTokens: options.maxTokens,
127
+ temperature: options.temperature,
128
+ systemPrompt: options.systemPrompt,
129
+ tools: options.tools,
130
+ toolChoice: options.toolChoice,
131
+ });
132
+ }
133
+ }
134
+ exports.WorkerProxy = WorkerProxy;
135
+ //# sourceMappingURL=worker-proxy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"worker-proxy.js","sourceRoot":"","sources":["../../src/agent/worker-proxy.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"vortex-tunnel.d.ts","sourceRoot":"","sources":["../src/vortex-tunnel.ts"],"names":[],"mappings":"AAsEA;;;GAGG;AACH,wBAAgB,WAAW,CAAC,IAAI,GAAE,MAAa,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAkFlF;AAqlCD,wBAAgB,UAAU,IAAI,IAAI,CAgBjC;AAED,wBAAgB,YAAY,IAAI,MAAM,GAAG,IAAI,CAE5C;AAED,wBAAgB,eAAe,IAAI,OAAO,CAEzC"}
1
+ {"version":3,"file":"vortex-tunnel.d.ts","sourceRoot":"","sources":["../src/vortex-tunnel.ts"],"names":[],"mappings":"AAwEA;;;GAGG;AACH,wBAAgB,WAAW,CAAC,IAAI,GAAE,MAAa,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAkFlF;AA4pCD,wBAAgB,UAAU,IAAI,IAAI,CAgBjC;AAED,wBAAgB,YAAY,IAAI,MAAM,GAAG,IAAI,CAE5C;AAED,wBAAgB,eAAe,IAAI,OAAO,CAEzC"}
@@ -43,6 +43,7 @@ exports.isTunnelRunning = isTunnelRunning;
43
43
  const axios_1 = __importDefault(require("axios"));
44
44
  const ws_1 = __importDefault(require("ws"));
45
45
  const http = __importStar(require("http"));
46
+ const agent_loop_1 = require("./agent/agent-loop");
46
47
  let tunnelWs = null;
47
48
  let tunnelUrl = null;
48
49
  let sessionId = null;
@@ -319,6 +320,17 @@ function handleGatewayMessage(msg) {
319
320
  // Gateway asking us to cancel a task
320
321
  handleTaskCancel(msg.task_id);
321
322
  break;
323
+ // ============== Agent Protocol ==============
324
+ case 'agent_cancel':
325
+ // Cancel running agent task
326
+ console.log(` [Agent] Received agent_cancel`);
327
+ (0, agent_loop_1.cancelCurrentTask)();
328
+ break;
329
+ case 'agent_continue':
330
+ // Inject user message into running agent
331
+ console.log(` [Agent] Received agent_continue: ${(msg.message || '').substring(0, 50)}...`);
332
+ (0, agent_loop_1.injectUserMessage)(msg.message || '', msg.images);
333
+ break;
322
334
  default:
323
335
  // Forward any other message to local server (v2 protocol - direct relay)
324
336
  // This handles input, resize, ping, etc. from browser
@@ -336,7 +348,19 @@ function handleGatewayMessage(msg) {
336
348
  */
337
349
  async function handleTaskExecute(msg) {
338
350
  const { task_id, task_type, payload } = msg;
339
- if (currentTask && !currentTask.cancelled) {
351
+ // run_agent tasks run independently — don't occupy currentTask slot
352
+ if (task_type === 'run_agent') {
353
+ if ((0, agent_loop_1.isRunning)()) {
354
+ console.warn(` [Agent] Agent already running, rejecting new run_agent`);
355
+ sendToGateway({
356
+ type: 'task_error',
357
+ task_id,
358
+ error: 'Agent is already running a task'
359
+ });
360
+ return;
361
+ }
362
+ }
363
+ else if (currentTask && !currentTask.cancelled) {
340
364
  // Already executing a task, shouldn't happen if gateway queues properly
341
365
  console.error(` [Task] Error: Already executing task ${currentTask.id}`);
342
366
  sendToGateway({
@@ -347,14 +371,17 @@ async function handleTaskExecute(msg) {
347
371
  return;
348
372
  }
349
373
  console.log(` [Task] Executing task ${task_id} (${task_type})`);
350
- currentTask = {
351
- id: task_id,
352
- type: task_type,
353
- payload,
354
- startTime: Date.now(),
355
- accumulatedOutput: '',
356
- cancelled: false
357
- };
374
+ // Only set currentTask for non-agent tasks
375
+ if (task_type !== 'run_agent') {
376
+ currentTask = {
377
+ id: task_id,
378
+ type: task_type,
379
+ payload,
380
+ startTime: Date.now(),
381
+ accumulatedOutput: '',
382
+ cancelled: false
383
+ };
384
+ }
358
385
  try {
359
386
  switch (task_type) {
360
387
  case 'exec':
@@ -372,6 +399,18 @@ async function handleTaskExecute(msg) {
372
399
  case 'list_directory':
373
400
  await executeListDirectoryTask(task_id, payload);
374
401
  break;
402
+ case 'run_agent':
403
+ // Fire-and-forget: agent loop runs async, reports via WorkerProxy HTTP
404
+ executeRunAgentTask(task_id, payload);
405
+ // Immediately reply so the tunnel task queue is freed
406
+ sendToGateway({
407
+ type: 'task_complete',
408
+ task_id,
409
+ success: true,
410
+ output: 'Agent started'
411
+ });
412
+ // Don't set currentTask — agent runs independently
413
+ return;
375
414
  default:
376
415
  throw new Error(`Unknown task type: ${task_type}`);
377
416
  }
@@ -410,6 +449,35 @@ function handleTaskCancel(taskId) {
410
449
  }
411
450
  }
412
451
  }
452
+ /**
453
+ * Execute agent loop task (fire-and-forget)
454
+ * The agent loop runs async and reports progress via WorkerProxy HTTP callbacks.
455
+ */
456
+ function executeRunAgentTask(taskId, payload) {
457
+ const req = {
458
+ taskId: payload.taskId || taskId,
459
+ userId: payload.userId || '',
460
+ sandboxId: payload.connectionId || payload.sessionId || '',
461
+ message: payload.message || '',
462
+ images: payload.images,
463
+ model: payload.model,
464
+ sessionId: payload.sessionId || '',
465
+ workerUrl: payload.workerUrl || '',
466
+ token: payload.token || '',
467
+ enableContext: payload.enableContext !== false,
468
+ workingDirectory: payload.workingDirectory,
469
+ connectionId: payload.connectionId,
470
+ cronJobId: payload.cronJobId,
471
+ cronRunId: payload.cronRunId,
472
+ };
473
+ console.log(` [Agent] Starting agent loop for task ${req.taskId}, user=${req.userId}, session=${req.sessionId}`);
474
+ // Fire and forget — agent loop manages its own lifecycle
475
+ (0, agent_loop_1.runAgentLoop)(req).then(() => {
476
+ console.log(` [Agent] Agent loop completed for task ${req.taskId}`);
477
+ }).catch((err) => {
478
+ console.error(` [Agent] Agent loop failed for task ${req.taskId}: ${err.message}`);
479
+ });
480
+ }
413
481
  /**
414
482
  * Execute a shell command task
415
483
  */