mirror of
https://github.com/earendil-works/pi.git
synced 2026-10-28 09:44:37 +08:00
fix(ai): use OpenCode protocol-specific endpoints (#11434)
closes #11132 pi sends every opencode and opencode-go request to the shared base (`https://opencode.ai/inference/v1`, `/inference/go/v1`), Jev included. this switches them to the documented protocol-specific endpoints, which is also what models.dev lists per model: | api | before | after | |---|---|---| | openai-completions / openai-responses | `/inference/v1` | `/inference/openai/v1` | | anthropic-messages | `/inference` | `/inference/anthropic` (SDK appends `/v1/messages`) | | google-generative-ai | `/inference/v1` | `/inference/google/v1beta` | | jev-1.13 / jev-1.13-free | `/inference/v1` | `/inference/systemone/v1` | go uses the same paths under `/inference/go/...`. changes: base URLs in `generate-models.ts`, the jev URL expectations in `test/classifier-models.test.ts`, and a stale comment in `providers/opencode.ts`. `models.generated.ts` has no diff since the catalog data is gitignored. verified with the regenerated catalog: - all 111 opencode/opencode-go models hit their new URL, none 404 - real requests with an OpenCode key returned replies on anthropic-messages, google-generative-ai, openai-responses, openai-completions and jev - go returned 403 "subscription required" from the new paths (my key has no Go sub), so routing works there too `npm run check` passes. `./test.sh` passes for ai and coding-agent; the only remaining failures were timeouts that pass in isolation and pi-env tests that need cargo locally. --- _Drafted with AI assistance, reviewed by me._
This commit is contained in:
1 parent
973b74c55f
commit
177e2ad7e4
3 files changed
+12
-12
No files matched your search
@@ -2272,23 +2272,23 @@ async function loadModelsDevData(): Promise<Model<any>[]> {
|
||||
|
||||
if (npm === "@ai-sdk/openai") {
|
||||
api = "openai-responses";
|
||||
baseUrl = `${variant.basePath}/v1`;
|
||||
baseUrl = `${variant.basePath}/openai/v1`;
|
||||
compat = { sessionAffinityFormat: "openai-nosession" };
|
||||
} else if (npm === "@ai-sdk/anthropic") {
|
||||
api = "anthropic-messages";
|
||||
// Anthropic SDK appends /v1/messages to baseURL
|
||||
baseUrl = variant.basePath;
|
||||
baseUrl = `${variant.basePath}/anthropic`;
|
||||
} else if (npm === "@ai-sdk/google") {
|
||||
api = "google-generative-ai";
|
||||
baseUrl = `${variant.basePath}/v1`;
|
||||
baseUrl = `${variant.basePath}/google/v1beta`;
|
||||
} else if (npm === "@ai-sdk/alibaba") {
|
||||
api = "openai-completions";
|
||||
baseUrl = `${variant.basePath}/v1`;
|
||||
baseUrl = `${variant.basePath}/openai/v1`;
|
||||
compat = { cacheControlFormat: "anthropic" };
|
||||
} else {
|
||||
// null, undefined, or @ai-sdk/openai-compatible
|
||||
api = "openai-completions";
|
||||
baseUrl = `${variant.basePath}/v1`;
|
||||
baseUrl = `${variant.basePath}/openai/v1`;
|
||||
}
|
||||
|
||||
if (variant.provider === "opencode" && modelId === "grok-build-0.1") {
|
||||
@@ -2304,11 +2304,11 @@ async function loadModelsDevData(): Promise<Model<any>[]> {
|
||||
// Fix known mismatches between models.dev npm data and actual
|
||||
// OpenCode Go endpoint behaviour. models.dev reports these models
|
||||
// as @ai-sdk/anthropic, but OpenCode Go serves them through the
|
||||
// OpenAI-compatible /v1/chat/completions path.
|
||||
// OpenAI-compatible /openai/v1/chat/completions path.
|
||||
if (variant.provider === "opencode-go") {
|
||||
if (modelId === "qwen3.5-plus" || modelId === "qwen3.6-plus") {
|
||||
api = "openai-completions";
|
||||
baseUrl = `${variant.basePath}/v1`;
|
||||
baseUrl = `${variant.basePath}/openai/v1`;
|
||||
// Qwen/DashScope uses enable_thinking at the top level.
|
||||
compat = { ...(compat ?? {}), thinkingFormat: "qwen" };
|
||||
}
|
||||
@@ -2681,7 +2681,7 @@ const OPENCODE_CLASSIFIER_MODELS: ClassifierModel<"typesafe-system-one">[] = [
|
||||
name: "Jev 1.13",
|
||||
api: "typesafe-system-one",
|
||||
provider: "opencode",
|
||||
baseUrl: "https://opencode.ai/inference/v1",
|
||||
baseUrl: "https://opencode.ai/inference/systemone/v1",
|
||||
input: ["text"],
|
||||
cost: { input: 0.042, output: 0, cacheRead: 0, cacheWrite: 0 },
|
||||
contextWindow: 32000,
|
||||
@@ -2692,7 +2692,7 @@ const OPENCODE_CLASSIFIER_MODELS: ClassifierModel<"typesafe-system-one">[] = [
|
||||
name: "Jev 1.13 Free",
|
||||
api: "typesafe-system-one",
|
||||
provider: "opencode",
|
||||
baseUrl: "https://opencode.ai/inference/v1",
|
||||
baseUrl: "https://opencode.ai/inference/systemone/v1",
|
||||
input: ["text"],
|
||||
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
|
||||
contextWindow: 32000,
|
||||
|
||||
@@ -22,7 +22,7 @@ export function opencodeProvider(): Provider<OpenCodeApi> {
|
||||
"openai-completions": withOpenCodeSessionHeader(openAICompletionsApi()),
|
||||
"openai-responses": withOpenCodeSessionHeader(openAIResponsesApi()),
|
||||
},
|
||||
// OpenCode Zen serves TypeSafe's System One protocol at /zen/v1/systemone.
|
||||
// OpenCode Zen serves TypeSafe's System One protocol at /inference/systemone/v1/systemone.
|
||||
classifiers: { "typesafe-system-one": typesafeSystemOneApi() },
|
||||
});
|
||||
}
|
||||
@@ -130,8 +130,8 @@ describe("Models with classifier models", () => {
|
||||
|
||||
it.each([
|
||||
["vercel-ai-gateway", "typesafe-ai/jev", "https://ai-gateway.vercel.sh/typesafe/v1/systemone"],
|
||||
["opencode", "jev-1.13", "https://opencode.ai/inference/v1/systemone"],
|
||||
["opencode", "jev-1.13-free", "https://opencode.ai/inference/v1/systemone"],
|
||||
["opencode", "jev-1.13", "https://opencode.ai/inference/systemone/v1/systemone"],
|
||||
["opencode", "jev-1.13-free", "https://opencode.ai/inference/systemone/v1/systemone"],
|
||||
])("routes %s Jev (%s) to its TypeSafe-compatible endpoint", async (provider, id, url) => {
|
||||
const models = builtinModels();
|
||||
const jev = models.getModelOfType("classifier", provider, id);
|
||||
|
||||
Reference in new issue
Block a user