pi-langfuse 1.5.5 → 1.5.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/package.json +3 -1
  2. package/src/langfuse.ts +41 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-langfuse",
3
- "version": "1.5.5",
3
+ "version": "1.5.6",
4
4
  "description": "Langfuse extension for Pi coding agent",
5
5
  "repository": {
6
6
  "type": "git",
@@ -46,6 +46,8 @@
46
46
  "@langfuse/client": "^5.3.0",
47
47
  "@langfuse/otel": "^5.3.0",
48
48
  "@langfuse/tracing": "^5.3.0",
49
+ "@opentelemetry/api": "^1.9.0",
50
+ "@opentelemetry/context-async-hooks": "^2.7.1",
49
51
  "@opentelemetry/sdk-node": "^0.218.0",
50
52
  "@opentelemetry/sdk-trace-base": "^2.0.1"
51
53
  },
package/src/langfuse.ts CHANGED
@@ -3,11 +3,23 @@ import { state } from "./state.js";
3
3
  import { randomUUID } from "node:crypto";
4
4
 
5
5
  let runtime: LangfuseRuntime | null = null;
6
+ let registeredContextManager: OtelContextManager | null = null;
6
7
  const activeSessions = new Set<string>();
7
8
  let lastRuntimeError: { scope: string; message: string; timestamp: Date } | null = null;
8
9
 
9
10
  type FallbackObservationType = "SPAN" | "GENERATION";
10
11
 
12
+ interface OtelContextManager {
13
+ enable(): OtelContextManager;
14
+ disable(): void;
15
+ }
16
+
17
+ interface OtelContextApi {
18
+ setGlobalContextManager(contextManager: OtelContextManager): boolean;
19
+ }
20
+
21
+ type AsyncHooksContextManagerCtor = new () => OtelContextManager;
22
+
11
23
  interface RestFallbackTrace {
12
24
  id: string;
13
25
  timestamp: string;
@@ -65,6 +77,24 @@ function debugLog(message: string) {
65
77
  }
66
78
  }
67
79
 
80
+ export function ensureOtelContextManager(
81
+ contextApi: OtelContextApi,
82
+ AsyncHooksContextManager: AsyncHooksContextManagerCtor,
83
+ ): boolean {
84
+ if (registeredContextManager) {
85
+ return true;
86
+ }
87
+
88
+ const contextManager = new AsyncHooksContextManager().enable();
89
+ if (contextApi.setGlobalContextManager(contextManager)) {
90
+ registeredContextManager = contextManager;
91
+ return true;
92
+ }
93
+
94
+ contextManager.disable();
95
+ return false;
96
+ }
97
+
68
98
  function rememberRuntimeError(scope: string, error: unknown) {
69
99
  lastRuntimeError = {
70
100
  scope,
@@ -372,8 +402,17 @@ export async function getRuntime(): Promise<LangfuseRuntime> {
372
402
  }
373
403
 
374
404
  if (!runtime) {
375
- const [{ BasicTracerProvider }, { LangfuseSpanProcessor }, tracing, { LangfuseClient }] = await Promise.all([
405
+ const [
406
+ { BasicTracerProvider },
407
+ { context },
408
+ { AsyncHooksContextManager },
409
+ { LangfuseSpanProcessor },
410
+ tracing,
411
+ { LangfuseClient },
412
+ ] = await Promise.all([
376
413
  import("@opentelemetry/sdk-trace-base"),
414
+ import("@opentelemetry/api"),
415
+ import("@opentelemetry/context-async-hooks"),
377
416
  import("@langfuse/otel"),
378
417
  import("@langfuse/tracing"),
379
418
  import("@langfuse/client"),
@@ -386,6 +425,7 @@ export async function getRuntime(): Promise<LangfuseRuntime> {
386
425
  };
387
426
 
388
427
  try {
428
+ ensureOtelContextManager(context, AsyncHooksContextManager);
389
429
  const spanProcessor = new LangfuseSpanProcessor({
390
430
  publicKey: state.config.publicKey,
391
431
  secretKey: state.config.secretKey,