feat(team-mode): team_read_messages pull tool + top-level team_create args#5463
Open
harshav167 wants to merge 2 commits into
Open
feat(team-mode): team_read_messages pull tool + top-level team_create args#5463harshav167 wants to merge 2 commits into
harshav167 wants to merge 2 commits into
Conversation
The lead could only see unread COUNTS via team_status; message BODIES were
only surfaced passively by the mailbox injector on the lead's next turn (and
consumed there). When the lead was busy or timing was off, member reports
piled up unread with no way to drain them, forcing a file side-channel.
Add team_read_messages({ teamRunId, sinceId?, mark_read? }): resolves the
caller's member identity (same path as team_send_message), reads its inbox
bodies via listUnreadMessages oldest-first, optionally filters after sinceId,
and by default acks them via ackMessages so they are not re-injected
(mark_read:false to peek). Additive and gated on team_mode.enabled; the
injector path is untouched.
Tests: read-messages.test.ts (bodies+ack, sinceId, peek, empty). Team record
now exposes 13 tools including team_read_messages; typecheck clean.
…-yeongyu#1) The team_create tool advertises the inline member shape, so agents routinely call it with the spec fields (name + members) at the top level and get rejected with "exactly one of teamName or inline_spec", costing a failed call every run. Fold top-level spec fields into inline_spec during arg preprocess (leadSessionId preserved), and document the accepted shape in the tool description and usage string. The documented teamName / inline_spec envelopes are unchanged. Test: lifecycle-top-level-args.test.ts (top-level coercion, leadSessionId preserved, inline_spec untouched, teamName path, empty still errors).
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.
Summary
team_read_messagesso a team lead can pull its own inbox bodies on demand — the biggest team-mode blocker was thatteam_statusexposes only unread COUNTS and the injector only surfaces messages passively on the lead's next turn (and consumes them).team_createaccept the natural top-level{ name, members }shape (folded intoinline_spec), so agents stop hitting"exactly one of teamName or inline_spec"on the obvious call.Changes
team_read_messages({ teamRunId, sinceId?, mark_read? })(new team tool, gated onteam_mode.enabled): resolves the caller's member identity viaresolveTeamRuntimeDetails(same path asteam_send_message), reads its inbox via the existinglistUnreadMessagesoldest-first, optionalsinceIdreturns only messages after that id, and by default acks read messages viaackMessagesso they are not re-injected (mark_read:falseto peek). Registered intool-registry-team-tools.ts,tool-registry-factories.ts, and thetoolsbarrel. The injector path is untouched.team_createtop-level coercion: fold top-level spec fields (name/members/…) intoinline_specduring arg preprocess when neitherteamNamenorinline_specis supplied (leadSessionIdpreserved). Tool description + usage string updated to advertise all three shapes.Testing
read-messages.test.ts(4): bodies oldest-first + ack,sinceIdfilter,mark_read:falsepeek, empty inbox.lifecycle-top-level-args.test.ts(5): top-level coercion,leadSessionIdpreserved,inline_specuntouched,teamNamepath, empty still errors.createTeamModeToolsRecordreturns 13 tools includingteam_read_messages.~/.local/share/opencode/opencode.dbsession count unchanged.Related Issues
Team-mode tooling friction observed in a real hyperplan run:
session_readhides tool args) / Recommended global Agents file #9 (lead-relay fidelity loss) →team_read_messages.team_createschema/description mismatch) → top-level coercion.Scoped to follow-up PRs (not here): #8/#2 (broadcast wakes idle members) and #5 (idle-wake determinism) touch the
prompt-async-gate/ live-delivery path and need their own PR with the mandatory duplicate-injection regression tests; #7 (list_modelscold-cache) belongs on the per-call-model-override branch wherelist_modelslives; #6 (filename ambiguity) is a hyperplan-skill prompt tweak.Summary by cubic
Adds a
team_read_messagestool for on-demand inbox reads, and letsteam_createaccept top-levelnameandmembers. This gives leads access to message bodies and removes a common arg mismatch.team_read_messages({ teamRunId, sinceId?, mark_read? }): returns the caller’s unread messages oldest-first, optionally aftersinceId. Marks them read by default; setmark_read:falseto peek. Gated by team mode; injector path unchanged.team_create: accepts top-levelnameandmembersand folds them intoinline_specautomatically. PreservesleadSessionId. Tool description and usage updated.Written for commit 7c71765. Summary will update on new commits.