pi-langfuse 1.5.8 → 1.5.9
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 +8 -0
- package/README_CN.md +8 -0
- package/index.ts +5 -5
- package/package.json +1 -1
- package/src/langfuse.ts +17 -1
package/README.md
CHANGED
|
@@ -77,6 +77,14 @@ export LANGFUSE_BASE_URL="https://cloud.langfuse.com" # optional; LANGFUSE_HOST
|
|
|
77
77
|
|
|
78
78
|
Saved config takes precedence. Environment variables are only used when `~/.pi/agent/pi-langfuse/config.json` is missing or incomplete.
|
|
79
79
|
|
|
80
|
+
For short-lived SDK hosts, set the bounded final score-delivery attempt during shutdown:
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
export PI_LANGFUSE_SCORE_SHUTDOWN_TIMEOUT=2 # seconds; defaults to 2 seconds
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
The extension attempts queued trace-level scores before other shutdown telemetry work. This value cannot extend the overall shutdown deadline.
|
|
87
|
+
|
|
80
88
|
Privacy controls can also be set through environment variables:
|
|
81
89
|
|
|
82
90
|
```bash
|
package/README_CN.md
CHANGED
|
@@ -77,6 +77,14 @@ export LANGFUSE_BASE_URL="https://cloud.langfuse.com" # 可选;也支持 LANG
|
|
|
77
77
|
|
|
78
78
|
保存的配置优先级更高。只有当 `~/.pi/agent/pi-langfuse/config.json` 缺失或不完整时,扩展才会使用环境变量。
|
|
79
79
|
|
|
80
|
+
对于短生命周期的 SDK 宿主,可设置关闭时最终分数发送尝试的上限:
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
export PI_LANGFUSE_SCORE_SHUTDOWN_TIMEOUT=2 # 单位为秒;默认 2 秒
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
扩展会在其他关闭遥测工作之前尝试发送已排队的 trace 级分数。该值不会延长总关闭超时。
|
|
87
|
+
|
|
80
88
|
隐私采集策略也可以通过环境变量设置:
|
|
81
89
|
|
|
82
90
|
```bash
|
package/index.ts
CHANGED
|
@@ -159,11 +159,11 @@ export default async function (pi: ExtensionAPI) {
|
|
|
159
159
|
pi.on("agent_end", async (event, ctx) => withSession(ctx, async () => {
|
|
160
160
|
await finishAgentRun(event);
|
|
161
161
|
const sessionId = state.currentSessionId;
|
|
162
|
-
|
|
163
|
-
shutdownRuntime(sessionId)
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
}
|
|
162
|
+
try {
|
|
163
|
+
await shutdownRuntime(sessionId);
|
|
164
|
+
} catch (error) {
|
|
165
|
+
console.warn("📊 Langfuse: Shutdown failed", error);
|
|
166
|
+
}
|
|
167
167
|
}));
|
|
168
168
|
|
|
169
169
|
const handleSessionInterruption = (reason: string) => {
|
package/package.json
CHANGED
package/src/langfuse.ts
CHANGED
|
@@ -60,6 +60,7 @@ interface RestFallbackStore {
|
|
|
60
60
|
const OTEL_VISIBILITY_TIMEOUT_MS = 1_500;
|
|
61
61
|
const OTEL_VISIBILITY_POLL_INTERVAL_MS = 200;
|
|
62
62
|
const DEFAULT_SHUTDOWN_STEP_TIMEOUT_MS = 2_000;
|
|
63
|
+
const DEFAULT_SCORE_SHUTDOWN_TIMEOUT_MS = 2_000;
|
|
63
64
|
const DEFAULT_LANGFUSE_REQUEST_TIMEOUT_SECONDS = 5;
|
|
64
65
|
const DEFAULT_SCORE_FLUSH_AT = 10;
|
|
65
66
|
const DEFAULT_SCORE_FLUSH_INTERVAL_MS = 1_000;
|
|
@@ -80,6 +81,13 @@ function resolvePositiveEnvNumber(name: string, fallback: number, integer = fals
|
|
|
80
81
|
return integer ? Math.floor(parsed) : parsed;
|
|
81
82
|
}
|
|
82
83
|
|
|
84
|
+
function getScoreShutdownTimeoutMs(): number {
|
|
85
|
+
return resolvePositiveEnvNumber(
|
|
86
|
+
"PI_LANGFUSE_SCORE_SHUTDOWN_TIMEOUT",
|
|
87
|
+
DEFAULT_SCORE_SHUTDOWN_TIMEOUT_MS / 1_000,
|
|
88
|
+
) * 1_000;
|
|
89
|
+
}
|
|
90
|
+
|
|
83
91
|
function delay(ms: number, signal?: AbortSignal) {
|
|
84
92
|
return new Promise<void>((resolve, reject) => {
|
|
85
93
|
if (signal?.aborted) {
|
|
@@ -642,6 +650,12 @@ function doShutdownRuntime(): Promise<void> {
|
|
|
642
650
|
const deadline = Date.now() + shutdownStepTimeoutMs;
|
|
643
651
|
const controller = new AbortController();
|
|
644
652
|
const abortTimeout = setTimeout(() => controller.abort(), shutdownStepTimeoutMs);
|
|
653
|
+
const scoreController = new AbortController();
|
|
654
|
+
const scoreAbortTimeout = setTimeout(
|
|
655
|
+
() => scoreController.abort(),
|
|
656
|
+
Math.min(getScoreShutdownTimeoutMs(), shutdownStepTimeoutMs),
|
|
657
|
+
);
|
|
658
|
+
scoreAbortTimeout.unref?.();
|
|
645
659
|
stopScoreFlush(rt);
|
|
646
660
|
|
|
647
661
|
try {
|
|
@@ -650,13 +664,13 @@ function doShutdownRuntime(): Promise<void> {
|
|
|
650
664
|
() => rt.scoreFlushPromise,
|
|
651
665
|
deadline,
|
|
652
666
|
);
|
|
667
|
+
await flushPendingScores(rt, scoreController.signal);
|
|
653
668
|
await withShutdownDeadline("OTel force flush", () => rt.tracerProvider?.forceFlush?.(), deadline);
|
|
654
669
|
await withShutdownDeadline(
|
|
655
670
|
"REST fallback ingestion",
|
|
656
671
|
() => fallbackToRestIngestion(rt, controller.signal),
|
|
657
672
|
deadline,
|
|
658
673
|
);
|
|
659
|
-
await flushPendingScores(rt, controller.signal);
|
|
660
674
|
await withShutdownDeadline("Langfuse score flush", () => rt.scoreClient.flush?.(), deadline);
|
|
661
675
|
await withShutdownDeadline("Langfuse client shutdown", () => rt.scoreClient.shutdown?.(), deadline);
|
|
662
676
|
await withShutdownDeadline("OTel tracer shutdown", () => rt.tracerProvider?.shutdown?.(), deadline);
|
|
@@ -665,6 +679,8 @@ function doShutdownRuntime(): Promise<void> {
|
|
|
665
679
|
console.warn("📊 Langfuse: Failed to flush/shutdown cleanly", e);
|
|
666
680
|
} finally {
|
|
667
681
|
clearTimeout(abortTimeout);
|
|
682
|
+
clearTimeout(scoreAbortTimeout);
|
|
683
|
+
scoreController.abort();
|
|
668
684
|
clearScoreFlushTimer(rt);
|
|
669
685
|
rt.scoreFlushController?.abort();
|
|
670
686
|
rt.scoreFlushController = undefined;
|