Kill dead API code: stream_events, parsing.rs, build_response_message, log_diagnostics
Deleted: api/parsing.rs entirely (parsing now in context_new.rs), stream_events (chat completions path), collect_stream, build_response_message, log_diagnostics, tools_to_json_str, start_stream, chat_completion_stream_temp. API layer is now just: stream_completion (token IDs in/out), SseReader, send_and_check, and types. Zero errors in api/. Co-Authored-By: Proof of Concept <poc@bcachefs.org>
This commit is contained in:
parent
48db4a42cc
commit
1e5cd0dd3f
3 changed files with 1 additions and 529 deletions
|
|
@ -7,7 +7,6 @@
|
|||
// Set POC_DEBUG=1 for verbose per-turn logging.
|
||||
|
||||
pub mod http;
|
||||
pub(crate) mod parsing;
|
||||
mod types;
|
||||
mod openai;
|
||||
|
||||
|
|
@ -21,8 +20,6 @@ use self::http::{HttpClient, HttpResponse};
|
|||
|
||||
use tokio::sync::mpsc;
|
||||
|
||||
use crate::agent::tools::{self as agent_tools, summarize_args, ActiveToolCall};
|
||||
|
||||
/// A JoinHandle that aborts its task when dropped.
|
||||
pub(crate) struct AbortOnDrop(tokio::task::JoinHandle<()>);
|
||||
|
||||
|
|
@ -44,12 +41,6 @@ pub(crate) struct SamplingParams {
|
|||
// Stream events — yielded by backends, consumed by the runner
|
||||
// ─────────────────────────────────────────────────────────────
|
||||
|
||||
/// Build the tools JSON string from a slice of Tools.
|
||||
fn tools_to_json_str(tools: &[agent_tools::Tool]) -> String {
|
||||
let inner: Vec<String> = tools.iter().map(|t| t.to_json()).collect();
|
||||
format!("[{}]", inner.join(","))
|
||||
}
|
||||
|
||||
/// One token from the streaming completions API.
|
||||
pub(crate) enum StreamToken {
|
||||
Token { text: String, id: u32 },
|
||||
|
|
@ -359,134 +350,3 @@ impl SseReader {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Build a response Message from accumulated content and tool calls.
|
||||
/// Shared by both backends — the wire format differs but the internal
|
||||
/// representation is the same.
|
||||
///
|
||||
/// If no structured tool calls came from the API but the content
|
||||
/// contains leaked tool call XML (e.g. `<tool_call>...</tool_call>`
|
||||
/// from models that emit tool calls as text), parse them out and
|
||||
/// promote them to structured tool_calls. This way all consumers
|
||||
/// see tool calls uniformly regardless of backend.
|
||||
pub(crate) fn build_response_message(
|
||||
content: String,
|
||||
tool_calls: Vec<ToolCall>,
|
||||
) -> Message {
|
||||
// If the API returned structured tool calls, use them as-is.
|
||||
if !tool_calls.is_empty() {
|
||||
return Message {
|
||||
role: Role::Assistant,
|
||||
content: if content.is_empty() { None }
|
||||
else { Some(MessageContent::Text(content)) },
|
||||
tool_calls: Some(tool_calls),
|
||||
tool_call_id: None,
|
||||
name: None,
|
||||
timestamp: None,
|
||||
};
|
||||
}
|
||||
|
||||
// Check for leaked tool calls in content text.
|
||||
let leaked = parsing::parse_leaked_tool_calls(&content);
|
||||
if !leaked.is_empty() {
|
||||
let cleaned = parsing::strip_leaked_artifacts(&content);
|
||||
return Message {
|
||||
role: Role::Assistant,
|
||||
content: if cleaned.trim().is_empty() { None }
|
||||
else { Some(MessageContent::Text(cleaned)) },
|
||||
tool_calls: Some(leaked),
|
||||
tool_call_id: None,
|
||||
name: None,
|
||||
timestamp: None,
|
||||
};
|
||||
}
|
||||
|
||||
Message {
|
||||
role: Role::Assistant,
|
||||
content: if content.is_empty() { None }
|
||||
else { Some(MessageContent::Text(content)) },
|
||||
tool_calls: None,
|
||||
tool_call_id: None,
|
||||
name: None,
|
||||
timestamp: None,
|
||||
}
|
||||
}
|
||||
|
||||
/// Log stream diagnostics. Shared by both backends.
|
||||
pub(crate) fn log_diagnostics(
|
||||
content_len: usize,
|
||||
tool_count: usize,
|
||||
reasoning_chars: usize,
|
||||
reasoning_effort: &str,
|
||||
finish_reason: &Option<String>,
|
||||
chunks_received: u64,
|
||||
sse_lines_parsed: u64,
|
||||
sse_parse_errors: u64,
|
||||
empty_deltas: u64,
|
||||
total_elapsed: Duration,
|
||||
first_content_at: Option<Duration>,
|
||||
usage: &Option<Usage>,
|
||||
tools: &[ToolCall],
|
||||
) {
|
||||
let debug = std::env::var("POC_DEBUG").is_ok();
|
||||
|
||||
if reasoning_chars > 0 && reasoning_effort == "none" {
|
||||
dbglog!(
|
||||
"note: {} chars leaked reasoning (suppressed from display)",
|
||||
reasoning_chars
|
||||
);
|
||||
}
|
||||
if content_len == 0 && tool_count == 0 {
|
||||
dbglog!(
|
||||
"WARNING: empty response (finish: {:?}, chunks: {}, reasoning: {}, \
|
||||
parse_errors: {}, empty_deltas: {}, {:.1}s)",
|
||||
finish_reason, chunks_received, reasoning_chars,
|
||||
sse_parse_errors, empty_deltas, total_elapsed.as_secs_f64()
|
||||
);
|
||||
}
|
||||
if finish_reason.is_none() && chunks_received > 0 {
|
||||
dbglog!(
|
||||
"WARNING: stream ended without finish_reason ({} chunks, {} content chars)",
|
||||
chunks_received, content_len
|
||||
);
|
||||
}
|
||||
if sse_parse_errors > 0 {
|
||||
dbglog!(
|
||||
"WARNING: {} SSE parse errors out of {} lines",
|
||||
sse_parse_errors, sse_lines_parsed
|
||||
);
|
||||
}
|
||||
|
||||
if debug {
|
||||
if let Some(u) = usage {
|
||||
dbglog!(
|
||||
"tokens: {} prompt + {} completion = {} total",
|
||||
u.prompt_tokens, u.completion_tokens, u.total_tokens
|
||||
);
|
||||
}
|
||||
let ttft = first_content_at
|
||||
.map(|d| format!("{:.1}s", d.as_secs_f64()))
|
||||
.unwrap_or_else(|| "none".to_string());
|
||||
dbglog!(
|
||||
"stream: {:.1}s total, TTFT={}, {} chunks, {} SSE lines, \
|
||||
{} content chars, {} reasoning chars, {} tools, \
|
||||
finish={:?}",
|
||||
total_elapsed.as_secs_f64(),
|
||||
ttft,
|
||||
chunks_received,
|
||||
sse_lines_parsed,
|
||||
content_len,
|
||||
reasoning_chars,
|
||||
tool_count,
|
||||
finish_reason,
|
||||
);
|
||||
if !tools.is_empty() {
|
||||
for (i, tc) in tools.iter().enumerate() {
|
||||
dbglog!(
|
||||
" tool[{}]: {} (id: {}, {} arg chars)",
|
||||
i, tc.function.name, tc.id, tc.function.arguments.len()
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue