agent-planner-mcp 1.5.4 → 1.5.6
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/SKILL.md +1 -1
- package/package.json +1 -1
- package/src/tools/bdi/_shared.js +19 -1
- package/src/tools/bdi/beliefs.js +14 -5
- package/src/tools/bdi/intentions.js +8 -4
package/SKILL.md
CHANGED
|
@@ -123,7 +123,7 @@ The `update_task` call is atomic — status change, log entry, claim release, an
|
|
|
123
123
|
|
|
124
124
|
```
|
|
125
125
|
1. claim_next_task(scope={ plan_id }, ttl_minutes=30) → exclusive ownership
|
|
126
|
-
2. task_context(
|
|
126
|
+
2. task_context(node_id, depth=4) periodically to refresh as work progresses
|
|
127
127
|
3. update_task(...) for state transitions
|
|
128
128
|
4. release_task(task_id, message='handoff to teammate') for explicit handoff
|
|
129
129
|
```
|
package/package.json
CHANGED
package/src/tools/bdi/_shared.js
CHANGED
|
@@ -26,6 +26,24 @@ function safeArray(value) {
|
|
|
26
26
|
return Array.isArray(value) ? value : [];
|
|
27
27
|
}
|
|
28
28
|
|
|
29
|
+
/**
|
|
30
|
+
* The web app origin (where /app/plans/:id lives), for building shareable plan
|
|
31
|
+
* links agents can post (e.g. to Slack). Derived from API_URL — the web app
|
|
32
|
+
* shares the origin and the API sits under /api behind nginx — with an explicit
|
|
33
|
+
* AGENTPLANNER_WEB_URL override for local/self-hosted setups where the UI is on
|
|
34
|
+
* a different host/port.
|
|
35
|
+
*/
|
|
36
|
+
function webOrigin() {
|
|
37
|
+
if (process.env.AGENTPLANNER_WEB_URL) return process.env.AGENTPLANNER_WEB_URL.replace(/\/+$/, '');
|
|
38
|
+
const api = process.env.API_URL || 'https://agentplanner.io/api';
|
|
39
|
+
return api.replace(/\/+$/, '').replace(/\/api$/, '') || 'https://agentplanner.io';
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/** Shareable web link to a plan (set the plan's visibility to unlisted/public for a rich unfurl). */
|
|
43
|
+
function planUrl(planId) {
|
|
44
|
+
return planId ? `${webOrigin()}/app/plans/${planId}` : null;
|
|
45
|
+
}
|
|
46
|
+
|
|
29
47
|
/**
|
|
30
48
|
* True when an error means the backend has no /v1 surface (pre-consolidation
|
|
31
49
|
* self-hosted API). Express returns a default 404 with no structured body for
|
|
@@ -38,4 +56,4 @@ function isV1Unavailable(err) {
|
|
|
38
56
|
return !(body && typeof body === 'object' && body.error);
|
|
39
57
|
}
|
|
40
58
|
|
|
41
|
-
module.exports = { asOf, formatResponse, errorResponse, safeArray, isV1Unavailable };
|
|
59
|
+
module.exports = { asOf, formatResponse, errorResponse, safeArray, isV1Unavailable, webOrigin, planUrl };
|
package/src/tools/bdi/beliefs.js
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* plan_analysis. Each answers one whole agentic question and returns `as_of`.
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
const { asOf, formatResponse, errorResponse, safeArray, isV1Unavailable } = require('./_shared');
|
|
8
|
+
const { asOf, formatResponse, errorResponse, safeArray, isV1Unavailable, planUrl } = require('./_shared');
|
|
9
9
|
|
|
10
10
|
// ─────────────────────────────────────────────────────────────────────────
|
|
11
11
|
// briefing — bundled mission control state. Replaces 4 round trips.
|
|
@@ -197,18 +197,26 @@ const taskContextDefinition = {
|
|
|
197
197
|
inputSchema: {
|
|
198
198
|
type: 'object',
|
|
199
199
|
properties: {
|
|
200
|
-
|
|
200
|
+
// `node_id` is the canonical name (matches every other tool + the skill
|
|
201
|
+
// docs). `task_id` is kept as an accepted alias for back-compat.
|
|
202
|
+
node_id: { type: 'string', description: 'The task/node id to load context for.' },
|
|
203
|
+
task_id: { type: 'string', description: 'Alias for node_id (back-compat).' },
|
|
201
204
|
depth: { type: 'integer', enum: [1, 2, 3, 4], default: 2 },
|
|
202
205
|
token_budget: { type: 'integer', default: 0 },
|
|
203
206
|
},
|
|
204
|
-
required
|
|
207
|
+
// Neither is strictly required at the schema level because either name is
|
|
208
|
+
// accepted; the handler validates that one was supplied with a clear error.
|
|
205
209
|
},
|
|
206
210
|
};
|
|
207
211
|
|
|
208
212
|
async function taskContextHandler(args, apiClient) {
|
|
209
|
-
const { task_id, depth = 2, token_budget = 0 } = args;
|
|
213
|
+
const { node_id, task_id, depth = 2, token_budget = 0 } = args;
|
|
214
|
+
const nodeId = node_id || task_id;
|
|
215
|
+
if (!nodeId) {
|
|
216
|
+
return errorResponse('invalid_arg', 'task_context requires node_id (the task/node id).');
|
|
217
|
+
}
|
|
210
218
|
const params = new URLSearchParams({
|
|
211
|
-
node_id:
|
|
219
|
+
node_id: nodeId,
|
|
212
220
|
depth: String(depth),
|
|
213
221
|
token_budget: String(token_budget),
|
|
214
222
|
log_limit: '10',
|
|
@@ -486,6 +494,7 @@ async function listPlansHandler(args, apiClient) {
|
|
|
486
494
|
summary,
|
|
487
495
|
plans: page.map((p) => ({
|
|
488
496
|
id: p.id,
|
|
497
|
+
url: planUrl(p.id),
|
|
489
498
|
title: p.title,
|
|
490
499
|
status: p.status,
|
|
491
500
|
visibility: p.visibility,
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
* See ../../../docs/MCP_v1.0_FULL_SURFACE.md for design rationale.
|
|
14
14
|
*/
|
|
15
15
|
|
|
16
|
-
const { asOf, formatResponse, errorResponse, isV1Unavailable } = require('./_shared');
|
|
16
|
+
const { asOf, formatResponse, errorResponse, isV1Unavailable, planUrl } = require('./_shared');
|
|
17
17
|
const { version: PKG_VERSION } = require('../../../package.json');
|
|
18
18
|
|
|
19
19
|
// Provenance tag stamped onto every plan this server creates, so a plan stays
|
|
@@ -854,16 +854,18 @@ async function formIntentionHandler(args, apiClient) {
|
|
|
854
854
|
tree,
|
|
855
855
|
client_version: CLIENT_TAG,
|
|
856
856
|
});
|
|
857
|
+
const facadePlanId = result.plan?.id || result.plan_id;
|
|
857
858
|
return formatResponse({
|
|
858
859
|
...result,
|
|
859
|
-
plan_id:
|
|
860
|
+
plan_id: facadePlanId,
|
|
861
|
+
url: planUrl(facadePlanId),
|
|
860
862
|
goal_id,
|
|
861
863
|
status: result.plan?.status || status,
|
|
862
864
|
is_draft: (result.plan?.status || status) === 'draft',
|
|
863
865
|
nodes_created: Array.isArray(result.tree) ? result.tree.length : undefined,
|
|
864
866
|
next_step: (result.plan?.status || status) === 'draft'
|
|
865
867
|
? "Plan created as draft. Will surface in dashboard pending for human review. Auto-promotes to active when first task moves to in_progress."
|
|
866
|
-
:
|
|
868
|
+
: `Plan active. Claim a task with claim_next_task({plan_id}) to begin work. Shareable link: ${planUrl(facadePlanId)} (set visibility:'unlisted' for a rich Slack/social preview).`,
|
|
867
869
|
});
|
|
868
870
|
} catch {
|
|
869
871
|
// Fall through to the legacy multi-call path for older/self-hosted APIs.
|
|
@@ -966,6 +968,7 @@ async function formIntentionHandler(args, apiClient) {
|
|
|
966
968
|
const response = {
|
|
967
969
|
as_of: asOf(),
|
|
968
970
|
plan_id: plan.id,
|
|
971
|
+
url: planUrl(plan.id),
|
|
969
972
|
goal_id,
|
|
970
973
|
status: plan.status,
|
|
971
974
|
is_draft: plan.status === 'draft',
|
|
@@ -975,7 +978,7 @@ async function formIntentionHandler(args, apiClient) {
|
|
|
975
978
|
structure,
|
|
976
979
|
next_step: plan.status === 'draft'
|
|
977
980
|
? "Plan created as draft. Will surface in dashboard pending for human review. Auto-promotes to active when first task moves to in_progress."
|
|
978
|
-
:
|
|
981
|
+
: `Plan active. Claim a task with claim_next_task({plan_id}) to begin work. Shareable link: ${planUrl(plan.id)} (set visibility:'unlisted' for a rich Slack/social preview).`,
|
|
979
982
|
};
|
|
980
983
|
if (createdWithoutDependencies) {
|
|
981
984
|
response.warning =
|
|
@@ -1153,6 +1156,7 @@ async function proposeResearchChainHandler(args, apiClient) {
|
|
|
1153
1156
|
return formatResponse({
|
|
1154
1157
|
as_of: asOf(),
|
|
1155
1158
|
plan_id,
|
|
1159
|
+
url: planUrl(plan_id),
|
|
1156
1160
|
parent_id,
|
|
1157
1161
|
rationale,
|
|
1158
1162
|
research: { id: created.research.id, title: created.research.title },
|