跳到主要内容

OpenAI Responses 接入

Workflow Code 可以把已适配的 Conversation 项目作为 OpenAI Responses API 服务调用。Desktop 默认在 127.0.0.1:7135 启动本地网关;本地项目直接在 Desktop 执行,服务器项目由 Desktop 透明流式转发到当前连接的 Workflow Server。也可以绕过 Desktop,直接调用 Server 的 /v1

该入口只实现 Responses、Conversations 和 Models 子集,不提供 /v1/chat/completions 或旧 /v1/completions

在 Desktop 获取调用信息

所有 Conversation 项目的工具目录都会显示 OpenAI API

  1. 打开 Conversation 项目详情,在 New Tab 中选择 OpenAI API
  2. 检查项目适配器、Desktop 网关和 Server 服务状态。
  3. 选择当前账号可用的模型。
  4. 为当前用户和当前项目创建 Key,或轮换已有 Key。
  5. 复制 base URL、Responses URL 和 curl、Node.js 或 Python 示例。

Desktop 网关只监听 loopback,不接受局域网连接。默认地址为:

Base URL: http://127.0.0.1:7135/v1
Responses URL: http://127.0.0.1:7135/v1/responses

服务器项目还会显示 Server 直连 base URL。通过 Desktop 地址调用服务器项目时,请求和 SSE 会原样流式转发到当前 Server;Key 仍由 Server 校验。

如果 7135 已被占用,只有 OpenAI 网关会停用,Desktop 其它功能继续运行。OpenAI API 页会显示端口错误,释放端口并重启 Desktop 后即可恢复。

未声明适配器的 Conversation 项目仍显示 OpenAI API 页和接入文档入口,但不能创建、轮换或使用项目 Key。

Key 与身份边界

项目 Key 使用 wfpk_* 格式,并同时绑定:

  • 当前登录用户;
  • 一个 Conversation 项目;
  • 该项目当前可用的 OpenAI 适配器。

因此公开请求保持标准 /v1/responses,不需要项目 Header 或自定义项目参数。/v1 只接受项目专属 Key;Desktop 登录凭据、账号 API Key和 Server 管理员 Key不能代替它。

完整 Key 只在创建或轮换后显示一次。Desktop SQLite 和 Server PostgreSQL 只保存 SHA-256 哈希与可识别前缀,之后无法重新读取完整值。Key 遗失时必须轮换;轮换和吊销立即使旧 Key 失效,但不会删除已有 Response 或 Conversation 资源。

不要把项目 Key 写入源码、项目环境文件、浏览器 bundle、截图或日志。推荐通过进程环境变量提供:

export OPENAI_API_KEY='wfpk_...'
export OPENAI_BASE_URL='http://127.0.0.1:7135/v1'

调用示例

curl

curl "$OPENAI_BASE_URL/responses" \
-H "Authorization: Bearer $OPENAI_API_KEY" \
-H 'Content-Type: application/json' \
-d '{
"model": "provider/model-id",
"input": "请概括这段内容。"
}'

Node.js

import OpenAI from "openai";

const client = new OpenAI({
apiKey: process.env.OPENAI_API_KEY,
baseURL: process.env.OPENAI_BASE_URL,
});

const response = await client.responses.create({
model: "provider/model-id",
input: "请概括这段内容。",
});

console.log(response.output_text);

Python

import os
from openai import OpenAI

client = OpenAI(
api_key=os.environ["OPENAI_API_KEY"],
base_url=os.environ["OPENAI_BASE_URL"],
)

response = client.responses.create(
model="provider/model-id",
input="请概括这段内容。",
)

print(response.output_text)

先调用 GET /v1/models 获取当前 Key 实际可用的模型 ID。Server 会按当前用户的 Provider 偏好选择第一个提供该模型的有效凭据。图片等硬能力不支持时会返回明确错误;已接受的可选采样参数会继续转交 Provider。若 Provider 以 unsupportedcompatibility warning 表示某个采样参数不可用,调用仍会继续,具体降级信息保留在响应的 Provider metadata 中。

支持的接口

资源接口
ResponsesPOST /v1/responses
Response 资源GET /v1/responses/{id}DELETE /v1/responses/{id}
取消POST /v1/responses/{id}/cancel
Response 输入GET /v1/responses/{id}/input_items
ConversationsPOST /v1/conversationsGET/POST/DELETE /v1/conversations/{id}
Conversation itemsGET/POST /v1/conversations/{id}/itemsGET/DELETE /v1/conversations/{id}/items/{item_id}
ModelsGET /v1/modelsGET /v1/models/{model}

列表接口接受 afterlimitorder=asc|desc,并返回 object: "list"datafirst_idlast_idhas_more

POST /v1/responses 支持以下请求字段:

字段支持范围
model必填,必须来自当前 Key 的 /v1/models
input字符串,或 user / assistant / system / developer message 数组。
instructions可选的本轮顶层指令。
temperaturetop_pmax_output_tokens转交给项目和 Provider;实际支持由模型能力决定。
text仅支持纯文本 format.type: "text"verbosity 接受 lowmediumhigh
include仅接受兼容值 reasoning.encrypted_content;当前子集不生成 reasoning item,因此不会增加额外输出。
store默认 true。控制 Response 资源保留,不删除显式 Conversation items。
stream返回标准 Responses SSE。不能与 background 同时使用。
background立即返回 queued,之后可轮询或取消。
previous_response_id继续一个状态为 completedincomplete 且仍保留的 Response。与 conversation 互斥。
conversation使用持久 Conversation ID 或 { "id": "conv_*" };对象形式必须包含有效的 id
metadata最多 16 个字符串键值对,保存在 API 资源中。

未知字段、冲突字段和协议子集之外的参数返回 invalid_request_error,不会被忽略。已接受的可选参数若仅被底层 Provider 标记为不支持,则按 Provider 的 warning 降级并继续执行。错误格式统一为:

{
"error": {
"message": "...",
"type": "invalid_request_error",
"param": "input",
"code": "invalid_value"
}
}

Response 对象只有在 status: "completed" 时才会填写 completed_atqueuedin_progressfailedcancelledincomplete 均返回 null

当 Provider 的 finish reason 表示达到输出上限或触发内容过滤时,网关返回 status: "incomplete",并分别填写 incomplete_details.reason: "max_output_tokens""content_filter"。已经生成的文本会保留在 output 中,对应 message item 的状态同样为 incomplete

输入与图片

message 内容支持字符串,或以下 content part:

  • 用户:input_textinput_image
  • 助手历史:output_text,也接受并规范化 input_text
  • system / developerinput_text,由内置适配器作为高优先级模型指令处理;
  • 图片:HTTP/HTTPS URL 或图片 data URL。

内置 Conversation、Codex、OpenCode 和小助手适配器都会显式应用 text.verbosity,不会只接受字段后忽略其语义。小助手复用 OpenCode 的适配和稳定输出项。include: ["reasoning.encrypted_content"] 是 OpenAI 仍接受的旧客户端兼容值;它不代表当前网关已实现 reasoning item。

最终有效输入必须包含用户文本或图片。图片只接受 JPEG、PNG、WebP 和 GIF;SVG 与普通文件不在首版范围。

图片进入受限下载和现有文件存储流程:每张最大 10 MiB、单请求合计最大 20 MiB、最多 16 张、下载超时 10 秒、最多 3 次重定向。网关校验实际文件签名与 MIME 类型,拒绝压缩 HTTP 响应、URL 内嵌凭据、loopback、私网、link-local、保留地址、云元数据地址及任何重定向后的非公网目标。

多轮状态

有两种互斥方式:

  • previous_response_id:把上一条状态为 completedincomplete 的 Response 输入和输出加入本轮上下文;
  • conversation:从持久 Conversation 读取 items,成功后原子追加本轮输入与输出。

previous_response_id 不会继承上一轮顶层 instructions。需要稳定指令时,每轮都重新发送:

const first = await client.responses.create({
model,
input: "第一问",
instructions: "始终使用简体中文回答。",
});

const second = await client.responses.create({
model,
input: "继续说明",
previous_response_id: first.id,
instructions: "始终使用简体中文回答。",
});

显式 Conversation 会在运行完成或以 incomplete 结束时追加本轮输入和已有输出;失败或取消不会追加。删除 Conversation 只删除 Conversation 资源,已有 items 及其图片引用按 Responses 协议保留。删除单个 item 返回更新后的 Conversation 对象,并在该图片不再被其它资源引用时回收文件。

流式与后台执行

stream: true 使用标准 Responses SSE 事件,顺序包括:

response.created
response.in_progress
response.output_item.added
response.content_part.added
response.output_text.delta
response.output_text.done
response.content_part.done
response.output_item.done
response.completed | response.incomplete

正常完成以 response.completed 结束;达到输出上限或触发内容过滤时保留部分文本,并以 response.incomplete 结束。流内失败发送 errorresponse.failed。流末尾不发送 Chat Completions 的 [DONE]。前台客户端断开时,Desktop 或 Server 会取消底层运行。

background: truestream: true 在首版互斥。后台创建立即返回 queued;使用 GET /v1/responses/{id} 轮询,使用 POST /v1/responses/{id}/cancel 幂等取消。Desktop 或 Server 重启时,遗留的 queued / in_progress 会标记为 failed,公开错误为 server_error,内部审计分类为 server_restart;首版不跨进程恢复任务。

反向代理 SSE

Server 在项目 OpenAI 调用信息中优先使用 WORKFLOW_API_PUBLIC_BASE_URL。该值必须是无内嵌凭据的 HTTP(S) URL,并会规范化为 origin;生产反向代理应显式设置它。未配置或配置无效时,Server 使用当前请求的协议和 Host,只有 Express 明确信任直连代理时才采用 X-Forwarded-Proto / X-Forwarded-Host,普通客户端发送这些 Header 不会改变展示地址。

反向代理必须关闭 SSE 缓冲和缓存,例如 Nginx:

location /v1/ {
proxy_pass http://127.0.0.1:7130;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_buffering off;
proxy_cache off;
proxy_read_timeout 3600s;
add_header X-Accel-Buffering no;
}

不要在 CDN、Ingress 或应用代理层重新聚合 text/event-stream 数据块。

保留、删除与隐私

资源默认保留
store: true 或缺省的 Response30 天。
前台 store: false Response请求结束后清除,不能再 retrieve。
后台 store: false Response终态后保留 10 分钟,供轮询。
Conversation保留到显式删除。
Conversation items保留到逐项删除;删除所属 Conversation 不会删除 items。

显式 Conversation items 不受 Response 的 store: false 影响。Desktop 启动及定时清理 SQLite;Server 启动及定时清理 PostgreSQL。删除或过期 Response、删除单个 Conversation item 时,会同时回收不再被其它资源引用的托管图片;删除 Conversation 本身不会回收其 items 使用的图片。

API 资源库按上述策略保存请求正文和输出。每次 OpenAI 调用开始时,都会立即在对应项目的运行记录中创建一条 OpenAI Responses 记录,完成、失败或取消后原位更新;Desktop 或 Server 重启也会把已开始但未完成的记录更新为失败终态。详情完整保存并展示标准化请求、标准 Response、Workflow 执行报告、节点输入输出、stdout、stderr、错误、finish reason 和 Provider metadata。store: false 只控制 Responses 协议资源的保留,不会裁剪项目运行记录。

完整 wfpk_* Key 和 Provider 凭据不写入运行记录;运行记录只保存 Key ID 与前缀。审计记录继续只保存身份、项目、模型、状态、时间、usage、错误分类和内部 run ID,不复制业务正文。普通 Conversation 历史也不会因 API 调用自动新增一份重复消息。

项目适配器

框架负责 HTTP 协议、Key、认证与权限、ID、校验、状态机、SSE、后台任务、持久化、图片安全、清理和审计。Conversation 项目开发者只负责把类型化 host input 映射到业务输入,并从声明的文本 output item 返回答案。

适配器声明位于 executor 的 conversation.openai

const ANSWER_ITEM_ID = "assistant-response";

export const executor = workflow.defineExecutor({
projectType: "conversation",
workflow: conversationWorkflow,
conversation: {
openai: {
enabled: true,
outputItemId: ANSWER_ITEM_ID,
},
},
});

项目运行时通过 workflow.readOpenAIConversationHostInput(context) 读取:

  • 标准化后的全部 messages
  • 本轮 instructions
  • model
  • temperaturetopPmaxOutputTokensverbosity
  • API Conversation ID 和项目运行记录正文持久化设置。

项目必须保持 outputItemId 稳定,把流式 delta 和最终文本写入该 item。项目可以针对自身无法表示的硬能力或参数做显式校验;使用 Core AI SDK Provider 时,Provider 返回的可选参数 unsupported / compatibility warning 不会自动阻断运行。框架会把完整调用信息和执行报告写入项目运行记录;项目无需再把同一份正文复制到普通 Conversation、KV 或审计记录,除非业务本身明确需要。

暂不支持

以下能力是框架后续 TODO。两个已知端点当前由网关显式返回 OpenAI 格式的 404 invalid_request_error;其它能力尚未实现,也不会被静默忽略:

  • /v1/responses/compact/v1/responses/input_tokens
  • Structured Outputs、reasoning 参数与 reasoning item、普通文件、Web Search、File Search、MCP、音频;
  • WebSocket、logprobs、prompt cache、service tier;
  • function/tool calling 的标准 item、call ID、流事件和状态恢复。

/compact 不是要求项目开发者额外实现的命令。工具调用需要框架先完成协议和恢复能力,之后项目开发者才负责工具定义、权限与业务执行。

/v1/chat/completions/v1/completions 是明确不支持的旧协议,不属于兼容 TODO。