tuplet 2.36.0 → 2.38.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 +1 -1
- package/dist/executor.d.ts.map +1 -1
- package/dist/executor.js +7 -3
- package/dist/executor.js.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/providers/llm/fallback.d.ts +55 -0
- package/dist/providers/llm/fallback.d.ts.map +1 -0
- package/dist/providers/llm/fallback.js +123 -0
- package/dist/providers/llm/fallback.js.map +1 -0
- package/dist/providers/llm/fallback.test.d.ts +2 -0
- package/dist/providers/llm/fallback.test.d.ts.map +1 -0
- package/dist/providers/llm/fallback.test.js +175 -0
- package/dist/providers/llm/fallback.test.js.map +1 -0
- package/dist/tools/ask-user.d.ts.map +1 -1
- package/dist/tools/ask-user.js +20 -1
- package/dist/tools/ask-user.js.map +1 -1
- package/dist/trace/index.d.ts +3 -0
- package/dist/trace/index.d.ts.map +1 -1
- package/dist/trace/index.js +3 -0
- package/dist/trace/index.js.map +1 -1
- package/dist/trace/langfuse.d.ts +96 -0
- package/dist/trace/langfuse.d.ts.map +1 -0
- package/dist/trace/langfuse.js +317 -0
- package/dist/trace/langfuse.js.map +1 -0
- package/dist/trace/multi.d.ts +42 -0
- package/dist/trace/multi.d.ts.map +1 -0
- package/dist/trace/multi.js +71 -0
- package/dist/trace/multi.js.map +1 -0
- package/dist/trace/multi.test.d.ts +2 -0
- package/dist/trace/multi.test.d.ts.map +1 -0
- package/dist/trace/multi.test.js +167 -0
- package/dist/trace/multi.test.js.map +1 -0
- package/dist/types.d.ts +16 -6
- package/dist/types.d.ts.map +1 -1
- package/dist/workspace.d.ts.map +1 -1
- package/dist/workspace.js.map +1 -1
- package/package.json +1 -1
package/dist/tools/ask-user.js
CHANGED
|
@@ -21,7 +21,26 @@ Example: ${toolName}({ "questions": [{"question": "What is your goal?", "header"
|
|
|
21
21
|
properties: {
|
|
22
22
|
questions: {
|
|
23
23
|
type: "array",
|
|
24
|
-
description: "Array of 1-4 questions. Each item has: question (string, required), header (short label, optional), options (array of
|
|
24
|
+
description: "Array of 1-4 questions. Each item has: question (string, required), header (short label, optional), options (array of strings, optional).",
|
|
25
|
+
items: {
|
|
26
|
+
type: "object",
|
|
27
|
+
properties: {
|
|
28
|
+
question: {
|
|
29
|
+
type: "string",
|
|
30
|
+
description: "The complete question to ask the user.",
|
|
31
|
+
},
|
|
32
|
+
header: {
|
|
33
|
+
type: "string",
|
|
34
|
+
description: "Short label (max 12 chars), e.g. 'Goal', 'Budget'.",
|
|
35
|
+
},
|
|
36
|
+
options: {
|
|
37
|
+
type: "array",
|
|
38
|
+
description: "Suggested answers shown as quick-pick chips.",
|
|
39
|
+
items: { type: "string" },
|
|
40
|
+
},
|
|
41
|
+
},
|
|
42
|
+
required: ["question"],
|
|
43
|
+
},
|
|
25
44
|
},
|
|
26
45
|
},
|
|
27
46
|
required: ["questions"],
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ask-user.js","sourceRoot":"","sources":["../../src/tools/ask-user.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH;;GAEG;AACH,MAAM,UAAU,iBAAiB;IAC/B,MAAM,QAAQ,GAAG,cAAc,CAAC;IAChC,OAAO;QACL,IAAI,EAAE,QAAQ;QACd,WAAW,EAAE;;;;WAIN,QAAQ;CAClB;QACG,UAAU,EAAE;YACV,IAAI,EAAE,QAAQ;YACd,UAAU,EAAE;gBACV,SAAS,EAAE;oBACT,IAAI,EAAE,OAAO;oBACb,WAAW,EACT,
|
|
1
|
+
{"version":3,"file":"ask-user.js","sourceRoot":"","sources":["../../src/tools/ask-user.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH;;GAEG;AACH,MAAM,UAAU,iBAAiB;IAC/B,MAAM,QAAQ,GAAG,cAAc,CAAC;IAChC,OAAO;QACL,IAAI,EAAE,QAAQ;QACd,WAAW,EAAE;;;;WAIN,QAAQ;CAClB;QACG,UAAU,EAAE;YACV,IAAI,EAAE,QAAQ;YACd,UAAU,EAAE;gBACV,SAAS,EAAE;oBACT,IAAI,EAAE,OAAO;oBACb,WAAW,EACT,2IAA2I;oBAC7I,KAAK,EAAE;wBACL,IAAI,EAAE,QAAQ;wBACd,UAAU,EAAE;4BACV,QAAQ,EAAE;gCACR,IAAI,EAAE,QAAQ;gCACd,WAAW,EAAE,wCAAwC;6BACtD;4BACD,MAAM,EAAE;gCACN,IAAI,EAAE,QAAQ;gCACd,WAAW,EAAE,oDAAoD;6BAClE;4BACD,OAAO,EAAE;gCACP,IAAI,EAAE,OAAO;gCACb,WAAW,EAAE,8CAA8C;gCAC3D,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;6BAC1B;yBACF;wBACD,QAAQ,EAAE,CAAC,UAAU,CAAC;qBACvB;iBACF;aACF;YACD,QAAQ,EAAE,CAAC,WAAW,CAAC;SACxB;QACD,OAAO,EAAE,KAAK,IAAI,EAAE;YAClB,iDAAiD;YACjD,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,uBAAuB,EAAE,CAAC;QAC1D,CAAC;KACF,CAAC;AACJ,CAAC"}
|
package/dist/trace/index.d.ts
CHANGED
|
@@ -8,4 +8,7 @@ export { OPENROUTER_MODEL_PRICING } from './openrouter-pricing.js';
|
|
|
8
8
|
export { TraceBuilder } from './builder.js';
|
|
9
9
|
export type { ConsoleTraceConfig } from './console.js';
|
|
10
10
|
export { ConsoleTraceProvider } from './console.js';
|
|
11
|
+
export type { LangfuseTraceConfig } from './langfuse.js';
|
|
12
|
+
export { LangfuseTraceProvider } from './langfuse.js';
|
|
13
|
+
export { MultiTraceProvider } from './multi.js';
|
|
11
14
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/trace/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,YAAY,EACV,OAAO,EACP,MAAM,EACN,YAAY,EACZ,YAAY,EACZ,aAAa,EACb,UAAU,EACV,SAAS,EACT,KAAK,EACL,YAAY,EACZ,aAAa,EACb,UAAU,EACX,MAAM,YAAY,CAAA;AAEnB,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,YAAY,CAAA;AAG5D,OAAO,EAAE,qBAAqB,EAAE,aAAa,EAAE,MAAM,cAAc,CAAA;AACnE,OAAO,EAAE,wBAAwB,EAAE,MAAM,yBAAyB,CAAA;AAGlE,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAA;AAG3C,YAAY,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAA;AACtD,OAAO,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/trace/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,YAAY,EACV,OAAO,EACP,MAAM,EACN,YAAY,EACZ,YAAY,EACZ,aAAa,EACb,UAAU,EACV,SAAS,EACT,KAAK,EACL,YAAY,EACZ,aAAa,EACb,UAAU,EACX,MAAM,YAAY,CAAA;AAEnB,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,YAAY,CAAA;AAG5D,OAAO,EAAE,qBAAqB,EAAE,aAAa,EAAE,MAAM,cAAc,CAAA;AACnE,OAAO,EAAE,wBAAwB,EAAE,MAAM,yBAAyB,CAAA;AAGlE,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAA;AAG3C,YAAY,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAA;AACtD,OAAO,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAA;AAGnD,YAAY,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAA;AACxD,OAAO,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAA;AAGrD,OAAO,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAA"}
|
package/dist/trace/index.js
CHANGED
|
@@ -8,4 +8,7 @@ export { OPENROUTER_MODEL_PRICING } from './openrouter-pricing.js';
|
|
|
8
8
|
// Builder
|
|
9
9
|
export { TraceBuilder } from './builder.js';
|
|
10
10
|
export { ConsoleTraceProvider } from './console.js';
|
|
11
|
+
export { LangfuseTraceProvider } from './langfuse.js';
|
|
12
|
+
// Multi Provider (fan-out to multiple providers)
|
|
13
|
+
export { MultiTraceProvider } from './multi.js';
|
|
11
14
|
//# sourceMappingURL=index.js.map
|
package/dist/trace/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/trace/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAiBH,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,YAAY,CAAA;AAE5D,UAAU;AACV,OAAO,EAAE,qBAAqB,EAAE,aAAa,EAAE,MAAM,cAAc,CAAA;AACnE,OAAO,EAAE,wBAAwB,EAAE,MAAM,yBAAyB,CAAA;AAElE,UAAU;AACV,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAA;AAI3C,OAAO,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/trace/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAiBH,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,YAAY,CAAA;AAE5D,UAAU;AACV,OAAO,EAAE,qBAAqB,EAAE,aAAa,EAAE,MAAM,cAAc,CAAA;AACnE,OAAO,EAAE,wBAAwB,EAAE,MAAM,yBAAyB,CAAA;AAElE,UAAU;AACV,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAA;AAI3C,OAAO,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAA;AAInD,OAAO,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAA;AAErD,iDAAiD;AACjD,OAAO,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAA"}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Langfuse Trace Provider — native (no dependencies)
|
|
3
|
+
*
|
|
4
|
+
* Posts directly to Langfuse's ingestion API
|
|
5
|
+
* (`POST {baseUrl}/api/public/ingestion`) using Node 20+ built-in fetch.
|
|
6
|
+
* The user only needs credentials — no OpenTelemetry SDK required.
|
|
7
|
+
*
|
|
8
|
+
* const trace = new LangfuseTraceProvider() // reads LANGFUSE_* env vars
|
|
9
|
+
*
|
|
10
|
+
* Env vars (any of):
|
|
11
|
+
* LANGFUSE_PUBLIC_KEY (required)
|
|
12
|
+
* LANGFUSE_SECRET_KEY (required)
|
|
13
|
+
* LANGFUSE_BASE_URL | LANGFUSE_BASEURL | LANGFUSE_HOST
|
|
14
|
+
* (default: https://cloud.langfuse.com)
|
|
15
|
+
*/
|
|
16
|
+
import type { Trace, TraceProvider, AgentSpan, LLMCallEvent, ToolCallEvent, ModelPricing } from './types.js';
|
|
17
|
+
export interface LangfuseTraceConfig {
|
|
18
|
+
/** Langfuse public key. Defaults to env LANGFUSE_PUBLIC_KEY. */
|
|
19
|
+
publicKey?: string;
|
|
20
|
+
/** Langfuse secret key. Defaults to env LANGFUSE_SECRET_KEY. */
|
|
21
|
+
secretKey?: string;
|
|
22
|
+
/** Langfuse base URL. Defaults to env LANGFUSE_BASE_URL / LANGFUSE_BASEURL / LANGFUSE_HOST or https://cloud.langfuse.com. */
|
|
23
|
+
baseUrl?: string;
|
|
24
|
+
/** Number of events to buffer before flushing. Default: 20. */
|
|
25
|
+
flushAt?: number;
|
|
26
|
+
/** Max time (ms) to hold buffered events before flushing. Default: 3000. */
|
|
27
|
+
flushIntervalMs?: number;
|
|
28
|
+
/** Network timeout (ms) per ingest request. Default: 10_000. */
|
|
29
|
+
requestTimeoutMs?: number;
|
|
30
|
+
/** Group runs into a Langfuse session. */
|
|
31
|
+
sessionId?: string;
|
|
32
|
+
/** Attach a Langfuse user id. */
|
|
33
|
+
userId?: string;
|
|
34
|
+
/** Tags applied to the trace. */
|
|
35
|
+
tags?: string[];
|
|
36
|
+
/** Free-form metadata applied to the trace. */
|
|
37
|
+
metadata?: Record<string, unknown>;
|
|
38
|
+
/** App release identifier (e.g. git sha). */
|
|
39
|
+
release?: string;
|
|
40
|
+
/** App version. */
|
|
41
|
+
version?: string;
|
|
42
|
+
/** Capture LLM messages/responses (default: true). Disable for sensitive data. */
|
|
43
|
+
captureMessages?: boolean;
|
|
44
|
+
/** Capture tool inputs/outputs (default: true). */
|
|
45
|
+
captureToolIO?: boolean;
|
|
46
|
+
/** Truncate captured payloads to this many characters. Default: 32_768. */
|
|
47
|
+
maxPayloadChars?: number;
|
|
48
|
+
/** Print ingestion errors to console (default: true). */
|
|
49
|
+
debug?: boolean;
|
|
50
|
+
/** Print a one-time confirmation line on first successful flush (default: false). */
|
|
51
|
+
verbose?: boolean;
|
|
52
|
+
/** Custom model pricing forwarded to the trace builder. */
|
|
53
|
+
modelPricing?: Record<string, ModelPricing>;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Sends tuplet trace events to Langfuse via the ingestion HTTP API.
|
|
57
|
+
*/
|
|
58
|
+
export declare class LangfuseTraceProvider implements TraceProvider {
|
|
59
|
+
readonly modelPricing?: Record<string, ModelPricing>;
|
|
60
|
+
private readonly endpoint;
|
|
61
|
+
private readonly auth;
|
|
62
|
+
private readonly flushAt;
|
|
63
|
+
private readonly flushIntervalMs;
|
|
64
|
+
private readonly requestTimeoutMs;
|
|
65
|
+
private readonly sessionId?;
|
|
66
|
+
private readonly userId?;
|
|
67
|
+
private readonly tags?;
|
|
68
|
+
private readonly metadata?;
|
|
69
|
+
private readonly release?;
|
|
70
|
+
private readonly version?;
|
|
71
|
+
private readonly captureMessages;
|
|
72
|
+
private readonly captureToolIO;
|
|
73
|
+
private readonly maxPayloadChars;
|
|
74
|
+
private readonly debug;
|
|
75
|
+
private readonly verbose;
|
|
76
|
+
private queue;
|
|
77
|
+
private flushTimer?;
|
|
78
|
+
private inFlight;
|
|
79
|
+
private firstSendLogged;
|
|
80
|
+
constructor(config?: LangfuseTraceConfig);
|
|
81
|
+
onTraceStart(trace: Trace): void;
|
|
82
|
+
onTraceEnd(trace: Trace): void;
|
|
83
|
+
onAgentStart(span: AgentSpan, trace: Trace): void;
|
|
84
|
+
onAgentEnd(span: AgentSpan, trace: Trace): void;
|
|
85
|
+
onLLMCall(event: LLMCallEvent, span: AgentSpan, trace: Trace): void;
|
|
86
|
+
onToolCall(event: ToolCallEvent, span: AgentSpan, trace: Trace): void;
|
|
87
|
+
/** Force-send any buffered events. Awaits the in-flight request too. */
|
|
88
|
+
flush(): Promise<void>;
|
|
89
|
+
/** Flush remaining events. Call before process exit. */
|
|
90
|
+
shutdown(): Promise<void>;
|
|
91
|
+
private observationParent;
|
|
92
|
+
private enqueue;
|
|
93
|
+
private send;
|
|
94
|
+
private cap;
|
|
95
|
+
}
|
|
96
|
+
//# sourceMappingURL=langfuse.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"langfuse.d.ts","sourceRoot":"","sources":["../../src/trace/langfuse.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAGH,OAAO,KAAK,EACV,KAAK,EACL,aAAa,EACb,SAAS,EACT,YAAY,EACZ,aAAa,EACb,YAAY,EACb,MAAM,YAAY,CAAA;AAEnB,MAAM,WAAW,mBAAmB;IAClC,gEAAgE;IAChE,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,gEAAgE;IAChE,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,6HAA6H;IAC7H,OAAO,CAAC,EAAE,MAAM,CAAA;IAEhB,+DAA+D;IAC/D,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,4EAA4E;IAC5E,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,gEAAgE;IAChE,gBAAgB,CAAC,EAAE,MAAM,CAAA;IAEzB,0CAA0C;IAC1C,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,iCAAiC;IACjC,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,iCAAiC;IACjC,IAAI,CAAC,EAAE,MAAM,EAAE,CAAA;IACf,+CAA+C;IAC/C,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAClC,6CAA6C;IAC7C,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,mBAAmB;IACnB,OAAO,CAAC,EAAE,MAAM,CAAA;IAEhB,kFAAkF;IAClF,eAAe,CAAC,EAAE,OAAO,CAAA;IACzB,mDAAmD;IACnD,aAAa,CAAC,EAAE,OAAO,CAAA;IACvB,2EAA2E;IAC3E,eAAe,CAAC,EAAE,MAAM,CAAA;IAExB,yDAAyD;IACzD,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,qFAAqF;IACrF,OAAO,CAAC,EAAE,OAAO,CAAA;IAEjB,2DAA2D;IAC3D,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,CAAA;CAC5C;AASD;;GAEG;AACH,qBAAa,qBAAsB,YAAW,aAAa;IACzD,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,CAAA;IAEpD,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAQ;IACjC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAQ;IAC7B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAQ;IAChC,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAQ;IACxC,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAQ;IAEzC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAQ;IACnC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAQ;IAChC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAU;IAChC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAyB;IACnD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAQ;IACjC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAQ;IAEjC,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAS;IACzC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAS;IACvC,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAQ;IACxC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAS;IAC/B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IAEjC,OAAO,CAAC,KAAK,CAAuB;IACpC,OAAO,CAAC,UAAU,CAAC,CAA+B;IAClD,OAAO,CAAC,QAAQ,CAAmC;IACnD,OAAO,CAAC,eAAe,CAAQ;gBAEnB,MAAM,GAAE,mBAAwB;IAyC5C,YAAY,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI;IAgBhC,UAAU,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI;IAsB9B,YAAY,CAAC,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,KAAK,GAAG,IAAI;IAYjD,UAAU,CAAC,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,KAAK,GAAG,IAAI;IAY/C,SAAS,CAAC,KAAK,EAAE,YAAY,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,KAAK,GAAG,IAAI;IAkCnE,UAAU,CAAC,KAAK,EAAE,aAAa,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,KAAK,GAAG,IAAI;IAkBrE,wEAAwE;IAClE,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAe5B,wDAAwD;IAClD,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAM/B,OAAO,CAAC,iBAAiB;IAQzB,OAAO,CAAC,OAAO;YAeD,IAAI;IA6DlB,OAAO,CAAC,GAAG;CAgBZ"}
|
|
@@ -0,0 +1,317 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Langfuse Trace Provider — native (no dependencies)
|
|
3
|
+
*
|
|
4
|
+
* Posts directly to Langfuse's ingestion API
|
|
5
|
+
* (`POST {baseUrl}/api/public/ingestion`) using Node 20+ built-in fetch.
|
|
6
|
+
* The user only needs credentials — no OpenTelemetry SDK required.
|
|
7
|
+
*
|
|
8
|
+
* const trace = new LangfuseTraceProvider() // reads LANGFUSE_* env vars
|
|
9
|
+
*
|
|
10
|
+
* Env vars (any of):
|
|
11
|
+
* LANGFUSE_PUBLIC_KEY (required)
|
|
12
|
+
* LANGFUSE_SECRET_KEY (required)
|
|
13
|
+
* LANGFUSE_BASE_URL | LANGFUSE_BASEURL | LANGFUSE_HOST
|
|
14
|
+
* (default: https://cloud.langfuse.com)
|
|
15
|
+
*/
|
|
16
|
+
import { randomUUID } from 'node:crypto';
|
|
17
|
+
/**
|
|
18
|
+
* Sends tuplet trace events to Langfuse via the ingestion HTTP API.
|
|
19
|
+
*/
|
|
20
|
+
export class LangfuseTraceProvider {
|
|
21
|
+
modelPricing;
|
|
22
|
+
endpoint;
|
|
23
|
+
auth;
|
|
24
|
+
flushAt;
|
|
25
|
+
flushIntervalMs;
|
|
26
|
+
requestTimeoutMs;
|
|
27
|
+
sessionId;
|
|
28
|
+
userId;
|
|
29
|
+
tags;
|
|
30
|
+
metadata;
|
|
31
|
+
release;
|
|
32
|
+
version;
|
|
33
|
+
captureMessages;
|
|
34
|
+
captureToolIO;
|
|
35
|
+
maxPayloadChars;
|
|
36
|
+
debug;
|
|
37
|
+
verbose;
|
|
38
|
+
queue = [];
|
|
39
|
+
flushTimer;
|
|
40
|
+
inFlight = Promise.resolve();
|
|
41
|
+
firstSendLogged = false;
|
|
42
|
+
constructor(config = {}) {
|
|
43
|
+
const publicKey = config.publicKey ?? process.env.LANGFUSE_PUBLIC_KEY;
|
|
44
|
+
const secretKey = config.secretKey ?? process.env.LANGFUSE_SECRET_KEY;
|
|
45
|
+
const baseUrl = config.baseUrl ??
|
|
46
|
+
process.env.LANGFUSE_BASE_URL ??
|
|
47
|
+
process.env.LANGFUSE_BASEURL ??
|
|
48
|
+
process.env.LANGFUSE_HOST ??
|
|
49
|
+
'https://cloud.langfuse.com';
|
|
50
|
+
if (!publicKey || !secretKey) {
|
|
51
|
+
throw new Error('LangfuseTraceProvider: missing credentials. Set LANGFUSE_PUBLIC_KEY and LANGFUSE_SECRET_KEY env vars or pass them in config.');
|
|
52
|
+
}
|
|
53
|
+
this.endpoint = `${baseUrl.replace(/\/+$/, '')}/api/public/ingestion`;
|
|
54
|
+
this.auth = Buffer.from(`${publicKey}:${secretKey}`).toString('base64');
|
|
55
|
+
this.flushAt = config.flushAt ?? 20;
|
|
56
|
+
this.flushIntervalMs = config.flushIntervalMs ?? 3000;
|
|
57
|
+
this.requestTimeoutMs = config.requestTimeoutMs ?? 10_000;
|
|
58
|
+
this.sessionId = config.sessionId;
|
|
59
|
+
this.userId = config.userId;
|
|
60
|
+
this.tags = config.tags;
|
|
61
|
+
this.metadata = config.metadata;
|
|
62
|
+
this.release = config.release;
|
|
63
|
+
this.version = config.version;
|
|
64
|
+
this.captureMessages = config.captureMessages ?? true;
|
|
65
|
+
this.captureToolIO = config.captureToolIO ?? true;
|
|
66
|
+
this.maxPayloadChars = config.maxPayloadChars ?? 32_768;
|
|
67
|
+
this.debug = config.debug ?? true;
|
|
68
|
+
this.verbose = config.verbose ?? false;
|
|
69
|
+
this.modelPricing = config.modelPricing;
|
|
70
|
+
}
|
|
71
|
+
// ----- TraceProvider hooks ------------------------------------------------
|
|
72
|
+
onTraceStart(trace) {
|
|
73
|
+
const root = trace.rootSpan;
|
|
74
|
+
this.enqueue('trace-create', {
|
|
75
|
+
id: trace.traceId,
|
|
76
|
+
timestamp: isoFrom(trace.startTime),
|
|
77
|
+
name: root.agentName,
|
|
78
|
+
input: this.captureMessages ? this.cap(root.inputMessage) : undefined,
|
|
79
|
+
userId: this.userId,
|
|
80
|
+
sessionId: this.sessionId,
|
|
81
|
+
tags: this.tags,
|
|
82
|
+
metadata: this.metadata,
|
|
83
|
+
release: this.release,
|
|
84
|
+
version: this.version
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
onTraceEnd(trace) {
|
|
88
|
+
this.enqueue('trace-create', {
|
|
89
|
+
id: trace.traceId,
|
|
90
|
+
timestamp: isoFrom(trace.startTime),
|
|
91
|
+
name: trace.rootSpan.agentName,
|
|
92
|
+
output: this.captureMessages ? this.cap(trace.rootSpan.outputResponse) : undefined,
|
|
93
|
+
metadata: {
|
|
94
|
+
...this.metadata,
|
|
95
|
+
durationMs: trace.durationMs,
|
|
96
|
+
totalCost: trace.totalCost,
|
|
97
|
+
totalInputTokens: trace.totalInputTokens,
|
|
98
|
+
totalOutputTokens: trace.totalOutputTokens,
|
|
99
|
+
totalCacheReadTokens: trace.totalCacheReadTokens,
|
|
100
|
+
totalCacheCreationTokens: trace.totalCacheCreationTokens,
|
|
101
|
+
totalLLMCalls: trace.totalLLMCalls,
|
|
102
|
+
totalToolCalls: trace.totalToolCalls,
|
|
103
|
+
costByModel: trace.costByModel
|
|
104
|
+
}
|
|
105
|
+
});
|
|
106
|
+
void this.flush();
|
|
107
|
+
}
|
|
108
|
+
onAgentStart(span, trace) {
|
|
109
|
+
if (span.depth === 0)
|
|
110
|
+
return; // root agent is the trace itself
|
|
111
|
+
this.enqueue('span-create', {
|
|
112
|
+
id: span.spanId,
|
|
113
|
+
traceId: trace.traceId,
|
|
114
|
+
name: span.agentName,
|
|
115
|
+
startTime: isoFrom(span.startTime),
|
|
116
|
+
parentObservationId: this.observationParent(span),
|
|
117
|
+
input: this.captureMessages ? this.cap(span.inputMessage) : undefined
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
onAgentEnd(span, trace) {
|
|
121
|
+
if (span.depth === 0)
|
|
122
|
+
return;
|
|
123
|
+
this.enqueue('span-update', {
|
|
124
|
+
id: span.spanId,
|
|
125
|
+
traceId: trace.traceId,
|
|
126
|
+
endTime: isoFrom(span.endTime ?? Date.now()),
|
|
127
|
+
output: this.captureMessages ? this.cap(span.outputResponse) : undefined,
|
|
128
|
+
level: span.status === 'error' ? 'ERROR' : 'DEFAULT',
|
|
129
|
+
statusMessage: span.status === 'interrupted' ? 'interrupted' : undefined
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
onLLMCall(event, span, trace) {
|
|
133
|
+
const startTime = event.timestamp - event.durationMs;
|
|
134
|
+
const usageDetails = {
|
|
135
|
+
input: event.inputTokens,
|
|
136
|
+
output: event.outputTokens,
|
|
137
|
+
total: event.inputTokens + event.outputTokens
|
|
138
|
+
};
|
|
139
|
+
if (event.cacheReadTokens)
|
|
140
|
+
usageDetails.cache_read_input = event.cacheReadTokens;
|
|
141
|
+
if (event.cacheCreationTokens)
|
|
142
|
+
usageDetails.cache_creation_input = event.cacheCreationTokens;
|
|
143
|
+
let input;
|
|
144
|
+
if (this.captureMessages) {
|
|
145
|
+
const wrapped = {};
|
|
146
|
+
if (event.systemPrompt)
|
|
147
|
+
wrapped.system = event.systemPrompt;
|
|
148
|
+
if (event.messages)
|
|
149
|
+
wrapped.messages = event.messages;
|
|
150
|
+
if (Object.keys(wrapped).length > 0)
|
|
151
|
+
input = wrapped;
|
|
152
|
+
}
|
|
153
|
+
this.enqueue('generation-create', {
|
|
154
|
+
id: event.spanId,
|
|
155
|
+
traceId: trace.traceId,
|
|
156
|
+
name: `llm.${event.modelId}`,
|
|
157
|
+
startTime: isoFrom(startTime),
|
|
158
|
+
endTime: isoFrom(event.timestamp),
|
|
159
|
+
parentObservationId: span.depth === 0 ? undefined : span.spanId,
|
|
160
|
+
model: event.modelId,
|
|
161
|
+
input: this.cap(input),
|
|
162
|
+
output: this.captureMessages ? this.cap(event.response) : undefined,
|
|
163
|
+
usageDetails,
|
|
164
|
+
costDetails: event.cost > 0 ? { total: event.cost } : undefined
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
onToolCall(event, span, trace) {
|
|
168
|
+
const startTime = event.timestamp - event.durationMs;
|
|
169
|
+
this.enqueue('span-create', {
|
|
170
|
+
id: event.spanId,
|
|
171
|
+
traceId: trace.traceId,
|
|
172
|
+
name: `tool.${event.toolName}`,
|
|
173
|
+
startTime: isoFrom(startTime),
|
|
174
|
+
endTime: isoFrom(event.timestamp),
|
|
175
|
+
parentObservationId: span.depth === 0 ? undefined : span.spanId,
|
|
176
|
+
input: this.captureToolIO ? this.cap(event.input) : undefined,
|
|
177
|
+
output: this.captureToolIO ? this.cap(event.output) : undefined,
|
|
178
|
+
level: event.output.success ? 'DEFAULT' : 'ERROR',
|
|
179
|
+
statusMessage: event.output.success ? undefined : event.output.error
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
// ----- public lifecycle ---------------------------------------------------
|
|
183
|
+
/** Force-send any buffered events. Awaits the in-flight request too. */
|
|
184
|
+
async flush() {
|
|
185
|
+
if (this.flushTimer) {
|
|
186
|
+
clearTimeout(this.flushTimer);
|
|
187
|
+
this.flushTimer = undefined;
|
|
188
|
+
}
|
|
189
|
+
if (this.queue.length === 0) {
|
|
190
|
+
await this.inFlight;
|
|
191
|
+
return;
|
|
192
|
+
}
|
|
193
|
+
const batch = this.queue;
|
|
194
|
+
this.queue = [];
|
|
195
|
+
this.inFlight = this.inFlight.then(() => this.send(batch));
|
|
196
|
+
await this.inFlight;
|
|
197
|
+
}
|
|
198
|
+
/** Flush remaining events. Call before process exit. */
|
|
199
|
+
async shutdown() {
|
|
200
|
+
await this.flush();
|
|
201
|
+
}
|
|
202
|
+
// ----- internals ----------------------------------------------------------
|
|
203
|
+
observationParent(span) {
|
|
204
|
+
// Sub-agent at depth 1 is parented directly to the trace (root has no observation).
|
|
205
|
+
// Deeper agents parent to the enclosing sub-agent observation.
|
|
206
|
+
if (!span.parentSpanId)
|
|
207
|
+
return undefined;
|
|
208
|
+
const parentDepth = (span.depth ?? 0) - 1;
|
|
209
|
+
return parentDepth >= 1 ? span.parentSpanId : undefined;
|
|
210
|
+
}
|
|
211
|
+
enqueue(type, body) {
|
|
212
|
+
this.queue.push({
|
|
213
|
+
id: randomUUID(),
|
|
214
|
+
type,
|
|
215
|
+
timestamp: new Date().toISOString(),
|
|
216
|
+
body: stripUndefined(body)
|
|
217
|
+
});
|
|
218
|
+
if (this.queue.length >= this.flushAt) {
|
|
219
|
+
void this.flush();
|
|
220
|
+
}
|
|
221
|
+
else if (!this.flushTimer) {
|
|
222
|
+
this.flushTimer = setTimeout(() => void this.flush(), this.flushIntervalMs);
|
|
223
|
+
this.flushTimer.unref?.();
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
async send(batch) {
|
|
227
|
+
const ctrl = new AbortController();
|
|
228
|
+
const timer = setTimeout(() => ctrl.abort(), this.requestTimeoutMs);
|
|
229
|
+
try {
|
|
230
|
+
const res = await fetch(this.endpoint, {
|
|
231
|
+
method: 'POST',
|
|
232
|
+
headers: {
|
|
233
|
+
'Content-Type': 'application/json',
|
|
234
|
+
Authorization: `Basic ${this.auth}`
|
|
235
|
+
},
|
|
236
|
+
body: JSON.stringify({ batch }),
|
|
237
|
+
signal: ctrl.signal
|
|
238
|
+
});
|
|
239
|
+
const text = await res.text().catch(() => '');
|
|
240
|
+
const parsed = parseJson(text);
|
|
241
|
+
if (!res.ok && res.status !== 207) {
|
|
242
|
+
if (this.debug) {
|
|
243
|
+
console.error(`[langfuse] ${res.status} ${res.statusText}: ${truncateForLog(text)}`);
|
|
244
|
+
}
|
|
245
|
+
return;
|
|
246
|
+
}
|
|
247
|
+
const successCount = parsed?.successes?.length ?? 0;
|
|
248
|
+
const errors = parsed?.errors ?? [];
|
|
249
|
+
if (this.verbose && !this.firstSendLogged) {
|
|
250
|
+
this.firstSendLogged = true;
|
|
251
|
+
console.log(`[langfuse] connected → ${this.endpoint} (sent ${batch.length}, accepted ${successCount}, rejected ${errors.length})`);
|
|
252
|
+
}
|
|
253
|
+
if (this.debug && errors.length > 0) {
|
|
254
|
+
for (const err of errors) {
|
|
255
|
+
const detail = typeof err.error === 'string'
|
|
256
|
+
? err.error
|
|
257
|
+
: err.error
|
|
258
|
+
? JSON.stringify(err.error)
|
|
259
|
+
: err.message ?? 'unknown';
|
|
260
|
+
console.error(`[langfuse] event ${err.id ?? '?'} rejected (${err.status ?? '?'}): ${truncateForLog(detail)}`);
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
catch (err) {
|
|
265
|
+
if (this.debug) {
|
|
266
|
+
console.error('[langfuse] ingest failed:', err instanceof Error ? err.message : err);
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
finally {
|
|
270
|
+
clearTimeout(timer);
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
cap(value) {
|
|
274
|
+
if (value == null)
|
|
275
|
+
return undefined;
|
|
276
|
+
if (typeof value === 'string') {
|
|
277
|
+
return value.length <= this.maxPayloadChars
|
|
278
|
+
? value
|
|
279
|
+
: value.slice(0, this.maxPayloadChars - 14) + '…[truncated]';
|
|
280
|
+
}
|
|
281
|
+
let serialized;
|
|
282
|
+
try {
|
|
283
|
+
serialized = JSON.stringify(value);
|
|
284
|
+
}
|
|
285
|
+
catch {
|
|
286
|
+
return String(value).slice(0, this.maxPayloadChars);
|
|
287
|
+
}
|
|
288
|
+
if (serialized.length <= this.maxPayloadChars)
|
|
289
|
+
return value;
|
|
290
|
+
return serialized.slice(0, this.maxPayloadChars - 14) + '…[truncated]';
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
function isoFrom(ms) {
|
|
294
|
+
return ms == null ? undefined : new Date(ms).toISOString();
|
|
295
|
+
}
|
|
296
|
+
function parseJson(text) {
|
|
297
|
+
if (!text)
|
|
298
|
+
return null;
|
|
299
|
+
try {
|
|
300
|
+
return JSON.parse(text);
|
|
301
|
+
}
|
|
302
|
+
catch {
|
|
303
|
+
return null;
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
function truncateForLog(text) {
|
|
307
|
+
return text.length > 500 ? text.slice(0, 500) + '…' : text;
|
|
308
|
+
}
|
|
309
|
+
function stripUndefined(obj) {
|
|
310
|
+
const out = {};
|
|
311
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
312
|
+
if (value !== undefined)
|
|
313
|
+
out[key] = value;
|
|
314
|
+
}
|
|
315
|
+
return out;
|
|
316
|
+
}
|
|
317
|
+
//# sourceMappingURL=langfuse.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"langfuse.js","sourceRoot":"","sources":["../../src/trace/langfuse.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Multi Trace Provider — fans out trace events to multiple TraceProviders.
|
|
3
|
+
*
|
|
4
|
+
* Useful when you want to record traces in two places at once (e.g. an internal
|
|
5
|
+
* Firestore/Postgres store *and* Langfuse for observability) without having to
|
|
6
|
+
* write a wrapper that forwards every callback by hand.
|
|
7
|
+
*
|
|
8
|
+
* const trace = new MultiTraceProvider([
|
|
9
|
+
* new ConsoleTraceProvider(),
|
|
10
|
+
* new LangfuseTraceProvider()
|
|
11
|
+
* ])
|
|
12
|
+
*
|
|
13
|
+
* new Tuplet({ ..., trace })
|
|
14
|
+
*
|
|
15
|
+
* Behavior:
|
|
16
|
+
* - Every callback fans out to all child providers in parallel via Promise.all.
|
|
17
|
+
* - Errors from any single child are caught and logged so one bad sink can't
|
|
18
|
+
* take down the agent run or block the other providers.
|
|
19
|
+
* - `modelPricing` resolves to the first child that defines one, so cost
|
|
20
|
+
* calculations stay consistent.
|
|
21
|
+
* - `flush()` / `shutdown()` fan out to children that implement them
|
|
22
|
+
* (e.g. LangfuseTraceProvider).
|
|
23
|
+
*/
|
|
24
|
+
import type { Trace, TraceProvider, AgentSpan, LLMCallEvent, ToolCallEvent, ModelPricing, CostUpdate } from './types.js';
|
|
25
|
+
export declare class MultiTraceProvider implements TraceProvider {
|
|
26
|
+
readonly modelPricing?: Record<string, ModelPricing>;
|
|
27
|
+
private readonly providers;
|
|
28
|
+
constructor(providers: TraceProvider[]);
|
|
29
|
+
onTraceStart(trace: Trace): Promise<void>;
|
|
30
|
+
onTraceEnd(trace: Trace): Promise<void>;
|
|
31
|
+
onAgentStart(span: AgentSpan, trace: Trace): Promise<void>;
|
|
32
|
+
onAgentEnd(span: AgentSpan, trace: Trace): Promise<void>;
|
|
33
|
+
onLLMCall(event: LLMCallEvent, span: AgentSpan, trace: Trace): Promise<void>;
|
|
34
|
+
onToolCall(event: ToolCallEvent, span: AgentSpan, trace: Trace): Promise<void>;
|
|
35
|
+
onCostUpdate(update: CostUpdate): Promise<void>;
|
|
36
|
+
/** Fan out flush() to children that implement it. Best-effort. */
|
|
37
|
+
flush(): Promise<void>;
|
|
38
|
+
/** Fan out shutdown() to children that implement it. Best-effort. */
|
|
39
|
+
shutdown(): Promise<void>;
|
|
40
|
+
private fanOut;
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=multi.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"multi.d.ts","sourceRoot":"","sources":["../../src/trace/multi.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,KAAK,EACV,KAAK,EACL,aAAa,EACb,SAAS,EACT,YAAY,EACZ,aAAa,EACb,YAAY,EACZ,UAAU,EACX,MAAM,YAAY,CAAA;AAOnB,qBAAa,kBAAmB,YAAW,aAAa;IACtD,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,CAAA;IACpD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAiB;gBAE/B,SAAS,EAAE,aAAa,EAAE;IAKhC,YAAY,CAAC,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC;IAIzC,UAAU,CAAC,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC;IAIvC,YAAY,CAAC,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC;IAI1D,UAAU,CAAC,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC;IAIxD,SAAS,CAAC,KAAK,EAAE,YAAY,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC;IAI5E,UAAU,CAAC,KAAK,EAAE,aAAa,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC;IAI9E,YAAY,CAAC,MAAM,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IAIrD,kEAAkE;IAC5D,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAI5B,qEAAqE;IAC/D,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;YAIjB,MAAM;CAarB"}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Multi Trace Provider — fans out trace events to multiple TraceProviders.
|
|
3
|
+
*
|
|
4
|
+
* Useful when you want to record traces in two places at once (e.g. an internal
|
|
5
|
+
* Firestore/Postgres store *and* Langfuse for observability) without having to
|
|
6
|
+
* write a wrapper that forwards every callback by hand.
|
|
7
|
+
*
|
|
8
|
+
* const trace = new MultiTraceProvider([
|
|
9
|
+
* new ConsoleTraceProvider(),
|
|
10
|
+
* new LangfuseTraceProvider()
|
|
11
|
+
* ])
|
|
12
|
+
*
|
|
13
|
+
* new Tuplet({ ..., trace })
|
|
14
|
+
*
|
|
15
|
+
* Behavior:
|
|
16
|
+
* - Every callback fans out to all child providers in parallel via Promise.all.
|
|
17
|
+
* - Errors from any single child are caught and logged so one bad sink can't
|
|
18
|
+
* take down the agent run or block the other providers.
|
|
19
|
+
* - `modelPricing` resolves to the first child that defines one, so cost
|
|
20
|
+
* calculations stay consistent.
|
|
21
|
+
* - `flush()` / `shutdown()` fan out to children that implement them
|
|
22
|
+
* (e.g. LangfuseTraceProvider).
|
|
23
|
+
*/
|
|
24
|
+
export class MultiTraceProvider {
|
|
25
|
+
modelPricing;
|
|
26
|
+
providers;
|
|
27
|
+
constructor(providers) {
|
|
28
|
+
this.providers = providers;
|
|
29
|
+
this.modelPricing = providers.find((p) => p.modelPricing)?.modelPricing;
|
|
30
|
+
}
|
|
31
|
+
async onTraceStart(trace) {
|
|
32
|
+
await this.fanOut((p) => p.onTraceStart?.(trace));
|
|
33
|
+
}
|
|
34
|
+
async onTraceEnd(trace) {
|
|
35
|
+
await this.fanOut((p) => p.onTraceEnd?.(trace));
|
|
36
|
+
}
|
|
37
|
+
async onAgentStart(span, trace) {
|
|
38
|
+
await this.fanOut((p) => p.onAgentStart?.(span, trace));
|
|
39
|
+
}
|
|
40
|
+
async onAgentEnd(span, trace) {
|
|
41
|
+
await this.fanOut((p) => p.onAgentEnd?.(span, trace));
|
|
42
|
+
}
|
|
43
|
+
async onLLMCall(event, span, trace) {
|
|
44
|
+
await this.fanOut((p) => p.onLLMCall?.(event, span, trace));
|
|
45
|
+
}
|
|
46
|
+
async onToolCall(event, span, trace) {
|
|
47
|
+
await this.fanOut((p) => p.onToolCall?.(event, span, trace));
|
|
48
|
+
}
|
|
49
|
+
async onCostUpdate(update) {
|
|
50
|
+
await this.fanOut((p) => p.onCostUpdate?.(update));
|
|
51
|
+
}
|
|
52
|
+
/** Fan out flush() to children that implement it. Best-effort. */
|
|
53
|
+
async flush() {
|
|
54
|
+
await this.fanOut((p) => p.flush?.());
|
|
55
|
+
}
|
|
56
|
+
/** Fan out shutdown() to children that implement it. Best-effort. */
|
|
57
|
+
async shutdown() {
|
|
58
|
+
await this.fanOut((p) => p.shutdown?.());
|
|
59
|
+
}
|
|
60
|
+
async fanOut(invoke) {
|
|
61
|
+
await Promise.all(this.providers.map(async (p) => {
|
|
62
|
+
try {
|
|
63
|
+
await invoke(p);
|
|
64
|
+
}
|
|
65
|
+
catch (err) {
|
|
66
|
+
console.error('[multi-trace] provider failed:', err);
|
|
67
|
+
}
|
|
68
|
+
}));
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
//# sourceMappingURL=multi.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"multi.js","sourceRoot":"","sources":["../../src/trace/multi.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAiBH,MAAM,OAAO,kBAAkB;IACpB,YAAY,CAA+B;IACnC,SAAS,CAAiB;IAE3C,YAAY,SAA0B;QACpC,IAAI,CAAC,SAAS,GAAG,SAAS,CAAA;QAC1B,IAAI,CAAC,YAAY,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,YAAY,CAAC,EAAE,YAAY,CAAA;IACzE,CAAC;IAED,KAAK,CAAC,YAAY,CAAC,KAAY;QAC7B,MAAM,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,YAAY,EAAE,CAAC,KAAK,CAAC,CAAC,CAAA;IACnD,CAAC;IAED,KAAK,CAAC,UAAU,CAAC,KAAY;QAC3B,MAAM,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,EAAE,CAAC,KAAK,CAAC,CAAC,CAAA;IACjD,CAAC;IAED,KAAK,CAAC,YAAY,CAAC,IAAe,EAAE,KAAY;QAC9C,MAAM,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,YAAY,EAAE,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,CAAA;IACzD,CAAC;IAED,KAAK,CAAC,UAAU,CAAC,IAAe,EAAE,KAAY;QAC5C,MAAM,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,EAAE,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,CAAA;IACvD,CAAC;IAED,KAAK,CAAC,SAAS,CAAC,KAAmB,EAAE,IAAe,EAAE,KAAY;QAChE,MAAM,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,KAAK,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC,CAAA;IAC7D,CAAC;IAED,KAAK,CAAC,UAAU,CAAC,KAAoB,EAAE,IAAe,EAAE,KAAY;QAClE,MAAM,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,EAAE,CAAC,KAAK,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC,CAAA;IAC9D,CAAC;IAED,KAAK,CAAC,YAAY,CAAC,MAAkB;QACnC,MAAM,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,YAAY,EAAE,CAAC,MAAM,CAAC,CAAC,CAAA;IACpD,CAAC;IAED,kEAAkE;IAClE,KAAK,CAAC,KAAK;QACT,MAAM,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAE,CAAuB,CAAC,KAAK,EAAE,EAAE,CAAC,CAAA;IAC9D,CAAC;IAED,qEAAqE;IACrE,KAAK,CAAC,QAAQ;QACZ,MAAM,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAE,CAAuB,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAA;IACjE,CAAC;IAEO,KAAK,CAAC,MAAM,CAClB,MAAkD;QAElD,MAAM,OAAO,CAAC,GAAG,CACf,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,EAAE,EAAE;YAC7B,IAAI,CAAC;gBACH,MAAM,MAAM,CAAC,CAAC,CAAC,CAAA;YACjB,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,OAAO,CAAC,KAAK,CAAC,gCAAgC,EAAE,GAAG,CAAC,CAAA;YACtD,CAAC;QACH,CAAC,CAAC,CACH,CAAA;IACH,CAAC;CACF"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"multi.test.d.ts","sourceRoot":"","sources":["../../src/trace/multi.test.ts"],"names":[],"mappings":""}
|