kimi-vercel-ai-sdk-provider 0.3.0 → 0.5.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/README.md +567 -17
  2. package/dist/index.d.mts +1750 -3
  3. package/dist/index.d.ts +1750 -3
  4. package/dist/index.js +2317 -161
  5. package/dist/index.js.map +1 -1
  6. package/dist/index.mjs +2292 -160
  7. package/dist/index.mjs.map +1 -1
  8. package/package.json +1 -1
  9. package/src/__tests__/auto-detect.test.ts +140 -0
  10. package/src/__tests__/code-validation.test.ts +267 -0
  11. package/src/__tests__/ensemble.test.ts +242 -0
  12. package/src/__tests__/file-cache.test.ts +310 -0
  13. package/src/__tests__/model-config.test.ts +120 -0
  14. package/src/__tests__/multi-agent.test.ts +201 -0
  15. package/src/__tests__/project-tools.test.ts +181 -0
  16. package/src/__tests__/reasoning-utils.test.ts +164 -0
  17. package/src/__tests__/tools.test.ts +76 -8
  18. package/src/chat/kimi-chat-language-model.ts +21 -2
  19. package/src/chat/kimi-chat-settings.ts +15 -1
  20. package/src/code-validation/detector.ts +319 -0
  21. package/src/code-validation/index.ts +31 -0
  22. package/src/code-validation/types.ts +291 -0
  23. package/src/code-validation/validator.ts +547 -0
  24. package/src/core/errors.ts +91 -0
  25. package/src/core/index.ts +15 -3
  26. package/src/core/types.ts +57 -2
  27. package/src/core/utils.ts +138 -0
  28. package/src/ensemble/index.ts +17 -0
  29. package/src/ensemble/multi-sampler.ts +433 -0
  30. package/src/ensemble/types.ts +279 -0
  31. package/src/files/attachment-processor.ts +51 -4
  32. package/src/files/file-cache.ts +260 -0
  33. package/src/files/index.ts +16 -1
  34. package/src/index.ts +102 -3
  35. package/src/kimi-provider.ts +354 -1
  36. package/src/multi-agent/index.ts +21 -0
  37. package/src/multi-agent/types.ts +312 -0
  38. package/src/multi-agent/workflows.ts +539 -0
  39. package/src/project-tools/index.ts +16 -0
  40. package/src/project-tools/scaffolder.ts +494 -0
  41. package/src/project-tools/types.ts +244 -0
  42. package/src/tools/auto-detect.ts +276 -0
  43. package/src/tools/index.ts +6 -2
  44. package/src/tools/prepare-tools.ts +179 -4
@@ -157,13 +157,17 @@ export function prepareKimiTools({
157
157
  continue;
158
158
  }
159
159
 
160
+ // Sanitize schema for Kimi compatibility
161
+ const sanitizedSchema = sanitizeToolSchema(tool.inputSchema);
162
+
160
163
  kimiTools.push({
161
164
  type: 'function',
162
165
  function: {
163
166
  name: tool.name,
164
167
  description: tool.description,
165
- parameters: tool.inputSchema,
166
- ...(tool.strict != null ? { strict: tool.strict } : {})
168
+ parameters: sanitizedSchema
169
+ // Don't pass strict mode to Kimi - it may cause issues
170
+ // ...(tool.strict != null ? { strict: tool.strict } : {})
167
171
  }
168
172
  });
169
173
  }
@@ -252,18 +256,189 @@ export function prepareKimiTools({
252
256
  // Tool Choice Polyfill Messages
253
257
  // ============================================================================
254
258
 
259
+ /**
260
+ * Tool descriptions for better guidance.
261
+ */
262
+ const TOOL_DESCRIPTIONS: Record<string, string> = {
263
+ $web_search:
264
+ 'Search the web for up-to-date information, current events, facts, news, prices, weather, or any data not available in your training',
265
+ $code: 'Execute code to perform calculations, data processing, algorithmic tasks, or verify code correctness'
266
+ };
267
+
268
+ /**
269
+ * Options for generating tool guidance messages.
270
+ */
271
+ export interface ToolGuidanceOptions {
272
+ /**
273
+ * The tool names available.
274
+ */
275
+ toolNames: string[];
276
+
277
+ /**
278
+ * The type of tool choice.
279
+ */
280
+ choiceType: 'required' | 'tool';
281
+
282
+ /**
283
+ * The specific tool name if choiceType is 'tool'.
284
+ */
285
+ targetTool?: string;
286
+
287
+ /**
288
+ * Optional context from the user's prompt to include.
289
+ */
290
+ promptContext?: string;
291
+
292
+ /**
293
+ * Whether to include detailed tool descriptions.
294
+ * @default true
295
+ */
296
+ includeDescriptions?: boolean;
297
+ }
298
+
299
+ /**
300
+ * Generate a comprehensive tool guidance message.
301
+ *
302
+ * @param options - Options for generating the message
303
+ * @returns The generated system message
304
+ */
305
+ export function generateToolGuidanceMessage(options: ToolGuidanceOptions): string {
306
+ const { toolNames, choiceType, targetTool, promptContext, includeDescriptions = true } = options;
307
+
308
+ const lines: string[] = ['=== TOOL USAGE GUIDANCE ===', ''];
309
+
310
+ // Add tool descriptions
311
+ if (includeDescriptions && toolNames.length > 0) {
312
+ lines.push('Available tools:');
313
+ for (const toolName of toolNames) {
314
+ const description = TOOL_DESCRIPTIONS[toolName] || 'Execute this tool';
315
+ lines.push(`- ${toolName}: ${description}`);
316
+ }
317
+ lines.push('');
318
+ }
319
+
320
+ // Add the requirement
321
+ if (choiceType === 'required') {
322
+ lines.push('⚠️ IMPORTANT: You MUST use at least one of the available tools to respond.');
323
+ lines.push('Do NOT provide a direct text response without first calling a tool.');
324
+ } else if (choiceType === 'tool' && targetTool) {
325
+ lines.push(`⚠️ IMPORTANT: You MUST use the "${targetTool}" tool to respond.`);
326
+ lines.push('Do NOT use any other tool or provide a direct text response.');
327
+ }
328
+
329
+ // Add context-specific guidance
330
+ if (promptContext) {
331
+ lines.push('');
332
+ lines.push(`Task context: ${promptContext.slice(0, 200)}${promptContext.length > 200 ? '...' : ''}`);
333
+ }
334
+
335
+ return lines.join('\n');
336
+ }
337
+
255
338
  /**
256
339
  * Generate a system message to force the model to use a tool.
257
340
  */
258
341
  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.`;
342
+ const tools = toolNames.split(', ');
343
+ return generateToolGuidanceMessage({
344
+ toolNames: tools,
345
+ choiceType: 'required',
346
+ includeDescriptions: true
347
+ });
260
348
  }
261
349
 
262
350
  /**
263
351
  * Generate a system message to force the model to use a specific tool.
264
352
  */
265
353
  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.`;
354
+ return generateToolGuidanceMessage({
355
+ toolNames: [toolName],
356
+ choiceType: 'tool',
357
+ targetTool: toolName,
358
+ includeDescriptions: true
359
+ });
360
+ }
361
+
362
+ // ============================================================================
363
+ // Schema Sanitization
364
+ // ============================================================================
365
+
366
+ /**
367
+ * JSON Schema keywords that may cause issues with Kimi's API.
368
+ * These are removed during sanitization to improve compatibility.
369
+ */
370
+ const UNSUPPORTED_SCHEMA_KEYWORDS = [
371
+ '$schema',
372
+ '$id',
373
+ '$ref',
374
+ '$defs',
375
+ 'definitions',
376
+ 'if',
377
+ 'then',
378
+ 'else',
379
+ 'allOf',
380
+ 'anyOf',
381
+ 'oneOf',
382
+ 'not',
383
+ 'patternProperties',
384
+ 'additionalItems',
385
+ 'contains',
386
+ 'propertyNames',
387
+ 'const',
388
+ 'contentMediaType',
389
+ 'contentEncoding',
390
+ 'examples',
391
+ '$comment'
392
+ ] as const;
393
+
394
+ /**
395
+ * Sanitize a JSON Schema for better Kimi API compatibility.
396
+ *
397
+ * This function removes advanced schema keywords that Kimi may not
398
+ * fully support, while preserving the essential structure for validation.
399
+ *
400
+ * @param schema - The original JSON Schema
401
+ * @returns A sanitized schema safe for Kimi
402
+ */
403
+ function sanitizeToolSchema(schema: unknown): unknown {
404
+ if (schema === null || schema === undefined) {
405
+ return schema;
406
+ }
407
+
408
+ if (Array.isArray(schema)) {
409
+ return schema.map(sanitizeToolSchema);
410
+ }
411
+
412
+ if (typeof schema !== 'object') {
413
+ return schema;
414
+ }
415
+
416
+ const sanitized: Record<string, unknown> = {};
417
+ const schemaObj = schema as Record<string, unknown>;
418
+
419
+ for (const [key, value] of Object.entries(schemaObj)) {
420
+ // Skip unsupported keywords
421
+ if (UNSUPPORTED_SCHEMA_KEYWORDS.includes(key as (typeof UNSUPPORTED_SCHEMA_KEYWORDS)[number])) {
422
+ continue;
423
+ }
424
+
425
+ // Recursively sanitize nested objects
426
+ if (key === 'properties' && typeof value === 'object' && value !== null) {
427
+ const props: Record<string, unknown> = {};
428
+ for (const [propKey, propValue] of Object.entries(value as Record<string, unknown>)) {
429
+ props[propKey] = sanitizeToolSchema(propValue);
430
+ }
431
+ sanitized[key] = props;
432
+ } else if (key === 'items' && typeof value === 'object') {
433
+ sanitized[key] = sanitizeToolSchema(value);
434
+ } else if (key === 'additionalProperties' && typeof value === 'object') {
435
+ sanitized[key] = sanitizeToolSchema(value);
436
+ } else {
437
+ sanitized[key] = value;
438
+ }
439
+ }
440
+
441
+ return sanitized;
267
442
  }
268
443
 
269
444
  // ============================================================================