modular-studio 1.0.6 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (198) hide show
  1. package/dist/assets/Badge-Bsy2H_p2.js +1 -0
  2. package/dist/assets/GraphPanel-D4X3faxA.js +47 -0
  3. package/dist/assets/{Input-ndEGQSgx.js → Input-Dyb88Erk.js} +1 -1
  4. package/dist/assets/KnowledgeTab-BccWz7Np.js +5 -0
  5. package/dist/assets/MemoryTab-Y_66cE01.js +16 -0
  6. package/dist/assets/QualificationTab-Dm9dEIpM.js +1 -0
  7. package/dist/assets/ReviewTab-BrfXSyyf.js +104 -0
  8. package/dist/assets/{Section-CgmwAj_2.js → Section-68XDCFTl.js} +1 -1
  9. package/dist/assets/TestTab-CLKRT63X.js +42 -0
  10. package/dist/assets/{ToolsTab-C10Ulm8b.js → ToolsTab-xumi9Uds.js} +1 -1
  11. package/dist/assets/icons-CS8RUPBi.js +1 -0
  12. package/dist/assets/index-B2bm0161.css +1 -0
  13. package/dist/assets/index-C626nWuA.js +422 -0
  14. package/dist/assets/services-BDk6yY4o.js +369 -0
  15. package/dist/index.html +4 -4
  16. package/dist-server/bin/modular-mcp.js +1 -0
  17. package/dist-server/server/index.d.ts.map +1 -1
  18. package/dist-server/server/index.js +30 -0
  19. package/dist-server/server/mcp/manager.d.ts +3 -0
  20. package/dist-server/server/mcp/manager.d.ts.map +1 -1
  21. package/dist-server/server/mcp/manager.js +64 -3
  22. package/dist-server/server/migrations/index.d.ts +11 -0
  23. package/dist-server/server/migrations/index.d.ts.map +1 -0
  24. package/dist-server/server/migrations/index.js +57 -0
  25. package/dist-server/server/routes/analytics.d.ts +3 -0
  26. package/dist-server/server/routes/analytics.d.ts.map +1 -0
  27. package/dist-server/server/routes/analytics.js +24 -0
  28. package/dist-server/server/routes/connectors/airtable.d.ts +7 -0
  29. package/dist-server/server/routes/connectors/airtable.d.ts.map +1 -0
  30. package/dist-server/server/routes/connectors/airtable.js +119 -0
  31. package/dist-server/server/routes/connectors/confluence.d.ts +7 -0
  32. package/dist-server/server/routes/connectors/confluence.d.ts.map +1 -0
  33. package/dist-server/server/routes/connectors/confluence.js +176 -0
  34. package/dist-server/server/routes/connectors/github.d.ts +7 -0
  35. package/dist-server/server/routes/connectors/github.d.ts.map +1 -0
  36. package/dist-server/server/routes/connectors/github.js +195 -0
  37. package/dist-server/server/routes/connectors/gmail.d.ts +7 -0
  38. package/dist-server/server/routes/connectors/gmail.d.ts.map +1 -0
  39. package/dist-server/server/routes/connectors/gmail.js +115 -0
  40. package/dist-server/server/routes/connectors/google-docs.d.ts +10 -0
  41. package/dist-server/server/routes/connectors/google-docs.d.ts.map +1 -0
  42. package/dist-server/server/routes/connectors/google-docs.js +165 -0
  43. package/dist-server/server/routes/connectors/google-drive.d.ts +7 -0
  44. package/dist-server/server/routes/connectors/google-drive.d.ts.map +1 -0
  45. package/dist-server/server/routes/connectors/google-drive.js +163 -0
  46. package/dist-server/server/routes/connectors/google-sheets.d.ts +7 -0
  47. package/dist-server/server/routes/connectors/google-sheets.d.ts.map +1 -0
  48. package/dist-server/server/routes/connectors/google-sheets.js +90 -0
  49. package/dist-server/server/routes/connectors/hubspot.d.ts +7 -0
  50. package/dist-server/server/routes/connectors/hubspot.d.ts.map +1 -0
  51. package/dist-server/server/routes/connectors/hubspot.js +134 -0
  52. package/dist-server/server/routes/connectors/index.d.ts +6 -0
  53. package/dist-server/server/routes/connectors/index.d.ts.map +1 -0
  54. package/dist-server/server/routes/connectors/index.js +38 -0
  55. package/dist-server/server/routes/connectors/jira.d.ts +7 -0
  56. package/dist-server/server/routes/connectors/jira.d.ts.map +1 -0
  57. package/dist-server/server/routes/connectors/jira.js +151 -0
  58. package/dist-server/server/routes/connectors/linear.d.ts +7 -0
  59. package/dist-server/server/routes/connectors/linear.d.ts.map +1 -0
  60. package/dist-server/server/routes/connectors/linear.js +154 -0
  61. package/dist-server/server/routes/connectors/notion.d.ts +10 -0
  62. package/dist-server/server/routes/connectors/notion.d.ts.map +1 -0
  63. package/dist-server/server/routes/connectors/notion.js +201 -0
  64. package/dist-server/server/routes/connectors/plane.d.ts +10 -0
  65. package/dist-server/server/routes/connectors/plane.d.ts.map +1 -0
  66. package/dist-server/server/routes/connectors/plane.js +189 -0
  67. package/dist-server/server/routes/connectors/shared.d.ts +25 -0
  68. package/dist-server/server/routes/connectors/shared.d.ts.map +1 -0
  69. package/dist-server/server/routes/connectors/shared.js +202 -0
  70. package/dist-server/server/routes/connectors/slack.d.ts +7 -0
  71. package/dist-server/server/routes/connectors/slack.d.ts.map +1 -0
  72. package/dist-server/server/routes/connectors/slack.js +153 -0
  73. package/dist-server/server/routes/cost.d.ts +3 -0
  74. package/dist-server/server/routes/cost.d.ts.map +1 -0
  75. package/dist-server/server/routes/cost.js +113 -0
  76. package/dist-server/server/routes/graph.d.ts +11 -0
  77. package/dist-server/server/routes/graph.d.ts.map +1 -0
  78. package/dist-server/server/routes/graph.js +213 -0
  79. package/dist-server/server/routes/lessons.d.ts.map +1 -1
  80. package/dist-server/server/routes/lessons.js +119 -5
  81. package/dist-server/server/routes/llm.d.ts.map +1 -1
  82. package/dist-server/server/routes/llm.js +85 -18
  83. package/dist-server/server/routes/metaprompt-v2.d.ts +3 -0
  84. package/dist-server/server/routes/metaprompt-v2.d.ts.map +1 -0
  85. package/dist-server/server/routes/metaprompt-v2.js +104 -0
  86. package/dist-server/server/routes/qualification.d.ts.map +1 -1
  87. package/dist-server/server/routes/qualification.js +61 -11
  88. package/dist-server/server/routes/skills-search.d.ts.map +1 -1
  89. package/dist-server/server/routes/skills-search.js +10 -0
  90. package/dist-server/server/routes/tool-analytics.d.ts +3 -0
  91. package/dist-server/server/routes/tool-analytics.d.ts.map +1 -0
  92. package/dist-server/server/routes/tool-analytics.js +47 -0
  93. package/dist-server/server/services/adapters/sqliteAdapter.d.ts +1 -0
  94. package/dist-server/server/services/adapters/sqliteAdapter.d.ts.map +1 -1
  95. package/dist-server/server/services/adapters/sqliteAdapter.js +78 -48
  96. package/dist-server/server/services/credentialStore.d.ts +10 -0
  97. package/dist-server/server/services/credentialStore.d.ts.map +1 -0
  98. package/dist-server/server/services/credentialStore.js +123 -0
  99. package/dist-server/server/services/hindsightClient.d.ts.map +1 -1
  100. package/dist-server/server/services/hindsightClient.js +1 -0
  101. package/dist-server/server/services/lessonExtractor.d.ts +2 -0
  102. package/dist-server/server/services/lessonExtractor.d.ts.map +1 -1
  103. package/dist-server/server/services/lessonExtractor.js +7 -2
  104. package/dist-server/server/services/repoIndexer.d.ts +7 -1
  105. package/dist-server/server/services/repoIndexer.d.ts.map +1 -1
  106. package/dist-server/server/services/repoIndexer.js +295 -94
  107. package/dist-server/server/services/sqliteStore.d.ts +64 -0
  108. package/dist-server/server/services/sqliteStore.d.ts.map +1 -1
  109. package/dist-server/server/services/sqliteStore.js +238 -0
  110. package/dist-server/src/config.d.ts +2 -0
  111. package/dist-server/src/config.d.ts.map +1 -0
  112. package/dist-server/src/config.js +3 -0
  113. package/dist-server/src/graph/db.d.ts +46 -0
  114. package/dist-server/src/graph/db.d.ts.map +1 -0
  115. package/dist-server/src/graph/db.js +241 -0
  116. package/dist-server/src/graph/extractors/code.d.ts +12 -0
  117. package/dist-server/src/graph/extractors/code.d.ts.map +1 -0
  118. package/dist-server/src/graph/extractors/code.js +239 -0
  119. package/dist-server/src/graph/extractors/cross-type.d.ts +16 -0
  120. package/dist-server/src/graph/extractors/cross-type.d.ts.map +1 -0
  121. package/dist-server/src/graph/extractors/cross-type.js +67 -0
  122. package/dist-server/src/graph/extractors/markdown.d.ts +29 -0
  123. package/dist-server/src/graph/extractors/markdown.d.ts.map +1 -0
  124. package/dist-server/src/graph/extractors/markdown.js +224 -0
  125. package/dist-server/src/graph/extractors/yaml.d.ts +15 -0
  126. package/dist-server/src/graph/extractors/yaml.d.ts.map +1 -0
  127. package/dist-server/src/graph/extractors/yaml.js +104 -0
  128. package/dist-server/src/graph/index.d.ts +62 -0
  129. package/dist-server/src/graph/index.d.ts.map +1 -0
  130. package/dist-server/src/graph/index.js +67 -0
  131. package/dist-server/src/graph/packer.d.ts +19 -0
  132. package/dist-server/src/graph/packer.d.ts.map +1 -0
  133. package/dist-server/src/graph/packer.js +134 -0
  134. package/dist-server/src/graph/resolver.d.ts +12 -0
  135. package/dist-server/src/graph/resolver.d.ts.map +1 -0
  136. package/dist-server/src/graph/resolver.js +81 -0
  137. package/dist-server/src/graph/scanner.d.ts +34 -0
  138. package/dist-server/src/graph/scanner.d.ts.map +1 -0
  139. package/dist-server/src/graph/scanner.js +252 -0
  140. package/dist-server/src/graph/traverser.d.ts +17 -0
  141. package/dist-server/src/graph/traverser.d.ts.map +1 -0
  142. package/dist-server/src/graph/traverser.js +185 -0
  143. package/dist-server/src/graph/types.d.ts +117 -0
  144. package/dist-server/src/graph/types.d.ts.map +1 -0
  145. package/dist-server/src/graph/types.js +63 -0
  146. package/dist-server/src/metaprompt/v2/assembler.d.ts +3 -0
  147. package/dist-server/src/metaprompt/v2/assembler.d.ts.map +1 -0
  148. package/dist-server/src/metaprompt/v2/assembler.js +261 -0
  149. package/dist-server/src/metaprompt/v2/context-strategist.d.ts +3 -0
  150. package/dist-server/src/metaprompt/v2/context-strategist.d.ts.map +1 -0
  151. package/dist-server/src/metaprompt/v2/context-strategist.js +173 -0
  152. package/dist-server/src/metaprompt/v2/evaluator.d.ts +3 -0
  153. package/dist-server/src/metaprompt/v2/evaluator.d.ts.map +1 -0
  154. package/dist-server/src/metaprompt/v2/evaluator.js +281 -0
  155. package/dist-server/src/metaprompt/v2/index.d.ts +41 -0
  156. package/dist-server/src/metaprompt/v2/index.d.ts.map +1 -0
  157. package/dist-server/src/metaprompt/v2/index.js +90 -0
  158. package/dist-server/src/metaprompt/v2/parser.d.ts +3 -0
  159. package/dist-server/src/metaprompt/v2/parser.d.ts.map +1 -0
  160. package/dist-server/src/metaprompt/v2/parser.js +138 -0
  161. package/dist-server/src/metaprompt/v2/pattern-selector.d.ts +3 -0
  162. package/dist-server/src/metaprompt/v2/pattern-selector.d.ts.map +1 -0
  163. package/dist-server/src/metaprompt/v2/pattern-selector.js +154 -0
  164. package/dist-server/src/metaprompt/v2/researcher.d.ts +3 -0
  165. package/dist-server/src/metaprompt/v2/researcher.d.ts.map +1 -0
  166. package/dist-server/src/metaprompt/v2/researcher.js +194 -0
  167. package/dist-server/src/metaprompt/v2/tool-discovery.d.ts +74 -0
  168. package/dist-server/src/metaprompt/v2/tool-discovery.d.ts.map +1 -0
  169. package/dist-server/src/metaprompt/v2/tool-discovery.js +290 -0
  170. package/dist-server/src/metaprompt/v2/types.d.ts +154 -0
  171. package/dist-server/src/metaprompt/v2/types.d.ts.map +1 -0
  172. package/dist-server/src/metaprompt/v2/types.js +2 -0
  173. package/dist-server/src/services/contradictionDetector.js +1 -1
  174. package/dist-server/src/services/llmService.d.ts +61 -0
  175. package/dist-server/src/services/llmService.d.ts.map +1 -0
  176. package/dist-server/src/services/llmService.js +222 -0
  177. package/dist-server/src/store/knowledgeBase.d.ts +5 -1
  178. package/dist-server/src/store/knowledgeBase.d.ts.map +1 -1
  179. package/dist-server/src/store/knowledgeBase.js +0 -1
  180. package/dist-server/src/store/mcp-registry.d.ts +29 -0
  181. package/dist-server/src/store/mcp-registry.d.ts.map +1 -0
  182. package/dist-server/src/store/mcp-registry.js +1303 -0
  183. package/dist-server/src/types/registry.types.d.ts +13 -0
  184. package/dist-server/src/types/registry.types.d.ts.map +1 -0
  185. package/dist-server/src/types/registry.types.js +2 -0
  186. package/dist-server/tsconfig.server.tsbuildinfo +1 -1
  187. package/package.json +118 -105
  188. package/scripts/cleanup-worktrees.ps1 +29 -0
  189. package/dist/assets/Badge-DrUmDAXz.js +0 -1
  190. package/dist/assets/KnowledgeTab-CxlC76Rf.js +0 -4
  191. package/dist/assets/MemoryTab-CUScYWs9.js +0 -16
  192. package/dist/assets/QualificationTab-BqnWSQHm.js +0 -1
  193. package/dist/assets/ReviewTab-DKYl6cR9.js +0 -103
  194. package/dist/assets/TestTab-iJ2vCf9l.js +0 -33
  195. package/dist/assets/icons-MKpPNvV8.js +0 -1
  196. package/dist/assets/index-B_ip7Amg.css +0 -1
  197. package/dist/assets/index-gBy3427k.js +0 -143
  198. package/dist/assets/services-CTWXQK6j.js +0 -356
@@ -0,0 +1,154 @@
1
+ import { fetchCompletion } from '../../services/llmService.js';
2
+ function parseJSON(text) {
3
+ try {
4
+ return JSON.parse(text);
5
+ }
6
+ catch { /* continue */ }
7
+ const fenceMatch = text.match(/```(?:json)?\s*([\s\S]*?)```/);
8
+ if (fenceMatch) {
9
+ try {
10
+ return JSON.parse(fenceMatch[1].trim());
11
+ }
12
+ catch { /* continue */ }
13
+ }
14
+ const braceMatch = text.match(/\{[\s\S]*\}/);
15
+ if (braceMatch) {
16
+ try {
17
+ return JSON.parse(braceMatch[0]);
18
+ }
19
+ catch { /* continue */ }
20
+ }
21
+ return null;
22
+ }
23
+ /**
24
+ * Signal-based heuristic scoring for workflow patterns.
25
+ * Returns a pre-scored suggestion that the LLM can refine.
26
+ */
27
+ function scorePatterns(parsed, research) {
28
+ const input = [
29
+ parsed.role,
30
+ parsed.domain,
31
+ ...parsed.success_criteria,
32
+ ...parsed.output_expectations,
33
+ ...parsed.constraints,
34
+ ].join(' ').toLowerCase();
35
+ const scores = {
36
+ prompt_chaining: 0,
37
+ routing: 0,
38
+ parallelization: 0,
39
+ orchestrator_workers: 0,
40
+ evaluator_optimizer: 0,
41
+ hybrid: 0,
42
+ };
43
+ // Prompt chaining signals
44
+ if (input.match(/step.?by.?step|first.*then.*finally|sequential|pipeline|extract.*then.*prioritize/))
45
+ scores.prompt_chaining += 3;
46
+ if (research.expert_frameworks.length >= 2)
47
+ scores.prompt_chaining += 2; // multiple frameworks → chain them
48
+ if (parsed.output_expectations.length >= 2)
49
+ scores.prompt_chaining += 1;
50
+ // Routing signals
51
+ if (input.match(/different types? of|depending on|classify|categorize|triage/))
52
+ scores.routing += 3;
53
+ if (input.match(/route|dispatch|handle.*(differently|separately)/))
54
+ scores.routing += 2;
55
+ // Parallelization signals
56
+ if (input.match(/multiple (perspectives|angles|criteria)|cross.?reference|simultaneously/))
57
+ scores.parallelization += 3;
58
+ if (input.match(/evaluate.*from.*angles|compare.*frameworks/))
59
+ scores.parallelization += 2;
60
+ if (research.methodology_frameworks.length >= 3)
61
+ scores.parallelization += 1;
62
+ // Orchestrator-workers signals
63
+ if (input.match(/dynamic|figure out|whatever.?is.?needed|unpredictable|complex.*multi/))
64
+ scores.orchestrator_workers += 3;
65
+ if (input.match(/break.*down|delegate|coordinate/))
66
+ scores.orchestrator_workers += 2;
67
+ // Evaluator-optimizer signals
68
+ if (input.match(/iterate|refine|polish|high.?quality|draft.*review|critique/))
69
+ scores.evaluator_optimizer += 3;
70
+ if (input.match(/improve|feedback.?loop|revise/))
71
+ scores.evaluator_optimizer += 2;
72
+ // Hybrid: if multiple patterns score high
73
+ const topScores = Object.values(scores).sort((a, b) => b - a);
74
+ if (topScores[0] > 0 && topScores[1] > 0 && topScores[1] >= topScores[0] * 0.6) {
75
+ scores.hybrid = topScores[0] + 1;
76
+ }
77
+ // Default to prompt_chaining if nothing stands out (safest pattern)
78
+ if (Object.values(scores).every(s => s === 0)) {
79
+ scores.prompt_chaining = 1;
80
+ }
81
+ return scores;
82
+ }
83
+ const PATTERN_SYSTEM_PROMPT = `You select the optimal agentic workflow pattern for an AI agent based on Anthropic's taxonomy.
84
+
85
+ Patterns:
86
+ - prompt_chaining: Fixed sequential steps, each output feeds next. Quality gates between steps.
87
+ - routing: Input classification → specialized handling. Different input types need different processes.
88
+ - parallelization: Independent subtasks run simultaneously, or multiple perspectives aggregated.
89
+ - orchestrator_workers: Central LLM dynamically breaks down tasks and delegates to workers.
90
+ - evaluator_optimizer: Generate → critique → refine loop. Iterative quality improvement.
91
+ - hybrid: Combination of patterns (specify which).
92
+
93
+ Return ONLY a JSON object:
94
+ {
95
+ "pattern": "<pattern_name>",
96
+ "justification": "<one sentence explaining why>",
97
+ "suggested_steps": ["<high-level step 1>", "<step 2>", ...]
98
+ }
99
+
100
+ Base your selection on the task shape, not on what sounds impressive. Most tasks are prompt_chaining. Only use complex patterns when the task genuinely requires them.`;
101
+ export async function runPatternSelector(parsed, research, llmConfig) {
102
+ const scores = scorePatterns(parsed, research);
103
+ const topPattern = Object.entries(scores).sort(([, a], [, b]) => b - a)[0][0];
104
+ const frameworksList = [
105
+ ...research.expert_frameworks.map(f => `${f.expert_name}: ${f.framework_name} (${f.steps.length} steps)`),
106
+ ...research.methodology_frameworks.map(f => `${f.name}: ${f.purpose}`),
107
+ ].join('\n');
108
+ const text = await fetchCompletion({
109
+ providerId: llmConfig.providerId,
110
+ model: llmConfig.model,
111
+ messages: [
112
+ { role: 'system', content: PATTERN_SYSTEM_PROMPT },
113
+ {
114
+ role: 'user',
115
+ content: `Role: ${parsed.role}
116
+ Domain: ${parsed.domain}
117
+ Success criteria: ${parsed.success_criteria.join(', ')}
118
+ Output expectations: ${parsed.output_expectations.join(', ')}
119
+ Constraints: ${parsed.constraints.join(', ')}
120
+
121
+ Frameworks to incorporate:
122
+ ${frameworksList}
123
+
124
+ Heuristic suggestion: ${topPattern} (score: ${scores[topPattern]})
125
+ All scores: ${JSON.stringify(scores)}
126
+
127
+ Select the best pattern and explain why.`,
128
+ },
129
+ ],
130
+ temperature: 0.2,
131
+ maxTokens: 1024,
132
+ });
133
+ const result = parseJSON(text);
134
+ if (!result || !result.pattern) {
135
+ // Fallback to heuristic
136
+ return {
137
+ pattern: topPattern,
138
+ justification: `Selected based on heuristic scoring. Top signal: ${topPattern} (score ${scores[topPattern]}).`,
139
+ suggested_steps: [
140
+ 'Extract and classify input data',
141
+ ...research.expert_frameworks.map(f => `Apply ${f.framework_name}`),
142
+ ...research.methodology_frameworks.slice(0, 3).map(f => `Apply ${f.name}`),
143
+ 'Self-check and validate output',
144
+ ],
145
+ };
146
+ }
147
+ const validPatterns = ['prompt_chaining', 'routing', 'parallelization', 'orchestrator_workers', 'evaluator_optimizer', 'hybrid'];
148
+ const pattern = validPatterns.includes(result.pattern) ? result.pattern : topPattern;
149
+ return {
150
+ pattern,
151
+ justification: result.justification ?? `Selected ${pattern} based on task analysis.`,
152
+ suggested_steps: result.suggested_steps ?? [],
153
+ };
154
+ }
@@ -0,0 +1,3 @@
1
+ import type { LLMCallConfig, ParsedInput, ResearchResult } from './types.js';
2
+ export declare function runResearcher(parsed: ParsedInput, llmConfig: LLMCallConfig): Promise<ResearchResult>;
3
+ //# sourceMappingURL=researcher.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"researcher.d.ts","sourceRoot":"","sources":["../../../../src/metaprompt/v2/researcher.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,WAAW,EAAE,cAAc,EAA6D,MAAM,YAAY,CAAC;AAmLxI,wBAAsB,aAAa,CACjC,MAAM,EAAE,WAAW,EACnB,SAAS,EAAE,aAAa,GACvB,OAAO,CAAC,cAAc,CAAC,CAkCzB"}
@@ -0,0 +1,194 @@
1
+ import { fetchCompletion } from '../../services/llmService.js';
2
+ function parseJSON(text) {
3
+ try {
4
+ return JSON.parse(text);
5
+ }
6
+ catch { /* continue */ }
7
+ const fenceMatch = text.match(/```(?:json)?\s*([\s\S]*?)```/);
8
+ if (fenceMatch) {
9
+ try {
10
+ return JSON.parse(fenceMatch[1].trim());
11
+ }
12
+ catch { /* continue */ }
13
+ }
14
+ const braceMatch = text.match(/\{[\s\S]*\}/);
15
+ if (braceMatch) {
16
+ try {
17
+ return JSON.parse(braceMatch[0]);
18
+ }
19
+ catch { /* continue */ }
20
+ }
21
+ return null;
22
+ }
23
+ /**
24
+ * Search the web using the Agent SDK's built-in WebSearch tool.
25
+ * Falls back to null if the server isn't available.
26
+ */
27
+ async function searchWeb(query) {
28
+ try {
29
+ const { fetchAgentSdkCompletion } = await import('../../services/llmService.js');
30
+ const result = await fetchAgentSdkCompletion({
31
+ prompt: `Search the web for: "${query}". Return ONLY the key findings as a concise summary (max 500 words). Focus on framework steps, methodology mechanics, scoring criteria.`,
32
+ maxTurns: 3,
33
+ });
34
+ return result && result.length > 20 ? result : null;
35
+ }
36
+ catch {
37
+ return null;
38
+ }
39
+ }
40
+ const EXPERT_SYSTEM_PROMPT = `You are a research analyst. Given a person's name and domain context, decompose their framework into executable steps.
41
+
42
+ Return ONLY a JSON object with this structure:
43
+ {
44
+ "expert_name": "...",
45
+ "framework_name": "...",
46
+ "core_concept": "...",
47
+ "steps": [
48
+ {
49
+ "step": "Step name",
50
+ "input": "What data goes in",
51
+ "process": "Exact procedure with specific criteria",
52
+ "output": "Named artifact with defined format"
53
+ }
54
+ ],
55
+ "decision_rules": ["If X then Y", "Override: when Z..."],
56
+ "artifacts": ["Artifact 1", "Artifact 2"],
57
+ "research_confidence": "high|medium|low",
58
+ "research_note": "Optional note if confidence < high"
59
+ }
60
+
61
+ CRITICAL:
62
+ - Steps must have SPECIFIC inputs/outputs/procedures — not "apply best practices"
63
+ - If you cannot find a canonical framework for this person, set confidence to "low" and explain in research_note
64
+ - Do NOT invent frameworks. If unknown, say so.`;
65
+ const METHODOLOGY_SYSTEM_PROMPT = `You are a research analyst. Given a methodology/framework name, decompose it into executable mechanics.
66
+
67
+ Return ONLY a JSON object with this structure:
68
+ {
69
+ "name": "...",
70
+ "purpose": "...",
71
+ "mechanics": {
72
+ "inputs": ["input1", "input2"],
73
+ "formula": "optional formula string",
74
+ "scoring": {
75
+ "dimension": { "description": "...", "scale": "..." }
76
+ },
77
+ "output": "Specific artifact",
78
+ "decision_rules": ["Rule 1", "Rule 2"]
79
+ },
80
+ "research_confidence": "high|medium|low",
81
+ "research_note": "Optional"
82
+ }
83
+
84
+ CRITICAL: Include exact scoring scales, formulas, and decision thresholds where they exist.`;
85
+ async function resolveExpert(expertName, domain, llmConfig, searchContext) {
86
+ const contextSection = searchContext ? `\n\nSearch context found:\n${searchContext}` : '\n\n(No web search available — use training knowledge, flag confidence accordingly)';
87
+ const text = await fetchCompletion({
88
+ providerId: llmConfig.providerId,
89
+ model: llmConfig.model,
90
+ messages: [
91
+ { role: 'system', content: EXPERT_SYSTEM_PROMPT },
92
+ { role: 'user', content: `Expert: ${expertName}\nDomain context: ${domain}${contextSection}` },
93
+ ],
94
+ temperature: 0.2,
95
+ maxTokens: 2048,
96
+ });
97
+ const parsed = parseJSON(text);
98
+ if (!parsed) {
99
+ return {
100
+ expert_name: expertName,
101
+ framework_name: `${expertName} (unresolved)`,
102
+ core_concept: '',
103
+ steps: [],
104
+ decision_rules: [],
105
+ artifacts: [],
106
+ research_confidence: 'low',
107
+ research_note: `\u26a0\ufe0f Could not parse research result for ${expertName}. Included as expertise reference only.`,
108
+ };
109
+ }
110
+ return {
111
+ expert_name: parsed.expert_name ?? expertName,
112
+ framework_name: parsed.framework_name ?? `${expertName} framework`,
113
+ core_concept: parsed.core_concept ?? '',
114
+ steps: parsed.steps ?? [],
115
+ decision_rules: parsed.decision_rules ?? [],
116
+ artifacts: parsed.artifacts ?? [],
117
+ research_confidence: parsed.research_confidence ?? 'medium',
118
+ research_note: parsed.research_note,
119
+ };
120
+ }
121
+ async function resolveMethodology(methodologyName, llmConfig, searchContext) {
122
+ const contextSection = searchContext ? `\n\nSearch context found:\n${searchContext}` : '\n\n(No web search available — use training knowledge, flag confidence accordingly)';
123
+ const text = await fetchCompletion({
124
+ providerId: llmConfig.providerId,
125
+ model: llmConfig.model,
126
+ messages: [
127
+ { role: 'system', content: METHODOLOGY_SYSTEM_PROMPT },
128
+ { role: 'user', content: `Methodology: ${methodologyName}${contextSection}` },
129
+ ],
130
+ temperature: 0.2,
131
+ maxTokens: 2048,
132
+ });
133
+ const parsed = parseJSON(text);
134
+ if (!parsed) {
135
+ return {
136
+ name: methodologyName,
137
+ purpose: '',
138
+ mechanics: { inputs: [], output: '', decision_rules: [] },
139
+ research_confidence: 'low',
140
+ research_note: `\u26a0\ufe0f Could not parse research result for ${methodologyName}.`,
141
+ };
142
+ }
143
+ return {
144
+ name: parsed.name ?? methodologyName,
145
+ purpose: parsed.purpose ?? '',
146
+ mechanics: parsed.mechanics ?? { inputs: [], output: '', decision_rules: [] },
147
+ research_confidence: parsed.research_confidence ?? 'medium',
148
+ research_note: parsed.research_note,
149
+ };
150
+ }
151
+ function detectConflicts(methodologies) {
152
+ const conflicts = [];
153
+ // Simple heuristic: check for overlapping purposes
154
+ const prioritizationFrameworks = methodologies.filter(m => m.purpose.toLowerCase().includes('prioriti') || m.name.match(/RICE|ICE|MoSCoW|Kano/i));
155
+ if (prioritizationFrameworks.length > 1) {
156
+ conflicts.push({
157
+ concern: 'feature prioritization',
158
+ frameworks: prioritizationFrameworks.map(f => f.name),
159
+ resolution: `Use ${prioritizationFrameworks[0].name} as primary. Others can serve as cross-checks or quick validation.`,
160
+ });
161
+ }
162
+ return conflicts;
163
+ }
164
+ export async function runResearcher(parsed, llmConfig) {
165
+ const research_notes = [];
166
+ // Try web search for each reference (graceful fallback if unavailable)
167
+ const expertFrameworks = [];
168
+ for (const expert of parsed.named_experts) {
169
+ const searchContext = await searchWeb(`${expert} framework methodology core steps`);
170
+ if (!searchContext) {
171
+ research_notes.push(`\u26a0\ufe0f Web search unavailable for ${expert}. Using training knowledge. Verify framework accuracy.`);
172
+ }
173
+ const framework = await resolveExpert(expert, parsed.domain, llmConfig, searchContext);
174
+ expertFrameworks.push(framework);
175
+ }
176
+ const methodologyFrameworks = [];
177
+ const allMethodologies = [...parsed.named_methodologies, ...parsed.implied_methodologies];
178
+ for (const methodology of allMethodologies) {
179
+ const searchContext = await searchWeb(`${methodology} framework scoring criteria steps`);
180
+ const framework = await resolveMethodology(methodology, llmConfig, searchContext);
181
+ if (parsed.implied_methodologies.includes(methodology) && !parsed.named_methodologies.includes(methodology)) {
182
+ framework.research_note = (framework.research_note ? framework.research_note + ' ' : '') +
183
+ `(inferred — confirm with user if critical)`;
184
+ }
185
+ methodologyFrameworks.push(framework);
186
+ }
187
+ const conflicts = detectConflicts(methodologyFrameworks);
188
+ return {
189
+ expert_frameworks: expertFrameworks,
190
+ methodology_frameworks: methodologyFrameworks,
191
+ conflicts,
192
+ research_notes,
193
+ };
194
+ }
@@ -0,0 +1,74 @@
1
+ /**
2
+ * Tool Discovery — suggests MCP servers, connectors, and skills
3
+ * based on the parsed metaprompt V2 input.
4
+ *
5
+ * MCP + connector matching is synchronous (in-memory).
6
+ * Skills discovery is async best-effort via skills.sh.
7
+ *
8
+ * Discovery strategy (in priority order):
9
+ * 1. Semantic table lookup — 26 curated intent→MCP mappings (score 1.0).
10
+ * 2. Fuzzy registry scan — ALL MCP_REGISTRY entries matched by name/description/tags.
11
+ * New entries added to the registry are discovered automatically here (score 0.5–0.9).
12
+ * 3. Native connectors — preferred over MCP when the same service has both.
13
+ * 4. Skills catalog — async fetch from skills.sh, best-effort, 10s timeout.
14
+ *
15
+ * Results are capped: 3 MCP + 2 connectors + 3 skills, sorted by relevance.
16
+ */
17
+ import type { ParsedInput } from './types.js';
18
+ export type ToolSource = 'skill' | 'mcp' | 'connector';
19
+ export interface DiscoveredTool {
20
+ id: string;
21
+ name: string;
22
+ description: string;
23
+ source: ToolSource;
24
+ matchReason: string;
25
+ matchTerm: string;
26
+ relevanceScore: number;
27
+ npmPackage?: string;
28
+ tags?: string[];
29
+ category?: string;
30
+ configFields?: Array<{
31
+ key: string;
32
+ label: string;
33
+ type: string;
34
+ required?: boolean;
35
+ }>;
36
+ owner?: string;
37
+ repo?: string;
38
+ url?: string;
39
+ installCmd?: string;
40
+ installs?: string;
41
+ service?: string;
42
+ authMethod?: string;
43
+ }
44
+ /**
45
+ * Discover MCP servers relevant to the parsed agent input.
46
+ * Runs semantic table lookup first, then fuzzy-matches all registry entries.
47
+ * @param parsed - Parsed metaprompt V2 input with tools, domain, and role.
48
+ * @param enabledMcpIds - Already-enabled MCP server IDs (excluded from suggestions).
49
+ * @returns Suggested MCP tools sorted by relevance, descending.
50
+ */
51
+ export declare function discoverMcpServers(parsed: ParsedInput, enabledMcpIds: string[]): DiscoveredTool[];
52
+ /**
53
+ * Discover native connectors (Notion, HubSpot, Slack, …) relevant to the parsed input.
54
+ * Prefers connectors over MCP when both cover the same service.
55
+ * @param parsed - Parsed metaprompt V2 input.
56
+ * @param enabledConnectorIds - Already-enabled connector IDs (excluded from suggestions).
57
+ * @returns Suggested connector tools at relevance 1.0.
58
+ */
59
+ export declare function discoverConnectors(parsed: ParsedInput, enabledConnectorIds: string[]): DiscoveredTool[];
60
+ export declare function discoverSkills(parsed: ParsedInput, installedSkillIds: string[], signal?: AbortSignal): Promise<DiscoveredTool[]>;
61
+ /**
62
+ * Discover all relevant tools (MCP + connectors + skills) for the parsed agent input.
63
+ * MCP and connector discovery is synchronous; skills discovery is async best-effort.
64
+ * @param parsed - Parsed metaprompt V2 input.
65
+ * @param installed - IDs of already-installed tools (excluded from suggestions).
66
+ * @param signal - Optional abort signal for the skills.sh network request.
67
+ * @returns Up to 8 tool suggestions (3 MCP + 2 connectors + 3 skills), sorted by relevance.
68
+ */
69
+ export declare function discoverTools(parsed: ParsedInput, installed: {
70
+ skillIds: string[];
71
+ mcpIds: string[];
72
+ connectorIds: string[];
73
+ }, signal?: AbortSignal): Promise<DiscoveredTool[]>;
74
+ //# sourceMappingURL=tool-discovery.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tool-discovery.d.ts","sourceRoot":"","sources":["../../../../src/metaprompt/v2/tool-discovery.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAIH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE9C,MAAM,MAAM,UAAU,GAAG,OAAO,GAAG,KAAK,GAAG,WAAW,CAAC;AAEvD,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,UAAU,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC;IAEvB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,KAAK,CAAC;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;IAEvF,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AA+FD;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,WAAW,EACnB,aAAa,EAAE,MAAM,EAAE,GACtB,cAAc,EAAE,CA0BlB;AAID;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,WAAW,EACnB,mBAAmB,EAAE,MAAM,EAAE,GAC5B,cAAc,EAAE,CAwBlB;AA6CD,wBAAsB,cAAc,CAClC,MAAM,EAAE,WAAW,EACnB,iBAAiB,EAAE,MAAM,EAAE,EAC3B,MAAM,CAAC,EAAE,WAAW,GACnB,OAAO,CAAC,cAAc,EAAE,CAAC,CA0D3B;AAID;;;;;;;GAOG;AACH,wBAAsB,aAAa,CACjC,MAAM,EAAE,WAAW,EACnB,SAAS,EAAE;IAAE,QAAQ,EAAE,MAAM,EAAE,CAAC;IAAC,MAAM,EAAE,MAAM,EAAE,CAAC;IAAC,YAAY,EAAE,MAAM,EAAE,CAAA;CAAE,EAC3E,MAAM,CAAC,EAAE,WAAW,GACnB,OAAO,CAAC,cAAc,EAAE,CAAC,CA4B3B"}