From 6072cae1c59bf16625b71215b370b27671d7ebef Mon Sep 17 00:00:00 2001 From: KXH Date: Sun, 2 Aug 2026 18:11:31 +0800 Subject: [PATCH] feat: publish FieldPilot online workbench --- README.md | 22 ++++++++++----------- docs/architecture.md | 2 +- docs/deployment-free-tier.md | 16 ++++++++++++--- docs/development-log.md | 9 +++++++++ docs/release-readiness.md | 31 +++++++++++++++--------------- docs/resume-project-description.md | 4 ++-- docs/roadmap.md | 4 ++-- frontend/src/App.vue | 2 +- frontend/src/ShowcasePage.vue | 22 +++++++++++++-------- frontend/src/main.ts | 5 ++++- frontend/src/styles.css | 3 ++- netlify.toml | 7 +++++-- 12 files changed, 80 insertions(+), 47 deletions(-) diff --git a/README.md b/README.md index b3ab066..6e30761 100644 --- a/README.md +++ b/README.md @@ -2,13 +2,13 @@ FieldPilot 面向经常跨省市出差的外勤人员,把口语描述中的地点、任务时间窗、紧密程度、交通偏好和公司报销规则转换为可验证、可比较、可动态重规划的执行方案。 -**在线专题:** [fieldpilot-kxh.netlify.app](https://fieldpilot-kxh.netlify.app/) · **源代码:** [github.com/KXHXK/fieldpilot](https://github.com/KXHXK/fieldpilot) +**在线项目站:** [fieldpilot-kxh.netlify.app](https://fieldpilot-kxh.netlify.app/) · **在线工作台:** [fieldpilot-kxh.netlify.app/workbench](https://fieldpilot-kxh.netlify.app/workbench) · **源代码:** [github.com/KXHXK/fieldpilot](https://github.com/KXHXK/fieldpilot) 当前开发版本是 `0.5.0-dev`。PydanticAI 单 Agent 只负责自然语言到严格 MissionDraft 的转换;确定性 Planner、Policy Engine 和独立 Verifier 负责时窗、候选、费用与报销判断。系统不会让模型编造车次、计算成本或执行购票订房。 > `0.1.0` 是已提交、可回退的技术基线,不是最终求职版本。目标 `v1.0` 将围绕真实跨城出差、任务时窗、报销约束和动态重规划重构;完整设计见 [企业级目标设计](docs/specs/2026-07-30-fieldpilot-enterprise-design.md)。在对应实现、评测和部署证据完成前,目标设计中的能力不得写成已落地事实。 -当前实现已完成领域持久化、有限搜索规划、高德路线与餐饮适配及降级、Agent 解析与审计、事件驱动重规划、执行检查点、严格后缀重规划、修订差异和 Vue 工作台闭环。面向访客的静态专题页已独立部署;可写的 FastAPI/PostgreSQL 公网后端、高德与 LLM 真实密钥、Docker 容器仍未完成验证,相关能力不会冒充已上线。 +当前实现已完成领域持久化、有限搜索规划、高德路线与餐饮适配及降级、Agent 解析与审计、事件驱动重规划、执行检查点、严格后缀重规划、修订差异和 Vue 工作台闭环。项目站与可写工作台部署在 Netlify,Render Docker/FastAPI 连接 Neon PostgreSQL;公网健康/就绪、完整写入 smoke、生产 CORS 与重启后持久化均已验证。公开环境仍使用 Mock LLM 与 Fixture Provider,不把合成库存或价格冒充实时数据。 ![FieldPilot v1 工作台](docs/fieldpilot-workbench.png) @@ -42,11 +42,11 @@ FieldPilot 面向经常跨省市出差的外勤人员,把口语描述中的地 | 能力 | 当前状态 | 验收边界 | | --- | --- | --- | | FastAPI + Pydantic 数据契约 | 已实现并测试 | 结构化 API 可复现 | -| PydanticAI 单 Agent + MissionDraft | 已实现结构化输出、Mock/fallback、TestModel 测试与 15 场景真实模型评测工作流;真实运行等待工作流凭证环境 | fallback 不计入真实模型指标,失败时工作流失败 | +| PydanticAI 单 Agent + MissionDraft | 已实现结构化输出、Mock/fallback、TestModel 测试与 15 场景 Kimi K2.6 真实模型评测 | 最终 run 15/15 live;fallback 不进入真实模型指标 | | 高德 v5 市内路线适配 | 已进入规划链路并完成 MockTransport 契约/故障测试;真实密钥未复验 | 已验证适配与降级,未验证实时服务可用性 | | 高德 v5 周边餐饮 POI | 已实现预算过滤、缓存、失败降级和来源快照;真实密钥未复验 | 无人均消费字段的 POI 不进入方案,Fixture 不冒充实时报价 | -| Vue v1 任务、方案、来源与重规划工作台 | 已实现并完成生产构建 | 本地真实浏览器链路已验收 | -| Mission、政策快照与计划修订持久化 | 已实现并测试 | SQLite 已验证,PostgreSQL 容器尚未实跑 | +| Vue v1 任务、方案、来源与重规划工作台 | 已实现、生产构建并部署 | 本地完整链路与公网 Agent 解析/方案创建已用真实浏览器验收 | +| Mission、政策快照与计划修订持久化 | 已实现并测试 | SQLite 与 Neon PostgreSQL 已验证;Render 重启后数据仍可读取 | | 有限搜索 Planner + Policy Engine + 独立 Verifier | 已实现;跨城、酒店和无 Key 餐饮使用明确 Fixture | 确定性规划可复现,数据模式必须随 segment 传递 | | 计划请求幂等、revision 冲突与激活 | 已实现并测试 | 并发与重放路径已有接口测试 | | AgentRun 审计、幂等与固定集 | 已实现输入指纹、trace 查询、5 场景 Mock 基线与独立 15 场景 live 固定集 | Mock 与 live 指标、数据集和报告分离 | @@ -54,14 +54,14 @@ FieldPilot 面向经常跨省市出差的外勤人员,把口语描述中的地 | ExecutionCheckpoint 与严格后缀重规划 | 已实现命令幂等、版本冲突、单调锁定/完成和前缀逐段一致性校验 | 只重算检查点后的可变后缀;有界搜索不声称全局最优 | | CrewAI、LlamaIndex、Pydantic Evals | 未接入 | 当前业务不需要 | | RAG、审批流、SSE、全局路线最优化 | 未实现 | 不属于当前已验收能力 | -| 独立公网静态专题页 | 已部署并完成 HTTP/CDN 验证 | 独立 URL,只展示经验证的架构、流程与边界,不连接可写后端 | -| FastAPI/PostgreSQL 公网服务 | 已提供 Render Blueprint、Neon URL 兼容和生产 CORS 配置;等待平台账号授权后部署 | 未取得公网 health/ready 与持久化证据前仍标记为未上线 | +| 公网项目站与在线工作台 | 已部署并完成 HTTP/CDN、SPA 路由及浏览器验证 | 根路径讲解架构,`/workbench` 调用生产 API;外部数据模式逐段标记 | +| FastAPI/PostgreSQL 公网服务 | Render Docker/FastAPI 与 Neon PostgreSQL 已部署 | health/ready、完整 R1/R2 smoke、CORS 和重启恢复均通过;免费层存在冷启动 | -## 公网静态专题 +## 公网项目站与在线工作台 -[FieldPilot 在线专题](https://fieldpilot-kxh.netlify.app/) 使用独立的 Vite `showcase` 构建模式,展示真实问题、Agent 与确定性系统的职责边界、检查点后缀重规划、架构取舍和验证证据。它与本地 Vue 工作台共用已验证的业务事实,但不调用或模拟一个不存在的公网后端。 +[FieldPilot 在线项目站](https://fieldpilot-kxh.netlify.app/) 使用 Vite `showcase` 构建模式展示业务问题、Agent 与确定性系统的职责边界、检查点后缀重规划、架构取舍和验证证据;同一构建的 [`/workbench`](https://fieldpilot-kxh.netlify.app/workbench) 连接 [Render API](https://fieldpilot-api-t7m6.onrender.com/api/health),可实际完成任务解释、持久化、规划、执行检查点与事件式重规划。 -当前生产部署为 Netlify deploy `6a6c82f34f699af981dae355`。已验证根路径和 SPA 回退返回 HTTPS 200、指纹化 JS/CSS 资源由 CDN 正确提供,CSP、COOP、`nosniff`、Referrer-Policy 与 Permissions-Policy 响应头生效。完整任务录入、持久化和重规划操作请按下文启动本地前后端。 +当前生产部署为 Netlify deploy `6a6f13259646109fe6f02be6`。已验证根路径与 `/workbench` 返回 HTTPS 200、指纹化 JS/CSS 由 CDN 正确提供,CSP 只允许指定 Render API;Render 只向正式 Netlify origin 返回 CORS 许可,随机预览域名会被拒绝。在线浏览器已显示 `API ok`,杭州示例解析为可提交的两任务严格草案。 ## 本地运行 @@ -139,7 +139,7 @@ cd ..\frontend npm run build ``` -当前结果(2026-08-01):后端 `51 passed`;Neon PostgreSQL 已执行 Alembic 至 `20260731_0004 (head)` 并通过就绪查询;完整工作台与静态专题两种前端生产构建成功;Kimi K2.6 的 15 场景最终全量 run 为 15/15 live、状态与安全标签准确率 100%、选定字段精确率 94.87%、澄清字段精确率 93.33%。本地 HTTP 冒烟、真实浏览器主链路和公网专题 HTTP/CDN 检查通过。Docker CLI 未安装,Render 公网容器仍等待控制台授权,因此不声称后端已上线。详细记录见 [开发日志](docs/development-log.md)。 +当前结果(2026-08-02):后端 `51 passed`;Neon PostgreSQL 已执行 Alembic 至 `20260731_0004 (head)`;完整工作台与项目专题两种前端生产构建成功;Kimi K2.6 的 15 场景最终全量 run 为 15/15 live、状态与安全标签准确率 100%、选定字段精确率 94.87%、澄清字段精确率 93.33%。本地链路、Render 公网 R1/R2 smoke、重启后持久化、生产 CORS、Netlify HTTP/CDN 和公网真实浏览器链路均通过。详细记录见 [开发日志](docs/development-log.md)。 运行中的完整 HTTP 冒烟(需要先启动后端): diff --git a/docs/architecture.md b/docs/architecture.md index 5606d39..a83bb88 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -75,4 +75,4 @@ SQLAlchemy/Alembic 管理 Mission、VisitTask、ExpensePolicy、PlanRevision、P ## 8. 交付边界 -本地已验证 SQLite、51 项 Pytest、Alembic `20260731_0004` 往返、运行中 HTTP 冒烟、真实浏览器执行检查点/后缀重规划链路与 Vue 生产构建。Neon `fieldpilot` 数据库已实际迁移到 head 并通过就绪查询;Kimi K2.6 已完成 15 场景真实模型评测。独立 Netlify 静态专题已上线并完成 HTTPS、SPA 回退、CDN 资源与安全响应头验证;它不连接可写后端。Render Blueprint、migration-on-start 和 CORS 已配置,公网容器仍在部署授权阶段。 +本地已验证 SQLite、51 项 Pytest、Alembic `20260731_0004` 往返、运行中 HTTP 冒烟、真实浏览器执行检查点/后缀重规划链路与 Vue 生产构建。Neon `fieldpilot` 数据库已迁移到 head;Kimi K2.6 已完成 15 场景真实模型评测。Netlify 根路径承载项目专题,`/workbench` 调用 Render Docker/FastAPI;公网 health/ready、R1/R2 smoke、精确 CORS、Neon 持久化和 Render 重启恢复均已验证。公开环境仍使用 Mock LLM 与 Fixture Provider,不具备真实预订、生产限流、多租户隔离或 SLA。 diff --git a/docs/deployment-free-tier.md b/docs/deployment-free-tier.md index 204c93e..e72026e 100644 --- a/docs/deployment-free-tier.md +++ b/docs/deployment-free-tier.md @@ -3,8 +3,8 @@ ## 目标拓扑 ```text -Netlify 静态专题 -> Render FastAPI -> Neon PostgreSQL -fieldpilot-kxh fieldpilot-api fieldpilot database +Netlify 项目站 + 工作台 -> Render FastAPI -> Neon PostgreSQL +fieldpilot-kxh fieldpilot-api fieldpilot database ``` 仓库根目录的 `render.yaml` 固定 Singapore、Docker runtime、`/api/ready` 健康检查、生产 CORS 和无密钥 Fixture 模式。`DATABASE_URL` 标记为 `sync: false`,只能在 Render 控制台录入,不能提交到 Git。 @@ -42,4 +42,14 @@ Invoke-RestMethod "$apiBase/api/ready" ## 当前状态 -截至 2026-08-01,Neon 项目和独立 `fieldpilot` 数据库已创建,四段 Alembic migration 已执行到 `20260731_0004 (head)`,并通过 `SELECT 1` 就绪查询。代码侧 Blueprint、Neon URL 归一化、migration-on-start、健康/就绪探针和 CORS 已准备。Render CLI 的 device-grant 请求在当前网络持续超时,应用内 Render 控制台尚未登录,因此仍没有公网 API URL,也不把“已配置”写成“已部署”。 +截至 2026-08-02,三层免费拓扑已上线:Netlify 项目站与工作台为 和 `/workbench`,Render API 为 ,数据进入 Neon `fieldpilot` PostgreSQL。初始生产容器部署 commit 为 `bc53426`,Netlify 生产 deploy 为 `6a6f13259646109fe6f02be6`。 + +已取得的上线证据: + +- `/api/health` 与 `/api/ready` 均为 HTTPS 200,数据库状态为 reachable,公开环境明确返回 `agent_mode=mock`、`local_route_provider=fixture`。 +- 公网 smoke 完成 Mission → R1 → 激活 → 执行检查点 → 任务改期事件 → R2 → Diff,得到 `protected_prefix_unchanged=true`。 +- Render 手动重启后,既有 Mission 仍为 active、R1/R2 与执行检查点仍可读取,证明状态不依赖临时文件系统。 +- 生产 Netlify origin 获得精确 CORS 许可;随机 Deploy Preview origin 被拒绝。工作台真实浏览器显示 `API ok` 并完成杭州示例 Agent 解析。 +- 数据库 owner 凭证在发布后完成轮换,旧凭证失效;仓库、文档和命令输出均不记录连接串。 + +免费层边界仍然存在:Render 空闲时可能冷启动;公开环境没有多租户认证和生产限流;高德真实 Key 未验收,铁路、航班与酒店仍是显式 Fixture。因此这是可交互工程演示环境,不承担真实预订或生产 SLA。 diff --git a/docs/development-log.md b/docs/development-log.md index bac9343..461a40d 100644 --- a/docs/development-log.md +++ b/docs/development-log.md @@ -341,3 +341,12 @@ Stage 4B:增加 AgentRun/DecisionTrace 持久化与请求幂等,建立版本 - 评测器在每例仅一次调用时将稳定率记为 `null`,避免把单样本恒等误写为 100% 稳定;artifact 新增实际澄清字段名,仍不保存用户原文或模型自由文本。 - Neon `fieldpilot` 数据库完成四段 Alembic migration,`alembic current` 为 `20260731_0004 (head)`,并通过独立 `SELECT 1` 就绪查询。连接凭证只在进程环境中短暂使用,未写入仓库或日志。 - 后端全量回归为 `51 passed`。Render CLI 到 `api.render.com` 的 device-grant 请求持续网络超时,应用内控制台又处于未登录状态,因此公网容器发布仍等待一次人工登录授权。 + +## 2026-08-02|Stage 14:零成本公网闭环与在线工作台 + +- 通过 Render Blueprint 创建 Singapore Free Docker Web Service `fieldpilot-api`,连接 Neon `fieldpilot` PostgreSQL;启动时 Alembic migration、`/api/health` 与 `/api/ready` 均成功,初始生产部署 commit 为 `bc53426`。 +- 公网完整 smoke 覆盖 Mission、R1 激活、执行检查点、任务改期事件、R2、Revision Diff 与严格受保护前缀,输出 `protected_prefix_unchanged=true`。手动重启 Render 后既有 Mission、R1/R2、Event 与执行检查点仍可读取。 +- 验证生产 CORS 只允许 `https://fieldpilot-kxh.netlify.app`;随机 Netlify Deploy Preview origin 无许可。数据库 owner 凭证随后完成轮换,旧凭证失效,连接串未写入仓库或文档。 +- 将同一 Netlify `showcase` 构建扩展为“根路径项目专题 + `/workbench` 在线工作台”,生产 CSP 只放行指定 Render API。正式站点真实浏览器显示 `API ok`,杭州示例经 Agent 解析后得到可提交的两任务严格草案。 +- Netlify 账户直接生产发布仍返回 403;预览 deploy `6a6f13259646109fe6f02be6` 构建并上传成功后,通过 Netlify 官方 restore deploy 操作晋升为同一份生产产物,没有重建或替换文件。 +- 公网环境明确使用 Mock LLM 与 Fixture Provider;真实高德 Key、生产限流、多租户认证和真实预订仍不属于已验证能力。 diff --git a/docs/release-readiness.md b/docs/release-readiness.md index 95a813e..97522f9 100644 --- a/docs/release-readiness.md +++ b/docs/release-readiness.md @@ -1,10 +1,10 @@ # FieldPilot 0.5.0-dev 发布验收清单 -验收日期:2026-08-01 +验收日期:2026-08-02 -验收分支:`fix/agent-output-canonicalization`(PR #10) +验收分支:`agent/public-workbench` -已知稳定回滚点:`f586208` +已知稳定回滚点:`bc53426`(首个已验证 Render 生产部署) ## 已验证 @@ -22,22 +22,23 @@ - [x] 真实浏览器完成 interpret → R1 → lock V1 → event → R2 → complete V2 → diff。 - [x] 浏览器控制台无 warning/error。 - [x] Fixture、manual、mock 状态在页面明确显示。 -- [x] 独立静态专题使用 `showcase` 构建模式,不向访客伪装可写公网后端。 +- [x] 根路径使用 `showcase` 项目专题,`/workbench` 连接实际公网后端;Mock/Fixture 来源在 UI 明确标记。 - [x] 专题页桌面/移动端无横向溢出,R1/R2 时间线切换有效,浏览器控制台无 warning/error。 - [x] Neon `fieldpilot` 数据库执行 Alembic 至 `20260731_0004 (head)`,并通过独立就绪查询。 - [x] Kimi K2.6 完成 15 场景真实评测:15/15 live、无 fallback;最终全量 run 的状态/安全标签准确率 100%,字段 94.87%,澄清 93.33%。 ## 已配置但未验证 -- [ ] Docker 镜像构建与 PostgreSQL Compose:本机没有 Docker CLI。 +- [x] Docker 镜像已由 Render 云端构建并运行;本地 PostgreSQL Compose/Nginx 仍因本机没有 Docker CLI 未实跑。 - [x] Render Free Blueprint、Neon PostgreSQL URL 归一化、migration-on-start、`/api/ready` 和生产 CORS 配置。 -- [ ] 独立 FastAPI/PostgreSQL 公网后端:Neon 已验证,Render 控制台仍等待登录授权;静态专题当前不调用该能力。 +- [x] 独立 FastAPI/PostgreSQL 公网后端:Render Docker/FastAPI 已连接 Neon,并通过完整 smoke、CORS 和重启恢复验证。 ## 远端验证 - [x] GitHub Actions `verify`:后端测试、Alembic schema check 与前端构建通过。 -- [x] Netlify 静态专题生产地址:。 -- [x] 生产 deploy `6a6c82f34f699af981dae355`:根路径、SPA 回退、JS/CSS CDN 资源与安全响应头通过 HTTP 验证。 +- [x] Netlify 项目站与在线工作台:、。 +- [x] 生产 deploy `6a6f13259646109fe6f02be6`:根路径、工作台、SPA 回退、JS/CSS CDN、CSP 与真实浏览器 Agent 解析通过。 +- [x] Render API:;初始生产 commit `bc53426`。 - [x] GitHub Actions live eval run `30687086569`:15/15 Kimi K2.6 调用为 live,artifact 已下载核验。 ## 需要外部凭证 @@ -46,11 +47,11 @@ - [x] 配置 `FIELD_PILOT_LLM_API_KEY` 与供应商 variables,运行 `fieldpilot-live-agent-eval`,下载与 Mock 分开的真实模型报告并记录 run URL/commit。 - [ ] 如果需要交互地图,单独配置公开的 Web JS Key 与安全码。 -## 公网后端发布前必须再次确认 +## 公网后端发布验收 -- [ ] 后端先部署并直接访问 HTTPS `/api/health` 和 `/api/ready`。 -- [ ] CORS 只允许实际前端 origin。 -- [ ] 前端 `VITE_API_BASE_URL` 指向正确 HTTPS 后端并重新构建。 -- [ ] 云端运行 migration,验证重启后 revision 和 event 仍存在。 -- [ ] 先跑便宜的 health/smoke,再运行真实 Provider 请求。 -- [ ] README 中只保留已验证事实,记录部署 commit 与回滚 commit。 +- [x] 后端 HTTPS `/api/health` 和 `/api/ready` 返回 200。 +- [x] CORS 只允许实际前端 origin,随机预览 origin 被拒绝。 +- [x] 前端 `VITE_API_BASE_URL` 指向正确 HTTPS 后端并重新构建。 +- [x] 云端 migration 完成;Render 重启后 revision、event 和执行检查点仍存在。 +- [x] health、完整 smoke 与公网真实浏览器链路通过;没有消耗真实 Provider 配额。 +- [x] README 记录已验证事实、初始部署 commit 与 Netlify deploy。 diff --git a/docs/resume-project-description.md b/docs/resume-project-description.md index c3fb23f..510915b 100644 --- a/docs/resume-project-description.md +++ b/docs/resume-project-description.md @@ -16,7 +16,7 @@ PydanticAI、FastAPI、Pydantic v2、SQLAlchemy/Alembic、Vue 3/TypeScript、htt ## 60 秒讲法 -FieldPilot 来自我真实跨省市出差时反复遇到的痛点:工作地点有时间窗,交通、酒店和餐饮分散在不同平台,公司又有报销上限,临时改期后很难快速确认整条行程仍可执行。我没有让大模型直接生成行程,而是让一个 PydanticAI Agent 只做口语到严格任务草案的转换;确认后由 Provider 层拿候选,确定性 Planner 做有界搜索,Policy Engine 算报销规则,再由独立 Verifier 复算不变量。计划和候选来源都会存成版本。现场改期时,事件在同一事务里修改事实,新计划引用事件,并输出前后成本、评分和行程段差异。当前无密钥 Fixture 全链路和故障路径已验证;真实高德/模型 Key 与公网部署我会明确说还没完成,不拿 Mock 指标冒充线上效果。 +FieldPilot 来自我真实跨省市出差时反复遇到的痛点:工作地点有时间窗,交通、酒店和餐饮分散在不同平台,公司又有报销上限,临时改期后很难快速确认整条行程仍可执行。我没有让大模型直接生成行程,而是让一个 PydanticAI Agent 只做口语到严格任务草案的转换;确认后由 Provider 层拿候选,确定性 Planner 做有界搜索,Policy Engine 算报销规则,再由独立 Verifier 复算不变量。计划和候选来源都会存成版本。现场改期时,事件在同一事务里修改事实,新计划引用事件,并输出前后成本、评分和行程段差异。Kimi K2.6 独立真实评测与无密钥 Fixture 全链路已经验证;Render Docker/FastAPI、Neon PostgreSQL 和 Netlify 工作台已经上线。公开环境仍明确使用 Mock LLM/Fixture,不把它描述为实时库存或生产 SLA。 ## 高频追问 @@ -36,6 +36,6 @@ Agent 负责从不完整口语中抽取多类约束并生成最少澄清问题 - “真实高德/Kimi/12306 已上线”或“实时库存准确”。 - “全局最优”“增量后缀重规划”“所有天气/延误自动处置”。 -- “生产 PostgreSQL/Docker/公网稳定运行”——仅提供配置,尚未完成本机容器与云端验证。 +- “生产级稳定性/SLA/多租户隔离”——当前验证的是免费层公网闭环、重启恢复和精确 CORS,不等于生产流量验证。 - CrewAI、LlamaIndex、RAG、MCP、SSE、HITL、自动预订。 - Mock 固定集的 1.00 指标作为真实模型准确率。 diff --git a/docs/roadmap.md b/docs/roadmap.md index 7518c41..8093f6d 100644 --- a/docs/roadmap.md +++ b/docs/roadmap.md @@ -2,9 +2,9 @@ ## P0:交付验收 -- 在具备 Docker 的环境运行 PostgreSQL Compose,验证 migration、ready probe、Nginx 代理、数据持久化与重启恢复。 +- [云端已完成] Render Docker + Neon PostgreSQL 已验证 migration、ready probe、数据持久化与重启恢复;本地 Compose/Nginx 仍因本机无 Docker CLI 未实跑。 - 用独立高德 Web Service Key 执行最小真实路线验收,保存脱敏快照;用模型 Key 跑 `mission-interpret-v1` 固定集,生成与 Mock 分开的延迟、Token、失败率和字段指标。 -- [已完成] 增加浏览器主链路验收与工作台截图,并发布独立静态专题地址;不复用智能旅游助手域名。完整可写公网后端仍未部署。 +- [已完成] 增加浏览器主链路验收与工作台截图,发布独立项目站、在线工作台和可写公网后端;不复用智能旅游助手域名。 ## P1:补齐核心业务 diff --git a/frontend/src/App.vue b/frontend/src/App.vue index 6be0753..0821170 100644 --- a/frontend/src/App.vue +++ b/frontend/src/App.vue @@ -274,7 +274,7 @@ function reset() {
FPFieldPilot - +
diff --git a/frontend/src/ShowcasePage.vue b/frontend/src/ShowcasePage.vue index 2f85ec2..5f89ddb 100644 --- a/frontend/src/ShowcasePage.vue +++ b/frontend/src/ShowcasePage.vue @@ -58,13 +58,14 @@ const stack = [
-

FIELD MISSION ORCHESTRATION · STATIC SHOWCASE

+

FIELD MISSION ORCHESTRATION · LIVE SYSTEM

把出差要求,
变成可执行行程。

FieldPilot 面向跨省市外勤场景,把地点、任务时间窗、紧密程度与报销规则转成可验证的交通、住宿、餐饮和多点任务方案;途中变化通过事件与执行检查点安全重规划。

@@ -78,7 +79,7 @@ const stack = [
预算余量
¥890
来源模式
fixture + manual
- 公开页使用已验证的合成数据证据,不连接可写后端。 + 在线工作台连接 Render FastAPI 与 Neon PostgreSQL;外部库存仍使用明确标记的 Fixture 数据。
@@ -151,7 +152,8 @@ const stack = [
API & DATABASE幂等、版本冲突与迁移往返

ExecutionCommand 保存命令指纹;expected_version 防止并发覆盖;Alembic 0004 可升级、检查和回退。

PLANNING受保护前缀逐字段一致

HTTP 冒烟输出 protected_prefix_unchanged=true;Verifier 测试覆盖删除、篡改和越界。

FRONTEND真实浏览器主链路

R1 → lock V1 → event → R2 → complete V2;已完成任务禁用,控制台无 warning/error。

-
DELIVERYGitHub main CI success

后端 46 项测试、迁移 schema check 与 Vue TypeScript/Vite production build 均通过。

+
DELIVERYGitHub main CI success

后端 51 项测试、迁移 schema check 与 Vue TypeScript/Vite production build 均通过。

+
PUBLIC RUNTIMERender + Neon 重启恢复通过

公网 smoke 覆盖 R1、事件式 R2、执行检查点和严格前缀保留;服务重启后仍可读取 Mission、Revision 与 Event。

开发日志 ↗ @@ -163,17 +165,21 @@ const stack = [

HONEST BOUNDARY

-

这是静态项目专题,
不是公开预订或写入服务。

+

可在线体验完整编排,
但不冒充真实预订平台。

-

完整工作台在本地连接 FastAPI、SQLite/PostgreSQL 配置与显式 Mock/Fixture。公网页面只展示已验证的合成场景和工程证据,不暴露模型、地图或数据库凭据。

+

公开工作台连接 FastAPI 与 PostgreSQL,可实际写入任务、生成修订、推进检查点并触发事件式重规划。演示环境不暴露模型、地图或数据库凭据,外部事实来源会在页面逐段标记。

  • 已实现:高德路线/餐饮适配契约、降级、缓存与来源快照。
  • 当前 Fixture:铁路、航班、酒店库存和价格,不抓取 12306 内部接口。
  • -
  • 尚未验证:真实高德/LLM Key、Docker/PostgreSQL 公网运行与生产级限流。
  • +
  • 公网已验证:Docker/FastAPI、Neon PostgreSQL、CORS、完整 smoke 与重启后持久化。
  • +
  • 仍未验证:真实高德 Key、生产限流和多租户身份隔离;公开环境使用 Mock LLM 与 Fixture Provider。
  • 算法口径:有界 Beam Search 可解释、可复现,但不声称全局最优。
- 查看源码、测试与文档 +
diff --git a/frontend/src/main.ts b/frontend/src/main.ts index 5014a36..5e2130b 100644 --- a/frontend/src/main.ts +++ b/frontend/src/main.ts @@ -4,4 +4,7 @@ import App from "./App.vue"; import ShowcasePage from "./ShowcasePage.vue"; import "./styles.css"; -createApp(import.meta.env.MODE === "showcase" ? ShowcasePage : App).mount("#app"); +const isPublicWorkbench = import.meta.env.MODE === "showcase" + && window.location.pathname.replace(/\/$/, "") === "/workbench"; + +createApp(import.meta.env.MODE === "showcase" && !isPublicWorkbench ? ShowcasePage : App).mount("#app"); diff --git a/frontend/src/styles.css b/frontend/src/styles.css index a09817d..bf65230 100644 --- a/frontend/src/styles.css +++ b/frontend/src/styles.css @@ -138,7 +138,8 @@ button.ghost { color: var(--green); background: transparent; border: 1px solid # .tool-list p { margin: 4px 0 0; color: var(--muted); font-size: 11px; line-height: 1.5; } .page-footer { display: flex; justify-content: space-between; margin: 70px 0 30px; padding-top: 20px; color: var(--muted); border-top: 1px solid var(--line); font-size: 11px; } -.topbar nav { margin-left: auto; margin-right: 18px; } +.topbar nav { display: flex; align-items: center; gap: 18px; margin-left: auto; margin-right: 18px; } +.topbar nav a { color: var(--green); text-decoration: none; } .text-button { padding: 7px 10px; color: var(--green); background: transparent; border: 1px solid var(--line); } .compact-hero { grid-template-columns: minmax(0, 1.3fr) minmax(330px, .7fr); padding: 64px 0 45px; align-items: center; } .compact-hero h1 { font-size: clamp(46px, 5.4vw, 72px); } diff --git a/netlify.toml b/netlify.toml index 6585d53..d8fbafb 100644 --- a/netlify.toml +++ b/netlify.toml @@ -1,7 +1,10 @@ [build] base = "frontend" command = "npm run build:showcase" - publish = "dist" + publish = "frontend/dist" + +[build.environment] + VITE_API_BASE_URL = "https://fieldpilot-api-t7m6.onrender.com/api" [[redirects]] from = "/*" @@ -11,7 +14,7 @@ [[headers]] for = "/*" [headers.values] - Content-Security-Policy = "default-src 'self'; script-src 'self'; style-src 'self'; img-src 'self' data:; font-src 'self' data:; connect-src 'self'; frame-ancestors 'none'; base-uri 'self'; form-action 'self'" + Content-Security-Policy = "default-src 'self'; script-src 'self'; style-src 'self'; img-src 'self' data:; font-src 'self' data:; connect-src 'self' https://fieldpilot-api-t7m6.onrender.com; frame-ancestors 'none'; base-uri 'self'; form-action 'self'" Cross-Origin-Opener-Policy = "same-origin" Permissions-Policy = "camera=(), microphone=(), geolocation=()" Referrer-Policy = "strict-origin-when-cross-origin"