morpheus-cli 0.9.5 → 0.9.7

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 (75) hide show
  1. package/README.md +63 -43
  2. package/dist/channels/discord.js +71 -21
  3. package/dist/channels/telegram.js +73 -19
  4. package/dist/cli/commands/restart.js +15 -0
  5. package/dist/cli/commands/start.js +18 -0
  6. package/dist/config/manager.js +61 -0
  7. package/dist/config/paths.js +1 -0
  8. package/dist/config/schemas.js +11 -3
  9. package/dist/http/api.js +3 -0
  10. package/dist/http/routers/link.js +239 -0
  11. package/dist/http/routers/skills.js +1 -8
  12. package/dist/runtime/apoc.js +1 -1
  13. package/dist/runtime/audit/repository.js +1 -1
  14. package/dist/runtime/link-chunker.js +214 -0
  15. package/dist/runtime/link-repository.js +301 -0
  16. package/dist/runtime/link-search.js +298 -0
  17. package/dist/runtime/link-worker.js +284 -0
  18. package/dist/runtime/link.js +295 -0
  19. package/dist/runtime/memory/sati/service.js +1 -1
  20. package/dist/runtime/memory/sqlite.js +52 -0
  21. package/dist/runtime/neo.js +1 -1
  22. package/dist/runtime/oracle.js +81 -44
  23. package/dist/runtime/scaffold.js +4 -17
  24. package/dist/runtime/skills/__tests__/loader.test.js +7 -10
  25. package/dist/runtime/skills/__tests__/registry.test.js +2 -18
  26. package/dist/runtime/skills/__tests__/tool.test.js +55 -224
  27. package/dist/runtime/skills/index.js +1 -2
  28. package/dist/runtime/skills/loader.js +0 -2
  29. package/dist/runtime/skills/registry.js +8 -20
  30. package/dist/runtime/skills/schema.js +0 -4
  31. package/dist/runtime/skills/tool.js +42 -209
  32. package/dist/runtime/smiths/delegator.js +1 -1
  33. package/dist/runtime/smiths/registry.js +1 -1
  34. package/dist/runtime/tasks/worker.js +12 -44
  35. package/dist/runtime/trinity.js +1 -1
  36. package/dist/types/config.js +14 -0
  37. package/dist/ui/assets/AuditDashboard-93LCGHG1.js +1 -0
  38. package/dist/ui/assets/{Chat-BNtutgja.js → Chat-CK5sNcQ1.js} +8 -8
  39. package/dist/ui/assets/{Chronos-3C8RPZcl.js → Chronos-m2h--GEe.js} +1 -1
  40. package/dist/ui/assets/{ConfirmationModal-ZQPBeJ2Z.js → ConfirmationModal-Dd5pUJme.js} +1 -1
  41. package/dist/ui/assets/{Dashboard-CqkHzr2F.js → Dashboard-ODwl7d-a.js} +1 -1
  42. package/dist/ui/assets/{DeleteConfirmationModal-CioxFWn_.js → DeleteConfirmationModal-CCcojDmr.js} +1 -1
  43. package/dist/ui/assets/Documents-dWnSoxFO.js +7 -0
  44. package/dist/ui/assets/{Logs-DBVanS0O.js → Logs-Dc9Z2LBj.js} +1 -1
  45. package/dist/ui/assets/{MCPManager-vXfL3P2U.js → MCPManager-CMkb8vMn.js} +1 -1
  46. package/dist/ui/assets/{ModelPricing-DyfdunLT.js → ModelPricing-DtHPPbEQ.js} +1 -1
  47. package/dist/ui/assets/{Notifications-VL-vep6d.js → Notifications-BPvo-DWP.js} +1 -1
  48. package/dist/ui/assets/{Pagination-oTGieBLM.js → Pagination-BHZKk42X.js} +1 -1
  49. package/dist/ui/assets/{SatiMemories-jaadkW0U.js → SatiMemories-BUPu1Lxr.js} +1 -1
  50. package/dist/ui/assets/SessionAudit-CFKF4DA8.js +9 -0
  51. package/dist/ui/assets/Settings-C4JrXfsR.js +47 -0
  52. package/dist/ui/assets/{Skills-DE3zziXL.js → Skills-BUlvJgJ4.js} +1 -1
  53. package/dist/ui/assets/{Smiths-pmogN1mU.js → Smiths-CDtJdY0I.js} +1 -1
  54. package/dist/ui/assets/{Tasks-Bs8s34Jc.js → Tasks-DK_cOsNK.js} +1 -1
  55. package/dist/ui/assets/{TrinityDatabases-D7uihcdp.js → TrinityDatabases-X07by-19.js} +1 -1
  56. package/dist/ui/assets/{UsageStats-B9gePLZ0.js → UsageStats-dYcgckLq.js} +1 -1
  57. package/dist/ui/assets/{WebhookManager-B2L3rCLM.js → WebhookManager-DDw5eX2R.js} +1 -1
  58. package/dist/ui/assets/{audit-Cggeu9mM.js → audit-DZ5WLUEm.js} +1 -1
  59. package/dist/ui/assets/{chronos-D3-sWhfU.js → chronos-B_HI4mlq.js} +1 -1
  60. package/dist/ui/assets/{config-CBqRUPgn.js → config-B-YxlVrc.js} +1 -1
  61. package/dist/ui/assets/index-DVjwJ8jT.css +1 -0
  62. package/dist/ui/assets/{index-zKplfrXZ.js → index-DfJwcKqG.js} +5 -5
  63. package/dist/ui/assets/{mcp-uL1R9hyA.js → mcp-k-_pwbqA.js} +1 -1
  64. package/dist/ui/assets/{skills-jmw8yTJs.js → skills-xMXangks.js} +1 -1
  65. package/dist/ui/assets/{stats-HOms6GnM.js → stats-C4QZIv5O.js} +1 -1
  66. package/dist/ui/assets/{vendor-icons-DMd9RGvJ.js → vendor-icons-NHF9HNeN.js} +1 -1
  67. package/dist/ui/index.html +3 -3
  68. package/dist/ui/sw.js +1 -1
  69. package/package.json +3 -1
  70. package/dist/runtime/__tests__/keymaker.test.js +0 -148
  71. package/dist/runtime/keymaker.js +0 -157
  72. package/dist/ui/assets/AuditDashboard-DliJ1CX0.js +0 -1
  73. package/dist/ui/assets/SessionAudit-BsXrWlwz.js +0 -9
  74. package/dist/ui/assets/Settings-B4eezRcg.js +0 -47
  75. package/dist/ui/assets/index-D4fzIKy1.css +0 -1
@@ -1,229 +1,62 @@
1
1
  /**
2
- * Skill Tools - skill_execute (sync) and skill_delegate (async)
2
+ * Skill Tool load_skill
3
+ *
4
+ * Oracle uses this tool to load skill content into context on-demand.
5
+ * Replaces the old skill_execute/skill_delegate + Keymaker pattern.
3
6
  */
4
7
  import { tool } from "@langchain/core/tools";
5
8
  import { z } from "zod";
6
- import { TaskRepository } from "../tasks/repository.js";
7
- import { TaskRequestContext } from "../tasks/context.js";
8
- import { DisplayManager } from "../display.js";
9
9
  import { SkillRegistry } from "./registry.js";
10
- import { executeKeymakerTask } from "../keymaker.js";
11
10
  import { AuditRepository } from "../audit/repository.js";
12
- // ============================================================================
13
- // skill_execute - Synchronous execution
14
- // ============================================================================
15
- /**
16
- * Generates the skill_execute tool description dynamically with sync skills.
17
- */
18
- export function getSkillExecuteDescription() {
19
- const registry = SkillRegistry.getInstance();
20
- const syncSkills = registry.getEnabled().filter((s) => s.execution_mode === 'sync');
21
- const skillList = syncSkills.length > 0
22
- ? syncSkills.map(s => `- ${s.name}: ${s.description}`).join('\n')
23
- : '(no sync skills enabled)';
24
- return `Execute a skill synchronously using Keymaker. The result is returned immediately.
25
-
26
- Keymaker has access to ALL tools (filesystem, shell, git, MCP, browser, etc.) and will execute the skill instructions.
27
-
28
- Available sync skills:
29
- ${skillList}
30
-
31
- Use this for skills that need immediate results in the conversation.`;
32
- }
33
- /**
34
- * Tool that Oracle uses to execute skills synchronously via Keymaker.
35
- * Result is returned directly to Oracle for inclusion in the response.
36
- */
37
- export const SkillExecuteTool = tool(async ({ skillName, objective }) => {
38
- const display = DisplayManager.getInstance();
39
- const registry = SkillRegistry.getInstance();
40
- // Validate skill exists and is enabled
41
- const skill = registry.get(skillName);
42
- if (!skill) {
43
- const available = registry.getEnabled().map(s => s.name).join(', ');
44
- return `Error: Skill "${skillName}" not found. Available skills: ${available || 'none'}`;
45
- }
46
- if (!skill.enabled) {
47
- return `Error: Skill "${skillName}" is disabled.`;
48
- }
49
- if (skill.execution_mode === 'async') {
50
- return `Error: Skill "${skillName}" is async-only. Use skill_delegate instead.`;
51
- }
52
- display.log(`Executing skill "${skillName}" synchronously...`, {
53
- source: "SkillExecuteTool",
54
- level: "info",
55
- });
56
- try {
57
- const ctx = TaskRequestContext.get();
58
- const sessionId = ctx?.session_id ?? "default";
59
- const taskContext = {
60
- origin_channel: ctx?.origin_channel ?? "api",
61
- session_id: sessionId,
62
- origin_message_id: ctx?.origin_message_id,
63
- origin_user_id: ctx?.origin_user_id,
64
- };
65
- // Execute Keymaker directly (synchronous)
66
- const result = await executeKeymakerTask(skillName, objective, taskContext);
67
- display.log(`Skill "${skillName}" completed successfully.`, {
68
- source: "SkillExecuteTool",
69
- level: "info",
70
- });
71
- // Emit audit events for sync execution (async path is handled by TaskWorker)
72
- const audit = AuditRepository.getInstance();
73
- if (result.usage && (result.usage.inputTokens > 0 || result.usage.outputTokens > 0)) {
74
- audit.insert({
75
- session_id: sessionId,
76
- event_type: 'llm_call',
77
- agent: 'keymaker',
78
- provider: result.usage.provider,
79
- model: result.usage.model,
80
- input_tokens: result.usage.inputTokens,
81
- output_tokens: result.usage.outputTokens,
82
- duration_ms: result.usage.durationMs,
83
- status: 'success',
84
- metadata: { step_count: result.usage.stepCount },
85
- });
86
- }
87
- audit.insert({
88
- session_id: sessionId,
89
- event_type: 'skill_executed',
90
- agent: 'keymaker',
91
- tool_name: skillName,
92
- duration_ms: result.usage?.durationMs,
93
- status: 'success',
94
- });
95
- return result;
96
- }
97
- catch (err) {
98
- display.log(`Skill execution error: ${err.message}`, {
99
- source: "SkillExecuteTool",
100
- level: "error",
101
- });
102
- return `Skill execution failed: ${err.message}`;
103
- }
104
- }, {
105
- name: "skill_execute",
106
- description: getSkillExecuteDescription(),
107
- schema: z.object({
108
- skillName: z.string().describe("Exact name of the sync skill to use"),
109
- objective: z.string().describe("Clear description of what to accomplish"),
110
- }),
111
- });
112
- // ============================================================================
113
- // skill_delegate - Asynchronous execution (background task)
114
- // ============================================================================
115
- /**
116
- * Generates the skill_delegate tool description dynamically with async skills.
117
- */
118
- export function getSkillDelegateDescription() {
119
- const registry = SkillRegistry.getInstance();
120
- const asyncSkills = registry.getEnabled().filter((s) => s.execution_mode === 'async');
121
- const skillList = asyncSkills.length > 0
122
- ? asyncSkills.map(s => `- ${s.name}: ${s.description}`).join('\n')
123
- : '(no async skills enabled)';
124
- return `Delegate a task to Keymaker as a background job. You will be notified when complete.
125
-
126
- Keymaker has access to ALL tools (filesystem, shell, git, MCP, browser, etc.) and will execute the skill instructions.
127
-
128
- Available async skills:
129
- ${skillList}
130
-
131
- Use this for long-running skills like builds, deployments, or batch processing.`;
132
- }
11
+ import { TaskRequestContext } from "../tasks/context.js";
133
12
  /**
134
- * Tool that Oracle uses to delegate tasks to Keymaker via async task queue.
135
- * Keymaker will execute the skill instructions in background.
13
+ * Creates the load_skill tool for Oracle.
14
+ * Returns skill content as context Oracle handles execution with its own tools.
136
15
  */
137
- export const SkillDelegateTool = tool(async ({ skillName, objective }) => {
138
- try {
139
- const display = DisplayManager.getInstance();
16
+ export function createLoadSkillTool() {
17
+ return tool(async ({ skillName }) => {
140
18
  const registry = SkillRegistry.getInstance();
141
- // Validate skill exists and is enabled
142
19
  const skill = registry.get(skillName);
143
20
  if (!skill) {
144
21
  const available = registry.getEnabled().map(s => s.name).join(', ');
145
- return `Error: Skill "${skillName}" not found. Available skills: ${available || 'none'}`;
22
+ return `Skill '${skillName}' not found. Available skills: ${available || 'none'}`;
146
23
  }
147
24
  if (!skill.enabled) {
148
- return `Error: Skill "${skillName}" is disabled.`;
149
- }
150
- if (skill.execution_mode !== 'async') {
151
- return `Error: Skill "${skillName}" is sync. Use skill_execute instead for immediate results.`;
25
+ return `Skill '${skillName}' is disabled.`;
152
26
  }
153
- // Check for duplicate delegation
154
- const existingAck = TaskRequestContext.findDuplicateDelegation("keymaker", `${skillName}:${objective}`);
155
- if (existingAck) {
156
- display.log(`Keymaker delegation deduplicated. Reusing task ${existingAck.task_id}.`, {
157
- source: "SkillDelegateTool",
158
- level: "info",
159
- });
160
- return `Task ${existingAck.task_id} already queued for Keymaker (${skillName}) execution.`;
161
- }
162
- if (!TaskRequestContext.canEnqueueDelegation()) {
163
- display.log(`Keymaker delegation blocked by per-turn limit.`, {
164
- source: "SkillDelegateTool",
165
- level: "warning",
27
+ // Emit audit event
28
+ try {
29
+ const ctx = TaskRequestContext.get();
30
+ const sessionId = ctx?.session_id ?? 'default';
31
+ AuditRepository.getInstance().insert({
32
+ session_id: sessionId,
33
+ event_type: 'skill_loaded',
34
+ agent: 'oracle',
35
+ tool_name: skillName,
36
+ status: 'success',
166
37
  });
167
- return "Delegation limit reached for this user turn. Wait for current tasks to complete.";
168
38
  }
169
- const ctx = TaskRequestContext.get();
170
- const repository = TaskRepository.getInstance();
171
- // Store skill name in context as JSON
172
- const taskContext = JSON.stringify({ skill: skillName });
173
- const created = repository.createTask({
174
- agent: "keymaker",
175
- input: objective,
176
- context: taskContext,
177
- origin_channel: ctx?.origin_channel ?? "api",
178
- session_id: ctx?.session_id ?? "default",
179
- origin_message_id: ctx?.origin_message_id ?? null,
180
- origin_user_id: ctx?.origin_user_id ?? null,
181
- max_attempts: 3,
182
- });
183
- TaskRequestContext.setDelegationAck({
184
- task_id: created.id,
185
- agent: "keymaker",
186
- task: `${skillName}:${objective}`,
187
- });
188
- display.log(`Keymaker task created: ${created.id} (skill: ${skillName})`, {
189
- source: "SkillDelegateTool",
190
- level: "info",
191
- meta: {
192
- agent: created.agent,
193
- skill: skillName,
194
- origin_channel: created.origin_channel,
195
- session_id: created.session_id,
196
- input: created.input,
197
- }
198
- });
199
- return `Task ${created.id} queued for Keymaker (skill: ${skillName}). You will be notified when complete.`;
200
- }
201
- catch (err) {
202
- const display = DisplayManager.getInstance();
203
- display.log(`SkillDelegateTool error: ${err.message}`, {
204
- source: "SkillDelegateTool",
205
- level: "error",
206
- });
207
- return `Keymaker task enqueue failed: ${err.message}`;
208
- }
209
- }, {
210
- name: "skill_delegate",
211
- description: getSkillDelegateDescription(),
212
- schema: z.object({
213
- skillName: z.string().describe("Exact name of the async skill to use"),
214
- objective: z.string().describe("Clear description of what Keymaker should accomplish"),
215
- }),
216
- });
217
- // ============================================================================
218
- // Utility functions
219
- // ============================================================================
39
+ catch { /* non-critical */ }
40
+ return `Loaded skill: ${skillName}\n\n${skill.content}`;
41
+ }, {
42
+ name: "load_skill",
43
+ description: buildLoadSkillDescription(),
44
+ schema: z.object({
45
+ skillName: z.string().describe("The name of the skill to load"),
46
+ }),
47
+ });
48
+ }
220
49
  /**
221
- * Updates both skill tool descriptions with current skill list.
222
- * Should be called after skills are loaded/reloaded.
50
+ * Builds the load_skill tool description with available skills.
223
51
  */
224
- export function updateSkillToolDescriptions() {
225
- SkillExecuteTool.description = getSkillExecuteDescription();
226
- SkillDelegateTool.description = getSkillDelegateDescription();
52
+ function buildLoadSkillDescription() {
53
+ const registry = SkillRegistry.getInstance();
54
+ const enabled = registry.getEnabled();
55
+ const skillList = enabled.length > 0
56
+ ? enabled.map(s => `- ${s.name}: ${s.description}`).join('\n')
57
+ : '(no skills available)';
58
+ return `Load a skill's instructions into your context. After loading, follow the instructions to handle the request using your existing tools or delegate to Agents.
59
+
60
+ Available skills:
61
+ ${skillList}`;
227
62
  }
228
- // Backwards compatibility alias
229
- export const updateSkillDelegateDescription = updateSkillToolDescriptions;
@@ -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: 50 });
159
+ const response = await agent.invoke({ messages }, { recursionLimit: 10 });
160
160
  const durationMs = Date.now() - startMs;
161
161
  // Extract final response
162
162
  const lastMessage = response.messages[response.messages.length - 1];
@@ -264,7 +264,7 @@ export class SmithRegistry extends EventEmitter {
264
264
  const lines = online.map(s => {
265
265
  const caps = s.capabilities.length > 0 ? ` (capabilities: ${s.capabilities.join(', ')})` : '';
266
266
  const os = s.stats?.os ? ` [${s.stats.os}]` : '';
267
- return `- **${s.name}**: ${s.host}:${s.port}${os}${caps}`;
267
+ return `- **${s.name}** (@${s.name}): ${s.host}:${s.port}${os}${caps}`;
268
268
  });
269
269
  return `\n## Available Smiths (Remote Agents)
270
270
  The following remote Smiths are online and can execute DevKit tasks on external machines:
@@ -3,7 +3,7 @@ import { DisplayManager } from '../display.js';
3
3
  import { Apoc } from '../apoc.js';
4
4
  import { Neo } from '../neo.js';
5
5
  import { Trinity } from '../trinity.js';
6
- import { executeKeymakerTask } from '../keymaker.js';
6
+ import { Link } from '../link.js';
7
7
  import { SmithDelegator } from '../smiths/delegator.js';
8
8
  import { TaskRepository } from './repository.js';
9
9
  import { AuditRepository } from '../audit/repository.js';
@@ -93,27 +93,6 @@ export class TaskWorker {
93
93
  });
94
94
  break;
95
95
  }
96
- case 'keymaker': {
97
- // Parse skill name from context JSON
98
- let skillName = 'unknown';
99
- if (task.context) {
100
- try {
101
- const parsed = JSON.parse(task.context);
102
- skillName = parsed.skill || 'unknown';
103
- }
104
- catch {
105
- // context is not JSON, use as skill name directly for backwards compat
106
- skillName = task.context;
107
- }
108
- }
109
- result = await executeKeymakerTask(skillName, task.input, {
110
- origin_channel: task.origin_channel,
111
- session_id: task.session_id,
112
- origin_message_id: task.origin_message_id ?? undefined,
113
- origin_user_id: task.origin_user_id ?? undefined,
114
- });
115
- break;
116
- }
117
96
  case 'smith': {
118
97
  // Parse smith name from context JSON
119
98
  let smithName = 'unknown';
@@ -130,6 +109,16 @@ export class TaskWorker {
130
109
  result = await delegator.delegate(smithName, task.input, task.context ?? undefined);
131
110
  break;
132
111
  }
112
+ case 'link': {
113
+ const link = Link.getInstance();
114
+ result = await link.execute(task.input, task.context ?? undefined, task.session_id, {
115
+ origin_channel: task.origin_channel,
116
+ session_id: task.session_id,
117
+ origin_message_id: task.origin_message_id ?? undefined,
118
+ origin_user_id: task.origin_user_id ?? undefined,
119
+ });
120
+ break;
121
+ }
133
122
  default: {
134
123
  throw new Error(`Unknown task agent: ${task.agent}`);
135
124
  }
@@ -152,7 +141,7 @@ export class TaskWorker {
152
141
  duration_ms: result.usage?.durationMs,
153
142
  status: 'success',
154
143
  });
155
- // Emit llm_call audit event if usage data is present (not keymaker skills)
144
+ // Emit llm_call audit event if usage data is present
156
145
  if (result.usage && (result.usage.inputTokens > 0 || result.usage.outputTokens > 0)) {
157
146
  audit.insert({
158
147
  session_id: task.session_id,
@@ -168,27 +157,6 @@ export class TaskWorker {
168
157
  metadata: { step_count: result.usage.stepCount },
169
158
  });
170
159
  }
171
- // Emit skill_executed for keymaker
172
- if (task.agent === 'keymaker') {
173
- let skillName = 'unknown';
174
- if (task.context) {
175
- try {
176
- skillName = JSON.parse(task.context).skill || task.context;
177
- }
178
- catch {
179
- skillName = task.context;
180
- }
181
- }
182
- audit.insert({
183
- session_id: task.session_id,
184
- task_id: task.id,
185
- event_type: 'skill_executed',
186
- agent: 'keymaker',
187
- tool_name: skillName,
188
- duration_ms: result.usage?.durationMs,
189
- status: 'success',
190
- });
191
- }
192
160
  this.display.log(`Task completed: ${task.id}`, { source: 'TaskWorker', level: 'success' });
193
161
  }
194
162
  catch (err) {
@@ -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: 50 });
241
+ const response = await this.agent.invoke({ messages }, { recursionLimit: 10 });
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'
@@ -79,6 +79,20 @@ export const DEFAULT_CONFIG = {
79
79
  personality: 'data_specialist',
80
80
  execution_mode: 'async',
81
81
  },
82
+ link: {
83
+ provider: 'openai',
84
+ model: 'gpt-4',
85
+ temperature: 0.2,
86
+ personality: 'documentation_specialist',
87
+ chunk_size: 500,
88
+ score_threshold: 0.5,
89
+ max_results: 10,
90
+ execution_mode: 'sync',
91
+ scan_interval_ms: 30000,
92
+ max_file_size_mb: 50,
93
+ vector_weight: 0.8,
94
+ bm25_weight: 0.2,
95
+ },
82
96
  smiths: {
83
97
  enabled: false,
84
98
  execution_mode: 'async',
@@ -0,0 +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-DZ5WLUEm.js";import{Q as _,O as D,h as L,i as F,as as v,E as k,m as N,A as z,g as S,aw as I,k as U,J as A,ax as W,K as $,p as G,ai as P}from"./vendor-icons-NHF9HNeN.js";import"./vendor-utils-D4NnWbOU.js";import"./index-DfJwcKqG.js";function u(r){return r===0?"$0.00":r<1e-4?"<$0.0001":r<.01?`$${r.toFixed(4)}`:`$${r.toFixed(2)}`}function m(r){return r>=1e6?`${(r/1e6).toFixed(1)}M`:r>=1e3?`${(r/1e3).toFixed(1)}k`:String(r)}function j(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 V(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 H({data:r}){const[i,l]=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,c)=>{const y=Math.max(4,Math.round(a.eventCount/s*88)),g=i===c;return e.jsxs("div",{className:"flex-1 flex flex-col items-center justify-end group",onMouseEnter:()=>l(c),onMouseLeave:()=>l(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:[a.date,": ",a.eventCount," events · ",u(a.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"}`})]},a.date)})})}function h({icon:r,label:i,value:l,sub:s,color:a="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[a]}`,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}),s&&e.jsx("div",{className:"text-[11px] opacity-60 mt-0.5 leading-snug",children:s})]})]})}function o({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})]})}const J={oracle:"🔮",apoc:"🧑‍🔬",neo:"🥷",trinity:"👩‍💻",smith:"🕶️",chronos:"⏰",sati:"🧠",telephonist:"📞",link:"🕵️‍♂️",unknown:"?"},w={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",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",link:"bg-indigo-100 text-indigo-700 dark:bg-indigo-900/40 dark:text-indigo-300",unknown:"bg-gray-100 text-gray-500 dark:bg-zinc-800 dark:text-matrix-secondary/60"};function M({agent:r}){const i=w[r]??w.unknown;return e.jsxs("span",{className:`inline-flex items-center gap-1 text-[11px] font-semibold px-1.5 py-0.5 rounded ${i}`,children:[J[r]??"?"," ",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 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(N,{size:13}),memory_persist:e.jsx(N,{size:13}),telephonist:e.jsx($,{size:13}),skill_loaded:e.jsx(A,{size:13}),chronos_job:e.jsx(S,{size:13}),task_created:e.jsx(P,{size:13}),task_completed:e.jsx(G,{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(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",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"},Y={hidden:{opacity:0},show:{opacity:1,transition:{staggerChildren:.04}}},x={hidden:{opacity:0,y:12},show:{opacity:1,y:0}},le=()=>{const{data:r,isLoading:i,mutate:l}=R();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(D,{size:24}),e.jsx("span",{className:"text-sm",children:"Failed to load audit data."})]});const{sessions:s,totals:a,byAgent:c,byModel:y,topTools:g,recentSessions:f,dailyActivity:p}=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,d)=>d[1]-t[1]),E=Math.max(...C.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:x,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(n.div,{variants:x,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(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(k,{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:j(a.totalDurationMs),color:"rose"})]}),e.jsxs(n.div,{variants:x,className:"grid grid-cols-1 md:grid-cols-2 gap-6",children:[e.jsxs(o,{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(o,{title:"Activity — Last 30 Days",icon:e.jsx(U,{size:14}),children:[e.jsx(H,{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:x,children:e.jsx(o,{title:"Events by Type",icon:e.jsx(z,{size:14}),children:e.jsx("div",{className:"space-y-2",children:C.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 ${Z[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:T(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:T(d,a.totalEventCount)})]},t))})})}),e.jsxs(n.div,{variants:x,className:"grid grid-cols-1 lg:grid-cols-2 gap-6",children:[e.jsx(o,{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(o,{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:x,children:e.jsx(o,{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:x,children:e.jsx(o,{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:V(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: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))})]})})})}),a.telephonistCount>0&&e.jsx(n.div,{variants:x,children:e.jsx(o,{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: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{le as AuditDashboard};