pi-rolecast 0.2.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/LICENSE +674 -0
- package/README.md +260 -0
- package/SKILL.md +89 -0
- package/dist/extension.d.ts +25 -0
- package/dist/extension.js +287 -0
- package/examples/rust/README.md +22 -0
- package/examples/rust/profile.yaml +51 -0
- package/package.json +71 -0
- package/references/dispatch-model-semantics.md +110 -0
- package/references/gate-runner-usage.md +19 -0
- package/references/migration-from-rust-agent-workflow.md +107 -0
- package/references/profile-schema.md +66 -0
- package/references/registry-resolution.md +14 -0
- package/references/scaffolder-usage.md +27 -0
- package/references/sync-settings-usage.md +67 -0
- package/registry/aliases.yaml +38 -0
- package/registry/built_in.yaml +42 -0
- package/requirements.txt +2 -0
- package/role-packs/coding/coding-architect.md +33 -0
- package/role-packs/coding/coding-auditor.md +31 -0
- package/role-packs/coding/coding-canary.md +31 -0
- package/role-packs/coding/coding-docs.md +32 -0
- package/role-packs/coding/coding-implementer.md +33 -0
- package/role-packs/coding/coding-mapper.md +31 -0
- package/role-packs/coding/coding-orchestrator.md +28 -0
- package/role-packs/coding/coding-planner.md +31 -0
- package/role-packs/coding/coding-profiler.md +31 -0
- package/role-packs/coding/coding-reviewer.md +32 -0
- package/role-packs/coding/coding-tester.md +32 -0
- package/scripts/gate_runner.py +155 -0
- package/scripts/install.sh +120 -0
- package/scripts/profile_loader.py +633 -0
- package/scripts/scaffolder.py +289 -0
- package/scripts/sync_settings.py +362 -0
- package/templates/blank.yaml +13 -0
- package/templates/go.yaml +44 -0
- package/templates/python.yaml +46 -0
- package/templates/rust.yaml +49 -0
- package/templates/typescript.yaml +46 -0
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# Rust example profile (pi-rolecast v0.2.0)
|
|
2
|
+
|
|
3
|
+
This directory contains the reference profile for the `coding` group of
|
|
4
|
+
pi-rolecast v0.2.0. It reproduces the routing decisions of the original
|
|
5
|
+
`rust-agent-workflow` skill (pre-2026-10-03), adapted to the new
|
|
6
|
+
grouped-role schema.
|
|
7
|
+
|
|
8
|
+
## Purpose
|
|
9
|
+
|
|
10
|
+
Users should:
|
|
11
|
+
|
|
12
|
+
1. Run `scaffolder init --template rust` in their project.
|
|
13
|
+
2. Diff the generated profile against `examples/rust/profile.yaml`.
|
|
14
|
+
3. If differences exist, decide deliberately which is canonical.
|
|
15
|
+
|
|
16
|
+
This file is the **ground truth** for "what the coding group does for Rust projects". If your scaffolder-generated profile diverges, file an issue.
|
|
17
|
+
|
|
18
|
+
## What this is NOT
|
|
19
|
+
|
|
20
|
+
This is not a one-click migration from `rust-agent-workflow`. See
|
|
21
|
+
`references/migration-from-rust-agent-workflow.md` for the v0.1.x → v0.2.0
|
|
22
|
+
upgrade path.
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# Reference profile reproducing today's rust-agent-workflow routing,
|
|
2
|
+
# updated for pi-rolecast v0.2.0 (grouped roles, hyphen-prefixed names).
|
|
3
|
+
# Generated manually from the old SKILL.md; this is the ground truth
|
|
4
|
+
# users cross-check their scaffolder-generated profile against.
|
|
5
|
+
|
|
6
|
+
framework_version: 0.2.0
|
|
7
|
+
name: rust-rolecast-example
|
|
8
|
+
description: |
|
|
9
|
+
Reference Rust profile preserving the routing decisions of the original
|
|
10
|
+
rust-agent-workflow skill, updated to the v0.2.0 grouped-role schema.
|
|
11
|
+
Use scaffolder init --template rust in your project to generate a
|
|
12
|
+
similar profile; this file is the canonical reference for cross-checking.
|
|
13
|
+
|
|
14
|
+
workflow:
|
|
15
|
+
role_groups: [coding]
|
|
16
|
+
|
|
17
|
+
gates:
|
|
18
|
+
compile:
|
|
19
|
+
commands: [cargo check --message-format short --all-targets]
|
|
20
|
+
timeout: 300
|
|
21
|
+
lint:
|
|
22
|
+
commands: [cargo clippy -- -D warnings]
|
|
23
|
+
timeout: 300
|
|
24
|
+
test:
|
|
25
|
+
commands: [cargo test]
|
|
26
|
+
timeout: 900
|
|
27
|
+
|
|
28
|
+
bindings:
|
|
29
|
+
coding-architect: {alias: opus-thinking-medium, channels: [official]}
|
|
30
|
+
coding-planner: {alias: deepseek-verifiable, channels: [official]}
|
|
31
|
+
coding-implementer: {alias: deepseek-verifiable, channels: [official]}
|
|
32
|
+
coding-tester: {alias: deepseek-verifiable, channels: [official]}
|
|
33
|
+
coding-reviewer: {alias: gpt-judgment-high, channels: [official, relay-default]}
|
|
34
|
+
coding-mapper: {alias: deepseek-verifiable, channels: [official]}
|
|
35
|
+
coding-profiler: {alias: deepseek-verifiable, channels: [official]}
|
|
36
|
+
coding-auditor: {alias: opus-thinking-high, channels: [official]}
|
|
37
|
+
coding-canary: {alias: minimax-fast, channels: [official]}
|
|
38
|
+
coding-docs: {alias: minimax-medium, channels: [official]}
|
|
39
|
+
coding-orchestrator: {alias: gpt-judgment-medium, channels: [official, relay-default]}
|
|
40
|
+
|
|
41
|
+
non_negotiables:
|
|
42
|
+
forbidden_patterns:
|
|
43
|
+
- pattern: '#\[allow\('
|
|
44
|
+
message: "never silence a diagnostic with #[allow(...)]"
|
|
45
|
+
- pattern: '\.unwrap\(\)'
|
|
46
|
+
message: "no bare .unwrap() — handle the Result"
|
|
47
|
+
|
|
48
|
+
escalation:
|
|
49
|
+
max_attempts: 2
|
|
50
|
+
on_permanent_failure: stop
|
|
51
|
+
preserve_logs: true
|
package/package.json
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "pi-rolecast",
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"description": "Multi-agent role framework for Pi. Groups of specialist agents (coding, video, etc.) bound to per-role models, dispatched via pi-subagents. Profile-driven, gate-verified, language-agnostic.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"author": {
|
|
8
|
+
"name": "rootazero",
|
|
9
|
+
"email": "zouguojunx@gmail.com"
|
|
10
|
+
},
|
|
11
|
+
"homepage": "https://github.com/rootazero/pi-rolecast#readme",
|
|
12
|
+
"repository": {
|
|
13
|
+
"type": "git",
|
|
14
|
+
"url": "git+https://github.com/rootazero/pi-rolecast.git"
|
|
15
|
+
},
|
|
16
|
+
"bugs": {
|
|
17
|
+
"url": "https://github.com/rootazero/pi-rolecast/issues"
|
|
18
|
+
},
|
|
19
|
+
"publishConfig": {
|
|
20
|
+
"access": "public"
|
|
21
|
+
},
|
|
22
|
+
"main": "./dist/extension.js",
|
|
23
|
+
"types": "./dist/extension.d.ts",
|
|
24
|
+
"files": [
|
|
25
|
+
"dist/",
|
|
26
|
+
"scripts/*.py",
|
|
27
|
+
"scripts/*.sh",
|
|
28
|
+
"!scripts/__pycache__/",
|
|
29
|
+
"!scripts/**/__pycache__/",
|
|
30
|
+
"!scripts/*.pyc",
|
|
31
|
+
"role-packs/",
|
|
32
|
+
"registry/",
|
|
33
|
+
"templates/",
|
|
34
|
+
"examples/",
|
|
35
|
+
"references/",
|
|
36
|
+
"SKILL.md",
|
|
37
|
+
"README.md",
|
|
38
|
+
"requirements.txt"
|
|
39
|
+
],
|
|
40
|
+
"scripts": {
|
|
41
|
+
"build": "tsc",
|
|
42
|
+
"typecheck": "tsc --noEmit",
|
|
43
|
+
"clean": "rm -rf dist",
|
|
44
|
+
"test": "tsx --test tests/unit/test_extension.ts",
|
|
45
|
+
"prepublishOnly": "npm run typecheck && npm run build && npm test"
|
|
46
|
+
},
|
|
47
|
+
"keywords": [
|
|
48
|
+
"pi-package",
|
|
49
|
+
"pi",
|
|
50
|
+
"pi-extension",
|
|
51
|
+
"agents",
|
|
52
|
+
"roles",
|
|
53
|
+
"rolecast",
|
|
54
|
+
"multi-agent",
|
|
55
|
+
"scaffolder",
|
|
56
|
+
"gate-runner"
|
|
57
|
+
],
|
|
58
|
+
"peerDependencies": {
|
|
59
|
+
"@earendil-works/pi-ai": ">=0.84.0",
|
|
60
|
+
"@earendil-works/pi-coding-agent": ">=0.84.0",
|
|
61
|
+
"@earendil-works/pi-tui": ">=0.84.0"
|
|
62
|
+
},
|
|
63
|
+
"pi": {
|
|
64
|
+
"extensions": [
|
|
65
|
+
"./dist/extension.js"
|
|
66
|
+
]
|
|
67
|
+
},
|
|
68
|
+
"devDependencies": {
|
|
69
|
+
"tsx": "^4.23.15"
|
|
70
|
+
}
|
|
71
|
+
}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Dispatch model semantics
|
|
3
|
+
description: How role model bindings flow through pi-subagents dispatch paths
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Dispatch model semantics
|
|
7
|
+
|
|
8
|
+
`sync_settings.py` writes project-local agent files at `<cwd>/.pi/agents/<role>.md`
|
|
9
|
+
with a `model: provider/modelId` frontmatter field for every profile binding.
|
|
10
|
+
This doc explains how that field is consumed on each dispatch path.
|
|
11
|
+
|
|
12
|
+
## The three dispatch paths in pi-subagents
|
|
13
|
+
|
|
14
|
+
### Path 1: Plain text prompt (no `@` mention)
|
|
15
|
+
|
|
16
|
+
- User types `design the API` or `/architect design the API` directly
|
|
17
|
+
- pi checks for a registered slash command — `/architect` is **not** registered
|
|
18
|
+
(only `/agents` is, by pi-subagents itself)
|
|
19
|
+
- Text falls through to the `input` event and reaches the **main LLM**
|
|
20
|
+
- The main LLM may decide to call the `agent` tool with
|
|
21
|
+
`subagent_type: "architect"`, but that is its choice — not guaranteed
|
|
22
|
+
- The main LLM uses the session's default model
|
|
23
|
+
|
|
24
|
+
> **Pitfall.** Typing `/architect design the API` does *not* dispatch a
|
|
25
|
+
> subagent. It is just text the main LLM sees. To get a guaranteed
|
|
26
|
+
> subagent dispatch you must use either Path 2 (`@handle` syntax) or Path 3
|
|
27
|
+
> (the `agent` tool).
|
|
28
|
+
|
|
29
|
+
### Path 2: `@handle` mention syntax (Claude Code style)
|
|
30
|
+
|
|
31
|
+
- User types `@architect design the API`
|
|
32
|
+
- pi-subagents' `input` handler (`dist/index.js` ≈ line 800) intercepts the
|
|
33
|
+
text. The mention regex is `/^@([\w-]+)\s+([\s\S]+)$/`
|
|
34
|
+
- pi-subagents dispatches **synchronously** to a subagent with the agent
|
|
35
|
+
file's `model:` and `thinking:` fields
|
|
36
|
+
- The subagent session is **fresh**; the parent's model does not change
|
|
37
|
+
|
|
38
|
+
> **Quirk.** This path requires `@` (not `/`) and at least one space before
|
|
39
|
+
> the message. `@architect` with no message is left alone.
|
|
40
|
+
|
|
41
|
+
### Path 3: `agent` tool / `SubagentWorkflow`
|
|
42
|
+
|
|
43
|
+
- `Agent({ subagent_type: 'architect' })` or
|
|
44
|
+
`SubagentWorkflow({ agentType: 'architect' })` — model-driven dispatch
|
|
45
|
+
- The new subagent session uses the agent file's `model:` and `thinking:`
|
|
46
|
+
- `resolveDefaultModel` (`@tintinweb/pi-subagents/dist/agent-runner.js`
|
|
47
|
+
≈ line 316) parses `provider/modelId` and resolves via the model registry
|
|
48
|
+
|
|
49
|
+
```js
|
|
50
|
+
// Agent tool example (subagent_type matches the role name)
|
|
51
|
+
await parallel([
|
|
52
|
+
() => agent("design the API", { label: 'architect', agentType: 'architect' }),
|
|
53
|
+
() => agent("implement it", { label: 'impl', agentType: 'implementer' }),
|
|
54
|
+
])
|
|
55
|
+
|
|
56
|
+
// SubagentWorkflow
|
|
57
|
+
await agent('coordinate the build', { agentType: 'orchestrator' })
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## Why `provider/modelId` format
|
|
61
|
+
|
|
62
|
+
`resolveDefaultModel` does:
|
|
63
|
+
|
|
64
|
+
```js
|
|
65
|
+
if (configModel) {
|
|
66
|
+
const slashIdx = configModel.indexOf("/");
|
|
67
|
+
if (slashIdx !== -1) {
|
|
68
|
+
const provider = configModel.slice(0, slashIdx);
|
|
69
|
+
const modelId = configModel.slice(slashIdx + 1);
|
|
70
|
+
// resolve in registry.find(provider, modelId)
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
return parentModel; // silent fallback
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
A plain `model: MiniMax-M3` (no slash) is rejected. The runner silently
|
|
77
|
+
falls back to the parent session's model — which is usually the default
|
|
78
|
+
model set at startup.
|
|
79
|
+
|
|
80
|
+
`sync_settings.py` therefore rewrites every binding to
|
|
81
|
+
`provider/modelId`. The mapping lives in the script as `VENDOR_TO_PROVIDER`:
|
|
82
|
+
|
|
83
|
+
| registry `vendor` | pi provider key | example model binding |
|
|
84
|
+
| ----------------- | ----------------- | ----------------------------- |
|
|
85
|
+
| `minimax` | `minimax-cn` | `minimax-cn/MiniMax-M3` |
|
|
86
|
+
| `deepseek` | `deepseek` | `deepseek/deepseek-flash` |
|
|
87
|
+
| `openai` | `openai-codex` | `openai-codex/gpt-6.1-sol` |
|
|
88
|
+
| `moonshotai` | `kimi-coding` | `kimi-coding/kimi-for-coding` |
|
|
89
|
+
| `typesafe` | `typesafe` | `typesafe/jev-latest` |
|
|
90
|
+
|
|
91
|
+
If your registry uses a vendor not in the table, add it to the script's
|
|
92
|
+
`VENDOR_TO_PROVIDER` and re-run `sync_settings.py`.
|
|
93
|
+
|
|
94
|
+
## Summary
|
|
95
|
+
|
|
96
|
+
| Path | Dispatch mechanism | Binding honoured? | Caveats |
|
|
97
|
+
| ------------------- | ------------------ | ----------------- | -------------------------------- |
|
|
98
|
+
| Plain text | main LLM | no | model is session default |
|
|
99
|
+
| `@handle` mention | sync subagent | **yes** | needs `@` + space + message |
|
|
100
|
+
| `agent` tool | sync subagent | **yes** | model-driven, needs no @ syntax |
|
|
101
|
+
| `SubagentWorkflow` | subagent pipeline | **yes** | orchestrator pattern |
|
|
102
|
+
|
|
103
|
+
## Practical usage
|
|
104
|
+
|
|
105
|
+
For interactive `pi` sessions, the cleanest invocation is the `@handle`
|
|
106
|
+
mention. For automation and subagent pipelines, use `agent` /
|
|
107
|
+
`SubagentWorkflow` with `subagent_type` / `agentType`.
|
|
108
|
+
|
|
109
|
+
The `sync_settings.py` output is the same for both — `provider/modelId` is
|
|
110
|
+
all that matters.
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# Gate runner usage (pi-rolecast v0.2.0)
|
|
2
|
+
|
|
3
|
+
```bash
|
|
4
|
+
python3 $SKILL_ROOT/scripts/gate_runner.py \
|
|
5
|
+
--profile .pi/rolecast.yaml \
|
|
6
|
+
[--phase NAME | --phase all] \
|
|
7
|
+
[--log-dir DIR] \
|
|
8
|
+
[--framework-root DIR]
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
The `--profile` flag also accepts the legacy `.pi/agent-workflow.yaml` filename for one release.
|
|
12
|
+
|
|
13
|
+
Exit codes: `0` (all phases pass), `1` (phase failed after retries), `2` (config error).
|
|
14
|
+
|
|
15
|
+
Phases run in declared order. Default escalation: `max_attempts=2`, `on_permanent_failure=stop`, `preserve_logs=true`.
|
|
16
|
+
|
|
17
|
+
Logs written to `<log-dir>/<timestamp>/<phase>-attempt<N>.log` plus `summary.json` on stdout. Default log directory is `.pi/rolecast-logs/` (was `.pi/agent-workflow-logs/` in v0.1.x).
|
|
18
|
+
|
|
19
|
+
Non-negotiables are NOT enforced by gate-runner; the reviewer agent checks them at diff-review time.
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
# Migration from v0.1.x (pi-agent-workflow) to v0.2.0 (pi-rolecast)
|
|
2
|
+
|
|
3
|
+
v0.2.0 is a **breaking release**. The package is renamed from `@rootazero/pi-agent-workflow` (scoped) to `pi-rolecast` (unscoped), roles are now grouped, and role names are hyphen-prefixed.
|
|
4
|
+
|
|
5
|
+
## Summary of changes
|
|
6
|
+
|
|
7
|
+
| Area | v0.1.x | v0.2.0 |
|
|
8
|
+
|---|---|---|
|
|
9
|
+
| npm package | `@rootazero/pi-agent-workflow` | `pi-rolecast` |
|
|
10
|
+
| Profile filename | `.pi/agent-workflow.yaml` | `.pi/rolecast.yaml` (legacy still recognised) |
|
|
11
|
+
| Role source dir | `agents/<role>.md` | `role-packs/<group>/<role>.md` |
|
|
12
|
+
| Role name format | `architect` | `coding-architect` (full prefixed) |
|
|
13
|
+
| Role scope | All roles are coding | Groups: coding, video, research, ... (future) |
|
|
14
|
+
| Profile field `workflow.role_groups` | (did not exist) | required top-level field |
|
|
15
|
+
| Dispatch mention | `@architect` | `@coding-architect` |
|
|
16
|
+
| Agent tool subagent_type | `architect` | `coding-architect` |
|
|
17
|
+
| Registry user-global dir | `~/.pi/agent-workflow/` | `~/.pi/rolecast/` |
|
|
18
|
+
| Log directory | `.pi/agent-workflow-logs/` | `.pi/rolecast-logs/` |
|
|
19
|
+
|
|
20
|
+
## Step-by-step migration
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
# 1. Uninstall the old package (keeps your project profile + agent files intact)
|
|
24
|
+
pi uninstall npm:@rootazero/pi-agent-workflow
|
|
25
|
+
|
|
26
|
+
# 2. Install the new package
|
|
27
|
+
pi install npm:pi-rolecast
|
|
28
|
+
|
|
29
|
+
# 3. In each project, re-run scaffolder to regenerate the profile
|
|
30
|
+
cd <your-project>
|
|
31
|
+
python3 $SKILL_ROOT/scripts/scaffolder.py init --template <lang> --force
|
|
32
|
+
|
|
33
|
+
# 4. Rename your profile file (optional — legacy name still works)
|
|
34
|
+
mv .pi/agent-workflow.yaml .pi/rolecast.yaml
|
|
35
|
+
|
|
36
|
+
# 5. Re-sync project-local agent files
|
|
37
|
+
python3 $SKILL_ROOT/scripts/sync_settings.py
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## Profile diff (before / after)
|
|
41
|
+
|
|
42
|
+
**Before (v0.1.x):**
|
|
43
|
+
|
|
44
|
+
```yaml
|
|
45
|
+
framework_version: 0.1.0
|
|
46
|
+
name: my-project
|
|
47
|
+
description: ...
|
|
48
|
+
gates:
|
|
49
|
+
compile: {commands: [cargo check], timeout: 300}
|
|
50
|
+
bindings:
|
|
51
|
+
architect: {alias: opus-thinking-medium, channels: [official]}
|
|
52
|
+
implementer: {alias: deepseek-verifiable, channels: [official]}
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
**After (v0.2.0):**
|
|
56
|
+
|
|
57
|
+
```yaml
|
|
58
|
+
framework_version: 0.2.0
|
|
59
|
+
name: my-project
|
|
60
|
+
description: ...
|
|
61
|
+
workflow:
|
|
62
|
+
role_groups: [coding]
|
|
63
|
+
gates:
|
|
64
|
+
compile: {commands: [cargo check], timeout: 300}
|
|
65
|
+
bindings:
|
|
66
|
+
coding-architect: {alias: opus-thinking-medium, channels: [official]}
|
|
67
|
+
coding-implementer: {alias: deepseek-verifiable, channels: [official]}
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
## What if I'm coming from the original `rust-agent-workflow`?
|
|
71
|
+
|
|
72
|
+
If you started on the very first `rust-agent-workflow` skill (pre-pi-agent-workflow), see the role-name translation below. The original skill used unprefixed names; pi-agent-workflow kept them; pi-rolecast prefixes them with the group.
|
|
73
|
+
|
|
74
|
+
| Original | v0.2.0 |
|
|
75
|
+
|---|---|
|
|
76
|
+
| (main) | coding-orchestrator |
|
|
77
|
+
| rust-architect | coding-architect |
|
|
78
|
+
| contract-planner | coding-planner |
|
|
79
|
+
| codemod | coding-implementer |
|
|
80
|
+
| test-writer | coding-tester |
|
|
81
|
+
| final-reviewer | coding-reviewer |
|
|
82
|
+
| repo-mapper | coding-mapper |
|
|
83
|
+
| perf-profiler | coding-profiler |
|
|
84
|
+
| safety-auditor | coding-auditor |
|
|
85
|
+
| relay-canary | coding-canary |
|
|
86
|
+
| docs-visual | coding-docs |
|
|
87
|
+
|
|
88
|
+
## Role groups roadmap
|
|
89
|
+
|
|
90
|
+
v0.2.0 ships with the `coding` group only. Future groups planned for separate releases:
|
|
91
|
+
|
|
92
|
+
- `video` — scriptwriter, narrator-prompt, thumbnail-designer, video-editor, transcript-cleaner, caption-styler, seo-optimizer, hook-generator
|
|
93
|
+
- `research` — literature-reviewer, data-analyst, fact-checker, summarizer
|
|
94
|
+
- `design` — ux-reviewer, copywriter, asset-curator, brand-checker
|
|
95
|
+
- `music` — composer, lyricist, mix-engineer, mastering-engineer
|
|
96
|
+
|
|
97
|
+
To enable a group once it's installed, add it to `workflow.role_groups`. Each group ships its own aliases + bindings defaults in its templates.
|
|
98
|
+
|
|
99
|
+
## Deprecation plan
|
|
100
|
+
|
|
101
|
+
The v0.2.0 release keeps these compatibility shims for **one** release cycle (until v0.3.0):
|
|
102
|
+
|
|
103
|
+
- `.pi/agent-workflow.yaml` still loads (with a stderr hint).
|
|
104
|
+
- Legacy unprefixed role names in `bindings:` print a hint pointing to the new prefixed name.
|
|
105
|
+
- The framework symlink path `~/.pi/agent/pi-agent-workflow` is removed on install (warning printed if found).
|
|
106
|
+
|
|
107
|
+
After v0.3.0 these shims will be removed and v0.2.x profiles will be the only supported format.
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
# Profile schema reference (pi-rolecast v0.2.0)
|
|
2
|
+
|
|
3
|
+
Full schema lives at `docs/superpowers/specs/2026-10-03-pi-agent-workflow-design.md` (historical) and the live validator at `scripts/profile_loader.py`.
|
|
4
|
+
|
|
5
|
+
## Top-level fields
|
|
6
|
+
|
|
7
|
+
| Field | Type | Required | Notes |
|
|
8
|
+
|---|---|---|---|
|
|
9
|
+
| `framework_version` | string | yes | Must match the installed framework version (e.g. `0.2.0`). |
|
|
10
|
+
| `name` | string | yes | Human-readable profile name. |
|
|
11
|
+
| `description` | string | yes | One-paragraph summary. |
|
|
12
|
+
| `workflow` | mapping | yes (v0.2.0+) | Holds `role_groups`. |
|
|
13
|
+
| `workflow.role_groups` | list[string] | yes | Which role groups are enabled. Empty list = no roles enabled. |
|
|
14
|
+
| `gates` | mapping | yes | Phase name → `{commands, timeout}`. May be empty. |
|
|
15
|
+
| `bindings` | mapping | yes | Full role name (`<group>-<role>` or custom name) → `{alias, channels}`. May be empty. |
|
|
16
|
+
| `non_negotiables` | mapping | no | `forbidden_patterns`, `scope_constraints`, `required_gates`. |
|
|
17
|
+
| `escalation` | mapping | no | `max_attempts`, `on_permanent_failure`, `preserve_logs`. |
|
|
18
|
+
| `trigger_overrides` | mapping | no | Phrase → `{role}`. |
|
|
19
|
+
| `custom_roles` | list | no | User-defined roles. |
|
|
20
|
+
|
|
21
|
+
## Roles and groups
|
|
22
|
+
|
|
23
|
+
Roles live in `role-packs/<group>/<role>.md` in the framework installation. The v0.2.0 release ships the `coding` group with 11 roles. Each role md file has YAML frontmatter:
|
|
24
|
+
|
|
25
|
+
```yaml
|
|
26
|
+
---
|
|
27
|
+
name: coding-architect
|
|
28
|
+
category: coding
|
|
29
|
+
description: Design system boundaries, public APIs, error strategies.
|
|
30
|
+
model: deepseek-flash
|
|
31
|
+
thinking: high
|
|
32
|
+
---
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
The `name:` field is the full role name used in profile bindings and dispatch mentions. It must match `<group>-<role>` so the `<group>-<role>` mention syntax (`@coding-architect`) works through pi-subagents.
|
|
36
|
+
|
|
37
|
+
Profile bindings reference these full names:
|
|
38
|
+
|
|
39
|
+
```yaml
|
|
40
|
+
bindings:
|
|
41
|
+
coding-architect: {alias: opus-thinking-medium, channels: [official]}
|
|
42
|
+
coding-implementer: {alias: deepseek-verifiable, channels: [official]}
|
|
43
|
+
# ...
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## Validation rules
|
|
47
|
+
|
|
48
|
+
1. `bindings` keys must be one of the role names from enabled `workflow.role_groups`, OR a `custom_roles` entry.
|
|
49
|
+
2. Each `alias` must resolve to a non-`withdrawn` model in the merged registry.
|
|
50
|
+
3. Each `channels` entry must be one the resolved model supports.
|
|
51
|
+
4. `gates` phases run in declared order; `--phase <undeclared>` is a config error.
|
|
52
|
+
5. Trigger phrase collisions across framework defaults + profile overrides + custom role triggers → error.
|
|
53
|
+
6. `forbidden_patterns[*].pattern` must compile as a regex.
|
|
54
|
+
7. `workflow.role_groups` must be a list of strings; group names not present in `role-packs/` cause the loader to skip them silently (an empty group is treated as "no roles available").
|
|
55
|
+
|
|
56
|
+
## Migration from v0.1.x
|
|
57
|
+
|
|
58
|
+
The legacy profile filename `.pi/agent-workflow.yaml` is still recognised for one release. Profile schema changes required:
|
|
59
|
+
|
|
60
|
+
| v0.1.x field | v0.2.0 replacement |
|
|
61
|
+
|---|---|
|
|
62
|
+
| `bindings: { architect: ... }` | `bindings: { coding-architect: ... }` + `workflow.role_groups: [coding]` |
|
|
63
|
+
| Profile file `.pi/agent-workflow.yaml` | `.pi/rolecast.yaml` |
|
|
64
|
+
| (no equivalent) | `workflow.role_groups: [...]` |
|
|
65
|
+
|
|
66
|
+
The profile loader prints a one-line hint when a legacy role name is detected in a binding.
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# Registry resolution reference (pi-rolecast v0.2.0)
|
|
2
|
+
|
|
3
|
+
Algorithm: spec §6.4 (7 steps).
|
|
4
|
+
|
|
5
|
+
Three override layers, deep-merged in order (later wins):
|
|
6
|
+
1. Built-in: `<framework>/registry/{built_in,aliases}.yaml`
|
|
7
|
+
2. User-global: `~/.pi/rolecast/{registry,aliases}-overrides.yaml` (renamed from `~/.pi/agent-workflow/` in v0.2.0)
|
|
8
|
+
3. Project-local: `<project>/.pi/rolecast-registry.yaml` (renamed from `agent-workflow-registry.yaml` in v0.2.0)
|
|
9
|
+
|
|
10
|
+
Status semantics:
|
|
11
|
+
- `stable` — resolves normally.
|
|
12
|
+
- `deprecated` — resolves with a warning.
|
|
13
|
+
- `experimental` — resolves; scaffolder init skips it from defaults.
|
|
14
|
+
- `withdrawn` — does NOT resolve. Profile fails to load.
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# Scaffolder usage (pi-rolecast v0.2.0)
|
|
2
|
+
|
|
3
|
+
## init
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
python3 $SKILL_ROOT/scripts/scaffolder.py init [--template LANG] [--blank] [--dry-run] [--force]
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
Auto-detects language from project files (Cargo.toml → rust, pyproject.toml → python, package.json+tsconfig.json → typescript, go.mod → go). Multi-language projects print a list; pass `--template` to pick.
|
|
10
|
+
|
|
11
|
+
Templates ship under `<framework>/templates/{rust,typescript,python,go,blank}.yaml`. The generated profile lands at `<project>/.pi/rolecast.yaml` and includes `workflow.role_groups: [coding]` by default.
|
|
12
|
+
|
|
13
|
+
## validate
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
python3 $SKILL_ROOT/scripts/scaffolder.py validate --profile <path>
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
Default profile path: `.pi/rolecast.yaml`. Legacy `.pi/agent-workflow.yaml` is also accepted. Delegates to `profile_loader.load_profile`. Exit code 0 = valid, non-zero = error.
|
|
20
|
+
|
|
21
|
+
## diff
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
python3 $SKILL_ROOT/scripts/scaffolder.py diff --profile <path>
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
Reads `profile.framework_version` and reports fields added/removed in newer framework schemas. No auto-merge.
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
# Sync settings usage (pi-rolecast v0.2.0)
|
|
2
|
+
|
|
3
|
+
The framework's profile bindings (alias -> model + channel) need to reach the actual Pi subagent dispatcher. `sync_settings.py` is that bridge.
|
|
4
|
+
|
|
5
|
+
## What it writes
|
|
6
|
+
|
|
7
|
+
When you run sync_settings against a project with a profile, two things happen:
|
|
8
|
+
|
|
9
|
+
1. **settings.json** — `~/.pi/agent/settings.json` -> `subagents.agentOverrides.<full-role-name>.{model,channel}` for each bound role. (Pi core does not currently read this key for dispatch; it is kept for parity with prior skills and debugging.)
|
|
10
|
+
2. **Project-local agent files** — `<project>/.pi/agents/<group>-<role>.md` is written with `model:` and `thinking:` frontmatter set from your binding. The full role name matches the binding key so pi-subagents can find it via `@<full-role-name>` mention syntax or `subagent_type: "<full-role-name>"`.
|
|
11
|
+
|
|
12
|
+
## Commands
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
python3 $SKILL_ROOT/scripts/sync_settings.py \
|
|
16
|
+
--profile .pi/rolecast.yaml \ # source of truth (legacy .pi/agent-workflow.yaml also accepted)
|
|
17
|
+
--framework-root $SKILL_ROOT # where role-packs/ lives
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
Useful flags:
|
|
21
|
+
- `--status` — show current sync state vs profile bindings; flags `DRIFT` if a project-local agent file's model field was manually edited away from the binding. Exits 0 regardless (informational only).
|
|
22
|
+
- `--dry-run` — print what would be written without touching disk.
|
|
23
|
+
- `--clear` — remove all `agentOverrides` from settings.json and delete every project-local agent file. User-made files and symlinks in the agents dir are preserved.
|
|
24
|
+
- `--no-settings` / `--no-agents` — skip settings.json / project-local agent files respectively.
|
|
25
|
+
- `--agents-dir <path>` — override the default `.pi/agents/` location.
|
|
26
|
+
- `--settings <path>` — override `~/.pi/agent/settings.json`.
|
|
27
|
+
- `--list-groups` — list available role groups from `role-packs/` and exit.
|
|
28
|
+
|
|
29
|
+
## When sync runs
|
|
30
|
+
|
|
31
|
+
- Automatically by `scripts/install.sh` whenever a profile is found in the cwd.
|
|
32
|
+
- Manually by you whenever you edit `.pi/rolecast.yaml` and want the change to take effect.
|
|
33
|
+
|
|
34
|
+
## pi-subagents dependency
|
|
35
|
+
|
|
36
|
+
`@tintinweb/pi-subagents` must be installed for role dispatch to actually work. `install.sh` warns when it's missing:
|
|
37
|
+
|
|
38
|
+
```
|
|
39
|
+
WARNING: pi-subagents not found in ~/.pi/agent/settings.json packages[]
|
|
40
|
+
Role symlinks are installed but dispatch won't work without pi-subagents.
|
|
41
|
+
Install with: pi install npm:@tintinweb/pi-subagents
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## `model:` resolution chain
|
|
45
|
+
|
|
46
|
+
When sync_settings resolves `model:` for a binding:
|
|
47
|
+
|
|
48
|
+
1. Profile binding specifies an alias (e.g. `opus-thinking-medium`).
|
|
49
|
+
2. Alias resolution uses the 3-layer registry merge (built-in -> user-global `~/.pi/rolecast/registry-overrides.yaml` -> project-local `.pi/rolecast-registry.yaml`). The alias points to a model ID (e.g. `MiniMax-M3`).
|
|
50
|
+
3. That model ID is rewritten to `provider/modelId` (see below) and written into the project-local agent file's `model:` frontmatter.
|
|
51
|
+
|
|
52
|
+
## `thinking:` resolution
|
|
53
|
+
|
|
54
|
+
The project-local agent file's `thinking:` field is preserved from the role-packs/<group>/<role>.md default. Each role's default is set by its output category:
|
|
55
|
+
- Judgement roles (orchestrator, architect, auditor, reviewer): `high`
|
|
56
|
+
- Meta roles (mapper, planner, profiler, docs): `medium`
|
|
57
|
+
- Verifiable roles (implementer, tester, canary): `low`
|
|
58
|
+
|
|
59
|
+
If you want to override `thinking:` per project, edit the project-local file after sync.
|
|
60
|
+
|
|
61
|
+
## provider/modelId format
|
|
62
|
+
|
|
63
|
+
`sync_settings.py` rewrites each binding to `provider/modelId` (e.g.
|
|
64
|
+
`minimax-cn/MiniMax-M3`, `openai-codex/gpt-6.1-sol`) before writing it
|
|
65
|
+
into the agent file. `pi-subagents` `resolveDefaultModel` only parses
|
|
66
|
+
strings that contain a `/`; plain `MiniMax-M3` would silently fall back to
|
|
67
|
+
the parent session's model. See [`dispatch-model-semantics.md`](./dispatch-model-semantics.md) for the full explanation.
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# Built-in alias set. Profiles reference aliases; framework resolves them.
|
|
2
|
+
# Adding an alias = PR; renaming an alias = breaking change.
|
|
3
|
+
|
|
4
|
+
aliases:
|
|
5
|
+
opus-thinking-medium:
|
|
6
|
+
preferred: claude-opus-5-5
|
|
7
|
+
fallback_chain: [claude-sonnet-5-5]
|
|
8
|
+
notes: "Frontier reasoning + thinking; judgement work"
|
|
9
|
+
|
|
10
|
+
opus-thinking-high:
|
|
11
|
+
preferred: claude-opus-5-5
|
|
12
|
+
fallback_chain: []
|
|
13
|
+
notes: "High-effort reasoning"
|
|
14
|
+
|
|
15
|
+
gpt-judgment-medium:
|
|
16
|
+
preferred: gpt-6.1-sol
|
|
17
|
+
fallback_chain: []
|
|
18
|
+
notes: "Judgement + relay channel; output reviewed"
|
|
19
|
+
|
|
20
|
+
gpt-judgment-high:
|
|
21
|
+
preferred: gpt-6.1-sol
|
|
22
|
+
fallback_chain: []
|
|
23
|
+
notes: "High-effort judgement"
|
|
24
|
+
|
|
25
|
+
deepseek-verifiable:
|
|
26
|
+
preferred: deepseek-v4.1-flash
|
|
27
|
+
fallback_chain: []
|
|
28
|
+
notes: "Verifiable-output work; trusted channel only"
|
|
29
|
+
|
|
30
|
+
minimax-medium:
|
|
31
|
+
preferred: minimax-m3
|
|
32
|
+
fallback_chain: []
|
|
33
|
+
notes: "Generation + general purpose"
|
|
34
|
+
|
|
35
|
+
minimax-fast:
|
|
36
|
+
preferred: minimax-m3
|
|
37
|
+
fallback_chain: []
|
|
38
|
+
notes: "Cheap, fast"
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# Built-in model registry shipped with pi-agent-workflow.
|
|
2
|
+
# Updated via framework version bumps. Add new models here; never mutate a
|
|
3
|
+
# shipped model — change `status: deprecated` or `withdrawn` instead.
|
|
4
|
+
|
|
5
|
+
models:
|
|
6
|
+
- id: claude-opus-5-5
|
|
7
|
+
vendor: anthropic
|
|
8
|
+
capabilities: {reasoning: high, thinking: true, context_window: 200000}
|
|
9
|
+
channels:
|
|
10
|
+
- {id: official, trust: trusted}
|
|
11
|
+
- {id: relay-default, trust: unverified}
|
|
12
|
+
cost_tier: high
|
|
13
|
+
status: stable
|
|
14
|
+
|
|
15
|
+
- id: claude-sonnet-5-5
|
|
16
|
+
vendor: anthropic
|
|
17
|
+
capabilities: {reasoning: medium, thinking: false, context_window: 200000}
|
|
18
|
+
channels:
|
|
19
|
+
- {id: official, trust: trusted}
|
|
20
|
+
cost_tier: medium
|
|
21
|
+
status: stable
|
|
22
|
+
|
|
23
|
+
- id: deepseek-v4.1-flash
|
|
24
|
+
vendor: deepseek
|
|
25
|
+
capabilities: {reasoning: medium, thinking: false, context_window: 64000}
|
|
26
|
+
channels: [{id: official, trust: trusted}]
|
|
27
|
+
cost_tier: low
|
|
28
|
+
status: stable
|
|
29
|
+
|
|
30
|
+
- id: gpt-6.1-sol
|
|
31
|
+
vendor: openai
|
|
32
|
+
capabilities: {reasoning: high, thinking: true, context_window: 128000}
|
|
33
|
+
channels: [{id: relay-default, trust: unverified}]
|
|
34
|
+
cost_tier: medium
|
|
35
|
+
status: stable
|
|
36
|
+
|
|
37
|
+
- id: minimax-m3
|
|
38
|
+
vendor: minimax
|
|
39
|
+
capabilities: {reasoning: medium, thinking: false, context_window: 200000}
|
|
40
|
+
channels: [{id: official, trust: trusted}]
|
|
41
|
+
cost_tier: low
|
|
42
|
+
status: stable
|
package/requirements.txt
ADDED