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:
ProofOfConcept 2026-04-04 17:58:49 -04:00 committed by Kent Overstreet
parent 618121067b
commit 6845644f7b
5 changed files with 41 additions and 42 deletions

View file

@ -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 }

View file

@ -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

View file

@ -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

View file

@ -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);

View file

@ -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.