refactor(core)!: model the provider prompt by role, with one file part - #218
Draft
cunninghamcard-bit wants to merge 4 commits into
Draft
cunninghamcard-bit wants to merge 4 commits into
cunninghamcard-bit wants to merge 4 commits into
Conversation
…vider prompts by hand What: deletes 34 test files under aimux-providers/tests. Each one builds provider prompts from the old message struct and asserts request JSON or parsed output that a hand-written mock server returns. Why: the next commit replaces the provider prompt type. These files pin Rust's own earlier behaviour rather than a recording or an upstream sample, so they are removed instead of being rewritten. The same files are removed on the provider factory branch. Recorded-cassette tests, upstream-sample tests and the remaining suites stay and are converted. Co-Authored-By: Claude Fable 5.1 <[email protected]> Claude-Session: https://claude.ai/code/session_01WGwanvo9WLU9HWD7sRR8TS
What: `LanguageModelPrompt` is now `Vec<LanguageModelMessage>`, an enum by role: a system message holds a string; user, assistant and tool messages hold their own part unions (`UserPart`, `AssistantPart`, `ToolPart`). The part structs (`TextPart`, `FilePart`, `ReasoningPart`, `ToolCallPart`, `ToolResultPart`) are each defined once. A provider sees exactly one file part, whose `data` is the existing `FileData` union. `convert_to_language_model_prompt` is the single conversion from user messages: it folds the five user-facing file variants into `FilePart` and rejects a part its role does not allow, or a system message that is not plain text, with `InvalidPrompt`. `LanguageModelPromptMessage` is removed. Why: this is the shape of upstream's `LanguageModelV4Message`. Before, every provider received the user-facing part union for every role, so each converter repeated five file arms and handled role and part combinations that cannot occur. The user-facing `ModelMessage` and `ContentPart` and their JSON are unchanged; the tool result fields and the two signature fields keep their current form and are listed as remaining differences. Co-Authored-By: Claude Fable 5.1 <[email protected]> Claude-Session: https://claude.ai/code/session_01WGwanvo9WLU9HWD7sRR8TS
…and tests What: the vendor converters (OpenAI chat and Responses, Open Responses, Anthropic, Bedrock, Google, Cohere, Mistral, xAI, Hugging Face), the replay helpers, the web and replay tools and the remaining tests match on `LanguageModelMessage` and the per-role parts. The five file arms in each converter become one arm that matches `FilePart.data`; arms for role and part combinations the types rule out are deleted. TypeScript types are regenerated. Why: follow-up to the core change. Request JSON for a given prompt is unchanged; the recorded-cassette and upstream-sample tests pass without any change to cassettes or fixtures. Co-Authored-By: Claude Fable 5.1 <[email protected]> Claude-Session: https://claude.ai/code/session_01WGwanvo9WLU9HWD7sRR8TS
The changelog is what binding authors read before upgrading; the prompt type change alters the provider trait input and the recorded prompt JSON. Co-Authored-By: Claude Fable 5.1 <[email protected]> Claude-Session: https://claude.ai/code/session_01WGwanvo9WLU9HWD7sRR8TS
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
The prompt a provider receives is modelled by role, with one file part, as upstream's
LanguageModelV4Message. Fourth of the protocol-type pull requests; it sits on the provider-options-type one and comes before the provider-factory PR (#214), because every vendor converter reads this type.Before and after
LanguageModelPromptMessage { role, content: Vec<ContentPart>, provider_options }for every roleLanguageModelMessage, an enum by role:System { content: String },User { content: Vec<UserPart> },Assistant { content: Vec<AssistantPart> },Tool { content: Vec<ToolPart> }ContentPartunion, any part under any roleTextPart,FilePart,ReasoningPart,ToolCallPart,ToolResultPart, each defined once; each role lists the parts it allowsImage,File,FileBase64,FileUrl,FileReferenceFilePart { data: FileData, media_type, filename }convert_to_language_model_promptfolds the five file variants intoFilePartand returnsInvalidPromptfor a part its role does not allow or a system message that is not plain textThe user-facing
ModelMessage,ContentPart,Roleand their JSON are unchanged.Vendor code
Each converter matches on the message variant and the per-role part. Its five file arms become one arm that matches
FilePart.data. Arms for role and part combinations that the types rule out are deleted. The request JSON for a given prompt is unchanged.Tests
34 hand-written mock-server test files are deleted in the first commit. They build provider prompts from the removed struct and assert Rust's own earlier behaviour; the same files are deleted on the provider-factory branch. Recorded-cassette tests, upstream-sample tests and the remaining suites are converted and pass.
Not in this pull request
ToolResultPartkeepsresultandis_error; upstream has a structuredoutputunion.ReasoningPart.signatureandToolCallPart.thought_signaturestay as fields; upstream carries them in provider options.Wire format
Recordings store the provider prompt. Its JSON changes in two places: a system message's
contentis a string, and a file part is{"type":"file","data":…}for all five former variants. Cassettes and contract fixtures are unchanged. TypeScript:LanguageModelPromptMessageis replaced byLanguageModelMessageand the part types.Verification
cargo fmt,cargo clippy --workspace --all-targets -D warnings,cargo doc,gen_ts_types.py --check; tests of core, provider-utils, providers, ffi, web, replay, cli: 2612 passed, 0 failed; Node and Python bindingscargo check. Without the deleted test files: 29 files, +1681 / −1859. With them and the changelog entry: 95 files, +2544 / −45865.🤖 Generated with Claude Code
https://claude.ai/code/session_01WGwanvo9WLU9HWD7sRR8TS