Add sandbox
ci/woodpecker/push/tests Pipeline was canceled

This commit is contained in:
qpismont committed 2026-09-17 13:16:15 +00:00
1 parent 536c55f27b
commit 99d1c2feef
16 files changed
+1537 -12

No files matched your search

+43 -1
View File
@@ -1,6 +1,10 @@
use std::time::Duration;
use openrouter_rs::{Message, api::chat::ChatCompletionRequest};
use openrouter_rs::{
Message,
api::chat::ChatCompletionRequest,
types::{Tool, ToolCall},
};
use tracing::instrument;
pub struct ChatResult {
@@ -8,6 +12,12 @@ pub struct ChatResult {
pub cost: Option<f64>,
}
pub struct ToolChatResult {
pub message: Option<String>,
pub tool_calls: Vec<ToolCall>,
pub cost: Option<f64>,
}
#[derive(Clone)]
pub struct OpenRouterClient {
client: openrouter_rs::OpenRouterClient,
@@ -47,4 +57,36 @@ impl OpenRouterClient {
cost: response.usage.and_then(|u| u.cost),
})
}
/// Sends a conversation with tool definitions and returns either a final
/// message or the tool calls requested by the model.
#[instrument(skip(self, messages, tools), err)]
pub async fn chat_with_tools(
&self,
messages: Vec<Message>,
tools: Vec<Tool>,
) -> anyhow::Result<ToolChatResult> {
let request = ChatCompletionRequest::builder()
.model(&self.model)
.enable_reasoning()
.messages(messages)
.tools(tools)
.tool_choice_auto()
.build()?;
let response = self.client.chat().create(&request).await?;
let choice = response
.choices
.first()
.ok_or_else(|| anyhow::anyhow!("No choices in response"))?;
Ok(ToolChatResult {
message: choice.content().map(String::from),
tool_calls: choice
.tool_calls()
.map(<[ToolCall]>::to_vec)
.unwrap_or_default(),
cost: response.usage.and_then(|u| u.cost),
})
}
}