mirror of
https://github.com/pchuan98/codex.git
synced 2026-07-01 00:31:56 +08:00
add standalone websearch api client (#23655)
add standalone web search request types and a `codex-api` client ahead of the extension-contributed search tool. this adds typed commands/settings and opaque encrypted output handling for the new standalone search flow. the endpoint types are close to finalized but may still shift slightly as that API settles.
This commit is contained in:
committed by
GitHub
Unverified
parent
d84b824d53
commit
ed6d73b3b9
@@ -0,0 +1,246 @@
|
||||
use crate::common::Reasoning;
|
||||
use codex_protocol::models::ResponseItem;
|
||||
use serde::Deserialize;
|
||||
use serde::Serialize;
|
||||
|
||||
#[derive(Debug, Clone, Serialize, PartialEq)]
|
||||
pub struct SearchRequest {
|
||||
pub id: String,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub model: Option<String>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub reasoning: Option<Reasoning>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub input: Option<SearchInput>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub commands: Option<SearchCommands>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub settings: Option<SearchSettings>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub max_output_tokens: Option<u64>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, PartialEq)]
|
||||
#[serde(untagged)]
|
||||
pub enum SearchInput {
|
||||
Text(String),
|
||||
Items(Vec<ResponseItem>),
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, Default, PartialEq)]
|
||||
pub struct SearchCommands {
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub search_query: Option<Vec<SearchQuery>>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub image_query: Option<Vec<SearchQuery>>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub open: Option<Vec<OpenOperation>>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub click: Option<Vec<ClickOperation>>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub find: Option<Vec<FindOperation>>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub screenshot: Option<Vec<ScreenshotOperation>>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub finance: Option<Vec<FinanceOperation>>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub weather: Option<Vec<WeatherOperation>>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub sports: Option<Vec<SportsOperation>>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub time: Option<Vec<TimeOperation>>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub response_length: Option<SearchResponseLength>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
|
||||
pub struct SearchQuery {
|
||||
pub q: String,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub recency: Option<u64>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub domains: Option<Vec<String>>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
|
||||
pub struct OpenOperation {
|
||||
pub ref_id: String,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub lineno: Option<u64>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
|
||||
pub struct ClickOperation {
|
||||
pub ref_id: String,
|
||||
pub id: u64,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
|
||||
pub struct FindOperation {
|
||||
pub ref_id: String,
|
||||
pub pattern: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
|
||||
pub struct ScreenshotOperation {
|
||||
pub ref_id: String,
|
||||
pub pageno: u64,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
|
||||
pub struct FinanceOperation {
|
||||
pub ticker: String,
|
||||
pub r#type: FinanceAssetType,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub market: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
|
||||
#[serde(rename_all = "lowercase")]
|
||||
pub enum FinanceAssetType {
|
||||
Equity,
|
||||
Fund,
|
||||
Crypto,
|
||||
Index,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
|
||||
pub struct WeatherOperation {
|
||||
pub location: String,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub start: Option<String>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub duration: Option<u64>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
|
||||
pub struct SportsOperation {
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub tool: Option<SportsToolName>,
|
||||
pub r#fn: SportsFunction,
|
||||
pub league: SportsLeague,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub team: Option<String>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub opponent: Option<String>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub date_from: Option<String>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub date_to: Option<String>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub num_games: Option<u64>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub locale: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
|
||||
#[serde(rename_all = "lowercase")]
|
||||
pub enum SportsToolName {
|
||||
Sports,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
|
||||
#[serde(rename_all = "lowercase")]
|
||||
pub enum SportsFunction {
|
||||
Schedule,
|
||||
Standings,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
|
||||
#[serde(rename_all = "lowercase")]
|
||||
pub enum SportsLeague {
|
||||
Nba,
|
||||
Wnba,
|
||||
Nfl,
|
||||
Nhl,
|
||||
Mlb,
|
||||
Epl,
|
||||
Ncaamb,
|
||||
Ncaawb,
|
||||
Ipl,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
|
||||
pub struct TimeOperation {
|
||||
pub utc_offset: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
|
||||
#[serde(rename_all = "lowercase")]
|
||||
pub enum SearchResponseLength {
|
||||
Short,
|
||||
Medium,
|
||||
Long,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, Default, PartialEq)]
|
||||
pub struct SearchSettings {
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub user_location: Option<ApproximateLocation>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub search_context_size: Option<SearchContextSize>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub filters: Option<SearchFilters>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub image_settings: Option<SearchImageSettings>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub allowed_callers: Option<Vec<AllowedCaller>>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub external_web_access: Option<bool>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
|
||||
pub struct ApproximateLocation {
|
||||
pub r#type: LocationType,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub country: Option<String>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub region: Option<String>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub city: Option<String>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub timezone: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
|
||||
#[serde(rename_all = "lowercase")]
|
||||
pub enum LocationType {
|
||||
Approximate,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
|
||||
#[serde(rename_all = "lowercase")]
|
||||
pub enum SearchContextSize {
|
||||
Low,
|
||||
Medium,
|
||||
High,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, Default, PartialEq, Eq)]
|
||||
pub struct SearchFilters {
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub allowed_domains: Option<Vec<String>>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub blocked_domains: Option<Vec<String>>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, Default, PartialEq, Eq)]
|
||||
pub struct SearchImageSettings {
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub max_results: Option<u64>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub caption: Option<bool>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum AllowedCaller {
|
||||
Direct,
|
||||
Shell,
|
||||
CodeInterpreter,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Deserialize, PartialEq, Eq)]
|
||||
pub struct SearchResponse {
|
||||
pub encrypted_output: String,
|
||||
}
|
||||
Reference in New Issue
Block a user