[codex] Derive object relay URL from telemetry relay (#4036)

* Derive object relay URL from telemetry relay

* Normalize telemetry relay URL before object derivation

Generated-By: looper 0.9.7 (runner=fixer, agent=codex)
This commit is contained in:
Ray Xi
2026-06-10 04:00:54 +00:00
committed by GitHub
parent 79baf085cd
commit b83f528f9c
4 changed files with 86 additions and 17 deletions
+4 -1
View File
@@ -177,7 +177,10 @@ function mergeTraceSafeManifests(
function inferObjectRegistrationRelayUrl(env: NodeJS.ProcessEnv = process.env): string | null {
const objectRelayUrl = env.OPEN_DESIGN_OBJECT_RELAY_URL?.trim();
if (!objectRelayUrl) return null;
if (!objectRelayUrl) {
const telemetryRelayUrl = env.OPEN_DESIGN_TELEMETRY_RELAY_URL?.trim();
return telemetryRelayUrl ? telemetryRelayUrl.replace(/\/+$/, '') : null;
}
try {
const url = new URL(objectRelayUrl);
url.pathname = url.pathname.replace(/\/api\/objects\/batch\/?$/, '/api/langfuse');
+12
View File
@@ -137,6 +137,18 @@ function storageRef(projectId: string, runId: string, objectClass: ObjectClass,
function inferRelayUrl(env: NodeJS.ProcessEnv): string | null {
const explicit = env.OPEN_DESIGN_OBJECT_RELAY_URL?.trim();
if (explicit) return explicit.replace(/\/+$/, '');
const rawTelemetryRelayUrl = env.OPEN_DESIGN_TELEMETRY_RELAY_URL?.trim();
if (!rawTelemetryRelayUrl) return null;
const telemetryRelayUrl = rawTelemetryRelayUrl.replace(/\/+$/, '');
try {
const url = new URL(telemetryRelayUrl);
if (!/\/api\/langfuse\/?$/u.test(url.pathname)) return null;
url.pathname = url.pathname.replace(/\/api\/langfuse\/?$/u, '/api/objects/batch');
return url.toString().replace(/\/+$/, '');
} catch {
const derived = telemetryRelayUrl.replace(/\/api\/langfuse\/?$/u, '/api/objects/batch');
return derived === telemetryRelayUrl ? null : derived.replace(/\/+$/, '');
}
return null;
}
+36 -10
View File
@@ -440,7 +440,7 @@ describe('langfuse-bridge.reportRunCompletedFromDaemon', () => {
});
});
it('keeps production telemetry relay object uploads disabled while preserving fallback manifests', async () => {
it('derives production object uploads from the telemetry relay while keeping bodies out of Langfuse', async () => {
await writeAppCfg({
installationId: 'install-uuid-1',
telemetry: { metrics: true, content: true, artifactManifest: true },
@@ -449,9 +449,35 @@ describe('langfuse-bridge.reportRunCompletedFromDaemon', () => {
await mkdir(projectDir, { recursive: true });
await writeFile(path.join(projectDir, 'brief.txt'), 'private attachment body');
await writeFile(path.join(projectDir, 'index.html'), '<!doctype html><h1>private artifact</h1>');
const fetchSpy = vi
.fn()
.mockResolvedValue(new Response('{}', { status: 207 }));
const fetchSpy = vi.fn(async (url: string, init: RequestInit) => {
if (url.includes('/api/objects/authorize')) {
const parsed = JSON.parse(init.body as string) as {
objects: Array<{ storage_ref: string; sha256: string; size_bytes: number }>;
};
expect(parsed.objects).toHaveLength(2);
return new Response(JSON.stringify({ upload_token: 'upload-token' }), { status: 200 });
}
if (url.includes('/api/objects/batch')) {
const parsed = JSON.parse(init.body as string) as {
upload_token: string;
objects: Array<{ storage_ref: string; content_base64: string }>;
};
expect(parsed.upload_token).toBe('upload-token');
expect(parsed.objects).toHaveLength(2);
return new Response(
JSON.stringify({
objects: parsed.objects.map((object) => ({
storage_ref: object.storage_ref,
status: 'available',
size_bytes: Buffer.from(object.content_base64, 'base64').byteLength,
sha256: `sha256:${object.storage_ref.split('/').at(-1)}`,
})),
}),
{ status: 200 },
);
}
return new Response('{}', { status: 207 });
});
const priorNodeEnv = process.env.NODE_ENV;
process.env.NODE_ENV = 'production';
process.env.OPEN_DESIGN_TELEMETRY_RELAY_URL = 'https://telemetry.open-design.ai/api/langfuse';
@@ -499,10 +525,12 @@ describe('langfuse-bridge.reportRunCompletedFromDaemon', () => {
delete process.env.LANGFUSE_SECRET_KEY;
}
expect(fetchSpy).toHaveBeenCalledTimes(1);
expect(fetchSpy).toHaveBeenCalledTimes(4);
expect(fetchSpy.mock.calls[0]![0]).toContain('/api/langfuse');
expect(fetchSpy.mock.calls[0]![0]).not.toContain('/api/objects/');
const init = fetchSpy.mock.calls[0]![1] as RequestInit;
expect(fetchSpy.mock.calls[1]![0]).toBe('https://telemetry.open-design.ai/api/objects/authorize');
expect(fetchSpy.mock.calls[2]![0]).toBe('https://telemetry.open-design.ai/api/objects/batch');
expect(fetchSpy.mock.calls[3]![0]).toContain('/api/langfuse');
const init = fetchSpy.mock.calls[3]![1] as RequestInit;
const langfuseBody = init.body as string;
expect(langfuseBody).not.toContain('private attachment body');
expect(langfuseBody).not.toContain('<!doctype html><h1>private artifact</h1>');
@@ -519,7 +547,7 @@ describe('langfuse-bridge.reportRunCompletedFromDaemon', () => {
object_class: 'artifact',
status: 'ok',
stored_in_open_design: true,
size_bytes: 41,
size_bytes: '<!doctype html><h1>private artifact</h1>'.length,
});
});
@@ -577,7 +605,6 @@ describe('langfuse-bridge.reportRunCompletedFromDaemon', () => {
return new Response('{}', { status: 207 });
});
process.env.OPEN_DESIGN_OBJECT_RELAY_URL = 'https://telemetry.open-design.ai/api/objects/batch';
process.env.OPEN_DESIGN_TELEMETRY_RELAY_URL = 'https://telemetry.open-design.ai/api/langfuse';
process.env.LANGFUSE_PUBLIC_KEY = 'pk';
process.env.LANGFUSE_SECRET_KEY = 'sk';
@@ -613,7 +640,6 @@ describe('langfuse-bridge.reportRunCompletedFromDaemon', () => {
fetchImpl: fetchSpy as any,
});
} finally {
delete process.env.OPEN_DESIGN_OBJECT_RELAY_URL;
delete process.env.OPEN_DESIGN_TELEMETRY_RELAY_URL;
delete process.env.LANGFUSE_PUBLIC_KEY;
delete process.env.LANGFUSE_SECRET_KEY;
@@ -272,12 +272,33 @@ describe('buildTraceObjectManifests', () => {
expect(manifests?.artifactManifest).toHaveLength(101);
});
it('leaves production telemetry relay configuration to fallback manifests without reading project files', async () => {
it('derives the object relay endpoint from the telemetry relay endpoint', async () => {
const projectsRoot = path.join(dataDir, 'projects');
const projectDir = path.join(projectsRoot, 'proj-1');
await mkdir(projectDir, { recursive: true });
await writeFile(path.join(projectDir, 'artifact.txt'), 'release artifact');
const fetchSpy = vi.fn();
const fetchSpy = vi.fn(async (url: string, init: RequestInit) => {
const parsed = JSON.parse(init.body as string) as {
objects: Array<{ storage_ref: string; content_base64?: string }>;
};
if (url.includes('/api/objects/authorize')) {
expect(parsed.objects).toHaveLength(1);
return new Response(JSON.stringify({ upload_token: 'upload-token' }), { status: 200 });
}
expect(url).toBe('https://telemetry.open-design.ai/api/objects/batch');
expect((parsed as unknown as { upload_token: string }).upload_token).toBe('upload-token');
expect(parsed.objects).toHaveLength(1);
return new Response(
JSON.stringify({
objects: parsed.objects.map((object) => ({
storage_ref: object.storage_ref,
status: 'available',
size_bytes: Buffer.from(object.content_base64!, 'base64').byteLength,
})),
}),
{ status: 200 },
);
});
const manifests = await buildTraceObjectManifests({
installationId: 'install-1',
@@ -292,14 +313,21 @@ describe('buildTraceObjectManifests', () => {
fetchImpl: fetchSpy as any,
env: {
NODE_ENV: 'production',
OPEN_DESIGN_TELEMETRY_RELAY_URL: 'https://telemetry.open-design.ai/api/langfuse',
OPEN_DESIGN_TELEMETRY_RELAY_URL: 'https://telemetry.open-design.ai/api/langfuse//',
},
now: () => new Date('2026-06-08T00:00:00.000Z'),
});
expect(manifests).toBeUndefined();
expect(projectFileReadTracker.calls).toBe(0);
expect(fetchSpy).not.toHaveBeenCalled();
expect(fetchSpy).toHaveBeenCalledTimes(2);
expect(fetchSpy.mock.calls[0]![0]).toBe('https://telemetry.open-design.ai/api/objects/authorize');
expect(fetchSpy.mock.calls[1]![0]).toBe('https://telemetry.open-design.ai/api/objects/batch');
expect(projectFileReadTracker.calls).toBe(1);
expect(manifests?.completeness).toBe('complete');
expect(manifests?.artifactManifest?.[0]).toMatchObject({
status: 'ok',
stored_in_open_design: true,
size_bytes: 'release artifact'.length,
});
});
it('skips over-limit project files before loading their contents', async () => {