modular-studio 1.0.5 → 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.
- package/README.md +122 -122
- package/dist/assets/Badge-Bsy2H_p2.js +1 -0
- package/dist/assets/GraphPanel-D4X3faxA.js +47 -0
- package/dist/assets/{Input-Bgp734xs.js → Input-Dyb88Erk.js} +1 -1
- package/dist/assets/KnowledgeTab-BccWz7Np.js +5 -0
- package/dist/assets/MemoryTab-Y_66cE01.js +16 -0
- package/dist/assets/QualificationTab-Dm9dEIpM.js +1 -0
- package/dist/assets/ReviewTab-BrfXSyyf.js +104 -0
- package/dist/assets/{Section-DoJrmytO.js → Section-68XDCFTl.js} +1 -1
- package/dist/assets/TestTab-CLKRT63X.js +42 -0
- package/dist/assets/ToolsTab-xumi9Uds.js +1 -0
- package/dist/assets/icons-CS8RUPBi.js +1 -0
- package/dist/assets/index-B2bm0161.css +1 -0
- package/dist/assets/index-C626nWuA.js +422 -0
- package/dist/assets/services-BDk6yY4o.js +369 -0
- package/dist/index.html +18 -18
- package/dist-server/bin/modular-mcp.js +1 -0
- package/dist-server/server/index.d.ts.map +1 -1
- package/dist-server/server/index.js +34 -0
- package/dist-server/server/mcp/manager.d.ts +3 -0
- package/dist-server/server/mcp/manager.d.ts.map +1 -1
- package/dist-server/server/mcp/manager.js +80 -5
- package/dist-server/server/migrations/index.d.ts +11 -0
- package/dist-server/server/migrations/index.d.ts.map +1 -0
- package/dist-server/server/migrations/index.js +57 -0
- package/dist-server/server/routes/agents.d.ts.map +1 -1
- package/dist-server/server/routes/agents.js +27 -0
- package/dist-server/server/routes/analytics.d.ts +3 -0
- package/dist-server/server/routes/analytics.d.ts.map +1 -0
- package/dist-server/server/routes/analytics.js +24 -0
- package/dist-server/server/routes/cache.d.ts +3 -0
- package/dist-server/server/routes/cache.d.ts.map +1 -0
- package/dist-server/server/routes/cache.js +55 -0
- package/dist-server/server/routes/connectors/airtable.d.ts +7 -0
- package/dist-server/server/routes/connectors/airtable.d.ts.map +1 -0
- package/dist-server/server/routes/connectors/airtable.js +119 -0
- package/dist-server/server/routes/connectors/confluence.d.ts +7 -0
- package/dist-server/server/routes/connectors/confluence.d.ts.map +1 -0
- package/dist-server/server/routes/connectors/confluence.js +176 -0
- package/dist-server/server/routes/connectors/github.d.ts +7 -0
- package/dist-server/server/routes/connectors/github.d.ts.map +1 -0
- package/dist-server/server/routes/connectors/github.js +195 -0
- package/dist-server/server/routes/connectors/gmail.d.ts +7 -0
- package/dist-server/server/routes/connectors/gmail.d.ts.map +1 -0
- package/dist-server/server/routes/connectors/gmail.js +115 -0
- package/dist-server/server/routes/connectors/google-docs.d.ts +10 -0
- package/dist-server/server/routes/connectors/google-docs.d.ts.map +1 -0
- package/dist-server/server/routes/connectors/google-docs.js +165 -0
- package/dist-server/server/routes/connectors/google-drive.d.ts +7 -0
- package/dist-server/server/routes/connectors/google-drive.d.ts.map +1 -0
- package/dist-server/server/routes/connectors/google-drive.js +163 -0
- package/dist-server/server/routes/connectors/google-sheets.d.ts +7 -0
- package/dist-server/server/routes/connectors/google-sheets.d.ts.map +1 -0
- package/dist-server/server/routes/connectors/google-sheets.js +90 -0
- package/dist-server/server/routes/connectors/hubspot.d.ts +7 -0
- package/dist-server/server/routes/connectors/hubspot.d.ts.map +1 -0
- package/dist-server/server/routes/connectors/hubspot.js +134 -0
- package/dist-server/server/routes/connectors/index.d.ts +6 -0
- package/dist-server/server/routes/connectors/index.d.ts.map +1 -0
- package/dist-server/server/routes/connectors/index.js +38 -0
- package/dist-server/server/routes/connectors/jira.d.ts +7 -0
- package/dist-server/server/routes/connectors/jira.d.ts.map +1 -0
- package/dist-server/server/routes/connectors/jira.js +151 -0
- package/dist-server/server/routes/connectors/linear.d.ts +7 -0
- package/dist-server/server/routes/connectors/linear.d.ts.map +1 -0
- package/dist-server/server/routes/connectors/linear.js +154 -0
- package/dist-server/server/routes/connectors/notion.d.ts +10 -0
- package/dist-server/server/routes/connectors/notion.d.ts.map +1 -0
- package/dist-server/server/routes/connectors/notion.js +201 -0
- package/dist-server/server/routes/connectors/plane.d.ts +10 -0
- package/dist-server/server/routes/connectors/plane.d.ts.map +1 -0
- package/dist-server/server/routes/connectors/plane.js +189 -0
- package/dist-server/server/routes/connectors/shared.d.ts +25 -0
- package/dist-server/server/routes/connectors/shared.d.ts.map +1 -0
- package/dist-server/server/routes/connectors/shared.js +202 -0
- package/dist-server/server/routes/connectors/slack.d.ts +7 -0
- package/dist-server/server/routes/connectors/slack.d.ts.map +1 -0
- package/dist-server/server/routes/connectors/slack.js +153 -0
- package/dist-server/server/routes/connectors.d.ts.map +1 -1
- package/dist-server/server/routes/connectors.js +47 -17
- package/dist-server/server/routes/cost.d.ts +3 -0
- package/dist-server/server/routes/cost.d.ts.map +1 -0
- package/dist-server/server/routes/cost.js +113 -0
- package/dist-server/server/routes/graph.d.ts +11 -0
- package/dist-server/server/routes/graph.d.ts.map +1 -0
- package/dist-server/server/routes/graph.js +213 -0
- package/dist-server/server/routes/lessons.d.ts +3 -0
- package/dist-server/server/routes/lessons.d.ts.map +1 -0
- package/dist-server/server/routes/lessons.js +160 -0
- package/dist-server/server/routes/llm.d.ts.map +1 -1
- package/dist-server/server/routes/llm.js +85 -18
- package/dist-server/server/routes/memory.d.ts.map +1 -1
- package/dist-server/server/routes/memory.js +31 -0
- package/dist-server/server/routes/metaprompt-v2.d.ts +3 -0
- package/dist-server/server/routes/metaprompt-v2.d.ts.map +1 -0
- package/dist-server/server/routes/metaprompt-v2.js +104 -0
- package/dist-server/server/routes/qualification.d.ts.map +1 -1
- package/dist-server/server/routes/qualification.js +342 -334
- package/dist-server/server/routes/repo-index.d.ts.map +1 -1
- package/dist-server/server/routes/repo-index.js +7 -0
- package/dist-server/server/routes/skills-search.d.ts.map +1 -1
- package/dist-server/server/routes/skills-search.js +192 -26
- package/dist-server/server/routes/tool-analytics.d.ts +3 -0
- package/dist-server/server/routes/tool-analytics.d.ts.map +1 -0
- package/dist-server/server/routes/tool-analytics.js +47 -0
- package/dist-server/server/services/adapters/hindsightAdapter.d.ts +28 -0
- package/dist-server/server/services/adapters/hindsightAdapter.d.ts.map +1 -0
- package/dist-server/server/services/adapters/hindsightAdapter.js +63 -0
- package/dist-server/server/services/adapters/postgresAdapter.js +30 -30
- package/dist-server/server/services/adapters/sqliteAdapter.d.ts +1 -0
- package/dist-server/server/services/adapters/sqliteAdapter.d.ts.map +1 -1
- package/dist-server/server/services/adapters/sqliteAdapter.js +66 -36
- package/dist-server/server/services/agentStore.d.ts +2 -1
- package/dist-server/server/services/agentStore.d.ts.map +1 -1
- package/dist-server/server/services/agentStore.js +2 -1
- package/dist-server/server/services/correctionDetector.d.ts +22 -0
- package/dist-server/server/services/correctionDetector.d.ts.map +1 -0
- package/dist-server/server/services/correctionDetector.js +91 -0
- package/dist-server/server/services/credentialStore.d.ts +10 -0
- package/dist-server/server/services/credentialStore.d.ts.map +1 -0
- package/dist-server/server/services/credentialStore.js +123 -0
- package/dist-server/server/services/hindsightClient.d.ts +15 -0
- package/dist-server/server/services/hindsightClient.d.ts.map +1 -0
- package/dist-server/server/services/hindsightClient.js +48 -0
- package/dist-server/server/services/lessonExtractor.d.ts +21 -0
- package/dist-server/server/services/lessonExtractor.d.ts.map +1 -0
- package/dist-server/server/services/lessonExtractor.js +92 -0
- package/dist-server/server/services/repoIndexer.d.ts +7 -1
- package/dist-server/server/services/repoIndexer.d.ts.map +1 -1
- package/dist-server/server/services/repoIndexer.js +295 -94
- package/dist-server/server/services/responseCache.d.ts +24 -0
- package/dist-server/server/services/responseCache.d.ts.map +1 -0
- package/dist-server/server/services/responseCache.js +163 -0
- package/dist-server/server/services/sqliteStore.d.ts +72 -0
- package/dist-server/server/services/sqliteStore.d.ts.map +1 -1
- package/dist-server/server/services/sqliteStore.js +291 -13
- package/dist-server/src/config.d.ts +2 -0
- package/dist-server/src/config.d.ts.map +1 -0
- package/dist-server/src/config.js +3 -0
- package/dist-server/src/graph/db.d.ts +46 -0
- package/dist-server/src/graph/db.d.ts.map +1 -0
- package/dist-server/src/graph/db.js +241 -0
- package/dist-server/src/graph/extractors/code.d.ts +12 -0
- package/dist-server/src/graph/extractors/code.d.ts.map +1 -0
- package/dist-server/src/graph/extractors/code.js +239 -0
- package/dist-server/src/graph/extractors/cross-type.d.ts +16 -0
- package/dist-server/src/graph/extractors/cross-type.d.ts.map +1 -0
- package/dist-server/src/graph/extractors/cross-type.js +67 -0
- package/dist-server/src/graph/extractors/markdown.d.ts +29 -0
- package/dist-server/src/graph/extractors/markdown.d.ts.map +1 -0
- package/dist-server/src/graph/extractors/markdown.js +224 -0
- package/dist-server/src/graph/extractors/yaml.d.ts +15 -0
- package/dist-server/src/graph/extractors/yaml.d.ts.map +1 -0
- package/dist-server/src/graph/extractors/yaml.js +104 -0
- package/dist-server/src/graph/index.d.ts +62 -0
- package/dist-server/src/graph/index.d.ts.map +1 -0
- package/dist-server/src/graph/index.js +67 -0
- package/dist-server/src/graph/packer.d.ts +19 -0
- package/dist-server/src/graph/packer.d.ts.map +1 -0
- package/dist-server/src/graph/packer.js +134 -0
- package/dist-server/src/graph/resolver.d.ts +12 -0
- package/dist-server/src/graph/resolver.d.ts.map +1 -0
- package/dist-server/src/graph/resolver.js +81 -0
- package/dist-server/src/graph/scanner.d.ts +34 -0
- package/dist-server/src/graph/scanner.d.ts.map +1 -0
- package/dist-server/src/graph/scanner.js +252 -0
- package/dist-server/src/graph/traverser.d.ts +17 -0
- package/dist-server/src/graph/traverser.d.ts.map +1 -0
- package/dist-server/src/graph/traverser.js +185 -0
- package/dist-server/src/graph/types.d.ts +117 -0
- package/dist-server/src/graph/types.d.ts.map +1 -0
- package/dist-server/src/graph/types.js +63 -0
- package/dist-server/src/metaprompt/v2/assembler.d.ts +3 -0
- package/dist-server/src/metaprompt/v2/assembler.d.ts.map +1 -0
- package/dist-server/src/metaprompt/v2/assembler.js +261 -0
- package/dist-server/src/metaprompt/v2/context-strategist.d.ts +3 -0
- package/dist-server/src/metaprompt/v2/context-strategist.d.ts.map +1 -0
- package/dist-server/src/metaprompt/v2/context-strategist.js +173 -0
- package/dist-server/src/metaprompt/v2/evaluator.d.ts +3 -0
- package/dist-server/src/metaprompt/v2/evaluator.d.ts.map +1 -0
- package/dist-server/src/metaprompt/v2/evaluator.js +281 -0
- package/dist-server/src/metaprompt/v2/index.d.ts +41 -0
- package/dist-server/src/metaprompt/v2/index.d.ts.map +1 -0
- package/dist-server/src/metaprompt/v2/index.js +90 -0
- package/dist-server/src/metaprompt/v2/parser.d.ts +3 -0
- package/dist-server/src/metaprompt/v2/parser.d.ts.map +1 -0
- package/dist-server/src/metaprompt/v2/parser.js +138 -0
- package/dist-server/src/metaprompt/v2/pattern-selector.d.ts +3 -0
- package/dist-server/src/metaprompt/v2/pattern-selector.d.ts.map +1 -0
- package/dist-server/src/metaprompt/v2/pattern-selector.js +154 -0
- package/dist-server/src/metaprompt/v2/researcher.d.ts +3 -0
- package/dist-server/src/metaprompt/v2/researcher.d.ts.map +1 -0
- package/dist-server/src/metaprompt/v2/researcher.js +194 -0
- package/dist-server/src/metaprompt/v2/tool-discovery.d.ts +74 -0
- package/dist-server/src/metaprompt/v2/tool-discovery.d.ts.map +1 -0
- package/dist-server/src/metaprompt/v2/tool-discovery.js +290 -0
- package/dist-server/src/metaprompt/v2/types.d.ts +154 -0
- package/dist-server/src/metaprompt/v2/types.d.ts.map +1 -0
- package/dist-server/src/metaprompt/v2/types.js +2 -0
- package/dist-server/src/services/contradictionDetector.js +1 -1
- package/dist-server/src/services/llmService.d.ts +61 -0
- package/dist-server/src/services/llmService.d.ts.map +1 -0
- package/dist-server/src/services/llmService.js +222 -0
- package/dist-server/src/store/knowledgeBase.d.ts +6 -1
- package/dist-server/src/store/knowledgeBase.d.ts.map +1 -1
- package/dist-server/src/store/knowledgeBase.js +0 -1
- package/dist-server/src/store/lessonStore.d.ts +26 -0
- package/dist-server/src/store/lessonStore.d.ts.map +1 -0
- package/dist-server/src/store/lessonStore.js +64 -0
- package/dist-server/src/store/mcp-registry.d.ts +29 -0
- package/dist-server/src/store/mcp-registry.d.ts.map +1 -0
- package/dist-server/src/store/mcp-registry.js +1303 -0
- package/dist-server/src/store/memoryStore.d.ts +12 -1
- package/dist-server/src/store/memoryStore.d.ts.map +1 -1
- package/dist-server/src/store/memoryStore.js +9 -0
- package/dist-server/src/types/registry.types.d.ts +13 -0
- package/dist-server/src/types/registry.types.d.ts.map +1 -0
- package/dist-server/src/types/registry.types.js +2 -0
- package/dist-server/tsconfig.server.tsbuildinfo +1 -1
- package/package.json +15 -1
- package/scripts/cleanup-worktrees.ps1 +29 -0
- package/dist/assets/Badge-22Ai0eyi.js +0 -1
- package/dist/assets/KnowledgeTab-DABxirZh.js +0 -4
- package/dist/assets/MemoryTab-DZeYElIT.js +0 -16
- package/dist/assets/QualificationTab-Dfpy3J30.js +0 -1
- package/dist/assets/ReviewTab-SD8lQuCc.js +0 -103
- package/dist/assets/TestTab-PDyMF8Fw.js +0 -33
- package/dist/assets/ToolsTab-B83qGCmG.js +0 -1
- package/dist/assets/icons-C2EV-le6.js +0 -1
- package/dist/assets/index-DkpMAxX7.css +0 -1
- package/dist/assets/index-q24ug5Qs.js +0 -143
- package/dist/assets/services-BaKotDf0.js +0 -343
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Context Graph — Type Definitions
|
|
3
|
+
*
|
|
4
|
+
* Universal dependency graph for code, markdown, YAML, and JSON files.
|
|
5
|
+
* Tracks cross-file relations for query-driven context assembly.
|
|
6
|
+
*/
|
|
7
|
+
import type { TreeIndex } from '../services/treeIndexer.js';
|
|
8
|
+
export type FileLanguage = 'typescript' | 'python' | 'markdown' | 'yaml' | 'json' | 'unknown';
|
|
9
|
+
export type SymbolKind = 'function' | 'class' | 'interface' | 'type' | 'const' | 'enum' | 'heading' | 'anchor' | 'definition' | 'link_target' | 'tag' | 'key' | 'schema' | 'export';
|
|
10
|
+
export interface SymbolDef {
|
|
11
|
+
name: string;
|
|
12
|
+
kind: SymbolKind;
|
|
13
|
+
signature?: string;
|
|
14
|
+
lineStart: number;
|
|
15
|
+
lineEnd: number;
|
|
16
|
+
isExported: boolean;
|
|
17
|
+
treeNodeId?: string;
|
|
18
|
+
docstring?: string;
|
|
19
|
+
tokens?: number;
|
|
20
|
+
}
|
|
21
|
+
export interface FileNode {
|
|
22
|
+
id: string;
|
|
23
|
+
path: string;
|
|
24
|
+
language: FileLanguage;
|
|
25
|
+
lastModified: number;
|
|
26
|
+
contentHash: string;
|
|
27
|
+
tokens: number;
|
|
28
|
+
treeIndex?: TreeIndex;
|
|
29
|
+
symbols: SymbolDef[];
|
|
30
|
+
}
|
|
31
|
+
export type RelationKind = 'imports' | 'calls' | 'extends' | 'implements' | 'uses_type' | 'tested_by' | 'tests' | 'links_to' | 'references' | 'continues' | 'supersedes' | 'depends_on' | 'defined_in' | 'documents' | 'configured_by' | 'related';
|
|
32
|
+
export interface Relation {
|
|
33
|
+
id?: number;
|
|
34
|
+
sourceFile: string;
|
|
35
|
+
sourceSymbol?: string;
|
|
36
|
+
targetFile: string;
|
|
37
|
+
targetSymbol?: string;
|
|
38
|
+
kind: RelationKind;
|
|
39
|
+
weight: number;
|
|
40
|
+
metadata?: Record<string, string>;
|
|
41
|
+
}
|
|
42
|
+
export interface ContextGraph {
|
|
43
|
+
nodes: Map<string, FileNode>;
|
|
44
|
+
relations: Relation[];
|
|
45
|
+
outgoing: Map<string, Relation[]>;
|
|
46
|
+
incoming: Map<string, Relation[]>;
|
|
47
|
+
symbolIndex: Map<string, FileNode[]>;
|
|
48
|
+
rootPath: string;
|
|
49
|
+
lastFullScan: number;
|
|
50
|
+
version: number;
|
|
51
|
+
}
|
|
52
|
+
export interface TraversalConfig {
|
|
53
|
+
maxDepth: number;
|
|
54
|
+
maxFiles: number;
|
|
55
|
+
tokenBudget: number;
|
|
56
|
+
minWeight: number;
|
|
57
|
+
followImports: boolean;
|
|
58
|
+
followCallers: boolean;
|
|
59
|
+
followTests: boolean;
|
|
60
|
+
followDocs: boolean;
|
|
61
|
+
followLinks: boolean;
|
|
62
|
+
followReferences: boolean;
|
|
63
|
+
}
|
|
64
|
+
export interface TraversalResult {
|
|
65
|
+
files: TraversalFile[];
|
|
66
|
+
totalTokens: number;
|
|
67
|
+
graphStats: {
|
|
68
|
+
nodesTraversed: number;
|
|
69
|
+
edgesFollowed: number;
|
|
70
|
+
nodesIncluded: number;
|
|
71
|
+
nodesPruned: number;
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
export interface TraversalFile {
|
|
75
|
+
node: FileNode;
|
|
76
|
+
relevance: number;
|
|
77
|
+
distance: number;
|
|
78
|
+
reason: string;
|
|
79
|
+
includeSymbols?: string[];
|
|
80
|
+
}
|
|
81
|
+
export interface EntryPoint {
|
|
82
|
+
fileId: string;
|
|
83
|
+
symbolName?: string;
|
|
84
|
+
confidence: number;
|
|
85
|
+
reason: 'Direct mention' | 'Filename match' | 'Semantic match';
|
|
86
|
+
}
|
|
87
|
+
export interface PackedContext {
|
|
88
|
+
items: PackedItem[];
|
|
89
|
+
totalTokens: number;
|
|
90
|
+
budgetUtilization: number;
|
|
91
|
+
}
|
|
92
|
+
export interface PackedItem {
|
|
93
|
+
file: FileNode;
|
|
94
|
+
content: string;
|
|
95
|
+
depth: number;
|
|
96
|
+
tokens: number;
|
|
97
|
+
relevance: number;
|
|
98
|
+
}
|
|
99
|
+
export interface UpdateResult {
|
|
100
|
+
filesUpdated: number;
|
|
101
|
+
relationsAdded: number;
|
|
102
|
+
relationsRemoved: number;
|
|
103
|
+
staleFilesTriggered: number;
|
|
104
|
+
durationMs: number;
|
|
105
|
+
}
|
|
106
|
+
export interface ScanResult extends UpdateResult {
|
|
107
|
+
totalFiles: number;
|
|
108
|
+
totalSymbols: number;
|
|
109
|
+
totalRelations: number;
|
|
110
|
+
}
|
|
111
|
+
export type TaskType = 'fix' | 'review' | 'explain' | 'build' | 'document' | 'research';
|
|
112
|
+
export declare const TRAVERSAL_PRESETS: Record<TaskType, Partial<TraversalConfig>>;
|
|
113
|
+
/**
|
|
114
|
+
* Auto-detect task type from query keywords.
|
|
115
|
+
*/
|
|
116
|
+
export declare function detectTaskType(query: string): TaskType;
|
|
117
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/graph/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,4BAA4B,CAAC;AAI5D,MAAM,MAAM,YAAY,GAAG,YAAY,GAAG,QAAQ,GAAG,UAAU,GAAG,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;AAI9F,MAAM,MAAM,UAAU,GAElB,UAAU,GAAG,OAAO,GAAG,WAAW,GAAG,MAAM,GAAG,OAAO,GAAG,MAAM,GAE9D,SAAS,GAAG,QAAQ,GAAG,YAAY,GAAG,aAAa,GAAG,KAAK,GAE3D,KAAK,GAAG,QAAQ,GAEhB,QAAQ,CAAC;AAEb,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,UAAU,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,OAAO,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAID,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,YAAY,CAAC;IACvB,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,OAAO,EAAE,SAAS,EAAE,CAAC;CACtB;AAID,MAAM,MAAM,YAAY,GAEpB,SAAS,GAAG,OAAO,GAAG,SAAS,GAAG,YAAY,GAAG,WAAW,GAC5D,WAAW,GAAG,OAAO,GAErB,UAAU,GAAG,YAAY,GAAG,WAAW,GAAG,YAAY,GACtD,YAAY,GAAG,YAAY,GAE3B,WAAW,GAAG,eAAe,GAAG,SAAS,CAAC;AAE9C,MAAM,WAAW,QAAQ;IACvB,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,IAAI,EAAE,YAAY,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACnC;AAID,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IAC7B,SAAS,EAAE,QAAQ,EAAE,CAAC;IACtB,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,QAAQ,EAAE,CAAC,CAAC;IAClC,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,QAAQ,EAAE,CAAC,CAAC;IAClC,WAAW,EAAE,GAAG,CAAC,MAAM,EAAE,QAAQ,EAAE,CAAC,CAAC;IACrC,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;CACjB;AAID,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,OAAO,CAAC;IACvB,aAAa,EAAE,OAAO,CAAC;IACvB,WAAW,EAAE,OAAO,CAAC;IACrB,UAAU,EAAE,OAAO,CAAC;IACpB,WAAW,EAAE,OAAO,CAAC;IACrB,gBAAgB,EAAE,OAAO,CAAC;CAC3B;AAED,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,aAAa,EAAE,CAAC;IACvB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE;QACV,cAAc,EAAE,MAAM,CAAC;QACvB,aAAa,EAAE,MAAM,CAAC;QACtB,aAAa,EAAE,MAAM,CAAC;QACtB,WAAW,EAAE,MAAM,CAAC;KACrB,CAAC;CACH;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,QAAQ,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;CAC3B;AAID,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,gBAAgB,GAAG,gBAAgB,GAAG,gBAAgB,CAAC;CAChE;AAID,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,UAAU,EAAE,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,iBAAiB,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,QAAQ,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;CACnB;AAID,MAAM,WAAW,YAAY;IAC3B,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,EAAE,MAAM,CAAC;IACvB,gBAAgB,EAAE,MAAM,CAAC;IACzB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,UAAW,SAAQ,YAAY;IAC9C,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,EAAE,MAAM,CAAC;CACxB;AAID,MAAM,MAAM,QAAQ,GAAG,KAAK,GAAG,QAAQ,GAAG,SAAS,GAAG,OAAO,GAAG,UAAU,GAAG,UAAU,CAAC;AAExF,eAAO,MAAM,iBAAiB,EAAE,MAAM,CAAC,QAAQ,EAAE,OAAO,CAAC,eAAe,CAAC,CAqCxE,CAAC;AAEF;;GAEG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,QAAQ,CAStD"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Context Graph — Type Definitions
|
|
3
|
+
*
|
|
4
|
+
* Universal dependency graph for code, markdown, YAML, and JSON files.
|
|
5
|
+
* Tracks cross-file relations for query-driven context assembly.
|
|
6
|
+
*/
|
|
7
|
+
export const TRAVERSAL_PRESETS = {
|
|
8
|
+
fix: {
|
|
9
|
+
maxDepth: 3, maxFiles: 15,
|
|
10
|
+
followImports: true, followCallers: false, followTests: true,
|
|
11
|
+
followDocs: false, followLinks: false, followReferences: false,
|
|
12
|
+
minWeight: 0.4,
|
|
13
|
+
},
|
|
14
|
+
review: {
|
|
15
|
+
maxDepth: 2, maxFiles: 25,
|
|
16
|
+
followImports: true, followCallers: true, followTests: true,
|
|
17
|
+
followDocs: true, followLinks: true, followReferences: false,
|
|
18
|
+
minWeight: 0.3,
|
|
19
|
+
},
|
|
20
|
+
explain: {
|
|
21
|
+
maxDepth: 4, maxFiles: 20,
|
|
22
|
+
followImports: true, followCallers: false, followTests: false,
|
|
23
|
+
followDocs: true, followLinks: true, followReferences: true,
|
|
24
|
+
minWeight: 0.3,
|
|
25
|
+
},
|
|
26
|
+
build: {
|
|
27
|
+
maxDepth: 2, maxFiles: 15,
|
|
28
|
+
followImports: true, followCallers: false, followTests: false,
|
|
29
|
+
followDocs: true, followLinks: false, followReferences: false,
|
|
30
|
+
minWeight: 0.5,
|
|
31
|
+
},
|
|
32
|
+
document: {
|
|
33
|
+
maxDepth: 3, maxFiles: 20,
|
|
34
|
+
followImports: true, followCallers: true, followTests: true,
|
|
35
|
+
followDocs: true, followLinks: true, followReferences: true,
|
|
36
|
+
minWeight: 0.3,
|
|
37
|
+
},
|
|
38
|
+
research: {
|
|
39
|
+
maxDepth: 4, maxFiles: 30,
|
|
40
|
+
followImports: false, followCallers: false, followTests: false,
|
|
41
|
+
followDocs: true, followLinks: true, followReferences: true,
|
|
42
|
+
minWeight: 0.2,
|
|
43
|
+
},
|
|
44
|
+
};
|
|
45
|
+
/**
|
|
46
|
+
* Auto-detect task type from query keywords.
|
|
47
|
+
*/
|
|
48
|
+
export function detectTaskType(query) {
|
|
49
|
+
const q = query.toLowerCase();
|
|
50
|
+
if (/fix|bug|error|crash|broken|issue/.test(q))
|
|
51
|
+
return 'fix';
|
|
52
|
+
if (/\bresearch\b|find|look.*up|what.*about/.test(q))
|
|
53
|
+
return 'research';
|
|
54
|
+
if (/\breview\b|pr\b|pull request|diff|changes/.test(q))
|
|
55
|
+
return 'review';
|
|
56
|
+
if (/explain|how does|what is|understand|walk.*through/.test(q))
|
|
57
|
+
return 'explain';
|
|
58
|
+
if (/add|build|create|implement|feature|new/.test(q))
|
|
59
|
+
return 'build';
|
|
60
|
+
if (/document|readme|write.*doc|api.*doc/.test(q))
|
|
61
|
+
return 'document';
|
|
62
|
+
return 'explain';
|
|
63
|
+
}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import type { LLMCallConfig, ParsedInput, ResearchResult, PatternSelection, ContextStrategy, AssembledAgent } from './types.js';
|
|
2
|
+
export declare function runAssembler(parsed: ParsedInput, research: ResearchResult, pattern: PatternSelection, context: ContextStrategy, llmConfig: LLMCallConfig): Promise<AssembledAgent>;
|
|
3
|
+
//# sourceMappingURL=assembler.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"assembler.d.ts","sourceRoot":"","sources":["../../../../src/metaprompt/v2/assembler.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,aAAa,EACb,WAAW,EACX,cAAc,EACd,gBAAgB,EAChB,eAAe,EACf,cAAc,EAKf,MAAM,YAAY,CAAC;AAuGpB,wBAAsB,YAAY,CAChC,MAAM,EAAE,WAAW,EACnB,QAAQ,EAAE,cAAc,EACxB,OAAO,EAAE,gBAAgB,EACzB,OAAO,EAAE,eAAe,EACxB,SAAS,EAAE,aAAa,GACvB,OAAO,CAAC,cAAc,CAAC,CA4DzB"}
|
|
@@ -0,0 +1,261 @@
|
|
|
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
|
+
const AGENTIC_PILLARS = {
|
|
24
|
+
persistence: 'Continue working until the task is fully complete. Do not stop at an intermediate step or ask the user to continue unless you are genuinely blocked.',
|
|
25
|
+
tool_discipline: 'Use available tools to verify information. Do not guess, hallucinate, or assume data you could look up. If a tool call fails, report the failure rather than making up a result.',
|
|
26
|
+
planning: 'Before each major step, briefly state what you are about to do and why. After completing a step, reflect: did it produce what was expected? If not, adjust before proceeding.',
|
|
27
|
+
};
|
|
28
|
+
const SELF_CHECK = {
|
|
29
|
+
questions: [
|
|
30
|
+
'Does every recommendation trace to specific evidence (quote, data, observation)?',
|
|
31
|
+
'Did I apply each framework as concrete steps, not just mention it?',
|
|
32
|
+
'Are there any claims I made without tool verification?',
|
|
33
|
+
'Is the output actionable by someone who has no prior context?',
|
|
34
|
+
'Did I flag uncertainties and assumptions explicitly?',
|
|
35
|
+
],
|
|
36
|
+
action: 'If any answer is "no", fix it before delivering.',
|
|
37
|
+
};
|
|
38
|
+
function buildFrameworkContext(research) {
|
|
39
|
+
const parts = [];
|
|
40
|
+
for (const ef of research.expert_frameworks) {
|
|
41
|
+
parts.push(`EXPERT: ${ef.expert_name} — ${ef.framework_name}
|
|
42
|
+
Core: ${ef.core_concept}
|
|
43
|
+
Steps:
|
|
44
|
+
${ef.steps.map((s, i) => ` ${i + 1}. ${s.step}\n Input: ${s.input}\n Process: ${s.process}\n Output: ${s.output}`).join('\n')}
|
|
45
|
+
Decision rules: ${ef.decision_rules.join('; ')}
|
|
46
|
+
Artifacts: ${ef.artifacts.join(', ')}
|
|
47
|
+
Confidence: ${ef.research_confidence}${ef.research_note ? ` — ${ef.research_note}` : ''}`);
|
|
48
|
+
}
|
|
49
|
+
for (const mf of research.methodology_frameworks) {
|
|
50
|
+
parts.push(`METHODOLOGY: ${mf.name}
|
|
51
|
+
Purpose: ${mf.purpose}
|
|
52
|
+
Inputs: ${mf.mechanics.inputs.join(', ')}
|
|
53
|
+
${mf.mechanics.formula ? `Formula: ${mf.mechanics.formula}` : ''}
|
|
54
|
+
${mf.mechanics.scoring ? `Scoring: ${JSON.stringify(mf.mechanics.scoring, null, 2)}` : ''}
|
|
55
|
+
Output: ${mf.mechanics.output}
|
|
56
|
+
Decision rules: ${mf.mechanics.decision_rules.join('; ')}
|
|
57
|
+
Confidence: ${mf.research_confidence}${mf.research_note ? ` — ${mf.research_note}` : ''}`);
|
|
58
|
+
}
|
|
59
|
+
if (research.conflicts.length > 0) {
|
|
60
|
+
parts.push(`CONFLICTS:\n${research.conflicts.map(c => `- ${c.concern}: ${c.frameworks.join(' vs ')} → ${c.resolution}`).join('\n')}`);
|
|
61
|
+
}
|
|
62
|
+
return parts.join('\n\n');
|
|
63
|
+
}
|
|
64
|
+
const ASSEMBLER_SYSTEM_PROMPT = `You assemble AI agent configurations from decomposed frameworks. Your output must operationalize every framework as executable workflow steps.
|
|
65
|
+
|
|
66
|
+
Return ONLY a JSON object:
|
|
67
|
+
{
|
|
68
|
+
"persona": "<max 3 sentences. WHO the agent is. No framework names. No methodology lists.>",
|
|
69
|
+
"role": "<one sentence: what the agent does>",
|
|
70
|
+
"workflow_steps": [
|
|
71
|
+
{
|
|
72
|
+
"number": 1,
|
|
73
|
+
"name": "[Framework]: [Action verb]",
|
|
74
|
+
"pattern": "chaining|routing|parallel|orchestrator|evaluator",
|
|
75
|
+
"input": "Explicit reference to data source or prior step output",
|
|
76
|
+
"process": "Exact procedure with scoring criteria, scales, decision trees. NOT 'apply best practices'.",
|
|
77
|
+
"output": "Named artifact with defined format (table, tree, scorecard, etc.)",
|
|
78
|
+
"decision_rules": ["If X then Y", "Override: when Z..."],
|
|
79
|
+
"tools_used": ["tool1"]
|
|
80
|
+
}
|
|
81
|
+
],
|
|
82
|
+
"context_strategy": "<brief description of document access approach>",
|
|
83
|
+
"output_schema": {
|
|
84
|
+
"primary_artifact": {
|
|
85
|
+
"name": "...",
|
|
86
|
+
"format": "Table|Tree|Narrative|Scorecard",
|
|
87
|
+
"required_fields": ["field1", "field2"]
|
|
88
|
+
},
|
|
89
|
+
"secondary_artifacts": [{ "name": "...", "format": "..." }],
|
|
90
|
+
"meta": {
|
|
91
|
+
"confidence_flags": "Required — tag uncertain items",
|
|
92
|
+
"source_citations": "Required — link claims to evidence"
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
CRITICAL RULES:
|
|
98
|
+
1. Every decomposed framework MUST produce at least one workflow step with concrete mechanics
|
|
99
|
+
2. Steps reference inputs explicitly ("pain point table from step 2", NOT "the data")
|
|
100
|
+
3. Process fields have scoring scales, formulas, classification criteria — NOT vague phrases
|
|
101
|
+
4. No duplicate content between persona and workflow
|
|
102
|
+
5. Persona is max 3 sentences, no framework names
|
|
103
|
+
6. Always end with a Self-Check step
|
|
104
|
+
7. If a framework has low confidence, add ⚠️ in the step name`;
|
|
105
|
+
export async function runAssembler(parsed, research, pattern, context, llmConfig) {
|
|
106
|
+
const frameworkContext = buildFrameworkContext(research);
|
|
107
|
+
const contextSummary = context.classified_documents.length > 0
|
|
108
|
+
? context.classified_documents.map(d => `- ${d.path}: ${d.category} (${d.estimated_tokens} tokens) — ${d.reasoning}`).join('\n')
|
|
109
|
+
: 'No documents provided.';
|
|
110
|
+
const text = await fetchCompletion({
|
|
111
|
+
providerId: llmConfig.providerId,
|
|
112
|
+
model: llmConfig.model,
|
|
113
|
+
messages: [
|
|
114
|
+
{ role: 'system', content: ASSEMBLER_SYSTEM_PROMPT },
|
|
115
|
+
{
|
|
116
|
+
role: 'user',
|
|
117
|
+
content: `Build an agent config from these inputs:
|
|
118
|
+
|
|
119
|
+
ROLE: ${parsed.role}
|
|
120
|
+
DOMAIN: ${parsed.domain}
|
|
121
|
+
SUCCESS CRITERIA: ${parsed.success_criteria.join(', ')}
|
|
122
|
+
CONSTRAINTS: ${parsed.constraints.join(', ')}
|
|
123
|
+
OUTPUT EXPECTATIONS: ${parsed.output_expectations.join(', ')}
|
|
124
|
+
|
|
125
|
+
WORKFLOW PATTERN: ${pattern.pattern} — ${pattern.justification}
|
|
126
|
+
SUGGESTED STEPS: ${pattern.suggested_steps.join(' → ')}
|
|
127
|
+
|
|
128
|
+
DECOMPOSED FRAMEWORKS:
|
|
129
|
+
${frameworkContext}
|
|
130
|
+
|
|
131
|
+
DOCUMENT STRATEGY:
|
|
132
|
+
${contextSummary}
|
|
133
|
+
|
|
134
|
+
TOOLS AVAILABLE: ${parsed.tools_requested.join(', ') || 'Filesystem, Web Search'}
|
|
135
|
+
|
|
136
|
+
Generate the agent config. Every framework above MUST become at least one workflow step with specific mechanics.`,
|
|
137
|
+
},
|
|
138
|
+
],
|
|
139
|
+
temperature: 0.3,
|
|
140
|
+
maxTokens: 4096,
|
|
141
|
+
});
|
|
142
|
+
const result = parseJSON(text);
|
|
143
|
+
if (!result) {
|
|
144
|
+
throw new Error(`Assembler: could not parse LLM response. Raw: ${text.slice(0, 300)}`);
|
|
145
|
+
}
|
|
146
|
+
// Post-process: ensure all required fields, inject pillars and self-check
|
|
147
|
+
const assembled = {
|
|
148
|
+
persona: result.persona ?? `You are a ${parsed.role} specializing in ${parsed.domain}.`,
|
|
149
|
+
role: result.role ?? `${parsed.role} for ${parsed.domain}`,
|
|
150
|
+
workflow_steps: ensureWorkflowSteps(result.workflow_steps ?? [], research, SELF_CHECK),
|
|
151
|
+
context_strategy: result.context_strategy ?? buildContextStrategyText(context),
|
|
152
|
+
output_schema: ensureOutputSchema(result.output_schema, parsed),
|
|
153
|
+
agentic_pillars: AGENTIC_PILLARS,
|
|
154
|
+
self_check: SELF_CHECK,
|
|
155
|
+
};
|
|
156
|
+
return assembled;
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* Ensure workflow steps cover all frameworks and end with self-check.
|
|
160
|
+
*/
|
|
161
|
+
function ensureWorkflowSteps(steps, research, selfCheck) {
|
|
162
|
+
const coveredExperts = new Set();
|
|
163
|
+
const coveredMethodologies = new Set();
|
|
164
|
+
for (const step of steps) {
|
|
165
|
+
const nameLower = step.name.toLowerCase();
|
|
166
|
+
for (const ef of research.expert_frameworks) {
|
|
167
|
+
if (nameLower.includes(ef.expert_name.toLowerCase()) || nameLower.includes(ef.framework_name.toLowerCase())) {
|
|
168
|
+
coveredExperts.add(ef.expert_name);
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
for (const mf of research.methodology_frameworks) {
|
|
172
|
+
if (nameLower.includes(mf.name.toLowerCase())) {
|
|
173
|
+
coveredMethodologies.add(mf.name);
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
// Add missing expert framework steps
|
|
178
|
+
for (const ef of research.expert_frameworks) {
|
|
179
|
+
if (!coveredExperts.has(ef.expert_name) && ef.steps.length > 0) {
|
|
180
|
+
const confLabel = ef.research_confidence === 'low' ? '⚠️ ' : '';
|
|
181
|
+
steps.push({
|
|
182
|
+
number: steps.length + 1,
|
|
183
|
+
name: `${confLabel}${ef.framework_name} (${ef.expert_name})`,
|
|
184
|
+
pattern: 'chaining',
|
|
185
|
+
input: ef.steps[0].input,
|
|
186
|
+
process: ef.steps.map(s => `${s.step}: ${s.process}`).join('\n'),
|
|
187
|
+
output: ef.steps[ef.steps.length - 1].output,
|
|
188
|
+
decision_rules: ef.decision_rules,
|
|
189
|
+
tools_used: [],
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
// Add missing methodology steps
|
|
194
|
+
for (const mf of research.methodology_frameworks) {
|
|
195
|
+
if (!coveredMethodologies.has(mf.name)) {
|
|
196
|
+
const confLabel = mf.research_confidence === 'low' ? '⚠️ ' : '';
|
|
197
|
+
steps.push({
|
|
198
|
+
number: steps.length + 1,
|
|
199
|
+
name: `${confLabel}${mf.name}`,
|
|
200
|
+
pattern: 'chaining',
|
|
201
|
+
input: mf.mechanics.inputs.join(', '),
|
|
202
|
+
process: [
|
|
203
|
+
mf.mechanics.formula ? `Formula: ${mf.mechanics.formula}` : '',
|
|
204
|
+
mf.mechanics.scoring ? `Scoring: ${Object.entries(mf.mechanics.scoring).map(([k, v]) => `${k}: ${v.description} (${v.scale})`).join('; ')}` : '',
|
|
205
|
+
].filter(Boolean).join('\n'),
|
|
206
|
+
output: mf.mechanics.output,
|
|
207
|
+
decision_rules: mf.mechanics.decision_rules,
|
|
208
|
+
tools_used: [],
|
|
209
|
+
});
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
// Renumber and add self-check as final step
|
|
213
|
+
const hasCheck = steps.some(s => s.name.toLowerCase().includes('self-check') || s.name.toLowerCase().includes('self check'));
|
|
214
|
+
if (!hasCheck) {
|
|
215
|
+
steps.push({
|
|
216
|
+
number: steps.length + 1,
|
|
217
|
+
name: 'Self-Check',
|
|
218
|
+
pattern: 'evaluator',
|
|
219
|
+
input: 'All prior step outputs',
|
|
220
|
+
process: selfCheck.questions.map(q => `- ${q}`).join('\n'),
|
|
221
|
+
output: 'Validated output — all checks pass before delivery',
|
|
222
|
+
decision_rules: [selfCheck.action],
|
|
223
|
+
tools_used: [],
|
|
224
|
+
});
|
|
225
|
+
}
|
|
226
|
+
// Renumber
|
|
227
|
+
steps.forEach((s, i) => { s.number = i + 1; });
|
|
228
|
+
return steps;
|
|
229
|
+
}
|
|
230
|
+
function buildContextStrategyText(context) {
|
|
231
|
+
if (context.classified_documents.length === 0)
|
|
232
|
+
return 'No documents — agent works from conversation input.';
|
|
233
|
+
const loaded = context.classified_documents.filter(d => d.category === 'always_loaded');
|
|
234
|
+
const onDemand = context.classified_documents.filter(d => d.category === 'on_demand');
|
|
235
|
+
const parts = [];
|
|
236
|
+
if (loaded.length > 0)
|
|
237
|
+
parts.push(`Always loaded: ${loaded.map(d => d.path).join(', ')}`);
|
|
238
|
+
if (onDemand.length > 0)
|
|
239
|
+
parts.push(`Fetch on demand: ${onDemand.map(d => d.path).join(', ')}`);
|
|
240
|
+
return parts.join('. ');
|
|
241
|
+
}
|
|
242
|
+
function ensureOutputSchema(schema, parsed) {
|
|
243
|
+
if (schema?.primary_artifact?.name && schema.primary_artifact.required_fields?.length > 0) {
|
|
244
|
+
return schema;
|
|
245
|
+
}
|
|
246
|
+
// Build from output expectations
|
|
247
|
+
return {
|
|
248
|
+
primary_artifact: {
|
|
249
|
+
name: parsed.output_expectations[0] ?? 'Analysis Report',
|
|
250
|
+
format: 'Table',
|
|
251
|
+
required_fields: parsed.output_expectations.length > 0
|
|
252
|
+
? parsed.output_expectations
|
|
253
|
+
: ['Finding', 'Evidence', 'Recommendation', 'Priority', 'Confidence'],
|
|
254
|
+
},
|
|
255
|
+
secondary_artifacts: parsed.output_expectations.slice(1).map(e => ({ name: e, format: 'Narrative' })),
|
|
256
|
+
meta: {
|
|
257
|
+
confidence_flags: 'Required — tag uncertain items',
|
|
258
|
+
source_citations: 'Required — link claims to evidence',
|
|
259
|
+
},
|
|
260
|
+
};
|
|
261
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context-strategist.d.ts","sourceRoot":"","sources":["../../../../src/metaprompt/v2/context-strategist.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,WAAW,EAAE,eAAe,EAAwC,MAAM,YAAY,CAAC;AAwDpH,wBAAsB,oBAAoB,CACxC,MAAM,EAAE,WAAW,EACnB,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,aAAa,GACvB,OAAO,CAAC,eAAe,CAAC,CA4F1B"}
|
|
@@ -0,0 +1,173 @@
|
|
|
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]*\}|\[[\s\S]*\]/);
|
|
15
|
+
if (braceMatch) {
|
|
16
|
+
try {
|
|
17
|
+
return JSON.parse(braceMatch[0]);
|
|
18
|
+
}
|
|
19
|
+
catch { /* continue */ }
|
|
20
|
+
}
|
|
21
|
+
return null;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Rough token estimation based on file type and size description.
|
|
25
|
+
*/
|
|
26
|
+
function estimateTokens(doc) {
|
|
27
|
+
const sizeMap = {
|
|
28
|
+
small: 500,
|
|
29
|
+
medium: 2000,
|
|
30
|
+
large: 8000,
|
|
31
|
+
'very large': 20000,
|
|
32
|
+
};
|
|
33
|
+
const base = sizeMap[doc.size_estimate.toLowerCase()] ?? 2000;
|
|
34
|
+
// Transcripts and meeting notes tend to be verbose
|
|
35
|
+
if (doc.inferred_type === 'signal' || doc.path.match(/transcript|meeting|interview/i)) {
|
|
36
|
+
return base * 1.5;
|
|
37
|
+
}
|
|
38
|
+
// Compressed/summary docs are smaller
|
|
39
|
+
if (doc.path.match(/compressed|summary/i)) {
|
|
40
|
+
return Math.floor(base * 0.5);
|
|
41
|
+
}
|
|
42
|
+
return base;
|
|
43
|
+
}
|
|
44
|
+
const CONTEXT_SYSTEM_PROMPT = `You classify documents for an AI agent's context window. Each document gets one category:
|
|
45
|
+
|
|
46
|
+
- always_loaded: Needed in every interaction. Small reference data (org charts, glossaries, key definitions). < ~2000 tokens.
|
|
47
|
+
- on_demand: Large or situationally needed. Transcripts, full reports. Agent fetches via tool when needed.
|
|
48
|
+
- compressed: Useful background but too large raw. Summarize for context, full available via tool.
|
|
49
|
+
- never_loaded: Not relevant to agent's purpose, or duplicates another document.
|
|
50
|
+
|
|
51
|
+
Return ONLY a JSON array:
|
|
52
|
+
[
|
|
53
|
+
{
|
|
54
|
+
"path": "...",
|
|
55
|
+
"category": "always_loaded|on_demand|compressed|never_loaded",
|
|
56
|
+
"reasoning": "Why this classification",
|
|
57
|
+
"estimated_tokens": <number>
|
|
58
|
+
}
|
|
59
|
+
]
|
|
60
|
+
|
|
61
|
+
Rules:
|
|
62
|
+
- Be aggressive about on_demand for large files. Transcripts are ALWAYS on_demand.
|
|
63
|
+
- Compressed summaries (.compressed.md) can be always_loaded if small enough.
|
|
64
|
+
- If two documents overlap significantly, mark the less useful one as never_loaded.`;
|
|
65
|
+
export async function runContextStrategist(parsed, tokenBudget, llmConfig) {
|
|
66
|
+
if (parsed.documents.length === 0) {
|
|
67
|
+
return {
|
|
68
|
+
classified_documents: [],
|
|
69
|
+
total_always_loaded_tokens: 0,
|
|
70
|
+
token_budget: tokenBudget,
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
const docList = parsed.documents.map((d, i) => `${i + 1}. path: "${d.path}" | type: ${d.inferred_type} | size: ${d.size_estimate}`).join('\n');
|
|
74
|
+
const text = await fetchCompletion({
|
|
75
|
+
providerId: llmConfig.providerId,
|
|
76
|
+
model: llmConfig.model,
|
|
77
|
+
messages: [
|
|
78
|
+
{ role: 'system', content: CONTEXT_SYSTEM_PROMPT },
|
|
79
|
+
{
|
|
80
|
+
role: 'user',
|
|
81
|
+
content: `Agent role: ${parsed.role}
|
|
82
|
+
Agent domain: ${parsed.domain}
|
|
83
|
+
Token budget: ${tokenBudget}
|
|
84
|
+
|
|
85
|
+
Documents to classify:
|
|
86
|
+
${docList}`,
|
|
87
|
+
},
|
|
88
|
+
],
|
|
89
|
+
temperature: 0.1,
|
|
90
|
+
maxTokens: 2048,
|
|
91
|
+
});
|
|
92
|
+
const rawResult = parseJSON(text);
|
|
93
|
+
let classified;
|
|
94
|
+
if (Array.isArray(rawResult)) {
|
|
95
|
+
classified = rawResult.map((item, i) => {
|
|
96
|
+
const doc = parsed.documents[i] ?? { path: item.path ?? '', inferred_type: 'unknown' };
|
|
97
|
+
const validCategories = ['always_loaded', 'on_demand', 'compressed', 'never_loaded'];
|
|
98
|
+
const category = validCategories.includes(item.category)
|
|
99
|
+
? item.category
|
|
100
|
+
: 'on_demand';
|
|
101
|
+
return {
|
|
102
|
+
path: item.path ?? doc.path,
|
|
103
|
+
inferred_type: doc.inferred_type,
|
|
104
|
+
category,
|
|
105
|
+
reasoning: item.reasoning ?? '',
|
|
106
|
+
estimated_tokens: item.estimated_tokens ?? estimateTokens(doc),
|
|
107
|
+
};
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
else {
|
|
111
|
+
// LLM parse failed — use heuristic fallback
|
|
112
|
+
classified = parsed.documents.map(doc => {
|
|
113
|
+
const tokens = estimateTokens(doc);
|
|
114
|
+
let category = 'on_demand';
|
|
115
|
+
if (doc.path.match(/compressed|summary|overview|glossary|structure/i) && tokens < 2000) {
|
|
116
|
+
category = 'always_loaded';
|
|
117
|
+
}
|
|
118
|
+
else if (doc.path.match(/transcript|meeting|interview/i)) {
|
|
119
|
+
category = 'on_demand';
|
|
120
|
+
}
|
|
121
|
+
else if (tokens > 5000) {
|
|
122
|
+
category = 'compressed';
|
|
123
|
+
}
|
|
124
|
+
else if (tokens <= 2000) {
|
|
125
|
+
category = 'always_loaded';
|
|
126
|
+
}
|
|
127
|
+
return {
|
|
128
|
+
path: doc.path,
|
|
129
|
+
inferred_type: doc.inferred_type,
|
|
130
|
+
category,
|
|
131
|
+
reasoning: 'Heuristic classification (LLM parse failed)',
|
|
132
|
+
estimated_tokens: tokens,
|
|
133
|
+
};
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
// Apply token budget rules
|
|
137
|
+
classified = applyTokenBudgetRules(classified, tokenBudget);
|
|
138
|
+
const totalAlwaysLoaded = classified
|
|
139
|
+
.filter(d => d.category === 'always_loaded')
|
|
140
|
+
.reduce((sum, d) => sum + d.estimated_tokens, 0);
|
|
141
|
+
const result = {
|
|
142
|
+
classified_documents: classified,
|
|
143
|
+
total_always_loaded_tokens: totalAlwaysLoaded,
|
|
144
|
+
token_budget: tokenBudget,
|
|
145
|
+
};
|
|
146
|
+
if (totalAlwaysLoaded > tokenBudget * 0.8) {
|
|
147
|
+
result.token_budget_warning = `⚠️ Always-loaded context uses ${Math.round(totalAlwaysLoaded / tokenBudget * 100)}% of token budget (${totalAlwaysLoaded}/${tokenBudget}). Consider increasing budget or moving documents to on-demand retrieval.`;
|
|
148
|
+
}
|
|
149
|
+
return result;
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* If always_loaded documents exceed 60% of budget, demote the largest ones.
|
|
153
|
+
*/
|
|
154
|
+
function applyTokenBudgetRules(docs, tokenBudget) {
|
|
155
|
+
const threshold = tokenBudget * 0.6;
|
|
156
|
+
let alwaysLoaded = docs.filter(d => d.category === 'always_loaded');
|
|
157
|
+
let totalTokens = alwaysLoaded.reduce((sum, d) => sum + d.estimated_tokens, 0);
|
|
158
|
+
if (totalTokens <= threshold)
|
|
159
|
+
return docs;
|
|
160
|
+
// Sort by tokens descending — demote largest first
|
|
161
|
+
const sorted = [...alwaysLoaded].sort((a, b) => b.estimated_tokens - a.estimated_tokens);
|
|
162
|
+
for (const doc of sorted) {
|
|
163
|
+
if (totalTokens <= threshold)
|
|
164
|
+
break;
|
|
165
|
+
const target = docs.find(d => d.path === doc.path);
|
|
166
|
+
if (target) {
|
|
167
|
+
target.category = 'on_demand';
|
|
168
|
+
target.reasoning += ' [Auto-demoted: exceeded 60% token budget threshold]';
|
|
169
|
+
totalTokens -= target.estimated_tokens;
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
return docs;
|
|
173
|
+
}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import type { LLMCallConfig, ParsedInput, ResearchResult, AssembledAgent, ContextStrategy, EvaluationResult } from './types.js';
|
|
2
|
+
export declare function runEvaluator(parsed: ParsedInput, research: ResearchResult, assembled: AssembledAgent, context: ContextStrategy, llmConfig: LLMCallConfig): Promise<EvaluationResult>;
|
|
3
|
+
//# sourceMappingURL=evaluator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"evaluator.d.ts","sourceRoot":"","sources":["../../../../src/metaprompt/v2/evaluator.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,aAAa,EACb,WAAW,EACX,cAAc,EACd,cAAc,EACd,eAAe,EACf,gBAAgB,EAEjB,MAAM,YAAY,CAAC;AAiOpB,wBAAsB,YAAY,CAChC,MAAM,EAAE,WAAW,EACnB,QAAQ,EAAE,cAAc,EACxB,SAAS,EAAE,cAAc,EACzB,OAAO,EAAE,eAAe,EACxB,SAAS,EAAE,aAAa,GACvB,OAAO,CAAC,gBAAgB,CAAC,CAkF3B"}
|