@workermill/agent 0.8.8 → 0.8.10
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 +6 -5
- package/dist/cli.js +23 -64
- package/dist/index.js +15 -123
- package/package.json +3 -2
- package/dist/ai-sdk-generate.d.ts +0 -33
- package/dist/ai-sdk-generate.js +0 -160
- package/dist/api.d.ts +0 -13
- package/dist/api.js +0 -29
- package/dist/cli.d.ts +0 -8
- package/dist/commands/logs.d.ts +0 -9
- package/dist/commands/logs.js +0 -52
- package/dist/commands/pull.d.ts +0 -4
- package/dist/commands/pull.js +0 -35
- package/dist/commands/setup.d.ts +0 -11
- package/dist/commands/setup.js +0 -412
- package/dist/commands/start.d.ts +0 -11
- package/dist/commands/start.js +0 -152
- package/dist/commands/status.d.ts +0 -6
- package/dist/commands/status.js +0 -86
- package/dist/commands/stop.d.ts +0 -6
- package/dist/commands/stop.js +0 -61
- package/dist/commands/update.d.ts +0 -1
- package/dist/commands/update.js +0 -20
- package/dist/config.d.ts +0 -77
- package/dist/config.js +0 -286
- package/dist/index.d.ts +0 -14
- package/dist/plan-validator.d.ts +0 -104
- package/dist/plan-validator.js +0 -436
- package/dist/planner.d.ts +0 -40
- package/dist/planner.js +0 -792
- package/dist/poller.d.ts +0 -20
- package/dist/poller.js +0 -346
- package/dist/providers.d.ts +0 -18
- package/dist/providers.js +0 -118
- package/dist/spawner.d.ts +0 -116
- package/dist/spawner.js +0 -603
- package/dist/updater.d.ts +0 -8
- package/dist/updater.js +0 -40
- package/dist/version.d.ts +0 -1
- package/dist/version.js +0 -4
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* AI SDK Text Generation with Tool Support
|
|
3
|
-
*
|
|
4
|
-
* Wraps the Vercel AI SDK to provide tool-enabled text generation for
|
|
5
|
-
* non-Anthropic providers (OpenAI, Google, Ollama). Anthropic planning
|
|
6
|
-
* still uses Claude CLI for tool access (battle-tested, OAuth auth).
|
|
7
|
-
*
|
|
8
|
-
* Tools: glob (file search), read_file (file reading), grep (content search).
|
|
9
|
-
* These match the tools Claude CLI exposes to analysts.
|
|
10
|
-
*/
|
|
11
|
-
import type { AIProvider } from "./providers.js";
|
|
12
|
-
export interface GenerateWithToolsOptions {
|
|
13
|
-
provider: AIProvider;
|
|
14
|
-
model: string;
|
|
15
|
-
apiKey: string;
|
|
16
|
-
prompt: string;
|
|
17
|
-
systemPrompt?: string;
|
|
18
|
-
workingDir?: string;
|
|
19
|
-
maxTokens?: number;
|
|
20
|
-
temperature?: number;
|
|
21
|
-
timeoutMs?: number;
|
|
22
|
-
maxSteps?: number;
|
|
23
|
-
/** Enable tool use (glob, read_file, grep). Default: true */
|
|
24
|
-
enableTools?: boolean;
|
|
25
|
-
}
|
|
26
|
-
/**
|
|
27
|
-
* Generate text using the Vercel AI SDK with optional tool support.
|
|
28
|
-
*
|
|
29
|
-
* For providers that support tool calling (OpenAI, Google, Anthropic),
|
|
30
|
-
* the model can use glob/read_file/grep to explore a cloned repo.
|
|
31
|
-
* maxSteps controls how many tool call rounds are allowed.
|
|
32
|
-
*/
|
|
33
|
-
export declare function generateTextWithTools(options: GenerateWithToolsOptions): Promise<string>;
|
package/dist/ai-sdk-generate.js
DELETED
|
@@ -1,160 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* AI SDK Text Generation with Tool Support
|
|
3
|
-
*
|
|
4
|
-
* Wraps the Vercel AI SDK to provide tool-enabled text generation for
|
|
5
|
-
* non-Anthropic providers (OpenAI, Google, Ollama). Anthropic planning
|
|
6
|
-
* still uses Claude CLI for tool access (battle-tested, OAuth auth).
|
|
7
|
-
*
|
|
8
|
-
* Tools: glob (file search), read_file (file reading), grep (content search).
|
|
9
|
-
* These match the tools Claude CLI exposes to analysts.
|
|
10
|
-
*/
|
|
11
|
-
import { generateText as aiGenerateText, tool, stepCountIs } from "ai";
|
|
12
|
-
import { createOpenAI } from "@ai-sdk/openai";
|
|
13
|
-
import { createAnthropic } from "@ai-sdk/anthropic";
|
|
14
|
-
import { createGoogleGenerativeAI } from "@ai-sdk/google";
|
|
15
|
-
import { z } from "zod";
|
|
16
|
-
import { execSync } from "child_process";
|
|
17
|
-
import { readFileSync, existsSync } from "fs";
|
|
18
|
-
/**
|
|
19
|
-
* Create the AI SDK model instance for a given provider.
|
|
20
|
-
*/
|
|
21
|
-
function createModel(provider, model, apiKey) {
|
|
22
|
-
switch (provider) {
|
|
23
|
-
case "anthropic": {
|
|
24
|
-
const anthropic = createAnthropic({ apiKey });
|
|
25
|
-
return anthropic(model);
|
|
26
|
-
}
|
|
27
|
-
case "openai": {
|
|
28
|
-
const openai = createOpenAI({ apiKey });
|
|
29
|
-
return openai(model);
|
|
30
|
-
}
|
|
31
|
-
case "google": {
|
|
32
|
-
const google = createGoogleGenerativeAI({ apiKey });
|
|
33
|
-
return google(model);
|
|
34
|
-
}
|
|
35
|
-
case "ollama": {
|
|
36
|
-
// Ollama uses OpenAI-compatible API
|
|
37
|
-
const ollama = createOpenAI({
|
|
38
|
-
baseURL: apiKey || "http://localhost:11434/v1",
|
|
39
|
-
apiKey: "ollama", // Ollama doesn't need a real key
|
|
40
|
-
});
|
|
41
|
-
return ollama(model);
|
|
42
|
-
}
|
|
43
|
-
default:
|
|
44
|
-
throw new Error(`Unsupported AI provider: ${provider}`);
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
// Zod schemas for tool inputs
|
|
48
|
-
const globSchema = z.object({
|
|
49
|
-
pattern: z
|
|
50
|
-
.string()
|
|
51
|
-
.describe("Glob pattern like '**/*.ts', 'src/**/*.js', 'package.json'"),
|
|
52
|
-
});
|
|
53
|
-
const readFileSchema = z.object({
|
|
54
|
-
path: z.string().describe("File path relative to the working directory"),
|
|
55
|
-
limit: z
|
|
56
|
-
.number()
|
|
57
|
-
.optional()
|
|
58
|
-
.describe("Max number of lines to read (default: 500)"),
|
|
59
|
-
});
|
|
60
|
-
const grepSchema = z.object({
|
|
61
|
-
pattern: z.string().describe("Search pattern (regex supported)"),
|
|
62
|
-
glob: z
|
|
63
|
-
.string()
|
|
64
|
-
.optional()
|
|
65
|
-
.describe("File glob to filter (e.g. '*.ts', '*.py')"),
|
|
66
|
-
});
|
|
67
|
-
/**
|
|
68
|
-
* Build filesystem tools scoped to a working directory.
|
|
69
|
-
* These are the same tools Claude CLI exposes (Glob, Read, Grep).
|
|
70
|
-
*/
|
|
71
|
-
function buildTools(workingDir) {
|
|
72
|
-
return {
|
|
73
|
-
glob: tool({
|
|
74
|
-
description: "Find files matching a glob pattern. Returns file paths relative to the working directory.",
|
|
75
|
-
inputSchema: globSchema,
|
|
76
|
-
execute: async (input) => {
|
|
77
|
-
try {
|
|
78
|
-
// Use find as a cross-platform glob (fast-glob not available)
|
|
79
|
-
const result = execSync(`find . -path './.git' -prune -o -path './node_modules' -prune -o -name '${input.pattern.replace(/\*\*/g, "*")}' -print 2>/dev/null | head -200`, { cwd: workingDir, encoding: "utf-8", timeout: 15000 }).trim();
|
|
80
|
-
if (!result) {
|
|
81
|
-
// Try with a broader approach for ** patterns
|
|
82
|
-
const broader = execSync(`find . -path './.git' -prune -o -path './node_modules' -prune -o -type f -print 2>/dev/null | head -500`, { cwd: workingDir, encoding: "utf-8", timeout: 15000 }).trim();
|
|
83
|
-
return broader || "No files found";
|
|
84
|
-
}
|
|
85
|
-
return result;
|
|
86
|
-
}
|
|
87
|
-
catch {
|
|
88
|
-
return "Error running glob search";
|
|
89
|
-
}
|
|
90
|
-
},
|
|
91
|
-
}),
|
|
92
|
-
read_file: tool({
|
|
93
|
-
description: "Read the contents of a file. Returns the file text.",
|
|
94
|
-
inputSchema: readFileSchema,
|
|
95
|
-
execute: async (input) => {
|
|
96
|
-
try {
|
|
97
|
-
const fullPath = `${workingDir}/${input.path}`.replace(/\/\//g, "/");
|
|
98
|
-
if (!existsSync(fullPath)) {
|
|
99
|
-
return `File not found: ${input.path}`;
|
|
100
|
-
}
|
|
101
|
-
const content = readFileSync(fullPath, "utf-8");
|
|
102
|
-
const lines = content.split("\n");
|
|
103
|
-
const maxLines = input.limit || 500;
|
|
104
|
-
if (lines.length > maxLines) {
|
|
105
|
-
return (lines.slice(0, maxLines).join("\n") +
|
|
106
|
-
`\n... (truncated, ${lines.length - maxLines} more lines)`);
|
|
107
|
-
}
|
|
108
|
-
return content;
|
|
109
|
-
}
|
|
110
|
-
catch (err) {
|
|
111
|
-
return `Error reading file: ${err instanceof Error ? err.message : String(err)}`;
|
|
112
|
-
}
|
|
113
|
-
},
|
|
114
|
-
}),
|
|
115
|
-
grep: tool({
|
|
116
|
-
description: "Search for a pattern in files. Returns matching lines with file paths and line numbers.",
|
|
117
|
-
inputSchema: grepSchema,
|
|
118
|
-
execute: async (input) => {
|
|
119
|
-
try {
|
|
120
|
-
const includeFlag = input.glob ? `--include='${input.glob}'` : "";
|
|
121
|
-
const result = execSync(`grep -rn ${includeFlag} --exclude-dir=node_modules --exclude-dir=.git '${input.pattern.replace(/'/g, "'\\''")}' . 2>/dev/null | head -100`, { cwd: workingDir, encoding: "utf-8", timeout: 15000 }).trim();
|
|
122
|
-
return result || "No matches found";
|
|
123
|
-
}
|
|
124
|
-
catch {
|
|
125
|
-
return "No matches found";
|
|
126
|
-
}
|
|
127
|
-
},
|
|
128
|
-
}),
|
|
129
|
-
};
|
|
130
|
-
}
|
|
131
|
-
/**
|
|
132
|
-
* Generate text using the Vercel AI SDK with optional tool support.
|
|
133
|
-
*
|
|
134
|
-
* For providers that support tool calling (OpenAI, Google, Anthropic),
|
|
135
|
-
* the model can use glob/read_file/grep to explore a cloned repo.
|
|
136
|
-
* maxSteps controls how many tool call rounds are allowed.
|
|
137
|
-
*/
|
|
138
|
-
export async function generateTextWithTools(options) {
|
|
139
|
-
const { provider, model: modelName, apiKey, prompt, systemPrompt, workingDir, maxTokens = 16384, temperature = 0.7, timeoutMs = 600_000, maxSteps = 15, enableTools = true, } = options;
|
|
140
|
-
const sdkModel = createModel(provider, modelName, apiKey);
|
|
141
|
-
const tools = enableTools && workingDir ? buildTools(workingDir) : undefined;
|
|
142
|
-
const abortController = new AbortController();
|
|
143
|
-
const timeout = setTimeout(() => abortController.abort(), timeoutMs);
|
|
144
|
-
try {
|
|
145
|
-
const result = await aiGenerateText({
|
|
146
|
-
model: sdkModel,
|
|
147
|
-
prompt,
|
|
148
|
-
system: systemPrompt,
|
|
149
|
-
maxOutputTokens: maxTokens,
|
|
150
|
-
temperature,
|
|
151
|
-
tools,
|
|
152
|
-
stopWhen: tools ? stepCountIs(maxSteps) : undefined,
|
|
153
|
-
abortSignal: abortController.signal,
|
|
154
|
-
});
|
|
155
|
-
return result.text;
|
|
156
|
-
}
|
|
157
|
-
finally {
|
|
158
|
-
clearTimeout(timeout);
|
|
159
|
-
}
|
|
160
|
-
}
|
package/dist/api.d.ts
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Shared Axios instance for talking to the WorkerMill cloud API.
|
|
3
|
-
* Configured lazily after config is loaded.
|
|
4
|
-
*/
|
|
5
|
-
import { type AxiosInstance } from "axios";
|
|
6
|
-
/**
|
|
7
|
-
* Initialize the shared API client.
|
|
8
|
-
*/
|
|
9
|
-
export declare function initApi(baseUrl: string, apiKey: string): void;
|
|
10
|
-
/**
|
|
11
|
-
* Get the shared API client. Must call initApi() first.
|
|
12
|
-
*/
|
|
13
|
-
export declare const api: AxiosInstance;
|
package/dist/api.js
DELETED
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Shared Axios instance for talking to the WorkerMill cloud API.
|
|
3
|
-
* Configured lazily after config is loaded.
|
|
4
|
-
*/
|
|
5
|
-
import axios from "axios";
|
|
6
|
-
let _api = null;
|
|
7
|
-
/**
|
|
8
|
-
* Initialize the shared API client.
|
|
9
|
-
*/
|
|
10
|
-
export function initApi(baseUrl, apiKey) {
|
|
11
|
-
_api = axios.create({
|
|
12
|
-
baseURL: baseUrl,
|
|
13
|
-
headers: {
|
|
14
|
-
"Content-Type": "application/json",
|
|
15
|
-
"x-api-key": apiKey,
|
|
16
|
-
},
|
|
17
|
-
timeout: 30_000,
|
|
18
|
-
});
|
|
19
|
-
}
|
|
20
|
-
/**
|
|
21
|
-
* Get the shared API client. Must call initApi() first.
|
|
22
|
-
*/
|
|
23
|
-
export const api = new Proxy({}, {
|
|
24
|
-
get(_target, prop) {
|
|
25
|
-
if (!_api)
|
|
26
|
-
throw new Error("API client not initialized. Call initApi() first.");
|
|
27
|
-
return _api[prop];
|
|
28
|
-
},
|
|
29
|
-
});
|
package/dist/cli.d.ts
DELETED
package/dist/commands/logs.d.ts
DELETED
package/dist/commands/logs.js
DELETED
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Logs Command — Live tail of agent logs.
|
|
3
|
-
*
|
|
4
|
-
* Works like `tail -f ~/.workermill/agent.log`.
|
|
5
|
-
* Shows the last N lines then follows new output.
|
|
6
|
-
*/
|
|
7
|
-
import chalk from "chalk";
|
|
8
|
-
import { existsSync, readFileSync, watchFile, statSync, openSync, readSync, closeSync } from "fs";
|
|
9
|
-
import { getLogFile } from "../config.js";
|
|
10
|
-
export async function logsCommand(options) {
|
|
11
|
-
const logFile = getLogFile();
|
|
12
|
-
if (!existsSync(logFile)) {
|
|
13
|
-
console.log(chalk.yellow("No log file found."));
|
|
14
|
-
console.log(chalk.dim(`Expected at: ${logFile}`));
|
|
15
|
-
console.log(chalk.dim("Start the agent with --detach to generate logs."));
|
|
16
|
-
return;
|
|
17
|
-
}
|
|
18
|
-
const tailLines = parseInt(options.lines || "50", 10);
|
|
19
|
-
// Show last N lines
|
|
20
|
-
const content = readFileSync(logFile, "utf-8");
|
|
21
|
-
const lines = content.split("\n");
|
|
22
|
-
const startIdx = Math.max(0, lines.length - tailLines);
|
|
23
|
-
const tail = lines.slice(startIdx).join("\n");
|
|
24
|
-
if (tail.trim()) {
|
|
25
|
-
process.stdout.write(tail);
|
|
26
|
-
if (!tail.endsWith("\n"))
|
|
27
|
-
process.stdout.write("\n");
|
|
28
|
-
}
|
|
29
|
-
console.log(chalk.dim(`── Following ${logFile} (Ctrl+C to stop) ──`));
|
|
30
|
-
// Follow new output
|
|
31
|
-
let lastSize = statSync(logFile).size;
|
|
32
|
-
watchFile(logFile, { interval: 500 }, () => {
|
|
33
|
-
try {
|
|
34
|
-
const currentSize = statSync(logFile).size;
|
|
35
|
-
if (currentSize <= lastSize) {
|
|
36
|
-
lastSize = currentSize;
|
|
37
|
-
return;
|
|
38
|
-
}
|
|
39
|
-
const fd = openSync(logFile, "r");
|
|
40
|
-
const buffer = Buffer.alloc(currentSize - lastSize);
|
|
41
|
-
readSync(fd, buffer, 0, buffer.length, lastSize);
|
|
42
|
-
closeSync(fd);
|
|
43
|
-
process.stdout.write(buffer.toString());
|
|
44
|
-
lastSize = currentSize;
|
|
45
|
-
}
|
|
46
|
-
catch {
|
|
47
|
-
// File may have been rotated
|
|
48
|
-
}
|
|
49
|
-
});
|
|
50
|
-
// Keep process alive
|
|
51
|
-
await new Promise(() => { });
|
|
52
|
-
}
|
package/dist/commands/pull.d.ts
DELETED
package/dist/commands/pull.js
DELETED
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Pull Command — Pull the latest worker Docker image.
|
|
3
|
-
*/
|
|
4
|
-
import chalk from "chalk";
|
|
5
|
-
import { spawnSync } from "child_process";
|
|
6
|
-
import { existsSync } from "fs";
|
|
7
|
-
import { loadConfigFromFile, getConfigFile } from "../config.js";
|
|
8
|
-
export async function pullCommand() {
|
|
9
|
-
let workerImage = "public.ecr.aws/a7k5r0v0/workermill-worker:latest";
|
|
10
|
-
// Use configured image if config exists
|
|
11
|
-
if (existsSync(getConfigFile())) {
|
|
12
|
-
const config = loadConfigFromFile();
|
|
13
|
-
workerImage = config.workerImage || workerImage;
|
|
14
|
-
}
|
|
15
|
-
console.log();
|
|
16
|
-
console.log(chalk.dim(` Pulling worker image: ${workerImage}`));
|
|
17
|
-
console.log(chalk.dim(" This may take a few minutes..."));
|
|
18
|
-
console.log();
|
|
19
|
-
const result = spawnSync("docker", ["pull", workerImage], {
|
|
20
|
-
stdio: "inherit",
|
|
21
|
-
timeout: 600_000,
|
|
22
|
-
});
|
|
23
|
-
console.log();
|
|
24
|
-
if (result.status === 0) {
|
|
25
|
-
console.log(chalk.green(` ✓ Worker image updated`));
|
|
26
|
-
}
|
|
27
|
-
else {
|
|
28
|
-
console.log(chalk.red(" ✗ Failed to pull worker image."));
|
|
29
|
-
if (result.error) {
|
|
30
|
-
console.log(chalk.yellow(` Error: ${result.error.message}`));
|
|
31
|
-
}
|
|
32
|
-
console.log(chalk.yellow(" Is Docker Desktop running?"));
|
|
33
|
-
process.exit(1);
|
|
34
|
-
}
|
|
35
|
-
}
|
package/dist/commands/setup.d.ts
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Setup Wizard — Interactive configuration for the WorkerMill Remote Agent.
|
|
3
|
-
*
|
|
4
|
-
* Prerequisites checked/installed:
|
|
5
|
-
* - Docker Desktop (must be installed manually)
|
|
6
|
-
* - Git for Windows (must be installed manually — required by Claude Code on Windows)
|
|
7
|
-
* - Claude CLI → winget on Windows, curl | bash on Linux/macOS/WSL
|
|
8
|
-
* - Claude auth → launches `claude` which prompts for sign-in on first run
|
|
9
|
-
* - Worker image → `docker pull public.ecr.aws/a7k5r0v0/workermill-worker:latest`
|
|
10
|
-
*/
|
|
11
|
-
export declare function setupCommand(): Promise<void>;
|