@morphllm/morphsdk 0.2.6

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 (168) hide show
  1. package/README.md +39 -0
  2. package/dist/chunk-4UVEBIDK.js +358 -0
  3. package/dist/chunk-4UVEBIDK.js.map +1 -0
  4. package/dist/chunk-4V46N27D.js +169 -0
  5. package/dist/chunk-4V46N27D.js.map +1 -0
  6. package/dist/chunk-4VWJFZVS.js +89 -0
  7. package/dist/chunk-4VWJFZVS.js.map +1 -0
  8. package/dist/chunk-5COKN3XD.js +91 -0
  9. package/dist/chunk-5COKN3XD.js.map +1 -0
  10. package/dist/chunk-5VQEQSJQ.js +394 -0
  11. package/dist/chunk-5VQEQSJQ.js.map +1 -0
  12. package/dist/chunk-63WE2C5R.js +43 -0
  13. package/dist/chunk-63WE2C5R.js.map +1 -0
  14. package/dist/chunk-74ZHKB54.js +9 -0
  15. package/dist/chunk-74ZHKB54.js.map +1 -0
  16. package/dist/chunk-7PZJQFCY.js +39 -0
  17. package/dist/chunk-7PZJQFCY.js.map +1 -0
  18. package/dist/chunk-BILUTNBC.js +83 -0
  19. package/dist/chunk-BILUTNBC.js.map +1 -0
  20. package/dist/chunk-G4DJ6VSM.js +78 -0
  21. package/dist/chunk-G4DJ6VSM.js.map +1 -0
  22. package/dist/chunk-HGIFACNP.js +59 -0
  23. package/dist/chunk-HGIFACNP.js.map +1 -0
  24. package/dist/chunk-OI5YYE36.js +189 -0
  25. package/dist/chunk-OI5YYE36.js.map +1 -0
  26. package/dist/chunk-PZ5AY32C.js +10 -0
  27. package/dist/chunk-PZ5AY32C.js.map +1 -0
  28. package/dist/chunk-VJK4PH5V.js +105 -0
  29. package/dist/chunk-VJK4PH5V.js.map +1 -0
  30. package/dist/chunk-WXBUVKYL.js +128 -0
  31. package/dist/chunk-WXBUVKYL.js.map +1 -0
  32. package/dist/chunk-X2K57BH6.js +1 -0
  33. package/dist/chunk-X2K57BH6.js.map +1 -0
  34. package/dist/chunk-YQMPVJ2L.js +32 -0
  35. package/dist/chunk-YQMPVJ2L.js.map +1 -0
  36. package/dist/chunk-YWS2GRQC.js +97 -0
  37. package/dist/chunk-YWS2GRQC.js.map +1 -0
  38. package/dist/chunk-ZQEWQ7LJ.js +97 -0
  39. package/dist/chunk-ZQEWQ7LJ.js.map +1 -0
  40. package/dist/client.cjs +1358 -0
  41. package/dist/client.cjs.map +1 -0
  42. package/dist/client.js +15 -0
  43. package/dist/client.js.map +1 -0
  44. package/dist/git/client.cjs +428 -0
  45. package/dist/git/client.cjs.map +1 -0
  46. package/dist/git/client.js +8 -0
  47. package/dist/git/client.js.map +1 -0
  48. package/dist/git/config.cjs +41 -0
  49. package/dist/git/config.cjs.map +1 -0
  50. package/dist/git/config.js +17 -0
  51. package/dist/git/config.js.map +1 -0
  52. package/dist/git/index.cjs +438 -0
  53. package/dist/git/index.cjs.map +1 -0
  54. package/dist/git/index.js +14 -0
  55. package/dist/git/index.js.map +1 -0
  56. package/dist/git/types.cjs +19 -0
  57. package/dist/git/types.cjs.map +1 -0
  58. package/dist/git/types.js +1 -0
  59. package/dist/git/types.js.map +1 -0
  60. package/dist/index.cjs +1372 -0
  61. package/dist/index.cjs.map +1 -0
  62. package/dist/index.js +34 -0
  63. package/dist/index.js.map +1 -0
  64. package/dist/tools/browser/anthropic.cjs +281 -0
  65. package/dist/tools/browser/anthropic.cjs.map +1 -0
  66. package/dist/tools/browser/anthropic.js +72 -0
  67. package/dist/tools/browser/anthropic.js.map +1 -0
  68. package/dist/tools/browser/core.cjs +459 -0
  69. package/dist/tools/browser/core.cjs.map +1 -0
  70. package/dist/tools/browser/core.js +21 -0
  71. package/dist/tools/browser/core.js.map +1 -0
  72. package/dist/tools/browser/index.cjs +497 -0
  73. package/dist/tools/browser/index.cjs.map +1 -0
  74. package/dist/tools/browser/index.js +27 -0
  75. package/dist/tools/browser/index.js.map +1 -0
  76. package/dist/tools/browser/openai.cjs +297 -0
  77. package/dist/tools/browser/openai.cjs.map +1 -0
  78. package/dist/tools/browser/openai.js +85 -0
  79. package/dist/tools/browser/openai.js.map +1 -0
  80. package/dist/tools/browser/prompts.cjs +64 -0
  81. package/dist/tools/browser/prompts.cjs.map +1 -0
  82. package/dist/tools/browser/prompts.js +10 -0
  83. package/dist/tools/browser/prompts.js.map +1 -0
  84. package/dist/tools/browser/types.cjs +19 -0
  85. package/dist/tools/browser/types.cjs.map +1 -0
  86. package/dist/tools/browser/types.js +1 -0
  87. package/dist/tools/browser/types.js.map +1 -0
  88. package/dist/tools/browser/vercel.cjs +242 -0
  89. package/dist/tools/browser/vercel.cjs.map +1 -0
  90. package/dist/tools/browser/vercel.js +49 -0
  91. package/dist/tools/browser/vercel.js.map +1 -0
  92. package/dist/tools/codebase_search/anthropic.cjs +267 -0
  93. package/dist/tools/codebase_search/anthropic.cjs.map +1 -0
  94. package/dist/tools/codebase_search/anthropic.js +11 -0
  95. package/dist/tools/codebase_search/anthropic.js.map +1 -0
  96. package/dist/tools/codebase_search/core.cjs +201 -0
  97. package/dist/tools/codebase_search/core.cjs.map +1 -0
  98. package/dist/tools/codebase_search/core.js +11 -0
  99. package/dist/tools/codebase_search/core.js.map +1 -0
  100. package/dist/tools/codebase_search/index.cjs +393 -0
  101. package/dist/tools/codebase_search/index.cjs.map +1 -0
  102. package/dist/tools/codebase_search/index.js +27 -0
  103. package/dist/tools/codebase_search/index.js.map +1 -0
  104. package/dist/tools/codebase_search/openai.cjs +316 -0
  105. package/dist/tools/codebase_search/openai.cjs.map +1 -0
  106. package/dist/tools/codebase_search/openai.js +21 -0
  107. package/dist/tools/codebase_search/openai.js.map +1 -0
  108. package/dist/tools/codebase_search/prompts.cjs +57 -0
  109. package/dist/tools/codebase_search/prompts.cjs.map +1 -0
  110. package/dist/tools/codebase_search/prompts.js +10 -0
  111. package/dist/tools/codebase_search/prompts.js.map +1 -0
  112. package/dist/tools/codebase_search/types.cjs +19 -0
  113. package/dist/tools/codebase_search/types.cjs.map +1 -0
  114. package/dist/tools/codebase_search/types.js +1 -0
  115. package/dist/tools/codebase_search/types.js.map +1 -0
  116. package/dist/tools/codebase_search/vercel.cjs +230 -0
  117. package/dist/tools/codebase_search/vercel.cjs.map +1 -0
  118. package/dist/tools/codebase_search/vercel.js +15 -0
  119. package/dist/tools/codebase_search/vercel.js.map +1 -0
  120. package/dist/tools/fastapply/anthropic.cjs +335 -0
  121. package/dist/tools/fastapply/anthropic.cjs.map +1 -0
  122. package/dist/tools/fastapply/anthropic.js +13 -0
  123. package/dist/tools/fastapply/anthropic.js.map +1 -0
  124. package/dist/tools/fastapply/core.cjs +267 -0
  125. package/dist/tools/fastapply/core.cjs.map +1 -0
  126. package/dist/tools/fastapply/core.js +15 -0
  127. package/dist/tools/fastapply/core.js.map +1 -0
  128. package/dist/tools/fastapply/index.cjs +500 -0
  129. package/dist/tools/fastapply/index.cjs.map +1 -0
  130. package/dist/tools/fastapply/index.js +32 -0
  131. package/dist/tools/fastapply/index.js.map +1 -0
  132. package/dist/tools/fastapply/openai.cjs +353 -0
  133. package/dist/tools/fastapply/openai.cjs.map +1 -0
  134. package/dist/tools/fastapply/openai.js +21 -0
  135. package/dist/tools/fastapply/openai.js.map +1 -0
  136. package/dist/tools/fastapply/prompts.cjs +68 -0
  137. package/dist/tools/fastapply/prompts.cjs.map +1 -0
  138. package/dist/tools/fastapply/prompts.js +10 -0
  139. package/dist/tools/fastapply/prompts.js.map +1 -0
  140. package/dist/tools/fastapply/types.cjs +19 -0
  141. package/dist/tools/fastapply/types.cjs.map +1 -0
  142. package/dist/tools/fastapply/types.js +1 -0
  143. package/dist/tools/fastapply/types.js.map +1 -0
  144. package/dist/tools/fastapply/vercel.cjs +347 -0
  145. package/dist/tools/fastapply/vercel.cjs.map +1 -0
  146. package/dist/tools/fastapply/vercel.js +17 -0
  147. package/dist/tools/fastapply/vercel.js.map +1 -0
  148. package/dist/tools/index.cjs +500 -0
  149. package/dist/tools/index.cjs.map +1 -0
  150. package/dist/tools/index.js +32 -0
  151. package/dist/tools/index.js.map +1 -0
  152. package/dist/tools/modelrouter/core.cjs +286 -0
  153. package/dist/tools/modelrouter/core.cjs.map +1 -0
  154. package/dist/tools/modelrouter/core.js +13 -0
  155. package/dist/tools/modelrouter/core.js.map +1 -0
  156. package/dist/tools/modelrouter/index.cjs +286 -0
  157. package/dist/tools/modelrouter/index.cjs.map +1 -0
  158. package/dist/tools/modelrouter/index.js +13 -0
  159. package/dist/tools/modelrouter/index.js.map +1 -0
  160. package/dist/tools/modelrouter/types.cjs +19 -0
  161. package/dist/tools/modelrouter/types.cjs.map +1 -0
  162. package/dist/tools/modelrouter/types.js +1 -0
  163. package/dist/tools/modelrouter/types.js.map +1 -0
  164. package/dist/tools/utils/resilience.cjs +115 -0
  165. package/dist/tools/utils/resilience.cjs.map +1 -0
  166. package/dist/tools/utils/resilience.js +12 -0
  167. package/dist/tools/utils/resilience.js.map +1 -0
  168. package/package.json +159 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../tools/fastapply/prompts.ts"],"sourcesContent":["/**\n * System prompts for edit_file tool\n */\n\nexport const EDIT_FILE_TOOL_DESCRIPTION = `Use this tool to make an edit to an existing file.\n\nThis will be read by a less intelligent model, which will quickly apply the edit. You should make it clear what the edit is, while also minimizing the unchanged code you write.\n\nWhen writing the edit, you should specify each edit in sequence, with the special comment // ... existing code ... to represent unchanged code in between edited lines.\n\nFor example:\n\n// ... existing code ...\nFIRST_EDIT\n// ... existing code ...\nSECOND_EDIT\n// ... existing code ...\nTHIRD_EDIT\n// ... existing code ...\n\nYou should still bias towards repeating as few lines of the original file as possible to convey the change.\nBut, each edit should contain minimally sufficient context of unchanged lines around the code you're editing to resolve ambiguity.\n\nDO NOT omit spans of pre-existing code (or comments) without using the // ... existing code ... comment to indicate its absence. If you omit the existing code comment, the model may inadvertently delete these lines.\n\nIf you plan on deleting a section, you must provide context before and after to delete it.\n\nMake sure it is clear what the edit should be, and where it should be applied.\nMake edits to a file in a single edit_file call instead of multiple edit_file calls to the same file. The apply model can handle many distinct edits at once.`;\n\nexport const EDIT_FILE_SYSTEM_PROMPT = `When the user is asking for edits to their code, use the edit_file tool to highlight the changes necessary and add comments to indicate where unchanged code has been skipped. For example:\n\n// ... existing code ...\n{{ edit_1 }}\n// ... existing code ...\n{{ edit_2 }}\n// ... existing code ...\n\nOften this will mean that the start/end of the file will be skipped, but that's okay! Rewrite the entire file ONLY if specifically requested. Always provide a brief explanation of the updates, unless the user specifically requests only the code.\n\nThese edit codeblocks are also read by a less intelligent language model, colloquially called the apply model, to update the file. To help specify the edit to the apply model, you will be very careful when generating the codeblock to not introduce ambiguity. You will specify all unchanged regions (code and comments) of the file with \"// ... existing code ...\" comment markers. This will ensure the apply model will not delete existing unchanged code or comments when editing the file.`;\n\n"],"mappings":";AAIO,IAAM,6BAA6B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA0BnC,IAAM,0BAA0B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;","names":[]}
@@ -0,0 +1,9 @@
1
+ // git/index.ts
2
+ import { default as default2 } from "isomorphic-git";
3
+ import { default as default3 } from "isomorphic-git/http/node";
4
+
5
+ export {
6
+ default2 as default,
7
+ default3 as default2
8
+ };
9
+ //# sourceMappingURL=chunk-74ZHKB54.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../git/index.ts"],"sourcesContent":["/**\n * Morph Git SDK\n * \n * Git operations for AI agents using Morph's backend infrastructure.\n * \n * @example\n * ```typescript\n * import { MorphGit } from 'morphsdk/git';\n * \n * const morphGit = new MorphGit({\n * apiKey: process.env.MORPH_API_KEY!\n * });\n * \n * // Initialize and push\n * await morphGit.init({ repoId: 'my-project', dir: './my-project' });\n * await morphGit.add({ dir: './my-project', filepath: 'src/app.ts' });\n * await morphGit.commit({ dir: './my-project', message: 'Update' });\n * await morphGit.push({ dir: './my-project' });\n * ```\n */\n\nexport { MorphGit } from './client.js';\nexport type {\n MorphGitConfig,\n CloneOptions,\n PushOptions,\n PullOptions,\n AddOptions,\n CommitOptions,\n StatusOptions,\n LogOptions,\n CheckoutOptions,\n BranchOptions,\n DiffOptions,\n CommitObject,\n StatusResult,\n} from './types.js';\n\n// Re-export isomorphic-git for advanced use cases\nexport { default as git } from 'isomorphic-git';\nexport { default as http } from 'isomorphic-git/http/node';\n\n"],"mappings":";AAuCA,SAAoB,WAAXA,gBAAsB;AAC/B,SAAoB,WAAXA,gBAAuB;","names":["default"]}
@@ -0,0 +1,39 @@
1
+ // tools/browser/prompts.ts
2
+ var BROWSER_TOOL_DESCRIPTION = `Execute natural language browser automation tasks using an AI-powered agent. The agent can navigate websites, interact with elements, fill forms, click buttons, and verify functionality.
3
+
4
+ Use this tool to:
5
+ - Test web applications end-to-end
6
+ - Verify UI functionality
7
+ - Automate user workflows
8
+ - Extract information from web pages
9
+
10
+ The agent uses GPT-4o-mini to interpret your task and execute the necessary browser actions. It runs in a remote browser via Browserless.io, so it can access any publicly accessible URL.
11
+
12
+ Important:
13
+ - Provide clear, specific task descriptions
14
+ - Include the starting URL if navigating to a specific page
15
+ - Use remote URLs (e.g., https://3000-xyz.e2b.dev) not localhost
16
+ - Complex tasks may require more max_steps`;
17
+ var BROWSER_SYSTEM_PROMPT = `You have access to browser automation capabilities. When testing or interacting with web applications:
18
+
19
+ 1. Be specific about what you're testing or verifying
20
+ 2. Break complex tasks into clear steps
21
+ 3. Always provide the full URL including protocol (https://)
22
+ 4. For localhost apps, use the remote tunnel URL (e.g., e2b.dev URLs)
23
+ 5. Specify the number of steps needed - simple tasks use 5-10, complex flows use 15-30
24
+
25
+ Example good tasks:
26
+ - "Go to https://3000-abc.e2b.dev and verify the landing page loads with a hero section"
27
+ - "Test guest checkout: add a pineapple to cart, proceed to checkout, fill shipping info, and verify order summary"
28
+ - "Navigate to the dashboard and click on the settings tab, then verify the API keys section is visible"
29
+
30
+ Example bad tasks:
31
+ - "test the app" (too vague)
32
+ - "go to localhost:3000" (use remote URL instead)
33
+ - "do everything" (not specific enough)`;
34
+
35
+ export {
36
+ BROWSER_TOOL_DESCRIPTION,
37
+ BROWSER_SYSTEM_PROMPT
38
+ };
39
+ //# sourceMappingURL=chunk-7PZJQFCY.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../tools/browser/prompts.ts"],"sourcesContent":["/**\n * Tool descriptions and prompts for AI models\n */\n\nexport const BROWSER_TOOL_DESCRIPTION = `Execute natural language browser automation tasks using an AI-powered agent. The agent can navigate websites, interact with elements, fill forms, click buttons, and verify functionality.\n\nUse this tool to:\n- Test web applications end-to-end\n- Verify UI functionality\n- Automate user workflows\n- Extract information from web pages\n\nThe agent uses GPT-4o-mini to interpret your task and execute the necessary browser actions. It runs in a remote browser via Browserless.io, so it can access any publicly accessible URL.\n\nImportant:\n- Provide clear, specific task descriptions\n- Include the starting URL if navigating to a specific page\n- Use remote URLs (e.g., https://3000-xyz.e2b.dev) not localhost\n- Complex tasks may require more max_steps`;\n\nexport const BROWSER_SYSTEM_PROMPT = `You have access to browser automation capabilities. When testing or interacting with web applications:\n\n1. Be specific about what you're testing or verifying\n2. Break complex tasks into clear steps\n3. Always provide the full URL including protocol (https://)\n4. For localhost apps, use the remote tunnel URL (e.g., e2b.dev URLs)\n5. Specify the number of steps needed - simple tasks use 5-10, complex flows use 15-30\n\nExample good tasks:\n- \"Go to https://3000-abc.e2b.dev and verify the landing page loads with a hero section\"\n- \"Test guest checkout: add a pineapple to cart, proceed to checkout, fill shipping info, and verify order summary\"\n- \"Navigate to the dashboard and click on the settings tab, then verify the API keys section is visible\"\n\nExample bad tasks:\n- \"test the app\" (too vague)\n- \"go to localhost:3000\" (use remote URL instead)\n- \"do everything\" (not specific enough)`;\n\n"],"mappings":";AAIO,IAAM,2BAA2B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAgBjC,IAAM,wBAAwB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;","names":[]}
@@ -0,0 +1,83 @@
1
+ import {
2
+ CODEBASE_SEARCH_DESCRIPTION,
3
+ CODEBASE_SEARCH_SYSTEM_PROMPT
4
+ } from "./chunk-YQMPVJ2L.js";
5
+ import {
6
+ executeCodebaseSearch
7
+ } from "./chunk-VJK4PH5V.js";
8
+
9
+ // tools/codebase_search/anthropic.ts
10
+ function createCodebaseSearchTool(config) {
11
+ const toolDefinition = {
12
+ name: "codebase_search",
13
+ description: CODEBASE_SEARCH_DESCRIPTION,
14
+ input_schema: {
15
+ type: "object",
16
+ properties: {
17
+ explanation: {
18
+ type: "string",
19
+ description: "One sentence explanation as to why this tool is being used, and how it contributes to the goal."
20
+ },
21
+ query: {
22
+ type: "string",
23
+ description: 'A complete question about what you want to understand. Ask as if talking to a colleague: "How does X work?", "What happens when Y?", "Where is Z handled?"'
24
+ },
25
+ target_directories: {
26
+ type: "array",
27
+ items: { type: "string" },
28
+ description: "Prefix directory paths to limit search scope (single directory only, no glob patterns). Use [] to search entire repo."
29
+ },
30
+ limit: {
31
+ type: "number",
32
+ description: "Maximum results to return (default: 10)"
33
+ }
34
+ },
35
+ required: ["query", "target_directories", "explanation"]
36
+ },
37
+ cache_control: { type: "ephemeral" }
38
+ };
39
+ return Object.assign(toolDefinition, {
40
+ execute: async (input) => {
41
+ return executeCodebaseSearch(input, config);
42
+ },
43
+ formatResult: (result) => {
44
+ return formatResult(result);
45
+ },
46
+ getSystemPrompt: () => {
47
+ return CODEBASE_SEARCH_SYSTEM_PROMPT;
48
+ }
49
+ });
50
+ }
51
+ function formatResult(result) {
52
+ if (!result.success) {
53
+ return `Search failed: ${result.error}`;
54
+ }
55
+ if (result.results.length === 0) {
56
+ return "No matching code found. Try rephrasing your query or broadening the search scope.";
57
+ }
58
+ const lines = [];
59
+ lines.push(`Found ${result.results.length} relevant code sections (searched ${result.stats.candidatesRetrieved} candidates in ${result.stats.searchTimeMs}ms):
60
+ `);
61
+ result.results.forEach((r, i) => {
62
+ const relevance = (r.rerankScore * 100).toFixed(1);
63
+ lines.push(`${i + 1}. ${r.filepath} (${relevance}% relevant)`);
64
+ lines.push(` Symbol: ${r.symbolPath}`);
65
+ lines.push(` Language: ${r.language}`);
66
+ lines.push(` Lines: ${r.startLine}-${r.endLine}`);
67
+ lines.push(` Code:`);
68
+ const codeLines = r.content.split("\n");
69
+ codeLines.slice(0, Math.min(codeLines.length, 20)).forEach((line) => {
70
+ lines.push(` ${line}`);
71
+ });
72
+ if (codeLines.length > 20) {
73
+ lines.push(` ... (${codeLines.length - 20} more lines)`);
74
+ }
75
+ lines.push("");
76
+ });
77
+ return lines.join("\n");
78
+ }
79
+
80
+ export {
81
+ createCodebaseSearchTool
82
+ };
83
+ //# sourceMappingURL=chunk-BILUTNBC.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../tools/codebase_search/anthropic.ts"],"sourcesContent":["/**\n * Anthropic SDK adapter for codebase_search tool\n */\n\nimport type { Tool } from '@anthropic-ai/sdk/resources/messages';\nimport { executeCodebaseSearch } from './core.js';\nimport { CODEBASE_SEARCH_DESCRIPTION, CODEBASE_SEARCH_SYSTEM_PROMPT } from './prompts.js';\nimport type { CodebaseSearchConfig, CodebaseSearchInput, CodebaseSearchResult } from './types.js';\n\n\n/**\n * Create Anthropic-native codebase_search tool with execute and formatResult methods\n * \n * @param config - Configuration with repoId\n * @returns Anthropic Tool definition with execute and formatResult methods\n * \n * @example\n * ```ts\n * import Anthropic from '@anthropic-ai/sdk';\n * import { createCodebaseSearchTool } from 'morphsdk/tools/anthropic';\n * \n * const client = new Anthropic({ apiKey: process.env.ANTHROPIC_API_KEY });\n * const tool = createCodebaseSearchTool({ repoId: 'my-project' });\n * \n * const response = await client.messages.create({\n * model: \"claude-sonnet-4-5-20250929\",\n * tools: [tool], // tool itself is the Tool definition\n * messages: [{ role: \"user\", content: \"Find authentication code\" }]\n * });\n * \n * // Execute tool and format result\n * const result = await tool.execute(toolUseBlock.input);\n * const formatted = tool.formatResult(result);\n * ```\n */\nexport function createCodebaseSearchTool(config: CodebaseSearchConfig) {\n const toolDefinition: Tool = {\n name: 'codebase_search',\n description: CODEBASE_SEARCH_DESCRIPTION,\n input_schema: {\n type: 'object',\n properties: {\n explanation: {\n type: 'string',\n description: 'One sentence explanation as to why this tool is being used, and how it contributes to the goal.',\n },\n query: {\n type: 'string',\n description: 'A complete question about what you want to understand. Ask as if talking to a colleague: \"How does X work?\", \"What happens when Y?\", \"Where is Z handled?\"',\n },\n target_directories: {\n type: 'array',\n items: { type: 'string' },\n description: 'Prefix directory paths to limit search scope (single directory only, no glob patterns). Use [] to search entire repo.',\n },\n limit: {\n type: 'number',\n description: 'Maximum results to return (default: 10)',\n },\n },\n required: ['query', 'target_directories', 'explanation'],\n },\n cache_control: { type: 'ephemeral' } as any,\n } as any;\n\n return Object.assign(toolDefinition, {\n execute: async (input: CodebaseSearchInput): Promise<CodebaseSearchResult> => {\n return executeCodebaseSearch(input, config);\n },\n formatResult: (result: CodebaseSearchResult): string => {\n return formatResult(result);\n },\n getSystemPrompt: (): string => {\n return CODEBASE_SEARCH_SYSTEM_PROMPT;\n },\n });\n}\n\n/**\n * Format search results for Claude\n * \n * @param result - Search result from endpoint\n * @returns Formatted string for tool_result\n */\nfunction formatResult(result: CodebaseSearchResult): string {\n if (!result.success) {\n return `Search failed: ${result.error}`;\n }\n\n if (result.results.length === 0) {\n return 'No matching code found. Try rephrasing your query or broadening the search scope.';\n }\n\n const lines: string[] = [];\n \n lines.push(`Found ${result.results.length} relevant code sections (searched ${result.stats.candidatesRetrieved} candidates in ${result.stats.searchTimeMs}ms):\\n`);\n\n result.results.forEach((r, i) => {\n const relevance = (r.rerankScore * 100).toFixed(1);\n lines.push(`${i + 1}. ${r.filepath} (${relevance}% relevant)`);\n lines.push(` Symbol: ${r.symbolPath}`);\n lines.push(` Language: ${r.language}`);\n lines.push(` Lines: ${r.startLine}-${r.endLine}`);\n lines.push(` Code:`);\n \n // Show code content with indentation\n const codeLines = r.content.split('\\n');\n codeLines.slice(0, Math.min(codeLines.length, 20)).forEach(line => {\n lines.push(` ${line}`);\n });\n \n if (codeLines.length > 20) {\n lines.push(` ... (${codeLines.length - 20} more lines)`);\n }\n \n lines.push('');\n });\n\n return lines.join('\\n');\n}\n\n"],"mappings":";;;;;;;;;AAmCO,SAAS,yBAAyB,QAA8B;AACrE,QAAM,iBAAuB;AAAA,IAC3B,MAAM;AAAA,IACN,aAAa;AAAA,IACb,cAAc;AAAA,MACZ,MAAM;AAAA,MACN,YAAY;AAAA,QACV,aAAa;AAAA,UACX,MAAM;AAAA,UACN,aAAa;AAAA,QACf;AAAA,QACA,OAAO;AAAA,UACL,MAAM;AAAA,UACN,aAAa;AAAA,QACf;AAAA,QACA,oBAAoB;AAAA,UAClB,MAAM;AAAA,UACN,OAAO,EAAE,MAAM,SAAS;AAAA,UACxB,aAAa;AAAA,QACf;AAAA,QACA,OAAO;AAAA,UACL,MAAM;AAAA,UACN,aAAa;AAAA,QACf;AAAA,MACF;AAAA,MACA,UAAU,CAAC,SAAS,sBAAsB,aAAa;AAAA,IACzD;AAAA,IACA,eAAe,EAAE,MAAM,YAAY;AAAA,EACrC;AAEA,SAAO,OAAO,OAAO,gBAAgB;AAAA,IACnC,SAAS,OAAO,UAA8D;AAC5E,aAAO,sBAAsB,OAAO,MAAM;AAAA,IAC5C;AAAA,IACA,cAAc,CAAC,WAAyC;AACtD,aAAO,aAAa,MAAM;AAAA,IAC5B;AAAA,IACA,iBAAiB,MAAc;AAC7B,aAAO;AAAA,IACT;AAAA,EACF,CAAC;AACH;AAQA,SAAS,aAAa,QAAsC;AAC1D,MAAI,CAAC,OAAO,SAAS;AACnB,WAAO,kBAAkB,OAAO,KAAK;AAAA,EACvC;AAEA,MAAI,OAAO,QAAQ,WAAW,GAAG;AAC/B,WAAO;AAAA,EACT;AAEA,QAAM,QAAkB,CAAC;AAEzB,QAAM,KAAK,SAAS,OAAO,QAAQ,MAAM,qCAAqC,OAAO,MAAM,mBAAmB,kBAAkB,OAAO,MAAM,YAAY;AAAA,CAAQ;AAEjK,SAAO,QAAQ,QAAQ,CAAC,GAAG,MAAM;AAC/B,UAAM,aAAa,EAAE,cAAc,KAAK,QAAQ,CAAC;AACjD,UAAM,KAAK,GAAG,IAAI,CAAC,KAAK,EAAE,QAAQ,KAAK,SAAS,aAAa;AAC7D,UAAM,KAAK,cAAc,EAAE,UAAU,EAAE;AACvC,UAAM,KAAK,gBAAgB,EAAE,QAAQ,EAAE;AACvC,UAAM,KAAK,aAAa,EAAE,SAAS,IAAI,EAAE,OAAO,EAAE;AAClD,UAAM,KAAK,UAAU;AAGrB,UAAM,YAAY,EAAE,QAAQ,MAAM,IAAI;AACtC,cAAU,MAAM,GAAG,KAAK,IAAI,UAAU,QAAQ,EAAE,CAAC,EAAE,QAAQ,UAAQ;AACjE,YAAM,KAAK,QAAQ,IAAI,EAAE;AAAA,IAC3B,CAAC;AAED,QAAI,UAAU,SAAS,IAAI;AACzB,YAAM,KAAK,aAAa,UAAU,SAAS,EAAE,cAAc;AAAA,IAC7D;AAEA,UAAM,KAAK,EAAE;AAAA,EACf,CAAC;AAED,SAAO,MAAM,KAAK,IAAI;AACxB;","names":[]}
@@ -0,0 +1,78 @@
1
+ import {
2
+ EDIT_FILE_SYSTEM_PROMPT,
3
+ EDIT_FILE_TOOL_DESCRIPTION
4
+ } from "./chunk-63WE2C5R.js";
5
+ import {
6
+ executeEditFile
7
+ } from "./chunk-4V46N27D.js";
8
+ import {
9
+ __export
10
+ } from "./chunk-PZ5AY32C.js";
11
+
12
+ // tools/fastapply/anthropic.ts
13
+ var anthropic_exports = {};
14
+ __export(anthropic_exports, {
15
+ createEditFileTool: () => createEditFileTool,
16
+ editFileTool: () => editFileTool
17
+ });
18
+ var editFileTool = {
19
+ name: "edit_file",
20
+ description: EDIT_FILE_TOOL_DESCRIPTION,
21
+ input_schema: {
22
+ type: "object",
23
+ properties: {
24
+ target_filepath: {
25
+ type: "string",
26
+ description: "The path of the target file to modify"
27
+ },
28
+ instructions: {
29
+ type: "string",
30
+ description: "A single sentence describing what you are changing (first person)"
31
+ },
32
+ code_edit: {
33
+ type: "string",
34
+ description: "The lazy edit with // ... existing code ... markers"
35
+ }
36
+ },
37
+ required: ["target_filepath", "instructions", "code_edit"]
38
+ }
39
+ };
40
+ function formatResult(result) {
41
+ if (!result.success) {
42
+ return `Error editing file: ${result.error}`;
43
+ }
44
+ const { changes } = result;
45
+ const summary = [
46
+ changes.linesAdded && `+${changes.linesAdded} lines`,
47
+ changes.linesRemoved && `-${changes.linesRemoved} lines`,
48
+ changes.linesModified && `~${changes.linesModified} lines modified`
49
+ ].filter(Boolean).join(", ");
50
+ if (result.udiff) {
51
+ return `Successfully applied changes to ${result.filepath}:
52
+
53
+ ${result.udiff}
54
+
55
+ Summary: ${summary}`;
56
+ }
57
+ return `Successfully applied changes to ${result.filepath}. ${summary}`;
58
+ }
59
+ function createEditFileTool(config = {}) {
60
+ return Object.assign({}, editFileTool, {
61
+ execute: async (input) => {
62
+ return executeEditFile(input, config);
63
+ },
64
+ formatResult: (result) => {
65
+ return formatResult(result);
66
+ },
67
+ getSystemPrompt: () => {
68
+ return EDIT_FILE_SYSTEM_PROMPT;
69
+ }
70
+ });
71
+ }
72
+
73
+ export {
74
+ editFileTool,
75
+ createEditFileTool,
76
+ anthropic_exports
77
+ };
78
+ //# sourceMappingURL=chunk-G4DJ6VSM.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../tools/fastapply/anthropic.ts"],"sourcesContent":["/**\n * Anthropic SDK adapter for edit_file tool\n */\n\nimport type { Tool } from '@anthropic-ai/sdk/resources/messages';\nimport { executeEditFile } from './core.js';\nimport { EDIT_FILE_TOOL_DESCRIPTION, EDIT_FILE_SYSTEM_PROMPT } from './prompts.js';\nimport type { EditFileInput, EditFileResult, EditFileConfig } from './types.js';\n\n/**\n * Anthropic-native tool definition for edit_file\n * \n * @example\n * ```ts\n * import Anthropic from '@anthropic-ai/sdk';\n * import { editFileTool } from 'morphsdk/tools/anthropic';\n * \n * const client = new Anthropic({ apiKey: process.env.ANTHROPIC_API_KEY });\n * \n * const response = await client.messages.create({\n * model: \"claude-sonnet-4-5-20250929\",\n * tools: [editFileTool],\n * messages: [{ role: \"user\", content: \"Fix the bug in app.ts\" }]\n * });\n * ```\n */\nexport const editFileTool: Tool = {\n name: 'edit_file',\n description: EDIT_FILE_TOOL_DESCRIPTION,\n input_schema: {\n type: 'object',\n properties: {\n target_filepath: {\n type: 'string',\n description: 'The path of the target file to modify',\n },\n instructions: {\n type: 'string',\n description: 'A single sentence describing what you are changing (first person)',\n },\n code_edit: {\n type: 'string',\n description: 'The lazy edit with // ... existing code ... markers',\n },\n },\n required: ['target_filepath', 'instructions', 'code_edit'],\n },\n};\n\n/**\n * Format the result for passing back to Claude\n * \n * @param result - The edit result\n * @returns Formatted string for tool_result\n */\nfunction formatResult(result: EditFileResult): string {\n if (!result.success) {\n return `Error editing file: ${result.error}`;\n }\n \n const { changes } = result;\n const summary = [\n changes.linesAdded && `+${changes.linesAdded} lines`,\n changes.linesRemoved && `-${changes.linesRemoved} lines`,\n changes.linesModified && `~${changes.linesModified} lines modified`,\n ]\n .filter(Boolean)\n .join(', ');\n \n if (result.udiff) {\n return `Successfully applied changes to ${result.filepath}:\\n\\n${result.udiff}\\n\\nSummary: ${summary}`;\n }\n \n return `Successfully applied changes to ${result.filepath}. ${summary}`;\n}\n\n/**\n * Create a custom edit_file tool with configuration\n * \n * @param config - Configuration options\n * @returns Tool definition with execute and formatResult methods\n * \n * @example\n * ```ts\n * const tool = createEditFileTool({\n * baseDir: './src',\n * generateUdiff: true,\n * morphApiKey: 'sk-...'\n * });\n * \n * // Use as Anthropic tool\n * const response = await client.messages.create({\n * tools: [tool], // tool itself is the Tool definition\n * ...\n * });\n * \n * // Execute and format\n * const result = await tool.execute(toolUseBlock.input);\n * const formatted = tool.formatResult(result);\n * ```\n */\nexport function createEditFileTool(config: EditFileConfig = {}) {\n return Object.assign({}, editFileTool, {\n execute: async (input: EditFileInput): Promise<EditFileResult> => {\n return executeEditFile(input, config);\n },\n formatResult: (result: EditFileResult): string => {\n return formatResult(result);\n },\n getSystemPrompt: (): string => {\n return EDIT_FILE_SYSTEM_PROMPT;\n },\n });\n}\n\n"],"mappings":";;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AA0BO,IAAM,eAAqB;AAAA,EAChC,MAAM;AAAA,EACN,aAAa;AAAA,EACb,cAAc;AAAA,IACZ,MAAM;AAAA,IACN,YAAY;AAAA,MACV,iBAAiB;AAAA,QACf,MAAM;AAAA,QACN,aAAa;AAAA,MACf;AAAA,MACA,cAAc;AAAA,QACZ,MAAM;AAAA,QACN,aAAa;AAAA,MACf;AAAA,MACA,WAAW;AAAA,QACT,MAAM;AAAA,QACN,aAAa;AAAA,MACf;AAAA,IACF;AAAA,IACA,UAAU,CAAC,mBAAmB,gBAAgB,WAAW;AAAA,EAC3D;AACF;AAQA,SAAS,aAAa,QAAgC;AACpD,MAAI,CAAC,OAAO,SAAS;AACnB,WAAO,uBAAuB,OAAO,KAAK;AAAA,EAC5C;AAEA,QAAM,EAAE,QAAQ,IAAI;AACpB,QAAM,UAAU;AAAA,IACd,QAAQ,cAAc,IAAI,QAAQ,UAAU;AAAA,IAC5C,QAAQ,gBAAgB,IAAI,QAAQ,YAAY;AAAA,IAChD,QAAQ,iBAAiB,IAAI,QAAQ,aAAa;AAAA,EACpD,EACG,OAAO,OAAO,EACd,KAAK,IAAI;AAEZ,MAAI,OAAO,OAAO;AAChB,WAAO,mCAAmC,OAAO,QAAQ;AAAA;AAAA,EAAQ,OAAO,KAAK;AAAA;AAAA,WAAgB,OAAO;AAAA,EACtG;AAEA,SAAO,mCAAmC,OAAO,QAAQ,KAAK,OAAO;AACvE;AA2BO,SAAS,mBAAmB,SAAyB,CAAC,GAAG;AAC9D,SAAO,OAAO,OAAO,CAAC,GAAG,cAAc;AAAA,IACrC,SAAS,OAAO,UAAkD;AAChE,aAAO,gBAAgB,OAAO,MAAM;AAAA,IACtC;AAAA,IACA,cAAc,CAAC,WAAmC;AAChD,aAAO,aAAa,MAAM;AAAA,IAC5B;AAAA,IACA,iBAAiB,MAAc;AAC7B,aAAO;AAAA,IACT;AAAA,EACF,CAAC;AACH;","names":[]}
@@ -0,0 +1,59 @@
1
+ import {
2
+ CODEBASE_SEARCH_DESCRIPTION
3
+ } from "./chunk-YQMPVJ2L.js";
4
+ import {
5
+ executeCodebaseSearch
6
+ } from "./chunk-VJK4PH5V.js";
7
+
8
+ // tools/codebase_search/vercel.ts
9
+ import { tool } from "ai";
10
+ import { z } from "zod";
11
+ function createCodebaseSearchTool(config) {
12
+ const schema = z.object({
13
+ query: z.string().describe('A complete question about what you want to understand. Ask as if talking to a colleague: "How does X work?", "What happens when Y?", "Where is Z handled?"'),
14
+ target_directories: z.array(z.string()).describe("Prefix directory paths to limit search scope (single directory only, no glob patterns). Use [] to search entire repo."),
15
+ explanation: z.string().describe("One sentence explanation as to why this tool is being used, and how it contributes to the goal."),
16
+ limit: z.number().optional().describe("Max results to return (default: 10)")
17
+ });
18
+ return tool({
19
+ description: CODEBASE_SEARCH_DESCRIPTION,
20
+ parameters: schema,
21
+ // @ts-ignore
22
+ execute: async (params) => {
23
+ const { query, target_directories, explanation, limit } = params;
24
+ const result = await executeCodebaseSearch(
25
+ { query, target_directories, explanation, limit },
26
+ config
27
+ );
28
+ if (!result.success) {
29
+ return {
30
+ error: result.error,
31
+ results: []
32
+ };
33
+ }
34
+ return {
35
+ found: result.results.length,
36
+ searchTime: `${result.stats.searchTimeMs}ms`,
37
+ results: result.results.map((r) => ({
38
+ file: r.filepath,
39
+ symbol: r.symbolPath,
40
+ lines: `${r.startLine}-${r.endLine}`,
41
+ language: r.language,
42
+ relevance: `${(r.rerankScore * 100).toFixed(1)}%`,
43
+ code: r.content
44
+ }))
45
+ };
46
+ }
47
+ });
48
+ }
49
+ function getSystemPrompt() {
50
+ return CODEBASE_SEARCH_DESCRIPTION;
51
+ }
52
+ var vercel_default = { createCodebaseSearchTool, getSystemPrompt };
53
+
54
+ export {
55
+ createCodebaseSearchTool,
56
+ getSystemPrompt,
57
+ vercel_default
58
+ };
59
+ //# sourceMappingURL=chunk-HGIFACNP.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../tools/codebase_search/vercel.ts"],"sourcesContent":["/**\n * Vercel AI SDK adapter for codebase_search tool\n */\n\nimport { tool } from 'ai';\nimport { z } from 'zod';\nimport { executeCodebaseSearch } from './core.js';\nimport { CODEBASE_SEARCH_DESCRIPTION } from './prompts.js';\nimport type { CodebaseSearchConfig } from './types.js';\n\n/**\n * Create Vercel AI SDK codebase_search tool\n * \n * @param config - Configuration with repoId\n * @returns Vercel AI SDK tool definition (execution built-in)\n * \n * @example\n * ```ts\n * import { generateText } from 'ai';\n * import { anthropic } from '@ai-sdk/anthropic';\n * import { createCodebaseSearchTool } from 'morphsdk/tools/codebase-search/vercel';\n * \n * const tool = createCodebaseSearchTool({ repoId: 'my-project' });\n * \n * const result = await generateText({\n * model: anthropic('claude-3-5-sonnet-20241022'),\n * tools: { codebaseSearch: tool },\n * prompt: \"Find authentication code\",\n * maxSteps: 5\n * });\n * \n * // Vercel AI SDK automatically executes and handles results\n * console.log(result.text);\n * ```\n */\nexport function createCodebaseSearchTool(config: CodebaseSearchConfig) {\n const schema = z.object({\n query: z.string().describe('A complete question about what you want to understand. Ask as if talking to a colleague: \"How does X work?\", \"What happens when Y?\", \"Where is Z handled?\"'),\n target_directories: z.array(z.string()).describe('Prefix directory paths to limit search scope (single directory only, no glob patterns). Use [] to search entire repo.'),\n explanation: z.string().describe('One sentence explanation as to why this tool is being used, and how it contributes to the goal.'),\n limit: z.number().optional().describe('Max results to return (default: 10)'),\n });\n\n // @ts-ignore - Vercel AI SDK tool() has execute runtime support but types are incomplete\n return tool({\n description: CODEBASE_SEARCH_DESCRIPTION,\n parameters: schema,\n // @ts-ignore\n execute: async (params) => {\n const { query, target_directories, explanation, limit } = params;\n const result = await executeCodebaseSearch(\n { query, target_directories, explanation, limit },\n config\n );\n\n if (!result.success) {\n return {\n error: result.error,\n results: [],\n };\n }\n\n // Format results for Vercel AI SDK\n return {\n found: result.results.length,\n searchTime: `${result.stats.searchTimeMs}ms`,\n results: result.results.map(r => ({\n file: r.filepath,\n symbol: r.symbolPath,\n lines: `${r.startLine}-${r.endLine}`,\n language: r.language,\n relevance: `${(r.rerankScore * 100).toFixed(1)}%`,\n code: r.content,\n })),\n };\n },\n });\n}\n\n/**\n * Get system prompt for Vercel AI SDK\n */\nexport function getSystemPrompt(): string {\n return CODEBASE_SEARCH_DESCRIPTION;\n}\n\n/**\n * Default export\n */\nexport default { createCodebaseSearchTool, getSystemPrompt };\n\n"],"mappings":";;;;;;;;AAIA,SAAS,YAAY;AACrB,SAAS,SAAS;AA8BX,SAAS,yBAAyB,QAA8B;AACrE,QAAM,SAAS,EAAE,OAAO;AAAA,IACtB,OAAO,EAAE,OAAO,EAAE,SAAS,4JAA4J;AAAA,IACvL,oBAAoB,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,SAAS,uHAAuH;AAAA,IACxK,aAAa,EAAE,OAAO,EAAE,SAAS,iGAAiG;AAAA,IAClI,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,qCAAqC;AAAA,EAC7E,CAAC;AAGD,SAAO,KAAK;AAAA,IACV,aAAa;AAAA,IACb,YAAY;AAAA;AAAA,IAEZ,SAAS,OAAO,WAAW;AACzB,YAAM,EAAE,OAAO,oBAAoB,aAAa,MAAM,IAAI;AAC1D,YAAM,SAAS,MAAM;AAAA,QACnB,EAAE,OAAO,oBAAoB,aAAa,MAAM;AAAA,QAChD;AAAA,MACF;AAEA,UAAI,CAAC,OAAO,SAAS;AACnB,eAAO;AAAA,UACL,OAAO,OAAO;AAAA,UACd,SAAS,CAAC;AAAA,QACZ;AAAA,MACF;AAGA,aAAO;AAAA,QACL,OAAO,OAAO,QAAQ;AAAA,QACtB,YAAY,GAAG,OAAO,MAAM,YAAY;AAAA,QACxC,SAAS,OAAO,QAAQ,IAAI,QAAM;AAAA,UAChC,MAAM,EAAE;AAAA,UACR,QAAQ,EAAE;AAAA,UACV,OAAO,GAAG,EAAE,SAAS,IAAI,EAAE,OAAO;AAAA,UAClC,UAAU,EAAE;AAAA,UACZ,WAAW,IAAI,EAAE,cAAc,KAAK,QAAQ,CAAC,CAAC;AAAA,UAC9C,MAAM,EAAE;AAAA,QACV,EAAE;AAAA,MACJ;AAAA,IACF;AAAA,EACF,CAAC;AACH;AAKO,SAAS,kBAA0B;AACxC,SAAO;AACT;AAKA,IAAO,iBAAQ,EAAE,0BAA0B,gBAAgB;","names":[]}
@@ -0,0 +1,189 @@
1
+ import {
2
+ fetchWithRetry,
3
+ withTimeout
4
+ } from "./chunk-4VWJFZVS.js";
5
+
6
+ // tools/modelrouter/core.ts
7
+ var DEFAULT_CONFIG = {
8
+ apiUrl: "https://api.morphllm.com",
9
+ timeout: 1e4,
10
+ // 10 seconds
11
+ debug: false
12
+ };
13
+ var MODEL_MAPPINGS = {
14
+ openai: {
15
+ balanced: {
16
+ easy: "gpt-5-mini",
17
+ medium: "gpt-5-low",
18
+ hard: "gpt-5-medium",
19
+ "needs-info": "gpt-5-mini"
20
+ },
21
+ aggressive: {
22
+ easy: "gpt-5-low",
23
+ medium: "gpt-5-medium",
24
+ hard: "gpt-5-high",
25
+ "needs-info": "gpt-5-mini"
26
+ }
27
+ },
28
+ anthropic: {
29
+ balanced: {
30
+ easy: "claude-4.5-haiku",
31
+ medium: "claude-4.5-haiku",
32
+ hard: "claude-4.5-sonnet",
33
+ "needs-info": "claude-4.5-haiku"
34
+ },
35
+ aggressive: {
36
+ easy: "claude-4.5-haiku",
37
+ medium: "claude-4.5-sonnet",
38
+ hard: "claude-4.5-sonnet",
39
+ "needs-info": "claude-4.5-haiku"
40
+ }
41
+ },
42
+ gemini: {
43
+ balanced: {
44
+ easy: "gemini-2.5-flash",
45
+ medium: "gemini-2.5-flash",
46
+ hard: "gemini-2.5-pro",
47
+ "needs-info": "gemini-2.5-flash"
48
+ },
49
+ aggressive: {
50
+ easy: "gemini-2.5-flash",
51
+ medium: "gemini-2.5-pro",
52
+ hard: "gemini-2.5-pro",
53
+ "needs-info": "gemini-2.5-flash"
54
+ }
55
+ }
56
+ };
57
+ var BaseRouter = class {
58
+ config;
59
+ provider;
60
+ constructor(provider, config = {}) {
61
+ this.provider = provider;
62
+ this.config = {
63
+ apiKey: config.apiKey,
64
+ apiUrl: config.apiUrl || DEFAULT_CONFIG.apiUrl,
65
+ timeout: config.timeout || DEFAULT_CONFIG.timeout,
66
+ debug: config.debug || DEFAULT_CONFIG.debug,
67
+ retryConfig: config.retryConfig
68
+ };
69
+ }
70
+ /**
71
+ * Map backend complexity classification to actual model name
72
+ */
73
+ mapComplexityToModel(complexity, mode) {
74
+ const mapping = MODEL_MAPPINGS[this.provider][mode];
75
+ return mapping[complexity];
76
+ }
77
+ /**
78
+ * Select the optimal model for a given input and mode
79
+ */
80
+ async selectModel(input) {
81
+ const mode = input.mode || "balanced";
82
+ const apiKey = this.config.apiKey || process.env.MORPH_API_KEY;
83
+ if (!apiKey) {
84
+ throw new Error(
85
+ "Morph API key is required. Set MORPH_API_KEY environment variable or pass apiKey in config."
86
+ );
87
+ }
88
+ const url = `${this.config.apiUrl}/router/${this.provider}`;
89
+ const payload = {
90
+ input: input.input,
91
+ mode
92
+ };
93
+ if (this.config.debug) {
94
+ console.log(`[ModelRouter] Requesting ${this.provider} model selection:`, {
95
+ mode,
96
+ inputLength: input.input.length
97
+ });
98
+ }
99
+ try {
100
+ const fetchPromise = fetchWithRetry(
101
+ url,
102
+ {
103
+ method: "POST",
104
+ headers: {
105
+ "Content-Type": "application/json",
106
+ Authorization: `Bearer ${apiKey}`
107
+ },
108
+ body: JSON.stringify(payload)
109
+ },
110
+ this.config.retryConfig
111
+ );
112
+ const response = await withTimeout(
113
+ fetchPromise,
114
+ this.config.timeout,
115
+ `Router API request timed out after ${this.config.timeout}ms`
116
+ );
117
+ if (!response.ok) {
118
+ const errorText = await response.text();
119
+ throw new Error(
120
+ `Router API error (${response.status}): ${errorText || response.statusText}`
121
+ );
122
+ }
123
+ const apiResult = await response.json();
124
+ const actualModel = this.mapComplexityToModel(apiResult.model, mode);
125
+ const result = {
126
+ model: actualModel,
127
+ reasoning: apiResult.reasoning
128
+ };
129
+ if (this.config.debug) {
130
+ console.log(`[ModelRouter] Complexity: ${apiResult.model}, Selected model: ${actualModel}`);
131
+ }
132
+ return result;
133
+ } catch (error) {
134
+ if (this.config.debug) {
135
+ console.error(`[ModelRouter] Error selecting model:`, error);
136
+ }
137
+ throw error;
138
+ }
139
+ }
140
+ };
141
+ var OpenAIRouter = class extends BaseRouter {
142
+ constructor(config = {}) {
143
+ super("openai", config);
144
+ }
145
+ /**
146
+ * Select optimal GPT-5 model
147
+ *
148
+ * @param input - User input and mode
149
+ * @returns Selected model name (gpt-5-mini | gpt-5-low | gpt-5-medium | gpt-5-high)
150
+ */
151
+ async selectModel(input) {
152
+ return super.selectModel(input);
153
+ }
154
+ };
155
+ var AnthropicRouter = class extends BaseRouter {
156
+ constructor(config = {}) {
157
+ super("anthropic", config);
158
+ }
159
+ /**
160
+ * Select optimal Claude model
161
+ *
162
+ * @param input - User input and mode
163
+ * @returns Selected model name (claude-4.5-haiku | claude-4.5-sonnet)
164
+ */
165
+ async selectModel(input) {
166
+ return super.selectModel(input);
167
+ }
168
+ };
169
+ var GeminiRouter = class extends BaseRouter {
170
+ constructor(config = {}) {
171
+ super("gemini", config);
172
+ }
173
+ /**
174
+ * Select optimal Gemini model
175
+ *
176
+ * @param input - User input and mode
177
+ * @returns Selected model name (gemini-2.5-flash | gemini-2.5-pro)
178
+ */
179
+ async selectModel(input) {
180
+ return super.selectModel(input);
181
+ }
182
+ };
183
+
184
+ export {
185
+ OpenAIRouter,
186
+ AnthropicRouter,
187
+ GeminiRouter
188
+ };
189
+ //# sourceMappingURL=chunk-OI5YYE36.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../tools/modelrouter/core.ts"],"sourcesContent":["/**\n * Core implementation for intelligent model routing\n */\n\nimport { fetchWithRetry, withTimeout } from '../utils/resilience.js';\nimport type {\n RouterConfig,\n RouterInput,\n RouterResult,\n ComplexityLevel,\n RouterMode,\n Provider,\n} from './types.js';\n\nconst DEFAULT_CONFIG = {\n apiUrl: 'https://api.morphllm.com',\n timeout: 10000, // 10 seconds\n debug: false,\n};\n\nconst MODEL_MAPPINGS: Record<Provider, Record<RouterMode, Record<ComplexityLevel, string>>> = {\n openai: {\n balanced: {\n easy: 'gpt-5-mini',\n medium: 'gpt-5-low',\n hard: 'gpt-5-medium',\n 'needs-info': 'gpt-5-mini',\n },\n aggressive: {\n easy: 'gpt-5-low',\n medium: 'gpt-5-medium',\n hard: 'gpt-5-high',\n 'needs-info': 'gpt-5-mini',\n },\n },\n anthropic: {\n balanced: {\n easy: 'claude-4.5-haiku',\n medium: 'claude-4.5-haiku',\n hard: 'claude-4.5-sonnet',\n 'needs-info': 'claude-4.5-haiku',\n },\n aggressive: {\n easy: 'claude-4.5-haiku',\n medium: 'claude-4.5-sonnet',\n hard: 'claude-4.5-sonnet',\n 'needs-info': 'claude-4.5-haiku',\n },\n },\n gemini: {\n balanced: {\n easy: 'gemini-2.5-flash',\n medium: 'gemini-2.5-flash',\n hard: 'gemini-2.5-pro',\n 'needs-info': 'gemini-2.5-flash',\n },\n aggressive: {\n easy: 'gemini-2.5-flash',\n medium: 'gemini-2.5-pro',\n hard: 'gemini-2.5-pro',\n 'needs-info': 'gemini-2.5-flash',\n },\n },\n};\n\nabstract class BaseRouter {\n protected config: Required<Omit<RouterConfig, 'apiKey' | 'retryConfig'>> & Pick<RouterConfig, 'apiKey' | 'retryConfig'>;\n protected provider: Provider;\n\n constructor(provider: Provider, config: RouterConfig = {}) {\n this.provider = provider;\n this.config = {\n apiKey: config.apiKey,\n apiUrl: config.apiUrl || DEFAULT_CONFIG.apiUrl,\n timeout: config.timeout || DEFAULT_CONFIG.timeout,\n debug: config.debug || DEFAULT_CONFIG.debug,\n retryConfig: config.retryConfig,\n };\n }\n\n /**\n * Map backend complexity classification to actual model name\n */\n protected mapComplexityToModel(complexity: ComplexityLevel, mode: RouterMode): string {\n const mapping = MODEL_MAPPINGS[this.provider][mode];\n return mapping[complexity];\n }\n\n /**\n * Select the optimal model for a given input and mode\n */\n async selectModel(input: RouterInput): Promise<RouterResult> {\n const mode = input.mode || 'balanced';\n const apiKey = this.config.apiKey || process.env.MORPH_API_KEY;\n\n if (!apiKey) {\n throw new Error(\n 'Morph API key is required. Set MORPH_API_KEY environment variable or pass apiKey in config.'\n );\n }\n\n const url = `${this.config.apiUrl}/router/${this.provider}`;\n const payload = {\n input: input.input,\n mode,\n };\n\n if (this.config.debug) {\n console.log(`[ModelRouter] Requesting ${this.provider} model selection:`, {\n mode,\n inputLength: input.input.length,\n });\n }\n\n try {\n const fetchPromise = fetchWithRetry(\n url,\n {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${apiKey}`,\n },\n body: JSON.stringify(payload),\n },\n this.config.retryConfig\n );\n\n const response = await withTimeout(\n fetchPromise,\n this.config.timeout,\n `Router API request timed out after ${this.config.timeout}ms`\n );\n\n if (!response.ok) {\n const errorText = await response.text();\n throw new Error(\n `Router API error (${response.status}): ${errorText || response.statusText}`\n );\n }\n\n const apiResult: { model: ComplexityLevel; reasoning?: string } = await response.json();\n const actualModel = this.mapComplexityToModel(apiResult.model, mode);\n\n const result: RouterResult = {\n model: actualModel,\n reasoning: apiResult.reasoning,\n };\n\n if (this.config.debug) {\n console.log(`[ModelRouter] Complexity: ${apiResult.model}, Selected model: ${actualModel}`);\n }\n\n return result;\n } catch (error) {\n if (this.config.debug) {\n console.error(`[ModelRouter] Error selecting model:`, error);\n }\n throw error;\n }\n }\n}\n\n/**\n * OpenAI model router for GPT-5 series\n */\nexport class OpenAIRouter extends BaseRouter {\n constructor(config: RouterConfig = {}) {\n super('openai', config);\n }\n\n /**\n * Select optimal GPT-5 model\n * \n * @param input - User input and mode\n * @returns Selected model name (gpt-5-mini | gpt-5-low | gpt-5-medium | gpt-5-high)\n */\n async selectModel(input: RouterInput): Promise<RouterResult> {\n return super.selectModel(input);\n }\n}\n\n/**\n * Anthropic model router for Claude 4.5 series\n */\nexport class AnthropicRouter extends BaseRouter {\n constructor(config: RouterConfig = {}) {\n super('anthropic', config);\n }\n\n /**\n * Select optimal Claude model\n * \n * @param input - User input and mode\n * @returns Selected model name (claude-4.5-haiku | claude-4.5-sonnet)\n */\n async selectModel(input: RouterInput): Promise<RouterResult> {\n return super.selectModel(input);\n }\n}\n\n/**\n * Google Gemini model router\n */\nexport class GeminiRouter extends BaseRouter {\n constructor(config: RouterConfig = {}) {\n super('gemini', config);\n }\n\n /**\n * Select optimal Gemini model\n * \n * @param input - User input and mode\n * @returns Selected model name (gemini-2.5-flash | gemini-2.5-pro)\n */\n async selectModel(input: RouterInput): Promise<RouterResult> {\n return super.selectModel(input);\n }\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1,10 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __export = (target, all) => {
3
+ for (var name in all)
4
+ __defProp(target, name, { get: all[name], enumerable: true });
5
+ };
6
+
7
+ export {
8
+ __export
9
+ };
10
+ //# sourceMappingURL=chunk-PZ5AY32C.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
@@ -0,0 +1,105 @@
1
+ import {
2
+ fetchWithRetry,
3
+ withTimeout
4
+ } from "./chunk-4VWJFZVS.js";
5
+
6
+ // tools/codebase_search/core.ts
7
+ var CodebaseSearchClient = class {
8
+ config;
9
+ constructor(config = {}) {
10
+ this.config = {
11
+ apiKey: config.apiKey,
12
+ searchUrl: process.env.MORPH_SEARCH_URL || "http://embedrerank.morphllm.com:8081",
13
+ debug: config.debug,
14
+ timeout: config.timeout || 3e4,
15
+ retryConfig: config.retryConfig
16
+ };
17
+ }
18
+ /**
19
+ * Execute a semantic code search
20
+ *
21
+ * @param input - Search parameters including query, repoId, and target directories
22
+ * @param overrides - Optional config overrides for this operation
23
+ * @returns Search results with ranked code matches
24
+ */
25
+ async search(input, overrides) {
26
+ return executeCodebaseSearch(
27
+ {
28
+ query: input.query,
29
+ target_directories: input.target_directories,
30
+ explanation: input.explanation,
31
+ limit: input.limit
32
+ },
33
+ { ...this.config, repoId: input.repoId, ...overrides }
34
+ );
35
+ }
36
+ };
37
+ async function executeCodebaseSearch(input, config) {
38
+ const apiKey = config.apiKey || process.env.MORPH_API_KEY;
39
+ if (!apiKey) {
40
+ throw new Error("MORPH_API_KEY not found. Set environment variable or pass in config");
41
+ }
42
+ const searchUrl = config.searchUrl || process.env.MORPH_SEARCH_URL || "http://embedrerank.morphllm.com:8081";
43
+ const timeout = config.timeout || 3e4;
44
+ const debug = config.debug || false;
45
+ if (debug) {
46
+ console.log(`[CodebaseSearch] Query: "${input.query.slice(0, 60)}..." repo=${config.repoId}`);
47
+ console.log(`[CodebaseSearch] URL: ${searchUrl}/v1/codebase_search`);
48
+ }
49
+ const startTime = Date.now();
50
+ try {
51
+ const fetchPromise = fetchWithRetry(
52
+ `${searchUrl}/v1/codebase_search`,
53
+ {
54
+ method: "POST",
55
+ headers: {
56
+ "Content-Type": "application/json",
57
+ "Authorization": `Bearer ${apiKey}`
58
+ },
59
+ body: JSON.stringify({
60
+ query: input.query,
61
+ repoId: config.repoId,
62
+ targetDirectories: input.target_directories || [],
63
+ limit: input.limit || 10,
64
+ candidateLimit: 50
65
+ })
66
+ },
67
+ config.retryConfig
68
+ );
69
+ const response = await withTimeout(fetchPromise, timeout, `Codebase search timed out after ${timeout}ms`);
70
+ if (!response.ok) {
71
+ const errorText = await response.text();
72
+ if (debug) console.error(`[CodebaseSearch] Error: ${response.status} - ${errorText}`);
73
+ return {
74
+ success: false,
75
+ results: [],
76
+ stats: { totalResults: 0, candidatesRetrieved: 0, searchTimeMs: 0 },
77
+ error: `Search failed (${response.status}): ${errorText}`
78
+ };
79
+ }
80
+ const data = await response.json();
81
+ const elapsed = Date.now() - startTime;
82
+ if (debug) {
83
+ console.log(`[CodebaseSearch] \u2705 ${data.results?.length || 0} results in ${elapsed}ms`);
84
+ }
85
+ return {
86
+ success: true,
87
+ results: data.results || [],
88
+ stats: data.stats || { totalResults: 0, candidatesRetrieved: 0, searchTimeMs: elapsed }
89
+ };
90
+ } catch (error) {
91
+ if (debug) console.error(`[CodebaseSearch] Exception: ${error instanceof Error ? error.message : error}`);
92
+ return {
93
+ success: false,
94
+ results: [],
95
+ stats: { totalResults: 0, candidatesRetrieved: 0, searchTimeMs: 0 },
96
+ error: error instanceof Error ? error.message : "Unknown error"
97
+ };
98
+ }
99
+ }
100
+
101
+ export {
102
+ CodebaseSearchClient,
103
+ executeCodebaseSearch
104
+ };
105
+ //# sourceMappingURL=chunk-VJK4PH5V.js.map