Fix loading when installed from git: import openAIResponsesApi from pi-ai/compat
Some checks failed
CI / test (22) (push) Failing after 25s
CI / test (24) (push) Failing after 37s

pi resolves only a fixed set of its own module paths for installed
extensions; pi-ai/api/* is not among them. Add a test that keeps
runtime imports within that set.
This commit is contained in:
Benjamin Hackl 2026-11-03 21:18:44 +01:00
commit 4a957f2796
2 changed files with 34 additions and 1 deletions

View file

@ -3,7 +3,9 @@ import {
type Model, type Model,
type Provider, type Provider,
} from "@earendil-works/pi-ai"; } from "@earendil-works/pi-ai";
import { openAIResponsesApi } from "@earendil-works/pi-ai/api/openai-responses.lazy"; // pi resolves only a fixed set of its own module paths for extensions; anything
// else (e.g. pi-ai/api/*) fails in a git/npm install. See test/imports.test.ts.
import { openAIResponsesApi } from "@earendil-works/pi-ai/compat";
import { getBuiltinModels } from "@earendil-works/pi-ai/providers/all"; import { getBuiltinModels } from "@earendil-works/pi-ai/providers/all";
export const PROVIDER_ID = "unigpt"; export const PROVIDER_ID = "unigpt";

31
test/imports.test.ts Normal file
View file

@ -0,0 +1,31 @@
import assert from "node:assert/strict";
import { readdirSync, readFileSync } from "node:fs";
import { test } from "node:test";
// Installed packages get no copy of pi in node_modules (pi is a peer
// dependency). pi maps only these specifiers to its own modules when loading
// an extension; see "Available Imports" in pi's docs/extensions.md.
const HOST_PROVIDED = new Set([
"@earendil-works/pi-coding-agent",
"@earendil-works/pi-agent-core",
"@earendil-works/pi-tui",
"@earendil-works/pi-ai",
"@earendil-works/pi-ai/compat",
"@earendil-works/pi-ai/models",
"@earendil-works/pi-ai/oauth",
"@earendil-works/pi-ai/providers/all",
"typebox",
"typebox/compile",
"typebox/value",
]);
test("runtime source imports only modules that pi provides to extensions", () => {
const sourceDir = new URL("../src/", import.meta.url);
for (const file of readdirSync(sourceDir).filter((name) => name.endsWith(".ts"))) {
const source = readFileSync(new URL(file, sourceDir), "utf8");
for (const [, specifier] of source.matchAll(/^\s*import\s[^;]*?from\s+"([^"]+)"/gms)) {
if (specifier.startsWith(".") || specifier.startsWith("node:")) continue;
assert.ok(HOST_PROVIDED.has(specifier), `src/${file} imports "${specifier}", which pi does not provide to installed extensions`);
}
}
});