@bowenqt/qiniu-ai-sdk 0.5.0 → 0.9.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/README.md CHANGED
@@ -21,6 +21,14 @@ TypeScript SDK for Qiniu Cloud AI Token API.
21
21
  npm install @bowenqt/qiniu-ai-sdk
22
22
  ```
23
23
 
24
+ ### Installation for Adapter Users
25
+
26
+ The Vercel AI SDK adapter is optional. Install the peer dependencies when you use it:
27
+
28
+ ```bash
29
+ npm install @bowenqt/qiniu-ai-sdk @ai-sdk/provider ai
30
+ ```
31
+
24
32
  ## Quick Start
25
33
 
26
34
  ```typescript
@@ -38,12 +46,12 @@ const chat = await client.chat.create({
38
46
  console.log(chat.choices[0].message.content);
39
47
 
40
48
  // Image generation (async)
41
- const imageTask = await client.image.create({
49
+ const imageResult = await client.image.generate({
42
50
  model: 'kling-v1',
43
51
  prompt: 'A futuristic city',
44
52
  });
45
- const imageResult = await client.image.waitForCompletion(imageTask.task_id);
46
- console.log(imageResult.data?.[0].url);
53
+ const imageFinal = await client.image.waitForResult(imageResult);
54
+ console.log(imageFinal.data?.[0].url || imageFinal.data?.[0].b64_json);
47
55
 
48
56
  // Video generation (async)
49
57
  const videoTask = await client.video.create({
@@ -72,6 +80,68 @@ for await (const chunk of stream) {
72
80
  }
73
81
  ```
74
82
 
83
+ ## Advanced Usage
84
+
85
+ ### StreamAccumulator (Manual Streaming)
86
+
87
+ ```typescript
88
+ import { QiniuAI, createStreamAccumulator, accumulateDelta } from '@bowenqt/qiniu-ai-sdk';
89
+
90
+ const client = new QiniuAI({ apiKey: 'Sk-xxx' });
91
+ const stream = client.chat.createStream({
92
+ model: 'gemini-2.5-flash',
93
+ messages: [{ role: 'user', content: 'Explain streaming in one sentence.' }],
94
+ });
95
+
96
+ const acc = createStreamAccumulator();
97
+ for await (const chunk of stream) {
98
+ const delta = chunk.choices[0]?.delta;
99
+ if (delta) {
100
+ accumulateDelta(acc, delta);
101
+ }
102
+ }
103
+ console.log(acc.content);
104
+ ```
105
+
106
+ ### parseSSEStream (Custom SSE Parsing)
107
+
108
+ ```typescript
109
+ import { parseSSEStream } from '@bowenqt/qiniu-ai-sdk';
110
+
111
+ const response = await fetch('https://api.qnaigc.com/v1/chat/completions', {
112
+ method: 'POST',
113
+ headers: {
114
+ 'Content-Type': 'application/json',
115
+ 'Authorization': `Bearer ${process.env.QINIU_API_KEY}`,
116
+ },
117
+ body: JSON.stringify({
118
+ model: 'gemini-2.5-flash',
119
+ messages: [{ role: 'user', content: 'Hello!' }],
120
+ stream: true,
121
+ }),
122
+ });
123
+
124
+ for await (const chunk of parseSSEStream(response)) {
125
+ console.log(chunk);
126
+ }
127
+ ```
128
+
129
+ ### createPoller (Custom Async Polling)
130
+
131
+ ```typescript
132
+ import { createPoller } from '@bowenqt/qiniu-ai-sdk';
133
+
134
+ const poller = createPoller({
135
+ intervalMs: 2000,
136
+ timeoutMs: 60000,
137
+ isTerminal: (result) => result.status === 'succeed' || result.status === 'failed',
138
+ getStatus: (id) => client.video.get(id),
139
+ });
140
+
141
+ const result = await poller.poll('task-id');
142
+ console.log(result.result);
143
+ ```
144
+
75
145
  ## Vercel AI SDK Adapter
76
146
 
77
147
  Use the adapter to integrate with the Vercel AI SDK (`streamText`, `generateText`).
@@ -248,10 +318,14 @@ for await (const chunk of stream) {
248
318
 
249
319
  #### `client.image`
250
320
 
251
- - `create(params: ImageGenerationRequest): Promise<{ task_id: string }>`
321
+ - `generate(params: ImageGenerationRequest): Promise<ImageCreateResult>`
322
+ - `waitForResult(result: ImageCreateResult, options?: WaitOptions): Promise<ImageGenerateResult>`
323
+ - `create(params: ImageGenerationRequest): Promise<{ task_id: string }>` (deprecated)
252
324
  - `edit(params: ImageEditRequest): Promise<ImageEditResponse>`
253
325
  - `get(taskId: string): Promise<ImageTaskResponse>`
254
- - `waitForCompletion(taskId: string, options?: WaitOptions): Promise<ImageTaskResponse>`
326
+ - `waitForCompletion(taskId: string, options?: WaitOptions): Promise<ImageTaskResponse>` (deprecated)
327
+
328
+ Note: For sync models (Gemini), `waitForResult` returns `status: 'succeed'` set by the SDK when data is returned.
255
329
 
256
330
  **Image Edit (Kling/Gemini):**
257
331
 
@@ -458,7 +532,7 @@ const res = await client.post<any>('/voice/tts', {
458
532
 
459
533
  ### Wait Options
460
534
 
461
- For `waitForCompletion` methods:
535
+ For `waitForCompletion` and `waitForResult` methods:
462
536
 
463
537
  ```typescript
464
538
  interface WaitOptions {
@@ -494,7 +568,11 @@ const controller = new AbortController();
494
568
  setTimeout(() => controller.abort(), 10000);
495
569
 
496
570
  try {
497
- const result = await client.image.waitForCompletion(taskId, {
571
+ const createResult = await client.image.generate({
572
+ model: 'kling-v2',
573
+ prompt: 'A cute cat',
574
+ });
575
+ const result = await client.image.waitForResult(createResult, {
498
576
  signal: controller.signal,
499
577
  });
500
578
  } catch (error) {
@@ -0,0 +1,48 @@
1
+ import type { QiniuAI } from '../client';
2
+ import type { ChatMessage, ToolCall } from '../lib/types';
3
+ export interface ToolExecutionContext {
4
+ toolCallId: string;
5
+ messages: ChatMessage[];
6
+ abortSignal?: AbortSignal;
7
+ }
8
+ export interface Tool {
9
+ description?: string;
10
+ parameters?: Record<string, unknown>;
11
+ execute?: (args: unknown, context: ToolExecutionContext) => Promise<unknown> | unknown;
12
+ }
13
+ export interface ToolResult {
14
+ toolCallId: string;
15
+ result: string;
16
+ }
17
+ export interface StepResult {
18
+ type: 'text' | 'tool_call' | 'tool_result';
19
+ content: string;
20
+ reasoning?: string;
21
+ toolCalls?: ToolCall[];
22
+ toolResults?: ToolResult[];
23
+ }
24
+ export interface GenerateTextOptions {
25
+ client: QiniuAI;
26
+ model: string;
27
+ prompt?: string;
28
+ messages?: ChatMessage[];
29
+ system?: string;
30
+ tools?: Record<string, Tool>;
31
+ maxSteps?: number;
32
+ onStepFinish?: (step: StepResult) => void;
33
+ abortSignal?: AbortSignal;
34
+ }
35
+ export interface GenerateTextResult {
36
+ text: string;
37
+ reasoning?: string;
38
+ steps: StepResult[];
39
+ usage?: {
40
+ prompt_tokens: number;
41
+ completion_tokens: number;
42
+ total_tokens: number;
43
+ };
44
+ finishReason: string | null;
45
+ }
46
+ export declare function generateText(options: GenerateTextOptions): Promise<GenerateTextResult>;
47
+ export declare function serializeToolResult(result: unknown): string;
48
+ //# sourceMappingURL=generate-text.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generate-text.d.ts","sourceRoot":"","sources":["../../src/ai/generate-text.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,KAAK,EAAyB,WAAW,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAIjF,MAAM,WAAW,oBAAoB;IACjC,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,WAAW,EAAE,CAAC;IACxB,WAAW,CAAC,EAAE,WAAW,CAAC;CAC7B;AAED,MAAM,WAAW,IAAI;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACrC,OAAO,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,oBAAoB,KAAK,OAAO,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC;CAC1F;AAED,MAAM,WAAW,UAAU;IACvB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,UAAU;IACvB,IAAI,EAAE,MAAM,GAAG,WAAW,GAAG,aAAa,CAAC;IAC3C,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,QAAQ,EAAE,CAAC;IACvB,WAAW,CAAC,EAAE,UAAU,EAAE,CAAC;CAC9B;AAED,MAAM,WAAW,mBAAmB;IAChC,MAAM,EAAE,OAAO,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,WAAW,EAAE,CAAC;IACzB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IAC7B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,UAAU,KAAK,IAAI,CAAC;IAC1C,WAAW,CAAC,EAAE,WAAW,CAAC;CAC7B;AAED,MAAM,WAAW,kBAAkB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,UAAU,EAAE,CAAC;IACpB,KAAK,CAAC,EAAE;QACJ,aAAa,EAAE,MAAM,CAAC;QACtB,iBAAiB,EAAE,MAAM,CAAC;QAC1B,YAAY,EAAE,MAAM,CAAC;KACxB,CAAC;IACF,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;CAC/B;AAED,wBAAsB,YAAY,CAAC,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,kBAAkB,CAAC,CA4E5F;AAED,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,OAAO,GAAG,MAAM,CAc3D"}
@@ -0,0 +1,169 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.generateText = generateText;
4
+ exports.serializeToolResult = serializeToolResult;
5
+ const errors_1 = require("../lib/errors");
6
+ async function generateText(options) {
7
+ const { client, model, tools, maxSteps = 1, onStepFinish, abortSignal, } = options;
8
+ const messages = normalizeMessages(options);
9
+ const steps = [];
10
+ let accumulatedText = '';
11
+ let accumulatedReasoning = '';
12
+ let usage;
13
+ let finishReason = null;
14
+ for (let stepIndex = 0; stepIndex < maxSteps; stepIndex += 1) {
15
+ const request = buildChatRequest({ model, messages, tools });
16
+ const streamResult = await consumeStream(client, request, abortSignal);
17
+ if (streamResult.usage) {
18
+ usage = streamResult.usage;
19
+ }
20
+ if (streamResult.finishReason !== undefined) {
21
+ finishReason = streamResult.finishReason;
22
+ }
23
+ if (streamResult.content) {
24
+ accumulatedText += streamResult.content;
25
+ }
26
+ if (streamResult.reasoningContent) {
27
+ accumulatedReasoning += streamResult.reasoningContent;
28
+ }
29
+ const textStep = {
30
+ type: 'text',
31
+ content: streamResult.content,
32
+ reasoning: streamResult.reasoningContent || undefined,
33
+ toolCalls: streamResult.toolCalls.length ? streamResult.toolCalls : undefined,
34
+ };
35
+ steps.push(textStep);
36
+ if (onStepFinish) {
37
+ onStepFinish(textStep);
38
+ }
39
+ if (!streamResult.toolCalls.length || !tools) {
40
+ return {
41
+ text: accumulatedText,
42
+ reasoning: accumulatedReasoning || undefined,
43
+ steps,
44
+ usage,
45
+ finishReason,
46
+ };
47
+ }
48
+ const toolCallSteps = streamResult.toolCalls.map((toolCall) => ({
49
+ type: 'tool_call',
50
+ content: toolCall.function.arguments,
51
+ toolCalls: [toolCall],
52
+ }));
53
+ steps.push(...toolCallSteps);
54
+ const toolResults = await executeTools(streamResult.toolCalls, tools, messages, abortSignal);
55
+ const toolResultSteps = toolResults.map((toolResult) => ({
56
+ type: 'tool_result',
57
+ content: toolResult.result,
58
+ toolResults: [toolResult],
59
+ }));
60
+ steps.push(...toolResultSteps);
61
+ messages.push(...toolResultsToMessages(streamResult.toolCalls, toolResults));
62
+ }
63
+ throw new errors_1.MaxStepsExceededError(maxSteps);
64
+ }
65
+ function serializeToolResult(result) {
66
+ if (result === undefined) {
67
+ return '';
68
+ }
69
+ if (typeof result === 'string') {
70
+ return result;
71
+ }
72
+ try {
73
+ return JSON.stringify(result);
74
+ }
75
+ catch {
76
+ return String(result);
77
+ }
78
+ }
79
+ function normalizeMessages(options) {
80
+ if (options.messages && options.messages.length > 0) {
81
+ return [...options.messages];
82
+ }
83
+ if (!options.prompt && !options.system) {
84
+ throw new Error('Either prompt or messages must be provided.');
85
+ }
86
+ const messages = [];
87
+ if (options.system) {
88
+ messages.push({ role: 'system', content: options.system });
89
+ }
90
+ if (options.prompt) {
91
+ messages.push({ role: 'user', content: options.prompt });
92
+ }
93
+ return messages;
94
+ }
95
+ function buildChatRequest(params) {
96
+ const { model, messages, tools } = params;
97
+ return {
98
+ model,
99
+ messages,
100
+ tools: tools ? Object.entries(tools).map(([name, tool]) => ({
101
+ type: 'function',
102
+ function: {
103
+ name,
104
+ description: tool.description,
105
+ parameters: tool.parameters ?? {},
106
+ },
107
+ })) : undefined,
108
+ };
109
+ }
110
+ async function consumeStream(client, request, abortSignal) {
111
+ const stream = client.chat.createStream(request, { signal: abortSignal });
112
+ let finalResult;
113
+ while (true) {
114
+ const { value, done } = await stream.next();
115
+ if (done) {
116
+ finalResult = value;
117
+ break;
118
+ }
119
+ }
120
+ return finalResult || {
121
+ content: '',
122
+ reasoningContent: '',
123
+ toolCalls: [],
124
+ finishReason: null,
125
+ usage: undefined,
126
+ };
127
+ }
128
+ function toolResultsToMessages(toolCalls, results) {
129
+ return toolCalls.map((toolCall) => {
130
+ const result = results.find((entry) => entry.toolCallId === toolCall.id);
131
+ return {
132
+ role: 'tool',
133
+ name: toolCall.function.name,
134
+ content: result?.result ?? '',
135
+ };
136
+ });
137
+ }
138
+ async function executeTools(toolCalls, tools, messages, abortSignal) {
139
+ const results = [];
140
+ for (const toolCall of toolCalls) {
141
+ const tool = tools[toolCall.function.name];
142
+ if (!tool || !tool.execute) {
143
+ throw new errors_1.ToolExecutionError(toolCall.function.name, 'Tool is not implemented.');
144
+ }
145
+ const args = parseToolArguments(toolCall.function.arguments);
146
+ const value = await tool.execute(args, {
147
+ toolCallId: toolCall.id,
148
+ messages,
149
+ abortSignal,
150
+ });
151
+ results.push({
152
+ toolCallId: toolCall.id,
153
+ result: serializeToolResult(value),
154
+ });
155
+ }
156
+ return results;
157
+ }
158
+ function parseToolArguments(payload) {
159
+ if (!payload) {
160
+ return {};
161
+ }
162
+ try {
163
+ return JSON.parse(payload);
164
+ }
165
+ catch {
166
+ return payload;
167
+ }
168
+ }
169
+ //# sourceMappingURL=generate-text.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generate-text.js","sourceRoot":"","sources":["../../src/ai/generate-text.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,165 @@
1
+ import { MaxStepsExceededError, ToolExecutionError } from '../lib/errors.mjs';
2
+ export async function generateText(options) {
3
+ const { client, model, tools, maxSteps = 1, onStepFinish, abortSignal, } = options;
4
+ const messages = normalizeMessages(options);
5
+ const steps = [];
6
+ let accumulatedText = '';
7
+ let accumulatedReasoning = '';
8
+ let usage;
9
+ let finishReason = null;
10
+ for (let stepIndex = 0; stepIndex < maxSteps; stepIndex += 1) {
11
+ const request = buildChatRequest({ model, messages, tools });
12
+ const streamResult = await consumeStream(client, request, abortSignal);
13
+ if (streamResult.usage) {
14
+ usage = streamResult.usage;
15
+ }
16
+ if (streamResult.finishReason !== undefined) {
17
+ finishReason = streamResult.finishReason;
18
+ }
19
+ if (streamResult.content) {
20
+ accumulatedText += streamResult.content;
21
+ }
22
+ if (streamResult.reasoningContent) {
23
+ accumulatedReasoning += streamResult.reasoningContent;
24
+ }
25
+ const textStep = {
26
+ type: 'text',
27
+ content: streamResult.content,
28
+ reasoning: streamResult.reasoningContent || undefined,
29
+ toolCalls: streamResult.toolCalls.length ? streamResult.toolCalls : undefined,
30
+ };
31
+ steps.push(textStep);
32
+ if (onStepFinish) {
33
+ onStepFinish(textStep);
34
+ }
35
+ if (!streamResult.toolCalls.length || !tools) {
36
+ return {
37
+ text: accumulatedText,
38
+ reasoning: accumulatedReasoning || undefined,
39
+ steps,
40
+ usage,
41
+ finishReason,
42
+ };
43
+ }
44
+ const toolCallSteps = streamResult.toolCalls.map((toolCall) => ({
45
+ type: 'tool_call',
46
+ content: toolCall.function.arguments,
47
+ toolCalls: [toolCall],
48
+ }));
49
+ steps.push(...toolCallSteps);
50
+ const toolResults = await executeTools(streamResult.toolCalls, tools, messages, abortSignal);
51
+ const toolResultSteps = toolResults.map((toolResult) => ({
52
+ type: 'tool_result',
53
+ content: toolResult.result,
54
+ toolResults: [toolResult],
55
+ }));
56
+ steps.push(...toolResultSteps);
57
+ messages.push(...toolResultsToMessages(streamResult.toolCalls, toolResults));
58
+ }
59
+ throw new MaxStepsExceededError(maxSteps);
60
+ }
61
+ export function serializeToolResult(result) {
62
+ if (result === undefined) {
63
+ return '';
64
+ }
65
+ if (typeof result === 'string') {
66
+ return result;
67
+ }
68
+ try {
69
+ return JSON.stringify(result);
70
+ }
71
+ catch {
72
+ return String(result);
73
+ }
74
+ }
75
+ function normalizeMessages(options) {
76
+ if (options.messages && options.messages.length > 0) {
77
+ return [...options.messages];
78
+ }
79
+ if (!options.prompt && !options.system) {
80
+ throw new Error('Either prompt or messages must be provided.');
81
+ }
82
+ const messages = [];
83
+ if (options.system) {
84
+ messages.push({ role: 'system', content: options.system });
85
+ }
86
+ if (options.prompt) {
87
+ messages.push({ role: 'user', content: options.prompt });
88
+ }
89
+ return messages;
90
+ }
91
+ function buildChatRequest(params) {
92
+ const { model, messages, tools } = params;
93
+ return {
94
+ model,
95
+ messages,
96
+ tools: tools ? Object.entries(tools).map(([name, tool]) => ({
97
+ type: 'function',
98
+ function: {
99
+ name,
100
+ description: tool.description,
101
+ parameters: tool.parameters ?? {},
102
+ },
103
+ })) : undefined,
104
+ };
105
+ }
106
+ async function consumeStream(client, request, abortSignal) {
107
+ const stream = client.chat.createStream(request, { signal: abortSignal });
108
+ let finalResult;
109
+ while (true) {
110
+ const { value, done } = await stream.next();
111
+ if (done) {
112
+ finalResult = value;
113
+ break;
114
+ }
115
+ }
116
+ return finalResult || {
117
+ content: '',
118
+ reasoningContent: '',
119
+ toolCalls: [],
120
+ finishReason: null,
121
+ usage: undefined,
122
+ };
123
+ }
124
+ function toolResultsToMessages(toolCalls, results) {
125
+ return toolCalls.map((toolCall) => {
126
+ const result = results.find((entry) => entry.toolCallId === toolCall.id);
127
+ return {
128
+ role: 'tool',
129
+ name: toolCall.function.name,
130
+ content: result?.result ?? '',
131
+ };
132
+ });
133
+ }
134
+ async function executeTools(toolCalls, tools, messages, abortSignal) {
135
+ const results = [];
136
+ for (const toolCall of toolCalls) {
137
+ const tool = tools[toolCall.function.name];
138
+ if (!tool || !tool.execute) {
139
+ throw new ToolExecutionError(toolCall.function.name, 'Tool is not implemented.');
140
+ }
141
+ const args = parseToolArguments(toolCall.function.arguments);
142
+ const value = await tool.execute(args, {
143
+ toolCallId: toolCall.id,
144
+ messages,
145
+ abortSignal,
146
+ });
147
+ results.push({
148
+ toolCallId: toolCall.id,
149
+ result: serializeToolResult(value),
150
+ });
151
+ }
152
+ return results;
153
+ }
154
+ function parseToolArguments(payload) {
155
+ if (!payload) {
156
+ return {};
157
+ }
158
+ try {
159
+ return JSON.parse(payload);
160
+ }
161
+ catch {
162
+ return payload;
163
+ }
164
+ }
165
+ //# sourceMappingURL=generate-text.js.map
@@ -0,0 +1,17 @@
1
+ import type { ZodTypeAny } from 'zod';
2
+ export type JsonSchema = {
3
+ type?: string;
4
+ properties?: Record<string, JsonSchema>;
5
+ required?: string[];
6
+ items?: JsonSchema;
7
+ enum?: unknown[];
8
+ oneOf?: JsonSchema[];
9
+ };
10
+ export interface ToolDefinition<PARAMETERS = unknown, RESULT = unknown> {
11
+ description?: string;
12
+ parameters: JsonSchema | ZodTypeAny;
13
+ execute?: (args: PARAMETERS) => Promise<RESULT> | RESULT;
14
+ }
15
+ export declare function tool<PARAMETERS, RESULT>(definition: ToolDefinition<PARAMETERS, RESULT>): ToolDefinition<PARAMETERS, RESULT>;
16
+ export declare function zodToJsonSchema(schema: ZodTypeAny): JsonSchema;
17
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/ai-tools/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,KAAK,CAAC;AAEtC,MAAM,MAAM,UAAU,GAAG;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IACxC,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,KAAK,CAAC,EAAE,UAAU,CAAC;IACnB,IAAI,CAAC,EAAE,OAAO,EAAE,CAAC;IACjB,KAAK,CAAC,EAAE,UAAU,EAAE,CAAC;CACxB,CAAC;AAEF,MAAM,WAAW,cAAc,CAAC,UAAU,GAAG,OAAO,EAAE,MAAM,GAAG,OAAO;IAClE,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,UAAU,GAAG,UAAU,CAAC;IACpC,OAAO,CAAC,EAAE,CAAC,IAAI,EAAE,UAAU,KAAK,OAAO,CAAC,MAAM,CAAC,GAAG,MAAM,CAAC;CAC5D;AAED,wBAAgB,IAAI,CAAC,UAAU,EAAE,MAAM,EAAE,UAAU,EAAE,cAAc,CAAC,UAAU,EAAE,MAAM,CAAC,GAAG,cAAc,CAAC,UAAU,EAAE,MAAM,CAAC,CAE3H;AAED,wBAAgB,eAAe,CAAC,MAAM,EAAE,UAAU,GAAG,UAAU,CAE9D"}
@@ -0,0 +1,77 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.tool = tool;
4
+ exports.zodToJsonSchema = zodToJsonSchema;
5
+ function tool(definition) {
6
+ return definition;
7
+ }
8
+ function zodToJsonSchema(schema) {
9
+ return convertSchema(schema);
10
+ }
11
+ function convertSchema(schema) {
12
+ const def = schema._def;
13
+ const typeName = def?.typeName;
14
+ switch (typeName) {
15
+ case 'ZodString':
16
+ return { type: 'string' };
17
+ case 'ZodNumber':
18
+ return { type: 'number' };
19
+ case 'ZodBoolean':
20
+ return { type: 'boolean' };
21
+ case 'ZodArray':
22
+ return { type: 'array', items: convertSchema(def.type) };
23
+ case 'ZodEnum':
24
+ return { type: 'string', enum: def.values };
25
+ case 'ZodLiteral':
26
+ return literalSchema(def.value);
27
+ case 'ZodObject':
28
+ return objectSchema(schema);
29
+ case 'ZodUnion':
30
+ return { oneOf: def.options.map(convertSchema) };
31
+ case 'ZodOptional':
32
+ return convertSchema(def.innerType);
33
+ case 'ZodNullable':
34
+ return convertSchema(def.innerType);
35
+ case 'ZodDefault':
36
+ return convertSchema(def.innerType);
37
+ default:
38
+ return {};
39
+ }
40
+ }
41
+ function objectSchema(schema) {
42
+ const def = schema._def;
43
+ const shapeSource = def?.shape;
44
+ const shape = typeof shapeSource === 'function' ? shapeSource() : shapeSource || {};
45
+ const properties = {};
46
+ const required = [];
47
+ for (const [key, value] of Object.entries(shape)) {
48
+ const { inner, optional } = unwrapOptional(value);
49
+ properties[key] = convertSchema(inner);
50
+ if (!optional) {
51
+ required.push(key);
52
+ }
53
+ }
54
+ const schemaResult = { type: 'object', properties };
55
+ if (required.length) {
56
+ schemaResult.required = required;
57
+ }
58
+ return schemaResult;
59
+ }
60
+ function unwrapOptional(schema) {
61
+ const def = schema._def;
62
+ if (!def?.typeName) {
63
+ return { inner: schema, optional: false };
64
+ }
65
+ if (def.typeName === 'ZodOptional' || def.typeName === 'ZodDefault') {
66
+ return { inner: def.innerType, optional: true };
67
+ }
68
+ return { inner: schema, optional: false };
69
+ }
70
+ function literalSchema(value) {
71
+ const valueType = typeof value;
72
+ if (valueType === 'string' || valueType === 'number' || valueType === 'boolean') {
73
+ return { type: valueType, enum: [value] };
74
+ }
75
+ return { enum: [value] };
76
+ }
77
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/ai-tools/index.ts"],"names":[],"mappings":"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"}