formatPendJob used job.HumanID ("1-0-1786764804-0") as the tool's `id`,
but the apiserver rejects dash-form job IDs as query input (only numeric is
accepted, utils.IsNumeric) — so an id copied out of scheduler_pend_reasons
could not be fed back into scheduler_get_job/cancel/hold/release (HTTP 400).
Use job.ID (numeric, same as scheduler_list_jobs' `id`) and keep `human_id`
for display. Round-trip verified on the cluster: pend_reasons id ->
scheduler_get_job succeeds.
Test: TestFormatPendJobIDConsistency (id is numeric, human_id preserved,
both with and without a pending_reason).
Co-Authored-By: Claude <noreply@anthropic.com>
New read-only tool that answers "why is my job waiting": lists PEND jobs (or
one by id) and translates each job's pending_reason into a human-readable
scenario (LSF bjobs -p style). Maps the PREASON_* codes surfaced by the
PEND-reason work (4e2ac86): no_resource / match_fail / limit_global /
limit_host / queue_closed / queue_draining / time_window / host_unavail.
- internal/pendreason.go: pending_reason JSON parsing (mirrors apiserver
rawPendReason) + reasonScenario() translation + bjobs -p style summary.
- internal/app.go: HandlePendReasons — id param for one job, else pending
list filtered by queue/owner/limit.
- cmd/main.go: register scheduler_pend_reasons (read-only).
- 5 unit tests (known/unknown codes, parse from JSON, missing reason,
summary format). go test ./... + go vet clean.
Co-Authored-By: Claude <noreply@anthropic.com>
Add four tools closing the submit→watch→analyze→suggest loop in the
request/response MCP model:
- scheduler_wait_job: poll a job to a terminal state or timeout.
- scheduler_analyze_failure: gather job record + output logs for failure
analysis (interpretation left to the LLM).
- scheduler_suggest_resources: conservative processor/node suggestions from
current cluster availability.
- scheduler_estimate_wait_time: rough wait estimate from pending count and
free cores (guidance, not a guarantee).
All verified live on t1 against the running apiserver.
Co-Authored-By: Claude <noreply@anthropic.com>
When a user asks to view cluster status (e.g. "看看机器情况"), the LLM saw
non-OK values in the MCP response (a node UNAVAIL, a job PEND/EXIT) and
treated them as incidents — proposing unsolicited diagnostic/repair actions
and referencing "known bugs". The user only wanted a factual status report.
Mitigation at the MCP layer:
- Add server instructions (returned to the client in the initialize
handshake) stating that the status tools return operational snapshots,
that UNAVAIL/PEND/EXIT/UNKWN are normal state, and that the model must
not speculate or propose actions unless the user explicitly asks.
- Append report-only guidance to the scheduler_list_nodes / list_jobs /
cluster_metrics descriptions.
Verified: initialize response carries the 857-char instructions; tools/list
shows the updated descriptions.
Co-Authored-By: Claude <noreply@anthropic.com>