@tinoy/pi-canon 0.6.1 → 0.6.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/index.ts +21 -3
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -24,7 +24,7 @@ pi install npm:@tinoy/pi-canon
|
|
|
24
24
|
- **Commands** — `/canon` (list, add, remove, edit, category management) and `/canon-dump`.
|
|
25
25
|
- **Injection** — the block is appended at `before_agent_start` and re-normalized on every provider request, so a run started by an injected message carries the same bytes as an interactive prompt.
|
|
26
26
|
- **Category headings** — a category sub-heading inside a scope group prints the store id after the word `category` (`#### Behavioural Preferences [category 1cg5lr]`), which is the same id a `canon_add` refusal lists; the word keeps it from reading as an entry handle, which the block renders as `[1i15c2]`. Uncategorized entries carry no id, and a scope group holding a single category stays flat with no sub-heading.
|
|
27
|
-
- **Peer notices** — entry changes are published over the `ipc` transport's bus (namespace `canon`); receivers match the entry scope against their own model and audience.
|
|
27
|
+
- **Peer notices** — entry changes are published over the `ipc` transport's bus (namespace `canon`); receivers match the entry scope against their own model and audience. A matching notice steers into a run that is already in flight, landing at the next tool boundary, and queues for the next turn when the session is idle, so it never wakes anything.
|
|
28
28
|
- **Tail sections** — another extension contributes prompt text through the `canon:section` event; its ids are published on `canon:sections`.
|
|
29
29
|
|
|
30
30
|
## Exports
|
package/index.ts
CHANGED
|
@@ -610,6 +610,23 @@ export default function (pi: ExtensionAPI) {
|
|
|
610
610
|
pi.events.emit("canon:sections", { ids: registeredSectionIds() });
|
|
611
611
|
});
|
|
612
612
|
|
|
613
|
+
// A notice steered into a live run lands at the next tool boundary, before the next
|
|
614
|
+
// LLM call; the passive queue drains only when a new turn starts, so a notice emitted
|
|
615
|
+
// mid-run would otherwise wait for the operator's next prompt. The passive route keeps
|
|
616
|
+
// the no-wake guarantee where it is needed — an idle session — and steer is used only
|
|
617
|
+
// while a run is in flight, where it cannot wake anything. A steer queued as the run
|
|
618
|
+
// settles can carry it one more LLM call; that is the price of a notice landing with the
|
|
619
|
+
// trajectory rather than after it.
|
|
620
|
+
let runInFlight = false;
|
|
621
|
+
|
|
622
|
+
pi.on("agent_start", () => {
|
|
623
|
+
runInFlight = true;
|
|
624
|
+
});
|
|
625
|
+
|
|
626
|
+
pi.on("agent_settled", () => {
|
|
627
|
+
runInFlight = false;
|
|
628
|
+
});
|
|
629
|
+
|
|
613
630
|
// keep the cached model fresh for notification filtering
|
|
614
631
|
pi.on("before_agent_start", async (event, ctx) => {
|
|
615
632
|
hookFiredSinceLastRequest = true;
|
|
@@ -797,9 +814,10 @@ export default function (pi: ExtensionAPI) {
|
|
|
797
814
|
display: true,
|
|
798
815
|
details: { fromSessionId: event.fromSessionId, canonId: payload.id },
|
|
799
816
|
},
|
|
800
|
-
//
|
|
801
|
-
// prompt;
|
|
802
|
-
|
|
817
|
+
// An idle session takes the passive queue, because steer would wake it like a
|
|
818
|
+
// prompt; a run already in flight takes steer, which lands at the next tool
|
|
819
|
+
// boundary instead of waiting for a turn that has not started.
|
|
820
|
+
{ deliverAs: runInFlight ? "steer" : "nextTurn" },
|
|
803
821
|
);
|
|
804
822
|
},
|
|
805
823
|
onReady(readyChannel: CanonChannel): void {
|