createOutputNode

workflow.createOutputNode() 创建输出节点。它既可以像普通节点一样同步格式化输入,也可以提供 stream 逐段输出,最后用 format 生成最终 payload。 当前输出协议直接使用 WorkflowOutputPayload.items。不要再把完整输出聚合到顶层 content 字段;每一段可见输出都应该是独立的 WorkflowOutputItem

签名

workflow.createOutputNode<Input, Output>(
  options: OutputStreamNodeOptions<Input, Output>,
): BaseStreamNode<Input, OutputStreamChunk, Output>

workflow.createOutputNode<Input, Output>(
  options: OutputNodeOptions<Input, Output> & {
    format: OutputFormatter<Input, Output>;
  },
): BaseNode<Input, Output>

workflow.createOutputNode<Input>(
  options?: OutputNodeOptions<Input, Input>,
): BaseNode<Input, Input>

参数

参数类型说明
optionsOutputNodeOptions | OutputStreamNodeOptions配置格式化函数、流式输出函数和节点元信息;不传时原样返回输入。

同步输出 options

字段类型说明
namestring输出节点名,默认 "output"。运行报告会收集名为 output 的成功输出。
format(input, context) => Output把输入转换成最终 payload;不传时原样返回 input。
historyLimitnumber节点执行历史保留条数,默认 50
metadataWorkflowNodeMetadataInput节点展示元信息。

流式输出 options

字段类型说明
namestring输出节点名,默认 "output"
stream(input, context) => Iterable<OutputStreamChunk>逐段产出字符串 chunk 或结构化 output item chunk。必填。
format(stream, input, context) => Output把累积后的 { text, items, chunks } 转成最终 payload。必填。
historyLimitnumber节点执行历史保留条数,默认 50
metadataWorkflowNodeMetadataInput节点展示元信息。

返回值

模式返回类型执行方式
同步输出BaseNode<Input, Output>workflow.runNode(outputNode, input, context)
流式输出BaseStreamNode<Input, OutputStreamChunk, Output>workflow.runStreamNode(outputNode, input, context)

输出流程

模式说明
同步接收 Input,通过 format(input, context) 生成 Output
流式接收 Input,先输出 string 或 item chunks,再把累积后的 { text, items, chunks } 交给 format。字符串 chunk 会自动追加到默认 Markdown item,普通流式输出无需手动创建 item。
在 conversation UI 里,如果同一段 assistant 回答会先流式展示、再通过最终 report 校准,推荐使用 workflow.createOutputItemChunk() 发送带稳定 idoutput_item_start / output_item_delta / output_item_end。这样 App 会按 item id 用最终结果替换 live item,而不是把字符串 chunk 生成的临时默认 item 和最终默认 item 各渲染一份。workspace/workflow/conversation 示例的主回答使用固定 conversation-answer id 来保持单条回复只展示一次。(issue #89) 如果 agent 文本会和工具调用穿插出现,不要把所有正文都 patch 到同一个稳定 item。工具调用前先结束当前 inline Output item,工具 detail item 输出后,再为后续正文创建新的 inline Output item;最终 items 应保持 正文段 -> 工具 detail -> 正文段 的事件顺序。(issue #91)

输出 item 协议

interface WorkflowOutputPayload extends WorkflowPayload {
  items: WorkflowOutputItem[];
}

interface WorkflowOutputItem {
  id: string;
  title: string;
  content: unknown;
  icon?: string;
  iconPreset?: "info" | "success" | "warning" | "error" | "note" | "code" | "list" | "quote" | "none";
  contentType?: "markdown" | "text" | "json" | "audio";
  collapsed?: boolean;
  metadata?: Record<string, unknown>;
}
contentType 只决定 UI 渲染方式:markdown 使用 Markdown 渲染,text 使用纯文本渲染,json 使用格式化 JSON 展示,audio 使用浏览器音频播放器。对象和数组可以直接放进 content,不要提前 stringify 成 Markdown code block。 audio item 的 content 使用对象结构:{ src, mimeType, name, size, durationMs?, format? }src 可以是安全的 data:audio/...;base64,...,也可以是 http(s) 音频 URL;本地 CLI/App 示例推荐用 data URL,避免依赖 server file storage。

输出 helper

API说明
workflow.createOutputItem(input)创建带稳定 id、icon 预置解析和默认 contentType 的 item。
workflow.createOutputPayload(input)创建 { errCode, errMessage, items } payload,并可保留业务扩展字段。
workflow.addOutputItem(payload, item)向现有 output payload 追加一个 item。
workflow.createOutputItemChunk(chunk)创建 output_item_start / output_item_delta / output_item_end 流式 chunk。

流式 item chunk

类型说明
output_item_start创建一个 item,包含 idtitleiconcontentTypecollapsed 等字段。
output_item_deltaitemId 追加或合并内容;字符串拼接,数组追加,对象浅合并。可选 item patch 更新 titleiconmetadata.status 等展示字段。
output_item_end标记 item 结束;当前主要用于协议完整性和 UI 后续扩展。

示例:同步输出

const outputNode = workflow.createOutputNode<Result, OutputPayload>({
  name: "output",
  format(result) {
    return {
      ...workflow.createOutputPayload({
        items: [{
          title: "Result",
          content: result.text,
          contentType: "markdown",
          collapsed: false,
        }],
      }),
      source: result.source,
    };
  },
});

示例:流式输出

const outputNode = workflow.createOutputNode<Result, OutputPayload>({
  name: "output",
  async *stream(result) {
    yield result.prefix;
    yield result.text;
  },
  format(stream) {
    return workflow.createOutputPayload({
      items: stream.items,
      totalChunks: stream.chunks.length,
    });
  },
});

示例:流式结构化 item

const outputNode = workflow.createOutputNode<ToolResult, OutputPayload>({
  name: "output",
  async *stream(result) {
    yield workflow.createOutputItemChunk({
      type: "output_item_start",
      item: {
        id: "tool-result",
        title: "Tool result",
        content: {},
        contentType: "json",
        collapsed: true,
      },
    });
    yield workflow.createOutputItemChunk({
      type: "output_item_delta",
      itemId: "tool-result",
      delta: result.payload,
      item: {
        title: "Tool result complete",
        icon: "success",
        metadata: { status: "success" },
      },
    });
    yield workflow.createOutputItemChunk({
      type: "output_item_end",
      itemId: "tool-result",
    });
  },
  format(stream) {
    return workflow.createOutputPayload({ items: stream.items });
  },
});

Payload 约束

字段说明
errCode最终 output payload 必须包含。成功值为 0
errMessage最终 output payload 必须包含。成功时为空字符串。
items最终 output payload 必须包含。每个 item 是一个可独立折叠/展开的输出块。