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.
package/dist/index.mjs CHANGED
@@ -96,6 +96,46 @@ var KimiContextLengthError = class extends KimiError {
96
96
  this.name = "KimiContextLengthError";
97
97
  }
98
98
  };
99
+ var KimiEnsembleValidationError = class extends KimiError {
100
+ constructor(message, config, modelId) {
101
+ super(message, "ensemble_validation_error", 400);
102
+ this.name = "KimiEnsembleValidationError";
103
+ this.config = config;
104
+ this.modelId = modelId;
105
+ }
106
+ };
107
+ var KimiEnsembleTimeoutError = class extends KimiError {
108
+ constructor(message, completedSamples, requestedSamples) {
109
+ super(message, "ensemble_timeout", 408);
110
+ this.name = "KimiEnsembleTimeoutError";
111
+ this.completedSamples = completedSamples;
112
+ this.requestedSamples = requestedSamples;
113
+ }
114
+ };
115
+ var KimiMultiAgentError = class extends KimiError {
116
+ constructor(message, workflow, step, stepError) {
117
+ super(message, "multi_agent_error", 500);
118
+ this.name = "KimiMultiAgentError";
119
+ this.workflow = workflow;
120
+ this.step = step;
121
+ this.stepError = stepError;
122
+ }
123
+ };
124
+ var KimiCodeValidationError = class extends KimiError {
125
+ constructor(message, validationErrors, attempts) {
126
+ super(message, "code_validation_error", 400);
127
+ this.name = "KimiCodeValidationError";
128
+ this.validationErrors = validationErrors;
129
+ this.attempts = attempts;
130
+ }
131
+ };
132
+ var KimiScaffoldError = class extends KimiError {
133
+ constructor(message, projectType) {
134
+ super(message, "scaffold_error", 500);
135
+ this.name = "KimiScaffoldError";
136
+ this.projectType = projectType;
137
+ }
138
+ };
99
139
 
100
140
  // src/core/types.ts
101
141
  var THINKING_MODEL_TEMPERATURE = 1;
@@ -239,6 +279,131 @@ function extractMessageContent(message) {
239
279
  return { text, reasoning };
240
280
  }
241
281
 
282
+ // src/tools/auto-detect.ts
283
+ var WEB_SEARCH_PATTERNS = [
284
+ // Direct search requests
285
+ { pattern: /search\s+(for|the\s+web|online|internet)/i, weight: 1, name: "direct_search" },
286
+ { pattern: /look\s+up\b/i, weight: 0.9, name: "look_up" },
287
+ { pattern: /find\s+(information|info|data|details)\s+(about|on|regarding)/i, weight: 0.9, name: "find_info" },
288
+ // Real-time/current information
289
+ {
290
+ pattern: /\b(latest|current|recent|today'?s?|now)\b.*\b(news|price|weather|update|version|status)/i,
291
+ weight: 1,
292
+ name: "current_info"
293
+ },
294
+ { pattern: /what\s+(is|are)\s+the\s+(latest|current|newest)/i, weight: 0.95, name: "what_latest" },
295
+ { pattern: /\b(right\s+now|at\s+the\s+moment|currently)\b/i, weight: 0.7, name: "temporal" },
296
+ // News and events
297
+ { pattern: /\bnews\b.*\b(about|on|regarding)\b/i, weight: 0.85, name: "news_about" },
298
+ { pattern: /what('?s|\s+is)\s+happening\b/i, weight: 0.8, name: "happening" },
299
+ { pattern: /\b(headline|breaking|trending)\b/i, weight: 0.85, name: "headlines" },
300
+ // Prices and markets
301
+ { pattern: /\b(price|cost|rate)\s+of\b/i, weight: 0.7, name: "price" },
302
+ { pattern: /\b(stock|crypto|bitcoin|ethereum|btc|eth)\s+(price|value|market)/i, weight: 0.95, name: "crypto_stock" },
303
+ { pattern: /how\s+much\s+(does|is|are).*\b(cost|worth)\b/i, weight: 0.7, name: "how_much" },
304
+ // Weather
305
+ { pattern: /\bweather\b.*\b(in|at|for|today|tomorrow|forecast)\b/i, weight: 0.95, name: "weather" },
306
+ // Documentation and APIs
307
+ { pattern: /\bdocumentation\b.*\b(for|of|about)\b/i, weight: 0.6, name: "documentation" },
308
+ { pattern: /official\s+(website|docs|documentation|guide)/i, weight: 0.7, name: "official_docs" },
309
+ // Verification needs
310
+ { pattern: /\b(verify|confirm|check|fact-check)\b.*\b(true|accurate|correct|real)\b/i, weight: 0.75, name: "verify" },
311
+ // Comparisons with external data
312
+ { pattern: /\bcompare\b.*\b(prices|reviews|ratings|options)\b/i, weight: 0.65, name: "compare" }
313
+ ];
314
+ var CODE_INTERPRETER_PATTERNS = [
315
+ // Direct code requests
316
+ { pattern: /write\s+(a\s+)?(function|code|script|program|algorithm)/i, weight: 0.95, name: "write_code" },
317
+ { pattern: /\b(code|implement|program)\s+(this|that|the|a)/i, weight: 0.85, name: "code_this" },
318
+ { pattern: /create\s+(a\s+)?(script|function|class|module)/i, weight: 0.9, name: "create_script" },
319
+ // Mathematical calculations
320
+ { pattern: /\bcalculate\b.*\d+/i, weight: 0.9, name: "calculate" },
321
+ { pattern: /\b(compute|evaluate|solve)\b.*\b(equation|expression|formula|problem)\b/i, weight: 0.9, name: "compute" },
322
+ { pattern: /what\s+(is|are)\s+\d+[\s+\-*/^]+\d+/i, weight: 0.95, name: "arithmetic" },
323
+ { pattern: /\b(factorial|fibonacci|prime|sqrt|power|exponent)\b/i, weight: 0.85, name: "math_functions" },
324
+ // Data processing
325
+ {
326
+ pattern: /\b(parse|process|transform|convert)\s+(this\s+)?(data|json|csv|xml)/i,
327
+ weight: 0.85,
328
+ name: "data_processing"
329
+ },
330
+ { pattern: /\b(analyze|process)\s+(this\s+)?(file|dataset|table)/i, weight: 0.8, name: "analyze_data" },
331
+ // Debugging
332
+ { pattern: /\bdebug\b.*\b(this|my|the)\s+(code|function|script|program)/i, weight: 0.9, name: "debug" },
333
+ { pattern: /\b(fix|correct|repair)\s+(this|my|the)\s+(error|bug|issue|problem)\b/i, weight: 0.85, name: "fix_error" },
334
+ {
335
+ pattern: /why\s+(is|does)\s+(this|my)\s+(code|function)\s+(not\s+work|fail|error)/i,
336
+ weight: 0.9,
337
+ name: "why_not_work"
338
+ },
339
+ // Testing
340
+ {
341
+ pattern: /\b(test|verify|validate)\s+(this|my|the)\s+(code|function|implementation)/i,
342
+ weight: 0.85,
343
+ name: "test_code"
344
+ },
345
+ { pattern: /\brun\s+(this|my|the)\s+(code|script|program)/i, weight: 0.95, name: "run_code" },
346
+ { pattern: /\bexecute\b.*\b(code|script|command)/i, weight: 0.95, name: "execute" },
347
+ // Code blocks in input (handles various markdown formats)
348
+ { pattern: /```[\w]*[\s\S]*?```/, weight: 0.7, name: "code_block" },
349
+ // Algorithm requests
350
+ { pattern: /\b(sort|search|traverse|optimize)\s+(algorithm|function|method)/i, weight: 0.85, name: "algorithm" },
351
+ // Regex
352
+ { pattern: /\b(regex|regular\s+expression)\b/i, weight: 0.75, name: "regex" },
353
+ // File operations
354
+ { pattern: /\b(read|write|create|delete)\s+(a\s+)?(file|directory|folder)/i, weight: 0.7, name: "file_ops" }
355
+ ];
356
+ function detectToolsFromPrompt(prompt, config = {}) {
357
+ const { confidenceThreshold = 0.3, includePartialMatches = true } = config;
358
+ const webSearchResult = detectPatterns(prompt, WEB_SEARCH_PATTERNS, includePartialMatches);
359
+ const codeInterpreterResult = detectPatterns(prompt, CODE_INTERPRETER_PATTERNS, includePartialMatches);
360
+ return {
361
+ webSearch: webSearchResult.confidence >= confidenceThreshold,
362
+ codeInterpreter: codeInterpreterResult.confidence >= confidenceThreshold,
363
+ webSearchConfidence: webSearchResult.confidence,
364
+ codeInterpreterConfidence: codeInterpreterResult.confidence,
365
+ webSearchMatches: webSearchResult.matches,
366
+ codeInterpreterMatches: codeInterpreterResult.matches
367
+ };
368
+ }
369
+ function shouldAutoEnableTools(prompt) {
370
+ const result = detectToolsFromPrompt(prompt);
371
+ return {
372
+ webSearch: result.webSearch,
373
+ codeInterpreter: result.codeInterpreter
374
+ };
375
+ }
376
+ function detectPatterns(text, patterns, includePartial) {
377
+ const matches = [];
378
+ let maxWeight = 0;
379
+ let matchCount = 0;
380
+ for (const { pattern, weight, name } of patterns) {
381
+ if (pattern.test(text)) {
382
+ matches.push(name);
383
+ maxWeight = Math.max(maxWeight, weight);
384
+ matchCount++;
385
+ }
386
+ }
387
+ let confidence = 0;
388
+ if (matchCount > 0) {
389
+ if (includePartial) {
390
+ const boost = Math.min(0.15, (matchCount - 1) * 0.05);
391
+ confidence = Math.min(1, maxWeight + boost);
392
+ } else {
393
+ confidence = maxWeight;
394
+ }
395
+ }
396
+ return { confidence, matches };
397
+ }
398
+ function hasToolOptOut(prompt) {
399
+ const webSearchOptOut = /(don'?t|do\s+not|without|no)\s+(search(ing)?|web|internet|online)/i.test(prompt);
400
+ const codeOptOut = /(don'?t|do\s+not|without|no)\s+(run(ning)?|execut(e|ing)|cod(e|ing))/i.test(prompt) || /without\s+[\w\s]*running\s+code/i.test(prompt) || /(or|and)\s+running\s+code/i.test(prompt);
401
+ return {
402
+ webSearch: webSearchOptOut,
403
+ codeInterpreter: codeOptOut
404
+ };
405
+ }
406
+
242
407
  // src/tools/builtin-tools.ts
243
408
  var KIMI_WEB_SEARCH_TOOL_NAME = "$web_search";
244
409
  var KIMI_CODE_INTERPRETER_TOOL_NAME = "$code";
@@ -435,11 +600,49 @@ function prepareKimiTools({
435
600
  }
436
601
  }
437
602
  }
603
+ var TOOL_DESCRIPTIONS = {
604
+ $web_search: "Search the web for up-to-date information, current events, facts, news, prices, weather, or any data not available in your training",
605
+ $code: "Execute code to perform calculations, data processing, algorithmic tasks, or verify code correctness"
606
+ };
607
+ function generateToolGuidanceMessage(options) {
608
+ const { toolNames, choiceType, targetTool, promptContext, includeDescriptions = true } = options;
609
+ const lines = ["=== TOOL USAGE GUIDANCE ===", ""];
610
+ if (includeDescriptions && toolNames.length > 0) {
611
+ lines.push("Available tools:");
612
+ for (const toolName of toolNames) {
613
+ const description = TOOL_DESCRIPTIONS[toolName] || "Execute this tool";
614
+ lines.push(`- ${toolName}: ${description}`);
615
+ }
616
+ lines.push("");
617
+ }
618
+ if (choiceType === "required") {
619
+ lines.push("\u26A0\uFE0F IMPORTANT: You MUST use at least one of the available tools to respond.");
620
+ lines.push("Do NOT provide a direct text response without first calling a tool.");
621
+ } else if (choiceType === "tool" && targetTool) {
622
+ lines.push(`\u26A0\uFE0F IMPORTANT: You MUST use the "${targetTool}" tool to respond.`);
623
+ lines.push("Do NOT use any other tool or provide a direct text response.");
624
+ }
625
+ if (promptContext) {
626
+ lines.push("");
627
+ lines.push(`Task context: ${promptContext.slice(0, 200)}${promptContext.length > 200 ? "..." : ""}`);
628
+ }
629
+ return lines.join("\n");
630
+ }
438
631
  function generateRequiredToolMessage(toolNames) {
439
- 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.`;
632
+ const tools = toolNames.split(", ");
633
+ return generateToolGuidanceMessage({
634
+ toolNames: tools,
635
+ choiceType: "required",
636
+ includeDescriptions: true
637
+ });
440
638
  }
441
639
  function generateSpecificToolMessage(toolName) {
442
- 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.`;
640
+ return generateToolGuidanceMessage({
641
+ toolNames: [toolName],
642
+ choiceType: "tool",
643
+ targetTool: toolName,
644
+ includeDescriptions: true
645
+ });
443
646
  }
444
647
  var UNSUPPORTED_SCHEMA_KEYWORDS = [
445
648
  "$schema",
@@ -785,7 +988,11 @@ var kimiProviderOptionsSchema = z2.object({
785
988
  /**
786
989
  * Enable tool choice polyfill for this request.
787
990
  */
788
- toolChoicePolyfill: z2.boolean().optional()
991
+ toolChoicePolyfill: z2.boolean().optional(),
992
+ /**
993
+ * Auto-enable tools based on prompt content analysis.
994
+ */
995
+ autoEnableTools: z2.boolean().optional()
789
996
  });
790
997
 
791
998
  // src/chat/kimi-chat-language-model.ts
@@ -1401,6 +1608,879 @@ var kimiChatChunkBaseSchema = z3.looseObject({
1401
1608
  });
1402
1609
  var kimiChatChunkSchema = z3.union([kimiChatChunkBaseSchema, kimiErrorSchema]);
1403
1610
 
1611
+ // src/code-validation/detector.ts
1612
+ var LANGUAGE_PATTERNS = [
1613
+ {
1614
+ language: "typescript",
1615
+ patterns: [
1616
+ { pattern: /:\s*(string|number|boolean|void|any|unknown|never)\b/, weight: 0.9, name: "type_annotation" },
1617
+ { pattern: /interface\s+\w+\s*{/, weight: 0.95, name: "interface" },
1618
+ { pattern: /type\s+\w+\s*=/, weight: 0.9, name: "type_alias" },
1619
+ { pattern: /<\w+>/, weight: 0.5, name: "generics" },
1620
+ { pattern: /import\s+.*\s+from\s+['"]/, weight: 0.7, name: "import_from" },
1621
+ { pattern: /export\s+(interface|type|enum)\b/, weight: 0.95, name: "export_type" },
1622
+ { pattern: /as\s+(string|number|boolean|any)\b/, weight: 0.85, name: "type_assertion" }
1623
+ ]
1624
+ },
1625
+ {
1626
+ language: "javascript",
1627
+ patterns: [
1628
+ { pattern: /\bfunction\s+\w+\s*\(/, weight: 0.6, name: "function_decl" },
1629
+ { pattern: /\bconst\s+\w+\s*=/, weight: 0.5, name: "const" },
1630
+ { pattern: /\blet\s+\w+\s*=/, weight: 0.5, name: "let" },
1631
+ { pattern: /=>\s*{/, weight: 0.6, name: "arrow_function" },
1632
+ { pattern: /require\s*\(['"]/, weight: 0.7, name: "require" },
1633
+ { pattern: /module\.exports\s*=/, weight: 0.85, name: "module_exports" },
1634
+ { pattern: /console\.(log|error|warn)\(/, weight: 0.5, name: "console" }
1635
+ ]
1636
+ },
1637
+ {
1638
+ language: "python",
1639
+ patterns: [
1640
+ { pattern: /\bdef\s+\w+\s*\([^)]*\)\s*:/, weight: 0.9, name: "def" },
1641
+ { pattern: /\bclass\s+\w+.*:/, weight: 0.85, name: "class" },
1642
+ { pattern: /\bimport\s+\w+/, weight: 0.6, name: "import" },
1643
+ { pattern: /\bfrom\s+\w+\s+import\b/, weight: 0.85, name: "from_import" },
1644
+ { pattern: /\bif\s+__name__\s*==\s*['"]__main__['"]\s*:/, weight: 0.95, name: "main_guard" },
1645
+ { pattern: /\bprint\s*\(/, weight: 0.5, name: "print" },
1646
+ { pattern: /\bself\.\w+/, weight: 0.85, name: "self" },
1647
+ { pattern: /#.*$/, weight: 0.3, name: "comment" }
1648
+ ]
1649
+ },
1650
+ {
1651
+ language: "java",
1652
+ patterns: [
1653
+ { pattern: /public\s+class\s+\w+/, weight: 0.95, name: "public_class" },
1654
+ { pattern: /public\s+static\s+void\s+main/, weight: 0.98, name: "main_method" },
1655
+ { pattern: /System\.out\.println/, weight: 0.9, name: "sysout" },
1656
+ { pattern: /\bpackage\s+[\w.]+;/, weight: 0.95, name: "package" },
1657
+ { pattern: /\bimport\s+[\w.]+;/, weight: 0.8, name: "import" },
1658
+ { pattern: /@Override\b/, weight: 0.9, name: "override" },
1659
+ { pattern: /\bprivate\s+\w+\s+\w+;/, weight: 0.7, name: "private_field" }
1660
+ ]
1661
+ },
1662
+ {
1663
+ language: "go",
1664
+ patterns: [
1665
+ { pattern: /\bpackage\s+main\b/, weight: 0.95, name: "package_main" },
1666
+ { pattern: /\bfunc\s+\w+\s*\(/, weight: 0.85, name: "func" },
1667
+ { pattern: /\bfmt\.Print/, weight: 0.9, name: "fmt_print" },
1668
+ { pattern: /\bimport\s+\(/, weight: 0.85, name: "import_block" },
1669
+ { pattern: /:=/, weight: 0.7, name: "short_var_decl" },
1670
+ { pattern: /\bgo\s+\w+\(/, weight: 0.9, name: "goroutine" },
1671
+ { pattern: /\bchan\s+\w+/, weight: 0.9, name: "channel" }
1672
+ ]
1673
+ },
1674
+ {
1675
+ language: "rust",
1676
+ patterns: [
1677
+ { pattern: /\bfn\s+\w+\s*\(/, weight: 0.9, name: "fn" },
1678
+ { pattern: /\blet\s+mut\s+\w+/, weight: 0.95, name: "let_mut" },
1679
+ { pattern: /\bimpl\s+\w+\s+for\s+\w+/, weight: 0.95, name: "impl_for" },
1680
+ { pattern: /\buse\s+[\w:]+;/, weight: 0.85, name: "use" },
1681
+ { pattern: /\bpub\s+(fn|struct|enum|mod)\b/, weight: 0.9, name: "pub" },
1682
+ { pattern: /->.*{/, weight: 0.7, name: "return_type" },
1683
+ { pattern: /\bprintln!\(/, weight: 0.95, name: "println_macro" }
1684
+ ]
1685
+ },
1686
+ {
1687
+ language: "ruby",
1688
+ patterns: [
1689
+ { pattern: /\bdef\s+\w+/, weight: 0.8, name: "def" },
1690
+ { pattern: /\bclass\s+\w+/, weight: 0.7, name: "class" },
1691
+ { pattern: /\bend\s*$/, weight: 0.4, name: "end" },
1692
+ { pattern: /\brequire\s+['"]/, weight: 0.85, name: "require" },
1693
+ { pattern: /\bputs\s+/, weight: 0.8, name: "puts" },
1694
+ { pattern: /@\w+/, weight: 0.5, name: "instance_var" },
1695
+ { pattern: /\.each\s+do\s*\|/, weight: 0.85, name: "each_block" }
1696
+ ]
1697
+ },
1698
+ {
1699
+ language: "php",
1700
+ patterns: [
1701
+ { pattern: /<\?php/, weight: 0.98, name: "php_tag" },
1702
+ { pattern: /\$\w+\s*=/, weight: 0.75, name: "php_var" },
1703
+ { pattern: /\bfunction\s+\w+\s*\(/, weight: 0.5, name: "function" },
1704
+ { pattern: /\becho\s+/, weight: 0.7, name: "echo" },
1705
+ { pattern: /->(\w+)\(/, weight: 0.6, name: "method_call" },
1706
+ { pattern: /\buse\s+[\w\\]+;/, weight: 0.8, name: "use" }
1707
+ ]
1708
+ },
1709
+ {
1710
+ language: "cpp",
1711
+ patterns: [
1712
+ { pattern: /#include\s*<[\w.]+>/, weight: 0.9, name: "include_angle" },
1713
+ { pattern: /#include\s*"[\w.]+"/, weight: 0.85, name: "include_quote" },
1714
+ { pattern: /\bstd::\w+/, weight: 0.9, name: "std_namespace" },
1715
+ { pattern: /\bint\s+main\s*\(/, weight: 0.95, name: "main" },
1716
+ { pattern: /\bcout\s*<</, weight: 0.95, name: "cout" },
1717
+ { pattern: /\bnamespace\s+\w+/, weight: 0.85, name: "namespace" },
1718
+ { pattern: /\btemplate\s*</, weight: 0.9, name: "template" }
1719
+ ]
1720
+ }
1721
+ ];
1722
+ function detectLanguage(code) {
1723
+ const scores = /* @__PURE__ */ new Map();
1724
+ for (const { language } of LANGUAGE_PATTERNS) {
1725
+ scores.set(language, { score: 0, indicators: [] });
1726
+ }
1727
+ for (const { language, patterns } of LANGUAGE_PATTERNS) {
1728
+ const langScore = scores.get(language);
1729
+ for (const { pattern, weight, name } of patterns) {
1730
+ if (pattern.test(code)) {
1731
+ langScore.score += weight;
1732
+ langScore.indicators.push(name);
1733
+ }
1734
+ }
1735
+ }
1736
+ let bestLanguage = "javascript";
1737
+ let bestScore = 0;
1738
+ let bestIndicators = [];
1739
+ for (const [language, { score, indicators }] of scores) {
1740
+ if (score > bestScore) {
1741
+ bestScore = score;
1742
+ bestLanguage = language;
1743
+ bestIndicators = indicators;
1744
+ }
1745
+ }
1746
+ const tsScore = scores.get("typescript").score;
1747
+ const jsScore = scores.get("javascript").score;
1748
+ if (tsScore > 0 && jsScore > 0 && Math.abs(tsScore - jsScore) < 0.5 && scores.get("typescript").indicators.some((i) => ["type_annotation", "interface", "type_alias", "export_type"].includes(i))) {
1749
+ bestLanguage = "typescript";
1750
+ bestScore = tsScore;
1751
+ bestIndicators = scores.get("typescript").indicators;
1752
+ }
1753
+ const maxPossibleScore = LANGUAGE_PATTERNS.find((l) => l.language === bestLanguage)?.patterns.reduce((sum, p) => sum + p.weight, 0) ?? 1;
1754
+ const confidence = Math.min(1, bestScore / Math.max(1, maxPossibleScore * 0.5));
1755
+ return {
1756
+ language: bestLanguage,
1757
+ confidence,
1758
+ indicators: bestIndicators
1759
+ };
1760
+ }
1761
+ function extractCodeBlocks(text) {
1762
+ const blocks = [];
1763
+ const fenceRegex = /```(\w*)\n([\s\S]*?)```/g;
1764
+ let match = fenceRegex.exec(text);
1765
+ while (match !== null) {
1766
+ blocks.push({
1767
+ code: match[2].trim(),
1768
+ language: match[1] || void 0,
1769
+ startIndex: match.index,
1770
+ endIndex: match.index + match[0].length
1771
+ });
1772
+ match = fenceRegex.exec(text);
1773
+ }
1774
+ if (blocks.length === 0) {
1775
+ const { confidence } = detectLanguage(text);
1776
+ if (confidence > 0.3) {
1777
+ blocks.push({
1778
+ code: text.trim(),
1779
+ startIndex: 0,
1780
+ endIndex: text.length
1781
+ });
1782
+ }
1783
+ }
1784
+ return {
1785
+ blocks,
1786
+ hasCode: blocks.length > 0
1787
+ };
1788
+ }
1789
+ function extractPrimaryCode(text) {
1790
+ const { blocks, hasCode } = extractCodeBlocks(text);
1791
+ if (!hasCode) {
1792
+ return void 0;
1793
+ }
1794
+ return blocks.reduce((largest, block) => block.code.length > largest.code.length ? block : largest).code;
1795
+ }
1796
+ function containsCode(text) {
1797
+ if (/```[\s\S]*```/.test(text)) {
1798
+ return true;
1799
+ }
1800
+ const quickCodePatterns = [
1801
+ /\bfunction\s+\w+\s*\([^)]*\)\s*\{/,
1802
+ // function declarations
1803
+ /\bconst\s+\w+\s*=\s*\([^)]*\)\s*=>/,
1804
+ // arrow functions
1805
+ /\bclass\s+\w+\s*(\s+extends\s+\w+)?\s*\{/,
1806
+ // class declarations
1807
+ /\bdef\s+\w+\s*\([^)]*\)\s*:/,
1808
+ // Python functions
1809
+ /\bimport\s+.*\s+from\s+['"]/,
1810
+ // ES imports
1811
+ /\b(if|for|while)\s*\([^)]*\)\s*\{/,
1812
+ // Control structures with braces
1813
+ /=>\s*\{[\s\S]*\}/,
1814
+ // Arrow function bodies
1815
+ /\breturn\s+[\w"'`{[<]/
1816
+ // Return statements
1817
+ ];
1818
+ for (const pattern of quickCodePatterns) {
1819
+ if (pattern.test(text)) {
1820
+ return true;
1821
+ }
1822
+ }
1823
+ const { confidence } = detectLanguage(text);
1824
+ return confidence > 0.4;
1825
+ }
1826
+ function getFileExtension(language) {
1827
+ const extensions = {
1828
+ javascript: "js",
1829
+ typescript: "ts",
1830
+ python: "py",
1831
+ java: "java",
1832
+ cpp: "cpp",
1833
+ go: "go",
1834
+ rust: "rs",
1835
+ ruby: "rb",
1836
+ php: "php",
1837
+ auto: "txt"
1838
+ };
1839
+ return extensions[language] || "txt";
1840
+ }
1841
+
1842
+ // src/code-validation/validator.ts
1843
+ var CodeValidator = class {
1844
+ constructor(options) {
1845
+ this.generateText = options.generateText;
1846
+ this.executeCode = options.executeCode;
1847
+ }
1848
+ /**
1849
+ * Validate code and optionally fix errors.
1850
+ *
1851
+ * @param code - The code to validate
1852
+ * @param config - Validation configuration
1853
+ * @param originalPrompt - The original user prompt (for context in fixes)
1854
+ * @returns Validation result
1855
+ */
1856
+ async validate(code, config, originalPrompt = "") {
1857
+ const {
1858
+ maxAttempts = 3,
1859
+ language: configLanguage = "auto",
1860
+ executionTimeoutMs = 3e4,
1861
+ strictness = "strict",
1862
+ returnPartialFix = true
1863
+ } = config;
1864
+ const language = configLanguage === "auto" ? detectLanguage(code).language : configLanguage;
1865
+ let currentCode = code;
1866
+ const allErrors = [];
1867
+ const allWarnings = [];
1868
+ const fixHistory = [];
1869
+ let attempts = 0;
1870
+ for (let i = 0; i < maxAttempts; i++) {
1871
+ attempts++;
1872
+ const validationResult = await this.validateCode(currentCode, language, strictness, executionTimeoutMs);
1873
+ const newErrors = validationResult.errors.filter(
1874
+ (e) => !allErrors.some((existing) => existing.message === e.message)
1875
+ );
1876
+ allErrors.push(...newErrors);
1877
+ allWarnings.push(...validationResult.warnings);
1878
+ if (validationResult.valid) {
1879
+ return {
1880
+ valid: true,
1881
+ errors: [],
1882
+ warnings: allWarnings,
1883
+ output: validationResult.output,
1884
+ executionTimeMs: validationResult.executionTimeMs,
1885
+ attempts,
1886
+ finalCode: currentCode,
1887
+ originalCode: code,
1888
+ language,
1889
+ fixHistory
1890
+ };
1891
+ }
1892
+ if (i === maxAttempts - 1) {
1893
+ break;
1894
+ }
1895
+ const fixResult = await this.attemptFix(currentCode, validationResult.errors, language, originalPrompt);
1896
+ fixHistory.push({
1897
+ attempt: attempts,
1898
+ codeBefore: currentCode,
1899
+ codeAfter: fixResult.code,
1900
+ errorsAddressed: validationResult.errors,
1901
+ success: false
1902
+ // Will be updated if next validation passes
1903
+ });
1904
+ if (fixResult.fixed) {
1905
+ currentCode = fixResult.code;
1906
+ } else {
1907
+ break;
1908
+ }
1909
+ }
1910
+ return {
1911
+ valid: false,
1912
+ errors: allErrors,
1913
+ warnings: allWarnings,
1914
+ attempts,
1915
+ finalCode: returnPartialFix ? currentCode : code,
1916
+ originalCode: code,
1917
+ language,
1918
+ fixHistory
1919
+ };
1920
+ }
1921
+ /**
1922
+ * Validate code without attempting fixes.
1923
+ */
1924
+ async validateCode(code, language, strictness, _timeoutMs) {
1925
+ const errors = [];
1926
+ const warnings = [];
1927
+ const staticErrors = this.performStaticAnalysis(code, language);
1928
+ errors.push(...staticErrors);
1929
+ if (staticErrors.some((e) => e.type === "syntax" && e.severity === "error")) {
1930
+ return { valid: false, errors, warnings };
1931
+ }
1932
+ if (this.executeCode) {
1933
+ try {
1934
+ const startTime = Date.now();
1935
+ const output = await this.executeCode(code, language);
1936
+ const executionTimeMs = Date.now() - startTime;
1937
+ const runtimeErrors = this.detectRuntimeErrors(output);
1938
+ errors.push(...runtimeErrors);
1939
+ if (runtimeErrors.length === 0) {
1940
+ return {
1941
+ valid: true,
1942
+ errors: [],
1943
+ warnings,
1944
+ output,
1945
+ executionTimeMs
1946
+ };
1947
+ }
1948
+ } catch (error) {
1949
+ const message = error instanceof Error ? error.message : "Execution failed";
1950
+ errors.push({
1951
+ type: "runtime",
1952
+ message,
1953
+ severity: "error"
1954
+ });
1955
+ }
1956
+ }
1957
+ if (!this.executeCode && strictness !== "lenient") {
1958
+ const llmValidation = await this.validateWithLLM(code, language);
1959
+ errors.push(...llmValidation.errors);
1960
+ warnings.push(...llmValidation.warnings);
1961
+ }
1962
+ return {
1963
+ valid: errors.length === 0,
1964
+ errors,
1965
+ warnings
1966
+ };
1967
+ }
1968
+ /**
1969
+ * Perform static analysis on code.
1970
+ */
1971
+ performStaticAnalysis(code, language) {
1972
+ const errors = [];
1973
+ switch (language) {
1974
+ case "javascript":
1975
+ case "typescript":
1976
+ errors.push(...this.analyzeJavaScript(code));
1977
+ break;
1978
+ case "python":
1979
+ errors.push(...this.analyzePython(code));
1980
+ break;
1981
+ default:
1982
+ errors.push(...this.analyzeGeneric(code));
1983
+ }
1984
+ return errors;
1985
+ }
1986
+ /**
1987
+ * Analyze JavaScript/TypeScript code.
1988
+ */
1989
+ analyzeJavaScript(code) {
1990
+ const errors = [];
1991
+ const patterns = [
1992
+ { pattern: /\bif\s*\([^)]*\)\s*[^{](?!.*[;{])/, message: "Missing braces after if statement" },
1993
+ { pattern: /\bfor\s*\([^)]*\)\s*[^{](?!.*[;{])/, message: "Missing braces after for loop" },
1994
+ { pattern: /==(?!=)/, message: "Use === instead of == for strict equality", isWarning: true },
1995
+ { pattern: /!=(?!=)/, message: "Use !== instead of != for strict inequality", isWarning: true },
1996
+ { pattern: /\bconsole\.log\(/, message: "Console.log found - remove for production", isWarning: true }
1997
+ ];
1998
+ const bracketBalance = this.checkBracketBalance(code);
1999
+ if (!bracketBalance.valid) {
2000
+ errors.push({
2001
+ type: "syntax",
2002
+ message: bracketBalance.message,
2003
+ severity: "error"
2004
+ });
2005
+ }
2006
+ for (const { pattern, message, isWarning } of patterns) {
2007
+ if (pattern.test(code)) {
2008
+ errors.push({
2009
+ type: isWarning ? "style" : "syntax",
2010
+ message,
2011
+ severity: isWarning ? "warning" : "error"
2012
+ });
2013
+ }
2014
+ }
2015
+ return errors;
2016
+ }
2017
+ /**
2018
+ * Analyze Python code.
2019
+ */
2020
+ analyzePython(code) {
2021
+ const errors = [];
2022
+ const lines = code.split("\n");
2023
+ let indentUnit = null;
2024
+ for (let i = 0; i < lines.length; i++) {
2025
+ const line = lines[i];
2026
+ if (line.trim() === "" || line.trim().startsWith("#")) {
2027
+ continue;
2028
+ }
2029
+ const leadingSpaces = line.match(/^(\s*)/)?.[1].length ?? 0;
2030
+ if (indentUnit === null && leadingSpaces > 0) {
2031
+ indentUnit = leadingSpaces;
2032
+ }
2033
+ if (/^\s*\t/.test(line) && /^\s* /.test(line)) {
2034
+ errors.push({
2035
+ type: "style",
2036
+ message: "Mixed tabs and spaces in indentation",
2037
+ line: i + 1,
2038
+ severity: "warning"
2039
+ });
2040
+ }
2041
+ }
2042
+ if (/\bprint\s+[^(]/.test(code)) {
2043
+ errors.push({
2044
+ type: "syntax",
2045
+ message: "Python 2 print statement syntax - use print() function",
2046
+ severity: "error"
2047
+ });
2048
+ }
2049
+ return errors;
2050
+ }
2051
+ /**
2052
+ * Generic code analysis.
2053
+ */
2054
+ analyzeGeneric(code) {
2055
+ const errors = [];
2056
+ const bracketBalance = this.checkBracketBalance(code);
2057
+ if (!bracketBalance.valid) {
2058
+ errors.push({
2059
+ type: "syntax",
2060
+ message: bracketBalance.message,
2061
+ severity: "error"
2062
+ });
2063
+ }
2064
+ return errors;
2065
+ }
2066
+ /**
2067
+ * Check bracket balance in code.
2068
+ */
2069
+ checkBracketBalance(code) {
2070
+ const stack = [];
2071
+ const pairs = {
2072
+ "(": ")",
2073
+ "[": "]",
2074
+ "{": "}"
2075
+ };
2076
+ const cleanCode = code.replace(/"[^"\\]*(\\.[^"\\]*)*"/g, '""').replace(/'[^'\\]*(\\.[^'\\]*)*'/g, "''").replace(/`[^`\\]*(\\.[^`\\]*)*`/g, "``").replace(/\/\/.*$/gm, "").replace(/\/\*[\s\S]*?\*\//g, "").replace(/#.*$/gm, "");
2077
+ for (const char of cleanCode) {
2078
+ if (char in pairs) {
2079
+ stack.push(pairs[char]);
2080
+ } else if (Object.values(pairs).includes(char)) {
2081
+ if (stack.length === 0 || stack.pop() !== char) {
2082
+ return { valid: false, message: `Unmatched bracket: ${char}` };
2083
+ }
2084
+ }
2085
+ }
2086
+ if (stack.length > 0) {
2087
+ return { valid: false, message: `Missing closing bracket: ${stack[stack.length - 1]}` };
2088
+ }
2089
+ return { valid: true, message: "" };
2090
+ }
2091
+ /**
2092
+ * Detect runtime errors from execution output.
2093
+ */
2094
+ detectRuntimeErrors(output) {
2095
+ const errors = [];
2096
+ const errorPatterns = [
2097
+ { pattern: /SyntaxError:\s*(.+)/i, type: "syntax" },
2098
+ { pattern: /ReferenceError:\s*(.+)/i, type: "runtime" },
2099
+ { pattern: /TypeError:\s*(.+)/i, type: "runtime" },
2100
+ { pattern: /RangeError:\s*(.+)/i, type: "runtime" },
2101
+ { pattern: /Error:\s*(.+)/i, type: "runtime" },
2102
+ { pattern: /Exception:\s*(.+)/i, type: "runtime" },
2103
+ { pattern: /Traceback \(most recent call last\)/i, type: "runtime" }
2104
+ ];
2105
+ for (const { pattern, type } of errorPatterns) {
2106
+ const match = output.match(pattern);
2107
+ if (match) {
2108
+ errors.push({
2109
+ type,
2110
+ message: match[1] || match[0],
2111
+ severity: "error"
2112
+ });
2113
+ }
2114
+ }
2115
+ return errors;
2116
+ }
2117
+ /**
2118
+ * Use LLM to validate code.
2119
+ */
2120
+ async validateWithLLM(code, language) {
2121
+ const prompt = `Analyze this ${language} code for errors. Only report actual bugs, not style preferences.
2122
+ Return JSON format: {"errors": [{"message": "...", "line": N, "type": "syntax|runtime|logic"}], "warnings": [{"message": "..."}]}
2123
+ If no errors, return: {"errors": [], "warnings": []}
2124
+
2125
+ Code:
2126
+ \`\`\`${language}
2127
+ ${code}
2128
+ \`\`\`
2129
+
2130
+ Respond ONLY with the JSON object, no other text.`;
2131
+ try {
2132
+ const result = await this.generateText(prompt);
2133
+ const parsed = JSON.parse(result.text);
2134
+ return {
2135
+ errors: (parsed.errors || []).map((e) => {
2136
+ return {
2137
+ type: e.type || "logic",
2138
+ message: e.message,
2139
+ line: e.line,
2140
+ severity: "error"
2141
+ };
2142
+ }),
2143
+ warnings: (parsed.warnings || []).map((w) => {
2144
+ return {
2145
+ type: "style",
2146
+ message: w.message,
2147
+ severity: "warning"
2148
+ };
2149
+ })
2150
+ };
2151
+ } catch {
2152
+ return { errors: [], warnings: [] };
2153
+ }
2154
+ }
2155
+ /**
2156
+ * Attempt to fix errors in code.
2157
+ */
2158
+ async attemptFix(code, errors, language, originalPrompt) {
2159
+ const errorList = errors.map((e) => `- ${e.type}: ${e.message}${e.line ? ` (line ${e.line})` : ""}`).join("\n");
2160
+ const prompt = `Fix the following errors in this ${language} code.
2161
+
2162
+ ${originalPrompt ? `Original request: ${originalPrompt}
2163
+ ` : ""}
2164
+ Errors to fix:
2165
+ ${errorList}
2166
+
2167
+ Current code:
2168
+ \`\`\`${language}
2169
+ ${code}
2170
+ \`\`\`
2171
+
2172
+ Provide ONLY the fixed code wrapped in a code block. No explanations.`;
2173
+ try {
2174
+ const result = await this.generateText(prompt);
2175
+ const extractedCode = extractPrimaryCode(result.text);
2176
+ if (extractedCode && extractedCode !== code) {
2177
+ return { fixed: true, code: extractedCode };
2178
+ }
2179
+ } catch {
2180
+ }
2181
+ return { fixed: false, code };
2182
+ }
2183
+ };
2184
+ function createPassedValidationResult(code, language, output) {
2185
+ return {
2186
+ valid: true,
2187
+ errors: [],
2188
+ warnings: [],
2189
+ output,
2190
+ attempts: 1,
2191
+ finalCode: code,
2192
+ originalCode: code,
2193
+ language
2194
+ };
2195
+ }
2196
+ function createFailedValidationResult(code, language, errors) {
2197
+ return {
2198
+ valid: false,
2199
+ errors,
2200
+ warnings: [],
2201
+ attempts: 1,
2202
+ finalCode: code,
2203
+ originalCode: code,
2204
+ language
2205
+ };
2206
+ }
2207
+
2208
+ // src/ensemble/multi-sampler.ts
2209
+ var MultiSampler = class {
2210
+ constructor(options) {
2211
+ this.modelId = options.modelId;
2212
+ this.baseTemperature = options.baseTemperature ?? 0.7;
2213
+ }
2214
+ /**
2215
+ * Generate multiple samples and select the best one.
2216
+ *
2217
+ * @param generateFn - Function to generate a single response
2218
+ * @param config - Ensemble configuration
2219
+ * @returns The ensemble result
2220
+ */
2221
+ async generate(generateFn, config) {
2222
+ const startTime = Date.now();
2223
+ const {
2224
+ n,
2225
+ selectionStrategy = "best",
2226
+ temperatureVariance = 0.1,
2227
+ scoringHeuristic = "confidence",
2228
+ customScorer,
2229
+ timeoutMs = 6e4,
2230
+ allowPartialFailure = true,
2231
+ minSuccessfulSamples = 1
2232
+ } = config;
2233
+ if (n < 1 || n > 10) {
2234
+ throw new Error("Ensemble n must be between 1 and 10");
2235
+ }
2236
+ const promises = Array.from({ length: n }, async (_, i) => {
2237
+ const temperature = Math.min(this.baseTemperature + i * temperatureVariance, 2);
2238
+ const sampleStart = Date.now();
2239
+ try {
2240
+ const result2 = await generateFn({ temperature, sampleIndex: i });
2241
+ return {
2242
+ text: result2.text,
2243
+ reasoning: result2.reasoning,
2244
+ toolCalls: result2.toolCalls,
2245
+ toolResults: result2.toolResults,
2246
+ usage: result2.usage,
2247
+ sampleIndex: i,
2248
+ temperature,
2249
+ finishReason: result2.finishReason,
2250
+ success: true,
2251
+ durationMs: Date.now() - sampleStart
2252
+ };
2253
+ } catch (error) {
2254
+ return {
2255
+ text: "",
2256
+ sampleIndex: i,
2257
+ temperature,
2258
+ finishReason: "error",
2259
+ success: false,
2260
+ error: error instanceof Error ? error.message : "Unknown error",
2261
+ durationMs: Date.now() - sampleStart
2262
+ };
2263
+ }
2264
+ });
2265
+ let responses;
2266
+ try {
2267
+ responses = await Promise.race([
2268
+ Promise.all(promises),
2269
+ new Promise(
2270
+ (_, reject) => setTimeout(() => reject(new Error("Ensemble generation timed out")), timeoutMs)
2271
+ )
2272
+ ]);
2273
+ } catch (_error) {
2274
+ const partialResponses = await Promise.all(
2275
+ promises.map(
2276
+ (p) => p.catch(
2277
+ () => ({
2278
+ text: "",
2279
+ sampleIndex: -1,
2280
+ temperature: 0,
2281
+ finishReason: "timeout",
2282
+ success: false,
2283
+ error: "Timed out"
2284
+ })
2285
+ )
2286
+ )
2287
+ );
2288
+ responses = partialResponses.filter((r) => r.sampleIndex >= 0);
2289
+ }
2290
+ const successfulResponses = responses.filter((r) => r.success);
2291
+ if (successfulResponses.length < minSuccessfulSamples && !allowPartialFailure) {
2292
+ throw new Error(
2293
+ `Only ${successfulResponses.length} samples succeeded, minimum required is ${minSuccessfulSamples}`
2294
+ );
2295
+ }
2296
+ if (successfulResponses.length === 0) {
2297
+ throw new Error("All ensemble samples failed");
2298
+ }
2299
+ const result = this.selectBest(successfulResponses, responses, {
2300
+ selectionStrategy,
2301
+ scoringHeuristic,
2302
+ customScorer,
2303
+ modelId: this.modelId,
2304
+ startTime
2305
+ });
2306
+ return result;
2307
+ }
2308
+ /**
2309
+ * Select the best response based on the strategy.
2310
+ */
2311
+ selectBest(successfulResponses, allResponses, options) {
2312
+ const { selectionStrategy, scoringHeuristic, customScorer, modelId, startTime } = options;
2313
+ const scored = successfulResponses.map((r) => {
2314
+ return {
2315
+ ...r,
2316
+ score: this.calculateScore(r, scoringHeuristic, customScorer)
2317
+ };
2318
+ });
2319
+ let winner;
2320
+ let alternatives;
2321
+ switch (selectionStrategy) {
2322
+ case "first":
2323
+ winner = scored[0];
2324
+ break;
2325
+ case "vote":
2326
+ winner = this.majorityVote(scored);
2327
+ break;
2328
+ case "best":
2329
+ scored.sort((a, b) => (b.score ?? 0) - (a.score ?? 0));
2330
+ winner = scored[0];
2331
+ break;
2332
+ case "all":
2333
+ winner = scored[0];
2334
+ alternatives = scored;
2335
+ break;
2336
+ default:
2337
+ throw new Error(`Unknown selection strategy: ${selectionStrategy}`);
2338
+ }
2339
+ const metadata = {
2340
+ nRequested: allResponses.length,
2341
+ nCompleted: successfulResponses.length,
2342
+ nFailed: allResponses.filter((r) => !r.success).length,
2343
+ selectionStrategy,
2344
+ winningIndex: winner.sampleIndex,
2345
+ scores: scored.map((r) => r.score ?? 0),
2346
+ durationMs: Date.now() - startTime,
2347
+ modelId,
2348
+ totalUsage: this.aggregateUsage(successfulResponses)
2349
+ };
2350
+ return {
2351
+ text: winner.text,
2352
+ reasoning: winner.reasoning,
2353
+ toolCalls: winner.toolCalls,
2354
+ toolResults: winner.toolResults,
2355
+ usage: winner.usage ?? { promptTokens: 0, completionTokens: 0, totalTokens: 0 },
2356
+ alternatives,
2357
+ metadata
2358
+ };
2359
+ }
2360
+ /**
2361
+ * Calculate score for a response based on the heuristic.
2362
+ */
2363
+ calculateScore(response, heuristic, customScorer) {
2364
+ switch (heuristic) {
2365
+ case "length":
2366
+ return 1e3 / (response.text.length + 1);
2367
+ case "confidence":
2368
+ return response.usage?.completionTokens ?? 0;
2369
+ case "code":
2370
+ return this.scoreCodeQuality(response.text);
2371
+ case "custom":
2372
+ if (!customScorer) {
2373
+ throw new Error("Custom scorer function required for custom heuristic");
2374
+ }
2375
+ return customScorer(response);
2376
+ default:
2377
+ return 0;
2378
+ }
2379
+ }
2380
+ /**
2381
+ * Score code quality based on heuristics.
2382
+ */
2383
+ scoreCodeQuality(text) {
2384
+ let score = 100;
2385
+ const errorPatterns = [
2386
+ { pattern: /SyntaxError/gi, penalty: 25 },
2387
+ { pattern: /ReferenceError/gi, penalty: 20 },
2388
+ { pattern: /TypeError/gi, penalty: 20 },
2389
+ { pattern: /undefined is not/gi, penalty: 15 },
2390
+ { pattern: /cannot read property/gi, penalty: 15 },
2391
+ { pattern: /is not defined/gi, penalty: 15 },
2392
+ { pattern: /unexpected token/gi, penalty: 20 },
2393
+ { pattern: /null is not/gi, penalty: 15 }
2394
+ ];
2395
+ for (const { pattern, penalty } of errorPatterns) {
2396
+ const matches = text.match(pattern);
2397
+ if (matches) {
2398
+ score -= penalty * matches.length;
2399
+ }
2400
+ }
2401
+ if (text.includes("```")) {
2402
+ score += 10;
2403
+ }
2404
+ if (/\/\/.*|\/\*[\s\S]*?\*\/|#.*/.test(text)) {
2405
+ score += 5;
2406
+ }
2407
+ if (/\b(test|spec|assert|expect|describe|it)\b/i.test(text)) {
2408
+ score += 5;
2409
+ }
2410
+ if (/:\s*(string|number|boolean|void|any|unknown|never)\b/.test(text)) {
2411
+ score += 5;
2412
+ }
2413
+ if (/\b(TODO|FIXME|XXX|HACK)\b/i.test(text)) {
2414
+ score -= 5;
2415
+ }
2416
+ return Math.max(0, score);
2417
+ }
2418
+ /**
2419
+ * Select the most common response (majority voting).
2420
+ */
2421
+ majorityVote(responses) {
2422
+ const normalized = responses.map((r) => {
2423
+ return {
2424
+ response: r,
2425
+ key: r.text.toLowerCase().replace(/\s+/g, " ").trim().slice(0, 500)
2426
+ };
2427
+ });
2428
+ const votes = /* @__PURE__ */ new Map();
2429
+ for (const { response, key } of normalized) {
2430
+ const existing = votes.get(key);
2431
+ if (existing) {
2432
+ existing.count++;
2433
+ } else {
2434
+ votes.set(key, { count: 1, response });
2435
+ }
2436
+ }
2437
+ let maxVotes = 0;
2438
+ let winner = responses[0];
2439
+ for (const { count, response } of votes.values()) {
2440
+ if (count > maxVotes) {
2441
+ maxVotes = count;
2442
+ winner = response;
2443
+ }
2444
+ }
2445
+ return winner;
2446
+ }
2447
+ /**
2448
+ * Aggregate usage across all responses.
2449
+ */
2450
+ aggregateUsage(responses) {
2451
+ return responses.reduce(
2452
+ (acc, r) => {
2453
+ return {
2454
+ promptTokens: acc.promptTokens + (r.usage?.promptTokens ?? 0),
2455
+ completionTokens: acc.completionTokens + (r.usage?.completionTokens ?? 0),
2456
+ totalTokens: acc.totalTokens + (r.usage?.totalTokens ?? 0)
2457
+ };
2458
+ },
2459
+ { promptTokens: 0, completionTokens: 0, totalTokens: 0 }
2460
+ );
2461
+ }
2462
+ };
2463
+ function createSingletonEnsembleResult(response, modelId, durationMs) {
2464
+ return {
2465
+ text: response.text,
2466
+ reasoning: response.reasoning,
2467
+ toolCalls: response.toolCalls,
2468
+ toolResults: response.toolResults,
2469
+ usage: response.usage ?? { promptTokens: 0, completionTokens: 0, totalTokens: 0 },
2470
+ metadata: {
2471
+ nRequested: 1,
2472
+ nCompleted: 1,
2473
+ nFailed: 0,
2474
+ selectionStrategy: "first",
2475
+ winningIndex: 0,
2476
+ scores: [100],
2477
+ durationMs,
2478
+ modelId,
2479
+ totalUsage: response.usage ?? { promptTokens: 0, completionTokens: 0, totalTokens: 0 }
2480
+ }
2481
+ };
2482
+ }
2483
+
1404
2484
  // src/files/file-cache.ts
1405
2485
  var FileCache = class {
1406
2486
  constructor(options = {}) {
@@ -2021,8 +3101,747 @@ function guessFilename(attachment, contentType) {
2021
3101
  return extensionMap[contentType] ?? "file.bin";
2022
3102
  }
2023
3103
 
3104
+ // src/multi-agent/types.ts
3105
+ var DEFAULT_SYSTEM_PROMPTS = {
3106
+ planner: `You are a system architect and planner. Your role is to:
3107
+ 1. Analyze the problem thoroughly
3108
+ 2. Break it down into clear, actionable steps
3109
+ 3. Consider edge cases and potential issues
3110
+ 4. Provide a detailed implementation plan
3111
+
3112
+ Format your response as a numbered list of steps that can be followed to implement the solution.`,
3113
+ executor: `You are an expert implementer. Your role is to:
3114
+ 1. Follow the provided plan precisely
3115
+ 2. Write clean, well-documented code
3116
+ 3. Handle edge cases mentioned in the plan
3117
+ 4. Ensure the implementation is complete and functional
3118
+
3119
+ Provide only the implementation code with necessary comments.`,
3120
+ proposer: `You are a solution architect. Your role is to:
3121
+ 1. Analyze the problem carefully
3122
+ 2. Propose a complete solution
3123
+ 3. Consider best practices and patterns
3124
+ 4. Write clean, maintainable code
3125
+
3126
+ Provide your solution with explanations for key design decisions.`,
3127
+ critic: `You are a code reviewer and critic. Your role is to:
3128
+ 1. Review the proposed solution critically
3129
+ 2. Identify any bugs, errors, or issues
3130
+ 3. Suggest improvements for performance and readability
3131
+ 4. Verify edge cases are handled
3132
+
3133
+ Provide specific, actionable feedback. Be thorough but constructive.`
3134
+ };
3135
+
3136
+ // src/multi-agent/workflows.ts
3137
+ var WorkflowRunner = class {
3138
+ constructor(generateText, validateCode) {
3139
+ this.generateText = generateText;
3140
+ this.validateCode = validateCode;
3141
+ }
3142
+ /**
3143
+ * Run a multi-agent workflow.
3144
+ */
3145
+ async run(prompt, config) {
3146
+ const startTime = Date.now();
3147
+ switch (config.workflow) {
3148
+ case "planner-executor":
3149
+ return this.runPlannerExecutor(prompt, config, startTime);
3150
+ case "proposer-critic":
3151
+ return this.runProposerCritic(prompt, config, startTime);
3152
+ case "debate":
3153
+ return this.runDebate(prompt, config, startTime);
3154
+ case "custom":
3155
+ if (!config.customWorkflow) {
3156
+ throw new Error("Custom workflow requires customWorkflow function");
3157
+ }
3158
+ return this.runCustom(prompt, config, startTime);
3159
+ default:
3160
+ throw new Error(`Unknown workflow type: ${config.workflow}`);
3161
+ }
3162
+ }
3163
+ /**
3164
+ * Planner-Executor workflow.
3165
+ */
3166
+ async runPlannerExecutor(prompt, config, startTime) {
3167
+ const steps = [];
3168
+ let totalUsage = { promptTokens: 0, completionTokens: 0, totalTokens: 0 };
3169
+ const modelA = config.modelA || "kimi-k2.5-thinking";
3170
+ const modelB = config.modelB || "kimi-k2.5";
3171
+ const planStart = Date.now();
3172
+ const plannerPrompt = `${config.systemPrompts?.planner || DEFAULT_SYSTEM_PROMPTS.planner}
3173
+
3174
+ Problem to solve:
3175
+ ${prompt}
3176
+
3177
+ Provide a detailed step-by-step plan.`;
3178
+ const planResult = await this.generateText(modelA, plannerPrompt);
3179
+ steps.push({
3180
+ agent: "A (Planner)",
3181
+ role: "planner",
3182
+ action: "Create implementation plan",
3183
+ input: prompt,
3184
+ output: planResult.text,
3185
+ timestamp: Date.now(),
3186
+ durationMs: Date.now() - planStart,
3187
+ usage: planResult.usage,
3188
+ model: modelA
3189
+ });
3190
+ totalUsage = this.addUsage(totalUsage, planResult.usage);
3191
+ const execStart = Date.now();
3192
+ const executorPrompt = `${config.systemPrompts?.executor || DEFAULT_SYSTEM_PROMPTS.executor}
3193
+
3194
+ Plan to implement:
3195
+ ${planResult.text}
3196
+
3197
+ Original problem: ${prompt}
3198
+
3199
+ Implement the solution following the plan.`;
3200
+ const execResult = await this.generateText(modelB, executorPrompt);
3201
+ steps.push({
3202
+ agent: "B (Executor)",
3203
+ role: "executor",
3204
+ action: "Implement solution",
3205
+ input: planResult.text,
3206
+ output: execResult.text,
3207
+ timestamp: Date.now(),
3208
+ durationMs: Date.now() - execStart,
3209
+ usage: execResult.usage,
3210
+ model: modelB
3211
+ });
3212
+ totalUsage = this.addUsage(totalUsage, execResult.usage);
3213
+ let validation;
3214
+ if (config.validateCode && this.validateCode) {
3215
+ const code = extractPrimaryCode(execResult.text);
3216
+ if (code) {
3217
+ const validStart = Date.now();
3218
+ const validResult = await this.validateCode(code);
3219
+ steps.push({
3220
+ agent: "Validator",
3221
+ role: "validator",
3222
+ action: "Validate code",
3223
+ input: code,
3224
+ output: validResult.valid ? "Code is valid" : `Errors: ${validResult.errors.join(", ")}`,
3225
+ timestamp: Date.now(),
3226
+ durationMs: Date.now() - validStart
3227
+ });
3228
+ validation = {
3229
+ valid: validResult.valid,
3230
+ errors: validResult.errors,
3231
+ finalCode: validResult.fixedCode || code
3232
+ };
3233
+ }
3234
+ }
3235
+ return {
3236
+ text: execResult.text,
3237
+ reasoning: planResult.text,
3238
+ intermediateSteps: steps,
3239
+ usage: totalUsage,
3240
+ metadata: this.buildMetadata(config, steps, startTime, [modelA, modelB]),
3241
+ validation
3242
+ };
3243
+ }
3244
+ /**
3245
+ * Proposer-Critic workflow.
3246
+ */
3247
+ async runProposerCritic(prompt, config, startTime) {
3248
+ const steps = [];
3249
+ let totalUsage = { promptTokens: 0, completionTokens: 0, totalTokens: 0 };
3250
+ const modelA = config.modelA || "kimi-k2.5";
3251
+ const modelB = config.modelB || "kimi-k2.5-thinking";
3252
+ const iterations = config.iterations || 2;
3253
+ let currentSolution = "";
3254
+ let critique = "";
3255
+ for (let i = 0; i < iterations; i++) {
3256
+ const proposeStart = Date.now();
3257
+ const proposerPrompt = i === 0 ? `${config.systemPrompts?.proposer || DEFAULT_SYSTEM_PROMPTS.proposer}
3258
+
3259
+ Problem: ${prompt}
3260
+
3261
+ Provide your solution.` : `${config.systemPrompts?.proposer || DEFAULT_SYSTEM_PROMPTS.proposer}
3262
+
3263
+ Problem: ${prompt}
3264
+
3265
+ Previous solution:
3266
+ ${currentSolution}
3267
+
3268
+ Critique/feedback to address:
3269
+ ${critique}
3270
+
3271
+ Provide an improved solution addressing the feedback.`;
3272
+ const proposeResult = await this.generateText(modelA, proposerPrompt);
3273
+ currentSolution = proposeResult.text;
3274
+ steps.push({
3275
+ agent: "A (Proposer)",
3276
+ role: "proposer",
3277
+ action: `Generate solution (iteration ${i + 1})`,
3278
+ input: i === 0 ? prompt : critique,
3279
+ output: currentSolution,
3280
+ timestamp: Date.now(),
3281
+ durationMs: Date.now() - proposeStart,
3282
+ usage: proposeResult.usage,
3283
+ model: modelA
3284
+ });
3285
+ totalUsage = this.addUsage(totalUsage, proposeResult.usage);
3286
+ if (i < iterations - 1) {
3287
+ const critiqueStart = Date.now();
3288
+ const criticPrompt = `${config.systemPrompts?.critic || DEFAULT_SYSTEM_PROMPTS.critic}
3289
+
3290
+ Original problem: ${prompt}
3291
+
3292
+ Solution to review:
3293
+ ${currentSolution}
3294
+
3295
+ Provide detailed feedback and suggestions for improvement.`;
3296
+ const critiqueResult = await this.generateText(modelB, criticPrompt);
3297
+ critique = critiqueResult.text;
3298
+ steps.push({
3299
+ agent: "B (Critic)",
3300
+ role: "critic",
3301
+ action: `Critique solution (iteration ${i + 1})`,
3302
+ input: currentSolution,
3303
+ output: critique,
3304
+ timestamp: Date.now(),
3305
+ durationMs: Date.now() - critiqueStart,
3306
+ usage: critiqueResult.usage,
3307
+ model: modelB
3308
+ });
3309
+ totalUsage = this.addUsage(totalUsage, critiqueResult.usage);
3310
+ }
3311
+ }
3312
+ let validation;
3313
+ if (config.validateCode && this.validateCode) {
3314
+ const code = extractPrimaryCode(currentSolution);
3315
+ if (code) {
3316
+ const validResult = await this.validateCode(code);
3317
+ validation = {
3318
+ valid: validResult.valid,
3319
+ errors: validResult.errors,
3320
+ finalCode: validResult.fixedCode || code
3321
+ };
3322
+ }
3323
+ }
3324
+ return {
3325
+ text: currentSolution,
3326
+ reasoning: critique,
3327
+ intermediateSteps: steps,
3328
+ usage: totalUsage,
3329
+ metadata: this.buildMetadata(config, steps, startTime, [modelA, modelB]),
3330
+ validation
3331
+ };
3332
+ }
3333
+ /**
3334
+ * Debate workflow.
3335
+ */
3336
+ async runDebate(prompt, config, startTime) {
3337
+ const steps = [];
3338
+ let totalUsage = { promptTokens: 0, completionTokens: 0, totalTokens: 0 };
3339
+ const modelA = config.modelA || "kimi-k2.5";
3340
+ const modelB = config.modelB || "kimi-k2.5";
3341
+ const iterations = config.iterations || 2;
3342
+ let positionA = "";
3343
+ let positionB = "";
3344
+ const initialPrompt = `Problem: ${prompt}
3345
+
3346
+ Provide your solution and reasoning.`;
3347
+ const aStart = Date.now();
3348
+ const aResult = await this.generateText(modelA, initialPrompt);
3349
+ positionA = aResult.text;
3350
+ steps.push({
3351
+ agent: "A",
3352
+ role: "proposer",
3353
+ action: "Initial position",
3354
+ input: prompt,
3355
+ output: positionA,
3356
+ timestamp: Date.now(),
3357
+ durationMs: Date.now() - aStart,
3358
+ usage: aResult.usage,
3359
+ model: modelA
3360
+ });
3361
+ totalUsage = this.addUsage(totalUsage, aResult.usage);
3362
+ const bStart = Date.now();
3363
+ const bResult = await this.generateText(modelB, initialPrompt);
3364
+ positionB = bResult.text;
3365
+ steps.push({
3366
+ agent: "B",
3367
+ role: "proposer",
3368
+ action: "Initial position",
3369
+ input: prompt,
3370
+ output: positionB,
3371
+ timestamp: Date.now(),
3372
+ durationMs: Date.now() - bStart,
3373
+ usage: bResult.usage,
3374
+ model: modelB
3375
+ });
3376
+ totalUsage = this.addUsage(totalUsage, bResult.usage);
3377
+ for (let i = 0; i < iterations - 1; i++) {
3378
+ const aDebateStart = Date.now();
3379
+ const aDebatePrompt = `Problem: ${prompt}
3380
+
3381
+ Your previous position:
3382
+ ${positionA}
3383
+
3384
+ Other perspective:
3385
+ ${positionB}
3386
+
3387
+ Consider the other perspective. Either defend your position with additional reasoning, or revise it based on valid points. Provide your updated solution.`;
3388
+ const aDebateResult = await this.generateText(modelA, aDebatePrompt);
3389
+ positionA = aDebateResult.text;
3390
+ steps.push({
3391
+ agent: "A",
3392
+ role: "proposer",
3393
+ action: `Debate round ${i + 1}`,
3394
+ input: positionB,
3395
+ output: positionA,
3396
+ timestamp: Date.now(),
3397
+ durationMs: Date.now() - aDebateStart,
3398
+ usage: aDebateResult.usage,
3399
+ model: modelA
3400
+ });
3401
+ totalUsage = this.addUsage(totalUsage, aDebateResult.usage);
3402
+ const bDebateStart = Date.now();
3403
+ const bDebatePrompt = `Problem: ${prompt}
3404
+
3405
+ Your previous position:
3406
+ ${positionB}
3407
+
3408
+ Other perspective:
3409
+ ${positionA}
3410
+
3411
+ Consider the other perspective. Either defend your position with additional reasoning, or revise it based on valid points. Provide your updated solution.`;
3412
+ const bDebateResult = await this.generateText(modelB, bDebatePrompt);
3413
+ positionB = bDebateResult.text;
3414
+ steps.push({
3415
+ agent: "B",
3416
+ role: "proposer",
3417
+ action: `Debate round ${i + 1}`,
3418
+ input: positionA,
3419
+ output: positionB,
3420
+ timestamp: Date.now(),
3421
+ durationMs: Date.now() - bDebateStart,
3422
+ usage: bDebateResult.usage,
3423
+ model: modelB
3424
+ });
3425
+ totalUsage = this.addUsage(totalUsage, bDebateResult.usage);
3426
+ }
3427
+ const finalText = positionA.length > positionB.length ? positionA : positionB;
3428
+ return {
3429
+ text: finalText,
3430
+ reasoning: `Debate synthesis from ${iterations} rounds`,
3431
+ intermediateSteps: steps,
3432
+ usage: totalUsage,
3433
+ metadata: this.buildMetadata(config, steps, startTime, [modelA, modelB])
3434
+ };
3435
+ }
3436
+ /**
3437
+ * Custom workflow.
3438
+ */
3439
+ async runCustom(prompt, config, startTime) {
3440
+ const steps = [];
3441
+ const modelA = config.modelA || "kimi-k2.5";
3442
+ const modelB = config.modelB || "kimi-k2.5";
3443
+ const context = {
3444
+ generateWithModelA: (p) => this.generateText(modelA, p),
3445
+ generateWithModelB: (p) => this.generateText(modelB, p),
3446
+ validateCode: this.validateCode,
3447
+ config,
3448
+ addStep: (step) => {
3449
+ steps.push({
3450
+ ...step,
3451
+ timestamp: Date.now(),
3452
+ durationMs: 0
3453
+ });
3454
+ }
3455
+ };
3456
+ const result = await config.customWorkflow(prompt, context);
3457
+ if (result.intermediateSteps.length === 0 && steps.length > 0) {
3458
+ result.intermediateSteps = steps;
3459
+ }
3460
+ result.metadata.durationMs = Date.now() - startTime;
3461
+ return result;
3462
+ }
3463
+ /**
3464
+ * Build metadata for result.
3465
+ */
3466
+ buildMetadata(config, steps, startTime, models) {
3467
+ return {
3468
+ workflow: config.workflow,
3469
+ iterations: steps.length,
3470
+ durationMs: Date.now() - startTime,
3471
+ models: [...new Set(models)],
3472
+ validationEnabled: config.validateCode ?? false,
3473
+ success: true
3474
+ };
3475
+ }
3476
+ /**
3477
+ * Add usage stats.
3478
+ */
3479
+ addUsage(a, b) {
3480
+ if (!b) {
3481
+ return a;
3482
+ }
3483
+ return {
3484
+ promptTokens: a.promptTokens + b.promptTokens,
3485
+ completionTokens: a.completionTokens + b.completionTokens,
3486
+ totalTokens: a.totalTokens + b.totalTokens
3487
+ };
3488
+ }
3489
+ };
3490
+ function createEmptyMultiAgentResult(workflow, error) {
3491
+ return {
3492
+ text: "",
3493
+ intermediateSteps: [],
3494
+ usage: { promptTokens: 0, completionTokens: 0, totalTokens: 0 },
3495
+ metadata: {
3496
+ workflow,
3497
+ iterations: 0,
3498
+ durationMs: 0,
3499
+ models: [],
3500
+ validationEnabled: false,
3501
+ success: false,
3502
+ error
3503
+ }
3504
+ };
3505
+ }
3506
+
3507
+ // src/project-tools/scaffolder.ts
3508
+ var ProjectScaffolder = class {
3509
+ constructor(options) {
3510
+ this.generateText = options.generateText;
3511
+ }
3512
+ /**
3513
+ * Scaffold a new project based on a description.
3514
+ *
3515
+ * @param description - Description of the project to create
3516
+ * @param config - Scaffold configuration
3517
+ * @returns Scaffold result with files and instructions
3518
+ */
3519
+ async scaffold(description, config = {}) {
3520
+ const {
3521
+ type = "auto",
3522
+ includeTests = true,
3523
+ includeCI = false,
3524
+ includeDocs = true,
3525
+ includeDocker = false,
3526
+ includeLinting = true,
3527
+ outputFormat = "files",
3528
+ useTypeScript = true,
3529
+ features = [],
3530
+ customTemplate
3531
+ } = config;
3532
+ const prompt = this.buildScaffoldPrompt(description, {
3533
+ type,
3534
+ includeTests,
3535
+ includeCI,
3536
+ includeDocs,
3537
+ includeDocker,
3538
+ includeLinting,
3539
+ useTypeScript,
3540
+ features,
3541
+ customTemplate
3542
+ });
3543
+ const result = await this.generateText(prompt);
3544
+ const parsed = this.parseResponse(result.text, type);
3545
+ return this.formatResult(parsed, outputFormat, result.text);
3546
+ }
3547
+ /**
3548
+ * Build the scaffold prompt.
3549
+ */
3550
+ buildScaffoldPrompt(description, config) {
3551
+ const parts = [];
3552
+ parts.push("Generate a complete project structure for the following description:");
3553
+ parts.push(`"${description}"`);
3554
+ parts.push("");
3555
+ if (config.type !== "auto") {
3556
+ parts.push(`Framework/Type: ${config.type}`);
3557
+ }
3558
+ parts.push(`Language: ${config.useTypeScript ? "TypeScript" : "JavaScript/Python/Go (as appropriate)"}`);
3559
+ const includes = [];
3560
+ if (config.includeTests) {
3561
+ includes.push("comprehensive test files");
3562
+ }
3563
+ if (config.includeCI) {
3564
+ includes.push("GitHub Actions CI/CD workflow");
3565
+ }
3566
+ if (config.includeDocs) {
3567
+ includes.push("README with setup instructions");
3568
+ }
3569
+ if (config.includeDocker) {
3570
+ includes.push("Dockerfile and docker-compose.yml");
3571
+ }
3572
+ if (config.includeLinting) {
3573
+ includes.push("ESLint/linting configuration");
3574
+ }
3575
+ if (includes.length > 0) {
3576
+ parts.push(`Include: ${includes.join(", ")}`);
3577
+ }
3578
+ if (config.features.length > 0) {
3579
+ parts.push(`Additional features: ${config.features.join(", ")}`);
3580
+ }
3581
+ if (config.customTemplate) {
3582
+ parts.push("");
3583
+ parts.push("Custom requirements:");
3584
+ parts.push(config.customTemplate);
3585
+ }
3586
+ parts.push("");
3587
+ parts.push("Respond with a JSON object in this exact format:");
3588
+ parts.push("```json");
3589
+ parts.push("{");
3590
+ parts.push(' "projectName": "project-name",');
3591
+ parts.push(' "projectType": "detected-type",');
3592
+ parts.push(' "technologies": ["tech1", "tech2"],');
3593
+ parts.push(' "files": [');
3594
+ parts.push(" {");
3595
+ parts.push(' "path": "relative/path/to/file.ts",');
3596
+ parts.push(' "content": "full file content here",');
3597
+ parts.push(' "description": "what this file does"');
3598
+ parts.push(" }");
3599
+ parts.push(" ],");
3600
+ parts.push(' "setupCommands": ["npm install", "npm run dev"],');
3601
+ parts.push(' "estimatedSetupTime": "5 minutes"');
3602
+ parts.push("}");
3603
+ parts.push("```");
3604
+ parts.push("");
3605
+ parts.push(
3606
+ "Include ALL necessary files for a working project: package.json/requirements.txt, source files, config files, etc."
3607
+ );
3608
+ parts.push("Make sure file contents are complete and functional, not placeholders.");
3609
+ return parts.join("\n");
3610
+ }
3611
+ /**
3612
+ * Parse the model response into structured data.
3613
+ */
3614
+ parseResponse(text, defaultType) {
3615
+ const jsonMatch = text.match(/```json\n?([\s\S]*?)```/) || text.match(/\{[\s\S]*"files"[\s\S]*\}/);
3616
+ if (jsonMatch) {
3617
+ try {
3618
+ const json = JSON.parse(jsonMatch[1] || jsonMatch[0]);
3619
+ const files = (json.files || []).map((f) => {
3620
+ return {
3621
+ path: f.path,
3622
+ content: f.content,
3623
+ description: f.description
3624
+ };
3625
+ });
3626
+ let projectType;
3627
+ if (json.projectType) {
3628
+ projectType = json.projectType;
3629
+ } else if (defaultType === "auto") {
3630
+ projectType = this.detectProjectType(files);
3631
+ } else {
3632
+ projectType = defaultType;
3633
+ }
3634
+ return {
3635
+ files,
3636
+ metadata: {
3637
+ projectType,
3638
+ projectName: json.projectName || "my-project",
3639
+ fileCount: files.length,
3640
+ totalSize: files.reduce((sum, f) => sum + (f.content?.length || 0), 0),
3641
+ estimatedSetupTime: json.estimatedSetupTime || "unknown",
3642
+ technologies: json.technologies || [],
3643
+ features: []
3644
+ },
3645
+ setupCommands: json.setupCommands || []
3646
+ };
3647
+ } catch {
3648
+ }
3649
+ }
3650
+ return this.parseFromCodeBlocks(text, defaultType);
3651
+ }
3652
+ /**
3653
+ * Parse files from markdown code blocks.
3654
+ */
3655
+ parseFromCodeBlocks(text, defaultType) {
3656
+ const files = [];
3657
+ const fileBlockRegex = /```(?:(\w+):)?([\w./-]+)\n([\s\S]*?)```/g;
3658
+ let match = fileBlockRegex.exec(text);
3659
+ while (match !== null) {
3660
+ const path = match[2];
3661
+ const content = match[3].trim();
3662
+ if (path.includes(".")) {
3663
+ files.push({
3664
+ path,
3665
+ content,
3666
+ description: void 0
3667
+ });
3668
+ }
3669
+ match = fileBlockRegex.exec(text);
3670
+ }
3671
+ if (files.length === 0) {
3672
+ const genericBlockRegex = /```(\w*)\n([\s\S]*?)```/g;
3673
+ let blockMatch = genericBlockRegex.exec(text);
3674
+ let index = 0;
3675
+ while (blockMatch !== null) {
3676
+ const lang = blockMatch[1] || "txt";
3677
+ const content = blockMatch[2].trim();
3678
+ if (content.length > 10) {
3679
+ const ext = this.getExtensionForLanguage(lang);
3680
+ files.push({
3681
+ path: `file${index}.${ext}`,
3682
+ content
3683
+ });
3684
+ index++;
3685
+ }
3686
+ blockMatch = genericBlockRegex.exec(text);
3687
+ }
3688
+ }
3689
+ return {
3690
+ files,
3691
+ metadata: {
3692
+ projectType: defaultType === "auto" ? this.detectProjectType(files) : defaultType,
3693
+ projectName: "my-project",
3694
+ fileCount: files.length,
3695
+ totalSize: files.reduce((sum, f) => sum + f.content.length, 0),
3696
+ estimatedSetupTime: "unknown",
3697
+ technologies: [],
3698
+ features: []
3699
+ },
3700
+ setupCommands: []
3701
+ };
3702
+ }
3703
+ /**
3704
+ * Detect project type from files.
3705
+ */
3706
+ detectProjectType(files) {
3707
+ const paths = files.map((f) => f.path.toLowerCase());
3708
+ const contents = files.map((f) => f.content);
3709
+ if (paths.some((p) => p.includes("next.config"))) {
3710
+ return "nextjs";
3711
+ }
3712
+ if (contents.some((c) => c.includes("from fastapi"))) {
3713
+ return "fastapi";
3714
+ }
3715
+ if (contents.some((c) => c.includes("from flask"))) {
3716
+ return "flask";
3717
+ }
3718
+ if (paths.some((p) => p.includes("package.json"))) {
3719
+ const pkgFile = files.find((f) => f.path.includes("package.json"));
3720
+ if (pkgFile) {
3721
+ if (pkgFile.content.includes('"react"')) {
3722
+ return "react";
3723
+ }
3724
+ if (pkgFile.content.includes('"vue"')) {
3725
+ return "vue";
3726
+ }
3727
+ if (pkgFile.content.includes('"express"')) {
3728
+ return "express";
3729
+ }
3730
+ if (pkgFile.content.includes('"fastify"')) {
3731
+ return "fastify";
3732
+ }
3733
+ }
3734
+ return "node";
3735
+ }
3736
+ if (paths.some((p) => p.includes("requirements.txt") || p.endsWith(".py"))) {
3737
+ return "python";
3738
+ }
3739
+ if (paths.some((p) => p.includes("go.mod") || p.endsWith(".go"))) {
3740
+ return "go";
3741
+ }
3742
+ if (paths.some((p) => p.includes("cargo.toml") || p.endsWith(".rs"))) {
3743
+ return "rust";
3744
+ }
3745
+ return "node";
3746
+ }
3747
+ /**
3748
+ * Get file extension for a language.
3749
+ */
3750
+ getExtensionForLanguage(lang) {
3751
+ const map = {
3752
+ typescript: "ts",
3753
+ javascript: "js",
3754
+ python: "py",
3755
+ go: "go",
3756
+ rust: "rs",
3757
+ json: "json",
3758
+ yaml: "yml",
3759
+ markdown: "md",
3760
+ html: "html",
3761
+ css: "css",
3762
+ shell: "sh",
3763
+ bash: "sh",
3764
+ dockerfile: "dockerfile",
3765
+ sql: "sql"
3766
+ };
3767
+ return map[lang.toLowerCase()] || "txt";
3768
+ }
3769
+ /**
3770
+ * Format the result based on output format.
3771
+ */
3772
+ formatResult(parsed, format, rawResponse) {
3773
+ const instructions = this.generateInstructions(parsed);
3774
+ return {
3775
+ files: format === "instructions" ? [] : parsed.files,
3776
+ instructions,
3777
+ setupCommands: parsed.setupCommands,
3778
+ metadata: parsed.metadata,
3779
+ rawResponse: format === "json" ? rawResponse : void 0
3780
+ };
3781
+ }
3782
+ /**
3783
+ * Generate setup instructions.
3784
+ */
3785
+ generateInstructions(parsed) {
3786
+ const lines = [];
3787
+ lines.push(`# ${parsed.metadata.projectName} Setup`);
3788
+ lines.push("");
3789
+ lines.push(`Project type: ${parsed.metadata.projectType}`);
3790
+ lines.push(`Files: ${parsed.metadata.fileCount}`);
3791
+ lines.push("");
3792
+ if (parsed.metadata.technologies.length > 0) {
3793
+ lines.push("## Technologies");
3794
+ lines.push(parsed.metadata.technologies.map((t) => `- ${t}`).join("\n"));
3795
+ lines.push("");
3796
+ }
3797
+ lines.push("## Quick Start");
3798
+ lines.push("");
3799
+ lines.push("1. Create project directory:");
3800
+ lines.push("```bash");
3801
+ lines.push(`mkdir ${parsed.metadata.projectName}`);
3802
+ lines.push(`cd ${parsed.metadata.projectName}`);
3803
+ lines.push("```");
3804
+ lines.push("");
3805
+ lines.push("2. Create the following files:");
3806
+ for (const file of parsed.files.slice(0, 10)) {
3807
+ lines.push(` - \`${file.path}\`${file.description ? `: ${file.description}` : ""}`);
3808
+ }
3809
+ if (parsed.files.length > 10) {
3810
+ lines.push(` - ... and ${parsed.files.length - 10} more files`);
3811
+ }
3812
+ lines.push("");
3813
+ if (parsed.setupCommands.length > 0) {
3814
+ lines.push("3. Run setup commands:");
3815
+ lines.push("```bash");
3816
+ lines.push(parsed.setupCommands.join("\n"));
3817
+ lines.push("```");
3818
+ lines.push("");
3819
+ }
3820
+ if (parsed.metadata.estimatedSetupTime !== "unknown") {
3821
+ lines.push(`Estimated setup time: ${parsed.metadata.estimatedSetupTime}`);
3822
+ }
3823
+ return lines.join("\n");
3824
+ }
3825
+ };
3826
+ function createEmptyScaffoldResult(error) {
3827
+ return {
3828
+ files: [],
3829
+ instructions: `Error: ${error}`,
3830
+ setupCommands: [],
3831
+ metadata: {
3832
+ projectType: "auto",
3833
+ projectName: "unknown",
3834
+ fileCount: 0,
3835
+ totalSize: 0,
3836
+ estimatedSetupTime: "unknown",
3837
+ technologies: [],
3838
+ features: []
3839
+ }
3840
+ };
3841
+ }
3842
+
2024
3843
  // src/version.ts
2025
- var VERSION = "0.4.0".length > 0 ? "0.4.0" : "0.0.0";
3844
+ var VERSION = "0.5.0".length > 0 ? "0.5.0" : "0.0.0";
2026
3845
 
2027
3846
  // src/kimi-provider.ts
2028
3847
  var GLOBAL_BASE_URL = "https://api.moonshot.ai/v1";
@@ -2078,6 +3897,82 @@ function createKimi(options = {}) {
2078
3897
  provider.rerankingModel = (modelId) => {
2079
3898
  throw new NoSuchModelError({ modelId, modelType: "rerankingModel" });
2080
3899
  };
3900
+ provider.ensemble = async (prompt, generateFn, ensembleOptions = {}) => {
3901
+ const { model = "kimi-k2.5", baseTemperature = 0.7, ...config } = ensembleOptions;
3902
+ const sampler = new MultiSampler({
3903
+ modelId: model,
3904
+ baseTemperature
3905
+ });
3906
+ const wrappedGenerateFn = async (options2) => {
3907
+ const languageModel = createChatModel(model, {});
3908
+ const result = await generateFn(languageModel, prompt, { temperature: options2.temperature });
3909
+ return {
3910
+ text: result.text,
3911
+ reasoning: result.reasoning,
3912
+ toolCalls: result.toolCalls,
3913
+ toolResults: result.toolResults,
3914
+ usage: result.usage,
3915
+ finishReason: result.finishReason ?? "stop"
3916
+ };
3917
+ };
3918
+ return sampler.generate(wrappedGenerateFn, {
3919
+ n: config.n ?? 3,
3920
+ selectionStrategy: config.selectionStrategy ?? "best",
3921
+ temperatureVariance: config.temperatureVariance ?? 0.1,
3922
+ scoringHeuristic: config.scoringHeuristic ?? "confidence",
3923
+ customScorer: config.customScorer,
3924
+ timeoutMs: config.timeoutMs ?? 6e4,
3925
+ allowPartialFailure: config.allowPartialFailure ?? true,
3926
+ minSuccessfulSamples: config.minSuccessfulSamples ?? 1
3927
+ });
3928
+ };
3929
+ provider.multiAgent = async (prompt, generateFn, agentOptions = {}) => {
3930
+ const { modelSettings, ...config } = agentOptions;
3931
+ const runner = new WorkflowRunner(generateFn);
3932
+ return runner.run(prompt, {
3933
+ workflow: config.workflow ?? "planner-executor",
3934
+ modelA: config.modelA ?? "kimi-k2.5-thinking",
3935
+ modelB: config.modelB ?? "kimi-k2.5",
3936
+ iterations: config.iterations ?? 2,
3937
+ validateCode: config.validateCode ?? false,
3938
+ timeoutMs: config.timeoutMs ?? 12e4,
3939
+ customWorkflow: config.customWorkflow,
3940
+ verbose: config.verbose ?? false,
3941
+ systemPrompts: config.systemPrompts
3942
+ });
3943
+ };
3944
+ provider.validateCode = async (code, generateFn, validateOptions = {}) => {
3945
+ const { model = "kimi-k2.5", modelSettings, ...config } = validateOptions;
3946
+ const languageModel = createChatModel(model, modelSettings);
3947
+ const llmGenerateFn = generateFn ? async (prompt) => generateFn(languageModel, prompt) : async (_prompt) => {
3948
+ return { text: "" };
3949
+ };
3950
+ const validator = new CodeValidator({
3951
+ generateText: llmGenerateFn
3952
+ });
3953
+ return validator.validate(code, {
3954
+ enabled: true,
3955
+ maxAttempts: config.maxAttempts ?? 3,
3956
+ language: config.language ?? "auto",
3957
+ strictness: config.strictness ?? "strict",
3958
+ executionTimeoutMs: config.executionTimeoutMs ?? 3e4,
3959
+ includeTests: config.includeTests ?? true,
3960
+ returnPartialFix: config.returnPartialFix ?? true
3961
+ });
3962
+ };
3963
+ provider.scaffoldProject = async (description, generateFn, scaffoldOptions = {}) => {
3964
+ const scaffolder = new ProjectScaffolder({
3965
+ generateText: generateFn
3966
+ });
3967
+ return scaffolder.scaffold(description, scaffoldOptions);
3968
+ };
3969
+ provider.detectTools = (prompt) => {
3970
+ const result = detectToolsFromPrompt(prompt);
3971
+ return {
3972
+ webSearch: result.webSearch,
3973
+ codeInterpreter: result.codeInterpreter
3974
+ };
3975
+ };
2081
3976
  return provider;
2082
3977
  }
2083
3978
  var kimi = createKimi();
@@ -2923,6 +4818,8 @@ function createKimiCode(options = {}) {
2923
4818
  }
2924
4819
  var kimiCode = createKimiCode();
2925
4820
  export {
4821
+ CodeValidator,
4822
+ DEFAULT_SYSTEM_PROMPTS,
2926
4823
  KIMI_CODE_BASE_URL,
2927
4824
  KIMI_CODE_DEFAULT_MODEL,
2928
4825
  KIMI_CODE_INTERPRETER_TOOL_NAME,
@@ -2931,22 +4828,43 @@ export {
2931
4828
  KimiAuthenticationError,
2932
4829
  KimiChatLanguageModel,
2933
4830
  KimiCodeLanguageModel,
4831
+ KimiCodeValidationError,
2934
4832
  KimiContentFilterError,
2935
4833
  KimiContextLengthError,
4834
+ KimiEnsembleTimeoutError,
4835
+ KimiEnsembleValidationError,
2936
4836
  KimiError,
2937
4837
  KimiFileClient,
2938
4838
  KimiModelNotFoundError,
4839
+ KimiMultiAgentError,
2939
4840
  KimiRateLimitError,
4841
+ KimiScaffoldError,
2940
4842
  KimiValidationError,
4843
+ MultiSampler,
4844
+ ProjectScaffolder,
2941
4845
  SUPPORTED_FILE_EXTENSIONS,
2942
4846
  SUPPORTED_MIME_TYPES,
4847
+ WorkflowRunner,
4848
+ containsCode,
2943
4849
  createCodeInterpreterTool,
4850
+ createEmptyMultiAgentResult,
4851
+ createEmptyScaffoldResult,
4852
+ createFailedValidationResult,
2944
4853
  createKimi,
2945
4854
  createKimiCode,
2946
4855
  createKimiWebSearchTool,
4856
+ createPassedValidationResult,
4857
+ createSingletonEnsembleResult,
2947
4858
  createWebSearchTool,
4859
+ detectLanguage,
4860
+ detectToolsFromPrompt,
4861
+ extractCodeBlocks,
4862
+ extractPrimaryCode,
4863
+ generateToolGuidanceMessage,
4864
+ getFileExtension,
2948
4865
  getMediaTypeFromExtension,
2949
4866
  getPurposeFromMediaType,
4867
+ hasToolOptOut,
2950
4868
  inferKimiCodeCapabilities,
2951
4869
  inferModelCapabilities,
2952
4870
  isDocumentMediaType,
@@ -2959,6 +4877,7 @@ export {
2959
4877
  kimiCodeProviderOptionsSchema,
2960
4878
  kimiProviderOptionsSchema,
2961
4879
  kimiTools,
2962
- processAttachments
4880
+ processAttachments,
4881
+ shouldAutoEnableTools
2963
4882
  };
2964
4883
  //# sourceMappingURL=index.mjs.map