mirror of
https://github.com/openai/codex.git
synced 2026-05-05 20:07:02 +00:00
Compare commits
1 Commits
pr20314-ap
...
etraut/app
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4a117c50ee |
@@ -190,6 +190,8 @@ pub struct InProcessClientStartArgs {
|
||||
pub enable_codex_api_key_env: bool,
|
||||
/// Client name reported during initialize.
|
||||
pub client_name: String,
|
||||
/// Optional backend originator override reported during initialize.
|
||||
pub originator_override: Option<String>,
|
||||
/// Client version reported during initialize.
|
||||
pub client_version: String,
|
||||
/// Whether experimental APIs are requested at initialize time.
|
||||
@@ -242,6 +244,7 @@ impl InProcessClientStartArgs {
|
||||
title: None,
|
||||
version: self.client_version.clone(),
|
||||
},
|
||||
originator_override: self.originator_override.clone(),
|
||||
capabilities: Some(capabilities),
|
||||
}
|
||||
}
|
||||
@@ -891,6 +894,7 @@ mod tests {
|
||||
session_source,
|
||||
enable_codex_api_key_env: false,
|
||||
client_name: "codex-app-server-client-test".to_string(),
|
||||
originator_override: None,
|
||||
client_version: "0.0.0-test".to_string(),
|
||||
experimental_api: true,
|
||||
opt_out_notification_methods: Vec::new(),
|
||||
@@ -988,6 +992,7 @@ mod tests {
|
||||
RemoteAppServerConnectArgs {
|
||||
websocket_url,
|
||||
client_name: "codex-app-server-client-test".to_string(),
|
||||
originator_override: None,
|
||||
client_version: "0.0.0-test".to_string(),
|
||||
experimental_api: true,
|
||||
opt_out_notification_methods: Vec::new(),
|
||||
@@ -995,6 +1000,56 @@ mod tests {
|
||||
}
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn initialize_params_include_originator_override_when_set() {
|
||||
let args = InProcessClientStartArgs {
|
||||
arg0_paths: Arg0DispatchPaths::default(),
|
||||
config: Arc::new(build_test_config().await),
|
||||
cli_overrides: Vec::new(),
|
||||
loader_overrides: LoaderOverrides::default(),
|
||||
cloud_requirements: CloudRequirementsLoader::default(),
|
||||
feedback: CodexFeedback::new(),
|
||||
config_warnings: Vec::new(),
|
||||
session_source: SessionSource::Cli,
|
||||
enable_codex_api_key_env: false,
|
||||
client_name: "codex-tui".to_string(),
|
||||
originator_override: Some("codex_cli_rs".to_string()),
|
||||
client_version: "0.0.0-test".to_string(),
|
||||
experimental_api: true,
|
||||
opt_out_notification_methods: Vec::new(),
|
||||
channel_capacity: 1,
|
||||
};
|
||||
|
||||
let params = args.initialize_params();
|
||||
|
||||
assert_eq!(params.originator_override, Some("codex_cli_rs".to_string()));
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn initialize_params_omit_originator_override_when_absent() {
|
||||
let args = InProcessClientStartArgs {
|
||||
arg0_paths: Arg0DispatchPaths::default(),
|
||||
config: Arc::new(build_test_config().await),
|
||||
cli_overrides: Vec::new(),
|
||||
loader_overrides: LoaderOverrides::default(),
|
||||
cloud_requirements: CloudRequirementsLoader::default(),
|
||||
feedback: CodexFeedback::new(),
|
||||
config_warnings: Vec::new(),
|
||||
session_source: SessionSource::Cli,
|
||||
enable_codex_api_key_env: false,
|
||||
client_name: "codex-tui".to_string(),
|
||||
originator_override: None,
|
||||
client_version: "0.0.0-test".to_string(),
|
||||
experimental_api: true,
|
||||
opt_out_notification_methods: Vec::new(),
|
||||
channel_capacity: 1,
|
||||
};
|
||||
|
||||
let params = args.initialize_params();
|
||||
|
||||
assert_eq!(params.originator_override, None);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn typed_request_roundtrip_works() {
|
||||
let client = start_test_client(SessionSource::Exec).await;
|
||||
|
||||
@@ -57,6 +57,7 @@ const INITIALIZE_TIMEOUT: Duration = Duration::from_secs(10);
|
||||
pub struct RemoteAppServerConnectArgs {
|
||||
pub websocket_url: String,
|
||||
pub client_name: String,
|
||||
pub originator_override: Option<String>,
|
||||
pub client_version: String,
|
||||
pub experimental_api: bool,
|
||||
pub opt_out_notification_methods: Vec<String>,
|
||||
@@ -80,11 +81,52 @@ impl RemoteAppServerConnectArgs {
|
||||
title: None,
|
||||
version: self.client_version.clone(),
|
||||
},
|
||||
originator_override: self.originator_override.clone(),
|
||||
capabilities: Some(capabilities),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::RemoteAppServerConnectArgs;
|
||||
use pretty_assertions::assert_eq;
|
||||
|
||||
#[test]
|
||||
fn initialize_params_include_originator_override_when_set() {
|
||||
let args = RemoteAppServerConnectArgs {
|
||||
websocket_url: "ws://127.0.0.1:1234".to_string(),
|
||||
client_name: "codex-tui".to_string(),
|
||||
originator_override: Some("codex_cli_rs".to_string()),
|
||||
client_version: "0.0.0-test".to_string(),
|
||||
experimental_api: true,
|
||||
opt_out_notification_methods: Vec::new(),
|
||||
channel_capacity: 1,
|
||||
};
|
||||
|
||||
let params = args.initialize_params();
|
||||
|
||||
assert_eq!(params.originator_override, Some("codex_cli_rs".to_string()));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn initialize_params_omit_originator_override_when_absent() {
|
||||
let args = RemoteAppServerConnectArgs {
|
||||
websocket_url: "ws://127.0.0.1:1234".to_string(),
|
||||
client_name: "codex-tui".to_string(),
|
||||
originator_override: None,
|
||||
client_version: "0.0.0-test".to_string(),
|
||||
experimental_api: true,
|
||||
opt_out_notification_methods: Vec::new(),
|
||||
channel_capacity: 1,
|
||||
};
|
||||
|
||||
let params = args.initialize_params();
|
||||
|
||||
assert_eq!(params.originator_override, None);
|
||||
}
|
||||
}
|
||||
|
||||
enum RemoteClientCommand {
|
||||
Request {
|
||||
request: Box<ClientRequest>,
|
||||
|
||||
@@ -981,6 +981,12 @@
|
||||
},
|
||||
"clientInfo": {
|
||||
"$ref": "#/definitions/ClientInfo"
|
||||
},
|
||||
"originatorOverride": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
|
||||
@@ -2246,6 +2246,12 @@
|
||||
},
|
||||
"clientInfo": {
|
||||
"$ref": "#/definitions/ClientInfo"
|
||||
},
|
||||
"originatorOverride": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
|
||||
@@ -4887,6 +4887,12 @@
|
||||
},
|
||||
"clientInfo": {
|
||||
"$ref": "#/definitions/ClientInfo"
|
||||
},
|
||||
"originatorOverride": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
|
||||
@@ -57,6 +57,12 @@
|
||||
},
|
||||
"clientInfo": {
|
||||
"$ref": "#/definitions/ClientInfo"
|
||||
},
|
||||
"originatorOverride": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
|
||||
@@ -4,4 +4,4 @@
|
||||
import type { ClientInfo } from "./ClientInfo";
|
||||
import type { InitializeCapabilities } from "./InitializeCapabilities";
|
||||
|
||||
export type InitializeParams = { clientInfo: ClientInfo, capabilities: InitializeCapabilities | null, };
|
||||
export type InitializeParams = { clientInfo: ClientInfo, originatorOverride?: string | null, capabilities: InitializeCapabilities | null, };
|
||||
|
||||
@@ -1001,6 +1001,7 @@ mod tests {
|
||||
title: Some("Codex VS Code Extension".to_string()),
|
||||
version: "0.1.0".to_string(),
|
||||
},
|
||||
originator_override: None,
|
||||
capabilities: Some(v1::InitializeCapabilities {
|
||||
experimental_api: true,
|
||||
opt_out_notification_methods: Some(vec![
|
||||
@@ -1066,6 +1067,7 @@ mod tests {
|
||||
title: Some("Codex VS Code Extension".to_string()),
|
||||
version: "0.1.0".to_string(),
|
||||
},
|
||||
originator_override: None,
|
||||
capabilities: Some(v1::InitializeCapabilities {
|
||||
experimental_api: true,
|
||||
opt_out_notification_methods: Some(vec![
|
||||
@@ -1079,6 +1081,39 @@ mod tests {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn serialize_initialize_with_originator_override() -> Result<()> {
|
||||
let request = ClientRequest::Initialize {
|
||||
request_id: RequestId::Integer(7),
|
||||
params: v1::InitializeParams {
|
||||
client_info: v1::ClientInfo {
|
||||
name: "codex-tui".to_string(),
|
||||
title: None,
|
||||
version: "0.1.0".to_string(),
|
||||
},
|
||||
originator_override: Some("codex_cli_rs".to_string()),
|
||||
capabilities: None,
|
||||
},
|
||||
};
|
||||
|
||||
assert_eq!(
|
||||
json!({
|
||||
"method": "initialize",
|
||||
"id": 7,
|
||||
"params": {
|
||||
"clientInfo": {
|
||||
"name": "codex-tui",
|
||||
"title": null,
|
||||
"version": "0.1.0"
|
||||
},
|
||||
"originatorOverride": "codex_cli_rs"
|
||||
}
|
||||
}),
|
||||
serde_json::to_value(&request)?,
|
||||
);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn conversation_id_serializes_as_plain_string() -> Result<()> {
|
||||
let id = ThreadId::from_string("67e55044-10b1-426f-9247-bb680e5fe0c8")?;
|
||||
|
||||
@@ -28,6 +28,9 @@ use crate::protocol::common::GitSha;
|
||||
pub struct InitializeParams {
|
||||
pub client_info: ClientInfo,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
#[ts(optional = nullable)]
|
||||
pub originator_override: Option<String>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub capabilities: Option<InitializeCapabilities>,
|
||||
}
|
||||
|
||||
|
||||
@@ -1526,6 +1526,7 @@ impl CodexClient {
|
||||
title: Some("Codex Toy App Server".to_string()),
|
||||
version: env!("CARGO_PKG_VERSION").to_string(),
|
||||
},
|
||||
originator_override: None,
|
||||
capabilities: Some(InitializeCapabilities {
|
||||
experimental_api,
|
||||
opt_out_notification_methods: Some(
|
||||
|
||||
@@ -80,6 +80,7 @@ Clients must send a single `initialize` request per transport connection before
|
||||
`initialize.params.capabilities` also supports per-connection notification opt-out via `optOutNotificationMethods`, which is a list of exact method names to suppress for that connection. Matching is exact (no wildcards/prefixes). Unknown method names are accepted and ignored.
|
||||
|
||||
Applications building on top of `codex app-server` should identify themselves via the `clientInfo` parameter.
|
||||
If you need backend requests to use a different `originator` header than the app-server client identity, set `originatorOverride`. When omitted, the backend originator defaults to `clientInfo.name`. When provided, the returned `userAgent` string also uses the override as its prefix.
|
||||
|
||||
**Important**: `clientInfo.name` is used to identify the client for the OpenAI Compliance Logs Platform. If
|
||||
you are developing a new Codex integration that is intended for enterprise use, please contact us to get it
|
||||
@@ -113,6 +114,7 @@ Example with notification opt-out:
|
||||
"title": "My Client",
|
||||
"version": "0.1.0"
|
||||
},
|
||||
"originatorOverride": "codex_cli_rs",
|
||||
"capabilities": {
|
||||
"experimentalApi": true,
|
||||
"optOutNotificationMethods": ["thread/started", "item/agentMessage/delta"]
|
||||
|
||||
@@ -771,6 +771,7 @@ mod tests {
|
||||
title: None,
|
||||
version: "0.0.0".to_string(),
|
||||
},
|
||||
originator_override: None,
|
||||
capabilities: None,
|
||||
},
|
||||
channel_capacity,
|
||||
|
||||
@@ -17,6 +17,7 @@ use crate::outgoing_message::OutgoingMessageSender;
|
||||
use crate::outgoing_message::RequestContext;
|
||||
use crate::transport::AppServerTransport;
|
||||
use async_trait::async_trait;
|
||||
use axum::http::HeaderValue;
|
||||
use codex_app_server_protocol::ChatgptAuthTokensRefreshParams;
|
||||
use codex_app_server_protocol::ChatgptAuthTokensRefreshReason;
|
||||
use codex_app_server_protocol::ChatgptAuthTokensRefreshResponse;
|
||||
@@ -548,15 +549,30 @@ impl MessageProcessor {
|
||||
title: _title,
|
||||
version,
|
||||
} = params.client_info;
|
||||
let effective_originator =
|
||||
params.originator_override.unwrap_or_else(|| name.clone());
|
||||
if HeaderValue::from_str(&name).is_err() {
|
||||
let error = JSONRPCErrorError {
|
||||
code: INVALID_REQUEST_ERROR_CODE,
|
||||
message: format!(
|
||||
"Invalid clientInfo.name: '{name}'. Must be a valid HTTP header value."
|
||||
),
|
||||
data: None,
|
||||
};
|
||||
self.outgoing
|
||||
.send_error(connection_request_id.clone(), error)
|
||||
.await;
|
||||
return;
|
||||
}
|
||||
session.app_server_client_name = Some(name.clone());
|
||||
session.client_version = Some(version.clone());
|
||||
if let Err(error) = set_default_originator(name.clone()) {
|
||||
if let Err(error) = set_default_originator(effective_originator.clone()) {
|
||||
match error {
|
||||
SetOriginatorError::InvalidHeaderValue => {
|
||||
let error = JSONRPCErrorError {
|
||||
code: INVALID_REQUEST_ERROR_CODE,
|
||||
message: format!(
|
||||
"Invalid clientInfo.name: '{name}'. Must be a valid HTTP header value."
|
||||
"Invalid originatorOverride: '{effective_originator}'. Must be a valid HTTP header value."
|
||||
),
|
||||
data: None,
|
||||
};
|
||||
|
||||
@@ -140,6 +140,7 @@ impl TracingHarness {
|
||||
title: None,
|
||||
version: "0.1.0".to_string(),
|
||||
},
|
||||
originator_override: None,
|
||||
capabilities: Some(InitializeCapabilities {
|
||||
experimental_api: true,
|
||||
..Default::default()
|
||||
|
||||
@@ -214,11 +214,28 @@ impl McpProcess {
|
||||
) -> anyhow::Result<JSONRPCMessage> {
|
||||
self.initialize_with_params(InitializeParams {
|
||||
client_info,
|
||||
originator_override: None,
|
||||
capabilities,
|
||||
})
|
||||
.await
|
||||
}
|
||||
|
||||
pub async fn initialize_with_originator_override(
|
||||
&mut self,
|
||||
client_info: ClientInfo,
|
||||
originator_override: Option<String>,
|
||||
) -> anyhow::Result<JSONRPCMessage> {
|
||||
self.initialize_with_params(InitializeParams {
|
||||
client_info,
|
||||
originator_override,
|
||||
capabilities: Some(InitializeCapabilities {
|
||||
experimental_api: true,
|
||||
..Default::default()
|
||||
}),
|
||||
})
|
||||
.await
|
||||
}
|
||||
|
||||
async fn initialize_with_params(
|
||||
&mut self,
|
||||
params: InitializeParams,
|
||||
|
||||
@@ -280,6 +280,7 @@ pub(super) async fn send_initialize_request(
|
||||
title: Some("WebSocket Test Client".to_string()),
|
||||
version: "0.1.0".to_string(),
|
||||
},
|
||||
originator_override: None,
|
||||
capabilities: None,
|
||||
};
|
||||
send_request(
|
||||
|
||||
@@ -58,6 +58,36 @@ async fn initialize_uses_client_info_name_as_originator() -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn initialize_uses_originator_override_when_present() -> Result<()> {
|
||||
let responses = Vec::new();
|
||||
let server = create_mock_responses_server_sequence_unchecked(responses).await;
|
||||
let codex_home = TempDir::new()?;
|
||||
create_config_toml(codex_home.path(), &server.uri(), "never")?;
|
||||
let mut mcp = McpProcess::new(codex_home.path()).await?;
|
||||
|
||||
let message = timeout(
|
||||
DEFAULT_READ_TIMEOUT,
|
||||
mcp.initialize_with_originator_override(
|
||||
ClientInfo {
|
||||
name: "codex-tui".to_string(),
|
||||
title: Some("Codex TUI".to_string()),
|
||||
version: "0.1.0".to_string(),
|
||||
},
|
||||
Some("codex_cli_rs".to_string()),
|
||||
),
|
||||
)
|
||||
.await??;
|
||||
|
||||
let JSONRPCMessage::Response(response) = message else {
|
||||
anyhow::bail!("expected initialize response, got {message:?}");
|
||||
};
|
||||
let InitializeResponse { user_agent, .. } = to_response::<InitializeResponse>(response)?;
|
||||
|
||||
assert!(user_agent.starts_with("codex_cli_rs/"));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn initialize_respects_originator_override_env_var() -> Result<()> {
|
||||
let responses = Vec::new();
|
||||
@@ -133,6 +163,44 @@ async fn initialize_rejects_invalid_client_name() -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn initialize_rejects_invalid_originator_override() -> Result<()> {
|
||||
let responses = Vec::new();
|
||||
let server = create_mock_responses_server_sequence_unchecked(responses).await;
|
||||
let codex_home = TempDir::new()?;
|
||||
create_config_toml(codex_home.path(), &server.uri(), "never")?;
|
||||
let mut mcp = McpProcess::new_with_env(
|
||||
codex_home.path(),
|
||||
&[("CODEX_INTERNAL_ORIGINATOR_OVERRIDE", None)],
|
||||
)
|
||||
.await?;
|
||||
|
||||
let message = timeout(
|
||||
DEFAULT_READ_TIMEOUT,
|
||||
mcp.initialize_with_originator_override(
|
||||
ClientInfo {
|
||||
name: "codex-tui".to_string(),
|
||||
title: Some("Codex TUI".to_string()),
|
||||
version: "0.1.0".to_string(),
|
||||
},
|
||||
Some("bad\rname".to_string()),
|
||||
),
|
||||
)
|
||||
.await??;
|
||||
|
||||
let JSONRPCMessage::Error(error) = message else {
|
||||
anyhow::bail!("expected initialize error, got {message:?}");
|
||||
};
|
||||
|
||||
assert_eq!(error.error.code, -32600);
|
||||
assert_eq!(
|
||||
error.error.message,
|
||||
"Invalid originatorOverride: 'bad\rname'. Must be a valid HTTP header value."
|
||||
);
|
||||
assert_eq!(error.error.data, None);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn initialize_opt_out_notification_methods_filters_notifications() -> Result<()> {
|
||||
let responses = Vec::new();
|
||||
|
||||
@@ -152,6 +152,84 @@ async fn turn_start_sends_originator_header() -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn turn_start_uses_originator_override_header() -> Result<()> {
|
||||
let responses = vec![create_final_assistant_message_sse_response("Done")?];
|
||||
let server = create_mock_responses_server_sequence_unchecked(responses).await;
|
||||
|
||||
let codex_home = TempDir::new()?;
|
||||
create_config_toml(
|
||||
codex_home.path(),
|
||||
&server.uri(),
|
||||
"never",
|
||||
&BTreeMap::from([(Feature::Personality, true)]),
|
||||
)?;
|
||||
|
||||
let mut mcp = McpProcess::new(codex_home.path()).await?;
|
||||
timeout(
|
||||
DEFAULT_READ_TIMEOUT,
|
||||
mcp.initialize_with_originator_override(
|
||||
ClientInfo {
|
||||
name: "codex-tui".to_string(),
|
||||
title: Some("Codex TUI".to_string()),
|
||||
version: "0.1.0".to_string(),
|
||||
},
|
||||
Some("codex_cli_rs".to_string()),
|
||||
),
|
||||
)
|
||||
.await??;
|
||||
|
||||
let thread_req = mcp
|
||||
.send_thread_start_request(ThreadStartParams {
|
||||
model: Some("mock-model".to_string()),
|
||||
..Default::default()
|
||||
})
|
||||
.await?;
|
||||
let thread_resp: JSONRPCResponse = timeout(
|
||||
DEFAULT_READ_TIMEOUT,
|
||||
mcp.read_stream_until_response_message(RequestId::Integer(thread_req)),
|
||||
)
|
||||
.await??;
|
||||
let ThreadStartResponse { thread, .. } = to_response::<ThreadStartResponse>(thread_resp)?;
|
||||
|
||||
let turn_req = mcp
|
||||
.send_turn_start_request(TurnStartParams {
|
||||
thread_id: thread.id.clone(),
|
||||
input: vec![V2UserInput::Text {
|
||||
text: "Hello".to_string(),
|
||||
text_elements: Vec::new(),
|
||||
}],
|
||||
..Default::default()
|
||||
})
|
||||
.await?;
|
||||
timeout(
|
||||
DEFAULT_READ_TIMEOUT,
|
||||
mcp.read_stream_until_response_message(RequestId::Integer(turn_req)),
|
||||
)
|
||||
.await??;
|
||||
|
||||
timeout(
|
||||
DEFAULT_READ_TIMEOUT,
|
||||
mcp.read_stream_until_notification_message("turn/completed"),
|
||||
)
|
||||
.await??;
|
||||
|
||||
let requests = server
|
||||
.received_requests()
|
||||
.await
|
||||
.expect("failed to fetch received requests");
|
||||
assert!(!requests.is_empty());
|
||||
for request in requests {
|
||||
let originator = request
|
||||
.headers
|
||||
.get("originator")
|
||||
.expect("originator header missing");
|
||||
assert_eq!(originator.to_str()?, "codex_cli_rs");
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn turn_start_emits_user_message_item_with_text_elements() -> Result<()> {
|
||||
let responses = vec![create_final_assistant_message_sse_response("Done")?];
|
||||
|
||||
@@ -100,6 +100,7 @@ impl AppServerClient {
|
||||
title: Some("Debug Client".to_string()),
|
||||
version: env!("CARGO_PKG_VERSION").to_string(),
|
||||
},
|
||||
originator_override: None,
|
||||
capabilities: Some(InitializeCapabilities {
|
||||
experimental_api: true,
|
||||
opt_out_notification_methods: None,
|
||||
|
||||
@@ -440,6 +440,7 @@ pub async fn run_main(cli: Cli, arg0_paths: Arg0DispatchPaths) -> anyhow::Result
|
||||
session_source: SessionSource::Exec,
|
||||
enable_codex_api_key_env: true,
|
||||
client_name: "codex-exec".to_string(),
|
||||
originator_override: None,
|
||||
client_version: env!("CARGO_PKG_VERSION").to_string(),
|
||||
experimental_api: true,
|
||||
opt_out_notification_methods: Vec::new(),
|
||||
|
||||
@@ -33,6 +33,7 @@ use codex_core::config_loader::CloudRequirementsLoader;
|
||||
use codex_core::config_loader::ConfigLoadError;
|
||||
use codex_core::config_loader::LoaderOverrides;
|
||||
use codex_core::config_loader::format_config_error_with_source;
|
||||
use codex_core::default_client::DEFAULT_ORIGINATOR;
|
||||
use codex_core::default_client::set_default_client_residency_requirement;
|
||||
use codex_core::format_exec_policy_error_with_source;
|
||||
use codex_core::path_utils;
|
||||
@@ -340,6 +341,7 @@ async fn connect_remote_app_server(websocket_url: String) -> color_eyre::Result<
|
||||
let app_server = RemoteAppServerClient::connect(RemoteAppServerConnectArgs {
|
||||
websocket_url,
|
||||
client_name: "codex-tui".to_string(),
|
||||
originator_override: Some(DEFAULT_ORIGINATOR.to_string()),
|
||||
client_version: env!("CARGO_PKG_VERSION").to_string(),
|
||||
experimental_api: true,
|
||||
opt_out_notification_methods: Vec::new(),
|
||||
@@ -434,6 +436,7 @@ where
|
||||
session_source: codex_protocol::protocol::SessionSource::Cli,
|
||||
enable_codex_api_key_env: false,
|
||||
client_name: "codex-tui".to_string(),
|
||||
originator_override: Some(DEFAULT_ORIGINATOR.to_string()),
|
||||
client_version: env!("CARGO_PKG_VERSION").to_string(),
|
||||
experimental_api: true,
|
||||
opt_out_notification_methods: Vec::new(),
|
||||
|
||||
@@ -920,6 +920,7 @@ mod tests {
|
||||
session_source: SessionSource::Cli,
|
||||
enable_codex_api_key_env: false,
|
||||
client_name: "test".to_string(),
|
||||
originator_override: None,
|
||||
client_version: "test".to_string(),
|
||||
experimental_api: true,
|
||||
opt_out_notification_methods: Vec::new(),
|
||||
|
||||
Reference in New Issue
Block a user