mirror of
https://github.com/danny-avila/LibreChat.git
synced 2026-08-27 04:07:05 +00:00
🪢 fix: disable central fanout media uploads for langfuse (#14642)
* fix(langfuse): disable central fanout media uploads * test(langfuse): cover fanout media policy in run config * chore(deps): bump agents for Langfuse media policy * chore(deps): bump agents to 3.3.13 * fix(langfuse): gate central fanout media uploads
This commit is contained in:
parent
4cec1a675f
commit
7775f25b0d
8 changed files with 57 additions and 7 deletions
|
|
@ -164,6 +164,9 @@ NODE_MAX_OLD_SPACE_SIZE=6144
|
|||
# See otel/langfuse-fanout/README.md.
|
||||
# LANGFUSE_FANOUT_ENABLED=false
|
||||
# LANGFUSE_FANOUT_COLLECTOR_URL=http://langfuse-fanout-collector:4318
|
||||
# App-side switch: set true to tell the Langfuse SDK not to create media uploads
|
||||
# for central/fallback collector traces. Tenant-routed media uploads are unchanged.
|
||||
# LANGFUSE_FANOUT_CENTRAL_MEDIA_UPLOAD_DISABLED=false
|
||||
# Emergency switch: unset/false defaults enabled; set true to keep central fanout export but skip tenant trace/score export.
|
||||
# LANGFUSE_FANOUT_TENANT_EXPORT_DISABLED=false
|
||||
# Langfuse Cloud base URL options: https://cloud.langfuse.com (EU),
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@
|
|||
"@azure/storage-blob": "^12.30.0",
|
||||
"@google/genai": "^2.8.0",
|
||||
"@keyv/redis": "^4.3.3",
|
||||
"@librechat/agents": "^3.3.12",
|
||||
"@librechat/agents": "^3.3.13",
|
||||
"@librechat/api": "*",
|
||||
"@librechat/data-schemas": "*",
|
||||
"@microsoft/microsoft-graph-client": "^3.0.7",
|
||||
|
|
|
|||
10
package-lock.json
generated
10
package-lock.json
generated
|
|
@ -61,7 +61,7 @@
|
|||
"@azure/storage-blob": "^12.30.0",
|
||||
"@google/genai": "^2.8.0",
|
||||
"@keyv/redis": "^4.3.3",
|
||||
"@librechat/agents": "^3.3.12",
|
||||
"@librechat/agents": "^3.3.13",
|
||||
"@librechat/api": "*",
|
||||
"@librechat/data-schemas": "*",
|
||||
"@microsoft/microsoft-graph-client": "^3.0.7",
|
||||
|
|
@ -10616,9 +10616,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@librechat/agents": {
|
||||
"version": "3.3.12",
|
||||
"resolved": "https://registry.npmjs.org/@librechat/agents/-/agents-3.3.12.tgz",
|
||||
"integrity": "sha512-kTB50KMlEXR3jMLmGMZzzSkne019k57Wy3Fv0dGX7I4G/oxJMgqZsw70KqiAMYokNOQnc1DoWGmIcZLgJYcewA==",
|
||||
"version": "3.3.13",
|
||||
"resolved": "https://registry.npmjs.org/@librechat/agents/-/agents-3.3.13.tgz",
|
||||
"integrity": "sha512-NOaUCvMaq82ftzZr/Z/3KL1LzfKO0YRHibhFigcx22KxrmeioyJ32w4RnrBsYGhLx0gDrI4nWlW6Sk0ZAH/YBQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@anthropic-ai/sdk": "^0.115.0",
|
||||
|
|
@ -42707,7 +42707,7 @@
|
|||
"@azure/storage-blob": "^12.30.0",
|
||||
"@google/genai": "^2.8.0",
|
||||
"@keyv/redis": "^4.3.3",
|
||||
"@librechat/agents": "^3.3.12",
|
||||
"@librechat/agents": "^3.3.13",
|
||||
"@librechat/data-schemas": "*",
|
||||
"@modelcontextprotocol/sdk": "^1.29.0",
|
||||
"@opentelemetry/api": "^1.9.0",
|
||||
|
|
|
|||
|
|
@ -107,7 +107,7 @@
|
|||
"@azure/storage-blob": "^12.30.0",
|
||||
"@google/genai": "^2.8.0",
|
||||
"@keyv/redis": "^4.3.3",
|
||||
"@librechat/agents": "^3.3.12",
|
||||
"@librechat/agents": "^3.3.13",
|
||||
"@librechat/data-schemas": "*",
|
||||
"@modelcontextprotocol/sdk": "^1.29.0",
|
||||
"@opentelemetry/api": "^1.9.0",
|
||||
|
|
|
|||
|
|
@ -222,6 +222,7 @@ beforeEach(() => {
|
|||
delete process.env.LANGFUSE_HOST;
|
||||
delete process.env.LANGFUSE_FANOUT_ENABLED;
|
||||
delete process.env.LANGFUSE_FANOUT_COLLECTOR_URL;
|
||||
delete process.env.LANGFUSE_FANOUT_CENTRAL_MEDIA_UPLOAD_DISABLED;
|
||||
delete process.env.LANGFUSE_FANOUT_TENANT_DESTINATIONS;
|
||||
delete process.env.LANGFUSE_FANOUT_TENANT_EXPORT_DISABLED;
|
||||
delete process.env.LANGFUSE_TRACING_ENABLED;
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ const envKeys = [
|
|||
'LANGFUSE_BASEURL',
|
||||
'LANGFUSE_FANOUT_ENABLED',
|
||||
'LANGFUSE_FANOUT_COLLECTOR_URL',
|
||||
'LANGFUSE_FANOUT_CENTRAL_MEDIA_UPLOAD_DISABLED',
|
||||
'LANGFUSE_FANOUT_TENANT_DESTINATIONS',
|
||||
'LANGFUSE_FANOUT_TENANT_EXPORT_DISABLED',
|
||||
'LANGFUSE_TRACING_ENABLED',
|
||||
|
|
@ -184,6 +185,7 @@ describe('buildLangfuseConfig', () => {
|
|||
'librechat.langfuse.destination': 'eu',
|
||||
},
|
||||
});
|
||||
expect(config).not.toHaveProperty('mediaUploadEnabled');
|
||||
});
|
||||
|
||||
it('fails closed to central-only export when tenant secret decryption fails', async () => {
|
||||
|
|
@ -438,4 +440,39 @@ describe('buildLangfuseConfig', () => {
|
|||
tags: ['tenant:tenant-1'],
|
||||
});
|
||||
});
|
||||
|
||||
it.each(['true', '1', 'yes', 'on'])(
|
||||
'disables central collector media uploads when LANGFUSE_FANOUT_CENTRAL_MEDIA_UPLOAD_DISABLED is %s',
|
||||
async (value) => {
|
||||
process.env.LANGFUSE_FANOUT_ENABLED = 'true';
|
||||
process.env.LANGFUSE_FANOUT_COLLECTOR_URL = 'http://collector-from-env:4318';
|
||||
process.env.LANGFUSE_FANOUT_CENTRAL_MEDIA_UPLOAD_DISABLED = value;
|
||||
const { buildLangfuseConfig } = await import('./config');
|
||||
|
||||
expect(buildLangfuseConfig({ tenantId: 'tenant-1' })).toEqual({
|
||||
deterministicTraceId: true,
|
||||
baseUrl: 'http://collector-from-env:4318',
|
||||
mediaUploadEnabled: false,
|
||||
metadata: { 'librechat.tenant.id': 'tenant-1' },
|
||||
tags: ['tenant:tenant-1'],
|
||||
});
|
||||
},
|
||||
);
|
||||
|
||||
it.each(['false', '0', 'no', 'off', ''])(
|
||||
'keeps central collector media uploads at the SDK default when LANGFUSE_FANOUT_CENTRAL_MEDIA_UPLOAD_DISABLED is %s',
|
||||
async (value) => {
|
||||
process.env.LANGFUSE_FANOUT_ENABLED = 'true';
|
||||
process.env.LANGFUSE_FANOUT_COLLECTOR_URL = 'http://collector-from-env:4318';
|
||||
process.env.LANGFUSE_FANOUT_CENTRAL_MEDIA_UPLOAD_DISABLED = value;
|
||||
const { buildLangfuseConfig } = await import('./config');
|
||||
|
||||
expect(buildLangfuseConfig({ tenantId: 'tenant-1' })).toEqual({
|
||||
deterministicTraceId: true,
|
||||
baseUrl: 'http://collector-from-env:4318',
|
||||
metadata: { 'librechat.tenant.id': 'tenant-1' },
|
||||
tags: ['tenant:tenant-1'],
|
||||
});
|
||||
},
|
||||
);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ import type { AppConfig } from '@librechat/data-schemas';
|
|||
import type { RunConfig } from '@librechat/agents';
|
||||
import {
|
||||
hasLangfuseEnvCredentials,
|
||||
isLangfuseCentralMediaUploadDisabled,
|
||||
isLangfuseFanoutEnabled,
|
||||
isLangfuseTenantExportEnabled,
|
||||
isLangfuseTraceSampled,
|
||||
|
|
@ -16,6 +17,7 @@ import { traceIdForMessage } from './trace';
|
|||
type LangfuseRunConfig = NonNullable<RunConfig['langfuse']>;
|
||||
type LangfuseRunConfigWithTraceAttributes = LangfuseRunConfig & {
|
||||
librechatTraceAttributes?: Record<string, string | number | boolean | null | undefined>;
|
||||
mediaUploadEnabled?: boolean;
|
||||
};
|
||||
type LangfuseTenantDestination = NonNullable<ReturnType<typeof resolveLangfuseTenantDestination>>;
|
||||
type LangfuseExportPlan =
|
||||
|
|
@ -226,6 +228,9 @@ export function buildLangfuseConfig({
|
|||
break;
|
||||
case 'fanoutCollector':
|
||||
langfuse.baseUrl = exportPlan.collectorUrl;
|
||||
if (isLangfuseCentralMediaUploadDisabled()) {
|
||||
langfuse.mediaUploadEnabled = false;
|
||||
}
|
||||
break;
|
||||
case 'disabled':
|
||||
langfuse.enabled = false;
|
||||
|
|
|
|||
|
|
@ -8,6 +8,10 @@ export function isLangfuseTenantExportEnabled(): boolean {
|
|||
return !isTrueEnv(process.env.LANGFUSE_FANOUT_TENANT_EXPORT_DISABLED);
|
||||
}
|
||||
|
||||
export function isLangfuseCentralMediaUploadDisabled(): boolean {
|
||||
return isTrueEnv(process.env.LANGFUSE_FANOUT_CENTRAL_MEDIA_UPLOAD_DISABLED);
|
||||
}
|
||||
|
||||
export function isLangfuseFanoutEnabled(): boolean {
|
||||
return (
|
||||
isTrueEnv(process.env.LANGFUSE_FANOUT_ENABLED) &&
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue