@cr1ms0n/pi-subagent 0.8.6 → 0.8.7

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 CHANGED
@@ -1,5 +1,13 @@
1
1
  # Changelog
2
2
 
3
+ ## Unreleased
4
+
5
+ ## 0.8.7 — 2026-09-14
6
+
7
+ ### Provider-safe tool schemas
8
+
9
+ - Strip internal TypeBox `~...` metadata from the `subagent` and `subagent_wait` schemas before Pi provider adapters receive them, while retaining the original schemas for local runtime validation.
10
+
3
11
  ## 0.8.6 — 2026-09-14
4
12
 
5
13
  ### Pi context management in child profiles
@@ -29,7 +29,7 @@
29
29
  - `persistence.ts`: versioned active-branch event folding and bounded child transcript metadata.
30
30
  - `maintenance.ts`: filesystem GC (session files) and abort-race helpers; kept out of persistence.
31
31
  - `usage.ts`: provider-reported root/subagent/combined accounting.
32
- - `policy.ts` / `schema.ts`: discriminated request validation and safe capability profiles. Pi context-management control-plane tools remain available to child allowlists without granting project-file write access.
32
+ - `policy.ts` / `schema.ts`: discriminated request validation and safe capability profiles. `schema.ts` retains the canonical TypeBox validators and derives provider-safe tool-schema projections; `extension.ts` registers those projections while validating calls with the originals. Pi context-management control-plane tools remain available to child allowlists without granting project-file write access.
33
33
  - `config.ts`: defaults ← `~/.pi/subagent.json` ← `PI_SUBAGENT_*` env overrides.
34
34
  - `structured.ts`: structured-output contract (dependency-free JSON-Schema subset
35
35
  validation, fenced json:result extraction, contract/repair prompts) and
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cr1ms0n/pi-subagent",
3
- "version": "0.8.6",
3
+ "version": "0.8.7",
4
4
  "description": "Community fork of Luke Parke's pi-subagent with explicit model policy and model visibility for Pi",
5
5
  "type": "module",
6
6
  "license": "MIT",
package/src/extension.ts CHANGED
@@ -28,7 +28,14 @@ import { CONTEXT_MANAGEMENT_TOOLS, parseDepth, parseSpawnPolicy, SPAWNS_ENV_VAR,
28
28
  import type { ChildRunner } from "./runner.js";
29
29
  import { ProcessLockManager } from "./process-lock.js";
30
30
  import { SessionScopedRunRegistry, snapshotFromLiveRun } from "./registry.js";
31
- import { SubagentParamsSchema, SubagentWaitParamsSchema, type SubagentParams, type SubagentWaitParams } from "./schema.js";
31
+ import {
32
+ ProviderSubagentParamsSchema,
33
+ ProviderSubagentWaitParamsSchema,
34
+ SubagentParamsSchema,
35
+ SubagentWaitParamsSchema,
36
+ type SubagentParams,
37
+ type SubagentWaitParams,
38
+ } from "./schema.js";
32
39
  import { BTW_ENTRY_TYPE, btwLabel, type BtwEntry } from "./btw.js";
33
40
  import { Semaphore } from "./semaphore.js";
34
41
  import type { RunSnapshot, TaskResult, TaskSpec, UsageStats } from "./types.js";
@@ -944,7 +951,7 @@ export default function registerSubagent(pi: ExtensionAPI): void {
944
951
  // usable immediately via agent:'name' (execute-time refresh); only the
945
952
  // system-prompt advertisement waits for the next session.
946
953
  promptGuidelines: guidelines(discoverAgents(process.cwd())),
947
- parameters: SubagentParamsSchema,
954
+ parameters: ProviderSubagentParamsSchema,
948
955
  async execute(_id, params: SubagentParams, signal, onUpdate, ctx) {
949
956
  // `subagent_wait` delegates here with a synthesized action:"wait" params
950
957
  // object, carrying its timeout through this non-schema field so the two
@@ -1507,7 +1514,7 @@ export default function registerSubagent(pi: ExtensionAPI): void {
1507
1514
  label: "Subagent wait",
1508
1515
  description:
1509
1516
  "Block until a background subagent run (async:true) settles, then deliver its output. Equivalent to subagent { action: 'wait', id }. Aborting or timing out leaves the run alive and collectable; use subagent { action: 'cancel' } to stop it.",
1510
- parameters: SubagentWaitParamsSchema,
1517
+ parameters: ProviderSubagentWaitParamsSchema,
1511
1518
  async execute(id, params: SubagentWaitParams, signal, onUpdate, ctx) {
1512
1519
  return subagentTool.execute(
1513
1520
  id,
package/src/schema.ts CHANGED
@@ -1,5 +1,27 @@
1
1
  import { Type, type Static } from "typebox";
2
2
 
3
+ /**
4
+ * Remove TypeBox's internal compositor metadata before a schema crosses into
5
+ * Pi's provider-facing tool catalog. The original schema is kept intact for
6
+ * local Value.Check/Value.Errors validation.
7
+ */
8
+ export function sanitizeProviderSchema<T>(value: T): T {
9
+ if (Array.isArray(value)) {
10
+ return value.map((item) => sanitizeProviderSchema(item)) as T;
11
+ }
12
+
13
+ if (value && typeof value === "object") {
14
+ const record = value as Record<string, unknown>;
15
+ return Object.fromEntries(
16
+ Object.entries(record)
17
+ .filter(([key]) => !key.startsWith("~"))
18
+ .map(([key, entry]) => [key, sanitizeProviderSchema(entry)] as const),
19
+ ) as T;
20
+ }
21
+
22
+ return value;
23
+ }
24
+
3
25
  const ThinkingLevel = Type.String({
4
26
  minLength: 1,
5
27
  maxLength: 64,
@@ -29,7 +51,7 @@ export const TaskFields = {
29
51
  system_prompt: Type.Optional(Type.String({ description: "Extra system prompt appended to the child's prompt (does not replace it)." })),
30
52
  model: Type.Optional(Type.String({ description: "**REQUIRED for every spawn call (task/tasks).** Exact model id from modelPolicy, in provider/model-id form. Calls without an explicit model are rejected; agent-file model, taskDefaults, and parent-session inheritance are ignored. Management actions (status/wait/cancel/steer/diff/apply/discard) do not need it." })),
31
53
  thinking: Type.Optional({ ...ThinkingLevel, description: "Opaque Pi thinking level for the child. Values such as max are passed through unchanged; Pi/model support decides validity. Defaults to agent thinking, profile taskDefaults.thinking, modelPolicy route thinking, then the parent's level." }),
32
- tools: Type.Optional(Type.Array(Type.String({ minLength: 1 }), { description: "Optional tool allowlist. explore/review profiles reject project-writing tools; Pi context-management tools remain available for context continuity." })),
54
+ tools: Type.Optional(Type.Array(Type.String(), { description: "Optional tool allowlist. explore/review profiles reject project-writing tools; Pi context-management tools remain available for context continuity." })),
33
55
  profile: Type.Optional({ ...Profile, description: "Capability profile: explore/review cannot write project files but retain Pi context-management tools; general inherits the parent's active tools and may write." }),
34
56
  cwd: Type.Optional(Type.String({ description: "Working directory for the child process." })),
35
57
  timeout_ms: Type.Optional(Type.Number({ minimum: 1, maximum: 24 * 60 * 60_000, description: "Total budget in milliseconds including queue time. Timed-out runs report which phase timed out." })),
@@ -152,6 +174,10 @@ export const SubagentWaitParamsSchema = Type.Object(
152
174
  },
153
175
  );
154
176
 
177
+ /** Provider-facing projections without TypeBox's internal `~...` metadata. */
178
+ export const ProviderSubagentParamsSchema = sanitizeProviderSchema(SubagentParamsSchema);
179
+ export const ProviderSubagentWaitParamsSchema = sanitizeProviderSchema(SubagentWaitParamsSchema);
180
+
155
181
  export type SubagentWaitParams = Static<typeof SubagentWaitParamsSchema>;
156
182
 
157
183
  /** Runtime guard used by tests/docs to assert provider compatibility. */