morpheus-cli 0.9.22 → 0.9.23
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/dist/channels/discord.js +5 -0
- package/dist/channels/telegram.js +5 -0
- package/dist/http/routers/display.js +5 -0
- package/dist/runtime/audit/repository.js +69 -1
- package/dist/runtime/chronos/worker.js +2 -0
- package/dist/runtime/display.js +32 -0
- package/dist/runtime/memory/sati/service.js +5 -0
- package/dist/runtime/oracle.js +5 -0
- package/dist/runtime/providers/factory.js +14 -2
- package/dist/runtime/smiths/delegator.js +3 -0
- package/dist/runtime/subagents/devkit-instrument.js +5 -0
- package/dist/runtime/subagents/link/link.js +120 -77
- package/dist/runtime/subagents/trinity/trinity.js +64 -34
- package/dist/runtime/tools/factory.js +6 -2
- package/dist/ui/assets/{AuditDashboard-z3OBbJ8I.js → AuditDashboard-ClqEr7jg.js} +1 -1
- package/dist/ui/assets/{Chat-aFz9FjrD.js → Chat-BwxZJphx.js} +1 -1
- package/dist/ui/assets/{Chronos-MP_NCj2A.js → Chronos-BafOMteb.js} +1 -1
- package/dist/ui/assets/{ConfirmationModal-B3gHIVKY.js → ConfirmationModal-DU0AwhXD.js} +1 -1
- package/dist/ui/assets/{Dashboard-OyZXnj44.js → Dashboard-DvJb72Xe.js} +174 -174
- package/dist/ui/assets/{DeleteConfirmationModal-D8QsQzwP.js → DeleteConfirmationModal-FSWLK6-I.js} +1 -1
- package/dist/ui/assets/{Documents-B8g_yv4f.js → Documents-D73CeGkW.js} +1 -1
- package/dist/ui/assets/{Logs-BWufAtHa.js → Logs-BrFWnLIL.js} +1 -1
- package/dist/ui/assets/{MCPManager-lLoGEyBy.js → MCPManager-_L2Yo-uY.js} +1 -1
- package/dist/ui/assets/{ModelPricing-CuYIUwXt.js → ModelPricing-CyXMdxJD.js} +1 -1
- package/dist/ui/assets/{Notifications-nI--fmYx.js → Notifications-BpHokTLS.js} +1 -1
- package/dist/ui/assets/{SatiMemories-DO3JDQBi.js → SatiMemories-CfSTgr9V.js} +1 -1
- package/dist/ui/assets/{SessionAudit-BWtJRkj1.js → SessionAudit-pOWRgJtc.js} +1 -1
- package/dist/ui/assets/{Settings-CblauAVd.js → Settings-CPDXAk18.js} +1 -1
- package/dist/ui/assets/{Skills-Dw6G5c8W.js → Skills-GIkCxMS3.js} +1 -1
- package/dist/ui/assets/{Smiths-B6-CnRMv.js → Smiths-ZcHXcrMt.js} +1 -1
- package/dist/ui/assets/{Tasks-DzUyw5z3.js → Tasks-DJ6R3d4f.js} +1 -1
- package/dist/ui/assets/{TrinityDatabases-DCjdwnLH.js → TrinityDatabases-CnRAkDuu.js} +1 -1
- package/dist/ui/assets/{UsageStats-VajzjndO.js → UsageStats-Bl7bs4ay.js} +1 -1
- package/dist/ui/assets/{WebhookManager-BbfMCiy-.js → WebhookManager-CEjjk4tx.js} +1 -1
- package/dist/ui/assets/{agents-CN_AKX_I.js → agents-DO69pNM1.js} +1 -1
- package/dist/ui/assets/{audit-M-5UGwoK.js → audit-CP5fC4m8.js} +1 -1
- package/dist/ui/assets/{chronos-mZ0RIvh4.js → chronos-DPhK718h.js} +1 -1
- package/dist/ui/assets/{config-7LGRnJ26.js → config-OLGQFNJL.js} +1 -1
- package/dist/ui/assets/{index-Db1XEN8v.js → index-B9ePr-vB.js} +2 -2
- package/dist/ui/assets/index-D_0tPLCk.css +1 -0
- package/dist/ui/assets/{mcp-YiYC-9IH.js → mcp-BeBznKtK.js} +1 -1
- package/dist/ui/assets/{skills-dc6Xqqhb.js → skills-wEUxSGB3.js} +1 -1
- package/dist/ui/assets/{stats-BzqxCDuj.js → stats-KMbKDMJ-.js} +1 -1
- package/dist/ui/assets/{useCurrency-CEc5edm2.js → useCurrency-Bgg-7MTE.js} +1 -1
- package/dist/ui/index.html +2 -2
- package/dist/ui/sw.js +1 -1
- package/package.json +1 -1
- package/dist/ui/assets/index-Bko2TlZY.css +0 -1
|
@@ -89,6 +89,7 @@ export class Link {
|
|
|
89
89
|
const search = this.search;
|
|
90
90
|
const repository = this.repository;
|
|
91
91
|
const agentConfig = this.agentConfig;
|
|
92
|
+
const display = DisplayManager.getInstance();
|
|
92
93
|
const searchTool = new DynamicStructuredTool({
|
|
93
94
|
name: 'link_search_documents',
|
|
94
95
|
description: 'Search ALL indexed user documents using hybrid vector + keyword search. Returns the most relevant document chunks for a given query. Use this for broad searches when you don\'t know which document contains the answer.',
|
|
@@ -97,16 +98,22 @@ export class Link {
|
|
|
97
98
|
limit: z.number().optional().describe('Maximum number of results to return (default: max_results from config)'),
|
|
98
99
|
}),
|
|
99
100
|
func: async ({ query, limit }) => {
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
101
|
+
display.startActivity('link', 'Searching documents...');
|
|
102
|
+
try {
|
|
103
|
+
const maxResults = limit ?? agentConfig.max_results;
|
|
104
|
+
const threshold = agentConfig.score_threshold;
|
|
105
|
+
const results = await search.search(query, maxResults, threshold);
|
|
106
|
+
if (results.length === 0) {
|
|
107
|
+
return `No relevant documents found for query: "${query}"`;
|
|
108
|
+
}
|
|
109
|
+
const formatted = results
|
|
110
|
+
.map((r, i) => `[${i + 1}] Source: ${r.filename} (chunk ${r.position}, score: ${r.score.toFixed(3)})\n${r.content}`)
|
|
111
|
+
.join('\n\n---\n\n');
|
|
112
|
+
return `Found ${results.length} relevant passages:\n\n${formatted}`;
|
|
113
|
+
}
|
|
114
|
+
finally {
|
|
115
|
+
display.endActivity('link', true);
|
|
105
116
|
}
|
|
106
|
-
const formatted = results
|
|
107
|
-
.map((r, i) => `[${i + 1}] Source: ${r.filename} (chunk ${r.position}, score: ${r.score.toFixed(3)})\n${r.content}`)
|
|
108
|
-
.join('\n\n---\n\n');
|
|
109
|
-
return `Found ${results.length} relevant passages:\n\n${formatted}`;
|
|
110
117
|
},
|
|
111
118
|
});
|
|
112
119
|
const listDocumentsTool = new DynamicStructuredTool({
|
|
@@ -116,21 +123,27 @@ export class Link {
|
|
|
116
123
|
name_filter: z.string().optional().describe('Optional partial filename to filter by (case-insensitive). E.g. "CV", "contrato", "readme"'),
|
|
117
124
|
}),
|
|
118
125
|
func: async ({ name_filter }) => {
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
126
|
+
display.startActivity('link', 'Listing documents...');
|
|
127
|
+
try {
|
|
128
|
+
const docs = repository.listDocuments('indexed');
|
|
129
|
+
if (docs.length === 0) {
|
|
130
|
+
return 'No indexed documents found.';
|
|
131
|
+
}
|
|
132
|
+
let filtered = docs;
|
|
133
|
+
if (name_filter) {
|
|
134
|
+
const lower = name_filter.toLowerCase();
|
|
135
|
+
filtered = docs.filter(d => d.filename.toLowerCase().includes(lower));
|
|
136
|
+
}
|
|
137
|
+
if (filtered.length === 0) {
|
|
138
|
+
const allNames = docs.map(d => `- ${d.filename}`).join('\n');
|
|
139
|
+
return `No documents matching "${name_filter}". Available documents:\n${allNames}`;
|
|
140
|
+
}
|
|
141
|
+
const lines = filtered.map(d => `- [${d.id}] ${d.filename} (${d.chunk_count} chunks)`);
|
|
142
|
+
return `Found ${filtered.length} document(s):\n${lines.join('\n')}`;
|
|
127
143
|
}
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
return `No documents matching "${name_filter}". Available documents:\n${allNames}`;
|
|
144
|
+
finally {
|
|
145
|
+
display.endActivity('link', true);
|
|
131
146
|
}
|
|
132
|
-
const lines = filtered.map(d => `- [${d.id}] ${d.filename} (${d.chunk_count} chunks)`);
|
|
133
|
-
return `Found ${filtered.length} document(s):\n${lines.join('\n')}`;
|
|
134
147
|
},
|
|
135
148
|
});
|
|
136
149
|
const searchInDocumentTool = new DynamicStructuredTool({
|
|
@@ -142,20 +155,26 @@ export class Link {
|
|
|
142
155
|
limit: z.number().optional().describe('Maximum number of results (default: max_results from config)'),
|
|
143
156
|
}),
|
|
144
157
|
func: async ({ document_id, query, limit }) => {
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
158
|
+
display.startActivity('link', 'Searching in document...');
|
|
159
|
+
try {
|
|
160
|
+
const doc = repository.getDocument(document_id);
|
|
161
|
+
if (!doc) {
|
|
162
|
+
return `Document not found: ${document_id}`;
|
|
163
|
+
}
|
|
164
|
+
const maxResults = limit ?? agentConfig.max_results;
|
|
165
|
+
const threshold = agentConfig.score_threshold;
|
|
166
|
+
const results = await search.searchInDocument(query, document_id, maxResults, threshold);
|
|
167
|
+
if (results.length === 0) {
|
|
168
|
+
return `No relevant passages found in "${doc.filename}" for query: "${query}"`;
|
|
169
|
+
}
|
|
170
|
+
const formatted = results
|
|
171
|
+
.map((r, i) => `[${i + 1}] (chunk ${r.position}, score: ${r.score.toFixed(3)})\n${r.content}`)
|
|
172
|
+
.join('\n\n---\n\n');
|
|
173
|
+
return `Found ${results.length} passages in "${doc.filename}":\n\n${formatted}`;
|
|
148
174
|
}
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
const results = await search.searchInDocument(query, document_id, maxResults, threshold);
|
|
152
|
-
if (results.length === 0) {
|
|
153
|
-
return `No relevant passages found in "${doc.filename}" for query: "${query}"`;
|
|
175
|
+
finally {
|
|
176
|
+
display.endActivity('link', true);
|
|
154
177
|
}
|
|
155
|
-
const formatted = results
|
|
156
|
-
.map((r, i) => `[${i + 1}] (chunk ${r.position}, score: ${r.score.toFixed(3)})\n${r.content}`)
|
|
157
|
-
.join('\n\n---\n\n');
|
|
158
|
-
return `Found ${results.length} passages in "${doc.filename}":\n\n${formatted}`;
|
|
159
178
|
},
|
|
160
179
|
});
|
|
161
180
|
// Tool: Summarize entire document via LLM
|
|
@@ -167,19 +186,25 @@ export class Link {
|
|
|
167
186
|
max_chunks: z.number().optional().describe('Maximum number of chunks to include in summary (default: 50)'),
|
|
168
187
|
}),
|
|
169
188
|
func: async ({ document_id, max_chunks }) => {
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
189
|
+
display.startActivity('link', 'Summarizing document...');
|
|
190
|
+
try {
|
|
191
|
+
const doc = repository.getDocument(document_id);
|
|
192
|
+
if (!doc) {
|
|
193
|
+
return `Document not found: ${document_id}`;
|
|
194
|
+
}
|
|
195
|
+
const chunks = repository.getChunksByDocument(document_id);
|
|
196
|
+
if (chunks.length === 0) {
|
|
197
|
+
return `Document "${doc.filename}" has no indexed chunks.`;
|
|
198
|
+
}
|
|
199
|
+
const limit = max_chunks ?? 50;
|
|
200
|
+
const chunksToSummarize = chunks.slice(0, limit);
|
|
201
|
+
const content = chunksToSummarize.map(c => c.content).join('\n\n---\n\n');
|
|
202
|
+
// Return the content for LLM to summarize - the ReactAgent will handle the summarization
|
|
203
|
+
return `Document: ${doc.filename}\nTotal chunks: ${chunks.length}\nChunks to summarize: ${chunksToSummarize.length}\n\nContent:\n${content}`;
|
|
173
204
|
}
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
return `Document "${doc.filename}" has no indexed chunks.`;
|
|
205
|
+
finally {
|
|
206
|
+
display.endActivity('link', true);
|
|
177
207
|
}
|
|
178
|
-
const limit = max_chunks ?? 50;
|
|
179
|
-
const chunksToSummarize = chunks.slice(0, limit);
|
|
180
|
-
const content = chunksToSummarize.map(c => c.content).join('\n\n---\n\n');
|
|
181
|
-
// Return the content for LLM to summarize - the ReactAgent will handle the summarization
|
|
182
|
-
return `Document: ${doc.filename}\nTotal chunks: ${chunks.length}\nChunks to summarize: ${chunksToSummarize.length}\n\nContent:\n${content}`;
|
|
183
208
|
},
|
|
184
209
|
});
|
|
185
210
|
// Tool: Summarize specific chunk via LLM
|
|
@@ -191,16 +216,22 @@ export class Link {
|
|
|
191
216
|
position: z.number().describe('The chunk position to summarize (1-based)'),
|
|
192
217
|
}),
|
|
193
218
|
func: async ({ document_id, position }) => {
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
219
|
+
display.startActivity('link', 'Summarizing chunk...');
|
|
220
|
+
try {
|
|
221
|
+
const doc = repository.getDocument(document_id);
|
|
222
|
+
if (!doc) {
|
|
223
|
+
return `Document not found: ${document_id}`;
|
|
224
|
+
}
|
|
225
|
+
const chunks = repository.getChunksByDocument(document_id);
|
|
226
|
+
const chunk = chunks.find(c => c.position === position);
|
|
227
|
+
if (!chunk) {
|
|
228
|
+
return `Chunk not found: position ${position}. Document "${doc.filename}" has ${chunks.length} chunks.`;
|
|
229
|
+
}
|
|
230
|
+
return `Document: ${doc.filename}\nChunk position: ${position}\n\nContent:\n${chunk.content}`;
|
|
197
231
|
}
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
if (!chunk) {
|
|
201
|
-
return `Chunk not found: position ${position}. Document "${doc.filename}" has ${chunks.length} chunks.`;
|
|
232
|
+
finally {
|
|
233
|
+
display.endActivity('link', true);
|
|
202
234
|
}
|
|
203
|
-
return `Document: ${doc.filename}\nChunk position: ${position}\n\nContent:\n${chunk.content}`;
|
|
204
235
|
},
|
|
205
236
|
});
|
|
206
237
|
// Tool: Extract key points from document
|
|
@@ -212,18 +243,24 @@ export class Link {
|
|
|
212
243
|
max_chunks: z.number().optional().describe('Maximum number of chunks to analyze (default: 50)'),
|
|
213
244
|
}),
|
|
214
245
|
func: async ({ document_id, max_chunks }) => {
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
246
|
+
display.startActivity('link', 'Extracting key points...');
|
|
247
|
+
try {
|
|
248
|
+
const doc = repository.getDocument(document_id);
|
|
249
|
+
if (!doc) {
|
|
250
|
+
return `Document not found: ${document_id}`;
|
|
251
|
+
}
|
|
252
|
+
const chunks = repository.getChunksByDocument(document_id);
|
|
253
|
+
if (chunks.length === 0) {
|
|
254
|
+
return `Document "${doc.filename}" has no indexed chunks.`;
|
|
255
|
+
}
|
|
256
|
+
const limit = max_chunks ?? 1000;
|
|
257
|
+
const chunksToAnalyze = chunks.slice(0, limit);
|
|
258
|
+
const content = chunksToAnalyze.map(c => c.content).join('\n\n---\n\n');
|
|
259
|
+
return `Document: ${doc.filename}\nTotal chunks: ${chunks.length}\nChunks to analyze: ${chunksToAnalyze.length}\n\nContent:\n${content}`;
|
|
218
260
|
}
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
return `Document "${doc.filename}" has no indexed chunks.`;
|
|
261
|
+
finally {
|
|
262
|
+
display.endActivity('link', true);
|
|
222
263
|
}
|
|
223
|
-
const limit = max_chunks ?? 1000;
|
|
224
|
-
const chunksToAnalyze = chunks.slice(0, limit);
|
|
225
|
-
const content = chunksToAnalyze.map(c => c.content).join('\n\n---\n\n');
|
|
226
|
-
return `Document: ${doc.filename}\nTotal chunks: ${chunks.length}\nChunks to analyze: ${chunksToAnalyze.length}\n\nContent:\n${content}`;
|
|
227
264
|
},
|
|
228
265
|
});
|
|
229
266
|
// Tool: Find differences between two documents
|
|
@@ -235,22 +272,28 @@ export class Link {
|
|
|
235
272
|
document_id_b: z.string().describe('Second document ID to compare'),
|
|
236
273
|
}),
|
|
237
274
|
func: async ({ document_id_a, document_id_b }) => {
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
275
|
+
display.startActivity('link', 'Comparing documents...');
|
|
276
|
+
try {
|
|
277
|
+
const docA = repository.getDocument(document_id_a);
|
|
278
|
+
const docB = repository.getDocument(document_id_b);
|
|
279
|
+
if (!docA) {
|
|
280
|
+
return `Document not found: ${document_id_a}`;
|
|
281
|
+
}
|
|
282
|
+
if (!docB) {
|
|
283
|
+
return `Document not found: ${document_id_b}`;
|
|
284
|
+
}
|
|
285
|
+
if (document_id_a === document_id_b) {
|
|
286
|
+
return 'Os documentos são idênticos (mesmo documento informado duas vezes).';
|
|
287
|
+
}
|
|
288
|
+
const chunksA = repository.getChunksByDocument(document_id_a);
|
|
289
|
+
const chunksB = repository.getChunksByDocument(document_id_b);
|
|
290
|
+
const contentA = chunksA.map(c => c.content).join('\n\n---\n\n');
|
|
291
|
+
const contentB = chunksB.map(c => c.content).join('\n\n---\n\n');
|
|
292
|
+
return `Document A: ${docA.filename} (${chunksA.length} chunks)\nDocument B: ${docB.filename} (${chunksB.length} chunks)\n\n--- Document A Content ---\n${contentA}\n\n--- Document B Content ---\n${contentB}`;
|
|
245
293
|
}
|
|
246
|
-
|
|
247
|
-
|
|
294
|
+
finally {
|
|
295
|
+
display.endActivity('link', true);
|
|
248
296
|
}
|
|
249
|
-
const chunksA = repository.getChunksByDocument(document_id_a);
|
|
250
|
-
const chunksB = repository.getChunksByDocument(document_id_b);
|
|
251
|
-
const contentA = chunksA.map(c => c.content).join('\n\n---\n\n');
|
|
252
|
-
const contentB = chunksB.map(c => c.content).join('\n\n---\n\n');
|
|
253
|
-
return `Document A: ${docA.filename} (${chunksA.length} chunks)\nDocument B: ${docB.filename} (${chunksB.length} chunks)\n\n--- Document A Content ---\n${contentA}\n\n--- Document B Content ---\n${contentB}`;
|
|
254
297
|
},
|
|
255
298
|
});
|
|
256
299
|
return [listDocumentsTool, searchTool, searchInDocumentTool, summarizeDocumentTool, summarizeChunkTool, extractKeyPointsTool, findDifferencesTool];
|
|
@@ -83,41 +83,54 @@ export class Trinity {
|
|
|
83
83
|
}
|
|
84
84
|
buildTrinityTools() {
|
|
85
85
|
const registry = DatabaseRegistry.getInstance();
|
|
86
|
+
const display = DisplayManager.getInstance();
|
|
86
87
|
const listDatabases = tool(async () => {
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
88
|
+
display.startActivity('trinit', 'Listing databases...');
|
|
89
|
+
try {
|
|
90
|
+
const dbs = registry.listDatabases();
|
|
91
|
+
if (dbs.length === 0)
|
|
92
|
+
return 'No databases registered.';
|
|
93
|
+
return dbs.map((db) => {
|
|
94
|
+
const schema = db.schema_json
|
|
95
|
+
? JSON.parse(db.schema_json)
|
|
96
|
+
: null;
|
|
97
|
+
let schemaSummary = 'schema not loaded';
|
|
98
|
+
if (schema) {
|
|
99
|
+
if (schema.databases) {
|
|
100
|
+
const totalTables = schema.databases.reduce((acc, d) => acc + d.tables.length, 0);
|
|
101
|
+
schemaSummary = `${schema.databases.length} databases, ${totalTables} tables total`;
|
|
102
|
+
}
|
|
103
|
+
else {
|
|
104
|
+
schemaSummary = schema.tables?.map((t) => t.name).join(', ') || 'no tables';
|
|
105
|
+
}
|
|
102
106
|
}
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
:
|
|
107
|
-
|
|
108
|
-
}
|
|
107
|
+
const updatedAt = db.schema_updated_at
|
|
108
|
+
? new Date(db.schema_updated_at).toISOString()
|
|
109
|
+
: 'never';
|
|
110
|
+
return `[${db.id}] ${db.name} (${db.type}) — ${schemaSummary} — schema updated: ${updatedAt}`;
|
|
111
|
+
}).join('\n');
|
|
112
|
+
}
|
|
113
|
+
finally {
|
|
114
|
+
display.endActivity('trinit', true);
|
|
115
|
+
}
|
|
109
116
|
}, {
|
|
110
117
|
name: 'trinity_list_databases',
|
|
111
118
|
description: 'List all registered databases with their name, type, and schema summary.',
|
|
112
119
|
schema: z.object({}),
|
|
113
120
|
});
|
|
114
121
|
const getSchema = tool(async ({ database_id }) => {
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
122
|
+
display.startActivity('trinit', 'Getting database schema...');
|
|
123
|
+
try {
|
|
124
|
+
const db = registry.getDatabase(database_id);
|
|
125
|
+
if (!db)
|
|
126
|
+
return `Database with id ${database_id} not found.`;
|
|
127
|
+
if (!db.schema_json)
|
|
128
|
+
return `No schema cached for database "${db.name}". Use trinity_refresh_schema first.`;
|
|
129
|
+
return `Schema for "${db.name}" (${db.type}):\n${db.schema_json}`;
|
|
130
|
+
}
|
|
131
|
+
finally {
|
|
132
|
+
display.endActivity('trinit', true);
|
|
133
|
+
}
|
|
121
134
|
}, {
|
|
122
135
|
name: 'trinity_get_schema',
|
|
123
136
|
description: 'Get the full cached schema of a registered database by its id.',
|
|
@@ -126,9 +139,12 @@ export class Trinity {
|
|
|
126
139
|
}),
|
|
127
140
|
});
|
|
128
141
|
const refreshSchema = tool(async ({ database_id }) => {
|
|
142
|
+
display.startActivity('trinit', 'Refreshing database schema...');
|
|
129
143
|
const db = registry.getDatabase(database_id);
|
|
130
|
-
if (!db)
|
|
144
|
+
if (!db) {
|
|
145
|
+
display.endActivity('trinit', false);
|
|
131
146
|
return `Database with id ${database_id} not found.`;
|
|
147
|
+
}
|
|
132
148
|
try {
|
|
133
149
|
const schema = await introspectSchema(db);
|
|
134
150
|
registry.updateSchema(database_id, JSON.stringify(schema, null, 2));
|
|
@@ -140,8 +156,12 @@ export class Trinity {
|
|
|
140
156
|
return `Schema refreshed for "${db.name}". Tables: ${schema.tables.map((t) => t.name).join(', ')}`;
|
|
141
157
|
}
|
|
142
158
|
catch (err) {
|
|
159
|
+
display.endActivity('trinit', false);
|
|
143
160
|
return `Failed to refresh schema for "${db.name}": ${err.message}`;
|
|
144
161
|
}
|
|
162
|
+
finally {
|
|
163
|
+
display.endActivity('trinit', true);
|
|
164
|
+
}
|
|
145
165
|
}, {
|
|
146
166
|
name: 'trinity_refresh_schema',
|
|
147
167
|
description: 'Re-introspect and update the cached schema for a registered database.',
|
|
@@ -150,18 +170,23 @@ export class Trinity {
|
|
|
150
170
|
}),
|
|
151
171
|
});
|
|
152
172
|
const testConnectionTool = tool(async ({ database_id }) => {
|
|
153
|
-
|
|
154
|
-
if (!db)
|
|
155
|
-
return `Database with id ${database_id} not found.`;
|
|
173
|
+
display.startActivity('trinit', 'Testing database connection...');
|
|
156
174
|
try {
|
|
175
|
+
const db = registry.getDatabase(database_id);
|
|
176
|
+
if (!db)
|
|
177
|
+
return `Database with id ${database_id} not found.`;
|
|
157
178
|
const ok = await testConnection(db);
|
|
158
179
|
return ok
|
|
159
180
|
? `Connection to "${db.name}" (${db.type}) successful.`
|
|
160
181
|
: `Connection to "${db.name}" (${db.type}) failed.`;
|
|
161
182
|
}
|
|
162
183
|
catch (err) {
|
|
184
|
+
display.endActivity('trinit', false);
|
|
163
185
|
return `Connection test failed: ${err.message}`;
|
|
164
186
|
}
|
|
187
|
+
finally {
|
|
188
|
+
display.endActivity('trinit', true);
|
|
189
|
+
}
|
|
165
190
|
}, {
|
|
166
191
|
name: 'trinity_test_connection',
|
|
167
192
|
description: 'Test connectivity to a registered database.',
|
|
@@ -170,10 +195,11 @@ export class Trinity {
|
|
|
170
195
|
}),
|
|
171
196
|
});
|
|
172
197
|
const executeQueryTool = tool(async ({ database_id, query, params, }) => {
|
|
173
|
-
|
|
174
|
-
if (!db)
|
|
175
|
-
return `Database with id ${database_id} not found.`;
|
|
198
|
+
display.startActivity('trinit', 'Executing database query...');
|
|
176
199
|
try {
|
|
200
|
+
const db = registry.getDatabase(database_id);
|
|
201
|
+
if (!db)
|
|
202
|
+
return `Database with id ${database_id} not found.`;
|
|
177
203
|
const result = await executeQuery(db, query, params);
|
|
178
204
|
if (result.rows.length === 0)
|
|
179
205
|
return `Query returned 0 rows. (rowCount: ${result.rowCount})`;
|
|
@@ -183,8 +209,12 @@ export class Trinity {
|
|
|
183
209
|
return `Rows (${result.rowCount}):\n${json}${note}`;
|
|
184
210
|
}
|
|
185
211
|
catch (err) {
|
|
212
|
+
display.endActivity('trinit', false);
|
|
186
213
|
return `Query execution failed: ${err.message}`;
|
|
187
214
|
}
|
|
215
|
+
finally {
|
|
216
|
+
display.endActivity('trinit', true);
|
|
217
|
+
}
|
|
188
218
|
}, {
|
|
189
219
|
name: 'trinity_execute_query',
|
|
190
220
|
description: 'Execute a SQL query (PostgreSQL/MySQL/SQLite) or MongoDB JSON command on a registered database. ' +
|
|
@@ -7,24 +7,28 @@ function instrumentMcpTool(tool, serverName, getSessionId) {
|
|
|
7
7
|
tool._call = async function (input, runManager) {
|
|
8
8
|
const startMs = Date.now();
|
|
9
9
|
const sessionId = getSessionId() ?? 'unknown';
|
|
10
|
+
const toolName = `${serverName}/${tool.name}`;
|
|
11
|
+
display.startActivity('neo', `MCP tool: ${tool.name}`);
|
|
10
12
|
try {
|
|
11
13
|
const result = await original(input, runManager);
|
|
12
14
|
AuditRepository.getInstance().insert({
|
|
13
15
|
session_id: sessionId,
|
|
14
16
|
event_type: 'mcp_tool',
|
|
15
17
|
agent: 'neo',
|
|
16
|
-
tool_name:
|
|
18
|
+
tool_name: toolName,
|
|
17
19
|
duration_ms: Date.now() - startMs,
|
|
18
20
|
status: 'success',
|
|
19
21
|
});
|
|
22
|
+
display.endActivity('neo', true);
|
|
20
23
|
return result;
|
|
21
24
|
}
|
|
22
25
|
catch (err) {
|
|
26
|
+
display.endActivity('neo', false);
|
|
23
27
|
AuditRepository.getInstance().insert({
|
|
24
28
|
session_id: sessionId,
|
|
25
29
|
event_type: 'mcp_tool',
|
|
26
30
|
agent: 'neo',
|
|
27
|
-
tool_name:
|
|
31
|
+
tool_name: toolName,
|
|
28
32
|
duration_ms: Date.now() - startMs,
|
|
29
33
|
status: 'error',
|
|
30
34
|
metadata: { error: err?.message ?? String(err) },
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{j as e,m as o}from"./vendor-motion-C3CZ8ZlO.js";import{L as E,r as B}from"./vendor-react-DikRIOlj.js";import{a as D}from"./audit-M-5UGwoK.js";import{u as R}from"./agents-CN_AKX_I.js";import{u as O}from"./useCurrency-CEc5edm2.js";import{Y as _,V as F,h as L,i as I,au as v,I as j,o as N,A as z,g as S,ay as U,k as W,N as w,az as V,O as A,r as P,ak as H}from"./vendor-icons-DE7PWdkN.js";import"./vendor-utils-BIYveU_1.js";import"./index-Db1XEN8v.js";import"./config-7LGRnJ26.js";function m(r){return r>=1e6?`${(r/1e6).toFixed(1)}M`:r>=1e3?`${(r/1e3).toFixed(1)}k`:String(r)}function k(r){if(r<1e3)return`${r}ms`;if(r<6e4)return`${(r/1e3).toFixed(1)}s`;const i=Math.floor(r/6e4),l=Math.floor(r%6e4/1e3);return`${i}m ${l}s`}function G(r){return r?new Date(r).toLocaleString(void 0,{month:"short",day:"numeric",hour:"2-digit",minute:"2-digit"}):"—"}function T(r,i){return i?`${Math.round(r/i*100)}%`:"0%"}function J({data:r,fmtCost:i}){const[l,d]=B.useState(null);if(!r.length)return e.jsx("p",{className:"text-xs text-gray-400 dark:text-matrix-secondary/50 py-4",children:"No activity in the last 30 days."});const s=Math.max(...r.map(a=>a.eventCount),1);return e.jsx("div",{className:"flex items-end gap-0.5 h-24 w-full relative",children:r.map((a,g)=>{const y=Math.max(4,Math.round(a.eventCount/s*88)),p=l===g;return e.jsxs("div",{className:"flex-1 flex flex-col items-center justify-end group",onMouseEnter:()=>d(g),onMouseLeave:()=>d(null),children:[p&&e.jsxs("div",{className:"absolute -top-10 left-1/2 -translate-x-1/2 z-10 bg-gray-900 dark:bg-zinc-800 text-white text-[10px] rounded px-2 py-1 whitespace-nowrap pointer-events-none shadow-lg",children:[a.date,": ",a.eventCount," events · ",i(a.estimatedCostUsd)]}),e.jsx("div",{style:{height:y},className:`w-full rounded-t transition-colors ${p?"bg-blue-500 dark:bg-matrix-highlight":"bg-blue-300/70 dark:bg-matrix-highlight/40 group-hover:bg-blue-400 dark:group-hover:bg-matrix-highlight/60"}`})]},a.date)})})}function h({icon:r,label:i,value:l,sub:d,color:s="blue"}){const a={blue:"bg-blue-50 dark:bg-blue-900/20 text-blue-600 dark:text-blue-400 border-blue-200 dark:border-blue-800/40",green:"bg-green-50 dark:bg-green-900/20 text-green-600 dark:text-matrix-highlight border-green-200 dark:border-green-800/40",amber:"bg-amber-50 dark:bg-amber-900/20 text-amber-600 dark:text-amber-400 border-amber-200 dark:border-amber-800/40",purple:"bg-purple-50 dark:bg-purple-900/20 text-purple-600 dark:text-purple-400 border-purple-200 dark:border-purple-800/40",rose:"bg-rose-50 dark:bg-rose-900/20 text-rose-600 dark:text-rose-400 border-rose-200 dark:border-rose-800/40",teal:"bg-teal-50 dark:bg-teal-900/20 text-teal-600 dark:text-teal-400 border-teal-200 dark:border-teal-800/40"};return e.jsxs("div",{className:`rounded-lg border p-4 flex gap-3 items-start ${a[s]}`,children:[e.jsx("div",{className:"mt-0.5 flex-shrink-0",children:r}),e.jsxs("div",{className:"min-w-0",children:[e.jsx("p",{className:"text-xs font-medium opacity-70 uppercase tracking-wider mb-0.5",children:i}),e.jsx("p",{className:"text-xl font-bold font-mono leading-tight",children:l}),d&&e.jsx("div",{className:"text-[11px] opacity-60 mt-0.5 leading-snug",children:d})]})]})}function x({title:r,icon:i,children:l}){return e.jsxs("div",{className:"rounded-lg border border-gray-200 dark:border-matrix-primary overflow-hidden bg-white dark:bg-zinc-900 shadow-sm",children:[e.jsxs("div",{className:"px-4 py-3 bg-gray-50 dark:bg-zinc-900 border-b border-gray-200 dark:border-matrix-primary flex items-center gap-2",children:[e.jsx("span",{className:"text-gray-500 dark:text-matrix-secondary/70",children:i}),e.jsx("h2",{className:"text-sm font-semibold text-gray-700 dark:text-matrix-secondary uppercase tracking-wider",children:r})]}),e.jsx("div",{className:"p-4",children:l})]})}function M({agent:r}){const{getByKey:i}=R(),l=i(r);return e.jsxs("span",{className:`inline-flex items-center gap-1 text-[11px] font-semibold px-1.5 py-0.5 rounded ${l.badgeClass}`,children:[l.emoji," ",r.toUpperCase()]})}function K({status:r}){const i={active:"bg-green-100 text-green-700 dark:bg-green-900/30 dark:text-matrix-highlight",paused:"bg-gray-100 text-gray-600 dark:bg-zinc-800 dark:text-matrix-secondary",archived:"bg-amber-100 text-amber-700 dark:bg-amber-900/30 dark:text-amber-300",deleted:"bg-red-100 text-red-700 dark:bg-red-900/30 dark:text-red-400",unknown:"bg-gray-100 text-gray-500 dark:bg-zinc-800 dark:text-matrix-secondary/60"};return e.jsx("span",{className:`text-[10px] font-semibold uppercase px-1.5 py-0.5 rounded ${i[r]??i.unknown}`,children:r})}const Y={llm_call:e.jsx(v,{size:13}),tool_call:e.jsx(j,{size:13}),mcp_tool:e.jsxs("svg",{width:"13",height:"13",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg",children:[e.jsx("path",{d:"M3.49994 11.7501L11.6717 3.57855C12.7762 2.47398 14.5672 2.47398 15.6717 3.57855C16.7762 4.68312 16.7762 6.47398 15.6717 7.57855M15.6717 7.57855L9.49994 13.7501M15.6717 7.57855C16.7762 6.47398 18.5672 6.47398 19.6717 7.57855C20.7762 8.68312 20.7762 10.474 19.6717 11.5785L12.7072 18.543C12.3167 18.9335 12.3167 19.5667 12.7072 19.9572L13.9999 21.2499",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round"}),e.jsx("path",{d:"M17.4999 9.74921L11.3282 15.921C10.2237 17.0255 8.43272 17.0255 7.32823 15.921C6.22373 14.8164 6.22373 13.0255 7.32823 11.921L13.4999 5.74939",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round"})]}),memory_recovery:e.jsx(N,{size:13}),memory_persist:e.jsx(N,{size:13}),telephonist:e.jsx(A,{size:13}),skill_loaded:e.jsx(w,{size:13}),chronos_job:e.jsx(S,{size:13}),task_created:e.jsx(H,{size:13}),task_completed:e.jsx(P,{size:13})},Z={llm_call:"text-blue-500 dark:text-blue-400",tool_call:"text-amber-500 dark:text-amber-400",mcp_tool:"text-purple-500 dark:text-purple-400",memory_recovery:"text-emerald-500 dark:text-emerald-400",memory_persist:"text-violet-500 dark:text-violet-400",telephonist:"text-rose-500 dark:text-rose-400",skill_loaded:"text-teal-500 dark:text-teal-400",chronos_job:"text-orange-500 dark:text-orange-400",task_created:"text-gray-500 dark:text-matrix-secondary",task_completed:"text-green-600 dark:text-matrix-highlight"};function q({eventType:r}){return r==="mcp_tool"?e.jsx("span",{className:"flex-shrink-0 text-purple-500 dark:text-purple-400",children:e.jsxs("svg",{width:"13",height:"13",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg",children:[e.jsx("path",{d:"M3.49994 11.7501L11.6717 3.57855C12.7762 2.47398 14.5672 2.47398 15.6717 3.57855C16.7762 4.68312 16.7762 6.47398 15.6717 7.57855M15.6717 7.57855L9.49994 13.7501M15.6717 7.57855C16.7762 6.47398 18.5672 6.47398 19.6717 7.57855C20.7762 8.68312 20.7762 10.474 19.6717 11.5785L12.7072 18.543C12.3167 18.9335 12.3167 19.5667 12.7072 19.9572L13.9999 21.2499",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round"}),e.jsx("path",{d:"M17.4999 9.74921L11.3282 15.921C10.2237 17.0255 8.43272 17.0255 7.32823 15.921C6.22373 14.8164 6.22373 13.0255 7.32823 11.921L13.4999 5.74939",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round"})]})}):e.jsx(j,{size:13,className:"flex-shrink-0 text-amber-500 dark:text-amber-400"})}const Q={llm_call:"bg-blue-400 dark:bg-blue-500",tool_call:"bg-amber-400 dark:bg-amber-500",mcp_tool:"bg-purple-400 dark:bg-purple-500",memory_recovery:"bg-emerald-400 dark:bg-emerald-500",memory_persist:"bg-violet-400 dark:bg-violet-500",telephonist:"bg-rose-400 dark:bg-rose-500",skill_loaded:"bg-teal-400 dark:bg-teal-500",chronos_job:"bg-orange-400 dark:bg-orange-500",task_created:"bg-gray-300 dark:bg-matrix-secondary/50",task_completed:"bg-green-400 dark:bg-matrix-highlight/70"},X={hidden:{opacity:0},show:{opacity:1,transition:{staggerChildren:.04}}},c={hidden:{opacity:0,y:12},show:{opacity:1,y:0}},oe=()=>{const{data:r,isLoading:i,mutate:l}=D(),{fmtCost:d}=O();if(i)return e.jsxs("div",{className:"flex items-center justify-center h-64 gap-3 text-gray-400 dark:text-matrix-secondary",children:[e.jsx(_,{size:20,className:"animate-spin"}),e.jsx("span",{className:"text-sm font-mono",children:"Loading audit data…"})]});if(!r)return e.jsxs("div",{className:"flex flex-col items-center justify-center h-64 gap-2 text-gray-400 dark:text-matrix-secondary",children:[e.jsx(F,{size:24}),e.jsx("span",{className:"text-sm",children:"Failed to load audit data."})]});const{sessions:s,totals:a,byAgent:g,byModel:y,topTools:p,recentSessions:f,dailyActivity:b}=r,C=[["llm_call",a.llmCallCount],["tool_call",a.toolCallCount],["mcp_tool",a.mcpToolCount],["memory_recovery",a.memoryRecoveryCount],["memory_persist",a.memoryPersistCount],["telephonist",a.telephonistCount],["skill_loaded",a.skillCount],["chronos_job",a.chronosJobCount],["task_created",a.taskCreatedCount],["task_completed",a.taskCompletedCount]].filter(([,t])=>t>0).sort((t,n)=>n[1]-t[1]),$=Math.max(...C.map(([,t])=>t),1);return e.jsxs(o.div,{variants:X,initial:"hidden",animate:"show",className:"space-y-6",children:[e.jsxs(o.div,{variants:c,className:"flex items-center justify-between flex-wrap gap-3",children:[e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx("div",{className:"w-10 h-10 rounded-lg bg-blue-500/10 dark:bg-blue-500/20 border border-blue-200 dark:border-blue-800/40 flex items-center justify-center",children:e.jsx(L,{className:"w-5 h-5 text-blue-600 dark:text-blue-400"})}),e.jsxs("div",{children:[e.jsx("h1",{className:"text-xl font-bold text-gray-900 dark:text-matrix-highlight",children:"Global Audit"}),e.jsxs("p",{className:"text-sm text-gray-500 dark:text-matrix-secondary/60 mt-0.5",children:[s.withAudit," sessions with audit data · ",a.totalEventCount.toLocaleString()," events total"]})]})]}),e.jsxs("button",{onClick:()=>l(),className:"flex items-center gap-2 px-3 py-2 rounded-lg border border-gray-200 dark:border-matrix-primary text-sm text-gray-500 dark:text-matrix-secondary hover:bg-gray-50 dark:hover:bg-zinc-900 transition-colors",children:[e.jsx(_,{size:14})," Refresh"]})]}),e.jsxs(o.div,{variants:c,className:"grid grid-cols-2 md:grid-cols-3 lg:grid-cols-6 gap-3",children:[e.jsx(h,{icon:e.jsx(I,{size:16}),label:"Total Cost",value:d(a.estimatedCostUsd),color:"green"}),e.jsx(h,{icon:e.jsx(v,{size:16}),label:"LLM Calls",value:a.llmCallCount.toLocaleString(),color:"blue"}),e.jsx(h,{icon:e.jsx(j,{size:16}),label:"Tool Calls",value:(a.toolCallCount+a.mcpToolCount).toLocaleString(),sub:e.jsxs(e.Fragment,{children:[e.jsxs("span",{children:[a.toolCallCount," native"]}),e.jsx("br",{}),e.jsxs("span",{children:[a.mcpToolCount," MCP"]})]}),color:"amber"}),e.jsx(h,{icon:e.jsx(N,{size:16}),label:"Memory Hits",value:a.memoryRecoveryCount.toLocaleString(),color:"teal"}),e.jsx(h,{icon:e.jsx(z,{size:16}),label:"Total Tokens",value:m(a.totalInputTokens+a.totalOutputTokens),sub:e.jsxs(e.Fragment,{children:[e.jsxs("span",{children:["↑",m(a.totalInputTokens)," in"]}),e.jsx("br",{}),e.jsxs("span",{children:["↓",m(a.totalOutputTokens)," out"]})]}),color:"purple"}),e.jsx(h,{icon:e.jsx(S,{size:16}),label:"Total Time",value:k(a.totalDurationMs),color:"rose"})]}),e.jsxs(o.div,{variants:c,className:"grid grid-cols-1 md:grid-cols-2 gap-6",children:[e.jsxs(x,{title:"Sessions",icon:e.jsx(U,{size:14}),children:[e.jsx("div",{className:"grid grid-cols-2 gap-3 mb-4",children:[{label:"Total",value:s.total,cls:"text-gray-700 dark:text-matrix-secondary"},{label:"With Audit",value:s.withAudit,cls:"text-blue-600 dark:text-blue-400"},{label:"Active",value:s.active,cls:"text-green-600 dark:text-matrix-highlight"},{label:"Paused",value:s.paused,cls:"text-gray-500 dark:text-matrix-secondary"},{label:"Archived",value:s.archived,cls:"text-amber-600 dark:text-amber-400"},{label:"Deleted",value:s.deleted,cls:"text-red-500 dark:text-red-400"}].map(({label:t,value:n,cls:u})=>e.jsxs("div",{className:"flex flex-col",children:[e.jsx("span",{className:"text-[10px] uppercase tracking-widest text-gray-400 dark:text-matrix-secondary/50",children:t}),e.jsx("span",{className:`text-2xl font-bold font-mono ${u}`,children:n})]},t))}),s.total>0&&e.jsxs("div",{className:"h-2 rounded-full overflow-hidden flex gap-px",children:[s.active>0&&e.jsx("div",{className:"bg-green-400 dark:bg-matrix-highlight/70",style:{flex:s.active}}),s.paused>0&&e.jsx("div",{className:"bg-gray-300 dark:bg-matrix-primary/50",style:{flex:s.paused}}),s.archived>0&&e.jsx("div",{className:"bg-amber-400 dark:bg-amber-500/70",style:{flex:s.archived}}),s.deleted>0&&e.jsx("div",{className:"bg-red-400 dark:bg-red-500/70",style:{flex:s.deleted}})]})]}),e.jsxs(x,{title:"Activity — Last 30 Days",icon:e.jsx(W,{size:14}),children:[e.jsx(J,{data:b,fmtCost:d}),b.length>0&&e.jsxs("div",{className:"flex gap-4 mt-2 text-[11px] text-gray-400 dark:text-matrix-secondary/50 font-mono",children:[e.jsx("span",{children:b[0]?.date}),e.jsx("span",{className:"flex-1 text-right",children:b[b.length-1]?.date})]})]})]}),e.jsx(o.div,{variants:c,children:e.jsx(x,{title:"Events by Type",icon:e.jsx(z,{size:14}),children:e.jsx("div",{className:"space-y-2",children:C.map(([t,n])=>e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx("span",{className:`flex-shrink-0 w-5 flex justify-center ${Z[t]??"text-gray-400"}`,children:Y[t]}),e.jsx("span",{className:"text-xs font-mono text-gray-600 dark:text-matrix-secondary w-32 flex-shrink-0",children:t}),e.jsx("div",{className:"flex-1 h-2 bg-gray-100 dark:bg-zinc-800 rounded-full overflow-hidden",children:e.jsx("div",{className:`h-full rounded-full transition-all ${Q[t]??"bg-gray-400"}`,style:{width:T(n,$)}})}),e.jsx("span",{className:"text-xs font-mono text-gray-500 dark:text-matrix-secondary w-16 text-right",children:n.toLocaleString()}),e.jsx("span",{className:"text-[10px] text-gray-400 dark:text-matrix-secondary/50 w-10 text-right",children:T(n,a.totalEventCount)})]},t))})})}),e.jsxs(o.div,{variants:c,className:"grid grid-cols-1 lg:grid-cols-2 gap-6",children:[e.jsx(x,{title:"By Agent",icon:e.jsx(w,{size:14}),children:g.length===0?e.jsx("p",{className:"text-sm text-gray-400 dark:text-matrix-secondary/50",children:"No agent data."}):e.jsx("div",{className:"overflow-x-auto",children:e.jsxs("table",{className:"w-full text-xs font-mono",children:[e.jsx("thead",{children:e.jsxs("tr",{className:"text-[10px] uppercase tracking-wider text-gray-400 dark:text-matrix-secondary/50 border-b border-gray-100 dark:border-matrix-primary/30",children:[e.jsx("th",{className:"pb-2 text-left",children:"Agent"}),e.jsx("th",{className:"pb-2 text-right",children:"LLM"}),e.jsx("th",{className:"pb-2 text-right",children:"Tools"}),e.jsx("th",{className:"pb-2 text-right",children:"Tokens"}),e.jsx("th",{className:"pb-2 text-right",children:"Time"}),e.jsx("th",{className:"pb-2 text-right",children:"Cost"})]})}),e.jsx("tbody",{className:"divide-y divide-gray-50 dark:divide-matrix-primary/20",children:g.map(t=>e.jsxs("tr",{className:"hover:bg-gray-50 dark:hover:bg-zinc-900/50",children:[e.jsx("td",{className:"py-1.5",children:e.jsx(M,{agent:t.agent})}),e.jsx("td",{className:"py-1.5 text-right text-gray-600 dark:text-matrix-secondary",children:t.llmCalls.toLocaleString()}),e.jsx("td",{className:"py-1.5 text-right text-gray-600 dark:text-matrix-secondary",children:t.toolCalls.toLocaleString()}),e.jsxs("td",{className:"py-1.5 text-right text-gray-500 dark:text-matrix-secondary/70",children:["↑",m(t.inputTokens)," ↓",m(t.outputTokens)]}),e.jsx("td",{className:"py-1.5 text-right text-gray-500 dark:text-matrix-secondary/70",children:k(t.totalDurationMs)}),e.jsx("td",{className:"py-1.5 text-right font-semibold text-gray-700 dark:text-matrix-secondary",children:d(t.estimatedCostUsd)})]},t.agent))})]})})}),e.jsx(x,{title:"By Model",icon:e.jsx(v,{size:14}),children:y.length===0?e.jsx("p",{className:"text-sm text-gray-400 dark:text-matrix-secondary/50",children:"No model data."}):e.jsx("div",{className:"overflow-x-auto",children:e.jsxs("table",{className:"w-full text-xs font-mono",children:[e.jsx("thead",{children:e.jsxs("tr",{className:"text-[10px] uppercase tracking-wider text-gray-400 dark:text-matrix-secondary/50 border-b border-gray-100 dark:border-matrix-primary/30",children:[e.jsx("th",{className:"pb-2 text-left",children:"Model"}),e.jsx("th",{className:"pb-2 text-right",children:"Calls"}),e.jsx("th",{className:"pb-2 text-right",children:"In"}),e.jsx("th",{className:"pb-2 text-right",children:"Out"}),e.jsx("th",{className:"pb-2 text-right",children:"Cost"})]})}),e.jsx("tbody",{className:"divide-y divide-gray-50 dark:divide-matrix-primary/20",children:y.map(t=>e.jsxs("tr",{className:"hover:bg-gray-50 dark:hover:bg-zinc-900/50",children:[e.jsxs("td",{className:"py-1.5",children:[e.jsx("div",{className:"text-gray-700 dark:text-matrix-secondary break-all leading-tight",children:t.model}),e.jsx("div",{className:"text-[10px] text-gray-400 dark:text-matrix-secondary/40",children:t.provider})]}),e.jsx("td",{className:"py-1.5 text-right text-gray-600 dark:text-matrix-secondary",children:t.calls.toLocaleString()}),e.jsx("td",{className:"py-1.5 text-right text-gray-500 dark:text-matrix-secondary/70",children:m(t.inputTokens)}),e.jsx("td",{className:"py-1.5 text-right text-gray-500 dark:text-matrix-secondary/70",children:m(t.outputTokens)}),e.jsx("td",{className:"py-1.5 text-right font-semibold text-gray-700 dark:text-matrix-secondary",children:d(t.estimatedCostUsd)})]},`${t.provider}/${t.model}`))})]})})})]}),p.length>0&&e.jsx(o.div,{variants:c,children:e.jsx(x,{title:"Top Tools",icon:e.jsx(j,{size:14}),children:e.jsx("div",{className:"overflow-x-auto",children:e.jsxs("table",{className:"w-full text-xs font-mono",children:[e.jsx("thead",{children:e.jsxs("tr",{className:"text-[10px] uppercase tracking-wider text-gray-400 dark:text-matrix-secondary/50 border-b border-gray-100 dark:border-matrix-primary/30",children:[e.jsx("th",{className:"pb-2 text-left",children:"Tool"}),e.jsx("th",{className:"pb-2 text-left",children:"Agent"}),e.jsx("th",{className:"pb-2 text-right",children:"Calls"}),e.jsx("th",{className:"pb-2 text-right",children:"Errors"}),e.jsx("th",{className:"pb-2 text-right",children:"Error rate"})]})}),e.jsx("tbody",{className:"divide-y divide-gray-50 dark:divide-matrix-primary/20",children:p.map((t,n)=>{const u=t.count?t.errorCount/t.count:0;return e.jsxs("tr",{className:"hover:bg-gray-50 dark:hover:bg-zinc-900/50",children:[e.jsx("td",{className:"py-1.5",children:e.jsxs("div",{className:"flex items-center gap-1.5",children:[e.jsx(q,{eventType:t.event_type}),e.jsx("span",{className:"text-gray-700 dark:text-matrix-secondary break-all",children:t.tool_name})]})}),e.jsx("td",{className:"py-1.5",children:t.agent?e.jsx(M,{agent:t.agent}):e.jsx("span",{className:"text-gray-400",children:"—"})}),e.jsx("td",{className:"py-1.5 text-right text-gray-600 dark:text-matrix-secondary",children:t.count.toLocaleString()}),e.jsx("td",{className:"py-1.5 text-right",children:e.jsx("span",{className:t.errorCount>0?"text-red-500 dark:text-red-400":"text-gray-400 dark:text-matrix-secondary/50",children:t.errorCount})}),e.jsx("td",{className:"py-1.5 text-right",children:e.jsx("span",{className:u>.1?"text-red-500 dark:text-red-400":u>0?"text-amber-500 dark:text-amber-400":"text-gray-400 dark:text-matrix-secondary/50",children:t.count>0?`${Math.round(u*100)}%`:"—"})})]},n)})})]})})})}),e.jsx(o.div,{variants:c,children:e.jsx(x,{title:"Recent Sessions with Audit",icon:e.jsx(L,{size:14}),children:f.length===0?e.jsx("p",{className:"text-sm text-gray-400 dark:text-matrix-secondary/50",children:"No sessions with audit data yet."}):e.jsx("div",{className:"overflow-x-auto",children:e.jsxs("table",{className:"w-full text-xs font-mono",children:[e.jsx("thead",{children:e.jsxs("tr",{className:"text-[10px] uppercase tracking-wider text-gray-400 dark:text-matrix-secondary/50 border-b border-gray-100 dark:border-matrix-primary/30",children:[e.jsx("th",{className:"pb-2 text-left",children:"Session"}),e.jsx("th",{className:"pb-2 text-left",children:"Status"}),e.jsx("th",{className:"pb-2 text-right",children:"Events"}),e.jsx("th",{className:"pb-2 text-right",children:"LLM"}),e.jsx("th",{className:"pb-2 text-right",children:"Duration"}),e.jsx("th",{className:"pb-2 text-right",children:"Cost"}),e.jsx("th",{className:"pb-2"})]})}),e.jsx("tbody",{className:"divide-y divide-gray-50 dark:divide-matrix-primary/20",children:f.map(t=>e.jsxs("tr",{className:"hover:bg-gray-50 dark:hover:bg-zinc-900/50",children:[e.jsxs("td",{className:"py-2",children:[e.jsx("div",{className:"text-gray-700 dark:text-matrix-secondary truncate max-w-[160px]",title:t.title??t.session_id,children:t.title??e.jsxs("span",{className:"text-gray-400 dark:text-matrix-secondary/40 font-mono text-[10px]",children:[t.session_id.slice(0,12),"…"]})}),t.started_at&&e.jsx("div",{className:"text-[10px] text-gray-400 dark:text-matrix-secondary/40",children:G(t.started_at)})]}),e.jsx("td",{className:"py-2",children:e.jsx(K,{status:t.status})}),e.jsx("td",{className:"py-2 text-right text-gray-600 dark:text-matrix-secondary",children:t.event_count.toLocaleString()}),e.jsx("td",{className:"py-2 text-right text-gray-500 dark:text-matrix-secondary/70",children:t.llmCallCount.toLocaleString()}),e.jsx("td",{className:"py-2 text-right text-gray-500 dark:text-matrix-secondary/70",children:k(t.totalDurationMs)}),e.jsx("td",{className:"py-2 text-right font-semibold text-gray-700 dark:text-matrix-secondary",children:d(t.estimatedCostUsd)}),e.jsx("td",{className:"py-2 text-right",children:e.jsx(E,{to:`/sessions/${t.session_id}/audit`,className:"inline-flex items-center gap-1 px-2 py-1 rounded border border-gray-200 dark:border-matrix-primary text-gray-400 dark:text-matrix-secondary hover:text-blue-600 dark:hover:text-matrix-highlight hover:border-blue-300 dark:hover:border-matrix-highlight/50 transition-colors",title:"View session audit",children:e.jsx(V,{size:11})})})]},t.session_id))})]})})})}),a.telephonistCount>0&&e.jsx(o.div,{variants:c,children:e.jsx(x,{title:"Audio / Telephonist",icon:e.jsx(A,{size:14}),children:e.jsxs("div",{className:"flex flex-wrap gap-8",children:[e.jsxs("div",{children:[e.jsx("p",{className:"text-[10px] uppercase tracking-widest text-gray-400 dark:text-matrix-secondary/50 mb-0.5",children:"Calls"}),e.jsx("p",{className:"text-2xl font-bold font-mono text-rose-500 dark:text-rose-400",children:a.telephonistCount.toLocaleString()})]}),e.jsxs("div",{children:[e.jsx("p",{className:"text-[10px] uppercase tracking-widest text-gray-400 dark:text-matrix-secondary/50 mb-0.5",children:"Total Audio"}),e.jsx("p",{className:"text-2xl font-bold font-mono text-rose-500 dark:text-rose-400",children:a.totalAudioSeconds<60?`${a.totalAudioSeconds.toFixed(1)}s`:`${(a.totalAudioSeconds/60).toFixed(1)}m`})]})]})})})]})};export{oe as AuditDashboard};
|
|
1
|
+
import{j as e,m as o}from"./vendor-motion-C3CZ8ZlO.js";import{L as E,r as B}from"./vendor-react-DikRIOlj.js";import{a as D}from"./audit-CP5fC4m8.js";import{u as R}from"./agents-DO69pNM1.js";import{u as O}from"./useCurrency-Bgg-7MTE.js";import{Y as _,V as F,h as L,i as I,au as v,I as j,o as N,A as z,g as S,ay as U,k as W,N as w,az as V,O as A,r as P,ak as H}from"./vendor-icons-DE7PWdkN.js";import"./vendor-utils-BIYveU_1.js";import"./index-B9ePr-vB.js";import"./config-OLGQFNJL.js";function m(r){return r>=1e6?`${(r/1e6).toFixed(1)}M`:r>=1e3?`${(r/1e3).toFixed(1)}k`:String(r)}function k(r){if(r<1e3)return`${r}ms`;if(r<6e4)return`${(r/1e3).toFixed(1)}s`;const i=Math.floor(r/6e4),l=Math.floor(r%6e4/1e3);return`${i}m ${l}s`}function G(r){return r?new Date(r).toLocaleString(void 0,{month:"short",day:"numeric",hour:"2-digit",minute:"2-digit"}):"—"}function T(r,i){return i?`${Math.round(r/i*100)}%`:"0%"}function J({data:r,fmtCost:i}){const[l,d]=B.useState(null);if(!r.length)return e.jsx("p",{className:"text-xs text-gray-400 dark:text-matrix-secondary/50 py-4",children:"No activity in the last 30 days."});const s=Math.max(...r.map(a=>a.eventCount),1);return e.jsx("div",{className:"flex items-end gap-0.5 h-24 w-full relative",children:r.map((a,g)=>{const y=Math.max(4,Math.round(a.eventCount/s*88)),p=l===g;return e.jsxs("div",{className:"flex-1 flex flex-col items-center justify-end group",onMouseEnter:()=>d(g),onMouseLeave:()=>d(null),children:[p&&e.jsxs("div",{className:"absolute -top-10 left-1/2 -translate-x-1/2 z-10 bg-gray-900 dark:bg-zinc-800 text-white text-[10px] rounded px-2 py-1 whitespace-nowrap pointer-events-none shadow-lg",children:[a.date,": ",a.eventCount," events · ",i(a.estimatedCostUsd)]}),e.jsx("div",{style:{height:y},className:`w-full rounded-t transition-colors ${p?"bg-blue-500 dark:bg-matrix-highlight":"bg-blue-300/70 dark:bg-matrix-highlight/40 group-hover:bg-blue-400 dark:group-hover:bg-matrix-highlight/60"}`})]},a.date)})})}function h({icon:r,label:i,value:l,sub:d,color:s="blue"}){const a={blue:"bg-blue-50 dark:bg-blue-900/20 text-blue-600 dark:text-blue-400 border-blue-200 dark:border-blue-800/40",green:"bg-green-50 dark:bg-green-900/20 text-green-600 dark:text-matrix-highlight border-green-200 dark:border-green-800/40",amber:"bg-amber-50 dark:bg-amber-900/20 text-amber-600 dark:text-amber-400 border-amber-200 dark:border-amber-800/40",purple:"bg-purple-50 dark:bg-purple-900/20 text-purple-600 dark:text-purple-400 border-purple-200 dark:border-purple-800/40",rose:"bg-rose-50 dark:bg-rose-900/20 text-rose-600 dark:text-rose-400 border-rose-200 dark:border-rose-800/40",teal:"bg-teal-50 dark:bg-teal-900/20 text-teal-600 dark:text-teal-400 border-teal-200 dark:border-teal-800/40"};return e.jsxs("div",{className:`rounded-lg border p-4 flex gap-3 items-start ${a[s]}`,children:[e.jsx("div",{className:"mt-0.5 flex-shrink-0",children:r}),e.jsxs("div",{className:"min-w-0",children:[e.jsx("p",{className:"text-xs font-medium opacity-70 uppercase tracking-wider mb-0.5",children:i}),e.jsx("p",{className:"text-xl font-bold font-mono leading-tight",children:l}),d&&e.jsx("div",{className:"text-[11px] opacity-60 mt-0.5 leading-snug",children:d})]})]})}function x({title:r,icon:i,children:l}){return e.jsxs("div",{className:"rounded-lg border border-gray-200 dark:border-matrix-primary overflow-hidden bg-white dark:bg-zinc-900 shadow-sm",children:[e.jsxs("div",{className:"px-4 py-3 bg-gray-50 dark:bg-zinc-900 border-b border-gray-200 dark:border-matrix-primary flex items-center gap-2",children:[e.jsx("span",{className:"text-gray-500 dark:text-matrix-secondary/70",children:i}),e.jsx("h2",{className:"text-sm font-semibold text-gray-700 dark:text-matrix-secondary uppercase tracking-wider",children:r})]}),e.jsx("div",{className:"p-4",children:l})]})}function M({agent:r}){const{getByKey:i}=R(),l=i(r);return e.jsxs("span",{className:`inline-flex items-center gap-1 text-[11px] font-semibold px-1.5 py-0.5 rounded ${l.badgeClass}`,children:[l.emoji," ",r.toUpperCase()]})}function K({status:r}){const i={active:"bg-green-100 text-green-700 dark:bg-green-900/30 dark:text-matrix-highlight",paused:"bg-gray-100 text-gray-600 dark:bg-zinc-800 dark:text-matrix-secondary",archived:"bg-amber-100 text-amber-700 dark:bg-amber-900/30 dark:text-amber-300",deleted:"bg-red-100 text-red-700 dark:bg-red-900/30 dark:text-red-400",unknown:"bg-gray-100 text-gray-500 dark:bg-zinc-800 dark:text-matrix-secondary/60"};return e.jsx("span",{className:`text-[10px] font-semibold uppercase px-1.5 py-0.5 rounded ${i[r]??i.unknown}`,children:r})}const Y={llm_call:e.jsx(v,{size:13}),tool_call:e.jsx(j,{size:13}),mcp_tool:e.jsxs("svg",{width:"13",height:"13",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg",children:[e.jsx("path",{d:"M3.49994 11.7501L11.6717 3.57855C12.7762 2.47398 14.5672 2.47398 15.6717 3.57855C16.7762 4.68312 16.7762 6.47398 15.6717 7.57855M15.6717 7.57855L9.49994 13.7501M15.6717 7.57855C16.7762 6.47398 18.5672 6.47398 19.6717 7.57855C20.7762 8.68312 20.7762 10.474 19.6717 11.5785L12.7072 18.543C12.3167 18.9335 12.3167 19.5667 12.7072 19.9572L13.9999 21.2499",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round"}),e.jsx("path",{d:"M17.4999 9.74921L11.3282 15.921C10.2237 17.0255 8.43272 17.0255 7.32823 15.921C6.22373 14.8164 6.22373 13.0255 7.32823 11.921L13.4999 5.74939",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round"})]}),memory_recovery:e.jsx(N,{size:13}),memory_persist:e.jsx(N,{size:13}),telephonist:e.jsx(A,{size:13}),skill_loaded:e.jsx(w,{size:13}),chronos_job:e.jsx(S,{size:13}),task_created:e.jsx(H,{size:13}),task_completed:e.jsx(P,{size:13})},Z={llm_call:"text-blue-500 dark:text-blue-400",tool_call:"text-amber-500 dark:text-amber-400",mcp_tool:"text-purple-500 dark:text-purple-400",memory_recovery:"text-emerald-500 dark:text-emerald-400",memory_persist:"text-violet-500 dark:text-violet-400",telephonist:"text-rose-500 dark:text-rose-400",skill_loaded:"text-teal-500 dark:text-teal-400",chronos_job:"text-orange-500 dark:text-orange-400",task_created:"text-gray-500 dark:text-matrix-secondary",task_completed:"text-green-600 dark:text-matrix-highlight"};function q({eventType:r}){return r==="mcp_tool"?e.jsx("span",{className:"flex-shrink-0 text-purple-500 dark:text-purple-400",children:e.jsxs("svg",{width:"13",height:"13",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg",children:[e.jsx("path",{d:"M3.49994 11.7501L11.6717 3.57855C12.7762 2.47398 14.5672 2.47398 15.6717 3.57855C16.7762 4.68312 16.7762 6.47398 15.6717 7.57855M15.6717 7.57855L9.49994 13.7501M15.6717 7.57855C16.7762 6.47398 18.5672 6.47398 19.6717 7.57855C20.7762 8.68312 20.7762 10.474 19.6717 11.5785L12.7072 18.543C12.3167 18.9335 12.3167 19.5667 12.7072 19.9572L13.9999 21.2499",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round"}),e.jsx("path",{d:"M17.4999 9.74921L11.3282 15.921C10.2237 17.0255 8.43272 17.0255 7.32823 15.921C6.22373 14.8164 6.22373 13.0255 7.32823 11.921L13.4999 5.74939",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round"})]})}):e.jsx(j,{size:13,className:"flex-shrink-0 text-amber-500 dark:text-amber-400"})}const Q={llm_call:"bg-blue-400 dark:bg-blue-500",tool_call:"bg-amber-400 dark:bg-amber-500",mcp_tool:"bg-purple-400 dark:bg-purple-500",memory_recovery:"bg-emerald-400 dark:bg-emerald-500",memory_persist:"bg-violet-400 dark:bg-violet-500",telephonist:"bg-rose-400 dark:bg-rose-500",skill_loaded:"bg-teal-400 dark:bg-teal-500",chronos_job:"bg-orange-400 dark:bg-orange-500",task_created:"bg-gray-300 dark:bg-matrix-secondary/50",task_completed:"bg-green-400 dark:bg-matrix-highlight/70"},X={hidden:{opacity:0},show:{opacity:1,transition:{staggerChildren:.04}}},c={hidden:{opacity:0,y:12},show:{opacity:1,y:0}},oe=()=>{const{data:r,isLoading:i,mutate:l}=D(),{fmtCost:d}=O();if(i)return e.jsxs("div",{className:"flex items-center justify-center h-64 gap-3 text-gray-400 dark:text-matrix-secondary",children:[e.jsx(_,{size:20,className:"animate-spin"}),e.jsx("span",{className:"text-sm font-mono",children:"Loading audit data…"})]});if(!r)return e.jsxs("div",{className:"flex flex-col items-center justify-center h-64 gap-2 text-gray-400 dark:text-matrix-secondary",children:[e.jsx(F,{size:24}),e.jsx("span",{className:"text-sm",children:"Failed to load audit data."})]});const{sessions:s,totals:a,byAgent:g,byModel:y,topTools:p,recentSessions:f,dailyActivity:b}=r,C=[["llm_call",a.llmCallCount],["tool_call",a.toolCallCount],["mcp_tool",a.mcpToolCount],["memory_recovery",a.memoryRecoveryCount],["memory_persist",a.memoryPersistCount],["telephonist",a.telephonistCount],["skill_loaded",a.skillCount],["chronos_job",a.chronosJobCount],["task_created",a.taskCreatedCount],["task_completed",a.taskCompletedCount]].filter(([,t])=>t>0).sort((t,n)=>n[1]-t[1]),$=Math.max(...C.map(([,t])=>t),1);return e.jsxs(o.div,{variants:X,initial:"hidden",animate:"show",className:"space-y-6",children:[e.jsxs(o.div,{variants:c,className:"flex items-center justify-between flex-wrap gap-3",children:[e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx("div",{className:"w-10 h-10 rounded-lg bg-blue-500/10 dark:bg-blue-500/20 border border-blue-200 dark:border-blue-800/40 flex items-center justify-center",children:e.jsx(L,{className:"w-5 h-5 text-blue-600 dark:text-blue-400"})}),e.jsxs("div",{children:[e.jsx("h1",{className:"text-xl font-bold text-gray-900 dark:text-matrix-highlight",children:"Global Audit"}),e.jsxs("p",{className:"text-sm text-gray-500 dark:text-matrix-secondary/60 mt-0.5",children:[s.withAudit," sessions with audit data · ",a.totalEventCount.toLocaleString()," events total"]})]})]}),e.jsxs("button",{onClick:()=>l(),className:"flex items-center gap-2 px-3 py-2 rounded-lg border border-gray-200 dark:border-matrix-primary text-sm text-gray-500 dark:text-matrix-secondary hover:bg-gray-50 dark:hover:bg-zinc-900 transition-colors",children:[e.jsx(_,{size:14})," Refresh"]})]}),e.jsxs(o.div,{variants:c,className:"grid grid-cols-2 md:grid-cols-3 lg:grid-cols-6 gap-3",children:[e.jsx(h,{icon:e.jsx(I,{size:16}),label:"Total Cost",value:d(a.estimatedCostUsd),color:"green"}),e.jsx(h,{icon:e.jsx(v,{size:16}),label:"LLM Calls",value:a.llmCallCount.toLocaleString(),color:"blue"}),e.jsx(h,{icon:e.jsx(j,{size:16}),label:"Tool Calls",value:(a.toolCallCount+a.mcpToolCount).toLocaleString(),sub:e.jsxs(e.Fragment,{children:[e.jsxs("span",{children:[a.toolCallCount," native"]}),e.jsx("br",{}),e.jsxs("span",{children:[a.mcpToolCount," MCP"]})]}),color:"amber"}),e.jsx(h,{icon:e.jsx(N,{size:16}),label:"Memory Hits",value:a.memoryRecoveryCount.toLocaleString(),color:"teal"}),e.jsx(h,{icon:e.jsx(z,{size:16}),label:"Total Tokens",value:m(a.totalInputTokens+a.totalOutputTokens),sub:e.jsxs(e.Fragment,{children:[e.jsxs("span",{children:["↑",m(a.totalInputTokens)," in"]}),e.jsx("br",{}),e.jsxs("span",{children:["↓",m(a.totalOutputTokens)," out"]})]}),color:"purple"}),e.jsx(h,{icon:e.jsx(S,{size:16}),label:"Total Time",value:k(a.totalDurationMs),color:"rose"})]}),e.jsxs(o.div,{variants:c,className:"grid grid-cols-1 md:grid-cols-2 gap-6",children:[e.jsxs(x,{title:"Sessions",icon:e.jsx(U,{size:14}),children:[e.jsx("div",{className:"grid grid-cols-2 gap-3 mb-4",children:[{label:"Total",value:s.total,cls:"text-gray-700 dark:text-matrix-secondary"},{label:"With Audit",value:s.withAudit,cls:"text-blue-600 dark:text-blue-400"},{label:"Active",value:s.active,cls:"text-green-600 dark:text-matrix-highlight"},{label:"Paused",value:s.paused,cls:"text-gray-500 dark:text-matrix-secondary"},{label:"Archived",value:s.archived,cls:"text-amber-600 dark:text-amber-400"},{label:"Deleted",value:s.deleted,cls:"text-red-500 dark:text-red-400"}].map(({label:t,value:n,cls:u})=>e.jsxs("div",{className:"flex flex-col",children:[e.jsx("span",{className:"text-[10px] uppercase tracking-widest text-gray-400 dark:text-matrix-secondary/50",children:t}),e.jsx("span",{className:`text-2xl font-bold font-mono ${u}`,children:n})]},t))}),s.total>0&&e.jsxs("div",{className:"h-2 rounded-full overflow-hidden flex gap-px",children:[s.active>0&&e.jsx("div",{className:"bg-green-400 dark:bg-matrix-highlight/70",style:{flex:s.active}}),s.paused>0&&e.jsx("div",{className:"bg-gray-300 dark:bg-matrix-primary/50",style:{flex:s.paused}}),s.archived>0&&e.jsx("div",{className:"bg-amber-400 dark:bg-amber-500/70",style:{flex:s.archived}}),s.deleted>0&&e.jsx("div",{className:"bg-red-400 dark:bg-red-500/70",style:{flex:s.deleted}})]})]}),e.jsxs(x,{title:"Activity — Last 30 Days",icon:e.jsx(W,{size:14}),children:[e.jsx(J,{data:b,fmtCost:d}),b.length>0&&e.jsxs("div",{className:"flex gap-4 mt-2 text-[11px] text-gray-400 dark:text-matrix-secondary/50 font-mono",children:[e.jsx("span",{children:b[0]?.date}),e.jsx("span",{className:"flex-1 text-right",children:b[b.length-1]?.date})]})]})]}),e.jsx(o.div,{variants:c,children:e.jsx(x,{title:"Events by Type",icon:e.jsx(z,{size:14}),children:e.jsx("div",{className:"space-y-2",children:C.map(([t,n])=>e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx("span",{className:`flex-shrink-0 w-5 flex justify-center ${Z[t]??"text-gray-400"}`,children:Y[t]}),e.jsx("span",{className:"text-xs font-mono text-gray-600 dark:text-matrix-secondary w-32 flex-shrink-0",children:t}),e.jsx("div",{className:"flex-1 h-2 bg-gray-100 dark:bg-zinc-800 rounded-full overflow-hidden",children:e.jsx("div",{className:`h-full rounded-full transition-all ${Q[t]??"bg-gray-400"}`,style:{width:T(n,$)}})}),e.jsx("span",{className:"text-xs font-mono text-gray-500 dark:text-matrix-secondary w-16 text-right",children:n.toLocaleString()}),e.jsx("span",{className:"text-[10px] text-gray-400 dark:text-matrix-secondary/50 w-10 text-right",children:T(n,a.totalEventCount)})]},t))})})}),e.jsxs(o.div,{variants:c,className:"grid grid-cols-1 lg:grid-cols-2 gap-6",children:[e.jsx(x,{title:"By Agent",icon:e.jsx(w,{size:14}),children:g.length===0?e.jsx("p",{className:"text-sm text-gray-400 dark:text-matrix-secondary/50",children:"No agent data."}):e.jsx("div",{className:"overflow-x-auto",children:e.jsxs("table",{className:"w-full text-xs font-mono",children:[e.jsx("thead",{children:e.jsxs("tr",{className:"text-[10px] uppercase tracking-wider text-gray-400 dark:text-matrix-secondary/50 border-b border-gray-100 dark:border-matrix-primary/30",children:[e.jsx("th",{className:"pb-2 text-left",children:"Agent"}),e.jsx("th",{className:"pb-2 text-right",children:"LLM"}),e.jsx("th",{className:"pb-2 text-right",children:"Tools"}),e.jsx("th",{className:"pb-2 text-right",children:"Tokens"}),e.jsx("th",{className:"pb-2 text-right",children:"Time"}),e.jsx("th",{className:"pb-2 text-right",children:"Cost"})]})}),e.jsx("tbody",{className:"divide-y divide-gray-50 dark:divide-matrix-primary/20",children:g.map(t=>e.jsxs("tr",{className:"hover:bg-gray-50 dark:hover:bg-zinc-900/50",children:[e.jsx("td",{className:"py-1.5",children:e.jsx(M,{agent:t.agent})}),e.jsx("td",{className:"py-1.5 text-right text-gray-600 dark:text-matrix-secondary",children:t.llmCalls.toLocaleString()}),e.jsx("td",{className:"py-1.5 text-right text-gray-600 dark:text-matrix-secondary",children:t.toolCalls.toLocaleString()}),e.jsxs("td",{className:"py-1.5 text-right text-gray-500 dark:text-matrix-secondary/70",children:["↑",m(t.inputTokens)," ↓",m(t.outputTokens)]}),e.jsx("td",{className:"py-1.5 text-right text-gray-500 dark:text-matrix-secondary/70",children:k(t.totalDurationMs)}),e.jsx("td",{className:"py-1.5 text-right font-semibold text-gray-700 dark:text-matrix-secondary",children:d(t.estimatedCostUsd)})]},t.agent))})]})})}),e.jsx(x,{title:"By Model",icon:e.jsx(v,{size:14}),children:y.length===0?e.jsx("p",{className:"text-sm text-gray-400 dark:text-matrix-secondary/50",children:"No model data."}):e.jsx("div",{className:"overflow-x-auto",children:e.jsxs("table",{className:"w-full text-xs font-mono",children:[e.jsx("thead",{children:e.jsxs("tr",{className:"text-[10px] uppercase tracking-wider text-gray-400 dark:text-matrix-secondary/50 border-b border-gray-100 dark:border-matrix-primary/30",children:[e.jsx("th",{className:"pb-2 text-left",children:"Model"}),e.jsx("th",{className:"pb-2 text-right",children:"Calls"}),e.jsx("th",{className:"pb-2 text-right",children:"In"}),e.jsx("th",{className:"pb-2 text-right",children:"Out"}),e.jsx("th",{className:"pb-2 text-right",children:"Cost"})]})}),e.jsx("tbody",{className:"divide-y divide-gray-50 dark:divide-matrix-primary/20",children:y.map(t=>e.jsxs("tr",{className:"hover:bg-gray-50 dark:hover:bg-zinc-900/50",children:[e.jsxs("td",{className:"py-1.5",children:[e.jsx("div",{className:"text-gray-700 dark:text-matrix-secondary break-all leading-tight",children:t.model}),e.jsx("div",{className:"text-[10px] text-gray-400 dark:text-matrix-secondary/40",children:t.provider})]}),e.jsx("td",{className:"py-1.5 text-right text-gray-600 dark:text-matrix-secondary",children:t.calls.toLocaleString()}),e.jsx("td",{className:"py-1.5 text-right text-gray-500 dark:text-matrix-secondary/70",children:m(t.inputTokens)}),e.jsx("td",{className:"py-1.5 text-right text-gray-500 dark:text-matrix-secondary/70",children:m(t.outputTokens)}),e.jsx("td",{className:"py-1.5 text-right font-semibold text-gray-700 dark:text-matrix-secondary",children:d(t.estimatedCostUsd)})]},`${t.provider}/${t.model}`))})]})})})]}),p.length>0&&e.jsx(o.div,{variants:c,children:e.jsx(x,{title:"Top Tools",icon:e.jsx(j,{size:14}),children:e.jsx("div",{className:"overflow-x-auto",children:e.jsxs("table",{className:"w-full text-xs font-mono",children:[e.jsx("thead",{children:e.jsxs("tr",{className:"text-[10px] uppercase tracking-wider text-gray-400 dark:text-matrix-secondary/50 border-b border-gray-100 dark:border-matrix-primary/30",children:[e.jsx("th",{className:"pb-2 text-left",children:"Tool"}),e.jsx("th",{className:"pb-2 text-left",children:"Agent"}),e.jsx("th",{className:"pb-2 text-right",children:"Calls"}),e.jsx("th",{className:"pb-2 text-right",children:"Errors"}),e.jsx("th",{className:"pb-2 text-right",children:"Error rate"})]})}),e.jsx("tbody",{className:"divide-y divide-gray-50 dark:divide-matrix-primary/20",children:p.map((t,n)=>{const u=t.count?t.errorCount/t.count:0;return e.jsxs("tr",{className:"hover:bg-gray-50 dark:hover:bg-zinc-900/50",children:[e.jsx("td",{className:"py-1.5",children:e.jsxs("div",{className:"flex items-center gap-1.5",children:[e.jsx(q,{eventType:t.event_type}),e.jsx("span",{className:"text-gray-700 dark:text-matrix-secondary break-all",children:t.tool_name})]})}),e.jsx("td",{className:"py-1.5",children:t.agent?e.jsx(M,{agent:t.agent}):e.jsx("span",{className:"text-gray-400",children:"—"})}),e.jsx("td",{className:"py-1.5 text-right text-gray-600 dark:text-matrix-secondary",children:t.count.toLocaleString()}),e.jsx("td",{className:"py-1.5 text-right",children:e.jsx("span",{className:t.errorCount>0?"text-red-500 dark:text-red-400":"text-gray-400 dark:text-matrix-secondary/50",children:t.errorCount})}),e.jsx("td",{className:"py-1.5 text-right",children:e.jsx("span",{className:u>.1?"text-red-500 dark:text-red-400":u>0?"text-amber-500 dark:text-amber-400":"text-gray-400 dark:text-matrix-secondary/50",children:t.count>0?`${Math.round(u*100)}%`:"—"})})]},n)})})]})})})}),e.jsx(o.div,{variants:c,children:e.jsx(x,{title:"Recent Sessions with Audit",icon:e.jsx(L,{size:14}),children:f.length===0?e.jsx("p",{className:"text-sm text-gray-400 dark:text-matrix-secondary/50",children:"No sessions with audit data yet."}):e.jsx("div",{className:"overflow-x-auto",children:e.jsxs("table",{className:"w-full text-xs font-mono",children:[e.jsx("thead",{children:e.jsxs("tr",{className:"text-[10px] uppercase tracking-wider text-gray-400 dark:text-matrix-secondary/50 border-b border-gray-100 dark:border-matrix-primary/30",children:[e.jsx("th",{className:"pb-2 text-left",children:"Session"}),e.jsx("th",{className:"pb-2 text-left",children:"Status"}),e.jsx("th",{className:"pb-2 text-right",children:"Events"}),e.jsx("th",{className:"pb-2 text-right",children:"LLM"}),e.jsx("th",{className:"pb-2 text-right",children:"Duration"}),e.jsx("th",{className:"pb-2 text-right",children:"Cost"}),e.jsx("th",{className:"pb-2"})]})}),e.jsx("tbody",{className:"divide-y divide-gray-50 dark:divide-matrix-primary/20",children:f.map(t=>e.jsxs("tr",{className:"hover:bg-gray-50 dark:hover:bg-zinc-900/50",children:[e.jsxs("td",{className:"py-2",children:[e.jsx("div",{className:"text-gray-700 dark:text-matrix-secondary truncate max-w-[160px]",title:t.title??t.session_id,children:t.title??e.jsxs("span",{className:"text-gray-400 dark:text-matrix-secondary/40 font-mono text-[10px]",children:[t.session_id.slice(0,12),"…"]})}),t.started_at&&e.jsx("div",{className:"text-[10px] text-gray-400 dark:text-matrix-secondary/40",children:G(t.started_at)})]}),e.jsx("td",{className:"py-2",children:e.jsx(K,{status:t.status})}),e.jsx("td",{className:"py-2 text-right text-gray-600 dark:text-matrix-secondary",children:t.event_count.toLocaleString()}),e.jsx("td",{className:"py-2 text-right text-gray-500 dark:text-matrix-secondary/70",children:t.llmCallCount.toLocaleString()}),e.jsx("td",{className:"py-2 text-right text-gray-500 dark:text-matrix-secondary/70",children:k(t.totalDurationMs)}),e.jsx("td",{className:"py-2 text-right font-semibold text-gray-700 dark:text-matrix-secondary",children:d(t.estimatedCostUsd)}),e.jsx("td",{className:"py-2 text-right",children:e.jsx(E,{to:`/sessions/${t.session_id}/audit`,className:"inline-flex items-center gap-1 px-2 py-1 rounded border border-gray-200 dark:border-matrix-primary text-gray-400 dark:text-matrix-secondary hover:text-blue-600 dark:hover:text-matrix-highlight hover:border-blue-300 dark:hover:border-matrix-highlight/50 transition-colors",title:"View session audit",children:e.jsx(V,{size:11})})})]},t.session_id))})]})})})}),a.telephonistCount>0&&e.jsx(o.div,{variants:c,children:e.jsx(x,{title:"Audio / Telephonist",icon:e.jsx(A,{size:14}),children:e.jsxs("div",{className:"flex flex-wrap gap-8",children:[e.jsxs("div",{children:[e.jsx("p",{className:"text-[10px] uppercase tracking-widest text-gray-400 dark:text-matrix-secondary/50 mb-0.5",children:"Calls"}),e.jsx("p",{className:"text-2xl font-bold font-mono text-rose-500 dark:text-rose-400",children:a.telephonistCount.toLocaleString()})]}),e.jsxs("div",{children:[e.jsx("p",{className:"text-[10px] uppercase tracking-widest text-gray-400 dark:text-matrix-secondary/50 mb-0.5",children:"Total Audio"}),e.jsx("p",{className:"text-2xl font-bold font-mono text-rose-500 dark:text-rose-400",children:a.totalAudioSeconds<60?`${a.totalAudioSeconds.toFixed(1)}s`:`${(a.totalAudioSeconds/60).toFixed(1)}m`})]})]})})})]})};export{oe as AuditDashboard};
|