mirror of
https://github.com/openclaw/openclaw.git
synced 2026-08-12 21:53:00 -06:00
test(llama-cpp): split inference mapping coverage
Punchcard-Session: frost-brook-timber-mx
This commit is contained in:
@@ -0,0 +1,101 @@
|
||||
import type { Context } from "openclaw/plugin-sdk/llm";
|
||||
import { describe, expect, it } from "vitest";
|
||||
import "./inference-provider.js";
|
||||
|
||||
const { mapContextToLlamaChatHistory, mapToolsToLlamaFunctions } = (
|
||||
globalThis as Record<PropertyKey, unknown>
|
||||
)[Symbol.for("openclaw.llamaCppInferenceTestApi")] as {
|
||||
mapContextToLlamaChatHistory: (context: Context) => unknown[];
|
||||
mapToolsToLlamaFunctions: (context: Context) => Record<string, unknown> | undefined;
|
||||
};
|
||||
|
||||
describe("llama.cpp inference mappings", () => {
|
||||
it("maps OpenClaw history and tool results into the model chat template history", () => {
|
||||
const context = {
|
||||
systemPrompt: "Be concise.",
|
||||
messages: [
|
||||
{ role: "user" as const, content: "weather?", timestamp: 1 },
|
||||
{
|
||||
role: "assistant" as const,
|
||||
api: "openai-completions",
|
||||
provider: "test",
|
||||
model: "test",
|
||||
stopReason: "toolUse" as const,
|
||||
usage: {
|
||||
input: 1,
|
||||
output: 1,
|
||||
cacheRead: 0,
|
||||
cacheWrite: 0,
|
||||
totalTokens: 2,
|
||||
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 },
|
||||
},
|
||||
timestamp: 2,
|
||||
content: [
|
||||
{ type: "text" as const, text: "Checking." },
|
||||
{
|
||||
type: "toolCall" as const,
|
||||
id: "call-1",
|
||||
name: "weather",
|
||||
arguments: { city: "Berlin" },
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
role: "toolResult" as const,
|
||||
toolCallId: "call-1",
|
||||
toolName: "weather",
|
||||
content: [{ type: "text" as const, text: "Sunny" }],
|
||||
isError: false,
|
||||
timestamp: 3,
|
||||
},
|
||||
{ role: "user" as const, content: "thanks", timestamp: 4 },
|
||||
],
|
||||
};
|
||||
|
||||
expect(mapContextToLlamaChatHistory(context)).toEqual([
|
||||
{ type: "system", text: "Be concise." },
|
||||
{ type: "user", text: "weather?" },
|
||||
{
|
||||
type: "model",
|
||||
response: [
|
||||
"Checking.",
|
||||
{
|
||||
type: "functionCall",
|
||||
name: "weather",
|
||||
params: { city: "Berlin" },
|
||||
result: "Sunny",
|
||||
},
|
||||
],
|
||||
},
|
||||
{ type: "user", text: "thanks" },
|
||||
]);
|
||||
});
|
||||
|
||||
it("maps JSON-schema tools to native node-llama-cpp function definitions", () => {
|
||||
expect(
|
||||
mapToolsToLlamaFunctions({
|
||||
messages: [],
|
||||
tools: [
|
||||
{
|
||||
name: "weather",
|
||||
description: "Get weather",
|
||||
parameters: {
|
||||
type: "object",
|
||||
properties: { city: { type: "string" } },
|
||||
required: ["city"],
|
||||
},
|
||||
},
|
||||
],
|
||||
}),
|
||||
).toEqual({
|
||||
weather: {
|
||||
description: "Get weather",
|
||||
params: {
|
||||
type: "object",
|
||||
properties: { city: { type: "string" } },
|
||||
required: ["city"],
|
||||
},
|
||||
},
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -56,12 +56,6 @@ vi.mock("node-llama-cpp", () => ({
|
||||
|
||||
import { createLlamaCppInferenceRuntime } from "./inference-provider.js";
|
||||
|
||||
const { mapContextToLlamaChatHistory, mapToolsToLlamaFunctions } = (
|
||||
globalThis as Record<PropertyKey, unknown>
|
||||
)[Symbol.for("openclaw.llamaCppInferenceTestApi")] as {
|
||||
mapContextToLlamaChatHistory: (context: Context) => unknown[];
|
||||
mapToolsToLlamaFunctions: (context: Context) => Record<string, unknown> | undefined;
|
||||
};
|
||||
type LlamaCppInferenceRuntime = ReturnType<typeof createLlamaCppInferenceRuntime>;
|
||||
let inferenceRuntime: LlamaCppInferenceRuntime;
|
||||
|
||||
@@ -165,95 +159,6 @@ afterEach(async () => {
|
||||
});
|
||||
|
||||
describe("llama.cpp inference provider", () => {
|
||||
it("maps OpenClaw history and tool results into the model chat template history", () => {
|
||||
const context = {
|
||||
systemPrompt: "Be concise.",
|
||||
messages: [
|
||||
{ role: "user" as const, content: "weather?", timestamp: 1 },
|
||||
{
|
||||
role: "assistant" as const,
|
||||
api: "openai-completions",
|
||||
provider: "test",
|
||||
model: "test",
|
||||
stopReason: "toolUse" as const,
|
||||
usage: {
|
||||
input: 1,
|
||||
output: 1,
|
||||
cacheRead: 0,
|
||||
cacheWrite: 0,
|
||||
totalTokens: 2,
|
||||
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 },
|
||||
},
|
||||
timestamp: 2,
|
||||
content: [
|
||||
{ type: "text" as const, text: "Checking." },
|
||||
{
|
||||
type: "toolCall" as const,
|
||||
id: "call-1",
|
||||
name: "weather",
|
||||
arguments: { city: "Berlin" },
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
role: "toolResult" as const,
|
||||
toolCallId: "call-1",
|
||||
toolName: "weather",
|
||||
content: [{ type: "text" as const, text: "Sunny" }],
|
||||
isError: false,
|
||||
timestamp: 3,
|
||||
},
|
||||
{ role: "user" as const, content: "thanks", timestamp: 4 },
|
||||
],
|
||||
};
|
||||
|
||||
expect(mapContextToLlamaChatHistory(context)).toEqual([
|
||||
{ type: "system", text: "Be concise." },
|
||||
{ type: "user", text: "weather?" },
|
||||
{
|
||||
type: "model",
|
||||
response: [
|
||||
"Checking.",
|
||||
{
|
||||
type: "functionCall",
|
||||
name: "weather",
|
||||
params: { city: "Berlin" },
|
||||
result: "Sunny",
|
||||
},
|
||||
],
|
||||
},
|
||||
{ type: "user", text: "thanks" },
|
||||
]);
|
||||
});
|
||||
|
||||
it("maps JSON-schema tools to native node-llama-cpp function definitions", () => {
|
||||
expect(
|
||||
mapToolsToLlamaFunctions({
|
||||
messages: [],
|
||||
tools: [
|
||||
{
|
||||
name: "weather",
|
||||
description: "Get weather",
|
||||
parameters: {
|
||||
type: "object",
|
||||
properties: { city: { type: "string" } },
|
||||
required: ["city"],
|
||||
},
|
||||
},
|
||||
],
|
||||
}),
|
||||
).toEqual({
|
||||
weather: {
|
||||
description: "Get weather",
|
||||
params: {
|
||||
type: "object",
|
||||
properties: { city: { type: "string" } },
|
||||
required: ["city"],
|
||||
},
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it("streams text deltas and reports native token-meter usage", async () => {
|
||||
mocks.generateResponse.mockImplementationOnce(async (_history, options) => {
|
||||
options.onTextChunk("Hel");
|
||||
|
||||
Reference in New Issue
Block a user