Repository navigation
feat(features,service,dev): the agent reads and replies on its Inbox threads - #3482
Merged
Merged
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
luke-agent
Bot
changed the base branch from
main
to
luke/inbox-thread-messages
October 17, 2026 13:32
14 tasks done
luke-agent
Bot
force-pushed
the
luke/inbox-thread-messages
branch
from
October 17, 2026 13:49
7625beb to
03a363e
Compare
luke-agent
Bot
force-pushed
the
luke/inbox-reply-tool
branch
from
October 17, 2026 13:49
376bdf0 to
29490ca
Compare
Merged
14 tasks done
luke-agent
Bot
force-pushed
the
luke/inbox-reply-tool
branch
from
October 17, 2026 14:17
29490ca to
45e0520
Compare
…threads read_inbox now answers each item's thread oldest first: who wrote each message (a member by name, or "you"), its words, and its files by name. A new reply_inbox tool writes the agent's own message on one of its items by key. It takes Markdown, and pictures named by their paths in the sandbox, read and kept as an image block's are. It leaves the item's status, answer, revision, and settledAt as they stand, and moves updatedAt. Its description says when to use it: to answer a member's "Inbox message", or to follow up on an item after its answer, with post_to_inbox under the same key when the item itself changes. The coder instructions say the same. Co-authored-by: luke-agent[bot] <339870089+luke-agent[bot]@users.noreply.github.com>
…member's agent replies nowhere reply_inbox with images reads them from the sandbox, so opensSandbox now counts it, and the turn's end records the branch and stops the sandbox as it does after any other sandbox read. An agent's reply is written only where its starter is still a member of the item's workspace, as its posts are. Co-authored-by: luke-agent[bot] <339870089+luke-agent[bot]@users.noreply.github.com>
luke-agent
Bot
force-pushed
the
luke/inbox-reply-tool
branch
from
October 17, 2026 14:28
45e0520 to
f990e06
Compare
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.
Builds on #3469, which has merged; this PR now targets
main.Summary
This is the agent half of Dean's request: a message can be added to an Inbox item's thread at any point. #3469 is the service half, and a separate worker builds the desktop half.
read_inboxshows each item's thread. Every inbox call answers with each item'sthread, oldest first. Each entry is{ from, text, files? }:fromis a member by name, "a former member" when their account is gone, or "you" for the agent itself.fileslists the files by name. A thread shows on settled items too, since a member can write on those.reply_inboxis a new tool inINBOX_TOOLS, with its eve fileapps/dev/tools/reply_inbox.tsmodelled onpost_to_inbox.ts.{ key, text, images?: [{ path }] }. It needs words, pictures, or both.textis Markdown of at most 8,000 characters, and there are at most 4 pictures.readSandboxImagewith the reply's own refusal wording, held to the image bound, and kept as message files named by the file's base name.settledAtstay as they are, andupdatedAtmoves.post_to_inboxunder the same key.AGENT_TOOL.REPLY_INBOX(coder only),CODER_TOOL.REPLY_INBOX, its context estimate, and the host's inbox door, which hands a reply the sandbox as it does a post.opensSandbox), so the turn's end records the branch and stops the sandbox. A reply is written only where the agent's starter is still a member of the item's workspace.replyInboxItem(agent, key, text, pictures)finds the agent's own item by key and writes through the samewriteInboxMessageas a member's message. That function now takes files as{ name, contentType, bytes }.The desktop's tool-call card has no case for
reply_inboxyet, so it draws the generic card. Drawing it as an inbox card is left to the desktop half.Evidence
pnpm check:affectedis killed by the sandbox's 8 GB limit when its tasks run in parallel, so I ran its parts one after another. All passed:pnpm knip,pnpm discarded-effect,pnpm oxlint, andbiome check.turbo run typecheck --concurrency=1over every dependent of@luke/features.vitest run packages/service/src/agents/coder-host packages/service/src/agents/agent-runtime packages/service/src/agents/link-examples.test.ts: 25 files, 135 tests passed.hosted-wire-schemas.test.ts: 359 tests passed.Invariants
./scripts/check.shgreen. (CI) Locally, its parts ran one after another, as above.LUKE_UPDATE_FIXTURESnot run, or diff explained line by line). (CI) One golden is new:inbox-wire-inboxReplyInputSchema.json, the tool's input{ key, text, images? }.packages/service/fixtures/coder-instructions/chat-off.jsongains one sentence in each of its four prompts, thereply_inboxguidance above; I checked that this sentence is the only difference.AGENTS.md"Testing") Two tests incoder-inbox.test.ts:read_inboxreturns the thread in order: a member's message under their name with its file named, then the agent's own reply as "you".reply_inboxwrites the agent's message with its picture, which is read from the sandbox, kept, and served. Status, answer, revision, andsettledAtstay, andupdatedAtmoves. It refuses another agent's key, an unknown key, empty words, and a file that is not a picture, and none of them writes anything.astype assertion outside the allowlisted files. (CI via anti-slop) The tool file'sas WireBoundaryInputis the same one every eve tool file carries.Effect.runPromise/runSync/runForkoutside the runtime edges and the shimstools/anti-slop/effect-edges.jsonrecords. (CI viaanti-slop/no-run-promise-outside-edges)setTimeout/setInterval/new Promise/AbortController/fs.watchoutside the filestools/anti-slop/effect-edges.jsonrecords. (CI viaanti-slop/no-raw-async-primitives)pnpm discarded-effect)vitest run --reporter=json) +4: the two above, a reply refused once its starter leaves the item's workspace, and the sandbox classifier counting a reply with pictures.AGENTS.md's "The permanent adaptors" with the reason it stays. Nothing is replaced.CLAUDE.md/AGENTS.mdsentence naming a changed part is edited; root pair stays byte-identical. None names these parts.PRIVACY.mdunchanged, or the change is a product decision called out in the PR body. Unchanged; feat(database,features,service): an Inbox item holds a thread of messages #3469 already describes a thread's messages.package.jsondeps match what the sources import by bare specifier;effectviacatalog:. (CI)@effect/platform-node,effect/sql) behind a barrel the renderer or a web function opens. (CI: existing renderernode:grep plus a new grep for those specifiers in renderer bundles)Notes
main.Made with Luke
Summary by cubic
The coding agent can now read and reply on its Inbox threads.
read_inboxanswers with each item's thread, oldest first, naming each writer ("you" for the agent, the member by name, or "a former member") and the files by name, on settled items too. The newreply_inboxtool writes the agent's message on one of its own items by key, with Markdown and up to 4 pictures read from the sandbox; it leaves status, answer, revision, andsettledAtas they stand, movesupdatedAt, and refuses unknown keys, replies with neither words nor pictures, and files that are not pictures. The coder instructions now say when to use it: to answer a member's "Inbox message" or to follow up after an answer, and to post the item again under the same key only when what it asks changes.Written for commit f990e06. Summary will update on new commits.