agent-planner-mcp 1.4.0 → 1.4.1

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agent-planner-mcp",
3
- "version": "1.4.0",
3
+ "version": "1.4.1",
4
4
  "description": "MCP server for AgentPlanner — AI agent orchestration with planning, dependencies, knowledge graphs, and human oversight",
5
5
  "main": "src/index.js",
6
6
  "bin": {
@@ -482,8 +482,8 @@ async function claimNextTaskHandler(args, apiClient) {
482
482
  if (!fresh) {
483
483
  try {
484
484
  const myTasks = await apiClient.users.getMyTasks({ plan_id });
485
- const tasks = (myTasks.tasks || myTasks || []).filter((t) => t.status === 'in_progress');
486
- if (plan_id) tasks.filter((t) => t.plan_id === plan_id);
485
+ let tasks = (myTasks.tasks || myTasks || []).filter((t) => t.status === 'in_progress');
486
+ if (plan_id) tasks = tasks.filter((t) => t.plan_id === plan_id);
487
487
  if (tasks[0]) {
488
488
  chosen = tasks[0];
489
489
  source = 'resume_in_progress';
@@ -491,20 +491,49 @@ async function claimNextTaskHandler(args, apiClient) {
491
491
  } catch {}
492
492
  }
493
493
 
494
- // 2. suggest_next_tasks
494
+ // 2. Dependency-aware suggestion via /context/suggest — the real endpoint
495
+ // (only ready, unclaimed tasks, in plan order). Track reachability so we
496
+ // can fail closed below: an empty result from a reachable endpoint means
497
+ // remaining work is dep-blocked, NOT "grab any not_started task".
498
+ let suggestReachable = false;
495
499
  if (!chosen && plan_id) {
496
500
  try {
497
501
  const params = new URLSearchParams({ plan_id, limit: '1' });
498
- const r = await apiClient.axiosInstance.get(`/plans/${plan_id}/suggest-next-tasks?${params}`);
499
- const suggested = (r.data?.tasks || r.data || [])[0];
502
+ const r = await apiClient.axiosInstance.get(`/context/suggest?${params}`);
503
+ suggestReachable = true;
504
+ const suggested = (r.data?.suggestions || r.data?.tasks || r.data || [])[0];
500
505
  if (suggested) {
501
506
  chosen = suggested;
502
507
  source = 'suggest_next_tasks';
503
508
  }
509
+ } catch {
510
+ // Endpoint unreachable (pre-suggest self-hosted API). Leave
511
+ // suggestReachable=false so the last-resort blind pick can run.
512
+ }
513
+ }
514
+
515
+ // 3. Fail-closed gate. When the dependency-aware endpoint is reachable but
516
+ // returned nothing, all remaining not_started work is blocked on
517
+ // incomplete dependencies — mirror the backend and refuse to hand out a
518
+ // dep-blind task. Only the truly-unreachable case falls through to (4).
519
+ if (!chosen && plan_id && suggestReachable) {
520
+ let hasNotStarted = false;
521
+ try {
522
+ const myTasks = await apiClient.users.getMyTasks({ plan_id });
523
+ hasNotStarted = (myTasks.tasks || myTasks || []).some((t) => t.status === 'not_started');
504
524
  } catch {}
525
+ return errorResponse(
526
+ 'not_found',
527
+ hasNotStarted
528
+ ? 'All remaining tasks are blocked on incomplete dependencies'
529
+ : 'No actionable task found in scope',
530
+ { reason: hasNotStarted ? 'blocked_on_dep' : 'no_work_in_scope' },
531
+ );
505
532
  }
506
533
 
507
- // 3. my_tasks fallback (first not_started)
534
+ // 4. Last-resort blind fallback ONLY when the dep-aware endpoint could not
535
+ // be reached at all (ancient self-hosted API with neither work-sessions
536
+ // nor /context/suggest). Against any current backend this never runs.
508
537
  if (!chosen) {
509
538
  try {
510
539
  const myTasks = await apiClient.users.getMyTasks({ plan_id });