feat(agent): add typed server API tools
This commit is contained in:
@@ -33,8 +33,11 @@ Agent 负责:
|
||||
| 历史会话检索 | `session_search` |
|
||||
| 用户偏好和项目事实 | `memory_manager` |
|
||||
| 可复用流程沉淀 | `skill_manager` |
|
||||
|
||||
当前实验版没有通用 TJWater 数据查询工具;如果缺少业务数据,应明确说明数据能力尚未接入,不得编造结果。
|
||||
| 项目背景 | `get_project_context` |
|
||||
| 监测设备/点位 | `list_monitoring_assets` |
|
||||
| 监测时序读数 | `query_monitoring_readings`(必须给出 `observed_from`、`observed_to`) |
|
||||
| 数据质量分析 | `start_data_quality_analysis`、`get_job_status` |
|
||||
| SWMM 仿真 | `start_simulation`、`get_job_status` |
|
||||
|
||||
## UI 约束
|
||||
|
||||
@@ -58,3 +61,18 @@ Agent 负责:
|
||||
## 记忆持久化
|
||||
|
||||
`memory_manager` 只保存长期有效的稳定事实或用户偏好。修改 memory 前先 list 当前 scope,再决定 add、replace 或 remove。
|
||||
## TJWater Server 受控领域工具
|
||||
|
||||
仅通过领域工具访问 Server;不得构造 URL、HTTP header、SQL、命令或项目 ID。
|
||||
|
||||
- 项目背景:`get_project_context`
|
||||
- 设备/监测点:`list_monitoring_assets`
|
||||
- 时序读数:`query_monitoring_readings`
|
||||
- 数据质量任务:`start_data_quality_analysis`(写操作,必须等待审批)
|
||||
- 仿真任务:`start_simulation`(写操作,必须等待审批)
|
||||
- 任务状态:`get_job_status`
|
||||
|
||||
查询历史监测数据时,必须先明确时间区间;不清楚区间时先追问,不得省略或自行扩大范围。需要数值结论时先调用 `query_monitoring_readings`,传入 `observed_from`、`observed_to`、`granularity`、`metrics` 和设备 ID,再调用 `show_chart` 或 `view_history` 展示。`view_history` 只负责打开前端历史面板,也必须传入 `start_time`、`end_time`。
|
||||
先查询数据再作判断。回答必须说明查询时间范围、粒度、指标,以及已创建任务的 ID 和状态。
|
||||
遇到空数据、拒绝、权限错误、超时或服务不可用时,明确说明事实,不得补全或猜测结果。
|
||||
工具返回 `result_ref` 时,说明完整结果已安全存储,并使用 preview 中的样本和统计作答。
|
||||
|
||||
@@ -9,4 +9,6 @@ export const frontendActionCallIdPlugin: Plugin = async () => ({
|
||||
},
|
||||
});
|
||||
|
||||
export const server = frontendActionCallIdPlugin;
|
||||
|
||||
export default frontendActionCallIdPlugin;
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
import { tool } from "@opencode-ai/plugin";
|
||||
import { callServerApiTool } from "./server_api_shared.js";
|
||||
export default tool({ description: "读取分析或仿真任务的状态。", args: { job_id: tool.schema.string().uuid(), job_type: tool.schema.enum(["analysis", "simulation"]) }, execute: (args, context) => callServerApiTool("get_job_status", args, context.sessionID) });
|
||||
@@ -0,0 +1,3 @@
|
||||
import { tool } from "@opencode-ai/plugin";
|
||||
import { callServerApiTool } from "./server_api_shared.js";
|
||||
export default tool({ description: "读取当前受控项目的基本信息。", args: {}, execute: (_args, context) => callServerApiTool("get_project_context", {}, context.sessionID) });
|
||||
@@ -0,0 +1,3 @@
|
||||
import { tool } from "@opencode-ai/plugin";
|
||||
import { callServerApiTool } from "./server_api_shared.js";
|
||||
export default tool({ description: "列出当前项目的监测设备和监测点。", args: { include: tool.schema.enum(["devices", "points", "all"]).default("all") }, execute: (args, context) => callServerApiTool("list_monitoring_assets", args, context.sessionID) });
|
||||
@@ -0,0 +1,3 @@
|
||||
import { tool } from "@opencode-ai/plugin";
|
||||
import { callServerApiTool } from "./server_api_shared.js";
|
||||
export default tool({ description: "按设备、时间范围、粒度和允许指标查询监测读数。", args: { device_ids: tool.schema.array(tool.schema.string().uuid()).min(1).max(100), observed_from: tool.schema.string().datetime(), observed_to: tool.schema.string().datetime(), granularity: tool.schema.enum(["5m", "1h", "1d"]).default("5m"), metrics: tool.schema.array(tool.schema.enum(["flow_mean", "flow_total", "conductivity_mean", "velocity_mean", "temperature_mean", "level_mean"])).min(1).max(6) }, execute: (args, context) => callServerApiTool("query_monitoring_readings", args, context.sessionID) });
|
||||
@@ -0,0 +1,13 @@
|
||||
const internalBaseUrl = process.env.TJWATER_AGENT_INTERNAL_BASE_URL ?? "http://127.0.0.1:8787";
|
||||
const internalToken = process.env.TJWATER_AGENT_INTERNAL_TOKEN ?? "";
|
||||
|
||||
export const callServerApiTool = async (name: string, args: unknown, sessionID: string) => {
|
||||
const response = await fetch(`${internalBaseUrl}/internal/tools/server-api/${name}`, {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json", "x-agent-internal-token": internalToken },
|
||||
body: JSON.stringify({ session_id: sessionID, args }),
|
||||
});
|
||||
const text = await response.text();
|
||||
if (!response.ok) throw new Error("TJWater domain tool bridge rejected the request");
|
||||
return text;
|
||||
};
|
||||
@@ -0,0 +1,3 @@
|
||||
import { tool } from "@opencode-ai/plugin";
|
||||
import { callServerApiTool } from "./server_api_shared.js";
|
||||
export default tool({ description: "创建数据质量分析任务。此操作会创建后台任务,需要用户审批。", args: { device_ids: tool.schema.array(tool.schema.string().uuid()).min(1).max(100), observed_from: tool.schema.string().datetime(), observed_to: tool.schema.string().datetime() }, execute: (args, context) => callServerApiTool("start_data_quality_analysis", args, context.sessionID) });
|
||||
@@ -0,0 +1,3 @@
|
||||
import { tool } from "@opencode-ai/plugin";
|
||||
import { callServerApiTool } from "./server_api_shared.js";
|
||||
export default tool({ description: "基于已注册模型版本创建仿真任务。此操作会创建后台任务,需要用户审批。", args: { model_version_id: tool.schema.string().uuid(), parameters: tool.schema.record(tool.schema.string(), tool.schema.unknown()).default({}) }, execute: (args, context) => callServerApiTool("start_simulation", args, context.sessionID) });
|
||||
@@ -2,7 +2,7 @@ import { tool } from "@opencode-ai/plugin";
|
||||
import { executeFrontendAction } from "./frontend_action.js";
|
||||
|
||||
export default tool({
|
||||
description: "为选定的管网要素打开前端的历史记录或计算结果面板。",
|
||||
description: "为选定的管网要素打开前端的历史记录或计算结果面板;必须提供 ISO8601 时间区间 start_time 和 end_time。",
|
||||
args: {
|
||||
reason: tool.schema
|
||||
.string()
|
||||
@@ -17,12 +17,12 @@ export default tool({
|
||||
.describe("History data source type."),
|
||||
start_time: tool.schema
|
||||
.string()
|
||||
.optional()
|
||||
.describe("Optional ISO8601 start time."),
|
||||
.datetime()
|
||||
.describe("Required ISO8601 inclusive start time for the history query."),
|
||||
end_time: tool.schema
|
||||
.string()
|
||||
.optional()
|
||||
.describe("Optional ISO8601 end time."),
|
||||
.datetime()
|
||||
.describe("Required ISO8601 exclusive end time for the history query; must be after start_time."),
|
||||
},
|
||||
async execute(args, context) {
|
||||
return executeFrontendAction("view_history", args, context);
|
||||
|
||||
@@ -23,6 +23,9 @@ export default tool({
|
||||
.string()
|
||||
.optional()
|
||||
.describe("Optional ISO8601 end time."),
|
||||
result_ref: tool.schema.string().optional().describe("Authorized large monitoring result reference."),
|
||||
metrics: tool.schema.array(tool.schema.string()).optional().describe("Metrics represented by the result."),
|
||||
granularity: tool.schema.enum(["5m", "1h", "1d"]).optional().describe("Reading aggregation granularity."),
|
||||
},
|
||||
async execute(args, context) {
|
||||
return executeFrontendAction("view_scada", args, context);
|
||||
|
||||
Reference in New Issue
Block a user