use super::*;
use tokio::sync::mpsc;
#[tokio::test]
async fn test_anthropic_text_delta() {
let event = serde_json::json!({
"type": "content_block_delta",
"delta": {"type": "text_delta", "text": "Hello"}
});
let (tx, mut rx) = mpsc::channel(16);
let mut text = String::new();
let mut tool_calls = Vec::new();
let mut usage = TokenUsage { input_tokens: 0, output_tokens: 0 };
let mut stop = StopReason::EndTurn;
let mut current_tool = None;
process_anthropic_event(
&event,
&mut text,
&mut tool_calls,
&mut usage,
&mut stop,
&mut current_tool,
&tx,
)
.await;
assert_eq!(text, "Hello");
let evt = rx.try_recv().expect("expected event");
assert!(matches!(evt, StreamEvent::TextDelta { text } if text == "Hello"));
}
#[tokio::test]
async fn test_anthropic_tool_use_stream() {
let (tx, _rx) = mpsc::channel(16);
let mut text = String::new();
let mut tool_calls = Vec::new();
let mut usage = TokenUsage { input_tokens: 0, output_tokens: 0 };
let mut stop = StopReason::EndTurn;
let mut current_tool = None;
let start = serde_json::json!({
"type": "content_block_start",
"content_block": {
"type": "tool_use",
"id": "tool_abc",
"name": "rag"
}
});
process_anthropic_event(
&start,
&mut text,
&mut tool_calls,
&mut usage,
&mut stop,
&mut current_tool,
&tx,
)
.await;
assert!(current_tool.is_some());
let delta = serde_json::json!({
"type": "content_block_delta",
"delta": {"partial_json": "{\"query\":\"test\"}"}
});
process_anthropic_event(
&delta,
&mut text,
&mut tool_calls,
&mut usage,
&mut stop,
&mut current_tool,
&tx,
)
.await;
let stop_evt = serde_json::json!({
"type": "content_block_stop"
});
process_anthropic_event(
&stop_evt,
&mut text,
&mut tool_calls,
&mut usage,
&mut stop,
&mut current_tool,
&tx,
)
.await;
assert_eq!(tool_calls.len(), 1);
assert_eq!(tool_calls[0].id, "tool_abc");
assert_eq!(tool_calls[0].name, "rag");
assert_eq!(tool_calls[0].input, serde_json::json!({"query": "test"}));
assert!(current_tool.is_none());
}
#[tokio::test]
async fn test_anthropic_message_start_usage() {
let (tx, _rx) = mpsc::channel(16);
let mut text = String::new();
let mut tool_calls = Vec::new();
let mut usage = TokenUsage { input_tokens: 0, output_tokens: 0 };
let mut stop = StopReason::EndTurn;
let mut current_tool = None;
let event = serde_json::json!({
"type": "message_start",
"message": {
"usage": {"input_tokens": 250}
}
});
process_anthropic_event(
&event,
&mut text,
&mut tool_calls,
&mut usage,
&mut stop,
&mut current_tool,
&tx,
)
.await;
assert_eq!(usage.input_tokens, 250);
}
#[tokio::test]
async fn test_anthropic_message_delta_stop() {
let (tx, _rx) = mpsc::channel(16);
let mut text = String::new();
let mut tool_calls = Vec::new();
let mut usage = TokenUsage { input_tokens: 0, output_tokens: 0 };
let mut stop = StopReason::EndTurn;
let mut current_tool = None;
let event = serde_json::json!({
"type": "message_delta",
"delta": {"stop_reason": "max_tokens"},
"usage": {"output_tokens": 4096}
});
process_anthropic_event(
&event,
&mut text,
&mut tool_calls,
&mut usage,
&mut stop,
&mut current_tool,
&tx,
)
.await;
assert_eq!(stop, StopReason::MaxTokens);
assert_eq!(usage.output_tokens, 4096);
}
#[tokio::test]
async fn test_openai_text_delta() {
let event = serde_json::json!({
"choices": [{
"delta": {"content": "World"},
"index": 0
}]
});
let (tx, mut rx) = mpsc::channel(16);
let mut text = String::new();
let mut tool_calls = Vec::new();
let mut usage = TokenUsage { input_tokens: 0, output_tokens: 0 };
let mut stop = StopReason::EndTurn;
process_openai_event(&event, &mut text, &mut tool_calls, &mut usage, &mut stop, &tx).await;
assert_eq!(text, "World");
let evt = rx.try_recv().expect("expected event");
assert!(matches!(evt, StreamEvent::TextDelta { text } if text == "World"));
}
#[tokio::test]
async fn test_openai_tool_call_stream() {
let (tx, _rx) = mpsc::channel(16);
let mut text = String::new();
let mut tool_calls = Vec::new();
let mut usage = TokenUsage { input_tokens: 0, output_tokens: 0 };
let mut stop = StopReason::EndTurn;
let event = serde_json::json!({
"choices": [{
"delta": {
"tool_calls": [{
"index": 0,
"id": "call_1",
"function": {
"name": "rag",
"arguments": "{\"query\":\"test\"}"
}
}]
},
"index": 0
}]
});
process_openai_event(&event, &mut text, &mut tool_calls, &mut usage, &mut stop, &tx).await;
assert_eq!(tool_calls.len(), 1);
assert_eq!(tool_calls[0].id, "call_1");
assert_eq!(tool_calls[0].name, "rag");
}
#[tokio::test]
async fn test_openai_finish_reason() {
let (tx, _rx) = mpsc::channel(16);
let mut text = String::new();
let mut tool_calls = Vec::new();
let mut usage = TokenUsage { input_tokens: 0, output_tokens: 0 };
let mut stop = StopReason::EndTurn;
let event = serde_json::json!({
"choices": [{
"delta": {},
"finish_reason": "length",
"index": 0
}]
});
process_openai_event(&event, &mut text, &mut tool_calls, &mut usage, &mut stop, &tx).await;
assert_eq!(stop, StopReason::MaxTokens);
}
#[tokio::test]
async fn test_openai_usage_event() {
let (tx, _rx) = mpsc::channel(16);
let mut text = String::new();
let mut tool_calls = Vec::new();
let mut usage = TokenUsage { input_tokens: 0, output_tokens: 0 };
let mut stop = StopReason::EndTurn;
let event = serde_json::json!({
"choices": [{"delta": {}, "index": 0}],
"usage": {
"prompt_tokens": 150,
"completion_tokens": 80
}
});
process_openai_event(&event, &mut text, &mut tool_calls, &mut usage, &mut stop, &tx).await;
assert_eq!(usage.input_tokens, 150);
assert_eq!(usage.output_tokens, 80);
}
#[tokio::test]
async fn test_anthropic_unknown_event_type_ignored() {
let (tx, _rx) = mpsc::channel(16);
let mut text = String::new();
let mut tool_calls = Vec::new();
let mut usage = TokenUsage { input_tokens: 0, output_tokens: 0 };
let mut stop = StopReason::EndTurn;
let mut current_tool = None;
let event = serde_json::json!({
"type": "ping"
});
process_anthropic_event(
&event,
&mut text,
&mut tool_calls,
&mut usage,
&mut stop,
&mut current_tool,
&tx,
)
.await;
assert!(text.is_empty());
assert!(tool_calls.is_empty());
}
#[tokio::test]
async fn test_anthropic_tool_use_stop_reason() {
let (tx, _rx) = mpsc::channel(16);
let mut text = String::new();
let mut tool_calls = Vec::new();
let mut usage = TokenUsage { input_tokens: 0, output_tokens: 0 };
let mut stop = StopReason::EndTurn;
let mut current_tool = None;
let event = serde_json::json!({
"type": "message_delta",
"delta": {"stop_reason": "tool_use"},
"usage": {"output_tokens": 100}
});
process_anthropic_event(
&event,
&mut text,
&mut tool_calls,
&mut usage,
&mut stop,
&mut current_tool,
&tx,
)
.await;
assert_eq!(stop, StopReason::ToolUse);
}
#[tokio::test]
async fn test_anthropic_stop_sequence_reason() {
let (tx, _rx) = mpsc::channel(16);
let mut text = String::new();
let mut tool_calls = Vec::new();
let mut usage = TokenUsage { input_tokens: 0, output_tokens: 0 };
let mut stop = StopReason::EndTurn;
let mut current_tool = None;
let event = serde_json::json!({
"type": "message_delta",
"delta": {"stop_reason": "stop_sequence"},
"usage": {"output_tokens": 42}
});
process_anthropic_event(
&event,
&mut text,
&mut tool_calls,
&mut usage,
&mut stop,
&mut current_tool,
&tx,
)
.await;
assert_eq!(stop, StopReason::StopSequence);
assert_eq!(usage.output_tokens, 42);
}
#[tokio::test]
async fn test_anthropic_content_block_start_text() {
let (tx, _rx) = mpsc::channel(16);
let mut text = String::new();
let mut tool_calls = Vec::new();
let mut usage = TokenUsage { input_tokens: 0, output_tokens: 0 };
let mut stop = StopReason::EndTurn;
let mut current_tool = None;
let event = serde_json::json!({
"type": "content_block_start",
"content_block": {
"type": "text",
"text": ""
}
});
process_anthropic_event(
&event,
&mut text,
&mut tool_calls,
&mut usage,
&mut stop,
&mut current_tool,
&tx,
)
.await;
assert!(current_tool.is_none());
}
#[tokio::test]
async fn test_anthropic_content_block_stop_no_tool() {
let (tx, _rx) = mpsc::channel(16);
let mut text = String::new();
let mut tool_calls = Vec::new();
let mut usage = TokenUsage { input_tokens: 0, output_tokens: 0 };
let mut stop = StopReason::EndTurn;
let mut current_tool = None;
let event = serde_json::json!({
"type": "content_block_stop"
});
process_anthropic_event(
&event,
&mut text,
&mut tool_calls,
&mut usage,
&mut stop,
&mut current_tool,
&tx,
)
.await;
assert!(tool_calls.is_empty());
}
#[tokio::test]
async fn test_openai_tool_calls_stop_reason() {
let (tx, _rx) = mpsc::channel(16);
let mut text = String::new();
let mut tool_calls = Vec::new();
let mut usage = TokenUsage { input_tokens: 0, output_tokens: 0 };
let mut stop = StopReason::EndTurn;
let event = serde_json::json!({
"choices": [{
"delta": {},
"finish_reason": "tool_calls",
"index": 0
}]
});
process_openai_event(&event, &mut text, &mut tool_calls, &mut usage, &mut stop, &tx).await;
assert_eq!(stop, StopReason::ToolUse);
}