mirror of
https://github.com/pchuan98/codex.git
synced 2026-07-01 00:31:56 +08:00
feat: bind package manager (#13571)
This commit is contained in:
@@ -1,13 +1,11 @@
|
||||
use async_trait::async_trait;
|
||||
use codex_artifacts::ArtifactBuildRequest;
|
||||
use codex_artifacts::ArtifactCommandOutput;
|
||||
use codex_artifacts::ArtifactRuntimeError;
|
||||
use codex_artifacts::ArtifactRuntimePlatform;
|
||||
use codex_artifacts::ArtifactRuntimeManager;
|
||||
use codex_artifacts::ArtifactRuntimeManagerConfig;
|
||||
use codex_artifacts::ArtifactsClient;
|
||||
use codex_artifacts::ArtifactsError;
|
||||
use codex_artifacts::InstalledArtifactRuntime;
|
||||
use serde_json::Value as JsonValue;
|
||||
use std::path::Path;
|
||||
use std::time::Duration;
|
||||
use std::time::Instant;
|
||||
|
||||
@@ -31,7 +29,7 @@ use codex_protocol::models::FunctionCallOutputBody;
|
||||
|
||||
const ARTIFACTS_TOOL_NAME: &str = "artifacts";
|
||||
const ARTIFACTS_PRAGMA_PREFIXES: [&str; 2] = ["// codex-artifacts:", "// codex-artifact-tool:"];
|
||||
const PINNED_ARTIFACT_RUNTIME_VERSION: &str = "2.4.0";
|
||||
pub(crate) const PINNED_ARTIFACT_RUNTIME_VERSION: &str = "2.4.0";
|
||||
const DEFAULT_EXECUTION_TIMEOUT: Duration = Duration::from_secs(30);
|
||||
|
||||
pub struct ArtifactsHandler;
|
||||
@@ -80,10 +78,9 @@ impl ToolHandler for ArtifactsHandler {
|
||||
}
|
||||
};
|
||||
|
||||
let runtime = resolve_preinstalled_runtime(&turn.config.codex_home)
|
||||
.await
|
||||
.map_err(artifacts_error)?;
|
||||
let client = ArtifactsClient::from_installed_runtime(runtime);
|
||||
let client = ArtifactsClient::from_runtime_manager(default_runtime_manager(
|
||||
turn.config.codex_home.clone(),
|
||||
));
|
||||
|
||||
let started_at = Instant::now();
|
||||
emit_exec_begin(session.as_ref(), turn.as_ref(), &call_id).await;
|
||||
@@ -122,31 +119,6 @@ impl ToolHandler for ArtifactsHandler {
|
||||
}
|
||||
}
|
||||
|
||||
async fn resolve_preinstalled_runtime(
|
||||
codex_home: &Path,
|
||||
) -> Result<InstalledArtifactRuntime, ArtifactsError> {
|
||||
let platform = ArtifactRuntimePlatform::detect_current()
|
||||
.map_err(ArtifactRuntimeError::from)
|
||||
.map_err(ArtifactsError::Runtime)?;
|
||||
let install_dir = codex_home
|
||||
.join("packages")
|
||||
.join("artifacts")
|
||||
.join(PINNED_ARTIFACT_RUNTIME_VERSION)
|
||||
.join(platform.as_str());
|
||||
if !install_dir.exists() {
|
||||
return Err(ArtifactsError::Io {
|
||||
context: format!(
|
||||
"artifact runtime {} is not installed at {}",
|
||||
PINNED_ARTIFACT_RUNTIME_VERSION,
|
||||
install_dir.display()
|
||||
),
|
||||
source: std::io::Error::new(std::io::ErrorKind::NotFound, "missing artifact runtime"),
|
||||
});
|
||||
}
|
||||
|
||||
InstalledArtifactRuntime::load(install_dir, platform).map_err(ArtifactsError::Runtime)
|
||||
}
|
||||
|
||||
fn parse_freeform_args(input: &str) -> Result<ArtifactsToolArgs, FunctionCallError> {
|
||||
if input.trim().is_empty() {
|
||||
return Err(FunctionCallError::RespondToModel(
|
||||
@@ -240,8 +212,11 @@ fn parse_pragma_prefix(line: &str) -> Option<&str> {
|
||||
.find_map(|prefix| line.strip_prefix(prefix))
|
||||
}
|
||||
|
||||
fn artifacts_error(error: ArtifactsError) -> FunctionCallError {
|
||||
FunctionCallError::RespondToModel(error.to_string())
|
||||
fn default_runtime_manager(codex_home: std::path::PathBuf) -> ArtifactRuntimeManager {
|
||||
ArtifactRuntimeManager::new(ArtifactRuntimeManagerConfig::with_default_release(
|
||||
codex_home,
|
||||
PINNED_ARTIFACT_RUNTIME_VERSION,
|
||||
))
|
||||
}
|
||||
|
||||
async fn emit_exec_begin(session: &Session, turn: &TurnContext, call_id: &str) {
|
||||
@@ -357,10 +332,26 @@ mod tests {
|
||||
);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn resolve_preinstalled_runtime_reads_pinned_cache_path() {
|
||||
#[test]
|
||||
fn default_runtime_manager_uses_openai_codex_release_base() {
|
||||
let codex_home = TempDir::new().expect("create temp codex home");
|
||||
let platform = ArtifactRuntimePlatform::detect_current().expect("detect platform");
|
||||
let manager = default_runtime_manager(codex_home.path().to_path_buf());
|
||||
|
||||
assert_eq!(
|
||||
manager.config().release().base_url().as_str(),
|
||||
"https://github.com/openai/codex/releases/download/"
|
||||
);
|
||||
assert_eq!(
|
||||
manager.config().release().runtime_version(),
|
||||
PINNED_ARTIFACT_RUNTIME_VERSION
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn load_cached_runtime_reads_pinned_cache_path() {
|
||||
let codex_home = TempDir::new().expect("create temp codex home");
|
||||
let platform =
|
||||
codex_artifacts::ArtifactRuntimePlatform::detect_current().expect("detect platform");
|
||||
let install_dir = codex_home
|
||||
.path()
|
||||
.join("packages")
|
||||
@@ -382,10 +373,26 @@ mod tests {
|
||||
.to_string(),
|
||||
)
|
||||
.expect("write manifest");
|
||||
std::fs::create_dir_all(install_dir.join("artifact-tool/dist"))
|
||||
.expect("create build entrypoint dir");
|
||||
std::fs::create_dir_all(install_dir.join("granola-render/dist"))
|
||||
.expect("create render entrypoint dir");
|
||||
std::fs::write(
|
||||
install_dir.join("artifact-tool/dist/artifact_tool.mjs"),
|
||||
"export const ok = true;\n",
|
||||
)
|
||||
.expect("write build entrypoint");
|
||||
std::fs::write(
|
||||
install_dir.join("granola-render/dist/render_cli.mjs"),
|
||||
"export const ok = true;\n",
|
||||
)
|
||||
.expect("write render entrypoint");
|
||||
|
||||
let runtime = resolve_preinstalled_runtime(codex_home.path())
|
||||
.await
|
||||
.expect("resolve runtime");
|
||||
let runtime = codex_artifacts::load_cached_runtime(
|
||||
codex_home.path(),
|
||||
PINNED_ARTIFACT_RUNTIME_VERSION,
|
||||
)
|
||||
.expect("resolve runtime");
|
||||
assert_eq!(runtime.runtime_version(), PINNED_ARTIFACT_RUNTIME_VERSION);
|
||||
assert_eq!(
|
||||
runtime.manifest().entrypoints,
|
||||
|
||||
@@ -29,6 +29,7 @@ use crate::sandboxing::SandboxPermissions;
|
||||
use crate::sandboxing::normalize_additional_permissions;
|
||||
pub use apply_patch::ApplyPatchHandler;
|
||||
pub use artifacts::ArtifactsHandler;
|
||||
pub(crate) use artifacts::PINNED_ARTIFACT_RUNTIME_VERSION;
|
||||
use codex_protocol::models::PermissionProfile;
|
||||
use codex_protocol::protocol::AskForApproval;
|
||||
pub use dynamic::DynamicToolHandler;
|
||||
|
||||
@@ -7,6 +7,7 @@ use crate::features::Feature;
|
||||
use crate::features::Features;
|
||||
use crate::mcp_connection_manager::ToolInfo;
|
||||
use crate::models_manager::collaboration_mode_presets::CollaborationModesConfig;
|
||||
use crate::tools::handlers::PINNED_ARTIFACT_RUNTIME_VERSION;
|
||||
use crate::tools::handlers::PLAN_TOOL;
|
||||
use crate::tools::handlers::SEARCH_TOOL_BM25_DEFAULT_LIMIT;
|
||||
use crate::tools::handlers::SEARCH_TOOL_BM25_TOOL_NAME;
|
||||
@@ -34,6 +35,7 @@ use serde_json::Value as JsonValue;
|
||||
use serde_json::json;
|
||||
use std::collections::BTreeMap;
|
||||
use std::collections::HashMap;
|
||||
use std::path::Path;
|
||||
|
||||
const SEARCH_TOOL_BM25_DESCRIPTION_TEMPLATE: &str =
|
||||
include_str!("../../templates/search_tool/tool_description.md");
|
||||
@@ -75,6 +77,7 @@ pub(crate) struct ToolsConfig {
|
||||
}
|
||||
|
||||
pub(crate) struct ToolsConfigParams<'a> {
|
||||
pub(crate) codex_home: &'a Path,
|
||||
pub(crate) model_info: &'a ModelInfo,
|
||||
pub(crate) features: &'a Features,
|
||||
pub(crate) web_search_mode: Option<WebSearchMode>,
|
||||
@@ -84,6 +87,7 @@ pub(crate) struct ToolsConfigParams<'a> {
|
||||
impl ToolsConfig {
|
||||
pub fn new(params: &ToolsConfigParams) -> Self {
|
||||
let ToolsConfigParams {
|
||||
codex_home,
|
||||
model_info,
|
||||
features,
|
||||
web_search_mode,
|
||||
@@ -98,7 +102,11 @@ impl ToolsConfig {
|
||||
let include_default_mode_request_user_input =
|
||||
include_request_user_input && features.enabled(Feature::DefaultModeRequestUserInput);
|
||||
let include_search_tool = features.enabled(Feature::Apps);
|
||||
let include_artifact_tools = features.enabled(Feature::Artifact);
|
||||
let include_artifact_tools = features.enabled(Feature::Artifact)
|
||||
&& codex_artifacts::is_js_runtime_available(
|
||||
codex_home,
|
||||
PINNED_ARTIFACT_RUNTIME_VERSION,
|
||||
);
|
||||
let include_image_gen_tool =
|
||||
features.enabled(Feature::ImageGeneration) && supports_image_generation(model_info);
|
||||
let include_agent_jobs = include_collab_tools && features.enabled(Feature::Sqlite);
|
||||
@@ -1405,7 +1413,7 @@ JS_SOURCE: /(?:\s*)(?:[^\s{\"`]|`[^`]|``[^`])[\s\S]*/
|
||||
|
||||
ToolSpec::Freeform(FreeformTool {
|
||||
name: "artifacts".to_string(),
|
||||
description: "Runs raw JavaScript against the preinstalled Codex @oai/artifact-tool runtime for creating presentations or spreadsheets. This is plain JavaScript executed by Node with top-level await, not TypeScript: do not use type annotations, `interface`, `type`, or `import type`. Author code the same way you would for `import { Presentation, Workbook, PresentationFile, SpreadsheetFile, FileBlob, ... } from \"@oai/artifact-tool\"`, but omit that import line because the package surface is already preloaded. Named exports are available directly on `globalThis`, and the full module is available as `globalThis.artifactTool` (also aliased as `globalThis.artifacts` and `globalThis.codexArtifacts`). Node built-ins such as `node:fs/promises` may still be imported when needed for saving preview bytes. This is a freeform tool: send raw JavaScript source text, optionally with a first-line pragma like `// codex-artifacts: timeout_ms=15000` or `// codex-artifact-tool: timeout_ms=15000`; do not send JSON/quotes/markdown fences."
|
||||
description: "Runs raw JavaScript against the preinstalled Codex @oai/artifact-tool runtime for creating presentations or spreadsheets. This is plain JavaScript executed by a local Node-compatible runtime with top-level await, not TypeScript: do not use type annotations, `interface`, `type`, or `import type`. Author code the same way you would for `import { Presentation, Workbook, PresentationFile, SpreadsheetFile, FileBlob, ... } from \"@oai/artifact-tool\"`, but omit that import line because the package surface is already preloaded. Named exports are available directly on `globalThis`, and the full module is available as `globalThis.artifactTool` (also aliased as `globalThis.artifacts` and `globalThis.codexArtifacts`). Node built-ins such as `node:fs/promises` may still be imported when needed for saving preview bytes. This is a freeform tool: send raw JavaScript source text, optionally with a first-line pragma like `// codex-artifacts: timeout_ms=15000` or `// codex-artifact-tool: timeout_ms=15000`; do not send JSON/quotes/markdown fences."
|
||||
.to_string(),
|
||||
format: FreeformToolFormat {
|
||||
r#type: "grammar".to_string(),
|
||||
@@ -2166,6 +2174,7 @@ mod tests {
|
||||
let mut features = Features::with_defaults();
|
||||
features.enable(Feature::UnifiedExec);
|
||||
let config = ToolsConfig::new(&ToolsConfigParams {
|
||||
codex_home: Path::new("."),
|
||||
model_info: &model_info,
|
||||
features: &features,
|
||||
web_search_mode: Some(WebSearchMode::Live),
|
||||
@@ -2229,6 +2238,7 @@ mod tests {
|
||||
let mut features = Features::with_defaults();
|
||||
features.enable(Feature::Collab);
|
||||
let tools_config = ToolsConfig::new(&ToolsConfigParams {
|
||||
codex_home: &config.codex_home,
|
||||
model_info: &model_info,
|
||||
features: &features,
|
||||
web_search_mode: Some(WebSearchMode::Cached),
|
||||
@@ -2249,12 +2259,53 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_build_specs_artifact_tool_enabled() {
|
||||
let config = test_config();
|
||||
let mut config = test_config();
|
||||
let runtime_root = tempfile::TempDir::new().expect("create temp codex home");
|
||||
let platform = codex_artifacts::ArtifactRuntimePlatform::detect_current()
|
||||
.expect("detect artifact platform");
|
||||
let install_dir = runtime_root
|
||||
.path()
|
||||
.join("packages")
|
||||
.join("artifacts")
|
||||
.join(PINNED_ARTIFACT_RUNTIME_VERSION)
|
||||
.join(platform.as_str());
|
||||
std::fs::create_dir_all(install_dir.join("node/bin")).expect("create runtime dir");
|
||||
std::fs::create_dir_all(install_dir.join("artifact-tool/dist"))
|
||||
.expect("create build entrypoint dir");
|
||||
std::fs::create_dir_all(install_dir.join("granola-render/dist"))
|
||||
.expect("create render entrypoint dir");
|
||||
std::fs::write(
|
||||
install_dir.join("manifest.json"),
|
||||
serde_json::json!({
|
||||
"schema_version": 1,
|
||||
"runtime_version": PINNED_ARTIFACT_RUNTIME_VERSION,
|
||||
"node": { "relative_path": "node/bin/node" },
|
||||
"entrypoints": {
|
||||
"build_js": { "relative_path": "artifact-tool/dist/artifact_tool.mjs" },
|
||||
"render_cli": { "relative_path": "granola-render/dist/render_cli.mjs" }
|
||||
}
|
||||
})
|
||||
.to_string(),
|
||||
)
|
||||
.expect("write manifest");
|
||||
std::fs::write(install_dir.join("node/bin/node"), "#!/bin/sh\n").expect("write node");
|
||||
std::fs::write(
|
||||
install_dir.join("artifact-tool/dist/artifact_tool.mjs"),
|
||||
"export const ok = true;\n",
|
||||
)
|
||||
.expect("write build entrypoint");
|
||||
std::fs::write(
|
||||
install_dir.join("granola-render/dist/render_cli.mjs"),
|
||||
"export const ok = true;\n",
|
||||
)
|
||||
.expect("write render entrypoint");
|
||||
config.codex_home = runtime_root.path().to_path_buf();
|
||||
let model_info =
|
||||
ModelsManager::construct_model_info_offline_for_tests("gpt-5-codex", &config);
|
||||
let mut features = Features::with_defaults();
|
||||
features.enable(Feature::Artifact);
|
||||
let tools_config = ToolsConfig::new(&ToolsConfigParams {
|
||||
codex_home: &config.codex_home,
|
||||
model_info: &model_info,
|
||||
features: &features,
|
||||
web_search_mode: Some(WebSearchMode::Cached),
|
||||
@@ -2273,6 +2324,7 @@ mod tests {
|
||||
features.enable(Feature::Collab);
|
||||
features.enable(Feature::Sqlite);
|
||||
let tools_config = ToolsConfig::new(&ToolsConfigParams {
|
||||
codex_home: &config.codex_home,
|
||||
model_info: &model_info,
|
||||
features: &features,
|
||||
web_search_mode: Some(WebSearchMode::Cached),
|
||||
@@ -2303,6 +2355,7 @@ mod tests {
|
||||
ModelsManager::construct_model_info_offline_for_tests("gpt-5-codex", &config);
|
||||
let mut features = Features::with_defaults();
|
||||
let tools_config = ToolsConfig::new(&ToolsConfigParams {
|
||||
codex_home: &config.codex_home,
|
||||
model_info: &model_info,
|
||||
features: &features,
|
||||
web_search_mode: Some(WebSearchMode::Cached),
|
||||
@@ -2317,6 +2370,7 @@ mod tests {
|
||||
|
||||
features.enable(Feature::DefaultModeRequestUserInput);
|
||||
let tools_config = ToolsConfig::new(&ToolsConfigParams {
|
||||
codex_home: &config.codex_home,
|
||||
model_info: &model_info,
|
||||
features: &features,
|
||||
web_search_mode: Some(WebSearchMode::Cached),
|
||||
@@ -2340,6 +2394,7 @@ mod tests {
|
||||
let mut features = Features::with_defaults();
|
||||
features.disable(Feature::MemoryTool);
|
||||
let tools_config = ToolsConfig::new(&ToolsConfigParams {
|
||||
codex_home: &config.codex_home,
|
||||
model_info: &model_info,
|
||||
features: &features,
|
||||
web_search_mode: Some(WebSearchMode::Cached),
|
||||
@@ -2360,6 +2415,7 @@ mod tests {
|
||||
let features = Features::with_defaults();
|
||||
|
||||
let tools_config = ToolsConfig::new(&ToolsConfigParams {
|
||||
codex_home: &config.codex_home,
|
||||
model_info: &model_info,
|
||||
features: &features,
|
||||
web_search_mode: Some(WebSearchMode::Cached),
|
||||
@@ -2386,6 +2442,7 @@ mod tests {
|
||||
features.enable(Feature::JsRepl);
|
||||
|
||||
let tools_config = ToolsConfig::new(&ToolsConfigParams {
|
||||
codex_home: &config.codex_home,
|
||||
model_info: &model_info,
|
||||
features: &features,
|
||||
web_search_mode: Some(WebSearchMode::Cached),
|
||||
@@ -2408,6 +2465,7 @@ mod tests {
|
||||
image_generation_features.enable(Feature::ImageGeneration);
|
||||
|
||||
let default_tools_config = ToolsConfig::new(&ToolsConfigParams {
|
||||
codex_home: &config.codex_home,
|
||||
model_info: &supported_model_info,
|
||||
features: &default_features,
|
||||
web_search_mode: Some(WebSearchMode::Cached),
|
||||
@@ -2422,6 +2480,7 @@ mod tests {
|
||||
);
|
||||
|
||||
let supported_tools_config = ToolsConfig::new(&ToolsConfigParams {
|
||||
codex_home: &config.codex_home,
|
||||
model_info: &supported_model_info,
|
||||
features: &image_generation_features,
|
||||
web_search_mode: Some(WebSearchMode::Cached),
|
||||
@@ -2431,6 +2490,7 @@ mod tests {
|
||||
assert_contains_tool_names(&supported_tools, &["image_generation"]);
|
||||
|
||||
let tools_config = ToolsConfig::new(&ToolsConfigParams {
|
||||
codex_home: &config.codex_home,
|
||||
model_info: &unsupported_model_info,
|
||||
features: &image_generation_features,
|
||||
web_search_mode: Some(WebSearchMode::Cached),
|
||||
@@ -2466,8 +2526,10 @@ mod tests {
|
||||
web_search_mode: Option<WebSearchMode>,
|
||||
expected_tools: &[&str],
|
||||
) {
|
||||
let config = test_config();
|
||||
let model_info = model_info_from_models_json(model_slug);
|
||||
let tools_config = ToolsConfig::new(&ToolsConfigParams {
|
||||
codex_home: &config.codex_home,
|
||||
model_info: &model_info,
|
||||
features,
|
||||
web_search_mode,
|
||||
@@ -2502,6 +2564,7 @@ mod tests {
|
||||
let features = Features::with_defaults();
|
||||
|
||||
let tools_config = ToolsConfig::new(&ToolsConfigParams {
|
||||
codex_home: &config.codex_home,
|
||||
model_info: &model_info,
|
||||
features: &features,
|
||||
web_search_mode: Some(WebSearchMode::Cached),
|
||||
@@ -2527,6 +2590,7 @@ mod tests {
|
||||
let features = Features::with_defaults();
|
||||
|
||||
let tools_config = ToolsConfig::new(&ToolsConfigParams {
|
||||
codex_home: &config.codex_home,
|
||||
model_info: &model_info,
|
||||
features: &features,
|
||||
web_search_mode: Some(WebSearchMode::Live),
|
||||
@@ -2553,6 +2617,7 @@ mod tests {
|
||||
let features = Features::with_defaults();
|
||||
|
||||
let tools_config = ToolsConfig::new(&ToolsConfigParams {
|
||||
codex_home: &config.codex_home,
|
||||
model_info: &model_info,
|
||||
features: &features,
|
||||
web_search_mode: Some(WebSearchMode::Live),
|
||||
@@ -2582,6 +2647,7 @@ mod tests {
|
||||
ModelsManager::construct_model_info_offline_for_tests("gpt-5-codex", &config);
|
||||
let features = Features::with_defaults();
|
||||
let tools_config = ToolsConfig::new(&ToolsConfigParams {
|
||||
codex_home: &config.codex_home,
|
||||
model_info: &model_info,
|
||||
features: &features,
|
||||
web_search_mode: Some(WebSearchMode::Cached),
|
||||
@@ -2605,6 +2671,7 @@ mod tests {
|
||||
ModelsManager::construct_model_info_offline_for_tests("gpt-5-codex", &config);
|
||||
let features = Features::with_defaults();
|
||||
let tools_config = ToolsConfig::new(&ToolsConfigParams {
|
||||
codex_home: &config.codex_home,
|
||||
model_info: &model_info,
|
||||
features: &features,
|
||||
web_search_mode: Some(WebSearchMode::Cached),
|
||||
@@ -2796,6 +2863,7 @@ mod tests {
|
||||
let mut features = Features::with_defaults();
|
||||
features.enable(Feature::UnifiedExec);
|
||||
let tools_config = ToolsConfig::new(&ToolsConfigParams {
|
||||
codex_home: &config.codex_home,
|
||||
model_info: &model_info,
|
||||
features: &features,
|
||||
web_search_mode: Some(WebSearchMode::Live),
|
||||
@@ -2820,6 +2888,7 @@ mod tests {
|
||||
features.enable(Feature::ShellZshFork);
|
||||
|
||||
let tools_config = ToolsConfig::new(&ToolsConfigParams {
|
||||
codex_home: &config.codex_home,
|
||||
model_info: &model_info,
|
||||
features: &features,
|
||||
web_search_mode: Some(WebSearchMode::Live),
|
||||
@@ -2846,6 +2915,7 @@ mod tests {
|
||||
let mut features = Features::with_defaults();
|
||||
features.enable(Feature::UnifiedExec);
|
||||
let tools_config = ToolsConfig::new(&ToolsConfigParams {
|
||||
codex_home: &config.codex_home,
|
||||
model_info: &model_info,
|
||||
features: &features,
|
||||
web_search_mode: Some(WebSearchMode::Cached),
|
||||
@@ -2862,6 +2932,7 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_test_model_info_includes_sync_tool() {
|
||||
let config = test_config();
|
||||
let mut model_info = model_info_from_models_json("gpt-5-codex");
|
||||
model_info.experimental_supported_tools = vec![
|
||||
"test_sync_tool".to_string(),
|
||||
@@ -2871,6 +2942,7 @@ mod tests {
|
||||
];
|
||||
let features = Features::with_defaults();
|
||||
let tools_config = ToolsConfig::new(&ToolsConfigParams {
|
||||
codex_home: &config.codex_home,
|
||||
model_info: &model_info,
|
||||
features: &features,
|
||||
web_search_mode: Some(WebSearchMode::Cached),
|
||||
@@ -2903,6 +2975,7 @@ mod tests {
|
||||
let mut features = Features::with_defaults();
|
||||
features.enable(Feature::UnifiedExec);
|
||||
let tools_config = ToolsConfig::new(&ToolsConfigParams {
|
||||
codex_home: &config.codex_home,
|
||||
model_info: &model_info,
|
||||
features: &features,
|
||||
web_search_mode: Some(WebSearchMode::Live),
|
||||
@@ -2990,6 +3063,7 @@ mod tests {
|
||||
let mut features = Features::with_defaults();
|
||||
features.enable(Feature::UnifiedExec);
|
||||
let tools_config = ToolsConfig::new(&ToolsConfigParams {
|
||||
codex_home: &config.codex_home,
|
||||
model_info: &model_info,
|
||||
features: &features,
|
||||
web_search_mode: Some(WebSearchMode::Cached),
|
||||
@@ -3036,6 +3110,7 @@ mod tests {
|
||||
let mut features = Features::with_defaults();
|
||||
features.enable(Feature::Apps);
|
||||
let tools_config = ToolsConfig::new(&ToolsConfigParams {
|
||||
codex_home: &config.codex_home,
|
||||
model_info: &model_info,
|
||||
features: &features,
|
||||
web_search_mode: Some(WebSearchMode::Cached),
|
||||
@@ -3104,6 +3179,7 @@ mod tests {
|
||||
let mut features = Features::with_defaults();
|
||||
features.enable(Feature::UnifiedExec);
|
||||
let tools_config = ToolsConfig::new(&ToolsConfigParams {
|
||||
codex_home: &config.codex_home,
|
||||
model_info: &model_info,
|
||||
features: &features,
|
||||
web_search_mode: Some(WebSearchMode::Cached),
|
||||
@@ -3159,6 +3235,7 @@ mod tests {
|
||||
let mut features = Features::with_defaults();
|
||||
features.enable(Feature::UnifiedExec);
|
||||
let tools_config = ToolsConfig::new(&ToolsConfigParams {
|
||||
codex_home: &config.codex_home,
|
||||
model_info: &model_info,
|
||||
features: &features,
|
||||
web_search_mode: Some(WebSearchMode::Cached),
|
||||
@@ -3211,6 +3288,7 @@ mod tests {
|
||||
features.enable(Feature::UnifiedExec);
|
||||
features.enable(Feature::ApplyPatchFreeform);
|
||||
let tools_config = ToolsConfig::new(&ToolsConfigParams {
|
||||
codex_home: &config.codex_home,
|
||||
model_info: &model_info,
|
||||
features: &features,
|
||||
web_search_mode: Some(WebSearchMode::Cached),
|
||||
@@ -3265,6 +3343,7 @@ mod tests {
|
||||
let mut features = Features::with_defaults();
|
||||
features.enable(Feature::UnifiedExec);
|
||||
let tools_config = ToolsConfig::new(&ToolsConfigParams {
|
||||
codex_home: &config.codex_home,
|
||||
model_info: &model_info,
|
||||
features: &features,
|
||||
web_search_mode: Some(WebSearchMode::Cached),
|
||||
@@ -3398,6 +3477,7 @@ Examples of valid command strings:
|
||||
let mut features = Features::with_defaults();
|
||||
features.enable(Feature::UnifiedExec);
|
||||
let tools_config = ToolsConfig::new(&ToolsConfigParams {
|
||||
codex_home: &config.codex_home,
|
||||
model_info: &model_info,
|
||||
features: &features,
|
||||
web_search_mode: Some(WebSearchMode::Cached),
|
||||
|
||||
Reference in New Issue
Block a user