Skip to content

review fixes + refactoring for 26035#26121

Draft
johnstcn wants to merge 7 commits into
mike/bedrock-config-ds37from
cj/mike/bedrock-config-ds37
Draft

review fixes + refactoring for 26035#26121
johnstcn wants to merge 7 commits into
mike/bedrock-config-ds37from
cj/mike/bedrock-config-ds37

Conversation

@johnstcn
Copy link
Copy Markdown
Member

@johnstcn johnstcn commented Jun 5, 2026

No description provided.

@johnstcn johnstcn self-assigned this Jun 5, 2026
@johnstcn
Copy link
Copy Markdown
Member Author

johnstcn commented Jun 5, 2026

/coder-agents-review

@coder-agents-review
Copy link
Copy Markdown
Contributor

coder-agents-review Bot commented Jun 5, 2026

Chat: Review in progress | View chat
Requested: 2026-06-05 22:10 UTC by @johnstcn

deep-review v0.7.1 | Round 1 | 3b7ca8b..a3bb9f5

Last posted: Round 1, 7 findings (1 P2, 2 P3, 4 Nit), COMMENT. Review

Finding inventory

Findings

# Sev Status Location Summary Round Reviewer Posted
CRF-1 P2 Open ai_providers_migrate.go:150 Error message references dp.Name when loading keys for existing.ID R1 Leorio P2, Razor P3 Yes
CRF-2 P3 Open chatd.go:8661 Best-effort fallback pattern duplicated across 4 call sites R1 Meruem P3, Zoro P3 Yes
CRF-3 P3 Open chatd_internal_test.go:367 require.Error too broad, does not pin to specific error path R1 Chopper Yes
CRF-4 Nit Open chatd_internal_test.go:375 Comment bloat: 3 sentences where 1 delivers the intent R1 Gon Yes
CRF-5 Nit Open subagent_internal_test.go:3668 Comment first sentence restates test name R1 Gon Yes
CRF-6 Nit Open ai_providers_migrate.go:111 existingDType/candidateDType naming cryptic (vestige of deleted wrapper) R1 Gon Yes
CRF-7 Nit Open ai_provider_canonical.go:13 database.AiProviderType* constants not migrated to codersdk.* R1 Kite, Knov, Meruem, Ryosuke, Razor Yes
CRF-8 P3 Dropped by orchestrator (intentional design confirmed by 4+ reviewers) model_routing_direct.go:104 directProviderHintAndProviderForConfig hard-errors vs sibling fallback R1 Kite No

Round log

Round 1

Panel. 1 P2, 2 P3, 4 Nit. 1 dropped. Reviewed against 3b7ca8b..a3bb9f5.

About deep-review

CRF = Coder Review Finding (P0-P4, Nit, Note)

Reviewer Focus
Bisky tests
Chopper ops/errors
Churn-guard change verification
Ging language modernization
Gon naming
Hisoka edge cases
Killua perf
Kite change integrity
Knov contracts
Knuckle SQL
Kurapika security
Law decomposition
Leorio docs
Luffy product
Mafu-san process
Mafuuu contracts
Melody dispatch/pairing
Meruem structural
Nami frontend
Netero mechanical checks
Pariston premise testing
Pen-botter product gaps
Razor verification
Robin duplication
Ryosuke Go arch
Takumi concurrency
Zoro shape

🤖 Managed by Coder Agents.

Copy link
Copy Markdown
Contributor

@coder-agents-review coder-agents-review Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Clean refactoring that removes six wrapper functions across two packages, changes db2sdk.CanonicalAIProviderType to return codersdk.AIProviderType (the right layer for a runtime concept), eliminates double-canonicalization in resolveAIGatewayRoute, and fixes a genuine bug in error reporting at ai_providers_migrate.go:144.

The test coverage is strong: 74.5% test density, every new error path is covered, and the TestEnabledProviderContainsName table-driven suite exercises 8 distinct code paths through the canonical/raw-type fallback logic.

1 P2, 2 P3, 4 Nit.

The P2 is a missed sibling of the bug fix the PR itself introduced: dp.Name at line 150 should be existing.Name, same as the fix at line 144. The P3s cover a test assertion that could be sharper and a question about whether the inlined best-effort fallback pattern (4 identical copies) should be re-consolidated.

"Boring code. Well-structured refactoring. The wrappers added nothing but indirection, and removing them reveals the actual data flow." (Hisoka)


coderd/ai_providers_migrate.go:150

P2 [CRF-1] The PR fixed the same class of bug at line 144 (dp.Nameexisting.Name), but this adjacent error was missed. GetAIProviderKeysByProviderID loads keys for existing.ID, but the error reports dp.Name. When the Bedrock candidate loop (lines 119-131) reassigns existing to a row found via byName["anthropic"], existing.Name differs from dp.Name, misdirecting an operator debugging a key-loading failure.

The PR correctly fixed the sibling at line 144, but the adjacent error on line 150 was missed. In the Bedrock migration path, existing can be set to a candidate found via byName[aibridge.ProviderAnthropic], so existing.Name may differ from dp.Name. (Leorio P2, Razor P3)

Fix: dp.Nameexisting.Name.

🤖

🤖 This review was automatically generated with Coder Agents.

Comment thread coderd/x/chatd/chatd.go
break
}
}
canonicalType, err := db2sdk.CanonicalAIProviderType(provider)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P3 [CRF-2] The PR removes bestEffortCanonicalAIProviderType* but inlines the identical 4-line warn-and-fallback block at 4 sites (chatd.go:8661, model_routing_aibridge.go:295, model_routing_direct.go:83, subagent.go:522). If the fallback behavior needs to change (log level, metric, default value), all four must be updated in lockstep.

The old wrapper absorbed a real decision (error strategy), not just indirection. A replacement helper returning codersdk.AIProviderType would keep the centralized behavior while preserving the return-type improvement. (Meruem P3, Zoro P3)

The trade-off (inline visibility vs DRY) is defensible at 4 copies, so P3. A bestEffortCanonicalAIProviderType(ctx, logger, provider) codersdk.AIProviderType helper would eliminate this drift risk.

🤖

_, _, err := server.directProviderHintAndProviderForConfig(ctx, database.ChatModelConfig{
AIProviderID: uuid.NullUUID{UUID: providerID, Valid: true},
})
require.Error(t, err)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P3 [CRF-3] require.Error(t, err) does not pin the test to the intended failure mode. The mock constrains execution today, but a refactor adding a new error before CanonicalAIProviderType would still pass this test without proving the intended behavioral change (best-effort → hard error).

The sibling test TestAIProviderConfigFromKeysFallsBackToRawTypeOnMalformedSettings does this correctly: it asserts both require.NoError and require.Equal(t, "anthropic", cfg.Provider), which distinguishes the fallback path from the canonical path. (Chopper)

Consider require.ErrorContains(t, err, "canonicalize") to pin to the intended error path.

🤖

Comment on lines +375 to +377
// Build valid Bedrock settings then corrupt the JSON. If parsing succeeded,
// CanonicalAIProviderType would return "bedrock". The fallback must return
// the raw provider.Type ("anthropic"), confirming the fallback path fired.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit [CRF-4] Comment is 36 words narrating the test mechanism when 14 deliver the intent. The test name and assertions already establish the scenario.

Rewrite: // Corrupt valid Bedrock JSON to verify the fallback returns the raw type rather than "bedrock". (Gon)

🤖

Comment on lines +3668 to +3669
// First provider fails canonicalization; second matches canonically.
// Verifies the first-pass loop continues on error rather than aborting.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit [CRF-5] First sentence restates the test name ("first provider fails canonicalization, second matches canonically"). Keep only the useful part: // Verifies the loop continues past canonicalization errors. (Gon)

🤖

return xerrors.Errorf("decode existing settings for %q: %w", existing.Name, err)
}
if canonicalDatabaseAIProviderType(existing.Type, existingSettings) == database.AiProviderTypeBedrock {
existingDType := database.AIProviderType(codersdk.CanonicalAIProviderType(codersdk.AIProviderType(existing.Type), existingSettings))
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit [CRF-6] existingDType and candidateDType (line 126) are cryptic. The "D" is a vestige of the deleted canonicalDatabaseAIProviderType wrapper. Every other site in this PR uses canonicalType or providerType for the same concept. existingCanonicalType and candidateCanonicalType would be self-documenting. (Gon)

🤖

)

func canonicalAIProviderType(provider database.AIProvider) (database.AIProviderType, error) {
return db2sdk.CanonicalAIProviderType(provider)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit [CRF-7] aiProviderTypeCanSatisfyRequest still references database.AiProviderTypeAnthropic and database.AiProviderTypeBedrock. The PR migrated every other switch/comparison in the chatd package to codersdk.AIProviderType* constants. The string values are identical, so no runtime effect, but this is the only holdout. Switching to codersdk.AIProviderTypeAnthropic/codersdk.AIProviderTypeBedrock would complete the migration and drop the database import from this file. (Kite, Knov, Meruem, Ryosuke, Razor)

🤖

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant