mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-30 07:13:39 +00:00
test: satisfy core test typecheck
This commit is contained in:
@@ -1,13 +1,7 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { agentLoop, agentLoopContinue } from "./agent-loop.js";
|
||||
import type {
|
||||
AgentContext,
|
||||
AgentEvent,
|
||||
AgentLoopConfig,
|
||||
AgentMessage,
|
||||
Model,
|
||||
StreamFn,
|
||||
} from "./types.js";
|
||||
import type { Message, Model } from "./llm.js";
|
||||
import type { AgentContext, AgentEvent, AgentLoopConfig, AgentMessage, StreamFn } from "./types.js";
|
||||
|
||||
const model: Model = {
|
||||
id: "test-model",
|
||||
@@ -24,7 +18,7 @@ const model: Model = {
|
||||
|
||||
const config: AgentLoopConfig = {
|
||||
model,
|
||||
convertToLlm: (messages) => messages,
|
||||
convertToLlm: (messages) => messages as Message[],
|
||||
};
|
||||
|
||||
const failingStreamFn: StreamFn = async () => {
|
||||
|
||||
@@ -13,13 +13,19 @@ const usage: Usage = {
|
||||
|
||||
const model: Model = {
|
||||
id: "test-model",
|
||||
name: "Test Model",
|
||||
provider: "test",
|
||||
api: "openai-responses",
|
||||
baseUrl: "https://example.test",
|
||||
reasoning: false,
|
||||
input: ["text"],
|
||||
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
|
||||
contextWindow: 1024,
|
||||
maxTokens: 1024,
|
||||
};
|
||||
|
||||
const context: Context = {
|
||||
messages: [{ role: "user", content: "hello" }],
|
||||
messages: [{ role: "user", content: "hello", timestamp: 1 }],
|
||||
};
|
||||
|
||||
function responseFromText(text: string): Response {
|
||||
@@ -40,7 +46,7 @@ describe("streamProxy", () => {
|
||||
});
|
||||
|
||||
it("flushes a final SSE frame without a trailing newline", async () => {
|
||||
const fetchMock = vi.fn(async () =>
|
||||
const fetchMock = vi.fn(async (_input: RequestInfo | URL, _init?: RequestInit) =>
|
||||
responseFromText(
|
||||
`data: ${JSON.stringify({
|
||||
type: "done",
|
||||
@@ -51,11 +57,12 @@ describe("streamProxy", () => {
|
||||
);
|
||||
vi.stubGlobal("fetch", fetchMock);
|
||||
|
||||
const stream = streamProxy(model, context, {
|
||||
const options = {
|
||||
authToken: "token",
|
||||
headers: { Authorization: "Bearer upstream", "x-api-key": "secret" },
|
||||
proxyUrl: "https://proxy.example",
|
||||
});
|
||||
};
|
||||
const stream = streamProxy(model, context, options);
|
||||
const events = [];
|
||||
for await (const event of stream) {
|
||||
events.push(event);
|
||||
|
||||
@@ -14,7 +14,7 @@ describe("read tool", () => {
|
||||
},
|
||||
});
|
||||
|
||||
const result = await tool.execute("call-1", { path });
|
||||
const result = await tool.execute("call-1", { path }, undefined, undefined, {} as never);
|
||||
const text = result.content[0]?.type === "text" ? result.content[0].text : "";
|
||||
|
||||
expect(text).toContain(`sed -n '1p' '${path}' | head -c ${DEFAULT_MAX_BYTES}`);
|
||||
|
||||
@@ -29,17 +29,21 @@ describe("Anthropic provider", () => {
|
||||
it("keeps Cloudflare AI Gateway upstream provider auth on the Anthropic API key", async () => {
|
||||
const model = {
|
||||
id: "claude-sonnet-4-6",
|
||||
name: "Claude Sonnet 4.6",
|
||||
provider: "cloudflare-ai-gateway",
|
||||
api: "anthropic-messages",
|
||||
baseUrl:
|
||||
"https://gateway.ai.cloudflare.com/v1/account/gateway/anthropic/v1/messages",
|
||||
baseUrl: "https://gateway.ai.cloudflare.com/v1/account/gateway/anthropic/v1/messages",
|
||||
reasoning: true,
|
||||
input: ["text"],
|
||||
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
|
||||
contextWindow: 200_000,
|
||||
maxTokens: 4096,
|
||||
headers: {
|
||||
"cf-aig-authorization": "Bearer gateway-token",
|
||||
},
|
||||
} satisfies Model<"anthropic-messages">;
|
||||
const context = {
|
||||
messages: [{ role: "user", content: "hello" }],
|
||||
messages: [{ role: "user", content: "hello", timestamp: 1 }],
|
||||
} satisfies Context;
|
||||
|
||||
streamAnthropic(model, context, {
|
||||
|
||||
@@ -1,7 +1,15 @@
|
||||
import type { Tool as OpenAIResponsesTool } from "openai/resources/responses/responses.js";
|
||||
import { describe, expect, it } from "vitest";
|
||||
import type { Model, Tool } from "../types.js";
|
||||
import { convertResponsesTools } from "./openai-responses-tools.js";
|
||||
|
||||
type ResponsesFunctionTool = Extract<OpenAIResponsesTool, { type: "function" }>;
|
||||
|
||||
function expectResponsesFunctionTool(tool: OpenAIResponsesTool | undefined): ResponsesFunctionTool {
|
||||
expect(tool).toHaveProperty("type", "function");
|
||||
return tool as ResponsesFunctionTool;
|
||||
}
|
||||
|
||||
const nativeOpenAIModel = {
|
||||
id: "gpt-5.5",
|
||||
name: "GPT-5.5",
|
||||
@@ -67,8 +75,9 @@ describe("convertResponsesTools", () => {
|
||||
{ model: nativeOpenAIModel },
|
||||
);
|
||||
|
||||
expect(converted[0]?.strict).toBe(false);
|
||||
expect(converted[0]?.parameters).toEqual({
|
||||
const tool = expectResponsesFunctionTool(converted[0]);
|
||||
expect(tool.strict).toBe(false);
|
||||
expect(tool.parameters).toEqual({
|
||||
type: "object",
|
||||
additionalProperties: false,
|
||||
properties: { path: { type: "string" } },
|
||||
@@ -88,8 +97,9 @@ describe("convertResponsesTools", () => {
|
||||
{ model: proxyOpenAIModel },
|
||||
);
|
||||
|
||||
expect(converted[0]).not.toHaveProperty("strict");
|
||||
expect(converted[0]?.parameters).toEqual({
|
||||
const tool = expectResponsesFunctionTool(converted[0]);
|
||||
expect(tool).not.toHaveProperty("strict");
|
||||
expect(tool.parameters).toEqual({
|
||||
type: "object",
|
||||
properties: {},
|
||||
});
|
||||
@@ -107,9 +117,8 @@ describe("convertResponsesTools", () => {
|
||||
parameters: {},
|
||||
} satisfies Tool;
|
||||
|
||||
expect(convertResponsesTools([zeta, alpha]).map((tool) => tool.name)).toEqual([
|
||||
"alpha",
|
||||
"zeta",
|
||||
]);
|
||||
expect(
|
||||
convertResponsesTools([zeta, alpha]).map((tool) => expectResponsesFunctionTool(tool).name),
|
||||
).toEqual(["alpha", "zeta"]);
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user