Skip to content

feat(orchestration): nested contacts → sessions with create + session send#4475

Merged
senamakel merged 3 commits into
tinyhumansai:mainfrom
sanil-23:feat/orchestration-contact-sessions
Jul 4, 2026
Merged

feat(orchestration): nested contacts → sessions with create + session send#4475
senamakel merged 3 commits into
tinyhumansai:mainfrom
sanil-23:feat/orchestration-contact-sessions

Conversation

@sanil-23

@sanil-23 sanil-23 commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Contacts sidebar is now an expandable tree in the TinyPlace relay (Brain → Orchestration): each accepted contact expands to reveal its sessions (by sessionId), with a "New session" action per contact. Sessions with no known contact peer land in an "Other sessions" bucket so nothing disappears.
  • New orchestration_sessions_create(agentId, label?) RPC mints a per-contact session (fresh uuid harness id, source: "user_created") and returns its summary.
  • orchestration_send_master_message gains an optional sessionId: when present the body is wrapped in a v1 SessionEnvelopeV1 stamped with that id (so a compliant peer threads its reply) and mirrored into the session window. The composer now sends under a selected session, not only Master.
  • Fix (address rendering): a contact's address is resolved from contact.requester / contact.addressee when the relay omits the top-level agentId — previously the address rendered blank and request cards had undefined React keys.
  • Fix (message loads): the orchestration_messages_list schema now declares limit; every message load was being rejected by param-validation.
  • i18n keys (contacts / noContacts / newSession / otherSessions) added across all 14 locales.
  • Autonomous reply threading: the wake-graph's send_dm now wraps a reply into a real harness session in a v1 session envelope too (previously plain), so the agent's own replies thread back under the same session — via a shared SessionEnvelopeV1::outgoing() builder reused by both send paths.
  • Pre-existing CI fix (unrelated): synced the config schema-catalog golden in worker_a_controller_schemas_are_fully_exposed with the config_get/set_privacy_mode controllers that feat(privacy): Privacy Mode + local-only inference enforcement (#4435) #4446 registered but never added — this test fails on every PR that runs the Rust E2E lane.

Problem

The orchestration surface listed contacts only as a flat, non-interactive list, and accepted contacts had nowhere to live until a peer happened to message you (sessions are minted only by Stage-3 ingest). There was no way to see a contact's sessions or start a new one. Two latent bugs made it worse: incoming-contact addresses rendered blank whenever the relay left agentId empty (the address is in the underlying contact record), and messages_list rejected every call because the handler read a limit param the schema never declared.

Solution

  • Frontend groups session chats under their peer contact and renders an expandable tree; a shared contactAddress(view) resolver (used for keys, display, @handle lookup, actions) falls back to contact.requester/addressee by direction.
  • useOrchestrationChats gains createSession() (creates + selects) and a chat-aware sendMessage(chat, body) that threads under a session (recipient = peer, sessionId) or falls back to the Master path.
  • Backend adds the sessions_create controller + a session_agent_id store lookup, and wraps outgoing session sends in a v1 envelope. upsert_session's conflict clause preserves an existing session's source, so a user-created session keeps its origin when a send mirrors into it.
  • Verified live against staging: orchestration_sessions_create -> ok, orchestration_messages_list -> ok (the param-validation rejections are gone).

Submission Checklist

If a section does not apply to this change, mark the item as N/A with a one-line reason. Do not delete items.

  • Tests added or updated (happy path + at least one failure / edge case) per Testing Strategy
  • Diff coverage ≥ 80% — Vitest (TinyPlaceOrchestrationTab: 12 cases incl. create-session, session-send, address fallback) + Rust (orchestration::schemas: envelope roundtrip, session persist/resolve). CI enforces the merged gate.
  • N/A — Coverage matrix: no matrix rows exist for the TinyPlace orchestration surface; behaviour/UI addition within an existing feature area.
  • N/A — no matrix feature IDs apply to this surface (see ## Related).
  • No new external network dependencies introduced (no new deps; uuid/chrono/serde_json already present).
  • N/A — Manual smoke: does not touch release-cut surfaces in docs/RELEASE-MANUAL-SMOKE.md.
  • N/A — no linked issue; user-driven feature, no Closes #NNN.

Impact

  • Desktop only (Brain → Orchestration / TinyPlace relay). No mobile/web/CLI surface.
  • Additive RPCs and one schema fix; no migrations. messages_list now accepts limit (previously silently rejected). No security or compatibility implications — session sends reuse the existing signal-send path.

Related

  • Closes: N/A
  • Follow-up PR(s)/TODOs: a locally-created session is empty until the first message is sent; full bidirectional threading now depends only on the peer honouring the v1 session envelope (both our send paths stamp it).

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

Linear Issue

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

Commit & Branch

  • Branch: feat/orchestration-contact-sessions
  • Commit SHA: d457e2c82408a7cc0f8f5947707e8c4077ae96fd

Validation Run

  • pnpm --filter openhuman-app format:check — Prettier applied clean to changed files.
  • pnpm typecheck — clean.
  • Focused tests: TinyPlaceOrchestrationTab.test.tsx (12/12); cargo test orchestration::schemas (6/6).
  • Rust fmt/check (changed): cargo fmt applied; cargo check --lib clean.
  • N/A — Tauri fmt/check: no app/src-tauri code changed.

Validation Blocked

  • command: N/A
  • error: N/A
  • impact: N/A

Behavior Changes

  • Intended behavior change: contacts expand to their sessions; users can create and message per-contact sessions.
  • User-visible effect: nested Contacts tree with "New session"; contact addresses/handles now render; session messages load (were previously rejected).

Summary by CodeRabbit

  • New Features

    • Added UI support for creating new orchestration sessions and starting nested sessions from accepted contacts.
    • Messages can now be sent in the context of the selected session thread; session and master messaging are handled more consistently.
  • Bug Fixes

    • Contact requests/acceptances now show and act on the resolved contact address (and best-effort @handle when available).
    • Composer behavior is improved: the input clears only after a successful send, and sending is enabled only when appropriate.
  • Documentation / Localization

    • Added new translated labels for contacts, no-contacts, new sessions, and other sessions across multiple languages.

@sanil-23 sanil-23 requested a review from a team July 3, 2026 21:03
@coderabbitai

coderabbitai Bot commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: aba08966-c812-419d-9d7d-cc2af3cb4feb

📥 Commits

Reviewing files that changed from the base of the PR and between 9636641 and 4e77740.

📒 Files selected for processing (22)
  • app/src/components/intelligence/TinyPlaceOrchestrationTab.test.tsx
  • app/src/components/intelligence/TinyPlaceOrchestrationTab.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/lib/orchestration/orchestrationClient.ts
  • app/src/lib/orchestration/useOrchestrationChats.ts
  • src/openhuman/orchestration/ops.rs
  • src/openhuman/orchestration/schemas.rs
  • src/openhuman/orchestration/store.rs
  • src/openhuman/orchestration/types.rs
✅ Files skipped from review due to trivial changes (10)
  • app/src/lib/i18n/pl.ts
  • app/src/lib/i18n/id.ts
  • app/src/lib/i18n/es.ts
  • app/src/lib/i18n/hi.ts
  • app/src/lib/i18n/pt.ts
  • app/src/lib/i18n/ar.ts
  • app/src/lib/i18n/zh-CN.ts
  • app/src/lib/i18n/ko.ts
  • app/src/lib/i18n/ru.ts
  • app/src/lib/i18n/it.ts
🚧 Files skipped from review as they are similar to previous changes (12)
  • app/src/lib/i18n/fr.ts
  • app/src/lib/i18n/bn.ts
  • app/src/lib/orchestration/orchestrationClient.ts
  • src/openhuman/orchestration/types.rs
  • app/src/lib/i18n/de.ts
  • app/src/lib/i18n/en.ts
  • app/src/components/intelligence/TinyPlaceOrchestrationTab.test.tsx
  • app/src/lib/orchestration/useOrchestrationChats.ts
  • src/openhuman/orchestration/store.rs
  • src/openhuman/orchestration/ops.rs
  • app/src/components/intelligence/TinyPlaceOrchestrationTab.tsx
  • src/openhuman/orchestration/schemas.rs

📝 Walkthrough

Walkthrough

Adds backend support for creating orchestration sessions and sending session-threaded master messages, exposes these via frontend client/hook APIs, reworks the TinyPlace orchestration tab UI to group sessions under resolved contact addresses with handle display and nested session creation, and adds i18n strings and tests.

Changes

Session creation and threading

Layer / File(s) Summary
Backend session creation and threaded messaging
src/openhuman/orchestration/schemas.rs, src/openhuman/orchestration/ops.rs, src/openhuman/orchestration/store.rs, src/openhuman/orchestration/types.rs
Adds orchestration_sessions_create controller/handler, extends orchestration_send_master_message with optional sessionId and recipient/window resolution, adds session_agent_id store lookup, session_send_plaintext/session_envelope_plaintext v1 envelope wrapping, SessionEnvelopeV1::outgoing, and related tests.
Frontend orchestration client and hook
app/src/lib/orchestration/orchestrationClient.ts, app/src/lib/orchestration/useOrchestrationChats.ts
Adds sessionsCreate RPC wrapper and SessionCreateResponse type, extends sendMasterMessage with sessionId, and replaces sendMaster with sendMessage(chat, body) plus createSession(agentId, label?) in the hook.
Orchestration tab contacts and sessions
app/src/components/intelligence/TinyPlaceOrchestrationTab.tsx
Derives accepted/pending contacts from resolved contactAddress, adds handle reverse-lookup, groups sessions under accepted contacts with expand/collapse and per-contact "new session" action, and updates composer gating and send flow.
Orchestration tab tests and localized strings
app/src/components/intelligence/TinyPlaceOrchestrationTab.test.tsx, app/src/lib/i18n/*.ts
Adds tests for contact address fallback, accepted-contact rendering, session creation, and threaded message sending; adds tinyplaceOrchestration.contacts/noContacts/newSession/otherSessions translation keys across all locale files.

Estimated code review effort: 4 (Complex) | ~60 minutes

Possibly related PRs

  • tinyhumansai/openhuman#4400: Both PRs touch the TinyPlace orchestration UI, extending the earlier pairing/contacts flow with contact address resolution and new orchestration RPCs.
  • tinyhumansai/openhuman#4430: Both PRs modify the TinyPlace orchestration tab UI and useOrchestrationChats hook, extending the prior orchestration refactor with session-aware send/create actions.
  • tinyhumansai/openhuman#4425: Both PRs are part of the orchestration session pipeline around SessionEnvelopeV1 and session-thread message handling.

Suggested labels: feature, rust-core, agent

Suggested reviewers: graycyrus, M3gA-Mind

Poem

A rabbit hops through sessions new,
Contacts resolved, addresses true.
Envelopes wrapped in v1 delight,
Nested chats blooming left and right.
Four locales sing, “New Session!” bright —
🐇 hop along, the threads take flight.

🚥 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 summarizes the main orchestration change: nested contacts/sessions, session creation, and session-targeted sending.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
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.

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

@coderabbitai coderabbitai Bot added 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. labels Jul 3, 2026

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: d457e2c824

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment on lines +338 to +340
const acceptedContactList = useMemo(
() =>
(pairingSnapshot?.contacts.contacts ?? []).filter(contact => contact.status === 'accepted'),

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Gate session creation on local pairings

When /contacts contains an accepted contact that is not also in the local orchestration pairing store (for example, accepted in TinyPlace or on another device), this list still exposes the new-session flow. That session can send outbound, but replies from that peer are discarded by ingest_one because it only decrypts senders returned by linked_agent_ids from the local pairings file (src/openhuman/orchestration/ingest.rs:158-162). Filter these contacts against pairingSnapshot.records or persist a linked pairing before enabling session creation.

Useful? React with 👍 / 👎.

},
label: None,
workspace: None,
last_seq: 0,

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Keep manual sends out of ingest health

When sessionId is present, this mirrors an owner-authored message into a non-pinned session and advances last_message_at; orchestration_status reports ingestLastMessageAt as MAX(last_message_at) over every non-pinned session, so a user sending to a session makes the ingest pipeline look fresh even if no inbound relay messages are being ingested. Empty sessions created above also set this timestamp, so please keep a separate last-ingested timestamp or exclude user-created/owner-only activity from that health query.

Useful? React with 👍 / 👎.

@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/components/intelligence/TinyPlaceOrchestrationTab.tsx`:
- Around line 576-599: The contact disclosure button in
TinyPlaceOrchestrationTab toggles nested sessions but doesn’t expose its open
state to assistive tech. Update the button in the contact row to include
aria-expanded, wired to the existing isOpen state used by toggleContact, so
screen readers can announce whether the session list is expanded or collapsed.
🪄 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: 89fefbc6-e42e-4b95-ac85-653a5c210b6a

📥 Commits

Reviewing files that changed from the base of the PR and between 6faeeaa and d457e2c.

📒 Files selected for processing (20)
  • app/src/components/intelligence/TinyPlaceOrchestrationTab.test.tsx
  • app/src/components/intelligence/TinyPlaceOrchestrationTab.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/lib/orchestration/orchestrationClient.ts
  • app/src/lib/orchestration/useOrchestrationChats.ts
  • src/openhuman/orchestration/schemas.rs
  • src/openhuman/orchestration/store.rs

Comment thread app/src/components/intelligence/TinyPlaceOrchestrationTab.tsx
senamakel added a commit to senamakel/openhuman that referenced this pull request Jul 3, 2026
Unrelated CI unblock: tinyhumansai#4446 (Privacy Mode) registered
`config_get_privacy_mode` / `config_set_privacy_mode` unconditionally
(src/openhuman/config/schemas/controllers.rs) but did not update the
`worker_a_controller_schemas_are_fully_exposed` golden in
tests/config_auth_app_state_connectivity_e2e.rs, so that test fails on
main for every PR that doesn't carry the fix. Add the two methods at their
sorted positions (same fix as tinyhumansai#4475) so this PR's Rust E2E / coverage
jobs go green.

Claude-Session: https://claude.ai/code/session_01KcmdqJVpjmnH31HqTHRLwG
sanil-23 added 3 commits July 4, 2026 09:54
… send

- Contacts sidebar is now expandable: each accepted contact expands to
  reveal its sessions (by sessionId) plus a "New session" action;
  sessions with no known contact peer fall into an "Other sessions" bucket.
- New orchestration_sessions_create RPC mints a per-contact session
  (fresh uuid harness id, source "user_created"); the composer now sends
  under a selected session too, not only Master.
- send_master_message gains an optional sessionId: the body is wrapped in
  a v1 session envelope stamped with that id (so a compliant peer threads
  the reply) and mirrored into the session window.
- Fix: resolve a contact's address from contact.requester/addressee when
  the relay omits the top-level agentId — previously the address rendered
  blank and the request cards had undefined React keys.
- Fix: orchestration_messages_list schema now declares `limit`; every
  message load was being rejected by param-validation.
- i18n keys (contacts/noContacts/newSession/otherSessions) across all 14 locales.
…n envelope

The wake-graph's send_dm sent replies as plain DMs, so a reply into a real
harness session was not stamped with the session id and a strict peer would
classify it as a non-session (Master) DM — breaking return-path threading.

- Centralize the outgoing-envelope builder as SessionEnvelopeV1::outgoing()
  and reuse it from the RPC send path and the graph send path.
- send_dm now wraps a reply into a real session in a v1 envelope (plain for
  the pinned Master/subconscious windows) via a testable session_send_plaintext.
…tton

Addresses CodeRabbit: the contact row toggles nested sessions but only
signalled state via the ▾/▸ glyph. Add aria-expanded for assistive tech,
asserted in the create-session test.
@sanil-23 sanil-23 force-pushed the feat/orchestration-contact-sessions branch from 9636641 to 4e77740 Compare July 4, 2026 04:25
@coderabbitai coderabbitai Bot added the bug label Jul 4, 2026
@sanil-23

sanil-23 commented Jul 4, 2026

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jul 4, 2026

Copy link
Copy Markdown
Contributor
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai coderabbitai Bot removed the bug label Jul 4, 2026
@senamakel senamakel merged commit 16d2989 into tinyhumansai:main Jul 4, 2026
21 of 31 checks passed
@github-project-automation github-project-automation Bot moved this from Todo to Done in Team Openhuman Jul 4, 2026
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

Status: Done

Development

Successfully merging this pull request may close these issues.

2 participants