chore: use a Conversation type (#3735)
This commit is contained in:
@@ -15,8 +15,8 @@ use super::formats::anthropic::{
|
||||
create_request, get_usage, response_to_message, response_to_streaming_message,
|
||||
};
|
||||
use super::utils::{emit_debug_trace, get_model, map_http_error_to_provider_error};
|
||||
use crate::conversation::message::Message;
|
||||
use crate::impl_provider_default;
|
||||
use crate::message::Message;
|
||||
use crate::model::ModelConfig;
|
||||
use crate::providers::retry::ProviderRetry;
|
||||
use rmcp::model::Tool;
|
||||
|
||||
@@ -10,8 +10,8 @@ use super::errors::ProviderError;
|
||||
use super::formats::openai::{create_request, get_usage, response_to_message};
|
||||
use super::retry::ProviderRetry;
|
||||
use super::utils::{emit_debug_trace, get_model, handle_response_openai_compat, ImageFormat};
|
||||
use crate::conversation::message::Message;
|
||||
use crate::impl_provider_default;
|
||||
use crate::message::Message;
|
||||
use crate::model::ModelConfig;
|
||||
use rmcp::model::Tool;
|
||||
|
||||
|
||||
@@ -4,7 +4,8 @@ use serde::{Deserialize, Serialize};
|
||||
|
||||
use super::errors::ProviderError;
|
||||
use super::retry::RetryConfig;
|
||||
use crate::message::Message;
|
||||
use crate::conversation::message::Message;
|
||||
use crate::conversation::Conversation;
|
||||
use crate::model::ModelConfig;
|
||||
use crate::utils::safe_truncate;
|
||||
use rmcp::model::Tool;
|
||||
@@ -370,7 +371,7 @@ pub trait Provider: Send + Sync {
|
||||
}
|
||||
|
||||
/// Returns the first 3 user messages as strings for session naming
|
||||
fn get_initial_user_messages(&self, messages: &[Message]) -> Vec<String> {
|
||||
fn get_initial_user_messages(&self, messages: &Conversation) -> Vec<String> {
|
||||
messages
|
||||
.iter()
|
||||
.filter(|m| m.role == rmcp::model::Role::User)
|
||||
@@ -381,7 +382,10 @@ pub trait Provider: Send + Sync {
|
||||
|
||||
/// Generate a session name/description based on the conversation history
|
||||
/// Creates a prompt asking for a concise description in 4 words or less.
|
||||
async fn generate_session_name(&self, messages: &[Message]) -> Result<String, ProviderError> {
|
||||
async fn generate_session_name(
|
||||
&self,
|
||||
messages: &Conversation,
|
||||
) -> Result<String, ProviderError> {
|
||||
let context = self.get_initial_user_messages(messages);
|
||||
let prompt = self.create_session_name_prompt(&context);
|
||||
let message = Message::user().with_text(&prompt);
|
||||
|
||||
@@ -3,8 +3,8 @@ use std::collections::HashMap;
|
||||
use super::base::{ConfigKey, Provider, ProviderMetadata, ProviderUsage};
|
||||
use super::errors::ProviderError;
|
||||
use super::retry::ProviderRetry;
|
||||
use crate::conversation::message::Message;
|
||||
use crate::impl_provider_default;
|
||||
use crate::message::Message;
|
||||
use crate::model::ModelConfig;
|
||||
use crate::providers::utils::emit_debug_trace;
|
||||
use anyhow::Result;
|
||||
|
||||
@@ -11,8 +11,8 @@ use super::base::{ConfigKey, Provider, ProviderMetadata, ProviderUsage, Usage};
|
||||
use super::errors::ProviderError;
|
||||
use super::utils::emit_debug_trace;
|
||||
use crate::config::Config;
|
||||
use crate::conversation::message::{Message, MessageContent};
|
||||
use crate::impl_provider_default;
|
||||
use crate::message::{Message, MessageContent};
|
||||
use crate::model::ModelConfig;
|
||||
use rmcp::model::Tool;
|
||||
|
||||
|
||||
@@ -18,8 +18,8 @@ use super::oauth;
|
||||
use super::retry::ProviderRetry;
|
||||
use super::utils::{get_model, handle_response_openai_compat, ImageFormat};
|
||||
use crate::config::ConfigError;
|
||||
use crate::conversation::message::Message;
|
||||
use crate::impl_provider_default;
|
||||
use crate::message::Message;
|
||||
use crate::model::ModelConfig;
|
||||
use crate::providers::formats::openai::{get_usage, response_to_streaming_message};
|
||||
use crate::providers::retry::{
|
||||
|
||||
@@ -174,7 +174,7 @@ fn create_provider(name: &str, model: ModelConfig) -> Result<Arc<dyn Provider>>
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::message::{Message, MessageContent};
|
||||
use crate::conversation::message::{Message, MessageContent};
|
||||
use crate::providers::base::{ProviderMetadata, ProviderUsage, Usage};
|
||||
use chrono::Utc;
|
||||
use rmcp::model::{AnnotateAble, RawTextContent, Role};
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
use crate::message::{Message, MessageContent};
|
||||
use crate::conversation::message::{Message, MessageContent};
|
||||
use crate::model::ModelConfig;
|
||||
use crate::providers::base::Usage;
|
||||
use crate::providers::errors::ProviderError;
|
||||
@@ -676,6 +676,7 @@ where
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::conversation::message::Message;
|
||||
use rmcp::object;
|
||||
use serde_json::json;
|
||||
|
||||
@@ -983,6 +984,7 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_tool_error_handling_maintains_pairing() {
|
||||
use crate::conversation::message::Message;
|
||||
use mcp_core::handler::ToolError;
|
||||
|
||||
let messages = vec![
|
||||
|
||||
@@ -11,7 +11,7 @@ use rmcp::model::{Content, RawContent, ResourceContents, Role, Tool};
|
||||
use serde_json::Value;
|
||||
|
||||
use super::super::base::Usage;
|
||||
use crate::message::{Message, MessageContent};
|
||||
use crate::conversation::message::{Message, MessageContent};
|
||||
|
||||
pub fn to_bedrock_message(message: &Message) -> Result<bedrock::Message> {
|
||||
bedrock::Message::builder()
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
use crate::message::{Message, MessageContent};
|
||||
use crate::conversation::message::{Message, MessageContent};
|
||||
use crate::model::ModelConfig;
|
||||
use crate::providers::utils::{
|
||||
convert_image, detect_image_path, is_valid_function_name, load_image_file, safely_parse_json,
|
||||
@@ -9,6 +9,7 @@ use mcp_core::{ToolCall, ToolError};
|
||||
use rmcp::model::{AnnotateAble, Content, RawContent, ResourceContents, Role, Tool};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde_json::{json, Value};
|
||||
|
||||
#[derive(Serialize)]
|
||||
struct DatabricksMessage {
|
||||
content: Value,
|
||||
@@ -616,6 +617,7 @@ pub fn create_request(
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::conversation::message::Message;
|
||||
use rmcp::object;
|
||||
use serde_json::json;
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use super::{anthropic, google};
|
||||
use crate::message::Message;
|
||||
use crate::conversation::message::Message;
|
||||
use crate::model::ModelConfig;
|
||||
use crate::providers::base::Usage;
|
||||
use anyhow::{Context, Result};
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
use crate::message::{Message, MessageContent};
|
||||
use crate::model::ModelConfig;
|
||||
use crate::providers::base::Usage;
|
||||
use crate::providers::errors::ProviderError;
|
||||
@@ -8,6 +7,7 @@ use mcp_core::tool::ToolCall;
|
||||
use rand::{distributions::Alphanumeric, Rng};
|
||||
use rmcp::model::{AnnotateAble, RawContent, Role, Tool};
|
||||
|
||||
use crate::conversation::message::{Message, MessageContent};
|
||||
use serde_json::{json, Map, Value};
|
||||
use std::ops::Deref;
|
||||
|
||||
@@ -335,6 +335,7 @@ pub fn create_request(
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::conversation::message::Message;
|
||||
use rmcp::{model::Content, object};
|
||||
use serde_json::json;
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
use crate::message::{Message, MessageContent};
|
||||
use crate::conversation::message::{Message, MessageContent};
|
||||
use crate::model::ModelConfig;
|
||||
use crate::providers::base::{ProviderUsage, Usage};
|
||||
use crate::providers::utils::{
|
||||
@@ -641,6 +641,7 @@ pub fn create_request(
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::conversation::message::Message;
|
||||
use rmcp::object;
|
||||
use serde_json::json;
|
||||
use tokio::pin;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
use crate::message::{Message, MessageContent};
|
||||
use crate::conversation::message::{Message, MessageContent};
|
||||
use crate::model::ModelConfig;
|
||||
use crate::providers::base::Usage;
|
||||
use crate::providers::errors::ProviderError;
|
||||
@@ -359,6 +359,7 @@ pub fn create_request(
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::conversation::message::Message;
|
||||
use rmcp::object;
|
||||
use serde_json::json;
|
||||
|
||||
@@ -546,6 +547,7 @@ data: {"id":"a9537c2c-2017-4906-9817-2456168d89fa","model":"claude-3-5-sonnet","
|
||||
|
||||
#[test]
|
||||
fn test_create_request_format() -> Result<()> {
|
||||
use crate::conversation::message::Message;
|
||||
use crate::model::ModelConfig;
|
||||
|
||||
let model_config = ModelConfig::new_or_fail("claude-3-5-sonnet");
|
||||
@@ -654,6 +656,7 @@ data: {"id":"a9537c2c-2017-4906-9817-2456168d89fa","model":"claude-3-5-sonnet","
|
||||
|
||||
#[test]
|
||||
fn test_create_request_excludes_tools_for_description() -> Result<()> {
|
||||
use crate::conversation::message::Message;
|
||||
use crate::model::ModelConfig;
|
||||
|
||||
let model_config = ModelConfig::new_or_fail("claude-3-5-sonnet");
|
||||
@@ -675,6 +678,7 @@ data: {"id":"a9537c2c-2017-4906-9817-2456168d89fa","model":"claude-3-5-sonnet","
|
||||
|
||||
#[test]
|
||||
fn test_message_formatting_skips_tool_requests() {
|
||||
use crate::conversation::message::Message;
|
||||
use mcp_core::tool::ToolCall;
|
||||
|
||||
// Create a conversation with text, tool requests, and tool responses
|
||||
|
||||
@@ -8,7 +8,7 @@ use serde_json::Value;
|
||||
use tokio::time::sleep;
|
||||
use url::Url;
|
||||
|
||||
use crate::message::Message;
|
||||
use crate::conversation::message::Message;
|
||||
use crate::model::ModelConfig;
|
||||
use crate::providers::base::{ConfigKey, Provider, ProviderMetadata, ProviderUsage};
|
||||
|
||||
|
||||
@@ -9,8 +9,8 @@ use tokio::process::Command;
|
||||
use super::base::{Provider, ProviderMetadata, ProviderUsage, Usage};
|
||||
use super::errors::ProviderError;
|
||||
use super::utils::emit_debug_trace;
|
||||
use crate::conversation::message::{Message, MessageContent};
|
||||
use crate::impl_provider_default;
|
||||
use crate::message::{Message, MessageContent};
|
||||
use crate::model::ModelConfig;
|
||||
use rmcp::model::Role;
|
||||
use rmcp::model::Tool;
|
||||
|
||||
@@ -18,8 +18,8 @@ use super::retry::ProviderRetry;
|
||||
use super::utils::{emit_debug_trace, get_model, handle_response_openai_compat, ImageFormat};
|
||||
|
||||
use crate::config::{Config, ConfigError};
|
||||
use crate::conversation::message::Message;
|
||||
use crate::impl_provider_default;
|
||||
use crate::message::Message;
|
||||
use crate::model::ModelConfig;
|
||||
use crate::providers::base::ConfigKey;
|
||||
use rmcp::model::Tool;
|
||||
|
||||
@@ -2,8 +2,8 @@ use super::api_client::{ApiClient, AuthMethod};
|
||||
use super::errors::ProviderError;
|
||||
use super::retry::ProviderRetry;
|
||||
use super::utils::{emit_debug_trace, handle_response_google_compat, unescape_json_values};
|
||||
use crate::conversation::message::Message;
|
||||
use crate::impl_provider_default;
|
||||
use crate::message::Message;
|
||||
use crate::model::ModelConfig;
|
||||
use crate::providers::base::{ConfigKey, Provider, ProviderMetadata, ProviderUsage};
|
||||
use crate::providers::formats::google::{create_request, get_usage, response_to_message};
|
||||
|
||||
@@ -2,8 +2,8 @@ use super::api_client::{ApiClient, AuthMethod};
|
||||
use super::errors::ProviderError;
|
||||
use super::retry::ProviderRetry;
|
||||
use super::utils::{get_model, handle_response_openai_compat};
|
||||
use crate::conversation::message::Message;
|
||||
use crate::impl_provider_default;
|
||||
use crate::message::Message;
|
||||
use crate::model::ModelConfig;
|
||||
use crate::providers::base::{ConfigKey, Provider, ProviderMetadata, ProviderUsage, Usage};
|
||||
use crate::providers::formats::openai::{create_request, get_usage, response_to_message};
|
||||
|
||||
@@ -6,7 +6,7 @@ use tokio::sync::Mutex;
|
||||
|
||||
use super::base::{LeadWorkerProviderTrait, Provider, ProviderMetadata, ProviderUsage};
|
||||
use super::errors::ProviderError;
|
||||
use crate::message::{Message, MessageContent};
|
||||
use crate::conversation::message::{Message, MessageContent};
|
||||
use crate::model::ModelConfig;
|
||||
use rmcp::model::Tool;
|
||||
use rmcp::model::{Content, RawContent};
|
||||
@@ -454,7 +454,7 @@ impl Provider for LeadWorkerProvider {
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::message::MessageContent;
|
||||
use crate::conversation::message::{Message, MessageContent};
|
||||
use crate::providers::base::{ProviderMetadata, ProviderUsage, Usage};
|
||||
use chrono::Utc;
|
||||
use rmcp::model::{AnnotateAble, RawTextContent, Role};
|
||||
|
||||
@@ -9,8 +9,8 @@ use super::embedding::EmbeddingCapable;
|
||||
use super::errors::ProviderError;
|
||||
use super::retry::ProviderRetry;
|
||||
use super::utils::{emit_debug_trace, get_model, handle_response_openai_compat, ImageFormat};
|
||||
use crate::conversation::message::Message;
|
||||
use crate::impl_provider_default;
|
||||
use crate::message::Message;
|
||||
use crate::model::ModelConfig;
|
||||
use rmcp::model::Tool;
|
||||
|
||||
|
||||
@@ -3,8 +3,9 @@ use super::base::{ConfigKey, Provider, ProviderMetadata, ProviderUsage, Usage};
|
||||
use super::errors::ProviderError;
|
||||
use super::retry::ProviderRetry;
|
||||
use super::utils::{get_model, handle_response_openai_compat};
|
||||
use crate::conversation::message::Message;
|
||||
use crate::conversation::Conversation;
|
||||
use crate::impl_provider_default;
|
||||
use crate::message::Message;
|
||||
use crate::model::ModelConfig;
|
||||
use crate::providers::formats::openai::{create_request, get_usage, response_to_message};
|
||||
use crate::utils::safe_truncate;
|
||||
@@ -159,7 +160,10 @@ impl Provider for OllamaProvider {
|
||||
|
||||
/// Generate a session name based on the conversation history
|
||||
/// This override filters out reasoning tokens that some Ollama models produce
|
||||
async fn generate_session_name(&self, messages: &[Message]) -> Result<String, ProviderError> {
|
||||
async fn generate_session_name(
|
||||
&self,
|
||||
messages: &Conversation,
|
||||
) -> Result<String, ProviderError> {
|
||||
let context = self.get_initial_user_messages(messages);
|
||||
let message = Message::user().with_text(self.create_session_name_prompt(&context));
|
||||
let result = self
|
||||
|
||||
@@ -20,8 +20,8 @@ use super::utils::{
|
||||
emit_debug_trace, get_model, handle_response_openai_compat, handle_status_openai_compat,
|
||||
ImageFormat,
|
||||
};
|
||||
use crate::conversation::message::Message;
|
||||
use crate::impl_provider_default;
|
||||
use crate::message::Message;
|
||||
use crate::model::ModelConfig;
|
||||
use crate::providers::base::MessageStream;
|
||||
use crate::providers::formats::openai::response_to_streaming_message;
|
||||
|
||||
@@ -10,8 +10,8 @@ use super::utils::{
|
||||
emit_debug_trace, get_model, handle_response_google_compat, handle_response_openai_compat,
|
||||
is_google_model,
|
||||
};
|
||||
use crate::conversation::message::Message;
|
||||
use crate::impl_provider_default;
|
||||
use crate::message::Message;
|
||||
use crate::model::ModelConfig;
|
||||
use crate::providers::formats::openai::{create_request, get_usage, response_to_message};
|
||||
use rmcp::model::Tool;
|
||||
|
||||
@@ -13,8 +13,8 @@ use super::base::{ConfigKey, Provider, ProviderMetadata, ProviderUsage, Usage};
|
||||
use super::errors::ProviderError;
|
||||
use super::retry::ProviderRetry;
|
||||
use super::utils::emit_debug_trace;
|
||||
use crate::conversation::message::{Message, MessageContent};
|
||||
use crate::impl_provider_default;
|
||||
use crate::message::{Message, MessageContent};
|
||||
use crate::model::ModelConfig;
|
||||
use chrono::Utc;
|
||||
use rmcp::model::Role;
|
||||
|
||||
@@ -10,8 +10,8 @@ use super::formats::snowflake::{create_request, get_usage, response_to_message};
|
||||
use super::retry::ProviderRetry;
|
||||
use super::utils::{get_model, map_http_error_to_provider_error, ImageFormat};
|
||||
use crate::config::ConfigError;
|
||||
use crate::conversation::message::Message;
|
||||
use crate::impl_provider_default;
|
||||
use crate::message::Message;
|
||||
use crate::model::ModelConfig;
|
||||
use rmcp::model::Tool;
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ use std::sync::{Arc, Mutex};
|
||||
|
||||
use super::base::{Provider, ProviderMetadata, ProviderUsage};
|
||||
use super::errors::ProviderError;
|
||||
use crate::message::Message;
|
||||
use crate::conversation::message::Message;
|
||||
use crate::model::ModelConfig;
|
||||
use rmcp::model::Tool;
|
||||
|
||||
@@ -162,7 +162,7 @@ impl Provider for TestProvider {
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::message::{Message, MessageContent};
|
||||
use crate::conversation::message::{Message, MessageContent};
|
||||
use crate::providers::base::{ProviderUsage, Usage};
|
||||
use chrono::Utc;
|
||||
use rmcp::model::{RawTextContent, Role, TextContent};
|
||||
|
||||
@@ -33,7 +33,8 @@
|
||||
use super::errors::ProviderError;
|
||||
use super::ollama::OLLAMA_DEFAULT_PORT;
|
||||
use super::ollama::OLLAMA_HOST;
|
||||
use crate::message::{Message, MessageContent};
|
||||
use crate::conversation::message::{Message, MessageContent};
|
||||
use crate::conversation::Conversation;
|
||||
use crate::model::ModelConfig;
|
||||
use crate::providers::formats::openai::create_request;
|
||||
use anyhow::Result;
|
||||
@@ -310,8 +311,8 @@ pub fn format_tool_info(tools: &[Tool]) -> String {
|
||||
/// Convert messages containing ToolRequest/ToolResponse to text messages for toolshim mode
|
||||
/// This is necessary because some providers (like Bedrock) validate that tool_use/tool_result
|
||||
/// blocks can only exist when tools are defined, but in toolshim mode we pass empty tools
|
||||
pub fn convert_tool_messages_to_text(messages: &[Message]) -> Vec<Message> {
|
||||
messages
|
||||
pub fn convert_tool_messages_to_text(messages: &[Message]) -> Conversation {
|
||||
let converted_messages: Vec<Message> = messages
|
||||
.iter()
|
||||
.map(|message| {
|
||||
let mut new_content = Vec::new();
|
||||
@@ -366,7 +367,9 @@ pub fn convert_tool_messages_to_text(messages: &[Message]) -> Vec<Message> {
|
||||
message.clone()
|
||||
}
|
||||
})
|
||||
.collect()
|
||||
.collect();
|
||||
|
||||
Conversation::new_unvalidated(converted_messages)
|
||||
}
|
||||
|
||||
/// Modifies the system prompt to include tool usage instructions when tool interpretation is enabled
|
||||
|
||||
@@ -9,8 +9,8 @@ use super::base::{ConfigKey, Provider, ProviderMetadata, ProviderUsage, Usage};
|
||||
use super::errors::ProviderError;
|
||||
use super::retry::ProviderRetry;
|
||||
use super::utils::map_http_error_to_provider_error;
|
||||
use crate::conversation::message::{Message, MessageContent};
|
||||
use crate::impl_provider_default;
|
||||
use crate::message::{Message, MessageContent};
|
||||
use crate::model::ModelConfig;
|
||||
use mcp_core::{ToolCall, ToolResult};
|
||||
use rmcp::model::{Role, Tool};
|
||||
|
||||
@@ -2,8 +2,8 @@ use super::api_client::{ApiClient, AuthMethod};
|
||||
use super::errors::ProviderError;
|
||||
use super::retry::ProviderRetry;
|
||||
use super::utils::{get_model, handle_response_openai_compat};
|
||||
use crate::conversation::message::Message;
|
||||
use crate::impl_provider_default;
|
||||
use crate::message::Message;
|
||||
use crate::model::ModelConfig;
|
||||
use crate::providers::base::{ConfigKey, Provider, ProviderMetadata, ProviderUsage, Usage};
|
||||
use crate::providers::formats::openai::{create_request, get_usage, response_to_message};
|
||||
|
||||
Reference in New Issue
Block a user