@tinoy/pi-canon 0.2.0 → 0.4.0
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 +2 -1
- package/{canon.ts → index.ts} +18 -17
- package/package.json +4 -4
package/README.md
CHANGED
|
@@ -16,12 +16,13 @@ pi install npm:@tinoy/pi-canon
|
|
|
16
16
|
- **Tools** — `canon_add`, `canon_remove`, `canon_edit`, `canon_category`.
|
|
17
17
|
- **Commands** — `/canon` (list, add, remove, edit, category management) and `/canon-dump`.
|
|
18
18
|
- **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.
|
|
19
|
+
- **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.
|
|
19
20
|
- **Peer notices** — entry changes are broadcast over the pi-intercom bus (namespace `canon`); receivers match the entry scope against their own model and audience.
|
|
20
21
|
- **Tail sections** — another extension contributes prompt text through the `canon:section` event; its ids are published on `canon:sections`.
|
|
21
22
|
|
|
22
23
|
## Exports
|
|
23
24
|
|
|
24
|
-
`
|
|
25
|
+
`index.ts` is the package entry, and it is also the module API:
|
|
25
26
|
|
|
26
27
|
| Export | What it is |
|
|
27
28
|
| --- | --- |
|
package/{canon.ts → index.ts}
RENAMED
|
@@ -31,11 +31,13 @@
|
|
|
31
31
|
*
|
|
32
32
|
* Store: ~/.pi/agent/canon/canon.json — { entries: [{id, text, model, audience, reason?, category?}], categories: [{id, title, description?}] }
|
|
33
33
|
* Categories are un-ordered; entries reference them by id. They render as sub-headings
|
|
34
|
-
* inside scope groups (store insertion order), with uncategorized entries last
|
|
34
|
+
* inside scope groups (store insertion order), with uncategorized entries last, and
|
|
35
|
+
* each heading carries the store's own id after the word `category`
|
|
36
|
+
* (`#### Behavioural Preferences [category 1cg5lr]`) — the word keeps the category id
|
|
37
|
+
* from reading as an entry handle, which the block renders as `[1i15c2]`.
|
|
35
38
|
* canon_add REQUIRES a category and canon_edit can only CHANGE one: every refusal
|
|
36
|
-
* lists the valid ids with their titles, so a retry costs no lookup call. The
|
|
37
|
-
*
|
|
38
|
-
* reaches the model. The store validator counts entries that are uncategorized or
|
|
39
|
+
* lists the valid ids with their titles, so a retry costs no lookup call. The store
|
|
40
|
+
* validator counts entries that are uncategorized or
|
|
39
41
|
* carry a category id the store no longer holds (both render as Uncategorized) and
|
|
40
42
|
* reports the count to the hook log once per distinct state.
|
|
41
43
|
* Both the injected block and /canon-dump group entries under scope headers (model ×
|
|
@@ -339,7 +341,8 @@ function scopeGroups(entries: CanonEntry[]): ScopeGroup[] {
|
|
|
339
341
|
);
|
|
340
342
|
}
|
|
341
343
|
|
|
342
|
-
/** Render the injected block: header, scope groups, category sub-headings inside
|
|
344
|
+
/** Render the injected block: header, scope groups, category sub-headings inside, each
|
|
345
|
+
* naming its store category id. */
|
|
343
346
|
function render(
|
|
344
347
|
store: Store,
|
|
345
348
|
model: string,
|
|
@@ -367,7 +370,7 @@ function render(
|
|
|
367
370
|
// only show category sub-headings when a scope group actually splits
|
|
368
371
|
const showCatHeadings = orderedCats.length + (uncat.length ? 1 : 0) >= 2;
|
|
369
372
|
for (const c of orderedCats) {
|
|
370
|
-
if (showCatHeadings) block += `\n\n#### ${c.title}`;
|
|
373
|
+
if (showCatHeadings) block += `\n\n#### ${c.title} [category ${c.id}]`;
|
|
371
374
|
block += `\n${buckets
|
|
372
375
|
.get(c.id)!
|
|
373
376
|
.map((e) => `[${e.id}] ${e.text}`)
|
|
@@ -417,11 +420,11 @@ function renderDump(
|
|
|
417
420
|
/**
|
|
418
421
|
* Resolve a category reference to its id.
|
|
419
422
|
*
|
|
420
|
-
* The
|
|
421
|
-
*
|
|
422
|
-
*
|
|
423
|
-
*
|
|
424
|
-
*
|
|
423
|
+
* The block prints each heading as its title followed by the store id
|
|
424
|
+
* (`#### <title> [category <id>]`), and a model that copies the heading copies the
|
|
425
|
+
* title most of the time, so both forms are accepted: an exact id wins, a title
|
|
426
|
+
* matches case-insensitively, and anything else fails with a short reason that the
|
|
427
|
+
* caller turns into a refusal.
|
|
425
428
|
*/
|
|
426
429
|
function lookupCategory(
|
|
427
430
|
store: Store,
|
|
@@ -447,10 +450,8 @@ function lookupCategory(
|
|
|
447
450
|
|
|
448
451
|
/**
|
|
449
452
|
* The refusal for every rejected category value: what failed, then every valid id
|
|
450
|
-
* with its title
|
|
451
|
-
*
|
|
452
|
-
* context, and the listing is the only place a category id is ever shown (the
|
|
453
|
-
* injected block renders titles).
|
|
453
|
+
* with its title, then the one instruction that answers it. Terse by construction —
|
|
454
|
+
* it lands in a model's context.
|
|
454
455
|
*/
|
|
455
456
|
function categoryRefusal(
|
|
456
457
|
store: Store,
|
|
@@ -747,7 +748,7 @@ export default function (pi: ExtensionAPI) {
|
|
|
747
748
|
}
|
|
748
749
|
}
|
|
749
750
|
|
|
750
|
-
// ---------- intercom channel (mirrors intercom-broadcast
|
|
751
|
+
// ---------- intercom channel (mirrors the intercom-broadcast package) ----------
|
|
751
752
|
|
|
752
753
|
const registration: CanonRegistration = {
|
|
753
754
|
namespace: NAMESPACE,
|
|
@@ -1243,7 +1244,7 @@ export default function (pi: ExtensionAPI) {
|
|
|
1243
1244
|
name: "canon_category",
|
|
1244
1245
|
label: "Manage canon categories",
|
|
1245
1246
|
description:
|
|
1246
|
-
"Manage canon categories: op add (title, description?) creates one; op edit (id, title?, description?) updates it; op remove (id) deletes it and detaches its entries to Uncategorized; op list shows all. Categories are un-ordered and render as sub-headings inside scope groups in store insertion order.",
|
|
1247
|
+
"Manage canon categories: op add (title, description?) creates one; op edit (id, title?, description?) updates it; op remove (id) deletes it and detaches its entries to Uncategorized; op list shows all. Categories are un-ordered and render as sub-headings inside scope groups in store insertion order, each heading naming the category id (`#### Tools [category u3q9pr]`).",
|
|
1247
1248
|
promptSnippet: "Manage canon categories (add/edit/remove/list)",
|
|
1248
1249
|
parameters: Type.Object({
|
|
1249
1250
|
op: Type.String({ description: "add | edit | remove | list" }),
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tinoy/pi-canon",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"description": "Durable system-prompt rules for pi: an on-disk canon store, its tools, and the /canon commands.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -13,18 +13,18 @@
|
|
|
13
13
|
"url": "https://github.com/tinoy1336/pi-extensions/issues"
|
|
14
14
|
},
|
|
15
15
|
"type": "module",
|
|
16
|
-
"main": "
|
|
16
|
+
"main": "index.ts",
|
|
17
17
|
"keywords": [
|
|
18
18
|
"pi-package"
|
|
19
19
|
],
|
|
20
20
|
"files": [
|
|
21
|
-
"
|
|
21
|
+
"index.ts",
|
|
22
22
|
"README.md",
|
|
23
23
|
"LICENSE"
|
|
24
24
|
],
|
|
25
25
|
"pi": {
|
|
26
26
|
"extensions": [
|
|
27
|
-
"./
|
|
27
|
+
"./index.ts"
|
|
28
28
|
]
|
|
29
29
|
},
|
|
30
30
|
"engines": {
|