fix(llm): support versioned OpenAI-compatible endpoints + optional bearer for local provider

Two issues blocked OpenAI-compatible servers that aren't Ollama-on-/v1:

1. LocalAdapter.isOpenAIWire matched only a literal /v1 path, so versioned
   endpoints like Zhipu/z.ai's /api/paas/v4 silently fell through to Ollama's
   native /api/chat wire format and failed. Match any /vN instead of literally /v1.

2. The `local` provider was treated as always-keyless, so servers that require
   a bearer (Zhipu/z.ai, Together, ...) could never authenticate. Read an
   optional key from TEMPEST_LOCAL_API_KEY (ZAI_API_KEY / ZHIPUAI_API_KEY as
   aliases), wire it through getApiKey/hasApiKey so `tempest test` and the
   mission engine accept a configured local provider, and document the options
   in the env template.

The key is read from env in-memory and never persisted into the store, matching
the existing env-key hardening invariant (api-key-env-static).

Adds src/__tests__/local-openai-wire-static.test.ts pinning both fixes.
Verified end-to-end against z.ai's GLM models (glm-4.5-air / 4.6 / 5.2).
This commit is contained in:
yaraul committed 2026-07-06 19:51:18 +03:00
1 parent c040afd977
commit 2613daef49
3 files changed
+100 -9

No files matched your search

+5 -2
View File
@@ -725,9 +725,12 @@ class LocalAdapter implements LLMProviderAdapter {
return { valid: true };
}
// A /v1 base URL means an OpenAI-compatible server (/chat/completions, choices[]).
// A versioned base URL (/v1, /v2, /v4, …) means an OpenAI-compatible server
// (/chat/completions, choices[]). Many OpenAI-compatible providers version their
// API at paths other than /v1 (e.g. Zhipu/z.ai exposes /api/paas/v4), so match any
// /vN rather than literally /v1.
private isOpenAIWire(baseUrl: string): boolean {
return /\/v1(\/|$)/.test(baseUrl);
return /\/v\d+(\/|$)/.test(baseUrl);
}
// Inject the Arsenal contract as a system turn when tools are offered, and