refactor(tools): move domain-owned tools into modules (#2977)

This commit is contained in:
Steven Enamakel
2026-05-29 13:08:50 -07:00
committed by GitHub
parent f89501312a
commit 2920e4724a
87 changed files with 155 additions and 158 deletions
+1
View File
@@ -313,6 +313,7 @@ Deep link plugin is registered where supported; behavior is platform-specific (s
- **`src/openhuman/`** — Domain logic. Current domains: `about_app`, `accessibility`, `agent`, `app_state`, `approval`, `autocomplete`, `billing`, `channels`, `composio`, `config`, `context`, `cost`, `credentials`, `cron`, `doctor`, `embeddings`, `encryption`, `health`, `heartbeat`, `integrations`, `learning`, `local_ai`, `meet`, `meet_agent`, `memory`, `migration`, `node_runtime`, `notifications`, `overlay`, `people`, `prompt_injection`, `provider_surfaces`, `providers`, `redirect_links`, `referral`, `routing`, `scheduler_gate`, `screen_intelligence`, `security`, `service`, `skills`, `socket`, `subconscious`, `team`, `text_input`, `threads`, `tokenjuice`, `tool_timeout`, `tools`, `tree_summarizer`, `update`, `voice`, `wallet`, `webhooks`, `webview_accounts`, `webview_apis`, `webview_notifications`. RPC controllers in per-domain `rpc.rs`; use **`RpcOutcome<T>`** pattern (see "RPC Controller Pattern" below).
- **`src/openhuman/` module layout**: **New** functionality must live in a **dedicated subdirectory** (e.g. `openhuman/my_domain/mod.rs` plus related files, or a new subfolder under an existing domain). Do **not** add new standalone `*.rs` files directly at `src/openhuman/` root (`dev_paths.rs` and `util.rs` are grandfathered).
- **Tool ownership rule**: Tool implementations that belong to a domain/module must live in that owning module's `tools.rs` (and optional `tools/` submodules), not in `src/openhuman/tools/impl/`. Re-export those tool types from `src/openhuman/tools/mod.rs` so callers continue to import agent-callable tools through `crate::openhuman::tools::*`. Keep `src/openhuman/tools/impl/` only for genuinely cross-cutting tool families without a clear owning domain (for example filesystem, browser/computer control, and generic system/network utilities).
- **Controller schema contract**: Shared controller metadata types live in `src/core/types.rs` / `src/core/mod.rs` (`ControllerSchema`, `FieldSchema`, `TypeSchema`) and are consumed by adapters (RPC/CLI).
- **Domain schema files**: For each domain, define controller schema metadata in a dedicated module inside the domain folder (example: `src/openhuman/cron/schemas.rs`) and export from the domain `mod.rs`.
- **Controller-only exposure rule**: Expose domain functionality to **CLI and JSON-RPC through the controller registry** (`schemas.rs` + registered handlers wired into `src/core/all.rs`). Do **not** add domain-specific branches in `src/core/cli.rs` or `src/core/jsonrpc.rs`.
+4 -4
View File
@@ -306,11 +306,11 @@ Canonical mapping of every product feature to its test source(s). Drives gap-fil
| ID | Feature | Layer | Test path(s) | Status | Notes |
| ----- | ------------------------------------------ | ----- | ----------------------------------------------------------------------------------------------------------------- | ------ | ---------------------------------------------------------------------- |
| 8.4.1 | Save Preference (general / situational) | RU | `src/openhuman/tools/impl/agent/save_preference_tests.rs` | ✅ | `save_preference` tool → `user_pref_{general,situational}`, topic-keyed |
| 8.4.1 | Save Preference (general / situational) | RU | `src/openhuman/agent/tools/save_preference_tests.rs` | ✅ | `save_preference` tool → `user_pref_{general,situational}`, topic-keyed |
| 8.4.2 | Lane A — Standing Prefs in System Prompt | RU | `src/openhuman/learning/prompt_sections.rs`, `src/openhuman/agent/harness/session/turn_tests.rs` | ✅ | General prefs rendered into the system prompt at thread start |
| 8.4.3 | Lane B — Situational Recall (vector-gated) | RU | `src/openhuman/memory/store/unified/query_tests.rs::recall_relevant_by_vector_gates_on_similarity` | ✅ | Per-turn; relevant query injects, unrelated suppresses |
| 8.4.4 | Same-Topic Contradiction (replace) | RU | `src/openhuman/tools/impl/agent/save_preference_tests.rs::recategorising_moves_pref_between_namespaces` | ✅ | `ON CONFLICT REPLACE`; a topic lives in exactly one scope |
| 8.4.5 | Cross-Topic Contradiction Surfacing | RU | `src/openhuman/tools/impl/agent/save_preference_tests.rs::save_surfaces_related_preference_for_contradiction_check` | ✅ | Related prefs surfaced in the tool result for the chat agent to resolve |
| 8.4.4 | Same-Topic Contradiction (replace) | RU | `src/openhuman/agent/tools/save_preference_tests.rs::recategorising_moves_pref_between_namespaces` | ✅ | `ON CONFLICT REPLACE`; a topic lives in exactly one scope |
| 8.4.5 | Cross-Topic Contradiction Surfacing | RU | `src/openhuman/agent/tools/save_preference_tests.rs::save_surfaces_related_preference_for_contradiction_check` | ✅ | Related prefs surfaced in the tool result for the chat agent to resolve |
| 8.4.6 | vector_chunks Model-Signature Recall Guard | RU | `src/openhuman/memory/store/unified/query_tests.rs::vector_recall_excludes_other_model_signature` | ✅ | Excludes cross-model vectors; dim-guards legacy rows |
---
@@ -368,7 +368,7 @@ Canonical mapping of every product feature to its test source(s). Drives gap-fil
| ------ | ------------------------- | ----- | ----------------------------------------------------- | ------ | ----- |
| 10.3.1 | Incoming Message Sync | RU+WD | `src/openhuman/channels/tests/`, `gmail-flow.spec.ts` | ✅ | |
| 10.3.2 | Message Deduplication | RU | `src/openhuman/channels/tests/` | ✅ | |
| 10.3.3 | WhatsApp Agent Retrieval | RU | `src/openhuman/tools/impl/whatsapp_data/` (this PR), `tests/json_rpc_e2e.rs::whatsapp_data_agent_tools_e2e_1341` (this PR) | ✅ | Three read-only agent tools wrap the local SQLite store; ingest stays internal-only. See [`docs/whatsapp-data-flow.md`](whatsapp-data-flow.md). |
| 10.3.3 | WhatsApp Agent Retrieval | RU | `src/openhuman/whatsapp_data/tools/` (this PR), `tests/json_rpc_e2e.rs::whatsapp_data_agent_tools_e2e_1341` (this PR) | ✅ | Three read-only agent tools wrap the local SQLite store; ingest stays internal-only. See [`docs/whatsapp-data-flow.md`](whatsapp-data-flow.md). |
| 10.3.4 | Real-Time vs Delayed Sync | RU | `src/openhuman/channels/tests/runtime_dispatch.rs` | ✅ | |
### 10.4 Messaging Operations
+3 -3
View File
@@ -17,7 +17,7 @@ The code path is split across several layers:
- built-in agent definitions in `src/openhuman/agent/agents/`
- harness data + task-local plumbing in `src/openhuman/agent/harness/`
- main session lifecycle in `src/openhuman/agent/harness/session/`
- delegation tools in `src/openhuman/tools/impl/agent/`
- delegation tools in `src/openhuman/agent/tools/`
- synthesised `delegate_*` tools in `src/openhuman/tools/orchestrator_tools.rs`
If you only read one file, the system looks simpler than it is. The actual runtime path crosses all of them.
@@ -42,7 +42,7 @@ If you only read one file, the system looks simpler than it is. The actual runti
### Subagent path
- `src/openhuman/tools/impl/agent/spawn_subagent.rs`
- `src/openhuman/agent/tools/spawn_subagent.rs`
Runtime tool entrypoint for explicit subagent spawns.
- `src/openhuman/agent/harness/fork_context.rs`
Task-local parent and fork context.
@@ -330,7 +330,7 @@ That history format is what the next iteration reasons from.
## Where `spawn_subagent` Enters
The explicit delegation tool lives in `src/openhuman/tools/impl/agent/spawn_subagent.rs`.
The explicit delegation tool lives in `src/openhuman/agent/tools/spawn_subagent.rs`.
Its flow is:
+1 -1
View File
@@ -120,7 +120,7 @@ You are an autonomous developer agent. Your job is to pick a GitHub issue and de
**Not blocked on #2707** — can be done now.
The `cron_add` logic exists in the agent tool (`src/openhuman/tools/impl/cron/add.rs`) but isn't exposed as an RPC controller. Need to add it to `src/openhuman/cron/schemas.rs`.
The `cron_add` logic exists in the agent tool (`src/openhuman/cron/tools/add.rs`) but isn't exposed as an RPC controller. Need to add it to `src/openhuman/cron/schemas.rs`.
**Changes:**
- `src/openhuman/cron/schemas.rs` — Add `"add"` controller with inputs: `name`, `schedule`, `prompt`, `session_target`, `model`, `agent_id`, `delivery`, `delete_after_run`
+1 -1
View File
@@ -60,7 +60,7 @@ The scanner write-path RPCs are registered as **internal-only** in [`src/core/al
The agent surfaces are exclusively read-only:
- [`src/openhuman/tools/impl/whatsapp_data/`](../src/openhuman/tools/impl/whatsapp_data/) — `whatsapp_data_list_chats`, `whatsapp_data_list_messages`, `whatsapp_data_search_messages`. All three wrap their RPC counterparts and emit a `"provider": "whatsapp"` tag in the response so the agent can cite WhatsApp as the source.
- [`src/openhuman/whatsapp_data/tools/`](../src/openhuman/whatsapp_data/tools/) — `whatsapp_data_list_chats`, `whatsapp_data_list_messages`, `whatsapp_data_search_messages`. All three wrap their RPC counterparts and emit a `"provider": "whatsapp"` tag in the response so the agent can cite WhatsApp as the source.
- [`src/openhuman/memory/query/`](../src/openhuman/memory/query/) — generic `memory_tree_*` tools. Filter by `source_kind: "chat"` or query directly; WhatsApp chat-day transcripts are tagged `whatsapp` so they surface in cross-source flows.
## Why the orchestrator only lists three of these
+2 -2
View File
@@ -104,8 +104,8 @@ The agent never sees the choice — it just calls into `Sandbox::run(...)` and t
- `src/openhuman/cron/scheduler.rs` — wraps shell jobs in `SecurityPolicy::from_config`.
- `src/openhuman/tools/local_cli.rs`, `tools/ops.rs`, and most `tools/impl/{system,network,memory,agent}/*.rs` — every executable tool consults `SecurityPolicy`.
- `src/openhuman/tools/impl/network/{curl,http_request,composio}.rs` — risk-classify outbound calls.
- `src/openhuman/tools/impl/memory/{store,forget}.rs` — sensitive-write tracking.
- `src/openhuman/tools/impl/agent/delegate.rs` — sub-agent dispatch goes through the autonomy gate.
- `src/openhuman/memory/tools/{store,forget}.rs` — sensitive-write tracking.
- `src/openhuman/agent/tools/delegate.rs` — sub-agent dispatch goes through the autonomy gate.
- `src/openhuman/credentials/` — uses `SecretStore` and `redact`.
## Tests
+1 -1
View File
@@ -28,7 +28,7 @@ In-process pub/sub plus typed request/response. Owns the global `EventBus` singl
## Called by
- ~33 sites across the workspace. Hot consumers:
- `src/openhuman/agent/bus.rs`, `agent/triage/{events,evaluator,escalation}.rs`, `tools/impl/agent/{dispatch,spawn_subagent}.rs` — agent + sub-agent events.
- `src/openhuman/agent/bus.rs`, `agent/triage/{events,evaluator,escalation}.rs`, `agent/tools/{dispatch,spawn_subagent}.rs` — agent + sub-agent events.
- `src/openhuman/memory/conversations/bus.rs` — conversation persistence subscriber.
- `src/openhuman/channels/bus.rs``ChannelInboundSubscriber`.
- `src/openhuman/cron/{bus,scheduler}.rs``CronDeliverySubscriber` + `CronJobTriggered` emission.
+1 -1
View File
@@ -1092,7 +1092,7 @@ fn is_provider_user_state_message(lower: &str) -> bool {
// personal Composio v3 tenant rejected with a 401 because the stored
// API key is invalid / revoked / has the wrong prefix. The canonical
// wire shape rendered by
// `src/openhuman/composio/tools/impl/network/composio.rs::response_error`
// `src/openhuman/composio/composio/tools/direct.rs::response_error`
// and the various direct-mode op wrappers is:
//
// `[composio-direct] list_connections failed: Composio v3
+1 -1
View File
@@ -34,7 +34,7 @@ Multi-agent orchestration domain. Owns the LLM tool-calling loop, sub-agent disp
- `src/openhuman/composio/bus.rs` — Composio trigger envelopes go through `agent::triage`.
- `src/openhuman/notifications/rpc.rs` — surfaces agent runs to the UI.
- `src/openhuman/learning/{reflection,tool_tracker,user_profile}.rs` — read transcripts + tool outcomes.
- `src/openhuman/tools/impl/agent/{dispatch,spawn_subagent}.rs``spawn_subagent` tool delegates here.
- `src/openhuman/agent/tools/{dispatch,spawn_subagent}.rs``spawn_subagent` tool delegates here.
- `src/core/all.rs` — controller registry wires `all_agent_registered_controllers`.
## Tests
+2 -2
View File
@@ -167,8 +167,8 @@ pub struct AgentDefinition {
/// so that reading a TOML makes the distinction obvious: `tools` is
/// "what I execute directly", `subagents` is "what I can delegate to".
///
/// [`ArchetypeDelegationTool`]: crate::openhuman::tools::impl::agent::ArchetypeDelegationTool
/// [`SkillDelegationTool`]: crate::openhuman::tools::impl::agent::SkillDelegationTool
/// [`ArchetypeDelegationTool`]: crate::openhuman::agent::tools::ArchetypeDelegationTool
/// [`SkillDelegationTool`]: crate::openhuman::agent::tools::SkillDelegationTool
#[serde(default)]
pub subagents: Vec<SubagentEntry>,
+1
View File
@@ -43,6 +43,7 @@ mod schemas;
pub mod stop_hooks;
pub mod task_board;
pub mod tool_policy;
pub mod tools;
pub mod tree_loader;
pub mod triage;
pub use schemas::{
+1
View File
@@ -1,5 +1,6 @@
mod ops;
mod schemas;
pub mod tools;
mod types;
pub use ops::{
+1
View File
@@ -20,6 +20,7 @@
pub mod index;
pub mod search;
pub mod store;
pub mod tools;
pub use index::{
code_tokens, count_code_files, current_ref, index_ref, structural_doc, IndexMode, IndexReport,
+2 -2
View File
@@ -689,7 +689,7 @@ const MODE_DIRECT_PAT: &str = COMPOSIO_MODE_DIRECT;
/// (calls `api.tinyhumans.ai/agent-integrations/composio/*`).
///
/// `Direct` wraps the existing direct-mode HTTP wrapper from
/// `tools/impl/network/composio.rs` that calls
/// `composio/tools/direct.rs` that calls
/// `https://backend.composio.dev/api/v{2,3}` with `x-api-key`. The
/// direct client does not currently cover every endpoint the
/// backend-proxied path exposes (no per-toolkit allowlist, no
@@ -801,7 +801,7 @@ pub fn create_composio_client(
// ── Direct-mode response reshapers ──────────────────────────────────
//
// The direct-mode `ComposioTool` (in `tools/impl/network/composio.rs`)
// The direct-mode `ComposioTool` (in `composio/tools/direct.rs`)
// speaks `backend.composio.dev/api/v3/*` natively. The helpers below
// reshape those v3 responses into the same envelopes the
// backend-proxied [`ComposioClient`] returns, so callers in `ops.rs` /
+4
View File
@@ -45,6 +45,10 @@ use super::providers::{
};
use super::types::ComposioToolsResponse;
mod direct;
pub use direct::{ComposioAction, ComposioConnectedAccount, ComposioTool};
/// Decision returned by [`evaluate_tool_visibility`].
enum ToolDecision {
/// Action is curated for this toolkit and user scope allows it.
@@ -1091,5 +1091,5 @@ impl ComposioConnectedAccount {
}
#[cfg(test)]
#[path = "composio_tests.rs"]
#[path = "direct_tests.rs"]
mod tests;
+1 -1
View File
@@ -734,7 +734,7 @@ mod search_config_tests {
/// (the async push surface that the backend currently mediates via
/// socket.io) do not work in direct mode — the user has to enable them
/// out-of-band on Composio's dashboard and configure their own webhook
/// sink. See `tools/impl/network/composio.rs` for the underlying client.
/// sink. See `composio/tools/direct.rs` for the underlying client.
pub const COMPOSIO_MODE_BACKEND: &str = "backend";
pub const COMPOSIO_MODE_DIRECT: &str = "direct";
+1 -1
View File
@@ -54,4 +54,4 @@ current channel + reply target — that is the routing path for the Telegram
- Unit: `ops_tests.rs`, `scheduler_tests.rs`, `store_tests.rs`.
- Schema/parsing coverage lives inside `schedule.rs` and `schemas.rs` `#[cfg(test)] mod tests` blocks.
- Delivery validation: `tools::impl::cron::add::tests` (announce-mode `allowed_users` checks).
- Delivery validation: `cron::tools::add::tests` (announce-mode `allowed_users` checks).
+1
View File
@@ -4,6 +4,7 @@ mod schedule;
mod schemas;
pub mod seed;
mod store;
pub mod tools;
mod types;
pub mod scheduler;
+1 -28
View File
@@ -6,38 +6,11 @@
//! endpoints directly when enabled; those callers must keep configured base URLs
//! trusted because requests leave the local core process.
pub mod apify;
pub mod brave;
pub mod client;
pub mod google_places;
pub mod parallel;
pub mod querit;
pub mod searxng;
pub mod seltz;
pub mod stock_prices;
pub mod tinyfish;
pub mod twilio;
pub mod tools;
pub mod types;
pub use apify::{ApifyGetRunResultsTool, ApifyGetRunStatusTool, ApifyRunActorTool};
pub use brave::{
BraveImageSearchTool, BraveNewsSearchTool, BraveVideoSearchTool, BraveWebSearchTool,
};
pub use client::{build_client, pricing_for_config, IntegrationClient};
pub use google_places::{GooglePlacesDetailsTool, GooglePlacesSearchTool};
pub use parallel::{
ParallelChatTool, ParallelDatasetTool, ParallelEnrichTool, ParallelExtractTool,
ParallelResearchTool, ParallelSearchTool,
};
pub use querit::QueritSearchTool;
pub use searxng::{SearxngSearchArgs, SearxngSearchResponse, SearxngSearchTool};
pub use seltz::SeltzSearchTool;
pub use stock_prices::{
StockCommodityTool, StockCryptoSeriesTool, StockExchangeRateTool, StockOptionsTool,
StockQuoteTool,
};
pub use tinyfish::{TinyFishAgentRunTool, TinyFishFetchTool, TinyFishSearchTool};
pub use twilio::TwilioCallTool;
pub use types::{
BackendResponse, IntegrationPricing, IntegrationPricingEntry, PricingIntegrations, ToolScope,
};
+34
View File
@@ -0,0 +1,34 @@
use super::IntegrationClient;
mod apify;
mod brave;
mod google_places;
mod parallel;
mod querit;
mod searxng;
mod seltz;
mod stock_prices;
mod tinyfish;
mod twilio;
pub use apify::{ApifyGetRunResultsTool, ApifyGetRunStatusTool, ApifyRunActorTool};
pub use brave::{
BraveImageSearchTool, BraveNewsSearchTool, BraveVideoSearchTool, BraveWebSearchTool,
};
pub use google_places::{GooglePlacesDetailsTool, GooglePlacesSearchTool};
pub use parallel::{
ParallelChatTool, ParallelDatasetTool, ParallelEnrichTool, ParallelExtractTool,
ParallelResearchTool, ParallelSearchTool, SearchResponse, SearchResultItem,
};
pub use querit::QueritSearchTool;
pub use searxng::{
normalize_categories, SearxngSearchArgs, SearxngSearchResponse, SearxngSearchTool,
MAX_RESULTS as SEARXNG_MAX_RESULTS,
};
pub use seltz::SeltzSearchTool;
pub use stock_prices::{
StockCommodityTool, StockCryptoSeriesTool, StockExchangeRateTool, StockOptionsTool,
StockQuoteTool,
};
pub use tinyfish::{TinyFishAgentRunTool, TinyFishFetchTool, TinyFishSearchTool};
pub use twilio::TwilioCallTool;
@@ -10,7 +10,8 @@
//!
//! The backend handles Twilio API credentials, billing, and rate limiting.
use super::{IntegrationClient, ToolScope};
use super::IntegrationClient;
use crate::openhuman::integrations::ToolScope;
use crate::openhuman::tools::traits::{PermissionLevel, Tool, ToolResult};
use async_trait::async_trait;
use serde::Deserialize;
+2 -2
View File
@@ -5,8 +5,8 @@ use crate::openhuman::agent::harness::AgentDefinitionRegistry;
use crate::openhuman::agent::Agent;
use crate::openhuman::config::rpc as config_rpc;
use crate::openhuman::inference::provider::traits::build_tool_instructions_text;
use crate::openhuman::integrations::searxng::MAX_RESULTS as SEARXNG_MAX_RESULTS;
use crate::openhuman::security::{SecurityPolicy, ToolOperation};
use crate::openhuman::tools::SEARXNG_MAX_RESULTS;
use super::write_dispatch;
@@ -737,7 +737,7 @@ fn build_rpc_params(
let mut params = Map::new();
params.insert("query".to_string(), Value::String(query));
if let Some(categories) = optional_string_array(&args, "categories")? {
crate::openhuman::integrations::searxng::normalize_categories(categories.clone())
crate::openhuman::tools::normalize_categories(categories.clone())
.map_err(|err| ToolCallError::InvalidParams(err.to_string()))?;
params.insert("categories".to_string(), Value::from(categories));
}
+1
View File
@@ -26,6 +26,7 @@ pub mod read_rpc;
pub mod remember;
pub mod schema;
pub mod sync;
pub mod tools;
pub mod util;
// Tree instances — policy and orchestration over the generic memory_tree engine.
+2 -2
View File
@@ -27,8 +27,8 @@ Trust boundary for the autonomous core. Owns the autonomy / risk policy, sandbox
- `src/openhuman/cron/scheduler.rs` — wraps shell jobs in `SecurityPolicy::from_config`.
- `src/openhuman/tools/local_cli.rs`, `tools/ops.rs`, and most `tools/impl/{system,network,memory,agent}/*.rs` — every executable tool consults `SecurityPolicy`.
- `src/openhuman/tools/impl/network/{curl,http_request,composio}.rs` — risk-classify outbound calls.
- `src/openhuman/tools/impl/memory/{store,forget}.rs` — sensitive-write tracking.
- `src/openhuman/tools/impl/agent/delegate.rs` — sub-agent dispatch goes through autonomy gate.
- `src/openhuman/memory/tools/{store,forget}.rs` — sensitive-write tracking.
- `src/openhuman/agent/tools/delegate.rs` — sub-agent dispatch goes through autonomy gate.
- `src/openhuman/credentials/` — uses `SecretStore` and `redact`.
## Tests
+1 -1
View File
@@ -444,7 +444,7 @@ fn emit_progress(location: &BoardLocation, cards: &[TaskBoardCard]) {
}
/// Process-global lock that test code (here and in
/// `tools::impl::agent::todo`) uses to serialize access to the shared
/// `agent::tools::todo`) uses to serialize access to the shared
/// scratch store under `cargo test`'s parallel runner.
#[cfg(test)]
pub(crate) fn scratch_test_lock() -> std::sync::MutexGuard<'static, ()> {
-14
View File
@@ -1,25 +1,11 @@
pub mod agent;
pub mod audio;
pub mod browser;
pub mod codegraph;
pub mod computer;
pub mod cron;
pub mod filesystem;
pub mod memory;
pub mod network;
pub mod system;
pub mod wallet;
pub mod whatsapp_data;
pub use agent::*;
pub use audio::*;
pub use browser::*;
pub use codegraph::*;
pub use computer::*;
pub use cron::*;
pub use filesystem::*;
pub use memory::*;
pub use network::*;
pub use system::*;
pub use wallet::*;
pub use whatsapp_data::*;
-2
View File
@@ -1,5 +1,4 @@
mod clob_auth;
mod composio;
mod curl;
mod gitbooks;
mod gmail_unsubscribe;
@@ -12,7 +11,6 @@ mod url_guard;
mod web_fetch;
mod web_search;
pub use composio::{ComposioAction, ComposioConnectedAccount, ComposioTool};
pub use curl::CurlTool;
pub use gitbooks::{GitbooksGetPageTool, GitbooksSearchTool};
pub use gmail_unsubscribe::GmailUnsubscribeTool;
@@ -1,6 +1,6 @@
use crate::openhuman::integrations::parallel::{SearchResponse, SearchResultItem};
use crate::openhuman::integrations::{IntegrationClient, SeltzSearchTool};
use crate::openhuman::integrations::IntegrationClient;
use crate::openhuman::tools::traits::{Tool, ToolCallOptions, ToolResult};
use crate::openhuman::tools::{SearchResponse, SearchResultItem, SeltzSearchTool};
use async_trait::async_trait;
use serde_json::{json, Value};
use sha2::{Digest, Sha256};
+9
View File
@@ -11,6 +11,15 @@ pub(crate) mod user_filter;
#[path = "impl/mod.rs"]
pub(crate) mod implementations;
pub use crate::openhuman::agent::tools::*;
pub use crate::openhuman::audio_toolkit::tools::*;
pub use crate::openhuman::codegraph::tools::*;
pub use crate::openhuman::composio::tools::*;
pub use crate::openhuman::cron::tools::*;
pub use crate::openhuman::integrations::tools::*;
pub use crate::openhuman::memory::tools::*;
pub use crate::openhuman::wallet::tools::*;
pub use crate::openhuman::whatsapp_data::tools::*;
pub use implementations::*;
pub use ops::*;
pub use policy::{DefaultToolPolicy, PolicyDecision, ToolPolicy};
+63 -79
View File
@@ -388,34 +388,24 @@ pub fn all_tools_with_runtime(
// pick it up once direct Parallel routing lands.
let client = crate::openhuman::integrations::build_client(root_config);
if let Some(client) = client {
tools.push(Box::new(crate::openhuman::tools::ParallelSearchTool::new(
Arc::clone(&client),
)));
tools.push(Box::new(crate::openhuman::tools::ParallelExtractTool::new(
Arc::clone(&client),
)));
tools.push(Box::new(crate::openhuman::tools::ParallelChatTool::new(
Arc::clone(&client),
)));
tools.push(Box::new(
crate::openhuman::integrations::ParallelSearchTool::new(Arc::clone(
&client,
)),
));
tools.push(Box::new(
crate::openhuman::integrations::ParallelExtractTool::new(Arc::clone(
&client,
)),
));
tools.push(Box::new(
crate::openhuman::integrations::ParallelChatTool::new(Arc::clone(&client)),
));
tools.push(Box::new(
crate::openhuman::integrations::ParallelResearchTool::new(Arc::clone(
&client,
)),
));
tools.push(Box::new(
crate::openhuman::integrations::ParallelEnrichTool::new(Arc::clone(
&client,
)),
));
tools.push(Box::new(
crate::openhuman::integrations::ParallelDatasetTool::new(Arc::clone(
&client,
)),
crate::openhuman::tools::ParallelResearchTool::new(Arc::clone(&client)),
));
tools.push(Box::new(crate::openhuman::tools::ParallelEnrichTool::new(
Arc::clone(&client),
)));
tools.push(Box::new(crate::openhuman::tools::ParallelDatasetTool::new(
Arc::clone(&client),
)));
// Layer the unified web_search slot too so the
// agent's default research path keeps working.
tools.push(Box::new(WebSearchTool::new(
@@ -437,29 +427,25 @@ pub fn all_tools_with_runtime(
SearchEngine::Brave => {
tracing::debug!("[search] active engine = brave (BYO direct API)");
let api_key = search.brave.api_key.clone();
tools.push(Box::new(crate::openhuman::tools::BraveWebSearchTool::new(
api_key.clone(),
max_results,
timeout_secs,
)));
tools.push(Box::new(crate::openhuman::tools::BraveNewsSearchTool::new(
api_key.clone(),
max_results,
timeout_secs,
)));
tools.push(Box::new(
crate::openhuman::integrations::BraveWebSearchTool::new(
crate::openhuman::tools::BraveImageSearchTool::new(
api_key.clone(),
max_results,
timeout_secs,
),
));
tools.push(Box::new(
crate::openhuman::integrations::BraveNewsSearchTool::new(
api_key.clone(),
max_results,
timeout_secs,
),
));
tools.push(Box::new(
crate::openhuman::integrations::BraveImageSearchTool::new(
api_key.clone(),
max_results,
timeout_secs,
),
));
tools.push(Box::new(
crate::openhuman::integrations::BraveVideoSearchTool::new(
crate::openhuman::tools::BraveVideoSearchTool::new(
api_key,
max_results,
timeout_secs,
@@ -469,21 +455,19 @@ pub fn all_tools_with_runtime(
SearchEngine::Querit => {
tracing::debug!("[search] active engine = querit (BYO direct API)");
tools.push(Box::new(
crate::openhuman::integrations::QueritSearchTool::new_web_search_tool(
search.querit.api_key.clone(),
None,
max_results,
timeout_secs,
),
));
tools.push(Box::new(
crate::openhuman::integrations::QueritSearchTool::new(
crate::openhuman::tools::QueritSearchTool::new_web_search_tool(
search.querit.api_key.clone(),
None,
max_results,
timeout_secs,
),
));
tools.push(Box::new(crate::openhuman::tools::QueritSearchTool::new(
search.querit.api_key.clone(),
None,
max_results,
timeout_secs,
)));
}
}
}
@@ -552,14 +536,14 @@ pub fn all_tools_with_runtime(
if let Some(client) = crate::openhuman::integrations::build_client(root_config) {
tracing::debug!("[integrations] client built successfully");
if root_config.integrations.apify.is_active() {
tools.push(Box::new(crate::openhuman::tools::ApifyRunActorTool::new(
Arc::clone(&client),
)));
tools.push(Box::new(
crate::openhuman::integrations::ApifyRunActorTool::new(Arc::clone(&client)),
crate::openhuman::tools::ApifyGetRunStatusTool::new(Arc::clone(&client)),
));
tools.push(Box::new(
crate::openhuman::integrations::ApifyGetRunStatusTool::new(Arc::clone(&client)),
));
tools.push(Box::new(
crate::openhuman::integrations::ApifyGetRunResultsTool::new(Arc::clone(&client)),
crate::openhuman::tools::ApifyGetRunResultsTool::new(Arc::clone(&client)),
));
tracing::debug!("[integrations] registered apify tools");
} else {
@@ -567,10 +551,10 @@ pub fn all_tools_with_runtime(
}
if root_config.integrations.google_places.is_active() {
tools.push(Box::new(
crate::openhuman::integrations::GooglePlacesSearchTool::new(Arc::clone(&client)),
crate::openhuman::tools::GooglePlacesSearchTool::new(Arc::clone(&client)),
));
tools.push(Box::new(
crate::openhuman::integrations::GooglePlacesDetailsTool::new(Arc::clone(&client)),
crate::openhuman::tools::GooglePlacesDetailsTool::new(Arc::clone(&client)),
));
tracing::debug!("[integrations] registered google_places tools");
} else {
@@ -586,43 +570,43 @@ pub fn all_tools_with_runtime(
);
}
if root_config.integrations.tinyfish.is_active() {
tools.push(Box::new(crate::openhuman::tools::TinyFishSearchTool::new(
Arc::clone(&client),
)));
tools.push(Box::new(crate::openhuman::tools::TinyFishFetchTool::new(
Arc::clone(&client),
)));
tools.push(Box::new(
crate::openhuman::integrations::TinyFishSearchTool::new(Arc::clone(&client)),
));
tools.push(Box::new(
crate::openhuman::integrations::TinyFishFetchTool::new(Arc::clone(&client)),
));
tools.push(Box::new(
crate::openhuman::integrations::TinyFishAgentRunTool::new(Arc::clone(&client)),
crate::openhuman::tools::TinyFishAgentRunTool::new(Arc::clone(&client)),
));
tracing::debug!("[integrations] registered tinyfish tools");
} else {
tracing::debug!("[integrations] tinyfish disabled — skipping");
}
if root_config.integrations.stock_prices.is_active() {
tools.push(Box::new(crate::openhuman::tools::StockQuoteTool::new(
Arc::clone(&client),
)));
tools.push(Box::new(
crate::openhuman::integrations::StockQuoteTool::new(Arc::clone(&client)),
crate::openhuman::tools::StockExchangeRateTool::new(Arc::clone(&client)),
));
tools.push(Box::new(crate::openhuman::tools::StockOptionsTool::new(
Arc::clone(&client),
)));
tools.push(Box::new(
crate::openhuman::integrations::StockExchangeRateTool::new(Arc::clone(&client)),
));
tools.push(Box::new(
crate::openhuman::integrations::StockOptionsTool::new(Arc::clone(&client)),
));
tools.push(Box::new(
crate::openhuman::integrations::StockCryptoSeriesTool::new(Arc::clone(&client)),
));
tools.push(Box::new(
crate::openhuman::integrations::StockCommodityTool::new(Arc::clone(&client)),
crate::openhuman::tools::StockCryptoSeriesTool::new(Arc::clone(&client)),
));
tools.push(Box::new(crate::openhuman::tools::StockCommodityTool::new(
Arc::clone(&client),
)));
tracing::debug!("[integrations] registered stock_prices tools");
} else {
tracing::debug!("[integrations] stock_prices disabled — skipping");
}
if root_config.integrations.twilio.is_active() {
tools.push(Box::new(
crate::openhuman::integrations::TwilioCallTool::new(Arc::clone(&client)),
));
tools.push(Box::new(crate::openhuman::tools::TwilioCallTool::new(
Arc::clone(&client),
)));
tracing::debug!("[integrations] registered twilio tools");
} else {
tracing::debug!("[integrations] twilio disabled — skipping");
+6 -6
View File
@@ -11,8 +11,8 @@ use serde_json::{json, Map, Value};
use crate::core::all::{ControllerFuture, RegisteredController};
use crate::core::{ControllerSchema, FieldSchema, TypeSchema};
use crate::openhuman::config::rpc as config_rpc;
use crate::openhuman::integrations::searxng::MAX_RESULTS as SEARXNG_MAX_RESULTS;
use crate::openhuman::tools::traits::Tool;
use crate::openhuman::tools::SEARXNG_MAX_RESULTS;
use crate::rpc::RpcOutcome;
pub fn all_controller_schemas() -> Vec<ControllerSchema> {
@@ -517,7 +517,7 @@ fn handle_web_search(params: Map<String, Value>) -> ControllerFuture {
});
let resp = client
.post::<crate::openhuman::integrations::parallel::SearchResponse>(
.post::<crate::openhuman::tools::SearchResponse>(
"/agent-integrations/parallel/search",
&body,
)
@@ -568,7 +568,7 @@ fn handle_seltz_search(params: Map<String, Value>) -> ControllerFuture {
"[rpc][tools.seltz_search] start"
);
let tool = crate::openhuman::integrations::SeltzSearchTool::new(
let tool = crate::openhuman::tools::SeltzSearchTool::new(
config.seltz.api_key.clone(),
config.seltz.api_url.clone(),
max_results,
@@ -650,7 +650,7 @@ fn handle_querit_search(params: Map<String, Value>) -> ControllerFuture {
"[rpc][tools.querit_search] start"
);
let tool = crate::openhuman::integrations::QueritSearchTool::new(
let tool = crate::openhuman::tools::QueritSearchTool::new(
config.search.querit.api_key.clone(),
None,
max_results,
@@ -729,7 +729,7 @@ fn handle_searxng_search(params: Map<String, Value>) -> ControllerFuture {
"[rpc][tools.searxng_search] start"
);
let tool = crate::openhuman::integrations::SearxngSearchTool::new(
let tool = crate::openhuman::tools::SearxngSearchTool::new(
config.searxng.base_url.clone(),
config.searxng.max_results,
config.searxng.default_language.clone(),
@@ -737,7 +737,7 @@ fn handle_searxng_search(params: Map<String, Value>) -> ControllerFuture {
);
let response = tool
.search(crate::openhuman::integrations::SearxngSearchArgs {
.search(crate::openhuman::tools::SearxngSearchArgs {
query,
categories,
language,
+1
View File
@@ -10,6 +10,7 @@ mod execution;
mod ops;
mod rpc;
mod schemas;
pub mod tools;
#[cfg(test)]
pub(crate) mod test_support;
+1
View File
@@ -21,6 +21,7 @@ pub mod rpc;
mod schemas;
mod sqlite_retry;
pub mod store;
pub mod tools;
pub mod types;
pub use schemas::{