opencode-plugboard 0.21.0 → 0.21.1
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 +2 -2
- package/package.json +1 -1
- package/src/openai/response.ts +16 -7
package/README.md
CHANGED
|
@@ -43,7 +43,7 @@ export PLUGBOARD_KEY_MY_APP=choose-a-long-random-string
|
|
|
43
43
|
{
|
|
44
44
|
"plugins": [
|
|
45
45
|
{
|
|
46
|
-
"package": "opencode-plugboard@0.21.
|
|
46
|
+
"package": "opencode-plugboard@0.21.1",
|
|
47
47
|
"options": {
|
|
48
48
|
"keys": { "my-app": "{env:PLUGBOARD_KEY_MY_APP}" },
|
|
49
49
|
"models": ["anthropic/claude-sonnet-4-6", "github-copilot/*", "opencode-go/glm-5.3-flash"],
|
|
@@ -390,7 +390,7 @@ A server shared by a Discord bot, n8n, Open WebUI and a coding agent, with most
|
|
|
390
390
|
{
|
|
391
391
|
"plugins": [
|
|
392
392
|
{
|
|
393
|
-
"package": "opencode-plugboard@0.21.
|
|
393
|
+
"package": "opencode-plugboard@0.21.1",
|
|
394
394
|
"options": {
|
|
395
395
|
// Reachable from the LAN. Non-loopback hosts refuse to start without keys.
|
|
396
396
|
"listen": { "host": "10.0.1.50", "port": 4010 },
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "opencode-plugboard",
|
|
3
|
-
"version": "0.21.
|
|
3
|
+
"version": "0.21.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"description": "Use the ChatGPT, Claude, Copilot and OpenCode Go logins in your OpenCode server from any app: an OpenCode V2 plugin serving OpenAI, Anthropic and Gemini compatible APIs.",
|
package/src/openai/response.ts
CHANGED
|
@@ -240,16 +240,25 @@ export function matchesSchema(value: unknown, schema: Readonly<Record<string, un
|
|
|
240
240
|
* the schema asks for (one code fence is stripped first). Undefined for any other text.
|
|
241
241
|
*/
|
|
242
242
|
export function textFallback(text: string, schema: Readonly<Record<string, unknown>>): string | undefined {
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
243
|
+
// The whole text (fenced or not), else the one fenced block inside prose: Claude, told not to call
|
|
244
|
+
// tools, skips `respond` and answers "Here is the JSON: ```json {...}```" (found by the live suite).
|
|
245
|
+
const fenced = [...text.matchAll(FENCE_ANYWHERE)].map((match) => match[1]!.trim())
|
|
246
|
+
const candidates = [unfence(text.trim()), ...(fenced.length === 1 ? fenced : [])]
|
|
247
|
+
for (const candidate of candidates) {
|
|
248
|
+
let value: unknown
|
|
249
|
+
try {
|
|
250
|
+
value = JSON.parse(candidate)
|
|
251
|
+
} catch {
|
|
252
|
+
continue
|
|
253
|
+
}
|
|
254
|
+
if (matchesSchema(value, schema)) return candidate
|
|
249
255
|
}
|
|
250
|
-
return
|
|
256
|
+
return undefined
|
|
251
257
|
}
|
|
252
258
|
|
|
259
|
+
/** Every fenced code block (```json or a bare ```) anywhere in the text. */
|
|
260
|
+
const FENCE_ANYWHERE = /```[ \t]*(?:json)?[ \t]*\r?\n([\s\S]*?)\r?\n?[ \t]*```/gi
|
|
261
|
+
|
|
253
262
|
/** One markdown code fence (```json or a bare ```) around the whole text. */
|
|
254
263
|
const FENCED = /^```[ \t]*(?:json)?[ \t]*\r?\n([\s\S]*?)\r?\n?[ \t]*```$/i
|
|
255
264
|
|