Parse `OpenRouter` response to `GraphBit` response
(&self, response: OpenRouterResponse)
| 136 | |
| 137 | /// Parse `OpenRouter` response to `GraphBit` response |
| 138 | fn parse_response(&self, response: OpenRouterResponse) -> GraphBitResult<LlmResponse> { |
| 139 | let choice = |
| 140 | response.choices.into_iter().next().ok_or_else(|| { |
| 141 | GraphBitError::llm_provider("openrouter", "No choices in response") |
| 142 | })?; |
| 143 | |
| 144 | let content = choice.message.content.unwrap_or_default(); |
| 145 | let tool_calls = choice |
| 146 | .message |
| 147 | .tool_calls |
| 148 | .unwrap_or_default() |
| 149 | .into_iter() |
| 150 | .map(|tc| LlmToolCall { |
| 151 | id: tc.id, |
| 152 | name: tc.function.name, |
| 153 | parameters: serde_json::from_str(&tc.function.arguments).unwrap_or_default(), |
| 154 | }) |
| 155 | .collect(); |
| 156 | |
| 157 | let finish_reason = match choice.finish_reason.as_deref() { |
| 158 | Some("stop") => FinishReason::Stop, |
| 159 | Some("length") => FinishReason::Length, |
| 160 | Some("tool_calls") => FinishReason::ToolCalls, |
| 161 | Some("content_filter") => FinishReason::ContentFilter, |
| 162 | Some(other) => FinishReason::Other(other.to_string()), |
| 163 | None => FinishReason::Stop, |
| 164 | }; |
| 165 | |
| 166 | let usage = if let Some(usage) = response.usage { |
| 167 | LlmUsage::new(usage.prompt_tokens, usage.completion_tokens) |
| 168 | } else { |
| 169 | LlmUsage::new(0, 0) |
| 170 | }; |
| 171 | |
| 172 | Ok(LlmResponse::new(content, &self.model) |
| 173 | .with_tool_calls(tool_calls) |
| 174 | .with_usage(usage) |
| 175 | .with_finish_reason(finish_reason) |
| 176 | .with_id(response.id)) |
| 177 | } |
| 178 | } |
| 179 | |
| 180 | #[async_trait] |
no test coverage detected