morpheus-cli 0.8.9 → 0.9.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (57) hide show
  1. package/dist/channels/discord.js +133 -6
  2. package/dist/channels/telegram.js +23 -17
  3. package/dist/http/api.js +2 -3
  4. package/dist/runtime/__tests__/keymaker.test.js +5 -2
  5. package/dist/runtime/apoc.js +7 -7
  6. package/dist/{devkit/registry.js → runtime/devkit-instrument.js} +5 -29
  7. package/dist/runtime/keymaker.js +6 -5
  8. package/dist/runtime/memory/sati/service.js +1 -1
  9. package/dist/runtime/memory/sqlite.js +31 -124
  10. package/dist/runtime/neo.js +1 -1
  11. package/dist/runtime/oracle.js +30 -52
  12. package/dist/runtime/smiths/delegator.js +2 -2
  13. package/dist/runtime/trinity.js +1 -1
  14. package/dist/ui/assets/{AuditDashboard-5sA8Sd8S.js → AuditDashboard-nVV9KKFp.js} +1 -1
  15. package/dist/ui/assets/Chat-ChsmnZzq.js +41 -0
  16. package/dist/ui/assets/{Chronos-BAjeLobF.js → Chronos-kgO7IkEj.js} +1 -1
  17. package/dist/ui/assets/{ConfirmationModal-fvgnOWTY.js → ConfirmationModal-D1BYPXJ4.js} +1 -1
  18. package/dist/ui/assets/{Dashboard-Ca5mSefz.js → Dashboard-DWB5NwQn.js} +1 -1
  19. package/dist/ui/assets/{DeleteConfirmationModal-A8EmnHoa.js → DeleteConfirmationModal-CgIMbyB7.js} +1 -1
  20. package/dist/ui/assets/{Logs-CYu7se7R.js → Logs-DGdRnEFi.js} +1 -1
  21. package/dist/ui/assets/{MCPManager-DsDA_ZVT.js → MCPManager-BDjWMRRX.js} +1 -1
  22. package/dist/ui/assets/{ModelPricing-DnSm_Nh-.js → ModelPricing-DAk1sS7D.js} +1 -1
  23. package/dist/ui/assets/{Notifications-CiljQzvM.js → Notifications-DMEq6EZR.js} +1 -1
  24. package/dist/ui/assets/{SatiMemories-rnO2b0LG.js → SatiMemories-BxicQE35.js} +1 -1
  25. package/dist/ui/assets/{SessionAudit-Dfvhge3Z.js → SessionAudit-CKJQf9LU.js} +1 -1
  26. package/dist/ui/assets/{Settings-OQlHAJoy.js → Settings-CulMd4Qr.js} +1 -1
  27. package/dist/ui/assets/{Skills-Crsybug0.js → Skills-DPoqYa8Y.js} +1 -1
  28. package/dist/ui/assets/{Smiths-wm90jRDT.js → Smiths-Clamjlph.js} +1 -1
  29. package/dist/ui/assets/{Tasks-C5FMu_Yu.js → Tasks-BfTkhB1J.js} +1 -1
  30. package/dist/ui/assets/{TrinityDatabases-BzYfecKI.js → TrinityDatabases-BmM1S9aQ.js} +1 -1
  31. package/dist/ui/assets/{UsageStats-CBo2vW2n.js → UsageStats-aAu2DFlb.js} +1 -1
  32. package/dist/ui/assets/{WebhookManager-0tDFkfHd.js → WebhookManager-DdnRSWl9.js} +1 -1
  33. package/dist/ui/assets/{audit-B-F8XPLi.js → audit-CqszEkOd.js} +1 -1
  34. package/dist/ui/assets/{chronos-BvMxfBQH.js → chronos-CPwFWid9.js} +1 -1
  35. package/dist/ui/assets/{config-DteVgNGR.js → config-D0DePxKu.js} +1 -1
  36. package/dist/ui/assets/{index-Cwqr-n0Y.js → index-BxVeRyTh.js} +2 -2
  37. package/dist/ui/assets/index-OLhpm8I7.css +1 -0
  38. package/dist/ui/assets/{mcp-DxzodOdH.js → mcp-Gjc3IZpO.js} +1 -1
  39. package/dist/ui/assets/{skills--hAyQnmG.js → skills-B5DnmnHW.js} +1 -1
  40. package/dist/ui/assets/{stats-Cibaisqd.js → stats-BAse7jj0.js} +1 -1
  41. package/dist/ui/index.html +2 -2
  42. package/dist/ui/sw.js +1 -1
  43. package/package.json +6 -4
  44. package/dist/devkit/adapters/shell.js +0 -80
  45. package/dist/devkit/index.js +0 -11
  46. package/dist/devkit/tools/browser.js +0 -825
  47. package/dist/devkit/tools/filesystem.js +0 -235
  48. package/dist/devkit/tools/git.js +0 -226
  49. package/dist/devkit/tools/network.js +0 -165
  50. package/dist/devkit/tools/packages.js +0 -73
  51. package/dist/devkit/tools/processes.js +0 -130
  52. package/dist/devkit/tools/shell.js +0 -106
  53. package/dist/devkit/tools/system.js +0 -132
  54. package/dist/devkit/types.js +0 -1
  55. package/dist/devkit/utils.js +0 -45
  56. package/dist/ui/assets/Chat-CjxeAQmd.js +0 -41
  57. package/dist/ui/assets/index-DcfyUdLI.css +0 -1
@@ -716,36 +716,19 @@ export class SQLiteChatMessageHistory extends BaseListChatMessageHistory {
716
716
  }
717
717
  async createNewSession() {
718
718
  const now = Date.now();
719
- // Transação para garantir consistência
720
- const tx = this.db.transaction(() => {
721
- // Pegar a sessão atualmente ativa
722
- const activeSession = this.db.prepare(`
723
- SELECT id FROM sessions
724
- WHERE status = 'active'
725
- `).get();
726
- // Se houver uma sessão ativa, mudar seu status para 'paused'
727
- if (activeSession) {
728
- this.db.prepare(`
729
- UPDATE sessions
730
- SET status = 'paused'
731
- WHERE id = ?
732
- `).run(activeSession.id);
733
- }
734
- // Criar uma nova sessão ativa
735
- const newId = randomUUID();
736
- this.db.prepare(`
737
- INSERT INTO sessions (
738
- id,
739
- started_at,
740
- status
741
- ) VALUES (?, ?, 'active')
742
- `).run(newId, now);
743
- // Atualizar o ID da sessão atual desta instância
744
- this.sessionId = newId;
745
- this.titleSet = false; // reset cache for new session
746
- });
747
- tx(); // Executar a transação
748
- this.display.log('✅ Nova sessão iniciada e sessão anterior pausada', { source: 'Sati' });
719
+ const newId = randomUUID();
720
+ this.db.prepare(`
721
+ INSERT INTO sessions (
722
+ id,
723
+ started_at,
724
+ status
725
+ ) VALUES (?, ?, 'active')
726
+ `).run(newId, now);
727
+ // Update this instance to point to the new session
728
+ this.sessionId = newId;
729
+ this.titleSet = false;
730
+ this.display.log('✅ New session created', { source: 'Sati' });
731
+ return newId;
749
732
  }
750
733
  chunkText(text, chunkSize = 500, overlap = 50) {
751
734
  if (!text || text.length === 0)
@@ -890,27 +873,6 @@ export class SQLiteChatMessageHistory extends BaseListChatMessageHistory {
890
873
  `).run(now, sessionId);
891
874
  });
892
875
  tx(); // Executar a transação
893
- // Se a sessão era active, verificar se há outra para ativar
894
- if (session.status === 'active') {
895
- const nextSession = this.db.prepare(`
896
- SELECT id FROM sessions
897
- WHERE status = 'paused'
898
- ORDER BY started_at DESC
899
- LIMIT 1
900
- `).get();
901
- if (nextSession) {
902
- // Promover a próxima sessão a ativa
903
- this.db.prepare(`
904
- UPDATE sessions
905
- SET status = 'active'
906
- WHERE id = ?
907
- `).run(nextSession.id);
908
- }
909
- else {
910
- // Nenhuma outra sessão, criar nova
911
- this.createFreshSession();
912
- }
913
- }
914
876
  }
915
877
  /**
916
878
  * Renomear uma sessão ativa ou pausada.
@@ -941,101 +903,46 @@ export class SQLiteChatMessageHistory extends BaseListChatMessageHistory {
941
903
  tx(); // Executar a transação
942
904
  }
943
905
  /**
944
- * Trocar o contexto ativo entre sessões não finalizadas.
945
- * Validar sessão alvo: existe e status ∈ (paused, active).
946
- * Se já for active, não faz nada.
947
- * Transação: sessão atual active → paused, sessão alvo → active.
948
- */
949
- /**
950
- * Creates a session row with status 'paused' if it doesn't already exist.
906
+ * Creates a session row with status 'active' if it doesn't already exist.
951
907
  * Safe to call multiple times — idempotent.
952
908
  */
953
909
  ensureSession(sessionId) {
954
910
  const existing = this.db.prepare('SELECT id FROM sessions WHERE id = ?').get(sessionId);
955
911
  if (!existing) {
956
- this.db.prepare("INSERT INTO sessions (id, started_at, status) VALUES (?, ?, 'paused')").run(sessionId, Date.now());
912
+ this.db.prepare("INSERT INTO sessions (id, started_at, status) VALUES (?, ?, 'active')").run(sessionId, Date.now());
957
913
  }
958
914
  }
915
+ /**
916
+ * Validates that the target session exists and is usable (not archived/deleted).
917
+ * No longer swaps active↔paused — sessions are independently usable from any channel.
918
+ */
959
919
  async switchSession(targetSessionId) {
960
- // Validar sessão alvo: existe e status ∈ (paused, active)
961
920
  const targetSession = this.db.prepare(`
962
921
  SELECT id, status FROM sessions
963
922
  WHERE id = ?
964
923
  `).get(targetSessionId);
965
924
  if (!targetSession) {
966
- throw new Error(`Sessão alvo com ID ${targetSessionId} não encontrada.`);
925
+ throw new Error(`Session with ID ${targetSessionId} not found.`);
967
926
  }
968
- if (targetSession.status !== 'active' && targetSession.status !== 'paused') {
969
- throw new Error(`Sessão alvo com ID ${targetSessionId} não está em estado ativo ou pausado. Status atual: ${targetSession.status}`);
927
+ if (targetSession.status === 'archived' || targetSession.status === 'deleted') {
928
+ throw new Error(`Session ${targetSessionId} is ${targetSession.status} and cannot be used.`);
970
929
  }
971
- // Se já for active, não faz nada
972
- if (targetSession.status === 'active') {
973
- return; // A sessão alvo já está ativa, não precisa fazer nada
974
- }
975
- // Transação: sessão atual active → paused, sessão alvo → active
976
- const tx = this.db.transaction(() => {
977
- // Pegar a sessão atualmente ativa
978
- const currentActiveSession = this.db.prepare(`
979
- SELECT id FROM sessions
980
- WHERE status = 'active'
981
- `).get();
982
- // Se houver uma sessão ativa, mudar seu status para 'paused'
983
- if (currentActiveSession) {
984
- this.db.prepare(`
985
- UPDATE sessions
986
- SET status = 'paused'
987
- WHERE id = ?
988
- `).run(currentActiveSession.id);
989
- }
990
- // Mudar o status da sessão alvo para 'active'
991
- this.db.prepare(`
992
- UPDATE sessions
993
- SET status = 'active'
994
- WHERE id = ?
995
- `).run(targetSessionId);
996
- });
997
- tx(); // Executar a transação
998
930
  }
999
931
  /**
1000
- * Garantir que sempre exista uma sessão ativa válida.
1001
- * Buscar sessão com status = 'active', retornar seu id se existir,
1002
- * ou criar nova sessão (createFreshSession) e retornar o novo id.
932
+ * Returns the most recently created usable session, or creates one if none exist.
933
+ * A session is usable if its status is 'active' or 'paused' (both are equivalent post-refactor).
1003
934
  */
1004
935
  async getCurrentSessionOrCreate() {
1005
- // Buscar sessão com status = 'active'
1006
- const activeSession = this.db.prepare(`
1007
- SELECT id FROM sessions
1008
- WHERE status = 'active'
1009
- `).get();
1010
- if (activeSession) {
1011
- // Se existir, retornar seu id
1012
- return activeSession.id;
1013
- }
1014
- else {
1015
- // Se não existir, criar nova sessão (createFreshSession) e retornar o novo id
1016
- const newId = await this.createFreshSession();
1017
- return newId;
1018
- }
1019
- }
1020
- async createFreshSession() {
1021
- // Validar que não existe sessão 'active'
1022
- const activeSession = this.db.prepare(`
936
+ const session = this.db.prepare(`
1023
937
  SELECT id FROM sessions
1024
- WHERE status = 'active'
938
+ WHERE status IN ('active', 'paused')
939
+ ORDER BY started_at DESC
940
+ LIMIT 1
1025
941
  `).get();
1026
- if (activeSession) {
1027
- throw new Error('Já existe uma sessão ativa. Não é possível criar uma nova sessão ativa.');
942
+ if (session) {
943
+ return session.id;
1028
944
  }
1029
- const now = Date.now();
1030
- const newId = randomUUID();
1031
- this.db.prepare(`
1032
- INSERT INTO sessions (
1033
- id,
1034
- started_at,
1035
- status
1036
- ) VALUES (?, ?, 'active')
1037
- `).run(newId, now);
1038
- return newId;
945
+ return this.createNewSession();
1039
946
  }
1040
947
  /**
1041
948
  * Lists all active and paused sessions with their basic information.
@@ -137,7 +137,7 @@ ${context ? `Context:\n${context}` : ""}
137
137
  };
138
138
  const inputCount = messages.length;
139
139
  const startMs = Date.now();
140
- const response = await TaskRequestContext.run(invokeContext, () => this.agent.invoke({ messages }, { recursionLimit: 100 }));
140
+ const response = await TaskRequestContext.run(invokeContext, () => this.agent.invoke({ messages }, { recursionLimit: 50 }));
141
141
  const durationMs = Date.now() - startMs;
142
142
  const lastMessage = response.messages[response.messages.length - 1];
143
143
  const content = typeof lastMessage.content === "string"
@@ -208,6 +208,8 @@ export class Oracle {
208
208
  if (!this.history) {
209
209
  throw new Error("Message history not initialized. Call initialize() first.");
210
210
  }
211
+ // Per-call scoped history — declared outside try so finally can close it.
212
+ let callHistory;
211
213
  try {
212
214
  this.display.log('Processing message...', { source: 'Oracle' });
213
215
  const userMessage = new HumanMessage(message);
@@ -347,13 +349,20 @@ bad:
347
349
  ${SkillRegistry.getInstance().getSystemPromptSection()}
348
350
  ${SmithRegistry.getInstance().getSystemPromptSection()}
349
351
  `);
352
+ // Resolve the authoritative session ID for this call.
353
+ // Priority: explicit taskContext > current history instance > fallback.
354
+ const currentSessionId = taskContext?.session_id
355
+ ?? ((this.history instanceof SQLiteChatMessageHistory) ? this.history.currentSessionId : undefined);
356
+ // Create a per-call scoped history so concurrent chat() calls for
357
+ // different sessions never interfere with each other.
358
+ callHistory = new SQLiteChatMessageHistory({
359
+ sessionId: currentSessionId ?? 'default',
360
+ databasePath: this.databasePath,
361
+ limit: this.config.llm?.context_window ?? 100,
362
+ });
350
363
  // Load existing history from database in reverse order (most recent first)
351
- let previousMessages = await this.history.getMessages();
364
+ let previousMessages = await callHistory.getMessages();
352
365
  previousMessages = previousMessages.reverse();
353
- // Propagate current session to Apoc so its token usage lands in the right session
354
- const currentSessionId = (this.history instanceof SQLiteChatMessageHistory)
355
- ? this.history.currentSessionId
356
- : undefined;
357
366
  // Sati Middleware: Retrieval
358
367
  let memoryMessage = null;
359
368
  try {
@@ -395,7 +404,7 @@ Use it to inform your response and tool selection (if needed), but do not assume
395
404
  let syncDelegationCount = 0;
396
405
  const oracleStartMs = Date.now();
397
406
  const response = await TaskRequestContext.run(invokeContext, async () => {
398
- const agentResponse = await this.provider.invoke({ messages }, { recursionLimit: 100 });
407
+ const agentResponse = await this.provider.invoke({ messages }, { recursionLimit: 50 });
399
408
  contextDelegationAcks = TaskRequestContext.getDelegationAcks();
400
409
  syncDelegationCount = TaskRequestContext.getSyncDelegationCount();
401
410
  return agentResponse;
@@ -474,8 +483,8 @@ Use it to inform your response and tool selection (if needed), but do not assume
474
483
  ackMessage.usage_metadata = ackResult.usage_metadata;
475
484
  }
476
485
  // Persist with addMessage so ack-provider usage is tracked per message row.
477
- await this.history.addMessage(userMessage);
478
- await this.history.addMessage(ackMessage);
486
+ await callHistory.addMessage(userMessage);
487
+ await callHistory.addMessage(ackMessage);
479
488
  // Unblock tasks for execution: the ack message is now persisted and will be
480
489
  // returned to the caller (Telegram / UI) immediately after this point.
481
490
  this.taskRepository.markAckSent(validDelegationAcks.map(a => a.task_id));
@@ -489,7 +498,7 @@ Use it to inform your response and tool selection (if needed), but do not assume
489
498
  provider: this.config.llm.provider,
490
499
  model: this.config.llm.model,
491
500
  };
492
- await this.history.addMessages([userMessage, failureMessage]);
501
+ await callHistory.addMessages([userMessage, failureMessage]);
493
502
  }
494
503
  else {
495
504
  const lastMessage = response.messages[response.messages.length - 1];
@@ -510,11 +519,11 @@ Use it to inform your response and tool selection (if needed), but do not assume
510
519
  if (usage) {
511
520
  failureMessage.usage_metadata = usage;
512
521
  }
513
- await this.history.addMessages([userMessage, failureMessage]);
522
+ await callHistory.addMessages([userMessage, failureMessage]);
514
523
  }
515
524
  else {
516
525
  // Persist user message + all generated messages in a single transaction
517
- await this.history.addMessages([userMessage, ...newGeneratedMessages]);
526
+ await callHistory.addMessages([userMessage, ...newGeneratedMessages]);
518
527
  }
519
528
  }
520
529
  this.display.log('Response generated.', { source: 'Oracle' });
@@ -539,6 +548,9 @@ Use it to inform your response and tool selection (if needed), but do not assume
539
548
  catch (err) {
540
549
  throw new ProviderError(this.config.llm.provider, err, "Chat request failed");
541
550
  }
551
+ finally {
552
+ callHistory?.close();
553
+ }
542
554
  }
543
555
  async getHistory() {
544
556
  if (!this.history) {
@@ -558,53 +570,19 @@ Use it to inform your response and tool selection (if needed), but do not assume
558
570
  throw new Error("Current history provider does not support session rollover.");
559
571
  }
560
572
  }
573
+ /**
574
+ * Updates the internal history pointer to the given session.
575
+ * No longer mutates DB session status — sessions are independently usable from any channel.
576
+ * Note: chat() uses per-call callHistory scoped to taskContext.session_id,
577
+ * so this method is only a fallback for callers that don't pass session in taskContext.
578
+ */
561
579
  async setSessionId(sessionId) {
562
580
  if (!this.history) {
563
581
  throw new Error("Message history not initialized. Call initialize() first.");
564
582
  }
565
- // Check if the history provider supports switching sessions
566
- // SQLiteChatMessageHistory does support it via constructor (new instance) or maybe we can add a method there too?
567
- // Actually SQLiteChatMessageHistory has `switchSession(targetSessionId)` but that one logic is "pause current, activate target".
568
- // For API usage, we might just want to *target* a session without necessarily changing the global "active" state regarding the Daemon?
569
- //
570
- // However, the user request implies this is "the" chat.
571
- // If we use `switchSession` it pauses others. That seems correct for a single-user agent model.
572
- //
573
- // But `SQLiteChatMessageHistory` properties are `sessionId`.
574
- // It seems `switchSession` in `sqlite.ts` updates the DB state.
575
- // We also need to update the `sessionId` property of the `SQLiteChatMessageHistory` instance held by Oracle.
576
- //
577
- // Let's check `SQLiteChatMessageHistory` again.
578
- // It has `sessionId` property.
579
- // It does NOT have a method to just update `sessionId` property without DB side effects?
580
- //
581
- // Use `switchSession` from `sqlite.ts` is good for "Active/Paused" state management.
582
- // But we also need the `history` instance to know it is now pointing to `sessionId`.
583
583
  if (this.history instanceof SQLiteChatMessageHistory) {
584
- // Logic:
585
- // 1. If currently active session is different, switch.
586
- // 2. Update internal sessionId.
587
- // Actually `switchSession` in `sqlite.ts` takes `targetSessionId`.
588
- // It updates the DB status.
589
- // It DOES NOT seem to update `this.sessionId` of the instance?
590
- // Wait, let me check `sqlite.ts` content from memory or view it again alongside.
591
- //
592
- // In `sqlite.ts`:
593
- // public async switchSession(targetSessionId: string): Promise<void> { ... }
594
- // It updates DB.
595
- // It DOES NOT update `this.sessionId`.
596
- //
597
- // So we need to ensure `this.history` points to the new session.
598
- // Since `SQLiteChatMessageHistory` might not allow changing `sessionId` publicly if it's protected/private...
599
- // It is `private sessionId: string;`.
600
- //
601
- // So simple fix: Re-instantiate `this.history`?
602
- // `this.history = new SQLiteChatMessageHistory({ sessionId: sessionId, ... })`
603
- //
604
- // This is safe and clean.
605
- // Ensure the target session exists before switching (creates as 'paused' if not found).
584
+ // Ensure the target session exists in DB
606
585
  this.history.ensureSession(sessionId);
607
- await this.history.switchSession(sessionId);
608
586
  // Close previous connection before re-instantiating to avoid file handle leaks
609
587
  this.history.close();
610
588
  // Re-instantiate to point to new session
@@ -5,7 +5,7 @@ import { DisplayManager } from '../display.js';
5
5
  import { SmithRegistry } from './registry.js';
6
6
  import { ConfigManager } from '../../config/manager.js';
7
7
  import { ProviderFactory } from '../providers/factory.js';
8
- import { buildDevKit } from '../../devkit/index.js';
8
+ import { buildDevKit } from 'morpheus-devkit';
9
9
  import { SQLiteChatMessageHistory } from '../memory/sqlite.js';
10
10
  import { AuditRepository } from '../audit/repository.js';
11
11
  import { TaskRequestContext } from '../tasks/context.js';
@@ -156,7 +156,7 @@ Respond in the same language as the task.`);
156
156
  : task;
157
157
  const messages = [systemMessage, new HumanMessage(userContent)];
158
158
  const startMs = Date.now();
159
- const response = await agent.invoke({ messages }, { recursionLimit: 100 });
159
+ const response = await agent.invoke({ messages }, { recursionLimit: 50 });
160
160
  const durationMs = Date.now() - startMs;
161
161
  // Extract final response
162
162
  const lastMessage = response.messages[response.messages.length - 1];
@@ -238,7 +238,7 @@ ${context ? `CONTEXT FROM ORACLE:\n${context}` : ''}
238
238
  const messages = [systemMessage, userMessage];
239
239
  try {
240
240
  const startMs = Date.now();
241
- const response = await this.agent.invoke({ messages }, { recursionLimit: 100 });
241
+ const response = await this.agent.invoke({ messages }, { recursionLimit: 50 });
242
242
  const durationMs = Date.now() - startMs;
243
243
  const lastMessage = response.messages[response.messages.length - 1];
244
244
  const content = typeof lastMessage.content === 'string'
@@ -1 +1 @@
1
- import{j as e,m as n}from"./vendor-motion-C3CZ8ZlO.js";import{L as O,r as B}from"./vendor-react-DikRIOlj.js";import{a as R}from"./audit-B-F8XPLi.js";import{O as C,av as D,j as L,i as F,ar as v,E as k,m as S,A as _,h as w,aw as I,e as U,I as A,ax as W,J as $,p as G,ah as V}from"./vendor-icons-BVuQI-6R.js";import"./vendor-utils-D4NnWbOU.js";import"./index-Cwqr-n0Y.js";function u(a){return a===0?"$0.00":a<1e-4?"<$0.0001":a<.01?`$${a.toFixed(4)}`:`$${a.toFixed(2)}`}function m(a){return a>=1e6?`${(a/1e6).toFixed(1)}M`:a>=1e3?`${(a/1e3).toFixed(1)}k`:String(a)}function j(a){if(a<1e3)return`${a}ms`;if(a<6e4)return`${(a/1e3).toFixed(1)}s`;const l=Math.floor(a/6e4),i=Math.floor(a%6e4/1e3);return`${l}m ${i}s`}function H(a){return a?new Date(a).toLocaleString(void 0,{month:"short",day:"numeric",hour:"2-digit",minute:"2-digit"}):"—"}function z(a,l){return l?`${Math.round(a/l*100)}%`:"0%"}function J({data:a}){const[l,i]=B.useState(null);if(!a.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(...a.map(r=>r.eventCount),1);return e.jsx("div",{className:"flex items-end gap-0.5 h-24 w-full relative",children:a.map((r,c)=>{const y=Math.max(4,Math.round(r.eventCount/s*88)),g=l===c;return e.jsxs("div",{className:"flex-1 flex flex-col items-center justify-end group",onMouseEnter:()=>i(c),onMouseLeave:()=>i(null),children:[g&&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:[r.date,": ",r.eventCount," events · ",u(r.estimatedCostUsd)]}),e.jsx("div",{style:{height:y},className:`w-full rounded-t transition-colors ${g?"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"}`})]},r.date)})})}function h({icon:a,label:l,value:i,sub:s,color:r="blue"}){const c={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 ${c[r]}`,children:[e.jsx("div",{className:"mt-0.5 flex-shrink-0",children:a}),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:l}),e.jsx("p",{className:"text-xl font-bold font-mono leading-tight",children:i}),s&&e.jsx("div",{className:"text-[11px] opacity-60 mt-0.5 leading-snug",children:s})]})]})}function x({title:a,icon:l,children:i}){return e.jsxs("div",{className:"rounded-lg border border-gray-200 dark:border-matrix-primary overflow-hidden",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:l}),e.jsx("h2",{className:"text-sm font-semibold text-gray-700 dark:text-matrix-secondary uppercase tracking-wider",children:a})]}),e.jsx("div",{className:"p-4",children:i})]})}const P={oracle:"🔮",apoc:"🧑‍🔬",neo:"🥷",trinity:"👩‍💻",smith:"🤖",keymaker:"🗝️",chronos:"⏰",sati:"🧠",telephonist:"📞",unknown:"?"},T={oracle:"bg-blue-100 text-blue-700 dark:bg-blue-900/40 dark:text-blue-300",apoc:"bg-amber-100 text-amber-700 dark:bg-amber-900/40 dark:text-amber-300",neo:"bg-purple-100 text-purple-700 dark:bg-purple-900/40 dark:text-purple-300",trinity:"bg-teal-100 text-teal-700 dark:bg-teal-900/40 dark:text-teal-300",smith:"bg-gray-200 text-gray-700 dark:bg-gray-700/60 dark:text-gray-300",keymaker:"bg-pink-100 text-pink-700 dark:bg-pink-900/40 dark:text-pink-300",chronos:"bg-orange-100 text-orange-700 dark:bg-orange-900/40 dark:text-orange-300",sati:"bg-emerald-100 text-emerald-700 dark:bg-emerald-900/40 dark:text-emerald-300",telephonist:"bg-rose-100 text-rose-700 dark:bg-rose-900/40 dark:text-rose-300",unknown:"bg-gray-100 text-gray-500 dark:bg-zinc-800 dark:text-matrix-secondary/60"};function M({agent:a}){const l=T[a]??T.unknown;return e.jsxs("span",{className:`inline-flex items-center gap-1 text-[11px] font-semibold px-1.5 py-0.5 rounded ${l}`,children:[P[a]??"?"," ",a.toUpperCase()]})}function Z({status:a}){const l={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 ${l[a]??l.unknown}`,children:a})}const q={llm_call:e.jsx(v,{size:13}),tool_call:e.jsx(k,{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(S,{size:13}),telephonist:e.jsx($,{size:13}),skill_executed:e.jsx(A,{size:13}),chronos_job:e.jsx(w,{size:13}),task_created:e.jsx(V,{size:13}),task_completed:e.jsx(G,{size:13})},K={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",telephonist:"text-rose-500 dark:text-rose-400",skill_executed:"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:a}){return a==="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(k,{size:13,className:"flex-shrink-0 text-amber-500 dark:text-amber-400"})}const X={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",telephonist:"bg-rose-400 dark:bg-rose-500",skill_executed:"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"},Y={hidden:{opacity:0},show:{opacity:1,transition:{staggerChildren:.04}}},o={hidden:{opacity:0,y:12},show:{opacity:1,y:0}},ie=()=>{const{data:a,isLoading:l,mutate:i}=R();if(l)return e.jsxs("div",{className:"flex items-center justify-center h-64 gap-3 text-gray-400 dark:text-matrix-secondary",children:[e.jsx(C,{size:20,className:"animate-spin"}),e.jsx("span",{className:"text-sm font-mono",children:"Loading audit data…"})]});if(!a)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(D,{size:24}),e.jsx("span",{className:"text-sm",children:"Failed to load audit data."})]});const{sessions:s,totals:r,byAgent:c,byModel:y,topTools:g,recentSessions:N,dailyActivity:p}=a,f=[["llm_call",r.llmCallCount],["tool_call",r.toolCallCount],["mcp_tool",r.mcpToolCount],["memory_recovery",r.memoryRecoveryCount],["telephonist",r.telephonistCount],["skill_executed",r.skillCount],["chronos_job",r.chronosJobCount],["task_created",r.taskCreatedCount],["task_completed",r.taskCompletedCount]].filter(([,t])=>t>0).sort((t,d)=>d[1]-t[1]),E=Math.max(...f.map(([,t])=>t),1);return e.jsxs(n.div,{variants:Y,initial:"hidden",animate:"show",className:"space-y-6",children:[e.jsxs(n.div,{variants:o,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 · ",r.totalEventCount.toLocaleString()," events total"]})]})]}),e.jsxs("button",{onClick:()=>i(),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(C,{size:14})," Refresh"]})]}),e.jsxs(n.div,{variants:o,className:"grid grid-cols-2 md:grid-cols-3 lg:grid-cols-6 gap-3",children:[e.jsx(h,{icon:e.jsx(F,{size:16}),label:"Total Cost",value:u(r.estimatedCostUsd),color:"green"}),e.jsx(h,{icon:e.jsx(v,{size:16}),label:"LLM Calls",value:r.llmCallCount.toLocaleString(),color:"blue"}),e.jsx(h,{icon:e.jsx(k,{size:16}),label:"Tool Calls",value:(r.toolCallCount+r.mcpToolCount).toLocaleString(),sub:e.jsxs(e.Fragment,{children:[e.jsxs("span",{children:[r.toolCallCount," native"]}),e.jsx("br",{}),e.jsxs("span",{children:[r.mcpToolCount," MCP"]})]}),color:"amber"}),e.jsx(h,{icon:e.jsx(S,{size:16}),label:"Memory Hits",value:r.memoryRecoveryCount.toLocaleString(),color:"teal"}),e.jsx(h,{icon:e.jsx(_,{size:16}),label:"Total Tokens",value:m(r.totalInputTokens+r.totalOutputTokens),sub:e.jsxs(e.Fragment,{children:[e.jsxs("span",{children:["↑",m(r.totalInputTokens)," in"]}),e.jsx("br",{}),e.jsxs("span",{children:["↓",m(r.totalOutputTokens)," out"]})]}),color:"purple"}),e.jsx(h,{icon:e.jsx(w,{size:16}),label:"Total Time",value:j(r.totalDurationMs),color:"rose"})]}),e.jsxs(n.div,{variants:o,className:"grid grid-cols-1 md:grid-cols-2 gap-6",children:[e.jsxs(x,{title:"Sessions",icon:e.jsx(I,{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:d,cls:b})=>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 ${b}`,children:d})]},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(U,{size:14}),children:[e.jsx(J,{data:p}),p.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:p[0]?.date}),e.jsx("span",{className:"flex-1 text-right",children:p[p.length-1]?.date})]})]})]}),e.jsx(n.div,{variants:o,children:e.jsx(x,{title:"Events by Type",icon:e.jsx(_,{size:14}),children:e.jsx("div",{className:"space-y-2",children:f.map(([t,d])=>e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx("span",{className:`flex-shrink-0 w-5 flex justify-center ${K[t]??"text-gray-400"}`,children:q[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 ${X[t]??"bg-gray-400"}`,style:{width:z(d,E)}})}),e.jsx("span",{className:"text-xs font-mono text-gray-500 dark:text-matrix-secondary w-16 text-right",children:d.toLocaleString()}),e.jsx("span",{className:"text-[10px] text-gray-400 dark:text-matrix-secondary/50 w-10 text-right",children:z(d,r.totalEventCount)})]},t))})})}),e.jsxs(n.div,{variants:o,className:"grid grid-cols-1 lg:grid-cols-2 gap-6",children:[e.jsx(x,{title:"By Agent",icon:e.jsx(A,{size:14}),children:c.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:c.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:j(t.totalDurationMs)}),e.jsx("td",{className:"py-1.5 text-right font-semibold text-gray-700 dark:text-matrix-secondary",children:u(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:u(t.estimatedCostUsd)})]},`${t.provider}/${t.model}`))})]})})})]}),g.length>0&&e.jsx(n.div,{variants:o,children:e.jsx(x,{title:"Top Tools",icon:e.jsx(k,{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:g.map((t,d)=>{const b=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:b>.1?"text-red-500 dark:text-red-400":b>0?"text-amber-500 dark:text-amber-400":"text-gray-400 dark:text-matrix-secondary/50",children:t.count>0?`${Math.round(b*100)}%`:"—"})})]},d)})})]})})})}),e.jsx(n.div,{variants:o,children:e.jsx(x,{title:"Recent Sessions with Audit",icon:e.jsx(L,{size:14}),children:N.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:N.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:H(t.started_at)})]}),e.jsx("td",{className:"py-2",children:e.jsx(Z,{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:j(t.totalDurationMs)}),e.jsx("td",{className:"py-2 text-right font-semibold text-gray-700 dark:text-matrix-secondary",children:u(t.estimatedCostUsd)}),e.jsx("td",{className:"py-2 text-right",children:e.jsx(O,{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(W,{size:11})})})]},t.session_id))})]})})})}),r.telephonistCount>0&&e.jsx(n.div,{variants:o,children:e.jsx(x,{title:"Audio / Telephonist",icon:e.jsx($,{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:r.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:r.totalAudioSeconds<60?`${r.totalAudioSeconds.toFixed(1)}s`:`${(r.totalAudioSeconds/60).toFixed(1)}m`})]})]})})})]})};export{ie as AuditDashboard};
1
+ import{j as e,m as n}from"./vendor-motion-C3CZ8ZlO.js";import{L as O,r as B}from"./vendor-react-DikRIOlj.js";import{a as R}from"./audit-CqszEkOd.js";import{O as C,av as D,j as L,i as F,ar as v,E as k,m as S,A as _,h as w,aw as I,e as U,I as A,ax as W,J as $,p as G,ah as V}from"./vendor-icons-BVuQI-6R.js";import"./vendor-utils-D4NnWbOU.js";import"./index-BxVeRyTh.js";function u(a){return a===0?"$0.00":a<1e-4?"<$0.0001":a<.01?`$${a.toFixed(4)}`:`$${a.toFixed(2)}`}function m(a){return a>=1e6?`${(a/1e6).toFixed(1)}M`:a>=1e3?`${(a/1e3).toFixed(1)}k`:String(a)}function j(a){if(a<1e3)return`${a}ms`;if(a<6e4)return`${(a/1e3).toFixed(1)}s`;const l=Math.floor(a/6e4),i=Math.floor(a%6e4/1e3);return`${l}m ${i}s`}function H(a){return a?new Date(a).toLocaleString(void 0,{month:"short",day:"numeric",hour:"2-digit",minute:"2-digit"}):"—"}function z(a,l){return l?`${Math.round(a/l*100)}%`:"0%"}function J({data:a}){const[l,i]=B.useState(null);if(!a.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(...a.map(r=>r.eventCount),1);return e.jsx("div",{className:"flex items-end gap-0.5 h-24 w-full relative",children:a.map((r,c)=>{const y=Math.max(4,Math.round(r.eventCount/s*88)),g=l===c;return e.jsxs("div",{className:"flex-1 flex flex-col items-center justify-end group",onMouseEnter:()=>i(c),onMouseLeave:()=>i(null),children:[g&&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:[r.date,": ",r.eventCount," events · ",u(r.estimatedCostUsd)]}),e.jsx("div",{style:{height:y},className:`w-full rounded-t transition-colors ${g?"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"}`})]},r.date)})})}function h({icon:a,label:l,value:i,sub:s,color:r="blue"}){const c={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 ${c[r]}`,children:[e.jsx("div",{className:"mt-0.5 flex-shrink-0",children:a}),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:l}),e.jsx("p",{className:"text-xl font-bold font-mono leading-tight",children:i}),s&&e.jsx("div",{className:"text-[11px] opacity-60 mt-0.5 leading-snug",children:s})]})]})}function x({title:a,icon:l,children:i}){return e.jsxs("div",{className:"rounded-lg border border-gray-200 dark:border-matrix-primary overflow-hidden",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:l}),e.jsx("h2",{className:"text-sm font-semibold text-gray-700 dark:text-matrix-secondary uppercase tracking-wider",children:a})]}),e.jsx("div",{className:"p-4",children:i})]})}const P={oracle:"🔮",apoc:"🧑‍🔬",neo:"🥷",trinity:"👩‍💻",smith:"🤖",keymaker:"🗝️",chronos:"⏰",sati:"🧠",telephonist:"📞",unknown:"?"},T={oracle:"bg-blue-100 text-blue-700 dark:bg-blue-900/40 dark:text-blue-300",apoc:"bg-amber-100 text-amber-700 dark:bg-amber-900/40 dark:text-amber-300",neo:"bg-purple-100 text-purple-700 dark:bg-purple-900/40 dark:text-purple-300",trinity:"bg-teal-100 text-teal-700 dark:bg-teal-900/40 dark:text-teal-300",smith:"bg-gray-200 text-gray-700 dark:bg-gray-700/60 dark:text-gray-300",keymaker:"bg-pink-100 text-pink-700 dark:bg-pink-900/40 dark:text-pink-300",chronos:"bg-orange-100 text-orange-700 dark:bg-orange-900/40 dark:text-orange-300",sati:"bg-emerald-100 text-emerald-700 dark:bg-emerald-900/40 dark:text-emerald-300",telephonist:"bg-rose-100 text-rose-700 dark:bg-rose-900/40 dark:text-rose-300",unknown:"bg-gray-100 text-gray-500 dark:bg-zinc-800 dark:text-matrix-secondary/60"};function M({agent:a}){const l=T[a]??T.unknown;return e.jsxs("span",{className:`inline-flex items-center gap-1 text-[11px] font-semibold px-1.5 py-0.5 rounded ${l}`,children:[P[a]??"?"," ",a.toUpperCase()]})}function Z({status:a}){const l={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 ${l[a]??l.unknown}`,children:a})}const q={llm_call:e.jsx(v,{size:13}),tool_call:e.jsx(k,{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(S,{size:13}),telephonist:e.jsx($,{size:13}),skill_executed:e.jsx(A,{size:13}),chronos_job:e.jsx(w,{size:13}),task_created:e.jsx(V,{size:13}),task_completed:e.jsx(G,{size:13})},K={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",telephonist:"text-rose-500 dark:text-rose-400",skill_executed:"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:a}){return a==="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(k,{size:13,className:"flex-shrink-0 text-amber-500 dark:text-amber-400"})}const X={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",telephonist:"bg-rose-400 dark:bg-rose-500",skill_executed:"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"},Y={hidden:{opacity:0},show:{opacity:1,transition:{staggerChildren:.04}}},o={hidden:{opacity:0,y:12},show:{opacity:1,y:0}},ie=()=>{const{data:a,isLoading:l,mutate:i}=R();if(l)return e.jsxs("div",{className:"flex items-center justify-center h-64 gap-3 text-gray-400 dark:text-matrix-secondary",children:[e.jsx(C,{size:20,className:"animate-spin"}),e.jsx("span",{className:"text-sm font-mono",children:"Loading audit data…"})]});if(!a)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(D,{size:24}),e.jsx("span",{className:"text-sm",children:"Failed to load audit data."})]});const{sessions:s,totals:r,byAgent:c,byModel:y,topTools:g,recentSessions:N,dailyActivity:p}=a,f=[["llm_call",r.llmCallCount],["tool_call",r.toolCallCount],["mcp_tool",r.mcpToolCount],["memory_recovery",r.memoryRecoveryCount],["telephonist",r.telephonistCount],["skill_executed",r.skillCount],["chronos_job",r.chronosJobCount],["task_created",r.taskCreatedCount],["task_completed",r.taskCompletedCount]].filter(([,t])=>t>0).sort((t,d)=>d[1]-t[1]),E=Math.max(...f.map(([,t])=>t),1);return e.jsxs(n.div,{variants:Y,initial:"hidden",animate:"show",className:"space-y-6",children:[e.jsxs(n.div,{variants:o,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 · ",r.totalEventCount.toLocaleString()," events total"]})]})]}),e.jsxs("button",{onClick:()=>i(),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(C,{size:14})," Refresh"]})]}),e.jsxs(n.div,{variants:o,className:"grid grid-cols-2 md:grid-cols-3 lg:grid-cols-6 gap-3",children:[e.jsx(h,{icon:e.jsx(F,{size:16}),label:"Total Cost",value:u(r.estimatedCostUsd),color:"green"}),e.jsx(h,{icon:e.jsx(v,{size:16}),label:"LLM Calls",value:r.llmCallCount.toLocaleString(),color:"blue"}),e.jsx(h,{icon:e.jsx(k,{size:16}),label:"Tool Calls",value:(r.toolCallCount+r.mcpToolCount).toLocaleString(),sub:e.jsxs(e.Fragment,{children:[e.jsxs("span",{children:[r.toolCallCount," native"]}),e.jsx("br",{}),e.jsxs("span",{children:[r.mcpToolCount," MCP"]})]}),color:"amber"}),e.jsx(h,{icon:e.jsx(S,{size:16}),label:"Memory Hits",value:r.memoryRecoveryCount.toLocaleString(),color:"teal"}),e.jsx(h,{icon:e.jsx(_,{size:16}),label:"Total Tokens",value:m(r.totalInputTokens+r.totalOutputTokens),sub:e.jsxs(e.Fragment,{children:[e.jsxs("span",{children:["↑",m(r.totalInputTokens)," in"]}),e.jsx("br",{}),e.jsxs("span",{children:["↓",m(r.totalOutputTokens)," out"]})]}),color:"purple"}),e.jsx(h,{icon:e.jsx(w,{size:16}),label:"Total Time",value:j(r.totalDurationMs),color:"rose"})]}),e.jsxs(n.div,{variants:o,className:"grid grid-cols-1 md:grid-cols-2 gap-6",children:[e.jsxs(x,{title:"Sessions",icon:e.jsx(I,{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:d,cls:b})=>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 ${b}`,children:d})]},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(U,{size:14}),children:[e.jsx(J,{data:p}),p.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:p[0]?.date}),e.jsx("span",{className:"flex-1 text-right",children:p[p.length-1]?.date})]})]})]}),e.jsx(n.div,{variants:o,children:e.jsx(x,{title:"Events by Type",icon:e.jsx(_,{size:14}),children:e.jsx("div",{className:"space-y-2",children:f.map(([t,d])=>e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx("span",{className:`flex-shrink-0 w-5 flex justify-center ${K[t]??"text-gray-400"}`,children:q[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 ${X[t]??"bg-gray-400"}`,style:{width:z(d,E)}})}),e.jsx("span",{className:"text-xs font-mono text-gray-500 dark:text-matrix-secondary w-16 text-right",children:d.toLocaleString()}),e.jsx("span",{className:"text-[10px] text-gray-400 dark:text-matrix-secondary/50 w-10 text-right",children:z(d,r.totalEventCount)})]},t))})})}),e.jsxs(n.div,{variants:o,className:"grid grid-cols-1 lg:grid-cols-2 gap-6",children:[e.jsx(x,{title:"By Agent",icon:e.jsx(A,{size:14}),children:c.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:c.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:j(t.totalDurationMs)}),e.jsx("td",{className:"py-1.5 text-right font-semibold text-gray-700 dark:text-matrix-secondary",children:u(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:u(t.estimatedCostUsd)})]},`${t.provider}/${t.model}`))})]})})})]}),g.length>0&&e.jsx(n.div,{variants:o,children:e.jsx(x,{title:"Top Tools",icon:e.jsx(k,{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:g.map((t,d)=>{const b=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:b>.1?"text-red-500 dark:text-red-400":b>0?"text-amber-500 dark:text-amber-400":"text-gray-400 dark:text-matrix-secondary/50",children:t.count>0?`${Math.round(b*100)}%`:"—"})})]},d)})})]})})})}),e.jsx(n.div,{variants:o,children:e.jsx(x,{title:"Recent Sessions with Audit",icon:e.jsx(L,{size:14}),children:N.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:N.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:H(t.started_at)})]}),e.jsx("td",{className:"py-2",children:e.jsx(Z,{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:j(t.totalDurationMs)}),e.jsx("td",{className:"py-2 text-right font-semibold text-gray-700 dark:text-matrix-secondary",children:u(t.estimatedCostUsd)}),e.jsx("td",{className:"py-2 text-right",children:e.jsx(O,{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(W,{size:11})})})]},t.session_id))})]})})})}),r.telephonistCount>0&&e.jsx(n.div,{variants:o,children:e.jsx(x,{title:"Audio / Telephonist",icon:e.jsx($,{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:r.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:r.totalAudioSeconds<60?`${r.totalAudioSeconds.toFixed(1)}s`:`${(r.totalAudioSeconds/60).toFixed(1)}m`})]})]})})})]})};export{ie as AuditDashboard};