chore(vendor): import pi 1.3.0

Imported as a linear vendor commit so forge rebases do not replay the upstream root tree.

git-subtree-dir: third_party/pi

git-subtree-split: 71023aec1546d6d677a65669c5665c0927ce0dd0
This commit is contained in:
2026-10-15 17:58:48 -04:00
parent 719370c8f7
commit 6081e3e325
1743 changed files with 205460 additions and 131705 deletions

View File

@@ -46,7 +46,7 @@ describe("llama.cpp extension", () => {
process.cwd(),
createEventBus(),
runtime,
"<inline:llama.cpp>",
"builtin:llama.cpp",
);
expect(extension.commands.get("llama")?.description).toBe("Manage llama.cpp router models");
@@ -91,6 +91,57 @@ describe("llama.cpp extension", () => {
]);
});
// Regression test for #9528.
it("discovers chat-template thinking support for loaded models", async () => {
let propsRequests = 0;
const { url } = await listen((request, response) => {
if (request.url === "/models") {
json(response, {
data: [{ id: "qwen", status: { value: "loaded" }, meta: { n_ctx: 32768 } }],
});
return;
}
const requestUrl = new URL(request.url ?? "", "http://localhost");
if (requestUrl.pathname === "/props") {
propsRequests++;
expect(requestUrl.searchParams.get("model")).toBe("qwen");
expect(requestUrl.searchParams.get("autoload")).toBe("false");
json(response, { chat_template: "{% if enable_thinking %}think{% endif %}" });
return;
}
response.writeHead(404).end();
});
const controller = createLlamaProvider();
await controller.provider.refreshModels?.({
credential: { type: "api_key", key: "local", env: { LLAMA_BASE_URL: url } },
stored: undefined,
publish: async (publication) => {
publication.update?.();
return true;
},
allowNetwork: true,
signal: new AbortController().signal,
});
expect(propsRequests).toBe(1);
expect(controller.provider.getModels()).toEqual([
expect.objectContaining({
id: "qwen",
reasoning: true,
thinkingLevelMap: {
off: "off",
minimal: null,
low: null,
medium: "medium",
high: null,
xhigh: null,
},
compat: expect.objectContaining({ thinkingFormat: "qwen-chat-template" }),
}),
]);
});
it("persists and restores selectable models for cache-only startup refreshes", async () => {
let cachedEntry: ModelsStoreEntry | undefined;
const { url } = await listen((request, response) => {
@@ -104,6 +155,10 @@ describe("llama.cpp extension", () => {
});
return;
}
if (request.url === "/props?model=loaded&autoload=false") {
json(response, {});
return;
}
response.writeHead(404).end();
});
@@ -122,7 +177,12 @@ describe("llama.cpp extension", () => {
signal: new AbortController().signal,
});
expect(first.provider.getModels().map((model) => model.id)).toEqual(["loaded", "sleeping"]);
expect(cachedEntry?.models.map((model) => model.id)).toEqual(["loaded", "sleeping"]);
expect(cachedEntry?.models.map((model) => [model.id, model.api])).toEqual([
["loaded", "openai-completions"],
["sleeping", "openai-completions"],
["loaded", "llama-cpp-classify"],
["sleeping", "llama-cpp-classify"],
]);
const second = createLlamaProvider();
await second.provider.refreshModels?.({
@@ -136,6 +196,89 @@ describe("llama.cpp extension", () => {
expect.objectContaining({ id: "loaded", baseUrl: `${url}/v1`, contextWindow: 32768 }),
expect.objectContaining({ id: "sleeping", baseUrl: `${url}/v1`, contextWindow: 32768 }),
]);
expect(second.provider.getAllModels?.().filter((model) => model.type === "classifier")).toEqual([
expect.objectContaining({ id: "loaded", api: "llama-cpp-classify", baseUrl: url, contextWindow: 32768 }),
expect.objectContaining({ id: "sleeping", api: "llama-cpp-classify", baseUrl: url, contextWindow: 32768 }),
]);
});
it("preserves cached llama.cpp context for unloaded autoload presets", async () => {
let cachedEntry: ModelsStoreEntry | undefined;
let loaded = true;
let unloadedArgs: string[] | undefined;
const { url } = await listen((request, response) => {
if (request.url === "/models") {
json(response, {
data: [
loaded
? {
id: "qwen",
status: { value: "loaded" },
source: "preset",
meta: { n_ctx: 65536, n_ctx_train: 128000 },
}
: {
id: "qwen",
status: { value: "unloaded", ...(unloadedArgs && { args: unloadedArgs }) },
source: "preset",
meta: { n_ctx_train: 128000 },
},
],
});
return;
}
if (request.url === "/props?model=qwen&autoload=false") {
json(response, {});
return;
}
if (request.url === "/props") {
json(response, { role: "router", models_autoload: true });
return;
}
response.writeHead(404).end();
});
const publish = async (publication: ModelsPublication): Promise<boolean> => {
if (publication.persist === null) cachedEntry = undefined;
else if (publication.persist !== undefined) cachedEntry = structuredClone(publication.persist);
publication.update?.();
return true;
};
const storedContextWindows = () =>
cachedEntry?.models.map((model) => ("contextWindow" in model ? model.contextWindow : undefined));
const credential = { type: "api_key" as const, key: "local", env: { LLAMA_BASE_URL: url } };
const first = createLlamaProvider();
await first.provider.refreshModels?.({
credential,
stored: cachedEntry,
publish,
allowNetwork: true,
signal: new AbortController().signal,
});
expect(storedContextWindows()).toEqual([65536, 65536]);
loaded = false;
const second = createLlamaProvider();
await second.provider.refreshModels?.({
credential,
stored: cachedEntry,
publish,
allowNetwork: true,
signal: new AbortController().signal,
});
expect(second.provider.getModels()).toEqual([expect.objectContaining({ id: "qwen", contextWindow: 65536 })]);
expect(storedContextWindows()).toEqual([65536, 65536]);
unloadedArgs = ["llama-server", "--ctx-size", "32768"];
await second.provider.refreshModels?.({
credential,
stored: cachedEntry,
publish,
allowNetwork: true,
signal: new AbortController().signal,
});
expect(storedContextWindows()).toEqual([32768, 32768]);
});
it("exposes unloaded presets only when router autoload is enabled", async () => {
@@ -179,7 +322,234 @@ describe("llama.cpp extension", () => {
expect(propsRequests).toBe(1);
expect(controller.provider.getModels().map((model) => model.id)).toEqual(["preset"]);
expect(cachedEntry?.models.map((model) => model.id)).toEqual(["preset"]);
expect(cachedEntry?.models.map((model) => [model.id, model.api])).toEqual([
["preset", "openai-completions"],
["preset", "llama-cpp-classify"],
]);
});
it("classifies with selectable models through llama-server", async () => {
const paths: string[] = [];
const { url } = await listen((request, response) => {
let body = "";
request.on("data", (chunk) => {
body += chunk;
});
request.on("end", () => {
paths.push(request.url ?? "");
const payload = JSON.parse(body) as { model: string; content?: string };
expect(payload.model).toBe("qwen");
if (request.url === "/tokenize") {
json(response, { tokens: [...(payload.content ?? "")].map((char) => char.codePointAt(0)) });
} else if (request.url === "/apply-template") {
json(response, { prompt: "<|im_start|>assistant\n" });
} else if (request.url === "/completion") {
json(response, {
completion_probabilities: [
{
top_logprobs: [
{ id: 66, token: "B", logprob: -0.1 },
{ id: 65, token: "A", logprob: -2.4 },
],
},
],
});
} else {
response.writeHead(404).end();
}
});
});
const controller = createLlamaProvider();
controller.setCatalog([{ id: "qwen", status: { value: "loaded" } }], url);
const classifier = controller.provider.getAllModels?.().find((model) => model.type === "classifier");
if (classifier?.type !== "classifier") throw new Error("missing classifier model");
// Provider auth resolves the OpenAI-compatible /v1 URL, which replaces the model's base URL.
const result = await controller.provider.classify!(
{ ...classifier, baseUrl: `${url}/v1` },
{
state: { message: "The build is red again." },
questions: {
kind: { type: "choice", instructions: "What is this about?", criteria: { billing: "", ci: "" } },
},
},
{ apiKey: "local" },
);
expect(result.errorMessage).toBeUndefined();
expect(result.answers.kind).toMatchObject({ type: "choice", choice: "ci" });
expect(paths).toContain("/completion");
});
it("exposes decision models reported by the catalog as native System One classifiers", async () => {
const propsModels: string[] = [];
const systemOneRequests: unknown[] = [];
const { url } = await listen((request, response) => {
let body = "";
request.on("data", (chunk) => {
body += chunk;
});
request.on("end", () => {
const requestUrl = new URL(request.url ?? "", "http://localhost");
if (requestUrl.pathname === "/models") {
json(response, {
data: [
{
id: "qwen",
status: { value: "loaded" },
architecture: { input_modalities: ["text"], output_modalities: ["text"] },
meta: { n_ctx: 32768 },
},
{
id: "kev",
status: { value: "loaded" },
architecture: { input_modalities: ["text"], output_modalities: ["decisions"] },
meta: { n_ctx: 8192 },
},
{
id: "laya",
status: { value: "sleeping" },
architecture: { input_modalities: ["text"], output_modalities: ["decisions"] },
},
// Servers before llama.cpp 0.6.0 may omit architecture.
{ id: "legacy", status: { value: "loaded" } },
],
});
return;
}
if (requestUrl.pathname === "/props") {
propsModels.push(requestUrl.searchParams.get("model") ?? "");
json(response, {});
return;
}
if (requestUrl.pathname === "/v1/systemone") {
const payload = JSON.parse(body) as { model: string; questions: Record<string, unknown> };
systemOneRequests.push(payload);
json(response, {
model: payload.model,
answers: Object.fromEntries(
Object.keys(payload.questions).map((id) => [id, { type: "noul", noul: 0.82 }]),
),
usage: { input_tokens: 42, output_tokens: 0 },
});
return;
}
response.writeHead(404).end();
});
});
let cachedEntry: ModelsStoreEntry | undefined;
const publish = async (publication: ModelsPublication): Promise<boolean> => {
if (publication.persist !== undefined && publication.persist !== null) {
cachedEntry = structuredClone(publication.persist);
}
publication.update?.();
return true;
};
const credential = { type: "api_key" as const, key: "local", env: { LLAMA_BASE_URL: url } };
const controller = createLlamaProvider();
await controller.provider.refreshModels?.({
credential,
stored: undefined,
publish,
allowNetwork: true,
signal: new AbortController().signal,
});
// The catalog identifies decision models, so a refresh neither probes them nor reads their chat template.
expect(systemOneRequests).toEqual([]);
expect(propsModels.sort()).toEqual(["legacy", "qwen"]);
expect(controller.provider.getModels().map((model) => model.id)).toEqual(["qwen", "legacy"]);
expect(cachedEntry?.models.map((model) => [model.id, model.api, model.baseUrl])).toEqual([
["qwen", "openai-completions", `${url}/v1`],
["legacy", "openai-completions", `${url}/v1`],
["qwen", "llama-cpp-classify", url],
["kev", "typesafe-system-one", `${url}/v1`],
["laya", "typesafe-system-one", `${url}/v1`],
["legacy", "llama-cpp-classify", url],
]);
const kev = controller.provider.getAllModels?.().find((model) => model.id === "kev");
if (kev?.type !== "classifier") throw new Error("missing decision classifier model");
expect(kev.contextWindow).toBe(8192);
const result = await controller.provider.classify!(
kev,
{
state: { message: "I was charged twice." },
questions: {
angry: {
type: "bool",
instructions: "Is the customer angry?",
criteria: { true: "angry", false: "calm" },
},
},
},
{ apiKey: "local" },
);
expect(result.errorMessage).toBeUndefined();
expect(result.answers.angry).toEqual({ type: "bool", probability: 0.82 });
expect(result.usage).toMatchObject({ input: 42, output: 0 });
expect(systemOneRequests).toEqual([
{
model: "kev",
state: { message: "I was charged twice." },
questions: {
angry: {
type: "noul",
instructions: "Is the customer angry?",
criteria: { true: "angry", false: "calm" },
},
},
},
]);
// A cache-only startup restores decision models with their native API.
const restored = createLlamaProvider();
await restored.provider.refreshModels?.({
credential,
stored: cachedEntry,
publish,
allowNetwork: false,
signal: new AbortController().signal,
});
expect(restored.provider.getModels().map((model) => model.id)).toEqual(["qwen", "legacy"]);
expect(
restored.provider
.getAllModels?.()
.filter((model) => model.type === "classifier")
.map((model) => [model.id, model.api]),
).toEqual([
["qwen", "llama-cpp-classify"],
["kev", "typesafe-system-one"],
["laya", "typesafe-system-one"],
["legacy", "llama-cpp-classify"],
]);
});
it("lists decision models that also output text for chat", () => {
const controller = createLlamaProvider();
controller.setCatalog(
[
{ id: "decide", status: { value: "sleeping" }, architecture: { output_modalities: ["decisions"] } },
{
id: "hybrid",
status: { value: "loaded" },
architecture: { output_modalities: ["text", "decisions"] },
},
],
"http://localhost:8080",
);
expect(controller.provider.getModels().map((model) => model.id)).toEqual(["hybrid"]);
expect(
controller.provider
.getAllModels?.()
.filter((model) => model.type === "classifier")
.map((model) => [model.id, model.api]),
).toEqual([
["decide", "typesafe-system-one"],
["hybrid", "typesafe-system-one"],
]);
});
it("hides unloaded presets when router autoload is disabled", async () => {