agentpool-cli 0.1.3__tar.gz → 0.1.4__tar.gz

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.
Files changed (121) hide show
  1. {agentpool_cli-0.1.3 → agentpool_cli-0.1.4}/CHANGELOG.md +11 -0
  2. {agentpool_cli-0.1.3 → agentpool_cli-0.1.4}/PKG-INFO +15 -8
  3. {agentpool_cli-0.1.3 → agentpool_cli-0.1.4}/README.md +14 -7
  4. {agentpool_cli-0.1.3 → agentpool_cli-0.1.4}/docs/agent-cli-and-mcp.md +7 -4
  5. {agentpool_cli-0.1.3 → agentpool_cli-0.1.4}/docs/agentpool-skill.md +22 -11
  6. {agentpool_cli-0.1.3 → agentpool_cli-0.1.4}/docs/mcp-clients.md +4 -3
  7. {agentpool_cli-0.1.3 → agentpool_cli-0.1.4}/docs/mcp-tools.md +13 -4
  8. {agentpool_cli-0.1.3 → agentpool_cli-0.1.4}/docs/onboarding.md +18 -13
  9. {agentpool_cli-0.1.3 → agentpool_cli-0.1.4}/docs/quickstart.md +1 -0
  10. {agentpool_cli-0.1.3 → agentpool_cli-0.1.4}/docs/setup-codex.md +1 -1
  11. {agentpool_cli-0.1.3 → agentpool_cli-0.1.4}/docs/setup-cursor.md +1 -1
  12. {agentpool_cli-0.1.3 → agentpool_cli-0.1.4}/docs/usage-detection.md +1 -1
  13. {agentpool_cli-0.1.3 → agentpool_cli-0.1.4}/pyproject.toml +1 -1
  14. {agentpool_cli-0.1.3 → agentpool_cli-0.1.4}/server.json +3 -3
  15. {agentpool_cli-0.1.3 → agentpool_cli-0.1.4}/src/agentpool/__init__.py +1 -1
  16. {agentpool_cli-0.1.3 → agentpool_cli-0.1.4}/src/agentpool/cli.py +78 -3
  17. {agentpool_cli-0.1.3 → agentpool_cli-0.1.4}/src/agentpool/config.py +18 -0
  18. {agentpool_cli-0.1.3 → agentpool_cli-0.1.4}/src/agentpool/mcp/resources.py +3 -0
  19. {agentpool_cli-0.1.3 → agentpool_cli-0.1.4}/src/agentpool/mcp/tools.py +22 -3
  20. {agentpool_cli-0.1.3 → agentpool_cli-0.1.4}/src/agentpool/mcp_server.py +32 -11
  21. {agentpool_cli-0.1.3 → agentpool_cli-0.1.4}/src/agentpool/onboarding.py +6 -0
  22. agentpool_cli-0.1.4/src/agentpool/preferences.py +134 -0
  23. {agentpool_cli-0.1.3 → agentpool_cli-0.1.4}/src/agentpool/providers/base.py +23 -10
  24. agentpool_cli-0.1.4/src/agentpool/providers/registry.py +269 -0
  25. {agentpool_cli-0.1.3 → agentpool_cli-0.1.4}/src/agentpool/session_manager.py +71 -6
  26. {agentpool_cli-0.1.3 → agentpool_cli-0.1.4}/src/agentpool/stats/compute.py +1 -1
  27. {agentpool_cli-0.1.3 → agentpool_cli-0.1.4}/src/agentpool/usage/devin.py +14 -1
  28. {agentpool_cli-0.1.3 → agentpool_cli-0.1.4}/tests/unit/test_cli.py +16 -0
  29. {agentpool_cli-0.1.3 → agentpool_cli-0.1.4}/tests/unit/test_mcp_surface.py +2 -0
  30. {agentpool_cli-0.1.3 → agentpool_cli-0.1.4}/tests/unit/test_mcp_tools.py +126 -5
  31. {agentpool_cli-0.1.3 → agentpool_cli-0.1.4}/tests/unit/test_models_config_store.py +22 -0
  32. {agentpool_cli-0.1.3 → agentpool_cli-0.1.4}/tests/unit/test_onboarding.py +4 -0
  33. {agentpool_cli-0.1.3 → agentpool_cli-0.1.4}/tests/unit/test_stats_mcp.py +2 -2
  34. {agentpool_cli-0.1.3 → agentpool_cli-0.1.4}/tests/unit/test_usage_probes.py +21 -0
  35. {agentpool_cli-0.1.3 → agentpool_cli-0.1.4}/uv.lock +1 -1
  36. agentpool_cli-0.1.3/src/agentpool/providers/registry.py +0 -139
  37. {agentpool_cli-0.1.3 → agentpool_cli-0.1.4}/.cursor/mcp.json.example +0 -0
  38. {agentpool_cli-0.1.3 → agentpool_cli-0.1.4}/.github/CODEOWNERS +0 -0
  39. {agentpool_cli-0.1.3 → agentpool_cli-0.1.4}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
  40. {agentpool_cli-0.1.3 → agentpool_cli-0.1.4}/.github/ISSUE_TEMPLATE/provider_probe.md +0 -0
  41. {agentpool_cli-0.1.3 → agentpool_cli-0.1.4}/.github/dependabot.yml +0 -0
  42. {agentpool_cli-0.1.3 → agentpool_cli-0.1.4}/.github/workflows/ci.yml +0 -0
  43. {agentpool_cli-0.1.3 → agentpool_cli-0.1.4}/.github/workflows/release.yml +0 -0
  44. {agentpool_cli-0.1.3 → agentpool_cli-0.1.4}/.gitignore +0 -0
  45. {agentpool_cli-0.1.3 → agentpool_cli-0.1.4}/.mcp.json.example +0 -0
  46. {agentpool_cli-0.1.3 → agentpool_cli-0.1.4}/AGENTS.md +0 -0
  47. {agentpool_cli-0.1.3 → agentpool_cli-0.1.4}/CONTRIBUTING.md +0 -0
  48. {agentpool_cli-0.1.3 → agentpool_cli-0.1.4}/LICENSE +0 -0
  49. {agentpool_cli-0.1.3 → agentpool_cli-0.1.4}/SECURITY.md +0 -0
  50. {agentpool_cli-0.1.3 → agentpool_cli-0.1.4}/docs/architecture.md +0 -0
  51. {agentpool_cli-0.1.3 → agentpool_cli-0.1.4}/docs/examples/README.md +0 -0
  52. {agentpool_cli-0.1.3 → agentpool_cli-0.1.4}/docs/examples.md +0 -0
  53. {agentpool_cli-0.1.3 → agentpool_cli-0.1.4}/docs/install.md +0 -0
  54. {agentpool_cli-0.1.3 → agentpool_cli-0.1.4}/docs/model-catalog.md +0 -0
  55. {agentpool_cli-0.1.3 → agentpool_cli-0.1.4}/docs/provider-adapters.md +0 -0
  56. {agentpool_cli-0.1.3 → agentpool_cli-0.1.4}/docs/provider-lifecycle-matrix.md +0 -0
  57. {agentpool_cli-0.1.3 → agentpool_cli-0.1.4}/docs/release.md +0 -0
  58. {agentpool_cli-0.1.3 → agentpool_cli-0.1.4}/docs/security.md +0 -0
  59. {agentpool_cli-0.1.3 → agentpool_cli-0.1.4}/docs/setup-claude-code.md +0 -0
  60. {agentpool_cli-0.1.3 → agentpool_cli-0.1.4}/docs/setup-copilot.md +0 -0
  61. {agentpool_cli-0.1.3 → agentpool_cli-0.1.4}/docs/setup-cursor-cli.md +0 -0
  62. {agentpool_cli-0.1.3 → agentpool_cli-0.1.4}/docs/setup-devin.md +0 -0
  63. {agentpool_cli-0.1.3 → agentpool_cli-0.1.4}/docs/setup-droid.md +0 -0
  64. {agentpool_cli-0.1.3 → agentpool_cli-0.1.4}/docs/stats.md +0 -0
  65. {agentpool_cli-0.1.3 → agentpool_cli-0.1.4}/docs/usage-probe-matrix.md +0 -0
  66. {agentpool_cli-0.1.3 → agentpool_cli-0.1.4}/scripts/install.sh +0 -0
  67. {agentpool_cli-0.1.3 → agentpool_cli-0.1.4}/src/agentpool/agent_io.py +0 -0
  68. {agentpool_cli-0.1.3 → agentpool_cli-0.1.4}/src/agentpool/artifacts.py +0 -0
  69. {agentpool_cli-0.1.3 → agentpool_cli-0.1.4}/src/agentpool/event_detection.py +0 -0
  70. {agentpool_cli-0.1.3 → agentpool_cli-0.1.4}/src/agentpool/fixtures/__init__.py +0 -0
  71. {agentpool_cli-0.1.3 → agentpool_cli-0.1.4}/src/agentpool/fixtures/fake_agents/__init__.py +0 -0
  72. {agentpool_cli-0.1.3 → agentpool_cli-0.1.4}/src/agentpool/fixtures/fake_agents/fake_approval_agent.py +0 -0
  73. {agentpool_cli-0.1.3 → agentpool_cli-0.1.4}/src/agentpool/fixtures/fake_agents/fake_common.py +0 -0
  74. {agentpool_cli-0.1.3 → agentpool_cli-0.1.4}/src/agentpool/fixtures/fake_agents/fake_completed_agent.py +0 -0
  75. {agentpool_cli-0.1.3 → agentpool_cli-0.1.4}/src/agentpool/fixtures/fake_agents/fake_idle_agent.py +0 -0
  76. {agentpool_cli-0.1.3 → agentpool_cli-0.1.4}/src/agentpool/fixtures/fake_agents/fake_limit_agent.py +0 -0
  77. {agentpool_cli-0.1.3 → agentpool_cli-0.1.4}/src/agentpool/fixtures/fake_agents/fake_patch_agent.py +0 -0
  78. {agentpool_cli-0.1.3 → agentpool_cli-0.1.4}/src/agentpool/fixtures/fake_agents/fake_question_agent.py +0 -0
  79. {agentpool_cli-0.1.3 → agentpool_cli-0.1.4}/src/agentpool/git_worktree.py +0 -0
  80. {agentpool_cli-0.1.3 → agentpool_cli-0.1.4}/src/agentpool/mcp/__init__.py +0 -0
  81. {agentpool_cli-0.1.3 → agentpool_cli-0.1.4}/src/agentpool/models.py +0 -0
  82. {agentpool_cli-0.1.3 → agentpool_cli-0.1.4}/src/agentpool/policy.py +0 -0
  83. {agentpool_cli-0.1.3 → agentpool_cli-0.1.4}/src/agentpool/provider_model_catalog.json +0 -0
  84. {agentpool_cli-0.1.3 → agentpool_cli-0.1.4}/src/agentpool/providers/__init__.py +0 -0
  85. {agentpool_cli-0.1.3 → agentpool_cli-0.1.4}/src/agentpool/redaction.py +0 -0
  86. {agentpool_cli-0.1.3 → agentpool_cli-0.1.4}/src/agentpool/runtimes/__init__.py +0 -0
  87. {agentpool_cli-0.1.3 → agentpool_cli-0.1.4}/src/agentpool/runtimes/base.py +0 -0
  88. {agentpool_cli-0.1.3 → agentpool_cli-0.1.4}/src/agentpool/runtimes/tmux.py +0 -0
  89. {agentpool_cli-0.1.3 → agentpool_cli-0.1.4}/src/agentpool/stats/__init__.py +0 -0
  90. {agentpool_cli-0.1.3 → agentpool_cli-0.1.4}/src/agentpool/stats/card.py +0 -0
  91. {agentpool_cli-0.1.3 → agentpool_cli-0.1.4}/src/agentpool/stats/queries.py +0 -0
  92. {agentpool_cli-0.1.3 → agentpool_cli-0.1.4}/src/agentpool/stats/render.py +0 -0
  93. {agentpool_cli-0.1.3 → agentpool_cli-0.1.4}/src/agentpool/stats/window.py +0 -0
  94. {agentpool_cli-0.1.3 → agentpool_cli-0.1.4}/src/agentpool/store.py +0 -0
  95. {agentpool_cli-0.1.3 → agentpool_cli-0.1.4}/src/agentpool/usage/__init__.py +0 -0
  96. {agentpool_cli-0.1.3 → agentpool_cli-0.1.4}/src/agentpool/usage/_common.py +0 -0
  97. {agentpool_cli-0.1.3 → agentpool_cli-0.1.4}/src/agentpool/usage/ccusage.py +0 -0
  98. {agentpool_cli-0.1.3 → agentpool_cli-0.1.4}/src/agentpool/usage/claude.py +0 -0
  99. {agentpool_cli-0.1.3 → agentpool_cli-0.1.4}/src/agentpool/usage/codex.py +0 -0
  100. {agentpool_cli-0.1.3 → agentpool_cli-0.1.4}/src/agentpool/usage/codexbar.py +0 -0
  101. {agentpool_cli-0.1.3 → agentpool_cli-0.1.4}/src/agentpool/usage/combine.py +0 -0
  102. {agentpool_cli-0.1.3 → agentpool_cli-0.1.4}/src/agentpool/usage/copilot.py +0 -0
  103. {agentpool_cli-0.1.3 → agentpool_cli-0.1.4}/src/agentpool/usage/parsers.py +0 -0
  104. {agentpool_cli-0.1.3 → agentpool_cli-0.1.4}/src/agentpool/usage/probes.py +0 -0
  105. {agentpool_cli-0.1.3 → agentpool_cli-0.1.4}/src/agentpool/usage/provider_parsers.py +0 -0
  106. {agentpool_cli-0.1.3 → agentpool_cli-0.1.4}/src/agentpool/usage/summary.py +0 -0
  107. {agentpool_cli-0.1.3 → agentpool_cli-0.1.4}/src/agentpool/utils.py +0 -0
  108. {agentpool_cli-0.1.3 → agentpool_cli-0.1.4}/tests/fixtures/provider_model_catalog_golden.json +0 -0
  109. {agentpool_cli-0.1.3 → agentpool_cli-0.1.4}/tests/fixtures/stats_seed.py +0 -0
  110. {agentpool_cli-0.1.3 → agentpool_cli-0.1.4}/tests/fixtures/usage/claude_usage.txt +0 -0
  111. {agentpool_cli-0.1.3 → agentpool_cli-0.1.4}/tests/fixtures/usage/codex_rate_limits.json +0 -0
  112. {agentpool_cli-0.1.3 → agentpool_cli-0.1.4}/tests/fixtures/usage/copilot_user.json +0 -0
  113. {agentpool_cli-0.1.3 → agentpool_cli-0.1.4}/tests/fixtures/usage/devin_plan_status.json +0 -0
  114. {agentpool_cli-0.1.3 → agentpool_cli-0.1.4}/tests/integration/test_fake_tmux_flow.py +0 -0
  115. {agentpool_cli-0.1.3 → agentpool_cli-0.1.4}/tests/unit/test_agent_io.py +0 -0
  116. {agentpool_cli-0.1.3 → agentpool_cli-0.1.4}/tests/unit/test_event_policy.py +0 -0
  117. {agentpool_cli-0.1.3 → agentpool_cli-0.1.4}/tests/unit/test_redaction.py +0 -0
  118. {agentpool_cli-0.1.3 → agentpool_cli-0.1.4}/tests/unit/test_stats_cli.py +0 -0
  119. {agentpool_cli-0.1.3 → agentpool_cli-0.1.4}/tests/unit/test_stats_window.py +0 -0
  120. {agentpool_cli-0.1.3 → agentpool_cli-0.1.4}/tests/unit/test_usage_provider_parsers.py +0 -0
  121. {agentpool_cli-0.1.3 → agentpool_cli-0.1.4}/tests/unit/test_usage_summary_enrichment.py +0 -0
@@ -2,6 +2,17 @@
2
2
 
3
3
  ## Unreleased
4
4
 
5
+ ## 0.1.4 - 2026-05-31
6
+
7
+ - Add Markdown delegation preferences at `~/.agentpool/preferences.md`, surfaced
8
+ through the CLI, MCP tools, MCP resources, inventory, usage summaries, model
9
+ listings, and spawn responses so agents can read one user-owned preference
10
+ source before choosing whether and how to use AgentPool.
11
+ - Bound live MCP usage refreshes so slow provider probes return partial data
12
+ instead of hanging the host session.
13
+ - Remove deprecated `gemini-cli` from the default provider set after Google's
14
+ transition to Antigravity CLI.
15
+
5
16
  ## 0.1.3 - 2026-05-29
6
17
 
7
18
  - Reposition docs and descriptions around the primary value: making full use of
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: agentpool-cli
3
- Version: 0.1.3
3
+ Version: 0.1.4
4
4
  Summary: Make full use of every coding-agent subscription you pay for: a local CLI + MCP server that surfaces live usage limits and offloads work to providers with headroom.
5
5
  Author: AgentPool contributors
6
6
  License-Expression: MIT
@@ -23,8 +23,8 @@ Description-Content-Type: text/markdown
23
23
  <!-- mcp-name: io.github.sidduHERE/agentpool -->
24
24
 
25
25
  You pay for several coding-agent subscriptions — Codex, Claude Code, Cursor,
26
- Copilot, Gemini — but you work in one at a time. The rest sit idle until your
27
- active provider hits its 5-hour or weekly limit, and then you stall.
26
+ Copilot, Devin, Droid — but you work in one at a time. The rest sit idle until
27
+ your active provider hits its 5-hour or weekly limit, and then you stall.
28
28
 
29
29
  AgentPool is a local Python CLI and MCP server that reads the live usage limits
30
30
  of every coding-agent subscription you have and lets you — or your primary
@@ -178,6 +178,9 @@ and the opt-in `get_usage_summary` tool.
178
178
  The default buffer is `policy.min_remaining_percent = 10`. If any reported
179
179
  quota window is below that buffer, the provider row is marked unusable for the
180
180
  summary. AgentPool still does not pick an alternative provider for you.
181
+ MCP usage refreshes are intentionally bounded and may return `partial=true`;
182
+ use the CLI commands above when a shell-capable agent needs a complete live
183
+ refresh.
181
184
 
182
185
  ## Provider Matrix
183
186
 
@@ -289,11 +292,15 @@ MCP-connected agents should read these once on connect:
289
292
 
290
293
  - `agentpool://onboarding`
291
294
  - `agentpool://skill.md`
292
-
293
- Then use tools for live operations. The default MCP toolset is deliberately
294
- small: inventory, usage snapshot, provider models, spawn, observe, send,
295
- interrupt, collect, artifact manifest, transcript paging, and terminate. Add
296
- opt-in toolsets with `agentpool mcp --toolsets default,stats,sessions,leases,worktrees`.
295
+ - `agentpool://preferences.md`
296
+
297
+ Then use tools for live operations. The user-owned preferences file also shows
298
+ up through `agentpool preferences` and `get_delegation_preferences()`. It may
299
+ say to use your native subagent system instead of AgentPool for some tasks. The
300
+ default MCP toolset is deliberately small: inventory, usage snapshot, usage
301
+ summary, provider models, preferences, spawn, observe, send, interrupt,
302
+ collect, artifact manifest, transcript paging, and terminate. Add opt-in
303
+ toolsets with `agentpool mcp --toolsets default,stats,sessions,leases,worktrees`.
297
304
 
298
305
  Coding agents with shell access should prefer the CLI path. It is more
299
306
  token-efficient because large worker output stays in artifact files and
@@ -3,8 +3,8 @@
3
3
  <!-- mcp-name: io.github.sidduHERE/agentpool -->
4
4
 
5
5
  You pay for several coding-agent subscriptions — Codex, Claude Code, Cursor,
6
- Copilot, Gemini — but you work in one at a time. The rest sit idle until your
7
- active provider hits its 5-hour or weekly limit, and then you stall.
6
+ Copilot, Devin, Droid — but you work in one at a time. The rest sit idle until
7
+ your active provider hits its 5-hour or weekly limit, and then you stall.
8
8
 
9
9
  AgentPool is a local Python CLI and MCP server that reads the live usage limits
10
10
  of every coding-agent subscription you have and lets you — or your primary
@@ -158,6 +158,9 @@ and the opt-in `get_usage_summary` tool.
158
158
  The default buffer is `policy.min_remaining_percent = 10`. If any reported
159
159
  quota window is below that buffer, the provider row is marked unusable for the
160
160
  summary. AgentPool still does not pick an alternative provider for you.
161
+ MCP usage refreshes are intentionally bounded and may return `partial=true`;
162
+ use the CLI commands above when a shell-capable agent needs a complete live
163
+ refresh.
161
164
 
162
165
  ## Provider Matrix
163
166
 
@@ -269,11 +272,15 @@ MCP-connected agents should read these once on connect:
269
272
 
270
273
  - `agentpool://onboarding`
271
274
  - `agentpool://skill.md`
272
-
273
- Then use tools for live operations. The default MCP toolset is deliberately
274
- small: inventory, usage snapshot, provider models, spawn, observe, send,
275
- interrupt, collect, artifact manifest, transcript paging, and terminate. Add
276
- opt-in toolsets with `agentpool mcp --toolsets default,stats,sessions,leases,worktrees`.
275
+ - `agentpool://preferences.md`
276
+
277
+ Then use tools for live operations. The user-owned preferences file also shows
278
+ up through `agentpool preferences` and `get_delegation_preferences()`. It may
279
+ say to use your native subagent system instead of AgentPool for some tasks. The
280
+ default MCP toolset is deliberately small: inventory, usage snapshot, usage
281
+ summary, provider models, preferences, spawn, observe, send, interrupt,
282
+ collect, artifact manifest, transcript paging, and terminate. Add opt-in
283
+ toolsets with `agentpool mcp --toolsets default,stats,sessions,leases,worktrees`.
277
284
 
278
285
  Coding agents with shell access should prefer the CLI path. It is more
279
286
  token-efficient because large worker output stays in artifact files and
@@ -48,15 +48,18 @@ The default MCP surface is narrow:
48
48
  agentpool mcp
49
49
  ```
50
50
 
51
- It exposes inventory, cached/live usage snapshots, provider models, spawn,
52
- observe, send, interrupt, artifact manifest, transcript paging, collect, and
53
- terminate.
51
+ It exposes inventory, compact usage summaries, cached raw usage snapshots,
52
+ provider models, spawn, observe, send, interrupt, artifact manifest, transcript
53
+ paging, collect, and terminate.
54
+ Explicit MCP refreshes avoid interactive provider TUI probes so a host like
55
+ Claude Code does not accidentally launch a nested Claude `/usage` UI inside
56
+ itself.
54
57
 
55
58
  Opt into more:
56
59
 
57
60
  ```bash
58
61
  agentpool mcp --toolsets default,stats,sessions,leases,worktrees
59
- agentpool mcp --tools get_usage_summary
62
+ agentpool mcp --tools validate_model_catalog
60
63
  AGENTPOOL_MCP_LOCKDOWN=1 agentpool mcp
61
64
  ```
62
65
 
@@ -11,12 +11,21 @@ need to delegate coding-agent work.
11
11
  ## Rules
12
12
 
13
13
  - AgentPool is a control plane, not an auto-router.
14
+ - Read the user's AgentPool preferences before deciding whether to delegate:
15
+ - CLI: `agentpool preferences`
16
+ - MCP: `get_delegation_preferences()` or `agentpool://preferences.md`
17
+ - These preferences may tell you to use your own native subagent system
18
+ instead of AgentPool for some tasks.
14
19
  - Choose provider and model explicitly. Never use `provider=auto`.
15
20
  - Prefer the CLI when you have shell access; use MCP for MCP-native/no-shell hosts.
16
21
  - Run or read usage before delegation:
17
22
  - CLI: `agentpool usage-summary --refresh --json`
18
- - MCP: `get_usage_snapshot(refresh=false)` for cached state, or
19
- `get_usage_snapshot(refresh=true)` for a live refresh.
23
+ - MCP: `get_usage_summary(refresh=false)` for compact cached state. Use
24
+ `get_usage_snapshot` only when you need raw snapshots. Avoid asking MCP to
25
+ run interactive provider TUI probes from inside that same provider's host
26
+ session; run a CLI refresh from a normal shell when you need a complete
27
+ live refresh. MCP `refresh=true` is bounded and can return `partial=true`
28
+ with unknown rows for slow providers.
20
29
  - Treat usage rows as a provider-id map. They are not ordered and not ranked.
21
30
  - Inspect provider models before spawning when the model is not already chosen:
22
31
  - CLI: `agentpool models --provider <provider-id>`
@@ -34,6 +43,7 @@ need to delegate coding-agent work.
34
43
 
35
44
  ```bash
36
45
  agentpool usage-summary --refresh --json
46
+ agentpool preferences
37
47
  agentpool models --provider <provider-id> --json
38
48
  agentpool spawn --provider <provider-id> --model <model-id> --repo . --task "<narrow task>" --isolation read_only --json
39
49
  agentpool observe <session-id> --wait-for completed,error,question,approval_prompt --timeout 120 --json
@@ -58,15 +68,16 @@ without dumping the whole file into context.
58
68
 
59
69
  ## Typical MCP Flow
60
70
 
61
- 1. `get_usage_snapshot(provider_id=..., refresh=false)`
62
- 2. `get_provider_models(provider_id=...)`
63
- 3. `spawn_worker(provider_id=..., model=..., repo_path=..., task=..., isolation="read_only")`
64
- 4. `observe_worker(session_id=..., wait_for=["completed","error","question","approval_prompt"], timeout_seconds=120)`
65
- 5. `send_worker_message(...)` or `interrupt_worker(...)`
66
- 6. `get_artifact_manifest(...)`
67
- 7. `read_worker_transcript(...)` for bounded transcript pages, only if needed
68
- 8. `collect_worker_artifacts(...)`
69
- 9. `terminate_worker(...)`
71
+ 1. `get_delegation_preferences()`
72
+ 2. `get_usage_summary(provider_id=..., refresh=false)`
73
+ 3. `get_provider_models(provider_id=...)`
74
+ 4. `spawn_worker(provider_id=..., model=..., repo_path=..., task=..., isolation="read_only")`
75
+ 5. `observe_worker(session_id=..., wait_for=["completed","error","question","approval_prompt"], timeout_seconds=120)`
76
+ 6. `send_worker_message(...)` or `interrupt_worker(...)`
77
+ 7. `get_artifact_manifest(...)`
78
+ 8. `read_worker_transcript(...)` for bounded transcript pages, only if needed
79
+ 9. `collect_worker_artifacts(...)`
80
+ 10. `terminate_worker(...)`
70
81
 
71
82
  Use opt-in MCP toolsets for extra surfaces:
72
83
 
@@ -10,7 +10,7 @@ Most users should not run that command by hand. Add it to your MCP host config,
10
10
  then let the host start AgentPool when needed.
11
11
 
12
12
  After setup, ask the agent to read `agentpool://skill.md`, then call
13
- `get_usage_snapshot(refresh=false)` and `get_provider_models()` before
13
+ `get_usage_summary(refresh=false)` and `get_provider_models()` before
14
14
  delegating work. Coding agents with shell access should usually prefer the
15
15
  `agentpool` CLI because it keeps large worker output in artifact files.
16
16
 
@@ -257,8 +257,9 @@ Restart Claude Desktop after editing the file.
257
257
  Once connected, a good first prompt is:
258
258
 
259
259
  ```text
260
- Read agentpool://skill.md. Then call
261
- get_usage_snapshot(refresh=false), get_provider_models(), and get_inventory() before
260
+ Read agentpool://skill.md and agentpool://preferences.md. Then call
261
+ get_delegation_preferences(), get_usage_summary(refresh=false),
262
+ get_provider_models(), and get_inventory() before
262
263
  spawning any workers. After spawn_worker, use observe_worker for the worker
263
264
  control loop; do not poll get_session/list_sessions as a substitute. Use
264
265
  read_worker_transcript with offset/limit only when you need bounded transcript
@@ -31,8 +31,10 @@ Unknown toolsets or tool names fail at server startup.
31
31
  The default toolset is the smallest worker lifecycle surface:
32
32
 
33
33
  - `get_inventory`
34
+ - `get_usage_summary`
34
35
  - `get_usage_snapshot`
35
36
  - `get_provider_models`
37
+ - `get_delegation_preferences`
36
38
  - `spawn_worker`
37
39
  - `observe_worker`
38
40
  - `send_worker_message`
@@ -48,13 +50,19 @@ Removed MCP aliases:
48
50
  - `get_capacity_summary`
49
51
  - `get_cached_usage_snapshot`
50
52
 
51
- Use `get_usage_snapshot(refresh=false)` for cached snapshots. Use the `usage`
52
- toolset if you need `get_usage_summary`, `validate_model_catalog`, or
53
+ Use `get_usage_summary(refresh=false)` for the compact provider-capacity view.
54
+ Use `get_usage_snapshot(refresh=false)` only when you need raw snapshots; cached
55
+ mode is the default for both. MCP refreshes intentionally avoid interactive
56
+ provider TUI probes that could interfere with the host agent session. Live MCP
57
+ refreshes are also time bounded; a slow provider returns an unknown row and the
58
+ response sets `partial=true` instead of letting the MCP connection sit open.
59
+ Use the CLI for a complete live refresh from shell-capable coding agents. Use
60
+ the `usage` toolset if you need `validate_model_catalog` or
53
61
  `filter_candidates`.
54
62
 
55
63
  ## Opt-In Toolsets
56
64
 
57
- - `usage`: `get_usage_summary`, `validate_model_catalog`, `filter_candidates`
65
+ - `usage`: `validate_model_catalog`, `filter_candidates`
58
66
  - `stats`: `get_stats`, `get_stats_card`
59
67
  - `sessions`: `list_sessions`, `get_session`, `attach_info`, `send_worker_keys`
60
68
  - `leases`: `acquire_file_lease`, `list_file_leases`, `release_file_lease`
@@ -73,7 +81,7 @@ metadata lookups, not substitutes for observation.
73
81
 
74
82
  Recommended loop:
75
83
 
76
- 1. `get_usage_snapshot(provider_id=..., refresh=false)`
84
+ 1. `get_usage_summary(provider_id=..., refresh=false)`
77
85
  2. `get_provider_models(provider_id=...)`
78
86
  3. `spawn_worker(provider_id=..., model=..., repo_path=..., task=..., isolation="read_only")`
79
87
  4. `observe_worker(session_id=..., wait_for=["completed","error","question","approval_prompt"], timeout_seconds=120)`
@@ -123,6 +131,7 @@ The default resource set is non-duplicative:
123
131
 
124
132
  - `agentpool://onboarding`
125
133
  - `agentpool://skill.md`
134
+ - `agentpool://preferences.md`
126
135
  - `agentpool://sessions/{session_id}/transcript`
127
136
  - `agentpool://sessions/{session_id}/events`
128
137
  - `agentpool://artifacts/{session_id}`
@@ -2,8 +2,9 @@
2
2
 
3
3
  AgentPool helps you use every coding-agent subscription you pay for. It reads
4
4
  the live usage limits of each provider you have (Codex, Claude Code, Cursor,
5
- Copilot, Gemini, ...) so you can offload work to whichever still has headroom
6
- instead of stalling when your active subscription hits its 5-hour or weekly cap.
5
+ Copilot, Devin, Droid, ...) so you can offload work to whichever still has
6
+ headroom instead of stalling when your active subscription hits its 5-hour or
7
+ weekly cap.
7
8
  It is a control plane for explicitly selected coding-agent CLIs: it does not
8
9
  route automatically and it does not choose a provider for you.
9
10
 
@@ -20,6 +21,7 @@ uv pip install -e ".[dev]"
20
21
 
21
22
  ```bash
22
23
  agentpool init
24
+ agentpool preferences
23
25
  agentpool setup cursor
24
26
  agentpool config validate
25
27
  agentpool doctor --deep --privacy
@@ -146,6 +148,7 @@ resource is missing from their context:
146
148
 
147
149
  - `agentpool://onboarding`
148
150
  - `agentpool://skill.md`
151
+ - `agentpool://preferences.md`
149
152
  - `agentpool://sessions/{session_id}/transcript`
150
153
  - `agentpool://sessions/{session_id}/events`
151
154
  - `agentpool://artifacts/{session_id}`
@@ -156,18 +159,20 @@ the CLI because it keeps transcripts and artifacts on disk until explicitly read
156
159
 
157
160
  ## Agent Operating Loop
158
161
 
159
- 1. Read usage and model state (`agentpool usage-summary --json`, `agentpool models --json`, or the matching MCP tools).
160
- 2. Pick the provider explicitly.
161
- 3. Use `read_only` for exploration and choose `worktree` explicitly only when
162
+ 1. Read the user's preferences (`agentpool preferences`, `get_delegation_preferences()`, or `agentpool://preferences.md`).
163
+ 2. Read usage and model state (`agentpool usage-summary --json`, `agentpool models --json`, or the matching MCP tools).
164
+ 3. Decide whether AgentPool is appropriate, or whether your own native subagent system is better for this task.
165
+ 4. Pick the provider explicitly.
166
+ 5. Use `read_only` for exploration and choose `worktree` explicitly only when
162
167
  AgentPool should create an isolated worktree.
163
- 4. Spawn one narrow worker.
164
- 5. Observe until question, approval, completion, error, or timeout.
165
- 6. Send steering or interrupt deliberately.
166
- 7. Use advisory file leases when multiple workers may touch the same files.
167
- 8. Read bounded transcript pages only when the manifest/summary is not enough.
168
- 9. Use paginated `sessions` / `list_sessions` reads for fleet metadata.
169
- 10. Read the artifact manifest, then collect artifacts.
170
- 11. Terminate sessions when done.
168
+ 6. Spawn one narrow worker.
169
+ 7. Observe until question, approval, completion, error, or timeout.
170
+ 8. Send steering or interrupt deliberately.
171
+ 9. Use advisory file leases when multiple workers may touch the same files.
172
+ 10. Read bounded transcript pages only when the manifest/summary is not enough.
173
+ 11. Use paginated `sessions` / `list_sessions` reads for fleet metadata.
174
+ 12. Read the artifact manifest, then collect artifacts.
175
+ 13. Terminate sessions when done.
171
176
 
172
177
  AgentPool never merges, pushes, silently accepts overage, stores provider
173
178
  credentials, scrapes browser pages, or ranks providers.
@@ -54,4 +54,5 @@ Use `--isolation worktree` instead of `read_only` for tasks that edit files.
54
54
 
55
55
  - Full agent guidance: `agentpool://skill.md`
56
56
  - Setup and privacy detail: `agentpool://onboarding`
57
+ - User delegation preferences: `agentpool://preferences.md`
57
58
  - MCP host config: `agentpool mcp-config --client <host> --absolute-command --install`
@@ -98,7 +98,7 @@ Then ask Codex:
98
98
 
99
99
  ```text
100
100
  Read agentpool://skill.md. Then call
101
- get_usage_snapshot(provider_id="codex-cli", refresh=false),
101
+ get_usage_summary(provider_id="codex-cli", refresh=false),
102
102
  get_provider_models(provider_id="codex-cli"), and get_inventory before spawning
103
103
  any workers. After spawn_worker, use
104
104
  observe_worker for the worker control loop. If Codex shows an update prompt,
@@ -47,5 +47,5 @@ See [docs/mcp-clients.md](mcp-clients.md) for other hosts.
47
47
  ## After Connect
48
48
 
49
49
  Ask Cursor to read `agentpool://skill.md`, then call
50
- `get_usage_snapshot(refresh=false)` and `get_provider_models()` before spawning
50
+ `get_usage_summary(refresh=false)` and `get_provider_models()` before spawning
51
51
  workers.
@@ -4,7 +4,7 @@ Usage is best effort and confidence-tagged. Unknown is valid.
4
4
 
5
5
  Allowed confidence values include `official`, `local_cli`, `local_config`, `provider_warning`, `observed`, `user_configured`, and `unknown`. AgentPool does not fabricate exact quotas and does not scrape browser sessions in v0.1.
6
6
 
7
- Live probes are only run by explicit usage requests. Inventory remains non-invasive and reports whether a provider supports an explicit usage probe. Successful explicit probes are persisted to SQLite; `agentpool usage --cached` and `get_usage_snapshot(refresh=false)` read the latest persisted snapshots without refreshing providers.
7
+ Live probes are only run by explicit usage requests. Inventory remains non-invasive and reports whether a provider supports an explicit usage probe. Successful explicit probes are persisted to SQLite; `agentpool usage --cached`, `get_usage_summary(refresh=false)`, and `get_usage_snapshot(refresh=false)` read the latest persisted snapshots without refreshing providers. MCP refreshes do not run interactive provider TUI probes, because those can interfere with the host agent that is calling AgentPool. MCP refreshes are also bounded by a short server-side budget; if a provider is slow, AgentPool returns a partial response with an unknown row instead of holding the MCP connection open.
8
8
 
9
9
  `agentpool usage-summary` returns a `providers` map keyed by provider id. The
10
10
  CLI `capacity-summary` command is a human convenience alias; MCP does not expose
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "agentpool-cli"
7
- version = "0.1.3"
7
+ version = "0.1.4"
8
8
  description = "Make full use of every coding-agent subscription you pay for: a local CLI + MCP server that surfaces live usage limits and offloads work to providers with headroom."
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.11"
@@ -2,8 +2,8 @@
2
2
  "$schema": "https://static.modelcontextprotocol.io/schemas/2025-12-11/server.schema.json",
3
3
  "name": "io.github.sidduHERE/agentpool",
4
4
  "title": "AgentPool",
5
- "description": "See live usage limits across your coding-agent subscriptions and offload work to a provider with headroom. Local-first, explicit selection, no auto-routing.",
6
- "version": "0.1.3",
5
+ "description": "See each coding-agent subscription's live limits and offload work to one with headroom.",
6
+ "version": "0.1.4",
7
7
  "repository": {
8
8
  "url": "https://github.com/sidduHERE/agentpool",
9
9
  "source": "github"
@@ -13,7 +13,7 @@
13
13
  {
14
14
  "registryType": "pypi",
15
15
  "identifier": "agentpool-cli",
16
- "version": "0.1.3",
16
+ "version": "0.1.4",
17
17
  "transport": {
18
18
  "type": "stdio"
19
19
  },
@@ -1,3 +1,3 @@
1
1
  """AgentPool local agent control plane."""
2
2
 
3
- __version__ = "0.1.3"
3
+ __version__ = "0.1.4"
@@ -36,6 +36,7 @@ from agentpool.onboarding import (
36
36
  setup_all_providers,
37
37
  setup_provider,
38
38
  )
39
+ from agentpool.preferences import PREFERENCES_PATH, ensure_preferences_file, preferences_payload
39
40
  from agentpool.mcp import tools as mcp_tools
40
41
  from agentpool.session_manager import SessionManager
41
42
  from agentpool.stats.card import render_stats_card
@@ -191,6 +192,10 @@ def init_command(
191
192
  return
192
193
  status = "wrote" if data["changed"] else "exists"
193
194
  console.print(f"config {status}: {data['config_path']}")
195
+ preferences = data.get("preferences") or {}
196
+ if preferences:
197
+ preferences_status = "wrote" if preferences.get("changed") else "exists"
198
+ console.print(f"preferences {preferences_status}: {preferences['path']}")
194
199
  if data.get("backup_path"):
195
200
  console.print(f"backup: {data['backup_path']}")
196
201
  console.print("next:")
@@ -264,6 +269,7 @@ def inventory(json_output: Annotated[bool, typer.Option("--json", help="Emit JSO
264
269
  provider["usage"]["status"] if provider.get("usage") else "unknown",
265
270
  )
266
271
  console.print(table)
272
+ console.print(f"preferences: {data['preferences']['path']}")
267
273
 
268
274
 
269
275
  @app.command(help="Show a provider usage snapshot (cached or freshly probed).")
@@ -316,6 +322,7 @@ def usage_summary(
316
322
  )
317
323
  console.print(f"source: {data['source']}")
318
324
  console.print(table)
325
+ console.print(f"preferences: {data['preferences']['path']}")
319
326
  except ToolError as exc:
320
327
  handle_tool_error(exc, json_output)
321
328
 
@@ -441,6 +448,7 @@ def onboard(json_output: Annotated[bool, typer.Option("--json", help="Emit JSON.
441
448
  "config_path": str(DEFAULT_CONFIG_PATH),
442
449
  "db_path": str(mgr.config.storage.db),
443
450
  "artifact_root": str(mgr.config.storage.artifacts),
451
+ "preferences": preferences_payload(include_text=False),
444
452
  "usage_backends": {
445
453
  "default": "combined",
446
454
  "available": ["native", "codexbar", "ccusage", "combined"],
@@ -459,6 +467,7 @@ def onboard(json_output: Annotated[bool, typer.Option("--json", help="Emit JSON.
459
467
  "mcp_resources": [
460
468
  "agentpool://onboarding",
461
469
  "agentpool://skill.md",
470
+ "agentpool://preferences.md",
462
471
  "agentpool://sessions/{session_id}/transcript",
463
472
  "agentpool://sessions/{session_id}/events",
464
473
  "agentpool://artifacts/{session_id}",
@@ -480,6 +489,7 @@ def onboard(json_output: Annotated[bool, typer.Option("--json", help="Emit JSON.
480
489
  console.print(f"config: {data['config_path']}")
481
490
  console.print(f"db: {data['db_path']}")
482
491
  console.print(f"artifacts: {data['artifact_root']}")
492
+ console.print(f"preferences: {data['preferences']['path']}")
483
493
  codexbar = data["usage_backends"]["codexbar"]
484
494
  console.print(f"codexbar: {'installed' if codexbar['installed'] else 'not installed'}")
485
495
  console.print("\nFirst commands:")
@@ -492,6 +502,61 @@ def onboard(json_output: Annotated[bool, typer.Option("--json", help="Emit JSON.
492
502
  console.print_json(json.dumps(data["mcp_host_config"]))
493
503
 
494
504
 
505
+ @app.command("preferences", help="Show or initialize the user-owned AgentPool preferences file.")
506
+ def preferences_command(
507
+ action: Annotated[
508
+ str,
509
+ typer.Argument(help="Action: show, init, or path."),
510
+ ] = "show",
511
+ path: Annotated[
512
+ Path,
513
+ typer.Option("--path", help="Preferences path. Defaults to ~/.agentpool/preferences.md."),
514
+ ] = PREFERENCES_PATH,
515
+ force: Annotated[bool, typer.Option("--force", help="Back up and overwrite during init.")] = False,
516
+ json_output: Annotated[bool, typer.Option("--json", help="Emit JSON.")] = False,
517
+ ) -> None:
518
+ """Show or create the Markdown preferences agents should read before delegation.
519
+
520
+ Examples:
521
+ agentpool preferences
522
+ agentpool preferences init
523
+ agentpool preferences --json
524
+ agentpool preferences path
525
+ """
526
+ action = action.strip().lower()
527
+ if action == "path":
528
+ data = {"path": str(path.expanduser()), "resource_uri": "agentpool://preferences.md"}
529
+ if json_output:
530
+ console.print_json(json.dumps(data, default=str))
531
+ else:
532
+ console.print(data["path"])
533
+ return
534
+ if action == "init":
535
+ data = ensure_preferences_file(path, force=force)
536
+ elif action == "show":
537
+ data = preferences_payload(path, include_text=True)
538
+ else:
539
+ handle_tool_error(
540
+ ToolError(
541
+ "INVALID_REQUEST",
542
+ "Preferences action must be one of: show, init, path.",
543
+ {"example": "agentpool preferences init"},
544
+ ),
545
+ json_output,
546
+ )
547
+ return
548
+ if json_output:
549
+ console.print_json(json.dumps(data, default=str))
550
+ return
551
+ if action == "init":
552
+ status = "wrote" if data["changed"] else "exists"
553
+ console.print(f"preferences {status}: {data['path']}")
554
+ if data.get("backup_path"):
555
+ console.print(f"backup: {data['backup_path']}")
556
+ return
557
+ console.print(data["text"], end="" if str(data["text"]).endswith("\n") else "\n")
558
+
559
+
495
560
  @app.command()
496
561
  def smoke(
497
562
  provider: Annotated[str, typer.Option("--provider", help="Provider id to smoke test.")] = "fake-question",
@@ -542,10 +607,16 @@ def smoke(
542
607
  def providers(json_output: Annotated[bool, typer.Option("--json", help="Emit JSON.")] = False) -> None:
543
608
  data = manager().inventory(include_usage=False)
544
609
  if json_output:
545
- console.print_json(json.dumps({"providers": data["providers"]}, default=str))
610
+ console.print_json(
611
+ json.dumps(
612
+ {"providers": data["providers"], "preferences": data["preferences"]},
613
+ default=str,
614
+ )
615
+ )
546
616
  else:
547
617
  for provider in data["providers"]:
548
618
  console.print(provider["id"])
619
+ console.print(f"preferences: {data['preferences']['path']}")
549
620
 
550
621
 
551
622
  @app.command("models", help="List the model catalog, or validate it with 'models validate'.")
@@ -580,9 +651,10 @@ def models_command(
580
651
  if not data["ok"]:
581
652
  raise typer.Exit(1)
582
653
  return
583
- rows = mgr.provider_models(provider)["providers"]
654
+ data = mgr.provider_models(provider)
655
+ rows = data["providers"]
584
656
  if json_output:
585
- console.print_json(json.dumps({"providers": rows}, default=str))
657
+ console.print_json(json.dumps(data, default=str))
586
658
  return
587
659
  if provider:
588
660
  row = rows[0]
@@ -609,6 +681,7 @@ def models_command(
609
681
  reasoning_text,
610
682
  )
611
683
  console.print(table)
684
+ console.print(f"preferences: {data['preferences']['path']}")
612
685
  return
613
686
  table = Table("Provider", "Default", "Smoke", "Selection", "Models", "Catalog")
614
687
  for row in rows:
@@ -621,6 +694,7 @@ def models_command(
621
694
  str(row["catalog_completeness"] or ""),
622
695
  )
623
696
  console.print(table)
697
+ console.print(f"preferences: {data['preferences']['path']}")
624
698
 
625
699
 
626
700
  @app.command()
@@ -853,6 +927,7 @@ def spawn(
853
927
  else:
854
928
  console.print(data["session"]["id"])
855
929
  console.print(data["attach_command"])
930
+ console.print(f"preferences: {data['preferences']['path']}")
856
931
  except ToolError as exc:
857
932
  handle_tool_error(exc, json_output)
858
933
 
@@ -16,6 +16,12 @@ from agentpool.utils import expand_user_path
16
16
  DEFAULT_CONFIG_PATH = Path("~/.agentpool/config.yaml").expanduser()
17
17
  DEFAULT_MODEL_CATALOG_PATH = Path(__file__).with_name("provider_model_catalog.json")
18
18
  FAKE_AGENT_DIR = Path(__file__).with_name("fixtures") / "fake_agents"
19
+ DEPRECATED_PROVIDER_IDS = {
20
+ "gemini-cli": (
21
+ "Gemini CLI has transitioned to Antigravity CLI; "
22
+ "AgentPool no longer exposes it as a supported provider."
23
+ ),
24
+ }
19
25
  FAKE_PROVIDER_SCRIPTS = {
20
26
  "fake-question": "fake_question_agent.py",
21
27
  "fake-approval": "fake_approval_agent.py",
@@ -299,6 +305,7 @@ def load_config(path: Path | None = None) -> AgentPoolConfig:
299
305
  _refresh_provider_models_from_catalog(merged_config.providers, load_model_catalog(model_catalog_paths))
300
306
  merged = merged_config.model_dump(mode="json")
301
307
  _repair_packaged_fake_provider_paths(merged)
308
+ _drop_deprecated_providers(merged)
302
309
  return AgentPoolConfig.model_validate(merged)
303
310
 
304
311
 
@@ -321,6 +328,9 @@ def validate_config(config: AgentPoolConfig) -> dict[str, Any]:
321
328
  errors.append("providers.auto is not allowed")
322
329
  if "factory-droid" in config.providers:
323
330
  warnings.append("factory-droid is a PRD compatibility name; use droid-cli for the droid binary")
331
+ for provider_id, reason in DEPRECATED_PROVIDER_IDS.items():
332
+ if provider_id in config.providers:
333
+ warnings.append(f"{provider_id} is deprecated and ignored by load_config: {reason}")
324
334
  for provider_id, provider in config.providers.items():
325
335
  if provider.command is not None and not provider.command:
326
336
  errors.append(f"providers.{provider_id}.command must not be empty")
@@ -371,3 +381,11 @@ def _repair_packaged_fake_provider_paths(config: dict[str, Any]) -> None:
371
381
  continue
372
382
  provider["binary_candidates"] = [sys.executable]
373
383
  provider["command"] = [sys.executable, str(FAKE_AGENT_DIR / script)]
384
+
385
+
386
+ def _drop_deprecated_providers(config: dict[str, Any]) -> None:
387
+ providers = config.get("providers")
388
+ if not isinstance(providers, dict):
389
+ return
390
+ for provider_id in DEPRECATED_PROVIDER_IDS:
391
+ providers.pop(provider_id, None)
@@ -6,6 +6,7 @@ from pathlib import Path
6
6
  from typing import Any
7
7
 
8
8
  from agentpool.agent_io import compact_artifact_manifest, lockdown_resource, omitted_worker_output, wrap_untrusted
9
+ from agentpool.preferences import read_preferences_text
9
10
  from agentpool.session_manager import SessionManager
10
11
 
11
12
  PROJECT_ROOT = Path(__file__).resolve().parents[3]
@@ -18,6 +19,8 @@ def read_resource(manager: SessionManager, uri: str, lockdown: bool = False) ->
18
19
  return _text_resource("onboarding.md")
19
20
  if uri == "agentpool://skill.md":
20
21
  return _text_resource("agentpool-skill.md")
22
+ if uri == "agentpool://preferences.md":
23
+ return read_preferences_text()
21
24
  prefix = "agentpool://sessions/"
22
25
  if uri.startswith(prefix):
23
26
  tail = uri[len(prefix) :]