Repository navigation
feat: send assistants a signed alert at a web address when a thread needs you, finishes or fails - #734
Merged
Conversation
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.
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
github-merge-queue
Bot
removed this pull request from the merge queue due to failed status checks
Oct 31, 2026
github-merge-queue
Bot
removed this pull request from the merge queue due to failed status checks
Oct 31, 2026
This branch was successfully deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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:
whsec_secret.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.Heads-up, cross-cutting: the outside agents' 16 RPCs now live in their own group,
WsOutsideAgentsRpcGroup, merged intoWsRpcGroup. 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 becameany, and onlybin.tsfailed 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.