@jaypie/mcp 0.2.3 → 0.2.5

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,411 @@
1
+ ---
2
+ description: Commander.js CLI integration with serviceHandler callbacks (onMessage, onComplete, onError, onFatal)
3
+ include: "**/cli/**"
4
+ ---
5
+
6
+ # Jaypie Vocabulary Commander Adapter
7
+
8
+ The Commander adapter (`@jaypie/vocabulary/commander`) integrates Jaypie service handlers with Commander.js CLI applications, providing automatic option generation, type coercion, and callback hooks for progress reporting.
9
+
10
+ **See also:** [Jaypie_Vocabulary_Package.md](Jaypie_Vocabulary_Package.md) for core serviceHandler documentation.
11
+
12
+ ## Installation
13
+
14
+ ```bash
15
+ npm install @jaypie/vocabulary commander
16
+ ```
17
+
18
+ ## Quick Start
19
+
20
+ ```typescript
21
+ import { Command } from "commander";
22
+ import { serviceHandler } from "@jaypie/vocabulary";
23
+ import { registerServiceCommand } from "@jaypie/vocabulary/commander";
24
+
25
+ const handler = serviceHandler({
26
+ alias: "greet",
27
+ description: "Greet a user",
28
+ input: {
29
+ userName: { type: String, flag: "user", letter: "u" },
30
+ loud: { type: Boolean, letter: "l", default: false },
31
+ },
32
+ service: ({ loud, userName }) => {
33
+ const greeting = `Hello, ${userName}!`;
34
+ console.log(loud ? greeting.toUpperCase() : greeting);
35
+ },
36
+ });
37
+
38
+ const program = new Command();
39
+ registerServiceCommand({ handler, program });
40
+ program.parse();
41
+ // Usage: greet --user Alice -l
42
+ ```
43
+
44
+ ## registerServiceCommand
45
+
46
+ The primary function for registering a service handler as a Commander command.
47
+
48
+ ### Options
49
+
50
+ | Option | Type | Description |
51
+ |--------|------|-------------|
52
+ | `handler` | `ServiceHandlerFunction` | Required. The service handler to register |
53
+ | `program` | `Command` | Required. Commander program or command |
54
+ | `name` | `string` | Override command name (default: handler.alias) |
55
+ | `description` | `string` | Override description (default: handler.description) |
56
+ | `exclude` | `string[]` | Field names to exclude from CLI options |
57
+ | `onComplete` | `OnCompleteCallback` | Called with handler's return value on success |
58
+ | `onError` | `OnErrorCallback` | Receives errors reported via `context.onError()` |
59
+ | `onFatal` | `OnFatalCallback` | Receives fatal errors (thrown or via `context.onFatal()`) |
60
+ | `onMessage` | `OnMessageCallback` | Receives messages from `context.sendMessage` |
61
+ | `overrides` | `Record<string, override>` | Per-field option overrides |
62
+
63
+ ## Callback Hooks
64
+
65
+ ### onMessage
66
+
67
+ Receives progress messages sent by the service via `context.sendMessage`:
68
+
69
+ ```typescript
70
+ import { Command } from "commander";
71
+ import { serviceHandler } from "@jaypie/vocabulary";
72
+ import { registerServiceCommand } from "@jaypie/vocabulary/commander";
73
+
74
+ const handler = serviceHandler({
75
+ alias: "process",
76
+ input: { jobId: { type: String, letter: "j" } },
77
+ service: async ({ jobId }, context) => {
78
+ // Send progress messages during execution
79
+ context?.sendMessage?.({ content: `Starting job ${jobId}` });
80
+
81
+ // Simulate work
82
+ await doStep1();
83
+ context?.sendMessage?.({ content: "Step 1 complete", level: "debug" });
84
+
85
+ await doStep2();
86
+ context?.sendMessage?.({ content: "Step 2 complete", level: "debug" });
87
+
88
+ context?.sendMessage?.({ content: "Job finished!", level: "info" });
89
+ return { jobId, status: "complete" };
90
+ },
91
+ });
92
+
93
+ const program = new Command();
94
+ registerServiceCommand({
95
+ handler,
96
+ program,
97
+ onMessage: (msg) => {
98
+ // msg: { content: string, level?: "trace"|"debug"|"info"|"warn"|"error" }
99
+ const level = msg.level || "info";
100
+ console[level](msg.content);
101
+ },
102
+ });
103
+ program.parse();
104
+ ```
105
+
106
+ **Important:** Errors in `onMessage` are swallowed to ensure messaging failures never halt service execution.
107
+
108
+ ### onComplete
109
+
110
+ Called with the handler's return value on successful completion:
111
+
112
+ ```typescript
113
+ registerServiceCommand({
114
+ handler,
115
+ program,
116
+ onComplete: (response) => {
117
+ // Called after service completes successfully
118
+ console.log("Result:", JSON.stringify(response, null, 2));
119
+
120
+ // Common patterns:
121
+ // - Save results to file
122
+ // - Display formatted output
123
+ // - Trigger follow-up actions
124
+ },
125
+ });
126
+ ```
127
+
128
+ ### onError
129
+
130
+ Receives errors that the service explicitly reports via `context.onError()`. Use this for recoverable errors that don't halt execution:
131
+
132
+ ```typescript
133
+ registerServiceCommand({
134
+ handler,
135
+ program,
136
+ onError: (error) => {
137
+ // Log recoverable errors
138
+ console.warn("Warning:", error.message);
139
+ },
140
+ });
141
+ ```
142
+
143
+ ### onFatal
144
+
145
+ Receives fatal errors - either thrown errors or errors reported via `context.onFatal()`. Any error that escapes the service (is thrown) is treated as fatal:
146
+
147
+ ```typescript
148
+ registerServiceCommand({
149
+ handler,
150
+ program,
151
+ onFatal: (error) => {
152
+ console.error("Fatal error:", error.message);
153
+ process.exit(1);
154
+ },
155
+ });
156
+ ```
157
+
158
+ **Error handling priority:**
159
+ 1. If `onFatal` is provided, thrown errors go to `onFatal`
160
+ 2. If only `onError` is provided, thrown errors fall back to `onError`
161
+ 3. If neither is provided, errors are re-thrown
162
+
163
+ ## Complete Example with All Callbacks
164
+
165
+ ```typescript
166
+ import { Command } from "commander";
167
+ import { serviceHandler } from "@jaypie/vocabulary";
168
+ import { registerServiceCommand } from "@jaypie/vocabulary/commander";
169
+
170
+ const evaluateHandler = serviceHandler({
171
+ alias: "evaluate",
172
+ description: "Run an evaluation job",
173
+ input: {
174
+ jobId: {
175
+ type: String,
176
+ flag: "job",
177
+ letter: "j",
178
+ description: "Job identifier",
179
+ },
180
+ priority: {
181
+ type: [1, 2, 3, 4, 5],
182
+ default: 3,
183
+ letter: "p",
184
+ description: "Job priority (1-5)",
185
+ },
186
+ tags: {
187
+ type: [String],
188
+ letter: "t",
189
+ required: false,
190
+ description: "Tags to apply",
191
+ },
192
+ dryRun: {
193
+ type: Boolean,
194
+ letter: "d",
195
+ default: false,
196
+ description: "Run without executing",
197
+ },
198
+ },
199
+ service: async ({ dryRun, jobId, priority, tags }, context) => {
200
+ context?.sendMessage?.({ content: `Initializing job ${jobId}...` });
201
+
202
+ if (dryRun) {
203
+ context?.sendMessage?.({ content: "Dry run mode - skipping execution", level: "warn" });
204
+ return { jobId, status: "dry-run", skipped: true };
205
+ }
206
+
207
+ // Handle recoverable errors without throwing
208
+ try {
209
+ await riskyOperation();
210
+ } catch (err) {
211
+ context?.onError?.(err); // Reports error but continues
212
+ }
213
+
214
+ context?.sendMessage?.({ content: `Running with priority ${priority}` });
215
+
216
+ if (tags?.length) {
217
+ context?.sendMessage?.({ content: `Applying tags: ${tags.join(", ")}`, level: "debug" });
218
+ }
219
+
220
+ // Simulate processing
221
+ for (let i = 1; i <= 5; i++) {
222
+ await new Promise(resolve => setTimeout(resolve, 100));
223
+ context?.sendMessage?.({ content: `Progress: ${i * 20}%`, level: "debug" });
224
+ }
225
+
226
+ context?.sendMessage?.({ content: "Evaluation complete!" });
227
+ return { jobId, status: "complete", results: 42 };
228
+ },
229
+ });
230
+
231
+ const program = new Command();
232
+ program.version("1.0.0").description("Evaluation CLI");
233
+
234
+ registerServiceCommand({
235
+ handler: evaluateHandler,
236
+ program,
237
+ onMessage: (msg) => {
238
+ const prefix = msg.level === "warn" ? "WARNING: " :
239
+ msg.level === "error" ? "ERROR: " : "";
240
+ console.log(`${prefix}${msg.content}`);
241
+ },
242
+ onComplete: (response) => {
243
+ console.log("\n--- Results ---");
244
+ console.log(JSON.stringify(response, null, 2));
245
+ },
246
+ onError: (error) => {
247
+ // Recoverable errors reported via context.onError()
248
+ console.warn("Warning:", error.message);
249
+ },
250
+ onFatal: (error) => {
251
+ // Fatal errors (thrown or via context.onFatal())
252
+ console.error("\nFatal:", error.message);
253
+ process.exit(1);
254
+ },
255
+ });
256
+
257
+ program.parse();
258
+ ```
259
+
260
+ Usage:
261
+ ```bash
262
+ # Basic execution
263
+ cli evaluate --job abc123
264
+
265
+ # With all options
266
+ cli evaluate -j abc123 -p 1 -t urgent -t critical --dry-run
267
+
268
+ # Help
269
+ cli evaluate --help
270
+ ```
271
+
272
+ ## Input Flag and Letter Properties
273
+
274
+ Define CLI flags directly in input definitions:
275
+
276
+ ```typescript
277
+ input: {
278
+ userName: {
279
+ type: String,
280
+ flag: "user", // Long flag: --user (instead of --user-name)
281
+ letter: "u", // Short flag: -u
282
+ description: "User name to greet",
283
+ },
284
+ verbose: {
285
+ type: Boolean,
286
+ letter: "v", // -v
287
+ },
288
+ }
289
+ // Generates: --user <userName>, -u and --verbose, -v
290
+ ```
291
+
292
+ ### Naming Convention
293
+
294
+ | Property | CLI Flag | Example |
295
+ |----------|----------|---------|
296
+ | `userName` (camelCase) | `--user-name` | Default behavior |
297
+ | `flag: "user"` | `--user` | Override long flag |
298
+ | `letter: "u"` | `-u` | Short flag |
299
+
300
+ ## Boolean Flag Behavior
301
+
302
+ Commander.js automatically handles boolean flags:
303
+ - `--verbose` sets to `true`
304
+ - `--no-verbose` sets to `false` (for flags with `default: true`)
305
+
306
+ ## Manual Integration
307
+
308
+ For more control, use `createCommanderOptions` and `parseCommanderOptions`:
309
+
310
+ ```typescript
311
+ import { Command } from "commander";
312
+ import { serviceHandler } from "@jaypie/vocabulary";
313
+ import {
314
+ createCommanderOptions,
315
+ parseCommanderOptions,
316
+ } from "@jaypie/vocabulary/commander";
317
+
318
+ const handler = serviceHandler({
319
+ input: {
320
+ userName: { type: String, description: "User name" },
321
+ maxRetries: { type: Number, default: 3 },
322
+ verbose: { type: Boolean },
323
+ },
324
+ service: (input) => console.log(input),
325
+ });
326
+
327
+ const program = new Command();
328
+
329
+ // Create options from handler input
330
+ const { options } = createCommanderOptions(handler.input, {
331
+ exclude: ["internalField"],
332
+ overrides: {
333
+ userName: { short: "u", description: "Override description" },
334
+ },
335
+ });
336
+ options.forEach((opt) => program.addOption(opt));
337
+
338
+ // Wire up action
339
+ program.action(async (opts) => {
340
+ const input = parseCommanderOptions(opts, { input: handler.input });
341
+ await handler(input);
342
+ });
343
+
344
+ program.parse();
345
+ ```
346
+
347
+ ## TypeScript Types
348
+
349
+ ```typescript
350
+ import type {
351
+ CommanderOptionOverride,
352
+ CreateCommanderOptionsConfig,
353
+ CreateCommanderOptionsResult,
354
+ OnCompleteCallback,
355
+ OnErrorCallback,
356
+ OnFatalCallback,
357
+ OnMessageCallback,
358
+ ParseCommanderOptionsConfig,
359
+ RegisterServiceCommandConfig,
360
+ RegisterServiceCommandResult,
361
+ } from "@jaypie/vocabulary/commander";
362
+ ```
363
+
364
+ ### Callback Type Definitions
365
+
366
+ ```typescript
367
+ // Message received from context.sendMessage
368
+ interface Message {
369
+ content: string;
370
+ level?: "trace" | "debug" | "info" | "warn" | "error";
371
+ }
372
+
373
+ // onMessage callback
374
+ type OnMessageCallback = (message: Message) => void | Promise<void>;
375
+
376
+ // onComplete callback - receives handler return value
377
+ type OnCompleteCallback<T = unknown> = (response: T) => void | Promise<void>;
378
+
379
+ // onError callback - receives errors from context.onError()
380
+ type OnErrorCallback = (error: unknown) => void | Promise<void>;
381
+
382
+ // onFatal callback - receives fatal errors (thrown or context.onFatal())
383
+ type OnFatalCallback = (error: unknown) => void | Promise<void>;
384
+ ```
385
+
386
+ ## Exports
387
+
388
+ ```typescript
389
+ // @jaypie/vocabulary/commander
390
+ export { createCommanderOptions } from "./createCommanderOptions.js";
391
+ export { parseCommanderOptions } from "./parseCommanderOptions.js";
392
+ export { registerServiceCommand } from "./registerServiceCommand.js";
393
+
394
+ export type {
395
+ CommanderOptionOverride,
396
+ CreateCommanderOptionsConfig,
397
+ CreateCommanderOptionsResult,
398
+ OnCompleteCallback,
399
+ OnErrorCallback,
400
+ OnFatalCallback,
401
+ OnMessageCallback,
402
+ ParseCommanderOptionsConfig,
403
+ RegisterServiceCommandConfig,
404
+ RegisterServiceCommandResult,
405
+ } from "./types.js";
406
+ ```
407
+
408
+ ## Related
409
+
410
+ - [Jaypie_Commander_CLI_Package.md](Jaypie_Commander_CLI_Package.md) - Setting up a Commander CLI project from scratch
411
+ - [Jaypie_Vocabulary_Package.md](Jaypie_Vocabulary_Package.md) - Core serviceHandler and type coercion
@@ -0,0 +1,312 @@
1
+ ---
2
+ description: LLM tool creation from serviceHandler for use with @jaypie/llm Toolkit
3
+ ---
4
+
5
+ # Jaypie Vocabulary LLM Adapter
6
+
7
+ The LLM adapter (`@jaypie/vocabulary/llm`) creates LLM tools from Jaypie service handlers for use with `@jaypie/llm` Toolkit, automatically generating JSON Schema from input definitions.
8
+
9
+ **See also:** [Jaypie_Vocabulary_Package.md](Jaypie_Vocabulary_Package.md) for core serviceHandler documentation.
10
+
11
+ ## Installation
12
+
13
+ ```bash
14
+ npm install @jaypie/vocabulary @jaypie/llm
15
+ ```
16
+
17
+ ## Quick Start
18
+
19
+ ```typescript
20
+ import { serviceHandler } from "@jaypie/vocabulary";
21
+ import { createLlmTool } from "@jaypie/vocabulary/llm";
22
+ import { Toolkit } from "@jaypie/llm";
23
+
24
+ const handler = serviceHandler({
25
+ alias: "greet",
26
+ description: "Greet a user by name",
27
+ input: {
28
+ userName: { type: String, description: "The user's name" },
29
+ loud: { type: Boolean, default: false, description: "Shout the greeting" },
30
+ },
31
+ service: ({ userName, loud }) => {
32
+ const greeting = `Hello, ${userName}!`;
33
+ return loud ? greeting.toUpperCase() : greeting;
34
+ },
35
+ });
36
+
37
+ const { tool } = createLlmTool({ handler });
38
+ const toolkit = new Toolkit([tool]);
39
+ ```
40
+
41
+ ## createLlmTool
42
+
43
+ Creates an LLM tool from a serviceHandler.
44
+
45
+ ### Options
46
+
47
+ | Option | Type | Description |
48
+ |--------|------|-------------|
49
+ | `handler` | `ServiceHandlerFunction` | Required. The service handler to adapt |
50
+ | `name` | `string` | Override tool name (defaults to handler.alias) |
51
+ | `description` | `string` | Override tool description (defaults to handler.description) |
52
+ | `message` | `string \| function` | Custom message for logging |
53
+ | `exclude` | `string[]` | Fields to exclude from tool parameters |
54
+ | `onComplete` | `OnCompleteCallback` | Called with tool's return value on success |
55
+ | `onError` | `OnErrorCallback` | Receives errors reported via `context.onError()` in service |
56
+ | `onFatal` | `OnFatalCallback` | Receives fatal errors (thrown or via `context.onFatal()`) |
57
+ | `onMessage` | `OnMessageCallback` | Receives messages from `context.sendMessage` in service |
58
+
59
+ ### Basic Usage
60
+
61
+ ```typescript
62
+ import { serviceHandler } from "@jaypie/vocabulary";
63
+ import { createLlmTool } from "@jaypie/vocabulary/llm";
64
+
65
+ const calculateHandler = serviceHandler({
66
+ alias: "calculate",
67
+ description: "Perform a mathematical calculation",
68
+ input: {
69
+ operation: { type: ["add", "subtract", "multiply", "divide"] },
70
+ a: { type: Number, description: "First operand" },
71
+ b: { type: Number, description: "Second operand" },
72
+ },
73
+ service: ({ operation, a, b }) => {
74
+ switch (operation) {
75
+ case "add": return a + b;
76
+ case "subtract": return a - b;
77
+ case "multiply": return a * b;
78
+ case "divide": return a / b;
79
+ }
80
+ },
81
+ });
82
+
83
+ const { tool } = createLlmTool({ handler: calculateHandler });
84
+
85
+ // Tool has these properties:
86
+ // tool.name: "calculate"
87
+ // tool.description: "Perform a mathematical calculation"
88
+ // tool.parameters: JSON Schema for inputs
89
+ // tool.function: The callable function
90
+ ```
91
+
92
+ ### Overriding Name and Description
93
+
94
+ ```typescript
95
+ const { tool } = createLlmTool({
96
+ handler,
97
+ name: "math_calculator",
98
+ description: "A tool for performing basic math operations",
99
+ });
100
+ ```
101
+
102
+ ### Excluding Fields
103
+
104
+ ```typescript
105
+ const handler = serviceHandler({
106
+ alias: "search",
107
+ input: {
108
+ query: { type: String },
109
+ limit: { type: Number, default: 10 },
110
+ _internalId: { type: String }, // Internal field
111
+ },
112
+ service: async (params) => { /* ... */ },
113
+ });
114
+
115
+ const { tool } = createLlmTool({
116
+ handler,
117
+ exclude: ["_internalId"], // Not exposed to LLM
118
+ });
119
+ ```
120
+
121
+ ### Lifecycle Callbacks
122
+
123
+ Services can use context callbacks to report progress, errors, and completion:
124
+
125
+ ```typescript
126
+ const handler = serviceHandler({
127
+ alias: "evaluate",
128
+ input: { jobId: { type: String } },
129
+ service: async ({ jobId }, context) => {
130
+ context?.sendMessage?.({ content: `Processing ${jobId}` });
131
+
132
+ try {
133
+ await riskyOperation();
134
+ } catch (err) {
135
+ context?.onError?.(err); // Reports error but continues
136
+ }
137
+
138
+ return { jobId, status: "complete" };
139
+ },
140
+ });
141
+
142
+ const { tool } = createLlmTool({
143
+ handler,
144
+ onComplete: (result) => console.log("Tool completed:", result),
145
+ onError: (error) => console.warn("Recoverable error:", error),
146
+ onFatal: (error) => console.error("Fatal error:", error),
147
+ onMessage: (msg) => console.log(`[${msg.level || "info"}] ${msg.content}`),
148
+ });
149
+ ```
150
+
151
+ **Error handling**: Services receive `context.onError()` and `context.onFatal()` callbacks to report errors without throwing. Any error that escapes the service (is thrown) is treated as fatal and routes to `onFatal`. If `onFatal` is not provided, thrown errors fall back to `onError`. Callback errors are swallowed to ensure failures never halt service execution.
152
+
153
+ ## inputToJsonSchema
154
+
155
+ Converts vocabulary input definitions to JSON Schema:
156
+
157
+ ```typescript
158
+ import { inputToJsonSchema } from "@jaypie/vocabulary/llm";
159
+
160
+ const schema = inputToJsonSchema({
161
+ userName: { type: String, description: "User's name" },
162
+ age: { type: Number, required: false },
163
+ role: { type: ["admin", "user", "guest"], default: "user" },
164
+ });
165
+
166
+ // Returns:
167
+ {
168
+ type: "object",
169
+ properties: {
170
+ userName: { type: "string", description: "User's name" },
171
+ age: { type: "number" },
172
+ role: { type: "string", enum: ["admin", "user", "guest"] },
173
+ },
174
+ required: ["userName"],
175
+ }
176
+ ```
177
+
178
+ ### Type Mappings
179
+
180
+ | Vocabulary Type | JSON Schema |
181
+ |-----------------|-------------|
182
+ | `String` | `{ type: "string" }` |
183
+ | `Number` | `{ type: "number" }` |
184
+ | `Boolean` | `{ type: "boolean" }` |
185
+ | `Array` | `{ type: "array" }` |
186
+ | `Object` | `{ type: "object" }` |
187
+ | `[String]` | `{ type: "array", items: { type: "string" } }` |
188
+ | `[Number]` | `{ type: "array", items: { type: "number" } }` |
189
+ | `/regex/` | `{ type: "string", pattern: "..." }` |
190
+ | `["a", "b"]` | `{ type: "string", enum: ["a", "b"] }` |
191
+ | `[1, 2, 3]` | `{ type: "number", enum: [1, 2, 3] }` |
192
+
193
+ ### Excluding Fields
194
+
195
+ ```typescript
196
+ const schema = inputToJsonSchema(handler.input, {
197
+ exclude: ["internalField", "debugMode"],
198
+ });
199
+ ```
200
+
201
+ ## Complete Example
202
+
203
+ ```typescript
204
+ import { serviceHandler } from "@jaypie/vocabulary";
205
+ import { createLlmTool } from "@jaypie/vocabulary/llm";
206
+ import { Llm, Toolkit } from "@jaypie/llm";
207
+
208
+ // Define service handlers
209
+ const weatherHandler = serviceHandler({
210
+ alias: "get_weather",
211
+ description: "Get current weather for a location",
212
+ input: {
213
+ location: { type: String, description: "City name or coordinates" },
214
+ units: { type: ["celsius", "fahrenheit"], default: "celsius" },
215
+ },
216
+ service: async ({ location, units }) => {
217
+ const weather = await fetchWeather(location);
218
+ return {
219
+ location,
220
+ temperature: units === "celsius" ? weather.tempC : weather.tempF,
221
+ units,
222
+ conditions: weather.conditions,
223
+ };
224
+ },
225
+ });
226
+
227
+ const searchHandler = serviceHandler({
228
+ alias: "search_web",
229
+ description: "Search the web for information",
230
+ input: {
231
+ query: { type: String, description: "Search query" },
232
+ maxResults: { type: Number, default: 5, description: "Maximum results" },
233
+ },
234
+ service: async ({ query, maxResults }) => {
235
+ return await performSearch(query, maxResults);
236
+ },
237
+ });
238
+
239
+ // Create tools
240
+ const { tool: weatherTool } = createLlmTool({ handler: weatherHandler });
241
+ const { tool: searchTool } = createLlmTool({ handler: searchHandler });
242
+
243
+ // Use with Toolkit
244
+ const toolkit = new Toolkit([weatherTool, searchTool]);
245
+ const llm = new Llm({ toolkit });
246
+
247
+ const response = await llm.ask("What's the weather in Tokyo?");
248
+ ```
249
+
250
+ ## TypeScript Types
251
+
252
+ ```typescript
253
+ import type {
254
+ CreateLlmToolConfig,
255
+ CreateLlmToolResult,
256
+ LlmTool,
257
+ OnCompleteCallback,
258
+ OnErrorCallback,
259
+ OnFatalCallback,
260
+ OnMessageCallback,
261
+ } from "@jaypie/vocabulary/llm";
262
+ ```
263
+
264
+ ### Type Definitions
265
+
266
+ ```typescript
267
+ interface LlmTool {
268
+ name: string;
269
+ description: string;
270
+ parameters: JsonSchema;
271
+ function: (params: Record<string, unknown>) => Promise<unknown>;
272
+ }
273
+
274
+ interface CreateLlmToolConfig {
275
+ handler: ServiceHandlerFunction;
276
+ name?: string;
277
+ description?: string;
278
+ message?: string | ((params: Record<string, unknown>) => string);
279
+ exclude?: string[];
280
+ onComplete?: OnCompleteCallback;
281
+ onError?: OnErrorCallback;
282
+ onFatal?: OnFatalCallback;
283
+ onMessage?: OnMessageCallback;
284
+ }
285
+
286
+ interface CreateLlmToolResult {
287
+ tool: LlmTool;
288
+ }
289
+ ```
290
+
291
+ ## Exports
292
+
293
+ ```typescript
294
+ // @jaypie/vocabulary/llm
295
+ export { createLlmTool } from "./createLlmTool.js";
296
+ export { inputToJsonSchema } from "./inputToJsonSchema.js";
297
+
298
+ export type {
299
+ CreateLlmToolConfig,
300
+ CreateLlmToolResult,
301
+ LlmTool,
302
+ OnCompleteCallback,
303
+ OnErrorCallback,
304
+ OnFatalCallback,
305
+ OnMessageCallback,
306
+ } from "./types.js";
307
+ ```
308
+
309
+ ## Related
310
+
311
+ - [Jaypie_Vocabulary_Package.md](Jaypie_Vocabulary_Package.md) - Core serviceHandler and type coercion
312
+ - [Jaypie_Llm_Tools.md](Jaypie_Llm_Tools.md) - LLM tools and Toolkit usage