@mcowger/oh-my-pi-plexus 1.4.9 → 1.4.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +21 -0
- package/dist/extension.js +5 -3
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -186,6 +186,26 @@ The plugins normalize either form to the Plexus root URL for storage and derive
|
|
|
186
186
|
|
|
187
187
|
OpenCode stores the API key in its native auth store and stores the Plexus base URL as auth metadata on that connection. Existing `provider.plexus.options.plexusBaseURL` config is still honored as a fallback.
|
|
188
188
|
|
|
189
|
+
`provider.plexus.options.baseURL` is also accepted as input-only compatibility config. Some external clients read OpenCode config files directly and only recognize `options.baseURL`. The plugin normalizes that value for Plexus discovery and then removes it from OpenCode's in-memory provider options, so individual models keep their own `/v1` or `/v1beta` endpoints instead of being overridden by a provider-wide URL.
|
|
190
|
+
|
|
191
|
+
For an OpenChamber-compatible OpenCode config, omit `options.apiKey` and authenticate through `/connect`:
|
|
192
|
+
|
|
193
|
+
```json
|
|
194
|
+
{
|
|
195
|
+
"provider": {
|
|
196
|
+
"plexus": {
|
|
197
|
+
"options": {
|
|
198
|
+
"baseURL": "https://plexus.example.com/v1"
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
Then run `/connect`, select **Plexus**, and authenticate against the same Plexus server. A raw unresolved `options.apiKey` value in this file can override the resolved runtime credential used by OpenChamber, including OpenCode `{env:NAME}` templates that OpenChamber does not expand when extra characters follow the template.
|
|
206
|
+
|
|
207
|
+
The plugin publishes models with `/v1` endpoints before `/v1beta` models. This ordering helps OpenChamber versions that derive a provider-wide endpoint from the first runtime model; it does not change model endpoints or OpenCode routing. Gemini models still use `/v1beta` through `@ai-sdk/google`.
|
|
208
|
+
|
|
189
209
|
The OpenCode plugin respects each model's `preferred_api` value and routes models through the matching SDK/API shape:
|
|
190
210
|
|
|
191
211
|
- `chat_completions` / `openai-completions` → OpenAI-compatible chat completions
|
|
@@ -350,6 +370,7 @@ Models with a falsy `id` are skipped. Missing metadata falls back to safe defaul
|
|
|
350
370
|
- **OpenCode** seeds the provider from the on-disk cache (or a placeholder model) once, during config loading — OpenCode's `provider.models` hook never fires for custom providers, so there is no live discovery at startup. Run `/plexus-refresh` to force a live fetch and rewrite the cache; because OpenCode has no way to hot-reload a custom provider's model list mid-session, a restart is required afterward to see the refreshed models in the picker.
|
|
351
371
|
- OpenCode models retain their upstream model ID, SDK dialect, release date, and reasoning metadata so OpenCode can generate its native GPT, Claude, Gemini, and OpenAI-compatible variants and apply its current request transforms. DeepSeek models also preserve `reasoning_content` across tool-call turns.
|
|
352
372
|
- OpenCode uses a 250K-token context window when Plexus supplies no context metadata; its output fallback remains 20% of that window.
|
|
373
|
+
- OpenCode moves `/v1beta` models after `/v1` models in published model order. Model endpoints and per-model SDK selection are unchanged.
|
|
353
374
|
- Both adapters convert Plexus's per-token base and tier rates to the per-million-token units expected by their host.
|
|
354
375
|
|
|
355
376
|
## Development
|
package/dist/extension.js
CHANGED
|
@@ -109289,7 +109289,7 @@ function matchesPattern(id, name, shortId, pattern) {
|
|
|
109289
109289
|
}
|
|
109290
109290
|
// ../plexus-models/src/convert.ts
|
|
109291
109291
|
var REASONING_PARAMS = new Set(["reasoning", "include_reasoning", "reasoning_effort"]);
|
|
109292
|
-
var NON_CHAT_PATTERN = /(?:^|[\W_])(?:embed(?:ding|dings)?|transcri(?:be[ds]?|ptions?)|whisper|speech[\W_]*to[\W_]*text|stt|text[\W_]*to[\W_]*speech|tts|image[\W_]*(?:gen(?:eration)?|\d+)
|
|
109292
|
+
var NON_CHAT_PATTERN = /(?:^|[\W_])(?:embed(?:ding|dings)?|transcri(?:be[ds]?|ptions?)|whisper|speech[\W_]*to[\W_]*text|stt|text[\W_]*to[\W_]*speech|tts|image(?:[\W_]*(?:gen(?:eration)?|\d+))?|diffusion|dall[\W_]*e|stable[\W_]*diffusion|sdxl|dream)(?:$|[\W_])/i;
|
|
109293
109293
|
var API_DIALECT_MAP = {
|
|
109294
109294
|
chat_completions: "openai-completions",
|
|
109295
109295
|
"openai-completions": "openai-completions",
|
|
@@ -109413,15 +109413,17 @@ function isChatModel(model) {
|
|
|
109413
109413
|
return false;
|
|
109414
109414
|
}
|
|
109415
109415
|
const outputModalities = model.architecture?.output_modalities;
|
|
109416
|
-
if (outputModalities !== undefined &&
|
|
109416
|
+
if (outputModalities !== undefined && (outputModalities.length === 0 || outputModalities.some((m) => m !== "text"))) {
|
|
109417
109417
|
return false;
|
|
109418
|
+
}
|
|
109418
109419
|
const modality = model.architecture?.modality;
|
|
109419
109420
|
if (modality?.includes("->")) {
|
|
109420
109421
|
const input = modality.split("->")[0] ?? "";
|
|
109421
109422
|
if (!input.toLowerCase().includes("text"))
|
|
109422
109423
|
return false;
|
|
109423
109424
|
const output = modality.split("->").at(-1) ?? "";
|
|
109424
|
-
|
|
109425
|
+
const outputTokens = output.toLowerCase().split(/[+,]/).map((t) => t.trim()).filter((t) => t.length > 0);
|
|
109426
|
+
if (outputTokens.length === 0 || outputTokens.some((t) => t !== "text"))
|
|
109425
109427
|
return false;
|
|
109426
109428
|
}
|
|
109427
109429
|
const apiHints = Array.isArray(model.preferred_api) ? model.preferred_api.join(" ") : model.preferred_api ?? "";
|