@grislabs/agentmeter 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,208 @@
1
+ # agentmeter
2
+
3
+ Cost intelligence for AI agents. Track per-task, per-workflow, per-customer costs across LLM calls, MCP tools, and agent payments.
4
+
5
+ **The problem:** Your AI agents make 15+ LLM calls, 8 tool calls, and trigger payments per task. Existing tools track per-API-call costs. Nobody tells you "that support ticket cost $2.47 to resolve" or "customer X is costing you $500/mo in agent spend."
6
+
7
+ **agentmeter answers:** What does each agent task cost, broken down by LLM inference, tool usage, and payments — per workflow, per customer?
8
+
9
+ ## Quick Start
10
+
11
+ ```bash
12
+ npm install @grislabs/agentmeter
13
+ ```
14
+
15
+ ### Zero-config auto-tracking
16
+
17
+ Patch your LLM client once. Every call is tracked automatically.
18
+
19
+ ```typescript
20
+ import Anthropic from "@anthropic-ai/sdk";
21
+ import { init, patchAnthropic } from "@grislabs/agentmeter";
22
+
23
+ init({ apiKey: "am_live_...", endpoint: "https://api.agentmeter.dev" });
24
+
25
+ const client = patchAnthropic(new Anthropic());
26
+
27
+ // All calls are now tracked — no other changes needed
28
+ const msg = await client.messages.create({
29
+ model: "claude-sonnet-4-20250514",
30
+ max_tokens: 1024,
31
+ messages: [{ role: "user", content: "Hello" }],
32
+ });
33
+ ```
34
+
35
+ Works with OpenAI too:
36
+
37
+ ```typescript
38
+ import OpenAI from "openai";
39
+ import { init, patchOpenAI } from "@grislabs/agentmeter";
40
+
41
+ init({ apiKey: "am_live_..." });
42
+ const client = patchOpenAI(new OpenAI());
43
+ ```
44
+
45
+ ### Workflow tracing
46
+
47
+ For per-task cost attribution, wrap your agent logic in `trace()`:
48
+
49
+ ```typescript
50
+ import { trace, extractors } from "@grislabs/agentmeter";
51
+
52
+ const result = await trace(
53
+ "resolve-ticket", // workflow name
54
+ { customerId: "cust_123" }, // tags for attribution
55
+ async (ctx) => {
56
+ // LLM call — cost tracked automatically
57
+ const analysis = await ctx.llm(
58
+ anthropic.messages.create({
59
+ model: "claude-sonnet-4-20250514",
60
+ max_tokens: 1024,
61
+ messages: [{ role: "user", content: ticket.description }],
62
+ }),
63
+ extractors.anthropic,
64
+ );
65
+
66
+ // Tool call with cost (e.g., paid MCP server)
67
+ const results = await ctx.tool(
68
+ "search-kb",
69
+ searchKnowledgeBase(ticket.query),
70
+ { cost: 0.01, costType: "mcp" },
71
+ );
72
+
73
+ // Agent payment (Stripe MPP, x402, etc.)
74
+ await ctx.payment(
75
+ {
76
+ provider: "stripe_mpp",
77
+ amount: 0.50,
78
+ description: "Premium data lookup",
79
+ },
80
+ callMPPEndpoint(query),
81
+ );
82
+
83
+ return { analysis, results };
84
+ },
85
+ );
86
+ // Trace recorded: $2.47 total (LLM: $0.03, Tools: $0.01, Payments: $0.50)
87
+ ```
88
+
89
+ ### Budget controls
90
+
91
+ Set cost limits per workflow. Kill runaway agents before they drain your budget.
92
+
93
+ ```typescript
94
+ import { budget } from "@grislabs/agentmeter";
95
+
96
+ budget("resolve-ticket", {
97
+ perRun: 5.00, // kill if single run exceeds $5
98
+ daily: 500, // alert at $500/day
99
+ monthly: 10_000, // hard cap at $10K/month
100
+ onExceeded: "kill", // "kill" | "alert" | "downgrade-model"
101
+ });
102
+ ```
103
+
104
+ Budget checks cover **all cost types** — LLM, tools, and payments combined.
105
+
106
+ ### MCP middleware
107
+
108
+ Auto-track all MCP tool calls without manual wrapping:
109
+
110
+ ```typescript
111
+ import { createMCPMiddleware } from "agentmeter/mcp";
112
+
113
+ const mcpMeter = createMCPMiddleware(mcpClient, {
114
+ defaultCostPerCall: 0.01,
115
+ toolCosts: { "premium-search": 0.10 },
116
+ });
117
+
118
+ await trace("my-workflow", {}, async (ctx) => {
119
+ const client = mcpMeter.wrap(ctx);
120
+ // All callTool invocations are now tracked with costs
121
+ await client.callTool({ name: "search", arguments: { q: "test" } });
122
+ });
123
+ ```
124
+
125
+ ## CLI
126
+
127
+ Check your agent costs from the terminal:
128
+
129
+ ```bash
130
+ # Overview: total spend, top workflows, daily trend
131
+ npx agentmeter status
132
+
133
+ # Workflow breakdown with cost percentiles (p50/p95)
134
+ npx agentmeter workflows
135
+
136
+ # Cost per customer
137
+ npx agentmeter customers
138
+
139
+ # Date range filter
140
+ npx agentmeter status --from=2026-03-01 --to=2026-03-22
141
+ ```
142
+
143
+ Configure via environment variable, `.env` file, or `agentmeter.config.json`:
144
+
145
+ ```bash
146
+ export AGENTMETER_API_KEY=am_live_...
147
+ export AGENTMETER_ENDPOINT=https://api.agentmeter.dev
148
+ ```
149
+
150
+ ## What's tracked
151
+
152
+ | Cost type | How | Example |
153
+ |-----------|-----|---------|
154
+ | **LLM inference** | Auto (via extractors or auto-patch) | Anthropic, OpenAI, Google |
155
+ | **MCP tool calls** | Manual (`cost` param) or MCP middleware | Paid MCP servers, API calls |
156
+ | **Agent payments** | `ctx.payment()` wrapper | Stripe MPP, x402, AP2 |
157
+ | **Compute** | Manual (`costType: "compute"`) | E2B sandbox, GPU time |
158
+
159
+ All costs roll up into `totalCost` per trace, split into `llmCost`, `toolCost`, and `paymentCost`.
160
+
161
+ ## Supported providers
162
+
163
+ Built-in extractors for token/cost calculation:
164
+
165
+ - `extractors.anthropic` — Claude (Opus, Sonnet, Haiku) with prompt caching support
166
+ - `extractors.openai` — GPT-4o, GPT-4o-mini, o1, o3-mini
167
+ - `extractors.google` — Gemini 2.0 Flash/Pro, Gemini 1.5
168
+
169
+ Custom models: use `setCustomPricing()` or pass cost directly.
170
+
171
+ ## API
172
+
173
+ ### `init(config)`
174
+
175
+ Initialize agentmeter. Call once at app startup.
176
+
177
+ ```typescript
178
+ init({
179
+ apiKey: "am_live_...", // your API key
180
+ endpoint: "https://api.agentmeter.dev", // API endpoint
181
+ local: false, // true = console output only, no API
182
+ flushIntervalMs: 10_000, // batch flush interval (default: 10s)
183
+ flushSize: 100, // batch size trigger (default: 100)
184
+ pricing: { // custom model pricing (per 1M tokens)
185
+ "my-model": { input: 1, output: 2 },
186
+ },
187
+ });
188
+ ```
189
+
190
+ ### `trace(workflow, tags, fn)`
191
+
192
+ Wrap agent logic. Returns whatever `fn` returns.
193
+
194
+ ### `budget(workflow, rule)`
195
+
196
+ Set cost limits. Checked on every LLM call, tool call, and payment.
197
+
198
+ ### `patchAnthropic(client)` / `patchOpenAI(client)`
199
+
200
+ Auto-track all LLM calls on a client instance. Returns the same client (mutated).
201
+
202
+ ### `flush()` / `shutdown()`
203
+
204
+ Flush pending events. Call `shutdown()` before process exit.
205
+
206
+ ## License
207
+
208
+ MIT
@@ -0,0 +1,48 @@
1
+ import type { LLMCallEvent, TraceTags } from "./types.js";
2
+ type EventEmitter = (event: LLMCallEvent) => void;
3
+ export declare function setAutoPatchEmitter(emitter: EventEmitter): void;
4
+ export declare function setDefaultTags(tags: TraceTags): void;
5
+ /**
6
+ * Patch an Anthropic client instance to auto-track all messages.create calls.
7
+ *
8
+ * @example
9
+ * ```ts
10
+ * import Anthropic from "@anthropic-ai/sdk";
11
+ * import { init, patchAnthropic } from "agentmeter";
12
+ *
13
+ * init({ apiKey: "am_..." });
14
+ * const client = patchAnthropic(new Anthropic());
15
+ *
16
+ * // All calls are now auto-tracked
17
+ * const msg = await client.messages.create({ model: "claude-sonnet-4", ... });
18
+ * ```
19
+ */
20
+ export declare function patchAnthropic<T extends {
21
+ messages: {
22
+ create: (...args: unknown[]) => unknown;
23
+ };
24
+ }>(client: T): T;
25
+ /**
26
+ * Patch an OpenAI client instance to auto-track all chat.completions.create calls.
27
+ *
28
+ * @example
29
+ * ```ts
30
+ * import OpenAI from "openai";
31
+ * import { init, patchOpenAI } from "agentmeter";
32
+ *
33
+ * init({ apiKey: "am_..." });
34
+ * const client = patchOpenAI(new OpenAI());
35
+ *
36
+ * // All calls are now auto-tracked
37
+ * const completion = await client.chat.completions.create({ model: "gpt-4o", ... });
38
+ * ```
39
+ */
40
+ export declare function patchOpenAI<T extends {
41
+ chat: {
42
+ completions: {
43
+ create: (...args: unknown[]) => unknown;
44
+ };
45
+ };
46
+ }>(client: T): T;
47
+ export {};
48
+ //# sourceMappingURL=auto-patch.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auto-patch.d.ts","sourceRoot":"","sources":["../src/auto-patch.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAE1D,KAAK,YAAY,GAAG,CAAC,KAAK,EAAE,YAAY,KAAK,IAAI,CAAC;AAKlD,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,YAAY,GAAG,IAAI,CAE/D;AAED,wBAAgB,cAAc,CAAC,IAAI,EAAE,SAAS,GAAG,IAAI,CAEpD;AAqCD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,cAAc,CAAC,CAAC,SAAS;IAAE,QAAQ,EAAE;QAAE,MAAM,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,OAAO,CAAA;KAAE,CAAA;CAAE,EAChG,MAAM,EAAE,CAAC,GACR,CAAC,CA2CH;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,WAAW,CAAC,CAAC,SAAS;IAAE,IAAI,EAAE;QAAE,WAAW,EAAE;YAAE,MAAM,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,OAAO,CAAA;SAAE,CAAA;KAAE,CAAA;CAAE,EAC1G,MAAM,EAAE,CAAC,GACR,CAAC,CAwCH"}
@@ -0,0 +1,129 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.setAutoPatchEmitter = setAutoPatchEmitter;
4
+ exports.setDefaultTags = setDefaultTags;
5
+ exports.patchAnthropic = patchAnthropic;
6
+ exports.patchOpenAI = patchOpenAI;
7
+ const pricing_js_1 = require("./pricing.js");
8
+ let _emitEvent = null;
9
+ let _defaultTags = {};
10
+ function setAutoPatchEmitter(emitter) {
11
+ _emitEvent = emitter;
12
+ }
13
+ function setDefaultTags(tags) {
14
+ _defaultTags = tags;
15
+ }
16
+ function emitLLMEvent(params) {
17
+ if (!_emitEvent)
18
+ return;
19
+ const cost = (0, pricing_js_1.calculateCost)(params.model, params.inputTokens, params.outputTokens, params.cachedInputTokens);
20
+ _emitEvent({
21
+ type: "llm",
22
+ traceId: "auto",
23
+ workflow: "auto",
24
+ tags: { ..._defaultTags },
25
+ model: params.model,
26
+ inputTokens: params.inputTokens,
27
+ outputTokens: params.outputTokens,
28
+ cachedInputTokens: params.cachedInputTokens,
29
+ cost,
30
+ durationMs: params.durationMs,
31
+ success: params.success,
32
+ error: params.error,
33
+ timestamp: Date.now(),
34
+ });
35
+ }
36
+ /**
37
+ * Patch an Anthropic client instance to auto-track all messages.create calls.
38
+ *
39
+ * @example
40
+ * ```ts
41
+ * import Anthropic from "@anthropic-ai/sdk";
42
+ * import { init, patchAnthropic } from "agentmeter";
43
+ *
44
+ * init({ apiKey: "am_..." });
45
+ * const client = patchAnthropic(new Anthropic());
46
+ *
47
+ * // All calls are now auto-tracked
48
+ * const msg = await client.messages.create({ model: "claude-sonnet-4", ... });
49
+ * ```
50
+ */
51
+ function patchAnthropic(client) {
52
+ const original = client.messages.create.bind(client.messages);
53
+ client.messages.create = async function (...args) {
54
+ const start = Date.now();
55
+ try {
56
+ const response = await original(...args);
57
+ emitLLMEvent({
58
+ model: response.model,
59
+ inputTokens: response.usage.input_tokens,
60
+ outputTokens: response.usage.output_tokens,
61
+ cachedInputTokens: (response.usage.cache_read_input_tokens ?? 0) +
62
+ (response.usage.cache_creation_input_tokens ?? 0),
63
+ durationMs: Date.now() - start,
64
+ success: true,
65
+ });
66
+ return response;
67
+ }
68
+ catch (err) {
69
+ emitLLMEvent({
70
+ model: "unknown",
71
+ inputTokens: 0,
72
+ outputTokens: 0,
73
+ cachedInputTokens: 0,
74
+ durationMs: Date.now() - start,
75
+ success: false,
76
+ error: err instanceof Error ? err.message : String(err),
77
+ });
78
+ throw err;
79
+ }
80
+ };
81
+ return client;
82
+ }
83
+ /**
84
+ * Patch an OpenAI client instance to auto-track all chat.completions.create calls.
85
+ *
86
+ * @example
87
+ * ```ts
88
+ * import OpenAI from "openai";
89
+ * import { init, patchOpenAI } from "agentmeter";
90
+ *
91
+ * init({ apiKey: "am_..." });
92
+ * const client = patchOpenAI(new OpenAI());
93
+ *
94
+ * // All calls are now auto-tracked
95
+ * const completion = await client.chat.completions.create({ model: "gpt-4o", ... });
96
+ * ```
97
+ */
98
+ function patchOpenAI(client) {
99
+ const original = client.chat.completions.create.bind(client.chat.completions);
100
+ client.chat.completions.create = async function (...args) {
101
+ const start = Date.now();
102
+ try {
103
+ const response = await original(...args);
104
+ emitLLMEvent({
105
+ model: response.model,
106
+ inputTokens: response.usage?.prompt_tokens ?? 0,
107
+ outputTokens: response.usage?.completion_tokens ?? 0,
108
+ cachedInputTokens: response.usage?.prompt_tokens_details?.cached_tokens ?? 0,
109
+ durationMs: Date.now() - start,
110
+ success: true,
111
+ });
112
+ return response;
113
+ }
114
+ catch (err) {
115
+ emitLLMEvent({
116
+ model: "unknown",
117
+ inputTokens: 0,
118
+ outputTokens: 0,
119
+ cachedInputTokens: 0,
120
+ durationMs: Date.now() - start,
121
+ success: false,
122
+ error: err instanceof Error ? err.message : String(err),
123
+ });
124
+ throw err;
125
+ }
126
+ };
127
+ return client;
128
+ }
129
+ //# sourceMappingURL=auto-patch.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auto-patch.js","sourceRoot":"","sources":["../src/auto-patch.ts"],"names":[],"mappings":"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"}
package/dist/cli.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":""}
package/dist/cli.js ADDED
@@ -0,0 +1,209 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ const node_fs_1 = require("node:fs");
5
+ const node_path_1 = require("node:path");
6
+ const DEFAULT_ENDPOINT = "http://localhost:3001";
7
+ function loadConfig() {
8
+ // 1. Check env vars
9
+ const envKey = process.env.AGENTMETER_API_KEY;
10
+ const envEndpoint = process.env.AGENTMETER_ENDPOINT;
11
+ // 2. Check config file
12
+ const configPath = (0, node_path_1.resolve)(process.cwd(), "agentmeter.config.json");
13
+ let fileConfig = {};
14
+ if ((0, node_fs_1.existsSync)(configPath)) {
15
+ try {
16
+ fileConfig = JSON.parse((0, node_fs_1.readFileSync)(configPath, "utf-8"));
17
+ }
18
+ catch {
19
+ // ignore malformed config
20
+ }
21
+ }
22
+ // 3. Check .env file for AGENTMETER_API_KEY
23
+ const envPath = (0, node_path_1.resolve)(process.cwd(), ".env");
24
+ if ((0, node_fs_1.existsSync)(envPath) && !envKey) {
25
+ const envContent = (0, node_fs_1.readFileSync)(envPath, "utf-8");
26
+ const match = envContent.match(/^AGENTMETER_API_KEY=(.+)$/m);
27
+ if (match)
28
+ fileConfig.apiKey = match[1].trim();
29
+ const endpointMatch = envContent.match(/^AGENTMETER_ENDPOINT=(.+)$/m);
30
+ if (endpointMatch)
31
+ fileConfig.endpoint = endpointMatch[1].trim();
32
+ }
33
+ return {
34
+ apiKey: envKey ?? fileConfig.apiKey,
35
+ endpoint: envEndpoint ?? fileConfig.endpoint ?? DEFAULT_ENDPOINT,
36
+ };
37
+ }
38
+ async function apiCall(path, config) {
39
+ const url = `${config.endpoint}${path}`;
40
+ const res = await fetch(url, {
41
+ headers: { Authorization: `Bearer ${config.apiKey}` },
42
+ });
43
+ if (!res.ok) {
44
+ if (res.status === 401)
45
+ throw new Error("Invalid API key");
46
+ throw new Error(`API error: ${res.status}`);
47
+ }
48
+ return res.json();
49
+ }
50
+ function formatUSD(n) {
51
+ return `$${n.toFixed(4)}`;
52
+ }
53
+ function padRight(s, len) {
54
+ return s.length >= len ? s.slice(0, len) : s + " ".repeat(len - s.length);
55
+ }
56
+ function padLeft(s, len) {
57
+ return s.length >= len ? s : " ".repeat(len - s.length) + s;
58
+ }
59
+ function printTable(headers, rows, colWidths) {
60
+ const sep = colWidths.map((w) => "─".repeat(w + 2)).join("┼");
61
+ const headerLine = headers.map((h, i) => ` ${padRight(h, colWidths[i])} `).join("│");
62
+ console.log(`┌${"─".repeat(sep.length)}┐`);
63
+ console.log(`│${headerLine}│`);
64
+ console.log(`├${sep}┤`);
65
+ for (const row of rows) {
66
+ const line = row.map((cell, i) => {
67
+ const isNum = /^\$|^\d/.test(cell);
68
+ return isNum ? ` ${padLeft(cell, colWidths[i])} ` : ` ${padRight(cell, colWidths[i])} `;
69
+ }).join("│");
70
+ console.log(`│${line}│`);
71
+ }
72
+ console.log(`└${"─".repeat(sep.length)}┘`);
73
+ }
74
+ async function cmdStatus(config, args) {
75
+ const from = args.find((a) => a.startsWith("--from="))?.split("=")[1];
76
+ const to = args.find((a) => a.startsWith("--to="))?.split("=")[1];
77
+ const params = new URLSearchParams();
78
+ if (from)
79
+ params.set("from", from);
80
+ if (to)
81
+ params.set("to", to);
82
+ const data = await apiCall(`/v1/overview?${params}`, config);
83
+ console.log(`\n AgentMeter Overview (${data.from.slice(0, 10)} → ${data.to.slice(0, 10)})\n`);
84
+ console.log(` Total spend: ${formatUSD(data.totals.totalCost)}`);
85
+ console.log(` Total traces: ${data.totals.traceCount}`);
86
+ console.log(` Errors: ${data.totals.errorCount}\n`);
87
+ if (data.topWorkflows.length > 0) {
88
+ console.log(" Top workflows by cost:\n");
89
+ printTable(["Workflow", "Traces", "Total Cost"], data.topWorkflows.map((w) => [w.workflow, String(w.traceCount), formatUSD(w.totalCost)]), [30, 8, 12]);
90
+ }
91
+ if (data.dailySpend.length > 0) {
92
+ console.log("\n Daily spend:\n");
93
+ printTable(["Day", "Traces", "Cost"], data.dailySpend.slice(-7).map((d) => [d.day, String(d.traceCount), formatUSD(d.dailyCost)]), [12, 8, 12]);
94
+ }
95
+ console.log();
96
+ }
97
+ async function cmdWorkflows(config, args) {
98
+ const from = args.find((a) => a.startsWith("--from="))?.split("=")[1];
99
+ const to = args.find((a) => a.startsWith("--to="))?.split("=")[1];
100
+ const params = new URLSearchParams();
101
+ if (from)
102
+ params.set("from", from);
103
+ if (to)
104
+ params.set("to", to);
105
+ const data = await apiCall(`/v1/workflows?${params}`, config);
106
+ if (data.workflows.length === 0) {
107
+ console.log("\n No workflow data found.\n");
108
+ return;
109
+ }
110
+ console.log("\n Workflows:\n");
111
+ printTable(["Workflow", "Traces", "Total $", "Avg $", "P50 $", "P95 $", "Errors"], data.workflows.map((w) => [
112
+ w.workflow,
113
+ String(w.traceCount),
114
+ formatUSD(w.totalCost),
115
+ formatUSD(w.avgCost),
116
+ formatUSD(w.p50Cost),
117
+ formatUSD(w.p95Cost),
118
+ String(w.errorCount),
119
+ ]), [25, 8, 12, 10, 10, 10, 7]);
120
+ console.log();
121
+ }
122
+ async function cmdCustomers(config, args) {
123
+ const from = args.find((a) => a.startsWith("--from="))?.split("=")[1];
124
+ const to = args.find((a) => a.startsWith("--to="))?.split("=")[1];
125
+ const params = new URLSearchParams();
126
+ if (from)
127
+ params.set("from", from);
128
+ if (to)
129
+ params.set("to", to);
130
+ const data = await apiCall(`/v1/customers?${params}`, config);
131
+ if (data.customers.length === 0) {
132
+ console.log("\n No customer data found.\n");
133
+ return;
134
+ }
135
+ console.log("\n Customer costs:\n");
136
+ printTable(["Customer", "Traces", "Total $", "Avg $/trace", "Workflows", "Errors"], data.customers.map((c) => [
137
+ c.customerId ?? "unknown",
138
+ String(c.traceCount),
139
+ formatUSD(c.totalCost),
140
+ formatUSD(c.avgCostPerTrace),
141
+ String(c.workflowCount),
142
+ String(c.errorCount),
143
+ ]), [20, 8, 12, 12, 10, 7]);
144
+ console.log();
145
+ }
146
+ function printHelp() {
147
+ console.log(`
148
+ agentmeter - Cost intelligence for AI agents
149
+
150
+ Usage:
151
+ npx agentmeter <command> [options]
152
+
153
+ Commands:
154
+ status Overview: total spend, top workflows, daily trend
155
+ workflows List all workflows with cost percentiles (p50/p95)
156
+ customers Cost breakdown per customer
157
+
158
+ Options:
159
+ --from=DATE Start date (default: 30 days ago)
160
+ --to=DATE End date (default: now)
161
+
162
+ Configuration (checked in order):
163
+ 1. AGENTMETER_API_KEY env var
164
+ 2. agentmeter.config.json in project root
165
+ 3. AGENTMETER_API_KEY in .env file
166
+
167
+ Examples:
168
+ npx agentmeter status
169
+ npx agentmeter workflows --from=2026-03-01
170
+ npx agentmeter customers --to=2026-03-22
171
+ `);
172
+ }
173
+ async function main() {
174
+ const args = process.argv.slice(2);
175
+ const command = args[0];
176
+ if (!command || command === "--help" || command === "-h") {
177
+ printHelp();
178
+ return;
179
+ }
180
+ const config = loadConfig();
181
+ if (!config.apiKey) {
182
+ console.error("\n Error: No API key found.");
183
+ console.error(" Set AGENTMETER_API_KEY in env, .env, or agentmeter.config.json\n");
184
+ process.exit(1);
185
+ }
186
+ try {
187
+ switch (command) {
188
+ case "status":
189
+ await cmdStatus(config, args);
190
+ break;
191
+ case "workflows":
192
+ await cmdWorkflows(config, args);
193
+ break;
194
+ case "customers":
195
+ await cmdCustomers(config, args);
196
+ break;
197
+ default:
198
+ console.error(`\n Unknown command: ${command}\n`);
199
+ printHelp();
200
+ process.exit(1);
201
+ }
202
+ }
203
+ catch (err) {
204
+ console.error(`\n Error: ${err instanceof Error ? err.message : err}\n`);
205
+ process.exit(1);
206
+ }
207
+ }
208
+ main();
209
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ import type { AgentMeterEvent } from "./types.js";
2
+ export declare class EventBuffer {
3
+ private _buffer;
4
+ private _flushTimer;
5
+ private _flushSize;
6
+ private _flushIntervalMs;
7
+ private _onFlush;
8
+ constructor(opts: {
9
+ flushSize: number;
10
+ flushIntervalMs: number;
11
+ onFlush: (events: AgentMeterEvent[]) => Promise<void>;
12
+ });
13
+ start(): void;
14
+ stop(): void;
15
+ push(event: AgentMeterEvent): void;
16
+ flush(): Promise<void>;
17
+ get pending(): number;
18
+ }
19
+ //# sourceMappingURL=event-buffer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"event-buffer.d.ts","sourceRoot":"","sources":["../src/event-buffer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAElD,qBAAa,WAAW;IACtB,OAAO,CAAC,OAAO,CAAyB;IACxC,OAAO,CAAC,WAAW,CAA+C;IAClE,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,gBAAgB,CAAS;IACjC,OAAO,CAAC,QAAQ,CAA+C;gBAEnD,IAAI,EAAE;QAChB,SAAS,EAAE,MAAM,CAAC;QAClB,eAAe,EAAE,MAAM,CAAC;QACxB,OAAO,EAAE,CAAC,MAAM,EAAE,eAAe,EAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;KACvD;IAMD,KAAK,IAAI,IAAI;IASb,IAAI,IAAI,IAAI;IAOZ,IAAI,CAAC,KAAK,EAAE,eAAe,GAAG,IAAI;IAO5B,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAW5B,IAAI,OAAO,IAAI,MAAM,CAEpB;CACF"}