llmtap 0.1.0 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/README.md +292 -0
  2. package/package.json +4 -4
package/README.md ADDED
@@ -0,0 +1,292 @@
1
+ <p align="center">
2
+ <h1 align="center">LLMTap</h1>
3
+ </p>
4
+
5
+ <h3 align="center">DevTools for AI Agents</h3>
6
+
7
+ <p align="center">
8
+ See every LLM call. Trace agent workflows. Track costs.<br/>
9
+ Local-first. Zero-config. Two lines of code.
10
+ </p>
11
+
12
+ <p align="center">
13
+ <a href="#quick-start">Quick Start</a> &middot;
14
+ <a href="#features">Features</a> &middot;
15
+ <a href="#supported-providers">Providers</a> &middot;
16
+ <a href="#api-reference">API</a> &middot;
17
+ <a href="#architecture">Architecture</a>
18
+ </p>
19
+
20
+ ---
21
+
22
+ Most LLM observability tools require cloud accounts, proxy configurations, or framework-specific callbacks. LLMTap takes a different approach: it runs entirely on your machine, instruments any LLM client with a single function call, and gives you a real-time dashboard at `localhost`.
23
+
24
+ No sign-ups. No API keys to manage the tool itself. Your prompts and responses never leave your machine.
25
+
26
+ <!-- hero-screenshot -->
27
+
28
+ ---
29
+
30
+ ## Quick Start
31
+
32
+ **1. Start LLMTap**
33
+
34
+ ```bash
35
+ npx llmtap
36
+ ```
37
+
38
+ The collector starts on `http://localhost:4781` and opens the dashboard.
39
+
40
+ **2. Instrument your code**
41
+
42
+ ```typescript
43
+ import OpenAI from "openai";
44
+ import { wrap } from "@llmtap/sdk";
45
+
46
+ const client = wrap(new OpenAI());
47
+ ```
48
+
49
+ **3. Use your client as normal**
50
+
51
+ ```typescript
52
+ const res = await client.chat.completions.create({
53
+ model: "gpt-4o",
54
+ messages: [{ role: "user", content: "Hello, world" }],
55
+ });
56
+ // Traced automatically -- tokens, cost, latency, full request/response
57
+ ```
58
+
59
+ Open `http://localhost:4781`. Traces appear in real time.
60
+
61
+ ---
62
+
63
+ ## Features
64
+
65
+ **Transparent instrumentation** -- `wrap()` returns an ES Proxy. Your client behaves identically. No code changes beyond the wrap call. Streaming, tool calls, and multi-turn conversations all work.
66
+
67
+ **Real-time dashboard** -- Traces stream to the browser via SSE. See every LLM call as it happens with token counts, costs, latency, and full message content.
68
+
69
+ <!-- dashboard-screenshot -->
70
+
71
+ **Cost tracking** -- Built-in pricing for 50+ models across all major providers. Input and output costs calculated per-call. Override pricing for custom or fine-tuned models at runtime.
72
+
73
+ **Trace grouping** -- Group multiple LLM calls into a single trace with `startTrace()`. See total cost and token usage for multi-step agent pipelines.
74
+
75
+ ```typescript
76
+ import { wrap, startTrace } from "@llmtap/sdk";
77
+
78
+ await startTrace("research-agent", async () => {
79
+ const plan = await client.chat.completions.create({ model: "gpt-4o", messages: [...] });
80
+ const draft = await client.chat.completions.create({ model: "gpt-4o-mini", messages: [...] });
81
+ });
82
+ // Both calls grouped under "research-agent" in the dashboard
83
+ ```
84
+
85
+ **Streaming support** -- Full support for streaming responses across all providers. Token counts and costs are captured after the stream completes. Your application sees the exact same stream.
86
+
87
+ **OpenTelemetry export** -- Export traces in OTLP format following GenAI Semantic Conventions. Forward to Datadog, Grafana, Jaeger, or any OTLP-compatible backend.
88
+
89
+ ```bash
90
+ OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4318 npx llmtap
91
+ ```
92
+
93
+ **Privacy by default** -- Everything runs locally. No data is sent anywhere unless you explicitly configure OTLP forwarding. Content capture can be disabled entirely.
94
+
95
+ ---
96
+
97
+ ## Supported Providers
98
+
99
+ LLMTap works with any provider that uses the OpenAI, Anthropic, or Google Gemini SDK format.
100
+
101
+ | Provider | SDK | Detection |
102
+ |----------|-----|-----------|
103
+ | **OpenAI** | `openai` | Automatic |
104
+ | **Anthropic** | `@anthropic-ai/sdk` | Automatic |
105
+ | **Google Gemini** | `@google/generative-ai` | Automatic |
106
+ | **DeepSeek** | `openai` (compatible) | Auto via base URL |
107
+ | **Groq** | `openai` (compatible) | Auto via base URL |
108
+ | **Together** | `openai` (compatible) | Auto via base URL |
109
+ | **Fireworks** | `openai` (compatible) | Auto via base URL |
110
+ | **OpenRouter** | `openai` (compatible) | Auto via base URL |
111
+ | **xAI (Grok)** | `openai` (compatible) | Auto via base URL |
112
+ | **Ollama** | `openai` (compatible) | Auto via base URL |
113
+ | **Vercel AI SDK** | `ai` | Via `wrapVercelAI()` |
114
+ | **Any OpenAI-compatible** | `openai` | Manual or auto |
115
+
116
+ ```typescript
117
+ // OpenAI
118
+ const openai = wrap(new OpenAI());
119
+
120
+ // Anthropic
121
+ import Anthropic from "@anthropic-ai/sdk";
122
+ const claude = wrap(new Anthropic());
123
+
124
+ // Google Gemini
125
+ import { GoogleGenerativeAI } from "@google/generative-ai";
126
+ const gemini = wrap(new GoogleGenerativeAI(process.env.GOOGLE_API_KEY));
127
+
128
+ // DeepSeek, Groq, or any OpenAI-compatible provider
129
+ const deepseek = wrap(new OpenAI({
130
+ baseURL: "https://api.deepseek.com",
131
+ apiKey: process.env.DEEPSEEK_API_KEY,
132
+ }));
133
+ ```
134
+
135
+ ---
136
+
137
+ ## API Reference
138
+
139
+ ### `wrap(client, options?)`
140
+
141
+ Wraps an LLM client to trace all API calls. Returns a proxy -- the client works identically.
142
+
143
+ ```typescript
144
+ const client = wrap(new OpenAI());
145
+ const client = wrap(new OpenAI(), { provider: "deepseek", tags: { env: "staging" } });
146
+ ```
147
+
148
+ | Option | Type | Description |
149
+ |--------|------|-------------|
150
+ | `provider` | `string` | Override auto-detected provider name |
151
+ | `tags` | `Record<string, string>` | Custom tags attached to every span |
152
+
153
+ ### `startTrace(name, fn, options?)`
154
+
155
+ Groups multiple LLM calls under a single trace.
156
+
157
+ ```typescript
158
+ const result = await startTrace("my-pipeline", async () => {
159
+ const step1 = await client.chat.completions.create({ ... });
160
+ const step2 = await client.chat.completions.create({ ... });
161
+ return step2;
162
+ }, { sessionId: "user-123", tags: { workflow: "summarize" } });
163
+ ```
164
+
165
+ | Option | Type | Description |
166
+ |--------|------|-------------|
167
+ | `sessionId` | `string` | Group traces into a session |
168
+ | `tags` | `Record<string, string>` | Custom tags on the trace |
169
+
170
+ ### `init(config)`
171
+
172
+ Configure the SDK globally. All options can also be set via environment variables.
173
+
174
+ ```typescript
175
+ import { init } from "@llmtap/sdk";
176
+
177
+ init({
178
+ collectorUrl: "http://localhost:4781",
179
+ captureContent: true,
180
+ enabled: true,
181
+ debug: false,
182
+ sessionId: "my-session",
183
+ onError: (err, ctx) => console.warn("LLMTap:", err.message),
184
+ });
185
+ ```
186
+
187
+ | Config | Env Var | Default | Description |
188
+ |--------|---------|---------|-------------|
189
+ | `collectorUrl` | `LLMTAP_COLLECTOR_URL` | `http://localhost:4781` | Collector endpoint |
190
+ | `captureContent` | `LLMTAP_CAPTURE_CONTENT` | `true` | Capture message content |
191
+ | `enabled` | `LLMTAP_ENABLED` | `true` | Enable/disable tracing |
192
+ | `debug` | `LLMTAP_DEBUG` | `false` | Debug logging |
193
+ | `sessionId` | `LLMTAP_SESSION_ID` | -- | Session grouping |
194
+
195
+ ### `wrapVercelAI(ai)`
196
+
197
+ Wraps the Vercel AI SDK for framework-level tracing across any underlying provider.
198
+
199
+ ### `shutdown()`
200
+
201
+ Flushes all buffered spans and shuts down the SDK. Call before process exit in serverless environments.
202
+
203
+ ```typescript
204
+ import { shutdown } from "@llmtap/sdk";
205
+ await shutdown();
206
+ ```
207
+
208
+ ---
209
+
210
+ ## Architecture
211
+
212
+ ```
213
+ Your Application
214
+ |
215
+ | wrap(client) -- ES Proxy intercepts LLM calls
216
+ |
217
+ v
218
+ @llmtap/sdk ───────────> @llmtap/collector ───────────> @llmtap/dashboard
219
+ Proxy-based Fastify + SQLite React + Vite
220
+ instrumentation REST API + SSE Real-time UI
221
+ | |
222
+ | Batched HTTP POST | SSE push on new spans Connects via SSE
223
+ | to /v1/spans | GET /v1/traces, /v1/stats and REST API
224
+ v v
225
+ ┌─────────────┐
226
+ │ SQLite DB │ Optional: OTLP export to
227
+ │ (WAL mode) │ ───> Datadog, Grafana, Jaeger
228
+ └─────────────┘
229
+ ```
230
+
231
+ | Package | Description |
232
+ |---------|-------------|
233
+ | `llmtap` | CLI entry point -- `npx llmtap` starts collector + dashboard |
234
+ | `@llmtap/sdk` | ES Proxy-based instrumentation for LLM clients |
235
+ | `@llmtap/collector` | Fastify server, SQLite storage, SSE, REST API |
236
+ | `@llmtap/dashboard` | React + Vite + Tailwind SPA with real-time updates |
237
+ | `@llmtap/shared` | Types, constants, pricing data, OTLP converter |
238
+
239
+ ---
240
+
241
+ ## CLI
242
+
243
+ ```bash
244
+ npx llmtap # Start collector + dashboard
245
+ npx llmtap --demo # Start with sample data
246
+ npx llmtap --port 8080 # Custom port
247
+ npx llmtap --retention 7d # Auto-delete old data
248
+ npx llmtap --host 0.0.0.0 # Expose to network
249
+ ```
250
+
251
+ ---
252
+
253
+ ## Comparison
254
+
255
+ | | LLMTap | LangSmith | Helicone | Langfuse |
256
+ |---|---|---|---|---|
257
+ | **Setup** | `npx` + 2 lines | SDK + cloud account | Proxy + cloud | SDK + self-host or cloud |
258
+ | **Data location** | Your machine | Their cloud | Their cloud | Your infra or theirs |
259
+ | **Pricing** | Free, no limits | $39/seat/mo | $79/mo | Free (self-host) |
260
+ | **Instrumentation** | `wrap(client)` | Framework-specific | Proxy gateway | SDK callbacks |
261
+
262
+ LLMTap is a developer tool -- fast to start, private by default, zero friction. Use it during development and prototyping. When you need production infrastructure, export your traces via OTLP to the platform of your choice.
263
+
264
+ ---
265
+
266
+ ## Development
267
+
268
+ ```bash
269
+ git clone https://github.com/DivyaanshuXD/LLMTap.git
270
+ cd llmtap
271
+ pnpm install
272
+ pnpm build # Build all packages
273
+ pnpm test # Run all tests (Vitest)
274
+ ```
275
+
276
+ TypeScript monorepo with pnpm workspaces and Turborepo. Packages build with tsup, the dashboard builds with Vite.
277
+
278
+ ## Contributing
279
+
280
+ Contributions are welcome.
281
+
282
+ 1. Fork the repository
283
+ 2. Create a feature branch: `git checkout -b feature/my-feature`
284
+ 3. Make your changes and add tests
285
+ 4. Run `pnpm build && pnpm test` to verify
286
+ 5. Open a pull request
287
+
288
+ Please open an issue first for large changes so we can discuss the approach.
289
+
290
+ ## License
291
+
292
+ MIT
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "llmtap",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "DevTools for AI Agents - See every LLM call, trace agent workflows, track costs",
5
5
  "type": "module",
6
6
  "bin": {
@@ -13,8 +13,8 @@
13
13
  "chalk": "^5.4.0",
14
14
  "commander": "^13.0.0",
15
15
  "open": "^10.1.0",
16
- "@llmtap/collector": "0.1.0",
17
- "@llmtap/shared": "0.1.0"
16
+ "@llmtap/collector": "0.1.1",
17
+ "@llmtap/shared": "0.1.1"
18
18
  },
19
19
  "devDependencies": {
20
20
  "@types/node": "^25.4.0",
@@ -38,7 +38,7 @@
38
38
  "license": "MIT",
39
39
  "repository": {
40
40
  "type": "git",
41
- "url": "https://github.com/llmtap/llmtap",
41
+ "url": "https://github.com/DivyaanshuXD/LLMTap",
42
42
  "directory": "packages/cli"
43
43
  },
44
44
  "scripts": {