kimi-vercel-ai-sdk-provider 0.2.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 (44) hide show
  1. package/LICENSE +198 -0
  2. package/README.md +871 -0
  3. package/dist/index.d.mts +1317 -0
  4. package/dist/index.d.ts +1317 -0
  5. package/dist/index.js +2764 -0
  6. package/dist/index.js.map +1 -0
  7. package/dist/index.mjs +2734 -0
  8. package/dist/index.mjs.map +1 -0
  9. package/package.json +70 -0
  10. package/src/__tests__/caching.test.ts +97 -0
  11. package/src/__tests__/chat.test.ts +386 -0
  12. package/src/__tests__/code-integration.test.ts +562 -0
  13. package/src/__tests__/code-provider.test.ts +289 -0
  14. package/src/__tests__/code.test.ts +427 -0
  15. package/src/__tests__/core.test.ts +172 -0
  16. package/src/__tests__/files.test.ts +185 -0
  17. package/src/__tests__/integration.test.ts +457 -0
  18. package/src/__tests__/provider.test.ts +188 -0
  19. package/src/__tests__/tools.test.ts +519 -0
  20. package/src/chat/index.ts +42 -0
  21. package/src/chat/kimi-chat-language-model.ts +829 -0
  22. package/src/chat/kimi-chat-messages.ts +297 -0
  23. package/src/chat/kimi-chat-response.ts +84 -0
  24. package/src/chat/kimi-chat-settings.ts +216 -0
  25. package/src/code/index.ts +66 -0
  26. package/src/code/kimi-code-language-model.ts +669 -0
  27. package/src/code/kimi-code-messages.ts +303 -0
  28. package/src/code/kimi-code-provider.ts +239 -0
  29. package/src/code/kimi-code-settings.ts +193 -0
  30. package/src/code/kimi-code-types.ts +354 -0
  31. package/src/core/errors.ts +140 -0
  32. package/src/core/index.ts +36 -0
  33. package/src/core/types.ts +148 -0
  34. package/src/core/utils.ts +210 -0
  35. package/src/files/attachment-processor.ts +276 -0
  36. package/src/files/file-utils.ts +257 -0
  37. package/src/files/index.ts +24 -0
  38. package/src/files/kimi-file-client.ts +292 -0
  39. package/src/index.ts +122 -0
  40. package/src/kimi-provider.ts +263 -0
  41. package/src/tools/builtin-tools.ts +273 -0
  42. package/src/tools/index.ts +33 -0
  43. package/src/tools/prepare-tools.ts +306 -0
  44. package/src/version.ts +4 -0
@@ -0,0 +1,306 @@
1
+ /**
2
+ * Tool preparation utilities for Kimi API.
3
+ * @module
4
+ */
5
+
6
+ import {
7
+ type LanguageModelV3CallOptions,
8
+ type LanguageModelV3ProviderTool,
9
+ type SharedV3Warning,
10
+ UnsupportedFunctionalityError
11
+ } from '@ai-sdk/provider';
12
+ import {
13
+ type KimiBuiltinTool,
14
+ type KimiCodeInterpreterToolOptions,
15
+ type KimiWebSearchToolOptions,
16
+ createCodeInterpreterTool,
17
+ createWebSearchTool
18
+ } from './builtin-tools';
19
+
20
+ // ============================================================================
21
+ // Types
22
+ // ============================================================================
23
+
24
+ /**
25
+ * A standard function tool for Kimi API.
26
+ */
27
+ export interface KimiFunctionTool {
28
+ type: 'function';
29
+ function: {
30
+ name: string;
31
+ description: string | undefined;
32
+ parameters: unknown;
33
+ strict?: boolean;
34
+ };
35
+ }
36
+
37
+ /**
38
+ * Union of all tool types supported by Kimi API.
39
+ */
40
+ export type KimiTool = KimiFunctionTool | KimiBuiltinTool;
41
+
42
+ /**
43
+ * Options for preparing tools.
44
+ */
45
+ export interface PrepareToolsOptions {
46
+ /**
47
+ * The tools from the call options.
48
+ */
49
+ tools: LanguageModelV3CallOptions['tools'];
50
+
51
+ /**
52
+ * The tool choice from the call options.
53
+ */
54
+ toolChoice?: LanguageModelV3CallOptions['toolChoice'];
55
+
56
+ /**
57
+ * Web search configuration.
58
+ */
59
+ webSearch?: boolean | KimiWebSearchToolOptions;
60
+
61
+ /**
62
+ * Code interpreter configuration.
63
+ */
64
+ codeInterpreter?: boolean | KimiCodeInterpreterToolOptions;
65
+
66
+ /**
67
+ * Enable tool choice polyfill for unsupported modes.
68
+ * When true, uses system message injection to simulate
69
+ * `required` and `tool` choices.
70
+ */
71
+ toolChoicePolyfill?: boolean;
72
+ }
73
+
74
+ /**
75
+ * Result of preparing tools.
76
+ */
77
+ export interface PrepareToolsResult {
78
+ /**
79
+ * The prepared tools for the API request.
80
+ */
81
+ tools: KimiTool[] | undefined;
82
+
83
+ /**
84
+ * The tool choice setting for the API request.
85
+ */
86
+ toolChoice: 'auto' | 'none' | undefined;
87
+
88
+ /**
89
+ * Any warnings generated during tool preparation.
90
+ */
91
+ toolWarnings: SharedV3Warning[];
92
+
93
+ /**
94
+ * System message to inject for tool choice polyfill.
95
+ * This should be prepended to the messages array.
96
+ */
97
+ toolChoiceSystemMessage?: string;
98
+ }
99
+
100
+ // ============================================================================
101
+ // Main Function
102
+ // ============================================================================
103
+
104
+ /**
105
+ * Prepare tools for a Kimi API request.
106
+ *
107
+ * This function processes user-defined tools and built-in tools,
108
+ * converting them to the format expected by the Kimi API.
109
+ *
110
+ * When `toolChoicePolyfill` is enabled, the function will generate
111
+ * system messages to simulate unsupported tool choice modes:
112
+ * - `required`: Injects a message instructing the model to use a tool
113
+ * - `tool`: Injects a message instructing the model to use a specific tool
114
+ *
115
+ * @param options - Tool preparation options
116
+ * @returns Prepared tools, tool choice, warnings, and optional system message
117
+ */
118
+ export function prepareKimiTools({
119
+ tools,
120
+ toolChoice,
121
+ webSearch,
122
+ codeInterpreter,
123
+ toolChoicePolyfill = true
124
+ }: PrepareToolsOptions): PrepareToolsResult {
125
+ tools = tools?.length ? tools : undefined;
126
+
127
+ const toolWarnings: SharedV3Warning[] = [];
128
+ const kimiTools: KimiTool[] = [];
129
+
130
+ // Add built-in web search tool if enabled
131
+ if (webSearch) {
132
+ const config = typeof webSearch === 'boolean' ? undefined : webSearch.config;
133
+ kimiTools.push(createWebSearchTool(config));
134
+ }
135
+
136
+ // Add built-in code interpreter tool if enabled
137
+ if (codeInterpreter) {
138
+ const config = typeof codeInterpreter === 'boolean' ? undefined : codeInterpreter.config;
139
+ kimiTools.push(createCodeInterpreterTool(config));
140
+ }
141
+
142
+ // Process user-defined tools
143
+ if (tools != null) {
144
+ for (const tool of tools) {
145
+ if (tool.type === 'provider') {
146
+ // Check if this is a Kimi built-in tool
147
+ const builtinTool = tryConvertToKimiBuiltinTool(tool);
148
+ if (builtinTool) {
149
+ kimiTools.push(builtinTool);
150
+ continue;
151
+ }
152
+
153
+ toolWarnings.push({
154
+ type: 'unsupported',
155
+ feature: `provider-defined tool ${tool.id}`
156
+ });
157
+ continue;
158
+ }
159
+
160
+ kimiTools.push({
161
+ type: 'function',
162
+ function: {
163
+ name: tool.name,
164
+ description: tool.description,
165
+ parameters: tool.inputSchema,
166
+ ...(tool.strict != null ? { strict: tool.strict } : {})
167
+ }
168
+ });
169
+ }
170
+ }
171
+
172
+ // Return undefined if no tools
173
+ if (kimiTools.length === 0) {
174
+ return { tools: undefined, toolChoice: undefined, toolWarnings };
175
+ }
176
+
177
+ // Handle tool choice
178
+ if (toolChoice == null) {
179
+ return { tools: kimiTools, toolChoice: undefined, toolWarnings };
180
+ }
181
+
182
+ switch (toolChoice.type) {
183
+ case 'auto':
184
+ case 'none':
185
+ return { tools: kimiTools, toolChoice: toolChoice.type, toolWarnings };
186
+
187
+ case 'required': {
188
+ if (toolChoicePolyfill) {
189
+ // Generate system message to force tool usage
190
+ const toolNames = kimiTools.map((t) => (t.type === 'function' ? t.function.name : t.function.name)).join(', ');
191
+ const systemMessage = generateRequiredToolMessage(toolNames);
192
+
193
+ toolWarnings.push({
194
+ type: 'compatibility',
195
+ feature: 'toolChoice.required',
196
+ details: 'Using tool choice polyfill with system message injection.'
197
+ });
198
+
199
+ return {
200
+ tools: kimiTools,
201
+ toolChoice: 'auto',
202
+ toolWarnings,
203
+ toolChoiceSystemMessage: systemMessage
204
+ };
205
+ }
206
+
207
+ toolWarnings.push({
208
+ type: 'compatibility',
209
+ feature: 'toolChoice.required',
210
+ details: 'Moonshot does not support required tool choice. Falling back to auto.'
211
+ });
212
+ return { tools: kimiTools, toolChoice: 'auto', toolWarnings };
213
+ }
214
+
215
+ case 'tool': {
216
+ if (toolChoicePolyfill) {
217
+ // Generate system message to force specific tool
218
+ const systemMessage = generateSpecificToolMessage(toolChoice.toolName);
219
+
220
+ toolWarnings.push({
221
+ type: 'compatibility',
222
+ feature: `toolChoice.tool:${toolChoice.toolName}`,
223
+ details: 'Using tool choice polyfill with system message injection.'
224
+ });
225
+
226
+ return {
227
+ tools: kimiTools,
228
+ toolChoice: 'auto',
229
+ toolWarnings,
230
+ toolChoiceSystemMessage: systemMessage
231
+ };
232
+ }
233
+
234
+ toolWarnings.push({
235
+ type: 'compatibility',
236
+ feature: `toolChoice.tool:${toolChoice.toolName}`,
237
+ details: 'Moonshot does not support forcing a specific tool. Falling back to auto.'
238
+ });
239
+ return { tools: kimiTools, toolChoice: 'auto', toolWarnings };
240
+ }
241
+
242
+ default: {
243
+ const _exhaustiveCheck: never = toolChoice;
244
+ throw new UnsupportedFunctionalityError({
245
+ functionality: `tool choice type: ${_exhaustiveCheck}`
246
+ });
247
+ }
248
+ }
249
+ }
250
+
251
+ // ============================================================================
252
+ // Tool Choice Polyfill Messages
253
+ // ============================================================================
254
+
255
+ /**
256
+ * Generate a system message to force the model to use a tool.
257
+ */
258
+ function generateRequiredToolMessage(toolNames: string): string {
259
+ return `IMPORTANT INSTRUCTION: You MUST use one of the available tools (${toolNames}) to respond to the user's request. Do NOT provide a direct text response without first calling a tool. Always invoke a tool to complete this task.`;
260
+ }
261
+
262
+ /**
263
+ * Generate a system message to force the model to use a specific tool.
264
+ */
265
+ function generateSpecificToolMessage(toolName: string): string {
266
+ return `IMPORTANT INSTRUCTION: You MUST use the "${toolName}" tool to respond to this request. Do NOT use any other tool or provide a direct text response. Call the "${toolName}" tool with appropriate parameters.`;
267
+ }
268
+
269
+ // ============================================================================
270
+ // Helper Functions
271
+ // ============================================================================
272
+
273
+ /**
274
+ * Try to convert a provider-defined tool to a Kimi built-in tool.
275
+ * Returns undefined if the tool is not a Kimi built-in tool.
276
+ */
277
+ function tryConvertToKimiBuiltinTool(tool: LanguageModelV3ProviderTool): KimiBuiltinTool | undefined {
278
+ // Check if this is a Kimi provider tool (id starts with 'kimi.')
279
+ if (!tool.id.startsWith('kimi.')) {
280
+ return undefined;
281
+ }
282
+
283
+ // Check if the args indicate a builtin_function type
284
+ const args = tool.args;
285
+ if (
286
+ args &&
287
+ typeof args === 'object' &&
288
+ 'type' in args &&
289
+ args.type === 'builtin_function' &&
290
+ 'function' in args &&
291
+ typeof args.function === 'object'
292
+ ) {
293
+ const fn = args.function as { name?: string; config?: Record<string, unknown> };
294
+ if (typeof fn.name === 'string') {
295
+ return {
296
+ type: 'builtin_function',
297
+ function: {
298
+ name: fn.name,
299
+ ...(fn.config ? { config: fn.config } : {})
300
+ }
301
+ };
302
+ }
303
+ }
304
+
305
+ return undefined;
306
+ }
package/src/version.ts ADDED
@@ -0,0 +1,4 @@
1
+ declare const __PACKAGE_VERSION__: string | undefined;
2
+
3
+ export const VERSION =
4
+ typeof __PACKAGE_VERSION__ === 'string' && __PACKAGE_VERSION__.length > 0 ? __PACKAGE_VERSION__ : '0.0.0';