@vybestack/llxprt-code-core 0.6.1 → 0.7.0-nightly.251206.43b97dbf4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (140) hide show
  1. package/dist/prompt-config/defaults/default-prompts.json +5 -2
  2. package/dist/src/agents/executor.js +2 -2
  3. package/dist/src/agents/executor.js.map +1 -1
  4. package/dist/src/auth/precedence.js +9 -10
  5. package/dist/src/auth/precedence.js.map +1 -1
  6. package/dist/src/auth/types.d.ts +6 -6
  7. package/dist/src/config/config.js +10 -4
  8. package/dist/src/config/config.js.map +1 -1
  9. package/dist/src/core/coreToolScheduler.d.ts +7 -0
  10. package/dist/src/core/coreToolScheduler.js +67 -0
  11. package/dist/src/core/coreToolScheduler.js.map +1 -1
  12. package/dist/src/core/geminiChat.d.ts +8 -0
  13. package/dist/src/core/geminiChat.js +63 -5
  14. package/dist/src/core/geminiChat.js.map +1 -1
  15. package/dist/src/core/prompts.js +9 -4
  16. package/dist/src/core/prompts.js.map +1 -1
  17. package/dist/src/core/turn.js +12 -8
  18. package/dist/src/core/turn.js.map +1 -1
  19. package/dist/src/ide/ide-client.js +4 -2
  20. package/dist/src/ide/ide-client.js.map +1 -1
  21. package/dist/src/index.d.ts +6 -2
  22. package/dist/src/index.js +6 -2
  23. package/dist/src/index.js.map +1 -1
  24. package/dist/src/mcp/token-storage/file-token-storage.js +1 -6
  25. package/dist/src/mcp/token-storage/file-token-storage.js.map +1 -1
  26. package/dist/src/mcp/token-storage/keychain-token-storage.js +3 -6
  27. package/dist/src/mcp/token-storage/keychain-token-storage.js.map +1 -1
  28. package/dist/src/parsers/TextToolCallParser.d.ts +0 -15
  29. package/dist/src/parsers/TextToolCallParser.js +21 -5
  30. package/dist/src/parsers/TextToolCallParser.js.map +1 -1
  31. package/dist/src/prompt-config/defaults/tool-defaults.js +5 -2
  32. package/dist/src/prompt-config/defaults/tool-defaults.js.map +1 -1
  33. package/dist/src/prompt-config/defaults/tools/code-search.md +3 -0
  34. package/dist/src/prompt-config/defaults/tools/direct-web-fetch.md +3 -0
  35. package/dist/src/prompt-config/defaults/tools/exa-web-search.md +14 -0
  36. package/dist/src/prompt-config/defaults/tools/{web-fetch.md → google-web-fetch.md} +1 -1
  37. package/dist/src/prompt-config/defaults/tools/{web-search.md → google-web-search.md} +1 -1
  38. package/dist/src/providers/BaseProvider.d.ts +3 -0
  39. package/dist/src/providers/BaseProvider.js +11 -0
  40. package/dist/src/providers/BaseProvider.js.map +1 -1
  41. package/dist/src/providers/IProvider.d.ts +3 -0
  42. package/dist/src/providers/ProviderManager.js +6 -0
  43. package/dist/src/providers/ProviderManager.js.map +1 -1
  44. package/dist/src/providers/anthropic/AnthropicProvider.d.ts +0 -1
  45. package/dist/src/providers/anthropic/AnthropicProvider.js +233 -22
  46. package/dist/src/providers/anthropic/AnthropicProvider.js.map +1 -1
  47. package/dist/src/providers/anthropic/schemaConverter.d.ts +63 -0
  48. package/dist/src/providers/anthropic/schemaConverter.js +189 -0
  49. package/dist/src/providers/anthropic/schemaConverter.js.map +1 -0
  50. package/dist/src/providers/gemini/GeminiProvider.js +110 -13
  51. package/dist/src/providers/gemini/GeminiProvider.js.map +1 -1
  52. package/dist/src/providers/gemini/thoughtSignatures.d.ts +51 -0
  53. package/dist/src/providers/gemini/thoughtSignatures.js +189 -0
  54. package/dist/src/providers/gemini/thoughtSignatures.js.map +1 -0
  55. package/dist/src/providers/openai/OpenAIProvider.d.ts +78 -1
  56. package/dist/src/providers/openai/OpenAIProvider.js +1159 -190
  57. package/dist/src/providers/openai/OpenAIProvider.js.map +1 -1
  58. package/dist/src/providers/openai/ToolCallNormalizer.d.ts +6 -0
  59. package/dist/src/providers/openai/ToolCallNormalizer.js +16 -2
  60. package/dist/src/providers/openai/ToolCallNormalizer.js.map +1 -1
  61. package/dist/src/providers/openai/schemaConverter.d.ts +67 -0
  62. package/dist/src/providers/openai/schemaConverter.js +191 -0
  63. package/dist/src/providers/openai/schemaConverter.js.map +1 -0
  64. package/dist/src/providers/openai-responses/OpenAIResponsesProvider.d.ts +0 -4
  65. package/dist/src/providers/openai-responses/OpenAIResponsesProvider.js +3 -75
  66. package/dist/src/providers/openai-responses/OpenAIResponsesProvider.js.map +1 -1
  67. package/dist/src/providers/openai-responses/schemaConverter.d.ts +65 -0
  68. package/dist/src/providers/openai-responses/schemaConverter.js +195 -0
  69. package/dist/src/providers/openai-responses/schemaConverter.js.map +1 -0
  70. package/dist/src/providers/openai-vercel/OpenAIVercelProvider.d.ts +146 -0
  71. package/dist/src/providers/openai-vercel/OpenAIVercelProvider.js +1177 -0
  72. package/dist/src/providers/openai-vercel/OpenAIVercelProvider.js.map +1 -0
  73. package/dist/src/providers/openai-vercel/errors.d.ts +46 -0
  74. package/dist/src/providers/openai-vercel/errors.js +137 -0
  75. package/dist/src/providers/openai-vercel/errors.js.map +1 -0
  76. package/dist/src/providers/openai-vercel/index.d.ts +22 -0
  77. package/dist/src/providers/openai-vercel/index.js +23 -0
  78. package/dist/src/providers/openai-vercel/index.js.map +1 -0
  79. package/dist/src/providers/openai-vercel/messageConversion.d.ts +36 -0
  80. package/dist/src/providers/openai-vercel/messageConversion.js +410 -0
  81. package/dist/src/providers/openai-vercel/messageConversion.js.map +1 -0
  82. package/dist/src/providers/openai-vercel/schemaConverter.d.ts +66 -0
  83. package/dist/src/providers/openai-vercel/schemaConverter.js +191 -0
  84. package/dist/src/providers/openai-vercel/schemaConverter.js.map +1 -0
  85. package/dist/src/providers/openai-vercel/toolIdUtils.d.ts +33 -0
  86. package/dist/src/providers/openai-vercel/toolIdUtils.js +117 -0
  87. package/dist/src/providers/openai-vercel/toolIdUtils.js.map +1 -0
  88. package/dist/src/providers/reasoning/reasoningUtils.d.ts +43 -0
  89. package/dist/src/providers/reasoning/reasoningUtils.js +92 -0
  90. package/dist/src/providers/reasoning/reasoningUtils.js.map +1 -0
  91. package/dist/src/providers/utils/localEndpoint.js +6 -2
  92. package/dist/src/providers/utils/localEndpoint.js.map +1 -1
  93. package/dist/src/runtime/AgentRuntimeContext.d.ts +27 -0
  94. package/dist/src/runtime/AgentRuntimeContext.js.map +1 -1
  95. package/dist/src/runtime/createAgentRuntimeContext.js +27 -1
  96. package/dist/src/runtime/createAgentRuntimeContext.js.map +1 -1
  97. package/dist/src/services/history/IContent.d.ts +6 -0
  98. package/dist/src/services/history/IContent.js.map +1 -1
  99. package/dist/src/settings/types.d.ts +1 -1
  100. package/dist/src/tools/IToolFormatter.d.ts +1 -1
  101. package/dist/src/tools/ToolFormatter.js +14 -2
  102. package/dist/src/tools/ToolFormatter.js.map +1 -1
  103. package/dist/src/tools/ToolIdStrategy.d.ts +72 -0
  104. package/dist/src/tools/ToolIdStrategy.js +107 -0
  105. package/dist/src/tools/ToolIdStrategy.js.map +1 -0
  106. package/dist/src/tools/codesearch.d.ts +21 -0
  107. package/dist/src/tools/codesearch.js +145 -0
  108. package/dist/src/tools/codesearch.js.map +1 -0
  109. package/dist/src/tools/direct-web-fetch.d.ts +22 -0
  110. package/dist/src/tools/direct-web-fetch.js +169 -0
  111. package/dist/src/tools/direct-web-fetch.js.map +1 -0
  112. package/dist/src/tools/exa-web-search.d.ts +24 -0
  113. package/dist/src/tools/exa-web-search.js +137 -0
  114. package/dist/src/tools/exa-web-search.js.map +1 -0
  115. package/dist/src/tools/{web-fetch.d.ts → google-web-fetch.d.ts} +4 -4
  116. package/dist/src/tools/{web-fetch.js → google-web-fetch.js} +29 -16
  117. package/dist/src/tools/google-web-fetch.js.map +1 -0
  118. package/dist/src/tools/{web-search-invocation.d.ts → google-web-search-invocation.d.ts} +1 -1
  119. package/dist/src/tools/{web-search-invocation.js → google-web-search-invocation.js} +2 -2
  120. package/dist/src/tools/google-web-search-invocation.js.map +1 -0
  121. package/dist/src/tools/{web-search.d.ts → google-web-search.d.ts} +4 -4
  122. package/dist/src/tools/{web-search.js → google-web-search.js} +6 -6
  123. package/dist/src/tools/google-web-search.js.map +1 -0
  124. package/dist/src/tools/todo-schemas.d.ts +4 -4
  125. package/dist/src/tools/tool-error.d.ts +4 -1
  126. package/dist/src/tools/tool-error.js +5 -0
  127. package/dist/src/tools/tool-error.js.map +1 -1
  128. package/dist/src/utils/fetch.d.ts +1 -1
  129. package/dist/src/utils/fetch.js +24 -2
  130. package/dist/src/utils/fetch.js.map +1 -1
  131. package/dist/src/utils/filesearch/ignore.js +3 -2
  132. package/dist/src/utils/filesearch/ignore.js.map +1 -1
  133. package/dist/src/utils/gitIgnoreParser.js +2 -1
  134. package/dist/src/utils/gitIgnoreParser.js.map +1 -1
  135. package/dist/src/utils/schemaValidator.js +41 -6
  136. package/dist/src/utils/schemaValidator.js.map +1 -1
  137. package/package.json +7 -1
  138. package/dist/src/tools/web-fetch.js.map +0 -1
  139. package/dist/src/tools/web-search-invocation.js.map +0 -1
  140. package/dist/src/tools/web-search.js.map +0 -1
@@ -0,0 +1,72 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2025 Vybestack LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ /**
7
+ * @plan PLAN-20251205-ISSUE712
8
+ * @description Tool ID strategy module for Kimi K2 and standard ID handling
9
+ *
10
+ * This module provides different strategies for resolving tool call IDs
11
+ * based on the tool format being used. Kimi K2 requires a specific ID format
12
+ * (functions.{name}:{index}) while most other providers use OpenAI-style
13
+ * call_xxx format.
14
+ */
15
+ import type { IContent, ToolCallBlock, ToolResponseBlock } from '../services/history/IContent.js';
16
+ import type { ToolFormat } from './IToolFormatter.js';
17
+ /**
18
+ * Interface for mapping tool IDs to provider-specific formats
19
+ */
20
+ export interface ToolIdMapper {
21
+ /**
22
+ * Resolves a tool call's internal ID to the provider-specific format
23
+ */
24
+ resolveToolCallId(tc: ToolCallBlock): string;
25
+ /**
26
+ * Resolves a tool response's callId to the provider-specific format
27
+ * that matches its corresponding tool call
28
+ */
29
+ resolveToolResponseId(tr: ToolResponseBlock): string;
30
+ }
31
+ /**
32
+ * Interface for creating tool ID mappers based on conversation contents
33
+ */
34
+ export interface ToolIdStrategy {
35
+ /**
36
+ * Creates a mapper that can resolve tool IDs for the given conversation
37
+ */
38
+ createMapper(contents: IContent[]): ToolIdMapper;
39
+ }
40
+ /**
41
+ * Checks if a model name indicates a Kimi K2 model that requires
42
+ * the special functions.{name}:{index} ID format.
43
+ *
44
+ * Uses specific pattern matching to avoid false positives from models
45
+ * that happen to contain 'k2' as part of their name (e.g., "gptk2-turbo").
46
+ *
47
+ * @param model - The model name to check
48
+ * @returns true if this is a K2 model requiring special ID handling
49
+ */
50
+ export declare function isKimiModel(model: string): boolean;
51
+ /**
52
+ * Kimi K2 strategy: Generates IDs in the format functions.{toolName}:{globalIndex}
53
+ *
54
+ * K2 uses a specific ID format where each tool call gets a sequential index
55
+ * based on its position in the conversation. This strategy scans all tool calls
56
+ * and assigns indices, then uses those indices when resolving IDs.
57
+ */
58
+ export declare const kimiStrategy: ToolIdStrategy;
59
+ /**
60
+ * Standard strategy: Converts internal hist_tool_xxx format to OpenAI call_xxx format
61
+ *
62
+ * This is the default strategy used for most providers (OpenAI, Qwen, DeepSeek, etc.)
63
+ * It simply normalizes the internal ID format to the OpenAI format.
64
+ */
65
+ export declare const standardStrategy: ToolIdStrategy;
66
+ /**
67
+ * Gets the appropriate tool ID strategy for a given tool format
68
+ *
69
+ * @param format - The tool format being used
70
+ * @returns The strategy to use for ID resolution
71
+ */
72
+ export declare function getToolIdStrategy(format: ToolFormat): ToolIdStrategy;
@@ -0,0 +1,107 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2025 Vybestack LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ import { normalizeToOpenAIToolId } from '../providers/openai-vercel/toolIdUtils.js';
7
+ /**
8
+ * Checks if a model name indicates a Kimi K2 model that requires
9
+ * the special functions.{name}:{index} ID format.
10
+ *
11
+ * Uses specific pattern matching to avoid false positives from models
12
+ * that happen to contain 'k2' as part of their name (e.g., "gptk2-turbo").
13
+ *
14
+ * @param model - The model name to check
15
+ * @returns true if this is a K2 model requiring special ID handling
16
+ */
17
+ export function isKimiModel(model) {
18
+ const lowerModel = model.toLowerCase();
19
+ // Explicit kimi branding
20
+ if (lowerModel.includes('kimi')) {
21
+ return true;
22
+ }
23
+ // Check for k2 at word boundaries:
24
+ // - starts with k2 (e.g., "k2-0527-preview")
25
+ // - ends with k2 or -k2 (e.g., "model-k2")
26
+ // - has k2 surrounded by non-alphanumeric (e.g., "kimi-k2-chat")
27
+ const k2Pattern = /(?:^|[^a-z0-9])k2(?:[^a-z0-9]|$)/;
28
+ return k2Pattern.test(lowerModel);
29
+ }
30
+ /**
31
+ * Kimi K2 strategy: Generates IDs in the format functions.{toolName}:{globalIndex}
32
+ *
33
+ * K2 uses a specific ID format where each tool call gets a sequential index
34
+ * based on its position in the conversation. This strategy scans all tool calls
35
+ * and assigns indices, then uses those indices when resolving IDs.
36
+ */
37
+ export const kimiStrategy = {
38
+ createMapper(contents) {
39
+ // Build a map of internal ID -> K2 format ID
40
+ const idToK2Id = new Map();
41
+ let globalIndex = 0;
42
+ // Scan all tool calls in the conversation
43
+ for (const content of contents) {
44
+ if (content.speaker !== 'ai')
45
+ continue;
46
+ for (const block of content.blocks) {
47
+ if (isToolCallBlock(block)) {
48
+ const k2Id = `functions.${block.name}:${globalIndex}`;
49
+ idToK2Id.set(block.id, k2Id);
50
+ globalIndex++;
51
+ }
52
+ }
53
+ }
54
+ return {
55
+ resolveToolCallId(tc) {
56
+ return idToK2Id.get(tc.id) ?? `functions.${tc.name}:${globalIndex++}`;
57
+ },
58
+ resolveToolResponseId(tr) {
59
+ // Look up the corresponding tool call's K2 ID
60
+ const k2Id = idToK2Id.get(tr.callId);
61
+ if (k2Id) {
62
+ return k2Id;
63
+ }
64
+ // Fallback: generate a new ID based on the tool name
65
+ // This handles orphan responses or responses to calls not yet seen
66
+ return `functions.${tr.toolName}:${globalIndex++}`;
67
+ },
68
+ };
69
+ },
70
+ };
71
+ /**
72
+ * Standard strategy: Converts internal hist_tool_xxx format to OpenAI call_xxx format
73
+ *
74
+ * This is the default strategy used for most providers (OpenAI, Qwen, DeepSeek, etc.)
75
+ * It simply normalizes the internal ID format to the OpenAI format.
76
+ */
77
+ export const standardStrategy = {
78
+ createMapper(_contents) {
79
+ return {
80
+ resolveToolCallId(tc) {
81
+ return normalizeToOpenAIToolId(tc.id);
82
+ },
83
+ resolveToolResponseId(tr) {
84
+ return normalizeToOpenAIToolId(tr.callId);
85
+ },
86
+ };
87
+ },
88
+ };
89
+ /**
90
+ * Gets the appropriate tool ID strategy for a given tool format
91
+ *
92
+ * @param format - The tool format being used
93
+ * @returns The strategy to use for ID resolution
94
+ */
95
+ export function getToolIdStrategy(format) {
96
+ if (format === 'kimi') {
97
+ return kimiStrategy;
98
+ }
99
+ return standardStrategy;
100
+ }
101
+ /**
102
+ * Type guard for ToolCallBlock
103
+ */
104
+ function isToolCallBlock(block) {
105
+ return block.type === 'tool_call';
106
+ }
107
+ //# sourceMappingURL=ToolIdStrategy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ToolIdStrategy.js","sourceRoot":"","sources":["../../../src/tools/ToolIdStrategy.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAmBH,OAAO,EAAE,uBAAuB,EAAE,MAAM,2CAA2C,CAAC;AA4BpF;;;;;;;;;GASG;AACH,MAAM,UAAU,WAAW,CAAC,KAAa;IACvC,MAAM,UAAU,GAAG,KAAK,CAAC,WAAW,EAAE,CAAC;IAEvC,yBAAyB;IACzB,IAAI,UAAU,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;QAChC,OAAO,IAAI,CAAC;IACd,CAAC;IAED,mCAAmC;IACnC,6CAA6C;IAC7C,2CAA2C;IAC3C,iEAAiE;IACjE,MAAM,SAAS,GAAG,kCAAkC,CAAC;IACrD,OAAO,SAAS,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;AACpC,CAAC;AAED;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,YAAY,GAAmB;IAC1C,YAAY,CAAC,QAAoB;QAC/B,6CAA6C;QAC7C,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAkB,CAAC;QAC3C,IAAI,WAAW,GAAG,CAAC,CAAC;QAEpB,0CAA0C;QAC1C,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;YAC/B,IAAI,OAAO,CAAC,OAAO,KAAK,IAAI;gBAAE,SAAS;YAEvC,KAAK,MAAM,KAAK,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;gBACnC,IAAI,eAAe,CAAC,KAAK,CAAC,EAAE,CAAC;oBAC3B,MAAM,IAAI,GAAG,aAAa,KAAK,CAAC,IAAI,IAAI,WAAW,EAAE,CAAC;oBACtD,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC;oBAC7B,WAAW,EAAE,CAAC;gBAChB,CAAC;YACH,CAAC;QACH,CAAC;QAED,OAAO;YACL,iBAAiB,CAAC,EAAiB;gBACjC,OAAO,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,aAAa,EAAE,CAAC,IAAI,IAAI,WAAW,EAAE,EAAE,CAAC;YACxE,CAAC;YAED,qBAAqB,CAAC,EAAqB;gBACzC,8CAA8C;gBAC9C,MAAM,IAAI,GAAG,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC;gBACrC,IAAI,IAAI,EAAE,CAAC;oBACT,OAAO,IAAI,CAAC;gBACd,CAAC;gBACD,qDAAqD;gBACrD,mEAAmE;gBACnE,OAAO,aAAa,EAAE,CAAC,QAAQ,IAAI,WAAW,EAAE,EAAE,CAAC;YACrD,CAAC;SACF,CAAC;IACJ,CAAC;CACF,CAAC;AAEF;;;;;GAKG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAmB;IAC9C,YAAY,CAAC,SAAqB;QAChC,OAAO;YACL,iBAAiB,CAAC,EAAiB;gBACjC,OAAO,uBAAuB,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;YACxC,CAAC;YAED,qBAAqB,CAAC,EAAqB;gBACzC,OAAO,uBAAuB,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC;YAC5C,CAAC;SACF,CAAC;IACJ,CAAC;CACF,CAAC;AAEF;;;;;GAKG;AACH,MAAM,UAAU,iBAAiB,CAAC,MAAkB;IAClD,IAAI,MAAM,KAAK,MAAM,EAAE,CAAC;QACtB,OAAO,YAAY,CAAC;IACtB,CAAC;IACD,OAAO,gBAAgB,CAAC;AAC1B,CAAC;AAED;;GAEG;AACH,SAAS,eAAe,CAAC,KAAmB;IAC1C,OAAO,KAAK,CAAC,IAAI,KAAK,WAAW,CAAC;AACpC,CAAC"}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2025 Vybestack LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ *
6
+ * Portions of this code are derived from opencode (https://github.com/sst/opencode)
7
+ * Copyright (c) 2025 opencode
8
+ * Licensed under the MIT License.
9
+ */
10
+ import { BaseDeclarativeTool, ToolInvocation, ToolResult } from './tools.js';
11
+ import { Config } from '../config/config.js';
12
+ export interface CodeSearchToolParams {
13
+ query: string;
14
+ tokensNum?: number;
15
+ }
16
+ export declare class CodeSearchTool extends BaseDeclarativeTool<CodeSearchToolParams, ToolResult> {
17
+ private readonly config;
18
+ static readonly Name = "codesearch";
19
+ constructor(config: Config);
20
+ protected createInvocation(params: CodeSearchToolParams): ToolInvocation<CodeSearchToolParams, ToolResult>;
21
+ }
@@ -0,0 +1,145 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2025 Vybestack LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ *
6
+ * Portions of this code are derived from opencode (https://github.com/sst/opencode)
7
+ * Copyright (c) 2025 opencode
8
+ * Licensed under the MIT License.
9
+ */
10
+ import { BaseDeclarativeTool, Kind, } from './tools.js';
11
+ import { ToolErrorType } from './tool-error.js';
12
+ import { BaseToolInvocation } from './tools.js';
13
+ import fetch from 'node-fetch';
14
+ const API_CONFIG = {
15
+ BASE_URL: 'https://mcp.exa.ai',
16
+ ENDPOINTS: {
17
+ CONTEXT: '/mcp',
18
+ },
19
+ };
20
+ export class CodeSearchTool extends BaseDeclarativeTool {
21
+ config;
22
+ static Name = 'codesearch';
23
+ constructor(config) {
24
+ super(CodeSearchTool.Name, 'CodeSearch', 'Search for relevant code snippets, APIs, Libraries, and SDKs documentation. Use this to find examples and usage patterns.', Kind.Search, {
25
+ type: 'object',
26
+ properties: {
27
+ query: {
28
+ type: 'string',
29
+ description: "Search query to find relevant context. For example, 'React useState hook examples', 'Python pandas dataframe filtering'.",
30
+ },
31
+ tokensNum: {
32
+ type: 'number',
33
+ description: 'Number of tokens to return (1000-50000). Default is 5000 tokens.',
34
+ default: 5000,
35
+ minimum: 1000,
36
+ maximum: 50000,
37
+ },
38
+ },
39
+ required: ['query'],
40
+ });
41
+ this.config = config;
42
+ }
43
+ createInvocation(params) {
44
+ return new CodeSearchToolInvocation(this.config, params);
45
+ }
46
+ }
47
+ class CodeSearchToolInvocation extends BaseToolInvocation {
48
+ config;
49
+ constructor(config, params) {
50
+ super(params);
51
+ this.config = config;
52
+ }
53
+ getDescription() {
54
+ return `Search code for: ${this.params.query}`;
55
+ }
56
+ async execute(signal, _updateOutput) {
57
+ const codeRequest = {
58
+ jsonrpc: '2.0',
59
+ id: 1,
60
+ method: 'tools/call',
61
+ params: {
62
+ name: 'get_code_context_exa',
63
+ arguments: {
64
+ query: this.params.query,
65
+ tokensNum: this.getEffectiveTokensNum(),
66
+ },
67
+ },
68
+ };
69
+ try {
70
+ const headers = {
71
+ accept: 'application/json, text/event-stream',
72
+ 'content-type': 'application/json',
73
+ };
74
+ const response = await fetch(`${API_CONFIG.BASE_URL}${API_CONFIG.ENDPOINTS.CONTEXT}`, {
75
+ method: 'POST',
76
+ headers,
77
+ body: JSON.stringify(codeRequest),
78
+ signal,
79
+ });
80
+ if (!response.ok) {
81
+ const errorText = await response.text();
82
+ throw new Error(`Code search error (${response.status}): ${errorText}`);
83
+ }
84
+ const responseText = await response.text();
85
+ // Parse SSE response
86
+ // The response from mcp.exa.ai seems to be SSE format "data: {...}"
87
+ const lines = responseText.split('\n');
88
+ for (const line of lines) {
89
+ if (line.startsWith('data: ')) {
90
+ try {
91
+ const data = JSON.parse(line.substring(6));
92
+ if (data.result &&
93
+ data.result.content &&
94
+ data.result.content.length > 0) {
95
+ const content = data.result.content[0].text;
96
+ return {
97
+ llmContent: content,
98
+ returnDisplay: content,
99
+ };
100
+ }
101
+ }
102
+ catch (_e) {
103
+ // Ignore parse errors for intermediate lines
104
+ }
105
+ }
106
+ }
107
+ return {
108
+ llmContent: 'No code snippets or documentation found. Please try a different query.',
109
+ returnDisplay: 'No results found.',
110
+ };
111
+ }
112
+ catch (error) {
113
+ const errorMessage = error instanceof Error ? error.message : String(error);
114
+ return {
115
+ llmContent: `Error performing code search: ${errorMessage}`,
116
+ returnDisplay: `Error: ${errorMessage}`,
117
+ error: {
118
+ message: errorMessage,
119
+ type: ToolErrorType.SEARCH_ERROR,
120
+ },
121
+ };
122
+ }
123
+ }
124
+ getEffectiveTokensNum() {
125
+ // Limits from: https://github.com/exa-labs/exa-mcp-server/blob/1ec2078b59d5e4503696fecf9ce40701ccef85cc/src/tools/exaCode.ts#L14
126
+ const LIMITS = {
127
+ DEFAULT: 5000,
128
+ MIN: 1000,
129
+ MAX: 50000,
130
+ };
131
+ const settingMaxTokens = this.config
132
+ .getSettingsService()
133
+ .get('tool-output-max-tokens');
134
+ // 1. Determine requested tokens (Param > Default)
135
+ let tokens = this.params.tokensNum ?? LIMITS.DEFAULT;
136
+ // 2. Apply setting as a hard cap if present
137
+ if (settingMaxTokens !== undefined &&
138
+ typeof settingMaxTokens === 'number') {
139
+ tokens = Math.min(tokens, settingMaxTokens);
140
+ }
141
+ // 3. Clamp to absolute API limits
142
+ return Math.max(LIMITS.MIN, Math.min(tokens, LIMITS.MAX));
143
+ }
144
+ }
145
+ //# sourceMappingURL=codesearch.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codesearch.js","sourceRoot":"","sources":["../../../src/tools/codesearch.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2025 Vybestack LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ *
6
+ * Portions of this code are derived from opencode (https://github.com/sst/opencode)
7
+ * Copyright (c) 2025 opencode
8
+ * Licensed under the MIT License.
9
+ */
10
+ import { BaseDeclarativeTool, ToolInvocation, ToolResult } from './tools.js';
11
+ import { Config } from '../config/config.js';
12
+ export interface DirectWebFetchToolParams {
13
+ url: string;
14
+ format: 'text' | 'markdown' | 'html';
15
+ timeout?: number;
16
+ }
17
+ export declare class DirectWebFetchTool extends BaseDeclarativeTool<DirectWebFetchToolParams, ToolResult> {
18
+ private readonly config;
19
+ static readonly Name = "direct_web_fetch";
20
+ constructor(config: Config);
21
+ protected createInvocation(params: DirectWebFetchToolParams): ToolInvocation<DirectWebFetchToolParams, ToolResult>;
22
+ }
@@ -0,0 +1,169 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2025 Vybestack LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ *
6
+ * Portions of this code are derived from opencode (https://github.com/sst/opencode)
7
+ * Copyright (c) 2025 opencode
8
+ * Licensed under the MIT License.
9
+ */
10
+ import { BaseDeclarativeTool, Kind, } from './tools.js';
11
+ import { ToolErrorType } from './tool-error.js';
12
+ import { BaseToolInvocation } from './tools.js';
13
+ import fetch from 'node-fetch';
14
+ import TurndownService from 'turndown';
15
+ import * as cheerio from 'cheerio';
16
+ const MAX_RESPONSE_SIZE = 5 * 1024 * 1024; // 5MB
17
+ const DEFAULT_TIMEOUT = 30 * 1000; // 30 seconds
18
+ const MAX_TIMEOUT = 120 * 1000; // 2 minutes
19
+ export class DirectWebFetchTool extends BaseDeclarativeTool {
20
+ config;
21
+ static Name = 'direct_web_fetch';
22
+ constructor(config) {
23
+ super(DirectWebFetchTool.Name, 'DirectWebFetch', 'Fetches content from a specified URL and converts it to the requested format (text, markdown, or html).', Kind.Search, {
24
+ type: 'object',
25
+ properties: {
26
+ url: {
27
+ type: 'string',
28
+ description: 'The URL to fetch content from',
29
+ },
30
+ format: {
31
+ type: 'string',
32
+ enum: ['text', 'markdown', 'html'],
33
+ description: 'The format to return the content in (text, markdown, or html)',
34
+ },
35
+ timeout: {
36
+ type: 'number',
37
+ description: 'Optional timeout in seconds (max 120)',
38
+ },
39
+ },
40
+ required: ['url', 'format'],
41
+ });
42
+ this.config = config;
43
+ }
44
+ createInvocation(params) {
45
+ return new DirectWebFetchToolInvocation(this.config, params);
46
+ }
47
+ }
48
+ class DirectWebFetchToolInvocation extends BaseToolInvocation {
49
+ constructor(_config, params, messageBus) {
50
+ super(params, messageBus);
51
+ }
52
+ getDescription() {
53
+ return `Fetch content from ${this.params.url}`;
54
+ }
55
+ async execute(signal, _updateOutput) {
56
+ const { url, format, timeout: timeoutSec } = this.params;
57
+ if (!url.startsWith('http://') && !url.startsWith('https://')) {
58
+ return {
59
+ llmContent: 'URL must start with http:// or https://',
60
+ returnDisplay: 'Invalid URL',
61
+ error: {
62
+ message: 'Invalid URL protocol',
63
+ type: ToolErrorType.INVALID_ARGUMENT,
64
+ },
65
+ };
66
+ }
67
+ const timeout = Math.min((timeoutSec ?? DEFAULT_TIMEOUT / 1000) * 1000, MAX_TIMEOUT);
68
+ // Build Accept header
69
+ let acceptHeader = '*/*';
70
+ switch (format) {
71
+ case 'markdown':
72
+ acceptHeader =
73
+ 'text/markdown;q=1.0, text/x-markdown;q=0.9, text/plain;q=0.8, text/html;q=0.7, */*;q=0.1';
74
+ break;
75
+ case 'text':
76
+ acceptHeader =
77
+ 'text/plain;q=1.0, text/markdown;q=0.9, text/html;q=0.8, */*;q=0.1';
78
+ break;
79
+ case 'html':
80
+ acceptHeader =
81
+ 'text/html;q=1.0, application/xhtml+xml;q=0.9, text/plain;q=0.8, text/markdown;q=0.7, */*;q=0.1';
82
+ break;
83
+ default:
84
+ acceptHeader =
85
+ 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8';
86
+ }
87
+ const controller = new AbortController();
88
+ const timeoutId = setTimeout(() => controller.abort(), timeout);
89
+ // If the parent signal aborts, we should also abort our controller
90
+ const onAbort = () => controller.abort();
91
+ signal.addEventListener('abort', onAbort);
92
+ try {
93
+ const response = await fetch(url, {
94
+ signal: controller.signal,
95
+ headers: {
96
+ 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
97
+ Accept: acceptHeader,
98
+ 'Accept-Language': 'en-US,en;q=0.9',
99
+ },
100
+ });
101
+ if (!response.ok) {
102
+ throw new Error(`Request failed with status code: ${response.status}`);
103
+ }
104
+ // Check content length
105
+ const contentLength = response.headers.get('content-length');
106
+ if (contentLength && parseInt(contentLength, 10) > MAX_RESPONSE_SIZE) {
107
+ throw new Error('Response too large (exceeds 5MB limit)');
108
+ }
109
+ const arrayBuffer = await response.arrayBuffer();
110
+ if (arrayBuffer.byteLength > MAX_RESPONSE_SIZE) {
111
+ throw new Error('Response too large (exceeds 5MB limit)');
112
+ }
113
+ const content = new TextDecoder().decode(arrayBuffer);
114
+ const contentType = response.headers.get('content-type') || '';
115
+ let output = content;
116
+ switch (format) {
117
+ case 'markdown':
118
+ if (contentType.includes('text/html')) {
119
+ output = this.convertHTMLToMarkdown(content);
120
+ }
121
+ break;
122
+ case 'text':
123
+ if (contentType.includes('text/html')) {
124
+ output = this.extractTextFromHTML(content);
125
+ }
126
+ break;
127
+ default:
128
+ break;
129
+ }
130
+ return {
131
+ llmContent: output,
132
+ returnDisplay: `Fetched ${url} as ${format}`,
133
+ };
134
+ }
135
+ catch (error) {
136
+ const errorMessage = error instanceof Error ? error.message : String(error);
137
+ return {
138
+ llmContent: `Error fetching URL: ${errorMessage}`,
139
+ returnDisplay: `Error: ${errorMessage}`,
140
+ error: {
141
+ message: errorMessage,
142
+ type: ToolErrorType.FETCH_ERROR,
143
+ },
144
+ };
145
+ }
146
+ finally {
147
+ clearTimeout(timeoutId);
148
+ signal.removeEventListener('abort', onAbort);
149
+ }
150
+ }
151
+ extractTextFromHTML(html) {
152
+ const $ = cheerio.load(html);
153
+ // Remove scripts, styles, etc.
154
+ $('script, style, noscript, iframe, object, embed').remove();
155
+ return $.text().trim();
156
+ }
157
+ convertHTMLToMarkdown(html) {
158
+ const turndownService = new TurndownService({
159
+ headingStyle: 'atx',
160
+ hr: '---',
161
+ bulletListMarker: '-',
162
+ codeBlockStyle: 'fenced',
163
+ emDelimiter: '*',
164
+ });
165
+ turndownService.remove(['script', 'style', 'meta', 'link']);
166
+ return turndownService.turndown(html);
167
+ }
168
+ }
169
+ //# sourceMappingURL=direct-web-fetch.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"direct-web-fetch.js","sourceRoot":"","sources":["../../../src/tools/direct-web-fetch.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,24 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2025 Vybestack LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ *
6
+ * Portions of this code are derived from opencode (https://github.com/sst/opencode)
7
+ * Copyright (c) 2025 opencode
8
+ * Licensed under the MIT License.
9
+ */
10
+ import { BaseDeclarativeTool, ToolInvocation, ToolResult } from './tools.js';
11
+ import { Config } from '../config/config.js';
12
+ export interface ExaWebSearchToolParams {
13
+ query: string;
14
+ numResults?: number;
15
+ livecrawl?: 'fallback' | 'preferred';
16
+ type?: 'auto' | 'fast' | 'deep';
17
+ contextMaxCharacters?: number;
18
+ }
19
+ export declare class ExaWebSearchTool extends BaseDeclarativeTool<ExaWebSearchToolParams, ToolResult> {
20
+ private readonly config;
21
+ static readonly Name = "exa_web_search";
22
+ constructor(config: Config);
23
+ protected createInvocation(params: ExaWebSearchToolParams): ToolInvocation<ExaWebSearchToolParams, ToolResult>;
24
+ }