Skip to content

Add TinyFish integration tools#2125

Merged
senamakel merged 4 commits into
tinyhumansai:mainfrom
pranavjana:feat/tinyfish-integration
May 20, 2026
Merged

Add TinyFish integration tools#2125
senamakel merged 4 commits into
tinyhumansai:mainfrom
pranavjana:feat/tinyfish-integration

Conversation

@pranavjana
Copy link
Copy Markdown
Contributor

@pranavjana pranavjana commented May 18, 2026

Summary

  • Adds backend-proxied TinyFish integration tools for search, rendered fetch, and goal-based browser automation.
  • TinyFish is web infrastructure for AI agents, providing Search, Fetch, Browser, and Agent APIs for live web retrieval and browser automation.
  • Registers tinyfish_search, tinyfish_fetch, and tinyfish_agent_run behind the standard integrations.tinyfish.enabled toggle.
  • Extends integration pricing/default structs, capability catalog metadata, fake backend coverage, and the coverage matrix.
  • Addresses CodeRabbit review feedback by adding TinyFish debug/error-path logging and recalculating coverage matrix totals.

Problem

OpenHuman has backend-proxied integration surfaces for providers like Apify, Parallel, Google Places, stock data, and Twilio, but no first-class TinyFish entry point. TinyFish maps cleanly onto the existing integration-tool model and gives the agent a single provider for web search, browser-rendered page extraction, and goal-based site automation.

Solution

This PR adds a Rust-side TinyFish integration module that follows the existing IntegrationClient pattern. The client continues to call OpenHuman backend routes, so TinyFish API keys, rate limits, and billing remain server-side.

The new tool family covers:

  • tinyfish_search: ranked search results with optional location/language/page/thumbnail parameters.
  • tinyfish_fetch: browser-rendered extraction for up to 10 known URLs, with format/link/image-link options.
  • tinyfish_agent_run: executable goal-based browser automation with optional structured output, stealth profile, proxy country, and vault scoping fields.

Tests use the existing fake integration backend and do not call TinyFish directly.

Submission Checklist

  • Tests added or updated (happy path + at least one failure / edge case) per Testing Strategy
  • Diff coverage ≥ 80% — CI Coverage Gate is the source of truth; focused Rust tests cover the changed integration paths locally.
  • Coverage matrix updated — added 7.2.3 TinyFish Integration Tools and recalculated the summary totals in docs/TEST-COVERAGE-MATRIX.md
  • All affected feature IDs from the matrix are listed in the PR description under ## Related
  • No new external network dependencies introduced (mock backend used per Testing Strategy)
  • Manual smoke checklist updated if this touches release-cut surfaces: N/A — backend-proxied tool registration only
  • Linked issue closed via Closes #NNN in the ## Related section: N/A — no linked issue

Impact

Runtime impact is limited to core tool registration when the user is signed in and integrations.tinyfish.enabled is true. There are no new client-side secrets or SDK dependencies. The OpenHuman backend must expose the corresponding /agent-integrations/tinyfish/* proxy routes for live execution.

Related

  • Feature ID: 7.2.3
  • Closes: N/A
  • Follow-up PR(s)/TODOs: Backend proxy routes for /agent-integrations/tinyfish/search, /agent-integrations/tinyfish/fetch, and /agent-integrations/tinyfish/agent/run if not already deployed.

AI Authored PR Metadata (required for Codex/Linear PRs)

Linear Issue

  • Key: N/A
  • URL: N/A

Commit & Branch

  • Branch: feat/tinyfish-integration
  • Commit SHA: 98094e099f26613ed1a421ce4c6d12292e6f36a8

Validation Run

  • pnpm --filter openhuman-app format:check
  • pnpm typecheck
  • Focused tests: cargo test --manifest-path Cargo.toml tinyfish --lib
  • Focused tests: cargo test --manifest-path Cargo.toml all_tools_registers_integration_families_when_enabled_and_signed_in --lib
  • Focused tests: cargo test --manifest-path Cargo.toml fake_backend --lib
  • Focused tests: cargo test --manifest-path Cargo.toml pricing_for_config_short_circuits_in_direct_mode --lib
  • Focused tests: cargo test --manifest-path Cargo.toml integration_pricing_defaults_on_missing_fields --lib
  • Rust fmt/check (if changed): cargo fmt --manifest-path Cargo.toml -- --check
  • Tauri fmt/check (if changed): repo pre-push hook completed pnpm --filter openhuman-app rust:format:check and pnpm --filter openhuman-app rust:check
  • Repo pre-push hook completed on final push after initializing vendored submodules and installing documented ninja prerequisite; eslint reported existing warnings but no errors.

Validation Blocked

  • N/A

Behavior Changes

  • Intended behavior change: Signed-in users with TinyFish enabled get three new integration tools in the agent/tool registry.
  • User-visible effect: The assistant can search, fetch rendered page content, or run TinyFish browser automations once backend proxy routes are available.

Parity Contract

  • Legacy behavior preserved: Existing integration families and Composio routing remain unchanged; TinyFish is additive and behind the same integration-toggle pattern.
  • Guard/fallback/dispatch parity checks: Fake backend tests assert TinyFish request paths and payload shape through the existing IntegrationClient dispatch path.

Duplicate / Superseded PR Handling

  • Duplicate PR(s): N/A
  • Canonical PR: This PR
  • Resolution (closed/superseded/updated): N/A

Summary by CodeRabbit

  • New Features
    • TinyFish Web Automation added with three capabilities:
      • Web search with location/language options
      • Multi-page fetch and content extraction
      • Goal-based browser automation (agent runs)
    • TinyFish can be enabled/disabled in app settings (Beta)
  • Documentation
    • Test-coverage matrix updated to include TinyFish coverage totals

Review Change Stack

@pranavjana pranavjana requested a review from a team May 18, 2026 15:37
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 18, 2026

📝 Walkthrough

Walkthrough

Adds TinyFish web-search, page-fetch, and browser-automation tools: configuration toggles and pricing fields, three Tool implementations that proxy via IntegrationClient, fake-backend routes and tests, runtime registration and integration tests, and documentation/catalog updates.

Changes

TinyFish Integration Tools

Layer / File(s) Summary
Configuration schema and integration types
src/openhuman/config/schema/tools.rs, src/openhuman/integrations/types.rs, src/openhuman/integrations/mod.rs, src/openhuman/composio/client_tests.rs
IntegrationsConfig gains a tinyfish toggle field; IntegrationToggle shape changed (mode/api_key/is_active) with tests; PricingIntegrations adds optional tinyfish pricing; integrations module declares and re-exports TinyFish tool types; pricing/defaults and client tests verify tinyfish defaults to None.
TinyFish tool implementations
src/openhuman/integrations/tinyfish.rs
Module docs/imports and helpers; three tools (TinyFishSearchTool, TinyFishFetchTool, TinyFishAgentRunTool) validate request parameters, call IntegrationClient endpoints, format responses (including costs and truncation), and return ToolResults.
Unit and deserialization tests for TinyFish tools
src/openhuman/integrations/tinyfish_tests.rs
Test helper creates IntegrationClient; tests validate tool metadata and parameter schemas; async tests assert input validation errors; deserialization tests cover search/fetch/agent-run responses.
Fake integration backend routes
src/openhuman/integrations/test_support.rs, src/openhuman/integrations/test_support_test.rs
Adds three POST endpoints to fake backend that record requests and return deterministic JSON; backend test exercises agent/run and asserts returned status and result fields.
Tool registration and integration tests
src/openhuman/tools/ops.rs, src/openhuman/tools/ops_tests.rs
Runtime conditionally registers TinyFish tools when enabled; test config enables tinyfish; registry test expects three tinyfish tools; new Tokio test executes search/fetch/agent-run against fake backend and verifies outputs and request payloads.
User-facing documentation
src/openhuman/about_app/catalog.rs, docs/TEST-COVERAGE-MATRIX.md
Capability entry added to in-app catalog (Beta, DERIVED_TO_BACKEND privacy); test coverage matrix updated and summary counts adjusted.

Sequence Diagram(s)

sequenceDiagram
  participant Agent
  participant TinyFishSearchTool
  participant TinyFishFetchTool
  participant TinyFishAgentRunTool
  participant IntegrationClient
  participant Backend
  Agent->>TinyFishSearchTool: invoke(search args)
  TinyFishSearchTool->>IntegrationClient: POST /agent-integrations/tinyfish/search
  IntegrationClient->>Backend: forward search request
  Backend->>IntegrationClient: search response
  IntegrationClient->>TinyFishSearchTool: response
  TinyFishSearchTool->>Agent: ToolResult

  Agent->>TinyFishFetchTool: invoke(fetch args)
  TinyFishFetchTool->>IntegrationClient: POST /agent-integrations/tinyfish/fetch
  IntegrationClient->>Backend: forward fetch request
  Backend->>IntegrationClient: fetch response
  IntegrationClient->>TinyFishFetchTool: response
  TinyFishFetchTool->>Agent: ToolResult

  Agent->>TinyFishAgentRunTool: invoke(agent run args)
  TinyFishAgentRunTool->>IntegrationClient: POST /agent-integrations/tinyfish/agent/run
  IntegrationClient->>Backend: forward agent.run request
  Backend->>IntegrationClient: agent.run response
  IntegrationClient->>TinyFishAgentRunTool: response
  TinyFishAgentRunTool->>Agent: ToolResult
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested reviewers

  • senamakel

"🐰 I hopped through code with a cheerful squeak,
TinyFish tools now search, fetch, and peek,
Fake backend logs the tales they seek,
Tests pass the crumbs; the rabbit grins cheek-to-cheek."

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 54.72% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Add TinyFish integration tools' directly and clearly summarizes the main change—introducing three new TinyFish backend-proxied tools (search, fetch, agent run) integrated into the OpenHuman platform.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot added the working A PR that is being worked on by the team. label May 18, 2026
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (3)
src/openhuman/integrations/tinyfish.rs (3)

310-418: ⚡ Quick win

Add debug logging on the error path.

The fetch tool logs at debug level on entry (line 339) but omits logging when the POST fails at line 416.

📊 Observability improvement
         match self
             .client
             .post::<TinyFishFetchResponse>("/agent-integrations/tinyfish/fetch", &body)
             .await
         {
             Ok(resp) => {
                 // ... existing success handling ...
             }
-            Err(e) => Ok(ToolResult::error(format!("TinyFish fetch failed: {e}"))),
+            Err(e) => {
+                tracing::debug!(error = %e, "[tinyfish_fetch] request failed");
+                Ok(ToolResult::error(format!("TinyFish fetch failed: {e}")))
+            }
         }

As per coding guidelines: use tracing at debug or trace level for error paths.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/openhuman/integrations/tinyfish.rs` around lines 310 - 418, The execute
method logs entry but doesn't emit debug info when the POST fails; update the
error path that handles the client.post::<TinyFishFetchResponse> call (the
Err(e) arm) to emit a tracing::debug (or tracing::error) with the error details
and relevant context (e.g., url_count or normalized_urls and request body)
before returning ToolResult::error, so failures are recorded with the actual
error and helpful context for debugging.

493-563: ⚡ Quick win

Use debug level and add error-path logging for consistency.

Line 527 uses info level, while search/fetch use debug. Line 558 returns an error without logging it first.

📊 Observability improvements
-        tracing::info!(url = url, "[tinyfish_agent_run] starting automation");
+        tracing::debug!(url = url, "[tinyfish_agent_run] starting automation");

         match self
             .client
             .post::<TinyFishAgentRunResponse>("/agent-integrations/tinyfish/agent/run", &body)
             .await
         {
             Ok(resp) => {
                 // ... existing success handling ...
             }
-            Err(e) => Ok(ToolResult::error(format!(
-                "TinyFish automation failed: {e}"
-            ))),
+            Err(e) => {
+                tracing::debug!(error = %e, "[tinyfish_agent_run] request failed");
+                Ok(ToolResult::error(format!("TinyFish automation failed: {e}")))
+            }
         }

As per coding guidelines: use tracing at debug or trace level for RPC entry/exit and error paths.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/openhuman/integrations/tinyfish.rs` around lines 493 - 563, The execute
method currently logs the RPC start at info level and returns errors without
logging; change tracing::info!(url = url, "[tinyfish_agent_run] starting
automation") to tracing::debug! (or trace per guidelines) and add a
tracing::debug/error log in the Err(e) branch that includes the url and the
error (and any run_id if available) before returning ToolResult::error; also add
a debug log on successful response exit (e.g., include resp.run_id, resp.status,
resp.error) to keep entry/exit and error-path observability consistent in
execute.

184-249: ⚡ Quick win

Consider debug-level logging on error path and aligning success-path log level.

Line 200 correctly uses debug level for the happy path, but line 247 returns an error without logging it first. Line 527 in agent_run uses info instead of debug.

📊 Observability improvements

Add debug logging on the error path:

         match self
             .client
             .post::<TinyFishSearchResponse>("/agent-integrations/tinyfish/search", &body)
             .await
         {
             Ok(resp) => {
                 // ... existing success handling ...
             }
-            Err(e) => Ok(ToolResult::error(format!("TinyFish search failed: {e}"))),
+            Err(e) => {
+                tracing::debug!(error = %e, "[tinyfish_search] request failed");
+                Ok(ToolResult::error(format!("TinyFish search failed: {e}")))
+            }
         }

As per coding guidelines: use tracing at debug or trace level for RPC entry/exit and error paths.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/openhuman/integrations/tinyfish.rs` around lines 184 - 249, The execute
method currently logs the happy path with tracing::debug but does not log
errors; add a tracing::debug (or tracing::trace if you prefer finer verbosity)
in the Err branch of TinyFishIntegration::execute before returning
ToolResult::error to record the error and request context (include query and
body summary); ensure the existing tracing::debug at the start of execute
remains. Also update the logging call in agent_run (which currently uses
tracing::info) to tracing::debug so RPC entry/exit and error paths use the same
debug-level convention.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@docs/TEST-COVERAGE-MATRIX.md`:
- Line 259: The summary totals in the "## Summary" block of
TEST-COVERAGE-MATRIX.md are out of date after adding the new "7.2.3 | TinyFish
Integration Tools" row; open that file, locate the "## Summary" table and
increment the overall covered leaf count and the total leaf count to reflect the
newly covered leaf (the new row references
src/openhuman/integrations/tinyfish_tests.rs and
src/openhuman/tools/ops_tests.rs::all_tools_executes_tinyfish_family_against_fake_backend),
then verify any derived percentages or aggregate subtotals in the same summary
table are recalculated accordingly so the matrix remains internally consistent.

---

Nitpick comments:
In `@src/openhuman/integrations/tinyfish.rs`:
- Around line 310-418: The execute method logs entry but doesn't emit debug info
when the POST fails; update the error path that handles the
client.post::<TinyFishFetchResponse> call (the Err(e) arm) to emit a
tracing::debug (or tracing::error) with the error details and relevant context
(e.g., url_count or normalized_urls and request body) before returning
ToolResult::error, so failures are recorded with the actual error and helpful
context for debugging.
- Around line 493-563: The execute method currently logs the RPC start at info
level and returns errors without logging; change tracing::info!(url = url,
"[tinyfish_agent_run] starting automation") to tracing::debug! (or trace per
guidelines) and add a tracing::debug/error log in the Err(e) branch that
includes the url and the error (and any run_id if available) before returning
ToolResult::error; also add a debug log on successful response exit (e.g.,
include resp.run_id, resp.status, resp.error) to keep entry/exit and error-path
observability consistent in execute.
- Around line 184-249: The execute method currently logs the happy path with
tracing::debug but does not log errors; add a tracing::debug (or tracing::trace
if you prefer finer verbosity) in the Err branch of TinyFishIntegration::execute
before returning ToolResult::error to record the error and request context
(include query and body summary); ensure the existing tracing::debug at the
start of execute remains. Also update the logging call in agent_run (which
currently uses tracing::info) to tracing::debug so RPC entry/exit and error
paths use the same debug-level convention.
🪄 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: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 091e4172-6c73-43ef-9a68-575ed5d39977

📥 Commits

Reviewing files that changed from the base of the PR and between 0b053c5 and 30a9f7f.

📒 Files selected for processing (12)
  • docs/TEST-COVERAGE-MATRIX.md
  • src/openhuman/about_app/catalog.rs
  • src/openhuman/composio/client_tests.rs
  • src/openhuman/config/schema/tools.rs
  • src/openhuman/integrations/mod.rs
  • src/openhuman/integrations/test_support.rs
  • src/openhuman/integrations/test_support_test.rs
  • src/openhuman/integrations/tinyfish.rs
  • src/openhuman/integrations/tinyfish_tests.rs
  • src/openhuman/integrations/types.rs
  • src/openhuman/tools/ops.rs
  • src/openhuman/tools/ops_tests.rs

Comment thread docs/TEST-COVERAGE-MATRIX.md
coderabbitai[bot]
coderabbitai Bot previously approved these changes May 18, 2026
@senamakel senamakel self-assigned this May 19, 2026
senamakel added 2 commits May 19, 2026 16:38
# Conflicts:
#	src/openhuman/config/schema/tools.rs
Extends `IntegrationToggle` with `mode` ("managed" | "byo") and
`api_key`. Adds `is_active()` that returns true iff:

  - `enabled = true` AND `mode = "managed"` (current behavior — the
    OpenHuman backend owns the upstream key), OR
  - `enabled = true` AND `mode = "byo"` AND `api_key` is a non-empty
    trimmed string.

Tool registration for apify, google_places, parallel, tinyfish,
stock_prices, and twilio now goes through `is_active()` so a BYO
toggle without a key never registers the tools — matching the rule
the upcoming Search Engines settings panel will surface to users.

Default behavior is unchanged: integrations default to managed mode
with no api_key, so existing configs continue to register tools as
soon as `enabled = true`.

Follow-up: a Search Engines settings panel (TinyFish, Parallel,
Google Places) needs a write-capable config RPC analogous to
composio_set_api_key / composio_clear_api_key. Tracked separately.
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/openhuman/config/schema/tools.rs`:
- Around line 562-576: IntegrationToggle currently derives Debug which will
print the sensitive api_key; remove the automatic Debug derive and provide a
manual impl Debug for IntegrationToggle (or drop Debug entirely) that redacts or
omits the api_key field when formatting, similar to the
PolymarketClobCredentials implementation later in this file; keep the existing
derives for Clone/Serialize/Deserialize/JsonSchema and ensure the manual Debug
impl references the struct name and prints enabled and mode but replaces api_key
with a constant like "<redacted>" or nothing.
- Around line 583-594: The is_active helper currently treats any mode other than
INTEGRATION_MODE_BYO as active; change it to fail closed by only returning true
for known, valid modes. Update the match on self.mode.as_str() in is_active:
keep the INTEGRATION_MODE_BYO arm that validates api_key using
api_key.as_deref().map(|s| !s.trim().is_empty()).unwrap_or(false), add an
explicit arm for the legitimate managed mode (e.g., INTEGRATION_MODE_MANAGED)
that returns true, and make the wildcard (_) arm return false so unknown/typo
modes are treated as inactive; ensure you reference the enabled field early as
the current guard remains.
🪄 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: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: dca5efbf-fe62-4316-b892-584733e9665e

📥 Commits

Reviewing files that changed from the base of the PR and between 98094e0 and 9623abc.

📒 Files selected for processing (3)
  • docs/TEST-COVERAGE-MATRIX.md
  • src/openhuman/about_app/catalog.rs
  • src/openhuman/config/schema/tools.rs
✅ Files skipped from review due to trivial changes (1)
  • docs/TEST-COVERAGE-MATRIX.md
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/openhuman/about_app/catalog.rs

Comment on lines 562 to +576
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
#[serde(default)]
pub struct IntegrationToggle {
#[serde(default = "defaults::default_true")]
pub enabled: bool,
/// Routing mode. One of [`INTEGRATION_MODE_MANAGED`] (default — the
/// OpenHuman backend proxies the call) or [`INTEGRATION_MODE_BYO`]
/// (the user's own API key is required and tools refuse to
/// register without it).
#[serde(default = "default_integration_mode")]
pub mode: String,
/// API key for [`INTEGRATION_MODE_BYO`]. Ignored in managed mode.
/// Trimmed empty / `None` ⇒ no BYO key configured.
#[serde(default)]
pub api_key: Option<String>,
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Redact api_key from Debug.

IntegrationToggle now contains a secret but still derives Debug, so any {:?} log of this config will print the raw BYO key. Please switch to a manual Debug impl, like PolymarketClobCredentials does later in this file, or drop the derive entirely.

Proposed fix
-#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
+#[derive(Clone, Serialize, Deserialize, JsonSchema)]
 #[serde(default)]
 pub struct IntegrationToggle {
     #[serde(default = "defaults::default_true")]
     pub enabled: bool,
@@
     #[serde(default)]
     pub api_key: Option<String>,
 }
+
+impl std::fmt::Debug for IntegrationToggle {
+    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+        f.debug_struct("IntegrationToggle")
+            .field("enabled", &self.enabled)
+            .field("mode", &self.mode)
+            .field("api_key", &self.api_key.as_ref().map(|_| "<redacted>"))
+            .finish()
+    }
+}

As per coding guidelines, "Never log secrets, raw JWTs, API keys, or full PII — redact or omit sensitive fields."

📝 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.

Suggested change
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
#[serde(default)]
pub struct IntegrationToggle {
#[serde(default = "defaults::default_true")]
pub enabled: bool,
/// Routing mode. One of [`INTEGRATION_MODE_MANAGED`] (default — the
/// OpenHuman backend proxies the call) or [`INTEGRATION_MODE_BYO`]
/// (the user's own API key is required and tools refuse to
/// register without it).
#[serde(default = "default_integration_mode")]
pub mode: String,
/// API key for [`INTEGRATION_MODE_BYO`]. Ignored in managed mode.
/// Trimmed empty / `None` ⇒ no BYO key configured.
#[serde(default)]
pub api_key: Option<String>,
#[derive(Clone, Serialize, Deserialize, JsonSchema)]
#[serde(default)]
pub struct IntegrationToggle {
#[serde(default = "defaults::default_true")]
pub enabled: bool,
/// Routing mode. One of [`INTEGRATION_MODE_MANAGED`] (default — the
/// OpenHuman backend proxies the call) or [`INTEGRATION_MODE_BYO`]
/// (the user's own API key is required and tools refuse to
/// register without it).
#[serde(default = "default_integration_mode")]
pub mode: String,
/// API key for [`INTEGRATION_MODE_BYO`]. Ignored in managed mode.
/// Trimmed empty / `None` ⇒ no BYO key configured.
#[serde(default)]
pub api_key: Option<String>,
}
impl std::fmt::Debug for IntegrationToggle {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("IntegrationToggle")
.field("enabled", &self.enabled)
.field("mode", &self.mode)
.field("api_key", &self.api_key.as_ref().map(|_| "<redacted>"))
.finish()
}
}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/openhuman/config/schema/tools.rs` around lines 562 - 576,
IntegrationToggle currently derives Debug which will print the sensitive
api_key; remove the automatic Debug derive and provide a manual impl Debug for
IntegrationToggle (or drop Debug entirely) that redacts or omits the api_key
field when formatting, similar to the PolymarketClobCredentials implementation
later in this file; keep the existing derives for
Clone/Serialize/Deserialize/JsonSchema and ensure the manual Debug impl
references the struct name and prints enabled and mode but replaces api_key with
a constant like "<redacted>" or nothing.

Comment on lines +583 to +594
pub fn is_active(&self) -> bool {
if !self.enabled {
return false;
}
match self.mode.as_str() {
INTEGRATION_MODE_BYO => self
.api_key
.as_deref()
.map(|s| !s.trim().is_empty())
.unwrap_or(false),
_ => true,
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Make unknown integration modes fail closed.

Any mode other than exact "byo" currently returns true, so a typo like "manged" or "BYO" still registers the integration as active. Since this helper is the registration gate, invalid values should be rejected or treated as inactive instead of silently enabling managed routing.

Proposed fix
     pub fn is_active(&self) -> bool {
         if !self.enabled {
             return false;
         }
         match self.mode.as_str() {
+            INTEGRATION_MODE_MANAGED => true,
             INTEGRATION_MODE_BYO => self
                 .api_key
                 .as_deref()
                 .map(|s| !s.trim().is_empty())
                 .unwrap_or(false),
-            _ => true,
+            _ => false,
         }
     }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/openhuman/config/schema/tools.rs` around lines 583 - 594, The is_active
helper currently treats any mode other than INTEGRATION_MODE_BYO as active;
change it to fail closed by only returning true for known, valid modes. Update
the match on self.mode.as_str() in is_active: keep the INTEGRATION_MODE_BYO arm
that validates api_key using api_key.as_deref().map(|s|
!s.trim().is_empty()).unwrap_or(false), add an explicit arm for the legitimate
managed mode (e.g., INTEGRATION_MODE_MANAGED) that returns true, and make the
wildcard (_) arm return false so unknown/typo modes are treated as inactive;
ensure you reference the enabled field early as the current guard remains.

@senamakel senamakel merged commit f684d30 into tinyhumansai:main May 20, 2026
29 checks passed
mtkik pushed a commit to mtkik/openhuman-meet that referenced this pull request May 21, 2026
Co-authored-by: Steven Enamakel <enamakel@tinyhumans.ai>
CodeGhost21 pushed a commit to CodeGhost21/openhuman that referenced this pull request May 22, 2026
Co-authored-by: Steven Enamakel <enamakel@tinyhumans.ai>
AusAgentSmith pushed a commit to AusAgentSmith/openhuman that referenced this pull request May 23, 2026
Co-authored-by: Steven Enamakel <enamakel@tinyhumans.ai>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

working A PR that is being worked on by the team.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants