Skip to content

Server API 执行类 endpoint 异常:CLI 正常,但 /message/prompt_async/command/shell/share 存在不一致或失败 #27744

@Brahmsky

Description

@Brahmsky

问题概述

在我的环境里,OpenCode 的 CLI 执行路径是正常的,但 server API 的多个执行类 endpoint 不能正常工作。

整体表现是:session / metadata 相关 API 基本可用,但执行相关 API 存在明显异常或契约不一致:

  • POST /session/{id}/message 会返回一个 assistant message,但 parts 为空,且 info.error.name = "MessageAbortedError"
  • POST /session/{id}/prompt_async 会接受请求,但后续生成的 assistant message 同样是空 parts + MessageAbortedError
  • POST /session/{id}/command 的实际行为和 SDK / OpenAPI 类型定义不一致
  • POST /session/{id}/shell 返回 500 UnknownError
  • GET /session/{id}/share 返回的是 HTML app shell,而不是 JSON

这会导致依赖 OpenCode server API 的集成工具无法工作,即使 CLI 路径是正常的。

环境信息

  • OpenCode 版本:1.15.0
  • 运行环境:WSL / Linux
  • 本地 provider / auth 状态:
    • OpenAI OAuth
    • GitHub Copilot OAuth
  • 成功执行的 CLI 路径实际命中:
    • providerID=openai
    • modelID=gpt-5.4

正常工作的 API

在同一环境中,下列 API 目前看起来是可用的:

  • GET /global/health
  • POST /session?directory=...
  • GET /session
  • GET /session/{id}
  • GET /session/status
  • GET /session/{id}/children
  • GET /session/{id}/todo
  • GET /session/{id}/diff
  • GET /session/{id}/message
  • POST /session/{id}/fork
  • POST /session/{id}/abort

无法正常工作的 API

1. POST /session/{id}/message

最小复现:

opencode serve --hostname 127.0.0.1 --port 4096
curl -sS -X POST 'http://127.0.0.1:4096/session?directory=%2Fhome%2Flifei%2FPrograms' \
  -H 'content-type: application/json' \
  -d '{"title":"api-default"}'

然后:

curl -sS -X POST 'http://127.0.0.1:4096/session/<SESSION_ID>/message' \
  -H 'content-type: application/json' \
  -d '{"parts":[{"type":"text","text":"Reply with exactly: API_OK"}]}'

实际结果:

  • HTTP 200
  • 返回 JSON 中确实有 assistant message
  • parts 为空
  • info.error.name = "MessageAbortedError"
  • info.error.data.message = "Aborted"

返回结构大致如下:

{
  "info": {
    "role": "assistant",
    "error": {
      "name": "MessageAbortedError",
      "data": { "message": "Aborted" }
    }
  },
  "parts": []
}

2. POST /session/{id}/prompt_async

curl -sS -X POST 'http://127.0.0.1:4096/session/<SESSION_ID>/prompt_async' \
  -H 'content-type: application/json' \
  -d '{"parts":[{"type":"text","text":"Reply with exactly: API_OK"}]}'

实际结果:

  • HTTP 204
  • 之后再调用 GET /session/{id}/message,会看到同样的问题:
    • assistant message 存在
    • parts 为空
    • info.error.name = "MessageAbortedError"

3. POST /session/{id}/command

根据本地安装的 SDK 类型定义,SessionCommandData.body.agent 看起来是可选的。

但实际行为是:

  • 不传 agent 时,服务端直接报 schema 错误:
    • Missing key at ["agent"]
  • 传了 agent 之后,请求仍然失败:
    • HTTP 503
    • 响应体为空

所以这里看起来存在 spec / runtime 不一致。

4. POST /session/{id}/shell

  • 不传 agent 时,会有 payload 校验错误
  • 传了 agent 后,服务端返回:
    • HTTP 500
    • UnknownError
  • server log 中能看到 SessionPrompt.shellImpl

5. GET /session/{id}/share

按照 SDK / spec,预期应该是 JSON session/share 响应。

但实际结果是:

  • HTTP 200
  • 返回的是 HTML app shell,而不是 JSON

重要对照:CLI 路径是正常的

同一环境中,CLI 执行没有问题:

opencode run "Reply with exactly: smoke ok"

会按预期输出文本结果。

我也验证过:

opencode run --format json "Reply with exactly: CLI_JSON_OK"

可以正常输出机器可读的 JSON event stream,并包含最终 assistant 文本。

所以这看起来不是一个通用的 provider / model / auth 故障,更像是 server API 的执行路径本身有问题。

日志观察

对于 API 驱动的 prompt 执行,日志显示 session 会进入 resolveTools,随后很快进入 session.idle,但不会像成功的 CLI 路径那样进入正常执行链路。

成功的 CLI 路径里,我能看到类似:

  • service=session.processor
  • service=llm ... stream

而失败的 API 路径里,更多是:

  • session.prompt ... resolveTools
  • 然后 session.idle
  • 没有最终的正常 assistant text 输出

为什么这个问题重要

这个问题会阻塞所有把 OpenCode 当成“可编程执行后端”的集成工具。

我是在测试一个本地 subagent / orchestration 插件时遇到的:插件和 OpenCode server 的通信本身是成功的,但执行类 endpoint 返回的是 aborted / empty assistant 结果,因此无法继续使用。

想确认的问题

  1. 这些问题是否是 1.15.0 已知的 regression?
  2. 当前 server API 是否仍然预期支持这些 endpoint,并与文档 / types-generated spec 一致?
  3. 对于 API 驱动执行,是否存在当前文档里没有写清楚的必要字段或调用顺序?
  4. /session/{id}/share 现在返回 HTML 是设计如此,还是另一个异常?

如果需要,我可以继续补一个更精简的 endpoint 对照表,或者提供更具体的返回 JSON 样例。

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions