mirror of
https://github.com/openai/codex.git
synced 2026-10-25 18:28:38 +00:00
feat(core): add deferred watchdog namespace
This commit is contained in:
+123
-54
@@ -93,8 +93,9 @@ pub(crate) use codex_tools::mcp_call_tool_result_output_schema;
|
||||
const TOOL_SEARCH_DESCRIPTION_TEMPLATE_SOURCE: &str =
|
||||
include_str!("../../templates/search_tool/tool_description.md");
|
||||
const TOOL_SEARCH_DESCRIPTION_TEMPLATE_KEY: &str = "app_descriptions";
|
||||
const AGENT_TOOLS_NAMESPACE: &str = "agents";
|
||||
const AGENT_TOOLS_NAMESPACE_DESCRIPTION: &str = "Agent collaboration tools for spawning, messaging, waiting on, listing, and closing subagents.";
|
||||
const WATCHDOG_TOOLS_NAMESPACE: &str = "watchdog";
|
||||
const WATCHDOG_TOOLS_NAMESPACE_DESCRIPTION: &str =
|
||||
"Watchdog-only tools for parent-thread recovery and watchdog check-in lifecycle control.";
|
||||
static TOOL_SEARCH_DESCRIPTION_TEMPLATE: LazyLock<Template> = LazyLock::new(|| {
|
||||
Template::parse(TOOL_SEARCH_DESCRIPTION_TEMPLATE_SOURCE)
|
||||
.unwrap_or_else(|err| panic!("tool_search description template must parse: {err}"))
|
||||
@@ -495,7 +496,10 @@ fn create_test_sync_tool() -> ToolSpec {
|
||||
})
|
||||
}
|
||||
|
||||
fn create_tool_search_tool(app_tools: &HashMap<String, ToolInfo>) -> ToolSpec {
|
||||
fn create_tool_search_tool(
|
||||
app_tools: &HashMap<String, ToolInfo>,
|
||||
include_watchdog_tools: bool,
|
||||
) -> ToolSpec {
|
||||
let properties = BTreeMap::from([
|
||||
(
|
||||
"query".to_string(),
|
||||
@@ -512,10 +516,13 @@ fn create_tool_search_tool(app_tools: &HashMap<String, ToolInfo>) -> ToolSpec {
|
||||
},
|
||||
),
|
||||
]);
|
||||
let mut app_descriptions = BTreeMap::from([(
|
||||
AGENT_TOOLS_NAMESPACE.to_string(),
|
||||
Some(AGENT_TOOLS_NAMESPACE_DESCRIPTION.to_string()),
|
||||
)]);
|
||||
let mut app_descriptions = BTreeMap::new();
|
||||
if include_watchdog_tools {
|
||||
app_descriptions.insert(
|
||||
WATCHDOG_TOOLS_NAMESPACE.to_string(),
|
||||
Some(WATCHDOG_TOOLS_NAMESPACE_DESCRIPTION.to_string()),
|
||||
);
|
||||
}
|
||||
for tool in app_tools.values() {
|
||||
if tool.server_name != CODEX_APPS_MCP_SERVER_NAME {
|
||||
continue;
|
||||
@@ -971,7 +978,7 @@ fn push_tool_spec(
|
||||
}
|
||||
}
|
||||
|
||||
fn create_agent_tools_namespace(tools: Vec<ToolSpec>) -> ToolSpec {
|
||||
fn create_watchdog_tools_namespace(tools: Vec<ToolSpec>) -> ToolSpec {
|
||||
let tools = tools
|
||||
.into_iter()
|
||||
.filter_map(|tool| match tool {
|
||||
@@ -981,8 +988,8 @@ fn create_agent_tools_namespace(tools: Vec<ToolSpec>) -> ToolSpec {
|
||||
.collect();
|
||||
|
||||
ToolSpec::Namespace(ResponsesApiNamespace {
|
||||
name: AGENT_TOOLS_NAMESPACE.to_string(),
|
||||
description: AGENT_TOOLS_NAMESPACE_DESCRIPTION.to_string(),
|
||||
name: WATCHDOG_TOOLS_NAMESPACE.to_string(),
|
||||
description: WATCHDOG_TOOLS_NAMESPACE_DESCRIPTION.to_string(),
|
||||
tools,
|
||||
})
|
||||
}
|
||||
@@ -1072,12 +1079,14 @@ fn create_list_agents_tool(agent_watchdog: bool) -> ToolSpec {
|
||||
})
|
||||
}
|
||||
|
||||
fn register_agent_tool_handler<H>(builder: &mut ToolRegistryBuilder, name: &str, handler: Arc<H>)
|
||||
fn register_watchdog_tool_handler<H>(builder: &mut ToolRegistryBuilder, name: &str, handler: Arc<H>)
|
||||
where
|
||||
H: crate::tools::registry::ToolHandler + 'static,
|
||||
{
|
||||
builder.register_handler(name, handler.clone());
|
||||
builder.register_handler(tool_handler_key(name, Some(AGENT_TOOLS_NAMESPACE)), handler);
|
||||
builder.register_handler(
|
||||
tool_handler_key(name, Some(WATCHDOG_TOOLS_NAMESPACE)),
|
||||
handler,
|
||||
);
|
||||
}
|
||||
|
||||
/// Builds the tool registry builder while collecting tool specs for later serialization.
|
||||
@@ -1326,12 +1335,13 @@ pub(crate) fn build_specs_with_discoverable_tools(
|
||||
builder.register_handler("request_permissions", request_permissions_handler);
|
||||
}
|
||||
|
||||
if config.search_tool && (app_tools.is_some() || config.collab_tools) {
|
||||
let include_tool_search = config.search_tool || config.collab_tools;
|
||||
if include_tool_search && (app_tools.is_some() || config.collab_tools) {
|
||||
let app_tools = app_tools.unwrap_or_default();
|
||||
let search_tool_handler = Arc::new(ToolSearchHandler::new(app_tools.clone()));
|
||||
push_tool_spec(
|
||||
&mut builder,
|
||||
create_tool_search_tool(&app_tools),
|
||||
create_tool_search_tool(&app_tools, config.agent_watchdog),
|
||||
/*supports_parallel_tool_calls*/ true,
|
||||
config.code_mode_enabled,
|
||||
);
|
||||
@@ -1471,91 +1481,150 @@ pub(crate) fn build_specs_with_discoverable_tools(
|
||||
|
||||
if config.collab_tools {
|
||||
if config.multi_agent_v2 {
|
||||
let mut agent_tools = vec![
|
||||
push_tool_spec(
|
||||
&mut builder,
|
||||
create_spawn_agent_tool_v2(SpawnAgentToolOptions {
|
||||
available_models: &config.available_models,
|
||||
agent_type_description: crate::agent::role::spawn_tool_spec::build(
|
||||
&config.agent_roles,
|
||||
),
|
||||
}),
|
||||
/*supports_parallel_tool_calls*/ false,
|
||||
config.code_mode_enabled,
|
||||
);
|
||||
push_tool_spec(
|
||||
&mut builder,
|
||||
create_send_message_tool(),
|
||||
/*supports_parallel_tool_calls*/ false,
|
||||
config.code_mode_enabled,
|
||||
);
|
||||
push_tool_spec(
|
||||
&mut builder,
|
||||
create_assign_task_tool(),
|
||||
/*supports_parallel_tool_calls*/ false,
|
||||
config.code_mode_enabled,
|
||||
);
|
||||
push_tool_spec(
|
||||
&mut builder,
|
||||
create_wait_agent_tool_v2(WaitAgentTimeoutOptions {
|
||||
default_timeout_ms: DEFAULT_WAIT_TIMEOUT_MS,
|
||||
min_timeout_ms: MIN_WAIT_TIMEOUT_MS,
|
||||
max_timeout_ms: MAX_WAIT_TIMEOUT_MS,
|
||||
}),
|
||||
create_close_agent_tool_v2(),
|
||||
create_list_agents_tool_v2(),
|
||||
];
|
||||
if config.agent_watchdog {
|
||||
agent_tools.push(create_compact_parent_context_tool());
|
||||
agent_tools.push(create_watchdog_self_close_tool());
|
||||
}
|
||||
push_tool_spec(
|
||||
&mut builder,
|
||||
create_agent_tools_namespace(agent_tools),
|
||||
/*supports_parallel_tool_calls*/ false,
|
||||
config.code_mode_enabled,
|
||||
);
|
||||
register_agent_tool_handler(&mut builder, "spawn_agent", Arc::new(SpawnAgentHandlerV2));
|
||||
register_agent_tool_handler(
|
||||
push_tool_spec(
|
||||
&mut builder,
|
||||
"send_message",
|
||||
Arc::new(SendMessageHandlerV2),
|
||||
create_close_agent_tool_v2(),
|
||||
/*supports_parallel_tool_calls*/ false,
|
||||
config.code_mode_enabled,
|
||||
);
|
||||
push_tool_spec(
|
||||
&mut builder,
|
||||
create_list_agents_tool_v2(),
|
||||
/*supports_parallel_tool_calls*/ false,
|
||||
config.code_mode_enabled,
|
||||
);
|
||||
register_agent_tool_handler(&mut builder, "assign_task", Arc::new(AssignTaskHandlerV2));
|
||||
register_agent_tool_handler(&mut builder, "wait_agent", Arc::new(WaitAgentHandlerV2));
|
||||
register_agent_tool_handler(&mut builder, "close_agent", Arc::new(CloseAgentHandlerV2));
|
||||
register_agent_tool_handler(&mut builder, "list_agents", Arc::new(ListAgentsHandlerV2));
|
||||
if config.agent_watchdog {
|
||||
register_agent_tool_handler(
|
||||
push_tool_spec(
|
||||
&mut builder,
|
||||
create_watchdog_tools_namespace(vec![
|
||||
create_compact_parent_context_tool(),
|
||||
create_watchdog_self_close_tool(),
|
||||
]),
|
||||
/*supports_parallel_tool_calls*/ false,
|
||||
config.code_mode_enabled,
|
||||
);
|
||||
}
|
||||
builder.register_handler("spawn_agent", Arc::new(SpawnAgentHandlerV2));
|
||||
builder.register_handler("send_message", Arc::new(SendMessageHandlerV2));
|
||||
builder.register_handler("assign_task", Arc::new(AssignTaskHandlerV2));
|
||||
builder.register_handler("wait_agent", Arc::new(WaitAgentHandlerV2));
|
||||
builder.register_handler("close_agent", Arc::new(CloseAgentHandlerV2));
|
||||
builder.register_handler("list_agents", Arc::new(ListAgentsHandlerV2));
|
||||
if config.agent_watchdog {
|
||||
register_watchdog_tool_handler(
|
||||
&mut builder,
|
||||
"compact_parent_context",
|
||||
Arc::new(CompactParentContextHandler),
|
||||
);
|
||||
register_watchdog_tool_handler(
|
||||
&mut builder,
|
||||
"watchdog_self_close",
|
||||
Arc::new(WatchdogSelfCloseHandlerV2),
|
||||
);
|
||||
}
|
||||
} else {
|
||||
let mut agent_tools = vec![
|
||||
push_tool_spec(
|
||||
&mut builder,
|
||||
create_spawn_agent_tool_v1(SpawnAgentToolOptions {
|
||||
available_models: &config.available_models,
|
||||
agent_type_description: crate::agent::role::spawn_tool_spec::build(
|
||||
&config.agent_roles,
|
||||
),
|
||||
}),
|
||||
/*supports_parallel_tool_calls*/ false,
|
||||
config.code_mode_enabled,
|
||||
);
|
||||
push_tool_spec(
|
||||
&mut builder,
|
||||
create_send_input_tool_v1(),
|
||||
/*supports_parallel_tool_calls*/ false,
|
||||
config.code_mode_enabled,
|
||||
);
|
||||
push_tool_spec(
|
||||
&mut builder,
|
||||
create_resume_agent_tool(),
|
||||
/*supports_parallel_tool_calls*/ false,
|
||||
config.code_mode_enabled,
|
||||
);
|
||||
push_tool_spec(
|
||||
&mut builder,
|
||||
create_wait_agent_tool_v1(WaitAgentTimeoutOptions {
|
||||
default_timeout_ms: DEFAULT_WAIT_TIMEOUT_MS,
|
||||
min_timeout_ms: MIN_WAIT_TIMEOUT_MS,
|
||||
max_timeout_ms: MAX_WAIT_TIMEOUT_MS,
|
||||
}),
|
||||
create_close_agent_tool_v1(),
|
||||
];
|
||||
if config.agent_watchdog {
|
||||
agent_tools.push(create_list_agents_tool(config.agent_watchdog));
|
||||
agent_tools.push(create_compact_parent_context_tool());
|
||||
agent_tools.push(create_watchdog_self_close_tool());
|
||||
}
|
||||
push_tool_spec(
|
||||
&mut builder,
|
||||
create_agent_tools_namespace(agent_tools),
|
||||
/*supports_parallel_tool_calls*/ false,
|
||||
config.code_mode_enabled,
|
||||
);
|
||||
register_agent_tool_handler(&mut builder, "spawn_agent", Arc::new(SpawnAgentHandler));
|
||||
register_agent_tool_handler(&mut builder, "send_input", Arc::new(SendInputHandler));
|
||||
register_agent_tool_handler(&mut builder, "resume_agent", Arc::new(ResumeAgentHandler));
|
||||
register_agent_tool_handler(&mut builder, "wait_agent", Arc::new(WaitAgentHandler));
|
||||
register_agent_tool_handler(&mut builder, "close_agent", Arc::new(CloseAgentHandler));
|
||||
register_agent_tool_handler(&mut builder, "list_agents", Arc::new(ListAgentsHandler));
|
||||
push_tool_spec(
|
||||
&mut builder,
|
||||
create_close_agent_tool_v1(),
|
||||
/*supports_parallel_tool_calls*/ false,
|
||||
config.code_mode_enabled,
|
||||
);
|
||||
if config.agent_watchdog {
|
||||
register_agent_tool_handler(
|
||||
push_tool_spec(
|
||||
&mut builder,
|
||||
create_list_agents_tool(config.agent_watchdog),
|
||||
/*supports_parallel_tool_calls*/ false,
|
||||
config.code_mode_enabled,
|
||||
);
|
||||
push_tool_spec(
|
||||
&mut builder,
|
||||
create_watchdog_tools_namespace(vec![
|
||||
create_compact_parent_context_tool(),
|
||||
create_watchdog_self_close_tool(),
|
||||
]),
|
||||
/*supports_parallel_tool_calls*/ false,
|
||||
config.code_mode_enabled,
|
||||
);
|
||||
}
|
||||
builder.register_handler("spawn_agent", Arc::new(SpawnAgentHandler));
|
||||
builder.register_handler("send_input", Arc::new(SendInputHandler));
|
||||
builder.register_handler("resume_agent", Arc::new(ResumeAgentHandler));
|
||||
builder.register_handler("wait_agent", Arc::new(WaitAgentHandler));
|
||||
builder.register_handler("close_agent", Arc::new(CloseAgentHandler));
|
||||
builder.register_handler("list_agents", Arc::new(ListAgentsHandler));
|
||||
if config.agent_watchdog {
|
||||
register_watchdog_tool_handler(
|
||||
&mut builder,
|
||||
"compact_parent_context",
|
||||
Arc::new(CompactParentContextHandler),
|
||||
);
|
||||
register_agent_tool_handler(
|
||||
register_watchdog_tool_handler(
|
||||
&mut builder,
|
||||
"watchdog_self_close",
|
||||
Arc::new(WatchdogSelfCloseHandler),
|
||||
|
||||
@@ -170,6 +170,20 @@ fn assert_lacks_tool_name(tools: &[ConfiguredToolSpec], expected_absent: &str) {
|
||||
);
|
||||
}
|
||||
|
||||
fn assert_contains_top_level_tool_name(tools: &[ConfiguredToolSpec], expected: &str) {
|
||||
assert!(
|
||||
tools.iter().any(|tool| tool.name() == expected),
|
||||
"expected top-level tool {expected} to be present"
|
||||
);
|
||||
}
|
||||
|
||||
fn assert_lacks_top_level_tool_name(tools: &[ConfiguredToolSpec], expected_absent: &str) {
|
||||
assert!(
|
||||
!tools.iter().any(|tool| tool.name() == expected_absent),
|
||||
"expected top-level tool {expected_absent} to be absent"
|
||||
);
|
||||
}
|
||||
|
||||
fn shell_tool_name(config: &ToolsConfig) -> Option<&'static str> {
|
||||
match config.shell_type {
|
||||
ConfigShellToolType::Default => Some("shell"),
|
||||
@@ -226,6 +240,38 @@ fn find_tool<'a>(tools: &'a [ConfiguredToolSpec], expected_name: &str) -> &'a Co
|
||||
panic!("expected tool {expected_name}")
|
||||
}
|
||||
|
||||
fn find_namespaced_tool(
|
||||
tools: &[ConfiguredToolSpec],
|
||||
namespace_name: &str,
|
||||
expected_name: &str,
|
||||
) -> ConfiguredToolSpec {
|
||||
let namespace = tools
|
||||
.iter()
|
||||
.find_map(|tool| match &tool.spec {
|
||||
ToolSpec::Namespace(namespace) if namespace.name == namespace_name => Some(namespace),
|
||||
_ => None,
|
||||
})
|
||||
.unwrap_or_else(|| panic!("expected namespace {namespace_name}"));
|
||||
|
||||
let tool = namespace
|
||||
.tools
|
||||
.iter()
|
||||
.find_map(|tool| match tool {
|
||||
codex_tools::ResponsesApiNamespaceTool::Function(tool)
|
||||
if tool.name == expected_name =>
|
||||
{
|
||||
Some(tool.clone())
|
||||
}
|
||||
_ => None,
|
||||
})
|
||||
.unwrap_or_else(|| panic!("expected tool {expected_name} in {namespace_name}"));
|
||||
|
||||
ConfiguredToolSpec::new(
|
||||
ToolSpec::Function(tool),
|
||||
/*supports_parallel_tool_calls*/ false,
|
||||
)
|
||||
}
|
||||
|
||||
fn strip_descriptions_schema(schema: &mut JsonSchema) {
|
||||
match schema {
|
||||
JsonSchema::Boolean { description }
|
||||
@@ -407,13 +453,19 @@ fn test_full_toolset_specs_for_gpt5_codex_unified_exec_web_search() {
|
||||
];
|
||||
if config.agent_watchdog {
|
||||
collab_specs.push(create_list_agents_tool(config.agent_watchdog));
|
||||
collab_specs.push(create_compact_parent_context_tool());
|
||||
collab_specs.push(create_watchdog_self_close_tool());
|
||||
}
|
||||
collab_specs
|
||||
};
|
||||
let spec = create_agent_tools_namespace(collab_specs.split_off(0));
|
||||
expected.insert(spec.name().to_string(), spec);
|
||||
for spec in collab_specs.split_off(0) {
|
||||
expected.insert(spec.name().to_string(), spec);
|
||||
}
|
||||
if config.agent_watchdog {
|
||||
let spec = create_watchdog_tools_namespace(vec![
|
||||
create_compact_parent_context_tool(),
|
||||
create_watchdog_self_close_tool(),
|
||||
]);
|
||||
expected.insert(spec.name().to_string(), spec);
|
||||
}
|
||||
|
||||
if config.exec_permission_approvals_enabled {
|
||||
let spec = create_request_permissions_tool(request_permissions_tool_description());
|
||||
@@ -458,12 +510,14 @@ fn test_build_specs_collab_tools_enabled() {
|
||||
&[],
|
||||
)
|
||||
.build();
|
||||
assert_contains_tool_names(&tools, &["tool_search"]);
|
||||
assert_contains_tool_names(
|
||||
&tools,
|
||||
&["spawn_agent", "send_input", "wait_agent", "close_agent"],
|
||||
);
|
||||
assert_lacks_tool_name(&tools, "spawn_agents_on_csv");
|
||||
assert_lacks_tool_name(&tools, "list_agents");
|
||||
assert_lacks_tool_name(&tools, "watchdog");
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -493,17 +547,12 @@ fn test_build_specs_watchdog_collab_tools_include_self_close_tool() {
|
||||
)
|
||||
.build();
|
||||
|
||||
assert_contains_tool_names(
|
||||
&tools,
|
||||
&[
|
||||
"watchdog_self_close",
|
||||
"compact_parent_context",
|
||||
"list_agents",
|
||||
"close_agent",
|
||||
],
|
||||
);
|
||||
assert_contains_top_level_tool_name(&tools, "watchdog");
|
||||
assert_contains_tool_names(&tools, &["tool_search", "list_agents", "close_agent"]);
|
||||
assert_lacks_top_level_tool_name(&tools, "watchdog_self_close");
|
||||
assert_lacks_top_level_tool_name(&tools, "compact_parent_context");
|
||||
|
||||
let watchdog_self_close = find_tool(&tools, "watchdog_self_close");
|
||||
let watchdog_self_close = find_namespaced_tool(&tools, "watchdog", "watchdog_self_close");
|
||||
let ToolSpec::Function(ResponsesApiTool {
|
||||
defer_loading: Some(deferred),
|
||||
..
|
||||
@@ -511,7 +560,16 @@ fn test_build_specs_watchdog_collab_tools_include_self_close_tool() {
|
||||
else {
|
||||
panic!("watchdog_self_close should be a function tool");
|
||||
};
|
||||
assert_eq!(*deferred, true);
|
||||
assert!(*deferred);
|
||||
let compact_parent_context = find_namespaced_tool(&tools, "watchdog", "compact_parent_context");
|
||||
let ToolSpec::Function(ResponsesApiTool {
|
||||
defer_loading: Some(deferred),
|
||||
..
|
||||
}) = &compact_parent_context.spec
|
||||
else {
|
||||
panic!("compact_parent_context should be a function tool");
|
||||
};
|
||||
assert!(*deferred);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -1457,6 +1515,7 @@ fn test_build_specs_gpt5_codex_default() {
|
||||
&[
|
||||
"update_plan",
|
||||
"request_user_input",
|
||||
"tool_search",
|
||||
"apply_patch",
|
||||
"web_search",
|
||||
"view_image",
|
||||
@@ -1480,6 +1539,7 @@ fn test_build_specs_gpt51_codex_default() {
|
||||
&[
|
||||
"update_plan",
|
||||
"request_user_input",
|
||||
"tool_search",
|
||||
"apply_patch",
|
||||
"web_search",
|
||||
"view_image",
|
||||
@@ -1505,6 +1565,7 @@ fn test_build_specs_gpt5_codex_unified_exec_web_search() {
|
||||
"write_stdin",
|
||||
"update_plan",
|
||||
"request_user_input",
|
||||
"tool_search",
|
||||
"apply_patch",
|
||||
"web_search",
|
||||
"view_image",
|
||||
@@ -1530,6 +1591,7 @@ fn test_build_specs_gpt51_codex_unified_exec_web_search() {
|
||||
"write_stdin",
|
||||
"update_plan",
|
||||
"request_user_input",
|
||||
"tool_search",
|
||||
"apply_patch",
|
||||
"web_search",
|
||||
"view_image",
|
||||
@@ -1553,6 +1615,7 @@ fn test_gpt_5_1_codex_max_defaults() {
|
||||
&[
|
||||
"update_plan",
|
||||
"request_user_input",
|
||||
"tool_search",
|
||||
"apply_patch",
|
||||
"web_search",
|
||||
"view_image",
|
||||
@@ -1576,6 +1639,7 @@ fn test_codex_5_1_mini_defaults() {
|
||||
&[
|
||||
"update_plan",
|
||||
"request_user_input",
|
||||
"tool_search",
|
||||
"apply_patch",
|
||||
"web_search",
|
||||
"view_image",
|
||||
@@ -1599,6 +1663,7 @@ fn test_gpt_5_defaults() {
|
||||
&[
|
||||
"update_plan",
|
||||
"request_user_input",
|
||||
"tool_search",
|
||||
"web_search",
|
||||
"view_image",
|
||||
"spawn_agent",
|
||||
@@ -1621,6 +1686,7 @@ fn test_gpt_5_1_defaults() {
|
||||
&[
|
||||
"update_plan",
|
||||
"request_user_input",
|
||||
"tool_search",
|
||||
"apply_patch",
|
||||
"web_search",
|
||||
"view_image",
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
## Watchdog-only Guidance
|
||||
|
||||
If you are acting as a watchdog check-in agent, `compact_parent_context` may be available.
|
||||
If you are acting as a watchdog check-in agent, the deferred `watchdog` namespace may be available
|
||||
through `tool_search`.
|
||||
|
||||
- Use `compact_parent_context` only when the parent thread is idle and appears stuck.
|
||||
- `compact_parent_context` is not part of the general subagent tool surface; do not mention or rely on it unless you are explicitly operating as a watchdog check-in agent.
|
||||
- `watchdog_self_close` is also available to this watchdog thread and can be used to end the check-in when work is complete.
|
||||
- Use `watchdog.compact_parent_context` only when the parent thread is idle and appears stuck.
|
||||
- `watchdog.compact_parent_context` is not part of the general subagent tool surface; do not
|
||||
mention or rely on it unless you are explicitly operating as a watchdog check-in agent.
|
||||
- `watchdog.watchdog_self_close` is also available to this watchdog thread and can be used to end
|
||||
the check-in when work is complete.
|
||||
|
||||
@@ -54,12 +54,13 @@ Use only the multi-agent tools that exist here:
|
||||
|
||||
- `spawn_agent` (prefer `fork_context = true` when shared context matters).
|
||||
- `send_input`.
|
||||
- `compact_parent_context` (watchdog-only recovery tool; see below).
|
||||
- `watchdog_self_close` (watchdog-only immediate exit tool; see below).
|
||||
- `tool_search` to discover deferred watchdog-only tools in the `watchdog` namespace.
|
||||
- `watchdog.compact_parent_context` (watchdog-only recovery tool; see below).
|
||||
- `watchdog.watchdog_self_close` (watchdog-only immediate exit tool; see below).
|
||||
- `wait`.
|
||||
- `close_agent`.
|
||||
|
||||
There is no cancel tool. Use `watchdog_self_close` to stop this watchdog check-in thread when its job is complete; use `close_agent` to stop subagents that are done or no longer needed.
|
||||
There is no cancel tool. Use `watchdog.watchdog_self_close` to stop this watchdog check-in thread when its job is complete; use `close_agent` to stop subagents that are done or no longer needed.
|
||||
|
||||
When recommending watchdogs to the root agent, keep `agent_type` at the default.
|
||||
|
||||
@@ -73,7 +74,7 @@ For token protocols (for example `ping N` / `pong N`), treat those as literal te
|
||||
|
||||
## Parent Recovery via Context Compaction
|
||||
|
||||
`compact_parent_context` asks the system to abbreviate/compact redundant parent-thread context so the parent can recover from loops.
|
||||
`watchdog.compact_parent_context` asks the system to abbreviate/compact redundant parent-thread context so the parent can recover from loops.
|
||||
|
||||
Use it only as a last resort:
|
||||
|
||||
@@ -81,9 +82,9 @@ Use it only as a last resort:
|
||||
- The parent is taking no meaningful actions (no concrete commands/edits/tests) and making no progress.
|
||||
- You already sent at least one direct corrective instruction with `send_input`, and it was ignored.
|
||||
|
||||
`watchdog_self_close` asks the runtime to end the current watchdog check-in thread immediately. Use it only after reporting status and when the check-in has no remaining work, to avoid idle watchdog loops.
|
||||
`watchdog.watchdog_self_close` asks the runtime to end the current watchdog check-in thread immediately. Use it only after reporting status and when the check-in has no remaining work, to avoid idle watchdog loops.
|
||||
|
||||
Do not call `compact_parent_context` for routine nudges or normal delays. Prefer precise `send_input` guidance first.
|
||||
Do not call `watchdog.compact_parent_context` for routine nudges or normal delays. Prefer precise `send_input` guidance first.
|
||||
|
||||
## Style
|
||||
|
||||
|
||||
Reference in New Issue
Block a user