agent-planner-mcp 0.9.0 → 1.0.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/AGENT_GUIDE.md +73 -10
- package/README.md +52 -50
- package/SKILL.md +155 -16
- package/package.json +1 -1
- package/src/tools/bdi/desires.js +104 -3
- package/src/tools/bdi/intentions.js +1107 -15
package/AGENT_GUIDE.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
# AgentPlanner Quick Reference (
|
|
1
|
+
# AgentPlanner Quick Reference (v1.0.0)
|
|
2
2
|
|
|
3
|
-
Tight cheat sheet for AI agents. Full docs: [SKILL.md](SKILL.md). Migration
|
|
3
|
+
Tight cheat sheet for AI agents. Full docs: [SKILL.md](SKILL.md). Migration history: [docs/MIGRATION_v0.9.md](docs/MIGRATION_v0.9.md), [docs/MIGRATION_v1.0.md](docs/MIGRATION_v1.0.md).
|
|
4
4
|
|
|
5
5
|
## Start here
|
|
6
6
|
|
|
@@ -9,7 +9,7 @@ get_started()
|
|
|
9
9
|
// → Returns the BDI tool surface map and recommended workflows
|
|
10
10
|
```
|
|
11
11
|
|
|
12
|
-
## The
|
|
12
|
+
## The 24 tools
|
|
13
13
|
|
|
14
14
|
### Beliefs (read state)
|
|
15
15
|
| Tool | When |
|
|
@@ -26,24 +26,66 @@ get_started()
|
|
|
26
26
|
|---|---|
|
|
27
27
|
| `list_goals` | Goal list with health summary |
|
|
28
28
|
| `update_goal` | Atomic goal change (subsumes link/unlink/achievers) |
|
|
29
|
+
| `derive_subgoal` | Propose a sub-goal under an existing parent (top-level goals stay UI-only) |
|
|
29
30
|
|
|
30
|
-
### Intentions
|
|
31
|
+
### Intentions — execution
|
|
31
32
|
| Tool | When |
|
|
32
33
|
|---|---|
|
|
33
34
|
| `claim_next_task` | Pick + claim + load context (one call) |
|
|
34
35
|
| `update_task` | Atomic status+log+release+learning |
|
|
35
36
|
| `release_task` | Explicit handoff |
|
|
36
|
-
| `queue_decision` | Escalate to human |
|
|
37
|
+
| `queue_decision` | Escalate to human (real decision queue) |
|
|
37
38
|
| `resolve_decision` | Pick up human's answer |
|
|
38
39
|
| `add_learning` | Write to knowledge graph |
|
|
39
40
|
|
|
40
|
-
|
|
41
|
+
### Intentions — creation (v1.0)
|
|
42
|
+
| Tool | When |
|
|
43
|
+
|---|---|
|
|
44
|
+
| `form_intention` | Create plan + initial tree under a goal, atomically |
|
|
45
|
+
| `extend_intention` | Add children under existing parent (lightweight, no queue) |
|
|
46
|
+
| `propose_research_chain` | RPI triple with 2 blocking edges in one call |
|
|
47
|
+
|
|
48
|
+
### Intentions — structural mutation (v1.0)
|
|
49
|
+
| Tool | When |
|
|
50
|
+
|---|---|
|
|
51
|
+
| `update_plan` | Edit plan title/description/status/visibility/metadata |
|
|
52
|
+
| `update_node` | Edit any node property except status |
|
|
53
|
+
| `move_node` | Reparent within plan; cycle-safe |
|
|
54
|
+
| `link_intentions` | Create dependency edge between two tasks |
|
|
55
|
+
| `unlink_intentions` | Remove a dependency edge |
|
|
56
|
+
| `delete_plan` | Soft-delete via status='archived' |
|
|
57
|
+
| `delete_node` | Soft-delete via status='archived' |
|
|
58
|
+
|
|
59
|
+
### Intentions — sharing & collaboration (v1.0)
|
|
60
|
+
| Tool | When |
|
|
61
|
+
|---|---|
|
|
62
|
+
| `share_plan` | Atomic visibility change + add/remove collaborators |
|
|
63
|
+
| `invite_member` | Add user to organization |
|
|
64
|
+
| `update_member_role` | Owner-only role change |
|
|
65
|
+
| `remove_member` | Owner/admin removes non-owner member |
|
|
66
|
+
|
|
67
|
+
## status='active' vs status='draft' (v1.0)
|
|
68
|
+
|
|
69
|
+
The single most important decision when calling a creation tool.
|
|
70
|
+
|
|
71
|
+
| Origin | Default | Why |
|
|
72
|
+
|---|---|---|
|
|
73
|
+
| **Human said so in chat** | `status='active'` (omit) | User already approved by asking. Don't bury their request in drafts. |
|
|
74
|
+
| **You're acting autonomously** | `status='draft'` (pass explicitly) | Let the human review before it activates. Drafts surface in the dashboard pending queue. |
|
|
75
|
+
| **You're uncertain** | use `queue_decision` instead | Drafts are for "I'm proposing structure"; the queue is for "I need an answer." |
|
|
76
|
+
|
|
77
|
+
Drafts auto-promote to active when work begins on any node (transitions to `in_progress`, `completed`, `blocked`, `plan_ready`). Promote explicitly via `update_plan({status: 'active'})` or `update_goal({status: 'active'})`.
|
|
78
|
+
|
|
79
|
+
## Workflow templates
|
|
41
80
|
|
|
42
81
|
### A) Mission control (Cowork autopilot)
|
|
43
82
|
```
|
|
44
83
|
briefing → check goal_health.summary
|
|
45
84
|
→ top_recommendation? act
|
|
46
|
-
→ at_risk goals? goal_state(goal_id)
|
|
85
|
+
→ at_risk goals? goal_state(goal_id)
|
|
86
|
+
→ if you can plan it: derive_subgoal + form_intention (status='draft')
|
|
87
|
+
→ if reversible: update_task or update_goal
|
|
88
|
+
→ if uncertain: queue_decision
|
|
47
89
|
→ add_learning to record
|
|
48
90
|
```
|
|
49
91
|
|
|
@@ -63,22 +105,43 @@ update_task(...) for transitions
|
|
|
63
105
|
release_task(message='handoff') for explicit handover
|
|
64
106
|
```
|
|
65
107
|
|
|
108
|
+
### D) Human-directed restructure (v1.0)
|
|
109
|
+
User: "Rename the launch plan to 'Public Beta', mark it active, and add me as editor on the auth plan."
|
|
110
|
+
```
|
|
111
|
+
update_plan({plan_id: '<launch>', title: 'Public Beta', status: 'active'})
|
|
112
|
+
share_plan({plan_id: '<auth>', add_collaborators: [{user_id: '<user>', role: 'editor'}]})
|
|
113
|
+
```
|
|
114
|
+
No UI required.
|
|
115
|
+
|
|
116
|
+
### E) Autonomous proposal (v1.0)
|
|
117
|
+
You spotted a gap during a scheduled tick.
|
|
118
|
+
```
|
|
119
|
+
derive_subgoal({parent_goal_id, title, rationale, status: 'draft'})
|
|
120
|
+
form_intention({goal_id: <new>, title, rationale, status: 'draft', tree: [...]})
|
|
121
|
+
// Both surface in the dashboard pending queue. Human reviews and either:
|
|
122
|
+
// - tells you "approve them" → update_goal/update_plan({status: 'active'}) for each
|
|
123
|
+
// - tells you "archive" → update_plan({status: 'archived'}) for each
|
|
124
|
+
```
|
|
125
|
+
|
|
66
126
|
## Decision rule
|
|
67
127
|
|
|
68
128
|
When in doubt between act and queue:
|
|
69
|
-
- Reversible local action (status, log, learning) → **act** via `update_task`
|
|
129
|
+
- Reversible local action (status, log, learning, edit, decompose) → **act** via `update_task`, `update_node`, `extend_intention`, `add_learning`
|
|
70
130
|
- External cost, public publish, strategy change, customer comm → **queue** via `queue_decision`
|
|
131
|
+
- Whole new direction or sub-goal you weren't asked for → propose as **draft** via `form_intention` / `derive_subgoal` with `status='draft'`
|
|
71
132
|
|
|
72
|
-
Never use `add_learning(entry_type='decision')` to fake a decision queue. `queue_decision` is
|
|
133
|
+
Never use `add_learning(entry_type='decision')` to fake a decision queue. `queue_decision` is the real tool.
|
|
73
134
|
|
|
74
135
|
## Atomic patterns to remember
|
|
75
136
|
|
|
76
137
|
- `update_task` does status + log + claim release + learning in one call. Don't decompose.
|
|
77
138
|
- `claim_next_task` does suggest + claim + context. Don't decompose.
|
|
78
139
|
- `briefing` does goals + decisions + tasks + activity + recommendation. Don't decompose.
|
|
140
|
+
- `form_intention` creates plan + tree atomically. Don't trickle node-by-node.
|
|
141
|
+
- `share_plan` does visibility + add + remove in one call. Don't fan out.
|
|
79
142
|
|
|
80
143
|
## Output discipline
|
|
81
144
|
|
|
82
145
|
- Every response carries `as_of` — surface this on live artifacts to indicate freshness.
|
|
83
|
-
- Every tool degrades gracefully on partial upstream failure — check `
|
|
146
|
+
- Every tool degrades gracefully on partial upstream failure — check `failures[]` if present.
|
|
84
147
|
- Keep follow-up calls minimal — these tools are designed to bundle.
|
package/README.md
CHANGED
|
@@ -210,59 +210,61 @@ Add the same JSON config to your Cline MCP settings in VS Code.
|
|
|
210
210
|
|
|
211
211
|
## Key Features
|
|
212
212
|
|
|
213
|
-
- **
|
|
214
|
-
- **
|
|
213
|
+
- **24 BDI-aligned tools** for state, goals, and committed actions — no CRUD shapes, every tool answers a whole agentic question
|
|
214
|
+
- **Full mutation surface (v1.0)** — agents and humans-via-agents can manage every plan/node/org property without leaving the conversation; UI is optional inspection
|
|
215
|
+
- **Draft-status seam** — autonomous agent creation lands as drafts surfacing in the dashboard pending queue; human-directed creation defaults to active
|
|
216
|
+
- **Dependency graph** — cycle detection, impact analysis, critical path
|
|
215
217
|
- **Progressive context** — 4-layer context assembly with token budgeting
|
|
216
218
|
- **Knowledge graph** — temporal knowledge via Graphiti (entities, facts, contradictions)
|
|
217
|
-
- **RPI chains** — Research
|
|
218
|
-
- **Goal tracking** — health dashboard, briefings, bottleneck detection
|
|
219
|
+
- **RPI chains** — Research → Plan → Implement task decomposition (one-call shortcut)
|
|
219
220
|
- **Task claims** — TTL-based locking for multi-agent coordination
|
|
220
|
-
- **Organizations** — multi-tenant isolation
|
|
221
|
-
|
|
222
|
-
## Available Tools
|
|
223
|
-
|
|
224
|
-
###
|
|
225
|
-
- `
|
|
226
|
-
- `
|
|
227
|
-
- `
|
|
228
|
-
- `
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
- `
|
|
234
|
-
- `
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
- `
|
|
239
|
-
- `
|
|
240
|
-
- `
|
|
241
|
-
- `
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
- `
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
- `
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
- `
|
|
255
|
-
- `
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
- `
|
|
260
|
-
- `
|
|
261
|
-
- `
|
|
262
|
-
|
|
263
|
-
###
|
|
264
|
-
- `
|
|
265
|
-
|
|
221
|
+
- **Organizations** — multi-tenant isolation with member management
|
|
222
|
+
|
|
223
|
+
## Available Tools (v1.0.0)
|
|
224
|
+
|
|
225
|
+
### Beliefs (read state)
|
|
226
|
+
- `briefing` — bundled mission control state in one call
|
|
227
|
+
- `task_context` — single task at progressive depth 1-4
|
|
228
|
+
- `goal_state` — single goal deep-dive (details + quality + progress + bottlenecks + gaps)
|
|
229
|
+
- `recall_knowledge` — knowledge graph query (facts, entities, episodes, contradictions)
|
|
230
|
+
- `search` — text search across plans/nodes
|
|
231
|
+
- `plan_analysis` — impact, critical path, bottlenecks, coherence
|
|
232
|
+
|
|
233
|
+
### Desires (goals)
|
|
234
|
+
- `list_goals` — goals with health rollup
|
|
235
|
+
- `update_goal` — atomic goal update (subsumes link/unlink/achievers)
|
|
236
|
+
- `derive_subgoal` *(v1.0)* — propose a sub-goal under an existing parent
|
|
237
|
+
|
|
238
|
+
### Intentions — execution
|
|
239
|
+
- `claim_next_task` — pick + claim + load context (one call)
|
|
240
|
+
- `update_task` — atomic status + log + claim release + learning
|
|
241
|
+
- `release_task` — explicit handoff
|
|
242
|
+
- `queue_decision` — escalate to human (real decision queue)
|
|
243
|
+
- `resolve_decision` — pick up human's answer (atomically materializes any `proposed_subtasks`)
|
|
244
|
+
- `add_learning` — record knowledge episode
|
|
245
|
+
|
|
246
|
+
### Intentions — creation *(v1.0)*
|
|
247
|
+
- `form_intention` — create plan + initial tree under a goal, atomically
|
|
248
|
+
- `extend_intention` — add children under an existing parent (lightweight)
|
|
249
|
+
- `propose_research_chain` — RPI triple with 2 blocking edges, in one call
|
|
250
|
+
|
|
251
|
+
### Intentions — structural mutation *(v1.0)*
|
|
252
|
+
- `update_plan` — edit any plan property
|
|
253
|
+
- `update_node` — edit any node property except status
|
|
254
|
+
- `move_node` — reparent within plan; cycle-safe
|
|
255
|
+
- `link_intentions` / `unlink_intentions` — manage dependency edges
|
|
256
|
+
- `delete_plan` / `delete_node` — soft-delete via `status='archived'` (recoverable)
|
|
257
|
+
|
|
258
|
+
### Intentions — sharing & collaboration *(v1.0)*
|
|
259
|
+
- `share_plan` — atomic visibility + add/remove collaborators
|
|
260
|
+
- `invite_member` — add user to org (by user_id or email)
|
|
261
|
+
- `update_member_role` — owner-only role change
|
|
262
|
+
- `remove_member` — owner/admin removes non-owner member
|
|
263
|
+
|
|
264
|
+
### Utility
|
|
265
|
+
- `get_started` — dynamic reference for new agents
|
|
266
|
+
|
|
267
|
+
See [SKILL.md](./SKILL.md) for full descriptions, the human-steering scenarios (A/B/C), and `status='draft'` vs `status='active'` guidance.
|
|
266
268
|
|
|
267
269
|
## LLM Skill Reference
|
|
268
270
|
|
package/SKILL.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: agentplanner
|
|
3
|
-
description: "Agent orchestration skill for AgentPlanner — BDI-aligned tools for state, goals,
|
|
4
|
-
version: 0.
|
|
3
|
+
description: "Agent orchestration skill for AgentPlanner — BDI-aligned tools for state, goals, committed actions, and full mutation surface with human oversight"
|
|
4
|
+
version: 1.0.0
|
|
5
5
|
homepage: https://agentplanner.io
|
|
6
6
|
metadata:
|
|
7
7
|
openclaw:
|
|
@@ -15,7 +15,7 @@ metadata:
|
|
|
15
15
|
|
|
16
16
|
You have access to the AgentPlanner MCP tools. AgentPlanner is a collaborative planning system where you track work, manage dependencies, and coordinate with humans. This document is your complete reference.
|
|
17
17
|
|
|
18
|
-
> **Prerequisite:** This skill requires the `agent-planner-mcp` MCP server (
|
|
18
|
+
> **Prerequisite:** This skill requires the `agent-planner-mcp` MCP server (v1.0.0+) to be connected. Create an API token at Settings → API Tokens on [agentplanner.io](https://agentplanner.io).
|
|
19
19
|
>
|
|
20
20
|
> **Setup by client:**
|
|
21
21
|
> - **Claude Desktop:** Download the [.mcpb](https://github.com/TAgents/agent-planner-mcp/releases/latest), double-click to install
|
|
@@ -23,9 +23,9 @@ You have access to the AgentPlanner MCP tools. AgentPlanner is a collaborative p
|
|
|
23
23
|
> - **Cursor / VS Code:** Add `npx agent-planner-mcp` to your MCP config with env vars `API_URL` and `USER_API_TOKEN`
|
|
24
24
|
> - **ChatGPT:** HTTP endpoint at `https://agentplanner.io/mcp`
|
|
25
25
|
|
|
26
|
-
## The
|
|
26
|
+
## The 24 tools, organized by intent
|
|
27
27
|
|
|
28
|
-
AgentPlanner exposes a **BDI-aligned** surface — Beliefs (state queries), Desires (goal management), Intentions (committed actions). Each tool answers one whole agentic question and returns an `as_of` ISO 8601 timestamp.
|
|
28
|
+
AgentPlanner exposes a **BDI-aligned** surface — Beliefs (state queries), Desires (goal management), Intentions (committed actions). Each tool answers one whole agentic question and returns an `as_of` ISO 8601 timestamp. v1.0.0 completes the mutation surface so humans can steer entirely through agent conversation — no UI required for normal operations.
|
|
29
29
|
|
|
30
30
|
### Beliefs — what is the state of the world?
|
|
31
31
|
|
|
@@ -40,9 +40,11 @@ AgentPlanner exposes a **BDI-aligned** surface — Beliefs (state queries), Desi
|
|
|
40
40
|
|
|
41
41
|
- `list_goals` — goals with health rollup (`{ on_track, at_risk, stale, total }`)
|
|
42
42
|
- `update_goal` — atomic goal update; subsumes link/unlink + achiever changes
|
|
43
|
+
- `derive_subgoal` *(v1.0)* — propose a sub-goal under an existing parent. Top-level goal creation stays UI-only.
|
|
43
44
|
|
|
44
45
|
### Intentions — what am I committing to?
|
|
45
46
|
|
|
47
|
+
**Execution (existing in v0.9):**
|
|
46
48
|
- `claim_next_task` — pick + claim + load context in one call (cornerstone for coding agents)
|
|
47
49
|
- `update_task` — atomic state transition (status + log + claim release + optional learning)
|
|
48
50
|
- `release_task` — explicit handoff
|
|
@@ -50,6 +52,26 @@ AgentPlanner exposes a **BDI-aligned** surface — Beliefs (state queries), Desi
|
|
|
50
52
|
- `resolve_decision` — pick up after human approval/deferral
|
|
51
53
|
- `add_learning` — record a knowledge episode for future recall
|
|
52
54
|
|
|
55
|
+
**Creation (v1.0):**
|
|
56
|
+
- `form_intention` — create a plan + initial phase/task tree under a goal, atomically
|
|
57
|
+
- `extend_intention` — add children under an existing phase or task (lightweight, no decision-queue gate)
|
|
58
|
+
- `propose_research_chain` — Research → Plan → Implement triple with two blocking edges, in one call
|
|
59
|
+
|
|
60
|
+
**Structural mutation (v1.0):**
|
|
61
|
+
- `update_plan` — edit any plan property (title, description, status, visibility, metadata)
|
|
62
|
+
- `update_node` — edit any node property except status (status routes through `update_task`)
|
|
63
|
+
- `move_node` — reparent within the same plan; cycle-safe
|
|
64
|
+
- `link_intentions` — create a dependency edge between two existing tasks
|
|
65
|
+
- `unlink_intentions` — remove a dependency edge by id
|
|
66
|
+
- `delete_plan` — soft-delete via `status='archived'`; recoverable
|
|
67
|
+
- `delete_node` — soft-delete via `status='archived'`
|
|
68
|
+
|
|
69
|
+
**Sharing and collaboration (v1.0):**
|
|
70
|
+
- `share_plan` — atomic visibility change + add/remove collaborators
|
|
71
|
+
- `invite_member` — add user to organization (by user_id or email)
|
|
72
|
+
- `update_member_role` — owner-only role change within an org
|
|
73
|
+
- `remove_member` — owner/admin can remove non-owner members
|
|
74
|
+
|
|
53
75
|
### Utility
|
|
54
76
|
|
|
55
77
|
- `get_started` — dynamic reference; call this if you're new to AgentPlanner
|
|
@@ -94,6 +116,131 @@ The `update_task` call is atomic — status change, log entry, claim release, an
|
|
|
94
116
|
4. release_task(task_id, message='handoff to teammate') for explicit handoff
|
|
95
117
|
```
|
|
96
118
|
|
|
119
|
+
### Peeking before claiming (v0.9.1+)
|
|
120
|
+
|
|
121
|
+
Pass `dry_run: true` to `claim_next_task` to see the candidate without claiming. Useful when an agent wants to inspect the next task and decide whether to take it, without leaving a phantom claim if it bails.
|
|
122
|
+
|
|
123
|
+
```
|
|
124
|
+
claim_next_task({ scope: { plan_id }, dry_run: true })
|
|
125
|
+
// → returns { candidate, source, claim: null, dry_run: true }
|
|
126
|
+
// Then claim for real:
|
|
127
|
+
claim_next_task({ scope: { plan_id } }) // dry_run defaults to false
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
### Proposing subtasks for human approval (v0.9.1+)
|
|
131
|
+
|
|
132
|
+
For high-touch proposals (entire new directions, structural changes the human should review before they materialize), use `queue_decision` with `proposed_subtasks` — tasks only get created on `resolve_decision({action: 'approve'})`.
|
|
133
|
+
|
|
134
|
+
```
|
|
135
|
+
queue_decision({
|
|
136
|
+
plan_id: '<plan>',
|
|
137
|
+
title: 'Approve adding 3 launch tasks?',
|
|
138
|
+
context: 'Found gap in launch goal — no Product Hunt subtasks exist yet',
|
|
139
|
+
smallest_input_needed: 'approve|defer|reject',
|
|
140
|
+
proposed_subtasks: [
|
|
141
|
+
{ parent_id: '<phase-id>', title: 'Draft PH listing copy', node_type: 'task' },
|
|
142
|
+
{ parent_id: '<phase-id>', title: 'Set up PH preview', node_type: 'task' },
|
|
143
|
+
{ parent_id: '<phase-id>', title: 'Schedule launch day', node_type: 'task' }
|
|
144
|
+
]
|
|
145
|
+
})
|
|
146
|
+
// On resolve_decision({ action: 'approve' }), the 3 tasks are atomically created
|
|
147
|
+
// and their IDs returned in created_subtasks[]. Defer/reject does nothing.
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
For routine decomposition (a task you're working on needs subtasks), use `extend_intention` directly — no decision queue, no friction.
|
|
151
|
+
|
|
152
|
+
## The human-steering loop (v1.0)
|
|
153
|
+
|
|
154
|
+
v1.0 closes the creation gap. There are three distinct flows depending on who initiated the action:
|
|
155
|
+
|
|
156
|
+
### Scenario A: Human directs you in conversation
|
|
157
|
+
|
|
158
|
+
User says "create a plan to ship the new auth flow under the security goal" or "mark the BSL launch plan completed."
|
|
159
|
+
|
|
160
|
+
Default to **`status='active'`** — the human asked for it, just do it.
|
|
161
|
+
|
|
162
|
+
```
|
|
163
|
+
form_intention({
|
|
164
|
+
goal_id: '<security-goal-id>',
|
|
165
|
+
title: 'Ship new auth flow',
|
|
166
|
+
rationale: 'User-requested plan to migrate auth to passkeys',
|
|
167
|
+
tree: [
|
|
168
|
+
{ node_type: 'phase', title: 'Discovery', children: [...] },
|
|
169
|
+
{ node_type: 'phase', title: 'Implementation', children: [...] },
|
|
170
|
+
]
|
|
171
|
+
})
|
|
172
|
+
// Plan lands as active. No approval needed — user already approved by asking.
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
```
|
|
176
|
+
update_plan({ plan_id: '<bsl-plan>', status: 'completed' })
|
|
177
|
+
// Done. No queue, no UI trip.
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
### Scenario B: You're acting autonomously (scheduled loop, etc.)
|
|
181
|
+
|
|
182
|
+
No explicit human direction. You decided the workspace needs new structure.
|
|
183
|
+
|
|
184
|
+
Pass **`status='draft'`** — let the human see what you proposed before it activates.
|
|
185
|
+
|
|
186
|
+
```
|
|
187
|
+
derive_subgoal({
|
|
188
|
+
parent_goal_id: '<launch-goal>',
|
|
189
|
+
title: 'First 3 paying customers',
|
|
190
|
+
rationale: 'Goal is at_risk — need a concrete intermediate target before broader push',
|
|
191
|
+
status: 'draft',
|
|
192
|
+
})
|
|
193
|
+
// Surfaces in dashboard pending. Human approves via update_goal({status: 'active'})
|
|
194
|
+
// or in the UI. Plans auto-promote to active when first task moves to in_progress.
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
### Scenario C: You're uncertain and want explicit input
|
|
198
|
+
|
|
199
|
+
Genuine ambiguity. Use `queue_decision`.
|
|
200
|
+
|
|
201
|
+
```
|
|
202
|
+
queue_decision({
|
|
203
|
+
title: 'Two conflicting facts about pricing',
|
|
204
|
+
context: 'Memory says $19/mo Pro tier; recent decision log says $29/mo. Which is current?',
|
|
205
|
+
smallest_input_needed: 'pick one',
|
|
206
|
+
options: [{ label: '$19' }, { label: '$29' }],
|
|
207
|
+
urgency: 'normal',
|
|
208
|
+
})
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
The decision queue is for genuine uncertainty, not as a default gate on everything you do.
|
|
212
|
+
|
|
213
|
+
## Editing structure (v1.0)
|
|
214
|
+
|
|
215
|
+
These are routine — call them whenever needed. No decision-queue ceremony.
|
|
216
|
+
|
|
217
|
+
| Want to... | Call |
|
|
218
|
+
|---|---|
|
|
219
|
+
| Rename a plan | `update_plan({plan_id, title})` |
|
|
220
|
+
| Rename a task | `update_node({node_id, title})` |
|
|
221
|
+
| Edit task instructions | `update_node({node_id, agent_instructions})` |
|
|
222
|
+
| Move a task under a different phase | `move_node({node_id, new_parent_id})` |
|
|
223
|
+
| Express B blocks A | `link_intentions({from_task_id: A, to_task_id: B, relation: 'blocks', rationale: '...'})` |
|
|
224
|
+
| Remove a stale dep | `unlink_intentions({dependency_id, plan_id})` |
|
|
225
|
+
| Archive a plan | `delete_plan({plan_id, reason})` |
|
|
226
|
+
| Archive a task | `delete_node({node_id})` |
|
|
227
|
+
| Restore an archived plan | `update_plan({plan_id, status: 'active', restore: true})` |
|
|
228
|
+
|
|
229
|
+
`delete_*` is soft delete (sets `status='archived'`) — fully recoverable. Hard delete stays REST + admin-only on purpose; agents shouldn't be able to permanently destroy data.
|
|
230
|
+
|
|
231
|
+
## Sharing and collaboration (v1.0)
|
|
232
|
+
|
|
233
|
+
| Want to... | Call |
|
|
234
|
+
|---|---|
|
|
235
|
+
| Make a plan public | `share_plan({plan_id, visibility: 'public'})` |
|
|
236
|
+
| Add a collaborator (by user_id) | `share_plan({plan_id, add_collaborators: [{user_id, role: 'editor'}]})` |
|
|
237
|
+
| Remove a collaborator | `share_plan({plan_id, remove_collaborators: [user_id]})` |
|
|
238
|
+
| Invite someone to the org | `invite_member({organization_id, email})` (or by `user_id`) |
|
|
239
|
+
| Promote member to admin | `update_member_role({organization_id, membership_id, new_role: 'admin'})` |
|
|
240
|
+
| Remove a member | `remove_member({organization_id, membership_id, reason})` |
|
|
241
|
+
|
|
242
|
+
Email-based collaborator invites stay UI-only; `share_plan` accepts user_ids only. The dedicated `invite_member` call accepts email for org-level invites.
|
|
243
|
+
|
|
97
244
|
## Goal coaching
|
|
98
245
|
|
|
99
246
|
When a user expresses intent — "I want to launch a feature", "we need better testing" — coach them into a structured goal before creating it.
|
|
@@ -159,18 +306,10 @@ recall_knowledge({
|
|
|
159
306
|
|
|
160
307
|
`result_kind` options: `'facts'`, `'entities'`, `'episodes'`, `'all'`. Default is `'all'` — narrow it to control payload size.
|
|
161
308
|
|
|
162
|
-
##
|
|
163
|
-
|
|
164
|
-
v0.9.0 is a breaking release. The old 63-tool surface is gone. See [MIGRATION_v0.9.md](docs/MIGRATION_v0.9.md) for the full mapping. Highlights:
|
|
165
|
-
|
|
166
|
-
- `check_goals_health` + `get_my_tasks` + `get_recent_episodes` + `check_coherence_pending` → `briefing`
|
|
167
|
-
- `quick_status` + `add_log` + `release_task` → `update_task`
|
|
168
|
-
- `suggest_next_tasks` + `claim_task` + `get_task_context` → `claim_next_task`
|
|
169
|
-
- `add_learning(entry_type='decision')` → `queue_decision` (real decision queue, not knowledge graph)
|
|
170
|
-
- `get_goal` + `goal_path` + `goal_progress` + `assess_goal_quality` → `goal_state`
|
|
171
|
-
- `recall_knowledge` + `find_entities` + `get_recent_episodes` + `check_contradictions` → `recall_knowledge`
|
|
309
|
+
## Migration history
|
|
172
310
|
|
|
173
|
-
|
|
311
|
+
- **v0.8.x → v0.9.0** — clean break. 63 legacy CRUD tools collapsed into 15 BDI-aligned tools. See [docs/MIGRATION_v0.9.md](docs/MIGRATION_v0.9.md) for the full mapping.
|
|
312
|
+
- **v0.9.x → v1.0.0** — additive. v0.9 read/update tools unchanged. Adds the full mutation surface (creation, structural edits, sharing, collaboration) so humans can steer entirely through agent conversation. The previously planned `ap_admin_*` namespace is no longer needed — those operations are now first-class BDI tools, with the draft-status seam keeping autonomous agent creation reviewable. See [docs/MIGRATION_v1.0.md](docs/MIGRATION_v1.0.md).
|
|
174
313
|
|
|
175
314
|
## Principles
|
|
176
315
|
|
package/package.json
CHANGED
package/src/tools/bdi/desires.js
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* BDI desires — goal management.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
* link/unlink and achiever changes)
|
|
4
|
+
* 3 tools: list_goals (with health rollup), update_goal (atomic, subsumes
|
|
5
|
+
* link/unlink and achiever changes), derive_subgoal (propose a sub-goal
|
|
6
|
+
* under an existing parent; mandatory parent — top-level goals stay UI-only).
|
|
6
7
|
*/
|
|
7
8
|
|
|
8
9
|
const { asOf, formatResponse, errorResponse, safeArray } = require('./_shared');
|
|
@@ -154,10 +155,110 @@ async function updateGoalHandler(args, apiClient) {
|
|
|
154
155
|
return formatResponse({ as_of: asOf(), goal_id, applied_changes: applied, failures, goal });
|
|
155
156
|
}
|
|
156
157
|
|
|
158
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
159
|
+
// derive_subgoal — propose a sub-goal under an existing parent.
|
|
160
|
+
// Top-level goals stay UI-only (strategic direction is human-set).
|
|
161
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
162
|
+
|
|
163
|
+
const VALID_GOAL_TYPES = ['outcome', 'constraint', 'metric', 'principle'];
|
|
164
|
+
const VALID_STATUSES = ['draft', 'active', 'achieved', 'paused', 'abandoned', 'archived'];
|
|
165
|
+
|
|
166
|
+
const deriveSubgoalDefinition = {
|
|
167
|
+
name: 'derive_subgoal',
|
|
168
|
+
description:
|
|
169
|
+
"Propose a sub-goal under an existing parent goal. parent_goal_id is " +
|
|
170
|
+
"mandatory — agents cannot create top-level goals (strategic direction is " +
|
|
171
|
+
"human-set). Defaults to status='active' for human-directed creation; pass " +
|
|
172
|
+
"status='draft' for autonomous loops so a human can review before promotion. " +
|
|
173
|
+
"Drafts surface in the dashboard pending queue.",
|
|
174
|
+
inputSchema: {
|
|
175
|
+
type: 'object',
|
|
176
|
+
properties: {
|
|
177
|
+
parent_goal_id: {
|
|
178
|
+
type: 'string',
|
|
179
|
+
description: "Required. The parent goal this sub-goal contributes to.",
|
|
180
|
+
},
|
|
181
|
+
title: { type: 'string' },
|
|
182
|
+
description: { type: 'string', description: "Optional extended description, appended after rationale." },
|
|
183
|
+
rationale: {
|
|
184
|
+
type: 'string',
|
|
185
|
+
description: "Why this sub-goal is needed to achieve the parent. Becomes the description; surfaces in human review.",
|
|
186
|
+
},
|
|
187
|
+
type: {
|
|
188
|
+
type: 'string',
|
|
189
|
+
enum: VALID_GOAL_TYPES,
|
|
190
|
+
default: 'outcome',
|
|
191
|
+
},
|
|
192
|
+
status: {
|
|
193
|
+
type: 'string',
|
|
194
|
+
enum: VALID_STATUSES,
|
|
195
|
+
default: 'active',
|
|
196
|
+
description: "Default 'active' for human-directed creation. Pass 'draft' when acting autonomously without explicit user direction.",
|
|
197
|
+
},
|
|
198
|
+
success_criteria: {
|
|
199
|
+
type: 'array',
|
|
200
|
+
items: { type: 'string' },
|
|
201
|
+
description: "Concrete, observable conditions that mark this sub-goal achieved.",
|
|
202
|
+
},
|
|
203
|
+
priority: { type: 'integer', default: 0 },
|
|
204
|
+
},
|
|
205
|
+
required: ['parent_goal_id', 'title', 'rationale'],
|
|
206
|
+
},
|
|
207
|
+
};
|
|
208
|
+
|
|
209
|
+
async function deriveSubgoalHandler(args, apiClient) {
|
|
210
|
+
const { parent_goal_id, title, description, rationale, type = 'outcome', status = 'active', success_criteria, priority } = args;
|
|
211
|
+
|
|
212
|
+
// Verify parent exists and inherit organization scope.
|
|
213
|
+
let parent;
|
|
214
|
+
try {
|
|
215
|
+
parent = await apiClient.goals.get(parent_goal_id);
|
|
216
|
+
} catch (err) {
|
|
217
|
+
return errorResponse('not_found', `Parent goal ${parent_goal_id} not found or not accessible: ${err.message}`);
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
// Compose description: rationale is primary; optional description appended.
|
|
221
|
+
const composedDescription = description
|
|
222
|
+
? `${rationale}\n\n${description}`
|
|
223
|
+
: rationale;
|
|
224
|
+
|
|
225
|
+
const payload = {
|
|
226
|
+
title,
|
|
227
|
+
description: composedDescription,
|
|
228
|
+
type,
|
|
229
|
+
status,
|
|
230
|
+
parentGoalId: parent_goal_id,
|
|
231
|
+
organizationId: parent.organization_id || parent.organizationId || undefined,
|
|
232
|
+
};
|
|
233
|
+
if (success_criteria) payload.successCriteria = { criteria: success_criteria };
|
|
234
|
+
if (typeof priority === 'number') payload.priority = priority;
|
|
235
|
+
|
|
236
|
+
let goal;
|
|
237
|
+
try {
|
|
238
|
+
goal = await apiClient.goals.create(payload);
|
|
239
|
+
} catch (err) {
|
|
240
|
+
const upstream = err.response?.data?.error || err.message;
|
|
241
|
+
return errorResponse('create_failed', `Failed to create sub-goal: ${upstream}`);
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
return formatResponse({
|
|
245
|
+
as_of: asOf(),
|
|
246
|
+
goal_id: goal.id,
|
|
247
|
+
parent_goal_id,
|
|
248
|
+
title: goal.title,
|
|
249
|
+
status: goal.status,
|
|
250
|
+
is_draft: goal.status === 'draft',
|
|
251
|
+
next_step: goal.status === 'draft'
|
|
252
|
+
? "Sub-goal created as draft. It will surface in the dashboard pending queue for human review. Promote via update_goal({status: 'active'}) once approved."
|
|
253
|
+
: "Sub-goal active. Link plans to it via update_goal({add_linked_plans: [...]}).",
|
|
254
|
+
});
|
|
255
|
+
}
|
|
256
|
+
|
|
157
257
|
module.exports = {
|
|
158
|
-
definitions: [listGoalsDefinition, updateGoalDefinition],
|
|
258
|
+
definitions: [listGoalsDefinition, updateGoalDefinition, deriveSubgoalDefinition],
|
|
159
259
|
handlers: {
|
|
160
260
|
list_goals: listGoalsHandler,
|
|
161
261
|
update_goal: updateGoalHandler,
|
|
262
|
+
derive_subgoal: deriveSubgoalHandler,
|
|
162
263
|
},
|
|
163
264
|
};
|