docs: document openai transport tests · openclaw/openclaw@1df9bca
steipete
·
2026-06-05
·
via Recent Commits to openclaw:main
| Original file line number | Diff line number | Diff line change |
|---|
|
| 1 | +// Verifies OpenAI Responses replay preserves reasoning and response item ids. |
1 | 2 | import type { AssistantMessage, Model, ToolResultMessage } from "openclaw/plugin-sdk/llm"; |
2 | 3 | import { stream } from "openclaw/plugin-sdk/llm"; |
3 | 4 | import { Type } from "typebox"; |
@@ -88,6 +89,7 @@ async function runAbortedOpenAIResponsesStream(params: {
|
88 | 89 | }>; |
89 | 90 | replayResponsesItemIds?: boolean; |
90 | 91 | }) { |
| 92 | +// Abort after payload capture so tests inspect serialization without network I/O. |
91 | 93 | const controller = new AbortController(); |
92 | 94 | controller.abort(); |
93 | 95 | let payload: Record<string, unknown> | undefined; |
@@ -224,6 +226,7 @@ describe("openai-responses reasoning replay", () => {
|
224 | 226 | }); |
225 | 227 | |
226 | 228 | it("does not replay a signed assistant message id after its reasoning item was pruned", async () => { |
| 229 | +// Signed message ids are only safe to replay when their preceding reasoning item survived. |
227 | 230 | expect( |
228 | 231 | resolveReplayableResponsesMessageId({ |
229 | 232 | replayResponsesItemIds: true, |
|
| Original file line number | Diff line number | Diff line change |
|---|
|
| 1 | +// Verifies OpenAI model selections route between OpenClaw and Codex runtimes. |
1 | 2 | import { describe, expect, it } from "vitest"; |
2 | 3 | import type { OpenClawConfig } from "../config/types.openclaw.js"; |
3 | 4 | import { |
@@ -21,6 +22,7 @@ describe("OpenAI runtime routing policy", () => {
|
21 | 22 | }); |
22 | 23 | |
23 | 24 | it("does not force Codex for custom OpenAI-compatible base URLs", () => { |
| 25 | +// A custom baseUrl means the provider key is only OpenAI-compatible, not official OpenAI. |
24 | 26 | const config = { |
25 | 27 | models: { |
26 | 28 | providers: { |
@@ -90,6 +92,7 @@ describe("OpenAI runtime routing policy", () => {
|
90 | 92 | }); |
91 | 93 | |
92 | 94 | it("keeps explicit OpenClaw plus Codex auth profile under the unified OpenAI provider", () => { |
| 95 | +// OpenAI auth now stays canonical even when the runtime is not Codex. |
93 | 96 | expect( |
94 | 97 | listOpenAIAuthProfileProvidersForAgentRuntime({ |
95 | 98 | provider: "openai", |
|
| Original file line number | Diff line number | Diff line change |
|---|
|
| 1 | +// Verifies session thinking levels reach OpenAI and Codex Responses transports. |
1 | 2 | import { Agent, type StreamFn } from "openclaw/plugin-sdk/agent-core"; |
2 | 3 | import { |
3 | 4 | createAssistantMessageEventStream, |
@@ -119,6 +120,7 @@ function createCapturingStreamFn(
|
119 | 120 | model: ResponsesModel, |
120 | 121 | capturedOptions: SimpleStreamOptions[], |
121 | 122 | ): StreamFn { |
| 123 | +// Captures Agent -> stream options while returning a complete assistant event. |
122 | 124 | return (_model, _context, options) => { |
123 | 125 | capturedOptions.push({ ...options }); |
124 | 126 | const stream = createAssistantMessageEventStream(); |
@@ -164,6 +166,7 @@ async function captureProviderPayload<
|
164 | 166 | ) => ReturnType<StreamFn>; |
165 | 167 | options: SimpleStreamOptions; |
166 | 168 | }): Promise<Record<string, unknown>> { |
| 169 | +// Stop at onPayload so transport serialization can be asserted without HTTP. |
167 | 170 | const payloadPromise = new Promise<Record<string, unknown>>((resolve, reject) => { |
168 | 171 | const timeout = setTimeout( |
169 | 172 | () => reject(new Error(`provider payload callback was not invoked for ${params.model.api}`)), |
|
| Original file line number | Diff line number | Diff line change |
|---|
|
| 1 | +// Verifies OpenAI strict tool schema normalization and cache behavior. |
1 | 2 | import { beforeEach, describe, expect, it } from "vitest"; |
2 | 3 | import { |
3 | 4 | clearOpenAIToolSchemaCacheForTest, |
@@ -35,6 +36,7 @@ describe("OpenAI strict tool schema normalization", () => {
|
35 | 36 | }); |
36 | 37 | |
37 | 38 | it("does not close permissive nested object schemas implicitly", () => { |
| 39 | +// Nested permissive objects stay incompatible unless callers make them strict. |
38 | 40 | const schema = { |
39 | 41 | type: "object", |
40 | 42 | properties: { |
@@ -69,6 +71,7 @@ describe("OpenAI strict tool schema normalization", () => {
|
69 | 71 | }); |
70 | 72 | |
71 | 73 | it("reuses normalized strict schemas for stable tool schema objects", () => { |
| 74 | +// Cache keys include unsupported-keyword policy, not just object identity. |
72 | 75 | const schema = { |
73 | 76 | type: "object", |
74 | 77 | properties: { |
|
| Original file line number | Diff line number | Diff line change |
|---|
|
| 1 | +// Verifies OpenAI-compatible streaming payloads, failures, and transport wrapping. |
1 | 2 | import { createServer } from "node:http"; |
2 | 3 | import type { Api, Model } from "openclaw/plugin-sdk/llm"; |
3 | 4 | import { describe, expect, it, vi } from "vitest"; |
@@ -99,6 +100,7 @@ function createAzureResponsesModel(): Model<"azure-openai-responses"> {
|
99 | 100 | } |
100 | 101 | |
101 | 102 | function neverYieldsStream(): AsyncIterable<unknown> { |
| 103 | +// Simulates an HTTP stream that opened but never delivered the first SSE event. |
102 | 104 | return { |
103 | 105 | [Symbol.asyncIterator]() { |
104 | 106 | return { |
@@ -116,6 +118,7 @@ async function* streamChunks(chunks: readonly unknown[]): AsyncGenerator<never>
|
116 | 118 | } |
117 | 119 | |
118 | 120 | function expectRecordFields(record: unknown, expected: Record<string, unknown>) { |
| 121 | +// Shared assertion helper for parsed transport payload/event records. |
119 | 122 | if (!record || typeof record !== "object") { |
120 | 123 | throw new Error("Expected record"); |
121 | 124 | } |
@@ -141,6 +144,7 @@ describe("openai transport stream", () => {
|
141 | 144 | }); |
142 | 145 | |
143 | 146 | it("observes detail-less Responses failures without leaking request ids", async () => { |
| 147 | +// Observation should preserve hashes/metadata shape while dropping raw request ids. |
144 | 148 | const model = createAzureResponsesModel(); |
145 | 149 | const event = { |
146 | 150 | type: "response.failed", |
|
| Original file line number | Diff line number | Diff line change |
|---|
|
| 1 | +// Verifies OpenClaw gateway tool schema, restart signaling, and config mutations. |
1 | 2 | import fs from "node:fs/promises"; |
2 | 3 | import os from "node:os"; |
3 | 4 | import path from "node:path"; |
@@ -19,13 +20,15 @@ vi.mock("./tools/gateway.js", () => ({
|
19 | 20 | })); |
20 | 21 | |
21 | 22 | function requireGatewayTool(agentSessionKey?: string) { |
| 23 | +// Tests run with restart enabled so schema and execution paths are visible. |
22 | 24 | return createGatewayTool({ |
23 | 25 | ...(agentSessionKey ? { agentSessionKey } : {}), |
24 | 26 | config: { commands: { restart: true } }, |
25 | 27 | }); |
26 | 28 | } |
27 | 29 | |
28 | 30 | function collectActionValues(schema: unknown, values: Set<string>): void { |
| 31 | +// Tool schemas can expose actions through const, enum, or anyOf variants. |
29 | 32 | if (!schema || typeof schema !== "object") { |
30 | 33 | return; |
31 | 34 | } |
@@ -109,6 +112,7 @@ function expectConfigMutationCall(params: {
|
109 | 112 | raw: string; |
110 | 113 | sessionKey: string; |
111 | 114 | }) { |
| 115 | +// Config writes must include the base hash from a preceding config.get read. |
112 | 116 | expect(params.callGatewayTool.mock.calls.some(([method]) => method === "config.get")).toBe(true); |
113 | 117 | const call = params.callGatewayTool.mock.calls.find(([method]) => method === params.action); |
114 | 118 | if (!call) { |
|
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。