Confirmed by experiment: how a picker can assign skills per agent, and where the boundary is
This commit is contained in:
@@ -0,0 +1,101 @@
|
||||
---
|
||||
type: context
|
||||
id: context.paperclip-harness.paperclipai
|
||||
title: paperclipai
|
||||
status: active
|
||||
source_of_truth: false
|
||||
freshness: current
|
||||
last_reviewed: 2026-11-10
|
||||
tags:
|
||||
- pack/paperclip-harness
|
||||
- agent-memory/context
|
||||
- autolearn
|
||||
- rich-discovery
|
||||
- repo/paperclipai
|
||||
---
|
||||
|
||||
# paperclipai
|
||||
|
||||
## Rich discovery update (2026-11-10 21:14:03)
|
||||
|
||||
You are right, and my explanation was wrong in a way that matters. Correcting it.
|
||||
|
||||
## Per-agent skills already exist — that is the design
|
||||
|
||||
`GET /api/agents/{id}/skills` returns a **separate** `desiredSkills` list for every agent. Setting it is one call:
|
||||
|
||||
```
|
||||
POST /api/agents/{id}/skills/sync
|
||||
{ "mode": "replace",
|
||||
"desiredSkills": ["company/<id>/nixos-workflow", "paperclipai/paperclip/paperclip"] }
|
||||
```
|
||||
|
||||
`replace` means "this agent gets exactly these". At run time the adapter builds a directory from **that agent's** list and passes it as `--skill`. Builder had its own list; Documenter has another. Different agents, different skills, no picker needed.
|
||||
|
||||
What I got wrong: I let a narrow caveat ("links persist in the shared directory, so a skill can linger") stand in for the whole model, which read as "one set for everybody". It is not. The list is per agent and it is stored in Paperclip.
|
||||
|
||||
Skills are drawn from `GET /api/skills/available`, the company list, and the catalog — any of which can be assigned to any agent with the call above.
|
||||
|
||||
## Per-agent extensions: yes, through the command
|
||||
|
||||
The adapter's own configuration document says the command defaults to `pi` and is settable per agent, and so is `env`:
|
||||
|
||||
```
|
||||
adapterConfig.command defaults to "pi"
|
||||
adapterConfig.env KEY=VALUE pairs
|
||||
```
|
||||
|
||||
So an agent gets its own wrapper:
|
||||
|
||||
```sh
|
||||
#!/bin/sh
|
||||
exec pi --extension npm:pi-memctx \
|
||||
--extension git:https://gitea…/pi-config/extensions/tavily-search/index.ts \
|
||||
"$@"
|
||||
```
|
||||
|
||||
and `PATCH /api/agents/{id}` sets `adapterConfig.command` to that file. The adapter appends its own arguments (`--mode json`, `--session`, `--skill`, `--tools`, `--model`) to whatever the command is, so the wrapper is additive and cannot break the run. `env` is the same lever for environment.
|
||||
|
||||
That gives you, today and without touching Paperclip's source:
|
||||
|
||||
- one wrapper per role — `builder`, `documenter`, `reviewer` — each with its own extension list;
|
||||
- a place to pass `--no-skills` if you ever want strict isolation;
|
||||
- a place to keep the tool list deliberately small.
|
||||
|
||||
So the honest summary is: **skills are per agent in Paperclip already; extensions are per agent through the agent's command.** My "one global set" sentence was simply false.
|
||||
|
||||
## History — three options, best first
|
||||
|
||||
1. **Open the real Pi session in a pane.** Every run is written to `~/.pi/paperclips/<timestamp>-<agentId>.jsonl` and Pi is started with `--session <file>`. A pane running `pi --session <that file>` shows the actual conversation with Pi's own interface, and can be continued. No new code — a tool-pane entry that takes a file path. The only risk is two writers on one session file, so use it on finished runs or as a deliberate hand-over.
|
||||
2. **A read-only transcript tab** in `Agents>agents`, drawn from the same JSONL. Integrated and safe, less faithful.
|
||||
3. **`pi --resume`** in a tool pane and pick the session from Pi's own list. Simplest, but you find it by eye.
|
||||
|
||||
`GET /api/agents/{id}/task-sessions` maps task → session file and working directory, so options 1 and 2 have a reliable index.
|
||||
|
||||
Written into `docs/PLAN-INTERFACE.md` as a correction; committed as `47aacfd`. Nothing in the running layout changed.
|
||||
|
||||
If you want, the next build can be small and specific: an `Agents>skills` tab that lists an agent's skills and adds or removes them with those two calls, and a `t` tool-pane entry that opens a chosen Pi session. Say which.
|
||||
|
||||
## Source paths observed
|
||||
|
||||
- `nix/store/rg248h9sz8dylm8p6a9w9fj4zrv4sgm5-pi-coding-agent-0.82.1/lib/node_modules/pi-monorepo/docs/usage.md`
|
||||
- `paperclipai/paperclip/paperclip`
|
||||
- `api/skills/available`
|
||||
- `pi-config/extensions/tavily-search/index.ts`
|
||||
|
||||
## Evidence
|
||||
|
||||
- Confidence: 84%
|
||||
- Reason: Update component/repository context with detailed discovered structure and configuration
|
||||
|
||||
## Related
|
||||
|
||||
- [[packs/paperclip-harness/00-system/pi-agent/memory-manifest|Memory Manifest]]
|
||||
|
||||
## Related learned memories <!-- same-turn-2026-11-10 21:14:03 -->
|
||||
|
||||
- session: [[packs/paperclip-harness/80-sessions/paperclip-pi-adapter-per-agent-skills-and-per-agent-extensio|Paperclip + Pi adapter: per-agent skills and per-agent extensions]]
|
||||
- session: [[packs/paperclip-harness/80-sessions/rich-discovery-paperclipai-2026-11-10-21-14-03|Rich discovery: paperclipai 2026-11-10 21:14:03]]
|
||||
- context: [[packs/paperclip-harness/20-context/paperclipai|paperclipai]]
|
||||
- runbook: [[packs/paperclip-harness/70-runbooks/tmp-deployment-operations|paperclipai deployment operations]]
|
||||
- observation: [[packs/paperclip-harness/60-observations/tmp-repository-structure-and-configuration-patterns|paperclipai repository structure and configuration patterns]]
|
||||
@@ -1805,3 +1805,88 @@ Committed as `77014d0` — documentation only, nothing in the running layout cha
|
||||
- session: [[packs/paperclip-harness/80-sessions/rich-discovery-pi-2026-11-10-21-03-21|Rich discovery: .pi 2026-11-10 21:03:21]]
|
||||
- context: [[packs/paperclip-harness/20-context/home|.pi]]
|
||||
- runbook: [[packs/paperclip-harness/70-runbooks/tmp-deployment-operations|.pi deployment operations]]
|
||||
|
||||
|
||||
---
|
||||
|
||||
## Update (2026-11-10 21:14:03)
|
||||
|
||||
## Structural/configuration observations (2026-11-10 21:14:03)
|
||||
|
||||
You are right, and my explanation was wrong in a way that matters. Correcting it.
|
||||
|
||||
## Per-agent skills already exist — that is the design
|
||||
|
||||
`GET /api/agents/{id}/skills` returns a **separate** `desiredSkills` list for every agent. Setting it is one call:
|
||||
|
||||
```
|
||||
POST /api/agents/{id}/skills/sync
|
||||
{ "mode": "replace",
|
||||
"desiredSkills": ["company/<id>/nixos-workflow", "paperclipai/paperclip/paperclip"] }
|
||||
```
|
||||
|
||||
`replace` means "this agent gets exactly these". At run time the adapter builds a directory from **that agent's** list and passes it as `--skill`. Builder had its own list; Documenter has another. Different agents, different skills, no picker needed.
|
||||
|
||||
What I got wrong: I let a narrow caveat ("links persist in the shared directory, so a skill can linger") stand in for the whole model, which read as "one set for everybody". It is not. The list is per agent and it is stored in Paperclip.
|
||||
|
||||
Skills are drawn from `GET /api/skills/available`, the company list, and the catalog — any of which can be assigned to any agent with the call above.
|
||||
|
||||
## Per-agent extensions: yes, through the command
|
||||
|
||||
The adapter's own configuration document says the command defaults to `pi` and is settable per agent, and so is `env`:
|
||||
|
||||
```
|
||||
adapterConfig.command defaults to "pi"
|
||||
adapterConfig.env KEY=VALUE pairs
|
||||
```
|
||||
|
||||
So an agent gets its own wrapper:
|
||||
|
||||
```sh
|
||||
#!/bin/sh
|
||||
exec pi --extension npm:pi-memctx \
|
||||
--extension git:https://gitea…/pi-config/extensions/tavily-search/index.ts \
|
||||
"$@"
|
||||
```
|
||||
|
||||
and `PATCH /api/agents/{id}` sets `adapterConfig.command` to that file. The adapter appends its own arguments (`--mode json`, `--session`, `--skill`, `--tools`, `--model`) to whatever the command is, so the wrapper is additive and cannot break the run. `env` is the same lever for environment.
|
||||
|
||||
That gives you, today and without touching Paperclip's source:
|
||||
|
||||
- one wrapper per role — `builder`, `documenter`, `reviewer` — each with its own extension list;
|
||||
- a place to pass `--no-skills` if you ever want strict isolation;
|
||||
- a place to keep the tool list deliberately small.
|
||||
|
||||
So the honest summary is: **skills are per agent in Paperclip already; extensions are per agent through the agent's command.** My "one global set" sentence was simply false.
|
||||
|
||||
## History — three options, best first
|
||||
|
||||
1. **Open the real Pi session in a pane.** Every run is written to `~/.pi/paperclips/<timestamp>-<agentId>.jsonl` and Pi is started with `--session <file>`. A pane running `pi --session <that file>` shows the actual conversation with Pi's own interface, and can be continued. No new code — a tool-pane entry that takes a file path. The only risk is two writers on one session file, so use it on finished runs or as a deliberate hand-over.
|
||||
2. **A read-only transcript tab** in `Agents>agents`, drawn from the same JSONL. Integrated and safe, less faithful.
|
||||
3. **`pi --resume`** in a tool pane and pick the session from Pi's own list. Simplest, but you find it by eye.
|
||||
|
||||
`GET /api/agents/{id}/task-sessions` maps task → session file and working directory, so options 1 and 2 have a reliable index.
|
||||
|
||||
Written into `docs/PLAN-INTERFACE.md` as a correction; committed as `47aacfd`. Nothing in the running layout changed.
|
||||
|
||||
If you want, the next build can be small and specific: an `Agents>skills` tab that lists an agent's skills and adds or removes them with those two calls, and a `t` tool-pane entry that opens a chosen Pi session. Say which.
|
||||
|
||||
## Source paths observed
|
||||
|
||||
- `nix/store/rg248h9sz8dylm8p6a9w9fj4zrv4sgm5-pi-coding-agent-0.82.1/lib/node_modules/pi-monorepo/docs/usage.md`
|
||||
- `paperclipai/paperclip/paperclip`
|
||||
- `api/skills/available`
|
||||
- `pi-config/extensions/tavily-search/index.ts`
|
||||
|
||||
## Evidence
|
||||
|
||||
- Confidence: 82%
|
||||
- Reason: Captured factual repo structure/configuration patterns from rich discovery
|
||||
|
||||
## Related learned memories <!-- same-turn-2026-11-10 21:14:03 -->
|
||||
|
||||
- session: [[packs/paperclip-harness/80-sessions/paperclip-pi-adapter-per-agent-skills-and-per-agent-extensio|Paperclip + Pi adapter: per-agent skills and per-agent extensions]]
|
||||
- session: [[packs/paperclip-harness/80-sessions/rich-discovery-paperclipai-2026-11-10-21-14-03|Rich discovery: paperclipai 2026-11-10 21:14:03]]
|
||||
- context: [[packs/paperclip-harness/20-context/paperclipai|paperclipai]]
|
||||
- runbook: [[packs/paperclip-harness/70-runbooks/tmp-deployment-operations|paperclipai deployment operations]]
|
||||
- observation: [[packs/paperclip-harness/60-observations/tmp-repository-structure-and-configuration-patterns|paperclipai repository structure and configuration patterns]]
|
||||
|
||||
@@ -515,3 +515,88 @@ Committed as `77014d0` — documentation only, nothing in the running layout cha
|
||||
- session: [[packs/paperclip-harness/80-sessions/rich-discovery-pi-2026-11-10-21-03-21|Rich discovery: .pi 2026-11-10 21:03:21]]
|
||||
- context: [[packs/paperclip-harness/20-context/home|.pi]]
|
||||
- runbook: [[packs/paperclip-harness/70-runbooks/tmp-deployment-operations|.pi deployment operations]]
|
||||
|
||||
|
||||
---
|
||||
|
||||
## Update (2026-11-10 21:14:03)
|
||||
|
||||
## Deployment/runbook details discovered (2026-11-10 21:14:03)
|
||||
|
||||
You are right, and my explanation was wrong in a way that matters. Correcting it.
|
||||
|
||||
## Per-agent skills already exist — that is the design
|
||||
|
||||
`GET /api/agents/{id}/skills` returns a **separate** `desiredSkills` list for every agent. Setting it is one call:
|
||||
|
||||
```
|
||||
POST /api/agents/{id}/skills/sync
|
||||
{ "mode": "replace",
|
||||
"desiredSkills": ["company/<id>/nixos-workflow", "paperclipai/paperclip/paperclip"] }
|
||||
```
|
||||
|
||||
`replace` means "this agent gets exactly these". At run time the adapter builds a directory from **that agent's** list and passes it as `--skill`. Builder had its own list; Documenter has another. Different agents, different skills, no picker needed.
|
||||
|
||||
What I got wrong: I let a narrow caveat ("links persist in the shared directory, so a skill can linger") stand in for the whole model, which read as "one set for everybody". It is not. The list is per agent and it is stored in Paperclip.
|
||||
|
||||
Skills are drawn from `GET /api/skills/available`, the company list, and the catalog — any of which can be assigned to any agent with the call above.
|
||||
|
||||
## Per-agent extensions: yes, through the command
|
||||
|
||||
The adapter's own configuration document says the command defaults to `pi` and is settable per agent, and so is `env`:
|
||||
|
||||
```
|
||||
adapterConfig.command defaults to "pi"
|
||||
adapterConfig.env KEY=VALUE pairs
|
||||
```
|
||||
|
||||
So an agent gets its own wrapper:
|
||||
|
||||
```sh
|
||||
#!/bin/sh
|
||||
exec pi --extension npm:pi-memctx \
|
||||
--extension git:https://gitea…/pi-config/extensions/tavily-search/index.ts \
|
||||
"$@"
|
||||
```
|
||||
|
||||
and `PATCH /api/agents/{id}` sets `adapterConfig.command` to that file. The adapter appends its own arguments (`--mode json`, `--session`, `--skill`, `--tools`, `--model`) to whatever the command is, so the wrapper is additive and cannot break the run. `env` is the same lever for environment.
|
||||
|
||||
That gives you, today and without touching Paperclip's source:
|
||||
|
||||
- one wrapper per role — `builder`, `documenter`, `reviewer` — each with its own extension list;
|
||||
- a place to pass `--no-skills` if you ever want strict isolation;
|
||||
- a place to keep the tool list deliberately small.
|
||||
|
||||
So the honest summary is: **skills are per agent in Paperclip already; extensions are per agent through the agent's command.** My "one global set" sentence was simply false.
|
||||
|
||||
## History — three options, best first
|
||||
|
||||
1. **Open the real Pi session in a pane.** Every run is written to `~/.pi/paperclips/<timestamp>-<agentId>.jsonl` and Pi is started with `--session <file>`. A pane running `pi --session <that file>` shows the actual conversation with Pi's own interface, and can be continued. No new code — a tool-pane entry that takes a file path. The only risk is two writers on one session file, so use it on finished runs or as a deliberate hand-over.
|
||||
2. **A read-only transcript tab** in `Agents>agents`, drawn from the same JSONL. Integrated and safe, less faithful.
|
||||
3. **`pi --resume`** in a tool pane and pick the session from Pi's own list. Simplest, but you find it by eye.
|
||||
|
||||
`GET /api/agents/{id}/task-sessions` maps task → session file and working directory, so options 1 and 2 have a reliable index.
|
||||
|
||||
Written into `docs/PLAN-INTERFACE.md` as a correction; committed as `47aacfd`. Nothing in the running layout changed.
|
||||
|
||||
If you want, the next build can be small and specific: an `Agents>skills` tab that lists an agent's skills and adds or removes them with those two calls, and a `t` tool-pane entry that opens a chosen Pi session. Say which.
|
||||
|
||||
## Source paths observed
|
||||
|
||||
- `nix/store/rg248h9sz8dylm8p6a9w9fj4zrv4sgm5-pi-coding-agent-0.82.1/lib/node_modules/pi-monorepo/docs/usage.md`
|
||||
- `paperclipai/paperclip/paperclip`
|
||||
- `api/skills/available`
|
||||
- `pi-config/extensions/tavily-search/index.ts`
|
||||
|
||||
## Evidence
|
||||
|
||||
- Confidence: 83%
|
||||
- Reason: Extracted repeatable deploy/configuration procedure from rich discovery
|
||||
|
||||
## Related learned memories <!-- same-turn-2026-11-10 21:14:03 -->
|
||||
|
||||
- session: [[packs/paperclip-harness/80-sessions/paperclip-pi-adapter-per-agent-skills-and-per-agent-extensio|Paperclip + Pi adapter: per-agent skills and per-agent extensions]]
|
||||
- session: [[packs/paperclip-harness/80-sessions/rich-discovery-paperclipai-2026-11-10-21-14-03|Rich discovery: paperclipai 2026-11-10 21:14:03]]
|
||||
- context: [[packs/paperclip-harness/20-context/paperclipai|paperclipai]]
|
||||
- runbook: [[packs/paperclip-harness/70-runbooks/tmp-deployment-operations|paperclipai deployment operations]]
|
||||
- observation: [[packs/paperclip-harness/60-observations/tmp-repository-structure-and-configuration-patterns|paperclipai repository structure and configuration patterns]]
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
---
|
||||
type: session
|
||||
id: session.paperclip-harness.paperclip-pi-adapter-per-agent-skills-and-per-agent-extensio
|
||||
title: Paperclip + Pi adapter: per-agent skills and per-agent extensions
|
||||
status: active
|
||||
source_of_truth: false
|
||||
freshness: current
|
||||
last_reviewed: 2026-11-10
|
||||
tags:
|
||||
- pack/paperclip-harness
|
||||
- agent-memory/session
|
||||
- paperclip
|
||||
- pi-coding-agent
|
||||
- per-agent-skills
|
||||
- per-agent-extensions
|
||||
- pi_local-adapter
|
||||
- task-sessions
|
||||
- session-history
|
||||
---
|
||||
|
||||
# Paperclip + Pi adapter: per-agent skills and per-agent extensions
|
||||
|
||||
Discovery turn correcting an earlier wrong claim that Paperclip supports only one skill set for all agents.
|
||||
|
||||
Per-agent skills (already implemented in Paperclip):
|
||||
- `GET /api/agents/{id}/skills` returns a separate `desiredSkills` list for each agent.
|
||||
- `POST /api/agents/{id}/skills/sync` with body `{ "mode": "add" | "remove" | "replace", "desiredSkills": [string | { key, versionId(uuid|null) }] }` syncs an agent's skills. `replace` means exactly that list.
|
||||
- At run time the pi_local adapter builds a skill directory from that agent's list and passes it to Pi as `--skill`.
|
||||
- Skill sources: `GET /api/skills/available`, the company list, and the skill catalog. Key format examples seen: `company/<id>/nixos-workflow`, `paperclipai/paperclip/paperclip`.
|
||||
- Caveat: skill links persist in a shared directory, so a skill can linger if not replaced.
|
||||
|
||||
Per-agent extensions (no Paperclip source change needed):
|
||||
- pi_local adapter config document (`agentConfigurationDoc` in adapter index.js) states `command` defaults to `pi` and `env` is KEY=VALUE; both are per agent.
|
||||
- `PATCH /api/agents/{id}` with `adapterConfig.command` set to a wrapper script gives each agent its own extension list. Example wrapper: `#!/bin/sh\nexec pi --extension npm:pi-memctx --extension git:https://.../extensions/tavily-search/index.ts "$@"`.
|
||||
- The adapter appends its own args (`--mode json`, `--session`, `--skill`, `--tools`, `--model`) to the command, so a wrapper is additive/safe.
|
||||
- `adapterConfig.env` is the same lever for env per agent.
|
||||
- Suggested role wrappers: `builder`, `documenter`, `reviewer`.
|
||||
|
||||
Pi runtime facts (pi-coding-agent):
|
||||
- Paperclip runs Pi with `--session <file>`; sessions live at `~/.pi/paperclips/<timestamp>-<agentId>.jsonl`.
|
||||
- `GET /api/agents/{id}/task-sessions` maps task -> session file and cwd.
|
||||
- Pi bash-tool env vars: `PI_CODING_AGENT`, `PI_SESSION_ID`, `PI_SESSION_FILE`, `PI_PROVIDER`, `PI_MODEL`, `PI_REASONING_LEVEL`. `PI_OFFLINE` configures Pi. Inspect `$PI_PROVIDER/$PI_MODEL` instead of inferring from prompt.
|
||||
- `pi -c/--continue` continues most recent session; `pi -r/--resume` browses sessions.
|
||||
|
||||
History-viewing options, best first:
|
||||
1. Tool pane running `pi --session <jsonl>` on a finished run (risk: two writers on one session file).
|
||||
2. Read-only transcript tab in `Agents>agents` from the same JSONL.
|
||||
3. `pi --resume` in a tool pane and pick by eye.
|
||||
|
||||
Repo/files touched: correction written to `docs/PLAN-INTERFACE.md`; commit `47aacfd`. Nothing in the running layout changed. Sandbox install pin: `npm install -g @earendil-works/pi-coding-agent@0.74.0` (adapter) while Nix has pi-coding-agent 0.82.1. Follow-ups the user could pick: an `Agents>skills` tab (list/add/remove via the two API calls) and a `t` tool-pane entry to open a chosen Pi session.
|
||||
|
||||
## Evidence
|
||||
|
||||
- Confidence: 90%
|
||||
- Reason: Rich discovery snapshot with concrete API endpoints, adapter config levers, session paths, and commit reference that a future agent can reuse.
|
||||
|
||||
## Related
|
||||
|
||||
- [[packs/paperclip-harness/00-system/pi-agent/memory-manifest|Memory Manifest]]
|
||||
|
||||
## Related learned memories <!-- same-turn-2026-11-10 21:14:03 -->
|
||||
|
||||
- session: [[packs/paperclip-harness/80-sessions/paperclip-pi-adapter-per-agent-skills-and-per-agent-extensio|Paperclip + Pi adapter: per-agent skills and per-agent extensions]]
|
||||
- session: [[packs/paperclip-harness/80-sessions/rich-discovery-paperclipai-2026-11-10-21-14-03|Rich discovery: paperclipai 2026-11-10 21:14:03]]
|
||||
- context: [[packs/paperclip-harness/20-context/paperclipai|paperclipai]]
|
||||
- runbook: [[packs/paperclip-harness/70-runbooks/tmp-deployment-operations|paperclipai deployment operations]]
|
||||
- observation: [[packs/paperclip-harness/60-observations/tmp-repository-structure-and-configuration-patterns|paperclipai repository structure and configuration patterns]]
|
||||
@@ -0,0 +1,104 @@
|
||||
---
|
||||
type: session
|
||||
id: session.paperclip-harness.rich-discovery-paperclipai-2026-11-10-21-14-03
|
||||
title: Rich discovery: paperclipai 2026-11-10 21:14:03
|
||||
status: active
|
||||
source_of_truth: false
|
||||
freshness: current
|
||||
last_reviewed: 2026-11-10
|
||||
tags:
|
||||
- pack/paperclip-harness
|
||||
- agent-memory/session
|
||||
- autolearn
|
||||
- rich-discovery
|
||||
- repo/paperclipai
|
||||
---
|
||||
|
||||
# Rich discovery: paperclipai 2026-11-10 21:14:03
|
||||
|
||||
Sanitized rich discovery snapshot captured automatically from the completed turn.
|
||||
|
||||
|
||||
## Source paths observed
|
||||
|
||||
- `nix/store/rg248h9sz8dylm8p6a9w9fj4zrv4sgm5-pi-coding-agent-0.82.1/lib/node_modules/pi-monorepo/docs/usage.md`
|
||||
- `paperclipai/paperclip/paperclip`
|
||||
- `api/skills/available`
|
||||
- `pi-config/extensions/tavily-search/index.ts`
|
||||
|
||||
## Final answer snapshot
|
||||
|
||||
You are right, and my explanation was wrong in a way that matters. Correcting it.
|
||||
|
||||
## Per-agent skills already exist — that is the design
|
||||
|
||||
`GET /api/agents/{id}/skills` returns a **separate** `desiredSkills` list for every agent. Setting it is one call:
|
||||
|
||||
```
|
||||
POST /api/agents/{id}/skills/sync
|
||||
{ "mode": "replace",
|
||||
"desiredSkills": ["company/<id>/nixos-workflow", "paperclipai/paperclip/paperclip"] }
|
||||
```
|
||||
|
||||
`replace` means "this agent gets exactly these". At run time the adapter builds a directory from **that agent's** list and passes it as `--skill`. Builder had its own list; Documenter has another. Different agents, different skills, no picker needed.
|
||||
|
||||
What I got wrong: I let a narrow caveat ("links persist in the shared directory, so a skill can linger") stand in for the whole model, which read as "one set for everybody". It is not. The list is per agent and it is stored in Paperclip.
|
||||
|
||||
Skills are drawn from `GET /api/skills/available`, the company list, and the catalog — any of which can be assigned to any agent with the call above.
|
||||
|
||||
## Per-agent extensions: yes, through the command
|
||||
|
||||
The adapter's own configuration document says the command defaults to `pi` and is settable per agent, and so is `env`:
|
||||
|
||||
```
|
||||
adapterConfig.command defaults to "pi"
|
||||
adapterConfig.env KEY=VALUE pairs
|
||||
```
|
||||
|
||||
So an agent gets its own wrapper:
|
||||
|
||||
```sh
|
||||
#!/bin/sh
|
||||
exec pi --extension npm:pi-memctx \
|
||||
--extension git:https://gitea…/pi-config/extensions/tavily-search/index.ts \
|
||||
"$@"
|
||||
```
|
||||
|
||||
and `PATCH /api/agents/{id}` sets `adapterConfig.command` to that file. The adapter appends its own arguments (`--mode json`, `--session`, `--skill`, `--tools`, `--model`) to whatever the command is, so the wrapper is additive and cannot break the run. `env` is the same lever for environment.
|
||||
|
||||
That gives you, today and without touching Paperclip's source:
|
||||
|
||||
- one wrapper per role — `builder`, `documenter`, `reviewer` — each with its own extension list;
|
||||
- a place to pass `--no-skills` if you ever want strict isolation;
|
||||
- a place to keep the tool list deliberately small.
|
||||
|
||||
So the honest summary is: **skills are per agent in Paperclip already; extensions are per agent through the agent's command.** My "one global set" sentence was simply false.
|
||||
|
||||
## History — three options, best first
|
||||
|
||||
1. **Open the real Pi session in a pane.** Every run is written to `~/.pi/paperclips/<timestamp>-<agentId>.jsonl` and Pi is started with `--session <file>`. A pane running `pi --session <that file>` shows the actual conversation with Pi's own interface, and can be continued. No new code — a tool-pane entry that takes a file path. The only risk is two writers on one session file, so use it on finished runs or as a deliberate hand-over.
|
||||
2. **A read-only transcript tab** in `Agents>agents`, drawn from the same JSONL. Integrated and safe, less faithful.
|
||||
3. **`pi --resume`** in a tool pane and pick the session from Pi's own list. Simplest, but you find it by eye.
|
||||
|
||||
`GET /api/agents/{id}/task-sessions` maps task → session file and working directory, so options 1 and 2 have a reliable index.
|
||||
|
||||
Written into `docs/PLAN-INTERFACE.md` as a correction; committed as `47aacfd`. Nothing in the running layout changed.
|
||||
|
||||
If you want, the next build can be small and specific: an `Agents>skills` tab that lists an agent's skills and adds or removes them with those two calls, and a `t` tool-pane entry that opens a chosen Pi session. Say which.
|
||||
|
||||
## Evidence
|
||||
|
||||
- Confidence: 86%
|
||||
- Reason: Preserve full sanitized discovery detail from a rich investigation turn
|
||||
|
||||
## Related
|
||||
|
||||
- [[packs/paperclip-harness/00-system/pi-agent/memory-manifest|Memory Manifest]]
|
||||
|
||||
## Related learned memories <!-- same-turn-2026-11-10 21:14:03 -->
|
||||
|
||||
- session: [[packs/paperclip-harness/80-sessions/paperclip-pi-adapter-per-agent-skills-and-per-agent-extensio|Paperclip + Pi adapter: per-agent skills and per-agent extensions]]
|
||||
- session: [[packs/paperclip-harness/80-sessions/rich-discovery-paperclipai-2026-11-10-21-14-03|Rich discovery: paperclipai 2026-11-10 21:14:03]]
|
||||
- context: [[packs/paperclip-harness/20-context/paperclipai|paperclipai]]
|
||||
- runbook: [[packs/paperclip-harness/70-runbooks/tmp-deployment-operations|paperclipai deployment operations]]
|
||||
- observation: [[packs/paperclip-harness/60-observations/tmp-repository-structure-and-configuration-patterns|paperclipai repository structure and configuration patterns]]
|
||||
@@ -490,3 +490,88 @@ deliberately small.
|
||||
|
||||
`GET /api/agents/{id}/task-sessions` maps task → session file and working directory, so option
|
||||
1 and 2 both have a reliable index and neither needs guessing.
|
||||
|
||||
---
|
||||
|
||||
# Confirmed: what the picker emulation needs, and what it can actually do
|
||||
|
||||
Researched by doing it, on this machine, with the board key. Everything below returned 200 or
|
||||
201 unless it says otherwise.
|
||||
|
||||
## The gap, measured
|
||||
|
||||
| Set | Where | Count |
|
||||
|---|---|---|
|
||||
| what the pi-config picker lists | `~/.agents/skills` | **21** (archify, caveman, nixos-workflow, tuios, …) |
|
||||
| what Paperclip can assign | `GET /api/companies/{id}/skills` | **9** (agentmail, obsidian-cli, paperclip, project-docs, system-architect, …) |
|
||||
|
||||
So eleven skills a person can see in the picker cannot be given to a Paperclip agent today,
|
||||
because Paperclip has never heard of them. That is the whole problem, and it is smaller than
|
||||
it looked.
|
||||
|
||||
## What works, in order
|
||||
|
||||
1. **Copy the skill into the company's managed directory.** A local import is refused from
|
||||
anywhere else — `POST …/skills/import` with a path under `~/.agents` returned **403
|
||||
`skill_workspace_boundary_denied`**, "Import from a configured Paperclip workspace or the
|
||||
company managed-skill directory". Copying to
|
||||
`~/.paperclip/instances/default/skills/<companyId>/<name>` and importing that path returned
|
||||
**201**:
|
||||
|
||||
```
|
||||
{"key": "local/9a9eba3826/nixos-workflow", "slug": "nixos-workflow", …}
|
||||
```
|
||||
|
||||
2. **Assign it to one agent, and only that agent**:
|
||||
|
||||
```
|
||||
POST /api/agents/{agentId}/skills/sync
|
||||
{"mode": "add", "desiredSkills": ["local/9a9eba3826/nixos-workflow"]} → 200
|
||||
```
|
||||
|
||||
Verified on `Documenter`: its list went from three skills to four and back to three after a
|
||||
`remove`. Different agents, different lists — as expected.
|
||||
|
||||
3. **Extensions have no Paperclip equivalent.** `~/.agents/extensions` holds them; Paperclip's
|
||||
skill model does not. The per-agent lever is `adapterConfig.command`, which defaults to `pi`
|
||||
and is appended to by the adapter. A wrapper per agent that passes `--extension …` and then
|
||||
`exec pi "$@"` is the equivalent of `pi-config` for a Paperclip run.
|
||||
|
||||
## So the emulation is this, and nothing more
|
||||
|
||||
A picker that does what `pi-config`'s does, for Paperclip agents:
|
||||
|
||||
- **reads** `~/.agents/skills` and `~/.agents/extensions` (the same source the picker uses),
|
||||
the company skill list, and the chosen agent's `desiredSkills`;
|
||||
- **marks** each entry: available but not in Paperclip · in Paperclip · on this agent;
|
||||
- **on choosing** an unavailable skill: copy it into the managed directory, import it, then
|
||||
`skills/sync` it onto that agent;
|
||||
- **on removing**: `skills/sync` with `remove`;
|
||||
- **for an extension**: add it to that agent's wrapper file and point
|
||||
`adapterConfig.command` at the wrapper.
|
||||
|
||||
That is a small command or one panel, not a new subsystem, and every step above is already
|
||||
verified.
|
||||
|
||||
## A change made while checking this
|
||||
|
||||
`nixos-workflow` was copied into the company's managed directory and imported, so it is now in
|
||||
Paperclip's list and can be assigned to any agent. It is assigned to nobody. Nothing else was
|
||||
changed; `Documenter`'s skills were put back exactly as they were.
|
||||
|
||||
## Pi history — the cheap answer is probably enough
|
||||
|
||||
The instinct is right. Every run is already a file:
|
||||
|
||||
```
|
||||
~/.pi/paperclips/<timestamp>-<agentId>.jsonl 178 of them here
|
||||
```
|
||||
|
||||
`GET /api/agents/{id}/task-sessions` maps a task to its session file and folder. So the
|
||||
cheapest useful thing is a tool-pane entry that opens `~/.pi/paperclips` in Yazi, or a pane
|
||||
running `pi --resume` that lists sessions and opens one with Pi's own interface. Both are
|
||||
minutes of work and neither invents anything.
|
||||
|
||||
A transcript tab inside `Agents>agents` is the integration option: read the JSONL, draw the
|
||||
messages, no second process. Worth doing only if the file browser feels like a detour after a
|
||||
week of use. Recommendation: do the cheap one now, decide later.
|
||||
|
||||
Reference in New Issue
Block a user