mirror of
https://github.com/luckyyzh/pi-agent-integrated.git
synced 2026-10-03 02:59:35 +00:00
feat: integrate Pi backend and Pi Web
This commit is contained in:
@@ -0,0 +1,87 @@
|
||||
import assert from "node:assert/strict";
|
||||
import test from "node:test";
|
||||
import React from "react";
|
||||
import { renderToStaticMarkup } from "react-dom/server";
|
||||
import { createJiti } from "jiti";
|
||||
|
||||
const jiti = createJiti(import.meta.url, {
|
||||
jsx: { runtime: "automatic" },
|
||||
tsconfigPaths: true,
|
||||
});
|
||||
const { ChatInput, ModelErrorBanner, filterModelOptions } = await jiti.import("./ChatInput.tsx");
|
||||
const { I18nProvider } = await jiti.import("../hooks/useI18n.tsx");
|
||||
|
||||
test("renders the upstream model error", () => {
|
||||
const html = renderToStaticMarkup(
|
||||
React.createElement(ModelErrorBanner, {
|
||||
error: "Invalid models.json schema:\nproviders.custom.models.0.id must not be empty",
|
||||
}),
|
||||
);
|
||||
|
||||
assert.match(html, /role="alert"/);
|
||||
assert.match(html, /Model error/);
|
||||
assert.match(html, /providers\.custom\.models\.0\.id must not be empty/);
|
||||
});
|
||||
|
||||
test("does not render an empty model error", () => {
|
||||
assert.equal(renderToStaticMarkup(React.createElement(ModelErrorBanner, { error: null })), "");
|
||||
});
|
||||
|
||||
test("keeps the model selector visible when a model error leaves no options", () => {
|
||||
const html = renderToStaticMarkup(
|
||||
React.createElement(
|
||||
I18nProvider,
|
||||
null,
|
||||
React.createElement(ChatInput, {
|
||||
onSend() {},
|
||||
onAbort() {},
|
||||
onModelChange() {},
|
||||
isStreaming: false,
|
||||
modelError: "Invalid models.json schema",
|
||||
modelList: [],
|
||||
modelNames: {},
|
||||
}),
|
||||
),
|
||||
);
|
||||
|
||||
assert.match(html, />No models</);
|
||||
assert.match(html, /title="No available models"/);
|
||||
});
|
||||
|
||||
test("filters model options by name and id", () => {
|
||||
const options = [
|
||||
{ provider: "ollama", modelId: "qwen3:latest", name: "Qwen 3" },
|
||||
{ provider: "anthropic", modelId: "claude-sonnet-4-6", name: "Claude Sonnet 4.6" },
|
||||
{ provider: "openai", modelId: "gpt-5.4", name: "GPT-5.4" },
|
||||
];
|
||||
|
||||
assert.deepEqual(filterModelOptions(options, "QWEN"), [options[0]]);
|
||||
assert.deepEqual(filterModelOptions(options, "claude-sonnet"), [options[1]]);
|
||||
assert.equal(filterModelOptions(options, "OpenAI").length, 0);
|
||||
assert.equal(filterModelOptions(options, "anthropic/claude").length, 0);
|
||||
assert.equal(filterModelOptions(options, "missing").length, 0);
|
||||
assert.equal(filterModelOptions(options, " "), options);
|
||||
});
|
||||
|
||||
test("renders compact errors above the input as a wrapping alert", () => {
|
||||
const error = "Compaction failed: OpenAI API error (403): <html>request forbidden</html>";
|
||||
const html = renderToStaticMarkup(
|
||||
React.createElement(
|
||||
I18nProvider,
|
||||
null,
|
||||
React.createElement(ChatInput, {
|
||||
onSend() {},
|
||||
onAbort() {},
|
||||
onCompact() {},
|
||||
isStreaming: false,
|
||||
compactError: error,
|
||||
}),
|
||||
),
|
||||
);
|
||||
|
||||
assert.match(html, /role="alert"/);
|
||||
assert.match(html, /Compaction failed: OpenAI API error/);
|
||||
assert.match(html, /<html>request forbidden<\/html>/);
|
||||
assert.match(html, /white-space:pre-wrap/);
|
||||
assert.ok(html.indexOf('role="alert"') < html.indexOf("<textarea"));
|
||||
});
|
||||
Reference in New Issue
Block a user