@lantos1618/better-ui 0.2.3 → 0.4.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.
Files changed (83) hide show
  1. package/README.md +271 -354
  2. package/dist/ThemeProvider-BYeqWMsn.d.mts +187 -0
  3. package/dist/ThemeProvider-BaVZaDBO.d.ts +187 -0
  4. package/dist/auth/index.d.mts +56 -0
  5. package/dist/auth/index.d.ts +56 -0
  6. package/dist/auth/index.js +104 -0
  7. package/dist/auth/index.mjs +67 -0
  8. package/dist/chunk-Y6FXYEAI.mjs +10 -0
  9. package/dist/components/index.d.mts +258 -0
  10. package/dist/components/index.d.ts +258 -0
  11. package/dist/components/index.js +1977 -0
  12. package/dist/components/index.mjs +1922 -0
  13. package/dist/index.d.mts +75 -0
  14. package/dist/index.d.ts +75 -0
  15. package/dist/index.js +587 -0
  16. package/dist/index.mjs +557 -0
  17. package/dist/persistence/index.d.mts +11 -0
  18. package/dist/persistence/index.d.ts +11 -0
  19. package/dist/persistence/index.js +66 -0
  20. package/dist/persistence/index.mjs +41 -0
  21. package/dist/react/index.d.mts +91 -0
  22. package/dist/react/index.d.ts +91 -0
  23. package/dist/react/index.js +284 -0
  24. package/dist/react/index.mjs +257 -0
  25. package/dist/tool-Ca2x-VNK.d.mts +361 -0
  26. package/dist/tool-Ca2x-VNK.d.ts +361 -0
  27. package/dist/types-CAOfGUPH.d.mts +31 -0
  28. package/dist/types-CAOfGUPH.d.ts +31 -0
  29. package/package.json +85 -30
  30. package/src/theme.css +101 -0
  31. package/lib/aui/README.md +0 -136
  32. package/lib/aui/__tests__/aui-complete.test.ts +0 -251
  33. package/lib/aui/__tests__/aui-comprehensive.test.ts +0 -376
  34. package/lib/aui/__tests__/aui-concise.test.ts +0 -278
  35. package/lib/aui/__tests__/aui-integration.test.ts +0 -309
  36. package/lib/aui/__tests__/aui-simple.test.ts +0 -116
  37. package/lib/aui/__tests__/aui.test.ts +0 -269
  38. package/lib/aui/__tests__/concise-api.test.ts +0 -165
  39. package/lib/aui/__tests__/core.test.ts +0 -265
  40. package/lib/aui/__tests__/simple-api.test.ts +0 -200
  41. package/lib/aui/ai-assistant.ts +0 -408
  42. package/lib/aui/ai-control.ts +0 -353
  43. package/lib/aui/client/use-aui.ts +0 -55
  44. package/lib/aui/client-control.ts +0 -551
  45. package/lib/aui/client-executor.ts +0 -417
  46. package/lib/aui/components/ToolRenderer.tsx +0 -22
  47. package/lib/aui/core.ts +0 -137
  48. package/lib/aui/demo.tsx +0 -89
  49. package/lib/aui/examples/ai-complete-demo.tsx +0 -359
  50. package/lib/aui/examples/ai-control-demo.tsx +0 -356
  51. package/lib/aui/examples/ai-control-tools.ts +0 -308
  52. package/lib/aui/examples/concise-api.tsx +0 -153
  53. package/lib/aui/examples/index.tsx +0 -163
  54. package/lib/aui/examples/quick-demo.tsx +0 -91
  55. package/lib/aui/examples/simple-demo.tsx +0 -71
  56. package/lib/aui/examples/simple-tools.tsx +0 -160
  57. package/lib/aui/examples/user-api.tsx +0 -208
  58. package/lib/aui/examples/user-requested.tsx +0 -174
  59. package/lib/aui/examples/weather-search-tools.tsx +0 -119
  60. package/lib/aui/examples.tsx +0 -367
  61. package/lib/aui/hooks/useAUITool.ts +0 -142
  62. package/lib/aui/hooks/useAUIToolEnhanced.ts +0 -343
  63. package/lib/aui/hooks/useAUITools.ts +0 -195
  64. package/lib/aui/index.ts +0 -156
  65. package/lib/aui/provider.tsx +0 -45
  66. package/lib/aui/server-control.ts +0 -386
  67. package/lib/aui/server-executor.ts +0 -165
  68. package/lib/aui/server.ts +0 -167
  69. package/lib/aui/tool-registry.ts +0 -380
  70. package/lib/aui/tools/advanced-examples.tsx +0 -86
  71. package/lib/aui/tools/ai-complete.ts +0 -375
  72. package/lib/aui/tools/api-tools.tsx +0 -230
  73. package/lib/aui/tools/data-tools.tsx +0 -232
  74. package/lib/aui/tools/dom-tools.tsx +0 -202
  75. package/lib/aui/tools/examples.ts +0 -43
  76. package/lib/aui/tools/file-tools.tsx +0 -202
  77. package/lib/aui/tools/form-tools.tsx +0 -233
  78. package/lib/aui/tools/index.ts +0 -8
  79. package/lib/aui/tools/navigation-tools.tsx +0 -172
  80. package/lib/aui/tools/notification-tools.ts +0 -213
  81. package/lib/aui/tools/state-tools.tsx +0 -209
  82. package/lib/aui/types.ts +0 -47
  83. package/lib/aui/vercel-ai.ts +0 -100
package/dist/index.js ADDED
@@ -0,0 +1,587 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/index.ts
21
+ var index_exports = {};
22
+ __export(index_exports, {
23
+ Tool: () => Tool,
24
+ ToolBuilder: () => ToolBuilder,
25
+ createAnthropicProvider: () => createAnthropicProvider,
26
+ createGoogleProvider: () => createGoogleProvider,
27
+ createOpenAIProvider: () => createOpenAIProvider,
28
+ createOpenRouterProvider: () => createOpenRouterProvider,
29
+ createProvider: () => createProvider,
30
+ tool: () => tool
31
+ });
32
+ module.exports = __toCommonJS(index_exports);
33
+
34
+ // src/tool.tsx
35
+ var import_react = require("react");
36
+ var import_jsx_runtime = require("react/jsx-runtime");
37
+ var Tool = class {
38
+ constructor(config) {
39
+ this.name = config.name;
40
+ this.description = config.description;
41
+ this.inputSchema = config.input;
42
+ this.outputSchema = config.output;
43
+ this.tags = config.tags || [];
44
+ this.cacheConfig = config.cache;
45
+ this.clientFetchConfig = config.clientFetch;
46
+ this.confirm = config.confirm ?? false;
47
+ this.hints = config.hints ?? {};
48
+ this.groupKey = config.groupKey;
49
+ this.autoRespond = config.autoRespond ?? false;
50
+ this._initView();
51
+ }
52
+ /**
53
+ * Define server-side implementation
54
+ * Runs on server (API routes, server components, etc.)
55
+ */
56
+ server(handler) {
57
+ this._server = handler;
58
+ return this;
59
+ }
60
+ /**
61
+ * Define client-side implementation
62
+ * Runs in browser. If not specified, auto-fetches to /api/tools/{name}
63
+ */
64
+ client(handler) {
65
+ this._client = handler;
66
+ return this;
67
+ }
68
+ /**
69
+ * Define view component for rendering results
70
+ * Our differentiator from TanStack AI
71
+ */
72
+ view(component) {
73
+ this._view = component;
74
+ this._initView();
75
+ return this;
76
+ }
77
+ /**
78
+ * Define streaming implementation
79
+ * The handler receives a `stream` callback to push partial updates.
80
+ */
81
+ stream(handler) {
82
+ this._stream = handler;
83
+ return this;
84
+ }
85
+ /**
86
+ * Execute the tool
87
+ * Automatically uses server or client handler based on environment
88
+ *
89
+ * SECURITY: Server handlers only run on server. Client automatically
90
+ * fetches from /api/tools/execute if no client handler is defined.
91
+ */
92
+ async run(input, ctx) {
93
+ const validated = this.inputSchema.parse(input);
94
+ const isServer = ctx?.isServer ?? typeof window === "undefined";
95
+ const context = {
96
+ cache: ctx?.cache || /* @__PURE__ */ new Map(),
97
+ fetch: ctx?.fetch || globalThis.fetch?.bind(globalThis),
98
+ isServer,
99
+ // Only include server-sensitive fields when actually on server
100
+ ...isServer ? {
101
+ env: ctx?.env,
102
+ headers: ctx?.headers,
103
+ cookies: ctx?.cookies,
104
+ user: ctx?.user,
105
+ session: ctx?.session
106
+ } : {
107
+ // Client-only fields
108
+ optimistic: ctx?.optimistic
109
+ }
110
+ };
111
+ if (this.cacheConfig && context.cache) {
112
+ const cacheKey = this.cacheConfig.key ? this.cacheConfig.key(validated) : `${this.name}:${JSON.stringify(validated)}`;
113
+ const cached = context.cache.get(cacheKey);
114
+ if (cached && cached.expiry > Date.now()) {
115
+ return cached.data;
116
+ }
117
+ }
118
+ let result;
119
+ if (context.isServer) {
120
+ if (!this._server) {
121
+ throw new Error(`Tool "${this.name}" has no server implementation`);
122
+ }
123
+ result = await this._server(validated, context);
124
+ } else {
125
+ if (this._client) {
126
+ result = await this._client(validated, context);
127
+ } else if (this._server) {
128
+ result = await this._defaultClientFetch(validated, context);
129
+ } else {
130
+ throw new Error(`Tool "${this.name}" has no implementation`);
131
+ }
132
+ }
133
+ if (this.outputSchema) {
134
+ try {
135
+ result = this.outputSchema.parse(result);
136
+ } catch (error) {
137
+ console.error(`Output validation failed for tool "${this.name}":`, error);
138
+ if (error instanceof Error && "errors" in error) {
139
+ console.error("Validation errors:", error.errors);
140
+ }
141
+ throw error;
142
+ }
143
+ }
144
+ if (this.cacheConfig && context.cache) {
145
+ const cacheKey = this.cacheConfig.key ? this.cacheConfig.key(validated) : `${this.name}:${JSON.stringify(validated)}`;
146
+ context.cache.set(cacheKey, {
147
+ data: result,
148
+ expiry: Date.now() + this.cacheConfig.ttl
149
+ });
150
+ }
151
+ return result;
152
+ }
153
+ /**
154
+ * Make the tool callable directly: await weather({ city: 'London' })
155
+ */
156
+ async call(input, ctx) {
157
+ return this.run(input, ctx);
158
+ }
159
+ /**
160
+ * Execute with streaming - returns async generator of partial results.
161
+ * Falls back to run() if no stream handler is defined.
162
+ */
163
+ async *runStream(input, ctx) {
164
+ const validated = this.inputSchema.parse(input);
165
+ if (!this._stream) {
166
+ const result = await this.run(input, ctx);
167
+ yield { partial: result, done: true };
168
+ return;
169
+ }
170
+ const isServer = ctx?.isServer ?? typeof window === "undefined";
171
+ const context = {
172
+ cache: ctx?.cache || /* @__PURE__ */ new Map(),
173
+ fetch: ctx?.fetch || globalThis.fetch?.bind(globalThis),
174
+ isServer,
175
+ ...isServer ? {
176
+ env: ctx?.env,
177
+ headers: ctx?.headers,
178
+ cookies: ctx?.cookies,
179
+ user: ctx?.user,
180
+ session: ctx?.session
181
+ } : {
182
+ optimistic: ctx?.optimistic
183
+ }
184
+ };
185
+ const queue = [];
186
+ let waiter = null;
187
+ const notify = () => {
188
+ waiter?.();
189
+ waiter = null;
190
+ };
191
+ const wait = () => new Promise((r) => {
192
+ waiter = r;
193
+ });
194
+ const streamFn = (partial) => {
195
+ queue.push({ partial });
196
+ notify();
197
+ };
198
+ let error = null;
199
+ let isDone = false;
200
+ this._stream(validated, { ...context, stream: streamFn }).then((result) => {
201
+ queue.push({ done: true, result });
202
+ isDone = true;
203
+ notify();
204
+ }).catch((err) => {
205
+ error = err instanceof Error ? err : new Error(String(err));
206
+ isDone = true;
207
+ notify();
208
+ });
209
+ while (true) {
210
+ while (queue.length > 0) {
211
+ const item = queue.shift();
212
+ if ("done" in item) {
213
+ let finalResult = item.result;
214
+ if (this.outputSchema) finalResult = this.outputSchema.parse(finalResult);
215
+ yield { partial: finalResult, done: true };
216
+ return;
217
+ }
218
+ yield { partial: item.partial, done: false };
219
+ }
220
+ if (error) throw error;
221
+ if (isDone && queue.length === 0) return;
222
+ await wait();
223
+ }
224
+ }
225
+ /**
226
+ * Default client fetch when no .client() is defined
227
+ *
228
+ * SECURITY: This ensures server handlers never run on the client.
229
+ * The server-side /api/tools/execute endpoint handles execution safely.
230
+ */
231
+ async _defaultClientFetch(input, ctx) {
232
+ const endpoint = this.clientFetchConfig?.endpoint || "/api/tools/execute";
233
+ const response = await ctx.fetch(endpoint, {
234
+ method: "POST",
235
+ headers: { "Content-Type": "application/json" },
236
+ body: JSON.stringify({ tool: this.name, input })
237
+ });
238
+ if (!response.ok) {
239
+ const error = await response.json().catch(() => ({}));
240
+ throw new Error(error.message || error.error || `Tool execution failed: ${response.statusText}`);
241
+ }
242
+ const data = await response.json();
243
+ return data.result ?? data.data ?? data;
244
+ }
245
+ _initView() {
246
+ const viewFn = this._view;
247
+ const name = this.name;
248
+ const ViewComponent = (props) => {
249
+ if (!viewFn) {
250
+ if (props.loading) return null;
251
+ if (props.error) return null;
252
+ if (!props.data) return null;
253
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("pre", { children: JSON.stringify(props.data, null, 2) });
254
+ }
255
+ if (!props.data && !props.loading && !props.error) {
256
+ return null;
257
+ }
258
+ return viewFn(props.data, {
259
+ loading: props.loading,
260
+ streaming: props.streaming,
261
+ error: props.error,
262
+ onAction: props.onAction
263
+ });
264
+ };
265
+ ViewComponent.displayName = `${name}View`;
266
+ this.View = (0, import_react.memo)(ViewComponent, (prevProps, nextProps) => {
267
+ if (prevProps.data !== nextProps.data) return false;
268
+ if (prevProps.loading !== nextProps.loading) return false;
269
+ if (prevProps.streaming !== nextProps.streaming) return false;
270
+ if (prevProps.error !== nextProps.error) return false;
271
+ return true;
272
+ });
273
+ }
274
+ /**
275
+ * Check if tool has a view
276
+ */
277
+ get hasView() {
278
+ return !!this._view;
279
+ }
280
+ /**
281
+ * Check if tool has server implementation
282
+ */
283
+ get hasServer() {
284
+ return !!this._server;
285
+ }
286
+ /**
287
+ * Check if tool has custom client implementation
288
+ */
289
+ get hasClient() {
290
+ return !!this._client;
291
+ }
292
+ /**
293
+ * Check if tool has a streaming implementation
294
+ */
295
+ get hasStream() {
296
+ return !!this._stream;
297
+ }
298
+ /**
299
+ * Check if tool requires human confirmation before executing (HITL)
300
+ * Returns true if `confirm` is truthy (boolean true or a function) OR `hints.destructive: true`
301
+ */
302
+ get requiresConfirmation() {
303
+ return !!this.confirm || this.hints.destructive === true;
304
+ }
305
+ /**
306
+ * Determine if a specific input should trigger user confirmation.
307
+ * - If `confirm` is a function, calls it with input
308
+ * - If `confirm` is boolean, returns it
309
+ * - If `hints.destructive`, returns true
310
+ */
311
+ shouldConfirm(input) {
312
+ if (typeof this.confirm === "function") {
313
+ if (input == null) return false;
314
+ return this.confirm(input);
315
+ }
316
+ if (typeof this.confirm === "boolean") {
317
+ return this.confirm;
318
+ }
319
+ return this.hints.destructive === true;
320
+ }
321
+ /**
322
+ * Get the entity group key for a given input.
323
+ * Returns `"toolName:groupKey(input)"` if groupKey is defined, otherwise undefined.
324
+ */
325
+ getGroupKey(input) {
326
+ if (!this.groupKey || input == null) return void 0;
327
+ return `${this.name}:${this.groupKey(input)}`;
328
+ }
329
+ /**
330
+ * Convert to plain object (for serialization)
331
+ *
332
+ * SECURITY: This intentionally excludes handlers and schemas to prevent
333
+ * accidental exposure of server logic or validation details.
334
+ */
335
+ toJSON() {
336
+ return {
337
+ name: this.name,
338
+ description: this.description,
339
+ tags: this.tags,
340
+ hasServer: this.hasServer,
341
+ hasClient: this.hasClient,
342
+ hasView: this.hasView,
343
+ hasStream: this.hasStream,
344
+ hasCache: !!this.cacheConfig,
345
+ confirm: !!this.confirm,
346
+ hints: this.hints,
347
+ requiresConfirmation: this.requiresConfirmation
348
+ // Intentionally NOT included: handlers, schemas, clientFetchConfig
349
+ };
350
+ }
351
+ /**
352
+ * Convert to AI SDK format (Vercel AI SDK v5 compatible)
353
+ *
354
+ * If `confirm` is true, the execute function is omitted so the AI SDK
355
+ * leaves the tool call at `state: 'input-available'`, enabling HITL
356
+ * confirmation on the client before execution.
357
+ */
358
+ toAITool() {
359
+ if (this.requiresConfirmation) {
360
+ return {
361
+ description: this.description || this.name,
362
+ inputSchema: this.inputSchema
363
+ };
364
+ }
365
+ return {
366
+ description: this.description || this.name,
367
+ inputSchema: this.inputSchema,
368
+ execute: async (input) => {
369
+ return this.run(input, { isServer: true });
370
+ }
371
+ };
372
+ }
373
+ };
374
+ function tool(nameOrConfig) {
375
+ if (typeof nameOrConfig === "string") {
376
+ return new ToolBuilder(nameOrConfig);
377
+ }
378
+ return new Tool(nameOrConfig);
379
+ }
380
+ var ToolBuilder = class {
381
+ constructor(name) {
382
+ this._tags = [];
383
+ this._name = name;
384
+ }
385
+ description(desc) {
386
+ this._description = desc;
387
+ return this;
388
+ }
389
+ /**
390
+ * Define input schema - enables type inference for handlers
391
+ *
392
+ * NOTE: Uses type assertion internally. This is safe because:
393
+ * 1. The schema is stored and used correctly at runtime
394
+ * 2. The return type correctly reflects the new generic parameter
395
+ * 3. TypeScript doesn't support "this type mutation" in fluent builders
396
+ */
397
+ input(schema) {
398
+ this._input = schema;
399
+ return this;
400
+ }
401
+ /**
402
+ * Define output schema - enables type inference for results
403
+ */
404
+ output(schema) {
405
+ this._output = schema;
406
+ return this;
407
+ }
408
+ tags(...tags) {
409
+ this._tags.push(...tags);
410
+ return this;
411
+ }
412
+ cache(config) {
413
+ this._cache = config;
414
+ return this;
415
+ }
416
+ /** Configure auto-fetch endpoint for client-side execution */
417
+ clientFetch(config) {
418
+ this._clientFetch = config;
419
+ return this;
420
+ }
421
+ /** Require human confirmation before executing (HITL) */
422
+ requireConfirm(value = true) {
423
+ this._confirm = value;
424
+ return this;
425
+ }
426
+ /** Set a groupKey function for collapsing related tool calls */
427
+ groupBy(fn) {
428
+ this._groupKey = fn;
429
+ return this;
430
+ }
431
+ /** Auto-send updated state to AI after user interacts with this tool's UI */
432
+ autoRespondAfterAction(value = true) {
433
+ this._autoRespond = value;
434
+ return this;
435
+ }
436
+ /** Set behavioral hints for the tool */
437
+ hints(hints) {
438
+ this._hints = hints;
439
+ return this;
440
+ }
441
+ server(handler) {
442
+ this._serverHandler = handler;
443
+ return this;
444
+ }
445
+ client(handler) {
446
+ this._clientHandler = handler;
447
+ return this;
448
+ }
449
+ stream(handler) {
450
+ this._streamHandler = handler;
451
+ return this;
452
+ }
453
+ view(component) {
454
+ this._viewComponent = component;
455
+ return this;
456
+ }
457
+ /**
458
+ * Build the final Tool instance
459
+ */
460
+ build() {
461
+ if (!this._input) {
462
+ throw new Error(`Tool "${this._name}" requires an input schema`);
463
+ }
464
+ const t = new Tool({
465
+ name: this._name,
466
+ description: this._description,
467
+ input: this._input,
468
+ output: this._output,
469
+ tags: this._tags,
470
+ cache: this._cache,
471
+ clientFetch: this._clientFetch,
472
+ confirm: this._confirm,
473
+ hints: this._hints,
474
+ groupKey: this._groupKey,
475
+ autoRespond: this._autoRespond
476
+ });
477
+ if (this._serverHandler) t.server(this._serverHandler);
478
+ if (this._clientHandler) t.client(this._clientHandler);
479
+ if (this._streamHandler) t.stream(this._streamHandler);
480
+ if (this._viewComponent) t.view(this._viewComponent);
481
+ return t;
482
+ }
483
+ /**
484
+ * Auto-build when accessing Tool methods
485
+ */
486
+ async run(input, ctx) {
487
+ return this.build().run(input, ctx);
488
+ }
489
+ async *runStream(input, ctx) {
490
+ yield* this.build().runStream(input, ctx);
491
+ }
492
+ get View() {
493
+ return this.build().View;
494
+ }
495
+ toJSON() {
496
+ return this.build().toJSON();
497
+ }
498
+ toAITool() {
499
+ return this.build().toAITool();
500
+ }
501
+ };
502
+
503
+ // src/providers/openai.ts
504
+ function createOpenAIProvider(config) {
505
+ return {
506
+ type: "openai",
507
+ modelId: config.model,
508
+ model: () => {
509
+ const id = "@ai-sdk/openai";
510
+ const { openai } = require(id);
511
+ return openai(config.model);
512
+ }
513
+ };
514
+ }
515
+
516
+ // src/providers/anthropic.ts
517
+ function createAnthropicProvider(config) {
518
+ return {
519
+ type: "anthropic",
520
+ modelId: config.model,
521
+ model: () => {
522
+ const id = "@ai-sdk/anthropic";
523
+ const { anthropic } = require(id);
524
+ return anthropic(config.model);
525
+ }
526
+ };
527
+ }
528
+
529
+ // src/providers/google.ts
530
+ function createGoogleProvider(config) {
531
+ return {
532
+ type: "google",
533
+ modelId: config.model,
534
+ model: () => {
535
+ const id = "@ai-sdk/google";
536
+ const { google } = require(id);
537
+ return google(config.model);
538
+ }
539
+ };
540
+ }
541
+
542
+ // src/providers/openrouter.ts
543
+ function createOpenRouterProvider(config) {
544
+ return {
545
+ type: "openrouter",
546
+ modelId: config.model,
547
+ model: () => {
548
+ const id = "@ai-sdk/openai";
549
+ const { createOpenAI } = require(id);
550
+ const openrouter = createOpenAI({
551
+ baseURL: config.baseURL || "https://openrouter.ai/api/v1",
552
+ apiKey: config.apiKey,
553
+ ...config.options
554
+ });
555
+ return openrouter(config.model);
556
+ }
557
+ };
558
+ }
559
+
560
+ // src/providers/index.ts
561
+ function createProvider(config) {
562
+ switch (config.provider) {
563
+ case "openai":
564
+ return createOpenAIProvider(config);
565
+ case "anthropic":
566
+ return createAnthropicProvider(config);
567
+ case "google":
568
+ return createGoogleProvider(config);
569
+ case "openrouter":
570
+ return createOpenRouterProvider(config);
571
+ default: {
572
+ const exhaustiveCheck = config.provider;
573
+ throw new Error(`Unknown provider: ${exhaustiveCheck}`);
574
+ }
575
+ }
576
+ }
577
+ // Annotate the CommonJS export names for ESM import in node:
578
+ 0 && (module.exports = {
579
+ Tool,
580
+ ToolBuilder,
581
+ createAnthropicProvider,
582
+ createGoogleProvider,
583
+ createOpenAIProvider,
584
+ createOpenRouterProvider,
585
+ createProvider,
586
+ tool
587
+ });