mirror of
https://github.com/openclaw/openclaw.git
synced 2026-04-18 23:37:26 +00:00
test(gateway): dedupe agent payload and stream fixtures
This commit is contained in:
@@ -11,6 +11,7 @@ import { GATEWAY_CLIENT_NAMES } from "../utils/message-channel.js";
|
||||
import { GatewayClient } from "./client.js";
|
||||
import { renderCatNoncePngBase64 } from "./live-image-probe.js";
|
||||
import { startGatewayServer } from "./server.js";
|
||||
import { extractPayloadText } from "./test-helpers.agent-results.js";
|
||||
|
||||
const LIVE = isTruthyEnvValue(process.env.LIVE) || isTruthyEnvValue(process.env.OPENCLAW_LIVE_TEST);
|
||||
const CLI_LIVE = isTruthyEnvValue(process.env.OPENCLAW_LIVE_CLI_BACKEND);
|
||||
@@ -77,15 +78,6 @@ function editDistance(a: string, b: string): number {
|
||||
return prev[bLen] ?? Number.POSITIVE_INFINITY;
|
||||
}
|
||||
|
||||
function extractPayloadText(result: unknown): string {
|
||||
const record = result as Record<string, unknown>;
|
||||
const payloads = Array.isArray(record.payloads) ? record.payloads : [];
|
||||
const texts = payloads
|
||||
.map((p) => (p && typeof p === "object" ? (p as Record<string, unknown>).text : undefined))
|
||||
.filter((t): t is string => typeof t === "string" && t.trim().length > 0);
|
||||
return texts.join("\n").trim();
|
||||
}
|
||||
|
||||
function parseJsonStringArray(name: string, raw?: string): string[] | undefined {
|
||||
const trimmed = raw?.trim();
|
||||
if (!trimmed) {
|
||||
|
||||
@@ -29,6 +29,7 @@ import { GATEWAY_CLIENT_MODES, GATEWAY_CLIENT_NAMES } from "../utils/message-cha
|
||||
import { GatewayClient } from "./client.js";
|
||||
import { renderCatNoncePngBase64 } from "./live-image-probe.js";
|
||||
import { startGatewayServer } from "./server.js";
|
||||
import { extractPayloadText } from "./test-helpers.agent-results.js";
|
||||
|
||||
const LIVE = isTruthyEnvValue(process.env.LIVE) || isTruthyEnvValue(process.env.OPENCLAW_LIVE_TEST);
|
||||
const GATEWAY_LIVE = isTruthyEnvValue(process.env.OPENCLAW_LIVE_GATEWAY);
|
||||
@@ -74,15 +75,6 @@ function assertNoReasoningTags(params: {
|
||||
}
|
||||
}
|
||||
|
||||
function extractPayloadText(result: unknown): string {
|
||||
const record = result as Record<string, unknown>;
|
||||
const payloads = Array.isArray(record.payloads) ? record.payloads : [];
|
||||
const texts = payloads
|
||||
.map((p) => (p && typeof p === "object" ? (p as Record<string, unknown>).text : undefined))
|
||||
.filter((t): t is string => typeof t === "string" && t.trim().length > 0);
|
||||
return texts.join("\n").trim();
|
||||
}
|
||||
|
||||
function isMeaningful(text: string): boolean {
|
||||
if (!text) {
|
||||
return false;
|
||||
|
||||
@@ -4,6 +4,7 @@ import os from "node:os";
|
||||
import path from "node:path";
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { startGatewayServer } from "./server.js";
|
||||
import { extractPayloadText } from "./test-helpers.agent-results.js";
|
||||
import {
|
||||
connectDeviceAuthReq,
|
||||
connectGatewayClient,
|
||||
@@ -13,15 +14,6 @@ import {
|
||||
import { installOpenAiResponsesMock } from "./test-helpers.openai-mock.js";
|
||||
import { buildOpenAiResponsesProviderConfig } from "./test-openai-responses-model.js";
|
||||
|
||||
function extractPayloadText(result: unknown): string {
|
||||
const record = result as Record<string, unknown>;
|
||||
const payloads = Array.isArray(record.payloads) ? record.payloads : [];
|
||||
const texts = payloads
|
||||
.map((p) => (p && typeof p === "object" ? (p as Record<string, unknown>).text : undefined))
|
||||
.filter((t): t is string => typeof t === "string" && t.trim().length > 0);
|
||||
return texts.join("\n").trim();
|
||||
}
|
||||
|
||||
describe("gateway e2e", () => {
|
||||
it(
|
||||
"runs a mock OpenAI tool call end-to-end via gateway agent loop",
|
||||
|
||||
@@ -2,6 +2,7 @@ import { afterAll, beforeAll, describe, expect, it } from "vitest";
|
||||
import { HISTORY_CONTEXT_MARKER } from "../auto-reply/reply/history.js";
|
||||
import { CURRENT_MESSAGE_MARKER } from "../auto-reply/reply/mentions.js";
|
||||
import { emitAgentEvent } from "../infra/agent-events.js";
|
||||
import { buildAssistantDeltaResult } from "./test-helpers.agent-results.js";
|
||||
import {
|
||||
agentCommand,
|
||||
getFreePort,
|
||||
@@ -389,12 +390,13 @@ describe("OpenAI-compatible HTTP API (e2e)", () => {
|
||||
try {
|
||||
{
|
||||
agentCommand.mockReset();
|
||||
agentCommand.mockImplementationOnce((async (opts: unknown) => {
|
||||
const runId = (opts as { runId?: string } | undefined)?.runId ?? "";
|
||||
emitAgentEvent({ runId, stream: "assistant", data: { delta: "he" } });
|
||||
emitAgentEvent({ runId, stream: "assistant", data: { delta: "llo" } });
|
||||
return { payloads: [{ text: "hello" }] } as never;
|
||||
}) as never);
|
||||
agentCommand.mockImplementationOnce((async (opts: unknown) =>
|
||||
buildAssistantDeltaResult({
|
||||
opts,
|
||||
emit: emitAgentEvent,
|
||||
deltas: ["he", "llo"],
|
||||
text: "hello",
|
||||
})) as never);
|
||||
|
||||
const res = await postChatCompletions(port, {
|
||||
stream: true,
|
||||
@@ -422,12 +424,13 @@ describe("OpenAI-compatible HTTP API (e2e)", () => {
|
||||
|
||||
{
|
||||
agentCommand.mockReset();
|
||||
agentCommand.mockImplementationOnce((async (opts: unknown) => {
|
||||
const runId = (opts as { runId?: string } | undefined)?.runId ?? "";
|
||||
emitAgentEvent({ runId, stream: "assistant", data: { delta: "hi" } });
|
||||
emitAgentEvent({ runId, stream: "assistant", data: { delta: "hi" } });
|
||||
return { payloads: [{ text: "hihi" }] } as never;
|
||||
}) as never);
|
||||
agentCommand.mockImplementationOnce((async (opts: unknown) =>
|
||||
buildAssistantDeltaResult({
|
||||
opts,
|
||||
emit: emitAgentEvent,
|
||||
deltas: ["hi", "hi"],
|
||||
text: "hihi",
|
||||
})) as never);
|
||||
|
||||
const repeatedRes = await postChatCompletions(port, {
|
||||
stream: true,
|
||||
|
||||
@@ -4,6 +4,7 @@ import { afterAll, beforeAll, describe, expect, it } from "vitest";
|
||||
import { HISTORY_CONTEXT_MARKER } from "../auto-reply/reply/history.js";
|
||||
import { CURRENT_MESSAGE_MARKER } from "../auto-reply/reply/mentions.js";
|
||||
import { emitAgentEvent } from "../infra/agent-events.js";
|
||||
import { buildAssistantDeltaResult } from "./test-helpers.agent-results.js";
|
||||
import { agentCommand, getFreePort, installGatewayTestHooks } from "./test-helpers.js";
|
||||
|
||||
installGatewayTestHooks({ scope: "suite" });
|
||||
@@ -433,12 +434,13 @@ describe("OpenResponses HTTP API (e2e)", () => {
|
||||
const port = enabledPort;
|
||||
try {
|
||||
agentCommand.mockReset();
|
||||
agentCommand.mockImplementationOnce((async (opts: unknown) => {
|
||||
const runId = (opts as { runId?: string } | undefined)?.runId ?? "";
|
||||
emitAgentEvent({ runId, stream: "assistant", data: { delta: "he" } });
|
||||
emitAgentEvent({ runId, stream: "assistant", data: { delta: "llo" } });
|
||||
return { payloads: [{ text: "hello" }] } as never;
|
||||
}) as never);
|
||||
agentCommand.mockImplementationOnce((async (opts: unknown) =>
|
||||
buildAssistantDeltaResult({
|
||||
opts,
|
||||
emit: emitAgentEvent,
|
||||
deltas: ["he", "llo"],
|
||||
text: "hello",
|
||||
})) as never);
|
||||
|
||||
const resDelta = await postResponses(port, {
|
||||
stream: true,
|
||||
|
||||
27
src/gateway/test-helpers.agent-results.ts
Normal file
27
src/gateway/test-helpers.agent-results.ts
Normal file
@@ -0,0 +1,27 @@
|
||||
type AgentDeltaEvent = {
|
||||
runId: string;
|
||||
stream: "assistant";
|
||||
data: { delta: string };
|
||||
};
|
||||
|
||||
export function extractPayloadText(result: unknown): string {
|
||||
const record = result as Record<string, unknown>;
|
||||
const payloads = Array.isArray(record.payloads) ? record.payloads : [];
|
||||
const texts = payloads
|
||||
.map((p) => (p && typeof p === "object" ? (p as Record<string, unknown>).text : undefined))
|
||||
.filter((t): t is string => typeof t === "string" && t.trim().length > 0);
|
||||
return texts.join("\n").trim();
|
||||
}
|
||||
|
||||
export function buildAssistantDeltaResult(params: {
|
||||
opts: unknown;
|
||||
emit: (event: AgentDeltaEvent) => void;
|
||||
deltas: string[];
|
||||
text: string;
|
||||
}): { payloads: Array<{ text: string }> } {
|
||||
const runId = (params.opts as { runId?: string } | undefined)?.runId ?? "";
|
||||
for (const delta of params.deltas) {
|
||||
params.emit({ runId, stream: "assistant", data: { delta } });
|
||||
}
|
||||
return { payloads: [{ text: params.text }] };
|
||||
}
|
||||
Reference in New Issue
Block a user