pi-opencode-go-provider 1.0.16 → 1.0.18

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.
@@ -0,0 +1,31 @@
1
+ {
2
+ "format": 1,
3
+ "entries": {
4
+ "topology/peer-seq": {
5
+ "key": "topology/peer-seq",
6
+ "value": {
7
+ "format": 1,
8
+ "next": 1
9
+ },
10
+ "version": 1,
11
+ "updatedAt": 1788421061231,
12
+ "updatedBy": {
13
+ "id": "session:01a06632-9590-73a7-8e4c-bf4f4d6d8277",
14
+ "name": "main",
15
+ "kind": "main",
16
+ "sessionId": "01a06632-9590-73a7-8e4c-bf4f4d6d8277"
17
+ }
18
+ }
19
+ },
20
+ "versions": {
21
+ "topology/peer-seq": 1,
22
+ "topology/hosts/ae5878888fad007023c5ff775ac6356930ec9eaacf6e5b09ceebb18d9d4e54c8": 419,
23
+ "sessions/01a06632-9590-73a7-8e4c-bf4f4d6d8277": 418,
24
+ "topology/participants/ae5878888fad007023c5ff775ac6356930ec9eaacf6e5b09ceebb18d9d4e54c8": 419
25
+ },
26
+ "tombstoneOrder": [
27
+ "sessions/01a06632-9590-73a7-8e4c-bf4f4d6d8277",
28
+ "topology/participants/ae5878888fad007023c5ff775ac6356930ec9eaacf6e5b09ceebb18d9d4e54c8",
29
+ "topology/hosts/ae5878888fad007023c5ff775ac6356930ec9eaacf6e5b09ceebb18d9d4e54c8"
30
+ ]
31
+ }
package/README.md CHANGED
@@ -20,6 +20,7 @@ _Go-optimized endpoints for lower latency — 14+ models for [pi](https://github
20
20
  - **Fast & Efficient** - Go-optimized endpoints for lower latency
21
21
  - **Cost Tracking** with per-model pricing for budget management
22
22
  - **Reasoning Models** with thinking level maps for proper effort control
23
+ - **Prompt-cache session affinity** — sends `x-opencode-session` and `x-opencode-client` so OpenCode Go can pin a session to the same cache node
23
24
 
24
25
  ## Installation
25
26
 
package/index.ts CHANGED
@@ -339,7 +339,40 @@ async function resolveApiKey(modelRegistry: ModelRegistry): Promise<void> {
339
339
  cachedApiKey = await modelRegistry.getApiKeyForProvider("opencode-go") ?? undefined;
340
340
  }
341
341
 
342
- // ─── Extension Entry Point ────────────────────────────────────────────────────
342
+ // OpenCode Go prompt-cache routing headers.
343
+ // Pi core already injects these in mergeProviderAttributionHeaders for
344
+ // provider "opencode-go" / host opencode.ai (see #4847). This hook is a
345
+ // backstop: it fills them only when missing, so older pi builds and any
346
+ // request path that skipped transformHeaders still pin the session.
347
+ // Per-request via before_provider_headers — not registerProvider.headers —
348
+ // because provider-wide headers leak to raw helper streams
349
+ // (getApiKeyAndHeaders) that must not inherit the main session's cache
350
+ // lineage. No custom streamSimple is needed; headers are applied before
351
+ // provider dispatch.
352
+ const OPENCODE_SESSION_HEADER = "x-opencode-session";
353
+ const OPENCODE_CLIENT_HEADER = "x-opencode-client";
354
+ const OPENCODE_CLIENT = "pi";
355
+
356
+ function headerLookup(headers: Record<string, string | null | undefined>, name: string): string | undefined {
357
+ const lower = name.toLowerCase();
358
+ for (const [key, value] of Object.entries(headers)) {
359
+ if (key.toLowerCase() === lower) return value ?? undefined;
360
+ }
361
+ return undefined;
362
+ }
363
+
364
+ export function applyOpenCodeSessionHeaders(
365
+ headers: Record<string, string | null>,
366
+ sessionId: string | undefined,
367
+ ): Record<string, string | null> {
368
+ if (sessionId && !headerLookup(headers, OPENCODE_SESSION_HEADER)) {
369
+ headers[OPENCODE_SESSION_HEADER] = sessionId;
370
+ }
371
+ if (!headerLookup(headers, OPENCODE_CLIENT_HEADER)) {
372
+ headers[OPENCODE_CLIENT_HEADER] = OPENCODE_CLIENT;
373
+ }
374
+ return headers;
375
+ }
343
376
 
344
377
  export default function (pi: ExtensionAPI) {
345
378
  const embeddedModels = modelsData as JsonModel[];
@@ -369,6 +402,11 @@ export default function (pi: ExtensionAPI) {
369
402
  })),
370
403
  });
371
404
 
405
+ pi.on("before_provider_headers", (event, ctx) => {
406
+ if (ctx.model?.provider !== PROVIDER_ID) return;
407
+ applyOpenCodeSessionHeaders(event.headers, ctx.sessionManager.getSessionId());
408
+ });
409
+
372
410
  pi.on("session_start", async (_event, ctx) => {
373
411
  revalidateAbort?.abort();
374
412
  revalidateAbort = new AbortController();