Files
next-tjwater-frontend/src/features/workbench/api/operational-task-client.ts
T
jiang 692bbf609c refactor: consolidate requests and finalize agent tool states
Share project JSON transport, interaction replies and report selectors.
Settle tool progress consistently for direct streams, reconnects and history, preserving failure reasons and stopped state.
2026-11-09 17:55:00 +08:00

635 lines
26 KiB
TypeScript

import { requestWorkbenchJson } from "./request-json";
import { z } from "zod";
import { investigationReportSchema, investigationDiagramSchema } from "./investigation-report";
import { investigationPresentationCursorSchema, investigationPresentationHistoryPageSchema, type InvestigationPresentationHistoryEvent } from "./investigation-presentation";
import type { WorkbenchAccess } from "./request-context";
const taskStatusSchema = z.enum(["queued", "running", "waiting_human", "completed", "failed", "cancelled"]);
const taskPrioritySchema = z.enum(["normal", "urgent"]);
const workbenchDateTimeSchema = z.string().datetime({ offset: true });
const taskSourceSchema = z.object({
kind: z.enum(["schedule", "external_system", "operator", "agent"]),
external_id: z.string().min(1).nullable(),
external_revision: z.number().int().positive().nullable(),
event_kind: z.string().min(1).nullable(),
deleted_at: workbenchDateTimeSchema.nullish(),
replay_context: z.object({
replay_id: z.string().uuid(),
knowledge_cutoff: workbenchDateTimeSchema,
batch_sequence: z.number().int().positive()
}).strict().nullish()
}).strict();
const taskTriggerSchema = z.object({
kind: z.enum(["schedule", "external_sync", "event", "manual"]),
occurred_at: workbenchDateTimeSchema,
detail: z.string().min(1)
}).strict();
const operationalTaskRunSchema = z.object({
run_id: z.string().uuid(),
task_id: z.string().uuid(),
generation: z.number().int().positive(),
execution_request_id: z.string().uuid(),
status: z.enum(["queued", "claimed", "running", "succeeded", "failed", "timed_out", "cancelled"]),
revision: z.number().int().positive(),
agent_session_id: z.string().min(1).nullable(),
agent_instance_id: z.string().min(1).nullable().optional(),
lease_expires_at: workbenchDateTimeSchema.nullable(),
heartbeat_at: workbenchDateTimeSchema.nullable(),
started_at: workbenchDateTimeSchema.nullable(),
finished_at: workbenchDateTimeSchema.nullable(),
failure_code: z.string().min(1).nullable(),
failure_detail: z.string().min(1).nullable(),
dispatch_attempts: z.number().int().nonnegative(),
next_dispatch_at: workbenchDateTimeSchema,
created_at: workbenchDateTimeSchema,
updated_at: workbenchDateTimeSchema
}).strict();
const operationalTaskRunPageSchema = z.object({
items: z.array(operationalTaskRunSchema),
next_cursor: z.string().min(1).nullable()
}).strict();
const taskSummarySchema = z.object({
execution_scope: z.string().min(1),
handling_context: z.record(z.unknown()).optional(),
project_id: z.string().uuid(),
task_id: z.string().uuid(),
task_type: z.enum(["scheduled_flow", "external_work_order", "event_investigation"]),
workflow: z.string().min(1),
lifecycle_status: z.enum(["open", "waiting_human", "completed", "failed", "cancelled"]),
active_run: operationalTaskRunSchema.nullable(),
latest_run: operationalTaskRunSchema.nullable().optional(),
status: taskStatusSchema,
priority: taskPrioritySchema,
revision: z.number().int().positive(),
execution_generation: z.number().int().positive(),
execution_request_id: z.string().uuid(),
title: z.string().min(1),
summary: z.string().min(1),
source: taskSourceSchema,
trigger: taskTriggerSchema,
scheduled_for: workbenchDateTimeSchema.nullable(),
agent_session_id: z.string().min(1).nullable(),
agent_lease_expires_at: workbenchDateTimeSchema.nullable(),
current_plan_revision: z.number().int().positive().nullable(),
current_report_revision: z.number().int().positive().nullable(),
created_at: workbenchDateTimeSchema,
updated_at: workbenchDateTimeSchema
}).strict();
const evidenceSchema = z.object({
evidence_id: z.string().min(1),
kind: z.enum(["system_data", "external_feedback", "human_input", "synthetic"]),
summary: z.string().min(1),
source_label: z.string().min(1),
source_ref: z.string().min(1).nullable(),
observed_at: workbenchDateTimeSchema,
recorded_at: workbenchDateTimeSchema,
recorded_by: z.string().min(1),
has_snapshot: z.boolean()
}).strict();
const planNodeSchema = z.object({
id: z.string().min(1),
title: z.string().min(1),
owner: z.enum(["agent", "human"]),
status: z.enum(["pending", "waiting", "running", "completed", "failed", "skipped", "cancelled"]),
detail: z.string().min(1),
evidence_refs: z.array(z.string().min(1)),
action_refs: z.array(z.string().uuid()),
kind: z.enum(["activity", "decision", "parallel_split", "parallel_join", "gate"]).nullish(),
selected_edge_id: z.string().min(1).nullish(),
gate_ref: z.string().uuid().nullish(),
revisits_node_id: z.string().min(1).nullish()
}).strict();
const planInputSchema = z.object({
schema: z.enum(["execution-plan@1", "execution-plan@2"]),
title: z.string().min(1),
reason: z.string().min(1),
nodes: z.array(planNodeSchema).min(1).max(100),
edges: z.array(z.object({
id: z.string().min(1).nullish(),
from: z.string().min(1),
to: z.string().min(1),
condition: z.string().min(1).nullable()
}).strict()).max(300)
}).strict();
const planSnapshotSchema = z.object({
revision: z.number().int().positive(),
execution_generation: z.number().int().positive().nullish(),
source_session_id: z.string().min(1),
published_at: workbenchDateTimeSchema,
published_by: z.string().min(1),
plan: planInputSchema
}).strict();
const reportInputSchema = investigationReportSchema;
const reportRevisionSchema = z.object({
revision: z.number().int().positive(),
execution_generation: z.number().int().positive().nullish(),
source_session_id: z.string().min(1),
published_at: workbenchDateTimeSchema,
published_by: z.string().min(1),
report: reportInputSchema
}).strict();
const progressSnapshotSchema = z.object({
revision: z.number().int().positive(),
run_id: z.string().uuid(),
execution_generation: z.number().int().positive(),
published_at: workbenchDateTimeSchema,
source_session_id: z.string().min(1),
progress: z.object({ summary: z.string().trim().min(1), diagram: investigationDiagramSchema.nullable() }).strict()
}).strict();
const reportPageSchema = z.object({
items: z.array(reportRevisionSchema),
next_offset: z.number().int().nonnegative().nullable(),
}).strict();
const actionReceiptSchema = z.object({
adapter: z.string().min(1),
receipt_id: z.string().min(1),
submitted_at: workbenchDateTimeSchema,
completed_at: workbenchDateTimeSchema.nullable(),
external_status: z.string().min(1),
detail: z.string().min(1)
}).strict();
const actionSchema = z.object({
action_id: z.string().uuid(),
task_id: z.string().uuid(),
version: z.number().int().positive(),
kind: z.enum(["create_work_order", "issue_command"]),
reason: z.string().min(1),
payload: z.record(z.string(), z.unknown()),
evidence_refs: z.array(z.string().min(1)),
node_id: z.string().min(1).nullable(),
required_approval_permission: z.string().min(1),
required_execution_permission: z.string().min(1),
approval_status: z.enum(["pending", "approved", "rejected"]),
execution_status: z.enum(["not_submitted", "submitted", "succeeded", "failed", "unsupported", "unknown"]),
execution_request_id: z.string().uuid().nullable(),
proposed_by: z.string().min(1),
proposed_at: workbenchDateTimeSchema,
edited_by: z.string().min(1).nullish(),
edited_at: workbenchDateTimeSchema.nullish(),
decided_by: z.string().min(1).nullable(),
decided_at: workbenchDateTimeSchema.nullable(),
decision_comment: z.string().min(1).nullable(),
executed_by: z.string().min(1).nullable(),
executed_at: workbenchDateTimeSchema.nullable(),
receipt: actionReceiptSchema.nullable(),
execution_detail: z.string().min(1).nullable()
}).strict();
const accessRequestSchema = z.object({
access_request_id: z.string().uuid(),
task_id: z.string().uuid(),
node_id: z.string().min(1),
scopes: z.array(z.string().min(1)),
reason: z.string().min(1),
status: z.enum(["pending", "approved", "rejected"]),
approved_scopes: z.array(z.string().min(1)),
version: z.number().int().positive(),
requested_by: z.string().min(1),
requested_at: workbenchDateTimeSchema,
decided_by: z.string().min(1).nullable(),
decided_at: workbenchDateTimeSchema.nullable(),
comment: z.string().min(1).nullable()
}).strict();
const taskPermissionsSchema = z.object({
can_publish_artifacts: z.boolean(),
can_propose_actions: z.boolean(),
can_sync_external_feedback: z.boolean(),
can_decide_work_orders: z.boolean(),
can_execute_work_orders: z.boolean(),
can_decide_commands: z.boolean(),
can_execute_commands: z.boolean(),
can_answer_questions: z.boolean().optional(),
can_decide_access: z.boolean().default(false)
}).strict();
const externalWorkOrderActivitySchema = z.object({
sequence: z.number().int().positive(),
occurred_at: workbenchDateTimeSchema,
actor: z.string().min(1),
kind: z.enum(["created", "updated", "feedback"]),
title: z.string().min(1),
detail: z.string().min(1)
}).strict();
const externalWorkOrderSnapshotSchema = z.preprocess((value) => {
if (value && typeof value === "object" && !Array.isArray(value)) {
const { subtasks: _legacySubtasks, ...flat } = value as Record<string, unknown>;
return flat;
}
return value;
}, z.object({
work_order_id: z.string().uuid(),
revision: z.number().int().positive(),
title: z.string().min(1),
summary: z.string().min(1),
status: z.enum(["draft", "open", "in_progress", "awaiting_reply", "completed", "cancelled"]),
priority: z.enum(["low", "normal", "high", "urgent"]),
assignee: z.string().min(1).nullable(),
scheduled_at: workbenchDateTimeSchema.nullable(),
work_order_type: z.enum(["general", "water_quality_complaint", "burst_report"]),
location: z.string().min(1).nullable(),
scenario_code: z.string().min(1).nullable(),
feedback_requirements: z.array(z.string().min(1)).default([]),
activity: z.array(externalWorkOrderActivitySchema).default([]),
origin: z.literal("system_data"),
updated_at: workbenchDateTimeSchema
}).strict());
const taskQuestionAnswerSchema = z.object({ question_id: z.string().min(1).max(128),
selected_option_ids: z.array(z.string().min(1).max(128)).max(12), custom_text: z.string().max(2000) }).strict();
const taskQuestionRequestSchema = z.object({
question_request_id: z.string().uuid(), task_id: z.string().uuid(), run_id: z.string().uuid(),
execution_generation: z.number().int().positive(), source_session_id: z.string(),
status: z.enum(["pending", "answered", "cancelled"]), version: z.number().int().positive(),
created_at: workbenchDateTimeSchema, answered_at: workbenchDateTimeSchema.nullable(), answered_by: z.string().nullable(),
questions: z.array(z.object({ question_id: z.string().min(1).max(128), title: z.string().min(1).max(200), body: z.string().min(1).max(2000),
options: z.array(z.object({ id: z.string().min(1).max(128), label: z.string().min(1).max(200) }).strict()).max(12),
mode: z.enum(["single", "multiple"]), allow_custom: z.boolean(), required: z.boolean() }).strict()).min(1).max(3),
answers: z.array(taskQuestionAnswerSchema).max(3)
}).strict();
export type TaskQuestionRequest = z.infer<typeof taskQuestionRequestSchema>;
export type TaskQuestionAnswer = z.infer<typeof taskQuestionAnswerSchema>;
export type AnswerTaskQuestion = (questionId: string, version: number, answers: TaskQuestionAnswer[], requestId: string) => Promise<unknown>;
const operationalTaskSchema = taskSummarySchema.extend({
latest_plan: planSnapshotSchema.nullable(),
latest_report: reportRevisionSchema.nullable(),
latest_progress: progressSnapshotSchema.nullish(),
evidence: z.array(evidenceSchema),
actions: z.array(actionSchema),
access_requests: z.array(accessRequestSchema).default([]),
questions: z.array(taskQuestionRequestSchema).optional(),
permissions: taskPermissionsSchema,
work_order_snapshot: externalWorkOrderSnapshotSchema.nullable().default(null)
}).strict();
const notificationSchema = z.object({
notification_id: z.string().uuid(),
task_id: z.string().uuid(),
kind: z.enum([
"task_created",
"action_pending",
"report_updated",
"task_completed",
"task_failed",
"run_delivery_degraded",
"access_approval_pending",
"action_approval_pending",
"human_input_required",
"external_coordination_failed"
]),
title: z.string().min(1),
description: z.string().min(1),
lifecycle_status: z.enum(["active", "resolved"]).default("active"),
subject_type: z.enum(["task", "run", "access_request", "action", "question"]).default("task"),
subject_id: z.string().uuid().nullable().default(null),
report_reference: z.object({ execution_generation: z.number().int().positive(), revision: z.number().int().positive() }).strict().nullish(),
resolved_at: workbenchDateTimeSchema.nullable().default(null),
resolution_reason: z.string().min(1).nullable().default(null),
status: z.enum(["unread", "read"]),
version: z.number().int().positive(),
required_permission: z.string().min(1).nullable(),
created_at: workbenchDateTimeSchema,
read_at: workbenchDateTimeSchema.nullable(),
read_by: z.string().min(1).nullable()
}).strict();
const notificationPageSchema = z.object({
items: z.array(notificationSchema),
limit: z.number().int().positive(),
offset: z.number().int().nonnegative(),
next_offset: z.number().int().nonnegative().nullable()
}).strict();
const scheduleSchema = z.object({
schedule_id: z.string().uuid(),
schedule_key: z.string().min(1),
title: z.string().min(1),
summary: z.string().min(1),
interval_seconds: z.number().int().min(60).max(31_536_000),
next_run_at: workbenchDateTimeSchema,
priority: taskPrioritySchema,
enabled: z.boolean(),
version: z.number().int().positive(),
created_at: workbenchDateTimeSchema,
updated_at: workbenchDateTimeSchema
}).strict();
const schedulePageSchema = z.object({ items: z.array(scheduleSchema) }).strict();
const taskDataSnapshotSchema = z.object({
// Snapshot sources include product MCP queries; access-request scopes remain unchanged.
source: z.enum(["workbench_runtime", "scada_devices", "scada_readings", "peripheral_points", "peripheral_work_orders", "peripheral_observations", "peripheral_test_data",
"get_analysis_run",
"get_element_gis_properties",
"get_element_properties",
"get_model_baseline_at_time",
"get_network_options",
"get_network_schema",
"get_scada_device",
"get_sensor_placement_run",
"get_source_gis_properties",
"get_task_context",
"get_task_evidence",
"get_workbench_runtime",
"list_analysis_results",
"list_analysis_runs",
"list_elements",
"list_scada_devices",
"list_sensor_placement_runs",
"query_analysis_series",
"query_analysis_values",
"query_element_history",
"query_model_baseline_field",
"query_model_baseline_series",
"query_peripheral_data",
"query_scada_readings",
"run_burst_detection",
"run_simulation",
"run_contaminant_simulation",
"analyze_valve_closure",
"analyze_flushing",
"analyze_pressure_regulation",
"optimize_sensor_placement",
"run_burst_location",
"analyze_valve_isolation",
"run_leakage_identification",
"get_mutation_status",
"query_nearby_elements",
"list_regions",
"get_region",
"get_region_nodes",
"get_node_connections",
"query_network_extent",
"list_major_nodes",
"get_model_configuration",
"list_model_configurations",
"search_project_places",
"reverse_geocode",
"get_project_info",
"export_project_model",
"get_sensor_placement_candidate",
"export_sensor_placement",
"list_task_schedules",
"get_task_run_history",
"calculate_demand_allocation",
"run_burst_simulation",
"edit_model_element",
"edit_model_configuration",
"clean_scada_readings",
"write_scada_readings",
"delete_scada_readings",
"save_simulation_scenario",
"create_sensor_placement",
"update_sensor_placement",
"create_operational_task",
"create_task_schedule",
"update_task_schedule",
"retry_operational_task",
"cancel_task_run",
]),
source_ref: z.string().min(1),
queried_at: workbenchDateTimeSchema,
origin: z.enum(["system_data", "synthetic"]),
data: z.unknown(),
truncated: z.boolean()
}).strict();
export type OperationalTaskSummary = z.infer<typeof taskSummarySchema>;
export type OperationalTask = z.infer<typeof operationalTaskSchema>;
export type OperationalTaskRun = z.infer<typeof operationalTaskRunSchema>;
export type TaskExecutionHistoryTarget = {
executionGeneration: number | null;
sessionId: string;
};
export type OperationalTaskPlan = z.infer<typeof planInputSchema>;
export type OperationalTaskAction = z.infer<typeof actionSchema>;
export type OperationalTaskAccessRequest = z.infer<typeof accessRequestSchema>;
export type OperationalTaskEvidence = z.infer<typeof evidenceSchema>;
export type OperationalTaskNotification = z.infer<typeof notificationSchema>;
export type OperationalTaskReport = z.infer<typeof reportRevisionSchema>;
export type OperationalTaskReportPage = z.infer<typeof reportPageSchema>;
export type OperationalTaskProgress = z.infer<typeof progressSnapshotSchema>;
export type OperationalTaskSchedule = z.infer<typeof scheduleSchema>;
export type OperationalTaskDataSnapshot = z.infer<typeof taskDataSnapshotSchema>;
export type ExternalWorkOrderSnapshot = z.infer<typeof externalWorkOrderSnapshotSchema>;
export type OperationalTaskDecision = "approved" | "rejected";
export function parseOperationalTask(value: unknown) {
return operationalTaskSchema.parse(value);
}
export function parseOperationalTaskSummary(value: unknown) {
return taskSummarySchema.parse(value);
}
export function parseOperationalTaskNotification(value: unknown) {
return notificationSchema.parse(value);
}
export type CreateOperationalTaskInput = {
request_id: string;
task_type: OperationalTask["task_type"];
workflow: string;
title: string;
summary: string;
priority: OperationalTask["priority"];
source: OperationalTask["source"];
trigger: OperationalTask["trigger"];
scheduled_for?: string;
agent_session_id?: string;
};
async function operationalTaskRequest(path: string, getAccessToken?: WorkbenchAccess, init?: RequestInit) {
return requestWorkbenchJson(`/api/v1${path}`, "工况任务请求", { access: getAccessToken, init });
}
export async function fetchOperationalTask(taskId: string, getAccessToken?: WorkbenchAccess, signal?: AbortSignal) {
return operationalTaskSchema.parse(await operationalTaskRequest(
`/operational-tasks/${encodeURIComponent(taskId)}`,
getAccessToken,
{ signal }
));
}
export async function fetchOperationalTaskReports(taskId: string, offset: number, getAccessToken?: WorkbenchAccess) {
return reportPageSchema.parse(await operationalTaskRequest(
`/operational-tasks/${encodeURIComponent(taskId)}/reports?limit=20&offset=${offset}`, getAccessToken,
));
}
export async function fetchOperationalTaskRuns(taskId: string, getAccessToken?: WorkbenchAccess) {
const runs: OperationalTaskRun[] = [];
const limit = 100;
for (let offset = 0; ; offset += limit) {
const page = operationalTaskRunPageSchema.parse(await operationalTaskRequest(
`/operational-tasks/${encodeURIComponent(taskId)}/runs?limit=${limit}&offset=${offset}`, getAccessToken,
));
runs.push(...page.items);
if (page.items.length < limit) return runs;
}
}
export async function fetchOperationalTaskPresentationCursor(taskId: string, getAccessToken?: WorkbenchAccess, signal?: AbortSignal) {
return investigationPresentationCursorSchema.parse(await operationalTaskRequest(
`/operational-tasks/${encodeURIComponent(taskId)}/presentation-cursor`, getAccessToken, { signal }
));
}
export async function fetchOperationalTaskPresentationHistory(
taskId: string,
through: number,
getAccessToken?: WorkbenchAccess,
signal?: AbortSignal
) {
const items: InvestigationPresentationHistoryEvent[] = [];
let after = 0;
while (true) {
signal?.throwIfAborted();
const page = investigationPresentationHistoryPageSchema.parse(
await operationalTaskRequest(
`/operational-tasks/${encodeURIComponent(taskId)}/presentation-events?after=${after}&through=${through}&limit=100`,
getAccessToken,
{ signal }
)
);
if (page.task_id !== taskId || page.event_cursor !== through)
throw new Error("调查展示历史与所选任务或游标不一致");
let previous = after;
for (const item of page.items) {
if (item.event_seq <= previous || item.event_seq > through)
throw new Error("调查展示历史顺序不合法");
previous = item.event_seq;
items.push({ ...item, task_id: taskId });
}
if (page.next_after === null) return items;
if (page.next_after !== previous || previous <= after)
throw new Error("调查展示历史分页没有前进");
after = previous;
}
}
export async function createOperationalTask(input: CreateOperationalTaskInput, getAccessToken?: WorkbenchAccess) {
return operationalTaskSchema.parse(await operationalTaskRequest(
"/operational-tasks",
getAccessToken,
{ method: "POST", body: JSON.stringify(input) }
));
}
export async function decideOperationalTaskAction(taskId: string, actionId: string, input: {
request_id: string;
expected_version: number;
decision: OperationalTaskDecision;
comment?: string;
}, getAccessToken?: WorkbenchAccess) {
return actionSchema.parse(await operationalTaskRequest(
`/operational-tasks/${encodeURIComponent(taskId)}/actions/${encodeURIComponent(actionId)}/decision`,
getAccessToken,
{ method: "POST", body: JSON.stringify(input) }
));
}
export async function executeOperationalTaskAction(taskId: string, actionId: string, input: {
request_id: string;
expected_version: number;
}, getAccessToken?: WorkbenchAccess) {
return actionSchema.parse(await operationalTaskRequest(
`/operational-tasks/${encodeURIComponent(taskId)}/actions/${encodeURIComponent(actionId)}/execute`,
getAccessToken,
{ method: "POST", body: JSON.stringify(input) }
));
}
export async function updateOperationalWorkOrderDraft(taskId: string, actionId: string, input: {
request_id: string; expected_version: number; payload: Record<string, unknown>;
}, getAccessToken?: WorkbenchAccess) {
return actionSchema.parse(await operationalTaskRequest(
`/operational-tasks/${encodeURIComponent(taskId)}/actions/${encodeURIComponent(actionId)}/draft`,
getAccessToken, { method: "PATCH", body: JSON.stringify(input) }
));
}
export async function confirmOperationalWorkOrderDispatch(taskId: string, actionId: string, input: {
request_id: string; expected_version: number;
}, getAccessToken?: WorkbenchAccess) {
return actionSchema.parse(await operationalTaskRequest(
`/operational-tasks/${encodeURIComponent(taskId)}/actions/${encodeURIComponent(actionId)}/confirm-dispatch`,
getAccessToken, { method: "POST", body: JSON.stringify(input) }
));
}
export async function decideOperationalTaskAccess(taskId: string, accessRequestId: string, input: {
request_id: string; expected_version: number; decision: "approved" | "rejected";
approved_scopes: string[]; comment?: string;
}, getAccessToken?: WorkbenchAccess) {
return accessRequestSchema.parse(await operationalTaskRequest(
`/operational-tasks/${encodeURIComponent(taskId)}/access-requests/${encodeURIComponent(accessRequestId)}/decision`,
getAccessToken, { method: "POST", body: JSON.stringify(input) }
));
}
export async function fetchOperationalTaskNotifications(getAccessToken?: WorkbenchAccess, signal?: AbortSignal) {
return notificationPageSchema.parse(await operationalTaskRequest(
"/operational-task-notifications?unread_only=false&limit=100&offset=0",
getAccessToken,
{ signal }
)).items;
}
export async function acknowledgeOperationalTaskNotification(notificationId: string, version: number, requestId: string, getAccessToken?: WorkbenchAccess) {
return notificationSchema.parse(await operationalTaskRequest(
`/operational-task-notifications/${encodeURIComponent(notificationId)}/acknowledge`,
getAccessToken,
{ method: "POST", body: JSON.stringify({ request_id: requestId, expected_version: version }) }
));
}
export async function fetchOperationalTaskSchedules(getAccessToken?: WorkbenchAccess, signal?: AbortSignal) {
return schedulePageSchema.parse(await operationalTaskRequest(
"/operational-tasks/schedules",
getAccessToken,
{ signal }
)).items;
}
export async function createOperationalTaskSchedule(input: {
request_id: string;
schedule_key: string;
title: string;
summary: string;
interval_seconds: number;
next_run_at: string;
priority: "normal" | "urgent";
}, getAccessToken?: WorkbenchAccess) {
return scheduleSchema.parse(await operationalTaskRequest(
"/operational-tasks/schedules",
getAccessToken,
{ method: "POST", body: JSON.stringify(input) }
));
}
export async function reconcileOperationalTaskAction(taskId: string, actionId: string, input: {
request_id: string;
expected_version: number;
}, getAccessToken?: WorkbenchAccess) {
return actionSchema.parse(await operationalTaskRequest(
`/operational-tasks/${encodeURIComponent(taskId)}/actions/${encodeURIComponent(actionId)}/reconcile`,
getAccessToken,
{ method: "POST", body: JSON.stringify(input) }
));
}
export async function fetchOperationalTaskEvidenceSnapshot(taskId: string, evidenceId: string, getAccessToken?: WorkbenchAccess) {
return taskDataSnapshotSchema.parse(await operationalTaskRequest(
`/operational-tasks/${encodeURIComponent(taskId)}/evidence/${encodeURIComponent(evidenceId)}/snapshot`,
getAccessToken
));
}
export function createOperationalRequestId() {
return crypto.randomUUID();
}
export async function answerOperationalTaskQuestion(taskId: string, questionId: string,
version: number, answers: TaskQuestionAnswer[], requestId: string, getAccessToken?: WorkbenchAccess) {
return operationalTaskSchema.parse(await operationalTaskRequest(
`/operational-tasks/${encodeURIComponent(taskId)}/questions/${encodeURIComponent(questionId)}/answer`,
getAccessToken, { method: "POST", body: JSON.stringify({ request_id: requestId,
expected_version: version, answers: z.array(taskQuestionAnswerSchema).max(3).parse(answers) }) }
));
}