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)]
25#[must_use = "build the response before discarding the builder"]
26pub struct ResponseBuilder {
27 response: Response,
28 next_output_index: usize,
29 item_id_to_index: hashbrown::HashMap<String, usize>,
30 active_items: hashbrown::HashMap<String, ActiveItemState>,
31 tool_call_correlation_ids: hashbrown::HashMap<String, String>,
32 used_tool_call_ids: hashbrown::HashSet<String>,
33 normalized: NormalizedBridgeState,
34}
35
36#[derive(Debug, Clone)]
38struct ActiveItemState {
39 output_index: usize,
40 content_index: usize,
41 prev_text: String,
43}
44
45#[derive(Debug, Clone)]
46struct NormalizedFunctionCallState {
47 item_id: String,
48 output_index: usize,
49 name: Option<String>,
50 arguments: String,
51}
52
53#[derive(Debug, Default)]
54struct NormalizedBridgeState {
55 response_started: bool,
56 message_item_id: Option<String>,
57 reasoning_item_id: Option<String>,
58 tool_calls: hashbrown::HashMap<String, NormalizedFunctionCallState>,
59}
60impl ResponseBuilder {
61 pub fn new(model: impl Into<String>) -> Self {
63 let response = Response::new(generate_response_id(), model);
64 Self {
65 response,
66 next_output_index: 0,
67 item_id_to_index: hashbrown::HashMap::new(),
68 active_items: hashbrown::HashMap::new(),
69 tool_call_correlation_ids: hashbrown::HashMap::new(),
70 used_tool_call_ids: hashbrown::HashSet::new(),
71 normalized: NormalizedBridgeState::default(),
72 }
73 }
74
75 pub(crate) fn response(&self) -> &Response {
77 &self.response
78 }
79
80 pub fn response_mut(&mut self) -> &mut Response {
82 &mut self.response
83 }
84
85 pub fn response_id(&self) -> &str {
87 &self.response.id
88 }
89
90 #[must_use]
92 pub fn build(self) -> Response {
93 self.response
94 }
95}
96
97mod emitter;
98mod items;
99mod normalized;
100
101pub use emitter::DualEventEmitter;
102
103#[cfg(test)]
104mod tests;