@getverbal/cli 0.4.3 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (249) hide show
  1. package/dist/agent-hooks/claude.d.ts +10 -0
  2. package/dist/agent-hooks/claude.d.ts.map +1 -0
  3. package/dist/agent-hooks/claude.js +218 -0
  4. package/dist/agent-hooks/claude.js.map +1 -0
  5. package/dist/agent-hooks/cli.d.ts +2 -0
  6. package/dist/agent-hooks/cli.d.ts.map +1 -0
  7. package/dist/agent-hooks/cli.js +271 -0
  8. package/dist/agent-hooks/cli.js.map +1 -0
  9. package/dist/agent-hooks/codex.d.ts +9 -0
  10. package/dist/agent-hooks/codex.d.ts.map +1 -0
  11. package/dist/agent-hooks/codex.js +349 -0
  12. package/dist/agent-hooks/codex.js.map +1 -0
  13. package/dist/agent-hooks/config.d.ts +32 -0
  14. package/dist/agent-hooks/config.d.ts.map +1 -0
  15. package/dist/agent-hooks/config.js +176 -0
  16. package/dist/agent-hooks/config.js.map +1 -0
  17. package/dist/agent-hooks/ingest.d.ts +4 -0
  18. package/dist/agent-hooks/ingest.d.ts.map +1 -0
  19. package/dist/agent-hooks/ingest.js +22 -0
  20. package/dist/agent-hooks/ingest.js.map +1 -0
  21. package/dist/agent-hooks/launchagent.d.ts +7 -0
  22. package/dist/agent-hooks/launchagent.d.ts.map +1 -0
  23. package/dist/agent-hooks/launchagent.js +51 -0
  24. package/dist/agent-hooks/launchagent.js.map +1 -0
  25. package/dist/agent-hooks/runtime-context.d.ts +20 -0
  26. package/dist/agent-hooks/runtime-context.d.ts.map +1 -0
  27. package/dist/agent-hooks/runtime-context.js +90 -0
  28. package/dist/agent-hooks/runtime-context.js.map +1 -0
  29. package/dist/agent-hooks/state.d.ts +26 -0
  30. package/dist/agent-hooks/state.d.ts.map +1 -0
  31. package/dist/agent-hooks/state.js +67 -0
  32. package/dist/agent-hooks/state.js.map +1 -0
  33. package/dist/agent-hooks/tokscale.d.ts +70 -0
  34. package/dist/agent-hooks/tokscale.d.ts.map +1 -0
  35. package/dist/agent-hooks/tokscale.js +142 -0
  36. package/dist/agent-hooks/tokscale.js.map +1 -0
  37. package/dist/agent-hooks/tool-extraction.d.ts +7 -0
  38. package/dist/agent-hooks/tool-extraction.d.ts.map +1 -0
  39. package/dist/agent-hooks/tool-extraction.js +100 -0
  40. package/dist/agent-hooks/tool-extraction.js.map +1 -0
  41. package/dist/agent-hooks/trace.d.ts +17 -0
  42. package/dist/agent-hooks/trace.d.ts.map +1 -0
  43. package/dist/agent-hooks/trace.js +25 -0
  44. package/dist/agent-hooks/trace.js.map +1 -0
  45. package/dist/auth/browser-auth.d.ts +6 -0
  46. package/dist/auth/browser-auth.d.ts.map +1 -0
  47. package/dist/auth/browser-auth.js +202 -0
  48. package/dist/auth/browser-auth.js.map +1 -0
  49. package/dist/auth/credentials.d.ts +6 -0
  50. package/dist/auth/credentials.d.ts.map +1 -0
  51. package/dist/auth/credentials.js +78 -0
  52. package/dist/auth/credentials.js.map +1 -0
  53. package/dist/cli.d.ts +3 -0
  54. package/dist/cli.d.ts.map +1 -0
  55. package/dist/cli.js +1513 -440
  56. package/dist/cli.js.map +1 -0
  57. package/dist/commands/dashboard.d.ts +2 -0
  58. package/dist/commands/dashboard.d.ts.map +1 -0
  59. package/dist/commands/dashboard.js +19 -0
  60. package/dist/commands/dashboard.js.map +1 -0
  61. package/dist/commands/hooks.d.ts +2 -0
  62. package/dist/commands/hooks.d.ts.map +1 -0
  63. package/dist/commands/hooks.js +6 -0
  64. package/dist/commands/hooks.js.map +1 -0
  65. package/dist/commands/import.d.ts +2 -0
  66. package/dist/commands/import.d.ts.map +1 -0
  67. package/dist/commands/import.js +129 -0
  68. package/dist/commands/import.js.map +1 -0
  69. package/dist/commands/init.d.ts +2 -0
  70. package/dist/commands/init.d.ts.map +1 -0
  71. package/dist/commands/init.js +262 -0
  72. package/dist/commands/init.js.map +1 -0
  73. package/dist/commands/logout.d.ts +2 -0
  74. package/dist/commands/logout.d.ts.map +1 -0
  75. package/dist/commands/logout.js +17 -0
  76. package/dist/commands/logout.js.map +1 -0
  77. package/dist/commands/mcp-serve.d.ts +2 -0
  78. package/dist/commands/mcp-serve.d.ts.map +1 -0
  79. package/dist/commands/mcp-serve.js +7 -0
  80. package/dist/commands/mcp-serve.js.map +1 -0
  81. package/dist/commands/status.d.ts +2 -0
  82. package/dist/commands/status.d.ts.map +1 -0
  83. package/dist/commands/status.js +43 -0
  84. package/dist/commands/status.js.map +1 -0
  85. package/dist/commands/uninstall.d.ts +2 -0
  86. package/dist/commands/uninstall.d.ts.map +1 -0
  87. package/dist/commands/uninstall.js +43 -0
  88. package/dist/commands/uninstall.js.map +1 -0
  89. package/dist/commands/update.d.ts +2 -0
  90. package/dist/commands/update.d.ts.map +1 -0
  91. package/dist/commands/update.js +58 -0
  92. package/dist/commands/update.js.map +1 -0
  93. package/dist/configure/claude-code.d.ts +7 -0
  94. package/dist/configure/claude-code.d.ts.map +1 -0
  95. package/dist/configure/claude-code.js +11 -0
  96. package/dist/configure/claude-code.js.map +1 -0
  97. package/dist/configure/claude-desktop.d.ts +8 -0
  98. package/dist/configure/claude-desktop.d.ts.map +1 -0
  99. package/dist/configure/claude-desktop.js +28 -0
  100. package/dist/configure/claude-desktop.js.map +1 -0
  101. package/dist/configure/codex.d.ts +7 -0
  102. package/dist/configure/codex.d.ts.map +1 -0
  103. package/dist/configure/codex.js +12 -0
  104. package/dist/configure/codex.js.map +1 -0
  105. package/dist/configure/cursor.d.ts +7 -0
  106. package/dist/configure/cursor.d.ts.map +1 -0
  107. package/dist/configure/cursor.js +12 -0
  108. package/dist/configure/cursor.js.map +1 -0
  109. package/dist/configure/index.d.ts +34 -0
  110. package/dist/configure/index.d.ts.map +1 -0
  111. package/dist/configure/index.js +153 -0
  112. package/dist/configure/index.js.map +1 -0
  113. package/dist/detect/claude-code.d.ts +3 -0
  114. package/dist/detect/claude-code.d.ts.map +1 -0
  115. package/dist/detect/claude-code.js +82 -0
  116. package/dist/detect/claude-code.js.map +1 -0
  117. package/dist/detect/claude-desktop.d.ts +3 -0
  118. package/dist/detect/claude-desktop.d.ts.map +1 -0
  119. package/dist/detect/claude-desktop.js +89 -0
  120. package/dist/detect/claude-desktop.js.map +1 -0
  121. package/dist/detect/codex.d.ts +3 -0
  122. package/dist/detect/codex.d.ts.map +1 -0
  123. package/dist/detect/codex.js +64 -0
  124. package/dist/detect/codex.js.map +1 -0
  125. package/dist/detect/cursor.d.ts +3 -0
  126. package/dist/detect/cursor.d.ts.map +1 -0
  127. package/dist/detect/cursor.js +81 -0
  128. package/dist/detect/cursor.js.map +1 -0
  129. package/dist/detect/index.d.ts +3 -0
  130. package/dist/detect/index.d.ts.map +1 -0
  131. package/dist/detect/index.js +28 -0
  132. package/dist/detect/index.js.map +1 -0
  133. package/dist/import/file-upload.d.ts +10 -0
  134. package/dist/import/file-upload.d.ts.map +1 -0
  135. package/dist/import/file-upload.js +37 -0
  136. package/dist/import/file-upload.js.map +1 -0
  137. package/dist/import/index.d.ts +11 -0
  138. package/dist/import/index.d.ts.map +1 -0
  139. package/dist/import/index.js +51 -0
  140. package/dist/import/index.js.map +1 -0
  141. package/dist/mcp/exports.d.ts +13 -0
  142. package/dist/mcp/exports.d.ts.map +1 -0
  143. package/dist/mcp/exports.js +13 -0
  144. package/dist/mcp/exports.js.map +1 -0
  145. package/dist/mcp/git-context.d.ts +17 -0
  146. package/dist/mcp/git-context.d.ts.map +1 -0
  147. package/dist/mcp/git-context.js +72 -0
  148. package/dist/mcp/git-context.js.map +1 -0
  149. package/dist/mcp/hooks/anthropic.d.ts +31 -0
  150. package/dist/mcp/hooks/anthropic.d.ts.map +1 -0
  151. package/dist/mcp/hooks/anthropic.js +137 -0
  152. package/dist/mcp/hooks/anthropic.js.map +1 -0
  153. package/dist/mcp/hooks/google.d.ts +53 -0
  154. package/dist/mcp/hooks/google.d.ts.map +1 -0
  155. package/dist/mcp/hooks/google.js +161 -0
  156. package/dist/mcp/hooks/google.js.map +1 -0
  157. package/dist/mcp/hooks/index.d.ts +9 -0
  158. package/dist/mcp/hooks/index.d.ts.map +1 -0
  159. package/dist/mcp/hooks/index.js +7 -0
  160. package/dist/mcp/hooks/index.js.map +1 -0
  161. package/dist/mcp/hooks/openai.d.ts +59 -0
  162. package/dist/mcp/hooks/openai.d.ts.map +1 -0
  163. package/dist/mcp/hooks/openai.js +158 -0
  164. package/dist/mcp/hooks/openai.js.map +1 -0
  165. package/dist/mcp/hooks/types.d.ts +8 -0
  166. package/dist/mcp/hooks/types.d.ts.map +1 -0
  167. package/dist/mcp/hooks/types.js +5 -0
  168. package/dist/mcp/hooks/types.js.map +1 -0
  169. package/dist/mcp/ingestor.d.ts +23 -0
  170. package/dist/mcp/ingestor.d.ts.map +1 -0
  171. package/dist/mcp/ingestor.js +310 -0
  172. package/dist/mcp/ingestor.js.map +1 -0
  173. package/dist/mcp/pricing.d.ts +19 -0
  174. package/dist/mcp/pricing.d.ts.map +1 -0
  175. package/dist/mcp/pricing.js +130 -0
  176. package/dist/mcp/pricing.js.map +1 -0
  177. package/dist/mcp/server.d.ts +10 -0
  178. package/dist/mcp/server.d.ts.map +1 -0
  179. package/dist/mcp/server.js +689 -0
  180. package/dist/mcp/server.js.map +1 -0
  181. package/dist/mcp/session-tracker.d.ts +52 -0
  182. package/dist/mcp/session-tracker.d.ts.map +1 -0
  183. package/dist/mcp/session-tracker.js +186 -0
  184. package/dist/mcp/session-tracker.js.map +1 -0
  185. package/dist/mcp/tools/analyze-spending-trend.d.ts +10 -0
  186. package/dist/mcp/tools/analyze-spending-trend.d.ts.map +1 -0
  187. package/dist/mcp/tools/analyze-spending-trend.js +126 -0
  188. package/dist/mcp/tools/analyze-spending-trend.js.map +1 -0
  189. package/dist/mcp/tools/get-budget-status.d.ts +9 -0
  190. package/dist/mcp/tools/get-budget-status.d.ts.map +1 -0
  191. package/dist/mcp/tools/get-budget-status.js +59 -0
  192. package/dist/mcp/tools/get-budget-status.js.map +1 -0
  193. package/dist/mcp/tools/get-cost-breakdown.d.ts +10 -0
  194. package/dist/mcp/tools/get-cost-breakdown.d.ts.map +1 -0
  195. package/dist/mcp/tools/get-cost-breakdown.js +52 -0
  196. package/dist/mcp/tools/get-cost-breakdown.js.map +1 -0
  197. package/dist/mcp/tools/get-model-efficiency.d.ts +9 -0
  198. package/dist/mcp/tools/get-model-efficiency.d.ts.map +1 -0
  199. package/dist/mcp/tools/get-model-efficiency.js +137 -0
  200. package/dist/mcp/tools/get-model-efficiency.js.map +1 -0
  201. package/dist/mcp/tools/get-recent-prompts.d.ts +13 -0
  202. package/dist/mcp/tools/get-recent-prompts.d.ts.map +1 -0
  203. package/dist/mcp/tools/get-recent-prompts.js +56 -0
  204. package/dist/mcp/tools/get-recent-prompts.js.map +1 -0
  205. package/dist/mcp/tools/get-roi-metrics.d.ts +9 -0
  206. package/dist/mcp/tools/get-roi-metrics.d.ts.map +1 -0
  207. package/dist/mcp/tools/get-roi-metrics.js +84 -0
  208. package/dist/mcp/tools/get-roi-metrics.js.map +1 -0
  209. package/dist/mcp/tools/get-usage-summary.d.ts +10 -0
  210. package/dist/mcp/tools/get-usage-summary.d.ts.map +1 -0
  211. package/dist/mcp/tools/get-usage-summary.js +47 -0
  212. package/dist/mcp/tools/get-usage-summary.js.map +1 -0
  213. package/dist/mcp/tools/index.d.ts +221 -0
  214. package/dist/mcp/tools/index.d.ts.map +1 -0
  215. package/dist/mcp/tools/index.js +161 -0
  216. package/dist/mcp/tools/index.js.map +1 -0
  217. package/dist/mcp/tools/list-projects.d.ts +6 -0
  218. package/dist/mcp/tools/list-projects.d.ts.map +1 -0
  219. package/dist/mcp/tools/list-projects.js +43 -0
  220. package/dist/mcp/tools/list-projects.js.map +1 -0
  221. package/dist/mcp/tools/optimize-prompt.d.ts +44 -0
  222. package/dist/mcp/tools/optimize-prompt.d.ts.map +1 -0
  223. package/dist/mcp/tools/optimize-prompt.js +95 -0
  224. package/dist/mcp/tools/optimize-prompt.js.map +1 -0
  225. package/dist/mcp/types.d.ts +118 -0
  226. package/dist/mcp/types.d.ts.map +1 -0
  227. package/dist/mcp/types.js +5 -0
  228. package/dist/mcp/types.js.map +1 -0
  229. package/dist/types.d.ts +18 -0
  230. package/dist/types.d.ts.map +1 -0
  231. package/dist/types.js +2 -0
  232. package/dist/types.js.map +1 -0
  233. package/dist/update-check/check.d.ts +6 -0
  234. package/dist/update-check/check.d.ts.map +1 -0
  235. package/dist/update-check/check.js +64 -0
  236. package/dist/update-check/check.js.map +1 -0
  237. package/dist/update-check/notify.d.ts +6 -0
  238. package/dist/update-check/notify.d.ts.map +1 -0
  239. package/dist/update-check/notify.js +40 -0
  240. package/dist/update-check/notify.js.map +1 -0
  241. package/dist/verify.d.ts +7 -0
  242. package/dist/verify.d.ts.map +1 -0
  243. package/dist/verify.js +40 -0
  244. package/dist/verify.js.map +1 -0
  245. package/dist/version.d.ts +9 -0
  246. package/dist/version.d.ts.map +1 -0
  247. package/dist/version.js +21 -0
  248. package/dist/version.js.map +1 -0
  249. package/package.json +10 -5
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Verbal ingestion client with batching, HMAC signing, and retry logic
3
+ */
4
+ import type { UsageEvent, IngestorConfig, IngestResult } from './types.js';
5
+ export declare class VerbalIngestor {
6
+ private config;
7
+ private eventBuffer;
8
+ private flushTimer?;
9
+ private readonly runtimeContext;
10
+ private readonly gitContext;
11
+ constructor(config: IngestorConfig);
12
+ track(event: UsageEvent): Promise<void>;
13
+ flush(): Promise<IngestResult>;
14
+ private buildIngestPayload;
15
+ private normalizeProvider;
16
+ private isUuid;
17
+ private postToIngest;
18
+ private sleepWithJitter;
19
+ private writeDeadLetter;
20
+ destroy(): void;
21
+ }
22
+ export declare function attachExitHooks(ingestor: VerbalIngestor): void;
23
+ //# sourceMappingURL=ingestor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ingestor.d.ts","sourceRoot":"","sources":["../../src/mcp/ingestor.ts"],"names":[],"mappings":"AAAA;;GAEG;AAMH,OAAO,KAAK,EAAE,UAAU,EAAiB,cAAc,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAM1F,qBAAa,cAAc;IACzB,OAAO,CAAC,MAAM,CAA2B;IACzC,OAAO,CAAC,WAAW,CAAoB;IACvC,OAAO,CAAC,UAAU,CAAC,CAAiB;IAEpC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAA2C;IAC1E,OAAO,CAAC,QAAQ,CAAC,UAAU,CAA0C;gBAEzD,MAAM,EAAE,cAAc;IAiC5B,KAAK,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IA6DvC,KAAK,IAAI,OAAO,CAAC,YAAY,CAAC;IAuBpC,OAAO,CAAC,kBAAkB;IAwE1B,OAAO,CAAC,iBAAiB;IASzB,OAAO,CAAC,MAAM;YAMA,YAAY;YAkFZ,eAAe;YAOf,eAAe;IAkB7B,OAAO,IAAI,IAAI;CAMhB;AAED,wBAAgB,eAAe,CAAC,QAAQ,EAAE,cAAc,GAAG,IAAI,CAkB9D"}
@@ -0,0 +1,310 @@
1
+ /**
2
+ * Verbal ingestion client with batching, HMAC signing, and retry logic
3
+ */
4
+ import crypto from 'node:crypto';
5
+ import fs from 'node:fs';
6
+ import os from 'node:os';
7
+ import path from 'node:path';
8
+ import { calculateCost } from './pricing.js';
9
+ import { getGitContext } from './git-context.js';
10
+ import { collectRuntimeContext } from '../agent-hooks/runtime-context.js';
11
+ import { sessionTracker } from './session-tracker.js';
12
+ export class VerbalIngestor {
13
+ config;
14
+ eventBuffer = [];
15
+ flushTimer;
16
+ // Cached at construction — runtime/git context doesn't change between track() calls
17
+ runtimeContext;
18
+ gitContext;
19
+ constructor(config) {
20
+ this.config = {
21
+ apiKey: config.apiKey,
22
+ endpoint: config.endpoint,
23
+ hmacSecret: config.hmacSecret ?? '',
24
+ orgId: config.orgId ?? '',
25
+ defaultProject: config.defaultProject ?? '',
26
+ defaultProvider: config.defaultProvider ?? '',
27
+ defaultModel: config.defaultModel ?? '',
28
+ source: config.source ?? 'mcp',
29
+ batchSize: config.batchSize ?? 50,
30
+ flushIntervalMs: config.flushIntervalMs ?? 5000,
31
+ httpTimeoutMs: config.httpTimeoutMs ?? 5000,
32
+ gitContextEnabled: config.gitContextEnabled ?? true,
33
+ costCalcEnabled: config.costCalcEnabled ?? true,
34
+ billingType: config.billingType ?? 'api',
35
+ maxRetries: config.maxRetries ?? 3,
36
+ retryBaseDelayMs: config.retryBaseDelayMs ?? 200,
37
+ deadLetterPath: config.deadLetterPath ?? path.join(os.homedir(), '.verbal', 'dead-letter.jsonl'),
38
+ };
39
+ this.runtimeContext = collectRuntimeContext();
40
+ this.gitContext = this.config.gitContextEnabled ? getGitContext(process.cwd()) : null;
41
+ if (this.config.flushIntervalMs > 0) {
42
+ this.flushTimer = setInterval(() => {
43
+ this.flush().catch((err) => {
44
+ console.error('[VerbalIngestor] Auto-flush error:', err);
45
+ });
46
+ }, this.config.flushIntervalMs);
47
+ }
48
+ }
49
+ async track(event) {
50
+ const metadata = {
51
+ ...(event.metadata ?? {}),
52
+ runtime: this.runtimeContext,
53
+ ...(this.gitContext ? { git: this.gitContext } : {}),
54
+ capture: {
55
+ mode: event.prompt || event.response ? 'full' : 'usage',
56
+ redaction_applied: Boolean(event.prompt || event.response),
57
+ token_source: event.metadata?.token_estimate_method ? 'estimated' : 'provider',
58
+ ingest_path: event.client ?? event.source ?? this.config.source,
59
+ },
60
+ };
61
+ const provider = event.provider ?? this.config.defaultProvider;
62
+ const model = event.model ?? this.config.defaultModel;
63
+ const tokensIn = event.tokens_in ?? 0;
64
+ const tokensOut = event.tokens_out ?? 0;
65
+ const effectiveBillingType = event.billing_type ?? this.config.billingType;
66
+ const computedCost = effectiveBillingType === 'subscription'
67
+ ? 0 // Subscription events: no per-token cost (flat fee tracked separately)
68
+ : (this.config.costCalcEnabled && event.cost === undefined && provider && model
69
+ ? calculateCost(model, tokensIn, tokensOut, event.cache_read_tokens, event.cache_write_tokens)
70
+ : event.cost);
71
+ const enrichedEvent = {
72
+ event_id: event.event_id ?? crypto.randomUUID(),
73
+ timestamp: event.timestamp ?? new Date().toISOString(),
74
+ source: event.source ?? this.config.source,
75
+ client: event.client ?? 'sdk-hooks',
76
+ org_id: event.org_id ?? (this.config.orgId || undefined),
77
+ project: event.project ?? (this.config.defaultProject || undefined),
78
+ cost: computedCost,
79
+ ...event,
80
+ metadata,
81
+ };
82
+ // Mutate original event so callers can read assigned fields (e.g. event_id, timestamp)
83
+ event.event_id = enrichedEvent.event_id;
84
+ event.timestamp = enrichedEvent.timestamp;
85
+ // Track session lifecycle for review prompting
86
+ if (enrichedEvent.session_id) {
87
+ const eventTime = enrichedEvent.timestamp
88
+ ? new Date(enrichedEvent.timestamp)
89
+ : new Date();
90
+ sessionTracker.updateSession(enrichedEvent.session_id, eventTime, enrichedEvent.org_id, enrichedEvent.user);
91
+ }
92
+ this.eventBuffer.push(enrichedEvent);
93
+ if (this.eventBuffer.length >= this.config.batchSize) {
94
+ await this.flush();
95
+ }
96
+ }
97
+ async flush() {
98
+ if (this.eventBuffer.length === 0) {
99
+ return { ok: true, sent: 0, failed: 0 };
100
+ }
101
+ const batch = this.eventBuffer.splice(0, this.config.batchSize);
102
+ const payloads = [];
103
+ for (const event of batch) {
104
+ const payload = this.buildIngestPayload(event);
105
+ if (payload) {
106
+ payloads.push(payload);
107
+ }
108
+ }
109
+ if (payloads.length === 0) {
110
+ return { ok: true, sent: 0, failed: 0 };
111
+ }
112
+ const body = payloads.length === 1 ? { event: payloads[0] } : { events: payloads };
113
+ return await this.postToIngest(body);
114
+ }
115
+ buildIngestPayload(event) {
116
+ const provider = this.normalizeProvider(event.provider ?? this.config.defaultProvider);
117
+ const model = event.model ?? this.config.defaultModel;
118
+ if (!provider || !model) {
119
+ console.warn('[VerbalIngestor] Skipping event: missing provider or model', {
120
+ event_id: event.event_id,
121
+ });
122
+ return null;
123
+ }
124
+ const tags = event.tags
125
+ ? event.tags.reduce((acc, tag) => {
126
+ acc[`tag:${tag}`] = 'true';
127
+ return acc;
128
+ }, {})
129
+ : {};
130
+ if (event.project) {
131
+ tags['project'] = event.project;
132
+ }
133
+ const metadata = {
134
+ ...(event.metadata ?? {}),
135
+ mcp: {
136
+ event_id: event.event_id,
137
+ event_type: event.event_type,
138
+ source: event.source,
139
+ client: event.client,
140
+ project: event.project,
141
+ user: event.user,
142
+ tags: event.tags,
143
+ cost: event.cost,
144
+ currency: event.currency,
145
+ prompt_name: event.prompt_name,
146
+ prompt_version: event.prompt_version,
147
+ session_id: event.session_id,
148
+ request_id: event.request_id,
149
+ response_id: event.response_id,
150
+ conversation_title: event.conversation_title,
151
+ duration_ms: event.duration_ms,
152
+ },
153
+ };
154
+ const mcp = (metadata.mcp ?? {});
155
+ return {
156
+ provider,
157
+ model,
158
+ prompt_tokens: event.tokens_in,
159
+ completion_tokens: event.tokens_out,
160
+ total_tokens: event.total_tokens,
161
+ cache_read_tokens: event.cache_read_tokens ?? mcp.cache_read_tokens,
162
+ cache_write_tokens: event.cache_write_tokens ?? mcp.cache_creation_tokens,
163
+ estimated_cost: event.cost,
164
+ request_id: event.request_id ?? event.event_id,
165
+ user_id: event.user && this.isUuid(event.user) ? event.user : undefined,
166
+ tags,
167
+ metadata,
168
+ prompt_content: event.prompt,
169
+ response_content: event.response,
170
+ conversation_id: event.conversation_id,
171
+ session_id: event.session_id,
172
+ source: event.source,
173
+ client: event.client,
174
+ billing_type: event.billing_type ?? this.config.billingType,
175
+ };
176
+ }
177
+ normalizeProvider(value) {
178
+ const normalized = value?.toLowerCase();
179
+ if (!normalized)
180
+ return undefined;
181
+ if (normalized.includes('anthropic') || normalized.includes('claude'))
182
+ return 'anthropic';
183
+ if (normalized.includes('openai') || normalized.includes('gpt'))
184
+ return 'openai';
185
+ if (normalized.includes('google') || normalized.includes('gemini'))
186
+ return 'google';
187
+ return undefined;
188
+ }
189
+ isUuid(value) {
190
+ return /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(value);
191
+ }
192
+ async postToIngest(body) {
193
+ const payload = JSON.stringify(body);
194
+ const headers = {
195
+ 'Content-Type': 'application/json',
196
+ Authorization: `Bearer ${this.config.apiKey}`,
197
+ };
198
+ if (this.config.hmacSecret) {
199
+ const signature = crypto
200
+ .createHmac('sha256', this.config.hmacSecret)
201
+ .update(payload)
202
+ .digest('hex');
203
+ headers['x-verbal-signature'] = signature;
204
+ }
205
+ const eventCount = 'events' in body ? body.events.length : 1;
206
+ for (let attempt = 0; attempt <= this.config.maxRetries; attempt++) {
207
+ const controller = new AbortController();
208
+ const timeout = setTimeout(() => controller.abort(), this.config.httpTimeoutMs);
209
+ try {
210
+ const response = await fetch(this.config.endpoint, {
211
+ method: 'POST',
212
+ headers,
213
+ body: payload,
214
+ signal: controller.signal,
215
+ });
216
+ if (response.ok) {
217
+ return {
218
+ ok: true,
219
+ status: response.status,
220
+ statusText: response.statusText,
221
+ sent: eventCount,
222
+ failed: 0,
223
+ };
224
+ }
225
+ if (attempt < this.config.maxRetries && response.status >= 500) {
226
+ await this.sleepWithJitter(attempt);
227
+ continue;
228
+ }
229
+ await this.writeDeadLetter(body, `HTTP ${response.status} ${response.statusText}`);
230
+ return {
231
+ ok: false,
232
+ status: response.status,
233
+ statusText: response.statusText,
234
+ sent: 0,
235
+ failed: eventCount,
236
+ };
237
+ }
238
+ catch (error) {
239
+ if (attempt < this.config.maxRetries) {
240
+ await this.sleepWithJitter(attempt);
241
+ continue;
242
+ }
243
+ const statusText = error instanceof Error ? error.message : 'Unknown error';
244
+ await this.writeDeadLetter(body, statusText);
245
+ return {
246
+ ok: false,
247
+ statusText,
248
+ sent: 0,
249
+ failed: eventCount,
250
+ };
251
+ }
252
+ finally {
253
+ clearTimeout(timeout);
254
+ }
255
+ }
256
+ await this.writeDeadLetter(body, 'Retry budget exhausted');
257
+ return {
258
+ ok: false,
259
+ statusText: 'Retry budget exhausted',
260
+ sent: 0,
261
+ failed: eventCount,
262
+ };
263
+ }
264
+ async sleepWithJitter(attempt) {
265
+ const base = this.config.retryBaseDelayMs * Math.pow(2, attempt);
266
+ const jitter = Math.floor(Math.random() * this.config.retryBaseDelayMs);
267
+ const delay = base + jitter;
268
+ await new Promise((resolve) => setTimeout(resolve, delay));
269
+ }
270
+ async writeDeadLetter(body, reason) {
271
+ try {
272
+ const dir = path.dirname(this.config.deadLetterPath);
273
+ fs.mkdirSync(dir, { recursive: true });
274
+ const record = {
275
+ timestamp: new Date().toISOString(),
276
+ reason,
277
+ body,
278
+ };
279
+ fs.appendFileSync(this.config.deadLetterPath, `${JSON.stringify(record)}\n`, 'utf8');
280
+ }
281
+ catch (error) {
282
+ console.error('[VerbalIngestor] Failed to write dead-letter record', error);
283
+ }
284
+ }
285
+ destroy() {
286
+ if (this.flushTimer) {
287
+ clearInterval(this.flushTimer);
288
+ this.flushTimer = undefined;
289
+ }
290
+ }
291
+ }
292
+ export function attachExitHooks(ingestor) {
293
+ const cleanup = () => {
294
+ ingestor.flush().catch((err) => {
295
+ console.error('[VerbalIngestor] Exit flush error:', err);
296
+ });
297
+ ingestor.destroy();
298
+ sessionTracker.destroy();
299
+ };
300
+ process.on('beforeExit', cleanup);
301
+ process.on('SIGINT', () => {
302
+ cleanup();
303
+ process.exit(0);
304
+ });
305
+ process.on('SIGTERM', () => {
306
+ cleanup();
307
+ process.exit(0);
308
+ });
309
+ }
310
+ //# sourceMappingURL=ingestor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ingestor.js","sourceRoot":"","sources":["../../src/mcp/ingestor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Pricing tables for major LLM providers (as of February 2026)
3
+ * Prices in USD per million tokens
4
+ */
5
+ export interface ModelPricing {
6
+ input_per_million: number;
7
+ output_per_million: number;
8
+ cache_read_per_million?: number;
9
+ cache_write_per_million?: number;
10
+ }
11
+ /**
12
+ * Calculate cost for a usage event based on model and token counts
13
+ */
14
+ export declare function calculateCost(model: string, inputTokens: number, outputTokens: number, cacheReadTokens?: number, cacheWriteTokens?: number): number;
15
+ /**
16
+ * Get pricing info for a model (for display purposes)
17
+ */
18
+ export declare function getPricing(model: string): ModelPricing | null;
19
+ //# sourceMappingURL=pricing.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pricing.d.ts","sourceRoot":"","sources":["../../src/mcp/pricing.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,WAAW,YAAY;IAC3B,iBAAiB,EAAE,MAAM,CAAC;IAC1B,kBAAkB,EAAE,MAAM,CAAC;IAC3B,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,uBAAuB,CAAC,EAAE,MAAM,CAAC;CAClC;AA0FD;;GAEG;AACH,wBAAgB,aAAa,CAC3B,KAAK,EAAE,MAAM,EACb,WAAW,EAAE,MAAM,EACnB,YAAY,EAAE,MAAM,EACpB,eAAe,CAAC,EAAE,MAAM,EACxB,gBAAgB,CAAC,EAAE,MAAM,GACxB,MAAM,CA2BR;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,YAAY,GAAG,IAAI,CAY7D"}
@@ -0,0 +1,130 @@
1
+ /**
2
+ * Pricing tables for major LLM providers (as of February 2026)
3
+ * Prices in USD per million tokens
4
+ */
5
+ const PRICING_TABLES = {
6
+ // Anthropic Claude models
7
+ 'claude-opus-4': {
8
+ input_per_million: 15.0,
9
+ output_per_million: 75.0,
10
+ cache_read_per_million: 1.5,
11
+ cache_write_per_million: 18.75,
12
+ },
13
+ 'claude-opus-4-6': {
14
+ input_per_million: 15.0,
15
+ output_per_million: 75.0,
16
+ cache_read_per_million: 1.5,
17
+ cache_write_per_million: 18.75,
18
+ },
19
+ 'claude-sonnet-4-5': {
20
+ input_per_million: 3.0,
21
+ output_per_million: 15.0,
22
+ cache_read_per_million: 0.3,
23
+ cache_write_per_million: 3.75,
24
+ },
25
+ 'claude-sonnet-4-5-20250929': {
26
+ input_per_million: 3.0,
27
+ output_per_million: 15.0,
28
+ cache_read_per_million: 0.3,
29
+ cache_write_per_million: 3.75,
30
+ },
31
+ 'claude-haiku-4-5': {
32
+ input_per_million: 0.8,
33
+ output_per_million: 4.0,
34
+ cache_read_per_million: 0.08,
35
+ cache_write_per_million: 1.0,
36
+ },
37
+ 'claude-haiku-4-5-20251001': {
38
+ input_per_million: 0.8,
39
+ output_per_million: 4.0,
40
+ cache_read_per_million: 0.08,
41
+ cache_write_per_million: 1.0,
42
+ },
43
+ 'claude-sonnet-4-6': {
44
+ input_per_million: 3.0,
45
+ output_per_million: 15.0,
46
+ cache_read_per_million: 0.3,
47
+ cache_write_per_million: 3.75,
48
+ },
49
+ 'claude-haiku-4-6': {
50
+ input_per_million: 0.8,
51
+ output_per_million: 4.0,
52
+ cache_read_per_million: 0.08,
53
+ cache_write_per_million: 1.0,
54
+ },
55
+ // OpenAI models
56
+ 'gpt-4': {
57
+ input_per_million: 30.0,
58
+ output_per_million: 60.0,
59
+ },
60
+ 'gpt-4-turbo': {
61
+ input_per_million: 10.0,
62
+ output_per_million: 30.0,
63
+ },
64
+ 'gpt-4o': {
65
+ input_per_million: 2.5,
66
+ output_per_million: 10.0,
67
+ },
68
+ 'gpt-4o-mini': {
69
+ input_per_million: 0.15,
70
+ output_per_million: 0.6,
71
+ },
72
+ 'gpt-3.5-turbo': {
73
+ input_per_million: 0.5,
74
+ output_per_million: 1.5,
75
+ },
76
+ // Google Gemini models
77
+ 'gemini-2.0-flash': {
78
+ input_per_million: 0.075,
79
+ output_per_million: 0.3,
80
+ },
81
+ 'gemini-1.5-pro': {
82
+ input_per_million: 1.25,
83
+ output_per_million: 5.0,
84
+ },
85
+ 'gemini-1.5-flash': {
86
+ input_per_million: 0.075,
87
+ output_per_million: 0.3,
88
+ },
89
+ };
90
+ /**
91
+ * Calculate cost for a usage event based on model and token counts
92
+ */
93
+ export function calculateCost(model, inputTokens, outputTokens, cacheReadTokens, cacheWriteTokens) {
94
+ const pricing = getPricing(model);
95
+ if (!pricing) {
96
+ // Unknown model - return 0 and log warning
97
+ console.warn(`[Pricing] No pricing data for model: ${model}`);
98
+ return 0;
99
+ }
100
+ let cost = 0;
101
+ // Input tokens
102
+ cost += (inputTokens / 1_000_000) * pricing.input_per_million;
103
+ // Output tokens
104
+ cost += (outputTokens / 1_000_000) * pricing.output_per_million;
105
+ // Cache tokens (Anthropic-specific)
106
+ if (cacheReadTokens && pricing.cache_read_per_million) {
107
+ cost += (cacheReadTokens / 1_000_000) * pricing.cache_read_per_million;
108
+ }
109
+ if (cacheWriteTokens && pricing.cache_write_per_million) {
110
+ cost += (cacheWriteTokens / 1_000_000) * pricing.cache_write_per_million;
111
+ }
112
+ return Math.round(cost * 100000) / 100000; // Round to 5 decimal places
113
+ }
114
+ /**
115
+ * Get pricing info for a model (for display purposes)
116
+ */
117
+ export function getPricing(model) {
118
+ // Exact match first
119
+ if (PRICING_TABLES[model])
120
+ return PRICING_TABLES[model];
121
+ // Prefix match for versioned model IDs (e.g., claude-sonnet-4-6-20261201 → claude-sonnet-4-6)
122
+ // Sort by length descending to match the most specific prefix first
123
+ const keys = Object.keys(PRICING_TABLES).sort((a, b) => b.length - a.length);
124
+ for (const key of keys) {
125
+ if (model.startsWith(key + '-'))
126
+ return PRICING_TABLES[key];
127
+ }
128
+ return null;
129
+ }
130
+ //# sourceMappingURL=pricing.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pricing.js","sourceRoot":"","sources":["../../src/mcp/pricing.ts"],"names":[],"mappings":"AAAA;;;GAGG;AASH,MAAM,cAAc,GAAiC;IACnD,0BAA0B;IAC1B,eAAe,EAAE;QACf,iBAAiB,EAAE,IAAI;QACvB,kBAAkB,EAAE,IAAI;QACxB,sBAAsB,EAAE,GAAG;QAC3B,uBAAuB,EAAE,KAAK;KAC/B;IACD,iBAAiB,EAAE;QACjB,iBAAiB,EAAE,IAAI;QACvB,kBAAkB,EAAE,IAAI;QACxB,sBAAsB,EAAE,GAAG;QAC3B,uBAAuB,EAAE,KAAK;KAC/B;IACD,mBAAmB,EAAE;QACnB,iBAAiB,EAAE,GAAG;QACtB,kBAAkB,EAAE,IAAI;QACxB,sBAAsB,EAAE,GAAG;QAC3B,uBAAuB,EAAE,IAAI;KAC9B;IACD,4BAA4B,EAAE;QAC5B,iBAAiB,EAAE,GAAG;QACtB,kBAAkB,EAAE,IAAI;QACxB,sBAAsB,EAAE,GAAG;QAC3B,uBAAuB,EAAE,IAAI;KAC9B;IACD,kBAAkB,EAAE;QAClB,iBAAiB,EAAE,GAAG;QACtB,kBAAkB,EAAE,GAAG;QACvB,sBAAsB,EAAE,IAAI;QAC5B,uBAAuB,EAAE,GAAG;KAC7B;IACD,2BAA2B,EAAE;QAC3B,iBAAiB,EAAE,GAAG;QACtB,kBAAkB,EAAE,GAAG;QACvB,sBAAsB,EAAE,IAAI;QAC5B,uBAAuB,EAAE,GAAG;KAC7B;IACD,mBAAmB,EAAE;QACnB,iBAAiB,EAAE,GAAG;QACtB,kBAAkB,EAAE,IAAI;QACxB,sBAAsB,EAAE,GAAG;QAC3B,uBAAuB,EAAE,IAAI;KAC9B;IACD,kBAAkB,EAAE;QAClB,iBAAiB,EAAE,GAAG;QACtB,kBAAkB,EAAE,GAAG;QACvB,sBAAsB,EAAE,IAAI;QAC5B,uBAAuB,EAAE,GAAG;KAC7B;IAED,gBAAgB;IAChB,OAAO,EAAE;QACP,iBAAiB,EAAE,IAAI;QACvB,kBAAkB,EAAE,IAAI;KACzB;IACD,aAAa,EAAE;QACb,iBAAiB,EAAE,IAAI;QACvB,kBAAkB,EAAE,IAAI;KACzB;IACD,QAAQ,EAAE;QACR,iBAAiB,EAAE,GAAG;QACtB,kBAAkB,EAAE,IAAI;KACzB;IACD,aAAa,EAAE;QACb,iBAAiB,EAAE,IAAI;QACvB,kBAAkB,EAAE,GAAG;KACxB;IACD,eAAe,EAAE;QACf,iBAAiB,EAAE,GAAG;QACtB,kBAAkB,EAAE,GAAG;KACxB;IAED,uBAAuB;IACvB,kBAAkB,EAAE;QAClB,iBAAiB,EAAE,KAAK;QACxB,kBAAkB,EAAE,GAAG;KACxB;IACD,gBAAgB,EAAE;QAChB,iBAAiB,EAAE,IAAI;QACvB,kBAAkB,EAAE,GAAG;KACxB;IACD,kBAAkB,EAAE;QAClB,iBAAiB,EAAE,KAAK;QACxB,kBAAkB,EAAE,GAAG;KACxB;CACF,CAAC;AAEF;;GAEG;AACH,MAAM,UAAU,aAAa,CAC3B,KAAa,EACb,WAAmB,EACnB,YAAoB,EACpB,eAAwB,EACxB,gBAAyB;IAEzB,MAAM,OAAO,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC;IAElC,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,2CAA2C;QAC3C,OAAO,CAAC,IAAI,CAAC,wCAAwC,KAAK,EAAE,CAAC,CAAC;QAC9D,OAAO,CAAC,CAAC;IACX,CAAC;IAED,IAAI,IAAI,GAAG,CAAC,CAAC;IAEb,eAAe;IACf,IAAI,IAAI,CAAC,WAAW,GAAG,SAAS,CAAC,GAAG,OAAO,CAAC,iBAAiB,CAAC;IAE9D,gBAAgB;IAChB,IAAI,IAAI,CAAC,YAAY,GAAG,SAAS,CAAC,GAAG,OAAO,CAAC,kBAAkB,CAAC;IAEhE,oCAAoC;IACpC,IAAI,eAAe,IAAI,OAAO,CAAC,sBAAsB,EAAE,CAAC;QACtD,IAAI,IAAI,CAAC,eAAe,GAAG,SAAS,CAAC,GAAG,OAAO,CAAC,sBAAsB,CAAC;IACzE,CAAC;IAED,IAAI,gBAAgB,IAAI,OAAO,CAAC,uBAAuB,EAAE,CAAC;QACxD,IAAI,IAAI,CAAC,gBAAgB,GAAG,SAAS,CAAC,GAAG,OAAO,CAAC,uBAAuB,CAAC;IAC3E,CAAC;IAED,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,GAAG,MAAM,CAAC,GAAG,MAAM,CAAC,CAAC,4BAA4B;AACzE,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,UAAU,CAAC,KAAa;IACtC,oBAAoB;IACpB,IAAI,cAAc,CAAC,KAAK,CAAC;QAAE,OAAO,cAAc,CAAC,KAAK,CAAC,CAAC;IAExD,8FAA8F;IAC9F,oEAAoE;IACpE,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC;IAC7E,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,IAAI,KAAK,CAAC,UAAU,CAAC,GAAG,GAAG,GAAG,CAAC;YAAE,OAAO,cAAc,CAAC,GAAG,CAAC,CAAC;IAC9D,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Verbal MCP Server with native SDK hooks
3
+ *
4
+ * This MCP server provides tools for logging LLM usage to Verbal and can be used
5
+ * with the hook adapters for transparent SDK integration.
6
+ *
7
+ * Based on the MCP Ingestion spec with native SDK hooks support.
8
+ */
9
+ export declare function startMcpServer(): Promise<void>;
10
+ //# sourceMappingURL=server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/mcp/server.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AA+uBH,wBAAsB,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC,CAKpD"}