Repository navigation
fix(gate): keep notices out of a batch's route; name its channels - #948
Open
nissa-seru wants to merge 1 commit into
Open
nissa-seru wants to merge 1 commit into
nissa-seru wants to merge 1 commit into
Conversation
A debounced gate batch let a chat:system notice decide its route, its addressed flag and the channel its wake names. A pin in a DM is addressed by its place, so as the newest addressed event it took the reply meant for a mention elsewhere in the same batch, though 0.28.0 says no notice decides where an agent's speech goes, even one addressed by its place. The direct path already skips notices. A batch in which no message addressed the agent sets no route, so under the default speech.locus its turn has no channel. The agent was then told its reply "came from no channel", and to ask whoever runs the host, though the batch's messages came from channels and nothing is misconfigured. - wakeProvenance sets notices aside before choosing the batch's event. A batch of notices alone names only the author of its newest notice that has one, as the same notice woken directly does. Its doc names the exception. - A batch in which no message addressed the agent lists the channels its messages came from, those the host resolved, keyed on server and id, in the new WakeProvenance.batchChannels. A push the host can't place is passed over. The framework carries the channels it names on the wake as the new InferenceRequest.wakeChannels; a merge keeps them unless a request in it names a channel. - With no locus, deliverSpeech's reason names those channels, says what came from them didn't address the agent and that no channel was chosen, and says to send explicitly, under prose routing by locus and hybrid and for a sleep's announcement. The notice calls this a routing situation (byDesign), where every other no-channel notice keeps "routing/configuration". The logged line keeps "no locus". - wakeProvenance's fallback time is a reduce, not a spread, so a very large batch can't overflow the call. - Tests: notices beside a message, addressed in a DM beside a mention, and alone; a batched notice's stamp against the same notice woken directly; the channels of one-channel, two-channel, push-only, unplaceable-push and two-server batches, and none for an addressed batch; the whole reason for one and two channels from batches of one to three messages, under locus and hybrid, and a sleep's; merges with a channel-naming wake, an addressed wake and an addressed notice; a fork's home kept; no notice when the fallback gives a channel; the log line and trace keeping "no locus"; a 200,000-event batch.
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.
In a debounced gate batch, a
chat:systemnotice no longer decides the batch's route, itsaddressedflag or the channel its wake names. When no message of a batch addressed the agent, the notice the agent gets for a reply that had no channel now names the channels the batch came from and says to send explicitly, where it said the turn came from no channel.At
a64cfc010f, a batch of a mention in one channel and a newer pin in a DM took the pin's DM as its route, not the mention's channel. 0.28.0's changelog says no notice decides where an agent's plain speech goes, even one addressed by its place. And a reply to a batch that addressed no one was told it "came from no channel" and to ask whoever runs the host, though the batch's messages came from channels and nothing is misconfigured. The six test files this change touches pass at this head, 281 tests, and witha64cfc010f's versions of the four source files it touches, 19 of them fail (see Tests). This change doesn't route such a batch: #945 proposes that separately, since it would change a rule agent-framework publishes.@antra-tess, we're asking you to review this before it's merged, since it changes what an agent reads: the
[send-undeliverable]notice it gets when its reply to a debounced batch that didn't address it went nowhere, and which message of a batch decides where its reply goes.Problem
At
a64cfc010f, in this change's tests run witha64cfc010f's versions of the four source files it touches (see Tests):A notice deciding a batch's route.
wakeProvenancetakes the batch's newest addressed event as its route, countingchat:systemnotices. Intest/event-gate.test.ts, a batch of a mention indiscord:g:roomand a newer pin indiscord:dm:5, which is tagged as addressing the agent, got the routediscord:dm:5, not the mention's channel. Intest/chat-system-notices.test.ts, a notice the gate batched stamped its turn'swakeChannelIdasworld:commons, where the same notice woken directly stamps none. 0.28.0's changelog says achat:systemnotice "no longer decides where an agent's plain speech goes … This holds when the notice is also addressed by its place (a pin in a DM)" (CHANGELOG.md:2072–2083).A notice that's false for a batch. A batch in which no message addressed the agent sets no route, and under the default
speech.locus: 'delivery'its turn had no channel in these tests. Intest/batched-wake-locus.test.ts, a reply to such a batch from one channel, and from two, got:The batch's messages did come from channels.
Changes
wakeProvenance,src/gate/event-gate.ts). Achat:systemnotice decides neither the batch's route, nor itsaddressedflag, nor the channel its wake names, even when it's addressed by its place. A batch of notices alone carries only the author of its newest notice that has one, as the same notice woken directly does.wakeProvenance's doc names the exception.WakeProvenance.batchChannelslists the registered channels its messages came from, those the host resolved, keyed on server and id, each once in the order they first appear. A push the host can't place is passed over, and a notice names no channel. The framework carries them on the wake as the newInferenceRequest.wakeChannels, and a turn merged from several such wakes names each channel once, unless a request in the merge names a channel.src/mcpl/channel-registry.ts,src/framework.ts). When such a turn routes its plain speech, or a sleep's announcement, with no channel to go to, the reason names those channels as the agent is shown them, says what came from them didn't address the agent and that no channel was chosen, and says to send its reply to that channel, or one of them, explicitly. The notice calls it "a routing situation", where every other no-channel notice keeps "routing/configuration". It holds under prose routing by locus and by hybrid. The reason lists every channel it's given, with no limit on how many. For three or more,src/mcpl/channel-registry.ts:6177at this head joins them as "#a, #b and #c". Only one channel and two ran here. The logged line keeps "no locus", which connectome-host'sscripts/connectome-doctorlooks for (:311at anima-research/connectome-host@82cbab99).wakeProvenance's fallback time is a reduce rather than a spread intoMath.max, so a very large batch can't overflow the call.WakeProvenance.batchChannelsandInferenceRequest.wakeChannelsare new optional fields of exported types.test/batched-wake-locus.test.ts,test/event-gate.test.ts,test/chat-system-notices.test.ts,test/turn-trigger-provenance.test.ts,test/channel-registry-routing.test.tsandtest/route-failure-targeting.test.ts, as the Tests section lists.With other open pull requests
At 21:42 UTC on October 30, this change merges with
mainata64cfc010fwithout conflicts, bygit merge-tree. Of the 50 open pull requests, 40 change a file that this change changes, each by its diff from its merge base withmain. Each was merged bygit merge-treewithmain, and with this change merged into it, and the conflict blocks in each file were counted.mainwithout conflicts. Ten of them, fix: pass the lists at 65 call sites without a spread, so 250,000 held wakes or judged events don't throw #942, fix(trace)!: TraceEvent lists every trace the framework raises, and tsc checks each raise against it (anima-research/agent-framework#899) #944, fix(gate): deliver what the gate held for a turn only if nothing took it back #943, fix(history, prose): one table of the tools that carry an agent's words, read by silencing, search, extract and the semantic index #914, Add opt-in required admission for inbound MCPL traffic #906, feat(scheduler): messageQuietPeriod — one turn per message burst (carries #179) #856, fix(references): while a reference is markednever, don't fetch or save its payload, and forget an earlier copy's path #851, fix(framework)!: decline a maxStreamTokens restart that won't fit #842, fix(mcpl,api): read a JSON-RPC envelope once: answer id null, refuse an invalid request with -32600 #534 and fix: a turn whose compile is refused for budget waits while compression is pending, and runs once its context fits #361, at448a67083f,c97253ce08,bf1b83a855,5d9af7beec,869bb3add7,965806c832,2f15c4293d,81ef4cfaf1,f9337c4794andb58be0b200, also merge with this change without conflicts. Five conflict with it:63682f368f: four blocks insrc/framework.ts, one insrc/mcpl/channel-registry.tsand one intest/route-failure-targeting.test.ts;acfccc9a24: one block insrc/gate/event-gate.ts;20610f0cfe: three blocks insrc/framework.ts, one insrc/gate/event-gate.tsand two insrc/mcpl/channel-registry.ts;b9c4979e89: one block insrc/gate/event-gate.ts;813fe034fc: one block insrc/framework.ts, four insrc/gate/event-gate.tsand one intest/event-gate.test.ts.main. With this change merged, 22 of them have the same number of conflict blocks in each file, and three change:665957dd5f:src/framework.tsgoes from 112 blocks to 113,src/gate/event-gate.tsfrom 11 to 13, andtest/batched-wake-locus.test.tsfrom 2 to 3;0bae78b1dd:src/framework.tsgoes from 109 to 110,src/gate/event-gate.tsfrom 11 to 13, andtest/batched-wake-locus.test.tsfrom 2 to 3;c3b440879a:src/mcpl/channel-registry.tsgoes from 10 to 11.Tests
Each run below was part of one invocation on Linux, in a clean checkout of
1e86b9ab1b, this head, with Node 24.22.2 and npm 11.19.1.npm installgave TypeScript 7.0.2,@animalabs/context-manager0.24.2,@animalabs/mcpl-core0.4.0,@animalabs/membrane0.8.0,@animalabs/chronicle0.5.1,@modelcontextprotocol/clientand@modelcontextprotocol/server2.4.0, discord.js 14.27.0, ws 8.22.0, chokidar 4.0.3 and@babel/parser7.29.12.At this head.
tsc --noEmitand the build succeed, and the six test files pass: 281 tests, none failing or cancelled, run with--test-force-exit, the flagnpm testuses.Red first, with
a64cfc010f'ssrc/framework.ts,src/gate/event-gate.ts,src/mcpl/channel-registry.tsandsrc/types/agent.tsin place of this change's. The build reported 8 type errors, each where a test usesbatchChannels,wakeChannelsorrouteSpeech's new argument, and still wrote the output the tests ran from. 19 tests fail:batched-wake-locus: 6 of 12, each a test of the notice: batches of one, two and three messages from one channel or two, under prose routing by locus and by hybrid, and a sleep's announcement. Each failure shows the old "came from no channel" notice.event-gate: 8 of 71: the pin in a DM beside a mention; a notice's channel; the channels of a batch that addressed no one, of pushes that name only their registered channel, and of one channel id on two servers; a push the host can't place, passed over; a newer ambient push that names only its route, not hiding an earlier event's channel and author; and a batch too large to spread into one call.turn-trigger-provenance: 3 of 11: a turn merged from several such wakes, one merged with a wake that names a channel, and a gate wake naming a channel another conversation fork calls home.chat-system-notices: 1 of 9, the batched notice's stamp.channel-registry-routing: 1 of 78, the reason's words and the log line.route-failure-targeting: none of its 100 fail, since a turn with no channel at all keeps "routing/configuration".The notice. At this head, a copy of
test/batched-wake-locus.test.tswith oneconsole.logadded printed the notice its tests get. For one channel, from batches of one message and of two:For two channels, from batches of two messages and of three: "… this turn came from #room (discord:g1:room) and #general (discord:g1:general), and what came from those didn't address you, and no channel was chosen for its reply; to reply in one of them, send your reply to that channel explicitly. This is a routing situation, not a channel failure. …"
Not verified
changelog.d/gate-batch-channels.changed.md, it keeps the old notice. No test runs it: the one test of a push the host can't place batches it beside a message whose channel resolves.MockMembrane). Nothing ran against Discord.changelog.d/gate-batch-notices.fixed.md,changelog.d/gate-batch-channels.changed.mdandchangelog.d/gate-batch-channels.added.md.Effie-2289 made the change, and Ada-1017 made its design calls. Internal reviews read its rounds. Humphrey-2407 wrote this description.