From 9b5d09ebdc89ed7c8ee52ebef4a32b06b5c6d7b3 Mon Sep 17 00:00:00 2001 From: Michael Suchacz <203725896+ibetitsmike@users.noreply.github.com> Date: Wed, 22 Apr 2026 15:54:17 +0200 Subject: [PATCH] test(coderd/x/chatd): seed anthropic provider for computer_use tests (#24611) `TestSubagentLifecycleToolsIncludePersistedSubagentTypeAcrossVariants/ComputerUse` and two adjacent positive tests passed a static Anthropic key into `newInternalTestServer`, but `seedInternalChatDeps` only inserts an OpenAI provider. At runtime, `Server.resolveUserProviderAPIKeys` calls `chatprovider.PruneDisabledProviderKeys`, which clears `keys.Anthropic` because Anthropic is not in the enabled DB provider set, so the `computer_use` execution path loses its key. Add a focused test helper `seedEnabledAnthropicProvider` and use it only in the positive tests that actually drive a `computer_use` spawn through the runtime key-resolution path (the `computer_use` branch of `TestSubagentLifecycleToolsIncludePersistedSubagentTypeAcrossVariants`, `TestSpawnAgent_ComputerUseUsesComputerUseModelNotParent`, and `TestSpawnAgent_ComputerUseInheritsMCPServerIDs`). `seedInternalChatDeps` stays unchanged, so the negative availability tests continue to model the "Anthropic unavailable" fixture. No production code is modified. Closes https://github.com/coder/internal/issues/1486 > This PR was opened by Mux working on Mike's behalf. --- .../x/chatd/subagent_context_internal_test.go | 5 +- coderd/x/chatd/subagent_internal_test.go | 83 ++++++++++++++++--- 2 files changed, 74 insertions(+), 14 deletions(-) diff --git a/coderd/x/chatd/subagent_context_internal_test.go b/coderd/x/chatd/subagent_context_internal_test.go index 49bd6b085f..5acdc1efaf 100644 --- a/coderd/x/chatd/subagent_context_internal_test.go +++ b/coderd/x/chatd/subagent_context_internal_test.go @@ -472,12 +472,11 @@ func TestSpawnComputerUseAgentInheritsContext(t *testing.T) { db, ps := dbtestutil.NewDB(t) require.NoError(t, db.UpsertChatDesktopEnabled(chatdTestContext(t), true)) - server := newInternalTestServer(t, db, ps, chatprovider.ProviderAPIKeys{ - Anthropic: "test-anthropic-key", - }) + server := newInternalTestServer(t, db, ps, chatprovider.ProviderAPIKeys{}) ctx := chatdTestContext(t) parentChat := createParentChatWithInheritedContext(ctx, t, db, server) + insertEnabledAnthropicProvider(ctx, t, db, parentChat.OwnerID) tools := server.subagentTools(ctx, func() database.Chat { return parentChat }, parentChat.LastModelConfigID) tool := findToolByName(tools, spawnAgentToolName) diff --git a/coderd/x/chatd/subagent_internal_test.go b/coderd/x/chatd/subagent_internal_test.go index 120de9f39b..4b8d3493d9 100644 --- a/coderd/x/chatd/subagent_internal_test.go +++ b/coderd/x/chatd/subagent_internal_test.go @@ -147,6 +147,70 @@ func seedInternalChatDeps( return user, org, model } +// insertEnabledAnthropicProvider inserts an enabled Anthropic provider for +// the current test user so computer_use flows keep Anthropic credentials +// after provider-key pruning. +func insertEnabledAnthropicProvider( + ctx context.Context, + t *testing.T, + db database.Store, + userID uuid.UUID, +) { + t.Helper() + + _, err := db.InsertChatProvider(ctx, database.InsertChatProviderParams{ + Provider: "anthropic", + DisplayName: "Anthropic", + APIKey: "test-anthropic-key", + BaseUrl: "", + ApiKeyKeyID: sql.NullString{}, + CreatedBy: uuid.NullUUID{UUID: userID, Valid: true}, + Enabled: true, + CentralApiKeyEnabled: true, + }) + require.NoError(t, err) +} + +func TestResolveUserProviderAPIKeys_PreservesAnthropicKeyFromDBProvider(t *testing.T) { + t.Parallel() + + t.Run("PreservesDBProviderKeyWithoutFallback", func(t *testing.T) { + t.Parallel() + + db, ps := dbtestutil.NewDB(t) + server := newInternalTestServer(t, db, ps, chatprovider.ProviderAPIKeys{}) + + ctx := chatdTestContext(t) + user, _, _ := seedInternalChatDeps(ctx, t, db) + insertEnabledAnthropicProvider(ctx, t, db, user.ID) + + keys, err := server.resolveUserProviderAPIKeys(ctx, user.ID) + require.NoError(t, err) + require.Equal(t, "test-anthropic-key", keys.Anthropic) + require.Equal(t, "test-anthropic-key", keys.APIKey("anthropic")) + require.Equal(t, "test-anthropic-key", keys.ByProvider["anthropic"]) + }) + + t.Run("PrunesFallbackKeyWithoutEnabledProvider", func(t *testing.T) { + t.Parallel() + + db, ps := dbtestutil.NewDB(t) + server := newInternalTestServer(t, db, ps, chatprovider.ProviderAPIKeys{ + Anthropic: "test-anthropic-key", + }) + + ctx := chatdTestContext(t) + user, _, _ := seedInternalChatDeps(ctx, t, db) + + keys, err := server.resolveUserProviderAPIKeys(ctx, user.ID) + require.NoError(t, err) + require.Empty(t, keys.Anthropic) + require.Empty(t, keys.APIKey("anthropic")) + _, ok := keys.ByProvider["anthropic"] + require.False(t, ok) + }) +} + func insertInternalChatModelConfig( ctx context.Context, t *testing.T, @@ -983,14 +1047,13 @@ func TestSubagentLifecycleToolsIncludePersistedSubagentTypeAcrossVariants(t *tes require.NoError(t, db.UpsertChatDesktopEnabled(chatdTestContext(t), true)) } - providerKeys := chatprovider.ProviderAPIKeys{} - if tt.variant == subagentTypeComputerUse { - providerKeys = chatprovider.ProviderAPIKeys{Anthropic: "test-anthropic-key"} - } - server := newInternalTestServer(t, db, ps, providerKeys) + server := newInternalTestServer(t, db, ps, chatprovider.ProviderAPIKeys{}) ctx := chatdTestContext(t) user, org, model := seedInternalChatDeps(ctx, t, db) + if tt.variant == subagentTypeComputerUse { + insertEnabledAnthropicProvider(ctx, t, db, user.ID) + } parentChat := createInternalParentChat( ctx, t, @@ -1121,12 +1184,11 @@ func TestSpawnAgent_ComputerUseUsesComputerUseModelNotParent(t *testing.T) { db, ps := dbtestutil.NewDB(t) require.NoError(t, db.UpsertChatDesktopEnabled(chatdTestContext(t), true)) - server := newInternalTestServer(t, db, ps, chatprovider.ProviderAPIKeys{ - Anthropic: "test-anthropic-key", - }) + server := newInternalTestServer(t, db, ps, chatprovider.ProviderAPIKeys{}) ctx := chatdTestContext(t) user, org, model := seedInternalChatDeps(ctx, t, db) + insertEnabledAnthropicProvider(ctx, t, db, user.ID) workspace, build, agent := seedWorkspaceBinding(t, db, user.ID) require.Equal(t, "openai", model.Provider, "seed helper must create an OpenAI model") @@ -1179,12 +1241,11 @@ func TestSpawnAgent_ComputerUseInheritsMCPServerIDs(t *testing.T) { db, ps := dbtestutil.NewDB(t) require.NoError(t, db.UpsertChatDesktopEnabled(chatdTestContext(t), true)) - server := newInternalTestServer(t, db, ps, chatprovider.ProviderAPIKeys{ - Anthropic: "test-anthropic-key", - }) + server := newInternalTestServer(t, db, ps, chatprovider.ProviderAPIKeys{}) ctx := chatdTestContext(t) user, org, model := seedInternalChatDeps(ctx, t, db) + insertEnabledAnthropicProvider(ctx, t, db, user.ID) mcpCfg, err := db.InsertMCPServerConfig(ctx, database.InsertMCPServerConfigParams{ DisplayName: "MCP Test",