Ts a Mistake
This commit is contained in:
11 files changed
+22292
No files matched your search
Generated
+9847
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,43 @@
|
||||
[package]
|
||||
name = "codexport"
|
||||
version = "0.1.0"
|
||||
edition = "2024"
|
||||
|
||||
[dependencies]
|
||||
serde.workspace = true
|
||||
serde_json.workspace = true
|
||||
anyhow.workspace = true
|
||||
rand.workspace = true
|
||||
tokio.workspace = true
|
||||
|
||||
# can this not show up
|
||||
winapi = { version = "=0.3.9", features = ["std"] } # because CODEX toolchain is lowk different
|
||||
icu_calendar = "=2.1.1" # you have to understand i had to look at the codex-rs lockfile for this bs
|
||||
|
||||
[dependencies.codex-backend-client]
|
||||
git = "https://github.com/openai/codex.git"
|
||||
rev = "54ec99cb545176d23790a757a98f18925dcc3191" # today is a good day to update the rev
|
||||
|
||||
[dependencies.codex-login]
|
||||
git = "https://github.com/openai/codex.git"
|
||||
rev = "54ec99cb545176d23790a757a98f18925dcc3191"
|
||||
|
||||
[dependencies.codex-config]
|
||||
git = "https://github.com/openai/codex.git"
|
||||
rev = "54ec99cb545176d23790a757a98f18925dcc3191"
|
||||
|
||||
[dependencies.codex-core]
|
||||
git = "https://github.com/openai/codex.git"
|
||||
rev = "54ec99cb545176d23790a757a98f18925dcc3191"
|
||||
|
||||
[dependencies.codex-protocol]
|
||||
git = "https://github.com/openai/codex.git"
|
||||
rev = "54ec99cb545176d23790a757a98f18925dcc3191"
|
||||
|
||||
# codexport shit
|
||||
# from codex-rs/Cargo.toml
|
||||
[patch.crates-io]
|
||||
# crossterm = { git = "https://github.com/nornagon/crossterm", rev = "87db8bfa6dc99427fd3b071681b07fc31c6ce995" }
|
||||
# ratatui = { git = "https://github.com/nornagon/ratatui", rev = "9b2ad1298408c45918ee9f8241a6f95498cdbed2" }
|
||||
tokio-tungstenite = { git = "https://github.com/openai-oss-forks/tokio-tungstenite", rev = "132f5b39c862e3a970f731d709608b3e6276d5f6" }
|
||||
tungstenite = { git = "https://github.com/openai-oss-forks/tungstenite-rs", rev = "9200079d3b54a1ff51072e24d81fd354f085156f" }
|
||||
@@ -0,0 +1,13 @@
|
||||
yo wsp
|
||||
|
||||
findings
|
||||
|
||||
# authenticate
|
||||
|
||||
you need a Config, then build a AuthManager from it.
|
||||
config will solve: Codex home, chatgpt base url
|
||||
Authdotjson is just File save type.
|
||||
|
||||
# status
|
||||
|
||||
you need to convert Authmanager to Codexauth, then run the backend_client::Client method get_rate_limits with it
|
||||
@@ -0,0 +1,138 @@
|
||||
//! Exports and convenience from [codex-cli][ccrs]
|
||||
//!
|
||||
//! [ccrs]: https://github.com/openai/codex/tree/main/codex-rs
|
||||
|
||||
use std::{path::Path, sync::Arc};
|
||||
|
||||
use anyhow::Context;
|
||||
use codex_backend_client::Client as BackendClient;
|
||||
use codex_core::config::Config;
|
||||
pub use codex_login::AuthDotJson;
|
||||
pub use codex_login::AuthManager as CodexAuthManager;
|
||||
use codex_login::AuthManager;
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Huge {
|
||||
pub config: Config,
|
||||
pub auth_manager: Arc<AuthManager>,
|
||||
pub client: BackendClient,
|
||||
}
|
||||
|
||||
async fn stock_backend_client() -> anyhow::Result<Huge> {
|
||||
let config = Config::load_with_cli_overrides(Vec::new())
|
||||
.await
|
||||
.context("Failed to load config")?;
|
||||
let auth_manager =
|
||||
AuthManager::shared_from_config(&config, /*enable_codex_api_key_env*/ false).await;
|
||||
let auth = auth_manager
|
||||
.auth()
|
||||
.await
|
||||
.ok_or_else(|| anyhow::anyhow!("Not logged in; run `codex login`"))?;
|
||||
|
||||
// Important: only ChatGPT-style auth modes can hit the Codex backend (“wham” or “api/codex”)
|
||||
anyhow::ensure!(auth.uses_codex_backend(), "Need ChatGPT/Codex-backend auth");
|
||||
|
||||
let client = BackendClient::from_auth(config.chatgpt_base_url.clone(), &auth)?;
|
||||
Ok(Huge {
|
||||
config,
|
||||
auth_manager,
|
||||
client,
|
||||
})
|
||||
}
|
||||
|
||||
pub use codex_protocol::protocol::RateLimitSnapshot as RateLimit; // wym snapshot
|
||||
|
||||
async fn quota(client: &BackendClient) -> anyhow::Result<RateLimit> {
|
||||
let quota = client.get_rate_limits().await?;
|
||||
Ok(quota)
|
||||
}
|
||||
|
||||
pub async fn renew(auth_mgr: &AuthManager) -> anyhow::Result<()> {
|
||||
// how is the codex-cli codebase even alive
|
||||
auth_mgr.refresh_token().await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
use anyhow::Result;
|
||||
use codex_login::{CLIENT_ID, ServerOptions, run_login_server};
|
||||
|
||||
/// side effects include:
|
||||
/// - running a temporary server for the device code flow
|
||||
/// - logged in for the rest of the process
|
||||
/// - that thing goes as soon as the process ends because ephemeral store is a lazy mutex
|
||||
/// - does not log out. that will expire after a while.
|
||||
/// - Do not write to disk. If you want to use the same login again, construct an AuthManager with Ephemeral store, and codex_home.
|
||||
/// you'll get the same auth.json in memory
|
||||
/// - this way you CAN logout using the auth manager.
|
||||
pub async fn chatgpt_login_to_auth_json(
|
||||
codex_home: std::path::PathBuf,
|
||||
) -> Result<Option<AuthDotJson>> {
|
||||
let store = codex_login::AuthCredentialsStoreMode::Ephemeral;
|
||||
let opts = ServerOptions::new(
|
||||
codex_home.clone(),
|
||||
CLIENT_ID.to_string(), // oh hell nah son
|
||||
None,
|
||||
store,
|
||||
);
|
||||
|
||||
let server = run_login_server(opts)?;
|
||||
eprintln!("Open this URL to login:\n\n{}\n", server.auth_url);
|
||||
|
||||
server.block_until_done().await?;
|
||||
|
||||
codex_login::load_auth_dot_json(&codex_home, store).context("can not load saved auth.json")
|
||||
}
|
||||
|
||||
pub async fn get_rate_limit() -> anyhow::Result<RateLimit> {
|
||||
let huge = stock_backend_client().await?;
|
||||
quota(&huge.client).await
|
||||
}
|
||||
|
||||
pub async fn use_login_server(
|
||||
codex_home: Option<std::path::PathBuf>,
|
||||
) -> anyhow::Result<Arc<AuthManager>> {
|
||||
// manual map because the ? operator doesn't work in closures and I don't wanna deal with it
|
||||
let codex_home = match codex_home {
|
||||
Some(path) => path,
|
||||
None => codex_core::config::find_codex_home()
|
||||
.context("Can not find codex home")?
|
||||
.into_path_buf(),
|
||||
};
|
||||
let cih = || codex_home.clone();
|
||||
chatgpt_login_to_auth_json(cih()).await?;
|
||||
let auth_mgr = auth_manager(cih(), codex_login::AuthCredentialsStoreMode::Ephemeral).await;
|
||||
Ok(auth_mgr)
|
||||
}
|
||||
|
||||
use codex_config::types::AuthCredentialsStoreMode;
|
||||
use std::path::PathBuf;
|
||||
|
||||
async fn auth_manager(
|
||||
codex_home: PathBuf,
|
||||
store_mode: AuthCredentialsStoreMode,
|
||||
) -> Arc<AuthManager> {
|
||||
AuthManager::shared(
|
||||
codex_home, /*enable_codex_api_key_env*/ false, store_mode,
|
||||
None, // uses default https://chatgpt.com/backend-api
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
||||
/// use this so ephemeral store key is different; idk why you need to login multiple times per session and not just dumping the auth.json to a folder somewhere but hey, you do you
|
||||
pub fn random_ass_codex_home(real_codex_home: &Path, yo: &str) -> PathBuf {
|
||||
real_codex_home.join(yo)
|
||||
}
|
||||
/// use to get a COMPLETELY random path.
|
||||
pub fn random_path_generator(name: Option<String>) -> PathBuf {
|
||||
PathBuf::from_iter(
|
||||
std::iter::repeat_with(|| rand::random::<u64>().to_string())
|
||||
.take(3)
|
||||
.chain(name),
|
||||
)
|
||||
}
|
||||
|
||||
pub async fn auth_mgr_from_auth_json(auth_json: AuthDotJson) -> Result<Arc<AuthManager>> {
|
||||
let store = codex_login::AuthCredentialsStoreMode::Ephemeral;
|
||||
let auth_manager = AuthManager::shared(random_path_generator(None), false, store, None).await; // C ahh arguments
|
||||
Ok(auth_manager)
|
||||
}
|
||||
Reference in new issue
Block a user