@aeondave/pi-persona 1.16.2 → 1.16.3
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/CHANGELOG.md +8 -0
- package/README.md +2 -2
- package/docs/REFERENCE.md +5 -3
- package/package.json +2 -2
- package/src/engine/adapter.ts +4 -2
- package/src/engine/inproc.ts +4 -2
- package/src/engine/spec-preflight.ts +13 -0
- package/src/telemetry/contract.ts +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,14 @@ used in its [GitHub releases](https://github.com/AeonDave/pi-persona/releases).
|
|
|
6
6
|
|
|
7
7
|
## [Unreleased]
|
|
8
8
|
|
|
9
|
+
## [1.16.3](https://github.com/AeonDave/pi-persona/releases/tag/v1.16.3) - 2026-10-13
|
|
10
|
+
|
|
11
|
+
### Fixed
|
|
12
|
+
|
|
13
|
+
- Reject Pi `+name`/`-name` tool modifiers in agent and per-run allowlists before either engine
|
|
14
|
+
starts. Those selectors are literal allowlist entries in pi-persona; Pi 1.2 instead applies them
|
|
15
|
+
to its default tools. Use `deny` or `excludeTools` for denials.
|
|
16
|
+
|
|
9
17
|
## [1.16.2](https://github.com/AeonDave/pi-persona/releases/tag/v1.16.2) - 2026-10-08
|
|
10
18
|
|
|
11
19
|
### Fixed
|
package/README.md
CHANGED
|
@@ -39,9 +39,9 @@ your customizations.
|
|
|
39
39
|
| Install option | Command |
|
|
40
40
|
|---|---|
|
|
41
41
|
| This project only | `pi install -l npm:@aeondave/pi-persona` |
|
|
42
|
-
| Pin this release | `pi install npm:@aeondave/pi-persona@1.16.
|
|
42
|
+
| Pin this release | `pi install npm:@aeondave/pi-persona@1.16.3` |
|
|
43
43
|
| Update an unpinned install | `pi update npm:@aeondave/pi-persona` |
|
|
44
|
-
| Git alternative | `pi install git:github.com/AeonDave/pi-persona@v1.16.
|
|
44
|
+
| Git alternative | `pi install git:github.com/AeonDave/pi-persona@v1.16.3` |
|
|
45
45
|
|
|
46
46
|
Restart Pi after updating. For a pinned install, install the new version or tag explicitly.
|
|
47
47
|
If switching from a Git install, remove that source first with
|
package/docs/REFERENCE.md
CHANGED
|
@@ -189,9 +189,11 @@ files are seed sources. A fresh install has no installed personas until `/person
|
|
|
189
189
|
| Preset | `presets/*.preset.json` | reusable council strategy, roster, and parameter bundle |
|
|
190
190
|
|
|
191
191
|
`tools` accepts an allowlist such as `[read, grep]`, an `allow`/`deny` object, or `[]` for no tools.
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
192
|
+
Entries are plain tool names or `*` patterns; Pi's `+name`/`-name` default-tool modifier
|
|
193
|
+
syntax is not an allowlist and is rejected. Use the `deny` field to remove tools. Omit `tools` to
|
|
194
|
+
inherit the session tool set. `model`, `isolation: worktree`,
|
|
195
|
+
`mcp: true`, and `purpose` are optional agent metadata. The body is the agent prompt. Inline roster
|
|
196
|
+
members specialise one agent with a role, model, or skills without requiring another agent file.
|
|
195
197
|
|
|
196
198
|
### Multi-agent quick start
|
|
197
199
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aeondave/pi-persona",
|
|
3
|
-
"version": "1.16.
|
|
3
|
+
"version": "1.16.3",
|
|
4
4
|
"private": false,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"description": "Supervised multi-agent orchestration for Pi — async workers, live steering, cross-session collaboration, and switchable personas.",
|
|
@@ -104,7 +104,7 @@
|
|
|
104
104
|
"typescript": "^7.0.2"
|
|
105
105
|
},
|
|
106
106
|
"pi": {
|
|
107
|
-
"image": "https://raw.githubusercontent.com/AeonDave/pi-persona/v1.16.
|
|
107
|
+
"image": "https://raw.githubusercontent.com/AeonDave/pi-persona/v1.16.3/assets/banner.png",
|
|
108
108
|
"video": "https://cdn.jsdelivr.net/gh/AeonDave/pi-persona@6655d281ce7965a75303dd704bd29db73db04070/assets/demo1.mp4",
|
|
109
109
|
"extensions": [
|
|
110
110
|
"./src/extension.ts"
|
package/src/engine/adapter.ts
CHANGED
|
@@ -18,7 +18,7 @@ import { type ChildEngineOptions, type ChildRunSpec, runChildAgent } from "./chi
|
|
|
18
18
|
import { looksLikeProviderError } from "./errors.ts";
|
|
19
19
|
import { nextChildHandle } from "./handles.ts";
|
|
20
20
|
import { combineSignals } from "./signals.ts";
|
|
21
|
-
import { unknownAgentFailure, unknownContractFailure } from "./spec-preflight.ts";
|
|
21
|
+
import { toolModifierFailure, unknownAgentFailure, unknownContractFailure } from "./spec-preflight.ts";
|
|
22
22
|
import type { ToolEvent } from "./stream.ts";
|
|
23
23
|
|
|
24
24
|
/** The engine-side face of the cross-process broker (spec B3/B4/B7) — a child-engine
|
|
@@ -113,6 +113,9 @@ export function makeEngine(deps: EngineAdapterDeps): StrategyEngine {
|
|
|
113
113
|
): Promise<AgentResult> {
|
|
114
114
|
const cfg = deps.resolveAgent(spec.agent);
|
|
115
115
|
if (!cfg) return unknownAgentFailure(spec.agent, deps.listAgents?.() ?? []);
|
|
116
|
+
const tools = spec.tools ?? cfg.tools;
|
|
117
|
+
const invalidTools = toolModifierFailure(spec.agent, tools);
|
|
118
|
+
if (invalidTools) return invalidTools;
|
|
116
119
|
|
|
117
120
|
// Resolved (and pinned) up front: the SAME def both instructs the member and
|
|
118
121
|
// validates its output — an instruction/validation drift is impossible. A named
|
|
@@ -132,7 +135,6 @@ export function makeEngine(deps: EngineAdapterDeps): StrategyEngine {
|
|
|
132
135
|
// a child without it defaults to "adaptive", which some models reject.
|
|
133
136
|
if (model && deps.childThinking && !model.includes(":")) model = `${model}:${deps.childThinking}`;
|
|
134
137
|
if (model) childSpec.model = model;
|
|
135
|
-
const tools = spec.tools ?? cfg.tools;
|
|
136
138
|
if (tools !== undefined) childSpec.tools = tools;
|
|
137
139
|
if (cfg.excludeTools && cfg.excludeTools.length > 0) childSpec.excludeTools = cfg.excludeTools;
|
|
138
140
|
// The shared behavioral layer (docs/SPINE.md) + the agent's own persona + any
|
package/src/engine/inproc.ts
CHANGED
|
@@ -35,7 +35,7 @@ import type { AgentResult } from "../orchestration/types.ts";
|
|
|
35
35
|
import { looksLikeProviderError } from "./errors.ts";
|
|
36
36
|
import { nextChildHandle } from "./handles.ts";
|
|
37
37
|
import { combineSignals } from "./signals.ts";
|
|
38
|
-
import { unknownAgentFailure, unknownContractFailure } from "./spec-preflight.ts";
|
|
38
|
+
import { toolModifierFailure, unknownAgentFailure, unknownContractFailure } from "./spec-preflight.ts";
|
|
39
39
|
import { applyEvent, createStreamState, emptyUsage, type ProgressSnapshot, snapshot } from "./stream.ts";
|
|
40
40
|
|
|
41
41
|
/** The minimal slice of Pi's AgentSession the engine drives — also the test seam. */
|
|
@@ -315,6 +315,9 @@ export function makeInProcessEngine(deps: InProcessDeps): StrategyEngine {
|
|
|
315
315
|
async run(spec: AgentRunSpec, onProgress?, callSignal?, onSteerable?): Promise<AgentResult> {
|
|
316
316
|
const cfg = deps.resolveAgent(spec.agent);
|
|
317
317
|
if (!cfg) return unknownAgentFailure(spec.agent, deps.listAgents?.() ?? []);
|
|
318
|
+
const tools = spec.tools ?? cfg.tools;
|
|
319
|
+
const invalidTools = toolModifierFailure(spec.agent, tools);
|
|
320
|
+
if (invalidTools) return invalidTools;
|
|
318
321
|
// A requested contract is a runtime guard, not merely prompt decoration. Resolve it
|
|
319
322
|
// before model/session construction so a missing name can never run unconstrained.
|
|
320
323
|
const requestedContract = spec.outputContract?.trim();
|
|
@@ -346,7 +349,6 @@ export function makeInProcessEngine(deps: InProcessDeps): StrategyEngine {
|
|
|
346
349
|
const rm = model as { provider?: string; id?: string };
|
|
347
350
|
const resolvedRef = rm.provider && rm.id ? `${rm.provider}/${rm.id}` : ref;
|
|
348
351
|
const thinkingLevel = isThinkingLevel(deps.childThinking) ? deps.childThinking : undefined;
|
|
349
|
-
const tools = spec.tools ?? cfg.tools;
|
|
350
352
|
const excludeTools = cfg.excludeTools;
|
|
351
353
|
|
|
352
354
|
// Diagnostic tag: which agent + which model ref + whether it was dynamically
|
|
@@ -31,3 +31,16 @@ export function unknownAgentFailure(agent: string, installed: string[]): AgentRe
|
|
|
31
31
|
export function unknownContractFailure(agent: string, requested: string, installed: string[]): AgentResult {
|
|
32
32
|
return failure(agent, `[${agent}] output contract "${requested}" not found${installedHint("contracts", installed)}`, "contract");
|
|
33
33
|
}
|
|
34
|
+
|
|
35
|
+
/** Pi's SDK treats leading `+`/`-` entries in `tools` as default-tool modifiers, not as
|
|
36
|
+
* literal allowlist entries. AgentRunSpec.tools and agent frontmatter use this field as an
|
|
37
|
+
* allowlist, so reject that syntax before either engine reaches Pi. Use excludeTools for denies. */
|
|
38
|
+
export function toolModifierFailure(agent: string, tools: readonly string[] | undefined): AgentResult | undefined {
|
|
39
|
+
const modifier = tools?.find((selector) => /^[+-]/.test(selector.trim()));
|
|
40
|
+
if (modifier === undefined) return undefined;
|
|
41
|
+
return failure(
|
|
42
|
+
agent,
|
|
43
|
+
`[${agent}] unsupported tool modifier "${modifier.trim()}" in tools allowlist; use plain tool names/patterns or excludeTools for denials`,
|
|
44
|
+
"contract",
|
|
45
|
+
);
|
|
46
|
+
}
|
|
@@ -4,7 +4,7 @@ export const TELEMETRY_EVENT_NAME = "pi:telemetry" as const;
|
|
|
4
4
|
export const LEGACY_TELEMETRY_EVENT_NAME = "pi-persona:telemetry" as const;
|
|
5
5
|
export const LEGACY_TELEMETRY_VERSION = 1 as const;
|
|
6
6
|
export const TELEMETRY_PRODUCER_ID = "pi-persona" as const;
|
|
7
|
-
export const TELEMETRY_PRODUCER_VERSION = "1.16.
|
|
7
|
+
export const TELEMETRY_PRODUCER_VERSION = "1.16.3" as const;
|
|
8
8
|
|
|
9
9
|
export type InstanceStatus = "active" | "idle" | "stopped" | "stale" | (string & {});
|
|
10
10
|
export type AgentKind = "subagent" | "delegate" | "council" | "flow" | "phase" | (string & {});
|