Skip to content

refactor(core): relocate the web chat conduit out of channels/ (#5002)#5004

Merged
senamakel merged 15 commits into
tinyhumansai:mainfrom
oxoxDev:refactor/5002-relocate-web-chat-conduit
Jul 18, 2026
Merged

refactor(core): relocate the web chat conduit out of channels/ (#5002)#5004
senamakel merged 15 commits into
tinyhumansai:mainfrom
oxoxDev:refactor/5002-relocate-web-chat-conduit

Conversation

@oxoxDev

@oxoxDev oxoxDev commented Jul 16, 2026

Copy link
Copy Markdown
Collaborator

🥞 Stacked PR — merge order (bottom → top)

  1. fix(tauri): resolve macOS-gated clippy -D warnings blocking pre-push (#5018) #5020 — macOS clippy fix ← unblocks all macOS pushes
  2. refactor(core): relocate the web chat conduit out of channels/ (#5002) #5004 — web_chat conduit relocationthis PR
  3. gates-off smoke lane — voice asserts + test-exec step (to be opened)
  4. fix(learning): email-signature subscriber + rebuild trigger silently depend on channels being configured #5003 — learning channels-coupling fix (to be opened)
  5. feat(core): feature gate — channels & webviews #4801 — channels feature gate (top, last child of epic Feature gates for core subsystems — tracking (lightweight harness builds) #4795)

This is position 2/5. Merge #5020 first.

Note on the diff: this branch is rebased on top of #5020, so its push clears the macOS pre-push clippy hook (#5018). Because a cross-fork PR's base must be an upstream branch, base stays main and the 6 clippy commits from #5020 currently appear in this diff. They will disappear automatically once #5020 merges — I'll rebase this branch onto fresh main and only the 9 web_chat relocation commits will remain. Review the web_chat-scoped commits here; the fix(tauri): … commits belong to #5020.

#4801 depends on this relocation.


Summary

Problem

channels::providers::web was filed as a chat provider, declared in providers/mod.rs alongside telegram, discord, slack, whatsapp, wechat. It is not a pluggable medium — it is the in-app chat conduit: start_chat, cancel_chat_scoped, publish_web_channel_event, subscribe_web_channel_events, spawn_progress_bridge, ChatRequestMetadata, presentation::deliver_response. It sits there only because it implements the same Channel trait, and implementing Channel is not the same as being a medium.

The dependency graph makes the mis-filing concrete — the arrows point the wrong way for a "provider":

  • The mediums depend on the conduit. providers/telegram/remote_control.rs calls web::invalidate_thread_sessions; channels::bus calls web::start_chat + web::subscribe_web_channel_events; channels::proactive and channels::host::adapters call web::publish_web_channel_event; channels::runtime::startup registers the four web::register_*_surface_subscriber handlers. 11 sites inside channels/ in total.
  • The conduit depends on no medium. Every super:: import inside web/ resolved to web's own submodules — zero references to context, runtime, bus, proactive, host, relay_runtime, cli, controllers, commands, or routes.
  • The harness depends on the conduit. threads::ops, agent::task_dispatcher::{executor,registry}, agent::harness::session::runtime, core::socketio, core::jsonrpc, agentbox::invoker, cron::scheduler, flows::ops. Roughly two-thirds of all external references to channels reach providers::web specifically.
  • The four register_*_surface_subscriber entry points under it are approval / automation-halt / egress / artifact surfaces — agent-harness concerns, not channel concerns.

Why this blocks #4801. DomainSet::harness() (#4796) is defined as agent + memory + threads + config + security, with channels: false. Gating the conduit along with the mediums makes harness() a runtime configuration that cannot compile, because threads and agent reach into it. The compile-time and runtime axes would contradict each other.

This is the third instance of a pattern AGENTS.md already names:

The gate follows the real dependency graph, not the directory name.

Prior instances, both still outstanding: mcp_client::{sanitize, client} (a docs tool dials McpHttpClient; the orchestrator sanitizes skill descriptions through sanitize_for_llm) and meet_agent::wav (a dependency-free RIFF writer called by the always-on desktop_companion for STT).

Solution

Move channels/providers/web/openhuman/web_chat/ and repoint every call site. After this, channelsweb_chat is a one-way dependency: gated code depending on always-on code, which is the correct direction.

Two #[path] traps — both files lived in providers/ and were reached only via #[path] from web/mod.rs, so neither was declared in providers/mod.rs:

  • web_errors.rs (#[path = "../web_errors.rs"]) — moved into web_chat/, #[path] attribute dropped as it is now redundant.
  • web_tests.rs (#[cfg(test)] #[path = "../web_tests.rs"]) — moved too. Missing this would have silently dropped 100+ tests from the build with CI still green. The #[path = "web_tests.rs"] form is retained so the module keeps the name tests (no symbol renames).

No back-compat re-export. channels no longer exports web at all. A shim would defeat the purpose — channels would still export the conduit, and #4801 would break the re-export the moment it gates the module.

src/core/all.rs keeps DomainGroup::Channels on the conduit's controller registration; only the path changed. The web RPC surface therefore stays hidden by DomainSet::harness() at runtime exactly as today. #4801 will #[cfg] that registration site — changing the group here would be an unreviewed behaviour change.

Subscriber names (last commit, isolated deliberately): the four EventHandler::name() returns read channels::web::*, naming a module that no longer exists. Renamed to web_chat::*, matching the <domain>::<purpose> convention its siblings follow (cron::delivery, memory::conversations::persistence). This is log-output only: name() is consumed at src/core/event_bus/bus.rs:145,169 and both uses are tracing fields — dispatch filters on domains(), not name(). Verified nothing keys on the old strings (no classifier, filter, or frontend reference).

Two call sites did not fit the mechanical rewrite:

  • tests/raw_coverage/channels_large_round25_raw_coverage_e2e.rsuse ...::providers::web::{self, test_support as web_support} bound the local name web; the rewrite would have rebound it to web_chat and broken 7 bare web:: uses. Written as {self as web, ...} to preserve the local binding rather than churn 7 call sites.
  • src/openhuman/inference/provider/error_code.rs — carried a rustdoc intra-doc link to channels::providers::web_errors::classify_inference_error. Repointed.

cargo fmt reflowed 4 call sites (agent/task_dispatcher/registry.rs, agentbox/invoker.rs, channels/bus.rs, cron/scheduler.rs) purely because the shorter path now fits on fewer lines. Verified whitespace-only — identical fields, values, and ..Default::default().

Submission Checklist

  • N/A: pure relocation — no behaviour is added or changed, so there is no new happy path or failure path to cover. The conduit's existing 155 tests moved with it and pass unchanged.
  • N/A: no executable logic changed — every changed line is an import path, module declaration, or file location. diff-cover has no new behaviour to measure.
  • N/A: no feature rows added, removed, or renamed — this moves a module, it does not change the feature surface. (Stale conduit paths in docs/TEST-COVERAGE-MATRIX.md were refreshed to match.)
  • N/A: no matrix feature IDs are affected by this change.
  • No new external network dependencies introduced — no dependency changes at all.
  • N/A: no release-cut surface behaviour changes — the shipped desktop build is byte-identical; only internal module paths move.
  • Linked issue closed via Closes in the ## Related section

Impact

  • Platform: none user-facing. Desktop build is byte-identical — same code, same behaviour, different module path.
  • User-visible: none.
  • Binary size: unchanged. No dependency added or removed.
  • Migration/compat: none. No wire contract, schema, config, or RPC surface change. /schema output is identical.
  • Observability: four subscriber name() strings change in tracing output (channels::web::*web_chat::*). Nothing consumes them programmatically.
  • Security: none.
  • Risk: low. Mechanical move, verified by --all-targets (which compiles the test code) and a repo-wide grep proof returning zero hits for the old paths.

Related


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

Linear Issue

  • Key: N/A — GitHub-issue driven
  • URL: N/A

Commit & Branch

  • Branch: refactor/5002-relocate-web-chat-conduit
  • Commit SHA: d0dfce27d

Validation Run

  • N/A: pnpm --filter openhuman-app format:check — no frontend files changed
  • N/A: pnpm typecheck — no TypeScript changed
  • Focused tests: GGML_NATIVE=OFF cargo test --lib openhuman::web_chat155 passed; 0 failed. cargo test --lib core::all::tests55 passed; 0 failed
  • Rust fmt/check (core): cargo fmt --check clean; GGML_NATIVE=OFF cargo check --manifest-path Cargo.toml → 0 errors; --all-targets → 0 errors
  • Tauri fmt/check: GGML_NATIVE=OFF cargo check --manifest-path app/src-tauri/Cargo.toml passes (2m38s) — the shell still builds
  • Grep proof: grep -rn "channels::providers::web\|channels::web" src testszero hits

Pre-existing issue verified, not introduced: cargo test --lib openhuman::web_chat stack-overflows on the default stack at cancel_chat_cooperatively_stops_in_flight_turn. Reproduced identically on base 70c12ad2a under the old path (openhuman::channels::providers::web::tests::cancel_chat_cooperatively_stops_in_flight_turnfatal runtime error: stack overflow), so it predates this change. All 155 pass with RUST_MIN_STACK=33554432. Same deep-async-stack class as the known task_local::scope case.

Summary by CodeRabbit

  • New Features

    • Improved web chat response delivery with segmented bubbles, first-bubble reactions/citations, and terminal usage details.
    • Added richer live web chat progress, including periodic inference heartbeats and better tool output forwarding with safe truncation.
    • Added web chat controls for queue status/clearing and more precise, thread-scoped cancellation.
    • Added centralized web error classification with safer, user-friendly messaging plus retry guidance and optional provider detail.
  • Bug Fixes

    • Improved retry/session recovery after rejected or malformed provider/tool history cases.
    • More consistent handling of timeouts, rate-limits (including Retry-After parsing), and empty-provider responses while preserving full content on segmentation.

@oxoxDev
oxoxDev requested a review from a team July 16, 2026 20:35
@coderabbitai

coderabbitai Bot commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

The web chat conduit is relocated from channels::providers::web to openhuman::web_chat. Runtime wiring, session and turn execution, presentation, progress events, schemas, error classification, tests, and documentation now reference the new module.

Changes

Web chat conduit relocation

Layer / File(s) Summary
Contracts, sessions, schemas, and errors
src/openhuman/web_chat/{mod,types,session,schemas,web_errors}.rs
Adds web-chat request types, session fingerprints, controller schemas, parameter handlers, and structured inference-error classification.
Turn execution and presentation
src/openhuman/web_chat/{run_task,presentation,progress_bridge}.rs, src/openhuman/web_chat/ops.rs
Implements cached and parallel turn execution, segmented response delivery, progress events, telemetry, tool-output capping, and inference heartbeats.
Runtime integration
src/core/*, src/openhuman/channels/*, src/openhuman/flows/ops.rs, src/openhuman/agent/*, src/openhuman/cron/scheduler.rs
Redirects controller registration, Socket.IO/SSE bridges, channel ingress, surface subscribers, autonomous flows, cron events, and session invalidation to web_chat.
Validation and references
src/openhuman/web_chat/*_tests.rs, tests/*, docs/*, src/openhuman/**/README.md, app/src-tauri/*
Updates coverage, imports, approval helpers, documentation references, and small macOS/application support changes.

Estimated code review effort: 5 (Critical) | ~120 minutes

Possibly related PRs

Suggested labels: rust-core, working

Suggested reviewers: senamakel

Poem

A rabbit moved chat from an old channel nest,
To web_chat, where new pathways rest.
Heartbeats hop and errors speak plain,
Tests guard each turn through sun and rain.
The conduit now bounds through code bright—
Squeak, relocated just right!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Out of Scope Changes check ⚠️ Warning The diff also includes unrelated cleanup edits in Tauri/app files and chat service docs that are not part of the web chat relocation. Remove the unrelated app/src-tauri and chatService changes, or split them into a separate PR focused on the web chat move.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed The PR relocates the web chat conduit to openhuman::web_chat, updates callers, moves web_errors/tests, and removes the old export as requested.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main refactor: moving web chat out of channels into web_chat.

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

@coderabbitai coderabbitai Bot added the rust-core Core Rust runtime in src/: CLI, core_server, shared infrastructure. label Jul 16, 2026

@coderabbitai coderabbitai Bot left a comment

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.

Actionable comments posted: 7

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/openhuman/channels/bus.rs (1)

92-101: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Update the stale web-chat diagnostic source label.

start_chat now comes from openhuman::web_chat, but src/openhuman/web_chat/ops.rs still reports the prompt-enforcement source as channels.providers.web.start_chat. Update that label to the canonical web_chat path so logs and security diagnostics do not retain the removed module reference.

As per coding guidelines, new or changed flows must include verbose, grep-friendly diagnostics; the relocation also requires stale old-path references to be removed.

🤖 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/channels/bus.rs` around lines 92 - 101, Update the
prompt-enforcement diagnostic source label used by start_chat in
openhuman::web_chat to the canonical web_chat path, removing the stale
channels.providers.web.start_chat reference. Keep the existing diagnostic
behavior and ensure no remaining logs or security diagnostics retain the removed
module path.

Source: Coding guidelines

🧹 Nitpick comments (3)
src/openhuman/web_chat/web_tests.rs (2)

1935-1982: 📐 Maintainability & Code Quality | 🔵 Trivial | 🏗️ Heavy lift

Prove that both turn futures execute concurrently.

These tests only observe entries registered in IN_FLIGHT/PARALLEL_IN_FLIGHT. They can pass even if execution is serialized after registration; the shared started: AtomicBool proves only that at least one task was polled. Use an active-task counter or two-party barrier and wait until both parked futures have entered concurrently.

As per coding guidelines, changed behavior must be proved in Rust.

Also applies to: 2131-2181

🤖 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/web_chat/web_tests.rs` around lines 1935 - 1982, Strengthen
start_chat_runs_distinct_threads_concurrently and the analogous test around the
shared started AtomicBool so the assertion observes execution, not only
IN_FLIGHT registration. Add an active-task counter or two-party barrier to
run_chat_task and wait until both distinct-thread futures are simultaneously
parked inside execution, then assert that condition before completing cleanup.

Source: Coding guidelines


1-12: 📐 Maintainability & Code Quality | 🔵 Trivial | 🏗️ Heavy lift

Split the oversized relocated web-chat modules into focused files.

  • src/openhuman/web_chat/web_tests.rs#L1-L12: separate classifier, schemas, session cache, and concurrency tests.
  • src/openhuman/web_chat/web_errors.rs#L1-L14: separate parsing, predicates, managed-code classification, and user-facing messages.

As per coding guidelines, prefer Rust files of approximately 500 lines or fewer.

🤖 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/web_chat/web_tests.rs` around lines 1 - 12, Split the oversized
web-chat modules into focused Rust files of approximately 500 lines or fewer: in
src/openhuman/web_chat/web_tests.rs lines 1-12, separate classifier, schema,
session-cache, and concurrency tests while preserving their existing behavior
and imports; in src/openhuman/web_chat/web_errors.rs lines 1-14, separate
parsing, predicate, managed-code classification, and user-facing message logic
into focused modules, updating module declarations and imports accordingly.

Source: Coding guidelines

src/openhuman/web_chat/progress_bridge.rs (1)

308-1457: 📐 Maintainability & Code Quality | 🔵 Trivial | 🏗️ Heavy lift

Split the bridge orchestration into focused modules.

spawn_progress_bridge combines every parent/subagent lifecycle branch, ledger persistence, wire presentation, heartbeats, and trace export in one 1,149-line function. Extract event handlers and move tests into sibling modules.

As per coding guidelines, “Prefer files of approximately 500 lines or fewer.”

🤖 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/web_chat/progress_bridge.rs` around lines 308 - 1457, Refactor
spawn_progress_bridge into focused sibling modules, extracting parent and
subagent event handling, ledger persistence, wire-event publishing, heartbeat
processing, and trace-export finalization while preserving behavior and shared
state. Keep spawn_progress_bridge as the orchestration loop that delegates to
these handlers, and move related tests into the corresponding modules; target
files of approximately 500 lines or fewer.

Source: Coding guidelines

🤖 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/approval/README.md`:
- Line 59: Update the architecture ownership statement for
ApprovalSurfaceSubscriber in the approval README to reference
src/openhuman/web_chat/, and remove the obsolete “No bus” wording while
preserving the surrounding documentation.

In `@src/openhuman/web_chat/presentation.rs`:
- Around line 220-225: Update segment_for_delivery and the additionally
referenced threshold and delay logic to use Unicode character counts via
chars().count() instead of str::len(), preserving the existing 80/40-character
behavior for actual characters. Add a boundary test covering multibyte CJK or
Arabic text at the relevant thresholds.
- Around line 64-73: The delivery flow around reaction_handle currently blocks
on optional reaction inference; wrap the reaction_handle await in a short
timeout, and if it expires, abort the task, log the timeout, and continue with
no reaction emoji. Preserve normal successful results and ensure segment and
chat_done delivery proceed without waiting indefinitely for try_reaction.

In `@src/openhuman/web_chat/session.rs`:
- Around line 182-203: Update build_session_fingerprint and
SessionCacheFingerprint to include the same normalized locale/directive used
when constructing the agent prompt, ensuring locale changes produce a distinct
fingerprint. Add or extend the session cache test to verify changing locale
causes a cache miss and agent rebuild.
- Around line 129-134: Update the short_thread calculation in the session
handling flow to truncate thread_id at a valid UTF-8 character boundary rather
than slicing at byte index 12. Preserve the 12-character maximum when possible,
avoid panics for multibyte thread IDs, and keep the existing
agent.set_agent_definition_name behavior.

In `@src/openhuman/web_chat/types.rs`:
- Around line 15-35: The session fingerprint must mirror all effective
agent-build inputs. In src/openhuman/web_chat/types.rs lines 15-35, add a
normalized locale field to SessionCacheFingerprint; in
src/openhuman/web_chat/run_task.rs lines 92-104, derive the provider role from
the model override or config.default_model and populate the locale fingerprint.
Add tests verifying locale changes and effective provider-binding changes force
a session rebuild.

In `@src/openhuman/web_chat/web_errors.rs`:
- Around line 739-750: Update the ClassifiedError construction to select message
and source together based on provider: retain the OpenHuman billing message for
provider "openhuman" or None, and use provider-specific upstream billing copy
for other providers while keeping source "provider". Pass the selected message
through with_provider_detail and preserve the existing retryability and metadata
fields.

---

Outside diff comments:
In `@src/openhuman/channels/bus.rs`:
- Around line 92-101: Update the prompt-enforcement diagnostic source label used
by start_chat in openhuman::web_chat to the canonical web_chat path, removing
the stale channels.providers.web.start_chat reference. Keep the existing
diagnostic behavior and ensure no remaining logs or security diagnostics retain
the removed module path.

---

Nitpick comments:
In `@src/openhuman/web_chat/progress_bridge.rs`:
- Around line 308-1457: Refactor spawn_progress_bridge into focused sibling
modules, extracting parent and subagent event handling, ledger persistence,
wire-event publishing, heartbeat processing, and trace-export finalization while
preserving behavior and shared state. Keep spawn_progress_bridge as the
orchestration loop that delegates to these handlers, and move related tests into
the corresponding modules; target files of approximately 500 lines or fewer.

In `@src/openhuman/web_chat/web_tests.rs`:
- Around line 1935-1982: Strengthen
start_chat_runs_distinct_threads_concurrently and the analogous test around the
shared started AtomicBool so the assertion observes execution, not only
IN_FLIGHT registration. Add an active-task counter or two-party barrier to
run_chat_task and wait until both distinct-thread futures are simultaneously
parked inside execution, then assert that condition before completing cleanup.
- Around line 1-12: Split the oversized web-chat modules into focused Rust files
of approximately 500 lines or fewer: in src/openhuman/web_chat/web_tests.rs
lines 1-12, separate classifier, schema, session-cache, and concurrency tests
while preserving their existing behavior and imports; in
src/openhuman/web_chat/web_errors.rs lines 1-14, separate parsing, predicate,
managed-code classification, and user-facing message logic into focused modules,
updating module declarations and imports accordingly.
🪄 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: ad14058d-aade-4b54-96b3-461e8bae7813

📥 Commits

Reviewing files that changed from the base of the PR and between 4eab04a and d0dfce2.

📒 Files selected for processing (67)
  • docs/TEST-COVERAGE-MATRIX.md
  • src/core/all.rs
  • src/core/event_bus/events.rs
  • src/core/jsonrpc.rs
  • src/core/observability.rs
  • src/core/socketio.rs
  • src/main.rs
  • src/openhuman/agent/README.md
  • src/openhuman/agent/progress_tracing/journal_projection.rs
  • src/openhuman/agent/task_dispatcher/executor.rs
  • src/openhuman/agent/task_dispatcher/registry.rs
  • src/openhuman/agent/triage/evaluator.rs
  • src/openhuman/agent/turn_origin.rs
  • src/openhuman/agent_orchestration/command_center/mod.rs
  • src/openhuman/agent_orchestration/run_ledger_finalize.rs
  • src/openhuman/agentbox/invoker.rs
  • src/openhuman/approval/README.md
  • src/openhuman/approval/gate.rs
  • src/openhuman/artifacts/store.rs
  • src/openhuman/channels/bus.rs
  • src/openhuman/channels/host/adapters.rs
  • src/openhuman/channels/mod.rs
  • src/openhuman/channels/proactive.rs
  • src/openhuman/channels/providers/mod.rs
  • src/openhuman/channels/providers/telegram/remote_control.rs
  • src/openhuman/channels/runtime/dispatch/processor.rs
  • src/openhuman/channels/runtime/startup.rs
  • src/openhuman/cron/scheduler.rs
  • src/openhuman/cron/scheduler_tests.rs
  • src/openhuman/flows/ops.rs
  • src/openhuman/inference/provider/error_code.rs
  • src/openhuman/meet_agent/brain/llm.rs
  • src/openhuman/mod.rs
  • src/openhuman/prompt_injection/README.md
  • src/openhuman/security/egress/mod.rs
  • src/openhuman/test_support/README.md
  • src/openhuman/test_support/introspect.rs
  • src/openhuman/threads/README.md
  • src/openhuman/threads/ops.rs
  • src/openhuman/wallet/README.md
  • src/openhuman/wallet/execution.rs
  • src/openhuman/web_chat/event_bus.rs
  • src/openhuman/web_chat/mod.rs
  • src/openhuman/web_chat/ops.rs
  • src/openhuman/web_chat/presentation.rs
  • src/openhuman/web_chat/presentation_tests.rs
  • src/openhuman/web_chat/progress_bridge.rs
  • src/openhuman/web_chat/run_task.rs
  • src/openhuman/web_chat/schemas.rs
  • src/openhuman/web_chat/session.rs
  • src/openhuman/web_chat/types.rs
  • src/openhuman/web_chat/web_errors.rs
  • src/openhuman/web_chat/web_tests.rs
  • tests/agent_harness_e2e.rs
  • tests/agentbox_e2e.rs
  • tests/composio_list_tools_stack_overflow_regression.rs
  • tests/raw_coverage/channels_bus_presentation_raw_coverage_e2e.rs
  • tests/raw_coverage/channels_large_round25_raw_coverage_e2e.rs
  • tests/raw_coverage/channels_provider_deep_raw_coverage_e2e.rs
  • tests/raw_coverage/channels_provider_leftovers_raw_coverage_e2e.rs
  • tests/raw_coverage/channels_runtime_raw_coverage_e2e.rs
  • tests/raw_coverage/channels_web_startup_raw_coverage_e2e.rs
  • tests/raw_coverage/channels_web_telegram_raw_coverage_e2e.rs
  • tests/raw_coverage/channels_web_yuanbao_round22_raw_coverage_e2e.rs
  • tests/raw_coverage/tools_approval_channels_raw_coverage_e2e.rs
  • tests/raw_coverage/tools_network_channels_raw_coverage_e2e.rs
  • tests/web_cancel_request_scoping.rs
💤 Files with no reviewable changes (2)
  • src/openhuman/channels/mod.rs
  • src/openhuman/channels/providers/mod.rs

@coderabbitai coderabbitai Bot left a comment

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.

Caution

Inline review comments failed to post. This is likely due to GitHub's internal server error or limits when posting large numbers of comments. If you are seeing this consistently it is likely a permissions issue. Please check "Moderation" -> "Code review limits" under your organization settings.

Actionable comments posted: 7

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/openhuman/channels/bus.rs (1)

92-101: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Update the stale web-chat diagnostic source label.

start_chat now comes from openhuman::web_chat, but src/openhuman/web_chat/ops.rs still reports the prompt-enforcement source as channels.providers.web.start_chat. Update that label to the canonical web_chat path so logs and security diagnostics do not retain the removed module reference.

As per coding guidelines, new or changed flows must include verbose, grep-friendly diagnostics; the relocation also requires stale old-path references to be removed.

🤖 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/channels/bus.rs` around lines 92 - 101, Update the
prompt-enforcement diagnostic source label used by start_chat in
openhuman::web_chat to the canonical web_chat path, removing the stale
channels.providers.web.start_chat reference. Keep the existing diagnostic
behavior and ensure no remaining logs or security diagnostics retain the removed
module path.

Source: Coding guidelines

🧹 Nitpick comments (3)
src/openhuman/web_chat/web_tests.rs (2)

1935-1982: 📐 Maintainability & Code Quality | 🔵 Trivial | 🏗️ Heavy lift

Prove that both turn futures execute concurrently.

These tests only observe entries registered in IN_FLIGHT/PARALLEL_IN_FLIGHT. They can pass even if execution is serialized after registration; the shared started: AtomicBool proves only that at least one task was polled. Use an active-task counter or two-party barrier and wait until both parked futures have entered concurrently.

As per coding guidelines, changed behavior must be proved in Rust.

Also applies to: 2131-2181

🤖 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/web_chat/web_tests.rs` around lines 1935 - 1982, Strengthen
start_chat_runs_distinct_threads_concurrently and the analogous test around the
shared started AtomicBool so the assertion observes execution, not only
IN_FLIGHT registration. Add an active-task counter or two-party barrier to
run_chat_task and wait until both distinct-thread futures are simultaneously
parked inside execution, then assert that condition before completing cleanup.

Source: Coding guidelines


1-12: 📐 Maintainability & Code Quality | 🔵 Trivial | 🏗️ Heavy lift

Split the oversized relocated web-chat modules into focused files.

  • src/openhuman/web_chat/web_tests.rs#L1-L12: separate classifier, schemas, session cache, and concurrency tests.
  • src/openhuman/web_chat/web_errors.rs#L1-L14: separate parsing, predicates, managed-code classification, and user-facing messages.

As per coding guidelines, prefer Rust files of approximately 500 lines or fewer.

🤖 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/web_chat/web_tests.rs` around lines 1 - 12, Split the oversized
web-chat modules into focused Rust files of approximately 500 lines or fewer: in
src/openhuman/web_chat/web_tests.rs lines 1-12, separate classifier, schema,
session-cache, and concurrency tests while preserving their existing behavior
and imports; in src/openhuman/web_chat/web_errors.rs lines 1-14, separate
parsing, predicate, managed-code classification, and user-facing message logic
into focused modules, updating module declarations and imports accordingly.

Source: Coding guidelines

src/openhuman/web_chat/progress_bridge.rs (1)

308-1457: 📐 Maintainability & Code Quality | 🔵 Trivial | 🏗️ Heavy lift

Split the bridge orchestration into focused modules.

spawn_progress_bridge combines every parent/subagent lifecycle branch, ledger persistence, wire presentation, heartbeats, and trace export in one 1,149-line function. Extract event handlers and move tests into sibling modules.

As per coding guidelines, “Prefer files of approximately 500 lines or fewer.”

🤖 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/web_chat/progress_bridge.rs` around lines 308 - 1457, Refactor
spawn_progress_bridge into focused sibling modules, extracting parent and
subagent event handling, ledger persistence, wire-event publishing, heartbeat
processing, and trace-export finalization while preserving behavior and shared
state. Keep spawn_progress_bridge as the orchestration loop that delegates to
these handlers, and move related tests into the corresponding modules; target
files of approximately 500 lines or fewer.

Source: Coding guidelines

🤖 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/approval/README.md`:
- Line 59: Update the architecture ownership statement for
ApprovalSurfaceSubscriber in the approval README to reference
src/openhuman/web_chat/, and remove the obsolete “No bus” wording while
preserving the surrounding documentation.

In `@src/openhuman/web_chat/presentation.rs`:
- Around line 220-225: Update segment_for_delivery and the additionally
referenced threshold and delay logic to use Unicode character counts via
chars().count() instead of str::len(), preserving the existing 80/40-character
behavior for actual characters. Add a boundary test covering multibyte CJK or
Arabic text at the relevant thresholds.
- Around line 64-73: The delivery flow around reaction_handle currently blocks
on optional reaction inference; wrap the reaction_handle await in a short
timeout, and if it expires, abort the task, log the timeout, and continue with
no reaction emoji. Preserve normal successful results and ensure segment and
chat_done delivery proceed without waiting indefinitely for try_reaction.

In `@src/openhuman/web_chat/session.rs`:
- Around line 182-203: Update build_session_fingerprint and
SessionCacheFingerprint to include the same normalized locale/directive used
when constructing the agent prompt, ensuring locale changes produce a distinct
fingerprint. Add or extend the session cache test to verify changing locale
causes a cache miss and agent rebuild.
- Around line 129-134: Update the short_thread calculation in the session
handling flow to truncate thread_id at a valid UTF-8 character boundary rather
than slicing at byte index 12. Preserve the 12-character maximum when possible,
avoid panics for multibyte thread IDs, and keep the existing
agent.set_agent_definition_name behavior.

In `@src/openhuman/web_chat/types.rs`:
- Around line 15-35: The session fingerprint must mirror all effective
agent-build inputs. In src/openhuman/web_chat/types.rs lines 15-35, add a
normalized locale field to SessionCacheFingerprint; in
src/openhuman/web_chat/run_task.rs lines 92-104, derive the provider role from
the model override or config.default_model and populate the locale fingerprint.
Add tests verifying locale changes and effective provider-binding changes force
a session rebuild.

In `@src/openhuman/web_chat/web_errors.rs`:
- Around line 739-750: Update the ClassifiedError construction to select message
and source together based on provider: retain the OpenHuman billing message for
provider "openhuman" or None, and use provider-specific upstream billing copy
for other providers while keeping source "provider". Pass the selected message
through with_provider_detail and preserve the existing retryability and metadata
fields.

---

Outside diff comments:
In `@src/openhuman/channels/bus.rs`:
- Around line 92-101: Update the prompt-enforcement diagnostic source label used
by start_chat in openhuman::web_chat to the canonical web_chat path, removing
the stale channels.providers.web.start_chat reference. Keep the existing
diagnostic behavior and ensure no remaining logs or security diagnostics retain
the removed module path.

---

Nitpick comments:
In `@src/openhuman/web_chat/progress_bridge.rs`:
- Around line 308-1457: Refactor spawn_progress_bridge into focused sibling
modules, extracting parent and subagent event handling, ledger persistence,
wire-event publishing, heartbeat processing, and trace-export finalization while
preserving behavior and shared state. Keep spawn_progress_bridge as the
orchestration loop that delegates to these handlers, and move related tests into
the corresponding modules; target files of approximately 500 lines or fewer.

In `@src/openhuman/web_chat/web_tests.rs`:
- Around line 1935-1982: Strengthen
start_chat_runs_distinct_threads_concurrently and the analogous test around the
shared started AtomicBool so the assertion observes execution, not only
IN_FLIGHT registration. Add an active-task counter or two-party barrier to
run_chat_task and wait until both distinct-thread futures are simultaneously
parked inside execution, then assert that condition before completing cleanup.
- Around line 1-12: Split the oversized web-chat modules into focused Rust files
of approximately 500 lines or fewer: in src/openhuman/web_chat/web_tests.rs
lines 1-12, separate classifier, schema, session-cache, and concurrency tests
while preserving their existing behavior and imports; in
src/openhuman/web_chat/web_errors.rs lines 1-14, separate parsing, predicate,
managed-code classification, and user-facing message logic into focused modules,
updating module declarations and imports accordingly.
🪄 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: ad14058d-aade-4b54-96b3-461e8bae7813

📥 Commits

Reviewing files that changed from the base of the PR and between 4eab04a and d0dfce2.

📒 Files selected for processing (67)
  • docs/TEST-COVERAGE-MATRIX.md
  • src/core/all.rs
  • src/core/event_bus/events.rs
  • src/core/jsonrpc.rs
  • src/core/observability.rs
  • src/core/socketio.rs
  • src/main.rs
  • src/openhuman/agent/README.md
  • src/openhuman/agent/progress_tracing/journal_projection.rs
  • src/openhuman/agent/task_dispatcher/executor.rs
  • src/openhuman/agent/task_dispatcher/registry.rs
  • src/openhuman/agent/triage/evaluator.rs
  • src/openhuman/agent/turn_origin.rs
  • src/openhuman/agent_orchestration/command_center/mod.rs
  • src/openhuman/agent_orchestration/run_ledger_finalize.rs
  • src/openhuman/agentbox/invoker.rs
  • src/openhuman/approval/README.md
  • src/openhuman/approval/gate.rs
  • src/openhuman/artifacts/store.rs
  • src/openhuman/channels/bus.rs
  • src/openhuman/channels/host/adapters.rs
  • src/openhuman/channels/mod.rs
  • src/openhuman/channels/proactive.rs
  • src/openhuman/channels/providers/mod.rs
  • src/openhuman/channels/providers/telegram/remote_control.rs
  • src/openhuman/channels/runtime/dispatch/processor.rs
  • src/openhuman/channels/runtime/startup.rs
  • src/openhuman/cron/scheduler.rs
  • src/openhuman/cron/scheduler_tests.rs
  • src/openhuman/flows/ops.rs
  • src/openhuman/inference/provider/error_code.rs
  • src/openhuman/meet_agent/brain/llm.rs
  • src/openhuman/mod.rs
  • src/openhuman/prompt_injection/README.md
  • src/openhuman/security/egress/mod.rs
  • src/openhuman/test_support/README.md
  • src/openhuman/test_support/introspect.rs
  • src/openhuman/threads/README.md
  • src/openhuman/threads/ops.rs
  • src/openhuman/wallet/README.md
  • src/openhuman/wallet/execution.rs
  • src/openhuman/web_chat/event_bus.rs
  • src/openhuman/web_chat/mod.rs
  • src/openhuman/web_chat/ops.rs
  • src/openhuman/web_chat/presentation.rs
  • src/openhuman/web_chat/presentation_tests.rs
  • src/openhuman/web_chat/progress_bridge.rs
  • src/openhuman/web_chat/run_task.rs
  • src/openhuman/web_chat/schemas.rs
  • src/openhuman/web_chat/session.rs
  • src/openhuman/web_chat/types.rs
  • src/openhuman/web_chat/web_errors.rs
  • src/openhuman/web_chat/web_tests.rs
  • tests/agent_harness_e2e.rs
  • tests/agentbox_e2e.rs
  • tests/composio_list_tools_stack_overflow_regression.rs
  • tests/raw_coverage/channels_bus_presentation_raw_coverage_e2e.rs
  • tests/raw_coverage/channels_large_round25_raw_coverage_e2e.rs
  • tests/raw_coverage/channels_provider_deep_raw_coverage_e2e.rs
  • tests/raw_coverage/channels_provider_leftovers_raw_coverage_e2e.rs
  • tests/raw_coverage/channels_runtime_raw_coverage_e2e.rs
  • tests/raw_coverage/channels_web_startup_raw_coverage_e2e.rs
  • tests/raw_coverage/channels_web_telegram_raw_coverage_e2e.rs
  • tests/raw_coverage/channels_web_yuanbao_round22_raw_coverage_e2e.rs
  • tests/raw_coverage/tools_approval_channels_raw_coverage_e2e.rs
  • tests/raw_coverage/tools_network_channels_raw_coverage_e2e.rs
  • tests/web_cancel_request_scoping.rs
💤 Files with no reviewable changes (2)
  • src/openhuman/channels/mod.rs
  • src/openhuman/channels/providers/mod.rs
🛑 Comments failed to post (7)
src/openhuman/approval/README.md (1)

59-59: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Remove the contradictory legacy ownership statement.

This update correctly points ApprovalSurfaceSubscriber to src/openhuman/web_chat/, but line 62 still says the subscriber lives in the channels web provider. Update that statement to src/openhuman/web_chat/ and remove the obsolete “No bus” wording.

As per coding guidelines, architecture documentation must be updated when module ownership changes.

🤖 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/approval/README.md` at line 59, Update the architecture
ownership statement for ApprovalSurfaceSubscriber in the approval README to
reference src/openhuman/web_chat/, and remove the obsolete “No bus” wording
while preserving the surrounding documentation.

Source: Coding guidelines

src/openhuman/web_chat/presentation.rs (2)

64-73: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Do not gate terminal delivery on optional reaction inference.

Spawning and immediately awaiting the task means no segment or chat_done event is emitted until the local-model call finishes. A slow or wedged reaction decision stalls an otherwise completed chat. Use a short timeout, then abort and skip the optional reaction while logging the outcome.

🤖 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/web_chat/presentation.rs` around lines 64 - 73, The delivery
flow around reaction_handle currently blocks on optional reaction inference;
wrap the reaction_handle await in a short timeout, and if it expires, abort the
task, log the timeout, and continue with no reaction emoji. Preserve normal
successful results and ensure segment and chat_done delivery proceed without
waiting indefinitely for try_reaction.

220-225: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Count characters rather than UTF-8 bytes.

str::len() makes CJK and Arabic text cross the 80/40-character thresholds too early and inflates delays. Use chars().count() consistently and add a multibyte boundary test.

Also applies to: 348-359, 412-426, 431-436

🤖 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/web_chat/presentation.rs` around lines 220 - 225, Update
segment_for_delivery and the additionally referenced threshold and delay logic
to use Unicode character counts via chars().count() instead of str::len(),
preserving the existing 80/40-character behavior for actual characters. Add a
boundary test covering multibyte CJK or Arabic text at the relevant thresholds.
src/openhuman/web_chat/session.rs (2)

129-134: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Truncate thread_id on character boundaries.

thread_id[..12] panics when byte 12 falls inside a multibyte UTF-8 character, aborting that chat turn.

Proposed fix
-            let short_thread = if thread_id.len() > 12 {
-                &thread_id[..12]
-            } else {
-                thread_id
-            };
+            let short_thread: String = thread_id.chars().take(12).collect();
             agent.set_agent_definition_name(format!("{target_agent_id}_{short_thread}"));
📝 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.

            let short_thread: String = thread_id.chars().take(12).collect();
            agent.set_agent_definition_name(format!("{target_agent_id}_{short_thread}"));
🤖 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/web_chat/session.rs` around lines 129 - 134, Update the
short_thread calculation in the session handling flow to truncate thread_id at a
valid UTF-8 character boundary rather than slicing at byte index 12. Preserve
the 12-character maximum when possible, avoid panics for multibyte thread IDs,
and keep the existing agent.set_agent_definition_name behavior.

182-203: 🎯 Functional Correctness | 🟠 Major | 🏗️ Heavy lift

Include locale-derived prompt state in the session fingerprint.

The agent prompt incorporates locale at Lines 87–91, but this fingerprint omits it. A locale change on the same thread therefore reuses the old localized agent. Add the normalized locale/directive to SessionCacheFingerprint and cover locale changes with a cache-miss test.

🤖 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/web_chat/session.rs` around lines 182 - 203, Update
build_session_fingerprint and SessionCacheFingerprint to include the same
normalized locale/directive used when constructing the agent prompt, ensuring
locale changes produce a distinct fingerprint. Add or extend the session cache
test to verify changing locale causes a cache miss and agent rebuild.
src/openhuman/web_chat/types.rs (1)

15-35: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Make the session fingerprint exactly mirror effective agent-build inputs.

The cache currently misses both a build input and the effective provider-role calculation, allowing stale agents to survive configuration changes.

  • src/openhuman/web_chat/types.rs#L15-L35: add normalized locale to SessionCacheFingerprint.
  • src/openhuman/web_chat/run_task.rs#L92-L104: derive the provider role from the override or config.default_model, and populate the locale fingerprint.

Add tests proving locale and effective provider-binding changes force a rebuild.

📍 Affects 2 files
  • src/openhuman/web_chat/types.rs#L15-L35 (this comment)
  • src/openhuman/web_chat/run_task.rs#L92-L104
🤖 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/web_chat/types.rs` around lines 15 - 35, The session
fingerprint must mirror all effective agent-build inputs. In
src/openhuman/web_chat/types.rs lines 15-35, add a normalized locale field to
SessionCacheFingerprint; in src/openhuman/web_chat/run_task.rs lines 92-104,
derive the provider role from the model override or config.default_model and
populate the locale fingerprint. Add tests verifying locale changes and
effective provider-binding changes force a session rebuild.
src/openhuman/web_chat/web_errors.rs (1)

739-750: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Use provider-specific copy for upstream billing failures.

For openrouter API error (402) and similar envelopes, source becomes "provider" but the message still says the managed OpenHuman model is out of credits. Select the message together with the source so users are directed to the correct billing system.

Proposed fix
-        let source: &'static str = match provider.as_deref() {
-            Some("openhuman") | None => "openhuman_billing",
-            Some(_) => "provider",
+        let (source, summary): (&'static str, &'static str) = match provider.as_deref() {
+            Some("openhuman") | None => (
+                "openhuman_billing",
+                inference_budget_exceeded_user_message(),
+            ),
+            Some(_) => (
+                "provider",
+                "Your AI provider reports an exhausted balance or billing restriction. \
+                 Update that provider's billing or plan settings to continue.",
+            ),
         };
         ClassifiedError {
             error_type: "budget_exhausted",
-            message: with_provider_detail(inference_budget_exceeded_user_message(), err),
+            message: with_provider_detail(summary, err),
📝 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.

        let (source, summary): (&'static str, &'static str) = match provider.as_deref() {
            Some("openhuman") | None => (
                "openhuman_billing",
                inference_budget_exceeded_user_message(),
            ),
            Some(_) => (
                "provider",
                "Your AI provider reports an exhausted balance or billing restriction. \
                 Update that provider's billing or plan settings to continue.",
            ),
        };
        ClassifiedError {
            error_type: "budget_exhausted",
            message: with_provider_detail(summary, err),
            source,
            retryable: false,
            retry_after_ms: None,
            provider,
            fallback_available: None,
🤖 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/web_chat/web_errors.rs` around lines 739 - 750, Update the
ClassifiedError construction to select message and source together based on
provider: retain the OpenHuman billing message for provider "openhuman" or None,
and use provider-specific upstream billing copy for other providers while
keeping source "provider". Pass the selected message through
with_provider_detail and preserve the existing retryability and metadata fields.

oxoxDev added 15 commits July 17, 2026 21:17
…5002)

Move channels/providers/web -> web_chat/, taking web_errors.rs and
web_tests.rs with it (both were reached via #[path] from web/mod.rs and
never declared in providers/mod.rs). Drop the now-redundant ../ path
attribute on web_errors. No back-compat re-export: channels no longer
exports web.
…humansai#5002)

The 5 channels/ modules that consume the conduit (bus, host::adapters,
proactive, telegram::remote_control, runtime::startup) now import it from
its new home. Dependency is one-way: channels -> web_chat.
)

Harness-family consumers (core::{socketio,jsonrpc,all,observability,
event_bus}, agent::task_dispatcher, threads::ops, agentbox::invoker,
cron::scheduler, flows::ops, test_support::introspect) now import the
conduit from openhuman::web_chat.

src/core/all.rs keeps its DomainGroup::Channels tag: the web RPC surface
must stay hidden by DomainSet::harness() at runtime exactly as today.
Re-tagging it would be an unreviewed behaviour change; tinyhumansai#4801 will cfg
this registration site instead.

rustfmt reflows 4 call sites purely because the shorter path now fits.
channels_large_round25 imported the module with {self}, which bound the
local name 'web'; rebound as {self as web} so its 7 bare web:: uses keep
resolving rather than renaming them.
Comment/README-only. Several already named a stale 'channels/providers/web.rs'
(the module has been a directory for a while); the move made them wrong twice
over. Historical plan snapshots under docs/plans, docs/superpowers and
docs/tinyagents-full-migration-plan are left as-is -- they record a past state.
…le (tinyhumansai#5002)

The four EventHandler::name() returns still read `channels::web::*`, naming a
module that no longer exists after the relocation. AGENTS.md's convention is
`<domain>::<purpose>`, and sibling subscribers follow it (`cron::delivery`,
`memory::conversations::persistence`).

Log-output only: `name()` is consumed at src/core/event_bus/bus.rs:145,169 and
both uses are tracing fields. Dispatch filters on `domains()`, not `name()`.
Verified nothing keys on the old strings — no classifier, filter, or frontend
reference.
…chat (tinyhumansai#5002)

The PromptEnforcementContext source label still read
`channels.providers.web.start_chat`, naming a module that no longer exists.
Siblings use the dotted module path (`agent.bus.run_turn`,
`agent.runtime.run_single`), so the canonical value is `web_chat.start_chat`.

Diagnostic-only: `source` is consumed at
src/openhuman/prompt_injection/detector.rs:504 as a `tracing::info!` field.
Verified nothing matches on the literal.

Caught by CodeRabbit on tinyhumansai#5004 — the original grep proof searched the Rust path
form (`channels::providers::web`) and was blind to the dot-separated string.
…nyhumansai#5002)

Comment referenced `channels/providers/web::ArtifactSurfaceSubscriber`; the
subscriber now lives in `web_chat`. Comment-only, no executable change.
@oxoxDev
oxoxDev force-pushed the refactor/5002-relocate-web-chat-conduit branch from d0dfce2 to bfd1997 Compare July 17, 2026 16:16
@coderabbitai coderabbitai Bot added the working A PR that is being worked on by the team. label Jul 17, 2026

@coderabbitai coderabbitai Bot left a comment

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.

Actionable comments posted: 1

🧹 Nitpick comments (1)
src/openhuman/web_chat/web_tests.rs (1)

1-12: 📐 Maintainability & Code Quality | 🔵 Trivial | 🏗️ Heavy lift

Split this 2,314-line test module by concern.

Separate validation, error-classification, schema/session, and concurrency tests into focused submodules under web_chat/web_tests/.

As per coding guidelines, Rust files should be approximately 500 lines or fewer.

🤖 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/web_chat/web_tests.rs` around lines 1 - 12, Split the oversized
web_tests module into focused submodules under web_chat/web_tests/, organizing
validation, error-classification, schema/session, and concurrency tests
separately. Update the module declarations and imports so all existing tests
continue to compile and run, while keeping each Rust file approximately 500
lines or fewer.

Source: Coding guidelines

🤖 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/web_chat/web_tests.rs`:
- Around line 18-31: Update the forced error/block override helpers and EnvGuard
used by start_chat/run_chat_task tests to return scoped, synchronous guards that
capture the exact prior state and restore it on Drop, including during panic or
timeout. Replace manual None resets and environment removal with guard
lifetimes, while retaining RUN_CHAT_TASK_TEST_LOCK for each test body so all
process-global mutations remain isolated.

---

Nitpick comments:
In `@src/openhuman/web_chat/web_tests.rs`:
- Around line 1-12: Split the oversized web_tests module into focused submodules
under web_chat/web_tests/, organizing validation, error-classification,
schema/session, and concurrency tests separately. Update the module declarations
and imports so all existing tests continue to compile and run, while keeping
each Rust file approximately 500 lines or fewer.
🪄 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: e28ff546-a3a9-4745-8d42-6bceecddde29

📥 Commits

Reviewing files that changed from the base of the PR and between d0dfce2 and bfd1997.

📒 Files selected for processing (74)
  • app/src-tauri/src/claude_code.rs
  • app/src-tauri/src/imessage_scanner/mod.rs
  • app/src-tauri/src/lib.rs
  • app/src-tauri/src/mascot_native_window.rs
  • app/src-tauri/src/native_notifications/mod.rs
  • app/src-tauri/src/notch_window.rs
  • app/src/services/chatService.ts
  • docs/TEST-COVERAGE-MATRIX.md
  • src/core/all.rs
  • src/core/event_bus/events.rs
  • src/core/jsonrpc.rs
  • src/core/observability.rs
  • src/core/socketio.rs
  • src/main.rs
  • src/openhuman/agent/README.md
  • src/openhuman/agent/progress_tracing/journal_projection.rs
  • src/openhuman/agent/task_dispatcher/executor.rs
  • src/openhuman/agent/task_dispatcher/registry.rs
  • src/openhuman/agent/triage/evaluator.rs
  • src/openhuman/agent/turn_origin.rs
  • src/openhuman/agent_orchestration/command_center/mod.rs
  • src/openhuman/agent_orchestration/run_ledger_finalize.rs
  • src/openhuman/agentbox/invoker.rs
  • src/openhuman/approval/README.md
  • src/openhuman/approval/gate.rs
  • src/openhuman/artifacts/store.rs
  • src/openhuman/channels/bus.rs
  • src/openhuman/channels/host/adapters.rs
  • src/openhuman/channels/mod.rs
  • src/openhuman/channels/proactive.rs
  • src/openhuman/channels/providers/mod.rs
  • src/openhuman/channels/providers/telegram/remote_control.rs
  • src/openhuman/channels/runtime/dispatch/processor.rs
  • src/openhuman/channels/runtime/startup.rs
  • src/openhuman/cron/scheduler.rs
  • src/openhuman/cron/scheduler_tests.rs
  • src/openhuman/flows/ops.rs
  • src/openhuman/inference/provider/error_code.rs
  • src/openhuman/meet_agent/brain/llm.rs
  • src/openhuman/mod.rs
  • src/openhuman/prompt_injection/README.md
  • src/openhuman/security/egress/mod.rs
  • src/openhuman/test_support/README.md
  • src/openhuman/test_support/introspect.rs
  • src/openhuman/threads/README.md
  • src/openhuman/threads/ops.rs
  • src/openhuman/wallet/README.md
  • src/openhuman/wallet/execution.rs
  • src/openhuman/web_chat/event_bus.rs
  • src/openhuman/web_chat/mod.rs
  • src/openhuman/web_chat/ops.rs
  • src/openhuman/web_chat/presentation.rs
  • src/openhuman/web_chat/presentation_tests.rs
  • src/openhuman/web_chat/progress_bridge.rs
  • src/openhuman/web_chat/run_task.rs
  • src/openhuman/web_chat/schemas.rs
  • src/openhuman/web_chat/session.rs
  • src/openhuman/web_chat/types.rs
  • src/openhuman/web_chat/web_errors.rs
  • src/openhuman/web_chat/web_tests.rs
  • tests/agent_harness_e2e.rs
  • tests/agentbox_e2e.rs
  • tests/composio_list_tools_stack_overflow_regression.rs
  • tests/raw_coverage/channels_bus_presentation_raw_coverage_e2e.rs
  • tests/raw_coverage/channels_large_round25_raw_coverage_e2e.rs
  • tests/raw_coverage/channels_provider_deep_raw_coverage_e2e.rs
  • tests/raw_coverage/channels_provider_leftovers_raw_coverage_e2e.rs
  • tests/raw_coverage/channels_runtime_raw_coverage_e2e.rs
  • tests/raw_coverage/channels_web_startup_raw_coverage_e2e.rs
  • tests/raw_coverage/channels_web_telegram_raw_coverage_e2e.rs
  • tests/raw_coverage/channels_web_yuanbao_round22_raw_coverage_e2e.rs
  • tests/raw_coverage/tools_approval_channels_raw_coverage_e2e.rs
  • tests/raw_coverage/tools_network_channels_raw_coverage_e2e.rs
  • tests/web_cancel_request_scoping.rs
💤 Files with no reviewable changes (2)
  • src/openhuman/channels/providers/mod.rs
  • src/openhuman/channels/mod.rs
🚧 Files skipped from review as they are similar to previous changes (55)
  • tests/raw_coverage/channels_web_yuanbao_round22_raw_coverage_e2e.rs
  • src/openhuman/agent/triage/evaluator.rs
  • src/openhuman/security/egress/mod.rs
  • src/openhuman/mod.rs
  • src/openhuman/web_chat/ops.rs
  • tests/raw_coverage/channels_web_startup_raw_coverage_e2e.rs
  • src/openhuman/channels/runtime/dispatch/processor.rs
  • tests/web_cancel_request_scoping.rs
  • src/openhuman/meet_agent/brain/llm.rs
  • tests/agentbox_e2e.rs
  • tests/raw_coverage/channels_web_telegram_raw_coverage_e2e.rs
  • tests/raw_coverage/channels_bus_presentation_raw_coverage_e2e.rs
  • src/openhuman/agent_orchestration/command_center/mod.rs
  • src/openhuman/artifacts/store.rs
  • src/core/event_bus/events.rs
  • src/openhuman/approval/gate.rs
  • src/openhuman/test_support/README.md
  • docs/TEST-COVERAGE-MATRIX.md
  • src/openhuman/agent/task_dispatcher/executor.rs
  • tests/raw_coverage/tools_network_channels_raw_coverage_e2e.rs
  • src/openhuman/inference/provider/error_code.rs
  • src/openhuman/approval/README.md
  • src/openhuman/channels/providers/telegram/remote_control.rs
  • src/openhuman/web_chat/event_bus.rs
  • tests/composio_list_tools_stack_overflow_regression.rs
  • tests/raw_coverage/channels_provider_leftovers_raw_coverage_e2e.rs
  • src/openhuman/threads/ops.rs
  • src/core/socketio.rs
  • src/openhuman/channels/bus.rs
  • src/openhuman/threads/README.md
  • src/main.rs
  • src/openhuman/channels/runtime/startup.rs
  • src/openhuman/cron/scheduler_tests.rs
  • src/openhuman/channels/host/adapters.rs
  • src/openhuman/test_support/introspect.rs
  • src/openhuman/web_chat/mod.rs
  • src/openhuman/wallet/README.md
  • src/openhuman/prompt_injection/README.md
  • src/openhuman/cron/scheduler.rs
  • tests/raw_coverage/channels_large_round25_raw_coverage_e2e.rs
  • src/core/jsonrpc.rs
  • src/openhuman/agentbox/invoker.rs
  • src/core/all.rs
  • src/core/observability.rs
  • src/openhuman/web_chat/session.rs
  • tests/raw_coverage/channels_provider_deep_raw_coverage_e2e.rs
  • src/openhuman/web_chat/run_task.rs
  • src/openhuman/flows/ops.rs
  • tests/raw_coverage/tools_approval_channels_raw_coverage_e2e.rs
  • src/openhuman/web_chat/presentation.rs
  • src/openhuman/web_chat/types.rs
  • src/openhuman/web_chat/schemas.rs
  • src/openhuman/web_chat/presentation_tests.rs
  • src/openhuman/web_chat/web_errors.rs
  • src/openhuman/web_chat/progress_bridge.rs

@coderabbitai coderabbitai Bot left a comment

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.

Caution

Inline review comments failed to post. This is likely due to GitHub's internal server error or limits when posting large numbers of comments. If you are seeing this consistently it is likely a permissions issue. Please check "Moderation" -> "Code review limits" under your organization settings.

Actionable comments posted: 1

🧹 Nitpick comments (1)
src/openhuman/web_chat/web_tests.rs (1)

1-12: 📐 Maintainability & Code Quality | 🔵 Trivial | 🏗️ Heavy lift

Split this 2,314-line test module by concern.

Separate validation, error-classification, schema/session, and concurrency tests into focused submodules under web_chat/web_tests/.

As per coding guidelines, Rust files should be approximately 500 lines or fewer.

🤖 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/web_chat/web_tests.rs` around lines 1 - 12, Split the oversized
web_tests module into focused submodules under web_chat/web_tests/, organizing
validation, error-classification, schema/session, and concurrency tests
separately. Update the module declarations and imports so all existing tests
continue to compile and run, while keeping each Rust file approximately 500
lines or fewer.

Source: Coding guidelines

🤖 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/web_chat/web_tests.rs`:
- Around line 18-31: Update the forced error/block override helpers and EnvGuard
used by start_chat/run_chat_task tests to return scoped, synchronous guards that
capture the exact prior state and restore it on Drop, including during panic or
timeout. Replace manual None resets and environment removal with guard
lifetimes, while retaining RUN_CHAT_TASK_TEST_LOCK for each test body so all
process-global mutations remain isolated.

---

Nitpick comments:
In `@src/openhuman/web_chat/web_tests.rs`:
- Around line 1-12: Split the oversized web_tests module into focused submodules
under web_chat/web_tests/, organizing validation, error-classification,
schema/session, and concurrency tests separately. Update the module declarations
and imports so all existing tests continue to compile and run, while keeping
each Rust file approximately 500 lines or fewer.
🪄 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: e28ff546-a3a9-4745-8d42-6bceecddde29

📥 Commits

Reviewing files that changed from the base of the PR and between d0dfce2 and bfd1997.

📒 Files selected for processing (74)
  • app/src-tauri/src/claude_code.rs
  • app/src-tauri/src/imessage_scanner/mod.rs
  • app/src-tauri/src/lib.rs
  • app/src-tauri/src/mascot_native_window.rs
  • app/src-tauri/src/native_notifications/mod.rs
  • app/src-tauri/src/notch_window.rs
  • app/src/services/chatService.ts
  • docs/TEST-COVERAGE-MATRIX.md
  • src/core/all.rs
  • src/core/event_bus/events.rs
  • src/core/jsonrpc.rs
  • src/core/observability.rs
  • src/core/socketio.rs
  • src/main.rs
  • src/openhuman/agent/README.md
  • src/openhuman/agent/progress_tracing/journal_projection.rs
  • src/openhuman/agent/task_dispatcher/executor.rs
  • src/openhuman/agent/task_dispatcher/registry.rs
  • src/openhuman/agent/triage/evaluator.rs
  • src/openhuman/agent/turn_origin.rs
  • src/openhuman/agent_orchestration/command_center/mod.rs
  • src/openhuman/agent_orchestration/run_ledger_finalize.rs
  • src/openhuman/agentbox/invoker.rs
  • src/openhuman/approval/README.md
  • src/openhuman/approval/gate.rs
  • src/openhuman/artifacts/store.rs
  • src/openhuman/channels/bus.rs
  • src/openhuman/channels/host/adapters.rs
  • src/openhuman/channels/mod.rs
  • src/openhuman/channels/proactive.rs
  • src/openhuman/channels/providers/mod.rs
  • src/openhuman/channels/providers/telegram/remote_control.rs
  • src/openhuman/channels/runtime/dispatch/processor.rs
  • src/openhuman/channels/runtime/startup.rs
  • src/openhuman/cron/scheduler.rs
  • src/openhuman/cron/scheduler_tests.rs
  • src/openhuman/flows/ops.rs
  • src/openhuman/inference/provider/error_code.rs
  • src/openhuman/meet_agent/brain/llm.rs
  • src/openhuman/mod.rs
  • src/openhuman/prompt_injection/README.md
  • src/openhuman/security/egress/mod.rs
  • src/openhuman/test_support/README.md
  • src/openhuman/test_support/introspect.rs
  • src/openhuman/threads/README.md
  • src/openhuman/threads/ops.rs
  • src/openhuman/wallet/README.md
  • src/openhuman/wallet/execution.rs
  • src/openhuman/web_chat/event_bus.rs
  • src/openhuman/web_chat/mod.rs
  • src/openhuman/web_chat/ops.rs
  • src/openhuman/web_chat/presentation.rs
  • src/openhuman/web_chat/presentation_tests.rs
  • src/openhuman/web_chat/progress_bridge.rs
  • src/openhuman/web_chat/run_task.rs
  • src/openhuman/web_chat/schemas.rs
  • src/openhuman/web_chat/session.rs
  • src/openhuman/web_chat/types.rs
  • src/openhuman/web_chat/web_errors.rs
  • src/openhuman/web_chat/web_tests.rs
  • tests/agent_harness_e2e.rs
  • tests/agentbox_e2e.rs
  • tests/composio_list_tools_stack_overflow_regression.rs
  • tests/raw_coverage/channels_bus_presentation_raw_coverage_e2e.rs
  • tests/raw_coverage/channels_large_round25_raw_coverage_e2e.rs
  • tests/raw_coverage/channels_provider_deep_raw_coverage_e2e.rs
  • tests/raw_coverage/channels_provider_leftovers_raw_coverage_e2e.rs
  • tests/raw_coverage/channels_runtime_raw_coverage_e2e.rs
  • tests/raw_coverage/channels_web_startup_raw_coverage_e2e.rs
  • tests/raw_coverage/channels_web_telegram_raw_coverage_e2e.rs
  • tests/raw_coverage/channels_web_yuanbao_round22_raw_coverage_e2e.rs
  • tests/raw_coverage/tools_approval_channels_raw_coverage_e2e.rs
  • tests/raw_coverage/tools_network_channels_raw_coverage_e2e.rs
  • tests/web_cancel_request_scoping.rs
💤 Files with no reviewable changes (2)
  • src/openhuman/channels/providers/mod.rs
  • src/openhuman/channels/mod.rs
🚧 Files skipped from review as they are similar to previous changes (55)
  • tests/raw_coverage/channels_web_yuanbao_round22_raw_coverage_e2e.rs
  • src/openhuman/agent/triage/evaluator.rs
  • src/openhuman/security/egress/mod.rs
  • src/openhuman/mod.rs
  • src/openhuman/web_chat/ops.rs
  • tests/raw_coverage/channels_web_startup_raw_coverage_e2e.rs
  • src/openhuman/channels/runtime/dispatch/processor.rs
  • tests/web_cancel_request_scoping.rs
  • src/openhuman/meet_agent/brain/llm.rs
  • tests/agentbox_e2e.rs
  • tests/raw_coverage/channels_web_telegram_raw_coverage_e2e.rs
  • tests/raw_coverage/channels_bus_presentation_raw_coverage_e2e.rs
  • src/openhuman/agent_orchestration/command_center/mod.rs
  • src/openhuman/artifacts/store.rs
  • src/core/event_bus/events.rs
  • src/openhuman/approval/gate.rs
  • src/openhuman/test_support/README.md
  • docs/TEST-COVERAGE-MATRIX.md
  • src/openhuman/agent/task_dispatcher/executor.rs
  • tests/raw_coverage/tools_network_channels_raw_coverage_e2e.rs
  • src/openhuman/inference/provider/error_code.rs
  • src/openhuman/approval/README.md
  • src/openhuman/channels/providers/telegram/remote_control.rs
  • src/openhuman/web_chat/event_bus.rs
  • tests/composio_list_tools_stack_overflow_regression.rs
  • tests/raw_coverage/channels_provider_leftovers_raw_coverage_e2e.rs
  • src/openhuman/threads/ops.rs
  • src/core/socketio.rs
  • src/openhuman/channels/bus.rs
  • src/openhuman/threads/README.md
  • src/main.rs
  • src/openhuman/channels/runtime/startup.rs
  • src/openhuman/cron/scheduler_tests.rs
  • src/openhuman/channels/host/adapters.rs
  • src/openhuman/test_support/introspect.rs
  • src/openhuman/web_chat/mod.rs
  • src/openhuman/wallet/README.md
  • src/openhuman/prompt_injection/README.md
  • src/openhuman/cron/scheduler.rs
  • tests/raw_coverage/channels_large_round25_raw_coverage_e2e.rs
  • src/core/jsonrpc.rs
  • src/openhuman/agentbox/invoker.rs
  • src/core/all.rs
  • src/core/observability.rs
  • src/openhuman/web_chat/session.rs
  • tests/raw_coverage/channels_provider_deep_raw_coverage_e2e.rs
  • src/openhuman/web_chat/run_task.rs
  • src/openhuman/flows/ops.rs
  • tests/raw_coverage/tools_approval_channels_raw_coverage_e2e.rs
  • src/openhuman/web_chat/presentation.rs
  • src/openhuman/web_chat/types.rs
  • src/openhuman/web_chat/schemas.rs
  • src/openhuman/web_chat/presentation_tests.rs
  • src/openhuman/web_chat/web_errors.rs
  • src/openhuman/web_chat/progress_bridge.rs
🛑 Comments failed to post (1)
src/openhuman/web_chat/web_tests.rs (1)

18-31: 🩺 Stability & Availability | 🟠 Major | 🏗️ Heavy lift

Make process-global test overrides scoped and panic-safe.

The mutex prevents concurrent writes, but a panic or timeout before the manual None reset releases the lock while leaving the forced error/block installed. The timeout EnvGuard also removes the variable instead of restoring a pre-existing value. Subsequent tests can therefore inherit stale state and fail order-dependently.

Have each override return a scoped guard that synchronously captures and restores the exact prior value on Drop.

Based on learnings, process-global test mutations should restore exact prior state with a scoped guard, even on panic.

Also applies to: 119-173, 647-822, 1935-2191

🤖 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/web_chat/web_tests.rs` around lines 18 - 31, Update the forced
error/block override helpers and EnvGuard used by start_chat/run_chat_task tests
to return scoped, synchronous guards that capture the exact prior state and
restore it on Drop, including during panic or timeout. Replace manual None
resets and environment removal with guard lifetimes, while retaining
RUN_CHAT_TASK_TEST_LOCK for each test body so all process-global mutations
remain isolated.

Source: Learnings

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

rust-core Core Rust runtime in src/: CLI, core_server, shared infrastructure. working A PR that is being worked on by the team.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

refactor(core): relocate the web chat conduit out of channels/

2 participants