couchloop-eq-mcp 1.1.4 → 1.2.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 +40 -38
- package/dist/clients/shrinkChatClient.d.ts +10 -10
- package/dist/index.js +81 -6
- package/dist/index.js.map +1 -1
- package/dist/server/http-mcp.d.ts.map +1 -1
- package/dist/server/http-mcp.js +17 -3
- package/dist/server/http-mcp.js.map +1 -1
- package/dist/server/sse.js +1 -1
- package/dist/tools/check-versions.d.ts +4 -4
- package/dist/tools/checkpoint.d.ts +2 -19
- package/dist/tools/checkpoint.d.ts.map +1 -1
- package/dist/tools/checkpoint.js +68 -2
- package/dist/tools/checkpoint.js.map +1 -1
- package/dist/tools/comprehensive-code-review.d.ts +78 -0
- package/dist/tools/comprehensive-code-review.d.ts.map +1 -0
- package/dist/tools/comprehensive-code-review.js +177 -0
- package/dist/tools/comprehensive-code-review.js.map +1 -0
- package/dist/tools/comprehensive-package-audit.d.ts +75 -0
- package/dist/tools/comprehensive-package-audit.d.ts.map +1 -0
- package/dist/tools/comprehensive-package-audit.js +151 -0
- package/dist/tools/comprehensive-package-audit.js.map +1 -0
- package/dist/tools/detect-build-context.d.ts +59 -0
- package/dist/tools/detect-build-context.d.ts.map +1 -0
- package/dist/tools/detect-build-context.js +80 -0
- package/dist/tools/detect-build-context.js.map +1 -0
- package/dist/tools/generate-upgrade-report.d.ts +85 -0
- package/dist/tools/generate-upgrade-report.d.ts.map +1 -0
- package/dist/tools/generate-upgrade-report.js +102 -0
- package/dist/tools/generate-upgrade-report.js.map +1 -0
- package/dist/tools/index-full.d.ts +1355 -0
- package/dist/tools/index-full.d.ts.map +1 -0
- package/dist/tools/index-full.js +611 -0
- package/dist/tools/index-full.js.map +1 -0
- package/dist/tools/index.d.ts +27 -1018
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +29 -554
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/insight.d.ts +31 -12
- package/dist/tools/insight.d.ts.map +1 -1
- package/dist/tools/insight.js +2 -1
- package/dist/tools/insight.js.map +1 -1
- package/dist/tools/intent-router.d.ts +142 -0
- package/dist/tools/intent-router.d.ts.map +1 -0
- package/dist/tools/intent-router.js +453 -0
- package/dist/tools/intent-router.js.map +1 -0
- package/dist/tools/prevent-ai-errors.d.ts +85 -0
- package/dist/tools/prevent-ai-errors.d.ts.map +1 -0
- package/dist/tools/prevent-ai-errors.js +97 -0
- package/dist/tools/prevent-ai-errors.js.map +1 -0
- package/dist/tools/primary-tools.d.ts +615 -0
- package/dist/tools/primary-tools.d.ts.map +1 -0
- package/dist/tools/primary-tools.js +355 -0
- package/dist/tools/primary-tools.js.map +1 -0
- package/dist/tools/protect-files.d.ts +1 -1
- package/dist/tools/sendMessage.d.ts.map +1 -1
- package/dist/tools/sendMessage.js +17 -152
- package/dist/tools/sendMessage.js.map +1 -1
- package/dist/tools/session.d.ts +1 -1
- package/dist/tools/smart-context.d.ts +66 -0
- package/dist/tools/smart-context.d.ts.map +1 -0
- package/dist/tools/smart-context.js +167 -0
- package/dist/tools/smart-context.js.map +1 -0
- package/dist/tools/status.d.ts +118 -0
- package/dist/tools/status.d.ts.map +1 -0
- package/dist/tools/status.js +366 -0
- package/dist/tools/status.js.map +1 -0
- package/dist/tools/verify.d.ts +126 -0
- package/dist/tools/verify.d.ts.map +1 -0
- package/dist/tools/verify.js +308 -0
- package/dist/tools/verify.js.map +1 -0
- package/dist/types/checkpoint.d.ts +26 -1
- package/dist/types/checkpoint.d.ts.map +1 -1
- package/dist/types/checkpoint.js +17 -0
- package/dist/types/checkpoint.js.map +1 -1
- package/dist/types/insight.d.ts +2 -2
- package/dist/types/journey.d.ts +18 -18
- package/dist/types/session.d.ts +2 -2
- package/dist/utils/sanitize.d.ts +24 -0
- package/dist/utils/sanitize.d.ts.map +1 -0
- package/dist/utils/sanitize.js +117 -0
- package/dist/utils/sanitize.js.map +1 -0
- package/dist/workflows/engine.d.ts +2 -1
- package/dist/workflows/engine.d.ts.map +1 -1
- package/dist/workflows/engine.js +7 -1
- package/dist/workflows/engine.js.map +1 -1
- package/dist/workflows/index.d.ts +3 -3
- package/package.json +1 -1
|
@@ -0,0 +1,355 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP Tools - Public API
|
|
3
|
+
*
|
|
4
|
+
* This module exports only the PRIMARY tools that users should see.
|
|
5
|
+
* All granular tools are internal engines used by these primary tools.
|
|
6
|
+
*
|
|
7
|
+
* PUBLIC TOOLS (8):
|
|
8
|
+
* 0. couchloop - Intent router (discoverability layer for loose commands)
|
|
9
|
+
* 1. verify - Pre-delivery verification (catches AI hallucinations, validates packages)
|
|
10
|
+
* 2. status - Dashboard (session progress, history, context, protection)
|
|
11
|
+
* 3. conversation - Therapeutic AI conversation with governance
|
|
12
|
+
* 4. code_review - Complete code analysis (security, quality, AI errors)
|
|
13
|
+
* 5. package_audit - Complete dependency audit (validation, versions, upgrades)
|
|
14
|
+
* 6. remember - Smart context capture (checkpoints, insights, decisions)
|
|
15
|
+
* 7. protect - File protection and safety features
|
|
16
|
+
*/
|
|
17
|
+
import { intentRouterTool, registerTools } from './intent-router.js';
|
|
18
|
+
import { sendMessage } from './sendMessage.js';
|
|
19
|
+
import { createSession, resumeSession } from './session.js';
|
|
20
|
+
import { endSession } from './session-manager.js';
|
|
21
|
+
import { handleComprehensiveCodeReview } from './comprehensive-code-review.js';
|
|
22
|
+
import { handleComprehensivePackageAudit } from './comprehensive-package-audit.js';
|
|
23
|
+
import { handleSmartContext } from './smart-context.js';
|
|
24
|
+
import { protectFiles, getProtectionStatus, listBackups, rollbackFile, enableCodeFreeze, disableCodeFreeze, } from './protect-files.js';
|
|
25
|
+
import { listJourneys, getJourneyStatus } from './journey.js';
|
|
26
|
+
import { getCheckpoints } from './checkpoint.js';
|
|
27
|
+
import { getInsights, getUserContext } from './insight.js';
|
|
28
|
+
import { verifyTool } from './verify.js';
|
|
29
|
+
import { statusTool } from './status.js';
|
|
30
|
+
import { logger } from '../utils/logger.js';
|
|
31
|
+
// ============================================================
|
|
32
|
+
// PRIMARY TOOL DEFINITIONS
|
|
33
|
+
// These are the only tools visible to users
|
|
34
|
+
// ============================================================
|
|
35
|
+
// Brainstorm system prompt - reflective questioning to help developers arrive at their own solutions
|
|
36
|
+
const BRAINSTORM_SYSTEM_PROMPT = `You are a reflective thinking partner for developers. Your primary role is to ask insightful questions that help developers discover their own best solution — but you also provide concrete analysis when they've narrowed down options.
|
|
37
|
+
|
|
38
|
+
DETECT THE MODE:
|
|
39
|
+
1. EXPLORATION: User has a vague idea or open-ended problem → Ask questions to help them think
|
|
40
|
+
2. COMPARISON: User presents 2-3 specific options (e.g., "Redis vs Memcached?") → Clarify context briefly, then provide analysis
|
|
41
|
+
|
|
42
|
+
FOR EXPLORATION MODE:
|
|
43
|
+
- Ask clarifying questions before suggesting anything
|
|
44
|
+
- Surface assumptions they may not have questioned
|
|
45
|
+
- Break complex problems into smaller, answerable pieces
|
|
46
|
+
- Ask 1-3 focused questions per response (not a barrage)
|
|
47
|
+
|
|
48
|
+
QUESTION PATTERNS:
|
|
49
|
+
1. SCOPE: "What problem are you really trying to solve?" / "Who is this for?"
|
|
50
|
+
2. CONSTRAINTS: "What's your timeline?" / "What existing systems does this need to work with?"
|
|
51
|
+
3. TRADE-OFFS: "If you had to choose between X and Y, which matters more?"
|
|
52
|
+
4. ASSUMPTIONS: "What are you assuming about the user?" / "Have you validated that?"
|
|
53
|
+
5. DECOMPOSITION: "What's the riskiest part?" / "What could you build first to learn more?"
|
|
54
|
+
|
|
55
|
+
FOR COMPARISON MODE (user asks "A vs B?" or "should I use X or Y?"):
|
|
56
|
+
1. Ask 1-2 quick clarifying questions about their specific context (scale, team experience, existing stack)
|
|
57
|
+
2. Then provide a structured comparison:
|
|
58
|
+
- Key differences that matter for their use case
|
|
59
|
+
- When to choose each option
|
|
60
|
+
- Your recommendation given what you know about their context
|
|
61
|
+
- Caveats or "it depends" factors they should verify
|
|
62
|
+
3. Be direct. Don't just list pros/cons — give them an actionable recommendation with reasoning.
|
|
63
|
+
|
|
64
|
+
RESPONSE STYLE:
|
|
65
|
+
- Start with understanding, not solutioning
|
|
66
|
+
- Summarize their thinking back periodically
|
|
67
|
+
- When they present options, acknowledge you'll help them decide (not just explore forever)
|
|
68
|
+
- Be concise — developers want signal, not fluff
|
|
69
|
+
|
|
70
|
+
Remember: The best solutions come from the developer's own understanding of their context. Your job is to help them think clearly AND give them useful analysis when they're ready for it.`;
|
|
71
|
+
const conversationTool = {
|
|
72
|
+
definition: {
|
|
73
|
+
name: 'conversation',
|
|
74
|
+
description: 'Start or continue an AI conversation with built-in crisis detection, emotional support, and session memory. Includes brainstorm mode for dev ideation. Triggers: "end session", "start session", "wrap up", "done for now", "talk", "chat", "feeling", "stressed", "help me", "brainstorm", "think through", "map out feature".',
|
|
75
|
+
annotations: {
|
|
76
|
+
readOnlyHint: false,
|
|
77
|
+
destructiveHint: false,
|
|
78
|
+
openWorldHint: true,
|
|
79
|
+
},
|
|
80
|
+
inputSchema: {
|
|
81
|
+
type: 'object',
|
|
82
|
+
properties: {
|
|
83
|
+
message: {
|
|
84
|
+
type: 'string',
|
|
85
|
+
description: 'Your message',
|
|
86
|
+
},
|
|
87
|
+
action: {
|
|
88
|
+
type: 'string',
|
|
89
|
+
enum: ['send', 'start', 'end', 'resume', 'status', 'brainstorm'],
|
|
90
|
+
description: 'Action: send (default), start new session, end session, resume previous, get status, or brainstorm (dev thinking partner)',
|
|
91
|
+
},
|
|
92
|
+
journey: {
|
|
93
|
+
type: 'string',
|
|
94
|
+
description: 'Optional journey to follow (e.g., "daily-reflection")',
|
|
95
|
+
},
|
|
96
|
+
session_id: {
|
|
97
|
+
type: 'string',
|
|
98
|
+
description: 'Session ID (auto-managed if not provided)',
|
|
99
|
+
},
|
|
100
|
+
},
|
|
101
|
+
required: ['message'],
|
|
102
|
+
},
|
|
103
|
+
},
|
|
104
|
+
handler: async (args) => {
|
|
105
|
+
const action = args.action || 'send';
|
|
106
|
+
switch (action) {
|
|
107
|
+
case 'start':
|
|
108
|
+
return createSession({
|
|
109
|
+
journey_slug: args.journey,
|
|
110
|
+
context: args.message,
|
|
111
|
+
});
|
|
112
|
+
case 'end':
|
|
113
|
+
return endSession(args.session_id);
|
|
114
|
+
case 'resume':
|
|
115
|
+
return resumeSession({ session_id: args.session_id });
|
|
116
|
+
case 'status':
|
|
117
|
+
if (args.session_id) {
|
|
118
|
+
return getJourneyStatus({ session_id: args.session_id });
|
|
119
|
+
}
|
|
120
|
+
return listJourneys({});
|
|
121
|
+
case 'brainstorm':
|
|
122
|
+
// Dev thinking partner - reflective questioning mode
|
|
123
|
+
return sendMessage({
|
|
124
|
+
message: args.message,
|
|
125
|
+
session_id: args.session_id,
|
|
126
|
+
system_prompt: BRAINSTORM_SYSTEM_PROMPT,
|
|
127
|
+
conversation_type: 'brainstorm',
|
|
128
|
+
save_checkpoint: true,
|
|
129
|
+
});
|
|
130
|
+
case 'send':
|
|
131
|
+
default:
|
|
132
|
+
return sendMessage({
|
|
133
|
+
message: args.message,
|
|
134
|
+
session_id: args.session_id,
|
|
135
|
+
save_checkpoint: true,
|
|
136
|
+
include_memory: true,
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
},
|
|
140
|
+
};
|
|
141
|
+
const codeReviewTool = {
|
|
142
|
+
definition: {
|
|
143
|
+
name: 'code_review',
|
|
144
|
+
description: 'Complete code review: security vulnerabilities (SQL injection, XSS, secrets), code quality (console.logs, TODOs, error handling), code smells (complexity, bloat), and AI-generated errors (hallucinated APIs, build context issues). One call, full analysis. Triggers: "review", "check code", "analyze", "security check", "lint", "find bugs", "is this safe".',
|
|
145
|
+
annotations: {
|
|
146
|
+
readOnlyHint: true,
|
|
147
|
+
destructiveHint: false,
|
|
148
|
+
openWorldHint: false,
|
|
149
|
+
},
|
|
150
|
+
inputSchema: {
|
|
151
|
+
type: 'object',
|
|
152
|
+
properties: {
|
|
153
|
+
code: {
|
|
154
|
+
type: 'string',
|
|
155
|
+
description: 'Code to review',
|
|
156
|
+
},
|
|
157
|
+
language: {
|
|
158
|
+
type: 'string',
|
|
159
|
+
description: 'Programming language (auto-detected if not specified)',
|
|
160
|
+
},
|
|
161
|
+
auto_fix: {
|
|
162
|
+
type: 'boolean',
|
|
163
|
+
description: 'Attempt to auto-fix issues (default: false)',
|
|
164
|
+
},
|
|
165
|
+
},
|
|
166
|
+
required: ['code'],
|
|
167
|
+
},
|
|
168
|
+
},
|
|
169
|
+
handler: handleComprehensiveCodeReview,
|
|
170
|
+
};
|
|
171
|
+
const packageAuditTool = {
|
|
172
|
+
definition: {
|
|
173
|
+
name: 'package_audit',
|
|
174
|
+
description: 'Complete dependency audit: validates packages exist and are legitimate (catches typosquatting), checks for outdated versions and security vulnerabilities, generates upgrade reports with migration guides and breaking changes. Triggers: "audit", "check dependencies", "outdated", "vulnerable packages", "upgrade", "npm audit", "security scan".',
|
|
175
|
+
annotations: {
|
|
176
|
+
readOnlyHint: true,
|
|
177
|
+
destructiveHint: false,
|
|
178
|
+
openWorldHint: true,
|
|
179
|
+
},
|
|
180
|
+
inputSchema: {
|
|
181
|
+
type: 'object',
|
|
182
|
+
properties: {
|
|
183
|
+
packages: {
|
|
184
|
+
type: 'array',
|
|
185
|
+
items: { type: 'string' },
|
|
186
|
+
description: 'Package names to audit',
|
|
187
|
+
},
|
|
188
|
+
registry: {
|
|
189
|
+
type: 'string',
|
|
190
|
+
enum: ['npm', 'pypi', 'maven', 'cargo', 'go', 'nuget', 'gem'],
|
|
191
|
+
description: 'Package registry (default: npm)',
|
|
192
|
+
},
|
|
193
|
+
},
|
|
194
|
+
required: ['packages'],
|
|
195
|
+
},
|
|
196
|
+
},
|
|
197
|
+
handler: handleComprehensivePackageAudit,
|
|
198
|
+
};
|
|
199
|
+
const rememberTool = {
|
|
200
|
+
definition: {
|
|
201
|
+
name: 'remember',
|
|
202
|
+
description: 'Capture and preserve important context from conversations. Automatically routes to the right storage: checkpoints for progress, insights for realizations, context for technical decisions. Prevents AI amnesia across conversations. Triggers: "save", "remember this", "checkpoint", "note", "don\'t forget", "keep track", "save progress", "log this".',
|
|
203
|
+
annotations: {
|
|
204
|
+
readOnlyHint: false,
|
|
205
|
+
destructiveHint: false,
|
|
206
|
+
openWorldHint: false,
|
|
207
|
+
},
|
|
208
|
+
inputSchema: {
|
|
209
|
+
type: 'object',
|
|
210
|
+
properties: {
|
|
211
|
+
content: {
|
|
212
|
+
type: 'string',
|
|
213
|
+
description: 'What to remember',
|
|
214
|
+
},
|
|
215
|
+
type: {
|
|
216
|
+
type: 'string',
|
|
217
|
+
enum: ['checkpoint', 'insight', 'decision', 'requirement', 'constraint', 'pattern'],
|
|
218
|
+
description: 'Type of context (affects where it\'s stored)',
|
|
219
|
+
},
|
|
220
|
+
tags: {
|
|
221
|
+
type: 'array',
|
|
222
|
+
items: { type: 'string' },
|
|
223
|
+
description: 'Tags for categorization',
|
|
224
|
+
},
|
|
225
|
+
action: {
|
|
226
|
+
type: 'string',
|
|
227
|
+
enum: ['save', 'recall', 'list'],
|
|
228
|
+
description: 'Action: save (default), recall previous context, or list saved items',
|
|
229
|
+
},
|
|
230
|
+
session_id: {
|
|
231
|
+
type: 'string',
|
|
232
|
+
description: 'Session to associate with',
|
|
233
|
+
},
|
|
234
|
+
},
|
|
235
|
+
required: ['content'],
|
|
236
|
+
},
|
|
237
|
+
},
|
|
238
|
+
handler: async (args) => {
|
|
239
|
+
const action = args.action || 'save';
|
|
240
|
+
const sessionId = args.session_id;
|
|
241
|
+
switch (action) {
|
|
242
|
+
case 'recall': {
|
|
243
|
+
// Get checkpoints and insights
|
|
244
|
+
const checkpoints = await getCheckpoints({ session_id: sessionId });
|
|
245
|
+
const insights = await getInsights({ session_id: sessionId, limit: 10 });
|
|
246
|
+
const userContext = await getUserContext({ include_recent_insights: true, include_session_history: true });
|
|
247
|
+
return {
|
|
248
|
+
checkpoints,
|
|
249
|
+
insights,
|
|
250
|
+
user_context: userContext,
|
|
251
|
+
};
|
|
252
|
+
}
|
|
253
|
+
case 'list':
|
|
254
|
+
return getInsights({ session_id: sessionId, limit: 20 });
|
|
255
|
+
case 'save':
|
|
256
|
+
default:
|
|
257
|
+
return handleSmartContext({
|
|
258
|
+
content: args.content,
|
|
259
|
+
type: args.type || 'insight',
|
|
260
|
+
tags: args.tags,
|
|
261
|
+
session_id: args.session_id,
|
|
262
|
+
});
|
|
263
|
+
}
|
|
264
|
+
},
|
|
265
|
+
};
|
|
266
|
+
const protectTool = {
|
|
267
|
+
definition: {
|
|
268
|
+
name: 'protect',
|
|
269
|
+
description: 'File protection and safety: prevent accidental deletions, create automatic backups, rollback changes, enable code freeze mode. Essential for safe AI-assisted development. Triggers: "backup", "protect", "freeze", "rollback", "undo", "restore", "safe mode".',
|
|
270
|
+
annotations: {
|
|
271
|
+
readOnlyHint: false,
|
|
272
|
+
destructiveHint: false,
|
|
273
|
+
openWorldHint: false,
|
|
274
|
+
},
|
|
275
|
+
inputSchema: {
|
|
276
|
+
type: 'object',
|
|
277
|
+
properties: {
|
|
278
|
+
action: {
|
|
279
|
+
type: 'string',
|
|
280
|
+
enum: ['check', 'backup', 'rollback', 'freeze', 'unfreeze', 'status', 'history'],
|
|
281
|
+
description: 'Action to perform',
|
|
282
|
+
},
|
|
283
|
+
path: {
|
|
284
|
+
type: 'string',
|
|
285
|
+
description: 'File path (for check, backup, rollback)',
|
|
286
|
+
},
|
|
287
|
+
operation: {
|
|
288
|
+
type: 'string',
|
|
289
|
+
enum: ['delete', 'overwrite', 'move'],
|
|
290
|
+
description: 'Operation type (for check)',
|
|
291
|
+
},
|
|
292
|
+
backup_id: {
|
|
293
|
+
type: 'string',
|
|
294
|
+
description: 'Backup ID (for rollback)',
|
|
295
|
+
},
|
|
296
|
+
},
|
|
297
|
+
required: ['action'],
|
|
298
|
+
},
|
|
299
|
+
},
|
|
300
|
+
handler: async (args) => {
|
|
301
|
+
const action = args.action;
|
|
302
|
+
switch (action) {
|
|
303
|
+
case 'check':
|
|
304
|
+
return protectFiles({
|
|
305
|
+
operation: args.operation,
|
|
306
|
+
path: args.path,
|
|
307
|
+
});
|
|
308
|
+
case 'status':
|
|
309
|
+
return getProtectionStatus({});
|
|
310
|
+
case 'history':
|
|
311
|
+
return listBackups({});
|
|
312
|
+
case 'rollback':
|
|
313
|
+
return rollbackFile({ backup_id: args.backup_id });
|
|
314
|
+
case 'freeze':
|
|
315
|
+
return enableCodeFreeze({});
|
|
316
|
+
case 'unfreeze':
|
|
317
|
+
return disableCodeFreeze({});
|
|
318
|
+
case 'backup':
|
|
319
|
+
// Create a backup by doing a protected check
|
|
320
|
+
return protectFiles({
|
|
321
|
+
operation: 'overwrite',
|
|
322
|
+
path: args.path,
|
|
323
|
+
});
|
|
324
|
+
default:
|
|
325
|
+
return { error: `Unknown action: ${action}` };
|
|
326
|
+
}
|
|
327
|
+
},
|
|
328
|
+
};
|
|
329
|
+
// ============================================================
|
|
330
|
+
// EXPORT ONLY PRIMARY TOOLS
|
|
331
|
+
// ============================================================
|
|
332
|
+
export async function setupTools() {
|
|
333
|
+
// Domain-specific tools (order matters for some clients)
|
|
334
|
+
const domainTools = [
|
|
335
|
+
verifyTool, // Pre-delivery verification (critical for catching AI errors)
|
|
336
|
+
statusTool, // Dashboard and status checks
|
|
337
|
+
conversationTool,
|
|
338
|
+
codeReviewTool,
|
|
339
|
+
packageAuditTool,
|
|
340
|
+
rememberTool,
|
|
341
|
+
protectTool,
|
|
342
|
+
];
|
|
343
|
+
// Register domain tools with intent router for internal invocation
|
|
344
|
+
registerTools(domainTools);
|
|
345
|
+
// Intent router (couchloop) goes FIRST for maximum discoverability
|
|
346
|
+
const tools = [
|
|
347
|
+
intentRouterTool,
|
|
348
|
+
...domainTools,
|
|
349
|
+
];
|
|
350
|
+
logger.info(`Prepared ${tools.length} primary MCP tools (including intent router)`);
|
|
351
|
+
return tools;
|
|
352
|
+
}
|
|
353
|
+
// Also export for internal use
|
|
354
|
+
export { handleComprehensiveCodeReview, handleComprehensivePackageAudit, handleSmartContext, };
|
|
355
|
+
//# sourceMappingURL=primary-tools.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"primary-tools.js","sourceRoot":"","sources":["../../src/tools/primary-tools.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACrE,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC5D,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAClD,OAAO,EAAE,6BAA6B,EAAE,MAAM,gCAAgC,CAAC;AAC/E,OAAO,EAAE,+BAA+B,EAAE,MAAM,kCAAkC,CAAC;AACnF,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AACxD,OAAO,EACL,YAAY,EACZ,mBAAmB,EACnB,WAAW,EACX,YAAY,EACZ,gBAAgB,EAChB,iBAAiB,GAClB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAC9D,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC3D,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAE5C,+DAA+D;AAC/D,2BAA2B;AAC3B,4CAA4C;AAC5C,+DAA+D;AAE/D,qGAAqG;AACrG,MAAM,wBAAwB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2LAkC0J,CAAC;AAE5L,MAAM,gBAAgB,GAAG;IACvB,UAAU,EAAE;QACV,IAAI,EAAE,cAAc;QACpB,WAAW,EAAE,iUAAiU;QAC9U,WAAW,EAAE;YACX,YAAY,EAAE,KAAK;YACnB,eAAe,EAAE,KAAK;YACtB,aAAa,EAAE,IAAI;SACpB;QACD,WAAW,EAAE;YACX,IAAI,EAAE,QAAQ;YACd,UAAU,EAAE;gBACV,OAAO,EAAE;oBACP,IAAI,EAAE,QAAQ;oBACd,WAAW,EAAE,cAAc;iBAC5B;gBACD,MAAM,EAAE;oBACN,IAAI,EAAE,QAAQ;oBACd,IAAI,EAAE,CAAC,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,YAAY,CAAC;oBAChE,WAAW,EAAE,2HAA2H;iBACzI;gBACD,OAAO,EAAE;oBACP,IAAI,EAAE,QAAQ;oBACd,WAAW,EAAE,uDAAuD;iBACrE;gBACD,UAAU,EAAE;oBACV,IAAI,EAAE,QAAQ;oBACd,WAAW,EAAE,2CAA2C;iBACzD;aACF;YACD,QAAQ,EAAE,CAAC,SAAS,CAAC;SACtB;KACF;IACD,OAAO,EAAE,KAAK,EAAE,IAA6B,EAAE,EAAE;QAC/C,MAAM,MAAM,GAAI,IAAI,CAAC,MAAiB,IAAI,MAAM,CAAC;QAEjD,QAAQ,MAAM,EAAE,CAAC;YACf,KAAK,OAAO;gBACV,OAAO,aAAa,CAAC;oBACnB,YAAY,EAAE,IAAI,CAAC,OAAiB;oBACpC,OAAO,EAAE,IAAI,CAAC,OAAiB;iBAChC,CAAC,CAAC;YACL,KAAK,KAAK;gBACR,OAAO,UAAU,CAAC,IAAI,CAAC,UAAoB,CAAC,CAAC;YAC/C,KAAK,QAAQ;gBACX,OAAO,aAAa,CAAC,EAAE,UAAU,EAAE,IAAI,CAAC,UAAoB,EAAE,CAAC,CAAC;YAClE,KAAK,QAAQ;gBACX,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;oBACpB,OAAO,gBAAgB,CAAC,EAAE,UAAU,EAAE,IAAI,CAAC,UAAoB,EAAE,CAAC,CAAC;gBACrE,CAAC;gBACD,OAAO,YAAY,CAAC,EAAE,CAAC,CAAC;YAC1B,KAAK,YAAY;gBACf,qDAAqD;gBACrD,OAAO,WAAW,CAAC;oBACjB,OAAO,EAAE,IAAI,CAAC,OAAO;oBACrB,UAAU,EAAE,IAAI,CAAC,UAAU;oBAC3B,aAAa,EAAE,wBAAwB;oBACvC,iBAAiB,EAAE,YAAY;oBAC/B,eAAe,EAAE,IAAI;iBACtB,CAAC,CAAC;YACL,KAAK,MAAM,CAAC;YACZ;gBACE,OAAO,WAAW,CAAC;oBACjB,OAAO,EAAE,IAAI,CAAC,OAAO;oBACrB,UAAU,EAAE,IAAI,CAAC,UAAU;oBAC3B,eAAe,EAAE,IAAI;oBACrB,cAAc,EAAE,IAAI;iBACrB,CAAC,CAAC;QACP,CAAC;IACH,CAAC;CACF,CAAC;AAEF,MAAM,cAAc,GAAG;IACrB,UAAU,EAAE;QACV,IAAI,EAAE,aAAa;QACnB,WAAW,EAAE,oWAAoW;QACjX,WAAW,EAAE;YACX,YAAY,EAAE,IAAI;YAClB,eAAe,EAAE,KAAK;YACtB,aAAa,EAAE,KAAK;SACrB;QACD,WAAW,EAAE;YACX,IAAI,EAAE,QAAQ;YACd,UAAU,EAAE;gBACV,IAAI,EAAE;oBACJ,IAAI,EAAE,QAAQ;oBACd,WAAW,EAAE,gBAAgB;iBAC9B;gBACD,QAAQ,EAAE;oBACR,IAAI,EAAE,QAAQ;oBACd,WAAW,EAAE,uDAAuD;iBACrE;gBACD,QAAQ,EAAE;oBACR,IAAI,EAAE,SAAS;oBACf,WAAW,EAAE,6CAA6C;iBAC3D;aACF;YACD,QAAQ,EAAE,CAAC,MAAM,CAAC;SACnB;KACF;IACD,OAAO,EAAE,6BAA6B;CACvC,CAAC;AAEF,MAAM,gBAAgB,GAAG;IACvB,UAAU,EAAE;QACV,IAAI,EAAE,eAAe;QACrB,WAAW,EAAE,uVAAuV;QACpW,WAAW,EAAE;YACX,YAAY,EAAE,IAAI;YAClB,eAAe,EAAE,KAAK;YACtB,aAAa,EAAE,IAAI;SACpB;QACD,WAAW,EAAE;YACX,IAAI,EAAE,QAAQ;YACd,UAAU,EAAE;gBACV,QAAQ,EAAE;oBACR,IAAI,EAAE,OAAO;oBACb,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;oBACzB,WAAW,EAAE,wBAAwB;iBACtC;gBACD,QAAQ,EAAE;oBACR,IAAI,EAAE,QAAQ;oBACd,IAAI,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,CAAC;oBAC7D,WAAW,EAAE,iCAAiC;iBAC/C;aACF;YACD,QAAQ,EAAE,CAAC,UAAU,CAAC;SACvB;KACF;IACD,OAAO,EAAE,+BAA+B;CACzC,CAAC;AAEF,MAAM,YAAY,GAAG;IACnB,UAAU,EAAE;QACV,IAAI,EAAE,UAAU;QAChB,WAAW,EAAE,4VAA4V;QACzW,WAAW,EAAE;YACX,YAAY,EAAE,KAAK;YACnB,eAAe,EAAE,KAAK;YACtB,aAAa,EAAE,KAAK;SACrB;QACD,WAAW,EAAE;YACX,IAAI,EAAE,QAAQ;YACd,UAAU,EAAE;gBACV,OAAO,EAAE;oBACP,IAAI,EAAE,QAAQ;oBACd,WAAW,EAAE,kBAAkB;iBAChC;gBACD,IAAI,EAAE;oBACJ,IAAI,EAAE,QAAQ;oBACd,IAAI,EAAE,CAAC,YAAY,EAAE,SAAS,EAAE,UAAU,EAAE,aAAa,EAAE,YAAY,EAAE,SAAS,CAAC;oBACnF,WAAW,EAAE,8CAA8C;iBAC5D;gBACD,IAAI,EAAE;oBACJ,IAAI,EAAE,OAAO;oBACb,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;oBACzB,WAAW,EAAE,yBAAyB;iBACvC;gBACD,MAAM,EAAE;oBACN,IAAI,EAAE,QAAQ;oBACd,IAAI,EAAE,CAAC,MAAM,EAAE,QAAQ,EAAE,MAAM,CAAC;oBAChC,WAAW,EAAE,sEAAsE;iBACpF;gBACD,UAAU,EAAE;oBACV,IAAI,EAAE,QAAQ;oBACd,WAAW,EAAE,2BAA2B;iBACzC;aACF;YACD,QAAQ,EAAE,CAAC,SAAS,CAAC;SACtB;KACF;IACD,OAAO,EAAE,KAAK,EAAE,IAA6B,EAAE,EAAE;QAC/C,MAAM,MAAM,GAAI,IAAI,CAAC,MAAiB,IAAI,MAAM,CAAC;QACjD,MAAM,SAAS,GAAG,IAAI,CAAC,UAAgC,CAAC;QAExD,QAAQ,MAAM,EAAE,CAAC;YACf,KAAK,QAAQ,CAAC,CAAC,CAAC;gBACd,+BAA+B;gBAC/B,MAAM,WAAW,GAAG,MAAM,cAAc,CAAC,EAAE,UAAU,EAAE,SAAS,EAAE,CAAC,CAAC;gBACpE,MAAM,QAAQ,GAAG,MAAM,WAAW,CAAC,EAAE,UAAU,EAAE,SAAS,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,CAAC;gBACzE,MAAM,WAAW,GAAG,MAAM,cAAc,CAAC,EAAE,uBAAuB,EAAE,IAAI,EAAE,uBAAuB,EAAE,IAAI,EAAE,CAAC,CAAC;gBAC3G,OAAO;oBACL,WAAW;oBACX,QAAQ;oBACR,YAAY,EAAE,WAAW;iBAC1B,CAAC;YACJ,CAAC;YACD,KAAK,MAAM;gBACT,OAAO,WAAW,CAAC,EAAE,UAAU,EAAE,SAAS,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,CAAC;YAC3D,KAAK,MAAM,CAAC;YACZ;gBACE,OAAO,kBAAkB,CAAC;oBACxB,OAAO,EAAE,IAAI,CAAC,OAAO;oBACrB,IAAI,EAAE,IAAI,CAAC,IAAI,IAAI,SAAS;oBAC5B,IAAI,EAAE,IAAI,CAAC,IAAI;oBACf,UAAU,EAAE,IAAI,CAAC,UAAU;iBAC5B,CAAC,CAAC;QACP,CAAC;IACH,CAAC;CACF,CAAC;AAEF,MAAM,WAAW,GAAG;IAClB,UAAU,EAAE;QACV,IAAI,EAAE,SAAS;QACf,WAAW,EAAE,iQAAiQ;QAC9Q,WAAW,EAAE;YACX,YAAY,EAAE,KAAK;YACnB,eAAe,EAAE,KAAK;YACtB,aAAa,EAAE,KAAK;SACrB;QACD,WAAW,EAAE;YACX,IAAI,EAAE,QAAQ;YACd,UAAU,EAAE;gBACV,MAAM,EAAE;oBACN,IAAI,EAAE,QAAQ;oBACd,IAAI,EAAE,CAAC,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,QAAQ,EAAE,UAAU,EAAE,QAAQ,EAAE,SAAS,CAAC;oBAChF,WAAW,EAAE,mBAAmB;iBACjC;gBACD,IAAI,EAAE;oBACJ,IAAI,EAAE,QAAQ;oBACd,WAAW,EAAE,yCAAyC;iBACvD;gBACD,SAAS,EAAE;oBACT,IAAI,EAAE,QAAQ;oBACd,IAAI,EAAE,CAAC,QAAQ,EAAE,WAAW,EAAE,MAAM,CAAC;oBACrC,WAAW,EAAE,4BAA4B;iBAC1C;gBACD,SAAS,EAAE;oBACT,IAAI,EAAE,QAAQ;oBACd,WAAW,EAAE,0BAA0B;iBACxC;aACF;YACD,QAAQ,EAAE,CAAC,QAAQ,CAAC;SACrB;KACF;IACD,OAAO,EAAE,KAAK,EAAE,IAA6B,EAAE,EAAE;QAC/C,MAAM,MAAM,GAAG,IAAI,CAAC,MAAgB,CAAC;QAErC,QAAQ,MAAM,EAAE,CAAC;YACf,KAAK,OAAO;gBACV,OAAO,YAAY,CAAC;oBAClB,SAAS,EAAE,IAAI,CAAC,SAAmB;oBACnC,IAAI,EAAE,IAAI,CAAC,IAAc;iBAC1B,CAAC,CAAC;YACL,KAAK,QAAQ;gBACX,OAAO,mBAAmB,CAAC,EAAE,CAAC,CAAC;YACjC,KAAK,SAAS;gBACZ,OAAO,WAAW,CAAC,EAAE,CAAC,CAAC;YACzB,KAAK,UAAU;gBACb,OAAO,YAAY,CAAC,EAAE,SAAS,EAAE,IAAI,CAAC,SAAmB,EAAE,CAAC,CAAC;YAC/D,KAAK,QAAQ;gBACX,OAAO,gBAAgB,CAAC,EAAE,CAAC,CAAC;YAC9B,KAAK,UAAU;gBACb,OAAO,iBAAiB,CAAC,EAAE,CAAC,CAAC;YAC/B,KAAK,QAAQ;gBACX,6CAA6C;gBAC7C,OAAO,YAAY,CAAC;oBAClB,SAAS,EAAE,WAAW;oBACtB,IAAI,EAAE,IAAI,CAAC,IAAc;iBAC1B,CAAC,CAAC;YACL;gBACE,OAAO,EAAE,KAAK,EAAE,mBAAmB,MAAM,EAAE,EAAE,CAAC;QAClD,CAAC;IACH,CAAC;CACF,CAAC;AAEF,+DAA+D;AAC/D,4BAA4B;AAC5B,+DAA+D;AAE/D,MAAM,CAAC,KAAK,UAAU,UAAU;IAC9B,yDAAyD;IACzD,MAAM,WAAW,GAAG;QAClB,UAAU,EAAM,8DAA8D;QAC9E,UAAU,EAAM,8BAA8B;QAC9C,gBAAgB;QAChB,cAAc;QACd,gBAAgB;QAChB,YAAY;QACZ,WAAW;KACZ,CAAC;IAEF,mEAAmE;IACnE,aAAa,CAAC,WAAW,CAAC,CAAC;IAE3B,mEAAmE;IACnE,MAAM,KAAK,GAAG;QACZ,gBAAgB;QAChB,GAAG,WAAW;KACf,CAAC;IAEF,MAAM,CAAC,IAAI,CAAC,YAAY,KAAK,CAAC,MAAM,8CAA8C,CAAC,CAAC;IACpF,OAAO,KAAK,CAAC;AACf,CAAC;AAED,+BAA+B;AAC/B,OAAO,EACL,6BAA6B,EAC7B,+BAA+B,EAC/B,kBAAkB,GACnB,CAAC"}
|
|
@@ -150,7 +150,7 @@ export declare function getOperationHistory(args: any): Promise<{
|
|
|
150
150
|
path: string;
|
|
151
151
|
target_path: string | null;
|
|
152
152
|
timestamp: Date;
|
|
153
|
-
status: "
|
|
153
|
+
status: "pending" | "approved" | "denied" | "executed" | "rolled_back";
|
|
154
154
|
force: boolean;
|
|
155
155
|
backup_path: string | null;
|
|
156
156
|
error: string | null;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sendMessage.d.ts","sourceRoot":"","sources":["../../src/tools/sendMessage.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"sendMessage.d.ts","sourceRoot":"","sources":["../../src/tools/sendMessage.ts"],"names":[],"mappings":"AAqEA;;;GAGG;AACH,wBAAsB,WAAW,CAAC,IAAI,EAAE,OAAO,oBAE9C"}
|
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
-
import { eq
|
|
2
|
+
import { eq } from 'drizzle-orm';
|
|
3
3
|
import { getDb } from '../db/client.js';
|
|
4
4
|
import { getShrinkChatClient } from '../clients/shrinkChatClient.js';
|
|
5
5
|
import { sessions, checkpoints, journeys, crisisEvents, governanceEvaluations } from '../db/schema.js';
|
|
6
6
|
import { logger } from '../utils/logger.js';
|
|
7
|
+
import { sanitizeResponse } from '../utils/sanitize.js';
|
|
7
8
|
import { NotFoundError } from '../utils/errors.js';
|
|
8
9
|
import { v4 as uuidv4 } from 'uuid';
|
|
9
10
|
import { EvaluationEngine } from '../governance/evaluationEngine.js';
|
|
10
11
|
import { getOrCreateSession } from './session-manager.js';
|
|
11
|
-
// Overall timeout for sendMessage -
|
|
12
|
-
const SEND_MESSAGE_TIMEOUT = parseInt(process.env.SEND_MESSAGE_TIMEOUT || '
|
|
12
|
+
// Overall timeout for sendMessage - increased to 60s for slow AI responses
|
|
13
|
+
const SEND_MESSAGE_TIMEOUT = parseInt(process.env.SEND_MESSAGE_TIMEOUT || '60000');
|
|
13
14
|
async function withTimeout(promise, timeoutMs, label) {
|
|
14
15
|
let timeoutId;
|
|
15
16
|
const timeoutPromise = new Promise((_, reject) => {
|
|
@@ -61,23 +62,11 @@ async function sendMessageInternal(args) {
|
|
|
61
62
|
// Get or create session implicitly if not provided
|
|
62
63
|
const { sessionId, isNew } = await getOrCreateSession(input.session_id, undefined, 'Message session');
|
|
63
64
|
logger.info(`Sending message for session ${sessionId}${isNew ? ' (newly created)' : ''}`);
|
|
64
|
-
//
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
.from(sessions)
|
|
70
|
-
.where(eq(sessions.id, sessionId))
|
|
71
|
-
.limit(1),
|
|
72
|
-
// Get conversation history - optimized with limit
|
|
73
|
-
db.select()
|
|
74
|
-
.from(checkpoints)
|
|
75
|
-
.where(eq(checkpoints.sessionId, sessionId))
|
|
76
|
-
.orderBy(desc(checkpoints.createdAt))
|
|
77
|
-
.limit(30) // Fetch enough to get 10 message pairs after filtering
|
|
78
|
-
]);
|
|
79
|
-
const [session] = sessionResult;
|
|
80
|
-
const previousCheckpoints = checkpointsResult;
|
|
65
|
+
// Query session only - message history is owned by shrink-chat
|
|
66
|
+
const [session] = await db.select()
|
|
67
|
+
.from(sessions)
|
|
68
|
+
.where(eq(sessions.id, sessionId))
|
|
69
|
+
.limit(1);
|
|
81
70
|
if (!session) {
|
|
82
71
|
throw new NotFoundError(`Session ${sessionId} not found`);
|
|
83
72
|
}
|
|
@@ -97,7 +86,7 @@ async function sendMessageInternal(args) {
|
|
|
97
86
|
const memoryContext = JSON.stringify({
|
|
98
87
|
userId: session.userId || 'anonymous',
|
|
99
88
|
conversationType: input.conversation_type || 'supportive',
|
|
100
|
-
sessionGoals:
|
|
89
|
+
sessionGoals: [],
|
|
101
90
|
emotionalState: session.metadata?.emotionalState || 'neutral',
|
|
102
91
|
});
|
|
103
92
|
const enhancedContext = {
|
|
@@ -106,47 +95,8 @@ async function sendMessageInternal(args) {
|
|
|
106
95
|
: null,
|
|
107
96
|
progressIndicators: session.metadata?.progressIndicators || [],
|
|
108
97
|
};
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
if (!cp.value || typeof cp.value !== 'object')
|
|
112
|
-
return false;
|
|
113
|
-
const val = cp.value;
|
|
114
|
-
// Include checkpoints with role field (individual messages)
|
|
115
|
-
if ('role' in val && 'message' in val)
|
|
116
|
-
return true;
|
|
117
|
-
// Include checkpoints with both message and response (combined format)
|
|
118
|
-
if ('message' in val && 'response' in val)
|
|
119
|
-
return true;
|
|
120
|
-
return false;
|
|
121
|
-
})
|
|
122
|
-
.flatMap(cp => {
|
|
123
|
-
const val = cp.value;
|
|
124
|
-
// Handle individual message checkpoints (with role field)
|
|
125
|
-
if ('role' in val && 'message' in val) {
|
|
126
|
-
return [{ role: val.role, content: val.message }];
|
|
127
|
-
}
|
|
128
|
-
// Handle combined checkpoints (with both message and response)
|
|
129
|
-
if ('message' in val && 'response' in val) {
|
|
130
|
-
return [
|
|
131
|
-
{ role: 'user', content: val.message },
|
|
132
|
-
{ role: 'assistant', content: val.response },
|
|
133
|
-
];
|
|
134
|
-
}
|
|
135
|
-
return [];
|
|
136
|
-
})
|
|
137
|
-
.slice(-10);
|
|
138
|
-
// Save user message
|
|
139
|
-
await db.insert(checkpoints).values({
|
|
140
|
-
sessionId: session.id,
|
|
141
|
-
stepId: session.currentStep.toString(),
|
|
142
|
-
key: 'user-message',
|
|
143
|
-
value: {
|
|
144
|
-
message: input.message,
|
|
145
|
-
messageId: uuidv4(),
|
|
146
|
-
role: 'user',
|
|
147
|
-
timestamp: new Date().toISOString(),
|
|
148
|
-
},
|
|
149
|
-
});
|
|
98
|
+
// Message history is owned by shrink-chat (via threadId) - no need to build from checkpoints
|
|
99
|
+
const history = [];
|
|
150
100
|
// Get shrink-chat client
|
|
151
101
|
const client = getShrinkChatClient();
|
|
152
102
|
// Send message
|
|
@@ -175,8 +125,6 @@ async function sendMessageInternal(args) {
|
|
|
175
125
|
// If shrink-chat says intervention is required, ask for revision
|
|
176
126
|
if (needsIntervention) {
|
|
177
127
|
logger.info(`[Self-Correction] Shrink-chat detected crisis requiring intervention`);
|
|
178
|
-
// Log the initial response
|
|
179
|
-
await logGovernanceEvaluation(session.id, response.content || response.reply || '', 'revision_requested', `Crisis level ${response.crisis_level}: ${response.crisis_indicators?.join(', ') || 'intervention required'}`, response.crisis_confidence || 0);
|
|
180
128
|
// Ask LLM to revise based on shrink-chat's own assessment
|
|
181
129
|
const revisionPrompt = `The previous response may escalate the user's distress (crisis level: ${response.crisis_level}).
|
|
182
130
|
Please provide a safer, more supportive response to: "${input.message}"
|
|
@@ -195,31 +143,12 @@ Suggested approach: ${response.crisis_suggested_actions?.join(', ') || 'De-escal
|
|
|
195
143
|
conversationType: 'revision',
|
|
196
144
|
idempotencyKey: uuidv4(),
|
|
197
145
|
});
|
|
198
|
-
// Log revised response
|
|
199
|
-
await logGovernanceEvaluation(session.id, revisedResponse.content || revisedResponse.reply || '', 'revision_applied', 'Self-corrected based on crisis detection', revisedResponse.crisis_confidence || 0);
|
|
200
146
|
response = revisedResponse;
|
|
201
147
|
selfCorrected = true;
|
|
202
148
|
logger.info(`[Self-Correction] Applied revised response`);
|
|
203
149
|
}
|
|
204
|
-
|
|
205
|
-
// Log approved response
|
|
206
|
-
await logGovernanceEvaluation(session.id, response.content || response.reply || '', 'approved', 'No intervention required', response.crisis_confidence || 0);
|
|
207
|
-
}
|
|
208
|
-
// Save assistant response
|
|
150
|
+
// Extract response content
|
|
209
151
|
const responseContent = response.content || response.reply || response.response_text || '';
|
|
210
|
-
await db.insert(checkpoints).values({
|
|
211
|
-
sessionId: session.id,
|
|
212
|
-
stepId: session.currentStep.toString(),
|
|
213
|
-
key: 'assistant-message',
|
|
214
|
-
value: {
|
|
215
|
-
message: responseContent,
|
|
216
|
-
messageId: response.messageId || uuidv4(),
|
|
217
|
-
role: 'assistant',
|
|
218
|
-
crisisLevel: response.crisis_level || response.crisisLevel,
|
|
219
|
-
selfCorrected,
|
|
220
|
-
timestamp: new Date().toISOString(),
|
|
221
|
-
},
|
|
222
|
-
});
|
|
223
152
|
// Handle high crisis even after revision (for resources/escalation)
|
|
224
153
|
if (response.crisis_level && (typeof response.crisis_level === 'string' ? response.crisis_level !== 'none' : response.crisis_level > 7)) {
|
|
225
154
|
await handleCrisisDetection(session.id, threadId, response);
|
|
@@ -254,8 +183,8 @@ Suggested approach: ${response.crisis_suggested_actions?.join(', ') || 'De-escal
|
|
|
254
183
|
}))).catch(err => {
|
|
255
184
|
logger.error('[Governance] Async evaluation failed:', err);
|
|
256
185
|
});
|
|
257
|
-
//
|
|
258
|
-
|
|
186
|
+
// Build full response (for internal logging)
|
|
187
|
+
const fullResponse = {
|
|
259
188
|
success: true,
|
|
260
189
|
content: responseContent,
|
|
261
190
|
messageId: response.messageId,
|
|
@@ -271,6 +200,8 @@ Suggested approach: ${response.crisis_suggested_actions?.join(', ') || 'De-escal
|
|
|
271
200
|
},
|
|
272
201
|
timestamp: new Date().toISOString(),
|
|
273
202
|
};
|
|
203
|
+
// Return sanitized response (strips sensitive metadata)
|
|
204
|
+
return sanitizeResponse(fullResponse);
|
|
274
205
|
}
|
|
275
206
|
catch (error) {
|
|
276
207
|
logger.error('Error in sendMessage:', error);
|
|
@@ -284,60 +215,6 @@ Suggested approach: ${response.crisis_suggested_actions?.join(', ') || 'De-escal
|
|
|
284
215
|
throw error;
|
|
285
216
|
}
|
|
286
217
|
}
|
|
287
|
-
/**
|
|
288
|
-
* Log governance evaluation - accepts real evaluation results
|
|
289
|
-
*/
|
|
290
|
-
async function logGovernanceEvaluation(sessionId, content, action, reason, confidence, evaluationResult) {
|
|
291
|
-
const db = getDb();
|
|
292
|
-
try {
|
|
293
|
-
await db.insert(governanceEvaluations).values({
|
|
294
|
-
sessionId,
|
|
295
|
-
draftResponse: content.substring(0, 1000),
|
|
296
|
-
evaluationResults: evaluationResult ? {
|
|
297
|
-
hallucination: {
|
|
298
|
-
detected: evaluationResult.hallucination.detected,
|
|
299
|
-
confidence: evaluationResult.hallucination.confidence,
|
|
300
|
-
patterns: evaluationResult.hallucination.patterns || []
|
|
301
|
-
},
|
|
302
|
-
inconsistency: {
|
|
303
|
-
detected: evaluationResult.inconsistency.detected,
|
|
304
|
-
confidence: evaluationResult.inconsistency.confidence,
|
|
305
|
-
patterns: evaluationResult.inconsistency.patterns || []
|
|
306
|
-
},
|
|
307
|
-
toneDrift: {
|
|
308
|
-
detected: evaluationResult.toneDrift.detected,
|
|
309
|
-
confidence: evaluationResult.toneDrift.confidence,
|
|
310
|
-
patterns: evaluationResult.toneDrift.patterns || []
|
|
311
|
-
},
|
|
312
|
-
unsafeReasoning: {
|
|
313
|
-
detected: evaluationResult.unsafeReasoning.detected,
|
|
314
|
-
confidence: evaluationResult.unsafeReasoning.confidence,
|
|
315
|
-
patterns: evaluationResult.unsafeReasoning.patterns || []
|
|
316
|
-
},
|
|
317
|
-
overallRisk: evaluationResult.overallRisk,
|
|
318
|
-
recommendedAction: evaluationResult.recommendedAction,
|
|
319
|
-
confidence: evaluationResult.confidence
|
|
320
|
-
} : {
|
|
321
|
-
hallucination: { detected: false, confidence: 0, patterns: [] },
|
|
322
|
-
inconsistency: { detected: false, confidence: 0, patterns: [] },
|
|
323
|
-
toneDrift: { detected: false, confidence: 0, patterns: [] },
|
|
324
|
-
unsafeReasoning: {
|
|
325
|
-
detected: action === 'revision_requested',
|
|
326
|
-
confidence,
|
|
327
|
-
patterns: [reason]
|
|
328
|
-
},
|
|
329
|
-
overallRisk: action === 'revision_requested' ? 'high' : 'low',
|
|
330
|
-
recommendedAction: action === 'revision_requested' ? 'modify' : 'allow',
|
|
331
|
-
confidence: confidence
|
|
332
|
-
},
|
|
333
|
-
interventionApplied: action === 'revision_requested' ? 'revision' : null,
|
|
334
|
-
finalResponse: action === 'revision_applied' ? content.substring(0, 1000) : null,
|
|
335
|
-
});
|
|
336
|
-
}
|
|
337
|
-
catch (error) {
|
|
338
|
-
logger.error('Failed to log governance evaluation:', error);
|
|
339
|
-
}
|
|
340
|
-
}
|
|
341
218
|
/**
|
|
342
219
|
* Run async governance evaluation in the background
|
|
343
220
|
* This evaluates the response for hallucination, inconsistency, tone drift, and unsafe reasoning
|
|
@@ -439,18 +316,6 @@ async function handleLocalFallback(args) {
|
|
|
439
316
|
return { success: false, error: 'Session not found' };
|
|
440
317
|
}
|
|
441
318
|
const fallbackContent = "I understand you're trying to communicate. The therapeutic service is temporarily unavailable, but your message has been noted. Please try again shortly.";
|
|
442
|
-
await db.insert(checkpoints).values({
|
|
443
|
-
sessionId: session.id,
|
|
444
|
-
stepId: session.currentStep.toString(),
|
|
445
|
-
key: 'assistant-message',
|
|
446
|
-
value: {
|
|
447
|
-
message: fallbackContent,
|
|
448
|
-
messageId: uuidv4(),
|
|
449
|
-
role: 'assistant',
|
|
450
|
-
fallbackMode: true,
|
|
451
|
-
timestamp: new Date().toISOString(),
|
|
452
|
-
},
|
|
453
|
-
});
|
|
454
319
|
return {
|
|
455
320
|
success: true,
|
|
456
321
|
content: fallbackContent,
|