@narumitw/pi-langfuse 0.51.2 → 0.52.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 +46 -3
- package/dist/chunks/chunk-N7WSLB5Q.ts +88 -0
- package/dist/chunks/chunk-N7WSLB5Q.ts.map +7 -0
- package/dist/chunks/{runtime-6ZHLVC3A.ts → runtime-GLRAF7FE.ts} +2 -2
- package/dist/chunks/runtime-GLRAF7FE.ts.map +7 -0
- package/dist/config.d.ts +1 -1
- package/dist/durable-projection.d.ts +9 -0
- package/dist/durable-recorder.d.ts +49 -0
- package/dist/durable.d.ts +25 -0
- package/dist/durable.js +638 -0
- package/dist/durable.js.map +7 -0
- package/dist/index.js +248 -159
- package/dist/index.js.map +4 -4
- package/dist/index.ts +244 -16
- package/dist/index.ts.map +4 -4
- package/dist/library-chunks/chunk-B64FXCNE.js +84 -0
- package/dist/library-chunks/chunk-B64FXCNE.js.map +7 -0
- package/dist/library-chunks/chunk-ETFOPFEP.js +10 -0
- package/dist/library-chunks/chunk-ETFOPFEP.js.map +7 -0
- package/dist/library-chunks/chunk-JPFN6GGS.js +153 -0
- package/dist/library-chunks/chunk-JPFN6GGS.js.map +7 -0
- package/dist/library-chunks/{runtime-A6SQ6VEH.js → runtime-6KYOZVOE.js} +5 -3
- package/dist/library-chunks/runtime-6KYOZVOE.js.map +7 -0
- package/dist/public-api.d.ts +1 -3
- package/dist/runtime-api.d.ts +3 -0
- package/dist/runtime-defaults.d.ts +1 -0
- package/dist/runtime.d.ts +1 -1
- package/dist/sanitizer.d.ts +1 -1
- package/docs/durable.md +126 -0
- package/package.json +22 -2
- package/src/config.ts +4 -1
- package/src/durable-projection.ts +106 -0
- package/src/durable-recorder.ts +493 -0
- package/src/durable.ts +195 -0
- package/src/public-api.ts +6 -12
- package/src/runtime-api.ts +8 -0
- package/src/runtime-core.ts +2 -1
- package/src/runtime-defaults.ts +1 -0
- package/src/runtime.ts +2 -1
- package/src/sanitizer.ts +16 -4
- package/dist/chunks/chunk-DBQAWNKG.ts +0 -316
- package/dist/chunks/chunk-DBQAWNKG.ts.map +0 -7
- package/dist/chunks/runtime-6ZHLVC3A.ts.map +0 -7
- package/dist/library-chunks/chunk-SAJ76IYU.js +0 -316
- package/dist/library-chunks/chunk-SAJ76IYU.js.map +0 -7
- package/dist/library-chunks/runtime-A6SQ6VEH.js.map +0 -7
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../src/runtime.ts"],
|
|
4
|
-
"sourcesContent": ["import { createHash } from \"node:crypto\";\nimport { LangfuseSpanProcessor } from \"@langfuse/otel\";\nimport {\n type LangfuseObservation,\n type LangfuseObservationAttributes,\n LangfuseOtelSpanAttributes,\n setLangfuseTracerProvider,\n startObservation,\n} from \"@langfuse/tracing\";\nimport type { SpanProcessor } from \"@opentelemetry/sdk-trace-base\";\nimport { NodeTracerProvider } from \"@opentelemetry/sdk-trace-node\";\nimport { DEFAULT_BASE_URL, type LangfuseConfig } from \"./config.js\";\nimport {\n type CreateLangfuseRuntimeOptions,\n createLangfuseRuntimeFromBackend,\n getLangfuseRuntimeInternal,\n type LangfuseRuntime,\n type LangfuseRuntimeInternal,\n} from \"./runtime-core.js\";\nimport type { Observation, ObservationAttributes, ObservationType, TraceBackend } from \"./tracing.js\";\n\nexport type {\n CreateLangfuseRuntimeOptions,\n LangfuseRuntime,\n LangfuseRuntimeConfig,\n} from \"./runtime-core.js\";\n\nconst RUNTIME_KEY = Symbol.for(\"@narumitw/pi-langfuse/runtime/v2\");\nconst LEGACY_RUNTIME_KEY = Symbol.for(\"@narumitw/pi-langfuse/runtime/v1\");\n\ninterface ResolvedRuntimeConfig {\n publicKey: string;\n secretKey: string;\n baseUrl: string;\n environment?: string;\n release?: string;\n}\n\ninterface SharedRuntime {\n fingerprint: string;\n runtime: LangfuseRuntimeInternal;\n shutdown: true;\n}\n\ntype GlobalWithRuntime = typeof globalThis & {\n [RUNTIME_KEY]?: Promise<SharedRuntime>;\n [LEGACY_RUNTIME_KEY]?: unknown;\n};\n\nexport interface RuntimeFactories {\n createProcessor(config: ResolvedRuntimeConfig): SpanProcessor;\n createProvider(processor: SpanProcessor): NodeTracerProvider;\n selectProvider(provider: NodeTracerProvider): void;\n}\n\nclass ProductionObservation implements Observation {\n readonly traceId: string;\n\n constructor(\n readonly native: LangfuseObservation,\n private readonly secrets: readonly string[],\n ) {\n this.traceId = native.traceId;\n }\n\n update(attributes: ObservationAttributes): Observation {\n const { sessionId, userId, ...observationAttributes } = maskObservationAttributes(attributes, this.secrets);\n this.native.updateOtelSpanAttributes(observationAttributes as LangfuseObservationAttributes);\n applySessionId(this.native, sessionId);\n applyUserId(this.native, userId);\n return this;\n }\n\n updateTrace(attributes: ObservationAttributes): Observation {\n const { input, output, metadata, name, sessionId, userId, tags, version } = maskObservationAttributes(\n attributes,\n this.secrets,\n );\n if (input !== undefined || output !== undefined) {\n this.native.setTraceIO({ input, output });\n }\n if (name !== undefined) {\n this.native.otelSpan.setAttribute(LangfuseOtelSpanAttributes.TRACE_NAME, name);\n }\n applySessionId(this.native, sessionId);\n applyUserId(this.native, userId);\n if (tags !== undefined) {\n this.native.otelSpan.setAttribute(LangfuseOtelSpanAttributes.TRACE_TAGS, tags);\n }\n if (version !== undefined) {\n this.native.otelSpan.setAttribute(LangfuseOtelSpanAttributes.VERSION, version);\n }\n for (const [key, value] of Object.entries(metadata ?? {})) {\n const serialized = serializeMetadataValue(value);\n if (serialized !== undefined) {\n this.native.otelSpan.setAttribute(`${LangfuseOtelSpanAttributes.TRACE_METADATA}.${key}`, serialized);\n }\n }\n return this;\n }\n\n end(endTime?: number): Observation {\n this.native.end(endTime);\n return this;\n }\n}\n\nclass ProductionTraceBackend implements TraceBackend {\n constructor(\n private readonly provider: NodeTracerProvider,\n private readonly processor: SpanProcessor,\n private readonly secrets: readonly string[],\n ) {}\n\n start(\n name: string,\n attributes: ObservationAttributes,\n options: { asType: ObservationType; parent?: Observation; startTime?: Date },\n ): Observation {\n const maskedName = maskSecretString(name, this.secrets);\n const { sessionId, userId, ...observationAttributes } = maskObservationAttributes(attributes, this.secrets);\n const parent = options.parent;\n const native =\n parent instanceof ProductionObservation\n ? startChild(parent.native, maskedName, observationAttributes, options.asType, options.startTime)\n : startRoot(maskedName, observationAttributes, options.asType, options.startTime);\n applySessionId(native, sessionId);\n applyUserId(native, userId);\n return new ProductionObservation(native, this.secrets);\n }\n\n async forceFlush(): Promise<void> {\n await this.processor.forceFlush();\n }\n\n async shutdown(): Promise<void> {\n await this.provider.shutdown();\n }\n}\n\nexport async function createLangfuseRuntime(options: CreateLangfuseRuntimeOptions = {}): Promise<LangfuseRuntime> {\n return createSharedRuntime(resolveLangfuseRuntimeConfig(options), defaultFactories);\n}\n\nexport async function createProductionBackend(\n config: LangfuseConfig,\n factoryOverrides: Partial<RuntimeFactories> = {},\n): Promise<TraceBackend> {\n const runtime = await createSharedRuntime(resolveLangfuseRuntimeConfig({ config, env: false }), {\n ...defaultFactories,\n ...factoryOverrides,\n });\n return getLangfuseRuntimeInternal(runtime).backend;\n}\n\nasync function createSharedRuntime(\n config: ResolvedRuntimeConfig,\n factories: RuntimeFactories,\n): Promise<LangfuseRuntime> {\n const globalRuntime = globalThis as GlobalWithRuntime;\n const fingerprint = configFingerprint(config);\n const existing = globalRuntime[RUNTIME_KEY];\n const legacyRuntime = globalRuntime[LEGACY_RUNTIME_KEY];\n if (legacyRuntime !== undefined && legacyRuntime !== existing) {\n throw new Error(\"An older Langfuse runtime is already loaded; restart the process before enabling this version.\");\n }\n if (existing) {\n if (legacyRuntime === undefined) globalRuntime[LEGACY_RUNTIME_KEY] = existing;\n const shared = await existing;\n if (shared.runtime.closed) {\n throw new Error(\"Langfuse tracing was already shut down; restart the process to enable it again.\");\n }\n if (shared.fingerprint !== fingerprint) {\n throw new Error(\"Langfuse configuration changed; restart the process to apply the new credentials.\");\n }\n return shared.runtime;\n }\n\n const initializing = initializeRuntime(config, fingerprint, factories);\n globalRuntime[RUNTIME_KEY] = initializing;\n globalRuntime[LEGACY_RUNTIME_KEY] = initializing;\n try {\n return (await initializing).runtime;\n } catch (error) {\n if (globalRuntime[RUNTIME_KEY] === initializing) delete globalRuntime[RUNTIME_KEY];\n if (globalRuntime[LEGACY_RUNTIME_KEY] === initializing) delete globalRuntime[LEGACY_RUNTIME_KEY];\n throw error;\n }\n}\n\nasync function initializeRuntime(\n config: ResolvedRuntimeConfig,\n fingerprint: string,\n factories: RuntimeFactories,\n): Promise<SharedRuntime> {\n const processor = factories.createProcessor(config);\n let provider: NodeTracerProvider | undefined;\n try {\n provider = factories.createProvider(processor);\n factories.selectProvider(provider);\n } catch (error) {\n await (provider?.shutdown() ?? processor.shutdown()).catch(() => undefined);\n throw error;\n }\n const runtime = getLangfuseRuntimeInternal(\n createLangfuseRuntimeFromBackend(\n new ProductionTraceBackend(provider, processor, [config.publicKey, config.secretKey]),\n ),\n );\n return { fingerprint, runtime, shutdown: true };\n}\n\nconst defaultFactories: RuntimeFactories = {\n createProcessor: (config) => {\n const secrets = [config.secretKey, config.publicKey];\n return new LangfuseSpanProcessor({\n publicKey: config.publicKey,\n secretKey: config.secretKey,\n baseUrl: config.baseUrl,\n environment: config.environment ?? \"\",\n release: config.release ?? \"\",\n flushAt: 512,\n flushInterval: 5,\n timeout: 5,\n mask: ({ data }) => maskSecrets(data, secrets),\n shouldExportSpan: ({ otelSpan }) => typeof otelSpan.attributes[\"langfuse.observation.type\"] === \"string\",\n });\n },\n createProvider: (processor) => new NodeTracerProvider({ spanProcessors: [processor] }),\n selectProvider: setLangfuseTracerProvider,\n};\n\nexport function resolveLangfuseRuntimeConfig(options: CreateLangfuseRuntimeOptions): ResolvedRuntimeConfig {\n const env = options.env === false ? undefined : (options.env ?? process.env);\n const publicKey = requiredSetting(\"publicKey\", options.config?.publicKey, env?.LANGFUSE_PUBLIC_KEY);\n const secretKey = requiredSetting(\"secretKey\", options.config?.secretKey, env?.LANGFUSE_SECRET_KEY);\n const explicitBaseUrl = options.config?.baseUrl;\n if (explicitBaseUrl !== undefined && !normalizeString(explicitBaseUrl)) {\n throw new Error(\"Langfuse baseUrl must be a non-empty string.\");\n }\n const rawBaseUrl = selectedSetting(explicitBaseUrl, env?.LANGFUSE_BASE_URL) ?? DEFAULT_BASE_URL;\n const baseUrl = normalizeBaseUrl(rawBaseUrl);\n if (!baseUrl) {\n throw new Error(\"Langfuse baseUrl must use HTTP or HTTPS without credentials, a query, or a fragment.\");\n }\n const environment = optionalSetting(\"environment\", options.config?.environment, env?.LANGFUSE_TRACING_ENVIRONMENT);\n if (environment && (environment.length > 40 || !/^(?!langfuse)[a-z0-9_-]+$/u.test(environment))) {\n throw new Error(\n \"Langfuse environment must be at most 40 lowercase letters, numbers, hyphens, or underscores and must not start with langfuse.\",\n );\n }\n const release = optionalSetting(\"release\", options.config?.release, env?.LANGFUSE_RELEASE);\n return { publicKey, secretKey, baseUrl, ...(environment ? { environment } : {}), ...(release ? { release } : {}) };\n}\n\nfunction requiredSetting(name: string, explicit: string | undefined, environment: string | undefined): string {\n const value = selectedSetting(explicit, environment);\n if (!value) throw new Error(`Langfuse ${name} is required.`);\n return value;\n}\n\nfunction optionalSetting(\n name: string,\n explicit: string | undefined,\n environment: string | undefined,\n): string | undefined {\n const selected = explicit !== undefined ? explicit : environment;\n if (selected === undefined) return undefined;\n const value = normalizeString(selected);\n if (!value) throw new Error(`Langfuse ${name} must be a non-empty string.`);\n return value;\n}\n\nfunction selectedSetting(explicit: string | undefined, environment: string | undefined): string | undefined {\n if (explicit !== undefined) return normalizeString(explicit);\n return normalizeString(environment);\n}\n\nfunction normalizeBaseUrl(value: string): string | undefined {\n try {\n const url = new URL(value);\n if (url.protocol !== \"http:\" && url.protocol !== \"https:\") return undefined;\n if (url.username || url.password || url.search || url.hash) return undefined;\n return url.toString().replace(/\\/+$/, \"\");\n } catch {\n return undefined;\n }\n}\n\nfunction normalizeString(value: unknown): string | undefined {\n return typeof value === \"string\" && value.trim() ? value.trim() : undefined;\n}\n\nfunction serializeMetadataValue(value: unknown): string | undefined {\n return typeof value === \"string\" ? value : JSON.stringify(value);\n}\n\nfunction maskObservationAttributes(\n attributes: ObservationAttributes,\n secrets: readonly string[],\n): ObservationAttributes {\n return {\n ...attributes,\n ...(attributes.metadata ? { metadata: maskSecrets(attributes.metadata, secrets) as Record<string, unknown> } : {}),\n ...(attributes.name ? { name: maskSecretString(attributes.name, secrets) } : {}),\n ...(attributes.sessionId ? { sessionId: maskSecretString(attributes.sessionId, secrets) } : {}),\n ...(attributes.userId ? { userId: maskSecretString(attributes.userId, secrets) } : {}),\n ...(attributes.tags ? { tags: attributes.tags.map((tag) => maskSecretString(tag, secrets)) } : {}),\n ...(attributes.statusMessage ? { statusMessage: maskSecretString(attributes.statusMessage, secrets) } : {}),\n ...(attributes.model ? { model: maskSecretString(attributes.model, secrets) } : {}),\n ...(attributes.version ? { version: maskSecretString(attributes.version, secrets) } : {}),\n ...(attributes.modelParameters\n ? {\n modelParameters: Object.fromEntries(\n Object.entries(attributes.modelParameters).map(([key, value]) => [\n maskSecretString(key, secrets),\n typeof value === \"string\" ? maskSecretString(value, secrets) : value,\n ]),\n ),\n }\n : {}),\n };\n}\n\nfunction maskSecretString(value: string, secrets: readonly string[]): string {\n return maskSecrets(value, secrets) as string;\n}\n\nfunction applySessionId(observation: LangfuseObservation, sessionId: string | undefined): void {\n if (sessionId !== undefined) {\n observation.otelSpan.setAttribute(LangfuseOtelSpanAttributes.TRACE_SESSION_ID, sessionId);\n }\n}\n\nfunction applyUserId(observation: LangfuseObservation, userId: string | undefined): void {\n if (userId !== undefined) {\n observation.otelSpan.setAttribute(LangfuseOtelSpanAttributes.TRACE_USER_ID, userId);\n }\n}\n\nfunction startRoot(\n name: string,\n attributes: ObservationAttributes,\n type: ObservationType,\n startTime?: Date,\n): LangfuseObservation {\n if (type === \"agent\") {\n return startObservation(name, attributes as LangfuseObservationAttributes, { asType: \"agent\", startTime });\n }\n if (type === \"generation\") {\n return startObservation(name, attributes as LangfuseObservationAttributes, {\n asType: \"generation\",\n startTime,\n });\n }\n if (type === \"tool\") {\n return startObservation(name, attributes as LangfuseObservationAttributes, { asType: \"tool\", startTime });\n }\n return startObservation(name, attributes as LangfuseObservationAttributes, { asType: \"span\", startTime });\n}\n\nfunction startChild(\n parent: LangfuseObservation,\n name: string,\n attributes: ObservationAttributes,\n type: ObservationType,\n startTime?: Date,\n): LangfuseObservation {\n if (startTime) {\n const parentSpanContext = parent.otelSpan.spanContext();\n if (type === \"agent\") {\n return startObservation(name, attributes as LangfuseObservationAttributes, {\n asType: \"agent\",\n parentSpanContext,\n startTime,\n });\n }\n if (type === \"generation\") {\n return startObservation(name, attributes as LangfuseObservationAttributes, {\n asType: \"generation\",\n parentSpanContext,\n startTime,\n });\n }\n if (type === \"tool\") {\n return startObservation(name, attributes as LangfuseObservationAttributes, {\n asType: \"tool\",\n parentSpanContext,\n startTime,\n });\n }\n return startObservation(name, attributes as LangfuseObservationAttributes, {\n asType: \"span\",\n parentSpanContext,\n startTime,\n });\n }\n if (type === \"agent\") {\n return parent.startObservation(name, attributes as LangfuseObservationAttributes, { asType: \"agent\" });\n }\n if (type === \"generation\") {\n return parent.startObservation(name, attributes as LangfuseObservationAttributes, { asType: \"generation\" });\n }\n if (type === \"tool\") {\n return parent.startObservation(name, attributes as LangfuseObservationAttributes, { asType: \"tool\" });\n }\n return parent.startObservation(name, attributes as LangfuseObservationAttributes, { asType: \"span\" });\n}\n\nfunction configFingerprint(config: ResolvedRuntimeConfig): string {\n return createHash(\"sha256\")\n .update(\n `${config.publicKey}\\0${config.secretKey}\\0${config.baseUrl}\\0${config.environment ?? \"\"}\\0${config.release ?? \"\"}`,\n )\n .digest(\"hex\");\n}\n\nexport function maskSecrets(data: unknown, secrets: readonly string[]): unknown {\n return maskSecretValue(data, secrets, new WeakSet<object>());\n}\n\nfunction maskSecretValue(data: unknown, secrets: readonly string[], active: WeakSet<object>): unknown {\n if (typeof data === \"string\") {\n let masked = data.replace(/\\b(?:sk|pk)-lf-[A-Za-z0-9_-]+\\b/g, \"[LANGFUSE_KEY_REDACTED]\");\n for (const secret of secrets) {\n if (secret) masked = masked.replaceAll(secret, \"[LANGFUSE_KEY_REDACTED]\");\n }\n return masked;\n }\n if (!data || typeof data !== \"object\") return data;\n if (active.has(data)) return \"[circular]\";\n\n active.add(data);\n try {\n if (Array.isArray(data)) {\n return data.map((item) => maskSecretValue(item, secrets, active));\n }\n return Object.fromEntries(\n Object.entries(data).map(([key, value]) => [\n maskSecretString(key, secrets),\n maskSecretValue(value, secrets, active),\n ]),\n );\n } finally {\n active.delete(data);\n }\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
6
|
-
"names": []
|
|
7
|
-
}
|
|
@@ -1,316 +0,0 @@
|
|
|
1
|
-
// @generated by scripts/build-runtime.mjs; do not edit.
|
|
2
|
-
// @ts-nocheck -- the generated entry uses a .ts extension for Pi's Jiti loader.
|
|
3
|
-
|
|
4
|
-
// src/config.ts
|
|
5
|
-
import { randomUUID } from "node:crypto";
|
|
6
|
-
import { chmod, mkdir, readFile, rename, rm, stat, writeFile } from "node:fs/promises";
|
|
7
|
-
import { dirname, join } from "node:path";
|
|
8
|
-
import { getAgentDir } from "@earendil-works/pi-coding-agent";
|
|
9
|
-
var CONFIG_FILE_NAME = "pi-langfuse.json";
|
|
10
|
-
var DEFAULT_BASE_URL = "https://us.cloud.langfuse.com";
|
|
11
|
-
function langfuseConfigPath() {
|
|
12
|
-
return join(getAgentDir(), CONFIG_FILE_NAME);
|
|
13
|
-
}
|
|
14
|
-
var configSaveQueues = /* @__PURE__ */ new Map();
|
|
15
|
-
function writeLangfuseConfig(patch, path = langfuseConfigPath()) {
|
|
16
|
-
const previous = configSaveQueues.get(path) ?? Promise.resolve();
|
|
17
|
-
const operation = previous.then(() => writeLangfuseConfigNow(patch, path));
|
|
18
|
-
const tail = operation.then(
|
|
19
|
-
() => void 0,
|
|
20
|
-
() => void 0
|
|
21
|
-
);
|
|
22
|
-
configSaveQueues.set(path, tail);
|
|
23
|
-
void tail.then(() => {
|
|
24
|
-
if (configSaveQueues.get(path) === tail) configSaveQueues.delete(path);
|
|
25
|
-
});
|
|
26
|
-
return operation;
|
|
27
|
-
}
|
|
28
|
-
async function writeLangfuseConfigNow(patch, path) {
|
|
29
|
-
const currentDocument = await readLangfuseDocumentForUpdate(path);
|
|
30
|
-
const normalized = normalizeLangfuseConfig({ ...currentDocument, ...patch });
|
|
31
|
-
if (!normalized.ok) throw new Error(normalized.reason);
|
|
32
|
-
const {
|
|
33
|
-
publicKey: _publicKey,
|
|
34
|
-
secretKey: _secretKey,
|
|
35
|
-
baseUrl: _baseUrl,
|
|
36
|
-
environment: _environment,
|
|
37
|
-
release: _release,
|
|
38
|
-
userId: _userId,
|
|
39
|
-
captureContent: _captureContent,
|
|
40
|
-
...unknownFields
|
|
41
|
-
} = currentDocument;
|
|
42
|
-
const nextDocument = { ...unknownFields, ...normalized.config };
|
|
43
|
-
await mkdir(dirname(path), { recursive: true, mode: 448 });
|
|
44
|
-
const tempPath = `${path}.${process.pid}.${randomUUID()}.tmp`;
|
|
45
|
-
try {
|
|
46
|
-
await writeFile(tempPath, `${JSON.stringify(nextDocument, null, 2)}
|
|
47
|
-
`, {
|
|
48
|
-
encoding: "utf8",
|
|
49
|
-
mode: 384
|
|
50
|
-
});
|
|
51
|
-
await chmod(tempPath, 384);
|
|
52
|
-
await rename(tempPath, path);
|
|
53
|
-
return normalized.config;
|
|
54
|
-
} catch (error) {
|
|
55
|
-
await rm(tempPath, { force: true }).catch(() => void 0);
|
|
56
|
-
throw error;
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
async function readLangfuseDocumentForUpdate(path) {
|
|
60
|
-
let parsed;
|
|
61
|
-
try {
|
|
62
|
-
parsed = JSON.parse(await readFile(path, "utf8"));
|
|
63
|
-
} catch (error) {
|
|
64
|
-
if (isNodeError(error) && error.code === "ENOENT") return {};
|
|
65
|
-
throw new Error(
|
|
66
|
-
`Cannot update ${CONFIG_FILE_NAME} because the existing file is malformed or unreadable; repair it first.`
|
|
67
|
-
);
|
|
68
|
-
}
|
|
69
|
-
const normalized = normalizeLangfuseConfig(parsed);
|
|
70
|
-
if (!normalized.ok) {
|
|
71
|
-
throw new Error(
|
|
72
|
-
`Cannot update ${CONFIG_FILE_NAME} because the existing file has invalid recognized fields; repair it first.`
|
|
73
|
-
);
|
|
74
|
-
}
|
|
75
|
-
return { ...parsed };
|
|
76
|
-
}
|
|
77
|
-
async function loadLangfuseConfig(path = langfuseConfigPath()) {
|
|
78
|
-
await configSaveQueues.get(path);
|
|
79
|
-
const warnings = [];
|
|
80
|
-
const permissionFailure = await ensurePrivatePermissions(path, warnings);
|
|
81
|
-
if (permissionFailure) {
|
|
82
|
-
return {
|
|
83
|
-
ok: false,
|
|
84
|
-
path,
|
|
85
|
-
warnings,
|
|
86
|
-
reason: `Refusing to load credentials: ${permissionFailure}`
|
|
87
|
-
};
|
|
88
|
-
}
|
|
89
|
-
let text;
|
|
90
|
-
try {
|
|
91
|
-
text = await readFile(path, "utf8");
|
|
92
|
-
} catch (error) {
|
|
93
|
-
if (isNodeError(error) && error.code === "ENOENT") {
|
|
94
|
-
return { ok: false, path, warnings, reason: `Configuration file not found: ${path}` };
|
|
95
|
-
}
|
|
96
|
-
return {
|
|
97
|
-
ok: false,
|
|
98
|
-
path,
|
|
99
|
-
warnings,
|
|
100
|
-
reason: `Failed to read ${path}: ${formatError(error)}`
|
|
101
|
-
};
|
|
102
|
-
}
|
|
103
|
-
let parsed;
|
|
104
|
-
try {
|
|
105
|
-
parsed = JSON.parse(text);
|
|
106
|
-
} catch {
|
|
107
|
-
return {
|
|
108
|
-
ok: false,
|
|
109
|
-
path,
|
|
110
|
-
warnings,
|
|
111
|
-
reason: `Failed to parse ${path} as JSON; repair the file before retrying.`
|
|
112
|
-
};
|
|
113
|
-
}
|
|
114
|
-
const normalized = normalizeLangfuseConfig(parsed);
|
|
115
|
-
if (!normalized.ok) return { ok: false, path, warnings, reason: normalized.reason };
|
|
116
|
-
return { ok: true, config: normalized.config, path, warnings };
|
|
117
|
-
}
|
|
118
|
-
function normalizeLangfuseConfig(value) {
|
|
119
|
-
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
120
|
-
return { ok: false, reason: "pi-langfuse.json must contain a JSON object." };
|
|
121
|
-
}
|
|
122
|
-
const input = value;
|
|
123
|
-
const publicKey = normalizeString(input.publicKey);
|
|
124
|
-
const secretKey = normalizeString(input.secretKey);
|
|
125
|
-
if (!publicKey) {
|
|
126
|
-
return { ok: false, reason: "pi-langfuse.json requires a literal publicKey string." };
|
|
127
|
-
}
|
|
128
|
-
if (!secretKey) {
|
|
129
|
-
return { ok: false, reason: "pi-langfuse.json requires a literal secretKey string." };
|
|
130
|
-
}
|
|
131
|
-
if (isInterpolation(publicKey)) {
|
|
132
|
-
return {
|
|
133
|
-
ok: false,
|
|
134
|
-
reason: "pi-langfuse.json publicKey must be literal; environment and command interpolation are not supported."
|
|
135
|
-
};
|
|
136
|
-
}
|
|
137
|
-
if (isInterpolation(secretKey)) {
|
|
138
|
-
return {
|
|
139
|
-
ok: false,
|
|
140
|
-
reason: "pi-langfuse.json secretKey must be literal; environment and command interpolation are not supported."
|
|
141
|
-
};
|
|
142
|
-
}
|
|
143
|
-
const rawBaseUrl = input.baseUrl === void 0 ? DEFAULT_BASE_URL : normalizeString(input.baseUrl);
|
|
144
|
-
if (!rawBaseUrl) {
|
|
145
|
-
return { ok: false, reason: "pi-langfuse.json baseUrl must be a non-empty string." };
|
|
146
|
-
}
|
|
147
|
-
const baseUrl = normalizeBaseUrl(rawBaseUrl);
|
|
148
|
-
if (!baseUrl) {
|
|
149
|
-
return {
|
|
150
|
-
ok: false,
|
|
151
|
-
reason: "pi-langfuse.json baseUrl must use HTTP or HTTPS without credentials, a query, or a fragment."
|
|
152
|
-
};
|
|
153
|
-
}
|
|
154
|
-
if (input.captureContent !== void 0 && typeof input.captureContent !== "boolean") {
|
|
155
|
-
return { ok: false, reason: "pi-langfuse.json captureContent must be a boolean." };
|
|
156
|
-
}
|
|
157
|
-
const environment = optionalString(input.environment, "environment");
|
|
158
|
-
if (!environment.ok) return environment;
|
|
159
|
-
if (environment.value && (environment.value.length > 40 || !/^(?!langfuse)[a-z0-9_-]+$/u.test(environment.value))) {
|
|
160
|
-
return {
|
|
161
|
-
ok: false,
|
|
162
|
-
reason: "pi-langfuse.json environment must be at most 40 lowercase letters, numbers, hyphens, or underscores and must not start with langfuse."
|
|
163
|
-
};
|
|
164
|
-
}
|
|
165
|
-
const release = optionalString(input.release, "release");
|
|
166
|
-
if (!release.ok) return release;
|
|
167
|
-
const userId = optionalString(input.userId, "userId");
|
|
168
|
-
if (!userId.ok) return userId;
|
|
169
|
-
if (userId.value && userId.value.length > 200) {
|
|
170
|
-
return { ok: false, reason: "pi-langfuse.json userId must be at most 200 characters." };
|
|
171
|
-
}
|
|
172
|
-
return {
|
|
173
|
-
ok: true,
|
|
174
|
-
config: {
|
|
175
|
-
publicKey,
|
|
176
|
-
secretKey,
|
|
177
|
-
baseUrl,
|
|
178
|
-
...environment.value ? { environment: environment.value } : {},
|
|
179
|
-
...release.value ? { release: release.value } : {},
|
|
180
|
-
...userId.value ? { userId: userId.value } : {},
|
|
181
|
-
captureContent: input.captureContent ?? true
|
|
182
|
-
}
|
|
183
|
-
};
|
|
184
|
-
}
|
|
185
|
-
async function ensurePrivatePermissions(path, warnings) {
|
|
186
|
-
try {
|
|
187
|
-
const file = await stat(path);
|
|
188
|
-
if ((file.mode & 511) !== 384) {
|
|
189
|
-
await chmod(path, 384);
|
|
190
|
-
const repaired = await stat(path);
|
|
191
|
-
if ((repaired.mode & 511) !== 384) {
|
|
192
|
-
throw new Error(`permissions remained ${(repaired.mode & 511).toString(8)}`);
|
|
193
|
-
}
|
|
194
|
-
warnings.push(`Restricted ${path} permissions to 0600.`);
|
|
195
|
-
}
|
|
196
|
-
} catch (error) {
|
|
197
|
-
if (isNodeError(error) && error.code === "ENOENT") return void 0;
|
|
198
|
-
const failure = `Failed to enforce 0600 permissions for ${path}: ${formatError(error)}`;
|
|
199
|
-
warnings.push(failure);
|
|
200
|
-
return failure;
|
|
201
|
-
}
|
|
202
|
-
return void 0;
|
|
203
|
-
}
|
|
204
|
-
function normalizeBaseUrl(value) {
|
|
205
|
-
try {
|
|
206
|
-
const url = new URL(value);
|
|
207
|
-
if (url.protocol !== "http:" && url.protocol !== "https:") return void 0;
|
|
208
|
-
if (url.username || url.password || url.search || url.hash) return void 0;
|
|
209
|
-
return url.toString().replace(/\/+$/, "");
|
|
210
|
-
} catch {
|
|
211
|
-
return void 0;
|
|
212
|
-
}
|
|
213
|
-
}
|
|
214
|
-
function optionalString(value, name) {
|
|
215
|
-
if (value === void 0) return { ok: true };
|
|
216
|
-
const normalized = normalizeString(value);
|
|
217
|
-
return normalized ? { ok: true, value: normalized } : { ok: false, reason: `pi-langfuse.json ${name} must be a non-empty string.` };
|
|
218
|
-
}
|
|
219
|
-
function normalizeString(value) {
|
|
220
|
-
return typeof value === "string" && value.trim() ? value.trim() : void 0;
|
|
221
|
-
}
|
|
222
|
-
function isInterpolation(value) {
|
|
223
|
-
return value.startsWith("$") || value.startsWith("!");
|
|
224
|
-
}
|
|
225
|
-
function isNodeError(error) {
|
|
226
|
-
return error instanceof Error && "code" in error;
|
|
227
|
-
}
|
|
228
|
-
function formatError(error) {
|
|
229
|
-
return error instanceof Error ? error.message : String(error);
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
// src/runtime-core.ts
|
|
233
|
-
var RUNTIME_INTERNAL_KEY = /* @__PURE__ */ Symbol.for("@narumitw/pi-langfuse/runtime-internal/v2");
|
|
234
|
-
var ManagedLangfuseRuntime = class {
|
|
235
|
-
constructor(backend) {
|
|
236
|
-
this.backend = backend;
|
|
237
|
-
}
|
|
238
|
-
backend;
|
|
239
|
-
state = "open";
|
|
240
|
-
sessionDisposers = /* @__PURE__ */ new Set();
|
|
241
|
-
flushQueue = Promise.resolve();
|
|
242
|
-
shutdownPromise;
|
|
243
|
-
get closed() {
|
|
244
|
-
return this.state !== "open";
|
|
245
|
-
}
|
|
246
|
-
registerSession(disposer) {
|
|
247
|
-
if (this.state !== "open") throw new Error("Langfuse runtime is shutting down or already closed.");
|
|
248
|
-
this.sessionDisposers.add(disposer);
|
|
249
|
-
return () => this.sessionDisposers.delete(disposer);
|
|
250
|
-
}
|
|
251
|
-
flush() {
|
|
252
|
-
if (this.state !== "open") {
|
|
253
|
-
return Promise.reject(new Error("Langfuse runtime is shutting down or already closed."));
|
|
254
|
-
}
|
|
255
|
-
const operation = this.flushQueue.then(() => this.backend.forceFlush());
|
|
256
|
-
this.flushQueue = operation.then(
|
|
257
|
-
() => void 0,
|
|
258
|
-
() => void 0
|
|
259
|
-
);
|
|
260
|
-
return operation;
|
|
261
|
-
}
|
|
262
|
-
shutdown() {
|
|
263
|
-
if (this.shutdownPromise) return this.shutdownPromise;
|
|
264
|
-
this.state = "closing";
|
|
265
|
-
this.shutdownPromise = this.shutdownNow();
|
|
266
|
-
return this.shutdownPromise;
|
|
267
|
-
}
|
|
268
|
-
async shutdownNow() {
|
|
269
|
-
const errors = [];
|
|
270
|
-
for (const dispose of [...this.sessionDisposers]) {
|
|
271
|
-
try {
|
|
272
|
-
await dispose("Langfuse runtime shut down before the Pi session was disposed.");
|
|
273
|
-
} catch (error) {
|
|
274
|
-
errors.push(error);
|
|
275
|
-
}
|
|
276
|
-
}
|
|
277
|
-
this.sessionDisposers.clear();
|
|
278
|
-
await this.flushQueue;
|
|
279
|
-
try {
|
|
280
|
-
await this.backend.forceFlush();
|
|
281
|
-
} catch (error) {
|
|
282
|
-
errors.push(error);
|
|
283
|
-
}
|
|
284
|
-
try {
|
|
285
|
-
await this.backend.shutdown();
|
|
286
|
-
} catch (error) {
|
|
287
|
-
errors.push(error);
|
|
288
|
-
} finally {
|
|
289
|
-
this.state = "closed";
|
|
290
|
-
}
|
|
291
|
-
if (errors.length === 1) throw errors[0];
|
|
292
|
-
if (errors.length > 1) throw new AggregateError(errors, "Langfuse runtime shutdown failed.");
|
|
293
|
-
}
|
|
294
|
-
};
|
|
295
|
-
function getLangfuseRuntimeInternal(runtime) {
|
|
296
|
-
const internal = runtime[RUNTIME_INTERNAL_KEY];
|
|
297
|
-
if (!internal) throw new Error("Langfuse runtime was not created by @narumitw/pi-langfuse.");
|
|
298
|
-
return internal;
|
|
299
|
-
}
|
|
300
|
-
function createLangfuseRuntimeFromBackend(backend) {
|
|
301
|
-
return registerLangfuseRuntime(new ManagedLangfuseRuntime(backend));
|
|
302
|
-
}
|
|
303
|
-
function registerLangfuseRuntime(runtime) {
|
|
304
|
-
Object.defineProperty(runtime, RUNTIME_INTERNAL_KEY, { value: runtime });
|
|
305
|
-
return runtime;
|
|
306
|
-
}
|
|
307
|
-
|
|
308
|
-
export {
|
|
309
|
-
DEFAULT_BASE_URL,
|
|
310
|
-
writeLangfuseConfig,
|
|
311
|
-
loadLangfuseConfig,
|
|
312
|
-
normalizeLangfuseConfig,
|
|
313
|
-
getLangfuseRuntimeInternal,
|
|
314
|
-
createLangfuseRuntimeFromBackend
|
|
315
|
-
};
|
|
316
|
-
//# sourceMappingURL=chunk-SAJ76IYU.js.map
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../src/config.ts", "../../src/runtime-core.ts"],
|
|
4
|
-
"sourcesContent": ["import { randomUUID } from \"node:crypto\";\nimport { chmod, mkdir, readFile, rename, rm, stat, writeFile } from \"node:fs/promises\";\nimport { dirname, join } from \"node:path\";\nimport { getAgentDir } from \"@earendil-works/pi-coding-agent\";\n\nconst CONFIG_FILE_NAME = \"pi-langfuse.json\";\nexport const DEFAULT_BASE_URL = \"https://us.cloud.langfuse.com\";\n\nexport interface LangfuseConfig {\n publicKey: string;\n secretKey: string;\n baseUrl: string;\n environment?: string;\n release?: string;\n userId?: string;\n captureContent: boolean;\n}\n\nexport type LangfuseConfigPatch = Partial<LangfuseConfig>;\n\nexport type LangfuseConfigResult =\n | { ok: true; config: LangfuseConfig; path: string; warnings: string[] }\n | { ok: false; path: string; warnings: string[]; reason: string };\n\nexport function langfuseConfigPath(): string {\n return join(getAgentDir(), CONFIG_FILE_NAME);\n}\n\nconst configSaveQueues = new Map<string, Promise<void>>();\n\nexport async function waitForLangfuseConfigWrites(path = langfuseConfigPath()): Promise<void> {\n await configSaveQueues.get(path);\n}\n\nexport function writeLangfuseConfig(patch: LangfuseConfigPatch, path = langfuseConfigPath()): Promise<LangfuseConfig> {\n const previous = configSaveQueues.get(path) ?? Promise.resolve();\n const operation = previous.then(() => writeLangfuseConfigNow(patch, path));\n const tail = operation.then(\n () => undefined,\n () => undefined,\n );\n configSaveQueues.set(path, tail);\n void tail.then(() => {\n if (configSaveQueues.get(path) === tail) configSaveQueues.delete(path);\n });\n return operation;\n}\n\nasync function writeLangfuseConfigNow(patch: LangfuseConfigPatch, path: string): Promise<LangfuseConfig> {\n const currentDocument = await readLangfuseDocumentForUpdate(path);\n const normalized = normalizeLangfuseConfig({ ...currentDocument, ...patch });\n if (!normalized.ok) throw new Error(normalized.reason);\n const {\n publicKey: _publicKey,\n secretKey: _secretKey,\n baseUrl: _baseUrl,\n environment: _environment,\n release: _release,\n userId: _userId,\n captureContent: _captureContent,\n ...unknownFields\n } = currentDocument;\n const nextDocument = { ...unknownFields, ...normalized.config };\n\n await mkdir(dirname(path), { recursive: true, mode: 0o700 });\n const tempPath = `${path}.${process.pid}.${randomUUID()}.tmp`;\n try {\n await writeFile(tempPath, `${JSON.stringify(nextDocument, null, 2)}\\n`, {\n encoding: \"utf8\",\n mode: 0o600,\n });\n await chmod(tempPath, 0o600);\n await rename(tempPath, path);\n return normalized.config;\n } catch (error) {\n await rm(tempPath, { force: true }).catch(() => undefined);\n throw error;\n }\n}\n\nasync function readLangfuseDocumentForUpdate(path: string): Promise<Record<string, unknown>> {\n let parsed: unknown;\n try {\n parsed = JSON.parse(await readFile(path, \"utf8\")) as unknown;\n } catch (error) {\n if (isNodeError(error) && error.code === \"ENOENT\") return {};\n throw new Error(\n `Cannot update ${CONFIG_FILE_NAME} because the existing file is malformed or unreadable; repair it first.`,\n );\n }\n const normalized = normalizeLangfuseConfig(parsed);\n if (!normalized.ok) {\n throw new Error(\n `Cannot update ${CONFIG_FILE_NAME} because the existing file has invalid recognized fields; repair it first.`,\n );\n }\n return { ...(parsed as Record<string, unknown>) };\n}\n\nexport async function loadLangfuseConfig(path = langfuseConfigPath()): Promise<LangfuseConfigResult> {\n await configSaveQueues.get(path);\n const warnings: string[] = [];\n const permissionFailure = await ensurePrivatePermissions(path, warnings);\n if (permissionFailure) {\n return {\n ok: false,\n path,\n warnings,\n reason: `Refusing to load credentials: ${permissionFailure}`,\n };\n }\n\n let text: string;\n try {\n text = await readFile(path, \"utf8\");\n } catch (error) {\n if (isNodeError(error) && error.code === \"ENOENT\") {\n return { ok: false, path, warnings, reason: `Configuration file not found: ${path}` };\n }\n return {\n ok: false,\n path,\n warnings,\n reason: `Failed to read ${path}: ${formatError(error)}`,\n };\n }\n\n let parsed: unknown;\n try {\n parsed = JSON.parse(text) as unknown;\n } catch {\n return {\n ok: false,\n path,\n warnings,\n reason: `Failed to parse ${path} as JSON; repair the file before retrying.`,\n };\n }\n\n const normalized = normalizeLangfuseConfig(parsed);\n if (!normalized.ok) return { ok: false, path, warnings, reason: normalized.reason };\n return { ok: true, config: normalized.config, path, warnings };\n}\n\nexport function normalizeLangfuseConfig(\n value: unknown,\n): { ok: true; config: LangfuseConfig } | { ok: false; reason: string } {\n if (!value || typeof value !== \"object\" || Array.isArray(value)) {\n return { ok: false, reason: \"pi-langfuse.json must contain a JSON object.\" };\n }\n const input = value as Record<string, unknown>;\n const publicKey = normalizeString(input.publicKey);\n const secretKey = normalizeString(input.secretKey);\n if (!publicKey) {\n return { ok: false, reason: \"pi-langfuse.json requires a literal publicKey string.\" };\n }\n if (!secretKey) {\n return { ok: false, reason: \"pi-langfuse.json requires a literal secretKey string.\" };\n }\n if (isInterpolation(publicKey)) {\n return {\n ok: false,\n reason: \"pi-langfuse.json publicKey must be literal; environment and command interpolation are not supported.\",\n };\n }\n if (isInterpolation(secretKey)) {\n return {\n ok: false,\n reason: \"pi-langfuse.json secretKey must be literal; environment and command interpolation are not supported.\",\n };\n }\n\n const rawBaseUrl = input.baseUrl === undefined ? DEFAULT_BASE_URL : normalizeString(input.baseUrl);\n if (!rawBaseUrl) {\n return { ok: false, reason: \"pi-langfuse.json baseUrl must be a non-empty string.\" };\n }\n const baseUrl = normalizeBaseUrl(rawBaseUrl);\n if (!baseUrl) {\n return {\n ok: false,\n reason: \"pi-langfuse.json baseUrl must use HTTP or HTTPS without credentials, a query, or a fragment.\",\n };\n }\n\n if (input.captureContent !== undefined && typeof input.captureContent !== \"boolean\") {\n return { ok: false, reason: \"pi-langfuse.json captureContent must be a boolean.\" };\n }\n const environment = optionalString(input.environment, \"environment\");\n if (!environment.ok) return environment;\n if (environment.value && (environment.value.length > 40 || !/^(?!langfuse)[a-z0-9_-]+$/u.test(environment.value))) {\n return {\n ok: false,\n reason:\n \"pi-langfuse.json environment must be at most 40 lowercase letters, numbers, hyphens, or underscores and must not start with langfuse.\",\n };\n }\n const release = optionalString(input.release, \"release\");\n if (!release.ok) return release;\n const userId = optionalString(input.userId, \"userId\");\n if (!userId.ok) return userId;\n if (userId.value && userId.value.length > 200) {\n return { ok: false, reason: \"pi-langfuse.json userId must be at most 200 characters.\" };\n }\n\n return {\n ok: true,\n config: {\n publicKey,\n secretKey,\n baseUrl,\n ...(environment.value ? { environment: environment.value } : {}),\n ...(release.value ? { release: release.value } : {}),\n ...(userId.value ? { userId: userId.value } : {}),\n captureContent: input.captureContent ?? true,\n },\n };\n}\n\nasync function ensurePrivatePermissions(path: string, warnings: string[]): Promise<string | undefined> {\n try {\n const file = await stat(path);\n if ((file.mode & 0o777) !== 0o600) {\n await chmod(path, 0o600);\n const repaired = await stat(path);\n if ((repaired.mode & 0o777) !== 0o600) {\n throw new Error(`permissions remained ${(repaired.mode & 0o777).toString(8)}`);\n }\n warnings.push(`Restricted ${path} permissions to 0600.`);\n }\n } catch (error) {\n if (isNodeError(error) && error.code === \"ENOENT\") return undefined;\n const failure = `Failed to enforce 0600 permissions for ${path}: ${formatError(error)}`;\n warnings.push(failure);\n return failure;\n }\n return undefined;\n}\n\nfunction normalizeBaseUrl(value: string): string | undefined {\n try {\n const url = new URL(value);\n if (url.protocol !== \"http:\" && url.protocol !== \"https:\") return undefined;\n if (url.username || url.password || url.search || url.hash) return undefined;\n return url.toString().replace(/\\/+$/, \"\");\n } catch {\n return undefined;\n }\n}\n\nfunction optionalString(value: unknown, name: string): { ok: true; value?: string } | { ok: false; reason: string } {\n if (value === undefined) return { ok: true };\n const normalized = normalizeString(value);\n return normalized\n ? { ok: true, value: normalized }\n : { ok: false, reason: `pi-langfuse.json ${name} must be a non-empty string.` };\n}\n\nfunction normalizeString(value: unknown): string | undefined {\n return typeof value === \"string\" && value.trim() ? value.trim() : undefined;\n}\n\nfunction isInterpolation(value: string): boolean {\n return value.startsWith(\"$\") || value.startsWith(\"!\");\n}\n\nfunction isNodeError(error: unknown): error is NodeJS.ErrnoException {\n return error instanceof Error && \"code\" in error;\n}\n\nfunction formatError(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n", "import type { TraceBackend } from \"./tracing.js\";\n\nexport interface LangfuseRuntimeConfig {\n publicKey?: string;\n secretKey?: string;\n baseUrl?: string;\n environment?: string;\n release?: string;\n}\n\nexport interface CreateLangfuseRuntimeOptions {\n config?: LangfuseRuntimeConfig;\n env?: NodeJS.ProcessEnv | false;\n}\n\nexport interface LangfuseRuntime {\n readonly closed: boolean;\n flush(): Promise<void>;\n shutdown(): Promise<void>;\n}\n\ntype RuntimeSessionDisposer = (statusMessage: string) => void | Promise<void>;\n\nexport interface LangfuseRuntimeInternal extends LangfuseRuntime {\n readonly backend: TraceBackend;\n registerSession(disposer: RuntimeSessionDisposer): () => void;\n}\n\nconst RUNTIME_INTERNAL_KEY = Symbol.for(\"@narumitw/pi-langfuse/runtime-internal/v2\");\n\nclass ManagedLangfuseRuntime implements LangfuseRuntimeInternal {\n private state: \"open\" | \"closing\" | \"closed\" = \"open\";\n private readonly sessionDisposers = new Set<RuntimeSessionDisposer>();\n private flushQueue = Promise.resolve();\n private shutdownPromise: Promise<void> | undefined;\n\n constructor(readonly backend: TraceBackend) {}\n\n get closed(): boolean {\n return this.state !== \"open\";\n }\n\n registerSession(disposer: RuntimeSessionDisposer): () => void {\n if (this.state !== \"open\") throw new Error(\"Langfuse runtime is shutting down or already closed.\");\n this.sessionDisposers.add(disposer);\n return () => this.sessionDisposers.delete(disposer);\n }\n\n flush(): Promise<void> {\n if (this.state !== \"open\") {\n return Promise.reject(new Error(\"Langfuse runtime is shutting down or already closed.\"));\n }\n const operation = this.flushQueue.then(() => this.backend.forceFlush());\n this.flushQueue = operation.then(\n () => undefined,\n () => undefined,\n );\n return operation;\n }\n\n shutdown(): Promise<void> {\n if (this.shutdownPromise) return this.shutdownPromise;\n this.state = \"closing\";\n this.shutdownPromise = this.shutdownNow();\n return this.shutdownPromise;\n }\n\n private async shutdownNow(): Promise<void> {\n const errors: unknown[] = [];\n for (const dispose of [...this.sessionDisposers]) {\n try {\n await dispose(\"Langfuse runtime shut down before the Pi session was disposed.\");\n } catch (error) {\n errors.push(error);\n }\n }\n this.sessionDisposers.clear();\n\n await this.flushQueue;\n try {\n await this.backend.forceFlush();\n } catch (error) {\n errors.push(error);\n }\n try {\n await this.backend.shutdown();\n } catch (error) {\n errors.push(error);\n } finally {\n this.state = \"closed\";\n }\n\n if (errors.length === 1) throw errors[0];\n if (errors.length > 1) throw new AggregateError(errors, \"Langfuse runtime shutdown failed.\");\n }\n}\n\nexport function getLangfuseRuntimeInternal(runtime: LangfuseRuntime): LangfuseRuntimeInternal {\n const internal = (runtime as LangfuseRuntime & { [key: symbol]: LangfuseRuntimeInternal | undefined })[\n RUNTIME_INTERNAL_KEY\n ];\n if (!internal) throw new Error(\"Langfuse runtime was not created by @narumitw/pi-langfuse.\");\n return internal;\n}\n\nexport function createLangfuseRuntimeFromBackend(backend: TraceBackend): LangfuseRuntime {\n return registerLangfuseRuntime(new ManagedLangfuseRuntime(backend));\n}\n\nexport function registerLangfuseRuntime(runtime: LangfuseRuntimeInternal): LangfuseRuntimeInternal {\n Object.defineProperty(runtime, RUNTIME_INTERNAL_KEY, { value: runtime });\n return runtime;\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
6
|
-
"names": []
|
|
7
|
-
}
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../src/runtime.ts"],
|
|
4
|
-
"sourcesContent": ["import { createHash } from \"node:crypto\";\nimport { LangfuseSpanProcessor } from \"@langfuse/otel\";\nimport {\n type LangfuseObservation,\n type LangfuseObservationAttributes,\n LangfuseOtelSpanAttributes,\n setLangfuseTracerProvider,\n startObservation,\n} from \"@langfuse/tracing\";\nimport type { SpanProcessor } from \"@opentelemetry/sdk-trace-base\";\nimport { NodeTracerProvider } from \"@opentelemetry/sdk-trace-node\";\nimport { DEFAULT_BASE_URL, type LangfuseConfig } from \"./config.js\";\nimport {\n type CreateLangfuseRuntimeOptions,\n createLangfuseRuntimeFromBackend,\n getLangfuseRuntimeInternal,\n type LangfuseRuntime,\n type LangfuseRuntimeInternal,\n} from \"./runtime-core.js\";\nimport type { Observation, ObservationAttributes, ObservationType, TraceBackend } from \"./tracing.js\";\n\nexport type {\n CreateLangfuseRuntimeOptions,\n LangfuseRuntime,\n LangfuseRuntimeConfig,\n} from \"./runtime-core.js\";\n\nconst RUNTIME_KEY = Symbol.for(\"@narumitw/pi-langfuse/runtime/v2\");\nconst LEGACY_RUNTIME_KEY = Symbol.for(\"@narumitw/pi-langfuse/runtime/v1\");\n\ninterface ResolvedRuntimeConfig {\n publicKey: string;\n secretKey: string;\n baseUrl: string;\n environment?: string;\n release?: string;\n}\n\ninterface SharedRuntime {\n fingerprint: string;\n runtime: LangfuseRuntimeInternal;\n shutdown: true;\n}\n\ntype GlobalWithRuntime = typeof globalThis & {\n [RUNTIME_KEY]?: Promise<SharedRuntime>;\n [LEGACY_RUNTIME_KEY]?: unknown;\n};\n\nexport interface RuntimeFactories {\n createProcessor(config: ResolvedRuntimeConfig): SpanProcessor;\n createProvider(processor: SpanProcessor): NodeTracerProvider;\n selectProvider(provider: NodeTracerProvider): void;\n}\n\nclass ProductionObservation implements Observation {\n readonly traceId: string;\n\n constructor(\n readonly native: LangfuseObservation,\n private readonly secrets: readonly string[],\n ) {\n this.traceId = native.traceId;\n }\n\n update(attributes: ObservationAttributes): Observation {\n const { sessionId, userId, ...observationAttributes } = maskObservationAttributes(attributes, this.secrets);\n this.native.updateOtelSpanAttributes(observationAttributes as LangfuseObservationAttributes);\n applySessionId(this.native, sessionId);\n applyUserId(this.native, userId);\n return this;\n }\n\n updateTrace(attributes: ObservationAttributes): Observation {\n const { input, output, metadata, name, sessionId, userId, tags, version } = maskObservationAttributes(\n attributes,\n this.secrets,\n );\n if (input !== undefined || output !== undefined) {\n this.native.setTraceIO({ input, output });\n }\n if (name !== undefined) {\n this.native.otelSpan.setAttribute(LangfuseOtelSpanAttributes.TRACE_NAME, name);\n }\n applySessionId(this.native, sessionId);\n applyUserId(this.native, userId);\n if (tags !== undefined) {\n this.native.otelSpan.setAttribute(LangfuseOtelSpanAttributes.TRACE_TAGS, tags);\n }\n if (version !== undefined) {\n this.native.otelSpan.setAttribute(LangfuseOtelSpanAttributes.VERSION, version);\n }\n for (const [key, value] of Object.entries(metadata ?? {})) {\n const serialized = serializeMetadataValue(value);\n if (serialized !== undefined) {\n this.native.otelSpan.setAttribute(`${LangfuseOtelSpanAttributes.TRACE_METADATA}.${key}`, serialized);\n }\n }\n return this;\n }\n\n end(endTime?: number): Observation {\n this.native.end(endTime);\n return this;\n }\n}\n\nclass ProductionTraceBackend implements TraceBackend {\n constructor(\n private readonly provider: NodeTracerProvider,\n private readonly processor: SpanProcessor,\n private readonly secrets: readonly string[],\n ) {}\n\n start(\n name: string,\n attributes: ObservationAttributes,\n options: { asType: ObservationType; parent?: Observation; startTime?: Date },\n ): Observation {\n const maskedName = maskSecretString(name, this.secrets);\n const { sessionId, userId, ...observationAttributes } = maskObservationAttributes(attributes, this.secrets);\n const parent = options.parent;\n const native =\n parent instanceof ProductionObservation\n ? startChild(parent.native, maskedName, observationAttributes, options.asType, options.startTime)\n : startRoot(maskedName, observationAttributes, options.asType, options.startTime);\n applySessionId(native, sessionId);\n applyUserId(native, userId);\n return new ProductionObservation(native, this.secrets);\n }\n\n async forceFlush(): Promise<void> {\n await this.processor.forceFlush();\n }\n\n async shutdown(): Promise<void> {\n await this.provider.shutdown();\n }\n}\n\nexport async function createLangfuseRuntime(options: CreateLangfuseRuntimeOptions = {}): Promise<LangfuseRuntime> {\n return createSharedRuntime(resolveLangfuseRuntimeConfig(options), defaultFactories);\n}\n\nexport async function createProductionBackend(\n config: LangfuseConfig,\n factoryOverrides: Partial<RuntimeFactories> = {},\n): Promise<TraceBackend> {\n const runtime = await createSharedRuntime(resolveLangfuseRuntimeConfig({ config, env: false }), {\n ...defaultFactories,\n ...factoryOverrides,\n });\n return getLangfuseRuntimeInternal(runtime).backend;\n}\n\nasync function createSharedRuntime(\n config: ResolvedRuntimeConfig,\n factories: RuntimeFactories,\n): Promise<LangfuseRuntime> {\n const globalRuntime = globalThis as GlobalWithRuntime;\n const fingerprint = configFingerprint(config);\n const existing = globalRuntime[RUNTIME_KEY];\n const legacyRuntime = globalRuntime[LEGACY_RUNTIME_KEY];\n if (legacyRuntime !== undefined && legacyRuntime !== existing) {\n throw new Error(\"An older Langfuse runtime is already loaded; restart the process before enabling this version.\");\n }\n if (existing) {\n if (legacyRuntime === undefined) globalRuntime[LEGACY_RUNTIME_KEY] = existing;\n const shared = await existing;\n if (shared.runtime.closed) {\n throw new Error(\"Langfuse tracing was already shut down; restart the process to enable it again.\");\n }\n if (shared.fingerprint !== fingerprint) {\n throw new Error(\"Langfuse configuration changed; restart the process to apply the new credentials.\");\n }\n return shared.runtime;\n }\n\n const initializing = initializeRuntime(config, fingerprint, factories);\n globalRuntime[RUNTIME_KEY] = initializing;\n globalRuntime[LEGACY_RUNTIME_KEY] = initializing;\n try {\n return (await initializing).runtime;\n } catch (error) {\n if (globalRuntime[RUNTIME_KEY] === initializing) delete globalRuntime[RUNTIME_KEY];\n if (globalRuntime[LEGACY_RUNTIME_KEY] === initializing) delete globalRuntime[LEGACY_RUNTIME_KEY];\n throw error;\n }\n}\n\nasync function initializeRuntime(\n config: ResolvedRuntimeConfig,\n fingerprint: string,\n factories: RuntimeFactories,\n): Promise<SharedRuntime> {\n const processor = factories.createProcessor(config);\n let provider: NodeTracerProvider | undefined;\n try {\n provider = factories.createProvider(processor);\n factories.selectProvider(provider);\n } catch (error) {\n await (provider?.shutdown() ?? processor.shutdown()).catch(() => undefined);\n throw error;\n }\n const runtime = getLangfuseRuntimeInternal(\n createLangfuseRuntimeFromBackend(\n new ProductionTraceBackend(provider, processor, [config.publicKey, config.secretKey]),\n ),\n );\n return { fingerprint, runtime, shutdown: true };\n}\n\nconst defaultFactories: RuntimeFactories = {\n createProcessor: (config) => {\n const secrets = [config.secretKey, config.publicKey];\n return new LangfuseSpanProcessor({\n publicKey: config.publicKey,\n secretKey: config.secretKey,\n baseUrl: config.baseUrl,\n environment: config.environment ?? \"\",\n release: config.release ?? \"\",\n flushAt: 512,\n flushInterval: 5,\n timeout: 5,\n mask: ({ data }) => maskSecrets(data, secrets),\n shouldExportSpan: ({ otelSpan }) => typeof otelSpan.attributes[\"langfuse.observation.type\"] === \"string\",\n });\n },\n createProvider: (processor) => new NodeTracerProvider({ spanProcessors: [processor] }),\n selectProvider: setLangfuseTracerProvider,\n};\n\nexport function resolveLangfuseRuntimeConfig(options: CreateLangfuseRuntimeOptions): ResolvedRuntimeConfig {\n const env = options.env === false ? undefined : (options.env ?? process.env);\n const publicKey = requiredSetting(\"publicKey\", options.config?.publicKey, env?.LANGFUSE_PUBLIC_KEY);\n const secretKey = requiredSetting(\"secretKey\", options.config?.secretKey, env?.LANGFUSE_SECRET_KEY);\n const explicitBaseUrl = options.config?.baseUrl;\n if (explicitBaseUrl !== undefined && !normalizeString(explicitBaseUrl)) {\n throw new Error(\"Langfuse baseUrl must be a non-empty string.\");\n }\n const rawBaseUrl = selectedSetting(explicitBaseUrl, env?.LANGFUSE_BASE_URL) ?? DEFAULT_BASE_URL;\n const baseUrl = normalizeBaseUrl(rawBaseUrl);\n if (!baseUrl) {\n throw new Error(\"Langfuse baseUrl must use HTTP or HTTPS without credentials, a query, or a fragment.\");\n }\n const environment = optionalSetting(\"environment\", options.config?.environment, env?.LANGFUSE_TRACING_ENVIRONMENT);\n if (environment && (environment.length > 40 || !/^(?!langfuse)[a-z0-9_-]+$/u.test(environment))) {\n throw new Error(\n \"Langfuse environment must be at most 40 lowercase letters, numbers, hyphens, or underscores and must not start with langfuse.\",\n );\n }\n const release = optionalSetting(\"release\", options.config?.release, env?.LANGFUSE_RELEASE);\n return { publicKey, secretKey, baseUrl, ...(environment ? { environment } : {}), ...(release ? { release } : {}) };\n}\n\nfunction requiredSetting(name: string, explicit: string | undefined, environment: string | undefined): string {\n const value = selectedSetting(explicit, environment);\n if (!value) throw new Error(`Langfuse ${name} is required.`);\n return value;\n}\n\nfunction optionalSetting(\n name: string,\n explicit: string | undefined,\n environment: string | undefined,\n): string | undefined {\n const selected = explicit !== undefined ? explicit : environment;\n if (selected === undefined) return undefined;\n const value = normalizeString(selected);\n if (!value) throw new Error(`Langfuse ${name} must be a non-empty string.`);\n return value;\n}\n\nfunction selectedSetting(explicit: string | undefined, environment: string | undefined): string | undefined {\n if (explicit !== undefined) return normalizeString(explicit);\n return normalizeString(environment);\n}\n\nfunction normalizeBaseUrl(value: string): string | undefined {\n try {\n const url = new URL(value);\n if (url.protocol !== \"http:\" && url.protocol !== \"https:\") return undefined;\n if (url.username || url.password || url.search || url.hash) return undefined;\n return url.toString().replace(/\\/+$/, \"\");\n } catch {\n return undefined;\n }\n}\n\nfunction normalizeString(value: unknown): string | undefined {\n return typeof value === \"string\" && value.trim() ? value.trim() : undefined;\n}\n\nfunction serializeMetadataValue(value: unknown): string | undefined {\n return typeof value === \"string\" ? value : JSON.stringify(value);\n}\n\nfunction maskObservationAttributes(\n attributes: ObservationAttributes,\n secrets: readonly string[],\n): ObservationAttributes {\n return {\n ...attributes,\n ...(attributes.metadata ? { metadata: maskSecrets(attributes.metadata, secrets) as Record<string, unknown> } : {}),\n ...(attributes.name ? { name: maskSecretString(attributes.name, secrets) } : {}),\n ...(attributes.sessionId ? { sessionId: maskSecretString(attributes.sessionId, secrets) } : {}),\n ...(attributes.userId ? { userId: maskSecretString(attributes.userId, secrets) } : {}),\n ...(attributes.tags ? { tags: attributes.tags.map((tag) => maskSecretString(tag, secrets)) } : {}),\n ...(attributes.statusMessage ? { statusMessage: maskSecretString(attributes.statusMessage, secrets) } : {}),\n ...(attributes.model ? { model: maskSecretString(attributes.model, secrets) } : {}),\n ...(attributes.version ? { version: maskSecretString(attributes.version, secrets) } : {}),\n ...(attributes.modelParameters\n ? {\n modelParameters: Object.fromEntries(\n Object.entries(attributes.modelParameters).map(([key, value]) => [\n maskSecretString(key, secrets),\n typeof value === \"string\" ? maskSecretString(value, secrets) : value,\n ]),\n ),\n }\n : {}),\n };\n}\n\nfunction maskSecretString(value: string, secrets: readonly string[]): string {\n return maskSecrets(value, secrets) as string;\n}\n\nfunction applySessionId(observation: LangfuseObservation, sessionId: string | undefined): void {\n if (sessionId !== undefined) {\n observation.otelSpan.setAttribute(LangfuseOtelSpanAttributes.TRACE_SESSION_ID, sessionId);\n }\n}\n\nfunction applyUserId(observation: LangfuseObservation, userId: string | undefined): void {\n if (userId !== undefined) {\n observation.otelSpan.setAttribute(LangfuseOtelSpanAttributes.TRACE_USER_ID, userId);\n }\n}\n\nfunction startRoot(\n name: string,\n attributes: ObservationAttributes,\n type: ObservationType,\n startTime?: Date,\n): LangfuseObservation {\n if (type === \"agent\") {\n return startObservation(name, attributes as LangfuseObservationAttributes, { asType: \"agent\", startTime });\n }\n if (type === \"generation\") {\n return startObservation(name, attributes as LangfuseObservationAttributes, {\n asType: \"generation\",\n startTime,\n });\n }\n if (type === \"tool\") {\n return startObservation(name, attributes as LangfuseObservationAttributes, { asType: \"tool\", startTime });\n }\n return startObservation(name, attributes as LangfuseObservationAttributes, { asType: \"span\", startTime });\n}\n\nfunction startChild(\n parent: LangfuseObservation,\n name: string,\n attributes: ObservationAttributes,\n type: ObservationType,\n startTime?: Date,\n): LangfuseObservation {\n if (startTime) {\n const parentSpanContext = parent.otelSpan.spanContext();\n if (type === \"agent\") {\n return startObservation(name, attributes as LangfuseObservationAttributes, {\n asType: \"agent\",\n parentSpanContext,\n startTime,\n });\n }\n if (type === \"generation\") {\n return startObservation(name, attributes as LangfuseObservationAttributes, {\n asType: \"generation\",\n parentSpanContext,\n startTime,\n });\n }\n if (type === \"tool\") {\n return startObservation(name, attributes as LangfuseObservationAttributes, {\n asType: \"tool\",\n parentSpanContext,\n startTime,\n });\n }\n return startObservation(name, attributes as LangfuseObservationAttributes, {\n asType: \"span\",\n parentSpanContext,\n startTime,\n });\n }\n if (type === \"agent\") {\n return parent.startObservation(name, attributes as LangfuseObservationAttributes, { asType: \"agent\" });\n }\n if (type === \"generation\") {\n return parent.startObservation(name, attributes as LangfuseObservationAttributes, { asType: \"generation\" });\n }\n if (type === \"tool\") {\n return parent.startObservation(name, attributes as LangfuseObservationAttributes, { asType: \"tool\" });\n }\n return parent.startObservation(name, attributes as LangfuseObservationAttributes, { asType: \"span\" });\n}\n\nfunction configFingerprint(config: ResolvedRuntimeConfig): string {\n return createHash(\"sha256\")\n .update(\n `${config.publicKey}\\0${config.secretKey}\\0${config.baseUrl}\\0${config.environment ?? \"\"}\\0${config.release ?? \"\"}`,\n )\n .digest(\"hex\");\n}\n\nexport function maskSecrets(data: unknown, secrets: readonly string[]): unknown {\n return maskSecretValue(data, secrets, new WeakSet<object>());\n}\n\nfunction maskSecretValue(data: unknown, secrets: readonly string[], active: WeakSet<object>): unknown {\n if (typeof data === \"string\") {\n let masked = data.replace(/\\b(?:sk|pk)-lf-[A-Za-z0-9_-]+\\b/g, \"[LANGFUSE_KEY_REDACTED]\");\n for (const secret of secrets) {\n if (secret) masked = masked.replaceAll(secret, \"[LANGFUSE_KEY_REDACTED]\");\n }\n return masked;\n }\n if (!data || typeof data !== \"object\") return data;\n if (active.has(data)) return \"[circular]\";\n\n active.add(data);\n try {\n if (Array.isArray(data)) {\n return data.map((item) => maskSecretValue(item, secrets, active));\n }\n return Object.fromEntries(\n Object.entries(data).map(([key, value]) => [\n maskSecretString(key, secrets),\n maskSecretValue(value, secrets, active),\n ]),\n );\n } finally {\n active.delete(data);\n }\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
6
|
-
"names": []
|
|
7
|
-
}
|