Skip to content

[Feature]: Let me hide agent-to-agent threads: a snooze that holds until its time, whatever activity happens #14625

Description

@genesis-gh-agorshkov

The use case

More and more of my work in T3 is threads talking to other threads. A typical setup:

  • One front-desk thread is the only one I talk to.
  • A few coordinator threads each run a workstream. They plan the work, check on progress and report back to the front desk.
  • Several worker threads per coordinator do the actual implementation. Coordinators message them many times an hour.

That's 10–15 threads busy all day, and only one or two of them are mine to read. The worker threads are lower-level agents. They should stay available, so I can open one when I want to look, but I don't want to deal with them day to day. I want to decide which threads I see, and have everything else stay out of my sidebar.

How we make it work today

There's no thread-to-thread messaging built in, so we built it ourselves:

  • Threads message each other through the T3 CLI (t3cli send, t3cli transcript).
  • A small supervisor process wakes coordinators on a schedule, for example "check your workers every hour" or "post a digest at 10:00 and 18:00".
  • Everything runs on one always-on server, and I use desktop and iOS clients.

This works well, apart from the sidebar. Every message between agents starts a turn, and starting a turn clears snooze. So a worker I snoozed until tomorrow is back in my inbox minutes later, and I see every thread all the time. Nothing else puts a thread away while keeping it alive:

What we're asking for

A snooze that means "hide this until this time, no matter what". In the snooze menu (and the API), add an option such as "Keep snoozed through activity", or a setting that makes it the default. With it on:

  • New turns, completions and background work don't un-snooze the thread, whether they come from another thread, an automation or the CLI.
  • The session keeps running normally. This only affects where the thread appears in my sidebar.
  • The thread comes back at the chosen time, or when I open it or un-snooze it myself.
  • It shows in the Snoozed shelf as usual, ideally with a small indicator for "has new activity" or "needs input". Then I can choose to look, without the thread forcing its way back.

The default snooze can keep today's behaviour. This is an explicit choice for threads I've decided aren't mine to watch.

Longer term

A built-in notion of thread-to-thread messaging would make this cleaner. For example, a thread could send to another thread, and the receiving thread would know the message came from an agent and not from me. Then the app could tell "the user is engaging with this thread" apart from "agents are talking", and treat the two differently in the sidebar and notifications. The snooze option above is the smallest change that solves the day-to-day problem.

Environment

T3 server on Linux (Ubuntu 26.04), always on, with desktop (macOS) and iOS clients. Seen on nightly 0.0.43-nightly.20260929.2428 (orchestrator V2).

Activity

  1. juliusmarminge commented on Oct 1, 2026

    @juliusmarminge
    Member

    Note

    Grok responding on behalf of Julius.

    Triage

    Thanks for laying out the setup so clearly, @genesis-gh-agorshkov. The front-desk, coordinator, and worker layout makes the problem easy to see. Nothing that ships today keeps a live worker out of the inbox until a set time while other agents keep messaging it, short of stopping its session. That gap is real, and how to close it is a product decision, so I'm labeling this as an enhancement for maintainers to weigh.

    Why snooze clears today

    • A new turn spends the snooze. thread.turn.start in apps/server/src/orchestration/decider.ts emits thread.unsnoozed with reason activity whenever snoozedUntil is set. This is documented and covered by decider.snoozed.test.ts. A t3cli send arrives as a regular user message, and the command doesn't record whether an agent or a person sent it, so the server can't tell a coordinator apart from you.
    • Completion brings the row back. threadRaisedHandWhileSnoozed in packages/client-runtime/src/state/threadSettled.ts treats a turn that finished after snoozedAt as a raised hand, which is the case in [Bug]: completed work wakes snoozed threads and breaks subsequent snoozing #6368 (open). A pending approval, a pending question, or a newer error also raise the hand.
    • A live session doesn't clear it. Snooze never pauses the agent, and a running session can stay snoozed.

    The other options fall short in the ways you described. Settle stops the provider session. Archive moves the thread out of the sidebar. The Working shelf PRs (#13926 and #14582, both open) only hide a thread while it's busy. Auto-settle (#13630) ends in a settle. And "Until done" in #13196 (open PR) does the opposite, waking the thread when the run ends.

    What a maintainer would need to decide

    "Whatever activity happens", taken literally, would also hide approvals and questions inside the Snoozed shelf. Snooze deliberately refuses to do that, because blocked work should come back and notify you. A narrower version that would still solve the day-to-day problem is a per-snooze flag, something like "Keep snoozed through activity", where:

    • new turns don't emit thread.unsnoozed while the flag is set,
    • a finished turn doesn't raise the hand, but approvals, questions, and fresh errors still do, and snooze still refuses to hide an open request,
    • the session keeps running, and Wake thread and the timer work as they do now,
    • the Snoozed shelf can show a small marker that a turn finished,
    • notification behaviour is handled separately and never swallows approvals, questions, or errors.

    Built-in thread-to-thread messaging would be a bigger feature. It isn't needed for this flag.

    Please hold off on a PR until a maintainer signs off on a direction (prior approval).

  2. genesis-gh-agorshkov commented on Oct 1, 2026

    @genesis-gh-agorshkov
    Author

    An update, for anyone hitting the same thing. As a stopgap, we now run a small service on our server that re-snoozes a thread whenever agent activity wakes it. It reads the event log and tells agent messages from user messages by their command id. This works, but it ran into one more limit that only the server can fix.

    If an agent messages a thread while that thread is mid-turn, the message is queued. thread.snooze is then refused with "has a queued turn start and cannot be snoozed" until a turn picks the message up, or until QUEUED_TURN_START_GRACE_MS (2 minutes) passes. In a coordinator setup this happens often: workers run long turns, and the coordinator messages them during those turns. So a thread the user snoozed comes back for up to two minutes at a time, and nothing outside the server can stop it.

    With a "keep snoozed through activity" option, the snooze would never be cleared in the first place, so both this and the one-second re-snooze workaround for #14298 would go away.

  3. locked and limited conversation to collaborators on Oct 11, 2026
  4. converted this issue into a discussion #18017 on Oct 11, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementRequested improvement or new capability.via-triageFiled through npx t3 triage

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions