diff --git a/src/engine/reflection/reflection-runner.test.ts b/src/engine/reflection/reflection-runner.test.ts index 4bfffc4..817b83f 100644 --- a/src/engine/reflection/reflection-runner.test.ts +++ b/src/engine/reflection/reflection-runner.test.ts @@ -44,6 +44,7 @@ function makeDeps() { repo, config: { reflection: {}, userFolderRoot: 'data/users' } as unknown as AppConfig, llmEndpoint: 'http://localhost:1', + llmApiKey: 'sk-reflection-test', llmModel: 'test-model', }; } @@ -170,3 +171,14 @@ describe('runReflectionJob', () => { ); }); }); + +describe('LLM credential propagation', () => { + it('passes the worker apiKey into the reflection LLM config (401 regression)', async () => { + vi.mocked(callReflectionLlm).mockResolvedValue(LLM_RESULT as never); + const deps = makeDeps(); + await runReflectionJob(deps, makeJob()); + expect(callReflectionLlm).toHaveBeenCalled(); + const cfg = vi.mocked(callReflectionLlm).mock.calls[0]![0] as { apiKey?: string }; + expect(cfg.apiKey).toBe('sk-reflection-test'); + }); +}); diff --git a/src/engine/reflection/reflection-runner.ts b/src/engine/reflection/reflection-runner.ts index ce883c2..bd1de90 100644 --- a/src/engine/reflection/reflection-runner.ts +++ b/src/engine/reflection/reflection-runner.ts @@ -18,6 +18,12 @@ export interface RunReflectionDeps { config: AppConfig; llmEndpoint: string; llmModel: string | undefined; + /** + * Worker's API key for the LLM endpoint. Without it, a gateway that + * enforces virtual keys rejects every reflection call with 401 + * (normal task calls always send the worker's key — reflection must too). + */ + llmApiKey?: string; } export async function runReflectionJob( @@ -79,6 +85,7 @@ export async function runReflectionJob( const llmCfg = { endpoint: deps.llmEndpoint, model: deps.llmModel, + apiKey: deps.llmApiKey, }; let llmResult; diff --git a/src/worker.ts b/src/worker.ts index b98a9f3..c2e2e6d 100644 --- a/src/worker.ts +++ b/src/worker.ts @@ -1776,6 +1776,9 @@ export class Worker { config: this.config, llmEndpoint: this.endpoint, llmModel: reflectionRoutingKey, + // Same credential as normal task LLM calls — a key-enforcing + // gateway 401s reflection without it. + llmApiKey: this.getWorkerDef().apiKey, }, job );