agent-planner-mcp 1.5.1 → 1.5.4
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/package.json +1 -1
- package/src/tools/bdi/beliefs.js +19 -3
- package/src/tools/bdi/intentions.js +13 -2
package/package.json
CHANGED
package/src/tools/bdi/beliefs.js
CHANGED
|
@@ -463,8 +463,10 @@ async function listPlansHandler(args, apiClient) {
|
|
|
463
463
|
const q = filter.query.toLowerCase();
|
|
464
464
|
plans = plans.filter((p) => (p.title || '').toLowerCase().includes(q));
|
|
465
465
|
}
|
|
466
|
-
plans = plans.slice(0, filter.limit || 50);
|
|
467
466
|
|
|
467
|
+
// Summarize the FULL filtered set BEFORE paginating — otherwise `total` and
|
|
468
|
+
// the status counts only reflect the truncated page, making an agent think
|
|
469
|
+
// it has seen every plan when it hasn't.
|
|
468
470
|
const summary = plans.reduce(
|
|
469
471
|
(acc, p) => {
|
|
470
472
|
acc[p.status] = (acc[p.status] || 0) + 1;
|
|
@@ -474,10 +476,15 @@ async function listPlansHandler(args, apiClient) {
|
|
|
474
476
|
{ total: 0 },
|
|
475
477
|
);
|
|
476
478
|
|
|
479
|
+
const limit = filter.limit || 50;
|
|
480
|
+
const page = plans.slice(0, limit);
|
|
481
|
+
summary.returned = page.length;
|
|
482
|
+
summary.truncated = plans.length > page.length; // true → raise `filter.limit` to see the rest
|
|
483
|
+
|
|
477
484
|
return formatResponse({
|
|
478
485
|
as_of: asOf(),
|
|
479
486
|
summary,
|
|
480
|
-
plans:
|
|
487
|
+
plans: page.map((p) => ({
|
|
481
488
|
id: p.id,
|
|
482
489
|
title: p.title,
|
|
483
490
|
status: p.status,
|
|
@@ -537,7 +544,16 @@ async function searchHandler(args, apiClient) {
|
|
|
537
544
|
result = await apiClient.search.searchPlan(scope_id, query);
|
|
538
545
|
} else {
|
|
539
546
|
const global = await apiClient.search.globalSearch(query);
|
|
540
|
-
|
|
547
|
+
// The backend returns `results` as a GROUPED object
|
|
548
|
+
// ({ plans, nodes, comments, logs }), not a flat array — so the old
|
|
549
|
+
// `Array.isArray(results) ? … : []` always fell to [] and global search
|
|
550
|
+
// returned nothing. Flatten both shapes.
|
|
551
|
+
const r = global?.results;
|
|
552
|
+
const all = Array.isArray(r)
|
|
553
|
+
? r
|
|
554
|
+
: r && typeof r === 'object'
|
|
555
|
+
? [...(r.plans || []), ...(r.nodes || []), ...(r.comments || []), ...(r.logs || [])]
|
|
556
|
+
: [];
|
|
541
557
|
const matchScope = (r) => {
|
|
542
558
|
if (scope === 'global') return true;
|
|
543
559
|
if (scope === 'plans') return r.type === 'plan';
|
|
@@ -938,7 +938,10 @@ async function formIntentionHandler(args, apiClient) {
|
|
|
938
938
|
continue;
|
|
939
939
|
}
|
|
940
940
|
try {
|
|
941
|
-
|
|
941
|
+
// Plan-scoped route — the bare /dependencies path is unmounted (only
|
|
942
|
+
// /dependencies/cross-plan + /external exist), so it 404s and silently
|
|
943
|
+
// dropped every inline edge. POST /plans/:id/dependencies is canonical.
|
|
944
|
+
await apiClient.axiosInstance.post(`/plans/${plan.id}/dependencies`, {
|
|
942
945
|
source_node_id: sourceId,
|
|
943
946
|
target_node_id: intent.targetId,
|
|
944
947
|
dependency_type: 'blocks',
|
|
@@ -1133,7 +1136,9 @@ async function proposeResearchChainHandler(args, apiClient) {
|
|
|
1133
1136
|
[created.plan.id, created.implement.id],
|
|
1134
1137
|
]) {
|
|
1135
1138
|
try {
|
|
1136
|
-
|
|
1139
|
+
// Plan-scoped route — bare /dependencies 404s (unmounted), which silently
|
|
1140
|
+
// dropped both chain edges and left 3 orphan tasks.
|
|
1141
|
+
await apiClient.axiosInstance.post(`/plans/${plan_id}/dependencies`, {
|
|
1137
1142
|
source_node_id: from,
|
|
1138
1143
|
target_node_id: to,
|
|
1139
1144
|
dependency_type: 'blocks',
|
|
@@ -1144,6 +1149,7 @@ async function proposeResearchChainHandler(args, apiClient) {
|
|
|
1144
1149
|
}
|
|
1145
1150
|
}
|
|
1146
1151
|
|
|
1152
|
+
const edgeFailures = failures.filter((f) => f.step === 'create_edge');
|
|
1147
1153
|
return formatResponse({
|
|
1148
1154
|
as_of: asOf(),
|
|
1149
1155
|
plan_id,
|
|
@@ -1154,6 +1160,11 @@ async function proposeResearchChainHandler(args, apiClient) {
|
|
|
1154
1160
|
implement: { id: created.implement.id, title: created.implement.title },
|
|
1155
1161
|
edges,
|
|
1156
1162
|
failures,
|
|
1163
|
+
// Fail loudly: don't let the caller believe the chain is wired when the
|
|
1164
|
+
// blocking edges didn't get created.
|
|
1165
|
+
...(edgeFailures.length
|
|
1166
|
+
? { warning: `Chain tasks created but ${edgeFailures.length} blocking edge(s) FAILED — the Research→Plan→Implement ordering is NOT wired: ${edgeFailures.map((f) => f.error).join('; ')}` }
|
|
1167
|
+
: {}),
|
|
1157
1168
|
next_step: "Claim the Research task with claim_next_task({plan_id}) to begin investigation.",
|
|
1158
1169
|
});
|
|
1159
1170
|
}
|