Repository navigation
feat(face-rooms): a plain line lets every Bot in the room answer, one pass, capped (#295) - #296
Conversation
… pass, capped (#295) Closes #295. Plain line: admin first then room order, up to 6 local Bots, each after the earlier replies, no follow-ups inside the pass; a friend's attested plain line (or @ALL) starts the same pass on the receiving home. @name targets one Bot; Bot posts still start only the Bots they @.
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: e0b11ed6b6
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| // One pass: a plain line's speakers do not call each other on (#295), so Bots in two homes cannot loop. | ||
| ...(isPlainFaceLine(room, opener) ? { single: true } : {}), |
There was a problem hiding this comment.
Track single-pass behavior per queued message
When another composer message arrives while a round is running, drainRoomInbox adds that message's speakers to this same round, but single remains based only on the original opener. Consequently, a plain line queued during a targeted/non-single round can have its Bot replies trigger extra @ turns, while an @Name line queued during a plain/single round has its normal follow-up calls suppressed. The one-pass policy needs to follow the slots created for each message rather than being a round-wide flag fixed here.
Useful? React with 👍 / 👎.
| const found = named.filter(other => other.id !== member.id) | ||
| const callees = leads && all ? [...found, ...others.filter(other => !found.includes(other))] : found | ||
| callMembers(round, turns, index, callees, `${member.name} mentioned you`, leads ? ROOM_ADMIN_TURNS_EACH : ROOM_TURNS_EACH, member.id) | ||
| if (!round.single) callMembers(round, turns, index, callees, `${member.name} mentioned you`, leads ? ROOM_ADMIN_TURNS_EACH : ROOM_TURNS_EACH, member.id) |
There was a problem hiding this comment.
Preserve one-pass behavior for late replies
This guard covers only replies completed while runRound is awaiting the participant. If a Bot starts a tool, is already busy, or waits for approval, the slot becomes working/waiting-approval; its eventual answer goes through lateRoomReply, which posts only late: true and loses the single marker. An @Name in that answer therefore opens another normal round despite the plain-line contract that Bot replies start no further rounds, so the single-pass state must also be propagated through deferred room turns.
Useful? React with 👍 / 👎.
… by every Bot (ThinkFlowLab#299) (ThinkFlowLab#300) Closes ThinkFlowLab#299. Refines ThinkFlowLab#295/ThinkFlowLab#296. ## Rule as implemented For a **plain** line (no `@name` / label / handle) in a face-to-face room — the owner's own, or a friend's line the server attests `typed_by_owner`: - `@Name` / label / handle still targets exactly that one Bot (unchanged). `@all` is unchanged (everyone) and is not routed (`everyone` flag now carried from the friend's `@all`). - Same single sequential round as ThinkFlowLab#296 (admin first, then room order, cap 6; replies' own `@`s start nothing, so no loops; later Bots see earlier replies). Each Bot's prompt now has a routing note (`routeNote`): answer only if the line is for you (named/role), or nobody before you answered it and you add something genuinely new; reply `[PASS]` if a Bot before you answered, if it is for another Bot by name/role, or if it follows up on another Bot's answer. The note lists what each member does (role) and the friends' Bots (who answer for themselves in their own home). - A line to everyone (`你们/大家/各位/everyone/introduce yourselves/…`, `ROOM_EVERYONE`) says each Bot may give its own short answer unless it would just repeat. - **Follow-up:** the Bot that spoke last before the line (`recentSpeaker`) is asked first and named in the note. - **Fallback:** if every Bot passes on the owner's own line, the first Bot that passed answers (`fallbackDue`; no pass option), so the user is never ignored. Not forced for a friend's attested line (their home answers it) nor when the follow-up is to a friend's Bot. - A pass is the existing `[PASS]` (`isPass`): nothing posted, logged, fanned out or shown, and no approval hold. No UI change; the only visible state is the existing "thinking" of a Bot whose turn is running. - Approval / Auto-send unchanged. A line the user adds mid-round is handled by the old rule (the round stops routing). No Bot Social change needed. ## Tests (`core/test/rounds.test.js`) pass posts nothing and one Bot answers; everyone-line may get several; `@Name` / friend `@all` unrouted; all-pass fallback (owner) / not forced (friend); fallback reply's `@` starts no turns; follow-up asks the last speaker first; follow-up to a friend's Bot not forced locally. `ARCH_DOCS_BASE=origin/main TZ=UTC npm run verify` green locally. Docs: core-host, social, plugin-runtime. Patches regenerated. Co-authored-by: Birfy <15378933+Birfy@users.noreply.github.com>
Closes #295. Follow-up to #288/#287 (user feedback: only the first Bot answered a plain line).
Rule
@naming a Bot) in a face room: one round, every local Bot in the room may answer, admin first, then the room's order, capped at 6 speakers, one at a time, each seeing the earlier replies (the existing sequential round). The round issingle: the replies' own@s start no follow-up turns inside it.typed_by_owner(the plugin passesattestedtopostHuman; a plain or@allattested line carriesplain: truein the post source). An attested line naming Bots calls only those; one naming only a friend's Bot calls none here; a server that cannot attest never starts Bots.@Name/ label / handle still targets only that Bot;@allunchanged (everyone, uncapped as before). A Bot's own post still starts only the Bots it@s and a remote Bot's post starts none, so two homes cannot set each other off. Approval / Auto-send gating of every outbound Bot line is unchanged.Tests
core
rounds(plain pass over two local Bots with a friend's Bot present, sees earlier reply, no follow-ups,@Writeronly one, Bot post none, unattested none, attested plain starts both; large room capped at 6),flybot(postHumanplain/@all/named/unattested/list), social (only stamped lines areattested).TZ=UTC npm run verifypasses.