Skip to content

feat: send assistants a signed alert at a web address when a thread needs you, finishes or fails - #734

Merged
badcuban merged 8 commits into
mainfrom
feat/assistants-alerts-out
Oct 31, 2026
Merged

badcuban merged 8 commits into
mainfrom
feat/assistants-alerts-out

Conversation

@badcuban

Copy link
Copy Markdown
Collaborator

Assistants (Grok Bot, dots and others) only learned what happened in Threadlines when they checked in, every few hours. Now this computer can wake them: Settings › Connections › Assistants gets "Alerts to a web address", and each address gets a signed alert when a thread needs you, finishes or fails. A Grok routine's webhook with its key as the Authorization header is the main use. Step 4 of docs/design/assistants.md.

How it works:

  • What's sent. Each alert carries the kind, the project, the computer and a link, never a thread's title or what its agents wrote. Alerts are signed with Standard Webhooks headers and a per-address whsec_ secret.
  • Network rules (net/outboundHttps.ts): https only. A host that resolves to any private, loopback, link-local, CGNAT or reserved address is refused (IPv4, IPv6, mapped and NAT64). The call connects only to the address that was checked, through its own agent and never a proxy, follows no redirects, and gets 10 seconds.
  • Never twice, never skipped. The attempt is written before each call, so one that may have arrived is never sent again. Each address keeps a watermark into the assistants' event record, so a retrying alert is never skipped, and turning an address on again doesn't replay what it missed.
  • Receiver answers. 410 turns the address off; three 401 or 403 answers in a row show as refused.
  • Checked again before each send. A needs-you that no longer needs you is dropped, and so is an alert for a thread you have open (on by default).
  • The record. It now runs while an address is on, not only while an assistant is connected.
  • Settings. Add, edit (the saved key is never shown again; keep, replace or clear it), send a test, copy the signing secret, turn off or on, and remove. Secrets live in the secret store, never in the database or the app.

Heads-up, cross-cutting: the outside agents' 16 RPCs now live in their own group, WsOutsideAgentsRpcGroup, merged into WsRpcGroup. Nothing changes on the wire. The reason: the main group's handler types sat at TypeScript's limit of 5 million instantiations per statement. Adding six RPCs pushed it over, and TypeScript said nothing; the server layer's type just became any, and only bin.ts failed to compile. The main group now has room for roughly 12 more RPCs. The lasting fix is splitting it further by area.

Reviewed by Sol (three findings, all fixed: an edit can't pair a new key with the old address, waiting alerts follow edits, a stalled 503 is retried). Checked live in a throwaway copy of the app, and the network code against a local HTTPS receiver. Not yet sent to a real public receiver or a real Grok routine.

Each target that's on gets the record's events of its kinds and projects,
signed with Standard Webhooks headers and its own whsec_ secret, under
outbound network rules (https only, public addresses only, pinned to the
checked address, no proxy, no redirects, 10 s). A retrying event holds the
target's watermark; a send that may have arrived is never repeated; 410
turns the target off; three 401/403 in a row show as refused. The record
runs while a target is on, and a target starts at the record's last seq.

The outside agents' RPCs move to their own group, merged into WsRpcGroup:
the main group's handler types sat at TypeScript's per-statement cap, and
past it the server layer's type silently became any.
Settings › Connections › Assistants gets "Alerts to a web address": one
row per address with its host, the kinds and projects it gets, and how
it's doing (last sent, retrying, refused or turned off by the receiver,
off, the last problem). Rows send a test, copy the signing secret, turn
off or on, edit and remove. Add and Edit share one dialog: the https
address, a write-only Authorization header (kept, replaced or cleared),
the kinds, the projects and "Skip threads I'm looking at"; the server's
refusal shows inline.

The web client wires the six new outsideAgents.alertTarget* calls. The
project picker moves out of the approval dialog so both dialogs share
it. The app guide gets the group as a place and the assistants topic
says how to use it with a Grok routine.
…keep the record

The sender's test fakes the environment without asserting its type away.
…ting alerts

A new Authorization value goes in a new secret entry, and the row's one
write switches the address and the entry together, so a failed save can't
leave the old address with the new key. Alerts waiting for a retry follow
the target's current kinds and projects. An answer whose body stalls keeps
its status, so a 503 that never finishes its body is retried.
@vercel

vercel Bot commented Oct 31, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
threadlines Ready Ready Preview Oct 31, 2026 8:04am UTC

Request Review

@badcuban
badcuban added this pull request to the merge queue Oct 31, 2026
@github-merge-queue
github-merge-queue Bot removed this pull request from the merge queue due to failed status checks Oct 31, 2026
@badcuban
badcuban added this pull request to the merge queue Oct 31, 2026
@github-merge-queue
github-merge-queue Bot removed this pull request from the merge queue due to failed status checks Oct 31, 2026
@badcuban
badcuban added this pull request to the merge queue Oct 31, 2026
Merged via the queue into main with commit f6e0d08 Oct 31, 2026
22 checks passed
@badcuban
badcuban deleted the feat/assistants-alerts-out branch October 31, 2026 09:06

This branch was successfully deployed

1 active deployment
Preview — ce0cc69f Deployed Oct 31, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant