From e7d05ce492ca76fb0fa0fdad5b7f6138c50299d6 Mon Sep 17 00:00:00 2001 From: Dylan Hurd Date: Fri, 29 Aug 2025 17:31:17 -0700 Subject: [PATCH] tests working --- codex-rs/core/src/openai_tools.rs | 12 +++- codex-rs/core/src/shell.rs | 24 +++++-- codex-rs/core/tests/suite/prompt_caching.rs | 76 ++++++++++++++++++++- 3 files changed, 102 insertions(+), 10 deletions(-) diff --git a/codex-rs/core/src/openai_tools.rs b/codex-rs/core/src/openai_tools.rs index bd2c5f4da8..afcf295918 100644 --- a/codex-rs/core/src/openai_tools.rs +++ b/codex-rs/core/src/openai_tools.rs @@ -542,7 +542,17 @@ pub(crate) fn get_openai_tools( } if let Some(mcp_tools) = mcp_tools { - for (name, tool) in mcp_tools.into_iter() { + let mut sorted_tools: Vec<_> = mcp_tools.into_iter().collect(); + sorted_tools.sort_by(|(name_a, _), (name_b, _)| { + let (server_a, tool_a) = name_a.split_once('/').unwrap_or((name_a.as_str(), "")); + let (server_b, tool_b) = name_b.split_once('/').unwrap_or((name_b.as_str(), "")); + + server_a + .cmp(server_b) + .then_with(|| tool_a.len().cmp(&tool_b.len())) + .then_with(|| tool_a.cmp(tool_b)) + }); + for (name, tool) in sorted_tools { match mcp_tool_to_openai_tool(name.clone(), tool.clone()) { Ok(converted_tool) => tools.push(OpenAiTool::Function(converted_tool)), Err(e) => { diff --git a/codex-rs/core/src/shell.rs b/codex-rs/core/src/shell.rs index 3a69874eb2..124d0b51b3 100644 --- a/codex-rs/core/src/shell.rs +++ b/codex-rs/core/src/shell.rs @@ -128,11 +128,22 @@ pub async fn default_user_shell() -> Shell { .output() .await .ok(); + + let shell_from_env = || { + let shell_path = std::env::var("SHELL").ok(); + let home_env = std::env::var("HOME").unwrap_or_else(|_| home.clone()); + shell_path + .filter(|path| path.ends_with("/zsh")) + .map(|shell_path| { + Shell::Zsh(ZshShell { + shell_path, + zshrc_path: format!("{home_env}/.zshrc"), + }) + }) + }; + match output { - Some(o) => { - if !o.status.success() { - return Shell::Unknown; - } + Some(o) if o.status.success() => { let stdout = String::from_utf8_lossy(&o.stdout); for line in stdout.lines() { if let Some(shell_path) = line.strip_prefix("UserShell: ") @@ -144,10 +155,9 @@ pub async fn default_user_shell() -> Shell { }); } } - - Shell::Unknown + shell_from_env().unwrap_or(Shell::Unknown) } - _ => Shell::Unknown, + _ => shell_from_env().unwrap_or(Shell::Unknown), } } diff --git a/codex-rs/core/tests/suite/prompt_caching.rs b/codex-rs/core/tests/suite/prompt_caching.rs index 13a8ecbb04..f43523558b 100644 --- a/codex-rs/core/tests/suite/prompt_caching.rs +++ b/codex-rs/core/tests/suite/prompt_caching.rs @@ -592,8 +592,80 @@ async fn mcp_server_ordering_is_preserved_across_requests() { mcp_servers.insert( "test_mcp_server_1".to_string(), McpServerConfig { - command: "bash -lc 'while read -r line; do echo \"{\"id\": 1, \"tools\": [{\"name\": \"test_tool_1\", \"description\": \"Test tool 1\" }]} \"; done'".to_string(), - args: vec![], + command: "bash".to_string(), + args: vec![ + "-lc".to_string(), + r#"TMP=$(mktemp) +cat <<'PY' > "$TMP" +import json +import sys + + +PROTOCOL_VERSION = "2025-06-18" + + +def send(message): + sys.stdout.write(json.dumps(message) + "\n") + sys.stdout.flush() + + +for line in sys.stdin: + try: + message = json.loads(line) + except json.JSONDecodeError: + continue + method = message.get("method") + if method == "initialize": + params = message.get("params") or {} + send( + { + "jsonrpc": "2.0", + "id": message.get("id"), + "result": { + "capabilities": {"tools": {"listChanged": True}}, + "protocolVersion": params.get("protocol_version", PROTOCOL_VERSION), + "serverInfo": { + "name": "test_mcp_server_1", + "title": "Test MCP Server 1", + "version": "0.0.1", + }, + }, + } + ) + elif method == "tools/list": + send( + { + "jsonrpc": "2.0", + "id": message.get("id"), + "result": { + "tools": [ + { + "name": "test_tool_1", + "description": "Test tool 1", + "inputSchema": {"type": "object"}, + } + ], + }, + } + ) + elif method == "notifications/initialized": + continue + else: + send( + { + "jsonrpc": "2.0", + "id": message.get("id"), + "error": { + "code": -32601, + "message": f"Method {method} not implemented", + }, + } + ) +PY +python3 "$TMP" +"# + .to_string(), + ], env: None, }, );