Merge pull request #1313 from pikasTech/fix/1292-post-task-feedback
fix: tidy OpenCode smoke post-task guidance
This commit is contained in:
@@ -88,12 +88,12 @@ OTel trace 内常见业务关联属性:
|
||||
|
||||
OpenCode 对话长时间显示 `Thinking`、用户发消息后无 assistant 文本、或怀疑 iframe/live state 没吃到事件时,先分别证明 provider、Cloud Web 代理和浏览器事件流三层状态。provider span 可能已经 200,但 UI 仍可能因 `/global/event` 目录、ticket 或 live state 不一致而不收敛。
|
||||
|
||||
优先用明确 service 的 TraceQL 查询 provider,避免普通 grep 漏掉新 span 名或属性:
|
||||
优先用增强后的 `--grep` 查询 provider/service 线索;当前 grep 会先推断合适的 TraceQL 候选查询,再在扫描到的 trace 内匹配 raw body、span name、route、status message 和 full span attributes:
|
||||
|
||||
```bash
|
||||
bun scripts/cli.ts platform-infra observability search \
|
||||
--target <node> \
|
||||
--query '{ resource.service.name = "opencode-provider-proxy" }' \
|
||||
--grep opencode-provider-proxy \
|
||||
--lookback-minutes 30 \
|
||||
--candidate-limit 100 \
|
||||
--limit 20
|
||||
@@ -106,7 +106,18 @@ Cloud Web 侧查 `/global/event` 长连接的 start span;长连接可能在调
|
||||
```bash
|
||||
bun scripts/cli.ts platform-infra observability search \
|
||||
--target <node> \
|
||||
--query '{ resource.service.name = "hwlab-cloud-web" && span.http.route = "/global/event" }' \
|
||||
--grep opencode.proxy.stream.start \
|
||||
--lookback-minutes 30 \
|
||||
--candidate-limit 300 \
|
||||
--limit 20
|
||||
```
|
||||
|
||||
属性 drill-down 可直接查 key/value;例如:
|
||||
|
||||
```bash
|
||||
bun scripts/cli.ts platform-infra observability search \
|
||||
--target <node> \
|
||||
--grep opencode.proxy.sse.directory_rewrite_enabled=true \
|
||||
--lookback-minutes 30 \
|
||||
--candidate-limit 300 \
|
||||
--limit 20
|
||||
@@ -114,7 +125,7 @@ bun scripts/cli.ts platform-infra observability search \
|
||||
|
||||
期望看到 `opencode.proxy.stream.start`,并检查 `opencode.proxy.sse.directory_rewrite_enabled`、`opencode.proxy.sse.directory_rewrite_from`、`opencode.proxy.sse.directory_rewrite_to`、`opencode.proxy.ticket_accepted`、`span.http.route=/global/event` 和 streaming 标记。`from=/workspace`、`to=/` 代表 HWLAB iframe/public route 与 OpenCode server workspace route 已对齐;如果该 rewrite 不存在或 ticket 未接受,provider 正常也不能说明 UI 正常。
|
||||
|
||||
关闭 OpenCode UI 卡住类 issue 时,OTel 只能证明链路状态;最终还要用 web-probe DOM/事件证据确认浏览器看到 assistant 文本、没有残留 `Thinking`,并且 EventSource 收到 `message.part.updated`、`step-finish`、`session.idle` 等事件。若 `--grep` 没搜到新属性或 span 名,改用上述 TraceQL query,再只对小范围 trace 使用 `trace --raw` 做 bounded attr drill-down。
|
||||
关闭 OpenCode UI 卡住类 issue 时,OTel 只能证明链路状态;最终还要用 `web-probe opencode-smoke` 或等价 DOM/事件证据确认浏览器看到 assistant 文本、没有残留 `Thinking`,并且 EventSource 收到 `message.part.updated`、`step-finish`、`session.idle` 等事件。若 `--grep` 没搜到新属性或 span 名,先阅读输出中的 `grepCoverage`、`grepQueryInference` 和 no-match Next;必要时再改用显式 TraceQL,例如 `{ resource.service.name = "hwlab-cloud-web" && .http.route = "/global/event" }`,并只对小范围 trace 使用 `trace --full|--raw` 做 bounded attr drill-down。
|
||||
|
||||
## Code Agent / AgentRun 排障
|
||||
|
||||
|
||||
@@ -170,7 +170,8 @@ MDTODO 或 Project Management 的 Web 重写/布局 closeout 不能只引用组
|
||||
- issue closeout 优先引用 `web-probe script` 输出的顶层 `issueEvidence` 或 `summary.issueEvidence`;只有需要展开调查时才粘贴 `probe.script.result`、`probe.steps` 或完整 `reportPath`,避免 stdout、summary 和 report 多层重复同一证据。
|
||||
- stdin heredoc 与 `--script-file` 都按 ES module 加载,脚本必须导出 `export default async ({ page, gotoStable, recordStep, ... }) => { ... }`;不要在模块顶层直接写 `return`。失败为 `Illegal return statement`、`does not provide an export named default` 或 finalUrl 仍是 `about:blank` 且 stepCount=0 时,先按 probe 脚本入口误用处理,不要归因成 Cloud Web 行为失败。
|
||||
- 自定义脚本需要主动失败时,优先返回 `{ ok: false, failedCondition: "..." }` 或抛出错误;兼容返回 `{ pass: false }`、`{ success: false }`,且 `{ ok: true, pass: false }` 仍按失败处理。`failedCondition`、`errorMessage`、`message`、`error`、`reason` 或 `summary` 会进入失败摘要;不要只把失败埋在普通业务字段里。
|
||||
- OpenCode iframe 或 direct-host smoke 必须等到 OpenCode frame/direct origin 可用后再操作 composer;填入 prompt 后优先点击可见的 `[data-action='prompt-submit']`,不要把 Enter-only 当成稳定提交路径。关闭 OpenCode 对话类 issue 时,`web-probe script` 顶层 `ok` 不能只是“脚本没抛错”;必须断言 DOM body 出现最终 assistant 文本、没有残留 `Thinking`,并记录 EventSource 或等价事件探针看到 `message.part.updated`、`step-finish`、`session.idle`。手工 EventSource 探针可以证明 `/global/event` 消息到达,但不能替代 UI DOM 终态证据。
|
||||
- OpenCode iframe 或 direct-host smoke 优先使用 typed `web-probe opencode-smoke --node <node> --lane <lane>`,不要重复手写一次性 Playwright 片段。该命令负责登录 HWLAB public origin、打开 `/opencode`、定位 iframe/direct origin、打开 project/composer、点击可见 `[data-action='prompt-submit']`、采集 EventSource,并断言 DOM assistant 文本与 update/finish/idle 终态。只有 typed 命令覆盖不到的额外 API 或 UI 细节才退回 `web-probe script`。
|
||||
- 自定义 OpenCode smoke 必须等到 OpenCode frame/direct origin 可用后再操作 composer;填入 prompt 后优先点击可见的 `[data-action='prompt-submit']`,不要把 Enter-only 当成稳定提交路径。关闭 OpenCode 对话类 issue 时,`web-probe script` 顶层 `ok` 不能只是“脚本没抛错”;必须断言 DOM body 出现最终 assistant 文本、没有残留 `Thinking`,并记录 EventSource 或等价事件探针看到 `message.part.updated`、`step-finish`、`session.idle`。手工 EventSource 探针可以证明 `/global/event` 消息到达,但不能替代 UI DOM 终态证据。
|
||||
- web-probe 由 UniDesk CLI 从 YAML 声明的 bootstrap admin sourceRef 读取凭据并建立同源 `hwlab_session`;脚本不得自行读取、打印或复制 Web 登录凭据、cookie、token 或完整 API key。
|
||||
- 需要禁用 `EventSource`、mock `Date`/clock、注入 preload hook 或修改浏览器启动前全局对象时,`page.addInitScript()` 必须在目标页面整页加载前注册,并用 `page.goto(new URL(path, origin).toString(), { waitUntil: "domcontentloaded" })` 进入目标 deep link;不要依赖 `gotoStable()` 复用当前 SPA 页面后再期待 init script 生效。若只在已加载页面上 route/block 请求,既有 SSE 或 store 状态可能继续更新,不能作为“无后端刷新依赖”的验收。
|
||||
- 脚本构造 URL 时使用 `new URL(path, baseUrl).toString()`;不要拼出 `//v1/...`。
|
||||
|
||||
@@ -117,9 +117,9 @@ Workbench prompt、TraceTimeline、final response、详情弹窗、session 切
|
||||
|
||||
HWLAB 接入 OpenCode 时,默认采用独立 `opencode-server` Pod 和独立 public hostname,通过 Cloud Web 的 `/opencode` 导航与 iframe 集成;不要把 OpenCode UI 与 HWLAB Cloud Web 合并到同一个 Pod,也不要让 public OpenCode hostname 直接暴露 OpenCode Basic Auth。Cloud Web 继续拥有 HWLAB 登录态和同源 session,OpenCode public hostname 应先经过 Cloud Web 鉴权代理;未登录访问 OpenCode host 的健康或 API 路径时,预期是 Cloud Web 的鉴权失败响应,而不是浏览器 Basic Auth 弹窗。
|
||||
|
||||
OpenCode provider/model、public hostname、SecretRef 和 extra FRP proxy 都必须从 issue/CLI 选中的 node/lane YAML 与目标 HWLAB repo render 读取;长期参考不硬编码当前模型或端口。关闭 OpenCode 集成、provider profile 或微前端入口类 issue 时,最小证据应来自选中 node/lane 的 `web-probe script`:登录 HWLAB public origin,打开 `/opencode`,确认 iframe origin、OpenCode `/global/health`、`/config` 中的 provider/model、`/session` 创建,以及 `/session/:id/message` 返回的 providerID、modelID、terminal finish 和最终 assistant text。只看到 `opencode-server` Pod ready、Caddy hostname 200 或 Secret 存在,不能替代这个浏览器入口 smoke。
|
||||
OpenCode provider/model、public hostname、SecretRef 和 extra FRP proxy 都必须从 issue/CLI 选中的 node/lane YAML 与目标 HWLAB repo render 读取;长期参考不硬编码当前模型或端口。关闭 OpenCode 集成、provider profile 或微前端入口类 issue 时,最小浏览器证据优先使用选中 node/lane 的 `web-probe opencode-smoke`:登录 HWLAB public origin,打开 `/opencode`,定位 iframe/direct OpenCode origin,打开 project/composer,点击可见 submit,确认最终 assistant 文本和 EventSource 终态事件。只有需要额外核对 `/global/health`、`/config` 或底层 `/session/:id/message` payload 时,才补 `web-probe script` 做 bounded API drill-down。只看到 `opencode-server` Pod ready、Caddy hostname 200 或 Secret 存在,不能替代浏览器入口 smoke。
|
||||
|
||||
排查 OpenCode 对话长时间停在 `Thinking` 或无 assistant 文本时,先拆分 provider 完成、Cloud Web 代理长连接和 UI live state 三层事实。provider 侧必须按 `opencode-provider-proxy` service 明确查 OTel,确认 `/v1/chat/completions` 状态、耗时、content chunk、reasoning-only drop 和 done line;Cloud Web 侧必须能看到 `/global/event` 的 `opencode.proxy.stream.start` span,以及 `opencode.proxy.sse.directory_rewrite_enabled`、`from=/workspace`、`to=/`、`ticket_accepted=true` 等属性。关闭证据必须包含浏览器 DOM 最终 assistant 文本、没有残留 `Thinking`,以及 EventSource 收到 `message.part.updated`、`step-finish`、`session.idle` 等事件;provider 200 或 `/session/:id/message` 返回 terminal 不能单独证明 UI 已收敛。OpenCode composer smoke 应优先点击可见的 `[data-action='prompt-submit']` 提交按钮;只依赖 Enter 在 contenteditable 状态下不稳定。
|
||||
排查 OpenCode 对话长时间停在 `Thinking` 或无 assistant 文本时,先拆分 provider 完成、Cloud Web 代理长连接和 UI live state 三层事实。provider 侧必须按 `opencode-provider-proxy` service 明确查 OTel,确认 `/v1/chat/completions` 状态、耗时、content chunk、reasoning-only drop 和 done line;Cloud Web 侧必须能看到 `/global/event` 的 `opencode.proxy.stream.start` span,以及 `opencode.proxy.sse.directory_rewrite_enabled`、`from=/workspace`、`to=/`、`ticket_accepted=true` 等属性。关闭证据必须包含 `web-probe opencode-smoke` 或等价浏览器 DOM 的最终 assistant 文本、没有残留 `Thinking`,以及 EventSource 收到 `message.part.updated`、`step-finish`、`session.idle` 等事件;provider 200 或 `/session/:id/message` 返回 terminal 不能单独证明 UI 已收敛。OpenCode composer smoke 应优先点击可见的 `[data-action='prompt-submit']` 提交按钮;只依赖 Enter 在 contenteditable 状态下不稳定。
|
||||
|
||||
## HWLAB FRP 维护
|
||||
|
||||
|
||||
@@ -61,6 +61,12 @@ OA Event Flow 的高频 trace 统计不得把每个 `trace-stats-updated` 投影
|
||||
|
||||
CLI 写 stdout/stderr 遇到下游 pipe 关闭的 `EPIPE` 必须安静退出,不能打印 Bun stack trace。常见验证命令是 `set -o pipefail; bun scripts/cli.ts server status | head -1`,应只看到第一行 JSON 而无额外错误噪声。
|
||||
|
||||
## OpenCode Trace Search
|
||||
|
||||
HWLAB OpenCode 对话排障时,`platform-infra observability search --grep` 是首选入口,而不是默认手写宽泛 TraceQL。`--grep opencode.proxy.stream.start` 应推断为 span name 查询,`--grep /global/event` 应推断为 route 查询,`--grep opencode.proxy.sse.directory_rewrite_enabled=true` 应推断为属性 bool 查询;候选 trace 取回后还必须在 raw body、span name、status message、route 和 full span attributes 中做二次匹配。默认输出必须披露 `grepCoverage` 和 `grepQueryInference`,无命中时给出显式 TraceQL 与扩大 candidate/window 的下一步。
|
||||
|
||||
OpenCode provider 侧至少保留 `opencode.provider.sse.content_chunks`、`content_chars`、`output_data_lines`、`done_lines`、`json_errors` 和 `reasoning_only_choices_dropped` 等属性摘要;Cloud Web `/global/event` 侧至少保留 `opencode.proxy.stream.start`、`opencode.proxy.sse.directory_rewrite_enabled`、directory rewrite from/to、`opencode.proxy.ticket_accepted` 和 streaming 标记。OTel 只能证明链路状态,关闭 UI 卡住类问题仍必须回到 `web-probe opencode-smoke` 或等价浏览器 DOM/EventSource 终态证据。
|
||||
|
||||
## Task Liveness
|
||||
|
||||
backend-core 必须把 queued、dispatched、running 视为待处理任务,并通过 `TASK_PENDING_TIMEOUT_MS` 对长时间没有 provider 终态回报的任务做超时处理。超时任务转为 failed,result 中保留 timeout、previousStatus 和 previousResult 摘要,避免 `态势总览` 的待处理数量长期卡住且无法解释。
|
||||
|
||||
@@ -2019,7 +2019,6 @@ export function parseNodeWebProbeOptions(args: string[]): NodeWebProbeOptions {
|
||||
"Passing means the browser DOM reached assistant text and the OpenCode EventSource produced update, finish and idle evidence.",
|
||||
],
|
||||
generatedPreferredCommands: {
|
||||
rerun: commandLabel,
|
||||
withExpectedText: `${commandLabel} --expect-text <assistant-substring>`,
|
||||
},
|
||||
scriptSource: {
|
||||
|
||||
Reference in New Issue
Block a user