diff --git a/src/frontend/mcp-server/internal/app.go b/src/frontend/mcp-server/internal/app.go index 3b8e5d1..c2bc05c 100644 --- a/src/frontend/mcp-server/internal/app.go +++ b/src/frontend/mcp-server/internal/app.go @@ -149,11 +149,17 @@ func (a *App) HandlePendReasons(ctx context.Context, req mcp.CallToolRequest) (* } // formatPendJob renders one job's PEND reason, or notes it is not waiting. +// +// `id` is the numeric job ID (scheduler_list_jobs' `id` and the value the +// other per-job tools accept as their `id` param) so a caller can round-trip +// it into scheduler_get_job/cancel/hold/release. `human_id` is kept for +// display only — the apiserver rejects dash-form job IDs as query input. func formatPendJob(job *sclient.URMJob) map[string]any { pr := parsePendingReason(*job) if pr == nil { return map[string]any{ - "id": job.HumanID, + "id": job.ID, + "human_id": job.HumanID, "name": job.Name, "queue": job.Queue, "status": job.Status, @@ -161,7 +167,8 @@ func formatPendJob(job *sclient.URMJob) map[string]any { } } return map[string]any{ - "id": job.HumanID, + "id": job.ID, + "human_id": job.HumanID, "name": job.Name, "queue": job.Queue, "status": job.Status, diff --git a/src/frontend/mcp-server/internal/pendreason_test.go b/src/frontend/mcp-server/internal/pendreason_test.go index 4e7fcb5..e19df6f 100644 --- a/src/frontend/mcp-server/internal/pendreason_test.go +++ b/src/frontend/mcp-server/internal/pendreason_test.go @@ -71,3 +71,33 @@ func TestPendReasonSummary(t *testing.T) { } } } + +func TestFormatPendJobIDConsistency(t *testing.T) { + job := sclient.URMJob{ + ID: "73931152729047040", + HumanID: "1-0-1786764804-0", + Name: "sleep 5", + Queue: "normal", + Status: "PEND", + } + // no pending_reason -> explanation branch + out := formatPendJob(&job) + if id, _ := out["id"].(string); id != job.ID { + t.Errorf("id = %q, want numeric %q (must round-trip into get/cancel/hold)", id, job.ID) + } + if hid, _ := out["human_id"].(string); hid != job.HumanID { + t.Errorf("human_id = %q, want %q", hid, job.HumanID) + } + + // with pending_reason -> main branch + job.Extensions = map[string]any{ + "pending_reason": `{"main_reason":3,"main_reason_name":"match_fail","host_reasons":[],"res_reasons":[]}`, + } + out = formatPendJob(&job) + if id, _ := out["id"].(string); id != job.ID { + t.Errorf("id (with reason) = %q, want numeric %q", id, job.ID) + } + if hid, _ := out["human_id"].(string); hid != job.HumanID { + t.Errorf("human_id (with reason) = %q, want %q", hid, job.HumanID) + } +}