Make standalone connector config deployable
This commit is contained in:
parent
54d8bc2525
commit
548ee73b01
3 changed files with 150 additions and 8 deletions
96
src/main.rs
96
src/main.rs
|
|
@ -1,11 +1,27 @@
|
|||
use std::ffi::OsString;
|
||||
use std::path::PathBuf;
|
||||
|
||||
use codex_connector::{CodexCallerConfig, CodexDaemonConfig};
|
||||
|
||||
const USAGE: &str = "usage:\n codex-connector --config PATH.cc\n codex-connector --initialize-single-caller-config PATH.cc BIND CODEX_EXECUTABLE CODEX_SHA256 CODEX_HOME REPLAY_STORE CALLER_RUNTIME_ID CONNECTION_KEY_FILE CONNECTION_KEY_EPOCH ALLOWED_MODEL MAX_CONCURRENT_REQUESTS MAX_PAYLOAD_BYTES MAX_OUTPUT_TOKENS";
|
||||
|
||||
fn main() {
|
||||
let mut args = std::env::args_os().skip(1);
|
||||
let config = match (args.next(), args.next(), args.next()) {
|
||||
(Some(flag), Some(path), None) if flag == "--config" => PathBuf::from(path),
|
||||
let args = std::env::args_os().skip(1).collect::<Vec<_>>();
|
||||
if args
|
||||
.first()
|
||||
.is_some_and(|value| value == "--initialize-single-caller-config")
|
||||
{
|
||||
if let Err(error) = initialize_single_caller_config(&args[1..]) {
|
||||
eprintln!("codex-connector config initialization failed: {error}");
|
||||
eprintln!("{USAGE}");
|
||||
std::process::exit(2);
|
||||
}
|
||||
return;
|
||||
}
|
||||
let config = match args.as_slice() {
|
||||
[flag, path] if flag == "--config" => PathBuf::from(path),
|
||||
_ => {
|
||||
eprintln!("usage: codex-connector --config PATH.cc");
|
||||
eprintln!("{USAGE}");
|
||||
std::process::exit(2);
|
||||
}
|
||||
};
|
||||
|
|
@ -14,3 +30,75 @@ fn main() {
|
|||
std::process::exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
fn initialize_single_caller_config(args: &[OsString]) -> Result<(), String> {
|
||||
let [
|
||||
path,
|
||||
bind,
|
||||
executable,
|
||||
executable_sha256,
|
||||
codex_home,
|
||||
replay_store,
|
||||
caller_runtime_id,
|
||||
connection_key_file,
|
||||
connection_key_epoch,
|
||||
allowed_model,
|
||||
max_concurrent_requests,
|
||||
max_payload_bytes,
|
||||
max_output_tokens,
|
||||
] = args
|
||||
else {
|
||||
return Err("expected exactly thirteen configuration values".to_string());
|
||||
};
|
||||
let config = CodexDaemonConfig::single_caller(
|
||||
os_text(bind, "bind")?,
|
||||
PathBuf::from(executable),
|
||||
parse_sha256(executable_sha256)?,
|
||||
PathBuf::from(codex_home),
|
||||
PathBuf::from(replay_store),
|
||||
CodexCallerConfig {
|
||||
caller_runtime_id: os_text(caller_runtime_id, "caller runtime")?,
|
||||
connection_key_file: PathBuf::from(connection_key_file),
|
||||
connection_key_epoch: parse_number(connection_key_epoch, "connection key epoch")?,
|
||||
allowed_models: vec![os_text(allowed_model, "allowed model")?],
|
||||
max_concurrent_requests: parse_number(
|
||||
max_concurrent_requests,
|
||||
"max concurrent requests",
|
||||
)?,
|
||||
max_payload_bytes: parse_number(max_payload_bytes, "max payload bytes")?,
|
||||
max_output_tokens: parse_number(max_output_tokens, "max output tokens")?,
|
||||
},
|
||||
);
|
||||
codex_connector::write_daemon_config(&PathBuf::from(path), &config)
|
||||
.map_err(|error| error.to_string())
|
||||
}
|
||||
|
||||
fn os_text(value: &OsString, field: &str) -> Result<String, String> {
|
||||
value
|
||||
.to_str()
|
||||
.filter(|value| !value.is_empty())
|
||||
.map(str::to_string)
|
||||
.ok_or_else(|| format!("{field} must be non-empty UTF-8"))
|
||||
}
|
||||
|
||||
fn parse_number<T>(value: &OsString, field: &str) -> Result<T, String>
|
||||
where
|
||||
T: std::str::FromStr,
|
||||
{
|
||||
os_text(value, field)?
|
||||
.parse()
|
||||
.map_err(|_| format!("{field} is not a valid integer"))
|
||||
}
|
||||
|
||||
fn parse_sha256(value: &OsString) -> Result<[u8; 32], String> {
|
||||
let value = os_text(value, "Codex SHA-256")?;
|
||||
if value.len() != 64 || !value.bytes().all(|byte| byte.is_ascii_hexdigit()) {
|
||||
return Err("Codex SHA-256 must be exactly 64 hexadecimal characters".to_string());
|
||||
}
|
||||
let mut digest = [0_u8; 32];
|
||||
for (index, output) in digest.iter_mut().enumerate() {
|
||||
*output = u8::from_str_radix(&value[index * 2..index * 2 + 2], 16)
|
||||
.map_err(|_| "Codex SHA-256 is malformed".to_string())?;
|
||||
}
|
||||
Ok(digest)
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue