Repository navigation
refactor(coderd/x/chatd): inline the model config provider identity - #31000
ibetitsmike wants to merge 1 commit into
Conversation
|
@codex review
|
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
|
Codex Review: Didn't find any major issues. Bravo. Reviewed commit: ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. Codex can also answer questions or update the PR. Try commenting "@codex address that feedback". |
|
@codex review
|
|
Codex Review: Didn't find any major issues. 🎉 Reviewed commit: ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. Codex can also answer questions or update the PR. Try commenting "@codex address that feedback". |
|
@codex review
|
|
Codex Review: Didn't find any major issues. What shall we delve into next? Reviewed commit: ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. Codex can also answer questions or update the PR. Try commenting "@codex address that feedback". |
|
@codex review
|
|
Codex Review: Didn't find any major issues. Hooray! Reviewed commit: ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. Codex can also answer questions or update the PR. Try commenting "@codex address that feedback". |
|
@codex review
|
|
Codex Review: Didn't find any major issues. Nice work! Reviewed commit: ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. Codex can also answer questions or update the PR. Try commenting "@codex address that feedback". |
|
@codex review
|
|
Codex Review: Didn't find any major issues. More of your lovely PRs please. Reviewed commit: ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. Codex can also answer questions or update the PR. Try commenting "@codex address that feedback". |
|
@codex review
|
|
Codex Review: Didn't find any major issues. 🎉 Reviewed commit: ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. Codex can also answer questions or update the PR. Try commenting "@codex address that feedback". |
|
This is fine to land as is. Heads up though: I'm going to look at improving how the provider switch filter works out which provider produced a row, as part of the OpenAI web search replay work (coder/fantasy#78, coder/fantasy#77, #31355). Right now it re-reads each row's model config every turn and compares exact provider rows, which is probably stricter than it needs to be for web search blocks. That'll likely touch these same lines, and will probably come after this is merged.
|
…rsion (#30996) Chat prompt tests built most of their stored-message fixtures in the legacy content format (`content_version` 0), so they exercised the legacy decoder instead of the current one. This PR changes tests only: it stamps those fixtures with `ContentVersionV1` and builds them with `MarshalParts`, so they keep passing after the legacy decoder is removed later in this stack. Tests of the version 0 decoder itself keep their version 0 rows until the layers above remove that decoder. **Why it is safe** - `mustMarshalContent` and `mustMarshalToolResult` now build current parts (`PartFromContent`, `ChatMessageToolResult`) and encode them with `MarshalParts`, the production write path. - `TestMixedFormatConversation` becomes `TestConvertMessagesWithFiles_Conversation` and uses current-format rows only. - `TestParseContent_BackwardCompat` does not change. Migration 000434 stamped every existing row with version 0, so its six cases of current-format parts in version 0 rows still cover the version 0 heuristics. #30998 moves those six cases to version 1 rows when it removes that decoder. - `TestProviderExecutedResult_LegacyToolRow` calls the legacy writers (`MarshalContent`, `MarshalToolResult`) directly, so its provider-executed tool row still goes through the legacy tool-row decoder. - `TestParseContent_ErrorPaths` runs its malformed-input cases on version 1 rows, and runs the same input on version 0 rows of each role (`v0/<role>/malformed_json`), so a version 0 parser that accepts malformed content still fails the suite. #30998 deletes the version 0 cases with that decoder. - I ran the 17 mutants listed below, each a `go test -overlay` edit of the current decode and prompt-conversion code in `chatprompt.go`, against the `chatprompt` and `db2sdk` tests on `main` and on this branch. Every mutant `main` catches is still caught. Two more are caught here: mutant 3, because `TestParseContent_ErrorPaths/system/malformed_json` used to hit the legacy system decoder, and mutant 14, by the new JSON `null` case of `TestConvertMessagesWithFiles_NormalizesAssistantToolCallInput`. Mutants 4 and 8 survive those tests on both. The `chatd` test `TestOrganizationSkillsFollowChatOwnerAccess` catches mutant 4, so 8 is an existing gap. - Mutants of the version 0 decoder fail on `main` and on this branch: version 0 assistant or user rows always take the envelope path, their current-format parts are dropped, legacy tool rows lose `provider_executed`, or a version 0 parser accepts malformed JSON. - With the version 0 case removed from `ParseContent` by an overlay, only tests of version 0 rows fail. #30997 deletes them, except the six `TestParseContent_BackwardCompat` cases, which #30998 moves, and the version 0 cases of `TestParseContent_ErrorPaths`, which #30998 deletes. <details> <summary>The 17 mutants</summary> 1. `ParseContent` returns no parts for a V1 row. 2. V1 decoding skips NUL restoration (`decodeNulInParts`). 3. The V1 parse error says "decode" instead of "parse". 4. Tool error string extraction is off (`toolResultPartToMessagePart`). Only a `chatd` test catches it. 5. Tool call input is dropped. 6. Tool call `ProviderExecuted` is dropped when reading. 7. Resolved file data is dropped. 8. The file media type fallback is dropped (`partsToMessageParts`). Survives. 9. User file IDs are not collected for resolution. 10. Text provider metadata is dropped. 11. File reference text is replaced by the raw content. 12. System messages are dropped. 13. Tool call `ProviderExecuted` is dropped when writing (`PartFromContent`). 14. `normalizeToolCallInput` keeps a JSON `null` input instead of `{}`. Survives on `main` only. 15. Text tool result `ProviderExecuted` is dropped. 16. Tool result IDs are dropped. 17. Assistant file IDs are resolved like user file IDs. </details> **Review focus** The rewritten conversation test in `chatprompt_test.go`. It checks the same prompt shape as before, but every row is in the current format. In the same file, `TestProviderExecutedResult_LegacyToolRow` keeps its legacy rows, `TestParseContent_ErrorPaths` checks malformed input on both content versions, and the input normalization table gains a JSON `null` case. The other changed test files only switch fixtures to the current format: `coderd/x/chatd/chatprompt/file_inline_test.go` (+4/-16), `coderd/database/db2sdk/db2sdk_test.go` (+11/-13), `coderd/x/chatd/message_conversion_test.go` (+3/-2) and `coderd/x/chatd/quickgen_internal_test.go` (+1). **Validation** - `go test ./coderd/x/chatd/... ./coderd/database/db2sdk/ -count=1 -p 4 -parallel 4`: ok - `go vet` on the touched packages and `golangci-lint run --fix=false ./coderd/x/chatd/chatprompt/...`: clean - pre-commit hook: passed **Stack** This stack retires chatd compatibility paths for chat data that older Coder versions stored. 1. #30996 stamp chat message fixtures with the current content version (this PR) 2. #30997 drop tests of the legacy content codec 3. #30998 retire the V0 chat message content decoder 4. #31000 inline the model config provider identity 5. #31005 retire the `close_agent` tool alias > Xum, an AI agent, opened this PR for @ibetitsmike and wrote this description.
825f14a to
7b3e5b4
Compare
This PR deletes
modelConfigProviderIdentityand its test table; both callers now useAIProviderID.UUID.String()directly. The helper fell back to the provider type name for model configs without anai_provider_id. It changes no behavior, because no such config reaches either caller: thechat_model_configs_ai_provider_required_when_activecheck constraint allows a NULLai_provider_idonly on deleted configs, and both callers reject such a config before they read the identity.gatewayProviderForConfig, which returns "AI Gateway routing requires AI provider metadata" for a config without a provider ID.resolveNormalizedProviderForModelConfig, which returnssql.ErrNoRows. The sanitizer treats that origin as unavailable and strips the row's provider-specific state (fail closed), as before.Why it is safe
The deleted table tested the helper. Its live contract is that identity is the provider instance UUID, so two providers of the same type are distinct. I mutated the two inlined lines and ran
./coderd/x/chatd/withgo test -overlay. The tests catch all three mutants:TestActiveServer_AnthropicProviderToolPreRequestGuard,TestOpenAIResponsesFullReplayPairsReasoningAndWebSearchand others fail.TestOpenAIResponsesReasoningNotReplayedAfterModelConfigChange/ProviderMovedandTestProviderSwitchSanitizesAndRestoresPEToolHistoryfail.git grep modelConfigProviderIdentityfinds no references left in the repository, includingsite/,enterprise/,cli/anddocs/.Review focus
sanitizeForeignProviderStateRowsnow discards the normalized provider name thatresolveModelConfigAndNormalizedProviderreturns. It still calls that function, because the function also checks that the config is enabled and its provider is valid.Validation
go test ./coderd/x/chatd/ -count=1 -p 4 -parallel 4: okgo vet ./coderd/x/chatd/andgolangci-lint run --fix=false ./coderd/x/chatd/...: cleanStack
This stack retires chatd compatibility paths for chat data that older Coder versions stored.
close_agenttool alias