- bash is now Delegatable so named Agents may run shell commands - remove the legacy anonymous 'general' path entirely: SubAgentManager run_background/run_foreground_batch/run_inline/run_foreground, filter_tools/get_skills_prompt, TaskNotification direct delivery, DelegateContext task-local, background_permits/admission, and the delegate tool's check_task/cancel_task/list_tasks actions (agent_task replaces them); /stop and todo migrate off the task-local bridge - stop writing the legacy background_tasks table (read-only transition); /api/tasks union still renders historical records - ship a built-in general-purpose Agent definition (resources/agents) released to ~/.picobot/agents on first run like built-in skills, with bash/read-only/search/web/calculator/sleep tools; root_delegates now defaults to it so orchestration works out of the box - update AGENTS/README/architecture/config/db-schema docs accordingly
53 lines
2.2 KiB
Rust
53 lines
2.2 KiB
Rust
//! Built-in Agent definitions, released to the user config directory on
|
|
//! first run just like built-in skills. A released definition is a regular
|
|
//! user-editable file afterwards; the installer never overwrites it.
|
|
|
|
use std::path::Path;
|
|
|
|
use crate::config::LLMProviderConfig;
|
|
|
|
mod embedded {
|
|
include!(concat!(env!("OUT_DIR"), "/embedded_agents.rs"));
|
|
}
|
|
|
|
/// Install built-in Agent definitions into `<config_dir>/agents/`. Files
|
|
/// that already exist (user-modified or user-created) are left untouched.
|
|
pub fn install_builtin_agents(config_dir: &Path, profiles: &std::collections::HashMap<String, LLMProviderConfig>) {
|
|
let agents_dir = config_dir.join("agents");
|
|
if let Err(error) = std::fs::create_dir_all(&agents_dir) {
|
|
tracing::warn!(dir = %agents_dir.display(), error = %error, "Failed to create agents directory");
|
|
return;
|
|
}
|
|
for agent in embedded::EMBEDDED_AGENTS {
|
|
let path = agents_dir.join(format!("{}.md", agent.name));
|
|
if path.exists() {
|
|
continue;
|
|
}
|
|
if let Err(error) = std::fs::write(&path, agent.content) {
|
|
tracing::warn!(name = agent.name, error = %error, "Failed to install built-in Agent definition");
|
|
continue;
|
|
}
|
|
let profile = match profiles.get("default").cloned() {
|
|
Some(profile) => profile,
|
|
None => {
|
|
tracing::warn!(
|
|
name = agent.name,
|
|
"Skipping built-in Agent validation: no 'default' provider profile configured"
|
|
);
|
|
continue;
|
|
}
|
|
};
|
|
// Validate the released file immediately so a future catalog load
|
|
// cannot fail on a broken built-in. Validation failure keeps the
|
|
// file (the user can edit it) but logs loudly.
|
|
match super::definition::parse_definition(&path, std::sync::Arc::new(profile)) {
|
|
Ok(_) => {
|
|
tracing::info!(name = agent.name, dir = %path.display(), "Installed built-in Agent definition");
|
|
}
|
|
Err(error) => {
|
|
tracing::warn!(name = agent.name, error = %error, "Installed built-in Agent definition failed validation");
|
|
}
|
|
}
|
|
}
|
|
}
|