api: move wire types and parsing to api module
Move FunctionCall, FunctionCallDelta, ToolCall, ToolCallDelta from tools/mod.rs to api/types.rs — these are API wire format, not tool definitions. Re-export from tools for existing callers. Move parsing.rs to api/parsing.rs — leaked tool call parsing is API plumbing. Co-Authored-By: Proof of Concept <poc@bcachefs.org>
This commit is contained in:
parent
618121067b
commit
6845644f7b
5 changed files with 41 additions and 42 deletions
|
|
@ -6,6 +6,7 @@
|
||||||
// Diagnostics: anomalies always logged to debug panel.
|
// Diagnostics: anomalies always logged to debug panel.
|
||||||
// Set POC_DEBUG=1 for verbose per-turn logging.
|
// Set POC_DEBUG=1 for verbose per-turn logging.
|
||||||
|
|
||||||
|
pub mod parsing;
|
||||||
pub mod types;
|
pub mod types;
|
||||||
mod openai;
|
mod openai;
|
||||||
|
|
||||||
|
|
@ -17,7 +18,8 @@ use std::time::{Duration, Instant};
|
||||||
|
|
||||||
use tokio::sync::mpsc;
|
use tokio::sync::mpsc;
|
||||||
|
|
||||||
use crate::agent::tools::{self as agent_tools, ToolCall, FunctionCall};
|
use crate::agent::tools::{self as agent_tools};
|
||||||
|
use types::{ToolCall, FunctionCall};
|
||||||
use crate::user::ui_channel::{UiMessage, UiSender};
|
use crate::user::ui_channel::{UiMessage, UiSender};
|
||||||
|
|
||||||
/// A JoinHandle that aborts its task when dropped.
|
/// A JoinHandle that aborts its task when dropped.
|
||||||
|
|
@ -488,9 +490,9 @@ pub fn build_response_message(
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check for leaked tool calls in content text.
|
// Check for leaked tool calls in content text.
|
||||||
let leaked = crate::agent::parsing::parse_leaked_tool_calls(&content);
|
let leaked = parsing::parse_leaked_tool_calls(&content);
|
||||||
if !leaked.is_empty() {
|
if !leaked.is_empty() {
|
||||||
let cleaned = crate::agent::parsing::strip_leaked_artifacts(&content);
|
let cleaned = parsing::strip_leaked_artifacts(&content);
|
||||||
return Message {
|
return Message {
|
||||||
role: Role::Assistant,
|
role: Role::Assistant,
|
||||||
content: if cleaned.trim().is_empty() { None }
|
content: if cleaned.trim().is_empty() { None }
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@
|
||||||
// Also handles streaming artifacts: whitespace inside XML tags from
|
// Also handles streaming artifacts: whitespace inside XML tags from
|
||||||
// token boundaries, </think> tags, etc.
|
// token boundaries, </think> tags, etc.
|
||||||
|
|
||||||
use crate::agent::tools::{ToolCall, FunctionCall};
|
use super::types::{ToolCall, FunctionCall};
|
||||||
|
|
||||||
/// Parse leaked tool calls from response text.
|
/// Parse leaked tool calls from response text.
|
||||||
/// Looks for `<tool_call>...</tool_call>` blocks and tries both
|
/// Looks for `<tool_call>...</tool_call>` blocks and tries both
|
||||||
|
|
@ -9,7 +9,38 @@
|
||||||
use chrono::Utc;
|
use chrono::Utc;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use crate::agent::tools::{ToolCall, ToolCallDelta};
|
/// Function call within a tool call — name + JSON arguments.
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
|
pub struct FunctionCall {
|
||||||
|
pub name: String,
|
||||||
|
pub arguments: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Partial function call within a streaming delta.
|
||||||
|
#[derive(Debug, Deserialize)]
|
||||||
|
pub struct FunctionCallDelta {
|
||||||
|
pub name: Option<String>,
|
||||||
|
pub arguments: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A tool call requested by the model.
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
|
pub struct ToolCall {
|
||||||
|
pub id: String,
|
||||||
|
#[serde(rename = "type")]
|
||||||
|
pub call_type: String,
|
||||||
|
pub function: FunctionCall,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A partial tool call within a streaming delta.
|
||||||
|
#[derive(Debug, Deserialize)]
|
||||||
|
pub struct ToolCallDelta {
|
||||||
|
pub index: usize,
|
||||||
|
pub id: Option<String>,
|
||||||
|
#[serde(rename = "type")]
|
||||||
|
pub call_type: Option<String>,
|
||||||
|
pub function: Option<FunctionCallDelta>,
|
||||||
|
}
|
||||||
|
|
||||||
/// Message content — either plain text or an array of content parts
|
/// Message content — either plain text or an array of content parts
|
||||||
/// (for multimodal messages with images). Serializes as a JSON string
|
/// (for multimodal messages with images). Serializes as a JSON string
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,6 @@
|
||||||
pub mod api;
|
pub mod api;
|
||||||
pub mod context;
|
pub mod context;
|
||||||
pub mod oneshot;
|
pub mod oneshot;
|
||||||
pub mod parsing;
|
|
||||||
pub mod tools;
|
pub mod tools;
|
||||||
pub mod training;
|
pub mod training;
|
||||||
|
|
||||||
|
|
@ -340,7 +339,7 @@ impl Agent {
|
||||||
tool_call_buf.push_str(&text);
|
tool_call_buf.push_str(&text);
|
||||||
if let Some(end) = tool_call_buf.find("</tool_call>") {
|
if let Some(end) = tool_call_buf.find("</tool_call>") {
|
||||||
let body = &tool_call_buf[..end];
|
let body = &tool_call_buf[..end];
|
||||||
if let Some(call) = crate::agent::parsing::parse_tool_call_body(body) {
|
if let Some(call) = crate::agent::api::parsing::parse_tool_call_body(body) {
|
||||||
let args: serde_json::Value =
|
let args: serde_json::Value =
|
||||||
serde_json::from_str(&call.function.arguments).unwrap_or_default();
|
serde_json::from_str(&call.function.arguments).unwrap_or_default();
|
||||||
let args_summary = summarize_args(&call.function.name, &args);
|
let args_summary = summarize_args(&call.function.name, &args);
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,6 @@ mod control;
|
||||||
mod vision;
|
mod vision;
|
||||||
pub mod working_stack;
|
pub mod working_stack;
|
||||||
|
|
||||||
use serde::{Serialize, Deserialize};
|
|
||||||
use std::future::Future;
|
use std::future::Future;
|
||||||
use std::pin::Pin;
|
use std::pin::Pin;
|
||||||
use std::time::Instant;
|
use std::time::Instant;
|
||||||
|
|
@ -57,40 +56,8 @@ impl Tool {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Function call within a tool call — name + JSON arguments.
|
// Re-export API wire types used by the agent turn loop
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
pub use super::api::types::{FunctionCall, ToolCall, ToolCallDelta};
|
||||||
pub struct FunctionCall {
|
|
||||||
pub name: String,
|
|
||||||
pub arguments: String,
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Partial function call within a streaming delta.
|
|
||||||
#[derive(Debug, Deserialize)]
|
|
||||||
pub struct FunctionCallDelta {
|
|
||||||
pub name: Option<String>,
|
|
||||||
pub arguments: Option<String>,
|
|
||||||
}
|
|
||||||
|
|
||||||
/// A tool call requested by the model.
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
||||||
pub struct ToolCall {
|
|
||||||
pub id: String,
|
|
||||||
#[serde(rename = "type")]
|
|
||||||
pub call_type: String,
|
|
||||||
pub function: FunctionCall,
|
|
||||||
}
|
|
||||||
|
|
||||||
/// A partial tool call within a streaming delta. The first chunk for a
|
|
||||||
/// given tool call carries the id and function name; subsequent chunks
|
|
||||||
/// carry argument fragments.
|
|
||||||
#[derive(Debug, Deserialize)]
|
|
||||||
pub struct ToolCallDelta {
|
|
||||||
pub index: usize,
|
|
||||||
pub id: Option<String>,
|
|
||||||
#[serde(rename = "type")]
|
|
||||||
pub call_type: Option<String>,
|
|
||||||
pub function: Option<FunctionCallDelta>,
|
|
||||||
}
|
|
||||||
|
|
||||||
/// A tool call in flight — metadata for TUI + JoinHandle for
|
/// A tool call in flight — metadata for TUI + JoinHandle for
|
||||||
/// result collection and cancellation.
|
/// result collection and cancellation.
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue