@polpo-ai/tools 0.7.18 → 0.8.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/dist/__tests__/custom-tools.test.d.ts +2 -0
- package/dist/__tests__/custom-tools.test.d.ts.map +1 -0
- package/dist/__tests__/custom-tools.test.js +253 -0
- package/dist/__tests__/custom-tools.test.js.map +1 -0
- package/dist/custom-tools.d.ts +105 -0
- package/dist/custom-tools.d.ts.map +1 -0
- package/dist/custom-tools.js +121 -0
- package/dist/custom-tools.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"custom-tools.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/custom-tools.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,253 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Phase 1 of defineTool — the pure-logic foundation (no sandbox, no API):
|
|
3
|
+
* - defineTool() authoring helper → CustomTool + __custom marker
|
|
4
|
+
* - getCustomToolErrors() shape/name validation (reused by the cloud API)
|
|
5
|
+
* - isCustomTool() type guard
|
|
6
|
+
* - normalizeToolResult() string | ToolResult → ToolResult
|
|
7
|
+
* - bindCustomTool() wrap a CustomTool into a runtime PolpoTool (ctx injection)
|
|
8
|
+
* - extractCustomTool() find the tool in a (bundled) module's exports
|
|
9
|
+
* - loadCustomToolBundle() import a bundle file + bind → PolpoTool (self-host path)
|
|
10
|
+
*
|
|
11
|
+
* Test-first: these encode the contract before the implementation exists.
|
|
12
|
+
*/
|
|
13
|
+
import { describe, it, expect, beforeEach, afterEach } from "vitest";
|
|
14
|
+
import { Type } from "@sinclair/typebox";
|
|
15
|
+
import { mkdtemp, writeFile, rm } from "node:fs/promises";
|
|
16
|
+
import { tmpdir } from "node:os";
|
|
17
|
+
import { join } from "node:path";
|
|
18
|
+
import { defineTool, getCustomToolErrors, isCustomTool, normalizeToolResult, bindCustomTool, extractCustomTool, loadCustomToolBundle, } from "../custom-tools.js";
|
|
19
|
+
/** Minimal ctx — bindCustomTool only passes it through, so stubs suffice. */
|
|
20
|
+
function fakeCtx(overrides = {}) {
|
|
21
|
+
return {
|
|
22
|
+
fs: { marker: "fs" },
|
|
23
|
+
shell: { marker: "shell" },
|
|
24
|
+
vault: { marker: "vault" },
|
|
25
|
+
env: { FOO: "bar" },
|
|
26
|
+
workDir: "/work",
|
|
27
|
+
polpo: { marker: "polpo" },
|
|
28
|
+
...overrides,
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
const EchoSchema = Type.Object({ msg: Type.String() });
|
|
32
|
+
describe("defineTool", () => {
|
|
33
|
+
it("returns the spec with the __custom marker", () => {
|
|
34
|
+
const tool = defineTool({
|
|
35
|
+
name: "echo",
|
|
36
|
+
description: "Echoes input",
|
|
37
|
+
parameters: EchoSchema,
|
|
38
|
+
execute: (_ctx, params) => `echo: ${params.msg}`,
|
|
39
|
+
});
|
|
40
|
+
expect(tool.__custom).toBe(true);
|
|
41
|
+
expect(tool.name).toBe("echo");
|
|
42
|
+
expect(tool.description).toBe("Echoes input");
|
|
43
|
+
expect(tool.parameters).toBe(EchoSchema);
|
|
44
|
+
expect(typeof tool.execute).toBe("function");
|
|
45
|
+
});
|
|
46
|
+
it("preserves optional label and clientSide", () => {
|
|
47
|
+
const tool = defineTool({
|
|
48
|
+
name: "echo",
|
|
49
|
+
label: "Echo Machine",
|
|
50
|
+
clientSide: true,
|
|
51
|
+
description: "d",
|
|
52
|
+
parameters: EchoSchema,
|
|
53
|
+
execute: () => "ok",
|
|
54
|
+
});
|
|
55
|
+
expect(tool.label).toBe("Echo Machine");
|
|
56
|
+
expect(tool.clientSide).toBe(true);
|
|
57
|
+
});
|
|
58
|
+
});
|
|
59
|
+
describe("getCustomToolErrors / isCustomTool", () => {
|
|
60
|
+
const valid = defineTool({
|
|
61
|
+
name: "do_thing",
|
|
62
|
+
description: "Does a thing",
|
|
63
|
+
parameters: EchoSchema,
|
|
64
|
+
execute: () => "ok",
|
|
65
|
+
});
|
|
66
|
+
it("accepts a valid tool", () => {
|
|
67
|
+
expect(getCustomToolErrors(valid)).toEqual([]);
|
|
68
|
+
expect(isCustomTool(valid)).toBe(true);
|
|
69
|
+
});
|
|
70
|
+
it("rejects non-objects", () => {
|
|
71
|
+
expect(getCustomToolErrors(null).length).toBeGreaterThan(0);
|
|
72
|
+
expect(getCustomToolErrors("nope").length).toBeGreaterThan(0);
|
|
73
|
+
expect(isCustomTool(null)).toBe(false);
|
|
74
|
+
});
|
|
75
|
+
it("requires a name", () => {
|
|
76
|
+
expect(getCustomToolErrors({ ...valid, name: "" }).join()).toMatch(/name/i);
|
|
77
|
+
});
|
|
78
|
+
it("enforces snake_case names", () => {
|
|
79
|
+
for (const bad of ["Echo", "my tool", "1tool", "my-tool", "MY_TOOL"]) {
|
|
80
|
+
expect(getCustomToolErrors({ ...valid, name: bad }).join()).toMatch(/snake_case|name/i);
|
|
81
|
+
}
|
|
82
|
+
for (const ok of ["echo", "do_thing", "get_user_v2", "a1_b2"]) {
|
|
83
|
+
expect(getCustomToolErrors({ ...valid, name: ok })).toEqual([]);
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
it("requires description, parameters and execute", () => {
|
|
87
|
+
expect(getCustomToolErrors({ ...valid, description: " " }).join()).toMatch(/description/i);
|
|
88
|
+
expect(getCustomToolErrors({ ...valid, parameters: undefined }).join()).toMatch(/parameters/i);
|
|
89
|
+
expect(getCustomToolErrors({ ...valid, execute: "x" }).join()).toMatch(/execute/i);
|
|
90
|
+
});
|
|
91
|
+
it("validates optional field types", () => {
|
|
92
|
+
expect(getCustomToolErrors({ ...valid, label: 5 }).join()).toMatch(/label/i);
|
|
93
|
+
expect(getCustomToolErrors({ ...valid, clientSide: "yes" }).join()).toMatch(/clientSide/i);
|
|
94
|
+
});
|
|
95
|
+
it("isCustomTool requires the __custom marker", () => {
|
|
96
|
+
const { __custom, ...withoutMarker } = valid;
|
|
97
|
+
expect(isCustomTool(withoutMarker)).toBe(false);
|
|
98
|
+
});
|
|
99
|
+
});
|
|
100
|
+
describe("normalizeToolResult", () => {
|
|
101
|
+
it("wraps a plain string into a text ToolResult", () => {
|
|
102
|
+
expect(normalizeToolResult("hello")).toEqual({
|
|
103
|
+
content: [{ type: "text", text: "hello" }],
|
|
104
|
+
details: null,
|
|
105
|
+
});
|
|
106
|
+
});
|
|
107
|
+
it("passes a well-formed ToolResult through unchanged", () => {
|
|
108
|
+
const r = { content: [{ type: "text", text: "x" }], details: { a: 1 } };
|
|
109
|
+
expect(normalizeToolResult(r)).toBe(r);
|
|
110
|
+
});
|
|
111
|
+
it("stringifies unexpected return values as a fallback", () => {
|
|
112
|
+
const out = normalizeToolResult({ foo: 1 });
|
|
113
|
+
expect(out.content[0]).toEqual({ type: "text", text: JSON.stringify({ foo: 1 }) });
|
|
114
|
+
});
|
|
115
|
+
});
|
|
116
|
+
describe("bindCustomTool", () => {
|
|
117
|
+
let tool;
|
|
118
|
+
beforeEach(() => {
|
|
119
|
+
tool = defineTool({
|
|
120
|
+
name: "echo",
|
|
121
|
+
description: "Echoes input",
|
|
122
|
+
parameters: EchoSchema,
|
|
123
|
+
execute: (_ctx, params) => `echo: ${params.msg}`,
|
|
124
|
+
});
|
|
125
|
+
});
|
|
126
|
+
it("produces a PolpoTool with name/label/description/parameters", () => {
|
|
127
|
+
const pt = bindCustomTool(tool, fakeCtx());
|
|
128
|
+
expect(pt.name).toBe("echo");
|
|
129
|
+
expect(pt.label).toBe("echo"); // defaults to name
|
|
130
|
+
expect(pt.description).toBe("Echoes input");
|
|
131
|
+
expect(pt.parameters).toBe(EchoSchema);
|
|
132
|
+
expect(typeof pt.execute).toBe("function");
|
|
133
|
+
});
|
|
134
|
+
it("defaults label to name, honors explicit label", () => {
|
|
135
|
+
expect(bindCustomTool(tool, fakeCtx()).label).toBe("echo");
|
|
136
|
+
const labeled = bindCustomTool({ ...tool, label: "Echo!" }, fakeCtx());
|
|
137
|
+
expect(labeled.label).toBe("Echo!");
|
|
138
|
+
});
|
|
139
|
+
it("runs execute with the injected ctx and normalizes a string result", async () => {
|
|
140
|
+
const pt = bindCustomTool(tool, fakeCtx());
|
|
141
|
+
const res = await pt.execute("call-1", { msg: "hi" });
|
|
142
|
+
expect(res).toEqual({ content: [{ type: "text", text: "echo: hi" }], details: null });
|
|
143
|
+
});
|
|
144
|
+
it("injects the full ctx (fs/shell/vault/env/workDir/polpo) plus signal & onUpdate", async () => {
|
|
145
|
+
let received;
|
|
146
|
+
const t = defineTool({
|
|
147
|
+
name: "spy",
|
|
148
|
+
description: "captures ctx",
|
|
149
|
+
parameters: EchoSchema,
|
|
150
|
+
execute: (ctx) => {
|
|
151
|
+
received = ctx;
|
|
152
|
+
return "ok";
|
|
153
|
+
},
|
|
154
|
+
});
|
|
155
|
+
const ctrl = new AbortController();
|
|
156
|
+
const onUpdate = () => { };
|
|
157
|
+
const pt = bindCustomTool(t, fakeCtx());
|
|
158
|
+
await pt.execute("c", { msg: "x" }, ctrl.signal, onUpdate);
|
|
159
|
+
expect(received.fs).toEqual({ marker: "fs" });
|
|
160
|
+
expect(received.shell).toEqual({ marker: "shell" });
|
|
161
|
+
expect(received.vault).toEqual({ marker: "vault" });
|
|
162
|
+
expect(received.env).toEqual({ FOO: "bar" });
|
|
163
|
+
expect(received.workDir).toBe("/work");
|
|
164
|
+
expect(received.polpo).toEqual({ marker: "polpo" });
|
|
165
|
+
expect(received.signal).toBe(ctrl.signal);
|
|
166
|
+
expect(received.onUpdate).toBe(onUpdate);
|
|
167
|
+
});
|
|
168
|
+
it("passes a ToolResult return value through unchanged", async () => {
|
|
169
|
+
const t = defineTool({
|
|
170
|
+
name: "rich",
|
|
171
|
+
description: "rich result",
|
|
172
|
+
parameters: EchoSchema,
|
|
173
|
+
execute: () => ({ content: [{ type: "text", text: "rich" }], details: { ok: true } }),
|
|
174
|
+
});
|
|
175
|
+
const res = await bindCustomTool(t, fakeCtx()).execute("c", { msg: "x" });
|
|
176
|
+
expect(res.details).toEqual({ ok: true });
|
|
177
|
+
});
|
|
178
|
+
it("propagates errors thrown inside execute", async () => {
|
|
179
|
+
const t = defineTool({
|
|
180
|
+
name: "boom",
|
|
181
|
+
description: "throws",
|
|
182
|
+
parameters: EchoSchema,
|
|
183
|
+
execute: () => {
|
|
184
|
+
throw new Error("kaboom");
|
|
185
|
+
},
|
|
186
|
+
});
|
|
187
|
+
await expect(bindCustomTool(t, fakeCtx()).execute("c", { msg: "x" })).rejects.toThrow("kaboom");
|
|
188
|
+
});
|
|
189
|
+
});
|
|
190
|
+
describe("extractCustomTool", () => {
|
|
191
|
+
const tool = defineTool({
|
|
192
|
+
name: "echo",
|
|
193
|
+
description: "d",
|
|
194
|
+
parameters: EchoSchema,
|
|
195
|
+
execute: () => "ok",
|
|
196
|
+
});
|
|
197
|
+
it("finds a tool passed directly", () => {
|
|
198
|
+
expect(extractCustomTool(tool)).toBe(tool);
|
|
199
|
+
});
|
|
200
|
+
it("finds a default export", () => {
|
|
201
|
+
expect(extractCustomTool({ default: tool })).toBe(tool);
|
|
202
|
+
});
|
|
203
|
+
it("finds a nested default (esbuild interop)", () => {
|
|
204
|
+
expect(extractCustomTool({ default: { default: tool } })).toBe(tool);
|
|
205
|
+
});
|
|
206
|
+
it("finds a named export", () => {
|
|
207
|
+
expect(extractCustomTool({ myTool: tool })).toBe(tool);
|
|
208
|
+
});
|
|
209
|
+
it("throws a helpful error when no tool is present", () => {
|
|
210
|
+
expect(() => extractCustomTool({ foo: 1 })).toThrow(/no custom tool|export default/i);
|
|
211
|
+
});
|
|
212
|
+
it("surfaces validation errors for a near-miss default export", () => {
|
|
213
|
+
const broken = { __custom: true, name: "Bad Name", description: "d", parameters: EchoSchema, execute: () => "x" };
|
|
214
|
+
expect(() => extractCustomTool({ default: broken })).toThrow(/snake_case|invalid/i);
|
|
215
|
+
});
|
|
216
|
+
});
|
|
217
|
+
describe("loadCustomToolBundle", () => {
|
|
218
|
+
let dir;
|
|
219
|
+
beforeEach(async () => {
|
|
220
|
+
dir = await mkdtemp(join(tmpdir(), "polpo-tool-"));
|
|
221
|
+
});
|
|
222
|
+
afterEach(async () => {
|
|
223
|
+
await rm(dir, { recursive: true, force: true });
|
|
224
|
+
});
|
|
225
|
+
it("imports a bundle file, binds ctx, and runs", async () => {
|
|
226
|
+
const file = join(dir, "echo.mjs");
|
|
227
|
+
await writeFile(file, `export default {
|
|
228
|
+
__custom: true,
|
|
229
|
+
name: "echo",
|
|
230
|
+
label: "Echo",
|
|
231
|
+
description: "echoes",
|
|
232
|
+
parameters: { type: "object", properties: { msg: { type: "string" } } },
|
|
233
|
+
execute: async (ctx, params) => "echo: " + params.msg + " @ " + ctx.workDir,
|
|
234
|
+
};`);
|
|
235
|
+
const pt = await loadCustomToolBundle(file, fakeCtx({ workDir: "/sandbox" }));
|
|
236
|
+
expect(pt.name).toBe("echo");
|
|
237
|
+
expect(pt.label).toBe("Echo");
|
|
238
|
+
const res = await pt.execute("c", { msg: "hi" });
|
|
239
|
+
expect(res.content[0]).toEqual({ type: "text", text: "echo: hi @ /sandbox" });
|
|
240
|
+
});
|
|
241
|
+
it("accepts an already-imported module object", async () => {
|
|
242
|
+
const tool = defineTool({ name: "echo", description: "d", parameters: EchoSchema, execute: () => "ok" });
|
|
243
|
+
const pt = await loadCustomToolBundle({ default: tool }, fakeCtx());
|
|
244
|
+
expect(pt.name).toBe("echo");
|
|
245
|
+
expect((await pt.execute("c", { msg: "x" })).content[0]).toEqual({ type: "text", text: "ok" });
|
|
246
|
+
});
|
|
247
|
+
it("rejects a bundle with no valid tool", async () => {
|
|
248
|
+
const file = join(dir, "bad.mjs");
|
|
249
|
+
await writeFile(file, `export const notATool = 42;`);
|
|
250
|
+
await expect(loadCustomToolBundle(file, fakeCtx())).rejects.toThrow(/no custom tool|export default/i);
|
|
251
|
+
});
|
|
252
|
+
});
|
|
253
|
+
//# sourceMappingURL=custom-tools.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"custom-tools.test.js","sourceRoot":"","sources":["../../src/__tests__/custom-tools.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* defineTool — native custom tools (Phase 1: authoring + validation + binding).
|
|
3
|
+
*
|
|
4
|
+
* Devs author a tool with capability-injected `ctx` (no ambient globals):
|
|
5
|
+
*
|
|
6
|
+
* export default defineTool({
|
|
7
|
+
* name: "create_invoice",
|
|
8
|
+
* description: "Create an invoice for a customer",
|
|
9
|
+
* parameters: Type.Object({ customerId: Type.String(), amount: Type.Number() }),
|
|
10
|
+
* async execute(ctx, params) {
|
|
11
|
+
* const res = await ctx.polpo.invoices.create(params);
|
|
12
|
+
* return `Created invoice ${res.id}`;
|
|
13
|
+
* },
|
|
14
|
+
* });
|
|
15
|
+
*
|
|
16
|
+
* At runtime the cloud bundles + executes this inside the per-project sandbox
|
|
17
|
+
* (Phases 2–3); for OSS self-host it runs in-process via {@link loadCustomToolBundle}.
|
|
18
|
+
* Both paths converge on {@link bindCustomTool}, which adapts the ctx-based
|
|
19
|
+
* `execute(ctx, params)` to the standard {@link PolpoTool} signature.
|
|
20
|
+
*/
|
|
21
|
+
import type { TSchema, Static } from "@sinclair/typebox";
|
|
22
|
+
import type { FileSystem } from "@polpo-ai/core/filesystem";
|
|
23
|
+
import type { Shell } from "@polpo-ai/core/shell";
|
|
24
|
+
import type { PolpoTool, ToolResult, ToolUpdateCallback } from "@polpo-ai/core";
|
|
25
|
+
import type { ResolvedVault } from "./types.js";
|
|
26
|
+
/**
|
|
27
|
+
* Capabilities injected into a custom tool's `execute`. Everything a tool can
|
|
28
|
+
* touch arrives here — there are no ambient globals or platform env access.
|
|
29
|
+
*/
|
|
30
|
+
export interface CustomToolContext {
|
|
31
|
+
/** Sandboxed filesystem rooted at the project workspace. */
|
|
32
|
+
fs: FileSystem;
|
|
33
|
+
/** Shell for running commands in the workspace. */
|
|
34
|
+
shell: Shell;
|
|
35
|
+
/** Agent vault — resolved credentials (API keys, SMTP, …). */
|
|
36
|
+
vault: ResolvedVault;
|
|
37
|
+
/** Safe environment variables (platform secrets stripped). */
|
|
38
|
+
env: Record<string, string | undefined>;
|
|
39
|
+
/** Absolute working directory inside the workspace. */
|
|
40
|
+
workDir: string;
|
|
41
|
+
/** Preconfigured Polpo SDK client, scoped to the project. Typed loosely in v1. */
|
|
42
|
+
polpo?: unknown;
|
|
43
|
+
/** Abort signal for this tool call. */
|
|
44
|
+
signal?: AbortSignal;
|
|
45
|
+
/** Stream partial results back to the runtime. */
|
|
46
|
+
onUpdate?: ToolUpdateCallback;
|
|
47
|
+
}
|
|
48
|
+
/** A custom tool's return value — a plain string (wrapped as text) or a full ToolResult. */
|
|
49
|
+
export type CustomToolExecuteResult = string | ToolResult;
|
|
50
|
+
/** The object passed to {@link defineTool}. */
|
|
51
|
+
export interface CustomToolSpec<T extends TSchema = TSchema> {
|
|
52
|
+
/** Unique, snake_case identifier exposed to the model. */
|
|
53
|
+
name: string;
|
|
54
|
+
/** What the tool does — shown to the model. */
|
|
55
|
+
description: string;
|
|
56
|
+
/** TypeBox schema for the tool arguments. */
|
|
57
|
+
parameters: T;
|
|
58
|
+
/** Human-friendly label for UIs. Defaults to `name`. */
|
|
59
|
+
label?: string;
|
|
60
|
+
/** Run on the client instead of the sandbox (plumbed in a later phase). */
|
|
61
|
+
clientSide?: boolean;
|
|
62
|
+
/** Tool body. Receives injected capabilities + validated params. */
|
|
63
|
+
execute: (ctx: CustomToolContext, params: Static<T>) => CustomToolExecuteResult | Promise<CustomToolExecuteResult>;
|
|
64
|
+
}
|
|
65
|
+
/** A defined custom tool — a {@link CustomToolSpec} tagged with the `__custom` marker. */
|
|
66
|
+
export interface CustomTool<T extends TSchema = TSchema> extends CustomToolSpec<T> {
|
|
67
|
+
readonly __custom: true;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Authoring helper. Returns the spec tagged with `__custom: true` so the loader
|
|
71
|
+
* and the cloud registry can recognize it. Pure — no side effects.
|
|
72
|
+
*/
|
|
73
|
+
export declare function defineTool<T extends TSchema>(spec: CustomToolSpec<T>): CustomTool<T>;
|
|
74
|
+
/**
|
|
75
|
+
* Validate a candidate tool's shape. Returns human-readable error strings
|
|
76
|
+
* (empty array = valid). Reused by the loader and the cloud `POST /v1/tools`
|
|
77
|
+
* endpoint so authors get identical feedback in the CLI, dashboard and at load.
|
|
78
|
+
*/
|
|
79
|
+
export declare function getCustomToolErrors(value: unknown): string[];
|
|
80
|
+
/** Type guard: a valid custom tool carrying the `__custom` marker. */
|
|
81
|
+
export declare function isCustomTool(value: unknown): value is CustomTool;
|
|
82
|
+
/** Coerce a custom tool's return value into a {@link ToolResult}. */
|
|
83
|
+
export declare function normalizeToolResult(result: CustomToolExecuteResult): ToolResult;
|
|
84
|
+
/** ctx without the per-call fields, which {@link bindCustomTool} supplies itself. */
|
|
85
|
+
export type CustomToolBindContext = Omit<CustomToolContext, "signal" | "onUpdate">;
|
|
86
|
+
/**
|
|
87
|
+
* Adapt a {@link CustomTool} (ctx-based `execute`) into a runtime {@link PolpoTool}
|
|
88
|
+
* (`execute(toolCallId, params, signal?, onUpdate?)`), binding the injected ctx.
|
|
89
|
+
* This is the "wrap at registration" step that lets custom and built-in tools
|
|
90
|
+
* coexist without touching the built-ins.
|
|
91
|
+
*/
|
|
92
|
+
export declare function bindCustomTool<T extends TSchema>(tool: CustomTool<T>, ctx: CustomToolBindContext): PolpoTool<T>;
|
|
93
|
+
/**
|
|
94
|
+
* Find the custom tool inside a (possibly bundled) module's exports. Accepts a
|
|
95
|
+
* tool passed directly, a default export, a nested default (esbuild interop),
|
|
96
|
+
* or the first matching named export. Throws a helpful error otherwise.
|
|
97
|
+
*/
|
|
98
|
+
export declare function extractCustomTool(moduleOrTool: unknown): CustomTool;
|
|
99
|
+
/**
|
|
100
|
+
* Load a custom tool bundle and bind it to a runtime ctx → {@link PolpoTool}.
|
|
101
|
+
* Accepts either a filesystem path to a bundled module (dynamic import — the
|
|
102
|
+
* OSS self-host path) or an already-imported module/tool object.
|
|
103
|
+
*/
|
|
104
|
+
export declare function loadCustomToolBundle(pathOrModule: string | object, ctx: CustomToolBindContext): Promise<PolpoTool>;
|
|
105
|
+
//# sourceMappingURL=custom-tools.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"custom-tools.d.ts","sourceRoot":"","sources":["../src/custom-tools.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import { pathToFileURL } from "node:url";
|
|
2
|
+
/** snake_case: lowercase letter start, then lowercase / digits / underscores. */
|
|
3
|
+
const NAME_RE = /^[a-z][a-z0-9_]*$/;
|
|
4
|
+
/**
|
|
5
|
+
* Authoring helper. Returns the spec tagged with `__custom: true` so the loader
|
|
6
|
+
* and the cloud registry can recognize it. Pure — no side effects.
|
|
7
|
+
*/
|
|
8
|
+
export function defineTool(spec) {
|
|
9
|
+
return { ...spec, __custom: true };
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Validate a candidate tool's shape. Returns human-readable error strings
|
|
13
|
+
* (empty array = valid). Reused by the loader and the cloud `POST /v1/tools`
|
|
14
|
+
* endpoint so authors get identical feedback in the CLI, dashboard and at load.
|
|
15
|
+
*/
|
|
16
|
+
export function getCustomToolErrors(value) {
|
|
17
|
+
if (typeof value !== "object" || value === null) {
|
|
18
|
+
return ["Tool must be an object (did you `export default defineTool({...})`?)"];
|
|
19
|
+
}
|
|
20
|
+
const t = value;
|
|
21
|
+
const errors = [];
|
|
22
|
+
if (typeof t.name !== "string" || t.name.length === 0) {
|
|
23
|
+
errors.push("`name` is required and must be a non-empty string");
|
|
24
|
+
}
|
|
25
|
+
else if (!NAME_RE.test(t.name)) {
|
|
26
|
+
errors.push(`\`name\` must be snake_case (lowercase letters, digits, underscores; starting with a letter): got "${t.name}"`);
|
|
27
|
+
}
|
|
28
|
+
if (typeof t.description !== "string" || t.description.trim().length === 0) {
|
|
29
|
+
errors.push("`description` is required and must be a non-empty string");
|
|
30
|
+
}
|
|
31
|
+
if (typeof t.parameters !== "object" || t.parameters === null) {
|
|
32
|
+
errors.push("`parameters` is required and must be a TypeBox schema object");
|
|
33
|
+
}
|
|
34
|
+
if (typeof t.execute !== "function") {
|
|
35
|
+
errors.push("`execute` is required and must be a function `(ctx, params) => result`");
|
|
36
|
+
}
|
|
37
|
+
if (t.label !== undefined && typeof t.label !== "string") {
|
|
38
|
+
errors.push("`label` must be a string when provided");
|
|
39
|
+
}
|
|
40
|
+
if (t.clientSide !== undefined && typeof t.clientSide !== "boolean") {
|
|
41
|
+
errors.push("`clientSide` must be a boolean when provided");
|
|
42
|
+
}
|
|
43
|
+
return errors;
|
|
44
|
+
}
|
|
45
|
+
/** Type guard: a valid custom tool carrying the `__custom` marker. */
|
|
46
|
+
export function isCustomTool(value) {
|
|
47
|
+
return (typeof value === "object" &&
|
|
48
|
+
value !== null &&
|
|
49
|
+
value.__custom === true &&
|
|
50
|
+
getCustomToolErrors(value).length === 0);
|
|
51
|
+
}
|
|
52
|
+
/** Coerce a custom tool's return value into a {@link ToolResult}. */
|
|
53
|
+
export function normalizeToolResult(result) {
|
|
54
|
+
if (typeof result === "string") {
|
|
55
|
+
return { content: [{ type: "text", text: result }], details: null };
|
|
56
|
+
}
|
|
57
|
+
if (result &&
|
|
58
|
+
typeof result === "object" &&
|
|
59
|
+
Array.isArray(result.content)) {
|
|
60
|
+
return result;
|
|
61
|
+
}
|
|
62
|
+
// Lenient fallback: a tool returned something unexpected — surface it as text
|
|
63
|
+
// rather than crashing the run.
|
|
64
|
+
return { content: [{ type: "text", text: JSON.stringify(result) }], details: result ?? null };
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Adapt a {@link CustomTool} (ctx-based `execute`) into a runtime {@link PolpoTool}
|
|
68
|
+
* (`execute(toolCallId, params, signal?, onUpdate?)`), binding the injected ctx.
|
|
69
|
+
* This is the "wrap at registration" step that lets custom and built-in tools
|
|
70
|
+
* coexist without touching the built-ins.
|
|
71
|
+
*/
|
|
72
|
+
export function bindCustomTool(tool, ctx) {
|
|
73
|
+
return {
|
|
74
|
+
name: tool.name,
|
|
75
|
+
label: tool.label ?? tool.name,
|
|
76
|
+
description: tool.description,
|
|
77
|
+
parameters: tool.parameters,
|
|
78
|
+
async execute(_toolCallId, params, signal, onUpdate) {
|
|
79
|
+
const result = await tool.execute({ ...ctx, signal, onUpdate }, params);
|
|
80
|
+
return normalizeToolResult(result);
|
|
81
|
+
},
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Find the custom tool inside a (possibly bundled) module's exports. Accepts a
|
|
86
|
+
* tool passed directly, a default export, a nested default (esbuild interop),
|
|
87
|
+
* or the first matching named export. Throws a helpful error otherwise.
|
|
88
|
+
*/
|
|
89
|
+
export function extractCustomTool(moduleOrTool) {
|
|
90
|
+
if (isCustomTool(moduleOrTool))
|
|
91
|
+
return moduleOrTool;
|
|
92
|
+
if (typeof moduleOrTool === "object" && moduleOrTool !== null) {
|
|
93
|
+
const mod = moduleOrTool;
|
|
94
|
+
const nestedDefault = mod.default?.default;
|
|
95
|
+
const candidates = [mod.default, nestedDefault, ...Object.values(mod)];
|
|
96
|
+
for (const c of candidates) {
|
|
97
|
+
if (isCustomTool(c))
|
|
98
|
+
return c;
|
|
99
|
+
}
|
|
100
|
+
// Near-miss: a __custom-tagged export that failed validation → surface why.
|
|
101
|
+
const near = candidates.find((c) => typeof c === "object" && c !== null && c.__custom === true);
|
|
102
|
+
if (near) {
|
|
103
|
+
const errs = getCustomToolErrors(near);
|
|
104
|
+
throw new Error(`Invalid custom tool:\n- ${errs.join("\n- ")}`);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
throw new Error("No custom tool found in module. Expected `export default defineTool({...})`.");
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Load a custom tool bundle and bind it to a runtime ctx → {@link PolpoTool}.
|
|
111
|
+
* Accepts either a filesystem path to a bundled module (dynamic import — the
|
|
112
|
+
* OSS self-host path) or an already-imported module/tool object.
|
|
113
|
+
*/
|
|
114
|
+
export async function loadCustomToolBundle(pathOrModule, ctx) {
|
|
115
|
+
const mod = typeof pathOrModule === "string"
|
|
116
|
+
? await import(pathToFileURL(pathOrModule).href)
|
|
117
|
+
: pathOrModule;
|
|
118
|
+
const tool = extractCustomTool(mod);
|
|
119
|
+
return bindCustomTool(tool, ctx);
|
|
120
|
+
}
|
|
121
|
+
//# sourceMappingURL=custom-tools.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"custom-tools.js","sourceRoot":"","sources":["../src/custom-tools.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -31,5 +31,7 @@ export { NodeShell } from "./adapters/node-shell.js";
|
|
|
31
31
|
export { assertPathAllowed, resolveAllowedPaths, isPathAllowed } from "./path-sandbox.js";
|
|
32
32
|
export { safeEnv, bashSafeEnv } from "./safe-env.js";
|
|
33
33
|
export { assertUrlAllowed } from "./ssrf-guard.js";
|
|
34
|
+
export { defineTool, getCustomToolErrors, isCustomTool, normalizeToolResult, bindCustomTool, extractCustomTool, loadCustomToolBundle, } from "./custom-tools.js";
|
|
35
|
+
export type { CustomTool, CustomToolSpec, CustomToolContext, CustomToolBindContext, CustomToolExecuteResult, } from "./custom-tools.js";
|
|
34
36
|
export type { ResolvedVault } from "./types.js";
|
|
35
37
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAGH,OAAO,EAAE,iBAAiB,EAAE,iBAAiB,IAAI,iBAAiB,EAAE,cAAc,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACnK,YAAY,EAAE,gBAAgB,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AAGjF,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AACxD,OAAO,EAAE,eAAe,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AACvE,OAAO,EAAE,oBAAoB,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAChG,OAAO,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AACvD,YAAY,EAAE,aAAa,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAGpF,OAAO,EAAE,kBAAkB,EAAE,sBAAsB,EAAE,0BAA0B,EAAE,MAAM,oBAAoB,CAAC;AAC5G,OAAO,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAC1E,OAAO,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAC1E,OAAO,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AACpE,OAAO,EAAE,eAAe,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AACvE,OAAO,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAC1E,OAAO,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAC1E,OAAO,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AAG7E,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAGtD,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAC/D,OAAO,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AAGrD,OAAO,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAC1F,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AACrD,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAGnD,YAAY,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAGH,OAAO,EAAE,iBAAiB,EAAE,iBAAiB,IAAI,iBAAiB,EAAE,cAAc,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACnK,YAAY,EAAE,gBAAgB,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AAGjF,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AACxD,OAAO,EAAE,eAAe,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AACvE,OAAO,EAAE,oBAAoB,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAChG,OAAO,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AACvD,YAAY,EAAE,aAAa,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAGpF,OAAO,EAAE,kBAAkB,EAAE,sBAAsB,EAAE,0BAA0B,EAAE,MAAM,oBAAoB,CAAC;AAC5G,OAAO,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAC1E,OAAO,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAC1E,OAAO,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AACpE,OAAO,EAAE,eAAe,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AACvE,OAAO,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAC1E,OAAO,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAC1E,OAAO,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AAG7E,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAGtD,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAC/D,OAAO,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AAGrD,OAAO,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAC1F,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AACrD,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAGnD,OAAO,EACL,UAAU,EACV,mBAAmB,EACnB,YAAY,EACZ,mBAAmB,EACnB,cAAc,EACd,iBAAiB,EACjB,oBAAoB,GACrB,MAAM,mBAAmB,CAAC;AAC3B,YAAY,EACV,UAAU,EACV,cAAc,EACd,iBAAiB,EACjB,qBAAqB,EACrB,uBAAuB,GACxB,MAAM,mBAAmB,CAAC;AAG3B,YAAY,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -36,4 +36,6 @@ export { NodeShell } from "./adapters/node-shell.js";
|
|
|
36
36
|
export { assertPathAllowed, resolveAllowedPaths, isPathAllowed } from "./path-sandbox.js";
|
|
37
37
|
export { safeEnv, bashSafeEnv } from "./safe-env.js";
|
|
38
38
|
export { assertUrlAllowed } from "./ssrf-guard.js";
|
|
39
|
+
// Custom tools (defineTool)
|
|
40
|
+
export { defineTool, getCustomToolErrors, isCustomTool, normalizeToolResult, bindCustomTool, extractCustomTool, loadCustomToolBundle, } from "./custom-tools.js";
|
|
39
41
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,oBAAoB;AACpB,OAAO,EAAE,iBAAiB,EAAE,iBAAiB,IAAI,iBAAiB,EAAE,cAAc,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAGnK,qDAAqD;AACrD,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AACxD,OAAO,EAAE,eAAe,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AACvE,OAAO,EAAE,oBAAoB,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAChG,OAAO,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AAGvD,0BAA0B;AAC1B,OAAO,EAAE,kBAAkB,EAAE,sBAAsB,EAAE,0BAA0B,EAAE,MAAM,oBAAoB,CAAC;AAC5G,OAAO,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAC1E,OAAO,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAC1E,OAAO,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AACpE,OAAO,EAAE,eAAe,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AACvE,OAAO,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAC1E,OAAO,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAC1E,OAAO,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AAC7E,0DAA0D;AAC1D,0CAA0C;AAC1C,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAEtD,8CAA8C;AAC9C,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAC/D,OAAO,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AAErD,qBAAqB;AACrB,OAAO,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAC1F,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AACrD,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,oBAAoB;AACpB,OAAO,EAAE,iBAAiB,EAAE,iBAAiB,IAAI,iBAAiB,EAAE,cAAc,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAGnK,qDAAqD;AACrD,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AACxD,OAAO,EAAE,eAAe,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AACvE,OAAO,EAAE,oBAAoB,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAChG,OAAO,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AAGvD,0BAA0B;AAC1B,OAAO,EAAE,kBAAkB,EAAE,sBAAsB,EAAE,0BAA0B,EAAE,MAAM,oBAAoB,CAAC;AAC5G,OAAO,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAC1E,OAAO,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAC1E,OAAO,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AACpE,OAAO,EAAE,eAAe,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AACvE,OAAO,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAC1E,OAAO,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAC1E,OAAO,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AAC7E,0DAA0D;AAC1D,0CAA0C;AAC1C,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAEtD,8CAA8C;AAC9C,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAC/D,OAAO,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AAErD,qBAAqB;AACrB,OAAO,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAC1F,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AACrD,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAEnD,4BAA4B;AAC5B,OAAO,EACL,UAAU,EACV,mBAAmB,EACnB,YAAY,EACZ,mBAAmB,EACnB,cAAc,EACd,iBAAiB,EACjB,oBAAoB,GACrB,MAAM,mBAAmB,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@polpo-ai/tools",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.8.0",
|
|
4
4
|
"description": "Agent tools for Polpo — coding, browser, email, search, and more. Core tools work everywhere, extended tools are opt-in.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
21
21
|
"@sinclair/typebox": "^0.34.0",
|
|
22
22
|
"nanoid": "^5.0.0",
|
|
23
|
-
"@polpo-ai/core": "0.
|
|
23
|
+
"@polpo-ai/core": "0.8.0"
|
|
24
24
|
},
|
|
25
25
|
"optionalDependencies": {
|
|
26
26
|
"@ai-sdk/anthropic": "^2.0.79",
|