agent-planner-mcp 1.5.14 → 1.5.17
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 +3 -0
- package/package.json +1 -1
- package/src/api-client.js +12 -0
- package/src/tools/bdi/desires.js +87 -12
- package/src/tools/bdi/utility.js +15 -3
package/SKILL.md
CHANGED
|
@@ -42,6 +42,9 @@ AgentPlanner exposes a **BDI-aligned** surface — Beliefs (state queries), Desi
|
|
|
42
42
|
- `update_goal` — atomic goal update; subsumes link/unlink + achiever changes
|
|
43
43
|
- `create_goal` — create a new top-level goal (no parent). Agents create goals directly when asked — no UI step. Defaults to `status='active'`.
|
|
44
44
|
- `derive_subgoal` *(v1.0)* — create a sub-goal under an existing parent (use `create_goal` for top-level).
|
|
45
|
+
- `record_criterion_progress` — set the `current` value of a measurable success criterion (by `criterion_id` or 0-based `index`, both shown in `goal_state`). The write that drives goal attainment, e.g. "p99 latency: current 140 → 100".
|
|
46
|
+
|
|
47
|
+
**Success criteria** (`success_criteria` on create/derive/update) accept either plain strings (qualitative) or structured measurable objects: `{ statement, metric?, target?, current?, unit?, direction: 'increase'|'decrease'|'boolean' }`. A criterion with **metric + target + direction** is *measurable* and counts toward goal attainment (`increase`: current ≥ target, `decrease`: current ≤ target, `boolean`: current truthy). Prefer measurable criteria — "p99 latency < 100ms" beats "make it fast".
|
|
45
48
|
|
|
46
49
|
### Intentions — what am I committing to?
|
|
47
50
|
|
package/package.json
CHANGED
package/src/api-client.js
CHANGED
|
@@ -592,6 +592,11 @@ const goals = {
|
|
|
592
592
|
return response.data;
|
|
593
593
|
},
|
|
594
594
|
|
|
595
|
+
recordCriterionProgress: async (goalId, body) => {
|
|
596
|
+
const response = await apiClient.post(`/goals/${goalId}/criteria/progress`, body);
|
|
597
|
+
return response.data;
|
|
598
|
+
},
|
|
599
|
+
|
|
595
600
|
// v2 goal-dependency endpoints
|
|
596
601
|
getPath: async (goalId, maxDepth) => {
|
|
597
602
|
const params = maxDepth ? `?max_depth=${maxDepth}` : '';
|
|
@@ -1087,6 +1092,12 @@ function createApiClient(token, options = {}) {
|
|
|
1087
1092
|
// Export the axios instance for direct use
|
|
1088
1093
|
const axiosInstance = apiClient;
|
|
1089
1094
|
|
|
1095
|
+
// ─── System ───────────────────────────────────────────────────
|
|
1096
|
+
// Operational metadata about the backend the MCP is talking to.
|
|
1097
|
+
const system = {
|
|
1098
|
+
version: () => apiClient.get('/version').then(r => r.data),
|
|
1099
|
+
};
|
|
1100
|
+
|
|
1090
1101
|
// ─── Coherence ────────────────────────────────────────────────
|
|
1091
1102
|
const coherence = {
|
|
1092
1103
|
getPending: () => apiClient.get('/coherence/pending').then(r => r.data),
|
|
@@ -1112,6 +1123,7 @@ module.exports = {
|
|
|
1112
1123
|
coherence,
|
|
1113
1124
|
users,
|
|
1114
1125
|
agentLoop,
|
|
1126
|
+
system,
|
|
1115
1127
|
v1,
|
|
1116
1128
|
axiosInstance, // Export for direct API calls
|
|
1117
1129
|
createApiClient // Factory for per-session clients (HTTP mode)
|
package/src/tools/bdi/desires.js
CHANGED
|
@@ -9,6 +9,35 @@
|
|
|
9
9
|
|
|
10
10
|
const { asOf, formatResponse, errorResponse, safeArray, apiErrorMessage } = require('./_shared');
|
|
11
11
|
|
|
12
|
+
// Success criteria accept plain strings (qualitative) or structured measurable
|
|
13
|
+
// units. A criterion with metric+target+direction becomes "measurable" and
|
|
14
|
+
// drives goal attainment (see the backend's goalCriteria.normalizeCriteria,
|
|
15
|
+
// which also maps legacy string[] / {criteria:[]} shapes onto this).
|
|
16
|
+
const SUCCESS_CRITERIA_SCHEMA = {
|
|
17
|
+
type: 'array',
|
|
18
|
+
description:
|
|
19
|
+
"Each entry is a plain string (qualitative) OR a structured object " +
|
|
20
|
+
"{ statement, metric?, target?, current?, unit?, direction: 'increase'|'decrease'|'boolean' }. " +
|
|
21
|
+
"Give a criterion metric+target+direction to make it measurable so it counts toward goal attainment.",
|
|
22
|
+
items: {
|
|
23
|
+
oneOf: [
|
|
24
|
+
{ type: 'string' },
|
|
25
|
+
{
|
|
26
|
+
type: 'object',
|
|
27
|
+
required: ['statement'],
|
|
28
|
+
properties: {
|
|
29
|
+
statement: { type: 'string', description: 'Human-readable condition.' },
|
|
30
|
+
metric: { type: 'string', description: 'What is measured, e.g. "p99 latency".' },
|
|
31
|
+
target: { description: 'Goal value (number or string).' },
|
|
32
|
+
current: { description: 'Latest observed value (number or string).' },
|
|
33
|
+
unit: { type: 'string', description: 'e.g. "ms", "%", "customers".' },
|
|
34
|
+
direction: { type: 'string', enum: ['increase', 'decrease', 'boolean'] },
|
|
35
|
+
},
|
|
36
|
+
},
|
|
37
|
+
],
|
|
38
|
+
},
|
|
39
|
+
};
|
|
40
|
+
|
|
12
41
|
const listGoalsDefinition = {
|
|
13
42
|
name: 'list_goals',
|
|
14
43
|
description:
|
|
@@ -93,7 +122,7 @@ const updateGoalDefinition = {
|
|
|
93
122
|
// Commitment: true once the goal is promoted to active execution
|
|
94
123
|
// (replaces the old desire/intention goal_type vocabulary).
|
|
95
124
|
committed: { type: 'boolean' },
|
|
96
|
-
success_criteria:
|
|
125
|
+
success_criteria: SUCCESS_CRITERIA_SCHEMA,
|
|
97
126
|
add_linked_plans: { type: 'array', items: { type: 'string' } },
|
|
98
127
|
remove_linked_plans: { type: 'array', items: { type: 'string' } },
|
|
99
128
|
add_achievers: { type: 'array', items: { type: 'string' } },
|
|
@@ -210,11 +239,7 @@ const deriveSubgoalDefinition = {
|
|
|
210
239
|
default: 'active',
|
|
211
240
|
description: "Default 'active' for human-directed creation. Pass 'draft' when acting autonomously without explicit user direction.",
|
|
212
241
|
},
|
|
213
|
-
success_criteria:
|
|
214
|
-
type: 'array',
|
|
215
|
-
items: { type: 'string' },
|
|
216
|
-
description: "Concrete, observable conditions that mark this sub-goal achieved.",
|
|
217
|
-
},
|
|
242
|
+
success_criteria: SUCCESS_CRITERIA_SCHEMA,
|
|
218
243
|
priority: { type: 'integer', default: 0 },
|
|
219
244
|
},
|
|
220
245
|
required: ['parent_goal_id', 'title', 'rationale'],
|
|
@@ -301,11 +326,7 @@ const createGoalDefinition = {
|
|
|
301
326
|
default: 'active',
|
|
302
327
|
description: "Default 'active' (live). Pass 'draft' to propose without activating.",
|
|
303
328
|
},
|
|
304
|
-
success_criteria:
|
|
305
|
-
type: 'array',
|
|
306
|
-
items: { type: 'string' },
|
|
307
|
-
description: "Concrete, observable conditions that mark this goal achieved.",
|
|
308
|
-
},
|
|
329
|
+
success_criteria: SUCCESS_CRITERIA_SCHEMA,
|
|
309
330
|
priority: { type: 'integer', minimum: 0, maximum: 10, default: 0 },
|
|
310
331
|
workspace_id: { type: 'string', description: "Optional. Target workspace; defaults to the active org's default workspace." },
|
|
311
332
|
},
|
|
@@ -342,12 +363,66 @@ async function createGoalHandler(args, apiClient) {
|
|
|
342
363
|
});
|
|
343
364
|
}
|
|
344
365
|
|
|
366
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
367
|
+
// record_criterion_progress — set the current value of a measurable criterion.
|
|
368
|
+
// This is the write that makes goal attainment real (metric moved 40→72).
|
|
369
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
370
|
+
|
|
371
|
+
const recordCriterionProgressDefinition = {
|
|
372
|
+
name: 'record_criterion_progress',
|
|
373
|
+
description:
|
|
374
|
+
"Record the latest observed value of one of a goal's success criteria " +
|
|
375
|
+
"(e.g. a metric moved 40→72). Identify the criterion by criterion_id " +
|
|
376
|
+
"(stable, like 'c0') or its 0-based index — both are visible in goal_state. " +
|
|
377
|
+
"Only measurable criteria (metric+target+direction) count toward attainment; " +
|
|
378
|
+
"this is the write that makes goal attainment real.",
|
|
379
|
+
inputSchema: {
|
|
380
|
+
type: 'object',
|
|
381
|
+
properties: {
|
|
382
|
+
goal_id: { type: 'string' },
|
|
383
|
+
criterion_id: { type: 'string', description: "Stable criterion id (e.g. 'c0'). Use this or index." },
|
|
384
|
+
index: { type: 'integer', description: '0-based position of the criterion. Alternative to criterion_id.' },
|
|
385
|
+
current: { description: 'Latest observed value (number or string). Required.' },
|
|
386
|
+
},
|
|
387
|
+
required: ['goal_id', 'current'],
|
|
388
|
+
},
|
|
389
|
+
};
|
|
390
|
+
|
|
391
|
+
async function recordCriterionProgressHandler(args, apiClient) {
|
|
392
|
+
const { goal_id, criterion_id, index, current } = args;
|
|
393
|
+
if (!goal_id) return errorResponse('invalid_arg', 'record_criterion_progress requires goal_id');
|
|
394
|
+
if (current === undefined) return errorResponse('invalid_arg', 'record_criterion_progress requires current');
|
|
395
|
+
if (!criterion_id && !Number.isInteger(index)) {
|
|
396
|
+
return errorResponse('invalid_arg', 'record_criterion_progress requires criterion_id or index');
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
const body = { current };
|
|
400
|
+
if (criterion_id) body.criterion_id = criterion_id;
|
|
401
|
+
if (Number.isInteger(index)) body.index = index;
|
|
402
|
+
|
|
403
|
+
try {
|
|
404
|
+
const result = await apiClient.goals.recordCriterionProgress(goal_id, body);
|
|
405
|
+
return formatResponse({ as_of: asOf(), goal_id, criterion: result.criterion, criteria: result.criteria });
|
|
406
|
+
} catch (err) {
|
|
407
|
+
const status = err.response?.status;
|
|
408
|
+
if (status === 404) return errorResponse('not_found', apiErrorMessage(err));
|
|
409
|
+
return errorResponse('upstream_unavailable', `record_criterion_progress failed: ${apiErrorMessage(err)}`);
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
|
|
345
413
|
module.exports = {
|
|
346
|
-
definitions: [
|
|
414
|
+
definitions: [
|
|
415
|
+
listGoalsDefinition,
|
|
416
|
+
updateGoalDefinition,
|
|
417
|
+
createGoalDefinition,
|
|
418
|
+
deriveSubgoalDefinition,
|
|
419
|
+
recordCriterionProgressDefinition,
|
|
420
|
+
],
|
|
347
421
|
handlers: {
|
|
348
422
|
list_goals: listGoalsHandler,
|
|
349
423
|
update_goal: updateGoalHandler,
|
|
350
424
|
create_goal: createGoalHandler,
|
|
351
425
|
derive_subgoal: deriveSubgoalHandler,
|
|
426
|
+
record_criterion_progress: recordCriterionProgressHandler,
|
|
352
427
|
},
|
|
353
428
|
};
|
package/src/tools/bdi/utility.js
CHANGED
|
@@ -19,19 +19,31 @@ const getStartedDefinition = {
|
|
|
19
19
|
},
|
|
20
20
|
};
|
|
21
21
|
|
|
22
|
-
async function getStartedHandler(args) {
|
|
22
|
+
async function getStartedHandler(args, apiClient) {
|
|
23
|
+
// Best-effort backend version so one call shows which builds are in play
|
|
24
|
+
// (the MCP and the API it is actually talking to are deployed separately).
|
|
25
|
+
let api = { version: 'unavailable' };
|
|
26
|
+
try {
|
|
27
|
+
if (apiClient?.system?.version) api = await apiClient.system.version();
|
|
28
|
+
} catch {
|
|
29
|
+
api = { version: 'unavailable' };
|
|
30
|
+
}
|
|
31
|
+
|
|
23
32
|
return formatResponse({
|
|
24
33
|
as_of: asOf(),
|
|
25
34
|
mcp_version: MCP_VERSION,
|
|
35
|
+
api_url: process.env.API_URL || 'http://localhost:3000',
|
|
36
|
+
api_version: api.version,
|
|
37
|
+
api_build: api.commit ? { commit: api.commit, started_at: api.started_at } : undefined,
|
|
26
38
|
overview:
|
|
27
39
|
"AgentPlanner exposes a BDI-aligned MCP surface. Tools are grouped by " +
|
|
28
40
|
"Beliefs (state queries), Desires (goals), and Intentions (committed actions). " +
|
|
29
41
|
"Each tool answers one whole agentic question and returns an `as_of` timestamp.",
|
|
30
42
|
tools_by_namespace: {
|
|
31
43
|
beliefs: ['briefing', 'list_plans', 'task_context', 'goal_state', 'recall_knowledge', 'search', 'plan_analysis'],
|
|
32
|
-
desires: ['list_goals', 'create_goal', 'update_goal', 'derive_subgoal'],
|
|
44
|
+
desires: ['list_goals', 'create_goal', 'update_goal', 'derive_subgoal', 'record_criterion_progress'],
|
|
33
45
|
intentions: ['form_intention', 'extend_intention', 'link_intentions', 'propose_research_chain', 'claim_next_task', 'update_task', 'update_node', 'release_task', 'queue_decision', 'resolve_decision', 'add_learning'],
|
|
34
|
-
workspaces: ['list_workspaces', 'create_workspace', 'list_blueprints', 'fork_blueprint', 'save_as_blueprint'],
|
|
46
|
+
workspaces: ['list_workspaces', 'create_workspace', 'list_blueprints', 'fork_blueprint', 'save_as_blueprint', 'delete_blueprint'],
|
|
35
47
|
},
|
|
36
48
|
recommended_workflows: [
|
|
37
49
|
{
|