tool_parser/traits.rs
1use async_trait::async_trait;
2use openai_protocol::common::Tool;
3
4use crate::{
5 errors::ParserResult,
6 types::{StreamingParseResult, ToolCall},
7};
8
9/// Core trait for all tool parsers
10#[async_trait]
11pub trait ToolParser: Send + Sync {
12 /// Parse complete tool calls from final output
13 /// Returns (remaining_normal_text, tool_calls) tuple
14 async fn parse_complete(&self, output: &str) -> ParserResult<(String, Vec<ToolCall>)>;
15
16 /// Like [`Self::parse_complete`], but with the request's tool schemas so
17 /// schema-aware parsers coerce arg values by declared type. The default
18 /// ignores `tools` and delegates to `parse_complete`.
19 async fn parse_complete_with_tools(
20 &self,
21 output: &str,
22 _tools: &[Tool],
23 ) -> ParserResult<(String, Vec<ToolCall>)> {
24 self.parse_complete(output).await
25 }
26
27 /// Parse tool calls from model output (streaming)
28 /// Parsers now maintain internal state, so self is mutable
29 ///
30 /// # Arguments
31 /// * `chunk` - New text chunk from model output
32 /// * `tools` - List of available tools for validation
33 async fn parse_incremental(
34 &mut self,
35 chunk: &str,
36 tools: &[Tool],
37 ) -> ParserResult<StreamingParseResult>;
38
39 /// Check if text contains tool calls in this parser's format
40 fn has_tool_markers(&self, text: &str) -> bool;
41
42 /// Get unstreamed tool call arguments
43 /// Returns tool call items for arguments that have been parsed but not yet streamed
44 fn get_unstreamed_tool_args(&self) -> Option<Vec<crate::types::ToolCallItem>> {
45 None
46 }
47
48 /// Reset the parser state for reuse across requests.
49 /// This should clear all buffers and reset state to initial values.
50 fn reset(&mut self) {
51 // Default no-op implementation
52 }
53}
54
55/// Trait for partial JSON parsing
56pub trait PartialJsonParser: Send + Sync {
57 /// Parse potentially incomplete JSON
58 fn parse(&self, input: &str) -> ParserResult<(serde_json::Value, usize)>;
59
60 /// Check if JSON is complete
61 fn is_complete(&self, input: &str) -> bool;
62
63 /// Get the maximum parsing depth
64 fn max_depth(&self) -> usize;
65}