rig_core/providers/chatgpt/
extension.rs1use std::collections::BTreeMap;
16
17use serde::Serialize;
18use serde_json::Value;
19
20use crate::completion::{ExtensionOptions, ProviderExtension, ReplyExtras};
21use crate::message::Api;
22use crate::providers::openai::extension::{AccessPrograms, Envelope, ItemPhase};
23
24#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
26pub struct ChatGptExt;
27
28impl ProviderExtension for ChatGptExt {
29 const PROVIDER: &'static str = crate::providers::chatgpt::PROVIDER_NAME;
30 type Options = ChatGptOptions;
31 type Extras = ChatGptExtras;
32}
33
34#[non_exhaustive]
38#[derive(Clone, Debug, Default, PartialEq, Serialize)]
39pub struct ChatGptOptions {
40 #[serde(rename = "openai.responses")]
42 pub responses: ChatGptResponses,
43}
44
45impl ChatGptOptions {
46 #[must_use]
48 pub fn prompt_cache_key(mut self, key: impl Into<String>) -> Self {
49 self.responses.prompt_cache_key = Some(key.into());
50 self
51 }
52
53 #[must_use]
55 pub fn client_metadata(mut self, key: impl Into<String>, value: impl Into<String>) -> Self {
56 self.responses
57 .client_metadata
58 .insert(key.into(), value.into());
59 self
60 }
61
62 #[must_use]
64 pub fn access_programs(mut self, programs: AccessPrograms) -> Self {
65 self.responses.access_programs = Some(programs);
66 self
67 }
68}
69
70impl ExtensionOptions for ChatGptOptions {
71 type Ext = ChatGptExt;
72}
73
74#[non_exhaustive]
77#[derive(Clone, Debug, Default, PartialEq, Serialize)]
78pub struct ChatGptResponses {
79 #[serde(skip_serializing_if = "Option::is_none")]
82 pub prompt_cache_key: Option<String>,
83 #[serde(skip_serializing_if = "BTreeMap::is_empty")]
85 pub client_metadata: BTreeMap<String, String>,
86 #[serde(skip_serializing_if = "Option::is_none")]
88 pub access_programs: Option<AccessPrograms>,
89}
90
91#[non_exhaustive]
94#[derive(Clone, Debug, Default, PartialEq)]
95pub struct ChatGptExtras {
96 pub service_tier: Option<String>,
98 pub reasoning_effort: Option<String>,
100 pub reasoning_summary: Option<String>,
102 pub reasoning_mode: Option<String>,
104 pub reasoning_context: Option<String>,
106 pub prompt_cache_retention: Option<String>,
108 pub incomplete_reason: Option<String>,
110 pub phases: Option<Vec<ItemPhase>>,
114}
115
116impl ReplyExtras for ChatGptExtras {
117 fn from_reply(_api: &Api, raw: &Value) -> Result<Self, serde_json::Error> {
118 let envelope = Envelope::from_reply(raw)?;
119 Ok(Self {
120 service_tier: envelope.service_tier,
121 reasoning_effort: envelope.reasoning_effort,
122 reasoning_summary: envelope.reasoning_summary,
123 reasoning_mode: envelope.reasoning_mode,
124 reasoning_context: envelope.reasoning_context,
125 prompt_cache_retention: envelope.prompt_cache_retention,
126 incomplete_reason: envelope.incomplete_reason,
127 phases: envelope.phases,
128 })
129 }
130}
131
132#[cfg(test)]
133mod tests;