chore: disable external and frontend tools

This commit is contained in:
2026-07-20 17:27:46 +08:00
parent c6231f7b00
commit 72019ac1f2
31 changed files with 63 additions and 899 deletions
-27
View File
@@ -1,27 +0,0 @@
type FrontendActionArgs = Record<string, unknown> & { __frontend_action_call_id?: string; reason?: string };
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 executeFrontendAction = async (
name: string,
args: FrontendActionArgs,
context: { sessionID: string },
) => {
const callId = args.__frontend_action_call_id;
if (!callId) throw new Error("frontend action bridge did not inject the OpenCode call ID");
const { __frontend_action_call_id: _callId, reason, ...params } = args;
let response: Response;
try {
response = await fetch(`${internalBaseUrl}/internal/frontend-actions/request`, {
method: "POST",
headers: { "Content-Type": "application/json", "x-agent-internal-token": internalToken },
body: JSON.stringify({ session_id: context.sessionID, call_id: callId, name, params, fallback_text: reason }),
});
} catch (error) {
throw new Error(`frontend action bridge unavailable: ${error instanceof Error ? error.message : String(error)}`);
}
const text = await response.text();
if (!response.ok) throw new Error(`frontend action bridge rejected request (${response.status}): ${text}`);
return text;
};
-37
View File
@@ -1,37 +0,0 @@
import { tool } from "@opencode-ai/plugin";
const internalBaseUrl =
process.env.TJWATER_AGENT_INTERNAL_BASE_URL ?? "http://127.0.0.1:8787";
const internalToken = process.env.TJWATER_AGENT_INTERNAL_TOKEN ?? "";
export default tool({
description:
"调用 TJWater 后端的天地图地理编码服务,将中国境内结构化地址或地点名称转换为经纬度。若需缩放地图,把返回的 location.lon/location.lat 传给 zoom_to_map,并设置 source_crs='EPSG:4326'。",
args: {
reason: tool.schema
.string()
.describe("Why geocoding is required for the current user request."),
keyword: tool.schema
.string()
.describe("Address or place name to geocode, such as 北京市人民政府."),
},
async execute(args, context) {
const response = await fetch(`${internalBaseUrl}/internal/tools/geocode`, {
method: "POST",
headers: {
"Content-Type": "application/json",
"x-agent-internal-token": internalToken,
},
body: JSON.stringify({
session_id: context.sessionID,
keyword: args.keyword,
}),
});
const text = await response.text();
if (!response.ok) {
throw new Error(text);
}
return text;
},
});
-3
View File
@@ -1,3 +0,0 @@
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) });
-10
View File
@@ -1,10 +0,0 @@
import { tool } from "@opencode-ai/plugin";
import { callServerApiTool } from "./server_api_shared.js";
export default tool({
description:
"列出当前项目可查询的 SCADA 资产。无请求参数;返回 assets 数组,包含 assets[].scada_id、external_id、site_external_id、name、kind、active。后续查询读数时必须使用 assets[].scada_id 作为 query_scada_readings.asset_ids;不要使用 GeoServer feature id/fid。",
args: {},
execute: (args, context) =>
callServerApiTool("list_scada_assets", args, context.sessionID),
});
-50
View File
@@ -1,50 +0,0 @@
import { tool } from "@opencode-ai/plugin";
import { callServerApiTool } from "./server_api_shared.js";
export default tool({
description:
"查询一个或多个 SCADA 资产在指定时间范围内的时序读数。调用前通常先用 list_scada_assets 获取资产 id;必须给出明确的 observed_from 和 observed_to,不要省略或自行扩大时间范围。",
args: {
asset_ids: tool.schema
.array(tool.schema.string().uuid())
.min(1)
.max(100)
.describe(
"SCADA asset UUID 数组,1 到 100 个。必须使用 list_scada_assets 返回的 assets[].scada_id,不要使用 GeoServer feature id/fid、external_id 或 site_external_id。",
),
observed_from: tool.schema
.string()
.datetime()
.describe(
"查询开始时间,ISO8601 datetime 字符串,必须包含时区,例如 2026-04-10T07:15:00Z 或 2026-04-10T15:15:00+08:00。包含该时刻。",
),
observed_to: tool.schema
.string()
.datetime()
.describe(
"查询结束时间,ISO8601 datetime 字符串,必须包含时区,且必须晚于 observed_from。服务端按半开区间处理:observed_at >= observed_from 且 observed_at < observed_to。",
),
granularity: tool.schema
.enum(["5m", "1h", "1d"])
.default("5m")
.describe(
"读数粒度:5m 为原始 5 分钟读数,1h 为小时聚合,1d 为日聚合。未指定时默认 5m。",
),
metrics: tool.schema
.array(
tool.schema.enum([
"conductivity_mean",
"level_mean",
"flow_mean",
"temperature_mean",
]),
)
.min(1)
.max(4)
.describe(
"要返回的指标数组,1 到 4 个。允许值:conductivity_mean(电导率均值)、level_mean(液位均值)、flow_mean(流量均值)、temperature_mean(温度均值)。",
),
},
execute: (args, context) =>
callServerApiTool("query_scada_readings", args, context.sessionID),
});
-13
View File
@@ -1,13 +0,0 @@
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;
};
-62
View File
@@ -1,62 +0,0 @@
import { tool } from "@opencode-ai/plugin";
const internalBaseUrl =
process.env.TJWATER_AGENT_INTERNAL_BASE_URL ?? "http://127.0.0.1:8787";
const internalToken = process.env.TJWATER_AGENT_INTERNAL_TOKEN ?? "";
export default tool({
description:
"调用 TJWater 后端的实时网页搜索服务。适合查询新闻、政策、规范、产品资料、公开网页事实等可能变化的信息。",
args: {
reason: tool.schema
.string()
.describe("Why web search is required for the current user request."),
query: tool.schema.string().describe("Search query text."),
freshness: tool.schema
.enum(["no_limit", "one_day", "one_week", "one_month", "one_year"])
.optional()
.describe("Optional freshness filter. Defaults to no_limit."),
summary: tool.schema
.boolean()
.optional()
.describe("Whether the backend should include page summaries."),
count: tool.schema
.number()
.int()
.positive()
.optional()
.describe("Optional result count, backend accepts 1 to 50."),
include: tool.schema
.array(tool.schema.string())
.optional()
.describe("Optional domains to include."),
exclude: tool.schema
.array(tool.schema.string())
.optional()
.describe("Optional domains to exclude."),
},
async execute(args, context) {
const response = await fetch(`${internalBaseUrl}/internal/tools/web-search`, {
method: "POST",
headers: {
"Content-Type": "application/json",
"x-agent-internal-token": internalToken,
},
body: JSON.stringify({
session_id: context.sessionID,
query: args.query,
freshness: args.freshness,
summary: args.summary,
count: args.count,
include: args.include,
exclude: args.exclude,
}),
});
const text = await response.text();
if (!response.ok) {
throw new Error(text);
}
return text;
},
});
-33
View File
@@ -1,33 +0,0 @@
import { tool } from "@opencode-ai/plugin";
import { executeFrontendAction } from "./frontend_action.js";
export default tool({
description:
"在前端地图上缩放定位到坐标。默认坐标为 EPSG:3857;如果来自天地图 geocode 的 lon/lat,传 source_crs='EPSG:4326',前端会转换为 EPSG:3857 后缩放。",
args: {
reason: tool.schema
.string()
.describe("Why this map zoom action is needed for the current request."),
x: tool.schema
.number()
.describe("X coordinate. For EPSG:4326 this is longitude; for EPSG:3857 this is meters."),
y: tool.schema
.number()
.describe("Y coordinate. For EPSG:4326 this is latitude; for EPSG:3857 this is meters."),
source_crs: tool.schema
.enum(["EPSG:3857", "EPSG:4326"])
.optional()
.describe("Input coordinate CRS. Defaults to EPSG:3857."),
zoom: tool.schema
.number()
.optional()
.describe("Optional OpenLayers zoom level. Defaults to 18."),
duration_ms: tool.schema
.number()
.optional()
.describe("Optional animation duration in milliseconds. Defaults to 1000."),
},
async execute(args, context) {
return executeFrontendAction("zoom_to_map", args, context);
},
});