agent-lattice 0.18.0 → 0.19.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 CHANGED
@@ -308,6 +308,82 @@ root and share one trace session. Each Agent keeps its own SDK session identity,
308
308
  recorded as `agent_session_id` metadata, so tracing does not change Agent state
309
309
  or returned SDK messages.
310
310
 
311
+ ## Langfuse Context Tracing
312
+
313
+ *Requires 0.19.0 or later.*
314
+
315
+ The Langfuse adapter targets the current Langfuse JS SDK generation
316
+ (`@langfuse/tracing` v5), which is OpenTelemetry-based. Register the
317
+ `LangfuseSpanProcessor` once at process startup, then create the tracer —
318
+ no other wiring needed.
319
+
320
+ Configure Langfuse with its standard environment variables:
321
+
322
+ ```bash
323
+ LANGFUSE_PUBLIC_KEY=<your-langfuse-public-key>
324
+ LANGFUSE_SECRET_KEY=<your-langfuse-secret-key>
325
+ LANGFUSE_BASE_URL=https://us.cloud.langfuse.com # or your self-hosted host
326
+ ```
327
+
328
+ ```bash
329
+ npm install @langfuse/otel @opentelemetry/sdk-trace-node
330
+ ```
331
+
332
+ ```ts
333
+ // instrumentation: register the span processor before agents run.
334
+ import { LangfuseSpanProcessor } from "@langfuse/otel";
335
+ import { NodeTracerProvider } from "@opentelemetry/sdk-trace-node";
336
+
337
+ export const langfuseSpanProcessor = new LangfuseSpanProcessor();
338
+
339
+ const tracerProvider = new NodeTracerProvider({
340
+ spanProcessors: [langfuseSpanProcessor],
341
+ });
342
+ tracerProvider.register();
343
+ ```
344
+
345
+ ```ts
346
+ import {
347
+ createAgent,
348
+ createCompositeContextTracer,
349
+ createJsonlContextTracer,
350
+ createLangfuseContextTracer,
351
+ } from "agent-lattice";
352
+ import { langfuseSpanProcessor } from "./instrumentation";
353
+
354
+ const tracer = createCompositeContextTracer([
355
+ createJsonlContextTracer({ path: ".agent-runs/session.jsonl" }),
356
+ createLangfuseContextTracer({
357
+ // Drained by tracer.flush()/close() so spans reach Langfuse before a
358
+ // short-lived process exits.
359
+ spanProcessor: langfuseSpanProcessor,
360
+ tags: ["local-debug"],
361
+ }),
362
+ ]);
363
+
364
+ const agent = createAgent({
365
+ apiKey: process.env.DEEPSEEK_API_KEY,
366
+ baseURL: "https://api.deepseek.com/anthropic",
367
+ model: "deepseek-v4-flash",
368
+ tracer,
369
+ });
370
+
371
+ try {
372
+ await agent.prompt("Trace this run.", { stream: false });
373
+ } finally {
374
+ await tracer.close?.();
375
+ }
376
+ ```
377
+
378
+ Langfuse receives one trace per SDK query: the agent run is a root `chain`
379
+ observation carrying the trace name, session id, and tags; model turns appear
380
+ as child `generation` observations and SDK tool calls as child `tool`
381
+ observations. For a `Team` query, delegated runs nest as child `chain`
382
+ observations under the team root, so one handoff invocation stays one trace.
383
+
384
+ `startObservation` defaults to the bundled `@langfuse/tracing` function; pass
385
+ `startObservation` only to inject a custom runtime or a test fake.
386
+
311
387
  Custom sinks can implement the same interface for SQLite, OpenTelemetry, object
312
388
  storage, or host-specific observability. A `ContextTracer` port object exposes
313
389
  methods only — `failOnError` is bound when the factory creates the tracer, not
package/dist/index.d.ts CHANGED
@@ -4,6 +4,8 @@ import type { OAuthClientProvider } from "@modelcontextprotocol/sdk/client/auth.
4
4
  import { type StdioServerParameters } from "@modelcontextprotocol/sdk/client/stdio.js";
5
5
  import { type StreamableHTTPClientTransportOptions } from "@modelcontextprotocol/sdk/client/streamableHttp.js";
6
6
  import type { RunEvent, RunTree, RunTreeConfig } from "langsmith/run_trees";
7
+ import { startObservation as bundledLangfuseStartObservation } from "@langfuse/tracing";
8
+ import type { LangfuseChain, LangfuseGeneration, LangfuseObservation, LangfuseTool } from "@langfuse/tracing";
7
9
  import { z } from "zod/v4";
8
10
  export type TextBlock = TextBlockParam;
9
11
  export type ImageBlock = ImageBlockParam;
@@ -153,6 +155,27 @@ export type LangSmithContextTracerOptions = {
153
155
  redact?: (event: ContextTraceEvent) => ContextTraceEvent | undefined;
154
156
  failOnError?: boolean;
155
157
  };
158
+ export type LangfuseKVMap = Record<string, unknown>;
159
+ export type LangfuseObservationLike = LangfuseObservation;
160
+ export type LangfuseChainLike = LangfuseChain;
161
+ export type LangfuseGenerationLike = LangfuseGeneration;
162
+ export type LangfuseToolLike = LangfuseTool;
163
+ export type LangfuseStartObservation = typeof bundledLangfuseStartObservation;
164
+ /** Drained by the Langfuse tracer's flush()/close(); a LangfuseSpanProcessor satisfies this. */
165
+ export type LangfuseFlushableSpanProcessor = {
166
+ forceFlush(): Promise<void>;
167
+ };
168
+ export type LangfuseContextTracerOptions = {
169
+ /** Defaults to the bundled @langfuse/tracing startObservation; inject a compatible function for custom runtimes or tests. */
170
+ startObservation?: LangfuseStartObservation;
171
+ /** Span processor drained on flush()/close() — pass the LangfuseSpanProcessor registered with your OpenTelemetry setup. */
172
+ spanProcessor?: LangfuseFlushableSpanProcessor;
173
+ name?: string;
174
+ tags?: string[];
175
+ metadata?: LangfuseKVMap;
176
+ redact?: (event: ContextTraceEvent) => ContextTraceEvent | undefined;
177
+ failOnError?: boolean;
178
+ };
156
179
  export type ModelMessage = {
157
180
  role: "user" | "assistant";
158
181
  content: string | ContentBlock[];
@@ -804,6 +827,16 @@ export declare function createJsonlContextTracer(options: JsonlContextTracerOpti
804
827
  export declare function createCompositeAgentHooks<TContext = unknown>(hooks: Array<AgentHooks<TContext> | undefined | null>): AgentHooks<TContext>;
805
828
  export declare function createCompositeContextTracer(tracers: Array<ContextTracer | undefined | null>): ContextTracer;
806
829
  export declare function createLangSmithContextTracer(options?: LangSmithContextTracerOptions): ContextTracer;
830
+ /**
831
+ * Langfuse trace sink built on the current @langfuse/tracing (v5) SDK. The SDK
832
+ * is OpenTelemetry-based: the host registers a LangfuseSpanProcessor (from
833
+ * @langfuse/otel) with a tracer provider, and this adapter maps context trace
834
+ * events onto observations — a chain per agent run, a generation per model
835
+ * turn, a tool observation per tool call, and event observations for
836
+ * everything else. Pass the registered span processor so flush()/close() can
837
+ * drain pending spans before a short-lived process exits.
838
+ */
839
+ export declare function createLangfuseContextTracer(options?: LangfuseContextTracerOptions): ContextTracer;
807
840
  export declare function skill(input: SkillInput): SkillDefinition;
808
841
  export declare function loadSkill(path: string): Promise<SkillDefinition>;
809
842
  export declare function createMCPTools(client: MCPClient, options?: MCPToolsOptions): Promise<Array<ToolDefinition<Record<string, unknown>>>>;