Files
codex/prs/bolinfest/study/PR-2852-study.md
2025-09-02 15:17:45 -07:00

140 lines
5.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
**DOs**
- **Emit Begin/End Pair:** Fire `WebSearchBegin` as a marker and include the actual `query` in `WebSearchEnd` for UI display.
```rust
// Emission
sess.tx_event.send(Event {
id: sub_id.to_string(),
msg: EventMsg::WebSearchBegin(WebSearchBeginEvent { call_id: call_id.clone() }),
}).await.ok();
sess.tx_event.send(Event {
id: sub_id.to_string(),
msg: EventMsg::WebSearchEnd(WebSearchEndEvent { call_id, query }),
}).await.ok();
```
- **Validate IDs Strongly:** Require a non-empty `call_id` on `WebSearchCall` before emitting `WebSearchEnd`; log and skip otherwise.
```rust
match item {
ResponseItem::WebSearchCall {
id: Some(call_id),
action: WebSearchAction::Search { query },
..
} if !call_id.is_empty() => {
sess.tx_event.send(Event {
id: sub_id.to_string(),
msg: EventMsg::WebSearchEnd(WebSearchEndEvent { call_id, query }),
}).await.ok();
}
ResponseItem::WebSearchCall { .. } => {
warn!("web_search_call missing call_id; skipping end event");
}
_ => {}
}
```
- **Centralize Tool Mapping:** Keep the `web_search` vs `web_search_preview` mapping in `OpenAiTool` (serde rename), and let `create_tools_json_for_responses_api` only serialize.
```rust
#[derive(Serialize)]
#[serde(tag = "type", rename_all = "snake_case")]
enum OpenAiTool {
#[serde(rename = "web_search_preview")]
WebSearch {},
}
pub fn create_tools_json_for_responses_api(
tools: &[OpenAiTool],
) -> anyhow::Result<Vec<serde_json::Value>> {
tools.iter().map(serde_json::to_value).collect::<Result<_, _>>().map_err(Into::into)
}
// Client
let tools_json = create_tools_json_for_responses_api(&prompt.tools)?;
```
- **Keep UI-Sensitive Fields Stable (or Plan Deprecations):** If removing `query` from `WebSearchBegin`, ensure UI is updated to read it from `WebSearchEnd` and communicate the change.
- **Exclude From History/Rollouts:** Treat `WebSearchCall` as non-history, non-rollout.
```rust
fn is_api_message(m: &ResponseItem) -> bool {
match m {
ResponseItem::WebSearchCall { .. } | ResponseItem::Other => false,
_ => true,
}
}
```
- **Simplify Ownership:** Prefer moves and defaults over unnecessary clones in config.
```rust
let history = cfg.history.unwrap_or_default();
let shell_environment_policy = cfg.shell_environment_policy.into();
let tui = cfg.tui.unwrap_or_default();
let chatgpt_base_url = config_profile.chatgpt_base_url
.or(cfg.chatgpt_base_url)
.unwrap_or("https://chatgpt.com/backend-api/".to_string());
```
- **Route SSE Explicitly:** Handle `"response.output_item.added"` separately to detect `"web_search_call"`; avoid lumping with unrelated kinds.
```rust
match event.kind.as_str() {
"response.output_item.added" => {
if let Some(item) = event.item.as_ref() {
if item.get("type").and_then(|v| v.as_str()) == Some("web_search_call") {
let call_id = item.get("id").and_then(|v| v.as_str()).unwrap_or("").to_string();
tx_event.send(Ok(ResponseEvent::WebSearchCallBegin { call_id })).await.ok();
}
}
}
"response.output_text.done" | "response.in_progress" => {}
_ => {}
}
```
- **Use Inline `format!` Captures:** Follow repo style for string formatting.
```rust
// DO
let msg = format!("Searched: {query}");
```
- **Update TUI on End:** Flush stream on begin; append a “Searched: …” history cell on end.
```rust
fn on_web_search_begin(&mut self, _: WebSearchBeginEvent) {
self.flush_answer_stream_with_separator();
}
fn on_web_search_end(&mut self, ev: WebSearchEndEvent) {
let query = ev.query;
self.add_to_history(history_cell::new_web_search_call(format!("Searched: {query}")));
}
```
**DONTs**
- **Dont Default Missing IDs:** Avoid `let call_id = id.unwrap_or_else(|| "".to_string());` which masks protocol issues.
```rust
// DON'T
let call_id = id.unwrap_or_else(|| "".to_string());
// DO
if let Some(call_id) = id.filter(|s| !s.is_empty()) { /* ... */ }
```
- **Dont Show Query on Begin:** The begin event may precede the finalized query; display it on `WebSearchEnd` only.
- **Dont Duplicate Tool Logic:** Dont rewrite the tool `type` in multiple layers (e.g., client). Keep it in `OpenAiTool`s serde mapping.
- **Dont Persist WebSearchCall:** Dont add `WebSearchCall` items to conversation history or rollout logs.
- **Dont Over-Clone Config:** Avoid `.clone()` on `Option`/`Copy`-like config fields when `unwrap_or_default`, `.or(...)`, and `.into()` suffice.
- **Dont Use Unsupported Tool Names:** Until the API accepts it reliably, dont send `"web_search"`; use `"web_search_preview"` via serde rename.
- **Dont Collapse SSE Branches:** Dont combine `"response.output_item.added"` with other event kinds; precise routing prevents regressions.
- **Dont Violate `format!` Style:** Avoid positional formatting when implicit captures are possible.
```rust
// DON'T
let msg = format!("Searched: {}", query);
// DO
let msg = format!("Searched: {query}");
```