lightrace 0.1.10 → 0.1.13
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
CHANGED
|
@@ -1,11 +1,27 @@
|
|
|
1
|
-
|
|
1
|
+
<p align="center">
|
|
2
|
+
<img src="https://raw.githubusercontent.com/SKE-Labs/lightrace/main/packages/frontend/public/white_transparent.png" alt="LightRace" width="280" />
|
|
3
|
+
</p>
|
|
2
4
|
|
|
3
|
-
|
|
5
|
+
<h1 align="center">lightrace-js</h1>
|
|
6
|
+
|
|
7
|
+
<p align="center">
|
|
8
|
+
<a href="https://www.npmjs.com/package/lightrace"><img src="https://img.shields.io/npm/v/lightrace?style=flat-square&color=ff1a1a" alt="npm version" /></a>
|
|
9
|
+
<a href="https://github.com/SKE-Labs/lightrace-js/stargazers"><img src="https://img.shields.io/github/stars/SKE-Labs/lightrace-js?style=flat-square" alt="GitHub stars" /></a>
|
|
10
|
+
<a href="https://github.com/SKE-Labs/lightrace-js/blob/main/LICENSE"><img src="https://img.shields.io/github/license/SKE-Labs/lightrace-js?style=flat-square" alt="License" /></a>
|
|
11
|
+
</p>
|
|
12
|
+
|
|
13
|
+
<p align="center">Lightweight LLM tracing SDK for TypeScript/JavaScript with remote tool invocation.</p>
|
|
14
|
+
|
|
15
|
+
---
|
|
4
16
|
|
|
5
17
|
## Install
|
|
6
18
|
|
|
7
19
|
```bash
|
|
20
|
+
npm install lightrace
|
|
21
|
+
# or
|
|
8
22
|
yarn add lightrace
|
|
23
|
+
# or
|
|
24
|
+
pnpm add lightrace
|
|
9
25
|
```
|
|
10
26
|
|
|
11
27
|
## Quick Start
|
|
@@ -74,10 +90,122 @@ trace(name, options, fn);
|
|
|
74
90
|
| `inputSchema` | `ZodType` | `undefined` | Optional Zod schema for tool input |
|
|
75
91
|
| `metadata` | `Record` | `undefined` | Static metadata attached to every call |
|
|
76
92
|
|
|
93
|
+
## Integrations
|
|
94
|
+
|
|
95
|
+
### Anthropic
|
|
96
|
+
|
|
97
|
+
```typescript
|
|
98
|
+
import Anthropic from "@anthropic-ai/sdk";
|
|
99
|
+
import { Lightrace, trace } from "lightrace";
|
|
100
|
+
import { LightraceAnthropicInstrumentor } from "lightrace/integrations/anthropic";
|
|
101
|
+
|
|
102
|
+
const lt = new Lightrace({ publicKey: "pk-lt-demo", secretKey: "sk-lt-demo" });
|
|
103
|
+
|
|
104
|
+
const anthropic = new Anthropic();
|
|
105
|
+
const instrumentor = new LightraceAnthropicInstrumentor({ client: lt });
|
|
106
|
+
instrumentor.instrument(anthropic);
|
|
107
|
+
|
|
108
|
+
const response = await anthropic.messages.create({
|
|
109
|
+
model: "claude-sonnet-4-20250514",
|
|
110
|
+
max_tokens: 256,
|
|
111
|
+
messages: [{ role: "user", content: "What is the capital of Mongolia?" }],
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
lt.flush();
|
|
115
|
+
await lt.shutdown();
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
### OpenAI
|
|
119
|
+
|
|
120
|
+
```typescript
|
|
121
|
+
import OpenAI from "openai";
|
|
122
|
+
import { Lightrace, trace } from "lightrace";
|
|
123
|
+
import { LightraceOpenAIInstrumentor } from "lightrace/integrations/openai";
|
|
124
|
+
|
|
125
|
+
const lt = new Lightrace({ publicKey: "pk-lt-demo", secretKey: "sk-lt-demo" });
|
|
126
|
+
|
|
127
|
+
const openai = new OpenAI();
|
|
128
|
+
const instrumentor = new LightraceOpenAIInstrumentor({ client: lt });
|
|
129
|
+
instrumentor.instrument(openai);
|
|
130
|
+
|
|
131
|
+
const response = await openai.chat.completions.create({
|
|
132
|
+
model: "gpt-4o-mini",
|
|
133
|
+
max_tokens: 256,
|
|
134
|
+
messages: [{ role: "user", content: "What is the speed of light?" }],
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
lt.flush();
|
|
138
|
+
await lt.shutdown();
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
### LangChain
|
|
142
|
+
|
|
143
|
+
```typescript
|
|
144
|
+
import { ChatOpenAI } from "@langchain/openai";
|
|
145
|
+
import { Lightrace } from "lightrace";
|
|
146
|
+
import { LightraceCallbackHandler } from "lightrace/integrations/langchain";
|
|
147
|
+
|
|
148
|
+
const lt = new Lightrace({ publicKey: "pk-lt-demo", secretKey: "sk-lt-demo" });
|
|
149
|
+
|
|
150
|
+
const handler = new LightraceCallbackHandler({ client: lt });
|
|
151
|
+
const model = new ChatOpenAI({ model: "gpt-4o-mini", maxTokens: 256 });
|
|
152
|
+
|
|
153
|
+
const response = await model.invoke("What is the speed of light?", {
|
|
154
|
+
callbacks: [handler],
|
|
155
|
+
});
|
|
156
|
+
|
|
157
|
+
lt.flush();
|
|
158
|
+
await lt.shutdown();
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
### Claude Agent SDK
|
|
162
|
+
|
|
163
|
+
```typescript
|
|
164
|
+
import { Lightrace } from "lightrace";
|
|
165
|
+
import { tracedQuery } from "lightrace/integrations/claude-agent-sdk";
|
|
166
|
+
|
|
167
|
+
const lt = new Lightrace({ publicKey: "pk-lt-demo", secretKey: "sk-lt-demo" });
|
|
168
|
+
|
|
169
|
+
for await (const message of tracedQuery({
|
|
170
|
+
prompt: "What files are in the current directory?",
|
|
171
|
+
options: { maxTurns: 3 },
|
|
172
|
+
client: lt,
|
|
173
|
+
traceName: "file-lister",
|
|
174
|
+
})) {
|
|
175
|
+
if (message.type === "result") {
|
|
176
|
+
const r = message as Record<string, unknown>;
|
|
177
|
+
console.log(r.result);
|
|
178
|
+
console.log(`Cost: $${r.total_cost_usd}`);
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
lt.flush();
|
|
183
|
+
await lt.shutdown();
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
You can also use the handler directly for more control:
|
|
187
|
+
|
|
188
|
+
```typescript
|
|
189
|
+
import { query } from "@anthropic-ai/claude-agent-sdk";
|
|
190
|
+
import { LightraceAgentHandler } from "lightrace/integrations/claude-agent-sdk";
|
|
191
|
+
|
|
192
|
+
const handler = new LightraceAgentHandler({ prompt: "Hello", client: lt, traceName: "my-agent" });
|
|
193
|
+
|
|
194
|
+
for await (const message of query({ prompt: "Hello" })) {
|
|
195
|
+
handler.handle(message);
|
|
196
|
+
}
|
|
197
|
+
```
|
|
198
|
+
|
|
77
199
|
## Compatibility
|
|
78
200
|
|
|
79
201
|
Lightrace server also accepts traces from Langfuse Python/JS SDKs.
|
|
80
202
|
|
|
203
|
+
## Related
|
|
204
|
+
|
|
205
|
+
- [Lightrace](https://github.com/SKE-Labs/lightrace) — the main platform (backend + frontend)
|
|
206
|
+
- [Lightrace CLI](https://github.com/SKE-Labs/lightrace-cli) — self-host with a single command
|
|
207
|
+
- [lightrace-python](https://github.com/SKE-Labs/lightrace-python) — Python SDK
|
|
208
|
+
|
|
81
209
|
## Development
|
|
82
210
|
|
|
83
211
|
```bash
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Claude Agent SDK integration for Lightrace.
|
|
3
|
+
*
|
|
4
|
+
* Wraps the `query()` async iterator from `@anthropic-ai/claude-agent-sdk`
|
|
5
|
+
* to emit OTel spans for each generation, tool call, and the overall agent run.
|
|
6
|
+
*
|
|
7
|
+
* @example Wrapper (recommended)
|
|
8
|
+
* ```ts
|
|
9
|
+
* import { Lightrace } from "lightrace";
|
|
10
|
+
* import { tracedQuery } from "lightrace/integrations/claude-agent-sdk";
|
|
11
|
+
*
|
|
12
|
+
* const lt = new Lightrace({ publicKey: "pk-lt-demo", secretKey: "sk-lt-demo" });
|
|
13
|
+
*
|
|
14
|
+
* for await (const message of tracedQuery({
|
|
15
|
+
* prompt: "What files are in the current directory?",
|
|
16
|
+
* client: lt,
|
|
17
|
+
* traceName: "file-lister",
|
|
18
|
+
* })) {
|
|
19
|
+
* if (message.type === "result") console.log(message.result);
|
|
20
|
+
* }
|
|
21
|
+
* ```
|
|
22
|
+
*
|
|
23
|
+
* @example Manual handler
|
|
24
|
+
* ```ts
|
|
25
|
+
* import { query } from "@anthropic-ai/claude-agent-sdk";
|
|
26
|
+
* import { LightraceAgentHandler } from "lightrace/integrations/claude-agent-sdk";
|
|
27
|
+
*
|
|
28
|
+
* const handler = new LightraceAgentHandler({ client: lt });
|
|
29
|
+
*
|
|
30
|
+
* for await (const message of query({ prompt: "Hello" })) {
|
|
31
|
+
* handler.handle(message);
|
|
32
|
+
* }
|
|
33
|
+
* ```
|
|
34
|
+
*/
|
|
35
|
+
import { TracingMixin, type TracingMixinOptions } from "./_base.js";
|
|
36
|
+
/** Minimal message shape — avoids hard dependency on @anthropic-ai/claude-agent-sdk. */
|
|
37
|
+
interface SDKMessageLike {
|
|
38
|
+
type: string;
|
|
39
|
+
[key: string]: unknown;
|
|
40
|
+
}
|
|
41
|
+
export interface LightraceAgentHandlerOptions extends TracingMixinOptions {
|
|
42
|
+
/** The prompt sent to the agent (captured as root trace input). */
|
|
43
|
+
prompt?: string;
|
|
44
|
+
}
|
|
45
|
+
export interface TracedQueryOptions extends TracingMixinOptions {
|
|
46
|
+
/** The prompt to send to the agent. */
|
|
47
|
+
prompt: string;
|
|
48
|
+
/** `ClaudeAgentOptions` to pass through to `query()`. */
|
|
49
|
+
options?: unknown;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Processes Claude Agent SDK messages to create Lightrace traces.
|
|
53
|
+
*
|
|
54
|
+
* Call {@link handle} for each message yielded by `query()`. The handler
|
|
55
|
+
* automatically creates a root agent span, child generation spans for each
|
|
56
|
+
* `AssistantMessage`, and child tool spans for each tool call.
|
|
57
|
+
*/
|
|
58
|
+
export declare class LightraceAgentHandler extends TracingMixin {
|
|
59
|
+
private prompt;
|
|
60
|
+
private agentRunId;
|
|
61
|
+
private toolRunIds;
|
|
62
|
+
private turnCount;
|
|
63
|
+
constructor(opts?: LightraceAgentHandlerOptions);
|
|
64
|
+
/** Process a single message from the agent SDK stream. */
|
|
65
|
+
handle(message: SDKMessageLike): void;
|
|
66
|
+
private onSystem;
|
|
67
|
+
private onAssistant;
|
|
68
|
+
private onUser;
|
|
69
|
+
private onResult;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Drop-in wrapper around `query()` that adds Lightrace tracing.
|
|
73
|
+
*
|
|
74
|
+
* Messages are yielded through unchanged. Requires `@anthropic-ai/claude-agent-sdk`
|
|
75
|
+
* to be installed.
|
|
76
|
+
*/
|
|
77
|
+
export declare function tracedQuery(opts: TracedQueryOptions): AsyncGenerator<SDKMessageLike, void>;
|
|
78
|
+
export {};
|
|
79
|
+
//# sourceMappingURL=claude-agent-sdk.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"claude-agent-sdk.d.ts","sourceRoot":"","sources":["../../src/integrations/claude-agent-sdk.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AAGH,OAAO,EAAE,YAAY,EAAkB,KAAK,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAIpF,wFAAwF;AACxF,UAAU,cAAc;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,4BAA6B,SAAQ,mBAAmB;IACvE,mEAAmE;IACnE,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,kBAAmB,SAAQ,mBAAmB;IAC7D,uCAAuC;IACvC,MAAM,EAAE,MAAM,CAAC;IACf,yDAAyD;IACzD,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAID;;;;;;GAMG;AACH,qBAAa,qBAAsB,SAAQ,YAAY;IACrD,OAAO,CAAC,MAAM,CAAqB;IACnC,OAAO,CAAC,UAAU,CAAuB;IACzC,OAAO,CAAC,UAAU,CAA6B;IAC/C,OAAO,CAAC,SAAS,CAAK;gBAEV,IAAI,CAAC,EAAE,4BAA4B;IAO/C,0DAA0D;IAC1D,MAAM,CAAC,OAAO,EAAE,cAAc,GAAG,IAAI;IAuBrC,OAAO,CAAC,QAAQ;IAOhB,OAAO,CAAC,WAAW;IAuEnB,OAAO,CAAC,MAAM;IAgCd,OAAO,CAAC,QAAQ;CAgCjB;AAID;;;;;GAKG;AACH,wBAAuB,WAAW,CAAC,IAAI,EAAE,kBAAkB,GAAG,cAAc,CAAC,cAAc,EAAE,IAAI,CAAC,CA4BjG"}
|
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Claude Agent SDK integration for Lightrace.
|
|
3
|
+
*
|
|
4
|
+
* Wraps the `query()` async iterator from `@anthropic-ai/claude-agent-sdk`
|
|
5
|
+
* to emit OTel spans for each generation, tool call, and the overall agent run.
|
|
6
|
+
*
|
|
7
|
+
* @example Wrapper (recommended)
|
|
8
|
+
* ```ts
|
|
9
|
+
* import { Lightrace } from "lightrace";
|
|
10
|
+
* import { tracedQuery } from "lightrace/integrations/claude-agent-sdk";
|
|
11
|
+
*
|
|
12
|
+
* const lt = new Lightrace({ publicKey: "pk-lt-demo", secretKey: "sk-lt-demo" });
|
|
13
|
+
*
|
|
14
|
+
* for await (const message of tracedQuery({
|
|
15
|
+
* prompt: "What files are in the current directory?",
|
|
16
|
+
* client: lt,
|
|
17
|
+
* traceName: "file-lister",
|
|
18
|
+
* })) {
|
|
19
|
+
* if (message.type === "result") console.log(message.result);
|
|
20
|
+
* }
|
|
21
|
+
* ```
|
|
22
|
+
*
|
|
23
|
+
* @example Manual handler
|
|
24
|
+
* ```ts
|
|
25
|
+
* import { query } from "@anthropic-ai/claude-agent-sdk";
|
|
26
|
+
* import { LightraceAgentHandler } from "lightrace/integrations/claude-agent-sdk";
|
|
27
|
+
*
|
|
28
|
+
* const handler = new LightraceAgentHandler({ client: lt });
|
|
29
|
+
*
|
|
30
|
+
* for await (const message of query({ prompt: "Hello" })) {
|
|
31
|
+
* handler.handle(message);
|
|
32
|
+
* }
|
|
33
|
+
* ```
|
|
34
|
+
*/
|
|
35
|
+
import { generateId, jsonSerializable } from "../utils.js";
|
|
36
|
+
import { TracingMixin, normalizeUsage } from "./_base.js";
|
|
37
|
+
// ── Handler ────────────────────────────────────────────────────────────────
|
|
38
|
+
/**
|
|
39
|
+
* Processes Claude Agent SDK messages to create Lightrace traces.
|
|
40
|
+
*
|
|
41
|
+
* Call {@link handle} for each message yielded by `query()`. The handler
|
|
42
|
+
* automatically creates a root agent span, child generation spans for each
|
|
43
|
+
* `AssistantMessage`, and child tool spans for each tool call.
|
|
44
|
+
*/
|
|
45
|
+
export class LightraceAgentHandler extends TracingMixin {
|
|
46
|
+
prompt;
|
|
47
|
+
agentRunId = null;
|
|
48
|
+
toolRunIds = new Map(); // tool_use_id → runId
|
|
49
|
+
turnCount = 0;
|
|
50
|
+
constructor(opts) {
|
|
51
|
+
super(opts);
|
|
52
|
+
this.prompt = opts?.prompt;
|
|
53
|
+
}
|
|
54
|
+
// ── Public API ─────────────────────────────────────────────────────
|
|
55
|
+
/** Process a single message from the agent SDK stream. */
|
|
56
|
+
handle(message) {
|
|
57
|
+
try {
|
|
58
|
+
switch (message.type) {
|
|
59
|
+
case "assistant":
|
|
60
|
+
this.onAssistant(message);
|
|
61
|
+
break;
|
|
62
|
+
case "user":
|
|
63
|
+
this.onUser(message);
|
|
64
|
+
break;
|
|
65
|
+
case "result":
|
|
66
|
+
this.onResult(message);
|
|
67
|
+
break;
|
|
68
|
+
case "system":
|
|
69
|
+
this.onSystem(message);
|
|
70
|
+
break;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
catch {
|
|
74
|
+
// Tracing errors should never break the agent loop
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
// ── Message handlers ───────────────────────────────────────────────
|
|
78
|
+
onSystem(msg) {
|
|
79
|
+
// Capture model from init message for the root span name
|
|
80
|
+
if (msg.subtype === "init" && !this.agentRunId) {
|
|
81
|
+
// We'll use the model info when the first assistant message arrives
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
onAssistant(msg) {
|
|
85
|
+
// Start root agent span on first assistant message
|
|
86
|
+
if (this.agentRunId === null) {
|
|
87
|
+
this.agentRunId = generateId();
|
|
88
|
+
this.registerRun(this.agentRunId, undefined, {
|
|
89
|
+
type: "span",
|
|
90
|
+
name: this.traceName ?? "claude-agent",
|
|
91
|
+
startTime: new Date(),
|
|
92
|
+
input: this.prompt,
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
this.turnCount++;
|
|
96
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
97
|
+
const raw = msg;
|
|
98
|
+
const betaMessage = raw.message;
|
|
99
|
+
const model = raw.model ?? betaMessage?.model;
|
|
100
|
+
const usage = betaMessage?.usage;
|
|
101
|
+
// Create a generation span for this turn
|
|
102
|
+
const genRunId = generateId();
|
|
103
|
+
this.registerRun(genRunId, this.agentRunId, {
|
|
104
|
+
type: "generation",
|
|
105
|
+
name: model ?? "claude",
|
|
106
|
+
startTime: new Date(),
|
|
107
|
+
input: undefined,
|
|
108
|
+
model,
|
|
109
|
+
});
|
|
110
|
+
// Extract content blocks
|
|
111
|
+
const content = betaMessage?.content ?? raw.content ?? [];
|
|
112
|
+
const outputBlocks = [];
|
|
113
|
+
for (const block of content) {
|
|
114
|
+
const b = block;
|
|
115
|
+
const blockType = b.type;
|
|
116
|
+
if (blockType === "text") {
|
|
117
|
+
outputBlocks.push({ type: "text", text: b.text ?? "" });
|
|
118
|
+
}
|
|
119
|
+
else if (blockType === "tool_use") {
|
|
120
|
+
const toolId = b.id;
|
|
121
|
+
const toolName = b.name;
|
|
122
|
+
const toolInput = b.input;
|
|
123
|
+
outputBlocks.push({
|
|
124
|
+
type: "tool_use",
|
|
125
|
+
id: toolId,
|
|
126
|
+
name: toolName,
|
|
127
|
+
input: jsonSerializable(toolInput),
|
|
128
|
+
});
|
|
129
|
+
// Start a tool span (ended when matching user message arrives)
|
|
130
|
+
const toolRunId = generateId();
|
|
131
|
+
this.toolRunIds.set(toolId, toolRunId);
|
|
132
|
+
this.registerRun(toolRunId, this.agentRunId, {
|
|
133
|
+
type: "tool",
|
|
134
|
+
name: toolName,
|
|
135
|
+
startTime: new Date(),
|
|
136
|
+
input: toolInput,
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
else {
|
|
140
|
+
outputBlocks.push(jsonSerializable(b));
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
// End the generation span (the LLM call itself is complete)
|
|
144
|
+
const normalizedUsage = usage ? normalizeUsage(usage) : null;
|
|
145
|
+
this.endRun(genRunId, outputBlocks, "DEFAULT", null, normalizedUsage ?? undefined);
|
|
146
|
+
}
|
|
147
|
+
onUser(msg) {
|
|
148
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
149
|
+
const raw = msg;
|
|
150
|
+
const userMessage = raw.message;
|
|
151
|
+
// User messages contain tool results as content blocks
|
|
152
|
+
const content = Array.isArray(userMessage?.content)
|
|
153
|
+
? userMessage.content
|
|
154
|
+
: Array.isArray(raw.content)
|
|
155
|
+
? raw.content
|
|
156
|
+
: [];
|
|
157
|
+
for (const block of content) {
|
|
158
|
+
const b = block;
|
|
159
|
+
if (b.type === "tool_result" && typeof b.tool_use_id === "string") {
|
|
160
|
+
const toolUseId = b.tool_use_id;
|
|
161
|
+
const toolRunId = this.toolRunIds.get(toolUseId);
|
|
162
|
+
if (toolRunId) {
|
|
163
|
+
this.toolRunIds.delete(toolUseId);
|
|
164
|
+
const isError = Boolean(b.is_error);
|
|
165
|
+
const output = b.content;
|
|
166
|
+
if (isError) {
|
|
167
|
+
this.endRun(toolRunId, jsonSerializable(output), "ERROR", String(output));
|
|
168
|
+
}
|
|
169
|
+
else {
|
|
170
|
+
this.endRun(toolRunId, jsonSerializable(output));
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
onResult(msg) {
|
|
177
|
+
// End any remaining tool spans
|
|
178
|
+
for (const [, toolRunId] of this.toolRunIds) {
|
|
179
|
+
this.endRun(toolRunId, null);
|
|
180
|
+
}
|
|
181
|
+
this.toolRunIds.clear();
|
|
182
|
+
if (this.agentRunId === null)
|
|
183
|
+
return;
|
|
184
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
185
|
+
const raw = msg;
|
|
186
|
+
const output = {};
|
|
187
|
+
if (raw.result !== undefined)
|
|
188
|
+
output.result = raw.result;
|
|
189
|
+
if (raw.num_turns !== undefined)
|
|
190
|
+
output.num_turns = raw.num_turns;
|
|
191
|
+
if (raw.total_cost_usd !== undefined)
|
|
192
|
+
output.total_cost_usd = raw.total_cost_usd;
|
|
193
|
+
if (raw.duration_ms !== undefined)
|
|
194
|
+
output.duration_ms = raw.duration_ms;
|
|
195
|
+
if (raw.subtype !== undefined)
|
|
196
|
+
output.subtype = raw.subtype;
|
|
197
|
+
const usage = raw.usage ? normalizeUsage(raw.usage) : null;
|
|
198
|
+
const isError = Boolean(raw.is_error);
|
|
199
|
+
if (isError) {
|
|
200
|
+
const errorMsg = raw.result ?? raw.subtype ?? "Agent error";
|
|
201
|
+
this.endRun(this.agentRunId, output, "ERROR", String(errorMsg), usage ?? undefined);
|
|
202
|
+
}
|
|
203
|
+
else {
|
|
204
|
+
this.endRun(this.agentRunId, output, "DEFAULT", null, usage ?? undefined);
|
|
205
|
+
}
|
|
206
|
+
this.agentRunId = null;
|
|
207
|
+
this.turnCount = 0;
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
// ── Wrapper ────────────────────────────────────────────────────────────────
|
|
211
|
+
/**
|
|
212
|
+
* Drop-in wrapper around `query()` that adds Lightrace tracing.
|
|
213
|
+
*
|
|
214
|
+
* Messages are yielded through unchanged. Requires `@anthropic-ai/claude-agent-sdk`
|
|
215
|
+
* to be installed.
|
|
216
|
+
*/
|
|
217
|
+
export async function* tracedQuery(opts) {
|
|
218
|
+
// Dynamic import to avoid hard dependency
|
|
219
|
+
let queryFn;
|
|
220
|
+
try {
|
|
221
|
+
// Use a variable to prevent TypeScript from resolving the optional peer dep
|
|
222
|
+
const modName = "@anthropic-ai/claude-agent-sdk";
|
|
223
|
+
const mod = await import(/* webpackIgnore: true */ modName);
|
|
224
|
+
queryFn = mod.query;
|
|
225
|
+
}
|
|
226
|
+
catch {
|
|
227
|
+
throw new Error("@anthropic-ai/claude-agent-sdk is required for this integration. " +
|
|
228
|
+
"Install it with: npm install @anthropic-ai/claude-agent-sdk");
|
|
229
|
+
}
|
|
230
|
+
const handler = new LightraceAgentHandler({
|
|
231
|
+
prompt: opts.prompt,
|
|
232
|
+
client: opts.client,
|
|
233
|
+
userId: opts.userId,
|
|
234
|
+
sessionId: opts.sessionId,
|
|
235
|
+
traceName: opts.traceName,
|
|
236
|
+
metadata: opts.metadata,
|
|
237
|
+
});
|
|
238
|
+
for await (const message of queryFn({ prompt: opts.prompt, options: opts.options })) {
|
|
239
|
+
handler.handle(message);
|
|
240
|
+
yield message;
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
//# sourceMappingURL=claude-agent-sdk.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"claude-agent-sdk.js","sourceRoot":"","sources":["../../src/integrations/claude-agent-sdk.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "lightrace",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.13",
|
|
4
4
|
"description": "Agentic development kit — LLM tracing, tool management, and agent primitives",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -25,6 +25,10 @@
|
|
|
25
25
|
"./integrations/llamaindex": {
|
|
26
26
|
"import": "./dist/integrations/llamaindex.js",
|
|
27
27
|
"types": "./dist/integrations/llamaindex.d.ts"
|
|
28
|
+
},
|
|
29
|
+
"./integrations/claude-agent-sdk": {
|
|
30
|
+
"import": "./dist/integrations/claude-agent-sdk.js",
|
|
31
|
+
"types": "./dist/integrations/claude-agent-sdk.d.ts"
|
|
28
32
|
}
|
|
29
33
|
},
|
|
30
34
|
"files": [
|
|
@@ -69,6 +73,7 @@
|
|
|
69
73
|
"@anthropic-ai/sdk": ">=0.30.0",
|
|
70
74
|
"openai": ">=4.0.0",
|
|
71
75
|
"llamaindex": ">=0.5.0",
|
|
76
|
+
"@anthropic-ai/claude-agent-sdk": ">=0.1.0",
|
|
72
77
|
"zod": "^3.0.0"
|
|
73
78
|
},
|
|
74
79
|
"peerDependenciesMeta": {
|
|
@@ -86,6 +91,9 @@
|
|
|
86
91
|
},
|
|
87
92
|
"llamaindex": {
|
|
88
93
|
"optional": true
|
|
94
|
+
},
|
|
95
|
+
"@anthropic-ai/claude-agent-sdk": {
|
|
96
|
+
"optional": true
|
|
89
97
|
}
|
|
90
98
|
},
|
|
91
99
|
"lint-staged": {
|