feat(agent): add controlled task execution

This commit is contained in:
2026-09-24 04:19:02 +08:00
parent d018bcae67
commit b31033e9ce
48 changed files with 14498 additions and 86 deletions
+13 -5
View File
@@ -1,6 +1,6 @@
# TJWater Agent 实验服务
# TJWater 供水 Agent 实验服务
基于 OpenCode 的实验性 Agent 服务,用于编排 TJWater 前端交互。
基于 OpenCode 的实验性供水 Agent 服务,用于编排 TJWater 供水管网前端交互。排水数据、排水分析流程和排水前端交互不在本仓库范围内。
本仓库与生产环境中的 `TJWaterAgent` 历史代码相互独立,不包含用户认证,也不包含旧版 `tjwater-cli` 桥接层。运行时请求默认使用本地上下文,后续可通过 `src/context/` 接入实际的认证提供方。
@@ -21,6 +21,7 @@ GET /api/v1/agent/chat/ui-registry
GET /api/v1/agent/chat/frontend-action-registry
POST /api/v1/agent/chat/frontend-actions/:action_id/result
POST /api/v1/agent/chat/session
POST /api/v1/agent/chat/task-executions
GET /api/v1/agent/chat/sessions
GET /api/v1/agent/chat/session/:session_id
GET /api/v1/agent/chat/session/:session_id/stream
@@ -28,6 +29,10 @@ POST /api/v1/agent/chat/stream
POST /api/v1/agent/chat/abort
```
工况 worker 通过 `POST /api/v1/agent/chat/task-executions` 提交 Server 已持久化的 `task_id`、`run_id` 和 `execution_request_id`。三者缺一即拒绝;Agent 不从进程内 Map 推断当前执行代次。Agent claim 成功后每 20 秒对该 run 心跳,正常流结束显式调用 `complete`,失败或中止显式调用 `fail`。计划、报告和完成命令均携带同一 run 身份,Server 是活动 run 与租约状态的唯一权威。
聊天 UIMessage 流与工作台业务事件流相互独立;业务状态由 Server 的 `/api/v1/workbench/events` 推送,不能混入 token SSE。
`POST /api/v1/agent/chat/stream` 通过 SSE 返回事件流。主要事件如下:
| 事件 | 用途 |
@@ -54,7 +59,7 @@ AGENT_LOCAL_PROJECT_ID=local-project
AGENT_LOCAL_NETWORK=local-network
```
监测时序数据从 Agent 项目的 `source/` 目录读取,并通过经过校验的本地技能进行分析。`get_project_context`、`list_scada_assets`、`query_scada_readings`、`web_search` 和 `geocode` 依赖 TJWater Server,因此当前不对外开放。
供水业务数据只来自用户输入、经过校验的事件上下文或已启用的受控工具。`get_project_context`、`list_scada_assets`、`query_scada_readings`、`web_search` 和 `geocode` 依赖 TJWater Server,因此当前不对外开放。
实验期间可以通过以下请求头覆盖本地上下文:
@@ -100,6 +105,10 @@ bun test tests/**/*.test.ts
`bun run check` 会检查服务代码和 `.opencode` 工具的类型。
工况任务工具通过本机内部桥访问 Agent,再由 Agent 使用当前请求的短期产品凭据调用 TJWater Server。`embedded` 模式会把启动时生成的内部密钥传给子进程;`client` 模式必须在 Agent 与外部 OpenCode 服务中配置相同的 `AGENT_INTERNAL_TOKEN` 后分别重启。缺少共享密钥时 Agent 会拒绝启动,工具桥也不会退化为仅凭 session ID 访问。
独立管理 Agent 与 OpenCode 时必须显式配置稳定的 `AGENT_INTERNAL_TOKEN`;如果 `bun --watch` 使用自动生成的密钥重启 Agent,仍在运行的 OpenCode 子进程会保留旧密钥,内部工具桥将拒绝请求。需要保留现有开发服务做隔离联调时,可运行 `bun run start:integration:isolated`。它默认使用 Agent `18787`、OpenCode `14096`,从当前仓库目录加载 `opencode.json`、`.opencode/` 与现有 provider 环境,并把 Agent Session、memory、result ref、Skill 及 OpenCode XDG 运行数据写入 `data/integration-18787/`,不会复用默认运行实例的数据目录。可用 `INTEGRATION_AGENT_PORT`、`INTEGRATION_OPENCODE_PORT`、`INTEGRATION_DATA_DIR` 覆盖这些隔离值;启动器不会输出内部密钥。
## CI/CD
Gitea Actions 通过 `.gitea/workflows/package.yml` 复用
@@ -108,5 +117,4 @@ Gitea Actions 通过 `.gitea/workflows/package.yml` 复用
提升为正式 `agent` 服务。
仓库需要配置 `REGISTRY_USERNAME`、`REGISTRY_PASSWORD` 和
`DEV_DEPLOY_SSH_KEY` 三个 Gitea Secrets。`.env`、持久化数据、日志和
`source/` 业务数据不会写入镜像;它们由 Dev 服务器通过环境文件和卷挂载。
`DEV_DEPLOY_SSH_KEY` 三个 Gitea Secrets。`.env`、持久化数据和日志不会写入镜像;它们由 Dev 服务器通过环境文件和卷挂载。