@metabob/minibob 0.1.2

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 (174) hide show
  1. package/ARCHITECTURE.md +255 -0
  2. package/CHANGELOG.md +112 -0
  3. package/README.md +380 -0
  4. package/bin/minibob.js +36 -0
  5. package/dist/acp-gossip.d.ts +72 -0
  6. package/dist/acp-gossip.d.ts.map +1 -0
  7. package/dist/acp-gossip.js +156 -0
  8. package/dist/acp-gossip.js.map +1 -0
  9. package/dist/acp.d.ts +62 -0
  10. package/dist/acp.d.ts.map +1 -0
  11. package/dist/acp.js +292 -0
  12. package/dist/acp.js.map +1 -0
  13. package/dist/activity.d.ts +157 -0
  14. package/dist/activity.d.ts.map +1 -0
  15. package/dist/activity.js +518 -0
  16. package/dist/activity.js.map +1 -0
  17. package/dist/agent-runtime.d.ts +104 -0
  18. package/dist/agent-runtime.d.ts.map +1 -0
  19. package/dist/boredom.d.ts +125 -0
  20. package/dist/boredom.d.ts.map +1 -0
  21. package/dist/boredom.js +244 -0
  22. package/dist/boredom.js.map +1 -0
  23. package/dist/cli/acp-server.d.ts +23 -0
  24. package/dist/cli/acp-server.d.ts.map +1 -0
  25. package/dist/cli/burrow.d.ts +26 -0
  26. package/dist/cli/burrow.d.ts.map +1 -0
  27. package/dist/cli/doctor.d.ts +22 -0
  28. package/dist/cli/doctor.d.ts.map +1 -0
  29. package/dist/cli/goal.d.ts +22 -0
  30. package/dist/cli/goal.d.ts.map +1 -0
  31. package/dist/cli/index.d.ts +47 -0
  32. package/dist/cli/index.d.ts.map +1 -0
  33. package/dist/cli/instance-registry.d.ts +78 -0
  34. package/dist/cli/instance-registry.d.ts.map +1 -0
  35. package/dist/cli/observe.d.ts +35 -0
  36. package/dist/cli/observe.d.ts.map +1 -0
  37. package/dist/cli/vessel.d.ts +14 -0
  38. package/dist/cli/vessel.d.ts.map +1 -0
  39. package/dist/composition-observer.d.ts +96 -0
  40. package/dist/composition-observer.d.ts.map +1 -0
  41. package/dist/config.d.ts +36 -0
  42. package/dist/config.d.ts.map +1 -0
  43. package/dist/config.js +128 -0
  44. package/dist/config.js.map +1 -0
  45. package/dist/docker/Dockerfile +35 -0
  46. package/dist/environment.d.ts +72 -0
  47. package/dist/environment.d.ts.map +1 -0
  48. package/dist/environment.js +142 -0
  49. package/dist/environment.js.map +1 -0
  50. package/dist/goal-processor.d.ts +165 -0
  51. package/dist/goal-processor.d.ts.map +1 -0
  52. package/dist/helm/minibob-cluster/Chart.yaml +13 -0
  53. package/dist/helm/minibob-cluster/templates/_helpers.tpl +60 -0
  54. package/dist/helm/minibob-cluster/templates/configmap.yaml +11 -0
  55. package/dist/helm/minibob-cluster/templates/deployment.yaml +108 -0
  56. package/dist/helm/minibob-cluster/templates/secret.yaml +10 -0
  57. package/dist/helm/minibob-cluster/templates/service.yaml +37 -0
  58. package/dist/helm/minibob-cluster/values-local.yaml +41 -0
  59. package/dist/helm/minibob-cluster/values-production.yaml +57 -0
  60. package/dist/helm/minibob-cluster/values-testing-cluster.yaml +43 -0
  61. package/dist/helm/minibob-cluster/values.yaml +127 -0
  62. package/dist/improviser.d.ts +74 -0
  63. package/dist/improviser.d.ts.map +1 -0
  64. package/dist/impulse-filter.d.ts +74 -0
  65. package/dist/impulse-filter.d.ts.map +1 -0
  66. package/dist/impulse.d.ts +92 -0
  67. package/dist/impulse.d.ts.map +1 -0
  68. package/dist/impulse.js +234 -0
  69. package/dist/impulse.js.map +1 -0
  70. package/dist/lib.d.ts +29 -0
  71. package/dist/lib.d.ts.map +1 -0
  72. package/dist/lib.js +18561 -0
  73. package/dist/lib.js.map +98 -0
  74. package/dist/lifecycle-hooks.d.ts +99 -0
  75. package/dist/lifecycle-hooks.d.ts.map +1 -0
  76. package/dist/lifecycle-hooks.js +135 -0
  77. package/dist/lifecycle-hooks.js.map +1 -0
  78. package/dist/llm.d.ts +31 -0
  79. package/dist/llm.d.ts.map +1 -0
  80. package/dist/llm.js +349 -0
  81. package/dist/llm.js.map +1 -0
  82. package/dist/mcp-activity-bridge.d.ts +66 -0
  83. package/dist/mcp-activity-bridge.d.ts.map +1 -0
  84. package/dist/mcp-activity-bridge.js +126 -0
  85. package/dist/mcp-activity-bridge.js.map +1 -0
  86. package/dist/mcp.d.ts +216 -0
  87. package/dist/mcp.d.ts.map +1 -0
  88. package/dist/mcp.js +292 -0
  89. package/dist/mcp.js.map +1 -0
  90. package/dist/memory-agent.d.ts +92 -0
  91. package/dist/memory-agent.d.ts.map +1 -0
  92. package/dist/memory-agent.js +277 -0
  93. package/dist/memory-agent.js.map +1 -0
  94. package/dist/runtime-mapping.d.ts +97 -0
  95. package/dist/runtime-mapping.d.ts.map +1 -0
  96. package/dist/search-first-executor.d.ts +113 -0
  97. package/dist/search-first-executor.d.ts.map +1 -0
  98. package/dist/session.d.ts +48 -0
  99. package/dist/session.d.ts.map +1 -0
  100. package/dist/template-extractor.d.ts +9 -0
  101. package/dist/template-extractor.d.ts.map +1 -0
  102. package/dist/template-generator.d.ts +12 -0
  103. package/dist/template-generator.d.ts.map +1 -0
  104. package/dist/tools.d.ts +58 -0
  105. package/dist/tools.d.ts.map +1 -0
  106. package/dist/tools.js +771 -0
  107. package/dist/tools.js.map +1 -0
  108. package/dist/types.d.ts +503 -0
  109. package/dist/types.d.ts.map +1 -0
  110. package/dist/types.js +8 -0
  111. package/dist/types.js.map +1 -0
  112. package/dist/understanding/analyzer.d.ts +55 -0
  113. package/dist/understanding/analyzer.d.ts.map +1 -0
  114. package/dist/understanding/explorer.d.ts +73 -0
  115. package/dist/understanding/explorer.d.ts.map +1 -0
  116. package/dist/understanding/index.d.ts +7 -0
  117. package/dist/understanding/index.d.ts.map +1 -0
  118. package/dist/understanding/types.d.ts +136 -0
  119. package/dist/understanding/types.d.ts.map +1 -0
  120. package/dist/validation.d.ts +29 -0
  121. package/dist/validation.d.ts.map +1 -0
  122. package/dist/validation.js +106 -0
  123. package/dist/validation.js.map +1 -0
  124. package/dist/vessel-bootstrap.d.ts +190 -0
  125. package/dist/vessel-bootstrap.d.ts.map +1 -0
  126. package/dist/vessel-registry.d.ts +229 -0
  127. package/dist/vessel-registry.d.ts.map +1 -0
  128. package/index.ts +1329 -0
  129. package/package.json +54 -0
  130. package/src/acp-gossip.ts +193 -0
  131. package/src/acp.ts +362 -0
  132. package/src/activity.ts +1464 -0
  133. package/src/agent-runtime.ts +365 -0
  134. package/src/boredom.ts +423 -0
  135. package/src/cli/acp-server.ts +377 -0
  136. package/src/cli/burrow.ts +896 -0
  137. package/src/cli/doctor.ts +526 -0
  138. package/src/cli/goal.ts +224 -0
  139. package/src/cli/index.ts +147 -0
  140. package/src/cli/instance-registry.ts +271 -0
  141. package/src/cli/observe.ts +682 -0
  142. package/src/cli/vessel.ts +287 -0
  143. package/src/components/SystemOverview.tsx +331 -0
  144. package/src/composition-observer.ts +449 -0
  145. package/src/config.ts +172 -0
  146. package/src/environment.ts +167 -0
  147. package/src/goal-processor.ts +654 -0
  148. package/src/improviser.ts +591 -0
  149. package/src/impulse-filter.ts +273 -0
  150. package/src/impulse.ts +311 -0
  151. package/src/lib.ts +147 -0
  152. package/src/lifecycle-hooks.ts +181 -0
  153. package/src/llm.ts +434 -0
  154. package/src/mcp-activity-bridge.ts +158 -0
  155. package/src/mcp.ts +747 -0
  156. package/src/memory-agent.ts +316 -0
  157. package/src/runtime-mapping.ts +527 -0
  158. package/src/search-first-executor.ts +666 -0
  159. package/src/session.ts +141 -0
  160. package/src/template-extractor.ts +256 -0
  161. package/src/template-generator.ts +130 -0
  162. package/src/tools.ts +924 -0
  163. package/src/types.ts +497 -0
  164. package/src/understanding/analyzer.ts +354 -0
  165. package/src/understanding/explorer.ts +488 -0
  166. package/src/understanding/index.ts +27 -0
  167. package/src/understanding/types.ts +153 -0
  168. package/src/validation.ts +125 -0
  169. package/src/vessel-bootstrap.ts +440 -0
  170. package/src/vessel-registry.ts +621 -0
  171. package/templates/core/edit-file.json +85 -0
  172. package/templates/understanding/diagnose-problem.json +32 -0
  173. package/templates/understanding/explore-codebase-v2.json +57 -0
  174. package/templates/understanding/explore-codebase.json +37 -0
package/dist/mcp.js ADDED
@@ -0,0 +1,292 @@
1
+ /**
2
+ * minibob MCP Client
3
+ *
4
+ * Integrates with Metabob backend for:
5
+ * - Activity template fetching
6
+ * - Execution metrics reporting
7
+ * - Impulse storage/retrieval
8
+ * - Learning and optimization
9
+ */
10
+ // =============================================================================
11
+ // MCP CLIENT
12
+ // =============================================================================
13
+ export class MCPClient {
14
+ endpoint;
15
+ apiKey;
16
+ timeout;
17
+ constructor(config) {
18
+ this.endpoint = config.endpoint.replace(/\/$/, ""); // Remove trailing slash
19
+ this.apiKey = config.apiKey;
20
+ this.timeout = config.timeout ?? 30000;
21
+ }
22
+ /**
23
+ * Fetch activity template by ID
24
+ */
25
+ async getActivityTemplate(templateId) {
26
+ try {
27
+ const response = await this.request("GET", `/activity-templates/${templateId}`);
28
+ if (!response.ok) {
29
+ if (response.status === 404)
30
+ return null;
31
+ throw new Error(`Failed to fetch template: ${response.status} ${response.statusText}`);
32
+ }
33
+ const data = await response.json();
34
+ return data.template ?? null;
35
+ }
36
+ catch (error) {
37
+ console.error(`[MCP] Error fetching template ${templateId}:`, error);
38
+ return null;
39
+ }
40
+ }
41
+ /**
42
+ * Search activity templates
43
+ */
44
+ async searchActivityTemplates(query) {
45
+ try {
46
+ const params = new URLSearchParams();
47
+ if (query?.category)
48
+ params.set("category", query.category);
49
+ if (query?.limit)
50
+ params.set("limit", String(query.limit));
51
+ const url = `/activity-templates?${params.toString()}`;
52
+ const response = await this.request("GET", url);
53
+ if (!response.ok) {
54
+ throw new Error(`Failed to search templates: ${response.status}`);
55
+ }
56
+ const data = await response.json();
57
+ return data.templates ?? [];
58
+ }
59
+ catch (error) {
60
+ console.error("[MCP] Error searching templates:", error);
61
+ return [];
62
+ }
63
+ }
64
+ /**
65
+ * Register activity template variant
66
+ * Called when executing a template loaded from local JSON file
67
+ */
68
+ async registerTemplate(template) {
69
+ try {
70
+ const payload = {
71
+ variant_id: template.id,
72
+ activity_id: template.id, // For now, variant_id === activity_id
73
+ variant_name: template.name,
74
+ description: template.description,
75
+ category: template.category,
76
+ task_steps: template.tasks,
77
+ scope: "global",
78
+ };
79
+ // Omit null/undefined fields (SurrealDB doesn't accept null, needs NONE or omitted)
80
+ Object.keys(payload).forEach(key => {
81
+ if (payload[key] === null || payload[key] === undefined) {
82
+ delete payload[key];
83
+ }
84
+ });
85
+ const response = await this.request("POST", "/templates", payload);
86
+ if (!response.ok) {
87
+ // 409 Conflict means template already exists - that's fine
88
+ if (response.status === 409) {
89
+ console.log(`[MCP] Template ${template.id} already registered`);
90
+ return true;
91
+ }
92
+ const errorText = await response.text();
93
+ console.warn(`[MCP] Failed to register template: ${response.status} - ${errorText}`);
94
+ return false;
95
+ }
96
+ console.log(`[MCP] ✓ Template ${template.id} registered successfully`);
97
+ return true;
98
+ }
99
+ catch (error) {
100
+ console.error("[MCP] Error registering template:", error);
101
+ return false;
102
+ }
103
+ }
104
+ /**
105
+ * Report activity execution results
106
+ */
107
+ async reportExecution(execution) {
108
+ try {
109
+ // Determine first failed task if execution failed
110
+ const failedTask = execution.taskResults.find((t) => t.status === "failed");
111
+ const payload = {
112
+ variant_id: execution.templateId,
113
+ success: execution.status === "completed",
114
+ duration_ms: execution.metrics?.duration || 0,
115
+ cost: execution.metrics?.cost || 0,
116
+ tokens: {
117
+ input: execution.metrics?.totalTokens?.input || 0,
118
+ output: execution.metrics?.totalTokens?.output || 0,
119
+ cache: 0, // MiniBob doesn't track cache tokens yet
120
+ },
121
+ };
122
+ // Only include optional fields if they have values (SurrealDB doesn't accept null)
123
+ if (failedTask?.error) {
124
+ payload.error_message = failedTask.error;
125
+ }
126
+ if (failedTask) {
127
+ payload.error_type = "task_execution_error";
128
+ payload.failed_task_id = failedTask.taskId;
129
+ }
130
+ // Omit empty arrays - SurrealDB will use default [] if field allows it
131
+ if (execution.impulses && execution.impulses.length > 0) {
132
+ payload.impulses_used = execution.impulses.map(imp => imp.id);
133
+ }
134
+ const response = await this.request("POST", "/executions", payload);
135
+ if (!response.ok) {
136
+ const errorText = await response.text();
137
+ console.warn(`[MCP] Failed to report execution: ${response.status} - ${errorText}`);
138
+ return false;
139
+ }
140
+ return true;
141
+ }
142
+ catch (error) {
143
+ console.error("[MCP] Error reporting execution:", error);
144
+ return false;
145
+ }
146
+ }
147
+ /**
148
+ * Store impulse in backend
149
+ */
150
+ async storeImpulse(impulse) {
151
+ try {
152
+ const payload = {
153
+ id: impulse.id,
154
+ pointer: impulse.pointer,
155
+ budget: impulse.budget,
156
+ priority: impulse.priority,
157
+ tags: impulse.tags,
158
+ content: impulse.content, // May be omitted if unloaded
159
+ };
160
+ const response = await this.request("POST", "/impulses", payload);
161
+ if (!response.ok) {
162
+ console.warn(`[MCP] Failed to store impulse: ${response.status}`);
163
+ return false;
164
+ }
165
+ return true;
166
+ }
167
+ catch (error) {
168
+ console.error("[MCP] Error storing impulse:", error);
169
+ return false;
170
+ }
171
+ }
172
+ /**
173
+ * Retrieve impulse from backend
174
+ */
175
+ async retrieveImpulse(impulseId) {
176
+ try {
177
+ const response = await this.request("GET", `/impulses/${impulseId}`);
178
+ if (!response.ok) {
179
+ if (response.status === 404)
180
+ return null;
181
+ throw new Error(`Failed to retrieve impulse: ${response.status}`);
182
+ }
183
+ const data = await response.json();
184
+ return data.impulse ?? null;
185
+ }
186
+ catch (error) {
187
+ console.error(`[MCP] Error retrieving impulse ${impulseId}:`, error);
188
+ return null;
189
+ }
190
+ }
191
+ /**
192
+ * Track impulse usage for learning
193
+ */
194
+ async trackImpulseUsage(impulseId, context) {
195
+ try {
196
+ const response = await this.request("POST", `/impulses/${impulseId}/usage`, context);
197
+ if (!response.ok) {
198
+ console.warn(`[MCP] Failed to track impulse usage: ${response.status}`);
199
+ return false;
200
+ }
201
+ return true;
202
+ }
203
+ catch (error) {
204
+ console.error("[MCP] Error tracking impulse usage:", error);
205
+ return false;
206
+ }
207
+ }
208
+ /**
209
+ * Register minibob vessel with backend
210
+ */
211
+ async registerVessel(manifest) {
212
+ try {
213
+ const response = await this.request("POST", "/vessels", manifest);
214
+ if (!response.ok) {
215
+ console.warn(`[MCP] Failed to register vessel: ${response.status}`);
216
+ return false;
217
+ }
218
+ console.log("[MCP] Vessel registered successfully");
219
+ return true;
220
+ }
221
+ catch (error) {
222
+ console.error("[MCP] Error registering vessel:", error);
223
+ return false;
224
+ }
225
+ }
226
+ /**
227
+ * Make HTTP request to MCP backend
228
+ */
229
+ async request(method, path, body) {
230
+ const url = `${this.endpoint}${path}`;
231
+ const headers = {
232
+ "Content-Type": "application/json",
233
+ };
234
+ if (this.apiKey) {
235
+ headers["Authorization"] = `Bearer ${this.apiKey}`;
236
+ }
237
+ const controller = new AbortController();
238
+ const timeoutId = setTimeout(() => controller.abort(), this.timeout);
239
+ try {
240
+ const response = await fetch(url, {
241
+ method,
242
+ headers,
243
+ body: body ? JSON.stringify(body) : undefined,
244
+ signal: controller.signal,
245
+ });
246
+ return response;
247
+ }
248
+ finally {
249
+ clearTimeout(timeoutId);
250
+ }
251
+ }
252
+ }
253
+ // =============================================================================
254
+ // SINGLETON MCP CLIENT
255
+ // =============================================================================
256
+ let mcpClient = null;
257
+ /**
258
+ * Initialize MCP client with backend health check (singleton)
259
+ *
260
+ * Checks backend availability before initialization.
261
+ * Returns null if backend is unreachable, allowing graceful fallback to local mode.
262
+ *
263
+ * @param config MCP configuration
264
+ * @param skipHealthCheck Skip health check (for testing)
265
+ * @returns MCPClient instance or null if backend unavailable
266
+ */
267
+ export async function initializeMCP(config, skipHealthCheck = false) {
268
+ if (!skipHealthCheck) {
269
+ const { checkBackendHealth } = await import("./environment");
270
+ const healthy = await checkBackendHealth(config.endpoint);
271
+ if (!healthy) {
272
+ console.warn("[MCP] Backend unavailable, using local mode");
273
+ return null;
274
+ }
275
+ }
276
+ mcpClient = new MCPClient(config);
277
+ console.log("[MCP] ✓ Client initialized");
278
+ return mcpClient;
279
+ }
280
+ /**
281
+ * Get MCP client instance
282
+ */
283
+ export function getMCPClient() {
284
+ return mcpClient;
285
+ }
286
+ /**
287
+ * Check if MCP is enabled
288
+ */
289
+ export function isMCPEnabled() {
290
+ return mcpClient !== null;
291
+ }
292
+ //# sourceMappingURL=mcp.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp.js","sourceRoot":"","sources":["../src/mcp.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,92 @@
1
+ /**
2
+ * SessionMemoryAgent - Automatic context preparation for activity execution
3
+ *
4
+ * Moved from metabob-opencode to minibob as part of library integration.
5
+ * This version is simplified to work with minibob's minimal dependencies.
6
+ *
7
+ * Design goals:
8
+ * - Fast analysis (<2s with Claude Haiku)
9
+ * - Automatic impulse creation based on intent
10
+ * - Self-contained (no opencode dependencies)
11
+ */
12
+ import z from "zod";
13
+ export declare namespace SessionMemoryAgent {
14
+ /**
15
+ * User intent classification schema
16
+ */
17
+ const IntentSchema: z.ZodObject<{
18
+ type: z.ZodEnum<{
19
+ refactor: "refactor";
20
+ other: "other";
21
+ exploration: "exploration";
22
+ code_fix: "code_fix";
23
+ feature_request: "feature_request";
24
+ question: "question";
25
+ }>;
26
+ confidence: z.ZodNumber;
27
+ reasoning: z.ZodString;
28
+ suggestedImpulses: z.ZodArray<z.ZodObject<{
29
+ id: z.ZodString;
30
+ type: z.ZodEnum<{
31
+ memo: "memo";
32
+ file: "file";
33
+ metabobIssue: "metabobIssue";
34
+ history: "history";
35
+ bashOutput: "bashOutput";
36
+ }>;
37
+ description: z.ZodString;
38
+ priority: z.ZodEnum<{
39
+ critical: "critical";
40
+ high: "high";
41
+ medium: "medium";
42
+ low: "low";
43
+ }>;
44
+ budget: z.ZodNumber;
45
+ pointer: z.ZodUnion<readonly [z.ZodObject<{
46
+ type: z.ZodLiteral<"file">;
47
+ path: z.ZodString;
48
+ offset: z.ZodOptional<z.ZodNumber>;
49
+ limit: z.ZodOptional<z.ZodNumber>;
50
+ }, z.core.$strip>, z.ZodObject<{
51
+ type: z.ZodLiteral<"memo">;
52
+ content: z.ZodString;
53
+ }, z.core.$strip>, z.ZodObject<{
54
+ type: z.ZodLiteral<"custom">;
55
+ resolver: z.ZodString;
56
+ data: z.ZodRecord<z.ZodString, z.ZodUnknown>;
57
+ }, z.core.$strip>]>;
58
+ }, z.core.$strip>>;
59
+ }, z.core.$strip>;
60
+ export type Intent = z.infer<typeof IntentSchema>;
61
+ /**
62
+ * Configuration for session memory agent
63
+ */
64
+ export interface Config {
65
+ enabled: boolean;
66
+ timeout: number;
67
+ model: string;
68
+ defaultBudget: number;
69
+ maxImpulses: number;
70
+ }
71
+ /**
72
+ * Analyze user intent from prompt text
73
+ * Returns intent classification with suggested impulses
74
+ */
75
+ export function analyzeIntent(input: {
76
+ promptText: string;
77
+ workingDirectory?: string;
78
+ config?: Partial<Config>;
79
+ }): Promise<Intent>;
80
+ /**
81
+ * Prepare impulses based on intent analysis
82
+ * Creates impulses in the impulse store
83
+ */
84
+ export function prepare(input: {
85
+ intent: Intent;
86
+ }): Promise<{
87
+ impulsesCreated: number;
88
+ impulseIds: string[];
89
+ }>;
90
+ export {};
91
+ }
92
+ //# sourceMappingURL=memory-agent.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"memory-agent.d.ts","sourceRoot":"","sources":["../src/memory-agent.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAKH,OAAO,CAAC,MAAM,KAAK,CAAA;AAEnB,yBAAiB,kBAAkB,CAAC;IAClC;;OAEG;IACH,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;qBA8BhB,CAAA;IAEF,MAAM,MAAM,MAAM,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,YAAY,CAAC,CAAA;IAEjD;;OAEG;IACH,MAAM,WAAW,MAAM;QACrB,OAAO,EAAE,OAAO,CAAA;QAChB,OAAO,EAAE,MAAM,CAAA;QACf,KAAK,EAAE,MAAM,CAAA;QACb,aAAa,EAAE,MAAM,CAAA;QACrB,WAAW,EAAE,MAAM,CAAA;KACpB;IAUD;;;OAGG;IACH,gBAAsB,aAAa,CAAC,KAAK,EAAE;QACzC,UAAU,EAAE,MAAM,CAAA;QAClB,gBAAgB,CAAC,EAAE,MAAM,CAAA;QACzB,MAAM,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,CAAA;KACzB,GAAG,OAAO,CAAC,MAAM,CAAC,CAsKlB;IAED;;;OAGG;IACH,gBAAsB,OAAO,CAAC,KAAK,EAAE;QAAE,MAAM,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC;QAChE,eAAe,EAAE,MAAM,CAAA;QACvB,UAAU,EAAE,MAAM,EAAE,CAAA;KACrB,CAAC,CAyDD;;CACF"}
@@ -0,0 +1,277 @@
1
+ /**
2
+ * SessionMemoryAgent - Automatic context preparation for activity execution
3
+ *
4
+ * Moved from metabob-opencode to minibob as part of library integration.
5
+ * This version is simplified to work with minibob's minimal dependencies.
6
+ *
7
+ * Design goals:
8
+ * - Fast analysis (<2s with Claude Haiku)
9
+ * - Automatic impulse creation based on intent
10
+ * - Self-contained (no opencode dependencies)
11
+ */
12
+ import { createAnthropicClient } from "./llm";
13
+ import { createImpulse, getImpulseStore } from "./impulse";
14
+ import z from "zod";
15
+ export var SessionMemoryAgent;
16
+ (function (SessionMemoryAgent) {
17
+ /**
18
+ * User intent classification schema
19
+ */
20
+ const IntentSchema = z.object({
21
+ type: z.enum(["code_fix", "feature_request", "question", "refactor", "exploration", "other"]),
22
+ confidence: z.number().min(0).max(1),
23
+ reasoning: z.string(),
24
+ suggestedImpulses: z.array(z.object({
25
+ id: z.string(),
26
+ type: z.enum(["file", "metabobIssue", "history", "memo", "bashOutput"]),
27
+ description: z.string(),
28
+ priority: z.enum(["critical", "high", "medium", "low"]),
29
+ budget: z.number().positive(),
30
+ pointer: z.union([
31
+ z.object({
32
+ type: z.literal("file"),
33
+ path: z.string(),
34
+ offset: z.number().optional(),
35
+ limit: z.number().optional(),
36
+ }),
37
+ z.object({
38
+ type: z.literal("memo"),
39
+ content: z.string(),
40
+ }),
41
+ z.object({
42
+ type: z.literal("custom"),
43
+ resolver: z.string(),
44
+ data: z.record(z.string(), z.unknown()),
45
+ }),
46
+ ]),
47
+ })),
48
+ });
49
+ const DEFAULT_CONFIG = {
50
+ enabled: true,
51
+ timeout: 3000,
52
+ model: "claude-3-5-haiku-20241022",
53
+ defaultBudget: 2000,
54
+ maxImpulses: 5,
55
+ };
56
+ /**
57
+ * Analyze user intent from prompt text
58
+ * Returns intent classification with suggested impulses
59
+ */
60
+ async function analyzeIntent(input) {
61
+ const cfg = { ...DEFAULT_CONFIG, ...input.config };
62
+ const start = Date.now();
63
+ try {
64
+ console.log("[MemoryAgent] Analyzing intent", {
65
+ promptLength: input.promptText.length,
66
+ model: cfg.model,
67
+ timeout: cfg.timeout,
68
+ });
69
+ if (!process.env.ANTHROPIC_API_KEY) {
70
+ throw new Error("ANTHROPIC_API_KEY environment variable not set");
71
+ }
72
+ // Create LLM client
73
+ const llmClient = createAnthropicClient(process.env.ANTHROPIC_API_KEY);
74
+ // Build system prompt
75
+ const systemPrompt = `You are the Session Memory Agent - an intent analyzer for conversational coding assistance.
76
+
77
+ ## Your Role
78
+
79
+ Analyze user messages to understand their intent and recommend context (impulses) to load.
80
+ You DO NOT execute tasks. You ONLY analyze intent and suggest what context might be helpful.
81
+
82
+ For trivial messages (greetings, acknowledgments), classify as type="other" with empty suggestedImpulses array.
83
+
84
+ ## Intent Types
85
+
86
+ - **code_fix**: User reports a bug, error, or unexpected behavior
87
+ - **feature_request**: User wants to add/modify functionality
88
+ - **question**: User asks about code, architecture, or how things work
89
+ - **refactor**: User wants to improve existing code structure
90
+ - **exploration**: User is exploring codebase or investigating
91
+ - **other**: Greetings, acknowledgments, or messages that don't need coding context
92
+
93
+ ## Impulse Types
94
+
95
+ 1. **file**: Specific source files
96
+ - For code_fix: error file, related tests
97
+ - For feature_request: files to modify, similar features
98
+ - For question: files being asked about
99
+
100
+ 2. **memo**: Inline context notes
101
+ - For important constraints, requirements, or decisions
102
+ - Short-term memory across turns
103
+
104
+ 3. **custom**: Custom pointer types for specialized resolvers
105
+
106
+ ## Budget Guidelines
107
+
108
+ - file: 1500-3000 tokens (depends on file size)
109
+ - memo: 200-500 tokens
110
+ - custom: Varies by resolver
111
+
112
+ ## Priority Guidelines
113
+
114
+ - **critical**: Must-have for understanding request
115
+ - **high**: Very important for request
116
+ - **medium**: Helpful but not essential
117
+ - **low**: Background context
118
+
119
+ ## Output Format
120
+
121
+ Return JSON with:
122
+ - type: Intent classification
123
+ - confidence: 0-1 (how confident you are)
124
+ - reasoning: Why you classified this way (1 sentence)
125
+ - suggestedImpulses: Array of recommended impulses (0-${cfg.maxImpulses})
126
+
127
+ ## Examples
128
+
129
+ **Input**: "Fix the TypeError in calculator.ts"
130
+ **Output**:
131
+ {
132
+ "type": "code_fix",
133
+ "confidence": 0.95,
134
+ "reasoning": "User reports specific error with file reference",
135
+ "suggestedImpulses": [
136
+ {
137
+ "id": "errorFile",
138
+ "type": "file",
139
+ "description": "File containing the error",
140
+ "priority": "high",
141
+ "budget": 2000,
142
+ "pointer": { "type": "file", "path": "calculator.ts" }
143
+ }
144
+ ]
145
+ }
146
+
147
+ **Input**: "hi"
148
+ **Output**:
149
+ {
150
+ "type": "other",
151
+ "confidence": 1.0,
152
+ "reasoning": "Simple greeting, no coding context needed",
153
+ "suggestedImpulses": []
154
+ }
155
+
156
+ Be conservative with impulses. Quality over quantity. Only suggest what's clearly needed.`;
157
+ // Call LLM
158
+ const result = await llmClient.complete({
159
+ model: cfg.model,
160
+ messages: [
161
+ {
162
+ role: "system",
163
+ content: systemPrompt + "\n\nIMPORTANT: Return ONLY valid JSON matching this schema. No markdown, no explanations.",
164
+ },
165
+ {
166
+ role: "user",
167
+ content: `Analyze this user message and suggest context impulses:\n\n"${input.promptText}"\n\nReturn JSON only.`,
168
+ },
169
+ ],
170
+ maxTokens: 2000,
171
+ temperature: 0.2,
172
+ });
173
+ // Parse JSON response
174
+ let intent;
175
+ try {
176
+ // Remove markdown code blocks if present
177
+ let jsonStr = result.content.trim();
178
+ if (jsonStr.startsWith("```json")) {
179
+ jsonStr = jsonStr.slice(7);
180
+ }
181
+ if (jsonStr.startsWith("```")) {
182
+ jsonStr = jsonStr.slice(3);
183
+ }
184
+ if (jsonStr.endsWith("```")) {
185
+ jsonStr = jsonStr.slice(0, -3);
186
+ }
187
+ const parsed = JSON.parse(jsonStr.trim());
188
+ intent = IntentSchema.parse(parsed);
189
+ }
190
+ catch (parseError) {
191
+ console.warn("[MemoryAgent] Failed to parse LLM response as JSON", {
192
+ error: parseError instanceof Error ? parseError.message : String(parseError),
193
+ response: result.content.slice(0, 200),
194
+ });
195
+ throw new Error("Failed to parse intent analysis response");
196
+ }
197
+ console.log("[MemoryAgent] Analysis complete", {
198
+ type: intent.type,
199
+ confidence: intent.confidence,
200
+ impulseCount: intent.suggestedImpulses.length,
201
+ elapsed: Date.now() - start,
202
+ });
203
+ return intent;
204
+ }
205
+ catch (error) {
206
+ console.warn("[MemoryAgent] Analysis failed, returning fallback", {
207
+ error: error instanceof Error ? error.message : String(error),
208
+ elapsed: Date.now() - start,
209
+ });
210
+ // Fallback: return "other" with no impulses
211
+ return {
212
+ type: "other",
213
+ confidence: 0,
214
+ reasoning: "Analysis failed, proceeding without context",
215
+ suggestedImpulses: [],
216
+ };
217
+ }
218
+ }
219
+ SessionMemoryAgent.analyzeIntent = analyzeIntent;
220
+ /**
221
+ * Prepare impulses based on intent analysis
222
+ * Creates impulses in the impulse store
223
+ */
224
+ async function prepare(input) {
225
+ const start = Date.now();
226
+ try {
227
+ const store = getImpulseStore();
228
+ let created = 0;
229
+ const impulseIds = [];
230
+ // Create impulses from suggestions
231
+ for (const suggestion of input.intent.suggestedImpulses) {
232
+ // Check if impulse already exists
233
+ const existing = store.get(suggestion.id);
234
+ if (existing) {
235
+ console.log("[MemoryAgent] Impulse already exists, skipping", { impulseId: suggestion.id });
236
+ continue;
237
+ }
238
+ // Create impulse (match Impulse type minus loaded/createdAt)
239
+ const impulse = createImpulse({
240
+ id: suggestion.id,
241
+ pointer: suggestion.pointer,
242
+ budget: suggestion.budget,
243
+ priority: suggestion.priority,
244
+ tags: ["memory-agent", `type:${suggestion.type}`],
245
+ });
246
+ created++;
247
+ impulseIds.push(impulse.id);
248
+ console.log("[MemoryAgent] Impulse created", {
249
+ impulseId: impulse.id,
250
+ type: suggestion.type,
251
+ priority: suggestion.priority,
252
+ budget: suggestion.budget,
253
+ });
254
+ }
255
+ console.log("[MemoryAgent] Preparation complete", {
256
+ created,
257
+ elapsed: Date.now() - start,
258
+ });
259
+ return {
260
+ impulsesCreated: created,
261
+ impulseIds,
262
+ };
263
+ }
264
+ catch (error) {
265
+ console.error("[MemoryAgent] Preparation failed", {
266
+ error: error instanceof Error ? error.message : String(error),
267
+ elapsed: Date.now() - start,
268
+ });
269
+ return {
270
+ impulsesCreated: 0,
271
+ impulseIds: [],
272
+ };
273
+ }
274
+ }
275
+ SessionMemoryAgent.prepare = prepare;
276
+ })(SessionMemoryAgent || (SessionMemoryAgent = {}));
277
+ //# sourceMappingURL=memory-agent.js.map