feat: introduce Rig agent runtime migration

This commit is contained in:
2026-08-04 02:15:18 -05:00
parent d9cf0d8ae3
commit 4c7270db8d
39 changed files with 2551 additions and 211 deletions
+2
View File
@@ -11,6 +11,8 @@ pub struct OpenAIClientConfig {
pub model: Option<String>,
pub max_input_tokens: Option<u32>,
pub max_output_tokens: Option<u32>,
pub use_rig: bool,
pub supports_system_messages: bool,
}
pub struct OpenAIClient {
+12 -9
View File
@@ -33,14 +33,14 @@ pub struct OpenAIStreamContext {
pub tool_result_archive: Vec<ConversationMessage>,
}
struct StreamUsage {
input_tokens: i32,
output_tokens: i32,
cache_read_tokens: i32,
cache_write_tokens: i32,
cost_in_cents: f32,
model_id: String,
max_context_tokens: Option<u32>,
pub(crate) struct StreamUsage {
pub(crate) input_tokens: i32,
pub(crate) output_tokens: i32,
pub(crate) cache_read_tokens: i32,
pub(crate) cache_write_tokens: i32,
pub(crate) cost_in_cents: f32,
pub(crate) model_id: String,
pub(crate) max_context_tokens: Option<u32>,
}
pub fn openai_stream_to_response_events(
@@ -533,7 +533,10 @@ fn build_tool_call_message(
)
}
fn build_stream_finished(reason: stream_finished::Reason, usage: StreamUsage) -> ResponseEvent {
pub(crate) fn build_stream_finished(
reason: stream_finished::Reason,
usage: StreamUsage,
) -> ResponseEvent {
let StreamUsage {
input_tokens,
output_tokens,
+54 -43
View File
@@ -24,27 +24,32 @@ pub struct TranslatorRequest {
pub global_rules: Vec<(String, String)>,
}
pub async fn execute(
params: TranslatorRequest,
request: &mut api::Request,
) -> Result<ResponseStream, OpenAIError> {
let client = OpenAIClient::from_config(params.config.clone());
pub(crate) struct PreparedTurn {
pub(crate) task_id: String,
pub(crate) needs_create_task: bool,
pub(crate) user_query: Option<String>,
pub(crate) messages: Vec<ConversationMessage>,
pub(crate) system_prompt: Option<String>,
pub(crate) tools: Vec<crate::ai::provider::types::ToolDefinition>,
pub(crate) model_id: String,
pub(crate) persistent_message_count: usize,
}
let task_id = params.root_task_id.unwrap_or_else(|| {
pub(crate) fn prepare_turn(params: &TranslatorRequest, request: &mut api::Request) -> PreparedTurn {
let task_id = params.root_task_id.clone().unwrap_or_else(|| {
request
.task_context
.as_ref()
.and_then(|tc| tc.tasks.first())
.map(|t| t.id.clone())
.map(|task| task.id.clone())
.unwrap_or_else(|| uuid::Uuid::new_v4().to_string())
});
let needs_create_task = request
.task_context
.as_ref()
.map(|tc| tc.tasks.is_empty())
.map(|task_context| task_context.tasks.is_empty())
.unwrap_or(true);
let model_id = if params.model_id.is_empty() || params.model_id == "auto" {
params
.config
@@ -52,7 +57,6 @@ pub async fn execute(
.clone()
.unwrap_or_else(|| "anthropic/claude-sonnet-4-6".to_string())
} else {
// If a model override is configured in settings, use it
params
.config
.model
@@ -60,25 +64,17 @@ pub async fn execute(
.unwrap_or_else(|| params.model_id.clone())
};
log::info!(
"[openai] Translator: model={model_id}, task_id={task_id}, needs_create_task={needs_create_task}"
);
request_translator::inject_input_messages_into_task(request);
let new_input_messages = request_translator::extract_new_input_messages(request);
let new_input_count = new_input_messages.len();
let persistent_message_count = params.message_history.len() + new_input_messages.len();
let mut messages = Vec::new();
// Prepend progressive summary as first message pair if present
if let Some(ref summary) = params.progressive_summary {
if let Some(summary) = &params.progressive_summary {
messages.push(ConversationMessage {
role: MessageRole::User,
content: MessageContent::Text(format!(
"<conversation-history-summary>\n{}\n</conversation-history-summary>\n\n\
The above summarizes earlier conversation history. The detailed messages below are the most recent exchanges.",
summary
"<conversation-history-summary>\n{summary}\n</conversation-history-summary>\n\n\
The above summarizes earlier conversation history. The detailed messages below are the most recent exchanges."
)),
});
messages.push(ConversationMessage {
@@ -90,26 +86,44 @@ pub async fn execute(
});
}
let history_len = params.message_history.len();
messages.extend(params.message_history);
if !new_input_messages.is_empty() {
log::info!(
"[openai] Appending {} new input messages to history of {}",
new_input_messages.len(),
history_len
);
messages.extend(new_input_messages);
}
messages.extend(params.message_history.clone());
messages.extend(new_input_messages);
for message in &mut messages {
message.truncate_tool_results_for_provider_request();
}
sanitize_messages_for_openai(&mut messages);
let system_prompt = request_translator::extract_system_prompt(request, &params.global_rules);
let tools = request_translator::extract_tools(request);
PreparedTurn {
task_id,
needs_create_task,
user_query: request_translator::extract_user_query_text(request),
messages,
system_prompt: request_translator::extract_system_prompt(request, &params.global_rules),
tools: request_translator::extract_tools(request),
model_id,
persistent_message_count,
}
}
pub async fn execute(
params: TranslatorRequest,
request: &mut api::Request,
) -> Result<ResponseStream, OpenAIError> {
let client = OpenAIClient::from_config(params.config.clone());
let PreparedTurn {
task_id,
needs_create_task,
user_query,
mut messages,
system_prompt,
tools,
model_id,
persistent_message_count,
} = prepare_turn(&params, request);
log::info!(
"[openai] Translator: model={model_id}, task_id={task_id}, needs_create_task={needs_create_task}"
);
log::info!(
"[openai] Sending {} messages, system_prompt={}, tools={}",
@@ -118,8 +132,6 @@ pub async fn execute(
tools.len()
);
let user_query_text = request_translator::extract_user_query_text(request);
let max_output_tokens = params
.config
.max_output_tokens
@@ -139,9 +151,8 @@ pub async fn execute(
// Store the message history for the controller
if let Ok(mut sent) = params.messages_sent.lock() {
let persistent_count = history_len + new_input_count;
if persistent_count > 0 && messages.len() >= persistent_count {
*sent = messages.split_off(messages.len() - persistent_count);
if persistent_message_count > 0 && messages.len() >= persistent_message_count {
*sent = messages.split_off(messages.len() - persistent_message_count);
} else {
*sent = messages;
}
@@ -152,7 +163,7 @@ pub async fn execute(
OpenAIStreamContext {
task_id,
needs_create_task,
user_query: user_query_text,
user_query,
messages_sent: params.messages_sent.clone(),
model_id,
max_context_tokens: params.config.max_input_tokens,