circuit-mcp 1.0.17 → 2.0.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/package.json +1 -1
- package/src/server.js +147 -185
package/package.json
CHANGED
package/src/server.js
CHANGED
|
@@ -74,7 +74,7 @@ async function handleMessage(message, token) {
|
|
|
74
74
|
protocolVersion: '2024-11-05',
|
|
75
75
|
serverInfo: {
|
|
76
76
|
name: 'circuit-mcp',
|
|
77
|
-
version: '
|
|
77
|
+
version: '2.0.0'
|
|
78
78
|
},
|
|
79
79
|
capabilities: {
|
|
80
80
|
tools: {},
|
|
@@ -84,7 +84,6 @@ async function handleMessage(message, token) {
|
|
|
84
84
|
};
|
|
85
85
|
|
|
86
86
|
case 'initialized':
|
|
87
|
-
// No response needed for notification
|
|
88
87
|
return null;
|
|
89
88
|
|
|
90
89
|
case 'tools/list':
|
|
@@ -94,111 +93,114 @@ async function handleMessage(message, token) {
|
|
|
94
93
|
result: {
|
|
95
94
|
tools: [
|
|
96
95
|
{
|
|
97
|
-
name: '
|
|
98
|
-
description: '
|
|
96
|
+
name: 'circuit.priorities',
|
|
97
|
+
description: 'What should I work on? Get ranked priorities with confidence indicators, trends, and memory context.',
|
|
99
98
|
inputSchema: {
|
|
100
99
|
type: 'object',
|
|
101
100
|
properties: {
|
|
101
|
+
lens: {
|
|
102
|
+
type: 'string',
|
|
103
|
+
description: "Focus lens: 'volume', 'urgency', 'revenue', 'retention', 'delight', 'feature'",
|
|
104
|
+
enum: ['volume', 'urgency', 'revenue', 'retention', 'delight', 'feature'],
|
|
105
|
+
default: 'volume'
|
|
106
|
+
},
|
|
107
|
+
segment: {
|
|
108
|
+
type: 'string',
|
|
109
|
+
description: "Filter by customer segment: 'enterprise', 'smb', 'all'",
|
|
110
|
+
default: 'all'
|
|
111
|
+
},
|
|
102
112
|
limit: {
|
|
103
113
|
type: 'number',
|
|
104
|
-
description: 'Number of priorities
|
|
114
|
+
description: 'Number of priorities (default: 5, max: 20)',
|
|
115
|
+
default: 5
|
|
105
116
|
},
|
|
106
|
-
|
|
117
|
+
category: {
|
|
107
118
|
type: 'string',
|
|
108
|
-
description:
|
|
109
|
-
enum: ['
|
|
119
|
+
description: "Filter by category: 'Bug', 'Feature', 'Friction', 'Complaint', 'Praise'",
|
|
120
|
+
enum: ['Bug', 'Feature', 'Friction', 'Complaint', 'Praise']
|
|
110
121
|
}
|
|
111
122
|
}
|
|
112
123
|
}
|
|
113
124
|
},
|
|
114
125
|
{
|
|
115
|
-
name: '
|
|
116
|
-
description: 'Get the full engineering
|
|
126
|
+
name: 'circuit.brief',
|
|
127
|
+
description: 'Get the full engineering spec for a priority. Includes brief content, customer context, version history, and related memory (previous ships, outcomes).',
|
|
117
128
|
inputSchema: {
|
|
118
129
|
type: 'object',
|
|
119
130
|
properties: {
|
|
120
131
|
priority_id: {
|
|
121
132
|
type: 'string',
|
|
122
|
-
description: 'The priority ID
|
|
133
|
+
description: 'The priority ID'
|
|
123
134
|
},
|
|
124
135
|
build_id: {
|
|
125
136
|
type: 'string',
|
|
126
137
|
description: 'The build ID directly (alternative to priority_id)'
|
|
138
|
+
},
|
|
139
|
+
include_history: {
|
|
140
|
+
type: 'boolean',
|
|
141
|
+
description: 'Include version history and related memory',
|
|
142
|
+
default: true
|
|
127
143
|
}
|
|
128
144
|
}
|
|
129
145
|
}
|
|
130
146
|
},
|
|
131
147
|
{
|
|
132
|
-
name: '
|
|
133
|
-
description:
|
|
148
|
+
name: 'circuit.act',
|
|
149
|
+
description: 'Take an action in Circuit. Ship a brief, start building, correct a classification, or submit new feedback.',
|
|
134
150
|
inputSchema: {
|
|
135
151
|
type: 'object',
|
|
136
152
|
properties: {
|
|
137
|
-
|
|
153
|
+
action: {
|
|
138
154
|
type: 'string',
|
|
139
|
-
description: '
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
}
|
|
144
|
-
},
|
|
145
|
-
{
|
|
146
|
-
name: 'mark_shipped',
|
|
147
|
-
description: "Mark a brief as 'shipped' - the feature has shipped! This closes the feedback loop and notifies customers.",
|
|
148
|
-
inputSchema: {
|
|
149
|
-
type: 'object',
|
|
150
|
-
properties: {
|
|
151
|
-
build_id: {
|
|
155
|
+
description: "Action to take: 'build' (start building), 'ship' (mark shipped), 'correct' (fix classification), 'submit' (add feedback)",
|
|
156
|
+
enum: ['build', 'ship', 'correct', 'submit']
|
|
157
|
+
},
|
|
158
|
+
brief_id: {
|
|
152
159
|
type: 'string',
|
|
153
|
-
description:
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
required: ['build_id']
|
|
157
|
-
}
|
|
158
|
-
},
|
|
159
|
-
{
|
|
160
|
-
name: 'mark_done',
|
|
161
|
-
description: "[Deprecated - use mark_shipped] Mark a brief as shipped.",
|
|
162
|
-
inputSchema: {
|
|
163
|
-
type: 'object',
|
|
164
|
-
properties: {
|
|
165
|
-
build_id: {
|
|
160
|
+
description: "Brief ID (for 'build' and 'ship' actions)"
|
|
161
|
+
},
|
|
162
|
+
priority_id: {
|
|
166
163
|
type: 'string',
|
|
167
|
-
description:
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
required: ['build_id']
|
|
171
|
-
}
|
|
172
|
-
},
|
|
173
|
-
{
|
|
174
|
-
name: 'search_feedback',
|
|
175
|
-
description: 'Search customer feedback by keyword. Useful for understanding pain points around specific features.',
|
|
176
|
-
inputSchema: {
|
|
177
|
-
type: 'object',
|
|
178
|
-
properties: {
|
|
179
|
-
query: {
|
|
164
|
+
description: "Priority ID (for 'correct' action)"
|
|
165
|
+
},
|
|
166
|
+
correction_type: {
|
|
180
167
|
type: 'string',
|
|
181
|
-
description:
|
|
168
|
+
description: "What to correct (for 'correct' action): 'category'",
|
|
169
|
+
enum: ['category']
|
|
182
170
|
},
|
|
183
|
-
|
|
184
|
-
type: '
|
|
185
|
-
description: '
|
|
171
|
+
original: {
|
|
172
|
+
type: 'string',
|
|
173
|
+
description: 'Original value being corrected'
|
|
174
|
+
},
|
|
175
|
+
corrected: {
|
|
176
|
+
type: 'string',
|
|
177
|
+
description: 'New corrected value'
|
|
178
|
+
},
|
|
179
|
+
feedback: {
|
|
180
|
+
type: 'string',
|
|
181
|
+
description: "Feedback text (for 'submit' action)"
|
|
182
|
+
},
|
|
183
|
+
source: {
|
|
184
|
+
type: 'string',
|
|
185
|
+
description: "Feedback source (for 'submit' action)",
|
|
186
|
+
default: 'mcp'
|
|
186
187
|
}
|
|
187
188
|
},
|
|
188
|
-
required: ['
|
|
189
|
+
required: ['action']
|
|
189
190
|
}
|
|
190
191
|
},
|
|
191
192
|
{
|
|
192
|
-
name: '
|
|
193
|
-
description: '
|
|
193
|
+
name: 'circuit.ask',
|
|
194
|
+
description: 'Ask anything about your feedback data. Searches across feedback, priorities, briefs, and help articles using semantic search.',
|
|
194
195
|
inputSchema: {
|
|
195
196
|
type: 'object',
|
|
196
197
|
properties: {
|
|
197
|
-
|
|
198
|
-
type: '
|
|
199
|
-
description: '
|
|
198
|
+
question: {
|
|
199
|
+
type: 'string',
|
|
200
|
+
description: "Natural language question (e.g., 'What are enterprise customers complaining about?', 'How do briefs work?')"
|
|
200
201
|
}
|
|
201
|
-
}
|
|
202
|
+
},
|
|
203
|
+
required: ['question']
|
|
202
204
|
}
|
|
203
205
|
}
|
|
204
206
|
]
|
|
@@ -232,7 +234,7 @@ async function handleMessage(message, token) {
|
|
|
232
234
|
}
|
|
233
235
|
|
|
234
236
|
/**
|
|
235
|
-
* Format priorities
|
|
237
|
+
* Format priorities response
|
|
236
238
|
*/
|
|
237
239
|
function formatPriorities(data) {
|
|
238
240
|
if (data.message) {
|
|
@@ -245,47 +247,49 @@ function formatPriorities(data) {
|
|
|
245
247
|
|
|
246
248
|
const lines = [];
|
|
247
249
|
|
|
250
|
+
if (data.memory_applied) {
|
|
251
|
+
lines.push(`*Memory active: ${data.ships_count} ships tracked, segment: ${data.segment_affinity || 'mixed'}*\n`);
|
|
252
|
+
}
|
|
253
|
+
|
|
248
254
|
for (const p of data.priorities) {
|
|
249
|
-
// Format trend indicator like Circuit UI
|
|
250
255
|
let trendText = '';
|
|
251
256
|
if (p.trend === 'up') {
|
|
252
|
-
trendText =
|
|
257
|
+
trendText = ` ↑${p.trend_percent ? ` ${p.trend_percent}%` : ''}`;
|
|
253
258
|
} else if (p.trend === 'down') {
|
|
254
|
-
trendText =
|
|
259
|
+
trendText = ` ↓${p.trend_percent ? ` ${p.trend_percent}%` : ''}`;
|
|
255
260
|
}
|
|
256
261
|
|
|
257
|
-
// Format: #Rank. Title
|
|
258
262
|
lines.push(`**#${p.rank}. ${p.theme}**`);
|
|
259
263
|
|
|
260
|
-
// Badges row: Category | X users | Trend | Status
|
|
261
264
|
const badges = [];
|
|
262
265
|
badges.push(p.category || 'Other');
|
|
263
266
|
badges.push(`${p.volume} users`);
|
|
264
267
|
if (trendText) badges.push(trendText.trim());
|
|
265
268
|
if (p.brief_status && p.brief_status !== 'no_brief') {
|
|
266
|
-
const statusLabel = { ready: 'Ready', building: 'Building', shipped: 'Shipped'
|
|
269
|
+
const statusLabel = { ready: 'Ready', building: 'Building', shipped: 'Shipped' }[p.brief_status];
|
|
267
270
|
if (statusLabel) badges.push(statusLabel);
|
|
268
271
|
}
|
|
272
|
+
if (p.matches_pattern) badges.push('matches pattern');
|
|
273
|
+
if (p.version) badges.push(p.version);
|
|
269
274
|
|
|
270
275
|
lines.push(badges.join(' · '));
|
|
271
276
|
|
|
272
|
-
// Key quote (customer voice)
|
|
273
277
|
if (p.key_quote) {
|
|
274
278
|
lines.push(`> "${p.key_quote}"`);
|
|
275
279
|
}
|
|
276
280
|
|
|
277
|
-
lines.push(`priority_id: \`${p.
|
|
281
|
+
lines.push(`priority_id: \`${p.priority_id}\`${p.build_id ? ` · build_id: \`${p.build_id}\`` : ''}`);
|
|
278
282
|
lines.push('');
|
|
279
283
|
}
|
|
280
284
|
|
|
281
285
|
lines.push('---');
|
|
282
|
-
lines.push('Use `
|
|
286
|
+
lines.push('Use `circuit.brief` with a priority_id to see the full engineering spec.');
|
|
283
287
|
|
|
284
288
|
return lines.join('\n');
|
|
285
289
|
}
|
|
286
290
|
|
|
287
291
|
/**
|
|
288
|
-
* Format brief
|
|
292
|
+
* Format brief response
|
|
289
293
|
*/
|
|
290
294
|
function formatBrief(data) {
|
|
291
295
|
if (data.error) {
|
|
@@ -293,51 +297,31 @@ function formatBrief(data) {
|
|
|
293
297
|
const p = data.priority;
|
|
294
298
|
let output = `# ${p.theme || 'Priority'}\n\n`;
|
|
295
299
|
output += `${p.category || 'Other'} · ${p.volume || 0} users\n\n`;
|
|
296
|
-
output += `**No brief generated yet
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
output += `${p.summary}\n\n`;
|
|
300
|
+
output += `**No brief generated yet.**\n\n`;
|
|
301
|
+
if (data.suggestion) {
|
|
302
|
+
output += `${data.suggestion}\n`;
|
|
300
303
|
}
|
|
301
|
-
|
|
302
|
-
if (p.key_quote) {
|
|
303
|
-
output += `> "${p.key_quote}"\n\n`;
|
|
304
|
-
}
|
|
305
|
-
|
|
306
|
-
output += `---\n\n`;
|
|
307
|
-
|
|
308
|
-
// Include deep link to Circuit
|
|
309
|
-
if (data.circuit_url) {
|
|
310
|
-
output += `**Generate brief:** ${data.circuit_url}\n\n`;
|
|
311
|
-
}
|
|
312
|
-
|
|
313
|
-
output += `Or I can help you draft implementation notes based on the customer feedback above.`;
|
|
314
304
|
return output;
|
|
315
305
|
}
|
|
316
306
|
return `Error: ${data.message || data.error}`;
|
|
317
307
|
}
|
|
318
308
|
|
|
319
309
|
const spec = data.spec_content || '';
|
|
320
|
-
|
|
321
|
-
// Build header like Circuit UI exports
|
|
322
|
-
// Format: # Title
|
|
323
|
-
// Priority: #X | Mentions: Y | Type: Z
|
|
324
|
-
// ---
|
|
325
|
-
// {spec content}
|
|
326
|
-
|
|
327
310
|
let output = '';
|
|
328
311
|
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
}[data.status] || data.status;
|
|
312
|
+
const title = data.title || 'Engineering Brief';
|
|
313
|
+
output += `# ${title}\n\n`;
|
|
314
|
+
|
|
315
|
+
const statusText = { ready: 'Ready', building: 'Building', shipped: 'Shipped' }[data.status] || data.status;
|
|
316
|
+
const versionBadge = data.version_badge ? ` · ${data.version_badge}` : '';
|
|
317
|
+
output += `Status: ${statusText}${versionBadge}\n`;
|
|
336
318
|
|
|
337
|
-
|
|
319
|
+
if (data.customer_context) {
|
|
320
|
+
const ctx = data.customer_context;
|
|
321
|
+
output += `${ctx.category} · ${ctx.volume} users · ${ctx.paying_percent}% paying\n`;
|
|
322
|
+
}
|
|
323
|
+
output += '\n';
|
|
338
324
|
|
|
339
|
-
// The spec_content should already be formatted markdown
|
|
340
|
-
// Clean up any XML-style tags to proper headers
|
|
341
325
|
let cleanSpec = spec
|
|
342
326
|
.replace(/<what_to_build>/gi, '## WHAT TO BUILD\n')
|
|
343
327
|
.replace(/<\/what_to_build>/gi, '\n')
|
|
@@ -352,6 +336,19 @@ function formatBrief(data) {
|
|
|
352
336
|
|
|
353
337
|
output += cleanSpec;
|
|
354
338
|
|
|
339
|
+
if (data.related_memory && data.related_memory.length > 0) {
|
|
340
|
+
output += '\n## WHAT CIRCUIT REMEMBERS\n\n';
|
|
341
|
+
for (const mem of data.related_memory) {
|
|
342
|
+
if (mem.type === 'ship') {
|
|
343
|
+
output += `- Shipped: ${mem.theme || mem.summary || 'Related feature'}\n`;
|
|
344
|
+
} else if (mem.type === 'correction') {
|
|
345
|
+
output += `- Correction: ${mem.summary || 'Classification adjusted'}\n`;
|
|
346
|
+
} else {
|
|
347
|
+
output += `- ${mem.summary || JSON.stringify(mem)}\n`;
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
|
|
355
352
|
output += `\n---\n`;
|
|
356
353
|
output += `build_id: \`${data.build_id}\``;
|
|
357
354
|
|
|
@@ -359,103 +356,76 @@ function formatBrief(data) {
|
|
|
359
356
|
}
|
|
360
357
|
|
|
361
358
|
/**
|
|
362
|
-
* Format
|
|
363
|
-
*/
|
|
364
|
-
function formatSearchResults(data) {
|
|
365
|
-
if (data.message) {
|
|
366
|
-
return data.message;
|
|
367
|
-
}
|
|
368
|
-
|
|
369
|
-
if (!data.results || data.results.length === 0) {
|
|
370
|
-
return 'No feedback found matching your search.';
|
|
371
|
-
}
|
|
372
|
-
|
|
373
|
-
const lines = [`**${data.total} results found**\n`];
|
|
374
|
-
|
|
375
|
-
for (const f of data.results) {
|
|
376
|
-
lines.push(`**${f.source}** · Urgency: ${f.urgency}/5`);
|
|
377
|
-
lines.push(`> "${f.text}"`);
|
|
378
|
-
lines.push('');
|
|
379
|
-
}
|
|
380
|
-
|
|
381
|
-
return lines.join('\n');
|
|
382
|
-
}
|
|
383
|
-
|
|
384
|
-
/**
|
|
385
|
-
* Format status change response
|
|
359
|
+
* Format act response
|
|
386
360
|
*/
|
|
387
|
-
function
|
|
361
|
+
function formatAct(data) {
|
|
388
362
|
if (data.error) {
|
|
389
363
|
return `Error: ${data.error}`;
|
|
390
364
|
}
|
|
391
365
|
|
|
392
366
|
if (data.success) {
|
|
393
|
-
|
|
367
|
+
let output = data.message;
|
|
368
|
+
if (data.memory_created) {
|
|
369
|
+
output += '\nShip memory recorded — Circuit will remember this for future briefs.';
|
|
370
|
+
}
|
|
371
|
+
return output;
|
|
394
372
|
}
|
|
395
373
|
|
|
396
374
|
return JSON.stringify(data, null, 2);
|
|
397
375
|
}
|
|
398
376
|
|
|
399
377
|
/**
|
|
400
|
-
* Format
|
|
378
|
+
* Format ask response
|
|
401
379
|
*/
|
|
402
|
-
function
|
|
380
|
+
function formatAsk(data) {
|
|
403
381
|
if (data.message) {
|
|
404
382
|
return data.message;
|
|
405
383
|
}
|
|
406
384
|
|
|
407
385
|
const lines = [];
|
|
408
386
|
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
if (data.category_breakdown) {
|
|
414
|
-
lines.push('**Category breakdown:**');
|
|
415
|
-
for (const [cat, count] of Object.entries(data.category_breakdown)) {
|
|
416
|
-
lines.push(`- ${cat}: ${count}`);
|
|
387
|
+
if (data.help_articles && data.help_articles.length > 0) {
|
|
388
|
+
lines.push('**Help Articles:**');
|
|
389
|
+
for (const a of data.help_articles) {
|
|
390
|
+
lines.push(`- **${a.title}**: ${a.content}`);
|
|
417
391
|
}
|
|
418
392
|
lines.push('');
|
|
419
393
|
}
|
|
420
394
|
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
lines.push(`- ${p.theme} (${p.volume} users, ${p.category})`);
|
|
395
|
+
if (data.priorities && data.priorities.length > 0) {
|
|
396
|
+
lines.push('**Related Priorities:**');
|
|
397
|
+
for (const p of data.priorities) {
|
|
398
|
+
lines.push(`- ${p.theme} (${p.category}, ${p.volume} users) — priority_id: \`${p.id}\``);
|
|
426
399
|
}
|
|
427
400
|
lines.push('');
|
|
428
401
|
}
|
|
429
402
|
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
if (data.trending_down && data.trending_down.length > 0) {
|
|
435
|
-
lines.push(`**Trending down:** ${data.trending_down.join(', ')}`);
|
|
436
|
-
}
|
|
437
|
-
|
|
438
|
-
// High urgency
|
|
439
|
-
if (data.high_urgency && data.high_urgency.length > 0) {
|
|
440
|
-
lines.push('\n**High urgency items:**');
|
|
441
|
-
for (const h of data.high_urgency) {
|
|
442
|
-
lines.push(`- ${h.theme} (urgency: ${h.urgency})`);
|
|
403
|
+
if (data.feedback && data.feedback.length > 0) {
|
|
404
|
+
lines.push('**Related Feedback:**');
|
|
405
|
+
for (const f of data.feedback) {
|
|
406
|
+
lines.push(`- [${f.source}] "${f.text}"`);
|
|
443
407
|
}
|
|
408
|
+
lines.push('');
|
|
444
409
|
}
|
|
445
410
|
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
lines.push('
|
|
449
|
-
|
|
450
|
-
|
|
411
|
+
if (data.your_patterns) {
|
|
412
|
+
const pat = data.your_patterns;
|
|
413
|
+
lines.push('**Your Patterns:**');
|
|
414
|
+
lines.push(`- Ships: ${pat.ships_count}`);
|
|
415
|
+
lines.push(`- Segment: ${pat.segment_affinity}`);
|
|
416
|
+
if (pat.top_categories) {
|
|
417
|
+
const cats = Object.entries(pat.top_categories).map(([k, v]) => `${k} (${Math.round(v * 100)}%)`).join(', ');
|
|
418
|
+
lines.push(`- Top categories: ${cats}`);
|
|
451
419
|
}
|
|
420
|
+
lines.push('');
|
|
452
421
|
}
|
|
453
422
|
|
|
454
|
-
lines.
|
|
455
|
-
|
|
456
|
-
lines.push(`View full details: ${data.circuit_url}`);
|
|
423
|
+
if (lines.length === 0) {
|
|
424
|
+
return `No results found for "${data.question}". Try rephrasing.`;
|
|
457
425
|
}
|
|
458
426
|
|
|
427
|
+
lines.push(`---\n${data.total} results found`);
|
|
428
|
+
|
|
459
429
|
return lines.join('\n');
|
|
460
430
|
}
|
|
461
431
|
|
|
@@ -466,29 +436,22 @@ async function handleToolCall(id, params, token) {
|
|
|
466
436
|
const { name, arguments: args } = params;
|
|
467
437
|
|
|
468
438
|
try {
|
|
469
|
-
// Call the Circuit MCP backend
|
|
470
439
|
const result = await callMcpApi(token, name, args || {});
|
|
471
440
|
|
|
472
|
-
// Format response based on tool type
|
|
473
441
|
let formattedText;
|
|
474
442
|
|
|
475
443
|
switch (name) {
|
|
476
|
-
case '
|
|
444
|
+
case 'circuit.priorities':
|
|
477
445
|
formattedText = formatPriorities(result);
|
|
478
446
|
break;
|
|
479
|
-
case '
|
|
447
|
+
case 'circuit.brief':
|
|
480
448
|
formattedText = formatBrief(result);
|
|
481
449
|
break;
|
|
482
|
-
case '
|
|
483
|
-
formattedText =
|
|
450
|
+
case 'circuit.act':
|
|
451
|
+
formattedText = formatAct(result);
|
|
484
452
|
break;
|
|
485
|
-
case '
|
|
486
|
-
|
|
487
|
-
case 'mark_done':
|
|
488
|
-
formattedText = formatStatusChange(result);
|
|
489
|
-
break;
|
|
490
|
-
case 'get_insights':
|
|
491
|
-
formattedText = formatInsights(result);
|
|
453
|
+
case 'circuit.ask':
|
|
454
|
+
formattedText = formatAsk(result);
|
|
492
455
|
break;
|
|
493
456
|
default:
|
|
494
457
|
formattedText = JSON.stringify(result, null, 2);
|
|
@@ -510,4 +473,3 @@ async function handleToolCall(id, params, token) {
|
|
|
510
473
|
};
|
|
511
474
|
}
|
|
512
475
|
}
|
|
513
|
-
|