fix(prompts): v2 prompt pipeline, integrations_agent, and subagent session plumbing#642
Conversation
…ectory structure
- Changed the source of truth path for session transcripts from `sessions/{DDMMYYYY}/{agent}_{index}.jsonl` to `session_raw/{DDMMYYYY}/{agent}_{index}.jsonl` to better reflect the organization of files.
- Updated the logic for creating and resolving transcript paths to accommodate the new directory structure, ensuring compatibility with legacy `.md` files.
- Improved documentation to clarify the changes in file organization and their implications for transcript management.
This refactor enhances the clarity and maintainability of session transcript handling by establishing a more logical file structure.
- Replaced `Vec<String>` with `Vec<ToolSummary<'_>>` for available tools in multiple agent prompt builders, enhancing type safety and clarity. - Introduced `render_tool_catalog` and `render_connected_integrations` functions to dynamically generate sections in prompts based on available tools and connected integrations. - Updated the `build` function in various agent prompts to utilize the new rendering functions, ensuring that prompts accurately reflect the current context and available resources. These changes improve the maintainability and functionality of the prompt generation process across different agents.
- Updated the prompt builders for various agents to utilize the sibling `prompt.md` template directly, enhancing clarity and maintainability. - Replaced `Vec<ToolSummary<'_>>` with `Vec<ToolSummary>` and `Vec<ConnectedIntegration>` for improved type safety in test cases. - Adjusted the `build` function to ensure consistent formatting and handling of tool catalogs across different agents. These changes simplify the prompt generation process and prepare the codebase for future enhancements.
…consistency - Exposed `filter_tool_indices` and `load_prompt_source` as `pub(crate)` to ensure that both the live runner and debug dump share the same filtering and loading logic, eliminating discrepancies. - Enhanced documentation for both functions to clarify their purpose and usage, improving maintainability and understanding of the codebase. These changes streamline the tool management process and enhance the reliability of debug outputs, ensuring consistency across different contexts.
- Updated the prompt builders for various agents to return fully-assembled system prompts, incorporating section helpers from `crate::openhuman::context::prompt`. - Replaced `Vec<ToolSummary<'_>>` with `Vec<ToolSummary>` and `Vec<ConnectedIntegration>` for improved type safety in test cases. - Adjusted the `build` function to ensure consistent formatting and handling of user files, tools, and workspace sections across different agents. These changes streamline the prompt generation process, improve maintainability, and prepare the codebase for future enhancements.
- Updated the prompt builders to support fully-assembled prompts from dynamic sources, allowing for more flexible prompt generation. - Introduced `PromptTool` and `PromptContext` structures to replace `ToolSummary`, improving type safety and clarity in prompt construction. - Refactored the handling of prompt sources in both the subagent runner and session builder to streamline the integration of dynamic prompts and legacy sources. These changes improve the maintainability and functionality of the prompt generation process, ensuring accurate representation of available tools and context in agent interactions.
- Enhanced the `PromptContext` structure to include additional fields for better context management, such as `skills`, `dispatcher_instructions`, and `tool_call_format`. - Replaced `ToolSummary` with `PromptTool` for improved type safety and clarity in prompt generation. - Updated the handling of dynamic prompt sources in both the subagent runner and debug dump, ensuring consistent integration and rendering of prompts. - Introduced a mechanism to handle empty visible tool names, enhancing the robustness of prompt generation. These changes streamline the prompt construction process and improve the overall maintainability of the codebase.
…mptBuilder - Moved prompt-related types and builders from `openhuman::context::prompt` to `openhuman::agent::prompts` for better modularity. - Introduced `SystemPromptBuilder` to streamline the construction of system prompts, allowing for flexible section management. - Updated module exports to maintain compatibility while enhancing the organization of prompt-related code. These changes improve the clarity and maintainability of the prompt generation process, aligning it more closely with the agents that utilize these prompts.
- Removed the "main" alias for the orchestrator in the prompt dumping process, treating it as just another registered agent. - Updated the `debug-agent-prompts.sh` script to reflect this change, ensuring all agents are included uniformly. - Revised documentation and error messages in `agent_cli.rs` to replace references to "main" with "orchestrator" for clarity. - Enhanced the debug dump functionality to maintain consistency across agent prompts, improving overall maintainability and usability. These changes streamline the prompt handling process and clarify the usage of agent identifiers in the CLI, aligning with the new architecture.
- Eliminated the CACHE_BOUNDARY marker from various agent prompt files, streamlining the prompt generation process. - Updated the build functions in multiple agents to ensure consistent handling of workspace rendering without the cache boundary. - Refactored related prompt handling logic to enhance clarity and maintainability, aligning with the new architecture. These changes simplify the prompt structure and improve the overall efficiency of prompt generation across agents.
…ompts - Eliminated all instances of cache boundary references from the subagent runner and related tests, simplifying the prompt handling logic. - Updated test assertions to reflect the removal of cache boundary checks, ensuring consistency across the testing framework. - Refactored the session manager to streamline the system prompt assembly process without relying on cache boundaries. These changes enhance the clarity and maintainability of the prompt generation process, aligning with the recent architectural updates.
- Removed unnecessary imports from multiple files, including `RandomState`, `Hasher`, and `SerializeMap`, to enhance code clarity and maintainability. - Simplified the structure of several modules by eliminating redundant use statements, ensuring a cleaner and more efficient codebase. These changes contribute to a more organized and readable code structure, aligning with ongoing refactoring efforts.
…ndling - Updated the `orchestrator`, `skills_agent`, and `welcome` prompts to streamline the rendering of connected integrations and delegation guides. - Introduced dedicated functions for rendering integration information, ensuring clarity in the agent's voice and responsibilities. - Removed redundant sections from the shared prompt builder, allowing each agent to manage its own prompt content more effectively. - Improved test coverage for prompt generation, ensuring accurate representation of connected integrations and skills. These changes enhance the maintainability and clarity of the prompt generation process, aligning with the recent architectural updates.
…rameters - Revised documentation for `connected_integrations` in the `Agent` struct to clarify its role in the agent's prompt rendering. - Updated the parameter name in `render_subagent_system_prompt_with_format` to `_connected_integrations` to indicate it is unused, enhancing code clarity. - Cleaned up import statements in the context module for better organization and maintainability. These changes improve the clarity of integration handling and streamline the code structure, aligning with ongoing refactoring efforts.
- Removed the `--skill` option from the `dump-prompt` command, streamlining the command usage and focusing on essential parameters. - Updated documentation to clarify the usage of the `dump-prompt` command and its parameters, enhancing user understanding. - Cleaned up the `DumpFlags` structure by removing unused fields, contributing to a more maintainable codebase. These changes improve the clarity and usability of the agent CLI, aligning with ongoing refactoring efforts.
- Introduced `load_dotenv_for_cli` to load environment variables for all CLI entrypoints, ensuring consistent configuration across commands. - Updated documentation to clarify the purpose of the dotenv loading mechanism. - Removed unnecessary blank lines in prompt rendering functions across multiple agents, enhancing code readability. These changes improve the maintainability and clarity of the CLI and prompt handling, aligning with ongoing refactoring efforts.
…line workspace resolution - Updated the script to load environment variables from a `.env` file, ensuring consistent configuration for prompt generation. - Simplified workspace resolution by delegating to the binary's internal logic, improving reliability and reducing code duplication. - Revised documentation to clarify the usage of command options and the impact of environment variables on prompt rendering. These changes improve the maintainability and clarity of the debug agent prompts script, aligning with ongoing refactoring efforts.
- Eliminated the `category_filter` from various agent definitions and related tests, streamlining the agent configuration. - Updated the `run_list` function in `agent_cli.rs` to reflect the removal of category filtering, enhancing output clarity. - Revised documentation and comments to remove references to the now-removed category filter, improving overall code maintainability. These changes contribute to a cleaner and more efficient agent architecture, aligning with ongoing refactoring efforts.
…ed service handling - Added the `integrations_agent` to manage service integrations via Composio, including a new TOML configuration and prompt structure. - Introduced the `tools_agent` for general ad-hoc tasks using built-in OpenHuman tools, with its own configuration and prompt. - Updated the loader to include both agents in the built-in agent list, increasing the total number of agents from 13 to 14. - Revised orchestrator and welcome prompts to delegate integration tasks to the new `integrations_agent`, ensuring clarity in agent responsibilities. - Enhanced tests to verify the registration and functionality of the new agents, improving overall test coverage. These changes expand the capabilities of the agent architecture, allowing for more specialized handling of integrations and tool usage.
…_agent - Changed all instances of `skills_agent` to `integrations_agent` across various files, including prompts, CLI commands, and tool registrations. - Updated documentation and comments to reflect the new agent name, ensuring clarity in agent responsibilities and usage. - Revised debug scripts to align with the new prompt structure for the integrations agent. These changes enhance consistency in the codebase and improve the clarity of agent interactions.
…t the codebase - Updated all instances of `skills_agent` to `integrations_agent` in various files, including tests, documentation, and comments. - Ensured consistency in agent references to improve clarity in agent responsibilities and interactions. - Revised related code structures to align with the new naming convention, enhancing overall maintainability. These changes support the transition to the new agent architecture and improve code readability.
…ntext handling - Introduced `DynamicPromptSection` to allow prompts to be built dynamically using a function pointer, enabling real-time access to the `PromptContext`. - Updated `SystemPromptBuilder` to support dynamic prompts, ensuring that late-arriving state like `connected_integrations` is accurately reflected in the rendered output. - Revised the prompt handling logic in the agent builder to streamline the integration of dynamic prompts, improving overall flexibility and responsiveness. These changes enhance the prompt generation process, aligning with the ongoing improvements in agent architecture and context management.
…integrations - Updated the `render_delegation_guide` function to list only the toolkits that are actively connected, omitting unauthorized toolkits to prevent hallucinations during delegation. - Revised related tests to ensure the prompt correctly reflects the current state of integrations, including scenarios where no integrations are connected. - Introduced a new utility function to filter out welcome-only tools from non-welcome agents, enhancing the clarity and safety of tool visibility. These changes improve the accuracy and focus of the delegation guide, aligning with the ongoing enhancements in agent prompt handling.
…nly operations - Modified the `agent.toml` configuration to clarify that the planner operates in a read-only mode, specifying that it does not mutate the workspace or memory. - Revised the prompt guidelines to reflect the read-only nature of the planner, emphasizing the need for explicit nodes for any required writes to be handled by downstream agents. These changes enhance the clarity of the planner's operational constraints and improve the overall structure of the planning process.
…nfigurations - Eliminated the `OPENHUMAN_WEB_SEARCH_ENABLED` environment variable and associated logic, as web search is now always enabled by default. - Updated the configuration schema to reflect the removal of the enable flag from `WebSearchConfig`. - Adjusted tool registration to ensure web search is always available, simplifying the configuration process. These changes streamline the web search functionality, ensuring it is consistently available across all sessions.
- Changed the `http_request` configuration to always be enabled, removing the dependency on the `config.http_request.enabled` flag. - This adjustment simplifies the configuration process and ensures consistent behavior across the application. These changes contribute to a more streamlined configuration and enhance the overall reliability of the onboarding process.
…nt prompts - Replaced the previous method of listing agent IDs and dumping prompts with a new `dump-all` command that consolidates the functionality into a single call. - Updated the script to handle output directory and workspace options more efficiently, leveraging Rust's `dump_all_agent_prompts` for processing. - Enhanced the handling of the `integrations_agent` to generate separate dumps for each connected toolkit, improving the clarity and organization of output files. - Revised related logging and summary generation to reflect the new structure, ensuring a more streamlined user experience. These changes modernize the prompt dumping process, aligning it with the latest architectural improvements and enhancing usability.
…egrations - Added a new `fetch_toolkit_actions` function to retrieve the current action catalogue for a specified Composio toolkit, enhancing the responsiveness of the integrations agent. - Updated the `subagent_runner` to utilize the fresh action list at spawn time, ensuring that the toolkit's actions reflect the latest backend state. - Modified the `render_integrations_agent` function to refresh the action catalogue during prompt generation, improving the accuracy of the displayed tools. These changes enhance the integration experience by providing up-to-date action information, aligning with the ongoing improvements in agent functionality.
…n handling - Modified the `agent.toml` to replace `wildcard` with `named` tools, enhancing control over tool visibility for the integrations agent. - Updated the `subagent_runner` to ensure that tool visibility aligns with the new TOML configuration, preventing unnecessary stripping of tools. - Revised the `render_integrations_agent` function to respect the updated tool scope, improving the accuracy of the tool list generated for subagents. These changes streamline the tool management process, ensuring that only explicitly defined tools are available during agent execution.
…ation detection - Introduced the `composio_list_connections` tool in the orchestrator's configuration, allowing the agent to detect newly-authorized Composio integrations mid-session. - Enhanced the `ComposioListConnectionsTool` to filter and return only currently-connected integrations with ACTIVE or CONNECTED status, improving the accuracy of integration management. - Updated the tool's description to clarify its functionality and usage context. These changes enhance the agent's ability to manage integrations dynamically, aligning with ongoing improvements in the integration experience.
- Modified the `render_delegation_guide` function to change the reference from **Settings → Integrations** to the **Skills** page for connecting integrations. This update clarifies the user instructions for integration management.
- Added `session_key` and `session_parent_prefix` fields to `ParentExecutionContext` to facilitate hierarchical transcript naming for sub-agents. - Updated `persist_subagent_transcript` to generate transcript filenames based on the parent's session key, ensuring a flat file structure that reflects the parent-child relationship. - Enhanced `AgentBuilder` and `Agent` to support the new session key management, allowing for better organization of session transcripts. - Adjusted related functions to ensure proper handling of session keys during agent execution and transcript persistence. These changes improve the clarity and organization of session transcripts, aligning with the ongoing enhancements in agent functionality.
…ranscript handling - Renamed the `integrations_agent_is_wildcard` test to `integrations_agent_tool_scope_honours_toml` to better reflect its purpose of validating tool scope based on TOML configuration. - Enhanced the test to assert that the `integrations_agent` correctly recognizes named tools instead of a wildcard. - Removed the `integrations_agent_has_extra_tools_for_export` test as it is no longer relevant to the current tool management strategy. - Improved the `latest_in_dir` function to clarify the handling of transcript naming schemes, ensuring proper differentiation between legacy and keyed formats. These changes streamline the testing process and improve the accuracy of tool scope validation, aligning with recent updates in agent functionality.
…ine inner loop - Removed the `persist_subagent_transcript` function, transitioning transcript persistence to occur per-iteration within the `run_inner_loop`, enhancing reliability by ensuring transcripts are written immediately after each provider response. - Updated the handling of session keys to maintain consistent naming for transcripts, reflecting the parent-child relationship in the file structure. - Simplified the code by eliminating redundant post-loop transcript writes, aligning with recent changes in agent functionality and improving overall clarity in transcript management.
📝 WalkthroughWalkthroughReplaces static per-agent prompt bodies with dynamic builders under src/openhuman/agent/prompts; removes system_prompt_cache_boundary in favor of session_key/session_parent_prefix for transcript naming; renames/retargets skills_agent → integrations_agent and adds tools_agent; removes env/web-search enable toggle and always-registers HTTP/web-search tools; many new per-agent prompt modules and CLI/script updates. Changes
Sequence Diagram(s)sequenceDiagram
participant Client as Client
participant Orchestrator as Orchestrator
participant Integrations as IntegrationsAgent
participant Tools as ToolsAgent
participant Composio as Composio
Client->>Orchestrator: Submit task
Orchestrator->>Orchestrator: Build system prompt (SystemPromptBuilder)
Orchestrator->>Orchestrator: Decide delegation
alt Needs external SaaS
Orchestrator->>Integrations: spawn_subagent(toolkit=...)
Integrations->>Integrations: Build prompt (dynamic, toolkit-scoped)
Integrations->>Composio: fetch_toolkit_actions(toolkit)
Composio-->>Integrations: actions list
Integrations->>Composio: execute action(s)
Composio-->>Integrations: action result
Integrations-->>Orchestrator: Action result
else Built-in-only
Orchestrator->>Tools: spawn_subagent
Tools->>Tools: Build prompt (dynamic, built-in tools)
Tools->>Tools: Execute built-in tool(s)
Tools-->>Orchestrator: Result
end
Orchestrator-->>Client: Final response
sequenceDiagram
participant AgentBuilder as Agent Builder
participant PromptBuilder as SystemPromptBuilder
participant PromptCtx as PromptContext
participant Sections as PromptSections
AgentBuilder->>PromptBuilder: select from PromptSource (Dynamic / Inline / File)
alt Dynamic
AgentBuilder->>PromptBuilder: from_dynamic(builder_fn)
PromptBuilder->>PromptCtx: gather workspace/tools/learned/connected_integrations
PromptBuilder->>Sections: render Archetype, UserFiles?, Tools, Safety, Workspace
Sections-->>PromptBuilder: rendered sections
PromptBuilder-->>AgentBuilder: final prompt string
else Inline/File
AgentBuilder->>PromptBuilder: from_final_body(text)
PromptBuilder-->>AgentBuilder: final prompt string
end
Estimated code review effort🎯 5 (Critical) | ⏱️ ~100 minutes Possibly related PRs
Suggested reviewers
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
…ty and formatting - Enhanced formatting in `agent_cli.rs` for better readability by adjusting the structure of string formatting. - Streamlined conditional checks in `subagent_runner.rs` to improve clarity and maintainability. - Simplified the handling of agent IDs in `builder.rs` to reduce line length and improve code flow. - Updated test cases in `tests.rs` for better alignment and readability of expected values. - Improved formatting in `debug_dump.rs` to enhance the clarity of toolkit action fetching and logging. These changes collectively enhance the overall readability and maintainability of the codebase, aligning with ongoing refactoring efforts.
There was a problem hiding this comment.
Actionable comments posted: 20
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (5)
src/openhuman/tools/orchestrator_tools.rs (1)
117-149:⚠️ Potential issue | 🟡 MinorUpdate the synthesized descriptions to
integrations_agenttoo.The routing docs/logs were renamed, but the tool descriptions the model sees still say "skills agent". That leaves prompt/schema text out of sync with the actual delegation target.
Diff
let description = if integration.description.trim().is_empty() { format!( - "Delegate to the skills agent with the `{}` integration pre-selected.", + "Delegate to the integrations agent with the `{}` integration pre-selected.", integration.toolkit ) } else { format!( - "Delegate to the skills agent using `{}`. {}", + "Delegate to the integrations agent using `{}`. {}", integration.toolkit, integration.description ) };🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/openhuman/tools/orchestrator_tools.rs` around lines 117 - 149, The tool descriptions still say "skills agent" but should reference "integrations_agent": update the two description formats inside the loop that builds SkillDelegationTool (where slug is produced by sanitise_slug(&integration.toolkit) and the SkillDelegationTool is constructed) to replace "Delegate to the skills agent" and "Delegate to the skills agent using" with "Delegate to the integrations_agent" (and adjust the surrounding wording if necessary) so tool_description reflects the actual delegation target used by integrations_agent; ensure both the empty-description fallback and the non-empty integration.description branch are changed, and keep the existing use of integration.toolkit and integration.description for context.src/openhuman/tools/impl/agent/spawn_subagent.rs (1)
209-284:⚠️ Potential issue | 🟠 MajorAdd branch-level diagnostics to the new
integrations_agenttoolkit gate.This changed control path has several user-facing failure modes but no debug/trace checkpoints, which makes triage difficult in production incidents.
🔍 Proposed logging additions
if definition.id == "integrations_agent" { let parent_ctx = current_parent(); + tracing::debug!( + agent_id = %definition.id, + requested_toolkit = ?toolkit_override, + parent_ctx_present = parent_ctx.is_some(), + "[spawn_subagent] validating integrations_agent toolkit gate" + ); let allowlist: Vec<&crate::openhuman::context::prompt::ConnectedIntegration> = parent_ctx .as_ref() @@ match toolkit_override.as_deref() { None => { + tracing::debug!( + connected_count = connected_slugs.len(), + "[spawn_subagent] toolkit missing for integrations_agent" + ); return Ok(ToolResult::error(format!( @@ None => { + tracing::debug!( + toolkit = %tk, + "[spawn_subagent] toolkit not present in allowlist" + ); return Ok(ToolResult::error(format!( @@ Some(ci) if !ci.connected => { + tracing::debug!( + toolkit = %tk, + "[spawn_subagent] toolkit present but not connected" + ); return Ok(ToolResult::success(format!( @@ Some(_) => { + tracing::debug!( + toolkit = %tk, + "[spawn_subagent] toolkit validated; proceeding to spawn" + ); // Connected — fall through to spawn. }As per coding guidelines:
src/**/*.rs: “Add substantial, development-oriented logs on new/changed flows; include logs at entry/exit points, branch decisions, external calls, retries/timeouts, state transitions, and error handling paths”.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/openhuman/tools/impl/agent/spawn_subagent.rs` around lines 209 - 284, Add development-oriented tracing around the integrations_agent gate in spawn_subagent: at the gate entry log definition.id and toolkit_override (use tracing::debug/trace), log the computed allowlist and connected_slugs, and then emit branch-level logs for each match arm — when toolkit_override is None (include connected_slugs), when toolkit not found in allowlist (log tk and the allowlist contents), when toolkit found but not connected (log ci.toolkit and ci.connected), and when toolkit is connected and you fall through to spawn (log the chosen toolkit and that you will proceed to spawn). Also add an exit/continuation trace just before the actual spawn call so production traces show the decision path end-to-end; use the same logging macro (trace/debug) and include unique symbols like definition.id, toolkit_override, tk, allowlist and connected_slugs to aid triage.src/openhuman/agent/harness/session/turn.rs (2)
602-628:⚠️ Potential issue | 🟠 MajorPersist again after tool results are appended.
The pre-tool flush protects the assistant reply, but a crash after
execute_tools()succeeds and before the next provider call still loses the tool-result messages. On resume, the transcript can replay the same tool calls without their prior results, which is dangerous for side-effecting tools.💾 Suggested follow-up
let formatted = self.tool_dispatcher.format_results(&results); self.history.push(formatted); + last_provider_messages = + Some(self.tool_dispatcher.to_provider_messages(&self.history)); + if let Some(ref messages) = last_provider_messages { + self.persist_session_transcript( + messages, + cumulative_input_tokens, + cumulative_output_tokens, + cumulative_cached_input_tokens, + cumulative_charged_usd, + last_turn_usage.as_ref(), + ); + } self.trim_history();🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/openhuman/agent/harness/session/turn.rs` around lines 602 - 628, After execute_tools returns and after extending all_tool_records and pushing the formatted tool results into history (the block that calls execute_tools(...), all_tool_records.extend(records), let formatted = self.tool_dispatcher.format_results(&results); self.history.push(formatted); self.trim_history()), immediately persist/flush the session state so the tool-result messages are saved before continuing (same mechanism used by the pre-tool flush). Ensure the flush happens after history.push and trim_history so a crash won't lose the appended tool-result entries.
1099-1111:⚠️ Potential issue | 🟠 MajorUse the session’s resolved config here, not a fresh
Config::load_or_init().Re-loading config at fetch time ignores the workspace/env/profile overrides that were already baked into this
Agent. That can populateconnected_integrationsandcomposio_clientfrom a different workspace/profile than the current session, anddebug_dumpnow exercises that mismatch directly.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/openhuman/agent/harness/session/turn.rs` around lines 1099 - 1111, The method fetch_connected_integrations is re-loading global config instead of using the session/agent's resolved config, which can cause workspace/profile mismatches; change it to use the session's resolved config field (e.g. self.config or self.resolved_config) instead of calling Config::load_or_init(), and pass that same config reference to crate::openhuman::composio::fetch_connected_integrations(...) and crate::openhuman::composio::build_composio_client(...), handling any Option/Result wrapper the session field uses so self.connected_integrations and self.composio_client are populated from the current session's config.src/openhuman/agent/harness/subagent_runner.rs (1)
1833-1880:⚠️ Potential issue | 🟠 MajorDon't drop to an empty body when a bundled prompt file should exist.
This loader only checks workspace overrides and then returns
String::new(). Any built-inPromptSource::Filesub-agent/debug-dump prompt shipped with the app loses its archetype body in packaged builds unless the workspace has copied that file first.As per coding guidelines, "Bundled AI prompts live under
src/openhuman/agent/prompts/at the repository root and are bundled viaapp/src-tauri/tauri.conf.jsonresources."🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/openhuman/agent/harness/subagent_runner.rs` around lines 1833 - 1880, The loader in load_prompt_source (handling PromptSource::File with variables workspace_dir and path) incorrectly gives up and returns an empty String when a built-in/bundled prompt isn’t present in the workspace; change the fallback logic to try loading the bundled prompt before returning empty: after checking workspace_dir.join("agent/prompts").join(path) and workspace_dir.join(path), attempt to read the app’s packaged resource/bundled prompts (the repository’s src/openhuman/agent/prompts/ files that are shipped via tauri resources) — e.g. resolve the runtime resources directory or an embedded assets map and call std::fs::read_to_string on that bundled path (or use an embedded lookup) and map errors into SubagentRunError::PromptLoad (same shape as the other read errors); only if that bundled lookup also fails should you warn and return Ok(String::new()).
🧹 Nitpick comments (6)
src/openhuman/tools/impl/agent/skill_delegation.rs (1)
58-63: Add a structured debug log before delegating tointegrations_agent.This changed dispatch path is an external call boundary and should emit a traceable log with stable fields.
🧭 Proposed logging addition
use async_trait::async_trait; use serde_json::json; +use tracing::debug; @@ - super::dispatch_subagent( + debug!( + tool = %self.tool_name, + skill_id = %self.skill_id, + target_agent = "integrations_agent", + "[agent_dispatch] delegating to sub-agent" + ); + super::dispatch_subagent( "integrations_agent", &self.tool_name, &prompt, Some(&self.skill_id), )As per coding guidelines "Add substantial, development-oriented logs on new/changed flows; include logs at ... external calls ... and use stable prefixes with correlation fields."
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/openhuman/tools/impl/agent/skill_delegation.rs` around lines 58 - 63, Add a structured trace/debug log immediately before calling super::dispatch_subagent in the code that delegates to "integrations_agent"; log stable fields such as tool_name (self.tool_name), skill_id (self.skill_id), agent ("integrations_agent"), and a correlation id (generate or pass-through if available), and include a short/hashed form of prompt rather than full content to avoid noise; ensure the log is emitted at trace/debug level and placed immediately before the super::dispatch_subagent(...) call so the external call boundary is observable in traces.src/openhuman/tools/impl/agent/dispatch.rs (1)
48-68: Rename the diagnostic field to match toolkit scoping.This path now applies
toolkit_override, but the entry log still reportsskill_filter. Keeping the old name makes delegation traces misleading when debugging why a Composio toolkit was selected. Renaming the arg/log label here would keep the new routing semantics observable end-to-end.Diff
pub(crate) async fn dispatch_subagent( agent_id: &str, tool_name: &str, prompt: &str, - skill_filter: Option<&str>, + toolkit_override: Option<&str>, ) -> anyhow::Result<ToolResult> { @@ log::info!( - "[agent] delegating to {} via {} (skill_filter={}) prompt_chars={}", + "[agent] delegating to {} via {} (toolkit_override={}) prompt_chars={}", agent_id, tool_name, - skill_filter.unwrap_or("<none>"), + toolkit_override.unwrap_or("<none>"), prompt.chars().count() ); @@ let options = SubagentRunOptions { skill_filter_override: None, - toolkit_override: skill_filter.map(str::to_string), + toolkit_override: toolkit_override.map(str::to_string), context: None, task_id: Some(task_id.clone()), };As per coding guidelines, "Add substantial, development-oriented logs on new/changed flows" and "Use structured, grep-friendly context in logs with stable prefixes".
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/openhuman/tools/impl/agent/dispatch.rs` around lines 48 - 68, The log message still labels the scope as "skill_filter" while the routing now uses SubagentRunOptions with toolkit_override (and skill_filter_override set to None); update the log::info call that references agent_id, tool_name, skill_filter.unwrap_or("<none>") and prompt.chars().count() to reflect the new routing semantics by renaming the diagnostic field to "toolkit_override" (or similar) and print the toolkit_override value (e.g., toolkit_override.map(|s| s.as_str()).unwrap_or("<none>")) so the trace matches the actual SubagentRunOptions setup and aids grep-friendly debugging.src/openhuman/agent/agents/code_executor/prompt.rs (1)
15-43: Consider centralizing the repeated prompt-section assembly pattern.
archivist,trigger_reactor, andcode_executornow share nearly identical section-glue logic. A shared helper (e.g., append-if-nonempty utilities) would reduce drift risk.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/openhuman/agent/agents/code_executor/prompt.rs` around lines 15 - 43, The build function repeats the same "append section if non-empty" pattern for ARCHETYPE, render_user_files, render_tools, render_safety, and render_workspace; extract that logic into a small helper (e.g., append_section or append_if_nonempty) that accepts the output String (or &mut String) and a section String + optional separator, then replace the repeated push_str/trim_end/conditional checks in build with calls to that helper and update archivist and trigger_reactor builds to use the same helper so the glue logic is centralized and consistent across agents.src/openhuman/agent/agents/summarizer/prompt.rs (2)
47-66: Strengthen the prompt builder test beyond non-empty output.
assert!(!body.is_empty())is too weak to catch section-order and delimiter regressions. Consider asserting presence/absence of at least one rendered section boundary.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/openhuman/agent/agents/summarizer/prompt.rs` around lines 47 - 66, The test build_returns_nonempty_body currently only asserts that build(&ctx) returns a non-empty string; strengthen it by asserting the presence of at least one expected section boundary or delimiter produced by the prompt builder (e.g., look for strings used as section separators in build such as "---", "###", or specific headings). Update the test to call build(&ctx).unwrap() and assert that the returned body.contains("<expected delimiter or heading>") and optionally assert that body does not contain any unexpected delimiter (to detect regressions), referencing the build function and PromptContext used in the test.
15-39: Extract shared prompt assembly to avoid cross-agent drift.This
buildbody is duplicated across multiple agent prompt modules. A single shared helper would reduce maintenance mistakes when section ordering/spacing changes.♻️ Proposed refactor sketch
- pub fn build(ctx: &PromptContext<'_>) -> Result<String> { - let mut out = String::with_capacity(4096); - out.push_str(ARCHETYPE.trim_end()); - out.push_str("\n\n"); - ... - Ok(out) - } + pub fn build(ctx: &PromptContext<'_>) -> Result<String> { + crate::openhuman::context::prompt::build_standard_prompt(ARCHETYPE, ctx) + }// e.g. in src/openhuman/context/prompt.rs pub fn build_standard_prompt(archetype: &str, ctx: &PromptContext<'_>) -> Result<String> { /* existing shared logic */ }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/openhuman/agent/agents/summarizer/prompt.rs` around lines 15 - 39, The build function duplicates prompt-assembly logic across agents; extract the shared sequence into a single helper (e.g., build_standard_prompt) that accepts archetype string and &PromptContext<'_>, then replace this module's build to call that helper with ARCHETYPE and ctx; move the common logic that appends ARCHETYPE, render_user_files, render_tools, and render_workspace (including their trim/end spacing rules) into the new function so render_user_files, render_tools, render_workspace, ARCHETYPE, and PromptContext are reused rather than reimplemented in each agent.src/openhuman/agent/agents/tools_agent/prompt.rs (1)
67-67: Consider making the"Tools Agent"assertion less copy-sensitive.This is a brittle invariant for prompt wording changes; asserting structural blocks/sections is usually more stable.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/openhuman/agent/agents/tools_agent/prompt.rs` at line 67, The test currently asserts the exact substring assert!(body.contains("Tools Agent")), which is brittle; change it to assert the presence of the Tools section more structurally by inspecting the body variable for a section header or loose match instead of exact copy — e.g., assert that body contains a "Tools" section header (like a heading marker followed by "Tools") or that both tokens "tools" and "agent" appear (or use a case-insensitive regex search for the words "tools" and "agent") so minor wording or punctuation changes won't break the test.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@app/src/lib/ai/skillsAgentContext.ts`:
- Line 1: Update the source-of-truth path comment at the top of
skillsAgentContext.ts so it points to the bundled prompt location under
src/openhuman/agent/prompts/ (e.g. change
"src/openhuman/agent/agents/integrations_agent/prompt.md" to
"src/openhuman/agent/prompts/integrations_agent/prompt.md") to match the
app-side prompt bundling conventions and avoid drift.
In `@scripts/debug-agent-prompts.sh`:
- Around line 28-38: The usage banner and help text still present --with-tools
as an active option but the script's dump-all path ignores it; update the top
usage block and any other help text to mark --with-tools as "deprecated / no-op"
(or "backwards-compatible no-op") and add a short note that dump-all ignores it,
so the help is not misleading. Search for the literal "--with-tools" and the
dump-all branch (references to dump-all and any WITH_TOOLS or with_tools
variables) and change wording to indicate deprecation/no-op consistently across
the script (usage header, option parsing help, and the dump-all comment).
In `@src/core/agent_cli.rs`:
- Around line 8-10: The top-level usage banner and help list are missing the new
"dump-all" subcommand; update the module docstring/banner at the top of
src/core/agent_cli.rs to include a usage line for "dump-all" and modify the
print_agent_help() function to add "dump-all" to the printed subcommand list
(matching the style/flags used for "dump-prompt" and "list") so the new entry
point is discoverable from openhuman agent --help.
- Around line 125-129: The formatting in the loop that constructs the filename
stem around sanitise_filename_component, dumped.agent_id, and dumped.toolkit is
not rustfmt-compliant; run cargo fmt to reformat the file
(src/core/agent_cli.rs) and ensure the block around the for loop (the iterator
over dumps, the match on dumped.toolkit, and the stem assignment) and the
similar block at lines 519-523 are properly aligned and wrapped according to
rustfmt rules so CI stops failing.
- Around line 266-279: run_dump_prompt currently allows --agent
integrations_agent to proceed without a toolkit, causing invalid downstream
behavior; add a preflight validation in run_dump_prompt that checks if agent ==
"integrations_agent" and returns an error (e.g. anyhow!("--toolkit is required
for integrations_agent")) when flags.toolkit.is_none(); perform the same
validation in the analogous code path referenced (lines ~506-509) where
DumpPromptOptions (or the spawn/dump variant) is constructed so any attempt to
build DumpPromptOptions without a toolkit for integrations_agent fails early.
In `@src/openhuman/agent/agents/integrations_agent/prompt.rs`:
- Around line 77-91: The loop that builds the XML-like block writes raw skill
metadata into out using writeln! (see the for skill in skills { ...
writeln!(out, ... skill.name, skill.description, location.display()) } block),
which allows characters like '<' and '&' to break the structure; fix by escaping
XML entities for skill.name, skill.description, and the computed location string
(from location.display()) before interpolating them into the template (implement
or call a small helper like escape_xml and use it when formatting those three
fields).
In `@src/openhuman/agent/agents/welcome/prompt.rs`:
- Around line 61-63: The loop writing markdown bullets may break if ci.toolkit
or ci.description contain newlines; sanitize both before writing by normalizing
whitespace and newlines to single spaces and trimming surrounding whitespace so
the bullet stays on one line. Locate the for ci in connected { let _ =
writeln!(out, "- **{}** — {}", ci.toolkit, ci.description); } block and replace
the direct fields with cleaned versions (e.g., toolkit_clean and
description_clean) that replace '\n'/'\r' with ' ', collapse repeated spaces,
and trim, then write those cleaned values to out.
In `@src/openhuman/agent/harness/payload_summarizer.rs`:
- Around line 50-52: Update the module-level documentation in
payload_summarizer.rs: replace the incorrect word "Welcome" with "Meanwhile" in
the sentence describing which agents receive None (the sentence that begins with
`Welcome, integrations_agent, researcher, planner, archivist...`) so the scope
description reads correctly; locate the doc comment block near the top of the
file (the comment that references `agent_id == "orchestrator"`) and make the
single-word substitution in that sentence.
In `@src/openhuman/agent/harness/session/builder.rs`:
- Around line 660-698: The File branch currently returns an empty prompt when
the workspace override is missing; change it to first try the workspace_path,
and if not present or unreadable then attempt to load the bundled prompt from
the repository resources (the packaged files under
src/openhuman/agent/prompts/<path> that are included via the app resources)
before falling back to an empty string; update the prompt construction in the
PromptSource::File arm so SystemPromptBuilder::for_subagent receives the
workspace file content when present, otherwise the bundled resource content (and
only if both fail use empty and log a warning). Ensure you reference
PromptSource::File, workspace_dir/workspace_path, body_text, and
SystemPromptBuilder::for_subagent when making the change.
In `@src/openhuman/agent/harness/session/tests.rs`:
- Around line 204-210: The array literal in the test function
agent_builder_threads_agent_definition_name_when_set is misformatted; run
rustfmt (cargo fmt) to reformat the test (specifically the for expected in [...]
array) so the elements conform to project style (each element/commas spacing as
rustfmt enforces) and then commit the formatted result.
In `@src/openhuman/agent/harness/subagent_runner.rs`:
- Around line 803-831: child_session_key and transcript_stem can collide when
two identical sub-agents are spawned within the same second; update the
child_session_key construction (the block that currently builds
child_session_key and the transcript_stem that uses it) to include a per-run
nonce (e.g. task_id or a generated UUID/nano timestamp) so each spawn is unique.
Concretely: append or interpolate a stable per-run identifier (prefer
parent.task_id if available, otherwise generate a Uuid::new_v4() or include
SystemTime::now().duration_since(UNIX_EPOCH).as_nanos()) into child_session_key
before building transcript_stem so format!("{unix_ts}_{sanitized}_{nonce}") (or
similar) is used instead of just "{unix_ts}_{sanitized}".
- Around line 571-585: The PromptContext is being constructed with an
empty_visible set which causes visible_tool_names to be empty and re-enables
wildcard prompt sections; instead build and pass the actual allowlist derived
from prompt_tools into PromptContext.visible_tool_names. Replace the
empty_visible reference with a HashSet of the tool names from prompt_tools
(e.g., collect the keys or map each tool to its name and collect into a HashSet)
so PromptContext receives the real filtered visible_tool_names; update places
that reference empty_visible (in subagent_runner.rs around the PromptContext
construction) to use that derived set.
In `@src/openhuman/agent/prompts/mod.rs`:
- Around line 1319-1348: The test function
render_subagent_system_prompt_honors_identity_safety_and_skills_flags contains a
stale assertion expecting the "## Available Skills" block even though
render_subagent_system_prompt_with_format no longer emits it; remove the
assert!(rendered.contains("## Available Skills")); line (or replace it with an
assertion that matches the current expected output) so the test matches the new
renderer behavior, leaving the other assertions for "## Project Context", "###
SOUL.md", and "## Safety" intact.
- Around line 928-957: The Err(_) arm in the std::fs::read_to_string(&path)
match currently swallows all errors; change it to match the error kind and only
silence std::io::ErrorKind::NotFound, while logging other failures at
debug/trace level (include the path/filename and the error). Concretely, replace
Err(_) with Err(e) => { if e.kind() == std::io::ErrorKind::NotFound { /* keep
silent */ } else { log::debug!("reading prompt file '{}': {}", path.display(),
e); } } so callers of the read logic (the block that writes into prompt and
references filename, path, max_chars) get diagnostics for permission/encoding
issues. Ensure log crate is imported/used consistently with the project logging
level.
- Around line 367-379: The schema key iteration in
render_pformat_signature_for_box_tool and the sibling helper (the function
starting at line 386) collects property names from a serde_json::Map without
sorting, which can violate the documented alphabetical ordering; after building
the Vec<String> of keys in each function (the local variable names), call
names.sort_unstable() before checking emptiness and formatting the signature so
the generated "name[a|b|c]" output is deterministic and alphabetical.
In `@src/openhuman/agent/triage/evaluator.rs`:
- Around line 313-315: Update the docstring that currently claims both
`Inline`/`File` are handled to accurately describe the implemented behavior:
only `PromptSource::Inline` and `PromptSource::Dynamic` are handled by this
function (remove or correct mention of `PromptSource::File`). Locate the doc
comment above the function that processes `PromptSource` (references to
`PromptSource::Dynamic`, `PromptSource::Inline`, and `PromptSource::File` appear
in the comment) and revise the text to state that built-ins use
`PromptSource::Dynamic` and custom TOML use `Inline`, and that `File` is not
handled here.
- Around line 323-347: The match arm for PromptSource::Dynamic currently
swallows errors from build(&ctx) and returns None; instead preserve the error
signal by logging or propagating it: replace the blanket `_ => None` handling
for build(&ctx) with logic that on Err(e) records the error (e.g., use
tracing::error!, log::error!, or eprintln! with the error and context including
def.id and that PromptSource::Dynamic failed) and then return None (or, if the
surrounding function can return a Result, propagate the error upward); update
the PromptSource::Dynamic block around build, PromptContext, and the match on
build(&ctx) so errors are not silently dropped but are surfaced via logging or
proper error propagation.
In `@src/openhuman/config/schema/load.rs`:
- Around line 631-634: The legacy env var OPENHUMAN_WEB_SEARCH_ENABLED is
currently ignored; update the config-load path that unregisters/always-registers
web-search (the code block in load.rs where web-search is unconditionally
registered) to detect if OPENHUMAN_WEB_SEARCH_ENABLED is set and emit a
warning-level log (including the env var name and its value) stating the legacy
flag is deprecated and no longer prevents web-search registration; also add a
regression test that sets OPENHUMAN_WEB_SEARCH_ENABLED=0 in the test
environment, runs the config load path, and asserts the warning log was emitted
to ensure operators see the deprecation notice.
In `@src/openhuman/context/debug_dump.rs`:
- Around line 248-385: render_integrations_agent currently returns build(&ctx)
directly so the dumped prompt lacks the runtime "text-mode tool protocol"
mutation that the live sub-agent runner appends; fix it by applying the same
system-prompt mutation the runner uses before returning the prompt: locate the
runner code that mutates the integrations_agent system prompt (the code that
appends the XML/tool-list instructions), extract or reuse that logic as a
helper, and invoke it here after let text = build(&ctx) ... to produce the final
text-mode prompt (references: function render_integrations_agent, variable build
(PromptSource::Dynamic), ctx, and the final build(&ctx) call).
In `@src/openhuman/tools/impl/agent/complete_onboarding.rs`:
- Around line 421-422: The embedded JSON example in the tool description is out
of sync with the new always-on flags emitted by build_status_snapshot(): update
the sample so integrations.web_search and integrations.http_request are both
true (replace the `"http_request": false` entry with `"http_request": true` and
ensure `"web_search": true` remains present) so the welcome agent’s contract
matches build_status_snapshot() output; locate the sample JSON in the tool
description near the code that references build_status_snapshot() and update the
example strings accordingly.
---
Outside diff comments:
In `@src/openhuman/agent/harness/session/turn.rs`:
- Around line 602-628: After execute_tools returns and after extending
all_tool_records and pushing the formatted tool results into history (the block
that calls execute_tools(...), all_tool_records.extend(records), let formatted =
self.tool_dispatcher.format_results(&results); self.history.push(formatted);
self.trim_history()), immediately persist/flush the session state so the
tool-result messages are saved before continuing (same mechanism used by the
pre-tool flush). Ensure the flush happens after history.push and trim_history so
a crash won't lose the appended tool-result entries.
- Around line 1099-1111: The method fetch_connected_integrations is re-loading
global config instead of using the session/agent's resolved config, which can
cause workspace/profile mismatches; change it to use the session's resolved
config field (e.g. self.config or self.resolved_config) instead of calling
Config::load_or_init(), and pass that same config reference to
crate::openhuman::composio::fetch_connected_integrations(...) and
crate::openhuman::composio::build_composio_client(...), handling any
Option/Result wrapper the session field uses so self.connected_integrations and
self.composio_client are populated from the current session's config.
In `@src/openhuman/agent/harness/subagent_runner.rs`:
- Around line 1833-1880: The loader in load_prompt_source (handling
PromptSource::File with variables workspace_dir and path) incorrectly gives up
and returns an empty String when a built-in/bundled prompt isn’t present in the
workspace; change the fallback logic to try loading the bundled prompt before
returning empty: after checking workspace_dir.join("agent/prompts").join(path)
and workspace_dir.join(path), attempt to read the app’s packaged
resource/bundled prompts (the repository’s src/openhuman/agent/prompts/ files
that are shipped via tauri resources) — e.g. resolve the runtime resources
directory or an embedded assets map and call std::fs::read_to_string on that
bundled path (or use an embedded lookup) and map errors into
SubagentRunError::PromptLoad (same shape as the other read errors); only if that
bundled lookup also fails should you warn and return Ok(String::new()).
In `@src/openhuman/tools/impl/agent/spawn_subagent.rs`:
- Around line 209-284: Add development-oriented tracing around the
integrations_agent gate in spawn_subagent: at the gate entry log definition.id
and toolkit_override (use tracing::debug/trace), log the computed allowlist and
connected_slugs, and then emit branch-level logs for each match arm — when
toolkit_override is None (include connected_slugs), when toolkit not found in
allowlist (log tk and the allowlist contents), when toolkit found but not
connected (log ci.toolkit and ci.connected), and when toolkit is connected and
you fall through to spawn (log the chosen toolkit and that you will proceed to
spawn). Also add an exit/continuation trace just before the actual spawn call so
production traces show the decision path end-to-end; use the same logging macro
(trace/debug) and include unique symbols like definition.id, toolkit_override,
tk, allowlist and connected_slugs to aid triage.
In `@src/openhuman/tools/orchestrator_tools.rs`:
- Around line 117-149: The tool descriptions still say "skills agent" but should
reference "integrations_agent": update the two description formats inside the
loop that builds SkillDelegationTool (where slug is produced by
sanitise_slug(&integration.toolkit) and the SkillDelegationTool is constructed)
to replace "Delegate to the skills agent" and "Delegate to the skills agent
using" with "Delegate to the integrations_agent" (and adjust the surrounding
wording if necessary) so tool_description reflects the actual delegation target
used by integrations_agent; ensure both the empty-description fallback and the
non-empty integration.description branch are changed, and keep the existing use
of integration.toolkit and integration.description for context.
---
Nitpick comments:
In `@src/openhuman/agent/agents/code_executor/prompt.rs`:
- Around line 15-43: The build function repeats the same "append section if
non-empty" pattern for ARCHETYPE, render_user_files, render_tools,
render_safety, and render_workspace; extract that logic into a small helper
(e.g., append_section or append_if_nonempty) that accepts the output String (or
&mut String) and a section String + optional separator, then replace the
repeated push_str/trim_end/conditional checks in build with calls to that helper
and update archivist and trigger_reactor builds to use the same helper so the
glue logic is centralized and consistent across agents.
In `@src/openhuman/agent/agents/summarizer/prompt.rs`:
- Around line 47-66: The test build_returns_nonempty_body currently only asserts
that build(&ctx) returns a non-empty string; strengthen it by asserting the
presence of at least one expected section boundary or delimiter produced by the
prompt builder (e.g., look for strings used as section separators in build such
as "---", "###", or specific headings). Update the test to call
build(&ctx).unwrap() and assert that the returned body.contains("<expected
delimiter or heading>") and optionally assert that body does not contain any
unexpected delimiter (to detect regressions), referencing the build function and
PromptContext used in the test.
- Around line 15-39: The build function duplicates prompt-assembly logic across
agents; extract the shared sequence into a single helper (e.g.,
build_standard_prompt) that accepts archetype string and &PromptContext<'_>,
then replace this module's build to call that helper with ARCHETYPE and ctx;
move the common logic that appends ARCHETYPE, render_user_files, render_tools,
and render_workspace (including their trim/end spacing rules) into the new
function so render_user_files, render_tools, render_workspace, ARCHETYPE, and
PromptContext are reused rather than reimplemented in each agent.
In `@src/openhuman/agent/agents/tools_agent/prompt.rs`:
- Line 67: The test currently asserts the exact substring
assert!(body.contains("Tools Agent")), which is brittle; change it to assert the
presence of the Tools section more structurally by inspecting the body variable
for a section header or loose match instead of exact copy — e.g., assert that
body contains a "Tools" section header (like a heading marker followed by
"Tools") or that both tokens "tools" and "agent" appear (or use a
case-insensitive regex search for the words "tools" and "agent") so minor
wording or punctuation changes won't break the test.
In `@src/openhuman/tools/impl/agent/dispatch.rs`:
- Around line 48-68: The log message still labels the scope as "skill_filter"
while the routing now uses SubagentRunOptions with toolkit_override (and
skill_filter_override set to None); update the log::info call that references
agent_id, tool_name, skill_filter.unwrap_or("<none>") and prompt.chars().count()
to reflect the new routing semantics by renaming the diagnostic field to
"toolkit_override" (or similar) and print the toolkit_override value (e.g.,
toolkit_override.map(|s| s.as_str()).unwrap_or("<none>")) so the trace matches
the actual SubagentRunOptions setup and aids grep-friendly debugging.
In `@src/openhuman/tools/impl/agent/skill_delegation.rs`:
- Around line 58-63: Add a structured trace/debug log immediately before calling
super::dispatch_subagent in the code that delegates to "integrations_agent"; log
stable fields such as tool_name (self.tool_name), skill_id (self.skill_id),
agent ("integrations_agent"), and a correlation id (generate or pass-through if
available), and include a short/hashed form of prompt rather than full content
to avoid noise; ensure the log is emitted at trace/debug level and placed
immediately before the super::dispatch_subagent(...) call so the external call
boundary is observable in traces.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 8ec86604-ef16-4185-bff8-367cf8a8fef7
📒 Files selected for processing (86)
.env.exampleapp/src/lib/ai/skillsAgentContext.tsscripts/debug-agent-prompts.shsrc/core/agent_cli.rssrc/core/cli.rssrc/openhuman/agent/agents/archivist/mod.rssrc/openhuman/agent/agents/archivist/prompt.rssrc/openhuman/agent/agents/code_executor/mod.rssrc/openhuman/agent/agents/code_executor/prompt.rssrc/openhuman/agent/agents/critic/mod.rssrc/openhuman/agent/agents/critic/prompt.rssrc/openhuman/agent/agents/integrations_agent/agent.tomlsrc/openhuman/agent/agents/integrations_agent/mod.rssrc/openhuman/agent/agents/integrations_agent/prompt.mdsrc/openhuman/agent/agents/integrations_agent/prompt.rssrc/openhuman/agent/agents/loader.rssrc/openhuman/agent/agents/mod.rssrc/openhuman/agent/agents/morning_briefing/agent.tomlsrc/openhuman/agent/agents/morning_briefing/mod.rssrc/openhuman/agent/agents/morning_briefing/prompt.rssrc/openhuman/agent/agents/orchestrator/agent.tomlsrc/openhuman/agent/agents/orchestrator/mod.rssrc/openhuman/agent/agents/orchestrator/prompt.rssrc/openhuman/agent/agents/planner/agent.tomlsrc/openhuman/agent/agents/planner/mod.rssrc/openhuman/agent/agents/planner/prompt.mdsrc/openhuman/agent/agents/planner/prompt.rssrc/openhuman/agent/agents/researcher/mod.rssrc/openhuman/agent/agents/researcher/prompt.rssrc/openhuman/agent/agents/skills_agent/agent.tomlsrc/openhuman/agent/agents/skills_agent/prompt.mdsrc/openhuman/agent/agents/summarizer/mod.rssrc/openhuman/agent/agents/summarizer/prompt.rssrc/openhuman/agent/agents/tool_maker/mod.rssrc/openhuman/agent/agents/tool_maker/prompt.rssrc/openhuman/agent/agents/tools_agent/agent.tomlsrc/openhuman/agent/agents/tools_agent/mod.rssrc/openhuman/agent/agents/tools_agent/prompt.mdsrc/openhuman/agent/agents/tools_agent/prompt.rssrc/openhuman/agent/agents/trigger_reactor/mod.rssrc/openhuman/agent/agents/trigger_reactor/prompt.rssrc/openhuman/agent/agents/trigger_triage/mod.rssrc/openhuman/agent/agents/trigger_triage/prompt.rssrc/openhuman/agent/agents/welcome/mod.rssrc/openhuman/agent/agents/welcome/prompt.rssrc/openhuman/agent/harness/archivist.rssrc/openhuman/agent/harness/builtin_definitions.rssrc/openhuman/agent/harness/definition.rssrc/openhuman/agent/harness/fork_context.rssrc/openhuman/agent/harness/payload_summarizer.rssrc/openhuman/agent/harness/session/builder.rssrc/openhuman/agent/harness/session/runtime.rssrc/openhuman/agent/harness/session/tests.rssrc/openhuman/agent/harness/session/transcript.rssrc/openhuman/agent/harness/session/turn.rssrc/openhuman/agent/harness/session/types.rssrc/openhuman/agent/harness/subagent_runner.rssrc/openhuman/agent/harness/tool_filter.rssrc/openhuman/agent/harness/tool_loop.rssrc/openhuman/agent/mod.rssrc/openhuman/agent/prompts/mod.rssrc/openhuman/agent/prompts/types.rssrc/openhuman/agent/triage/escalation.rssrc/openhuman/agent/triage/evaluator.rssrc/openhuman/channels/runtime/dispatch.rssrc/openhuman/channels/runtime/startup.rssrc/openhuman/composio/action_tool.rssrc/openhuman/composio/mod.rssrc/openhuman/composio/ops.rssrc/openhuman/composio/tools.rssrc/openhuman/config/schema/load.rssrc/openhuman/config/schema/tools.rssrc/openhuman/config/schema/types.rssrc/openhuman/context/debug_dump.rssrc/openhuman/context/manager.rssrc/openhuman/context/mod.rssrc/openhuman/context/prompt.rssrc/openhuman/providers/reliable.rssrc/openhuman/providers/traits.rssrc/openhuman/tools/impl/agent/complete_onboarding.rssrc/openhuman/tools/impl/agent/dispatch.rssrc/openhuman/tools/impl/agent/skill_delegation.rssrc/openhuman/tools/impl/agent/spawn_subagent.rssrc/openhuman/tools/ops.rssrc/openhuman/tools/orchestrator_tools.rstests/agent_harness_public.rs
💤 Files with no reviewable changes (7)
- src/openhuman/agent/agents/morning_briefing/agent.toml
- src/openhuman/agent/harness/tool_loop.rs
- tests/agent_harness_public.rs
- src/openhuman/providers/reliable.rs
- src/openhuman/agent/agents/skills_agent/agent.toml
- src/openhuman/agent/agents/skills_agent/prompt.md
- src/openhuman/config/schema/tools.rs
| @@ -1,4 +1,4 @@ | |||
| // Source of truth: src/openhuman/agent/agents/skills_agent/prompt.md | |||
| // Source of truth: src/openhuman/agent/agents/integrations_agent/prompt.md | |||
There was a problem hiding this comment.
Source-of-truth path likely points to the wrong prompt location.
This comment now points to src/openhuman/agent/agents/integrations_agent/prompt.md, but prompt bundling conventions for this repo place bundled prompts under src/openhuman/agent/prompts/. Please update the path to the actual bundled prompt file to avoid future drift.
Based on learnings: Bundled AI prompts live under src/openhuman/agent/prompts/ (and are loaded via the app-side prompt loading pipeline).
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@app/src/lib/ai/skillsAgentContext.ts` at line 1, Update the source-of-truth
path comment at the top of skillsAgentContext.ts so it points to the bundled
prompt location under src/openhuman/agent/prompts/ (e.g. change
"src/openhuman/agent/agents/integrations_agent/prompt.md" to
"src/openhuman/agent/prompts/integrations_agent/prompt.md") to match the
app-side prompt bundling conventions and avoid drift.
| fn run_dump_prompt(args: &[String]) -> Result<()> { | ||
| let flags = parse_dump_flags(args)?; | ||
| let agent = flags | ||
| .agent | ||
| .clone() | ||
| .ok_or_else(|| anyhow!("--agent <id> is required (use `main` for the orchestrator)"))?; | ||
| let agent = flags.agent.clone().ok_or_else(|| { | ||
| anyhow!("--agent <id> is required (e.g. `orchestrator`, `integrations_agent`, `welcome`)") | ||
| })?; | ||
|
|
||
| init_quiet_logging(flags.verbose); | ||
|
|
||
| let options = DumpPromptOptions { | ||
| agent_id: agent, | ||
| skill_filter: flags.skill.clone(), | ||
| toolkit: flags.toolkit.clone(), | ||
| workspace_dir_override: flags.workspace.clone(), | ||
| model_override: flags.model.clone(), | ||
| stub_composio: flags.stub_composio, | ||
| }; |
There was a problem hiding this comment.
Reject dump-prompt --agent integrations_agent without --toolkit.
The help text says --toolkit is required for integrations_agent, but run_dump_prompt() currently forwards None. That leaves users with a downstream error path, or worse, a dump that doesn't correspond to any real sub-agent spawn.
Suggested fix
fn run_dump_prompt(args: &[String]) -> Result<()> {
let flags = parse_dump_flags(args)?;
let agent = flags.agent.clone().ok_or_else(|| {
anyhow!("--agent <id> is required (e.g. `orchestrator`, `integrations_agent`, `welcome`)")
})?;
+ if agent == "integrations_agent" && flags.toolkit.is_none() {
+ return Err(anyhow!(
+ "--toolkit <slug> is required when --agent integrations_agent"
+ ));
+ }
init_quiet_logging(flags.verbose);Also applies to: 506-509
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/core/agent_cli.rs` around lines 266 - 279, run_dump_prompt currently
allows --agent integrations_agent to proceed without a toolkit, causing invalid
downstream behavior; add a preflight validation in run_dump_prompt that checks
if agent == "integrations_agent" and returns an error (e.g. anyhow!("--toolkit
is required for integrations_agent")) when flags.toolkit.is_none(); perform the
same validation in the analogous code path referenced (lines ~506-509) where
DumpPromptOptions (or the spawn/dump variant) is constructed so any attempt to
build DumpPromptOptions without a toolkit for integrations_agent fails early.
| // `OPENHUMAN_WEB_SEARCH_ENABLED` is intentionally ignored — | ||
| // web search is unconditionally registered in the tool set. | ||
| // Only the provider / API-key / budget knobs remain | ||
| // environment-configurable. |
There was a problem hiding this comment.
Don't silently ignore the legacy web-search disable flag.
If an existing deployment still sets OPENHUMAN_WEB_SEARCH_ENABLED=0, this change now enables web-search tooling without any signal. At minimum, warn when either legacy env var is present so operators can see that the old control no longer works, and add a regression test for that path.
Diff
- // `OPENHUMAN_WEB_SEARCH_ENABLED` is intentionally ignored —
- // web search is unconditionally registered in the tool set.
- // Only the provider / API-key / budget knobs remain
- // environment-configurable.
+ if let Ok(raw) = std::env::var("OPENHUMAN_WEB_SEARCH_ENABLED")
+ .or_else(|_| std::env::var("WEB_SEARCH_ENABLED"))
+ {
+ tracing::warn!(
+ value = %raw,
+ "[config] OPENHUMAN_WEB_SEARCH_ENABLED is deprecated and ignored; web search is always enabled"
+ );
+ }As per coding guidelines, "Add substantial, development-oriented logs on new/changed flows" and "New or changed behavior must ship with matching documentation".
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| // `OPENHUMAN_WEB_SEARCH_ENABLED` is intentionally ignored — | |
| // web search is unconditionally registered in the tool set. | |
| // Only the provider / API-key / budget knobs remain | |
| // environment-configurable. | |
| if let Ok(raw) = std::env::var("OPENHUMAN_WEB_SEARCH_ENABLED") | |
| .or_else(|_| std::env::var("WEB_SEARCH_ENABLED")) | |
| { | |
| tracing::warn!( | |
| value = %raw, | |
| "[config] OPENHUMAN_WEB_SEARCH_ENABLED is deprecated and ignored; web search is always enabled" | |
| ); | |
| } |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/openhuman/config/schema/load.rs` around lines 631 - 634, The legacy env
var OPENHUMAN_WEB_SEARCH_ENABLED is currently ignored; update the config-load
path that unregisters/always-registers web-search (the code block in load.rs
where web-search is unconditionally registered) to detect if
OPENHUMAN_WEB_SEARCH_ENABLED is set and emit a warning-level log (including the
env var name and its value) stating the legacy flag is deprecated and no longer
prevents web-search registration; also add a regression test that sets
OPENHUMAN_WEB_SEARCH_ENABLED=0 in the test environment, runs the config load
path, and asserts the warning log was emitted to ensure operators see the
deprecation notice.
There was a problem hiding this comment.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
src/openhuman/agent/harness/subagent_runner.rs (1)
1846-1882:⚠️ Potential issue | 🟠 Major
PromptSource::Filestill drops bundled prompts when the workspace override is absent.This branch falls straight to
String::new()unless the file exists in the workspace, so file-backed built-in sub-agents boot with an empty archetype body outside a dev workspace. It needs the same bundled-resource fallback as the rest of the prompt pipeline. Based on learnings, bundled AI prompts live undersrc/openhuman/agent/prompts/at the repository root and are bundled viaapp/src-tauri/tauri.conf.jsonresources.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/openhuman/agent/harness/subagent_runner.rs` around lines 1846 - 1882, PromptSource::File currently returns an empty string whenever the requested path isn't found in the workspace; change the branch so after checking workspace_path and workspace_root_path it attempts the bundled-resource fallback used elsewhere: try to load the prompt from the built-in prompts bundled under src/openhuman/agent/prompts/ (the same resource path the binary ships via the IdentitySection/tauri resources), e.g. resolve the bundled filename (basename of path) and read it from the embedded resources (or include_str!-equivalent location) and return that content (mapping any io error to SubagentRunError::PromptLoad with path and source), and only if the bundled resource is also missing then warn and return Ok(String::new()); keep references to PromptSource::File, workspace_dir/workspace_path/workspace_root_path and SubagentRunError::PromptLoad to locate where to add the fallback.
♻️ Duplicate comments (6)
src/openhuman/agent/harness/subagent_runner.rs (2)
572-586:⚠️ Potential issue | 🟠 MajorPass the filtered allowlist into
PromptContext.
prompt_toolsare already narrowed here, butvisible_tool_namesis still an empty set. Dynamic prompt sections treat that as “no filter active”, so this sub-agent can render broader tool-driven sections than the runner actually allows.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/openhuman/agent/harness/subagent_runner.rs` around lines 572 - 586, The PromptContext is being created with visible_tool_names set to an always-empty empty_visible, which bypasses the actual filtered tools; instead, construct a HashSet<String> of the allowed tool names from prompt_tools (e.g., iterate prompt_tools and collect each tool.name.clone() or equivalent identifier) and pass a reference to that set into PromptContext.visible_tool_names (replace empty_visible with the new visible set) so the prompt rendering honors the runner's tool allowlist; ensure the visible set variable lives long enough for the PromptContext borrow.
804-832:⚠️ Potential issue | 🟠 MajorMake the child transcript key collision-proof.
{unix_ts}_{agent_id}still collides when the same parent spawns two identical sub-agents within one second, so those runs can write into the same JSONL. Foldtask_idor another per-run nonce intochild_session_key.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/openhuman/agent/harness/subagent_runner.rs` around lines 804 - 832, The child transcript key generation (child_session_key) currently uses only unix_ts and agent_id which can collide if two identical sub-agents spawn within the same second; update child_session_key to include a per-run nonce (e.g., task_id or a generated UUID/nonce) so each run is unique: locate the block computing child_session_key and transcript_stem (symbols child_session_key, transcript_stem, agent_id, parent.session_key, parent.session_parent_prefix) and append or incorporate a stable per-run identifier (task_id if available on parent or generate a short random/UUID nonce) into the formatted string so the final key becomes unix_ts_agentid_nonce and prevents JSONL collisions.src/openhuman/agent/harness/session/builder.rs (1)
666-693:⚠️ Potential issue | 🟠 MajorDon't fall back to an empty body for bundled prompt files.
If the workspace override is absent, this path silently builds the agent with an empty prompt body instead of loading the packaged prompt resource. That strips persona/instructions for any file-backed built-in agent outside a dev workspace. Based on learnings, bundled AI prompts live under
src/openhuman/agent/prompts/at the repository root and are bundled viaapp/src-tauri/tauri.conf.jsonresources.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/openhuman/agent/harness/session/builder.rs` around lines 666 - 693, Currently PromptSource::File branch reads only workspace_dir overrides and falls back to an empty body; change it to try loading the bundled resource when workspace_path doesn't exist or fails to read: after computing workspace_path (using config.workspace_dir.join("agent").join("prompts").join(path)), if workspace file missing or read_to_string returns Err, attempt to load the packaged prompt resource from the repo bundle (the runtime resources path that maps to src/openhuman/agent/prompts/ via the tauri resources config) and only if that also fails then log a warning and use an empty body; ensure SystemPromptBuilder::for_subagent still receives the resolved body_text and preserve existing flags (def.omit_identity, def.omit_safety_preamble, def.omit_skills_catalog).src/core/agent_cli.rs (2)
271-284:⚠️ Potential issue | 🟡 MinorReject
integrations_agentdumps without--toolkit.Help text says
--toolkitis required, but this path still forwardsNoneand relies on a later error fromdump_agent_prompt(). Fail fast here so the CLI error matches the documented contract.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/core/agent_cli.rs` around lines 271 - 284, In run_dump_prompt, enforce the documented contract by rejecting calls for the "integrations_agent" agent when no toolkit is provided: after obtaining flags and agent (in run_dump_prompt) add a check that if agent == "integrations_agent" && flags.toolkit.is_none() you return an Err(anyhow!(...)) explaining "--toolkit is required for integrations_agent" (or similar). This fails fast before creating DumpPromptOptions and calling dump_agent_prompt, keeping parse_dump_flags, DumpPromptOptions, and dump_agent_prompt unchanged.
8-10:⚠️ Potential issue | 🟡 MinorAdvertise
dump-allin the top-level help.The subcommand is wired up, but the module banner and
print_agent_help()still only showlistanddump-prompt, soopenhuman agent --helphides the new entry point.Also applies to: 490-497
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/core/agent_cli.rs` around lines 8 - 10, Update the top-level usage banner and the help text generation to advertise the new "dump-all" subcommand: add a usage line for "openhuman agent dump-all [--workspace <path>] [--json] [-v]" to the module-level docstring/usage block in src/core/agent_cli.rs and modify the print_agent_help() function to include "dump-all" (with the same flag descriptions as dump-prompt/dump) in the list of subcommands so that "openhuman agent --help" shows the new entry point; ensure you mirror the formatting and flags used by the existing "dump-prompt" and "list" entries.src/openhuman/context/debug_dump.rs (1)
348-380:⚠️ Potential issue | 🟠 Major
integrations_agentdumps still miss the runtime XML tool protocol.The live runner appends the text-mode tool instructions before the first provider call when
integrations_agentcarries toolkit tools. This path returnsbuild(&ctx)directly, so the exported dump is still not the bytes the model actually sees on that text-mode path.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/openhuman/context/debug_dump.rs` around lines 348 - 380, The dump currently returns build(&ctx) directly so it omits the runtime XML tool protocol that the live runner prepends for integrations_agent with toolkit tools; after computing text = build(&ctx) (and before returning), detect when prompt_tools contains toolkit/integration tools (use prompt_tools and narrow_integrations) and append the same runtime XML tool protocol bytes/string the live runner inserts before the first provider call (reuse the existing helper used by the runner if one exists, or implement a small function to render the XML protocol and concat it to text), then return that combined string so the exported dump matches the actual model input.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/openhuman/agent/harness/session/builder.rs`:
- Around line 382-399: The session_key generation in the session builder (the
session_key block that uses SystemTime and agent_definition_name) only uses
seconds so concurrent starts can collide; fix it by appending a per-run
nonce/UUID to the formatted key (e.g. call uuid::Uuid::new_v4().to_string() or
another cryptographically random nonce) so the final session_key becomes
"{unix_ts}_{sanitized}_{uuid}". Ensure you add the uuid call next to the
existing formatted components (using the same sanitized agent id and unix_ts)
and import/handle the uuid generation where session_key is constructed.
---
Outside diff comments:
In `@src/openhuman/agent/harness/subagent_runner.rs`:
- Around line 1846-1882: PromptSource::File currently returns an empty string
whenever the requested path isn't found in the workspace; change the branch so
after checking workspace_path and workspace_root_path it attempts the
bundled-resource fallback used elsewhere: try to load the prompt from the
built-in prompts bundled under src/openhuman/agent/prompts/ (the same resource
path the binary ships via the IdentitySection/tauri resources), e.g. resolve the
bundled filename (basename of path) and read it from the embedded resources (or
include_str!-equivalent location) and return that content (mapping any io error
to SubagentRunError::PromptLoad with path and source), and only if the bundled
resource is also missing then warn and return Ok(String::new()); keep references
to PromptSource::File, workspace_dir/workspace_path/workspace_root_path and
SubagentRunError::PromptLoad to locate where to add the fallback.
---
Duplicate comments:
In `@src/core/agent_cli.rs`:
- Around line 271-284: In run_dump_prompt, enforce the documented contract by
rejecting calls for the "integrations_agent" agent when no toolkit is provided:
after obtaining flags and agent (in run_dump_prompt) add a check that if agent
== "integrations_agent" && flags.toolkit.is_none() you return an
Err(anyhow!(...)) explaining "--toolkit is required for integrations_agent" (or
similar). This fails fast before creating DumpPromptOptions and calling
dump_agent_prompt, keeping parse_dump_flags, DumpPromptOptions, and
dump_agent_prompt unchanged.
- Around line 8-10: Update the top-level usage banner and the help text
generation to advertise the new "dump-all" subcommand: add a usage line for
"openhuman agent dump-all [--workspace <path>] [--json] [-v]" to the
module-level docstring/usage block in src/core/agent_cli.rs and modify the
print_agent_help() function to include "dump-all" (with the same flag
descriptions as dump-prompt/dump) in the list of subcommands so that "openhuman
agent --help" shows the new entry point; ensure you mirror the formatting and
flags used by the existing "dump-prompt" and "list" entries.
In `@src/openhuman/agent/harness/session/builder.rs`:
- Around line 666-693: Currently PromptSource::File branch reads only
workspace_dir overrides and falls back to an empty body; change it to try
loading the bundled resource when workspace_path doesn't exist or fails to read:
after computing workspace_path (using
config.workspace_dir.join("agent").join("prompts").join(path)), if workspace
file missing or read_to_string returns Err, attempt to load the packaged prompt
resource from the repo bundle (the runtime resources path that maps to
src/openhuman/agent/prompts/ via the tauri resources config) and only if that
also fails then log a warning and use an empty body; ensure
SystemPromptBuilder::for_subagent still receives the resolved body_text and
preserve existing flags (def.omit_identity, def.omit_safety_preamble,
def.omit_skills_catalog).
In `@src/openhuman/agent/harness/subagent_runner.rs`:
- Around line 572-586: The PromptContext is being created with
visible_tool_names set to an always-empty empty_visible, which bypasses the
actual filtered tools; instead, construct a HashSet<String> of the allowed tool
names from prompt_tools (e.g., iterate prompt_tools and collect each
tool.name.clone() or equivalent identifier) and pass a reference to that set
into PromptContext.visible_tool_names (replace empty_visible with the new
visible set) so the prompt rendering honors the runner's tool allowlist; ensure
the visible set variable lives long enough for the PromptContext borrow.
- Around line 804-832: The child transcript key generation (child_session_key)
currently uses only unix_ts and agent_id which can collide if two identical
sub-agents spawn within the same second; update child_session_key to include a
per-run nonce (e.g., task_id or a generated UUID/nonce) so each run is unique:
locate the block computing child_session_key and transcript_stem (symbols
child_session_key, transcript_stem, agent_id, parent.session_key,
parent.session_parent_prefix) and append or incorporate a stable per-run
identifier (task_id if available on parent or generate a short random/UUID
nonce) into the formatted string so the final key becomes unix_ts_agentid_nonce
and prevents JSONL collisions.
In `@src/openhuman/context/debug_dump.rs`:
- Around line 348-380: The dump currently returns build(&ctx) directly so it
omits the runtime XML tool protocol that the live runner prepends for
integrations_agent with toolkit tools; after computing text = build(&ctx) (and
before returning), detect when prompt_tools contains toolkit/integration tools
(use prompt_tools and narrow_integrations) and append the same runtime XML tool
protocol bytes/string the live runner inserts before the first provider call
(reuse the existing helper used by the runner if one exists, or implement a
small function to render the XML protocol and concat it to text), then return
that combined string so the exported dump matches the actual model input.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: e5aa1c00-a297-4480-afa8-f65349d3b142
📒 Files selected for processing (6)
src/core/agent_cli.rssrc/openhuman/agent/harness/session/builder.rssrc/openhuman/agent/harness/session/tests.rssrc/openhuman/agent/harness/subagent_runner.rssrc/openhuman/context/debug_dump.rstests/agent_harness_public.rs
🚧 Files skipped from review as they are similar to previous changes (2)
- tests/agent_harness_public.rs
- src/openhuman/agent/harness/session/tests.rs
| session_key: { | ||
| let unix_ts = std::time::SystemTime::now() | ||
| .duration_since(std::time::UNIX_EPOCH) | ||
| .map(|d| d.as_secs()) | ||
| .unwrap_or(0); | ||
| let agent_id = self.agent_definition_name.as_deref().unwrap_or("main"); | ||
| let sanitized: String = agent_id | ||
| .chars() | ||
| .map(|c| { | ||
| if c.is_ascii_alphanumeric() || c == '_' || c == '-' { | ||
| c | ||
| } else { | ||
| '_' | ||
| } | ||
| }) | ||
| .collect(); | ||
| format!("{unix_ts}_{sanitized}") | ||
| }, |
There was a problem hiding this comment.
Root session keys are still only second-resolution.
Sessions started for the same agent within one second get the same session_key, which then collides in the keyed transcript hierarchy just like the child-session case. Please add a per-run nonce or UUID here as well.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/openhuman/agent/harness/session/builder.rs` around lines 382 - 399, The
session_key generation in the session builder (the session_key block that uses
SystemTime and agent_definition_name) only uses seconds so concurrent starts can
collide; fix it by appending a per-run nonce/UUID to the formatted key (e.g.
call uuid::Uuid::new_v4().to_string() or another cryptographically random nonce)
so the final session_key becomes "{unix_ts}_{sanitized}_{uuid}". Ensure you add
the uuid call next to the existing formatted components (using the same
sanitized agent id and unix_ts) and import/handle the uuid generation where
session_key is constructed.
There was a problem hiding this comment.
Actionable comments posted: 5
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
src/openhuman/agent/harness/subagent_runner.rs (1)
1041-1171:⚠️ Potential issue | 🟠 MajorPersist again after appending tool results.
This now writes the transcript before tool execution, but not after the
role=tool/[Tool results]messages are pushed. If the process dies between tool completion and the next provider response, the last iteration on disk is missing the actual tool outputs, which defeats the new per-iteration persistence goal.📝 Minimal follow-up
if force_text_mode && !text_mode_result_block.is_empty() { history.push(ChatMessage::user(format!( "[Tool results]\n{text_mode_result_block}" ))); } + + persist_transcript(history, &usage); }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/openhuman/agent/harness/subagent_runner.rs` around lines 1041 - 1171, The transcript is persisted before executing tools but not after appending the tool outputs, so add a second call to persist_transcript(history, &usage) right after the native_calls handling where tool results are pushed into history (i.e., after the loop that builds text_mode_result_block and after the branches that push ChatMessage::tool and ChatMessage::user entries), ensuring both the force_text_mode path (text_mode_result_block -> ChatMessage::user) and the non-text path (history.push(ChatMessage::tool(...))) are flushed to disk.src/openhuman/tools/impl/agent/spawn_subagent.rs (1)
111-117:⚠️ Potential issue | 🟡 MinorFix the stale connected-toolkit hint.
This message still points to
composio list_connection, but the PR renamed that surface tocomposio_list_connections. As written, the recovery path tells the caller to use the wrong name.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/openhuman/tools/impl/agent/spawn_subagent.rs` around lines 111 - 117, The connected-toolkit hint message still references the old command name "composio list_connection"; locate the string literal in spawn_subagent.rs (the connected-toolkit / schema description or recovery hint) that mentions "composio list_connection" and update it to the new command name "composio_list_connections" so the recovery guidance matches the renamed surface.
♻️ Duplicate comments (1)
src/openhuman/agent/prompts/mod.rs (1)
367-378:⚠️ Potential issue | 🟠 MajorSort schema keys before formatting
name[a|b|c].These helpers still depend on map iteration order even though the tool-use contract above says the signature is alphabetical by parameter name. If
serde_jsonis built withpreserve_order, the rendered order can drift and the model will be told to pass positional args in the wrong order. This looks like the same unresolved issue that was raised earlier on this file.Verification
#!/bin/bash rg -n --glob 'Cargo.toml' 'serde_json|preserve_order' rg -n -C2 'alphabetical by parameter name|render_pformat_signature_for_(box_tool|prompt)|keys\(\)\.cloned\(\)\.collect' src/openhuman/agent/prompts/mod.rsAlso applies to: 386-401
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/openhuman/agent/prompts/mod.rs` around lines 367 - 378, The function render_pformat_signature_for_box_tool collects parameter names from tool.parameters_schema() into names but relies on map iteration order; collect the keys into a Vec, sort them alphabetically (e.g., names.sort()) before formatting so the signature is deterministic (name[a|b|c]); apply the same change to the analogous helper(s) around lines 386-401 that build parameter name lists from a schema to ensure all rendered signatures are alphabetically ordered.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/core/agent_cli.rs`:
- Around line 111-175: run_dump_all lacks development-oriented logs around its
async calls and file writes; add namespaced debug!/trace! entries at function
entry and exit in run_dump_all (and similarly in run_dump_prompt), log before
calling dump_all_agent_prompts/dump_agent_prompt and immediately after their
awaited results (include workspace/model/toolkit info), and log outcomes of each
file write and any error branches (use debug! for high-level and trace! for
detailed payloads like dumped.agent_id, stem, prompt_path, meta_path,
tool_counts); use the existing logging initialization (init_quiet_logging) so
these debug/trace statements are visible when verbose, and ensure messages
reference the functions dump_all_agent_prompts, dump_agent_prompt, run_dump_all,
and run_dump_prompt for easy traceability.
- Around line 9-20: Update the top-level module banner/docs so the `dump-prompt`
usage reflects the conditional toolkit requirement: add `[--toolkit <slug>]` (or
a short parenthetical “required for integrations_agent”) to the `openhuman agent
dump-prompt` help line and add one sentence clarifying that `run_dump_prompt()`
will require `--toolkit` when `--agent integrations_agent`; also update
AGENTS.md/feature docs to mirror this behavior. Locate the banner/doc comment at
the top of src/core/agent_cli.rs (references: `dump-prompt`, `run_dump_prompt`,
`integrations_agent`) and make the cosmetic/doc change so CLI help and docs
match actual runtime requirements.
In `@src/openhuman/agent/harness/subagent_runner.rs`:
- Around line 577-584: The PromptContext is being created with an empty
dispatcher_instructions which causes PromptSource::Dynamic flows (which rely on
render_tools(ctx) reading ctx.dispatcher_instructions) to lose JSON/P-Format
call protocol; populate PromptContext.dispatcher_instructions with the same
system/dispatcher instructions used for inline/file prompts (e.g., the output of
render_subagent_system_prompt or the parent/definition dispatcher text) so
dynamic sub-agents receive the correct call protocol; update the PromptContext
construction in subagent_runner.rs to pass that rendered dispatcher instructions
string instead of "".
In `@src/openhuman/agent/prompts/mod.rs`:
- Around line 877-895: The code unconditionally overwrites the on-disk workspace
file when the builtin hash changes, potentially erasing user edits; change the
logic to read the current file contents (std::fs::read_to_string(&path)) and
compare that content to stored_hash (the previously recorded builtin hash)
before writing: only write default_content and update hash_path when the file
either doesn't exist or its contents equal stored_hash (meaning it hasn't been
locally modified); if the file exists and its contents differ from stored_hash,
do not overwrite—log a warning/info that the file diverged and skip writing.
Ensure you still create parent with create_dir_all when writing and keep using
variables current_hash, stored_hash, path, hash_path, and default_content.
In `@src/openhuman/context/debug_dump.rs`:
- Around line 274-287: The dump path currently unconditionally replaces
integration.tools with the result of
crate::openhuman::composio::fetch_toolkit_actions, which can be empty or error
and differs from the runner behavior in run_typed_mode that preserves
cached_integration.tools on empty/error; change the logic so you attempt
fetch_toolkit_actions(&composio_client, &integration.toolkit).await, and only
assign integration.tools = fetched_tools when the call succeeds and returns a
non-empty list—otherwise leave integration.tools as the existing
cached_integration.tools (or fall back to it on error), mirroring
run_typed_mode's cached-catalog fallback.
---
Outside diff comments:
In `@src/openhuman/agent/harness/subagent_runner.rs`:
- Around line 1041-1171: The transcript is persisted before executing tools but
not after appending the tool outputs, so add a second call to
persist_transcript(history, &usage) right after the native_calls handling where
tool results are pushed into history (i.e., after the loop that builds
text_mode_result_block and after the branches that push ChatMessage::tool and
ChatMessage::user entries), ensuring both the force_text_mode path
(text_mode_result_block -> ChatMessage::user) and the non-text path
(history.push(ChatMessage::tool(...))) are flushed to disk.
In `@src/openhuman/tools/impl/agent/spawn_subagent.rs`:
- Around line 111-117: The connected-toolkit hint message still references the
old command name "composio list_connection"; locate the string literal in
spawn_subagent.rs (the connected-toolkit / schema description or recovery hint)
that mentions "composio list_connection" and update it to the new command name
"composio_list_connections" so the recovery guidance matches the renamed
surface.
---
Duplicate comments:
In `@src/openhuman/agent/prompts/mod.rs`:
- Around line 367-378: The function render_pformat_signature_for_box_tool
collects parameter names from tool.parameters_schema() into names but relies on
map iteration order; collect the keys into a Vec, sort them alphabetically
(e.g., names.sort()) before formatting so the signature is deterministic
(name[a|b|c]); apply the same change to the analogous helper(s) around lines
386-401 that build parameter name lists from a schema to ensure all rendered
signatures are alphabetically ordered.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: f223283a-9c0e-4972-95d4-6ee8bc769608
📒 Files selected for processing (13)
scripts/debug-agent-prompts.shsrc/core/agent_cli.rssrc/openhuman/agent/agents/integrations_agent/prompt.rssrc/openhuman/agent/agents/welcome/prompt.rssrc/openhuman/agent/harness/session/turn.rssrc/openhuman/agent/harness/subagent_runner.rssrc/openhuman/agent/prompts/mod.rssrc/openhuman/agent/triage/evaluator.rssrc/openhuman/config/schema/load.rssrc/openhuman/context/debug_dump.rssrc/openhuman/tools/impl/agent/complete_onboarding.rssrc/openhuman/tools/impl/agent/spawn_subagent.rssrc/openhuman/tools/orchestrator_tools.rs
✅ Files skipped from review due to trivial changes (1)
- src/openhuman/config/schema/load.rs
🚧 Files skipped from review as they are similar to previous changes (6)
- src/openhuman/tools/impl/agent/complete_onboarding.rs
- src/openhuman/agent/agents/welcome/prompt.rs
- src/openhuman/agent/triage/evaluator.rs
- src/openhuman/agent/agents/integrations_agent/prompt.rs
- src/openhuman/agent/harness/session/turn.rs
- src/openhuman/tools/orchestrator_tools.rs
…ce-file preservation, cached-tool fallback, transcript persistence - subagent_runner: populate PromptContext.dispatcher_instructions for Dynamic prompts (was empty string, dropping the ## Tool Use Protocol block in render_tools for PFormat/Json/Native sub-agents) - subagent_runner: add post-tool persist_transcript after tool results are appended so a mid-round crash doesn't lose tool outputs - prompts::sync_workspace_file: preserve user-edited workspace files — only overwrite when the file doesn't exist OR its current hash matches the stored builtin hash - context::debug_dump: mirror runner's cached-tool fallback — keep cached action catalogue on empty/error from fetch_toolkit_actions instead of blanking it - core::agent_cli: add entry/exit debug logs around dump_all / dump_prompt calls and a trace log around each prompt file write; update module banner to note --toolkit is required when --agent is integrations_agent
There was a problem hiding this comment.
♻️ Duplicate comments (1)
src/openhuman/agent/prompts/mod.rs (1)
367-402: 🛠️ Refactor suggestion | 🟠 MajorSort schema keys before generating
name[a|b|c]signatures.The documentation at line 790 promises "Arguments are positional — match the order shown in each tool's
Call as:signature above (alphabetical by parameter name)." However, bothrender_pformat_signature_for_box_tool(lines 367–379) andrender_pformat_signature_for_prompt(lines 386–402) iterate overserde_json::Mapwithout explicit sorting.While
serde_jsonusesBTreeMapby default (which iterates alphabetically), this relies on an implementation detail that can change if thepreserve_orderfeature is enabled elsewhere. Explicitly sorting ensures the contract holds regardless of feature flags.♻️ Proposed fix
fn render_pformat_signature_for_box_tool(tool: &dyn crate::openhuman::tools::Tool) -> String { let schema = tool.parameters_schema(); - let names: Vec<String> = schema + let mut names: Vec<String> = schema .get("properties") .and_then(|p| p.as_object()) .map(|m| m.keys().cloned().collect()) .unwrap_or_default(); + names.sort_unstable(); if names.is_empty() { format!("{}[]", tool.name()) } else { format!("{}[{}]", tool.name(), names.join("|")) } } fn render_pformat_signature_for_prompt(tool: &PromptTool<'_>) -> String { - let names: Vec<String> = tool + let mut names: Vec<String> = tool .parameters_schema .as_deref() .and_then(|s| serde_json::from_str::<serde_json::Value>(s).ok()) .and_then(|v| { v.get("properties") .and_then(|p| p.as_object()) .map(|m| m.keys().cloned().collect()) }) .unwrap_or_default(); + names.sort_unstable(); if names.is_empty() { format!("{}[]", tool.name) } else { format!("{}[{}]", tool.name, names.join("|")) } }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/openhuman/agent/prompts/mod.rs` around lines 367 - 402, Both render_pformat_signature_for_box_tool and render_pformat_signature_for_prompt currently collect property names from a JSON object and rely on iteration order; change each to explicitly sort the collected names before formatting the signature (e.g., collect keys into names Vec<String>, call names.sort_unstable() or names.sort(), then use names.join("|")). Locate the key-collection logic in render_pformat_signature_for_box_tool (where schema.get("properties")...map(|m| m.keys().cloned().collect())) and in render_pformat_signature_for_prompt (the block that parses parameters_schema and maps to keys), and insert a sort step on the Vec<String> before the is_empty check/formatting.
🧹 Nitpick comments (3)
src/openhuman/agent/prompts/mod.rs (1)
896-907: Consider logging read errors in user-modification check.When determining if the user has modified a workspace file, read errors (e.g., permission issues) are silently treated as "user modified", which is the safe fallback. However, per coding guidelines, error handling paths should include diagnostic logs.
🪵 Suggested improvement
let user_unmodified = if file_exists { match std::fs::read_to_string(&path) { Ok(disk) => { let mut hasher = std::collections::hash_map::DefaultHasher::new(); disk.hash(&mut hasher); let disk_hash = format!("{:016x}", hasher.finish()); disk_hash == stored_hash } - Err(_) => false, + Err(e) => { + log::debug!( + "[agent:prompt] could not read {filename} to check modification status: {e}" + ); + false + } } } else { false };As per coding guidelines, "Add substantial, development-oriented logs on new/changed flows" and "include logs at ... error handling paths."
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/openhuman/agent/prompts/mod.rs` around lines 896 - 907, The read error branch of the std::fs::read_to_string(&path) match currently swallows errors—update the Err(_) arm to log the failure (include path and the error) before returning false so diagnostics exist when permission/IO issues occur; target the match around std::fs::read_to_string(&path) that computes disk_hash and compares to stored_hash, use the existing logging facility (or log/tracing) to emit a development-oriented message referencing path and the error, then preserve the current fallback return value.src/openhuman/context/debug_dump.rs (1)
362-374: The error message for non-Dynamic prompt source is slightly confusing.When
PromptSource::Dynamic(_)matches, the error message would print"Dynamic", but this branch is unreachable. The match arm labeling is correct but the debug output in the error is redundant since it can only beInlineorFile.🔧 Cleaner error message
_ => { return Err(anyhow!( - "integrations_agent must use PromptSource::Dynamic; got {:?}", - match &definition.system_prompt { - PromptSource::Inline(_) => "Inline", - PromptSource::File { .. } => "File", - PromptSource::Dynamic(_) => "Dynamic", - } + "integrations_agent must use PromptSource::Dynamic; got {}", + match &definition.system_prompt { + PromptSource::Inline(_) => "Inline", + PromptSource::File { .. } => "File", + PromptSource::Dynamic(_) => unreachable!(), + } )); }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/openhuman/context/debug_dump.rs` around lines 362 - 374, The error message in the match for definition.system_prompt includes "Dynamic" even though that branch is unreachable; update the error construction in the non-Dynamic arm so it only reports the actual possible variants (PromptSource::Inline or PromptSource::File) or simply formats the prompt source directly (e.g., format!("{:?}", definition.system_prompt)) to avoid the redundant "Dynamic" case. Locate the match around PromptSource::Dynamic(...) that returns Err(anyhow!(...)) and replace the inner match that maps to "Inline"/"File"/"Dynamic" with either a two-arm match for PromptSource::Inline and PromptSource::File or a Debug formatting of definition.system_prompt to produce a clearer error message.src/core/agent_cli.rs (1)
540-541: Consider adding[--toolkit <slug>]to the dump-prompt summary line.The top-level help shows
dump-prompt --agent <id> [--workspace <path>] ...but omits--toolkit, making it less discoverable thatintegrations_agentrequires it. The detailed help (lines 557-560) documents it well, but a brief mention in the summary would help.🔧 Suggested change
- println!(" openhuman agent dump-prompt --agent <id> [--workspace <path>] [--model <name>] [--with-tools] [--json] [-v]"); + println!(" openhuman agent dump-prompt --agent <id> [--toolkit <slug>] [--workspace <path>] [--model <name>] [--with-tools] [--json] [-v]");🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/core/agent_cli.rs` around lines 540 - 541, The summary help lines in agent_cli.rs (the two println calls that print the usage for "openhuman agent dump-prompt" and "openhuman agent dump-all") omit the optional --toolkit flag, making the requirement for integrations_agent non-discoverable; update the first usage string printed for "dump-prompt" to include " [--toolkit <slug>]" (and add to any other summary usage that should mention toolkit) so the short help matches the detailed help and flags documented later (look for the println! invocations that output "openhuman agent dump-prompt --agent <id> ..." and update that literal to include the toolkit option).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Duplicate comments:
In `@src/openhuman/agent/prompts/mod.rs`:
- Around line 367-402: Both render_pformat_signature_for_box_tool and
render_pformat_signature_for_prompt currently collect property names from a JSON
object and rely on iteration order; change each to explicitly sort the collected
names before formatting the signature (e.g., collect keys into names
Vec<String>, call names.sort_unstable() or names.sort(), then use
names.join("|")). Locate the key-collection logic in
render_pformat_signature_for_box_tool (where schema.get("properties")...map(|m|
m.keys().cloned().collect())) and in render_pformat_signature_for_prompt (the
block that parses parameters_schema and maps to keys), and insert a sort step on
the Vec<String> before the is_empty check/formatting.
---
Nitpick comments:
In `@src/core/agent_cli.rs`:
- Around line 540-541: The summary help lines in agent_cli.rs (the two println
calls that print the usage for "openhuman agent dump-prompt" and "openhuman
agent dump-all") omit the optional --toolkit flag, making the requirement for
integrations_agent non-discoverable; update the first usage string printed for
"dump-prompt" to include " [--toolkit <slug>]" (and add to any other summary
usage that should mention toolkit) so the short help matches the detailed help
and flags documented later (look for the println! invocations that output
"openhuman agent dump-prompt --agent <id> ..." and update that literal to
include the toolkit option).
In `@src/openhuman/agent/prompts/mod.rs`:
- Around line 896-907: The read error branch of the
std::fs::read_to_string(&path) match currently swallows errors—update the Err(_)
arm to log the failure (include path and the error) before returning false so
diagnostics exist when permission/IO issues occur; target the match around
std::fs::read_to_string(&path) that computes disk_hash and compares to
stored_hash, use the existing logging facility (or log/tracing) to emit a
development-oriented message referencing path and the error, then preserve the
current fallback return value.
In `@src/openhuman/context/debug_dump.rs`:
- Around line 362-374: The error message in the match for
definition.system_prompt includes "Dynamic" even though that branch is
unreachable; update the error construction in the non-Dynamic arm so it only
reports the actual possible variants (PromptSource::Inline or
PromptSource::File) or simply formats the prompt source directly (e.g.,
format!("{:?}", definition.system_prompt)) to avoid the redundant "Dynamic"
case. Locate the match around PromptSource::Dynamic(...) that returns
Err(anyhow!(...)) and replace the inner match that maps to
"Inline"/"File"/"Dynamic" with either a two-arm match for PromptSource::Inline
and PromptSource::File or a Debug formatting of definition.system_prompt to
produce a clearer error message.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 27d0c32f-5d70-47dd-a59a-690f68c0d84a
📒 Files selected for processing (4)
src/core/agent_cli.rssrc/openhuman/agent/harness/subagent_runner.rssrc/openhuman/agent/prompts/mod.rssrc/openhuman/context/debug_dump.rs
…ssion plumbing (tinyhumansai#642) * refactor(transcript): update session transcript paths and enhance directory structure - Changed the source of truth path for session transcripts from `sessions/{DDMMYYYY}/{agent}_{index}.jsonl` to `session_raw/{DDMMYYYY}/{agent}_{index}.jsonl` to better reflect the organization of files. - Updated the logic for creating and resolving transcript paths to accommodate the new directory structure, ensuring compatibility with legacy `.md` files. - Improved documentation to clarify the changes in file organization and their implications for transcript management. This refactor enhances the clarity and maintainability of session transcript handling by establishing a more logical file structure. * refactor(prompts): update tool handling in prompt builders - Replaced `Vec<String>` with `Vec<ToolSummary<'_>>` for available tools in multiple agent prompt builders, enhancing type safety and clarity. - Introduced `render_tool_catalog` and `render_connected_integrations` functions to dynamically generate sections in prompts based on available tools and connected integrations. - Updated the `build` function in various agent prompts to utilize the new rendering functions, ensuring that prompts accurately reflect the current context and available resources. These changes improve the maintainability and functionality of the prompt generation process across different agents. * refactor(prompts): streamline prompt builders for agent templates - Updated the prompt builders for various agents to utilize the sibling `prompt.md` template directly, enhancing clarity and maintainability. - Replaced `Vec<ToolSummary<'_>>` with `Vec<ToolSummary>` and `Vec<ConnectedIntegration>` for improved type safety in test cases. - Adjusted the `build` function to ensure consistent formatting and handling of tool catalogs across different agents. These changes simplify the prompt generation process and prepare the codebase for future enhancements. * refactor(harness): unify tool filtering and prompt loading for debug consistency - Exposed `filter_tool_indices` and `load_prompt_source` as `pub(crate)` to ensure that both the live runner and debug dump share the same filtering and loading logic, eliminating discrepancies. - Enhanced documentation for both functions to clarify their purpose and usage, improving maintainability and understanding of the codebase. These changes streamline the tool management process and enhance the reliability of debug outputs, ensuring consistency across different contexts. * refactor(prompts): enhance prompt builders for agent templates - Updated the prompt builders for various agents to return fully-assembled system prompts, incorporating section helpers from `crate::openhuman::context::prompt`. - Replaced `Vec<ToolSummary<'_>>` with `Vec<ToolSummary>` and `Vec<ConnectedIntegration>` for improved type safety in test cases. - Adjusted the `build` function to ensure consistent formatting and handling of user files, tools, and workspace sections across different agents. These changes streamline the prompt generation process, improve maintainability, and prepare the codebase for future enhancements. * refactor(prompts): enhance prompt context handling for dynamic sources - Updated the prompt builders to support fully-assembled prompts from dynamic sources, allowing for more flexible prompt generation. - Introduced `PromptTool` and `PromptContext` structures to replace `ToolSummary`, improving type safety and clarity in prompt construction. - Refactored the handling of prompt sources in both the subagent runner and session builder to streamline the integration of dynamic prompts and legacy sources. These changes improve the maintainability and functionality of the prompt generation process, ensuring accurate representation of available tools and context in agent interactions. * refactor(prompts): improve prompt context and tool handling - Enhanced the `PromptContext` structure to include additional fields for better context management, such as `skills`, `dispatcher_instructions`, and `tool_call_format`. - Replaced `ToolSummary` with `PromptTool` for improved type safety and clarity in prompt generation. - Updated the handling of dynamic prompt sources in both the subagent runner and debug dump, ensuring consistent integration and rendering of prompts. - Introduced a mechanism to handle empty visible tool names, enhancing the robustness of prompt generation. These changes streamline the prompt construction process and improve the overall maintainability of the codebase. * refactor(prompts): reorganize prompt handling and introduce SystemPromptBuilder - Moved prompt-related types and builders from `openhuman::context::prompt` to `openhuman::agent::prompts` for better modularity. - Introduced `SystemPromptBuilder` to streamline the construction of system prompts, allowing for flexible section management. - Updated module exports to maintain compatibility while enhancing the organization of prompt-related code. These changes improve the clarity and maintainability of the prompt generation process, aligning it more closely with the agents that utilize these prompts. * refactor(prompts): unify agent prompt handling and update CLI references - Removed the "main" alias for the orchestrator in the prompt dumping process, treating it as just another registered agent. - Updated the `debug-agent-prompts.sh` script to reflect this change, ensuring all agents are included uniformly. - Revised documentation and error messages in `agent_cli.rs` to replace references to "main" with "orchestrator" for clarity. - Enhanced the debug dump functionality to maintain consistency across agent prompts, improving overall maintainability and usability. These changes streamline the prompt handling process and clarify the usage of agent identifiers in the CLI, aligning with the new architecture. * refactor(prompts): remove CACHE_BOUNDARY references from agent prompts - Eliminated the CACHE_BOUNDARY marker from various agent prompt files, streamlining the prompt generation process. - Updated the build functions in multiple agents to ensure consistent handling of workspace rendering without the cache boundary. - Refactored related prompt handling logic to enhance clarity and maintainability, aligning with the new architecture. These changes simplify the prompt structure and improve the overall efficiency of prompt generation across agents. * refactor(prompts): remove cache boundary references from tests and prompts - Eliminated all instances of cache boundary references from the subagent runner and related tests, simplifying the prompt handling logic. - Updated test assertions to reflect the removal of cache boundary checks, ensuring consistency across the testing framework. - Refactored the session manager to streamline the system prompt assembly process without relying on cache boundaries. These changes enhance the clarity and maintainability of the prompt generation process, aligning with the recent architectural updates. * refactor(harness): clean up unused imports and streamline code - Removed unnecessary imports from multiple files, including `RandomState`, `Hasher`, and `SerializeMap`, to enhance code clarity and maintainability. - Simplified the structure of several modules by eliminating redundant use statements, ensuring a cleaner and more efficient codebase. These changes contribute to a more organized and readable code structure, aligning with ongoing refactoring efforts. * refactor(prompts): enhance agent prompt structures and integration handling - Updated the `orchestrator`, `skills_agent`, and `welcome` prompts to streamline the rendering of connected integrations and delegation guides. - Introduced dedicated functions for rendering integration information, ensuring clarity in the agent's voice and responsibilities. - Removed redundant sections from the shared prompt builder, allowing each agent to manage its own prompt content more effectively. - Improved test coverage for prompt generation, ensuring accurate representation of connected integrations and skills. These changes enhance the maintainability and clarity of the prompt generation process, aligning with the recent architectural updates. * refactor(session): update integration handling and clean up prompt parameters - Revised documentation for `connected_integrations` in the `Agent` struct to clarify its role in the agent's prompt rendering. - Updated the parameter name in `render_subagent_system_prompt_with_format` to `_connected_integrations` to indicate it is unused, enhancing code clarity. - Cleaned up import statements in the context module for better organization and maintainability. These changes improve the clarity of integration handling and streamline the code structure, aligning with ongoing refactoring efforts. * refactor(agent_cli): simplify command options and improve documentation - Removed the `--skill` option from the `dump-prompt` command, streamlining the command usage and focusing on essential parameters. - Updated documentation to clarify the usage of the `dump-prompt` command and its parameters, enhancing user understanding. - Cleaned up the `DumpFlags` structure by removing unused fields, contributing to a more maintainable codebase. These changes improve the clarity and usability of the agent CLI, aligning with ongoing refactoring efforts. * refactor(cli): streamline dotenv loading and clean up prompt rendering - Introduced `load_dotenv_for_cli` to load environment variables for all CLI entrypoints, ensuring consistent configuration across commands. - Updated documentation to clarify the purpose of the dotenv loading mechanism. - Removed unnecessary blank lines in prompt rendering functions across multiple agents, enhancing code readability. These changes improve the maintainability and clarity of the CLI and prompt handling, aligning with ongoing refactoring efforts. * refactor(debug-agent-prompts): enhance environment loading and streamline workspace resolution - Updated the script to load environment variables from a `.env` file, ensuring consistent configuration for prompt generation. - Simplified workspace resolution by delegating to the binary's internal logic, improving reliability and reducing code duplication. - Revised documentation to clarify the usage of command options and the impact of environment variables on prompt rendering. These changes improve the maintainability and clarity of the debug agent prompts script, aligning with ongoing refactoring efforts. * refactor(agent): remove category filter and simplify agent definitions - Eliminated the `category_filter` from various agent definitions and related tests, streamlining the agent configuration. - Updated the `run_list` function in `agent_cli.rs` to reflect the removal of category filtering, enhancing output clarity. - Revised documentation and comments to remove references to the now-removed category filter, improving overall code maintainability. These changes contribute to a cleaner and more efficient agent architecture, aligning with ongoing refactoring efforts. * feat(agents): introduce integrations_agent and tools_agent for enhanced service handling - Added the `integrations_agent` to manage service integrations via Composio, including a new TOML configuration and prompt structure. - Introduced the `tools_agent` for general ad-hoc tasks using built-in OpenHuman tools, with its own configuration and prompt. - Updated the loader to include both agents in the built-in agent list, increasing the total number of agents from 13 to 14. - Revised orchestrator and welcome prompts to delegate integration tasks to the new `integrations_agent`, ensuring clarity in agent responsibilities. - Enhanced tests to verify the registration and functionality of the new agents, improving overall test coverage. These changes expand the capabilities of the agent architecture, allowing for more specialized handling of integrations and tool usage. * refactor(agents): update references from skills_agent to integrations_agent - Changed all instances of `skills_agent` to `integrations_agent` across various files, including prompts, CLI commands, and tool registrations. - Updated documentation and comments to reflect the new agent name, ensuring clarity in agent responsibilities and usage. - Revised debug scripts to align with the new prompt structure for the integrations agent. These changes enhance consistency in the codebase and improve the clarity of agent interactions. * refactor(agents): rename skills_agent to integrations_agent throughout the codebase - Updated all instances of `skills_agent` to `integrations_agent` in various files, including tests, documentation, and comments. - Ensured consistency in agent references to improve clarity in agent responsibilities and interactions. - Revised related code structures to align with the new naming convention, enhancing overall maintainability. These changes support the transition to the new agent architecture and improve code readability. * refactor(prompts): implement dynamic prompt rendering for enhanced context handling - Introduced `DynamicPromptSection` to allow prompts to be built dynamically using a function pointer, enabling real-time access to the `PromptContext`. - Updated `SystemPromptBuilder` to support dynamic prompts, ensuring that late-arriving state like `connected_integrations` is accurately reflected in the rendered output. - Revised the prompt handling logic in the agent builder to streamline the integration of dynamic prompts, improving overall flexibility and responsiveness. These changes enhance the prompt generation process, aligning with the ongoing improvements in agent architecture and context management. * refactor(prompts): refine delegation guide to display only connected integrations - Updated the `render_delegation_guide` function to list only the toolkits that are actively connected, omitting unauthorized toolkits to prevent hallucinations during delegation. - Revised related tests to ensure the prompt correctly reflects the current state of integrations, including scenarios where no integrations are connected. - Introduced a new utility function to filter out welcome-only tools from non-welcome agents, enhancing the clarity and safety of tool visibility. These changes improve the accuracy and focus of the delegation guide, aligning with the ongoing enhancements in agent prompt handling. * refactor(planner): update tool usage and prompt guidelines for read-only operations - Modified the `agent.toml` configuration to clarify that the planner operates in a read-only mode, specifying that it does not mutate the workspace or memory. - Revised the prompt guidelines to reflect the read-only nature of the planner, emphasizing the need for explicit nodes for any required writes to be handled by downstream agents. These changes enhance the clarity of the planner's operational constraints and improve the overall structure of the planning process. * refactor(config): remove web search enable flag and update related configurations - Eliminated the `OPENHUMAN_WEB_SEARCH_ENABLED` environment variable and associated logic, as web search is now always enabled by default. - Updated the configuration schema to reflect the removal of the enable flag from `WebSearchConfig`. - Adjusted tool registration to ensure web search is always available, simplifying the configuration process. These changes streamline the web search functionality, ensuring it is consistently available across all sessions. * refactor(config): update http_request flag to always enabled - Changed the `http_request` configuration to always be enabled, removing the dependency on the `config.http_request.enabled` flag. - This adjustment simplifies the configuration process and ensures consistent behavior across the application. These changes contribute to a more streamlined configuration and enhance the overall reliability of the onboarding process. * refactor(debug-agent-prompts): transition to dump-all command for agent prompts - Replaced the previous method of listing agent IDs and dumping prompts with a new `dump-all` command that consolidates the functionality into a single call. - Updated the script to handle output directory and workspace options more efficiently, leveraging Rust's `dump_all_agent_prompts` for processing. - Enhanced the handling of the `integrations_agent` to generate separate dumps for each connected toolkit, improving the clarity and organization of output files. - Revised related logging and summary generation to reflect the new structure, ensuring a more streamlined user experience. These changes modernize the prompt dumping process, aligning it with the latest architectural improvements and enhancing usability. * feat(composio): implement dynamic fetching of toolkit actions for integrations - Added a new `fetch_toolkit_actions` function to retrieve the current action catalogue for a specified Composio toolkit, enhancing the responsiveness of the integrations agent. - Updated the `subagent_runner` to utilize the fresh action list at spawn time, ensuring that the toolkit's actions reflect the latest backend state. - Modified the `render_integrations_agent` function to refresh the action catalogue during prompt generation, improving the accuracy of the displayed tools. These changes enhance the integration experience by providing up-to-date action information, aligning with the ongoing improvements in agent functionality. * refactor(integrations-agent): update tool visibility and configuration handling - Modified the `agent.toml` to replace `wildcard` with `named` tools, enhancing control over tool visibility for the integrations agent. - Updated the `subagent_runner` to ensure that tool visibility aligns with the new TOML configuration, preventing unnecessary stripping of tools. - Revised the `render_integrations_agent` function to respect the updated tool scope, improving the accuracy of the tool list generated for subagents. These changes streamline the tool management process, ensuring that only explicitly defined tools are available during agent execution. * feat(composio): add composio_list_connections tool for dynamic integration detection - Introduced the `composio_list_connections` tool in the orchestrator's configuration, allowing the agent to detect newly-authorized Composio integrations mid-session. - Enhanced the `ComposioListConnectionsTool` to filter and return only currently-connected integrations with ACTIVE or CONNECTED status, improving the accuracy of integration management. - Updated the tool's description to clarify its functionality and usage context. These changes enhance the agent's ability to manage integrations dynamically, aligning with ongoing improvements in the integration experience. * fix(prompt): update delegation guide to reference Skills page - Modified the `render_delegation_guide` function to change the reference from **Settings → Integrations** to the **Skills** page for connecting integrations. This update clarifies the user instructions for integration management. * feat(session): introduce session key management for sub-agents - Added `session_key` and `session_parent_prefix` fields to `ParentExecutionContext` to facilitate hierarchical transcript naming for sub-agents. - Updated `persist_subagent_transcript` to generate transcript filenames based on the parent's session key, ensuring a flat file structure that reflects the parent-child relationship. - Enhanced `AgentBuilder` and `Agent` to support the new session key management, allowing for better organization of session transcripts. - Adjusted related functions to ensure proper handling of session keys during agent execution and transcript persistence. These changes improve the clarity and organization of session transcripts, aligning with the ongoing enhancements in agent functionality. * refactor(tests): update integrations agent tests for tool scope and transcript handling - Renamed the `integrations_agent_is_wildcard` test to `integrations_agent_tool_scope_honours_toml` to better reflect its purpose of validating tool scope based on TOML configuration. - Enhanced the test to assert that the `integrations_agent` correctly recognizes named tools instead of a wildcard. - Removed the `integrations_agent_has_extra_tools_for_export` test as it is no longer relevant to the current tool management strategy. - Improved the `latest_in_dir` function to clarify the handling of transcript naming schemes, ensuring proper differentiation between legacy and keyed formats. These changes streamline the testing process and improve the accuracy of tool scope validation, aligning with recent updates in agent functionality. * refactor(subagent_runner): improve transcript persistence and streamline inner loop - Removed the `persist_subagent_transcript` function, transitioning transcript persistence to occur per-iteration within the `run_inner_loop`, enhancing reliability by ensuring transcripts are written immediately after each provider response. - Updated the handling of session keys to maintain consistent naming for transcripts, reflecting the parent-child relationship in the file structure. - Simplified the code by eliminating redundant post-loop transcript writes, aligning with recent changes in agent functionality and improving overall clarity in transcript management. * refactor(agent_cli, subagent_runner, session): improve code readability and formatting - Enhanced formatting in `agent_cli.rs` for better readability by adjusting the structure of string formatting. - Streamlined conditional checks in `subagent_runner.rs` to improve clarity and maintainability. - Simplified the handling of agent IDs in `builder.rs` to reduce line length and improve code flow. - Updated test cases in `tests.rs` for better alignment and readability of expected values. - Improved formatting in `debug_dump.rs` to enhance the clarity of toolkit action fetching and logging. These changes collectively enhance the overall readability and maintainability of the codebase, aligning with ongoing refactoring efforts. * fix(tests): add missing session_key fields to ParentExecutionContext stub * fix: address PR review feedback * fix(prompts-v2): round 2 PR review — dispatcher instructions, workspace-file preservation, cached-tool fallback, transcript persistence - subagent_runner: populate PromptContext.dispatcher_instructions for Dynamic prompts (was empty string, dropping the ## Tool Use Protocol block in render_tools for PFormat/Json/Native sub-agents) - subagent_runner: add post-tool persist_transcript after tool results are appended so a mid-round crash doesn't lose tool outputs - prompts::sync_workspace_file: preserve user-edited workspace files — only overwrite when the file doesn't exist OR its current hash matches the stored builtin hash - context::debug_dump: mirror runner's cached-tool fallback — keep cached action catalogue on empty/error from fetch_toolkit_actions instead of blanking it - core::agent_cli: add entry/exit debug logs around dump_all / dump_prompt calls and a trace log around each prompt file write; update module banner to note --toolkit is required when --agent is integrations_agent
Summary
SystemPromptBuilder, dynamic prompt rendering with context handling, and remove legacyCACHE_BOUNDARYreferences.skills_agent→integrations_agent; addtools_agent; make delegation guide reference Skills page and only show connected integrations.composio_list_connectionstool and dynamic toolkit action fetching for integrations.http_request, remove web search enable flag, simplifyagent_clioptions, streamline dotenv loading, transition debug prompts todump-all.Test plan
yarn typecheck/yarn lint/yarn format:checkcleancargo check(core + tauri) cleancargo test)Summary by CodeRabbit
New Features
Bug Fixes
Changes