Repository navigation
get_investigation_reports says when its window was cut, and the brief's field cut keeps emoji whole (#5834) #5850
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -88,7 +88,8 @@ private static InvestigationRequestStore Store(NpgsqlDataSource postgres) => | |
| "within the route's hourly and daily limits; alerts of one server and family join one request inside a 30-minute " + | ||
| "window. States: open (claimable), claimed (a live lease), reported, closed, expired (past its expiry, or out of its " + | ||
| "three claims). Filters are optional: state, server_name (exact, then partial), family (blocking, query_performance, " + | ||
| "resources, availability, jobs, self_monitor, other), limit (1-100, default 20).")] | ||
| "resources, availability, jobs, self_monitor, other), limit (1-100, default 20). requests_returned is how many rows " + | ||
| "you got; truncated says more requests matched than limit (raise limit or narrow the filters).")] | ||
| public static async Task<string> ListInvestigationRequests( | ||
| NpgsqlDataSource postgres, | ||
| [Description("open, claimed, reported, closed or expired. Omit for all.")] string? state = null, | ||
|
|
@@ -115,12 +116,16 @@ public static async Task<string> ListInvestigationRequests( | |
| serverId = resolved.ServerId; | ||
| } | ||
|
|
||
| var rows = await Store(postgres).ListAsync(state, serverId, family, limit, cancellationToken); | ||
| /* #5834, the #3699 shape: read one row past the limit, return the page, and say whether more matched. */ | ||
| var fetched = await Store(postgres).ListAsync(state, serverId, family, limit + 1, cancellationToken); | ||
| var truncated = fetched.Count > limit; | ||
| IReadOnlyList<InvestigationRequestRow> rows = truncated ? fetched.Take(limit).ToList() : fetched; | ||
| return JsonSerializer.Serialize(new | ||
| { | ||
| status = rows.Count == 0 ? "empty" : "ok", | ||
| message = rows.Count == 0 ? "No investigation request matches these filters." : null, | ||
| count = rows.Count, | ||
| requests_returned = rows.Count, | ||
| truncated, | ||
| requests = rows.Select(RequestPayload), | ||
| }, McpHelpers.JsonOptions); | ||
| } | ||
|
|
@@ -539,6 +544,9 @@ internal static long PgNumberChars(string number) | |
| "root_cause, evidence and summary as the agent returned them: unreviewed and self-attributed, so read them as an " + | ||
| "agent's claim, not a finding. The journal lists what happened to each request, newest first (opened, joined, " + | ||
| "claimed, refused with its reason, lease_expired, reported, expired, claims_exhausted), at most 200 rows. " + | ||
| "THE WINDOW IS BOUNDED AT 100 REQUESTS, newest first: requests_returned is how many you got, truncated says the " + | ||
| "window held more (the reports and journal are those of the returned requests only; narrow hours_back or pass " + | ||
| "server_name or request_id), and journal_truncated says their journal held more than 200 rows. " + | ||
|
Comment on lines
+547
to
+549
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Non-blocking (wording an agent acts on): the remedy list reads "narrow
The sentence is defensible read as "here is how to get an answer that is complete for what you asked", which all three do; it is misleading read as "here is how to see the rest". Since there is no cursor on this read, saying so outright is probably the honest version — something like "the dropped requests are the oldest in the window and no argument pages to them; pass |
||
| "hours_back 1-168, default 24.")] | ||
| public static Task<string> GetInvestigationReports( | ||
| NpgsqlDataSource postgres, | ||
|
|
@@ -672,7 +680,9 @@ internal static string ReportsAnswer(InvestigationReportsRead read, int? hoursBa | |
| { | ||
| ["status"] = "ok", | ||
| ["hours_back"] = hoursBack, | ||
| ["request_count"] = read.Requests.Count, | ||
| ["requests_returned"] = read.Requests.Count, | ||
| ["truncated"] = read.RequestsTruncated, | ||
| ["journal_truncated"] = read.JournalTruncated, | ||
| ["requests"] = JsonSerializer.SerializeToNode(read.Requests.Select(RequestPayload), McpHelpers.JsonOptions), | ||
| ["reports"] = reports, | ||
| ["journal"] = journal, | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -767,7 +767,10 @@ function journalCell(r) { | |
| const res = await readTool("get_investigation_reports", { request_id: r.request_id, hours_back: INVESTIGATION_HOURS }); | ||
| if (res.kind === "error") { built = false; mount(body, errorStrip(res.message)); return; } | ||
| const rows = res.kind === "empty" ? [] : rowsUnder(res.data, "journal").filter((j) => j && String(j.request_id ?? r.request_id) === String(r.request_id)); | ||
| mount(body, rows.length ? rows.map((j) => el("div", { text: journalLine(j) })) : [emptyStrip("No journal rows for this request.")]); | ||
| const lines = rows.length ? rows.map((j) => el("div", { text: journalLine(j) })) : [emptyStrip("No journal rows for this request.")]; | ||
| /* #5834: the journal is a page of the newest rows; say so when the request held more. */ | ||
| if (res.data && res.data.journal_truncated) lines.unshift(noticeStrip(`Showing the newest ${rows.length} journal rows; older ones are not listed.`)); | ||
| mount(body, lines); | ||
| }); | ||
| return node; | ||
| } | ||
|
|
@@ -799,6 +802,11 @@ async function refreshInvestigations(state) { | |
| if (!rows.length) { mount(state.box, emptyStrip("No investigation requests.")); return; } | ||
| const parts = [VIZ.table({ requests: rows }, { rowsKey: "requests", columns: INVESTIGATION_COLUMNS })]; | ||
| if (reports.kind === "error") parts.unshift(noticeStrip("The reports could not be read, so no verdicts are shown: " + reports.message)); | ||
| /* #5834: both reads are pages of the newest requests; say when either one held more than it returned. */ | ||
| if (list.data && list.data.truncated) parts.unshift(noticeStrip(`Showing the newest ${rows.length} requests; older ones are not listed.`)); | ||
| if (reports.kind !== "error" && reports.data && reports.data.truncated) { | ||
| parts.unshift(noticeStrip(`The last ${INVESTIGATION_HOURS} hours held more requests than one reports read returns, so older requests may show no verdict.`)); | ||
| } | ||
|
Comment on lines
+807
to
+809
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Non-blocking — the wording check you asked for in the PR body. All three notices are accurate about their own read:
One imprecision worth a word, pre-existing and only surfaced by this notice: the two reads do not cover the same set. The list read ( Cheapest honest fix is to say the window in the un-cut case too (the panel already knows |
||
| mount(state.box, parts); | ||
| } | ||
|
|
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Non-blocking (reuse): these three lines are
McpHelpers.BoundPagere-spelled —McpHelpers.cs:660-665isidentical, down to the
.Take(limit).ToList()on the truncated branch only. The body calls this "the #3699 shape", and #3699 bound its sites through that helper (McpPageContractTests.PgPagedToolsThroughTheHelper, andMcpPayloadContractCensusTests' own failure message says "fetch cap + 1, bind throughMcpHelpers.BoundPageand publishtruncated"). Behaviour is the same today, so this is a cleanup, not a defect: