Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,20 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Breaking

- The prompt a provider receives is modelled by role (`aimux-core`), as the AI
SDK's `LanguageModelV4Message`. `LanguageModelPrompt` is
`Vec<LanguageModelMessage>`: `System { content: String }`,
`User { content: Vec<UserPart> }`, `Assistant { content: Vec<AssistantPart> }`,
`Tool { content: Vec<ToolPart> }`. The parts are `TextPart`, `FilePart`,
`ReasoningPart`, `ToolCallPart`, `ToolResultPart`. A provider sees one file
part, `FilePart { data: FileData, media_type, filename }`; the five
user-facing file variants are folded into it by
`convert_to_language_model_prompt`, which now returns `Result` and rejects a
part its role does not allow. `LanguageModelPromptMessage` is removed. The
user-facing `ModelMessage` and `ContentPart` are unchanged. Recordings store
the new prompt JSON: a system message's `content` is a string and every file
input is a `file` part.

- Provider options and provider metadata have one typed shape, the AI SDK's
`Record<string, JSONObject>`: `SharedProviderOptions` and
`SharedProviderMetadata` (`ProviderMetadata` is an alias) are
Expand Down
8 changes: 2 additions & 6 deletions aimux-core/src/composite.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
use std::sync::Arc;

use crate::language_model::LanguageModel;
use crate::language_model_message::{LanguageModelPrompt, LanguageModelPromptMessage};
use crate::language_model_message::{LanguageModelMessage, LanguageModelPrompt};
use crate::result::GenerateContent;
use crate::types::{InputTokenUsage, OutputTokenUsage, Usage};

Expand Down Expand Up @@ -117,10 +117,6 @@ pub fn build_aggregator_prompt(
body.push('\n');
}

out.push(LanguageModelPromptMessage {
role: crate::message::Role::User,
content: vec![crate::content::ContentPart::text(body)],
provider_options: None,
});
out.push(LanguageModelMessage::user_text(body));
out
}
18 changes: 14 additions & 4 deletions aimux-core/src/generate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -527,12 +527,22 @@ pub async fn generate_text(
prompt: impl Into<ModelPrompt>,
options: GenerateTextOptions,
) -> Result<GenerateTextResult, AiMuxError> {
// 1. Convert user prompt to provider-facing prompt.
let (messages, instructions) = split_prompt(prompt.into(), options.instructions.as_deref());
let lm_prompt = convert_to_language_model_prompt(&messages, instructions)?;
generate_text_from_language_model_prompt(model, lm_prompt, messages, options).await
}

// Replay already has a provider prompt. Keep it intact instead of converting
// through user content, which cannot represent every provider part.
pub(crate) async fn generate_text_from_language_model_prompt(
model: &dyn LanguageModel,
lm_prompt: crate::language_model_message::LanguageModelPrompt,
messages: Vec<ModelMessage>,
options: GenerateTextOptions,
) -> Result<GenerateTextResult, AiMuxError> {
let repair_tool_call = options.repair_tool_call.clone();
let tools = options.tools.clone();
let operation_instructions = options.instructions.clone();
let (messages, instructions) = split_prompt(prompt.into(), operation_instructions.as_deref());
let lm_prompt = convert_to_language_model_prompt(&messages, instructions);

// 2. Build CallOptions.
let mut call_options = options.into_call_options(lm_prompt);
Expand Down Expand Up @@ -874,7 +884,7 @@ pub async fn stream_text(
let tools = options.tools.clone();
let operation_instructions = options.instructions.clone();
let (messages, instructions) = split_prompt(prompt.into(), operation_instructions.as_deref());
let lm_prompt = convert_to_language_model_prompt(&messages, instructions);
let lm_prompt = convert_to_language_model_prompt(&messages, instructions)?;

// 2. Build CallOptions.
let mut call_options = options.into_call_options(lm_prompt);
Expand Down
Loading