diff --git a/src/gateway/server-methods/agent.test.ts b/src/gateway/server-methods/agent.test.ts index 4696d205b83..411d62df9dd 100644 --- a/src/gateway/server-methods/agent.test.ts +++ b/src/gateway/server-methods/agent.test.ts @@ -303,7 +303,7 @@ describe("gateway agent handler", () => { expect(capturedEntry?.acp).toEqual(existingAcpMeta); }); - it("forwards provider and model overrides to ingress agent runs", async () => { + it("forwards provider and model overrides for admin-scoped callers", async () => { primeMainAgentRun(); await invokeAgent( @@ -315,7 +315,14 @@ describe("gateway agent handler", () => { model: "claude-haiku-4-6", idempotencyKey: "test-idem-model-override", }, - { reqId: "test-idem-model-override" }, + { + reqId: "test-idem-model-override", + client: { + connect: { + scopes: ["operator.admin"], + }, + } as AgentHandlerArgs["client"], + }, ); const lastCall = mocks.agentCommand.mock.calls.at(-1); @@ -327,6 +334,37 @@ describe("gateway agent handler", () => { ); }); + it("does not forward provider and model overrides for write-scoped callers", async () => { + primeMainAgentRun(); + + await invokeAgent( + { + message: "test override", + agentId: "main", + sessionKey: "agent:main:main", + provider: "anthropic", + model: "claude-haiku-4-6", + idempotencyKey: "test-idem-model-override-write", + }, + { + reqId: "test-idem-model-override-write", + client: { + connect: { + scopes: ["operator.write"], + }, + } as AgentHandlerArgs["client"], + }, + ); + + const lastCall = mocks.agentCommand.mock.calls.at(-1); + expect(lastCall?.[0]).toEqual( + expect.objectContaining({ + provider: undefined, + model: undefined, + }), + ); + }); + it("preserves cliSessionIds from existing session entry", async () => { const existingCliSessionIds = { "claude-cli": "abc-123-def" }; const existingClaudeCliSessionId = "abc-123-def"; diff --git a/src/gateway/server-methods/agent.ts b/src/gateway/server-methods/agent.ts index 1cfd7798dd2..30fa0f3debb 100644 --- a/src/gateway/server-methods/agent.ts +++ b/src/gateway/server-methods/agent.ts @@ -194,6 +194,8 @@ export const agentHandlers: GatewayRequestHandlers = { inputProvenance?: InputProvenance; }; const senderIsOwner = resolveSenderIsOwnerFromClient(client); + const providerOverride = senderIsOwner ? request.provider : undefined; + const modelOverride = senderIsOwner ? request.model : undefined; const cfg = loadConfig(); const idem = request.idempotencyKey; const normalizedSpawned = normalizeSpawnedRunMetadata({ @@ -586,8 +588,8 @@ export const agentHandlers: GatewayRequestHandlers = { ingressOpts: { message, images, - provider: request.provider, - model: request.model, + provider: providerOverride, + model: modelOverride, to: resolvedTo, sessionId: resolvedSessionId, sessionKey: resolvedSessionKey,