From d6efb180dd7d41d04e870f54720d47dceaaae307 Mon Sep 17 00:00:00 2001 From: lik Date: Wed, 9 Sep 2026 17:36:25 +0800 Subject: [PATCH] tmp --- .../bot-escort-admin}/agent.js | 0 .../bot-escort-admin}/prompts.js | 0 agent/{escort => bots/bot-escort}/AGENTS.md | 0 agent/{escort => bots/bot-escort}/agent.js | 0 agent/{escort => bots/bot-escort}/prompts.js | 0 agent/{escort => bots/bot-escort}/task.js | 0 agent/escort-admin/tools/index.js | 26 -- agent/escort/skills/baidu-ai-map/SKILL.md | 243 ----------------- agent/escort/skills/baidu-ai-map/_meta.json | 6 - agent/escort/tools/calendar/calendar_info.js | 42 --- .../tools/calendar/lunar_calendar_info.js | 62 ----- agent/escort/tools/calendar/utils.js | 87 ------ agent/escort/tools/calendar/year_holidays.js | 52 ---- agent/escort/tools/calendar/year_terms.js | 46 ---- agent/escort/tools/db/escort_record_set.js | 117 -------- agent/escort/tools/geo/latlon.js | 40 --- agent/escort/tools/system/envs.js | 83 ------ agent/escort/tools/system/fs_info.js | 257 ------------------ agent/escort/tools/system/hardware_info.js | 112 -------- .../escort/tools/system/installed_software.js | 101 ------- agent/escort/tools/system/os_info.js | 89 ------ agent/escort/tools/system/os_network_info.js | 242 ----------------- agent/escort/tools/system/os_socket_info.js | 157 ----------- agent/escort/tools/system/system_time.js | 17 -- agent/escort/tools/web/fetch.js | 35 --- agent/escort/tools/web/http_get.js | 62 ----- agent/escort/tools/web/http_post.js | 88 ------ agent/escort/tools/web/search.js | 36 --- .../skills/baidu-ai-map/SKILL.md | 0 .../skills/baidu-ai-map/_meta.json | 0 .../skills/medical-escort-standard/SKILL.md | 0 .../medical-escort-standard/standard.md | 0 .../tools/calendar/calendar_info.js | 0 .../tools/calendar/lunar_calendar_info.js | 0 .../tools/calendar/utils.js | 0 .../tools/calendar/year_holidays.js | 0 .../tools/calendar/year_terms.js | 0 .../tools/db/escort_record_query.js | 0 .../tools/db/escort_record_query_admin.js} | 0 .../tools/db/escort_record_set.js | 0 .../tools/geo/latlon.js | 0 agent/{escort => infra}/tools/index.js | 0 .../tools/system/envs.js | 0 .../tools/system/fs_info.js | 0 .../tools/system/hardware_info.js | 0 .../tools/system/installed_software.js | 0 .../tools/system/os_info.js | 0 .../tools/system/os_network_info.js | 0 .../tools/system/os_socket_info.js | 0 .../tools/system/system_time.js | 0 .../tools/web/fetch.js | 0 .../tools/web/http_get.js | 0 .../tools/web/http_post.js | 0 .../tools/web/search.js | 0 54 files changed, 2000 deletions(-) rename agent/{escort-admin => bots/bot-escort-admin}/agent.js (100%) rename agent/{escort-admin => bots/bot-escort-admin}/prompts.js (100%) rename agent/{escort => bots/bot-escort}/AGENTS.md (100%) rename agent/{escort => bots/bot-escort}/agent.js (100%) rename agent/{escort => bots/bot-escort}/prompts.js (100%) rename agent/{escort => bots/bot-escort}/task.js (100%) delete mode 100644 agent/escort-admin/tools/index.js delete mode 100644 agent/escort/skills/baidu-ai-map/SKILL.md delete mode 100644 agent/escort/skills/baidu-ai-map/_meta.json delete mode 100644 agent/escort/tools/calendar/calendar_info.js delete mode 100644 agent/escort/tools/calendar/lunar_calendar_info.js delete mode 100644 agent/escort/tools/calendar/utils.js delete mode 100644 agent/escort/tools/calendar/year_holidays.js delete mode 100644 agent/escort/tools/calendar/year_terms.js delete mode 100644 agent/escort/tools/db/escort_record_set.js delete mode 100644 agent/escort/tools/geo/latlon.js delete mode 100644 agent/escort/tools/system/envs.js delete mode 100644 agent/escort/tools/system/fs_info.js delete mode 100644 agent/escort/tools/system/hardware_info.js delete mode 100644 agent/escort/tools/system/installed_software.js delete mode 100644 agent/escort/tools/system/os_info.js delete mode 100644 agent/escort/tools/system/os_network_info.js delete mode 100644 agent/escort/tools/system/os_socket_info.js delete mode 100644 agent/escort/tools/system/system_time.js delete mode 100644 agent/escort/tools/web/fetch.js delete mode 100644 agent/escort/tools/web/http_get.js delete mode 100644 agent/escort/tools/web/http_post.js delete mode 100644 agent/escort/tools/web/search.js rename agent/{escort-admin => infra}/skills/baidu-ai-map/SKILL.md (100%) rename agent/{escort-admin => infra}/skills/baidu-ai-map/_meta.json (100%) rename agent/{escort => infra}/skills/medical-escort-standard/SKILL.md (100%) rename agent/{escort => infra}/skills/medical-escort-standard/standard.md (100%) rename agent/{escort-admin => infra}/tools/calendar/calendar_info.js (100%) rename agent/{escort-admin => infra}/tools/calendar/lunar_calendar_info.js (100%) rename agent/{escort-admin => infra}/tools/calendar/utils.js (100%) rename agent/{escort-admin => infra}/tools/calendar/year_holidays.js (100%) rename agent/{escort-admin => infra}/tools/calendar/year_terms.js (100%) rename agent/{escort => infra}/tools/db/escort_record_query.js (100%) rename agent/{escort-admin/tools/db/escort_record_query.js => infra/tools/db/escort_record_query_admin.js} (100%) rename agent/{escort-admin => infra}/tools/db/escort_record_set.js (100%) rename agent/{escort-admin => infra}/tools/geo/latlon.js (100%) rename agent/{escort => infra}/tools/index.js (100%) rename agent/{escort-admin => infra}/tools/system/envs.js (100%) rename agent/{escort-admin => infra}/tools/system/fs_info.js (100%) rename agent/{escort-admin => infra}/tools/system/hardware_info.js (100%) rename agent/{escort-admin => infra}/tools/system/installed_software.js (100%) rename agent/{escort-admin => infra}/tools/system/os_info.js (100%) rename agent/{escort-admin => infra}/tools/system/os_network_info.js (100%) rename agent/{escort-admin => infra}/tools/system/os_socket_info.js (100%) rename agent/{escort-admin => infra}/tools/system/system_time.js (100%) rename agent/{escort-admin => infra}/tools/web/fetch.js (100%) rename agent/{escort-admin => infra}/tools/web/http_get.js (100%) rename agent/{escort-admin => infra}/tools/web/http_post.js (100%) rename agent/{escort-admin => infra}/tools/web/search.js (100%) diff --git a/agent/escort-admin/agent.js b/agent/bots/bot-escort-admin/agent.js similarity index 100% rename from agent/escort-admin/agent.js rename to agent/bots/bot-escort-admin/agent.js diff --git a/agent/escort-admin/prompts.js b/agent/bots/bot-escort-admin/prompts.js similarity index 100% rename from agent/escort-admin/prompts.js rename to agent/bots/bot-escort-admin/prompts.js diff --git a/agent/escort/AGENTS.md b/agent/bots/bot-escort/AGENTS.md similarity index 100% rename from agent/escort/AGENTS.md rename to agent/bots/bot-escort/AGENTS.md diff --git a/agent/escort/agent.js b/agent/bots/bot-escort/agent.js similarity index 100% rename from agent/escort/agent.js rename to agent/bots/bot-escort/agent.js diff --git a/agent/escort/prompts.js b/agent/bots/bot-escort/prompts.js similarity index 100% rename from agent/escort/prompts.js rename to agent/bots/bot-escort/prompts.js diff --git a/agent/escort/task.js b/agent/bots/bot-escort/task.js similarity index 100% rename from agent/escort/task.js rename to agent/bots/bot-escort/task.js diff --git a/agent/escort-admin/tools/index.js b/agent/escort-admin/tools/index.js deleted file mode 100644 index c38562d..0000000 --- a/agent/escort-admin/tools/index.js +++ /dev/null @@ -1,26 +0,0 @@ -// Tool 模块统一导出入口 -// 提供工具基类、注册表和所有工具类的统一导出 - -// Web工具 (LangChain format) -export { webFetchTool } from './web/fetch.js'; -export { webSearchTool } from './web/search.js'; -export { httpGetTool } from './web/http_get.js'; -export { httpPostTool } from './web/http_post.js'; - -// 日历工具 (LangChain format) -export { getCalendarInfoTool } from './calendar/calendar_info.js'; -export { getLunarCalendarInfoTool } from './calendar/lunar_calendar_info.js'; -export { getYearHolidaysTool } from './calendar/year_holidays.js'; -export { getYearTermsTool } from './calendar/year_terms.js'; - -// 地理工具 (LangChain format) -export { getLatLngTool } from './geo/latlon.js'; - -// 系统工具 (LangChain format) -export { getEnvTool } from './system/envs.js'; - -// db -export { escortRecordQueryTool } from './db/escort_record_query.js'; -export { escortRecordSetTool } from './db/escort_record_set.js'; - - diff --git a/agent/escort/skills/baidu-ai-map/SKILL.md b/agent/escort/skills/baidu-ai-map/SKILL.md deleted file mode 100644 index da2c113..0000000 --- a/agent/escort/skills/baidu-ai-map/SKILL.md +++ /dev/null @@ -1,243 +0,0 @@ ---- -name: baidu-ai-map -description: 为Agent提供地图和位置相关的能力,例如 AI 地点检索(周边信息)、AI 路线规划、地理编码与逆地理编码、天气查询等地图工具。 ---- - -# 百度地图服务 Agent Plan - -提供大模型友好调用的地图工具skills/baidu-ai-map/SKILL.md,支持POI搜索、导航、语义化 AI 搜索、语义化 AI 路线规划、地理编码与逆地理编码、天气查询。 - -## 使用准则 - -### 准则 1:API 端点 - -所有能力统一使用: - -> **Base URL**: `https://api.map.baidu.com/` - -### 准则 2:SK 凭证安全处理 - -SK(Service Key)是调用所有 API 的必须凭证: - -1. 优先读取环境变量 `BAIDU_MAP_AUTH_TOKEN`。 -2. 如果为空,提示用户前往 [百度地图 Agent Plan](https://lbs.baidu.com/apiconsole/agentplan) 申请。 -3. 设置环境变量: - -```bash -export BAIDU_MAP_AUTH_TOKEN="你的SK" -``` - -### 准则 3:统一鉴权方式(Header 传入) - -调用所有 API 时,统一通过 Header 传入: - -- `Authorization: Bearer $BAIDU_MAP_AUTH_TOKEN` - -示例: - -```bash -curl --get "https://api.map.baidu.com/agent_plan/v1/place" \ - -H "Authorization: Bearer $BAIDU_MAP_AUTH_TOKEN" \ - --data-urlencode "user_raw_request=帮我找北京可带宠物的咖啡馆" \ - --data-urlencode "region=北京市" -``` - -### 准则 4:优先使用http_get工具,避免直接调用curl,curl在window下支持不好 - -## 全局参数与行为约束 - -1. `user_raw_request` 必须是完整的用户需求,不可压缩为关键词。 -2. `user_raw_request` 出现“我附近”等非明确地点时,可根据上下文为用户推理为具体地点名称,但不可对坐标进行推理。 -3. `user_raw_request` 需保留定语/约束词,例如“评分最高”“最近”“最便宜”“3公里内”。 -4. 不得编造坐标;`center` / `location` / `refer_pois` 仅可来自用户明确提供或可信来源,当无可靠坐标时,必须先向用户澄清或先调用 `geocoding` / `place` 等工具获取。 -5. 统一使用 Header 鉴权:`Authorization: Bearer $BAIDU_MAP_AUTH_TOKEN`。 -6. 经纬度至少保留小数点后 6 位。 -7. 所有工具返回坐标类型统一为 `gcj02`。 -8. 禁止使用 grep/sed/awk/jq/python脚本 正则裁剪响应后再推断字段,这会造成百度地图 Agent Plan 巨额的token消耗;短时间内遇到相同或高度相似请求时,应优先基于结果直接推理,避免重复发起请求。 -9. `direction` 可能返回两类结果:路线结果,或起终点澄清结果。当返回起终点澄清结果时,应先根据用户需求推理最合理候选;若仍无法唯一确定,应引导用户在候选中选择后再继续规划。 - -## 工具详解 - -### 1. Place(语义化AI地点检索) - -#### API - -`GET /agent_plan/v1/place` - -#### 参数输入(给模型) - -Required: -- `user_raw_request`: 用户原始需求,原样完整传入,不可压缩为关键词;保留约束词(如“评分最高”“最近”“3公里内”) -- `region`: 城市或区域限制 - -Optional: -- `center`: 检索中心点和排序参考点(`lat,lng`,gcj02) -- `sort`: `distance` 或 `relevance`(默认 `relevance`) - -Rules: -- `sort=distance` 时,`center` 必传 -- `center` 只能来自用户明确提供或可信来源,禁止推测/编造,可通过 `geocoding` / `place` 等工具获取 -- 经纬度至少保留小数点后 6 位 - -#### 鉴权 - -- GET:Header `Authorization: Bearer $BAIDU_MAP_AUTH_TOKEN` - -#### 示例 - -```bash -# 1) 帮我查一下八达岭长城附近的五星级酒店 -curl --get "https://api.map.baidu.com/agent_plan/v1/place" \ - -H "Authorization: Bearer $BAIDU_MAP_AUTH_TOKEN" \ - --data-urlencode "user_raw_request=帮我查一下八达岭长城附近的五星级酒店" \ - --data-urlencode "region=延庆区" \ - --data-urlencode "sort=relevance" - -# 2) 离我最近的火锅店(distance 排序) -curl --get "https://api.map.baidu.com/agent_plan/v1/place" \ - -H "Authorization: Bearer $BAIDU_MAP_AUTH_TOKEN" \ - --data-urlencode "user_raw_request=离我最近的火锅店" \ - --data-urlencode "region=北京市" \ - --data-urlencode "center=40.056800,116.308300" \ - --data-urlencode "sort=distance" -``` - -### 2. Direction(语义化AI路线规划) - -#### API - -`GET /agent_plan/v1/direction` - -#### 参数输入 - -Required: -- `user_raw_request`: 用户原始需求,包含起点和终点;保留路线约束词,需要推理并改写用户原始的交通方式 -- `location`: 用户当前位置坐标(`lat,lng`,gcj02) - -Optional: -- `refer_pois`: 地点精确映射,格式 `地点名称:uid,纬度,经度;地点名称:uid,纬度,经度` - -Rules: -- 当前仅支持驾车、步行、骑行、公交路线规划。`user_raw_request` 中出现其他交通方式时,需要改写到这四种交通方式 -- `location` 当起点有歧义(如同名地标、模糊起点)时,路线规划服务会基于当前位置推理最合理的起点位置 -- `refer_pois` 默认不传,用于同名地点消歧,仅在 `user_raw_request` 中明确有歧义地点时传入 -- `refer_pois` / `location` 的经纬度至少保留小数点后 6 位,禁止推测/编造,可通过 `geocoding` / `place` 等工具获取 - -#### 鉴权 - -- GET:Header `Authorization: Bearer $BAIDU_MAP_AUTH_TOKEN` - -#### 示例 - -```bash -# 1) 帮我规划从故宫到颐和园的驾车路线 -curl --get "https://api.map.baidu.com/agent_plan/v1/direction" \ - -H "Authorization: Bearer $BAIDU_MAP_AUTH_TOKEN" \ - --data-urlencode "user_raw_request=帮我规划从故宫到颐和园的驾车路线" \ - --data-urlencode "location=39.914590,116.403770" - -# 2) “我家”别名映射 -curl --get "https://api.map.baidu.com/agent_plan/v1/direction" \ - -H "Authorization: Bearer $BAIDU_MAP_AUTH_TOKEN" \ - --data-urlencode "user_raw_request=步行去我家附近最近的中餐厅" \ - --data-urlencode "location=40.056800,116.308300" \ - --data-urlencode "refer_pois=我家:fbc88a21464370106e3e1b52,40.092180,116.345310" - -# 2) 交通方式推理改写:从王府井打车去三里屯要多久 -curl --get "https://api.map.baidu.com/agent_plan/v1/direction" \ - -H "Authorization: Bearer $BAIDU_MAP_AUTH_TOKEN" \ - --data-urlencode "user_raw_request=从王府井驾车去三里屯要多久" \ - --data-urlencode "location=39.914590,116.403770" -``` - -### 3. Geocoding(地理编码) - -#### API - -`GET /agent_plan/v1/geocoding` - -#### 参数输入 - -Required: -- `address`: 要解析的完整地址 - -Optional: -- `region`: 城市/区域提示(减少歧义) - -Rules: -- 地址越完整,解析越稳定 - -#### 鉴权 - -- GET:Header `Authorization: Bearer $BAIDU_MAP_AUTH_TOKEN` - -#### 示例 - -```bash -curl --get "https://api.map.baidu.com/agent_plan/v1/geocoding" \ - -H "Authorization: Bearer $BAIDU_MAP_AUTH_TOKEN" \ - --data-urlencode "address=北京市海淀区上地十街10号百度大厦" \ - --data-urlencode "region=北京市" -``` - -### 4. Reverse Geocoding(逆地理编码) - -#### API - -`GET /agent_plan/v1/reverse_geocoding` - -#### 参数输入 - -Required: -- `location`: `lat,lng` 格式坐标(gcj02) - -Rules: -- 经纬度至少保留小数点后 6 位 - -#### 鉴权 - -- GET:Header `Authorization: Bearer $BAIDU_MAP_AUTH_TOKEN` - -#### 示例 - -```bash -curl --get "https://api.map.baidu.com/agent_plan/v1/reverse_geocoding" \ - -H "Authorization: Bearer $BAIDU_MAP_AUTH_TOKEN" \ - --data-urlencode "location=40.056800,116.308300" -``` - -### 5. Weather(天气查询) - -#### API - -`GET /agent_plan/v1/weather` - -#### 参数输入 - -Optional: -- `region`: 行政区划名称 -- `location`: `lat,lng` 格式坐标(gcj02) - -Rules: -- `region` 与 `location` 至少传一个 -- `location` 传入时,经纬度至少保留小数点后 6 位 - -#### 鉴权 - -- GET:Header `Authorization: Bearer $BAIDU_MAP_AUTH_TOKEN` - -#### 示例 - -```bash -# 1) 按坐标查询天气 -curl --get "https://api.map.baidu.com/agent_plan/v1/weather" \ - -H "Authorization: Bearer $BAIDU_MAP_AUTH_TOKEN" \ - --data-urlencode "location=38.766230,116.432130" -``` - -## 错误处理 - -1. 如果缺少 token,提示用户执行: - 申请地址:https://lbs.baidu.com/apiconsole/agentplan - `export BAIDU_MAP_AUTH_TOKEN=""` -2. 如果提示参数错误,重新阅读本Skills查阅如何传参 \ No newline at end of file diff --git a/agent/escort/skills/baidu-ai-map/_meta.json b/agent/escort/skills/baidu-ai-map/_meta.json deleted file mode 100644 index 6b82a79..0000000 --- a/agent/escort/skills/baidu-ai-map/_meta.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "ownerId": "kn778b6bf766ym71fdvrc5yvg98319rv", - "slug": "baidu-ai-map", - "version": "1.0.6", - "publishedAt": 1776928968682 -} \ No newline at end of file diff --git a/agent/escort/tools/calendar/calendar_info.js b/agent/escort/tools/calendar/calendar_info.js deleted file mode 100644 index 7c87047..0000000 --- a/agent/escort/tools/calendar/calendar_info.js +++ /dev/null @@ -1,42 +0,0 @@ -import { tool } from "langchain" -import lunar from "lunar-javascript" -const { Solar, Lunar, HolidayUtil, TermUtil } = lunar -import { getAccurateTime } from "./utils.js" - -/** - * 日历工具 - * 提供准确时间、农历信息、节气、节日和老黄历等信息 - */ -export const getCalendarInfoTool = tool( - async () => { - try { - // 获取准确时间 - const timeInfo = await getAccurateTime() - - // 获取农历信息 - const date = new Date(timeInfo.timestamp) - const solar = Solar.fromDate(date) - const lunar = solar.getLunar() - - // 组合返回结果 - const result = { - time: timeInfo, - weekday: solar.getWeek(), - lunar: { - lunar: lunar.toString(), - solar: solar.toString(), - - } - } - - return JSON.stringify(result, null, 2) - } catch (error) { - console.error('Error in calendar tool:', error) - return JSON.stringify({ error: error.message }, null, 2) - } - }, - { - name: "get_calendar_info", - description: "获取当前准确日期时间,以及对应的农历日期" - } -) \ No newline at end of file diff --git a/agent/escort/tools/calendar/lunar_calendar_info.js b/agent/escort/tools/calendar/lunar_calendar_info.js deleted file mode 100644 index efa9271..0000000 --- a/agent/escort/tools/calendar/lunar_calendar_info.js +++ /dev/null @@ -1,62 +0,0 @@ -import { tool } from "langchain" -import lunarLib from "lunar-javascript" -const { Solar } = lunarLib - -/** - * 特定日期日历工具 - * 基于 lunar-javascript 提供指定日期的完整农历信息 - */ -export const getLunarCalendarInfoTool = tool( - async ({ year, month, day }) => { - try { - const solar = Solar.fromYmd(year, month, day) - const lunar = solar.getLunar() - - const result = { - solar: solar.toString(), - weekday: `星期${solar.getWeekInChinese()}`, - lunar: lunar.toString(), - ganzhiYear: lunar.getYearInGanZhi(), - zodiac: lunar.getYearShengXiao(), - solarTerms: lunar.getJieQi() || null, - festivals: [...solar.getFestivals(), ...lunar.getFestivals()], - yi: lunar.getDayYi(), - ji: lunar.getDayJi(), - xiShen: lunar.getDayPositionXiDesc(), - caiShen: lunar.getDayPositionCaiDesc() - } - - return JSON.stringify(result, null, 2) - } catch (error) { - return JSON.stringify({ error: error.message }, null, 2) - } - }, - { - name: "get_lunar_calendar_info", - description: "获取指定日期的日历信息,包括农历信息、老黄历、当年生肖、今日宜忌、喜神方位、财神方位、今日节气、今日节日等", - schema: { - type: "object", - properties: { - year: { - type: "number", - description: "年份", - minimum: 1900, - maximum: 2100 - }, - month: { - type: "number", - description: "月份", - minimum: 1, - maximum: 12 - }, - day: { - type: "number", - description: "日期", - minimum: 1, - maximum: 31 - } - }, - required: ["year", "month", "day"] - } - } -) diff --git a/agent/escort/tools/calendar/utils.js b/agent/escort/tools/calendar/utils.js deleted file mode 100644 index cda776f..0000000 --- a/agent/escort/tools/calendar/utils.js +++ /dev/null @@ -1,87 +0,0 @@ -import * as z from "zod" -import { tool } from "langchain" -import lunar from "lunar-javascript" -const { Solar, Lunar, HolidayUtil, TermUtil } = lunar - -/** - * 获取准确时间工具 - * 通过国内权威时间源获取当前准确时间 - * @returns {string} - 返回当前准确时间的JSON字符串 - */ -export async function getAccurateTime() { - const timeSources = [ - { - name: 'timeapi.io', - url: 'https://timeapi.io/api/Time/current/zone?timeZone=Asia/Shanghai', - method: 'json' - }, - { - name: '国家授时中心', - url: 'http://www.ntsc.ac.cn', - method: 'header' - }, - { - name: '阿里云', - url: 'https://www.aliyun.com', - method: 'header' - }, - { - name: '腾讯云', - url: 'https://cloud.tencent.com', - method: 'header' - }, - { - name: '华为云', - url: 'https://www.huaweicloud.com', - method: 'header' - } - ] - - for (const source of timeSources) { - try { - const startTime = Date.now() - // 每个时间源限时 3 秒,防止单个源 TCP 挂起长时间阻塞 - const res = await fetch(source.url, { signal: AbortSignal.timeout(3000) }) - const latency = Date.now() - startTime - - let timestamp = null - let beijingTime = null - - if (source.method === 'json') { - const data = await res.json() - timestamp = new Date(data.dateTime).getTime() - beijingTime = data.dateTime - } else if (source.method === 'header') { - const dateHeader = res.headers.get('Date') - if (dateHeader) { - timestamp = new Date(dateHeader).getTime() - beijingTime = new Date(timestamp).toLocaleString('zh-CN', { timeZone: 'Asia/Shanghai' }) - } - } - - if (timestamp) { - return { - timestamp, - date: new Date(timestamp).toISOString(), - localTime: beijingTime, - source: source.name, - latency: latency, - success: true - } - } - } catch (error) { - console.log(`从 ${source.name} 获取时间失败: ${error.message}`) - continue - } - } - - const date = new Date() - return { - timestamp: date.getTime(), - date: date.toISOString(), - localTime: date.toLocaleString('zh-CN', { timeZone: 'Asia/Shanghai' }), - success: false, - message: '使用本地时间作为备份' - } -} - diff --git a/agent/escort/tools/calendar/year_holidays.js b/agent/escort/tools/calendar/year_holidays.js deleted file mode 100644 index 5546e3c..0000000 --- a/agent/escort/tools/calendar/year_holidays.js +++ /dev/null @@ -1,52 +0,0 @@ -import { tool } from "langchain" -import lunarLib from "lunar-javascript" -const { Solar, HolidayUtil } = lunarLib - -/** - * 年份节日列表工具 - * 基于 lunar-javascript 计算全年节日(公历节日 + 农历传统节日)与法定节假日安排 - */ -export const getYearHolidaysTool = tool( - async ({ year }) => { - try { - // 法定节假日安排(含调休补班) - const legal = HolidayUtil.getHolidays(year).map(h => ({ - date: h.getTarget().toString(), - name: h.getName(), - type: h.isWork() ? "调休上班" : "放假" - })) - - // 遍历全年日期,收集公历节日与农历传统节日(春节、中秋、端午等) - const festivals = [] - const start = Solar.fromYmd(year, 1, 1) - const days = Solar.fromYmd(year + 1, 1, 1).subtract(start) - for (let i = 0; i < days; i++) { - const d = start.next(i) - const names = [...d.getFestivals(), ...d.getLunar().getFestivals()] - if (names.length) { - festivals.push({ date: d.toString(), name: names.join("、") }) - } - } - - return JSON.stringify({ year, legal, festivals }, null, 2) - } catch (error) { - return JSON.stringify({ error: error.message }, null, 2) - } - }, - { - name: "get_year_holidays", - description: "查询给定年份节日所在日期列表,包括法定节假日安排(含调休)与传统节日", - schema: { - type: "object", - properties: { - year: { - type: "number", - description: "年份", - minimum: 1900, - maximum: 2100 - } - }, - required: ["year"] - } - } -) diff --git a/agent/escort/tools/calendar/year_terms.js b/agent/escort/tools/calendar/year_terms.js deleted file mode 100644 index 4b3b22b..0000000 --- a/agent/escort/tools/calendar/year_terms.js +++ /dev/null @@ -1,46 +0,0 @@ -import { tool } from "langchain" -import lunarLib from "lunar-javascript" -const { Lunar } = lunarLib - -// 当年冬至在节气表中的 key 为英文(上一年冬至占用中文 key) -const EN_TERM_NAMES = { DONG_ZHI: "冬至" } - -/** - * 年份节气列表工具 - * 基于 lunar-javascript 计算给定年份的 24 节气精确日期 - */ -export const getYearTermsTool = tool( - async ({ year }) => { - try { - const table = Lunar.fromYmd(year, 1, 1).getJieQiTable() - const terms = [] - for (const [key, solar] of Object.entries(table)) { - // 只保留属于目标年份的节气(表首含上一年边界节气) - if (solar.getYear() !== year) continue - const name = EN_TERM_NAMES[key] ?? key - terms.push({ date: solar.toString(), name }) - } - terms.sort((a, b) => a.date.localeCompare(b.date)) - - return JSON.stringify({ year, terms }, null, 2) - } catch (error) { - return JSON.stringify({ error: error.message }, null, 2) - } - }, - { - name: "get_year_terms", - description: "查询给定年份节气所在日期列表", - schema: { - type: "object", - properties: { - year: { - type: "number", - description: "年份", - minimum: 1900, - maximum: 2100 - } - }, - required: ["year"] - } - } -) diff --git a/agent/escort/tools/db/escort_record_set.js b/agent/escort/tools/db/escort_record_set.js deleted file mode 100644 index a0dd2f8..0000000 --- a/agent/escort/tools/db/escort_record_set.js +++ /dev/null @@ -1,117 +0,0 @@ -import { tool } from "@langchain/core/tools"; -import z from "zod"; -import mongoose from "mongoose"; -import { DBModel } from "../../../../models/index.js"; - -const escortRecordSetTool = tool( - async ({ orderId, status, notes, payment }) => { - try { - if (!orderId) { - return { - success: false, - error: "Record ID (_id) is required as the lookup key", - }; - } - - if (!mongoose.Types.ObjectId.isValid(orderId)) { - return { - success: false, - error: `Invalid record ID: ${orderId}. A valid record _id is required.`, - }; - } - - const record = await DBModel.EscortRecord.findById(orderId); - if (!record) { - return { - success: false, - error: `No escort record found for order ID: ${orderId}`, - }; - } - - const update = {}; - - if (status !== undefined) { - update.status = status; - } - - if (notes !== undefined) { - if (notes.patientNote !== undefined) { - update["notes.patientNote"] = notes.patientNote; - } - if (notes.escortNote !== undefined) { - update["notes.escortNote"] = notes.escortNote; - } - if (notes.medicalSummary !== undefined) { - update["notes.medicalSummary"] = notes.medicalSummary; - } - } - - if (payment !== undefined) { - if (payment.totalFee !== undefined) { - update["payment.totalFee"] = payment.totalFee; - } - if (payment.paidFee !== undefined) { - update["payment.paidFee"] = payment.paidFee; - } - if (payment.status !== undefined) { - update["payment.status"] = payment.status; - } - } - - update["meta.updatetime"] = Date.now(); - - const updatedRecord = await DBModel.EscortRecord.findByIdAndUpdate( - record._id, - { $set: update }, - { new: true } - ); - - return { - success: true, - data: updatedRecord, - }; - } catch (error) { - return { - success: false, - error: error.message, - }; - } - }, - { - name: "escort_record_set", - description: - "Update escort record fields by record ID (_id). Supports updating status, notes (patientNote, escortNote, medicalSummary), and payment (totalFee, paidFee, status). Only provided fields will be updated.", - schema: z.object({ - orderId: z - .string() - .describe("Record ID (_id) used as the lookup key"), - status: z - .enum(["pending", "confirmed", "in_progress", "completed", "cancelled"]) - .optional() - .describe( - "Appointment status: pending (待确认), confirmed (已确认), in_progress (进行中), completed (已完成), cancelled (已取消)" - ), - notes: z - .object({ - patientNote: z.string().optional().describe("Patient remarks / special requirements"), - escortNote: z.string().optional().describe("Escort service notes"), - medicalSummary: z.string().optional().describe("Medical visit summary"), - }) - .optional() - .describe("Notes information to update"), - payment: z - .object({ - totalFee: z.number().optional().describe("Total service fee (RMB)"), - paidFee: z.number().optional().describe("Amount already paid (RMB)"), - status: z - .enum(["unpaid", "partial", "paid", "refunded"]) - .optional() - .describe("Payment status: unpaid, partial, paid, refunded"), - }) - .optional() - .describe("Payment information to update"), - }), - } -); - -export { escortRecordSetTool }; diff --git a/agent/escort/tools/geo/latlon.js b/agent/escort/tools/geo/latlon.js deleted file mode 100644 index 6741188..0000000 --- a/agent/escort/tools/geo/latlon.js +++ /dev/null @@ -1,40 +0,0 @@ -import * as z from "zod" -import { tool } from "langchain" - -/** - * 获取城市经纬度工具 - * @param {string} city - 城市名称 - * @returns {Object|null} - 返回经纬度对象 {lat, lng},如果未找到则返回null - */ -export const getLatLngTool = tool( - async (input) => { - const { city } = input - try { - // 使用open-meteo地理编码API获取经纬度 - console.log('获取城市经纬度:', city) - const url = `https://geocoding-api.open-meteo.com/v1/search?name=${encodeURIComponent(city)}&language=zh&count=1` - const res = await fetch(url) - const data = await res.json() - - if (data.results?.length) { - return { - lat: data.results[0].latitude, - lng: data.results[0].longitude - } - } - - // 如果没有找到结果,返回null - return null - } catch (error) { - console.error('地理编码API调用失败:', error) - return null - } - }, - { - name: "get_lat_lng", - description: `根据城市名称获取经纬度信息`, - schema: z.object({ - city: z.string().describe("城市名称,例如:北京市海淀区") - }) - } -) diff --git a/agent/escort/tools/system/envs.js b/agent/escort/tools/system/envs.js deleted file mode 100644 index e65f7bf..0000000 --- a/agent/escort/tools/system/envs.js +++ /dev/null @@ -1,83 +0,0 @@ -// LangChain 环境变量工具 - -import { tool } from '@langchain/core/tools'; -import { z } from 'zod'; - -/** - * 获取环境变量工具 - * @param {Object} input - 输入参数 - * @param {string} [input.name] - 环境变量名,不指定则返回所有 - * @returns {string} - 返回环境变量值或所有环境变量的JSON字符串 - */ -export const getEnvTool = tool( - async (input) => { - const { name } = input || {}; - - const sensitiveKeys = ['API_KEY', 'SECRET', 'PASSWORD', 'TOKEN', 'CREDENTIAL']; - const isSensitive = (key) => sensitiveKeys.some(s => key.toUpperCase().includes(s)); - - if (name) { - const value = process.env[name]; - if (value === undefined) { - return JSON.stringify({ error: `Environment variable '${name}' not found` }); - } - // 按名查询同样脱敏,防止 LLM 绕过读取密钥 - return JSON.stringify({ name, value: isSensitive(name) ? '***REDACTED***' : value }); - } - - // 返回所有环境变量(过滤敏感信息) - const env = { ...process.env }; - for (const key of Object.keys(env)) { - if (isSensitive(key)) { - env[key] = '***REDACTED***'; - } - } - - return JSON.stringify({ env }); - }, - { - name: 'env_get', - description: '获取环境变量的值。如果不指定变量名,则返回所有环境变量。', - schema: z.object({ - name: z.string().optional().describe('环境变量名,不指定则返回所有') - }) - } -); - -/** - * 设置环境变量工具 - * @param {Object} input - 输入参数 - * @param {string} input.name - 环境变量名 - * @param {string} input.value - 环境变量值 - * @returns {string} - 返回设置结果的JSON字符串 - */ -export const setEnvTool = tool( - async (input) => { - const { name, value } = input || {}; - - if (!name) { - return JSON.stringify({ error: 'Environment variable name is required' }); - } - - if (value === undefined) { - return JSON.stringify({ error: 'Environment variable value is required' }); - } - - try { - process.env[name] = value; - return JSON.stringify({ success: true, name, value }); - } catch (error) { - return JSON.stringify({ error: `Failed to set environment variable: ${error.message}` }); - } - }, - { - name: 'env_set', - description: '设置环境变量的值。', - schema: z.object({ - name: z.string().describe('环境变量名'), - value: z.string().describe('环境变量值') - }) - } -); - -export default getEnvTool; \ No newline at end of file diff --git a/agent/escort/tools/system/fs_info.js b/agent/escort/tools/system/fs_info.js deleted file mode 100644 index f84a7a7..0000000 --- a/agent/escort/tools/system/fs_info.js +++ /dev/null @@ -1,257 +0,0 @@ -import * as z from "zod" -import { tool } from "langchain" -import os from 'os' -import { promisify } from 'util' -import { exec } from 'child_process' - -const execPromise = promisify(exec) - -/** - * 获取系统文件信息工具 - * @returns {string} - 返回系统文件信息的 JSON 字符串,包括分区信息和各分区剩余空间 - */ -export const getSystemFileInfoTool = tool( - async (input) => { - try { - const fileSystemInfo = { - platform: os.platform(), - partitions: [], - volumeInfo: [], - diskHealth: [], - inodeInfo: [] - } - - // 获取文件系统信息(Windows) - if (os.platform() === 'win32') { - try { - const { stdout } = await execPromise('powershell -Command "Get-WmiObject Win32_LogicalDisk | Select-Object DeviceID,Description,FileSystem,Size,FreeSpace,VolumeName | ConvertTo-Json"') - const partitionData = JSON.parse(stdout) - const partitionsArray = Array.isArray(partitionData) ? partitionData : [partitionData] - - fileSystemInfo.partitions = partitionsArray.map(disk => { - const size = disk.Size ? parseInt(disk.Size) : 0 - const freeSpace = disk.FreeSpace ? parseInt(disk.FreeSpace) : 0 - const usedSpace = size - freeSpace - - return { - device: disk.DeviceID || 'N/A', - description: disk.Description || 'N/A', - filesystem: disk.FileSystem || 'N/A', - volumeName: disk.VolumeName || 'N/A', - size: size > 0 ? `${(size / (1024 * 1024 * 1024)).toFixed(2)} GB` : 'N/A', - freeSpace: freeSpace > 0 ? `${(freeSpace / (1024 * 1024 * 1024)).toFixed(2)} GB` : 'N/A', - usedSpace: usedSpace > 0 ? `${(usedSpace / (1024 * 1024 * 1024)).toFixed(2)} GB` : 'N/A', - usePercent: size > 0 ? `${((usedSpace / size) * 100).toFixed(2)}%` : 'N/A' - } - }).filter(item => item) - - // 获取卷详细信息(Windows) - try { - const { stdout } = await execPromise('powershell -Command "Get-WmiObject Win32_LogicalDisk | Select-Object VolumeName,VolumeSerialNumber,FileSystem,MaximumComponentLength,DeviceID,DriveType | ConvertTo-Json"') - const allVolumeData = JSON.parse(stdout) - const volumeArray = Array.isArray(allVolumeData) ? allVolumeData : [allVolumeData] - - fileSystemInfo.volumeInfo = volumeArray.map(vol => ({ - device: vol.DeviceID || 'N/A', - volumeName: vol.VolumeName || 'N/A', - serialNumber: vol.VolumeSerialNumber || 'N/A', - fileSystem: vol.FileSystem || 'N/A', - maxComponentLength: vol.MaximumComponentLength || 'N/A', - deviceID: vol.DeviceID || 'N/A', - driveType: vol.DriveType === 2 ? 'Removable' : vol.DriveType === 3 ? 'Local' : vol.DriveType === 4 ? 'Network' : vol.DriveType === 5 ? 'CD-ROM' : 'Unknown' - })).filter(item => item) - } catch (error) { - console.error('Error getting volume info:', error) - } - - // 获取磁盘健康状态(Windows SMART) - try { - const { stdout } = await execPromise('powershell -Command "Get-WmiObject Win32_DiskDrive | Select-Object Model,Status,SerialNumber,Size,MediaType | ConvertTo-Json"') - const diskData = JSON.parse(stdout) - const diskArray = Array.isArray(diskData) ? diskData : [diskData] - fileSystemInfo.diskHealth = diskArray.map(disk => { - return { - model: disk.Model || 'N/A', - status: disk.Status || 'N/A', - serialNumber: disk.SerialNumber || 'N/A', - size: disk.Size ? `${(parseInt(disk.Size) / (1024 * 1024 * 1024)).toFixed(2)} GB` : 'N/A' - } - }).filter(item => item) - } catch (error) { - console.error('Error getting disk health:', error) - } - } catch (error) { - console.error('Error getting file system info:', error) - fileSystemInfo.error = 'Error getting file system info' - } - } - // 获取文件系统信息(Linux) - else if (os.platform() === 'linux') { - try { - const { stdout } = await execPromise('df -h') - fileSystemInfo.partitions = stdout.trim().split('\n').slice(1).map(line => { - const parts = line.trim().split(/\s+/) - if (parts.length >= 6) { - return { - device: parts[0], - size: parts[1], - usedSpace: parts[2], - freeSpace: parts[3], - usePercent: parts[4], - mountedOn: parts[5] - } - } - return null - }).filter(item => item) - - // 获取挂载选项和文件系统类型(Linux) - try { - const { stdout } = await execPromise('mount | column -t') - const mountLines = stdout.trim().split('\n') - const mountInfo = {} - mountLines.forEach(line => { - const match = line.match(/^(.+?)\s+on\s+(.+?)\s+type\s+(.+?)\s+\((.*)\)$/) - if (match) { - mountInfo[match[2]] = { - device: match[1], - filesystem: match[3], - options: match[4] - } - } - }) - fileSystemInfo.mountInfo = mountInfo - } catch (error) { - console.error('Error getting mount info:', error) - } - - // 获取inode信息(Linux) - try { - const { stdout } = await execPromise('df -i') - fileSystemInfo.inodeInfo = stdout.trim().split('\n').slice(1).map(line => { - const parts = line.trim().split(/\s+/) - if (parts.length >= 6) { - return { - device: parts[0], - totalInodes: parts[1], - usedInodes: parts[2], - freeInodes: parts[3], - usePercent: parts[4], - mountedOn: parts[5] - } - } - return null - }).filter(item => item) - } catch (error) { - console.error('Error getting inode info:', error) - } - - // 获取磁盘健康状态(Linux SMART) - try { - const { stdout } = await execPromise('smartctl --health --json /dev/sda 2>/dev/null || echo "{}"') - if (stdout && stdout.includes('smart_status')) { - const healthData = JSON.parse(stdout) - fileSystemInfo.diskHealth.push({ - device: '/dev/sda', - status: healthData.smart_status?.passed ? 'OK' : 'Failed', - powerOnHours: healthData.power_on_time?.hours || 'N/A', - temperature: healthData.temperature?.current || 'N/A' - }) - } - } catch (error) { - console.log('SMART info not available or requires root') - } - } catch (error) { - console.error('Error getting file system info:', error) - fileSystemInfo.error = 'Error getting file system info' - } - } - // 获取文件系统信息(macOS) - else if (os.platform() === 'darwin') { - try { - const { stdout } = await execPromise('df -h') - fileSystemInfo.partitions = stdout.trim().split('\n').slice(1).map(line => { - const parts = line.trim().split(/\s+/) - if (parts.length >= 6) { - return { - device: parts[0], - size: parts[1], - usedSpace: parts[2], - freeSpace: parts[3], - usePercent: parts[4], - mountedOn: parts[5] - } - } - return null - }).filter(item => item) - - // 获取卷详细信息(macOS) - try { - const diskInfo = await execPromise('diskutil info -all') - const diskLines = diskInfo.stdout.trim().split('\n\n') - diskLines.forEach(disk => { - const volMatch = disk.match(/Volume Name:\s+(.+)/) - const devMatch = disk.match(/Device Node:\s+(.+)/) - const fsMatch = disk.match(/File System Personality:\s+(.+)/) - const serialMatch = disk.match(/Disk UUID:\s+(.+)/) - - if (devMatch) { - fileSystemInfo.volumeInfo.push({ - device: devMatch[1], - volumeName: volMatch ? volMatch[1] : 'N/A', - filesystem: fsMatch ? fsMatch[1] : 'N/A', - serialNumber: serialMatch ? serialMatch[1] : 'N/A' - }) - } - }) - } catch (error) { - console.error('Error getting volume info:', error) - } - - // 获取inode信息(macOS) - try { - const { stdout } = await execPromise('df -i') - fileSystemInfo.inodeInfo = stdout.trim().split('\n').slice(1).map(line => { - const parts = line.trim().split(/\s+/) - if (parts.length >= 6) { - return { - device: parts[0], - totalInodes: parts[1], - usedInodes: parts[2], - freeInodes: parts[3], - usePercent: parts[4], - mountedOn: parts[5] - } - } - return null - }).filter(item => item) - } catch (error) { - console.error('Error getting inode info:', error) - } - - // 获取磁盘健康状态(macOS) - try { - const { stdout } = await execPromise('diskutil smartStatus -all 2>/dev/null || echo "N/A"') - if (stdout && stdout !== 'N/A') { - fileSystemInfo.diskHealth = stdout.trim() - } - } catch (error) { - console.log('SMART status not available') - } - } catch (error) { - console.error('Error getting file system info:', error) - fileSystemInfo.error = 'Error getting file system info' - } - } - - return JSON.stringify(fileSystemInfo, null, 2) - } catch (error) { - console.error('Error getting file system info:', error) - return JSON.stringify({ error: error.message }, null, 2) - } - }, - { - name: "get_system_file_info", - description: `获取系统硬盘分区和文件系统信息,包括分区信息、卷标、序列号、磁盘健康状态、inode信息等`, - schema: z.object({}) - } -) diff --git a/agent/escort/tools/system/hardware_info.js b/agent/escort/tools/system/hardware_info.js deleted file mode 100644 index 9edfac6..0000000 --- a/agent/escort/tools/system/hardware_info.js +++ /dev/null @@ -1,112 +0,0 @@ -import * as z from "zod" -import { tool } from "langchain" -import os from 'os' -import { promisify } from 'util' -import { exec } from 'child_process' - -const execPromise = promisify(exec) - -/** - * 获取系统硬件配置信息工具 - * @returns {string} - 返回系统硬件配置信息的 JSON 字符串 - */ -export const getHardwareInfoTool = tool( - async (input) => { - try { - const hardwareInfo = { - cpu: { - cores: os.cpus().length, - model: os.cpus()[0].model, - speed: os.cpus()[0].speed - }, - memory: { - total: `${(os.totalmem() / (1024 ** 3)).toFixed(2)} GB`, - free: `${(os.freemem() / (1024 ** 3)).toFixed(2)} GB` - }, - disks: [], - gpu: [] - } - - // 获取硬盘信息(Windows) - if (os.platform() === 'win32') { - try { - const { stdout } = await execPromise('powershell -Command "Get-WmiObject Win32_DiskDrive | Select-Object Model,InterfaceType,Size | ConvertTo-Json"') - const diskData = JSON.parse(stdout) - const diskArray = Array.isArray(diskData) ? diskData : [diskData] - hardwareInfo.disks = diskArray.map(disk => ({ - model: disk.Model || 'N/A', - interfaceType: disk.InterfaceType || 'N/A', - size: disk.Size ? `${(parseInt(disk.Size) / (1024 * 1024 * 1024)).toFixed(2)} GB` : 'N/A' - })).filter(item => item) - } catch (error) { - console.error('Error getting disk info:', error) - } - - // 获取显卡信息(Windows) - try { - const { stdout } = await execPromise('wmic path win32_videocontroller get name') - hardwareInfo.gpu = stdout.trim().split('\n').slice(1).filter(line => line.trim()) - } catch (error) { - console.error('Error getting GPU info:', error) - } - } - // 获取硬盘和显卡信息(Linux) - else if (os.platform() === 'linux') { - try { - const { stdout } = await execPromise('lsblk -o NAME,MODEL,SIZE,TYPE | grep disk') - const diskLines = stdout.trim().split('\n') - hardwareInfo.disks = diskLines.map(line => { - const parts = line.trim().split(/\s+/) - if (parts.length >= 3) { - return { - name: parts[0], - model: parts.slice(1, -1).join(' '), - size: parts[parts.length - 1] - } - } - return null - }).filter(item => item) - } catch (error) { - console.error('Error getting disk info:', error) - } - - try { - const { stdout } = await execPromise('lspci | grep VGA') - hardwareInfo.gpu = stdout.trim().split('\n').map(line => line.trim()) - } catch (error) { - console.error('Error getting GPU info:', error) - } - } - // 获取硬盘和显卡信息(macOS) - else if (os.platform() === 'darwin') { - try { - const { stdout } = await execPromise('diskutil list') - hardwareInfo.disks = [{ - info: stdout.trim() - }] - } catch (error) { - console.error('Error getting disk info:', error) - } - - try { - const { stdout } = await execPromise('system_profiler SPDisplaysDataType') - hardwareInfo.gpu = [{ - info: stdout.trim() - }] - } catch (error) { - console.error('Error getting GPU info:', error) - } - } - - return JSON.stringify(hardwareInfo, null, 2) - } catch (error) { - console.error('Error getting hardware info:', error) - return JSON.stringify({ error: error.message }, null, 2) - } - }, - { - name: "get_hardware_info", - description: `获取系统硬件配置信息,包括CPU、内存、硬盘、显卡等`, - schema: z.object({}) - } -) diff --git a/agent/escort/tools/system/installed_software.js b/agent/escort/tools/system/installed_software.js deleted file mode 100644 index 430e4db..0000000 --- a/agent/escort/tools/system/installed_software.js +++ /dev/null @@ -1,101 +0,0 @@ -import * as z from "zod" -import { tool } from "langchain" -import os from 'os' -import { promisify } from 'util' -import { exec } from 'child_process' - -const execPromise = promisify(exec) - -/** - * 获取已安装软件信息工具 - * @returns {string} - 返回已安装软件信息的 JSON 字符串 - */ -export const getInstalledSoftwareTool = tool( - async (input) => { - try { - const softwareInfo = { - platform: os.platform(), - software: [] - } - - // 获取Windows已安装软件 - if (os.platform() === 'win32') { - try { - const { stdout } = await execPromise('powershell -Command "Get-WmiObject Win32_Product | Select-Object Name,Version,Vendor,InstallDate | ConvertTo-Json"') - const softwareData = JSON.parse(stdout) - const softwareArray = Array.isArray(softwareData) ? softwareData : [softwareData] - softwareInfo.software = softwareArray.map(soft => ({ - name: soft.Name || 'N/A', - version: soft.Version || 'N/A', - vendor: soft.Vendor || 'N/A', - installDate: soft.InstallDate || 'N/A' - })).filter(item => item) - } catch (error) { - console.error('Error getting installed software:', error) - } - } - // 获取Linux已安装软件 - else if (os.platform() === 'linux') { - try { - // 尝试使用dpkg(Debian/Ubuntu) - const { stdout: dpkgOutput } = await execPromise('dpkg -l 2>/dev/null || echo "N/A"') - if (dpkgOutput && dpkgOutput !== 'N/A') { - const lines = dpkgOutput.trim().split('\n').slice(5) - softwareInfo.software = lines.map(line => { - const parts = line.trim().split(/\s+/) - if (parts.length >= 3) { - return { - name: parts[1], - version: parts[2], - description: parts.slice(3).join(' ') - } - } - return null - }).filter(item => item) - } else { - // 尝试使用rpm(RHEL/CentOS) - const { stdout: rpmOutput } = await execPromise('rpm -qa 2>/dev/null || echo "N/A"') - if (rpmOutput && rpmOutput !== 'N/A') { - const lines = rpmOutput.trim().split('\n') - softwareInfo.software = lines.map(line => { - const match = line.match(/(.+)-(.+)-(.+)/) - if (match) { - return { - name: match[1], - version: `${match[2]}-${match[3]}` - } - } - return null - }).filter(item => item) - } - } - } catch (error) { - console.error('Error getting installed software:', error) - } - } - // 获取macOS已安装软件 - else if (os.platform() === 'darwin') { - try { - const { stdout } = await execPromise('find /Applications -name "*.app" -type d | sort') - const apps = stdout.trim().split('\n') - softwareInfo.software = apps.map(app => ({ - name: app.split('/').pop().replace('.app', ''), - path: app - })).filter(item => item) - } catch (error) { - console.error('Error getting installed software:', error) - } - } - - return JSON.stringify(softwareInfo, null, 2) - } catch (error) { - console.error('Error getting installed software:', error) - return JSON.stringify({ error: error.message }, null, 2) - } - }, - { - name: "get_installed_software", - description: `获取系统已安装的软件信息,包括软件名称、版本、供应商等`, - schema: z.object({}) - } -) diff --git a/agent/escort/tools/system/os_info.js b/agent/escort/tools/system/os_info.js deleted file mode 100644 index 120bd62..0000000 --- a/agent/escort/tools/system/os_info.js +++ /dev/null @@ -1,89 +0,0 @@ -import * as z from "zod" -import { tool } from "langchain" -import os from 'os' -import { promisify } from 'util' -import { exec } from 'child_process' - -const execPromise = promisify(exec) - -/** - * 获取操作系统信息工具 - * @returns {string} - 返回操作系统信息的 JSON 字符串 - */ -export const getOsInfoTool = tool( - async (input) => { - try { - const osInfo = { - platform: os.platform(), - arch: os.arch(), - release: os.release(), - hostname: os.hostname(), - uptime: `${Math.round(os.uptime() / 3600)} hours`, - nodeVersion: process.version, - homeDir: os.homedir(), - tempDir: os.tmpdir(), - userInfo: os.userInfo() - } - - // 获取Windows详细信息 - if (os.platform() === 'win32') { - try { - const { stdout } = await execPromise('powershell -Command "Get-WmiObject Win32_OperatingSystem | Select-Object Caption,Version,BuildNumber,OSArchitecture | ConvertTo-Json"') - const winInfo = JSON.parse(stdout) - osInfo.windows = { - caption: winInfo.Caption || 'N/A', - version: winInfo.Version || 'N/A', - buildNumber: winInfo.BuildNumber || 'N/A', - architecture: winInfo.OSArchitecture || 'N/A' - } - } catch (error) { - console.error('Error getting Windows info:', error) - } - } - // 获取Linux详细信息 - else if (os.platform() === 'linux') { - try { - const { stdout } = await execPromise('cat /etc/os-release') - const lines = stdout.trim().split('\n') - const linuxInfo = {} - lines.forEach(line => { - const match = line.match(/(.+?)=(.+)/) - if (match) { - linuxInfo[match[1]] = match[2].replace(/"/g, '') - } - }) - osInfo.linux = linuxInfo - } catch (error) { - console.error('Error getting Linux info:', error) - } - } - // 获取macOS详细信息 - else if (os.platform() === 'darwin') { - try { - const { stdout } = await execPromise('sw_vers') - const lines = stdout.trim().split('\n') - const macInfo = {} - lines.forEach(line => { - const match = line.match(/(.+?):\s+(.+)/) - if (match) { - macInfo[match[1]] = match[2] - } - }) - osInfo.macOS = macInfo - } catch (error) { - console.error('Error getting macOS info:', error) - } - } - - return JSON.stringify(osInfo, null, 2) - } catch (error) { - console.error('Error getting OS info:', error) - return JSON.stringify({ error: error.message }, null, 2) - } - }, - { - name: "get_os_info", - description: `获取操作系统信息,包括平台、架构、版本、主机名、运行时间等`, - schema: z.object({}) - } -) diff --git a/agent/escort/tools/system/os_network_info.js b/agent/escort/tools/system/os_network_info.js deleted file mode 100644 index ae47394..0000000 --- a/agent/escort/tools/system/os_network_info.js +++ /dev/null @@ -1,242 +0,0 @@ -import * as z from "zod" -import { tool } from "langchain" -import os from 'os' -import { promisify } from 'util' -import { exec } from 'child_process' - -const execPromise = promisify(exec) - -/** - * 获取系统网卡和网络连接信息工具 - * @returns {string} - 返回网络信息的 JSON 字符串,包括网卡信息和网络连接信息 - */ -export const getNetworkInfoTool = tool( - async (input) => { - try { - const networkInfo = { - platform: os.platform(), - networkInterfaces: [], - dnsServers: [], - gateway: [] - } - - // 获取网络接口信息(跨平台) - const interfaces = os.networkInterfaces() - for (const [name, addresses] of Object.entries(interfaces)) { - networkInfo.networkInterfaces.push({ - name, - addresses: addresses.map(addr => ({ - family: addr.family, - address: addr.address, - netmask: addr.netmask, - mac: addr.mac, - internal: addr.internal, - cidr: addr.cidr - })) - }) - } - - // 获取详细网络信息(Windows) - if (os.platform() === 'win32') { - try { - const { stdout } = await execPromise('ipconfig /all') - const lines = stdout.trim().split('\n') - let currentAdapter = null - - lines.forEach(line => { - const adapterMatch = line.match(/适配器\s+(.+?):/) - if (adapterMatch) { - if (currentAdapter) { - networkInfo.networkInterfaces.push(currentAdapter) - } - currentAdapter = { - name: adapterMatch[1], - description: '', - macAddress: '', - dhcpEnabled: false, - ipAddress: [], - subnetMask: [], - defaultGateway: [], - dnsServers: [] - } - } else if (currentAdapter) { - const descMatch = line.match(/描述\s+(.+)/) - if (descMatch) currentAdapter.description = descMatch[1].trim() - - const macMatch = line.match(/物理地址\s+:\s+(.+)/) - if (macMatch) currentAdapter.macAddress = macMatch[1].trim() - - const dhcpMatch = line.match(/DHCP 已启用\s+:\s+(.+)/) - if (dhcpMatch) currentAdapter.dhcpEnabled = dhcpMatch[1].trim() === '是' - - const ipMatch = line.match(/IPv4 地址\s+:\s+(.+)/) - if (ipMatch) currentAdapter.ipAddress.push(ipMatch[1].trim()) - - const subnetMatch = line.match(/子网掩码\s+:\s+(.+)/) - if (subnetMatch) currentAdapter.subnetMask.push(subnetMatch[1].trim()) - - const gatewayMatch = line.match(/默认网关\s+:\s+(.+)/) - if (gatewayMatch && gatewayMatch[1].trim()) currentAdapter.defaultGateway.push(gatewayMatch[1].trim()) - - const dnsMatch = line.match(/DNS 服务器\s+:\s+(.+)/) - if (dnsMatch && dnsMatch[1].trim()) currentAdapter.dnsServers.push(dnsMatch[1].trim()) - } - }) - - if (currentAdapter) { - networkInfo.networkInterfaces.push(currentAdapter) - } - } catch (error) { - console.error('Error getting network config:', error) - } - - // 获取DNS服务器(Windows) - try { - const { stdout } = await execPromise('nslookup localhost 2>&1') - const dnsMatch = stdout.match(/Server:\s+(.+)/) - if (dnsMatch) { - networkInfo.dnsServers.push(dnsMatch[1].trim()) - } - } catch (error) { - console.error('Error getting DNS servers:', error) - } - } - // 获取详细网络信息(Linux) - else if (os.platform() === 'linux') { - try { - const { stdout } = await execPromise('ip addr show') - const lines = stdout.trim().split('\n') - let currentInterface = null - - lines.forEach(line => { - const interfaceMatch = line.match(/^\d+:\s+(\w+):/) - if (interfaceMatch) { - if (currentInterface) { - networkInfo.networkInterfaces.push(currentInterface) - } - currentInterface = { - name: interfaceMatch[1], - state: '', - macAddress: '', - ipAddress: [], - subnetMask: [] - } - } else if (currentInterface) { - const stateMatch = line.match(/state\s+(\w+)/) - if (stateMatch) currentInterface.state = stateMatch[1] - - const macMatch = line.match(/link\/ether\s+([a-fA-F0-9:]+)/) - if (macMatch) currentInterface.macAddress = macMatch[1] - - const ipMatch = line.match(/inet\s+(\d+\.\d+\.\d+\.\d+)\/(\d+)/) - if (ipMatch) { - currentInterface.ipAddress.push(ipMatch[1]) - const maskLength = parseInt(ipMatch[2]) - currentInterface.subnetMask.push(maskLength) - } - } - }) - - if (currentInterface) { - networkInfo.networkInterfaces.push(currentInterface) - } - } catch (error) { - console.error('Error getting network config:', error) - } - - // 获取DNS服务器(Linux) - try { - const { stdout } = await execPromise('cat /etc/resolv.conf') - const dnsMatches = stdout.match(/nameserver\s+(.+)/g) - if (dnsMatches) { - networkInfo.dnsServers = dnsMatches.map(match => match.replace('nameserver', '').trim()) - } - } catch (error) { - console.error('Error getting DNS servers:', error) - } - - // 获取网关(Linux) - try { - const { stdout } = await execPromise('ip route show default') - const gatewayMatch = stdout.match(/default via (\d+\.\d+\.\d+\.\d+)/) - if (gatewayMatch) { - networkInfo.gateway.push(gatewayMatch[1]) - } - } catch (error) { - console.error('Error getting gateway:', error) - } - } - // 获取详细网络信息(macOS) - else if (os.platform() === 'darwin') { - try { - const { stdout } = await execPromise('ifconfig') - const lines = stdout.trim().split('\n') - let currentInterface = null - - lines.forEach(line => { - const interfaceMatch = line.match(/^(\w+):/) - if (interfaceMatch) { - if (currentInterface) { - networkInfo.networkInterfaces.push(currentInterface) - } - currentInterface = { - name: interfaceMatch[1], - status: '', - macAddress: '', - ipAddress: [], - subnetMask: [] - } - } else if (currentInterface) { - const statusMatch = line.match(/status:\s+(\w+)/) - if (statusMatch) currentInterface.status = statusMatch[1] - - const macMatch = line.match(/ether\s+([a-fA-F0-9:]+)/) - if (macMatch) currentInterface.macAddress = macMatch[1] - - const ipMatch = line.match(/inet\s+(\d+\.\d+\.\d+\.\d+)\s+netmask\s+(0x[0-9a-fA-F]+)/) - if (ipMatch) { - currentInterface.ipAddress.push(ipMatch[1]) - currentInterface.subnetMask.push(ipMatch[2]) - } - } - }) - - if (currentInterface) { - networkInfo.networkInterfaces.push(currentInterface) - } - } catch (error) { - console.error('Error getting network config:', error) - } - - // 获取DNS服务器(macOS) - try { - const { stdout } = await execPromise('scutil --dns | grep nameserver | awk \'{print $3}\'') - networkInfo.dnsServers = stdout.trim().split('\n').filter(dns => dns) - } catch (error) { - console.error('Error getting DNS servers:', error) - } - - // 获取网关(macOS) - try { - const { stdout } = await execPromise('netstat -nr | grep default') - const gatewayMatch = stdout.match(/default\s+(\d+\.\d+\.\d+\.\d+)/) - if (gatewayMatch) { - networkInfo.gateway.push(gatewayMatch[1]) - } - } catch (error) { - console.error('Error getting gateway:', error) - } - } - - return JSON.stringify(networkInfo, null, 2) - } catch (error) { - console.error('Error getting network info:', error) - return JSON.stringify({ error: error.message }, null, 2) - } - }, - { - name: "get_network_info", - description: `获取系统网卡和网络信息,包括网卡配置、IP地址、MAC地址、DNS服务器、网关等`, - schema: z.object({}) - } -) diff --git a/agent/escort/tools/system/os_socket_info.js b/agent/escort/tools/system/os_socket_info.js deleted file mode 100644 index 8874aac..0000000 --- a/agent/escort/tools/system/os_socket_info.js +++ /dev/null @@ -1,157 +0,0 @@ -import * as z from "zod" -import { tool } from "langchain" -import os from 'os' -import { promisify } from 'util' -import { exec } from 'child_process' - -const execPromise = promisify(exec) - -/** - * 获取系统活动连接和Socket信息工具 - * @returns {string} - 返回Socket信息的 JSON 字符串,包括活动连接和监听端口等 - */ -export const getSocketInfoTool = tool( - async (input) => { - try { - const socketInfo = { - platform: os.platform(), - activeConnections: [], - listeningPorts: [] - } - - // 获取活动连接(Windows) - if (os.platform() === 'win32') { - try { - const { stdout } = await execPromise('netstat -ano') - const lines = stdout.trim().split('\n').slice(4) - socketInfo.activeConnections = lines.map(line => { - const parts = line.trim().split(/\s+/) - if (parts.length >= 5) { - return { - protocol: parts[0], - localAddress: parts[1], - foreignAddress: parts[2], - state: parts[3], - processId: parts[4] - } - } - return null - }).filter(item => item) - } catch (error) { - console.error('Error getting active connections:', error) - } - - // 获取监听端口(Windows) - try { - const { stdout } = await execPromise('netstat -an | findstr LISTENING') - const lines = stdout.trim().split('\n') - socketInfo.listeningPorts = lines.map(line => { - const parts = line.trim().split(/\s+/) - if (parts.length >= 4) { - return { - protocol: parts[0], - localAddress: parts[1], - state: parts[3] - } - } - return null - }).filter(item => item) - } catch (error) { - console.error('Error getting listening ports:', error) - } - } - // 获取活动连接(Linux) - else if (os.platform() === 'linux') { - try { - const { stdout } = await execPromise('ss -tuln') - const lines = stdout.trim().split('\n').slice(1) - socketInfo.activeConnections = lines.map(line => { - const parts = line.trim().split(/\s+/) - if (parts.length >= 5) { - return { - protocol: parts[0], - state: parts[1], - localAddress: parts[4], - peerAddress: parts[5] - } - } - return null - }).filter(item => item) - } catch (error) { - console.error('Error getting active connections:', error) - } - - // 获取监听端口(Linux) - try { - const { stdout } = await execPromise('ss -tulpn') - const lines = stdout.trim().split('\n').slice(1) - socketInfo.listeningPorts = lines.map(line => { - const parts = line.trim().split(/\s+/) - if (parts.length >= 6) { - return { - protocol: parts[0], - state: parts[1], - localAddress: parts[4], - processInfo: parts[5] - } - } - return null - }).filter(item => item) - } catch (error) { - console.error('Error getting listening ports:', error) - } - } - // 获取活动连接(macOS) - else if (os.platform() === 'darwin') { - try { - const { stdout } = await execPromise('netstat -an') - const lines = stdout.trim().split('\n').slice(2) - socketInfo.activeConnections = lines.map(line => { - const parts = line.trim().split(/\s+/) - if (parts.length >= 6) { - return { - protocol: parts[0], - localAddress: parts[3], - foreignAddress: parts[4], - state: parts[5] - } - } - return null - }).filter(item => item) - } catch (error) { - console.error('Error getting active connections:', error) - } - - // 获取监听端口(macOS) - try { - const { stdout } = await execPromise('netstat -an | grep LISTEN') - const lines = stdout.trim().split('\n') - socketInfo.listeningPorts = lines.map(line => { - const parts = line.trim().split(/\s+/) - if (parts.length >= 6) { - return { - protocol: parts[0], - localAddress: parts[3], - foreignAddress: parts[4], - state: parts[5] - } - } - return null - }).filter(item => item) - } catch (error) { - console.error('Error getting listening ports:', error) - } - } - - return JSON.stringify(socketInfo, null, 2) - } catch (error) { - console.error('Error getting socket info:', error) - return JSON.stringify({ error: error.message }, null, 2) - } - }, - { - name: "get_socket_info", - description: `获取系统活动连接和Socket信息,包括TCP/UDP连接、监听端口、进程ID等`, - schema: z.object({}) - } -) diff --git a/agent/escort/tools/system/system_time.js b/agent/escort/tools/system/system_time.js deleted file mode 100644 index bd26718..0000000 --- a/agent/escort/tools/system/system_time.js +++ /dev/null @@ -1,17 +0,0 @@ -import * as z from "zod" -import { tool } from "langchain" - -/** - * 获取系统时间工具 - * @returns {string} - 返回当前系统时间 - */ -export const getSystemTimeTool = tool( - (input) => { - return new Date().toLocaleString() - }, - { - name: "get_system_time", - description: `获取当前系统时间`, - schema: z.object({}) - } -) diff --git a/agent/escort/tools/web/fetch.js b/agent/escort/tools/web/fetch.js deleted file mode 100644 index e8297d7..0000000 --- a/agent/escort/tools/web/fetch.js +++ /dev/null @@ -1,35 +0,0 @@ -import { TavilyExtract } from "@langchain/tavily"; -import { tool } from "@langchain/core/tools"; -import * as z from "zod" -import config from "../../../../conf.json" with { type: "json" }; - -const webFetchTool = tool( - async ({ - extractDepth = "basic", - includeImages = false, - format = "markdown", - urls = [], - }) => { - const tavilyExtract = new TavilyExtract({ - tavilyApiKey: config.agent.tavily.apiKey, - extractDepth, - includeImages, - format - }); - return await tavilyExtract._call({ urls }); - }, - { - name: "web_fetch", - description: "Run a web fetch", - schema: z.object({ - extractDepth: z.enum(["basic", "advanced"]).default("basic"), - includeImages: z.boolean().default(false), - format: z - .enum(["markdown", "json"]) - .default("markdown"), - urls: z.array(z.string().describe("The urls")).default([]), - }), - }, -); - -export { webFetchTool }; diff --git a/agent/escort/tools/web/http_get.js b/agent/escort/tools/web/http_get.js deleted file mode 100644 index 5af87a0..0000000 --- a/agent/escort/tools/web/http_get.js +++ /dev/null @@ -1,62 +0,0 @@ -import { tool } from 'langchain'; -import * as z from 'zod'; - -export const httpGetTool = tool( - async ({ url, headers = {}, timeout = 30000 }) => { - try { - new URL(url); - } catch (e) { - return JSON.stringify({ success: false, error: `Invalid URL: ${url}` }); - } - - try { - const controller = new AbortController(); - const timeoutId = setTimeout(() => controller.abort(), timeout); - - const response = await fetch(url, { - method: 'GET', - headers: { - 'User-Agent': 'XAgent-Bot/1.0', - ...headers - }, - signal: controller.signal - }); - - clearTimeout(timeoutId); - - const contentType = response.headers.get('content-type') || ''; - let body; - - if (contentType.includes('application/json')) { - body = await response.json(); - } else if (contentType.includes('text/') || contentType.includes('application/javascript')) { - body = await response.text(); - } else { - const buffer = await response.arrayBuffer(); - body = Buffer.from(buffer).toString('base64'); - } - - return JSON.stringify({ - success: true, - status: response.status, - statusText: response.statusText, - headers: Object.fromEntries(response.headers.entries()), - body - }); - } catch (error) { - if (error.name === 'AbortError') { - return JSON.stringify({ success: false, error: `Request timed out after ${timeout}ms` }); - } - return JSON.stringify({ success: false, error: error.message }); - } - }, - { - name: 'http_get', - description: 'Send HTTP GET request and return response content. Supports custom headers and timeout settings.', - schema: z.object({ - url: z.string().describe('Request URL'), - headers: z.record(z.string(), z.string()).optional().describe('Request headers'), - timeout: z.number().optional().describe('Timeout in milliseconds, default 30000') - }) - } -); \ No newline at end of file diff --git a/agent/escort/tools/web/http_post.js b/agent/escort/tools/web/http_post.js deleted file mode 100644 index 8461991..0000000 --- a/agent/escort/tools/web/http_post.js +++ /dev/null @@ -1,88 +0,0 @@ -import { tool } from "@langchain/core/tools"; -import z from "zod"; - -const httpPostTool = tool( - async ({ url, body, headers = {}, contentType = 'json', timeout = 30000 }) => { - try { - new URL(url); - } catch (e) { - return { success: false, error: `Invalid URL: ${url}` }; - } - - let requestBody; - const requestHeaders = { - 'User-Agent': 'XAgent-Bot/1.0', - ...headers - }; - - switch (contentType) { - case 'json': - requestHeaders['Content-Type'] = 'application/json'; - requestBody = typeof body === 'string' ? body : JSON.stringify(body); - break; - case 'form': - requestHeaders['Content-Type'] = 'application/x-www-form-urlencoded'; - if (typeof body === 'object') { - requestBody = new URLSearchParams(body).toString(); - } else { - requestBody = body; - } - break; - case 'text': - requestHeaders['Content-Type'] = 'text/plain'; - requestBody = typeof body === 'string' ? body : JSON.stringify(body); - break; - default: - requestBody = typeof body === 'string' ? body : JSON.stringify(body); - } - - try { - const controller = new AbortController(); - const timeoutId = setTimeout(() => controller.abort(), timeout); - - const response = await fetch(url, { - method: 'POST', - headers: requestHeaders, - body: requestBody, - signal: controller.signal - }); - - clearTimeout(timeoutId); - - const responseContentType = response.headers.get('content-type') || ''; - let responseBody; - - if (responseContentType.includes('application/json')) { - responseBody = await response.json(); - } else { - responseBody = await response.text(); - } - - return { - success: true, - status: response.status, - statusText: response.statusText, - headers: Object.fromEntries(response.headers.entries()), - body: responseBody - }; - } catch (error) { - if (error.name === 'AbortError') { - return { success: false, error: `Request timed out after ${timeout}ms` }; - } - return { success: false, error: error.message }; - } - }, - { - name: "http_post", - description: "Send HTTP POST request. Supports JSON and form data.", - schema: z.object({ - url: z.string().describe("Request URL"), - body: z.union([z.string(), z.object({})]).describe("Request body, can be string or JSON object"), - headers: z.record(z.string()).optional().describe("Request headers"), - contentType: z.enum(['json', 'form', 'text', 'raw']).optional().describe("Content type, default json"), - timeout: z.number().optional().describe("Timeout in milliseconds, default 30000") - }), - }, -); - -export { httpPostTool }; diff --git a/agent/escort/tools/web/search.js b/agent/escort/tools/web/search.js deleted file mode 100644 index 7d2d309..0000000 --- a/agent/escort/tools/web/search.js +++ /dev/null @@ -1,36 +0,0 @@ -import { TavilySearch } from "@langchain/tavily"; -import { tool } from "@langchain/core/tools"; -import * as z from "zod" -import config from "../../../../conf.json" with { type: "json" }; - -const webSearchTool = tool( - async ({ - query, - maxResults = 5, - topic = "general", - includeRawContent = false, - }) => { - const tavilySearch = new TavilySearch({ - maxResults, - tavilyApiKey: config.agent.tavily.apiKey, - includeRawContent, - topic, - }); - return await tavilySearch._call({ query }); - }, - { - name: "internet_search", - description: "Run a web search", - schema: z.object({ - query: z.string().describe("The search query"), - maxResults: z.number().optional().default(5), - topic: z - .enum(["general", "news", "finance"]) - .optional() - .default("general"), - includeRawContent: z.boolean().optional().default(false), - }), - }, -); - -export { webSearchTool }; diff --git a/agent/escort-admin/skills/baidu-ai-map/SKILL.md b/agent/infra/skills/baidu-ai-map/SKILL.md similarity index 100% rename from agent/escort-admin/skills/baidu-ai-map/SKILL.md rename to agent/infra/skills/baidu-ai-map/SKILL.md diff --git a/agent/escort-admin/skills/baidu-ai-map/_meta.json b/agent/infra/skills/baidu-ai-map/_meta.json similarity index 100% rename from agent/escort-admin/skills/baidu-ai-map/_meta.json rename to agent/infra/skills/baidu-ai-map/_meta.json diff --git a/agent/escort/skills/medical-escort-standard/SKILL.md b/agent/infra/skills/medical-escort-standard/SKILL.md similarity index 100% rename from agent/escort/skills/medical-escort-standard/SKILL.md rename to agent/infra/skills/medical-escort-standard/SKILL.md diff --git a/agent/escort/skills/medical-escort-standard/standard.md b/agent/infra/skills/medical-escort-standard/standard.md similarity index 100% rename from agent/escort/skills/medical-escort-standard/standard.md rename to agent/infra/skills/medical-escort-standard/standard.md diff --git a/agent/escort-admin/tools/calendar/calendar_info.js b/agent/infra/tools/calendar/calendar_info.js similarity index 100% rename from agent/escort-admin/tools/calendar/calendar_info.js rename to agent/infra/tools/calendar/calendar_info.js diff --git a/agent/escort-admin/tools/calendar/lunar_calendar_info.js b/agent/infra/tools/calendar/lunar_calendar_info.js similarity index 100% rename from agent/escort-admin/tools/calendar/lunar_calendar_info.js rename to agent/infra/tools/calendar/lunar_calendar_info.js diff --git a/agent/escort-admin/tools/calendar/utils.js b/agent/infra/tools/calendar/utils.js similarity index 100% rename from agent/escort-admin/tools/calendar/utils.js rename to agent/infra/tools/calendar/utils.js diff --git a/agent/escort-admin/tools/calendar/year_holidays.js b/agent/infra/tools/calendar/year_holidays.js similarity index 100% rename from agent/escort-admin/tools/calendar/year_holidays.js rename to agent/infra/tools/calendar/year_holidays.js diff --git a/agent/escort-admin/tools/calendar/year_terms.js b/agent/infra/tools/calendar/year_terms.js similarity index 100% rename from agent/escort-admin/tools/calendar/year_terms.js rename to agent/infra/tools/calendar/year_terms.js diff --git a/agent/escort/tools/db/escort_record_query.js b/agent/infra/tools/db/escort_record_query.js similarity index 100% rename from agent/escort/tools/db/escort_record_query.js rename to agent/infra/tools/db/escort_record_query.js diff --git a/agent/escort-admin/tools/db/escort_record_query.js b/agent/infra/tools/db/escort_record_query_admin.js similarity index 100% rename from agent/escort-admin/tools/db/escort_record_query.js rename to agent/infra/tools/db/escort_record_query_admin.js diff --git a/agent/escort-admin/tools/db/escort_record_set.js b/agent/infra/tools/db/escort_record_set.js similarity index 100% rename from agent/escort-admin/tools/db/escort_record_set.js rename to agent/infra/tools/db/escort_record_set.js diff --git a/agent/escort-admin/tools/geo/latlon.js b/agent/infra/tools/geo/latlon.js similarity index 100% rename from agent/escort-admin/tools/geo/latlon.js rename to agent/infra/tools/geo/latlon.js diff --git a/agent/escort/tools/index.js b/agent/infra/tools/index.js similarity index 100% rename from agent/escort/tools/index.js rename to agent/infra/tools/index.js diff --git a/agent/escort-admin/tools/system/envs.js b/agent/infra/tools/system/envs.js similarity index 100% rename from agent/escort-admin/tools/system/envs.js rename to agent/infra/tools/system/envs.js diff --git a/agent/escort-admin/tools/system/fs_info.js b/agent/infra/tools/system/fs_info.js similarity index 100% rename from agent/escort-admin/tools/system/fs_info.js rename to agent/infra/tools/system/fs_info.js diff --git a/agent/escort-admin/tools/system/hardware_info.js b/agent/infra/tools/system/hardware_info.js similarity index 100% rename from agent/escort-admin/tools/system/hardware_info.js rename to agent/infra/tools/system/hardware_info.js diff --git a/agent/escort-admin/tools/system/installed_software.js b/agent/infra/tools/system/installed_software.js similarity index 100% rename from agent/escort-admin/tools/system/installed_software.js rename to agent/infra/tools/system/installed_software.js diff --git a/agent/escort-admin/tools/system/os_info.js b/agent/infra/tools/system/os_info.js similarity index 100% rename from agent/escort-admin/tools/system/os_info.js rename to agent/infra/tools/system/os_info.js diff --git a/agent/escort-admin/tools/system/os_network_info.js b/agent/infra/tools/system/os_network_info.js similarity index 100% rename from agent/escort-admin/tools/system/os_network_info.js rename to agent/infra/tools/system/os_network_info.js diff --git a/agent/escort-admin/tools/system/os_socket_info.js b/agent/infra/tools/system/os_socket_info.js similarity index 100% rename from agent/escort-admin/tools/system/os_socket_info.js rename to agent/infra/tools/system/os_socket_info.js diff --git a/agent/escort-admin/tools/system/system_time.js b/agent/infra/tools/system/system_time.js similarity index 100% rename from agent/escort-admin/tools/system/system_time.js rename to agent/infra/tools/system/system_time.js diff --git a/agent/escort-admin/tools/web/fetch.js b/agent/infra/tools/web/fetch.js similarity index 100% rename from agent/escort-admin/tools/web/fetch.js rename to agent/infra/tools/web/fetch.js diff --git a/agent/escort-admin/tools/web/http_get.js b/agent/infra/tools/web/http_get.js similarity index 100% rename from agent/escort-admin/tools/web/http_get.js rename to agent/infra/tools/web/http_get.js diff --git a/agent/escort-admin/tools/web/http_post.js b/agent/infra/tools/web/http_post.js similarity index 100% rename from agent/escort-admin/tools/web/http_post.js rename to agent/infra/tools/web/http_post.js diff --git a/agent/escort-admin/tools/web/search.js b/agent/infra/tools/web/search.js similarity index 100% rename from agent/escort-admin/tools/web/search.js rename to agent/infra/tools/web/search.js