@anvia/langfuse 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/LICENSE +21 -0
- package/README.md +77 -0
- package/dist/index.d.ts +32 -0
- package/dist/index.js +415 -0
- package/dist/index.js.map +1 -0
- package/package.json +37 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Indra Zulfi
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
# @anvia/langfuse
|
|
2
|
+
|
|
3
|
+
Langfuse tracing adapter for Anvia.
|
|
4
|
+
|
|
5
|
+
Use this package to attach Langfuse tracing to Anvia agents and to publish evaluation scores from Anvia eval reporters.
|
|
6
|
+
|
|
7
|
+
## Installation
|
|
8
|
+
|
|
9
|
+
```sh
|
|
10
|
+
pnpm add @anvia/langfuse @anvia/core
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
In this monorepo, the package is available through the workspace:
|
|
14
|
+
|
|
15
|
+
```sh
|
|
16
|
+
pnpm --filter @anvia/langfuse build
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Usage
|
|
20
|
+
|
|
21
|
+
```ts
|
|
22
|
+
import { AgentBuilder } from "@anvia/core";
|
|
23
|
+
import { OpenAIClient } from "@anvia/openai";
|
|
24
|
+
import { langfuse } from "@anvia/langfuse";
|
|
25
|
+
|
|
26
|
+
const tracing = langfuse.create({
|
|
27
|
+
publicKey,
|
|
28
|
+
secretKey,
|
|
29
|
+
baseUrl,
|
|
30
|
+
environment,
|
|
31
|
+
release,
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
const client = new OpenAIClient({
|
|
35
|
+
apiKey,
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
const agent = new AgentBuilder("support", client.completionModel())
|
|
39
|
+
.instructions("Answer support questions clearly.")
|
|
40
|
+
.observe(tracing)
|
|
41
|
+
.build();
|
|
42
|
+
|
|
43
|
+
const response = await agent.prompt("How do I reset my password?").send();
|
|
44
|
+
|
|
45
|
+
console.log(response.output);
|
|
46
|
+
|
|
47
|
+
await tracing.flush();
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
Use `flush()` after short-lived jobs. Use `shutdown()` when the process is exiting.
|
|
51
|
+
|
|
52
|
+
## Eval Scores
|
|
53
|
+
|
|
54
|
+
```ts
|
|
55
|
+
import { createLangfuseEvalReporter } from "@anvia/langfuse";
|
|
56
|
+
|
|
57
|
+
const reporter = createLangfuseEvalReporter(tracing);
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
The reporter reads trace information from eval output when available, then publishes metric scores to Langfuse.
|
|
61
|
+
|
|
62
|
+
## Exports
|
|
63
|
+
|
|
64
|
+
- `langfuse`
|
|
65
|
+
- `createLangfuseEvalReporter`
|
|
66
|
+
- `LangfuseTracing`
|
|
67
|
+
- `LangfuseTracingOptions`
|
|
68
|
+
- `LangfuseScoreArgs`
|
|
69
|
+
- `LangfuseEvalReporterOptions`
|
|
70
|
+
|
|
71
|
+
## Development
|
|
72
|
+
|
|
73
|
+
```sh
|
|
74
|
+
pnpm --filter @anvia/langfuse typecheck
|
|
75
|
+
pnpm --filter @anvia/langfuse test
|
|
76
|
+
pnpm --filter @anvia/langfuse build
|
|
77
|
+
```
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { JsonValue, AgentObserver, EvalReporter } from '@anvia/core';
|
|
2
|
+
|
|
3
|
+
type LangfuseTracingOptions = {
|
|
4
|
+
publicKey?: string | undefined;
|
|
5
|
+
secretKey?: string | undefined;
|
|
6
|
+
baseUrl?: string | undefined;
|
|
7
|
+
environment?: string | undefined;
|
|
8
|
+
release?: string | undefined;
|
|
9
|
+
};
|
|
10
|
+
type LangfuseScoreArgs = {
|
|
11
|
+
traceId?: string | undefined;
|
|
12
|
+
observationId?: string | undefined;
|
|
13
|
+
name: string;
|
|
14
|
+
value: number;
|
|
15
|
+
comment?: string | undefined;
|
|
16
|
+
metadata?: Record<string, JsonValue | undefined> | undefined;
|
|
17
|
+
};
|
|
18
|
+
type LangfuseTracing = AgentObserver & {
|
|
19
|
+
flush(): Promise<void>;
|
|
20
|
+
shutdown(): Promise<void>;
|
|
21
|
+
score(args: LangfuseScoreArgs): Promise<void>;
|
|
22
|
+
};
|
|
23
|
+
type LangfuseEvalReporterOptions = {
|
|
24
|
+
publishInvalid?: boolean | undefined;
|
|
25
|
+
strict?: boolean | undefined;
|
|
26
|
+
};
|
|
27
|
+
declare const langfuse: {
|
|
28
|
+
create(options?: LangfuseTracingOptions): LangfuseTracing;
|
|
29
|
+
};
|
|
30
|
+
declare function createLangfuseEvalReporter<Input = unknown, Output = unknown, Expected = unknown>(tracing: Pick<LangfuseTracing, "score">, options?: LangfuseEvalReporterOptions): EvalReporter<Input, Output, Expected>;
|
|
31
|
+
|
|
32
|
+
export { type LangfuseEvalReporterOptions, type LangfuseScoreArgs, type LangfuseTracing, type LangfuseTracingOptions, createLangfuseEvalReporter, langfuse };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,415 @@
|
|
|
1
|
+
// src/index.ts
|
|
2
|
+
import {
|
|
3
|
+
textFromAssistantContent
|
|
4
|
+
} from "@anvia/core";
|
|
5
|
+
import { LangfuseSpanProcessor } from "@langfuse/otel";
|
|
6
|
+
import {
|
|
7
|
+
LangfuseOtelSpanAttributes,
|
|
8
|
+
startObservation
|
|
9
|
+
} from "@langfuse/tracing";
|
|
10
|
+
import { NodeSDK } from "@opentelemetry/sdk-node";
|
|
11
|
+
var langfuse = {
|
|
12
|
+
create(options = {}) {
|
|
13
|
+
return new LangfuseAgentObserver(options);
|
|
14
|
+
}
|
|
15
|
+
};
|
|
16
|
+
function createLangfuseEvalReporter(tracing, options = {}) {
|
|
17
|
+
return {
|
|
18
|
+
async report(args) {
|
|
19
|
+
if (args.outcome.outcome === "invalid" && options.publishInvalid !== true) {
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
const trace = traceFromEvalReport(args);
|
|
23
|
+
if (trace?.traceId === void 0 || trace.traceId.length === 0) {
|
|
24
|
+
if (options.strict === true) {
|
|
25
|
+
throw new Error("Langfuse eval reporter requires traceId");
|
|
26
|
+
}
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
await tracing.score({
|
|
30
|
+
traceId: trace.traceId,
|
|
31
|
+
name: args.metric.name,
|
|
32
|
+
value: scoreValue(args.outcome),
|
|
33
|
+
metadata: {
|
|
34
|
+
suiteName: args.suiteName,
|
|
35
|
+
caseId: args.case.id,
|
|
36
|
+
outcome: args.outcome.outcome
|
|
37
|
+
},
|
|
38
|
+
...trace.observationId === void 0 ? {} : { observationId: trace.observationId },
|
|
39
|
+
...scoreComment(args.outcome) === void 0 ? {} : { comment: scoreComment(args.outcome) }
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
function scoreValue(outcome) {
|
|
45
|
+
if (outcome.outcome === "invalid") {
|
|
46
|
+
return 0;
|
|
47
|
+
}
|
|
48
|
+
if (typeof outcome.score === "number") {
|
|
49
|
+
return outcome.score;
|
|
50
|
+
}
|
|
51
|
+
if (typeof outcome.score === "boolean") {
|
|
52
|
+
return outcome.score ? 1 : 0;
|
|
53
|
+
}
|
|
54
|
+
if (typeof outcome.score === "object" && outcome.score !== null && "score" in outcome.score && typeof outcome.score.score === "number") {
|
|
55
|
+
return outcome.score.score;
|
|
56
|
+
}
|
|
57
|
+
return outcome.outcome === "pass" ? 1 : 0;
|
|
58
|
+
}
|
|
59
|
+
function scoreComment(outcome) {
|
|
60
|
+
return outcome.comment ?? (outcome.outcome === "invalid" ? outcome.reason : void 0);
|
|
61
|
+
}
|
|
62
|
+
function traceFromEvalReport(args) {
|
|
63
|
+
const outputTrace = traceFromOutput(args.output);
|
|
64
|
+
if (outputTrace !== void 0) {
|
|
65
|
+
return outputTrace;
|
|
66
|
+
}
|
|
67
|
+
const traceId = args.case.metadata?.traceId;
|
|
68
|
+
const observationId = args.case.metadata?.observationId;
|
|
69
|
+
if (typeof traceId !== "string") {
|
|
70
|
+
return void 0;
|
|
71
|
+
}
|
|
72
|
+
return {
|
|
73
|
+
traceId,
|
|
74
|
+
...typeof observationId === "string" ? { observationId } : {}
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
function traceFromOutput(output) {
|
|
78
|
+
if (typeof output !== "object" || output === null || !("trace" in output)) {
|
|
79
|
+
return void 0;
|
|
80
|
+
}
|
|
81
|
+
const trace = output.trace;
|
|
82
|
+
if (typeof trace !== "object" || trace === null) {
|
|
83
|
+
return void 0;
|
|
84
|
+
}
|
|
85
|
+
const traceId = trace.traceId;
|
|
86
|
+
const observationId = trace.observationId;
|
|
87
|
+
if (typeof traceId !== "string") {
|
|
88
|
+
return void 0;
|
|
89
|
+
}
|
|
90
|
+
return {
|
|
91
|
+
traceId,
|
|
92
|
+
...typeof observationId === "string" ? { observationId } : {}
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
var LangfuseAgentObserver = class {
|
|
96
|
+
processor;
|
|
97
|
+
sdk;
|
|
98
|
+
publicKey;
|
|
99
|
+
secretKey;
|
|
100
|
+
baseUrl;
|
|
101
|
+
constructor(options) {
|
|
102
|
+
this.publicKey = emptyToUndefined(options.publicKey);
|
|
103
|
+
this.secretKey = emptyToUndefined(options.secretKey);
|
|
104
|
+
this.baseUrl = emptyToUndefined(options.baseUrl) ?? "https://cloud.langfuse.com";
|
|
105
|
+
const processorOptions = {
|
|
106
|
+
baseUrl: this.baseUrl
|
|
107
|
+
};
|
|
108
|
+
if (this.publicKey !== void 0) processorOptions.publicKey = this.publicKey;
|
|
109
|
+
if (this.secretKey !== void 0) processorOptions.secretKey = this.secretKey;
|
|
110
|
+
const environment = emptyToUndefined(options.environment);
|
|
111
|
+
if (environment !== void 0) processorOptions.environment = environment;
|
|
112
|
+
const release = emptyToUndefined(options.release);
|
|
113
|
+
if (release !== void 0) processorOptions.release = release;
|
|
114
|
+
this.processor = new LangfuseSpanProcessor(processorOptions);
|
|
115
|
+
this.sdk = new NodeSDK({
|
|
116
|
+
spanProcessors: [this.processor]
|
|
117
|
+
});
|
|
118
|
+
this.sdk.start();
|
|
119
|
+
}
|
|
120
|
+
async startRun(args) {
|
|
121
|
+
const traceId = args.trace?.traceId;
|
|
122
|
+
const rootAttributes = {
|
|
123
|
+
input: {
|
|
124
|
+
prompt: args.prompt,
|
|
125
|
+
history: args.history
|
|
126
|
+
},
|
|
127
|
+
metadata: {
|
|
128
|
+
agentName: args.agentName,
|
|
129
|
+
agentDescription: args.agentDescription,
|
|
130
|
+
maxTurns: args.maxTurns,
|
|
131
|
+
...args.trace?.metadata ?? {}
|
|
132
|
+
}
|
|
133
|
+
};
|
|
134
|
+
if (args.trace?.version !== void 0) {
|
|
135
|
+
rootAttributes.version = args.trace.version;
|
|
136
|
+
}
|
|
137
|
+
const root = startObservation(
|
|
138
|
+
args.agentName ?? "agent.run",
|
|
139
|
+
rootAttributes,
|
|
140
|
+
traceId === void 0 ? { asType: "agent" } : {
|
|
141
|
+
asType: "agent",
|
|
142
|
+
parentSpanContext: {
|
|
143
|
+
traceId,
|
|
144
|
+
spanId: "0000000000000001",
|
|
145
|
+
traceFlags: 1
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
);
|
|
149
|
+
applyTraceAttributes(root, args);
|
|
150
|
+
return new LangfuseRunObserver(root, {
|
|
151
|
+
traceId: root.traceId,
|
|
152
|
+
observationId: root.id
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
async flush() {
|
|
156
|
+
await this.processor.forceFlush();
|
|
157
|
+
}
|
|
158
|
+
async shutdown() {
|
|
159
|
+
await this.sdk.shutdown();
|
|
160
|
+
}
|
|
161
|
+
async score(args) {
|
|
162
|
+
if (args.traceId === void 0 || args.traceId.length === 0) {
|
|
163
|
+
throw new Error("Langfuse score requires traceId");
|
|
164
|
+
}
|
|
165
|
+
if (this.publicKey === void 0 || this.secretKey === void 0) {
|
|
166
|
+
throw new Error("Langfuse score requires publicKey and secretKey");
|
|
167
|
+
}
|
|
168
|
+
const body = {
|
|
169
|
+
traceId: args.traceId,
|
|
170
|
+
name: args.name,
|
|
171
|
+
value: args.value
|
|
172
|
+
};
|
|
173
|
+
if (args.observationId !== void 0) body.observationId = args.observationId;
|
|
174
|
+
if (args.comment !== void 0) body.comment = args.comment;
|
|
175
|
+
if (args.metadata !== void 0) body.metadata = args.metadata;
|
|
176
|
+
const response = await fetch(`${this.baseUrl}/api/public/scores`, {
|
|
177
|
+
method: "POST",
|
|
178
|
+
headers: {
|
|
179
|
+
Authorization: `Basic ${Buffer.from(`${this.publicKey}:${this.secretKey}`).toString("base64")}`,
|
|
180
|
+
"Content-Type": "application/json"
|
|
181
|
+
},
|
|
182
|
+
body: JSON.stringify(body)
|
|
183
|
+
});
|
|
184
|
+
if (!response.ok) {
|
|
185
|
+
throw new Error(
|
|
186
|
+
`Langfuse score failed with HTTP ${response.status}: ${await response.text()}`
|
|
187
|
+
);
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
};
|
|
191
|
+
function applyTraceAttributes(root, args) {
|
|
192
|
+
const traceName = args.trace?.name ?? args.agentName;
|
|
193
|
+
if (traceName !== void 0) {
|
|
194
|
+
root.otelSpan.setAttribute(LangfuseOtelSpanAttributes.TRACE_NAME, traceName);
|
|
195
|
+
}
|
|
196
|
+
if (args.trace?.userId !== void 0) {
|
|
197
|
+
root.otelSpan.setAttribute(LangfuseOtelSpanAttributes.TRACE_USER_ID, args.trace.userId);
|
|
198
|
+
}
|
|
199
|
+
if (args.trace?.sessionId !== void 0) {
|
|
200
|
+
root.otelSpan.setAttribute(LangfuseOtelSpanAttributes.TRACE_SESSION_ID, args.trace.sessionId);
|
|
201
|
+
}
|
|
202
|
+
if (args.trace?.tags !== void 0) {
|
|
203
|
+
root.otelSpan.setAttribute(LangfuseOtelSpanAttributes.TRACE_TAGS, args.trace.tags);
|
|
204
|
+
}
|
|
205
|
+
for (const [key, value] of Object.entries(args.trace?.metadata ?? {})) {
|
|
206
|
+
const serialized = serializeMetadataValue(value);
|
|
207
|
+
if (serialized === void 0) {
|
|
208
|
+
continue;
|
|
209
|
+
}
|
|
210
|
+
root.otelSpan.setAttribute(`${LangfuseOtelSpanAttributes.TRACE_METADATA}.${key}`, serialized);
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
function serializeMetadataValue(value) {
|
|
214
|
+
if (value === void 0) {
|
|
215
|
+
return void 0;
|
|
216
|
+
}
|
|
217
|
+
if (typeof value === "string") {
|
|
218
|
+
return value;
|
|
219
|
+
}
|
|
220
|
+
try {
|
|
221
|
+
return JSON.stringify(value);
|
|
222
|
+
} catch {
|
|
223
|
+
return "<failed to serialize>";
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
var LangfuseRunObserver = class {
|
|
227
|
+
constructor(root, trace) {
|
|
228
|
+
this.root = root;
|
|
229
|
+
this.trace = trace;
|
|
230
|
+
}
|
|
231
|
+
root;
|
|
232
|
+
trace;
|
|
233
|
+
turnSpans = /* @__PURE__ */ new Map();
|
|
234
|
+
startGeneration(args) {
|
|
235
|
+
this.closeEarlierTurns(args.turn);
|
|
236
|
+
const turn = this.turnSpan(args.turn);
|
|
237
|
+
const generation = turn.startObservation(
|
|
238
|
+
`model.turn.${args.turn}`,
|
|
239
|
+
{
|
|
240
|
+
input: args.request.chatHistory,
|
|
241
|
+
model: args.request.model ?? "default",
|
|
242
|
+
modelParameters: modelParameters(args.request),
|
|
243
|
+
metadata: {
|
|
244
|
+
turn: args.turn,
|
|
245
|
+
toolCount: args.request.tools.length,
|
|
246
|
+
hasOutputSchema: args.request.outputSchema !== void 0
|
|
247
|
+
}
|
|
248
|
+
},
|
|
249
|
+
{ asType: "generation" }
|
|
250
|
+
);
|
|
251
|
+
return new LangfuseGenerationObserver(generation);
|
|
252
|
+
}
|
|
253
|
+
startTool(args) {
|
|
254
|
+
const turn = this.turnSpan(args.turn);
|
|
255
|
+
const tool = turn.startObservation(
|
|
256
|
+
`tool.${args.toolName}`,
|
|
257
|
+
{
|
|
258
|
+
input: {
|
|
259
|
+
args: args.args,
|
|
260
|
+
toolCall: args.toolCall
|
|
261
|
+
},
|
|
262
|
+
metadata: {
|
|
263
|
+
turn: args.turn,
|
|
264
|
+
internalCallId: args.internalCallId,
|
|
265
|
+
toolCallId: args.toolCallId
|
|
266
|
+
}
|
|
267
|
+
},
|
|
268
|
+
{ asType: "tool" }
|
|
269
|
+
);
|
|
270
|
+
return new LangfuseToolObserver(tool);
|
|
271
|
+
}
|
|
272
|
+
end(args) {
|
|
273
|
+
this.closeAllTurns();
|
|
274
|
+
this.root.update({
|
|
275
|
+
output: args.output,
|
|
276
|
+
metadata: {
|
|
277
|
+
usage: args.usage,
|
|
278
|
+
messages: args.messages
|
|
279
|
+
}
|
|
280
|
+
}).end();
|
|
281
|
+
}
|
|
282
|
+
error(args) {
|
|
283
|
+
this.closeAllTurns();
|
|
284
|
+
this.root.update({
|
|
285
|
+
level: "ERROR",
|
|
286
|
+
statusMessage: errorMessage(args.error),
|
|
287
|
+
output: {
|
|
288
|
+
error: errorMessage(args.error)
|
|
289
|
+
},
|
|
290
|
+
metadata: {
|
|
291
|
+
usage: args.usage,
|
|
292
|
+
messages: args.messages
|
|
293
|
+
}
|
|
294
|
+
}).end();
|
|
295
|
+
}
|
|
296
|
+
turnSpan(turn) {
|
|
297
|
+
const existing = this.turnSpans.get(turn);
|
|
298
|
+
if (existing !== void 0) {
|
|
299
|
+
return existing;
|
|
300
|
+
}
|
|
301
|
+
const span = this.root.startObservation(
|
|
302
|
+
`turn.${turn}`,
|
|
303
|
+
{
|
|
304
|
+
metadata: { turn }
|
|
305
|
+
},
|
|
306
|
+
{ asType: "span" }
|
|
307
|
+
);
|
|
308
|
+
this.turnSpans.set(turn, span);
|
|
309
|
+
return span;
|
|
310
|
+
}
|
|
311
|
+
closeEarlierTurns(currentTurn) {
|
|
312
|
+
for (const [turn, span] of this.turnSpans) {
|
|
313
|
+
if (turn < currentTurn) {
|
|
314
|
+
span.end();
|
|
315
|
+
this.turnSpans.delete(turn);
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
closeAllTurns() {
|
|
320
|
+
for (const span of this.turnSpans.values()) {
|
|
321
|
+
span.end();
|
|
322
|
+
}
|
|
323
|
+
this.turnSpans.clear();
|
|
324
|
+
}
|
|
325
|
+
};
|
|
326
|
+
var LangfuseGenerationObserver = class {
|
|
327
|
+
constructor(generation) {
|
|
328
|
+
this.generation = generation;
|
|
329
|
+
}
|
|
330
|
+
generation;
|
|
331
|
+
end(args) {
|
|
332
|
+
this.generation.update({
|
|
333
|
+
output: {
|
|
334
|
+
messageId: args.response.messageId,
|
|
335
|
+
content: args.response.choice,
|
|
336
|
+
text: textFromAssistantContent(args.response.choice)
|
|
337
|
+
},
|
|
338
|
+
usageDetails: usageDetails(args.response.usage),
|
|
339
|
+
metadata: {
|
|
340
|
+
turn: args.turn
|
|
341
|
+
}
|
|
342
|
+
}).end();
|
|
343
|
+
}
|
|
344
|
+
error(args) {
|
|
345
|
+
this.generation.update({
|
|
346
|
+
level: "ERROR",
|
|
347
|
+
statusMessage: errorMessage(args.error),
|
|
348
|
+
output: { error: errorMessage(args.error) },
|
|
349
|
+
metadata: { turn: args.turn }
|
|
350
|
+
}).end();
|
|
351
|
+
}
|
|
352
|
+
};
|
|
353
|
+
var LangfuseToolObserver = class {
|
|
354
|
+
constructor(tool) {
|
|
355
|
+
this.tool = tool;
|
|
356
|
+
}
|
|
357
|
+
tool;
|
|
358
|
+
end(args) {
|
|
359
|
+
const attributes = {
|
|
360
|
+
output: args.result,
|
|
361
|
+
metadata: {
|
|
362
|
+
turn: args.turn,
|
|
363
|
+
internalCallId: args.internalCallId,
|
|
364
|
+
toolCallId: args.toolCallId,
|
|
365
|
+
skipped: args.skipped
|
|
366
|
+
},
|
|
367
|
+
level: args.skipped ? "WARNING" : "DEFAULT"
|
|
368
|
+
};
|
|
369
|
+
if (args.skipped) {
|
|
370
|
+
attributes.statusMessage = "Tool call skipped by hook";
|
|
371
|
+
}
|
|
372
|
+
this.tool.update(attributes).end();
|
|
373
|
+
}
|
|
374
|
+
error(args) {
|
|
375
|
+
this.tool.update({
|
|
376
|
+
level: "ERROR",
|
|
377
|
+
statusMessage: errorMessage(args.error),
|
|
378
|
+
output: { error: errorMessage(args.error) },
|
|
379
|
+
metadata: {
|
|
380
|
+
turn: args.turn,
|
|
381
|
+
internalCallId: args.internalCallId,
|
|
382
|
+
toolCallId: args.toolCallId
|
|
383
|
+
}
|
|
384
|
+
}).end();
|
|
385
|
+
}
|
|
386
|
+
};
|
|
387
|
+
function modelParameters(request) {
|
|
388
|
+
const params = {};
|
|
389
|
+
if (request.temperature !== void 0) params.temperature = request.temperature;
|
|
390
|
+
if (request.maxTokens !== void 0) params.maxTokens = request.maxTokens;
|
|
391
|
+
if (request.toolChoice !== void 0) {
|
|
392
|
+
params.toolChoice = typeof request.toolChoice === "string" ? request.toolChoice : request.toolChoice.name;
|
|
393
|
+
}
|
|
394
|
+
return params;
|
|
395
|
+
}
|
|
396
|
+
function usageDetails(usage) {
|
|
397
|
+
return {
|
|
398
|
+
inputTokens: usage.inputTokens,
|
|
399
|
+
outputTokens: usage.outputTokens,
|
|
400
|
+
totalTokens: usage.totalTokens,
|
|
401
|
+
cachedInputTokens: usage.cachedInputTokens,
|
|
402
|
+
cacheCreationInputTokens: usage.cacheCreationInputTokens
|
|
403
|
+
};
|
|
404
|
+
}
|
|
405
|
+
function emptyToUndefined(value) {
|
|
406
|
+
return value === void 0 || value.length === 0 ? void 0 : value;
|
|
407
|
+
}
|
|
408
|
+
function errorMessage(error) {
|
|
409
|
+
return error instanceof Error ? error.message : String(error);
|
|
410
|
+
}
|
|
411
|
+
export {
|
|
412
|
+
createLangfuseEvalReporter,
|
|
413
|
+
langfuse
|
|
414
|
+
};
|
|
415
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["import {\n type AgentGenerationEndArgs,\n type AgentGenerationErrorArgs,\n type AgentGenerationObserver,\n type AgentGenerationStartArgs,\n type AgentObserver,\n type AgentRunEndArgs,\n type AgentRunErrorArgs,\n type AgentRunObserver,\n type AgentRunStartArgs,\n type AgentToolEndArgs,\n type AgentToolErrorArgs,\n type AgentToolObserver,\n type AgentToolStartArgs,\n type AgentTraceInfo,\n type EvalOutcome,\n type EvalReportArgs,\n type EvalReporter,\n type JsonValue,\n textFromAssistantContent,\n} from \"@anvia/core\";\nimport { LangfuseSpanProcessor } from \"@langfuse/otel\";\nimport {\n type LangfuseAgent,\n type LangfuseGeneration,\n LangfuseOtelSpanAttributes,\n type LangfuseSpan,\n type LangfuseTool,\n startObservation,\n} from \"@langfuse/tracing\";\nimport { NodeSDK } from \"@opentelemetry/sdk-node\";\n\nexport type LangfuseTracingOptions = {\n publicKey?: string | undefined;\n secretKey?: string | undefined;\n baseUrl?: string | undefined;\n environment?: string | undefined;\n release?: string | undefined;\n};\n\nexport type LangfuseScoreArgs = {\n traceId?: string | undefined;\n observationId?: string | undefined;\n name: string;\n value: number;\n comment?: string | undefined;\n metadata?: Record<string, JsonValue | undefined> | undefined;\n};\n\nexport type LangfuseTracing = AgentObserver & {\n flush(): Promise<void>;\n shutdown(): Promise<void>;\n score(args: LangfuseScoreArgs): Promise<void>;\n};\n\nexport type LangfuseEvalReporterOptions = {\n publishInvalid?: boolean | undefined;\n strict?: boolean | undefined;\n};\n\nexport const langfuse = {\n create(options: LangfuseTracingOptions = {}): LangfuseTracing {\n return new LangfuseAgentObserver(options);\n },\n};\n\nexport function createLangfuseEvalReporter<Input = unknown, Output = unknown, Expected = unknown>(\n tracing: Pick<LangfuseTracing, \"score\">,\n options: LangfuseEvalReporterOptions = {},\n): EvalReporter<Input, Output, Expected> {\n return {\n async report(args) {\n if (args.outcome.outcome === \"invalid\" && options.publishInvalid !== true) {\n return;\n }\n\n const trace = traceFromEvalReport(args);\n if (trace?.traceId === undefined || trace.traceId.length === 0) {\n if (options.strict === true) {\n throw new Error(\"Langfuse eval reporter requires traceId\");\n }\n return;\n }\n\n await tracing.score({\n traceId: trace.traceId,\n name: args.metric.name,\n value: scoreValue(args.outcome),\n metadata: {\n suiteName: args.suiteName,\n caseId: args.case.id,\n outcome: args.outcome.outcome,\n },\n ...(trace.observationId === undefined ? {} : { observationId: trace.observationId }),\n ...(scoreComment(args.outcome) === undefined\n ? {}\n : { comment: scoreComment(args.outcome) as string }),\n });\n },\n };\n}\n\nfunction scoreValue(outcome: EvalOutcome): number {\n if (outcome.outcome === \"invalid\") {\n return 0;\n }\n if (typeof outcome.score === \"number\") {\n return outcome.score;\n }\n if (typeof outcome.score === \"boolean\") {\n return outcome.score ? 1 : 0;\n }\n if (\n typeof outcome.score === \"object\" &&\n outcome.score !== null &&\n \"score\" in outcome.score &&\n typeof (outcome.score as { score?: unknown }).score === \"number\"\n ) {\n return (outcome.score as { score: number }).score;\n }\n return outcome.outcome === \"pass\" ? 1 : 0;\n}\n\nfunction scoreComment(outcome: EvalOutcome): string | undefined {\n return outcome.comment ?? (outcome.outcome === \"invalid\" ? outcome.reason : undefined);\n}\n\nfunction traceFromEvalReport<Input, Output, Expected>(\n args: EvalReportArgs<Input, Output, unknown, Expected>,\n): AgentTraceInfo | undefined {\n const outputTrace = traceFromOutput(args.output);\n if (outputTrace !== undefined) {\n return outputTrace;\n }\n const traceId = args.case.metadata?.traceId;\n const observationId = args.case.metadata?.observationId;\n if (typeof traceId !== \"string\") {\n return undefined;\n }\n return {\n traceId,\n ...(typeof observationId === \"string\" ? { observationId } : {}),\n };\n}\n\nfunction traceFromOutput(output: unknown): AgentTraceInfo | undefined {\n if (typeof output !== \"object\" || output === null || !(\"trace\" in output)) {\n return undefined;\n }\n const trace = (output as { trace?: unknown }).trace;\n if (typeof trace !== \"object\" || trace === null) {\n return undefined;\n }\n const traceId = (trace as { traceId?: unknown }).traceId;\n const observationId = (trace as { observationId?: unknown }).observationId;\n if (typeof traceId !== \"string\") {\n return undefined;\n }\n return {\n traceId,\n ...(typeof observationId === \"string\" ? { observationId } : {}),\n };\n}\n\nclass LangfuseAgentObserver implements LangfuseTracing {\n private readonly processor: LangfuseSpanProcessor;\n private readonly sdk: NodeSDK;\n private readonly publicKey: string | undefined;\n private readonly secretKey: string | undefined;\n private readonly baseUrl: string;\n\n constructor(options: LangfuseTracingOptions) {\n this.publicKey = emptyToUndefined(options.publicKey);\n this.secretKey = emptyToUndefined(options.secretKey);\n this.baseUrl = emptyToUndefined(options.baseUrl) ?? \"https://cloud.langfuse.com\";\n const processorOptions: ConstructorParameters<typeof LangfuseSpanProcessor>[0] = {\n baseUrl: this.baseUrl,\n };\n if (this.publicKey !== undefined) processorOptions.publicKey = this.publicKey;\n if (this.secretKey !== undefined) processorOptions.secretKey = this.secretKey;\n const environment = emptyToUndefined(options.environment);\n if (environment !== undefined) processorOptions.environment = environment;\n const release = emptyToUndefined(options.release);\n if (release !== undefined) processorOptions.release = release;\n this.processor = new LangfuseSpanProcessor(processorOptions);\n this.sdk = new NodeSDK({\n spanProcessors: [this.processor],\n });\n this.sdk.start();\n }\n\n async startRun(args: AgentRunStartArgs): Promise<AgentRunObserver> {\n const traceId = args.trace?.traceId;\n const rootAttributes: Parameters<typeof startObservation>[1] = {\n input: {\n prompt: args.prompt,\n history: args.history,\n },\n metadata: {\n agentName: args.agentName,\n agentDescription: args.agentDescription,\n maxTurns: args.maxTurns,\n ...(args.trace?.metadata ?? {}),\n },\n };\n if (args.trace?.version !== undefined) {\n rootAttributes.version = args.trace.version;\n }\n\n const root = startObservation(\n args.agentName ?? \"agent.run\",\n rootAttributes,\n traceId === undefined\n ? { asType: \"agent\" }\n : {\n asType: \"agent\",\n parentSpanContext: {\n traceId,\n spanId: \"0000000000000001\",\n traceFlags: 1,\n },\n },\n );\n applyTraceAttributes(root, args);\n\n return new LangfuseRunObserver(root, {\n traceId: root.traceId,\n observationId: root.id,\n });\n }\n\n async flush(): Promise<void> {\n await this.processor.forceFlush();\n }\n\n async shutdown(): Promise<void> {\n await this.sdk.shutdown();\n }\n\n async score(args: LangfuseScoreArgs): Promise<void> {\n if (args.traceId === undefined || args.traceId.length === 0) {\n throw new Error(\"Langfuse score requires traceId\");\n }\n if (this.publicKey === undefined || this.secretKey === undefined) {\n throw new Error(\"Langfuse score requires publicKey and secretKey\");\n }\n\n const body: Record<string, unknown> = {\n traceId: args.traceId,\n name: args.name,\n value: args.value,\n };\n if (args.observationId !== undefined) body.observationId = args.observationId;\n if (args.comment !== undefined) body.comment = args.comment;\n if (args.metadata !== undefined) body.metadata = args.metadata;\n\n const response = await fetch(`${this.baseUrl}/api/public/scores`, {\n method: \"POST\",\n headers: {\n Authorization: `Basic ${Buffer.from(`${this.publicKey}:${this.secretKey}`).toString(\"base64\")}`,\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify(body),\n });\n if (!response.ok) {\n throw new Error(\n `Langfuse score failed with HTTP ${response.status}: ${await response.text()}`,\n );\n }\n }\n}\n\nfunction applyTraceAttributes(root: LangfuseAgent, args: AgentRunStartArgs): void {\n const traceName = args.trace?.name ?? args.agentName;\n if (traceName !== undefined) {\n root.otelSpan.setAttribute(LangfuseOtelSpanAttributes.TRACE_NAME, traceName);\n }\n if (args.trace?.userId !== undefined) {\n root.otelSpan.setAttribute(LangfuseOtelSpanAttributes.TRACE_USER_ID, args.trace.userId);\n }\n if (args.trace?.sessionId !== undefined) {\n root.otelSpan.setAttribute(LangfuseOtelSpanAttributes.TRACE_SESSION_ID, args.trace.sessionId);\n }\n if (args.trace?.tags !== undefined) {\n root.otelSpan.setAttribute(LangfuseOtelSpanAttributes.TRACE_TAGS, args.trace.tags);\n }\n for (const [key, value] of Object.entries(args.trace?.metadata ?? {})) {\n const serialized = serializeMetadataValue(value);\n if (serialized === undefined) {\n continue;\n }\n root.otelSpan.setAttribute(`${LangfuseOtelSpanAttributes.TRACE_METADATA}.${key}`, serialized);\n }\n}\n\nfunction serializeMetadataValue(value: unknown): string | undefined {\n if (value === undefined) {\n return undefined;\n }\n if (typeof value === \"string\") {\n return value;\n }\n try {\n return JSON.stringify(value);\n } catch {\n return \"<failed to serialize>\";\n }\n}\n\nclass LangfuseRunObserver implements AgentRunObserver {\n private readonly turnSpans = new Map<number, LangfuseSpan>();\n\n constructor(\n private readonly root: LangfuseAgent,\n readonly trace: AgentTraceInfo,\n ) {}\n\n startGeneration(args: AgentGenerationStartArgs): AgentGenerationObserver {\n this.closeEarlierTurns(args.turn);\n const turn = this.turnSpan(args.turn);\n const generation = turn.startObservation(\n `model.turn.${args.turn}`,\n {\n input: args.request.chatHistory,\n model: args.request.model ?? \"default\",\n modelParameters: modelParameters(args.request),\n metadata: {\n turn: args.turn,\n toolCount: args.request.tools.length,\n hasOutputSchema: args.request.outputSchema !== undefined,\n },\n },\n { asType: \"generation\" },\n );\n return new LangfuseGenerationObserver(generation);\n }\n\n startTool(args: AgentToolStartArgs): AgentToolObserver {\n const turn = this.turnSpan(args.turn);\n const tool = turn.startObservation(\n `tool.${args.toolName}`,\n {\n input: {\n args: args.args,\n toolCall: args.toolCall,\n },\n metadata: {\n turn: args.turn,\n internalCallId: args.internalCallId,\n toolCallId: args.toolCallId,\n },\n },\n { asType: \"tool\" },\n );\n return new LangfuseToolObserver(tool);\n }\n\n end(args: AgentRunEndArgs): void {\n this.closeAllTurns();\n this.root\n .update({\n output: args.output,\n metadata: {\n usage: args.usage,\n messages: args.messages,\n },\n })\n .end();\n }\n\n error(args: AgentRunErrorArgs): void {\n this.closeAllTurns();\n this.root\n .update({\n level: \"ERROR\",\n statusMessage: errorMessage(args.error),\n output: {\n error: errorMessage(args.error),\n },\n metadata: {\n usage: args.usage,\n messages: args.messages,\n },\n })\n .end();\n }\n\n private turnSpan(turn: number): LangfuseSpan {\n const existing = this.turnSpans.get(turn);\n if (existing !== undefined) {\n return existing;\n }\n\n const span = this.root.startObservation(\n `turn.${turn}`,\n {\n metadata: { turn },\n },\n { asType: \"span\" },\n );\n this.turnSpans.set(turn, span);\n return span;\n }\n\n private closeEarlierTurns(currentTurn: number): void {\n for (const [turn, span] of this.turnSpans) {\n if (turn < currentTurn) {\n span.end();\n this.turnSpans.delete(turn);\n }\n }\n }\n\n private closeAllTurns(): void {\n for (const span of this.turnSpans.values()) {\n span.end();\n }\n this.turnSpans.clear();\n }\n}\n\nclass LangfuseGenerationObserver implements AgentGenerationObserver {\n constructor(private readonly generation: LangfuseGeneration) {}\n\n end(args: AgentGenerationEndArgs): void {\n this.generation\n .update({\n output: {\n messageId: args.response.messageId,\n content: args.response.choice,\n text: textFromAssistantContent(args.response.choice),\n },\n usageDetails: usageDetails(args.response.usage),\n metadata: {\n turn: args.turn,\n },\n })\n .end();\n }\n\n error(args: AgentGenerationErrorArgs): void {\n this.generation\n .update({\n level: \"ERROR\",\n statusMessage: errorMessage(args.error),\n output: { error: errorMessage(args.error) },\n metadata: { turn: args.turn },\n })\n .end();\n }\n}\n\nclass LangfuseToolObserver implements AgentToolObserver {\n constructor(private readonly tool: LangfuseTool) {}\n\n end(args: AgentToolEndArgs): void {\n const attributes: Parameters<LangfuseTool[\"update\"]>[0] = {\n output: args.result,\n metadata: {\n turn: args.turn,\n internalCallId: args.internalCallId,\n toolCallId: args.toolCallId,\n skipped: args.skipped,\n },\n level: args.skipped ? \"WARNING\" : \"DEFAULT\",\n };\n if (args.skipped) {\n attributes.statusMessage = \"Tool call skipped by hook\";\n }\n this.tool.update(attributes).end();\n }\n\n error(args: AgentToolErrorArgs): void {\n this.tool\n .update({\n level: \"ERROR\",\n statusMessage: errorMessage(args.error),\n output: { error: errorMessage(args.error) },\n metadata: {\n turn: args.turn,\n internalCallId: args.internalCallId,\n toolCallId: args.toolCallId,\n },\n })\n .end();\n }\n}\n\nfunction modelParameters(\n request: AgentGenerationStartArgs[\"request\"],\n): Record<string, string | number> {\n const params: Record<string, string | number> = {};\n if (request.temperature !== undefined) params.temperature = request.temperature;\n if (request.maxTokens !== undefined) params.maxTokens = request.maxTokens;\n if (request.toolChoice !== undefined) {\n params.toolChoice =\n typeof request.toolChoice === \"string\" ? request.toolChoice : request.toolChoice.name;\n }\n return params;\n}\n\nfunction usageDetails(usage: AgentGenerationEndArgs[\"response\"][\"usage\"]): Record<string, number> {\n return {\n inputTokens: usage.inputTokens,\n outputTokens: usage.outputTokens,\n totalTokens: usage.totalTokens,\n cachedInputTokens: usage.cachedInputTokens,\n cacheCreationInputTokens: usage.cacheCreationInputTokens,\n };\n}\n\nfunction emptyToUndefined(value: string | undefined): string | undefined {\n return value === undefined || value.length === 0 ? undefined : value;\n}\n\nfunction errorMessage(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n"],"mappings":"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","names":[]}
|
package/package.json
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@anvia/langfuse",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Langfuse tracing adapter for Anvia.",
|
|
5
|
+
"author": "anvia",
|
|
6
|
+
"maintainer": "Indra Zulfi",
|
|
7
|
+
"license": "MIT",
|
|
8
|
+
"files": [
|
|
9
|
+
"dist"
|
|
10
|
+
],
|
|
11
|
+
"type": "module",
|
|
12
|
+
"main": "./dist/index.js",
|
|
13
|
+
"types": "./dist/index.d.ts",
|
|
14
|
+
"exports": {
|
|
15
|
+
".": {
|
|
16
|
+
"types": "./dist/index.d.ts",
|
|
17
|
+
"import": "./dist/index.js"
|
|
18
|
+
}
|
|
19
|
+
},
|
|
20
|
+
"dependencies": {
|
|
21
|
+
"@langfuse/otel": "^5.2.0",
|
|
22
|
+
"@langfuse/tracing": "^5.2.0",
|
|
23
|
+
"@opentelemetry/sdk-node": "^0.216.0",
|
|
24
|
+
"@anvia/core": "0.1.0"
|
|
25
|
+
},
|
|
26
|
+
"devDependencies": {
|
|
27
|
+
"@types/node": "^24.9.1",
|
|
28
|
+
"tsup": "^8.5.0",
|
|
29
|
+
"typescript": "^5.9.3",
|
|
30
|
+
"vitest": "^4.0.8"
|
|
31
|
+
},
|
|
32
|
+
"scripts": {
|
|
33
|
+
"build": "tsup src/index.ts --format esm --dts --sourcemap --clean",
|
|
34
|
+
"test": "vitest run",
|
|
35
|
+
"typecheck": "tsc --noEmit"
|
|
36
|
+
}
|
|
37
|
+
}
|