pi-canary 1.1.0 → 1.1.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/extensions/canary.ts +12 -3
- package/package.json +1 -1
- package/skills/canary-help/SKILL.md +1 -1
package/README.md
CHANGED
|
@@ -51,7 +51,7 @@ Persistent configuration lives in `extensions/canary.json`. You can ask the agen
|
|
|
51
51
|
|
|
52
52
|
| Key | Default | Description |
|
|
53
53
|
|-----|---------|-------------|
|
|
54
|
-
| `COUNT` | `3` | Number of canary tokens injected per turn |
|
|
54
|
+
| `COUNT` | `3` | Number of canary tokens injected per turn (`0` disables the canary check entirely) |
|
|
55
55
|
| `POSITION` | `end` | Where tokens are injected: `start`, `equidistant`, or `end` |
|
|
56
56
|
| `VARIANT` | `fixed` | `fixed` = same tokens every turn (preserves KV cache); `variant` = new tokens each turn |
|
|
57
57
|
| `FAIL_COMPACT` | `0` | Compact context after N consecutive failures (`0` = disabled) |
|
package/extensions/canary.ts
CHANGED
|
@@ -116,10 +116,19 @@ export default function (pi: ExtensionAPI) {
|
|
|
116
116
|
verifyContextSent = true;
|
|
117
117
|
const messages = [...event.messages];
|
|
118
118
|
|
|
119
|
-
//
|
|
120
|
-
//
|
|
119
|
+
// Replace the original user question with a neutral prompt so the agent focuses
|
|
120
|
+
// only on the canary check. We keep the user role (replacing content, not the
|
|
121
|
+
// message) because some providers (e.g. llama-server) use Jinja2 chat templates
|
|
122
|
+
// that require a user message at the end of the conversation — removing it causes
|
|
123
|
+
// template parsing to fail with "No user query found in messages." The original
|
|
124
|
+
// question remains in session history and reappears in Phase 2.
|
|
121
125
|
if (messages.length > 0 && (messages[messages.length - 1] as any).role === "user") {
|
|
122
|
-
messages.
|
|
126
|
+
const lastMsg = messages[messages.length - 1] as any;
|
|
127
|
+
if (typeof lastMsg.content === "string") {
|
|
128
|
+
lastMsg.content = "Please return the canary tokens.";
|
|
129
|
+
} else if (Array.isArray(lastMsg.content) && lastMsg.content.length > 0) {
|
|
130
|
+
lastMsg.content = [{ type: "text", text: "Please return the canary tokens." }];
|
|
131
|
+
}
|
|
123
132
|
}
|
|
124
133
|
|
|
125
134
|
const histLen = messages.length;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pi-canary",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.2",
|
|
4
4
|
"description": "Pi extension: silently verifies agent context awareness every turn using hidden canary tokens. KV-cache friendly.",
|
|
5
5
|
"keywords": ["pi-package", "pi", "pi-coding-agent", "extension", "context-awareness", "canary", "safety", "verification", "local-llm"],
|
|
6
6
|
"license": "MIT",
|
|
@@ -21,7 +21,7 @@ injected into the conversation history. Passed = proceed; failed = warning.
|
|
|
21
21
|
|
|
22
22
|
| Key | Default | Valid values | What it controls |
|
|
23
23
|
|-----|---------|-------------|-----------------|
|
|
24
|
-
| `COUNT` | `3` | integer
|
|
24
|
+
| `COUNT` | `3` | integer ≥ 0 | Number of canary tokens per turn (`0` disables the canary check entirely) |
|
|
25
25
|
| `POSITION` | `end` | `start` \| `equidistant` \| `end` | Where tokens are injected in context |
|
|
26
26
|
| `VARIANT` | `fixed` | `fixed` \| `variant` | Fixed reuses same tokens (KV-cache friendly); variant regenerates each turn |
|
|
27
27
|
| `FAIL_COMPACT` | `0` | integer ≥ 0 | Trigger compaction after N consecutive failures (0 = disabled) |
|