beercan 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 +187 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +546 -0
- package/dist/cli.js.map +1 -0
- package/dist/client.d.ts +8 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +29 -0
- package/dist/client.js.map +1 -0
- package/dist/config.d.ts +49 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +61 -0
- package/dist/config.js.map +1 -0
- package/dist/core/gatekeeper.d.ts +163 -0
- package/dist/core/gatekeeper.d.ts.map +1 -0
- package/dist/core/gatekeeper.js +247 -0
- package/dist/core/gatekeeper.js.map +1 -0
- package/dist/core/job-queue.d.ts +61 -0
- package/dist/core/job-queue.d.ts.map +1 -0
- package/dist/core/job-queue.js +123 -0
- package/dist/core/job-queue.js.map +1 -0
- package/dist/core/logger.d.ts +22 -0
- package/dist/core/logger.d.ts.map +1 -0
- package/dist/core/logger.js +65 -0
- package/dist/core/logger.js.map +1 -0
- package/dist/core/role-templates.d.ts +3 -0
- package/dist/core/role-templates.d.ts.map +1 -0
- package/dist/core/role-templates.js +179 -0
- package/dist/core/role-templates.js.map +1 -0
- package/dist/core/roles.d.ts +94 -0
- package/dist/core/roles.d.ts.map +1 -0
- package/dist/core/roles.js +206 -0
- package/dist/core/roles.js.map +1 -0
- package/dist/core/runner.d.ts +76 -0
- package/dist/core/runner.d.ts.map +1 -0
- package/dist/core/runner.js +307 -0
- package/dist/core/runner.js.map +1 -0
- package/dist/events/daemon.d.ts +9 -0
- package/dist/events/daemon.d.ts.map +1 -0
- package/dist/events/daemon.js +29 -0
- package/dist/events/daemon.js.map +1 -0
- package/dist/events/event-bus.d.ts +35 -0
- package/dist/events/event-bus.d.ts.map +1 -0
- package/dist/events/event-bus.js +41 -0
- package/dist/events/event-bus.js.map +1 -0
- package/dist/events/index.d.ts +41 -0
- package/dist/events/index.d.ts.map +1 -0
- package/dist/events/index.js +57 -0
- package/dist/events/index.js.map +1 -0
- package/dist/events/sources/filesystem-source.d.ts +23 -0
- package/dist/events/sources/filesystem-source.d.ts.map +1 -0
- package/dist/events/sources/filesystem-source.js +95 -0
- package/dist/events/sources/filesystem-source.js.map +1 -0
- package/dist/events/sources/macos-source.d.ts +23 -0
- package/dist/events/sources/macos-source.d.ts.map +1 -0
- package/dist/events/sources/macos-source.js +123 -0
- package/dist/events/sources/macos-source.js.map +1 -0
- package/dist/events/sources/polling-source.d.ts +23 -0
- package/dist/events/sources/polling-source.d.ts.map +1 -0
- package/dist/events/sources/polling-source.js +47 -0
- package/dist/events/sources/polling-source.js.map +1 -0
- package/dist/events/sources/webhook-source.d.ts +23 -0
- package/dist/events/sources/webhook-source.d.ts.map +1 -0
- package/dist/events/sources/webhook-source.js +132 -0
- package/dist/events/sources/webhook-source.js.map +1 -0
- package/dist/events/trigger-manager.d.ts +78 -0
- package/dist/events/trigger-manager.d.ts.map +1 -0
- package/dist/events/trigger-manager.js +130 -0
- package/dist/events/trigger-manager.js.map +1 -0
- package/dist/index.d.ts +123 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +225 -0
- package/dist/index.js.map +1 -0
- package/dist/mcp/index.d.ts +4 -0
- package/dist/mcp/index.d.ts.map +1 -0
- package/dist/mcp/index.js +3 -0
- package/dist/mcp/index.js.map +1 -0
- package/dist/mcp/manager.d.ts +99 -0
- package/dist/mcp/manager.d.ts.map +1 -0
- package/dist/mcp/manager.js +143 -0
- package/dist/mcp/manager.js.map +1 -0
- package/dist/mcp/tool-adapter.d.ts +20 -0
- package/dist/mcp/tool-adapter.d.ts.map +1 -0
- package/dist/mcp/tool-adapter.js +29 -0
- package/dist/mcp/tool-adapter.js.map +1 -0
- package/dist/memory/embeddings.d.ts +28 -0
- package/dist/memory/embeddings.d.ts.map +1 -0
- package/dist/memory/embeddings.js +90 -0
- package/dist/memory/embeddings.js.map +1 -0
- package/dist/memory/hybrid-search.d.ts +31 -0
- package/dist/memory/hybrid-search.d.ts.map +1 -0
- package/dist/memory/hybrid-search.js +114 -0
- package/dist/memory/hybrid-search.js.map +1 -0
- package/dist/memory/index.d.ts +55 -0
- package/dist/memory/index.d.ts.map +1 -0
- package/dist/memory/index.js +175 -0
- package/dist/memory/index.js.map +1 -0
- package/dist/memory/knowledge-graph.d.ts +21 -0
- package/dist/memory/knowledge-graph.d.ts.map +1 -0
- package/dist/memory/knowledge-graph.js +118 -0
- package/dist/memory/knowledge-graph.js.map +1 -0
- package/dist/memory/schemas.d.ts +187 -0
- package/dist/memory/schemas.d.ts.map +1 -0
- package/dist/memory/schemas.js +75 -0
- package/dist/memory/schemas.js.map +1 -0
- package/dist/memory/sqlite-vec-store.d.ts +22 -0
- package/dist/memory/sqlite-vec-store.d.ts.map +1 -0
- package/dist/memory/sqlite-vec-store.js +37 -0
- package/dist/memory/sqlite-vec-store.js.map +1 -0
- package/dist/memory/working-memory.d.ts +22 -0
- package/dist/memory/working-memory.d.ts.map +1 -0
- package/dist/memory/working-memory.js +53 -0
- package/dist/memory/working-memory.js.map +1 -0
- package/dist/scheduler/index.d.ts +3 -0
- package/dist/scheduler/index.d.ts.map +1 -0
- package/dist/scheduler/index.js +2 -0
- package/dist/scheduler/index.js.map +1 -0
- package/dist/scheduler/scheduler.d.ts +82 -0
- package/dist/scheduler/scheduler.d.ts.map +1 -0
- package/dist/scheduler/scheduler.js +127 -0
- package/dist/scheduler/scheduler.js.map +1 -0
- package/dist/schemas.d.ts +328 -0
- package/dist/schemas.d.ts.map +1 -0
- package/dist/schemas.js +77 -0
- package/dist/schemas.js.map +1 -0
- package/dist/storage/database.d.ts +97 -0
- package/dist/storage/database.d.ts.map +1 -0
- package/dist/storage/database.js +685 -0
- package/dist/storage/database.js.map +1 -0
- package/dist/tools/builtin/filesystem.d.ts +11 -0
- package/dist/tools/builtin/filesystem.d.ts.map +1 -0
- package/dist/tools/builtin/filesystem.js +137 -0
- package/dist/tools/builtin/filesystem.js.map +1 -0
- package/dist/tools/builtin/memory.d.ts +13 -0
- package/dist/tools/builtin/memory.d.ts.map +1 -0
- package/dist/tools/builtin/memory.js +299 -0
- package/dist/tools/builtin/memory.js.map +1 -0
- package/dist/tools/builtin/notification.d.ts +5 -0
- package/dist/tools/builtin/notification.d.ts.map +1 -0
- package/dist/tools/builtin/notification.js +36 -0
- package/dist/tools/builtin/notification.js.map +1 -0
- package/dist/tools/builtin/web.d.ts +7 -0
- package/dist/tools/builtin/web.d.ts.map +1 -0
- package/dist/tools/builtin/web.js +191 -0
- package/dist/tools/builtin/web.js.map +1 -0
- package/dist/tools/registry.d.ts +36 -0
- package/dist/tools/registry.d.ts.map +1 -0
- package/dist/tools/registry.js +49 -0
- package/dist/tools/registry.js.map +1 -0
- package/package.json +73 -0
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
// ── Web Fetch ───────────────────────────────────────────────
|
|
2
|
+
// Fetches web page content. Uses Cloudflare Browser Rendering API
|
|
3
|
+
// if CLOUDFLARE_API_TOKEN + CLOUDFLARE_ACCOUNT_ID are set,
|
|
4
|
+
// otherwise falls back to native fetch.
|
|
5
|
+
export const webFetchDefinition = {
|
|
6
|
+
name: "web_fetch",
|
|
7
|
+
description: "Fetch the text content of a web page. Returns clean text/markdown content. Handles JavaScript-rendered pages when Cloudflare Browser Rendering is configured. Good for reading documentation, articles, API responses.",
|
|
8
|
+
inputSchema: {
|
|
9
|
+
type: "object",
|
|
10
|
+
properties: {
|
|
11
|
+
url: { type: "string", description: "URL to fetch" },
|
|
12
|
+
headers: {
|
|
13
|
+
type: "object",
|
|
14
|
+
description: "Optional HTTP headers to include",
|
|
15
|
+
},
|
|
16
|
+
max_length: {
|
|
17
|
+
type: "number",
|
|
18
|
+
description: "Maximum response length in characters (default 50000)",
|
|
19
|
+
},
|
|
20
|
+
},
|
|
21
|
+
required: ["url"],
|
|
22
|
+
},
|
|
23
|
+
};
|
|
24
|
+
export const webFetchHandler = async (input) => {
|
|
25
|
+
const url = input.url;
|
|
26
|
+
const maxLength = input.max_length ?? 50000;
|
|
27
|
+
const customHeaders = input.headers ?? {};
|
|
28
|
+
// Try Cloudflare Browser Rendering first (handles JS-rendered pages)
|
|
29
|
+
const cfToken = process.env.CLOUDFLARE_API_TOKEN;
|
|
30
|
+
const cfAccount = process.env.CLOUDFLARE_ACCOUNT_ID;
|
|
31
|
+
if (cfToken && cfAccount) {
|
|
32
|
+
try {
|
|
33
|
+
return await fetchViaCloudflare(url, cfAccount, cfToken, maxLength);
|
|
34
|
+
}
|
|
35
|
+
catch (err) {
|
|
36
|
+
// Fall back to native fetch on CF error
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
// Native fetch fallback
|
|
40
|
+
const controller = new AbortController();
|
|
41
|
+
const timeout = setTimeout(() => controller.abort(), 30000);
|
|
42
|
+
try {
|
|
43
|
+
const response = await fetch(url, {
|
|
44
|
+
headers: {
|
|
45
|
+
"User-Agent": "BeerCan-Agent/1.0",
|
|
46
|
+
...customHeaders,
|
|
47
|
+
},
|
|
48
|
+
signal: controller.signal,
|
|
49
|
+
redirect: "follow",
|
|
50
|
+
});
|
|
51
|
+
if (!response.ok) {
|
|
52
|
+
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
|
|
53
|
+
}
|
|
54
|
+
const text = await response.text();
|
|
55
|
+
if (text.length > maxLength) {
|
|
56
|
+
return text.slice(0, maxLength) + `\n\n--- Truncated at ${maxLength} characters ---`;
|
|
57
|
+
}
|
|
58
|
+
return text;
|
|
59
|
+
}
|
|
60
|
+
finally {
|
|
61
|
+
clearTimeout(timeout);
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
/**
|
|
65
|
+
* Fetch page content via Cloudflare Browser Rendering /crawl API.
|
|
66
|
+
* Two-step: POST starts async crawl job, GET retrieves results.
|
|
67
|
+
* Returns HTML content from the rendered page.
|
|
68
|
+
*/
|
|
69
|
+
async function fetchViaCloudflare(url, accountId, apiToken, maxLength) {
|
|
70
|
+
const baseUrl = `https://api.cloudflare.com/client/v4/accounts/${accountId}/browser-rendering/crawl`;
|
|
71
|
+
const headers = {
|
|
72
|
+
"Authorization": `Bearer ${apiToken}`,
|
|
73
|
+
"Content-Type": "application/json",
|
|
74
|
+
};
|
|
75
|
+
// Step 1: Start crawl job
|
|
76
|
+
const startResponse = await fetch(baseUrl, {
|
|
77
|
+
method: "POST",
|
|
78
|
+
headers,
|
|
79
|
+
body: JSON.stringify({ url }),
|
|
80
|
+
});
|
|
81
|
+
if (!startResponse.ok) {
|
|
82
|
+
const errBody = await startResponse.text();
|
|
83
|
+
throw new Error(`Cloudflare crawl start failed (${startResponse.status}): ${errBody}`);
|
|
84
|
+
}
|
|
85
|
+
const startData = await startResponse.json();
|
|
86
|
+
if (!startData.success || !startData.result) {
|
|
87
|
+
throw new Error(`Cloudflare crawl start error: ${JSON.stringify(startData.errors)}`);
|
|
88
|
+
}
|
|
89
|
+
const jobId = startData.result;
|
|
90
|
+
// Step 2: Poll for results (max 30s, check every 2s)
|
|
91
|
+
const deadline = Date.now() + 30_000;
|
|
92
|
+
while (Date.now() < deadline) {
|
|
93
|
+
await new Promise((r) => setTimeout(r, 2000));
|
|
94
|
+
const pollResponse = await fetch(`${baseUrl}/${jobId}`, { headers });
|
|
95
|
+
if (!pollResponse.ok)
|
|
96
|
+
continue;
|
|
97
|
+
const pollData = await pollResponse.json();
|
|
98
|
+
if (!pollData.success)
|
|
99
|
+
continue;
|
|
100
|
+
const status = pollData.result?.status;
|
|
101
|
+
if (status === "completed") {
|
|
102
|
+
// Extract HTML from first completed record
|
|
103
|
+
const records = pollData.result?.records ?? [];
|
|
104
|
+
const record = records.find((r) => r.status === "completed" && r.html);
|
|
105
|
+
if (record) {
|
|
106
|
+
// Strip HTML tags for cleaner text output
|
|
107
|
+
const text = stripHtml(record.html);
|
|
108
|
+
const title = record.metadata?.title ? `# ${record.metadata.title}\n\n` : "";
|
|
109
|
+
const content = title + text;
|
|
110
|
+
if (content.length > maxLength) {
|
|
111
|
+
return content.slice(0, maxLength) + `\n\n--- Truncated at ${maxLength} characters ---`;
|
|
112
|
+
}
|
|
113
|
+
return content;
|
|
114
|
+
}
|
|
115
|
+
throw new Error("Cloudflare crawl completed but no content in response");
|
|
116
|
+
}
|
|
117
|
+
if (status === "failed") {
|
|
118
|
+
throw new Error("Cloudflare crawl job failed");
|
|
119
|
+
}
|
|
120
|
+
// status is "pending" or "running" — keep polling
|
|
121
|
+
}
|
|
122
|
+
throw new Error("Cloudflare crawl timed out after 30s");
|
|
123
|
+
}
|
|
124
|
+
/** Simple HTML tag stripper — extracts text content */
|
|
125
|
+
function stripHtml(html) {
|
|
126
|
+
return html
|
|
127
|
+
.replace(/<script[^>]*>[\s\S]*?<\/script>/gi, "")
|
|
128
|
+
.replace(/<style[^>]*>[\s\S]*?<\/style>/gi, "")
|
|
129
|
+
.replace(/<[^>]+>/g, " ")
|
|
130
|
+
.replace(/ /g, " ")
|
|
131
|
+
.replace(/&/g, "&")
|
|
132
|
+
.replace(/</g, "<")
|
|
133
|
+
.replace(/>/g, ">")
|
|
134
|
+
.replace(/"/g, '"')
|
|
135
|
+
.replace(/'/g, "'")
|
|
136
|
+
.replace(/\s+/g, " ")
|
|
137
|
+
.trim();
|
|
138
|
+
}
|
|
139
|
+
// ── HTTP Request ────────────────────────────────────────────
|
|
140
|
+
// Full HTTP request with method, headers, body control.
|
|
141
|
+
export const httpRequestDefinition = {
|
|
142
|
+
name: "http_request",
|
|
143
|
+
description: "Make an HTTP request with full control over method, headers, and body. Returns status code, response headers, and body. Use for API integrations, webhooks, form submissions.",
|
|
144
|
+
inputSchema: {
|
|
145
|
+
type: "object",
|
|
146
|
+
properties: {
|
|
147
|
+
url: { type: "string", description: "Request URL" },
|
|
148
|
+
method: {
|
|
149
|
+
type: "string",
|
|
150
|
+
enum: ["GET", "POST", "PUT", "PATCH", "DELETE", "HEAD"],
|
|
151
|
+
description: "HTTP method (default GET)",
|
|
152
|
+
},
|
|
153
|
+
headers: { type: "object", description: "HTTP headers" },
|
|
154
|
+
body: { type: "string", description: "Request body (for POST/PUT/PATCH)" },
|
|
155
|
+
timeout_ms: { type: "number", description: "Timeout in milliseconds (default 30000)" },
|
|
156
|
+
},
|
|
157
|
+
required: ["url"],
|
|
158
|
+
},
|
|
159
|
+
};
|
|
160
|
+
export const httpRequestHandler = async (input) => {
|
|
161
|
+
const url = input.url;
|
|
162
|
+
const method = input.method ?? "GET";
|
|
163
|
+
const headers = input.headers ?? {};
|
|
164
|
+
const body = input.body;
|
|
165
|
+
const timeoutMs = input.timeout_ms ?? 30000;
|
|
166
|
+
const controller = new AbortController();
|
|
167
|
+
const timeout = setTimeout(() => controller.abort(), timeoutMs);
|
|
168
|
+
try {
|
|
169
|
+
const response = await fetch(url, {
|
|
170
|
+
method,
|
|
171
|
+
headers: {
|
|
172
|
+
"User-Agent": "BeerCan-Agent/1.0",
|
|
173
|
+
...headers,
|
|
174
|
+
},
|
|
175
|
+
body: body ?? undefined,
|
|
176
|
+
signal: controller.signal,
|
|
177
|
+
redirect: "follow",
|
|
178
|
+
});
|
|
179
|
+
const responseBody = await response.text();
|
|
180
|
+
const truncatedBody = responseBody.length > 100_000
|
|
181
|
+
? responseBody.slice(0, 100_000) + "\n--- Truncated ---"
|
|
182
|
+
: responseBody;
|
|
183
|
+
const responseHeaders = {};
|
|
184
|
+
response.headers.forEach((value, key) => { responseHeaders[key] = value; });
|
|
185
|
+
return `STATUS: ${response.status} ${response.statusText}\nHEADERS: ${JSON.stringify(responseHeaders)}\nBODY:\n${truncatedBody}`;
|
|
186
|
+
}
|
|
187
|
+
finally {
|
|
188
|
+
clearTimeout(timeout);
|
|
189
|
+
}
|
|
190
|
+
};
|
|
191
|
+
//# sourceMappingURL=web.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"web.js","sourceRoot":"","sources":["../../../src/tools/builtin/web.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { ToolDefinition } from "../schemas.js";
|
|
2
|
+
export type ToolHandler = (input: Record<string, unknown>) => Promise<string>;
|
|
3
|
+
export interface RegisteredTool {
|
|
4
|
+
definition: ToolDefinition;
|
|
5
|
+
handler: ToolHandler;
|
|
6
|
+
}
|
|
7
|
+
export declare class ToolRegistry {
|
|
8
|
+
private tools;
|
|
9
|
+
register(definition: ToolDefinition, handler: ToolHandler): void;
|
|
10
|
+
get(name: string): RegisteredTool | undefined;
|
|
11
|
+
has(name: string): boolean;
|
|
12
|
+
/**
|
|
13
|
+
* Get tool definitions filtered by an allow-list.
|
|
14
|
+
* Pass ["*"] to get all tools.
|
|
15
|
+
*/
|
|
16
|
+
getDefinitions(allowedTools?: string[]): ToolDefinition[];
|
|
17
|
+
/**
|
|
18
|
+
* Convert definitions to Anthropic API tool format.
|
|
19
|
+
*/
|
|
20
|
+
toAnthropicTools(allowedTools?: string[]): AnthropicTool[];
|
|
21
|
+
execute(name: string, input: Record<string, unknown>): Promise<{
|
|
22
|
+
output?: string;
|
|
23
|
+
error?: string;
|
|
24
|
+
}>;
|
|
25
|
+
}
|
|
26
|
+
interface AnthropicTool {
|
|
27
|
+
name: string;
|
|
28
|
+
description: string;
|
|
29
|
+
input_schema: {
|
|
30
|
+
type: "object";
|
|
31
|
+
properties: Record<string, unknown>;
|
|
32
|
+
required?: string[];
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
export {};
|
|
36
|
+
//# sourceMappingURL=registry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/tools/registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAIpD,MAAM,MAAM,WAAW,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;AAE9E,MAAM,WAAW,cAAc;IAC7B,UAAU,EAAE,cAAc,CAAC;IAC3B,OAAO,EAAE,WAAW,CAAC;CACtB;AAID,qBAAa,YAAY;IACvB,OAAO,CAAC,KAAK,CAAqC;IAElD,QAAQ,CAAC,UAAU,EAAE,cAAc,EAAE,OAAO,EAAE,WAAW,GAAG,IAAI;IAIhE,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,cAAc,GAAG,SAAS;IAI7C,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAI1B;;;OAGG;IACH,cAAc,CAAC,YAAY,GAAE,MAAM,EAAU,GAAG,cAAc,EAAE;IAShE;;OAEG;IACH,gBAAgB,CAAC,YAAY,GAAE,MAAM,EAAU,GAAG,aAAa,EAAE;IAQ3D,OAAO,CACX,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC7B,OAAO,CAAC;QAAE,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CAYhD;AAID,UAAU,aAAa;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE;QACZ,IAAI,EAAE,QAAQ,CAAC;QACf,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QACpC,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;KACrB,CAAC;CACH"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
// ── Tool Registry ────────────────────────────────────────────
|
|
2
|
+
export class ToolRegistry {
|
|
3
|
+
tools = new Map();
|
|
4
|
+
register(definition, handler) {
|
|
5
|
+
this.tools.set(definition.name, { definition, handler });
|
|
6
|
+
}
|
|
7
|
+
get(name) {
|
|
8
|
+
return this.tools.get(name);
|
|
9
|
+
}
|
|
10
|
+
has(name) {
|
|
11
|
+
return this.tools.has(name);
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Get tool definitions filtered by an allow-list.
|
|
15
|
+
* Pass ["*"] to get all tools.
|
|
16
|
+
*/
|
|
17
|
+
getDefinitions(allowedTools = ["*"]) {
|
|
18
|
+
if (allowedTools.includes("*")) {
|
|
19
|
+
return Array.from(this.tools.values()).map((t) => t.definition);
|
|
20
|
+
}
|
|
21
|
+
return allowedTools
|
|
22
|
+
.map((name) => this.tools.get(name)?.definition)
|
|
23
|
+
.filter(Boolean);
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Convert definitions to Anthropic API tool format.
|
|
27
|
+
*/
|
|
28
|
+
toAnthropicTools(allowedTools = ["*"]) {
|
|
29
|
+
return this.getDefinitions(allowedTools).map((d) => ({
|
|
30
|
+
name: d.name,
|
|
31
|
+
description: d.description,
|
|
32
|
+
input_schema: d.inputSchema,
|
|
33
|
+
}));
|
|
34
|
+
}
|
|
35
|
+
async execute(name, input) {
|
|
36
|
+
const tool = this.tools.get(name);
|
|
37
|
+
if (!tool) {
|
|
38
|
+
return { error: `Unknown tool: ${name}` };
|
|
39
|
+
}
|
|
40
|
+
try {
|
|
41
|
+
const output = await tool.handler(input);
|
|
42
|
+
return { output };
|
|
43
|
+
}
|
|
44
|
+
catch (err) {
|
|
45
|
+
return { error: err.message ?? String(err) };
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
//# sourceMappingURL=registry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/tools/registry.ts"],"names":[],"mappings":"AAWA,gEAAgE;AAEhE,MAAM,OAAO,YAAY;IACf,KAAK,GAAG,IAAI,GAAG,EAA0B,CAAC;IAElD,QAAQ,CAAC,UAA0B,EAAE,OAAoB;QACvD,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,EAAE,EAAE,UAAU,EAAE,OAAO,EAAE,CAAC,CAAC;IAC3D,CAAC;IAED,GAAG,CAAC,IAAY;QACd,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAC9B,CAAC;IAED,GAAG,CAAC,IAAY;QACd,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAC9B,CAAC;IAED;;;OAGG;IACH,cAAc,CAAC,eAAyB,CAAC,GAAG,CAAC;QAC3C,IAAI,YAAY,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;YAC/B,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC;QAClE,CAAC;QACD,OAAO,YAAY;aAChB,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,UAAU,CAAC;aAC/C,MAAM,CAAC,OAAO,CAAqB,CAAC;IACzC,CAAC;IAED;;OAEG;IACH,gBAAgB,CAAC,eAAyB,CAAC,GAAG,CAAC;QAC7C,OAAO,IAAI,CAAC,cAAc,CAAC,YAAY,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YACnD,IAAI,EAAE,CAAC,CAAC,IAAI;YACZ,WAAW,EAAE,CAAC,CAAC,WAAW;YAC1B,YAAY,EAAE,CAAC,CAAC,WAAkB;SACnC,CAAC,CAAC,CAAC;IACN,CAAC;IAED,KAAK,CAAC,OAAO,CACX,IAAY,EACZ,KAA8B;QAE9B,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAClC,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,OAAO,EAAE,KAAK,EAAE,iBAAiB,IAAI,EAAE,EAAE,CAAC;QAC5C,CAAC;QACD,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;YACzC,OAAO,EAAE,MAAM,EAAE,CAAC;QACpB,CAAC;QAAC,OAAO,GAAQ,EAAE,CAAC;YAClB,OAAO,EAAE,KAAK,EAAE,GAAG,CAAC,OAAO,IAAI,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC;QAC/C,CAAC;IACH,CAAC;CACF"}
|
package/package.json
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "beercan",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Autonomous agent system — smarter than you, and it knows it.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"types": "dist/index.d.ts",
|
|
8
|
+
"bin": {
|
|
9
|
+
"beercan": "dist/cli.js"
|
|
10
|
+
},
|
|
11
|
+
"files": [
|
|
12
|
+
"dist",
|
|
13
|
+
"README.md",
|
|
14
|
+
"LICENSE"
|
|
15
|
+
],
|
|
16
|
+
"keywords": [
|
|
17
|
+
"ai",
|
|
18
|
+
"agent",
|
|
19
|
+
"autonomous",
|
|
20
|
+
"claude",
|
|
21
|
+
"anthropic",
|
|
22
|
+
"pipeline",
|
|
23
|
+
"orchestration",
|
|
24
|
+
"multi-agent",
|
|
25
|
+
"rag",
|
|
26
|
+
"memory",
|
|
27
|
+
"knowledge-graph",
|
|
28
|
+
"sqlite",
|
|
29
|
+
"mcp"
|
|
30
|
+
],
|
|
31
|
+
"license": "MIT",
|
|
32
|
+
"repository": {
|
|
33
|
+
"type": "git",
|
|
34
|
+
"url": "https://github.com/ArchieGoodwin/beercan"
|
|
35
|
+
},
|
|
36
|
+
"homepage": "https://beercan.run",
|
|
37
|
+
"engines": {
|
|
38
|
+
"node": ">=18.0.0"
|
|
39
|
+
},
|
|
40
|
+
"scripts": {
|
|
41
|
+
"build": "tsc",
|
|
42
|
+
"dev": "tsx watch src/index.ts",
|
|
43
|
+
"start": "node dist/index.ts",
|
|
44
|
+
"beercan": "tsx src/cli.ts",
|
|
45
|
+
"test": "vitest run --exclude tests/integration.test.ts",
|
|
46
|
+
"test:watch": "vitest --exclude tests/integration.test.ts",
|
|
47
|
+
"test:integration": "vitest run tests/integration.test.ts",
|
|
48
|
+
"test:all": "vitest run"
|
|
49
|
+
},
|
|
50
|
+
"dependencies": {
|
|
51
|
+
"@anthropic-ai/sdk": "^0.39.0",
|
|
52
|
+
"@modelcontextprotocol/sdk": "^1.27.1",
|
|
53
|
+
"@types/node-cron": "^3.0.11",
|
|
54
|
+
"better-sqlite3": "^12.8.0",
|
|
55
|
+
"chalk": "^5.4.0",
|
|
56
|
+
"dotenv": "^16.4.0",
|
|
57
|
+
"https-proxy-agent": "^8.0.0",
|
|
58
|
+
"node-cron": "^4.2.1",
|
|
59
|
+
"node-fetch": "^3.3.2",
|
|
60
|
+
"sqlite-vec": "^0.1.7-alpha.2",
|
|
61
|
+
"undici": "^7.23.0",
|
|
62
|
+
"uuid": "^11.1.0",
|
|
63
|
+
"zod": "^3.24.0"
|
|
64
|
+
},
|
|
65
|
+
"devDependencies": {
|
|
66
|
+
"@types/better-sqlite3": "^7.6.13",
|
|
67
|
+
"@types/node": "^22.0.0",
|
|
68
|
+
"@types/uuid": "^10.0.0",
|
|
69
|
+
"tsx": "^4.19.0",
|
|
70
|
+
"typescript": "^5.7.0",
|
|
71
|
+
"vitest": "^4.1.0"
|
|
72
|
+
}
|
|
73
|
+
}
|