kimi-vercel-ai-sdk-provider 0.4.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.
@@ -0,0 +1,244 @@
1
+ /**
2
+ * Types for project scaffolding functionality.
3
+ * @module
4
+ */
5
+
6
+ // ============================================================================
7
+ // Configuration Types
8
+ // ============================================================================
9
+
10
+ /**
11
+ * Supported project types/frameworks.
12
+ */
13
+ export type ProjectType =
14
+ | 'nextjs'
15
+ | 'react'
16
+ | 'vue'
17
+ | 'node'
18
+ | 'express'
19
+ | 'fastify'
20
+ | 'python'
21
+ | 'fastapi'
22
+ | 'flask'
23
+ | 'go'
24
+ | 'rust'
25
+ | 'auto';
26
+
27
+ /**
28
+ * Output format for scaffolded projects.
29
+ */
30
+ export type OutputFormat = 'files' | 'json' | 'instructions';
31
+
32
+ /**
33
+ * Configuration for project scaffolding.
34
+ */
35
+ export interface ScaffoldConfig {
36
+ /**
37
+ * Project type/framework.
38
+ * @default 'auto'
39
+ */
40
+ type?: ProjectType;
41
+
42
+ /**
43
+ * Include testing setup.
44
+ * @default true
45
+ */
46
+ includeTests?: boolean;
47
+
48
+ /**
49
+ * Include CI/CD configuration (e.g., GitHub Actions).
50
+ * @default false
51
+ */
52
+ includeCI?: boolean;
53
+
54
+ /**
55
+ * Include documentation (README, API docs).
56
+ * @default true
57
+ */
58
+ includeDocs?: boolean;
59
+
60
+ /**
61
+ * Include Docker configuration.
62
+ * @default false
63
+ */
64
+ includeDocker?: boolean;
65
+
66
+ /**
67
+ * Include ESLint/Prettier configuration.
68
+ * @default true
69
+ */
70
+ includeLinting?: boolean;
71
+
72
+ /**
73
+ * Output format.
74
+ * @default 'files'
75
+ */
76
+ outputFormat?: OutputFormat;
77
+
78
+ /**
79
+ * TypeScript vs JavaScript (for applicable frameworks).
80
+ * @default true
81
+ */
82
+ useTypeScript?: boolean;
83
+
84
+ /**
85
+ * Additional features to include.
86
+ */
87
+ features?: string[];
88
+
89
+ /**
90
+ * Custom template or instructions to include.
91
+ */
92
+ customTemplate?: string;
93
+ }
94
+
95
+ // ============================================================================
96
+ // Result Types
97
+ // ============================================================================
98
+
99
+ /**
100
+ * A single file in the scaffolded project.
101
+ */
102
+ export interface ProjectFile {
103
+ /**
104
+ * Relative path from project root.
105
+ */
106
+ path: string;
107
+
108
+ /**
109
+ * File contents.
110
+ */
111
+ content: string;
112
+
113
+ /**
114
+ * Description of the file's purpose.
115
+ */
116
+ description?: string;
117
+
118
+ /**
119
+ * Whether this is a binary file (base64 encoded).
120
+ */
121
+ binary?: boolean;
122
+ }
123
+
124
+ /**
125
+ * Metadata about the scaffolded project.
126
+ */
127
+ export interface ProjectMetadata {
128
+ /**
129
+ * Detected or specified project type.
130
+ */
131
+ projectType: ProjectType;
132
+
133
+ /**
134
+ * Project name (derived from description).
135
+ */
136
+ projectName: string;
137
+
138
+ /**
139
+ * Number of files generated.
140
+ */
141
+ fileCount: number;
142
+
143
+ /**
144
+ * Total size of all files (bytes).
145
+ */
146
+ totalSize: number;
147
+
148
+ /**
149
+ * Estimated setup time.
150
+ */
151
+ estimatedSetupTime: string;
152
+
153
+ /**
154
+ * Main technologies/dependencies used.
155
+ */
156
+ technologies: string[];
157
+
158
+ /**
159
+ * Features included in the project.
160
+ */
161
+ features: string[];
162
+ }
163
+
164
+ /**
165
+ * Result of scaffolding a project.
166
+ */
167
+ export interface ScaffoldResult {
168
+ /**
169
+ * Generated project files.
170
+ */
171
+ files: ProjectFile[];
172
+
173
+ /**
174
+ * Setup instructions for the user.
175
+ */
176
+ instructions: string;
177
+
178
+ /**
179
+ * Commands to run for setup.
180
+ */
181
+ setupCommands: string[];
182
+
183
+ /**
184
+ * Project metadata.
185
+ */
186
+ metadata: ProjectMetadata;
187
+
188
+ /**
189
+ * Raw response from the model (for debugging).
190
+ */
191
+ rawResponse?: string;
192
+ }
193
+
194
+ // ============================================================================
195
+ // Template Types
196
+ // ============================================================================
197
+
198
+ /**
199
+ * A project template definition.
200
+ */
201
+ export interface ProjectTemplate {
202
+ /**
203
+ * Template identifier.
204
+ */
205
+ id: string;
206
+
207
+ /**
208
+ * Human-readable name.
209
+ */
210
+ name: string;
211
+
212
+ /**
213
+ * Template description.
214
+ */
215
+ description: string;
216
+
217
+ /**
218
+ * Project type this template is for.
219
+ */
220
+ projectType: ProjectType;
221
+
222
+ /**
223
+ * Base files that are always included.
224
+ */
225
+ baseFiles: ProjectFile[];
226
+
227
+ /**
228
+ * Optional files based on configuration.
229
+ */
230
+ optionalFiles?: {
231
+ condition: keyof ScaffoldConfig;
232
+ files: ProjectFile[];
233
+ }[];
234
+
235
+ /**
236
+ * Default setup commands.
237
+ */
238
+ setupCommands: string[];
239
+
240
+ /**
241
+ * Technologies used.
242
+ */
243
+ technologies: string[];
244
+ }
@@ -0,0 +1,276 @@
1
+ /**
2
+ * Auto-detection utilities for enabling tools based on prompt content.
3
+ * @module
4
+ */
5
+
6
+ // ============================================================================
7
+ // Types
8
+ // ============================================================================
9
+
10
+ /**
11
+ * Result of auto-detecting which tools should be enabled.
12
+ */
13
+ export interface AutoDetectToolsResult {
14
+ /**
15
+ * Whether web search should be enabled.
16
+ */
17
+ webSearch: boolean;
18
+
19
+ /**
20
+ * Whether code interpreter should be enabled.
21
+ */
22
+ codeInterpreter: boolean;
23
+
24
+ /**
25
+ * Confidence score (0-1) for web search detection.
26
+ */
27
+ webSearchConfidence: number;
28
+
29
+ /**
30
+ * Confidence score (0-1) for code interpreter detection.
31
+ */
32
+ codeInterpreterConfidence: number;
33
+
34
+ /**
35
+ * Patterns that matched for web search.
36
+ */
37
+ webSearchMatches: string[];
38
+
39
+ /**
40
+ * Patterns that matched for code interpreter.
41
+ */
42
+ codeInterpreterMatches: string[];
43
+ }
44
+
45
+ /**
46
+ * Configuration for auto-detect behavior.
47
+ */
48
+ export interface AutoDetectConfig {
49
+ /**
50
+ * Minimum confidence threshold to enable a tool.
51
+ * @default 0.3
52
+ */
53
+ confidenceThreshold?: number;
54
+
55
+ /**
56
+ * Whether to include partial matches in detection.
57
+ * @default true
58
+ */
59
+ includePartialMatches?: boolean;
60
+ }
61
+
62
+ // ============================================================================
63
+ // Detection Patterns
64
+ // ============================================================================
65
+
66
+ /**
67
+ * Patterns that suggest web search would be helpful.
68
+ * Each pattern has an associated confidence weight.
69
+ */
70
+ const WEB_SEARCH_PATTERNS: Array<{ pattern: RegExp; weight: number; name: string }> = [
71
+ // Direct search requests
72
+ { pattern: /search\s+(for|the\s+web|online|internet)/i, weight: 1.0, name: 'direct_search' },
73
+ { pattern: /look\s+up\b/i, weight: 0.9, name: 'look_up' },
74
+ { pattern: /find\s+(information|info|data|details)\s+(about|on|regarding)/i, weight: 0.9, name: 'find_info' },
75
+
76
+ // Real-time/current information
77
+ {
78
+ pattern: /\b(latest|current|recent|today'?s?|now)\b.*\b(news|price|weather|update|version|status)/i,
79
+ weight: 1.0,
80
+ name: 'current_info'
81
+ },
82
+ { pattern: /what\s+(is|are)\s+the\s+(latest|current|newest)/i, weight: 0.95, name: 'what_latest' },
83
+ { pattern: /\b(right\s+now|at\s+the\s+moment|currently)\b/i, weight: 0.7, name: 'temporal' },
84
+
85
+ // News and events
86
+ { pattern: /\bnews\b.*\b(about|on|regarding)\b/i, weight: 0.85, name: 'news_about' },
87
+ { pattern: /what('?s|\s+is)\s+happening\b/i, weight: 0.8, name: 'happening' },
88
+ { pattern: /\b(headline|breaking|trending)\b/i, weight: 0.85, name: 'headlines' },
89
+
90
+ // Prices and markets
91
+ { pattern: /\b(price|cost|rate)\s+of\b/i, weight: 0.7, name: 'price' },
92
+ { pattern: /\b(stock|crypto|bitcoin|ethereum|btc|eth)\s+(price|value|market)/i, weight: 0.95, name: 'crypto_stock' },
93
+ { pattern: /how\s+much\s+(does|is|are).*\b(cost|worth)\b/i, weight: 0.7, name: 'how_much' },
94
+
95
+ // Weather
96
+ { pattern: /\bweather\b.*\b(in|at|for|today|tomorrow|forecast)\b/i, weight: 0.95, name: 'weather' },
97
+
98
+ // Documentation and APIs
99
+ { pattern: /\bdocumentation\b.*\b(for|of|about)\b/i, weight: 0.6, name: 'documentation' },
100
+ { pattern: /official\s+(website|docs|documentation|guide)/i, weight: 0.7, name: 'official_docs' },
101
+
102
+ // Verification needs
103
+ { pattern: /\b(verify|confirm|check|fact-check)\b.*\b(true|accurate|correct|real)\b/i, weight: 0.75, name: 'verify' },
104
+
105
+ // Comparisons with external data
106
+ { pattern: /\bcompare\b.*\b(prices|reviews|ratings|options)\b/i, weight: 0.65, name: 'compare' }
107
+ ];
108
+
109
+ /**
110
+ * Patterns that suggest code interpreter would be helpful.
111
+ * Each pattern has an associated confidence weight.
112
+ */
113
+ const CODE_INTERPRETER_PATTERNS: Array<{ pattern: RegExp; weight: number; name: string }> = [
114
+ // Direct code requests
115
+ { pattern: /write\s+(a\s+)?(function|code|script|program|algorithm)/i, weight: 0.95, name: 'write_code' },
116
+ { pattern: /\b(code|implement|program)\s+(this|that|the|a)/i, weight: 0.85, name: 'code_this' },
117
+ { pattern: /create\s+(a\s+)?(script|function|class|module)/i, weight: 0.9, name: 'create_script' },
118
+
119
+ // Mathematical calculations
120
+ { pattern: /\bcalculate\b.*\d+/i, weight: 0.9, name: 'calculate' },
121
+ { pattern: /\b(compute|evaluate|solve)\b.*\b(equation|expression|formula|problem)\b/i, weight: 0.9, name: 'compute' },
122
+ { pattern: /what\s+(is|are)\s+\d+[\s+\-*/^]+\d+/i, weight: 0.95, name: 'arithmetic' },
123
+ { pattern: /\b(factorial|fibonacci|prime|sqrt|power|exponent)\b/i, weight: 0.85, name: 'math_functions' },
124
+
125
+ // Data processing
126
+ {
127
+ pattern: /\b(parse|process|transform|convert)\s+(this\s+)?(data|json|csv|xml)/i,
128
+ weight: 0.85,
129
+ name: 'data_processing'
130
+ },
131
+ { pattern: /\b(analyze|process)\s+(this\s+)?(file|dataset|table)/i, weight: 0.8, name: 'analyze_data' },
132
+
133
+ // Debugging
134
+ { pattern: /\bdebug\b.*\b(this|my|the)\s+(code|function|script|program)/i, weight: 0.9, name: 'debug' },
135
+ { pattern: /\b(fix|correct|repair)\s+(this|my|the)\s+(error|bug|issue|problem)\b/i, weight: 0.85, name: 'fix_error' },
136
+ {
137
+ pattern: /why\s+(is|does)\s+(this|my)\s+(code|function)\s+(not\s+work|fail|error)/i,
138
+ weight: 0.9,
139
+ name: 'why_not_work'
140
+ },
141
+
142
+ // Testing
143
+ {
144
+ pattern: /\b(test|verify|validate)\s+(this|my|the)\s+(code|function|implementation)/i,
145
+ weight: 0.85,
146
+ name: 'test_code'
147
+ },
148
+ { pattern: /\brun\s+(this|my|the)\s+(code|script|program)/i, weight: 0.95, name: 'run_code' },
149
+ { pattern: /\bexecute\b.*\b(code|script|command)/i, weight: 0.95, name: 'execute' },
150
+
151
+ // Code blocks in input (handles various markdown formats)
152
+ { pattern: /```[\w]*[\s\S]*?```/, weight: 0.7, name: 'code_block' },
153
+
154
+ // Algorithm requests
155
+ { pattern: /\b(sort|search|traverse|optimize)\s+(algorithm|function|method)/i, weight: 0.85, name: 'algorithm' },
156
+
157
+ // Regex
158
+ { pattern: /\b(regex|regular\s+expression)\b/i, weight: 0.75, name: 'regex' },
159
+
160
+ // File operations
161
+ { pattern: /\b(read|write|create|delete)\s+(a\s+)?(file|directory|folder)/i, weight: 0.7, name: 'file_ops' }
162
+ ];
163
+
164
+ // ============================================================================
165
+ // Main Functions
166
+ // ============================================================================
167
+
168
+ /**
169
+ * Automatically detect which tools should be enabled based on prompt content.
170
+ *
171
+ * @param prompt - The user's prompt text
172
+ * @param config - Optional detection configuration
173
+ * @returns Detection result with tool recommendations
174
+ *
175
+ * @example
176
+ * ```ts
177
+ * const result = detectToolsFromPrompt('What is the current price of Bitcoin?');
178
+ * // result.webSearch === true
179
+ * // result.webSearchConfidence === 0.95
180
+ * ```
181
+ */
182
+ export function detectToolsFromPrompt(prompt: string, config: AutoDetectConfig = {}): AutoDetectToolsResult {
183
+ const { confidenceThreshold = 0.3, includePartialMatches = true } = config;
184
+
185
+ const webSearchResult = detectPatterns(prompt, WEB_SEARCH_PATTERNS, includePartialMatches);
186
+ const codeInterpreterResult = detectPatterns(prompt, CODE_INTERPRETER_PATTERNS, includePartialMatches);
187
+
188
+ return {
189
+ webSearch: webSearchResult.confidence >= confidenceThreshold,
190
+ codeInterpreter: codeInterpreterResult.confidence >= confidenceThreshold,
191
+ webSearchConfidence: webSearchResult.confidence,
192
+ codeInterpreterConfidence: codeInterpreterResult.confidence,
193
+ webSearchMatches: webSearchResult.matches,
194
+ codeInterpreterMatches: codeInterpreterResult.matches
195
+ };
196
+ }
197
+
198
+ /**
199
+ * Simple version that just returns boolean flags.
200
+ * Useful for quick checks without detailed confidence info.
201
+ *
202
+ * @param prompt - The user's prompt text
203
+ * @returns Object with boolean flags for each tool
204
+ */
205
+ export function shouldAutoEnableTools(prompt: string): {
206
+ webSearch: boolean;
207
+ codeInterpreter: boolean;
208
+ } {
209
+ const result = detectToolsFromPrompt(prompt);
210
+ return {
211
+ webSearch: result.webSearch,
212
+ codeInterpreter: result.codeInterpreter
213
+ };
214
+ }
215
+
216
+ // ============================================================================
217
+ // Helper Functions
218
+ // ============================================================================
219
+
220
+ /**
221
+ * Detect patterns in text and calculate confidence.
222
+ */
223
+ function detectPatterns(
224
+ text: string,
225
+ patterns: Array<{ pattern: RegExp; weight: number; name: string }>,
226
+ includePartial: boolean
227
+ ): { confidence: number; matches: string[] } {
228
+ const matches: string[] = [];
229
+ let maxWeight = 0;
230
+ let matchCount = 0;
231
+
232
+ for (const { pattern, weight, name } of patterns) {
233
+ if (pattern.test(text)) {
234
+ matches.push(name);
235
+ maxWeight = Math.max(maxWeight, weight);
236
+ matchCount++;
237
+ }
238
+ }
239
+
240
+ // Calculate confidence based on matches
241
+ // Use the max weight as the base, boosted by additional matches
242
+ let confidence = 0;
243
+ if (matchCount > 0) {
244
+ if (includePartial) {
245
+ // Boost confidence slightly for multiple matches (diminishing returns)
246
+ const boost = Math.min(0.15, (matchCount - 1) * 0.05);
247
+ confidence = Math.min(1.0, maxWeight + boost);
248
+ } else {
249
+ confidence = maxWeight;
250
+ }
251
+ }
252
+
253
+ return { confidence, matches };
254
+ }
255
+
256
+ /**
257
+ * Check if a prompt explicitly mentions not wanting tool usage.
258
+ * Useful for respecting user preferences.
259
+ */
260
+ export function hasToolOptOut(prompt: string): {
261
+ webSearch: boolean;
262
+ codeInterpreter: boolean;
263
+ } {
264
+ const webSearchOptOut = /(don'?t|do\s+not|without|no)\s+(search(ing)?|web|internet|online)/i.test(prompt);
265
+ // Match phrases like: "don't run", "without running code", "no code execution", etc.
266
+ // Also match "or running code" type phrases after a "without" earlier in sentence
267
+ const codeOptOut =
268
+ /(don'?t|do\s+not|without|no)\s+(run(ning)?|execut(e|ing)|cod(e|ing))/i.test(prompt) ||
269
+ /without\s+[\w\s]*running\s+code/i.test(prompt) ||
270
+ /(or|and)\s+running\s+code/i.test(prompt);
271
+
272
+ return {
273
+ webSearch: webSearchOptOut,
274
+ codeInterpreter: codeOptOut
275
+ };
276
+ }
@@ -3,6 +3,7 @@
3
3
  * @module
4
4
  */
5
5
 
6
+ export type { AutoDetectConfig, AutoDetectToolsResult } from './auto-detect';
6
7
  export type {
7
8
  KimiBuiltinTool,
8
9
  KimiCodeInterpreterConfig,
@@ -15,8 +16,11 @@ export type {
15
16
  KimiFunctionTool,
16
17
  KimiTool,
17
18
  PrepareToolsOptions,
18
- PrepareToolsResult
19
+ PrepareToolsResult,
20
+ ToolGuidanceOptions
19
21
  } from './prepare-tools';
22
+ // Auto-detection
23
+ export { detectToolsFromPrompt, hasToolOptOut, shouldAutoEnableTools } from './auto-detect';
20
24
  // Built-in tools
21
25
  export {
22
26
  KIMI_CODE_INTERPRETER_TOOL_NAME,
@@ -30,4 +34,4 @@ export {
30
34
  kimiTools
31
35
  } from './builtin-tools';
32
36
  // Tool preparation
33
- export { prepareKimiTools } from './prepare-tools';
37
+ export { generateToolGuidanceMessage, prepareKimiTools } from './prepare-tools';
@@ -256,18 +256,107 @@ export function prepareKimiTools({
256
256
  // Tool Choice Polyfill Messages
257
257
  // ============================================================================
258
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
+
259
338
  /**
260
339
  * Generate a system message to force the model to use a tool.
261
340
  */
262
341
  function generateRequiredToolMessage(toolNames: string): string {
263
- 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
+ });
264
348
  }
265
349
 
266
350
  /**
267
351
  * Generate a system message to force the model to use a specific tool.
268
352
  */
269
353
  function generateSpecificToolMessage(toolName: string): string {
270
- 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
+ });
271
360
  }
272
361
 
273
362
  // ============================================================================