mirror of
https://github.com/katanemo/plano.git
synced 2026-05-21 13:55:15 +02:00
Add first-class ChatGPT subscription provider support (#881)
* Add first-class ChatGPT subscription provider support * Address PR feedback: move uuid import to top, reuse parsed config in up() * Add ChatGPT token watchdog for seamless long-lived sessions * Address PR feedback: error on stream=false for ChatGPT, fix auth file permissions * Replace ChatGPT watchdog/restart with passthrough_auth --------- Co-authored-by: Musa Malik <musam@uw.edu>
This commit is contained in:
parent
aa726b1bba
commit
78dc4edad9
18 changed files with 693 additions and 20 deletions
|
|
@ -77,7 +77,7 @@ impl ProviderRequestType {
|
|||
&mut self,
|
||||
provider_id: ProviderId,
|
||||
upstream_api: &SupportedUpstreamAPIs,
|
||||
) {
|
||||
) -> Result<(), ProviderRequestError> {
|
||||
if provider_id == ProviderId::XAI
|
||||
&& matches!(
|
||||
upstream_api,
|
||||
|
|
@ -89,6 +89,48 @@ impl ProviderRequestType {
|
|||
req.web_search_options = None;
|
||||
}
|
||||
}
|
||||
|
||||
// ChatGPT requires instructions, store=false, and input as a list
|
||||
if provider_id == ProviderId::ChatGPT {
|
||||
if let Self::ResponsesAPIRequest(req) = self {
|
||||
use crate::apis::openai_responses::{
|
||||
InputItem, InputMessage, InputParam, MessageContent, MessageRole,
|
||||
};
|
||||
|
||||
const CHATGPT_BASE_INSTRUCTIONS: &str =
|
||||
"You are Codex, based on GPT-5. You are running as a coding agent in the Codex CLI on a user's computer.";
|
||||
match &req.instructions {
|
||||
Some(existing) if existing.contains(CHATGPT_BASE_INSTRUCTIONS) => {}
|
||||
Some(existing) => {
|
||||
req.instructions =
|
||||
Some(format!("{}\n\n{}", CHATGPT_BASE_INSTRUCTIONS, existing));
|
||||
}
|
||||
None => {
|
||||
req.instructions = Some(CHATGPT_BASE_INSTRUCTIONS.to_string());
|
||||
}
|
||||
}
|
||||
req.store = Some(false);
|
||||
if req.stream == Some(false) {
|
||||
return Err(ProviderRequestError {
|
||||
message: "Non-streaming requests are not supported for the ChatGPT Codex provider. Set stream=true or omit the stream field.".to_string(),
|
||||
source: None,
|
||||
});
|
||||
}
|
||||
req.stream = Some(true);
|
||||
|
||||
// ChatGPT backend requires input to be a list, not a plain string
|
||||
if let InputParam::Text(text) = &req.input {
|
||||
req.input = InputParam::Items(vec![InputItem::Message(InputMessage {
|
||||
role: MessageRole::User,
|
||||
content: MessageContent::Text(text.clone()),
|
||||
})]);
|
||||
}
|
||||
if let InputParam::SingleItem(item) = &req.input {
|
||||
req.input = InputParam::Items(vec![item.clone()]);
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -824,10 +866,12 @@ mod tests {
|
|||
..Default::default()
|
||||
});
|
||||
|
||||
request.normalize_for_upstream(
|
||||
ProviderId::XAI,
|
||||
&SupportedUpstreamAPIs::OpenAIChatCompletions(OpenAIApi::ChatCompletions),
|
||||
);
|
||||
request
|
||||
.normalize_for_upstream(
|
||||
ProviderId::XAI,
|
||||
&SupportedUpstreamAPIs::OpenAIChatCompletions(OpenAIApi::ChatCompletions),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let ProviderRequestType::ChatCompletionsRequest(req) = request else {
|
||||
panic!("expected chat request");
|
||||
|
|
@ -852,10 +896,12 @@ mod tests {
|
|||
..Default::default()
|
||||
});
|
||||
|
||||
request.normalize_for_upstream(
|
||||
ProviderId::OpenAI,
|
||||
&SupportedUpstreamAPIs::OpenAIChatCompletions(OpenAIApi::ChatCompletions),
|
||||
);
|
||||
request
|
||||
.normalize_for_upstream(
|
||||
ProviderId::OpenAI,
|
||||
&SupportedUpstreamAPIs::OpenAIChatCompletions(OpenAIApi::ChatCompletions),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let ProviderRequestType::ChatCompletionsRequest(req) = request else {
|
||||
panic!("expected chat request");
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue