mirror of
https://github.com/hanzoai/dev.git
synced 2026-10-17 15:34:54 +00:00
feat(core/agents): add 'cloud' agent support across run_agent, /plan, /solve; docs and examples; basic tests
- core/agent_tool: recognize "cloud" model and append prompt positionally; honor per‑mode args - core/codex(agent_run): include "cloud" in command resolution + PATH check - core/slash_commands: default /plan,/solve models now include "cloud"; test asserts prompt includes it - core/agent_defaults: add cloud case (no default flags); unit test ensures empty defaults - docs: note default agent set includes "cloud"; add config example Build passes via ./build-fast.sh. Full test suite currently fails on unrelated preexisting test drift (protocol/test-support imports, enum shapes).
This commit is contained in:
@@ -50,7 +50,20 @@ pub fn default_params_for(name: &str, read_only: bool) -> Vec<String> {
|
||||
]
|
||||
}
|
||||
}
|
||||
// Cloud agent: do not assume a prompt flag by default. Users can
|
||||
// configure args via [[agents]]; we will append the prompt positionally.
|
||||
"cloud" => Vec::new(),
|
||||
_ => Vec::new(),
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn cloud_defaults_are_empty_both_modes() {
|
||||
assert!(default_params_for("cloud", true).is_empty());
|
||||
assert!(default_params_for("cloud", false).is_empty());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -652,6 +652,21 @@ async fn execute_model_with_permissions(
|
||||
cmd.args(defaults);
|
||||
}
|
||||
}
|
||||
// Cloud agent: append prompt positionally; do not assume a -p flag.
|
||||
"cloud" => {
|
||||
// If config provided explicit args for this mode, do not append defaults.
|
||||
let have_mode_args = config
|
||||
.as_ref()
|
||||
.map(|c| if read_only { c.args_read_only.is_some() } else { c.args_write.is_some() })
|
||||
.unwrap_or(false);
|
||||
if have_mode_args {
|
||||
cmd.arg(prompt);
|
||||
} else {
|
||||
let mut defaults = crate::agent_defaults::default_params_for(model_name, read_only);
|
||||
defaults.push(prompt.to_string());
|
||||
cmd.args(defaults);
|
||||
}
|
||||
}
|
||||
_ => { return Err(format!("Unknown model: {}", model)); }
|
||||
}
|
||||
|
||||
|
||||
@@ -6491,6 +6491,8 @@ pub(crate) async fn handle_run_agent(sess: &Session, ctx: &ToolCallCtx, argument
|
||||
"claude" => ("claude".to_string(), false),
|
||||
"gemini" => ("gemini".to_string(), false),
|
||||
"qwen" => ("qwen".to_string(), false),
|
||||
// Cloud agent treated as external CLI by default.
|
||||
"cloud" => ("cloud".to_string(), false),
|
||||
_ => (m, false),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@ fn get_default_models() -> Vec<String> {
|
||||
"gemini".to_string(),
|
||||
"qwen".to_string(),
|
||||
"code".to_string(),
|
||||
"cloud".to_string(),
|
||||
]
|
||||
}
|
||||
|
||||
@@ -238,7 +239,10 @@ mod tests {
|
||||
// Test /plan command
|
||||
let result = handle_slash_command("/plan implement a new feature", None);
|
||||
assert!(result.is_some());
|
||||
assert!(result.unwrap().contains("Create a comprehensive plan"));
|
||||
let plan_prompt = result.unwrap();
|
||||
assert!(plan_prompt.contains("Create a comprehensive plan"));
|
||||
// Default agents list should include cloud when no [[agents]] configured
|
||||
assert!(plan_prompt.to_ascii_lowercase().contains("cloud"));
|
||||
|
||||
// Test /solve command
|
||||
let result = handle_slash_command("/solve fix the bug in authentication", None);
|
||||
|
||||
@@ -97,6 +97,19 @@ description = "Custom LLM implementation"
|
||||
args = ["--config", "/path/to/config.json"]
|
||||
env = { MODEL_PATH = "/models/custom.bin", TEMP = "0.7" }
|
||||
|
||||
# Cloud agent example
|
||||
[[agents]]
|
||||
name = "cloud"
|
||||
command = "cloud" # or a fully-qualified CLI if different
|
||||
enabled = true
|
||||
read-only = true # cloud work typically runs remotely; local writes aren’t needed
|
||||
description = "Submit tasks to a remote cloud worker"
|
||||
# By default no extra flags are passed; the prompt is appended positionally.
|
||||
# If your CLI expects a flag before the prompt, specify it here, e.g.:
|
||||
# args = ["submit", "-p"]
|
||||
# Optional environment:
|
||||
# env = { CODEX_CLOUD_ENV = "prod" }
|
||||
|
||||
# Sandbox Configuration
|
||||
# Controls file system access and permissions
|
||||
sandbox-mode = "workspace-write"
|
||||
|
||||
@@ -424,6 +424,8 @@ tool_timeout_sec = 30
|
||||
|
||||
Sub-agents are orchestrated helper workflows you can trigger with slash commands (for example `/plan`, `/solve`, `/code`). Each entry under `[[subagents.commands]]` defines the slash command name, whether spawned agents run in read-only mode, which `agents` to launch, and extra guidance for both the orchestrator (Code) and the individual agents.
|
||||
|
||||
By default (when no `[[agents]]` are configured) Code advertises these agent names for multi-agent runs: `claude`, `gemini`, `qwen`, `code`, and `cloud`. You can override that set by defining `[[agents]]` entries or by specifying `agents = [ … ]` on a given `[[subagents.commands]]` entry.
|
||||
|
||||
```toml
|
||||
[[subagents.commands]]
|
||||
name = "context"
|
||||
|
||||
@@ -93,3 +93,7 @@ Implementation Notes
|
||||
new command, please update this document to keep the UI and docs in sync.
|
||||
- Prompt formatting for `/plan`, `/solve`, and `/code` lives in
|
||||
`codex-rs/core/src/slash_commands.rs`.
|
||||
When no `[[agents]]` are configured, the orchestrator advertises the
|
||||
following agent names to the LLM for multi‑agent runs: `claude`, `gemini`,
|
||||
`qwen`, `code`, and `cloud`. You can replace or pin this set via `[[agents]]`
|
||||
or per‑command `[[subagents.commands]].agents`.
|
||||
|
||||
Reference in New Issue
Block a user