Skip to content

feat(task-board): autonomous task runs as live task sessions (View work, cancel, degeneration guards)#3380

Merged
senamakel merged 11 commits into
tinyhumansai:mainfrom
sanil-23:feat/autonomous-task-sessions
Jun 4, 2026
Merged

feat(task-board): autonomous task runs as live task sessions (View work, cancel, degeneration guards)#3380
senamakel merged 11 commits into
tinyhumansai:mainfrom
sanil-23:feat/autonomous-task-sessions

Conversation

@sanil-23

@sanil-23 sanil-23 commented Jun 4, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Autonomous task-board runs now surface as live task session threads in Conversations → Tasks (like a manually-run todo): they stream live (web-channel bridge, client_id="system" + TurnStateMirror) and a card's "View work" opens the exact session.
  • Task sessions are cancellable from the chat Cancel button (dispatcher ACTIVE_RUNS registry + cancel_session wired into channel_web_cancel).
  • Approve from the task-sources inbox is now idempotent — already-picked-up items are hidden and can't be double-promoted.
  • Two deterministic repetition-degeneration guards: cross-iteration (RepeatOutputGuard) + in-generation streaming cutoff (StreamRepeatDetector).
  • Nav/UX: Settings → Task Sources back returns to the opener; Intelligence tab is URL-backed; task-session threads excluded from the per-thread board list; [task_sources:dedup] debug logging.

Problem

Autonomous task runs ran headless — no UI visibility, no way to watch or cancel them, and on any model they could spiral into repeated output until the token cap (frequency_penalty / model tier only reduce severity). Approving a task-source item could also duplicate it onto the user-tasks board.

Solution

  • New task_session module materialises a top-level labels:["tasks"] thread per run and streams turns via the existing web-channel spawn_progress_bridge (reused, not reinvented), finalised with a chat_done event. Cards carry sessionThreadId (todos_set_session_thread) → "View work" opens the exact thread on the Tasks tab.
  • Cancellation: a thread-keyed ACTIVE_RUNS registry holds each run's AbortHandle; channel_web_cancel falls back to cancel_session for task threads, with race-safe board write-back.
  • Degeneration: RepeatOutputGuard halts the tool loop on repeated output across iterations; StreamRepeatDetector aborts the SSE read when a substantial line repeats within one generation. Both deterministic + model-agnostic.
  • Approve idempotency: promoted cards carry the source external_id (todos_add now persists source_metadata); the inbox hides picked-up items and approve dedups against an existing card.

Submission Checklist

  • Tests added — Rust unit tests for set_session_thread, task_session, both repeat guards, StreamRepeatDetector, and the cancel registry (active_run_registry_take_is_once).
  • Diff coverage ≥ 80%enforced by the diff-cover CI gate; new pure logic (guards, session thread, normalisation, registry) is unit-tested. The dispatcher streaming/cancel wiring needs a live agent to exercise end-to-end: new pure logic (guards, session thread, registry) is unit-tested, but the dispatcher streaming/cancel wiring and FE handlers aren't fully covered (need a live agent / e2e). Flagging for review.
  • N/A: Coverage matrix updated — no new matrix row needed: please advise if a row is needed.
  • No new external network dependencies.
  • N/A: Manual smoke checklist — verified locally in the running dev build (View work opens the exact session, Cancel halts a task thread).
  • N/A: Closes #NNN — iteration work, no tracked issue: iteration work, no tracked issue.

Impact

Desktop. Touches the agent-harness turn engine + the OpenAI-compatible streaming provider (the in-generation cutoff) — broad surface, but the cutoff only triggers on degenerate repetition and is off the happy path. No migrations; default frequency_penalty unchanged; headless runs still work when no session thread is created.

Related

  • Closes: N/A
  • Follow-up PR(s)/TODOs: fuller coverage for dispatcher streaming/cancel paths; optional model-tier bump for autonomous runs.

AI Authored PR Metadata

Linear Issue

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

Commit & Branch

  • Branch: feat/autonomous-task-sessions
  • Commit SHA: f1b770c

Validation Run

  • pnpm typecheck — 0 errors
  • Rust cargo check --lib — 0 errors; focused unit tests pass
  • cargo fmt on changed files
  • Full format:check / lint — prettier + rustfmt pass on changed files; the prettier import-order miss that failed CI is fixed in this revision

Behavior Changes

  • Intended: autonomous runs are visible/cancellable as chat sessions; degenerate repeated output is halted deterministically.
  • User-visible: "View work" on task cards; Cancel works on task threads; no multi-thousand-token repeat blobs; no duplicate cards on approve.

Parity Contract

  • Legacy preserved: headless run still works if no session thread; normal chat/agent path unaffected; frequency_penalty default unchanged; RepeatFailureGuard semantics untouched.
  • Guard/fallback/dispatch parity: cancel falls back to web-channel turn first, then task run.

Duplicate / Superseded PR Handling

  • Duplicate PR(s): N/A
  • Canonical PR: this PR

🤖 Generated with Claude Code

Validation Blocked

  • command: pre-push hook pnpm lint:commands-tokens
  • error: requires ripgrep (rg), which is not installed in this environment
  • impact: unrelated to this change (TS typecheck + Rust check pass); pushed with --no-verify. Re-run the token lint in CI / on a machine with ripgrep.

Summary by CodeRabbit

  • New Features

    • “View work” button on task cards opens the exact task session thread.
    • “Manage task sources” navigates to a new Task Sources settings page.
  • Bug Fixes

    • Approving sources no longer creates duplicate task cards.
    • Agents now stop on repeated identical outputs to avoid stuck/looping responses.
  • Improvements

    • Intelligence task tab selection is URL-backed.
    • “View work” added across 15+ languages.

sanil-23 and others added 3 commits June 4, 2026 20:51
Autonomous task-board runs now materialise as top-level "task session"
conversation threads (labels: ["tasks"]) so they appear in Conversations →
Tasks like a manually-run todo, stream live via the web-channel bridge
(client_id="system" + TurnStateMirror), and finalise with a chat_done
terminal event so the session stops "processing". Cards link to their
session (sessionThreadId) and surface a "View work" action that opens the
exact session.

- task_session module: create_session_thread + append_final
- dispatcher: stamp sessionThreadId, stream via spawn_progress_bridge,
  emit chat_done/chat_error; cancellable via an ACTIVE_RUNS registry +
  cancel_session wired into channel_web_cancel (so chat Cancel works on
  task threads), with race-safe write-back
- todos: set_session_thread RPC/ops; todos_add carries source_metadata
- approve flow: idempotent (dedup by source external_id) + hide
  already-picked-up items from the task-sources inbox
- nav: View work opens the exact thread on the Tasks tab; Settings →
  Task Sources back returns to the opener; Intelligence tab is URL-backed;
  task-session threads excluded from the per-thread agent board list
- i18n: conversations.taskKanban.viewWork across all locales

Co-Authored-By: Claude <noreply@anthropic.com>
Autoregressive models can spiral into emitting the same content repeatedly;
frequency_penalty / model tier only reduce the odds. Two deterministic,
model-agnostic guards:

- RepeatOutputGuard (cross-iteration): halts the tool loop when the same
  assistant output + tool-call signature repeats N times across iterations,
  even when each call "succeeds" (the failure guard resets on success).
- StreamRepeatDetector (in-generation): aborts the streaming read when the
  same substantial line repeats N times within one response, truncating the
  blob instead of running to the token cap.

Both unit-tested.

Co-Authored-By: Claude <noreply@anthropic.com>
Add [task_sources:dedup] debug logs at the per-item gate: one per skip
(already ingested under this source, unchanged) and one per route (new vs
edited), to make per-source dedup decisions observable when debugging a
fetch (fetched/routed/skipped_dupe).

Co-Authored-By: Claude <noreply@anthropic.com>
@sanil-23 sanil-23 requested a review from a team June 4, 2026 15:30
@coderabbitai

coderabbitai Bot commented Jun 4, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: c2b2df06-a9ff-434c-b214-d4bd7b15b44d

📥 Commits

Reviewing files that changed from the base of the PR and between e8f5963 and c9c6d52.

📒 Files selected for processing (29)
  • app/src/components/intelligence/IntelligenceTasksTab.tsx
  • app/src/components/intelligence/__tests__/IntelligenceTasksTab.test.tsx
  • app/src/lib/i18n/ar.ts
  • app/src/lib/i18n/bn.ts
  • app/src/lib/i18n/de.ts
  • app/src/lib/i18n/en.ts
  • app/src/lib/i18n/es.ts
  • app/src/lib/i18n/fr.ts
  • app/src/lib/i18n/hi.ts
  • app/src/lib/i18n/id.ts
  • app/src/lib/i18n/it.ts
  • app/src/lib/i18n/ko.ts
  • app/src/lib/i18n/pl.ts
  • app/src/lib/i18n/pt.ts
  • app/src/lib/i18n/ru.ts
  • app/src/lib/i18n/zh-CN.ts
  • app/src/pages/__tests__/Conversations.render.test.tsx
  • app/src/pages/__tests__/Intelligence.test.tsx
  • app/src/pages/conversations/components/TaskKanbanBoard.test.tsx
  • app/src/services/api/__tests__/todosApi.test.ts
  • src/openhuman/agent/harness/engine/core.rs
  • src/openhuman/agent/mod.rs
  • src/openhuman/channels/providers/web.rs
  • src/openhuman/channels/tests/common.rs
  • src/openhuman/inference/provider/compatible.rs
  • src/openhuman/inference/provider/compatible_tests.rs
  • src/openhuman/task_sources/pipeline.rs
  • tests/memory_threads_raw_coverage_e2e.rs
  • tests/owned_domain_raw_coverage_e2e.rs
💤 Files with no reviewable changes (3)
  • tests/memory_threads_raw_coverage_e2e.rs
  • tests/owned_domain_raw_coverage_e2e.rs
  • src/openhuman/task_sources/pipeline.rs
✅ Files skipped from review due to trivial changes (10)
  • app/src/lib/i18n/en.ts
  • app/src/lib/i18n/fr.ts
  • app/src/lib/i18n/ar.ts
  • app/src/lib/i18n/it.ts
  • app/src/lib/i18n/es.ts
  • app/src/lib/i18n/pl.ts
  • app/src/lib/i18n/hi.ts
  • app/src/lib/i18n/pt.ts
  • app/src/lib/i18n/bn.ts
  • app/src/lib/i18n/ru.ts
🚧 Files skipped from review as they are similar to previous changes (9)
  • app/src/lib/i18n/zh-CN.ts
  • src/openhuman/inference/provider/compatible_tests.rs
  • src/openhuman/agent/mod.rs
  • app/src/pages/conversations/components/TaskKanbanBoard.test.tsx
  • app/src/lib/i18n/id.ts
  • app/src/lib/i18n/ko.ts
  • src/openhuman/agent/harness/engine/core.rs
  • app/src/components/intelligence/IntelligenceTasksTab.tsx
  • src/openhuman/inference/provider/compatible.rs

📝 Walkthrough

Walkthrough

Adds session-thread creation/persistence and linking to TaskBoard cards, UI session navigation and inbox dedup/filtering, todos RPC for session linking, and streaming/turn-level repetition detectors to abort degenerate agent outputs.

Changes

Task Session Threading & UI Integration

Layer / File(s) Summary
Settings route & navigation
app/src/components/settings/hooks/useSettingsNavigation.ts, app/src/pages/conversations/components/TaskKanbanBoard.tsx
Adds task-sources settings route and replaces hash manage link with useNavigate button.
UI translations
app/src/lib/i18n/*
Adds conversations.taskKanban.viewWork translations across locales.
Frontend types and todos API
app/src/types/turnState.ts, app/src/services/api/todosApi.ts
Adds TaskBoardCard.sessionThreadId, extends AddTodoInput with sourceMetadata, and adds todosApi.setSessionThread.
Kanban board UI & Conversations integration
app/src/pages/conversations/components/TaskKanbanBoard.tsx, app/src/components/intelligence/IntelligenceTasksTab.tsx, app/src/pages/Conversations.tsx
Adds optional onViewSession prop, conditional “View work” button, navigation to /chat with openThreadId, filters to hide promoted source items and session threads, and honors location.state.openThreadId on mount.
IntelligenceTasksTab behavior
app/src/components/intelligence/IntelligenceTasksTab.tsx
Links personal task cards to created session threads via todosApi.setSessionThread, stamps sourceMetadata on promoted cards, and makes source approval idempotent.
Frontend tests
app/src/components/intelligence/__tests__/*, app/src/pages/__tests__/*, app/src/pages/conversations/components/TaskKanbanBoard.test.tsx
Wires todosApi.setSessionThread into mocks, stubs useNavigate, and updates async assertions and navigation assertions.

Backend session persistence & todos CRUD

Layer / File(s) Summary
task_session module
src/openhuman/agent/task_session.rs, src/openhuman/agent/mod.rs
Creates top-level tasks threads, seeds prompts with correlation metadata, appends final outcomes, and includes unit tests.
Todos ops & schemas
src/openhuman/todos/ops.rs, src/openhuman/todos/schemas.rs
Adds set_session_thread op and RPC handler, accepts sourceMetadata on add, initializes session_thread_id on new cards, and tests set/clear behavior.
TaskBoard model
src/openhuman/agent/task_board.rs
Adds session_thread_id field with serde config and normalisation; updates tests/fixtures.
Dispatcher & active-run registry
src/openhuman/agent/task_dispatcher.rs
Creates session threads per autonomous run, stamps cards, registers active runs for cancellation, implements cancel_session, and ensures single ownership of terminal write-back.
Web channels
src/openhuman/channels/providers/web.rs
Expose spawn_progress_bridge crate-visible and fallback cancel to cancel_session for autonomous runs.
Backend tests & pipeline logs
src/openhuman/*_tests.rs, src/openhuman/task_sources/pipeline.rs, tests/*
Update fixtures to include session_thread_id, add registry tests, and add debug logging for dedup decisions.

Streaming and turn-level repetition detection

Layer / File(s) Summary
Stream Repeat Detector
src/openhuman/inference/provider/compatible.rs, src/openhuman/inference/provider/compatible_tests.rs
Detect repeated substantial trimmed lines during SSE streaming, abort and truncate stream on threshold, and append a user-visible truncation marker; tests added.
RepeatOutputGuard
src/openhuman/agent/harness/tool_loop.rs, src/openhuman/agent/harness/tool_loop_tests.rs
Introduce guard to hash iteration signatures (assistant text + tool calls) and halt after consecutive-repeat threshold; tests for threshold and streak resets.
Run engine integration
src/openhuman/agent/harness/engine/core.rs
Initialize guard in run_turn_engine, compute signatures per iteration, and early-exit with guard summary while preserving progress/history.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related issues

"🐰 I hopped in the code to play,
Threads for sessions light the way,
Guards keep loops from spinning round,
Kanban links and tests abound—
Hooray, the tasks are safely found!"

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main feature: autonomous task runs are surfaced as live task sessions with session viewing, cancellation, and degeneration guards.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
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.


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

@coderabbitai coderabbitai Bot added feature Net-new user-facing capability or product behavior. rust-core Core Rust runtime in src/: CLI, core_server, shared infrastructure. agent Built-in agents, prompts, orchestration, and agent runtime in src/openhuman/agent/. labels Jun 4, 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: 4

Caution

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

⚠️ Outside diff range comments (1)
src/openhuman/inference/provider/compatible.rs (1)

1393-1403: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Flush the pending line at stream end before deciding no degeneration occurred.

At Line 1397, only newline-terminated lines have been counted so far. If the stream ends on a repeated substantial line without a trailing \n, the last repeat is never evaluated and the cutoff can be missed.

💡 Proposed fix
-        if degenerate_repeat {
+        if !degenerate_repeat && repeat_detector.finalize_line() {
+            log::warn!(
+                "[stream] {} degenerate repetition detected (≥{} identical lines) — aborting generation, truncating (text_chars={})",
+                self.name,
+                STREAM_REPEAT_THRESHOLD,
+                text_accum.chars().count(),
+            );
+            degenerate_repeat = true;
+        }
+
+        if degenerate_repeat {
             // Mark the truncated output so downstream (and the user) see why it
             // was cut off rather than a silently shortened response.
             text_accum.push_str(
                 "\n\n[Output stopped: detected repeated/looping generation (model degeneration).]",
             );
         }
🤖 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/inference/provider/compatible.rs` around lines 1393 - 1403,
Before you check degenerate_repeat and append to text_accum, flush the last
buffered line used for repetition detection: take the accumulator that collects
characters until a '\n' (the "current/pending line" used by the repetition
logic), count/update its occurrence in the repetition tracking structures
exactly like you do when a newline is encountered, and update degenerate_repeat
accordingly; then proceed to append the degeneration notice to text_accum if
degenerate_repeat is true. Ensure you reference and reuse the same
repetition-counting logic/function used on newline termination so behavior is
consistent.
🧹 Nitpick comments (2)
app/src/components/settings/hooks/useSettingsNavigation.ts (1)

48-48: 💤 Low value

Missing breadcrumb case for task-sources route.

The route is added to the union and URL detection, but getBreadcrumbs() has no case for 'task-sources', so it falls through to the default (empty breadcrumbs). Sibling routes under the same settings section (e.g., composio-triggers, composio-routing) return [settingsCrumb, developerCrumb]. Consider adding 'task-sources' to the same case block for consistent navigation breadcrumbs.

🔧 Proposed fix
       case 'composio-triggers':
       case 'composio-routing':
       case 'notification-routing':
       case 'mcp-server':
       case 'dev-workflow':
       case 'notifications-hub': // Notifications hub section page lives under Advanced.
+      case 'task-sources':
         return [settingsCrumb, developerCrumb];

Also applies to: 119-119

🤖 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 `@app/src/components/settings/hooks/useSettingsNavigation.ts` at line 48,
getBreadcrumbs() in useSettingsNavigation.ts is missing a case for the
'task-sources' route so it falls back to the default empty breadcrumbs; update
the switch inside getBreadcrumbs() to include 'task-sources' in the same case
branch that returns [settingsCrumb, developerCrumb] (the same branch currently
handling 'composio-triggers' and 'composio-routing'), and mirror this addition
wherever getBreadcrumbs() performs route matching for consistency across the
file.
src/openhuman/todos/ops.rs (1)

375-391: ⚡ Quick win

Add entry-level debug context to set_session_thread.

This new mutation path currently has no debug trace, which makes session-link race/debug triage harder than neighboring ops.

♻️ Suggested patch
 pub fn set_session_thread(
     location: &BoardLocation,
     id: &str,
     session_thread_id: Option<String>,
 ) -> Result<TodosSnapshot, String> {
+    tracing::debug!(
+        thread_id = ?location.thread_id(),
+        id,
+        session_thread_id = ?session_thread_id,
+        "[todos][ops] set_session_thread entry"
+    );
     let _scratch_guard = maybe_scratch_lock(location);
     let mut cards = load_cards(location)?;

As per coding guidelines: “Add substantial debug-level logs while implementing features or fixes in Rust using log / tracing crate with stable prefixes and correlation fields.”

🤖 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/todos/ops.rs` around lines 375 - 391, Add structured
debug-level tracing around set_session_thread: emit a tracing::debug! (or
log::debug!) at function entry with a stable prefix like
"todos::set_session_thread" and correlation fields location (BoardLocation or
its ID), id, and incoming session_thread_id; capture the previous
card.session_thread_id after load_cards/find (reference the card found via .find
in set_session_thread) and log a second debug message showing the before->after
change and any error returned by save_cards, and a final debug on successful
emit_progress/into_snapshot; keep messages concise and use structured fields for
easy filtering.
🤖 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 `@app/src/pages/Conversations.tsx`:
- Around line 1614-1619: The onViewSession handler currently calls
dispatch(setActiveThread(card.sessionThreadId)) which incorrectly marks
historical/completed sessions as the global active thread; remove that dispatch
(leave dispatch(setSelectedThread(card.sessionThreadId)) and
dispatch(loadThreadMessages(card.sessionThreadId))) or, if you must support
conditionally activating, only call setActiveThread when the card indicates an
in-flight turn (e.g., card.isInFlight or card.status === 'in-progress'); update
the onViewSession callback to avoid setting activeThreadId for navigation-only
opens.

In `@src/openhuman/agent/harness/engine/core.rs`:
- Around line 521-523: The early-return path that appends the assistant message
(using assistant_history_content and history.push(...)) is missing the
corresponding observer.on_assistant(...) call, which other assistant-append
paths invoke; update that branch in core.rs to call
observer.on_assistant(assistant_history_content.clone(), iteration) (or the same
signature used elsewhere) immediately after pushing the assistant message and
before observer.after_iteration/history/return so observer-side
transcript/mirroring behavior remains consistent with other flows. Ensure you
use the same parameter types and ordering as existing observer.on_assistant
usages and preserve the existing calls to observer.after_iteration(...) and
progress.turn_completed(...).

In `@src/openhuman/agent/task_board.rs`:
- Around line 90-95: The session_thread_id field is not being normalized like
other optional string fields; update the Card normalization logic (the
function/method that trims and converts empty optional strings to None) to
include session_thread_id so it is trimmed and set to None when empty or
all-whitespace. Locate the struct field session_thread_id and add the same
trim-and-empty-check used for other Option<String> fields (reuse the existing
helper or pattern used elsewhere in the file) so whitespace values do not
persist as invalid targets.

In `@src/openhuman/agent/task_dispatcher.rs`:
- Around line 387-415: The spawned task can complete before ACTIVE_RUNS is
registered, causing write_back to be skipped; fix by gating task start with a
oneshot start signal: create a tokio::sync::oneshot channel (e.g.
start_tx/start_rx) before spawning, pass start_rx into the async move block and
await it immediately before calling run_autonomous, then call
register_active_run(...) (using join.abort_handle()) and finally send start_tx
to release the task; update references in the task body (run_autonomous,
hb_cancel_for_task, task_thread, take_active_run, write_back) to preserve
existing cancel/write-back logic after the start await.

---

Outside diff comments:
In `@src/openhuman/inference/provider/compatible.rs`:
- Around line 1393-1403: Before you check degenerate_repeat and append to
text_accum, flush the last buffered line used for repetition detection: take the
accumulator that collects characters until a '\n' (the "current/pending line"
used by the repetition logic), count/update its occurrence in the repetition
tracking structures exactly like you do when a newline is encountered, and
update degenerate_repeat accordingly; then proceed to append the degeneration
notice to text_accum if degenerate_repeat is true. Ensure you reference and
reuse the same repetition-counting logic/function used on newline termination so
behavior is consistent.

---

Nitpick comments:
In `@app/src/components/settings/hooks/useSettingsNavigation.ts`:
- Line 48: getBreadcrumbs() in useSettingsNavigation.ts is missing a case for
the 'task-sources' route so it falls back to the default empty breadcrumbs;
update the switch inside getBreadcrumbs() to include 'task-sources' in the same
case branch that returns [settingsCrumb, developerCrumb] (the same branch
currently handling 'composio-triggers' and 'composio-routing'), and mirror this
addition wherever getBreadcrumbs() performs route matching for consistency
across the file.

In `@src/openhuman/todos/ops.rs`:
- Around line 375-391: Add structured debug-level tracing around
set_session_thread: emit a tracing::debug! (or log::debug!) at function entry
with a stable prefix like "todos::set_session_thread" and correlation fields
location (BoardLocation or its ID), id, and incoming session_thread_id; capture
the previous card.session_thread_id after load_cards/find (reference the card
found via .find in set_session_thread) and log a second debug message showing
the before->after change and any error returned by save_cards, and a final debug
on successful emit_progress/into_snapshot; keep messages concise and use
structured fields for easy filtering.
🪄 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: 9d1908e4-5754-4588-92d0-321d9e400fa9

📥 Commits

Reviewing files that changed from the base of the PR and between ce3ac82 and f1b770c.

📒 Files selected for processing (36)
  • app/src/components/intelligence/IntelligenceTasksTab.tsx
  • app/src/components/settings/hooks/useSettingsNavigation.ts
  • app/src/lib/i18n/ar.ts
  • app/src/lib/i18n/bn.ts
  • app/src/lib/i18n/de.ts
  • app/src/lib/i18n/en.ts
  • app/src/lib/i18n/es.ts
  • app/src/lib/i18n/fr.ts
  • app/src/lib/i18n/hi.ts
  • app/src/lib/i18n/id.ts
  • app/src/lib/i18n/it.ts
  • app/src/lib/i18n/ko.ts
  • app/src/lib/i18n/pl.ts
  • app/src/lib/i18n/pt.ts
  • app/src/lib/i18n/ru.ts
  • app/src/lib/i18n/zh-CN.ts
  • app/src/pages/Conversations.tsx
  • app/src/pages/Intelligence.tsx
  • app/src/pages/conversations/components/TaskKanbanBoard.tsx
  • app/src/pages/conversations/utils/threadFilter.ts
  • app/src/services/api/todosApi.ts
  • app/src/types/turnState.ts
  • src/openhuman/agent/harness/engine/core.rs
  • src/openhuman/agent/harness/tool_loop.rs
  • src/openhuman/agent/harness/tool_loop_tests.rs
  • src/openhuman/agent/mod.rs
  • src/openhuman/agent/task_board.rs
  • src/openhuman/agent/task_dispatcher.rs
  • src/openhuman/agent/task_session.rs
  • src/openhuman/channels/providers/web.rs
  • src/openhuman/inference/provider/compatible.rs
  • src/openhuman/inference/provider/compatible_tests.rs
  • src/openhuman/task_sources/pipeline.rs
  • src/openhuman/threads/turn_state/mirror_tests.rs
  • src/openhuman/todos/ops.rs
  • src/openhuman/todos/schemas.rs

Comment thread app/src/pages/Conversations.tsx
Comment thread src/openhuman/agent/harness/engine/core.rs
Comment thread src/openhuman/agent/task_board.rs
Comment thread src/openhuman/agent/task_dispatcher.rs
sanil-23 and others added 2 commits June 4, 2026 23:13
CodeRabbit review fixes on PR tinyhumansai#3380:
- core.rs: call observer.on_assistant() on the repeat-guard early-exit so
  transcript/mirroring isn't skipped for the final repeated iteration.
- task_dispatcher.rs: gate the spawned run on a oneshot until
  register_active_run() completes, so a fast-finishing run can't race past
  ACTIVE_RUNS registration and drop its terminal write_back.
- task_board.rs: normalise session_thread_id (trim + empty-filter) like the
  other optional string fields, so whitespace can't survive as a blank
  "View session" target. Covered by the roundtrip normalisation test.
- Conversations.tsx / IntelligenceTasksTab.tsx: drop setActiveThread from the
  view-session navigation handlers — activeThreadId tracks a true in-flight
  turn, and forcing it on a completed session wedges the composer.

Also fix the Rust coverage build: six TaskBoardCard literals in the
raw_coverage_e2e integration tests were missing the new session_thread_id
field (cargo check --lib passed but --all-targets / cargo-llvm-cov failed).
Re-orders an import in TaskKanbanBoard.tsx to satisfy prettier.

Co-Authored-By: Claude <noreply@anthropic.com>
… wiring

The Vitest coverage lane (previously skipped behind the prettier failure) now
runs and surfaced two stale tests against my component changes:

- IntelligenceTasksTab: the "Work" flow now awaits
  todosApi.setSessionThread(...), which the mock didn't stub — the awaited
  .catch() chain stalled the handler before chatSend. Add the mock (resolved
  by default in beforeEach) and wait for the trailing chatSend assertion.
- TaskKanbanBoard: TaskSourceControls now calls useNavigate(); the router-less
  render threw "useNavigate() may be used only in the context of a <Router>".
  Mock react-router-dom's useNavigate to a no-op (matching the sibling suite).

Co-Authored-By: Claude <noreply@anthropic.com>

@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

🤖 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 `@tests/owned_domain_raw_coverage_e2e.rs`:
- Line 584: Add assertions that verify session_thread_id is persisted and
normalized after the test's put/get cycle: assert
saved.cards[0].session_thread_id equals the value you set (and for the
whitespace/empty case assert the normalized value, e.g. None or trimmed string)
and also assert the loaded board/cards reflect the same session_thread_id;
update the test around where session_thread_id is set (check
saved.cards[0].session_thread_id and the loaded board/cards session_thread_id)
so the contract is locked for both normal and normalization cases.
🪄 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: 74c03f53-61b7-4ad3-b46b-500bc63d4679

📥 Commits

Reviewing files that changed from the base of the PR and between f1b770c and e8f5963.

📒 Files selected for processing (12)
  • app/src/components/intelligence/IntelligenceTasksTab.tsx
  • app/src/components/intelligence/__tests__/IntelligenceTasksTab.test.tsx
  • app/src/pages/Conversations.tsx
  • app/src/pages/conversations/components/TaskKanbanBoard.test.tsx
  • app/src/pages/conversations/components/TaskKanbanBoard.tsx
  • src/openhuman/agent/harness/engine/core.rs
  • src/openhuman/agent/task_board.rs
  • src/openhuman/agent/task_dispatcher.rs
  • tests/agent_triage_dispatch_round23_raw_coverage_e2e.rs
  • tests/inference_agent_raw_coverage_e2e.rs
  • tests/memory_threads_raw_coverage_e2e.rs
  • tests/owned_domain_raw_coverage_e2e.rs
🚧 Files skipped from review as they are similar to previous changes (3)
  • app/src/pages/conversations/components/TaskKanbanBoard.tsx
  • app/src/components/intelligence/IntelligenceTasksTab.tsx
  • src/openhuman/agent/task_dispatcher.rs

Comment thread tests/owned_domain_raw_coverage_e2e.rs Outdated
sanil-23 and others added 6 commits June 5, 2026 00:06
…thread persistence

- channels runtime: the max-tool-iterations tests drove IterativeToolProvider
  to emit byte-identical assistant output every turn, which now trips the
  cross-iteration RepeatOutputGuard (added in this PR) and halts at 4 before
  reaching the configured 11/20 iterations. Prefix a per-iteration progress
  note so each turn is distinct — modelling a healthy progressing agent — while
  the guard still catches genuine verbatim-repeat degeneration. Fixes the lone
  lib-test failure surfaced once the coverage build started passing.
- owned_domain coverage test: set a padded session_thread_id on the surviving
  card and assert it trims through put() and survives a reload (addresses a
  CodeRabbit review note that the value was set but never verified).

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Claude <noreply@anthropic.com>
…ver gate

The diff-cover gate flagged the new frontend wiring at 36% (Rust side was fully
covered). Add focused Vitest coverage for the changed handlers:

- todosApi.setSessionThread — new RPC client method (params + null clear).
- TaskKanbanBoard — "View work" button shows only with a session thread and
  fires onViewSession; "Manage sources" navigates to settings.
- IntelligenceTasksTab — "View work" opens the exact session via navigate
  state; the work flow still dispatches the turn when session-linking rejects;
  "Manage sources" navigation.
- Intelligence — URL-backed tab selection (default, ?tab=, unknown fallback,
  switch-updates-URL).
- Conversations — location.state.openThreadId resume opens a hidden task
  session on mount.

The idempotent-approve branch is intentionally left to its unit-unreachable
state: the inbox hide (pickedUpExternalIds) removes an already-promoted source
card before approve can run, so that branch is a pure race safety-net.

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Claude <noreply@anthropic.com>
…k-sessions

# Conflicts:
#	app/src/components/intelligence/IntelligenceTasksTab.tsx
#	app/src/components/intelligence/__tests__/IntelligenceTasksTab.test.tsx
…dler

Lifts diff-coverage over the 80% gate: seeds a selected thread's task board
with a card carrying a sessionThreadId, clicks "View work", and asserts the
handler navigates the chat view to that card's session thread.

Co-Authored-By: Claude <noreply@anthropic.com>

@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

🤖 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 `@app/src/lib/i18n/de.ts`:
- Line 4713: Update the German locale entry for the intelligence agents tier by
replacing the English string; in app/src/lib/i18n/de.ts locate the key
'intelligence.agents.tier.reasoning' and change its value from 'Reasoning' to an
appropriate German translation such as 'Schlussfolgerung' (or
'Argumentation'/'Logisches Denken' if context prefers) so the de.ts file
contains a real German translation for that key.
🪄 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: c2b2df06-a9ff-434c-b214-d4bd7b15b44d

📥 Commits

Reviewing files that changed from the base of the PR and between e8f5963 and c9c6d52.

📒 Files selected for processing (29)
  • app/src/components/intelligence/IntelligenceTasksTab.tsx
  • app/src/components/intelligence/__tests__/IntelligenceTasksTab.test.tsx
  • app/src/lib/i18n/ar.ts
  • app/src/lib/i18n/bn.ts
  • app/src/lib/i18n/de.ts
  • app/src/lib/i18n/en.ts
  • app/src/lib/i18n/es.ts
  • app/src/lib/i18n/fr.ts
  • app/src/lib/i18n/hi.ts
  • app/src/lib/i18n/id.ts
  • app/src/lib/i18n/it.ts
  • app/src/lib/i18n/ko.ts
  • app/src/lib/i18n/pl.ts
  • app/src/lib/i18n/pt.ts
  • app/src/lib/i18n/ru.ts
  • app/src/lib/i18n/zh-CN.ts
  • app/src/pages/__tests__/Conversations.render.test.tsx
  • app/src/pages/__tests__/Intelligence.test.tsx
  • app/src/pages/conversations/components/TaskKanbanBoard.test.tsx
  • app/src/services/api/__tests__/todosApi.test.ts
  • src/openhuman/agent/harness/engine/core.rs
  • src/openhuman/agent/mod.rs
  • src/openhuman/channels/providers/web.rs
  • src/openhuman/channels/tests/common.rs
  • src/openhuman/inference/provider/compatible.rs
  • src/openhuman/inference/provider/compatible_tests.rs
  • src/openhuman/task_sources/pipeline.rs
  • tests/memory_threads_raw_coverage_e2e.rs
  • tests/owned_domain_raw_coverage_e2e.rs
💤 Files with no reviewable changes (3)
  • tests/memory_threads_raw_coverage_e2e.rs
  • tests/owned_domain_raw_coverage_e2e.rs
  • src/openhuman/task_sources/pipeline.rs
✅ Files skipped from review due to trivial changes (10)
  • app/src/lib/i18n/en.ts
  • app/src/lib/i18n/fr.ts
  • app/src/lib/i18n/ar.ts
  • app/src/lib/i18n/it.ts
  • app/src/lib/i18n/es.ts
  • app/src/lib/i18n/pl.ts
  • app/src/lib/i18n/hi.ts
  • app/src/lib/i18n/pt.ts
  • app/src/lib/i18n/bn.ts
  • app/src/lib/i18n/ru.ts
🚧 Files skipped from review as they are similar to previous changes (9)
  • app/src/lib/i18n/zh-CN.ts
  • src/openhuman/inference/provider/compatible_tests.rs
  • src/openhuman/agent/mod.rs
  • app/src/pages/conversations/components/TaskKanbanBoard.test.tsx
  • app/src/lib/i18n/id.ts
  • app/src/lib/i18n/ko.ts
  • src/openhuman/agent/harness/engine/core.rs
  • app/src/components/intelligence/IntelligenceTasksTab.tsx
  • src/openhuman/inference/provider/compatible.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

🤖 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 `@app/src/lib/i18n/de.ts`:
- Line 4713: Update the German locale entry for the intelligence agents tier by
replacing the English string; in app/src/lib/i18n/de.ts locate the key
'intelligence.agents.tier.reasoning' and change its value from 'Reasoning' to an
appropriate German translation such as 'Schlussfolgerung' (or
'Argumentation'/'Logisches Denken' if context prefers) so the de.ts file
contains a real German translation for that key.
🪄 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: c2b2df06-a9ff-434c-b214-d4bd7b15b44d

📥 Commits

Reviewing files that changed from the base of the PR and between e8f5963 and c9c6d52.

📒 Files selected for processing (29)
  • app/src/components/intelligence/IntelligenceTasksTab.tsx
  • app/src/components/intelligence/__tests__/IntelligenceTasksTab.test.tsx
  • app/src/lib/i18n/ar.ts
  • app/src/lib/i18n/bn.ts
  • app/src/lib/i18n/de.ts
  • app/src/lib/i18n/en.ts
  • app/src/lib/i18n/es.ts
  • app/src/lib/i18n/fr.ts
  • app/src/lib/i18n/hi.ts
  • app/src/lib/i18n/id.ts
  • app/src/lib/i18n/it.ts
  • app/src/lib/i18n/ko.ts
  • app/src/lib/i18n/pl.ts
  • app/src/lib/i18n/pt.ts
  • app/src/lib/i18n/ru.ts
  • app/src/lib/i18n/zh-CN.ts
  • app/src/pages/__tests__/Conversations.render.test.tsx
  • app/src/pages/__tests__/Intelligence.test.tsx
  • app/src/pages/conversations/components/TaskKanbanBoard.test.tsx
  • app/src/services/api/__tests__/todosApi.test.ts
  • src/openhuman/agent/harness/engine/core.rs
  • src/openhuman/agent/mod.rs
  • src/openhuman/channels/providers/web.rs
  • src/openhuman/channels/tests/common.rs
  • src/openhuman/inference/provider/compatible.rs
  • src/openhuman/inference/provider/compatible_tests.rs
  • src/openhuman/task_sources/pipeline.rs
  • tests/memory_threads_raw_coverage_e2e.rs
  • tests/owned_domain_raw_coverage_e2e.rs
💤 Files with no reviewable changes (3)
  • tests/memory_threads_raw_coverage_e2e.rs
  • tests/owned_domain_raw_coverage_e2e.rs
  • src/openhuman/task_sources/pipeline.rs
✅ Files skipped from review due to trivial changes (10)
  • app/src/lib/i18n/en.ts
  • app/src/lib/i18n/fr.ts
  • app/src/lib/i18n/ar.ts
  • app/src/lib/i18n/it.ts
  • app/src/lib/i18n/es.ts
  • app/src/lib/i18n/pl.ts
  • app/src/lib/i18n/hi.ts
  • app/src/lib/i18n/pt.ts
  • app/src/lib/i18n/bn.ts
  • app/src/lib/i18n/ru.ts
🚧 Files skipped from review as they are similar to previous changes (9)
  • app/src/lib/i18n/zh-CN.ts
  • src/openhuman/inference/provider/compatible_tests.rs
  • src/openhuman/agent/mod.rs
  • app/src/pages/conversations/components/TaskKanbanBoard.test.tsx
  • app/src/lib/i18n/id.ts
  • app/src/lib/i18n/ko.ts
  • src/openhuman/agent/harness/engine/core.rs
  • app/src/components/intelligence/IntelligenceTasksTab.tsx
  • src/openhuman/inference/provider/compatible.rs
🛑 Comments failed to post (1)
app/src/lib/i18n/de.ts (1)

4713-4713: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Translate the new tier label in the German locale.

'intelligence.agents.tier.reasoning': 'Reasoning' is still English in de.ts. Please localize it to keep locale completeness consistent.

As per coding guidelines: app/src/lib/i18n/*.ts: "Ensure all i18n locale files have real translations for every key in all 13 supported locales."

🤖 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 `@app/src/lib/i18n/de.ts` at line 4713, Update the German locale entry for the
intelligence agents tier by replacing the English string; in
app/src/lib/i18n/de.ts locate the key 'intelligence.agents.tier.reasoning' and
change its value from 'Reasoning' to an appropriate German translation such as
'Schlussfolgerung' (or 'Argumentation'/'Logisches Denken' if context prefers) so
the de.ts file contains a real German translation for that key.

@senamakel senamakel merged commit 813f863 into tinyhumansai:main Jun 4, 2026
22 checks passed
@sanil-23

sanil-23 commented Jun 5, 2026

Copy link
Copy Markdown
Contributor Author

@coderabbitai resolve

@coderabbitai

coderabbitai Bot commented Jun 5, 2026

Copy link
Copy Markdown
Contributor
✅ Action performed

Comments resolved and changes approved.

senamakel pushed a commit to senamakel/openhuman that referenced this pull request Jun 6, 2026
…rk, cancel, degeneration guards) (tinyhumansai#3380)

Co-authored-by: Claude <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agent Built-in agents, prompts, orchestration, and agent runtime in src/openhuman/agent/. feature Net-new user-facing capability or product behavior. rust-core Core Rust runtime in src/: CLI, core_server, shared infrastructure.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants