mirror of
https://github.com/badlogic/pi-mono.git
synced 2026-11-05 23:37:25 +00:00
Add the constrained sampling API and provider plumbing for OpenAI and Anthropic tool calls, including grammar sampling variants and model capability metadata.
63 lines
2.1 KiB
TypeScript
63 lines
2.1 KiB
TypeScript
import { Type } from "typebox";
|
|
import { describe, expect, it } from "vitest";
|
|
import { complete, getModel } from "../src/compat.ts";
|
|
import type { Context, Model } from "../src/types.ts";
|
|
|
|
interface MistralToolPayload {
|
|
tools?: Array<{
|
|
type: "function";
|
|
function: {
|
|
name: string;
|
|
parameters: Record<string, unknown>;
|
|
strict?: boolean;
|
|
};
|
|
}>;
|
|
}
|
|
|
|
describe("Mistral tool schema serialization", () => {
|
|
it("strips TypeBox symbol keys before the SDK validates tool schemas", async () => {
|
|
const model: Model<"mistral-conversations"> = {
|
|
...getModel("mistral", "devstral-medium-latest"),
|
|
baseUrl: "http://127.0.0.1:9",
|
|
};
|
|
const parameters = Type.Object({
|
|
nested: Type.Object({
|
|
value: Type.String(),
|
|
}),
|
|
});
|
|
const context: Context = {
|
|
messages: [{ role: "user", content: "Hi", timestamp: Date.now() }],
|
|
tools: [
|
|
{
|
|
name: "inspect_schema",
|
|
description: "Inspect the schema",
|
|
parameters,
|
|
constrainedSampling: { type: "json_schema", strict: "require" },
|
|
},
|
|
],
|
|
};
|
|
let capturedPayload: MistralToolPayload | undefined;
|
|
|
|
const response = await complete(model, context, {
|
|
apiKey: "fake-key",
|
|
onPayload: (payload) => {
|
|
capturedPayload = payload as MistralToolPayload;
|
|
return payload;
|
|
},
|
|
});
|
|
|
|
expect(capturedPayload?.tools).toHaveLength(1);
|
|
expect(capturedPayload?.tools?.[0]?.function.strict).toBe(true);
|
|
const payloadParameters = capturedPayload?.tools?.[0]?.function.parameters;
|
|
expect(payloadParameters).toBeDefined();
|
|
expect(Object.getOwnPropertySymbols(payloadParameters ?? {})).toHaveLength(0);
|
|
const properties = payloadParameters?.properties;
|
|
expect(properties).toBeTruthy();
|
|
expect(Object.getOwnPropertySymbols((properties as Record<string, unknown>) ?? {})).toHaveLength(0);
|
|
const nested = (properties as Record<string, unknown> | undefined)?.nested;
|
|
expect(nested).toBeTruthy();
|
|
expect(Object.getOwnPropertySymbols((nested as Record<string, unknown>) ?? {})).toHaveLength(0);
|
|
expect(response.stopReason).toBe("error");
|
|
expect(response.errorMessage).not.toContain("Input validation failed");
|
|
});
|
|
});
|