26 lines
3.9 KiB
TypeScript
26 lines
3.9 KiB
TypeScript
import { tool } from "../tool.js";
|
|
import { getInternalBridgeConfig } from "../internalBridge.js";
|
|
import { taskPresentationCommandSchema } from "../../src/product/task-presentation.js";
|
|
import { taskPublicationCommandSchema } from "./task-publication-schema.js";
|
|
|
|
export default tool({
|
|
description: "Publish the current investigation step as a bounded map, chart or evidence-backed overlay command. Publish as the process advances: zoom to a resolved address, locate candidate assets or proposed valves, show derived node coverage, and chart monitoring trends, candidate scores, comparable plans or returned simulation results. Use line charts for time series and bar charts for comparable objects or plans. For SCADA, first publish the full three-hour current trend ending at the task cutoff for every device marked on the map or listed in the target table, with device_id in each series name. Publish pressure and flow separately. Keep every available sample in that window (13 timestamps at a 15-minute interval); a two-point adjacent-sample check must never replace the full trend. Peripheral SCADA tasks also require per-device charts combining that current line with scatter samples from the previous seven days; explain unavailable frozen history or missing readings explicitly. Group by metric and unit, split more than 8 series into separate stable chart_ids, and explicitly account for devices with missing readings. Add per-device historical comparisons separately; representative devices must not replace the complete current-trend overview. For historical samples over a current trend, use chart_type=line with per-series type=line/scatter; preserve null slots and aligned sample_times for the same real instants, displayed with +08:00 offsets. Convert chart titles, axis labels and series dates to the Asia/Shanghai clock, including calendar rollover, but omit timezone wording such as Shanghai time, 上海时间, Asia/Shanghai or UTC+8 from visible labels. Name the time axis 时间. Keep explicit offsets in sample_times. Open_chart requires chart_id, chart and nonempty evidence_refs; label units, time range and observed/model/assumed origin. Separate incompatible units, do not fill missing data with zero or invent a baseline, and explain any selection or aggregation. Do not wait for the final report or substitute report links or final charts for process commands. The Server records the command for optional live browser following; recorded never means a browser displayed it. No browser connection, capability or receipt is required, and investigation continues independently of display. Chart data must reflect the referenced persisted evidence. Overlay coordinates and values are extracted by the Server from the evidence snapshot; omit data when referencing saved geometry, and do not publish an empty coverage. Any supplied data is validated against the evidence snapshot. Never supply invented geometry or arbitrary code. Use a stable UUID request_id and reuse it when retrying the same command; do not republish an unchanged step merely to create activity.",
|
|
args: {
|
|
request_id: tool.schema.string().uuid().describe("Stable UUID idempotency key; reuse for retries of this command"),
|
|
command: taskPublicationCommandSchema,
|
|
},
|
|
async execute(args, context) {
|
|
const command = taskPresentationCommandSchema.parse(args.command);
|
|
const { baseUrl, internalToken } = getInternalBridgeConfig();
|
|
const response = await fetch(`${baseUrl}/internal/operational-task/presentation`, {
|
|
method: "POST",
|
|
headers: { "Content-Type": "application/json", "x-agent-internal-token": internalToken },
|
|
signal: context.signal,
|
|
body: JSON.stringify({ session_id: context.sessionID, request_id: args.request_id, command }),
|
|
});
|
|
const text = await response.text();
|
|
if (!response.ok) throw new Error(`task presentation publish failed (${response.status}): ${text}`);
|
|
return text;
|
|
},
|
|
});
|