vtcode_llm/open_responses/bridge/
mod.rs1use serde_json::json;
8
9use super::{
10 ContentPart, CustomItem, FunctionCallItem, ItemStatus, MessageItem, MessageRole, OpenResponseError, OpenUsage,
11 OutputItem, ReasoningItem, Response, ResponseStatus, ResponseStreamEvent, StreamEventEmitter,
12 response::{generate_item_id, generate_response_id},
13};
14use crate::provider::{FinishReason, NormalizedStreamEvent, ToolCall};
15use vtcode_exec_events::{
16 CommandExecutionStatus, McpToolCallStatus, PatchApplyStatus, ThreadEvent, ThreadItem, ThreadItemDetails,
17 ToolOutputItem,
18};
19
20#[derive(Debug)]
25pub struct ResponseBuilder {
26 response: Response,
27 next_output_index: usize,
28 item_id_to_index: hashbrown::HashMap<String, usize>,
29 active_items: hashbrown::HashMap<String, ActiveItemState>,
30 tool_call_correlation_ids: hashbrown::HashMap<String, String>,
31 used_tool_call_ids: hashbrown::HashSet<String>,
32 normalized: NormalizedBridgeState,
33}
34
35#[derive(Debug, Clone)]
37struct ActiveItemState {
38 output_index: usize,
39 content_index: usize,
40 prev_text: String,
42}
43
44#[derive(Debug, Clone)]
45struct NormalizedFunctionCallState {
46 item_id: String,
47 output_index: usize,
48 name: Option<String>,
49 arguments: String,
50}
51
52#[derive(Debug, Default)]
53struct NormalizedBridgeState {
54 response_started: bool,
55 message_item_id: Option<String>,
56 reasoning_item_id: Option<String>,
57 tool_calls: hashbrown::HashMap<String, NormalizedFunctionCallState>,
58}
59impl ResponseBuilder {
60 pub fn new(model: impl Into<String>) -> Self {
62 let response = Response::new(generate_response_id(), model);
63 Self {
64 response,
65 next_output_index: 0,
66 item_id_to_index: hashbrown::HashMap::new(),
67 active_items: hashbrown::HashMap::new(),
68 tool_call_correlation_ids: hashbrown::HashMap::new(),
69 used_tool_call_ids: hashbrown::HashSet::new(),
70 normalized: NormalizedBridgeState::default(),
71 }
72 }
73
74 pub(crate) fn response(&self) -> &Response {
76 &self.response
77 }
78
79 pub fn response_mut(&mut self) -> &mut Response {
81 &mut self.response
82 }
83
84 pub fn response_id(&self) -> &str {
86 &self.response.id
87 }
88
89 pub fn build(self) -> Response {
91 self.response
92 }
93}
94
95mod emitter;
96mod items;
97mod normalized;
98
99pub use emitter::DualEventEmitter;
100
101#[cfg(test)]
102mod tests;