Dashboard › opencode-lore › Session 09xkKPUGmmms
09xkKPUGmmmslaeV9Implement the single provider security blocker in /home/byk/Code/opencode-lore-provider-error current additive empty child qzwttkwl (description fix(responses): isolate failure telemetry) over immutable lpmvqrur/0dd569b5. You may edit but do not commit/push/rebase/bookmark/server/network/production DB. Read AGENTS.md, quality/REVIEW.md/scripts. TDD mandatory: add adversarial tests with a registered log sink whose error() throws for all 3 accepted provider-failure settlement paths: plain/passthrough, recall-aware principal, and recall-aware continuation. Prove tests fail on current behavior. Assertions: exactly one sanitized fixed response.failed terminal, unsuccessful accounting exactly once, rollback exactly once where applicable, continuation never becomes completed, no provider/private data, diagnostics cannot alter classification/delivery. Implement the smallest non-throwing fixed-message reporting helper; it must contain sink/logger failure and never recurse/log arbitrary callback error. Apply only at accepted provider-failure categorical log sites, preserve durable best-effort visibility when logger succeeds. Remove helper/containment as mutation and prove all named tests fail; restore. Run complete two provider stream suites, six-file affected integration matrix, gateway typecheck, format. Use apply_patch. Return exact fail-first/mutation/pass counts, changed files, residual risk. If Lore warning, recover via lore recall/local UI and continue; never warning-only/empty.
<skill_content name="jj-guide"> # Skill: jj-guide # jj Guide for AI Agents Jujutsu (jj) is a Git-compatible VCS with mutable commits, automatic snapshotting, no staging area, and first-class conflicts. This skill teaches you how to use it safely from a non-interactive agent environment. If `.jj/` exists in the repo root, this is a jj repo. **Use `jj` commands, not `git`.** In a colocated repo (`.jj/` *and* `.git/`), git tools can read the state, but mutations should go through `jj` so the operation log stays consistent. ## Critical Rules - **NEVER** use interactive flags (`-i`, `--interactive`). TUI prompts hang in agent environments. This applies to `jj split -i`, `jj squash -i`, `jj commit -i`, `jj resolve`, `jj diffedit`, etc. - **ALWAYS** pass `-m "msg"` when describing/committing. Without `-m`, an editor opens and hangs. - **VERIFY** mutations with `jj st` and `jj log` after `squash`, `abandon`, `rebase`, `restore`, `commit`. ...
/home/byk/Code/opencode-lore-provider-error/AGENTS.md
/home/byk/Code/opencode-lore-provider-error/quality/use_cases_manifest.json /home/byk/Code/opencode-lore-provider-error/quality/results/tdd-results.json /home/byk/Code/opencode-lore-provider-error/quality/results/code-review-findings.md /home/byk/Code/opencode-lore-provider-error/quality/results/BUG-006.red.log /home/byk/Code/opencode-lore-provider-error/quality/results/BUG-006.green.log /home/byk/Code/opencode-lore-provider-error/quality/results/BUG-001.red.log /home/byk/Code/opencode-lore-provider-error/quality/results/BUG-001.green.log /home/byk/Code/opencode-lore-provider-error/quality/requirements_manifest.json /home/byk/Code/opencode-lore-provider-error/quality/plans/worker-chatgpt-backend-model-reuse.md /home/byk/Code/opencode-lore-provider-error/quality/plans/modem-recall-code-anchors.md /home/byk/Code/opencode-lore-provider-error/quality/plans/lore-cli-stricli-agent-experience.md /home/byk/Code/opencode-lore-provider-error/quality/plans/import-reuse-credentials-provider-defaul...
No files found
/home/byk/Code/opencode-lore-provider-error/scripts/smoke-install.mjs /home/byk/Code/opencode-lore-provider-error/scripts/generate-release-checksums.mjs /home/byk/Code/opencode-lore-provider-error/scripts/generate-env-docs.ts /home/byk/Code/opencode-lore-provider-error/scripts/generate-config-docs.ts /home/byk/Code/opencode-lore-provider-error/scripts/extract-cch-seed.ts /home/byk/Code/opencode-lore-provider-error/scripts/check-social-meta.mjs /home/byk/Code/opencode-lore-provider-error/scripts/check-preview-links.mjs /home/byk/Code/opencode-lore-provider-error/scripts/check-patches.ts /home/byk/Code/opencode-lore-provider-error/scripts/check-docs-links.mjs /home/byk/Code/opencode-lore-provider-error/scripts/check-cc-version.ts /home/byk/Code/opencode-lore-provider-error/scripts/cch-scan.c /home/byk/Code/opencode-lore-provider-error/scripts/bump-version.sh
<path>/home/byk/Code/opencode-lore-provider-error/AGENTS.md</path> <type>file</type> <content> 1: <!-- This section is maintained by the coding agent via lore (https://github.com/BYK/loreai) --> 2: ## Long-term Knowledge 3: 4: For long-term knowledge entries managed by [lore](https://github.com/BYK/loreai) (gotchas, patterns, decisions, architecture), see [`.lore.md`](.lore.md) in the project root. 5: <!-- End lore-managed section --> 6: 7: ## Review 8: 9: See [`quality/REVIEW.md`](quality/REVIEW.md) for the review heuristics and workflow — regression-test discipline, adversarial-order state setup, fan-out registry coverage, recurring bug-class batteries, and the two-reviewer rule. Every non-trivial PR requires an adversarial correctness review before merge. 10: 11: # Project Overview 12: 13: Lore is a **three-tier memory architecture** for AI coding agents. ...
<path>/home/byk/Code/opencode-lore-provider-error/quality/REVIEW.md</path> <type>file</type> <content> 1: # Review Heuristics — Lore 2: 3: This document codifies the review bar for pull requests. It exists because 4: adversarial review has repeatedly caught correctness bugs that a green test 5: suite missed — skip/early-return branches, lifecycle sequences, and fan-out 6: registry gaps. Institutionalizing these patterns so they compound. 7: 8: The review workflow (§6) is referenced from AGENTS.md. 9: 10: --- 11: 12: ## 1. Regression-test discipline 13: 14: Every adversarial-review finding that surfaces a defect **must** land a 15: deterministic regression test in the same PR. The test: 16: - fails on the base branch (proving it reproduces the bug), 17: - passes on the fix (proving the fix works), 18: - drives the *real* precondition, not an artificially-constructed state (e.g. ...
<path>/home/byk/Code/opencode-lore-provider-error/package.json</path>
<type>file</type>
<content>
1: {
2: "name": "lore-monorepo",
3: "private": true,
4: "type": "module",
5: "license": "FSL-1.1-Apache-2.0",
6: "description": "Monorepo root for Lore — three-tier memory architecture",
7: "main": "./packages/opencode/src/index.ts",
8: "exports": {
9: ".": "./packages/opencode/src/index.ts"
10: },
11: "packageManager": "pnpm@10.28.0",
12: "volta": {
13: "node": "24.16.0",
14: "pnpm": "10.28.0"
15: },
16: "pnpm": {
17: "onlyBuiltDependencies": [
18: "esbuild",
19: "onnxruntime-node",
20: "sharp"
21: ],
22: "overrides": {
23: "basic-ftp": "5.3.1",
24: "ip-address": "10.2.0",
25: "fast-xml-parser": "5.7.3",
26: "@huggingface/hub": "2.11.0",
27: "onnxruntime-node": "1.27.0",
28: "yaml": ">=2.8.3",
29: "esbuild": ">=0.28.1",
30: "@opentelemetry/core": ">=2.8.0",
31: ...
The working copy has no changes. Working copy (@) : qzwttkwl d3b014cf (empty) fix(responses): isolate failure telemetry Parent commit (@-): lpmvqrur 0dd569b5 fix/responses-provider-failures | fix(responses): unify provider failure handling Warning: These bookmarks have conflicts: fix/responses-private-references Hint: Use `jj bookmark list` to see details. Use `jj bookmark set <name> -r <rev>` to resolve. qzwttkwltwzr d3b014cfcbb9 fix(responses): isolate failure telemetry lpmvqrurxwlm 0dd569b520ba fix(responses): unify provider failure handling wswlsmrnuzlq 24880457763b fix(responses): reject non-monotonic provider failures
Found 3 matches /home/byk/Code/opencode-lore-provider-error/packages/gateway/src/pipeline.ts: Line 10616: // provider failures only through the fixed public envelope. /home/byk/Code/opencode-lore-provider-error/packages/gateway/src/server.ts: Line 828: // Report only the allowlisted recall-continuation failure category. The /home/byk/Code/opencode-lore-provider-error/packages/gateway/src/stream/openai-responses.ts: Line 600: "openai-responses provider failure";
Found 100 matches (more matches available) /home/byk/Code/opencode-lore-provider-error/packages/gateway/src/pipeline.ts: Line 130: providerRoutingValue, Line 142: extractProviderHeader, Line 144: resolveProviderRoute, Line 220: RESPONSES_PROVIDER_FAILURE_LOG, Line 221: sanitizeResponsesProviderFailureTerminal, Line 222: validateResponsesProviderFailureTerminal, Line 270: canonicalWorkerProviderID, Line 273: workerProviderSupportsProtocol, Line 285: copyProviderAuthHeaders, Line 318: getModelEntrySyncForProvider, Line 320: lookupProviderRoute, Line 2630: * adjacency is intentionally left alone (pre-existing behavior; providers accept Line 3802: * `providerID` (when known from the request route) selects the Line 3803: * provider-qualified pricing entry so a bare id published by many providers at Line 3805: * zenmux) is priced from the provider the session is ACTUALLY routed to — the Line 3806: * flat map is ...
<path>/home/byk/Code/opencode-lore-provider-error/packages/gateway/src/stream/openai-responses.ts</path>
<type>file</type>
<content>
540: ? { type: "output_text", text: part.value }
541: : { type: "refusal", refusal: part.value },
542: );
543: return finalizedContent.length > 0
544: ? { ...snapshot, content: finalizedContent }
545: : snapshot;
546: }
547:
548: /** Validated unsuccessful terminal, carrying usage for accounting-only paths. */
549: export class ResponsesTerminalError extends Error {
550: constructor(
551: readonly response: GatewayResponse,
552: readonly status: string,
553: ) {
554: super(`upstream Responses request ended with status ${status}`);
555: this.name = "ResponsesTerminalError";
556: }
557: }
558:
559: export function makeResponsesAccState(): ResponsesAccState {
560: return {
561: id: "",
562: model: "",
563: created: false,
564: stopReason: "end_turn",
565: usage: { inputTokens: 0, ...
Found 5 matches /home/byk/Code/opencode-lore-provider-error/packages/gateway/src/pipeline.ts: Line 220: RESPONSES_PROVIDER_FAILURE_LOG, Line 10315: log.error(RESPONSES_PROVIDER_FAILURE_LOG); Line 10994: log.error(RESPONSES_PROVIDER_FAILURE_LOG); /home/byk/Code/opencode-lore-provider-error/packages/gateway/src/stream/openai-responses.ts: Line 599: export const RESPONSES_PROVIDER_FAILURE_LOG = Line 2223: log.error(RESPONSES_PROVIDER_FAILURE_LOG);
Found 100 matches (more matches available)
/home/byk/Code/opencode-lore-provider-error/packages/pi/test/internal.test.ts:
Line 24: log.registerSink(silentSink);
Line 275: log.registerSink({
Line 300: log.registerSink({
Line 317: log.registerSink({
Line 392: log.registerSink({
/home/byk/Code/opencode-lore-provider-error/packages/gateway/test/cch.test.ts:
Line 951: log.registerSink({
Line 960: log.registerSink(silentSink);
/home/byk/Code/opencode-lore-provider-error/packages/gateway/test/cache-stability.e2e.test.ts:
Line 1990: log.registerSink(captureSink);
Line 2053: log.registerSink(silentSink);
/home/byk/Code/opencode-lore-provider-error/packages/core/test/vec0-orphan-maintenance.test.ts:
Line 57: log.registerSink({ info() {}, warn() {}, error() {}, captureException() {} });
Line 89: log.registerSink({
Line 183: log.registerSink({
Line 321: ...
<path>/home/byk/Code/opencode-lore-provider-error/packages/core/src/log.ts</path>
<type>file</type>
<content>
1: /**
2: * Lightweight logger that suppresses informational messages by default.
3: *
4: * In TUI mode, all stderr output renders as red "error" text — confusing
5: * for routine status messages like "incremental distillation" or "pruned
6: * temporal messages". Only actual errors should be visible by default.
7: *
8: * Set LORE_DEBUG=1 to see informational messages (useful when debugging
9: * the plugin itself).
10: *
11: * ## Sink registration
12: *
13: * An optional {@link LogSink} can be registered via {@link registerSink}.
14: * When registered, every log call (regardless of `isDebug`) also forwards
15: * to the sink. This is used by the gateway to bridge logs → Sentry without
16: * adding a Sentry dependency to `@loreai/core`.
17: *
18: * ## File logging
19: *
20: * All log calls (info, warn, error) are written to a persistent log file
21: * at ...
<path>/home/byk/Code/opencode-lore-provider-error/packages/core/src/log.ts</path>
<type>file</type>
<content>
350: }
351: if (!existing.isFile() || existing.isSymbolicLink()) {
352: throw new Error(`Refusing non-regular rotated log file: ${path}`);
353: }
354: assertCurrentOwner(existing, path);
355: const fd = openSync(
356: path,
357: constants.O_RDONLY | constants.O_NONBLOCK | NO_FOLLOW,
358: );
359: try {
360: const info = fstatSync(fd);
361: if (!info.isFile()) {
362: throw new Error(`Refusing non-regular rotated log file: ${path}`);
363: }
364: assertCurrentOwner(info, path);
365: assertSameFile(existing, info, path);
366: unlinkSync(path);
367: } finally {
368: closeSync(fd);
369: }
370: }
371:
372: /**
373: * Resolve the log file path. Returns `undefined` in test environments
374: * or if the directory cannot be created.
375: */
376: function resolveLogPath(): string | undefined {
377: if ...
No files found
Found 100 matches (more matches available)
/home/byk/Code/opencode-lore-provider-error/packages/gateway/test/bedrock.test.ts:
Line 7: * recognizer (`isBedrockMantleHost`), the provider route (`bedrockMantle: true`,
Line 140: // (the provider route's protocol), so workers use the anthropic path.
Line 153: test("warms a bedrock-mantle session (provider id)", () => {
Line 166: test("warms a bedrock-mantle session detected by host (no provider header)", () => {
/home/byk/Code/opencode-lore-provider-error/packages/gateway/test/bedrock-runtime.test.ts:
Line 351: let cancelled = false;
Line 361: cancelled = true;
Line 394: expect(cancelled).toBe(true);
Line 433: let cancelled = false;
Line 439: cancelled = true;
Line 458: expect(cancelled).toBe(true);
/home/byk/Code/opencode-lore-provider-error/packages/gateway/test/bedrock-routing.test.ts:
Line 6: * Anthropic Messages API). ...
No files found
/home/byk/Code/opencode-lore-provider-error/packages/gateway/test/worker-copilot-responses.test.ts /home/byk/Code/opencode-lore-provider-error/packages/gateway/test/openai-responses-stream.test.ts /home/byk/Code/opencode-lore-provider-error/packages/gateway/test/openai-responses-recall-aware-stream.test.ts /home/byk/Code/opencode-lore-provider-error/packages/gateway/test/responses-upstream-error-relay.test.ts /home/byk/Code/opencode-lore-provider-error/packages/gateway/test/responses-compact-routing.test.ts /home/byk/Code/opencode-lore-provider-error/packages/gateway/test/openai-responses.test.ts
Found 51 matches
/home/byk/Code/opencode-lore-provider-error/packages/gateway/test/openai-responses-stream.test.ts:
Line 650: event: "response.failed",
Line 652: type: "response.failed",
Line 676: expect(capturedLogs).toEqual(["openai-responses provider failure"]);
Line 724: event: "response.failed",
Line 726: type: "response.failed",
Line 4157: reader.cancel().then(() => "cancelled"),
Line 4160: expect(outcome).toBe("cancelled");
Line 4183: expect(output).not.toContain("event: response.failed");
Line 4195: expect(output).toContain("event: response.failed");
Line 4226: expect(output).toContain("response.failed");
Line 4251: expect(codex).not.toContain("response.failed");
Line 4260: expect(publicOutput).toContain("response.failed");
Line 4264: ["response.failed", "failed"],
Line 4265: ["response.failed", "cancelled"],
Line 4267: ["response.done", ...
Found 100 matches (more matches available)
/home/byk/Code/opencode-lore-provider-error/packages/gateway/test/openai-responses-recall-aware-stream.test.ts:
Line 174: const PUBLIC_GATEWAY_ERROR = "Gateway request failed";
Line 178: ["response.failed", "response.failed", "failed"],
Line 180: ["cancelled response.done", "response.done", "cancelled"],
Line 244: expect(out).not.toContain("response.failed");
Line 295: ["response.failed", "failed"],
Line 296: ["response.failed", "cancelled"],
Line 298: ["response.done", "cancelled"],
Line 300: "sanitizes a principal provider failure received as %s with status %s",
Line 373: expect(capturedLogs).toEqual(["openai-responses provider failure"]);
Line 376: .find((frame) => frame.startsWith("event: response.failed\n"));
Line 384: type: "response.failed",
Line 470: expect(capturedLogs).toEqual(["openai-responses provider failure"]);
Line 540: ...
<path>/home/byk/Code/opencode-lore-provider-error/packages/gateway/test/openai-responses-stream.test.ts</path>
<type>file</type>
<content>
1: /**
2: * Tests for the OpenAI Responses API SSE stream accumulator.
3: *
4: * Covers:
5: * - Text output accumulation from delta events
6: * - Function call accumulation from arguments delta events
7: * - Usage extraction from response.completed
8: * - Stop reason mapping from status
9: * - Mixed text + function_call output
10: */
11: import { log } from "@loreai/core";
12: import { afterEach, describe, test, expect, vi } from "vitest";
13: import {
14: accumulateResponsesSSEStream,
15: isSupportedResponsesOutputItemType,
16: isValidResponsesOutputItemStatus,
17: makeResponsesAccState,
18: responsesDoneItemMatchesAdded,
19: responsesTerminalItemMatches,
20: SUPPORTED_RESPONSES_OUTPUT_ITEM_TYPES,
21: streamResponsesPassthrough,
22: translateAnthropicStreamToResponses,
23: } from ...
<path>/home/byk/Code/opencode-lore-provider-error/packages/gateway/test/openai-responses-stream.test.ts</path>
<type>file</type>
<content>
575: model: "gpt-5.5",
576: status: "incomplete",
577: usage: { input_tokens: 40, output_tokens: 100 },
578: },
579: },
580: },
581: ]);
582:
583: const result = await accumulateResponsesSSEStream(response);
584: expect(result.stopReason).toBe("max_tokens");
585: expect(result.usage?.outputTokens).toBe(100);
586: });
587:
588: test.each([
589: ["max_output_tokens", "max_tokens"],
590: ["content_filter", "content_filter"],
591: ])(
592: "strict empty incomplete response maps %s without requiring output items",
593: async (reason, stopReason) => {
594: const response = buildSSEResponse([
595: {
596: event: "response.incomplete",
597: data: {
598: type: "response.incomplete",
599: response: ...
<path>/home/byk/Code/opencode-lore-provider-error/packages/gateway/src/stream/openai-responses.ts</path>
<type>file</type>
<content>
2100: maxFrames?: number;
2101: onSemanticContent?: () => void;
2102: /** Called only after the event has passed strict validation and mutation. */
2103: onValidatedEvent?: (event: string, data: string) => void | Promise<void>;
2104: /** Passthrough clients must receive a provider's valid failure terminal. */
2105: allowFailureTerminal?: boolean;
2106: /** Buffered callers that run successful-turn side effects must reject
2107: * incomplete terminals rather than treating a parsed body as completion. */
2108: requireCompletedTerminal?: boolean;
2109: /** Internal state injection used by validated true passthrough. */
2110: state?: ResponsesAccState;
2111: onReader?: (reader: ReadableStreamDefaultReader<Uint8Array>) => void;
2112: } = {},
2113: ): Promise<GatewayResponse> {
2114: const state = opts.state ...
Found 1 matches /home/byk/Code/opencode-lore-provider-error/packages/gateway/src/stream/openai-responses.ts: Line 2711: export function streamResponsesPassthrough(
<path>/home/byk/Code/opencode-lore-provider-error/packages/gateway/src/stream/openai-responses.ts</path>
<type>file</type>
<content>
2680: * payload (multi-line `data:` payloads are re-prefixed per line so nothing is
2681: * dropped or re-serialized — `reasoning_summary`, content_part annotations,
2682: * etc. survive intact because we forward the original `data` string).
2683: */
2684: export function formatResponsesEvent(event: string, data: string): string {
2685: const dataLines = data
2686: .split("\n")
2687: .map((line) => `data: ${line}`)
2688: .join("\n");
2689: return `event: ${event}\n${dataLines}\n\n`;
2690: }
2691:
2692: /**
2693: * Stream an OpenAI Responses API upstream straight through to a Responses-API
2694: * client, forwarding each SSE event as it arrives while accumulating a complete
2695: * `GatewayResponse` in parallel. ...
<path>/home/byk/Code/opencode-lore-provider-error/packages/gateway/src/stream/openai-responses.ts</path>
<type>file</type>
<content>
2889: );
2890: clearKeepalive();
2891: if (!completed) {
2892: completed = true;
2893: onComplete(
2894: accumulated,
2895: state.terminalEvent === "response.completed",
2896: );
2897: }
2898: safeClose();
2899: } catch (err) {
2900: clearKeepalive();
2901: if (downstreamCancelled) {
2902: cleanup();
2903: return;
2904: }
2905: if (externalAborted) {
2906: safeError(signal?.reason ?? err);
2907: return;
2908: }
2909: log.error(
2910: `openai-responses passthrough stream error${
2911: sessionID ? ` (session=${sessionID.slice(0, 16)})` : ""
2912: }:`,
2913: err,
2914: ...
<path>/home/byk/Code/opencode-lore-provider-error/packages/gateway/test/openai-responses-recall-aware-stream.test.ts</path>
<type>file</type>
<content>
1: /**
2: * Unit tests for `streamResponsesRecallAware` — the true-streaming,
3: * recall-aware OpenAI Responses (codex/ChatGPT) streamer.
4: *
5: * Regression for the "Provider response headers timed out after 10000ms" issue:
6: * the buffered `accumulateResponsesSSEStream` path withholds ALL client bytes
7: * until the entire (slow, reasoning-heavy) upstream completes, so opencode's
8: * 10s `ProviderHeaderTimeoutError` fired on ChatGPT sessions. This streamer
9: * forwards events live while transparently intercepting a `recall`
10: * function_call (emit marker, run follow-up, rebuild the terminal
11: * `response.completed`).
12: */
13: import { log } from "@loreai/core";
14: import { afterEach, describe, test, expect } from "vitest";
15: import { streamResponsesRecallAware } from "../src/pipeline";
16: import {
17: ...
<path>/home/byk/Code/opencode-lore-provider-error/packages/gateway/test/openai-responses-recall-aware-stream.test.ts</path>
<type>file</type>
<content>
270: );
271: let completeCalls = 0;
272: const client = streamResponsesRecallAware(upstream, {
273: onComplete: () => completeCalls++,
274: onRecall: async () => ({ anchorText: "", resultText: "" }),
275: runFollowUp: async () => {
276: throw new Error("should not be called");
277: },
278: });
279: if (!client.body) throw new Error("test response has no body");
280: const reader = client.body.getReader();
281: const decoder = new TextDecoder();
282: let seen = "";
283: while (!seen.includes("event: response.completed")) {
284: const { done, value } = await reader.read();
285: if (done) throw new Error("stream closed before terminal event");
286: if (value) seen += decoder.decode(value, { stream: true });
287: }
288: await reader.cancel();
289: ...
<path>/home/byk/Code/opencode-lore-provider-error/packages/gateway/test/openai-responses-recall-aware-stream.test.ts</path>
<type>file</type>
<content>
8700: ids: ["k:one", "k:two"],
8701: detailOffset: undefined,
8702: detailLimit: undefined,
8703: },
8704: },
8705: ])(
8706: "accepts nullable strict $mode recall arguments",
8707: async ({ args, expected }) => {
8708: let seen:
8709: | {
8710: query: string;
8711: scope?: string;
8712: id?: string;
8713: ids?: string[];
8714: detailOffset?: number;
8715: detailLimit?: number;
8716: }
8717: | undefined;
8718: const client = streamResponsesRecallAware(
8719: streamFrom([
8720: created("resp_nullable_args", "gpt-5.6-terra"),
8721: recallCall(0, args),
8722: completed("resp_nullable_args"),
8723: ]),
8724: {
8725: ...
<path>/home/byk/Code/opencode-lore-provider-error/packages/gateway/src/pipeline.ts</path>
<type>file</type>
<content>
10190: const terminalResponseLifecycleSnapshot = terminalStateSnapshot
10191: ? { ...responseLifecycleFor(state) }
10192: : undefined;
10193: const normalizationStateBeforeTerminal = terminalStateSnapshot
10194: ? codexNormalizationStates.get(state)
10195: : undefined;
10196: const terminalNormalizationSnapshot =
10197: normalizationStateBeforeTerminal
10198: ? cloneResponsesAccState(normalizationStateBeforeTerminal)
10199: : undefined;
10200: const terminalRecallSnapshot = terminalStateSnapshot
10201: ? ...
<path>/home/byk/Code/opencode-lore-provider-error/packages/gateway/src/pipeline.ts</path>
<type>file</type>
<content>
10870: if (held.transactional) {
10871: transactionalEvents.push(held.chunk);
10872: } else {
10873: queueTransactional(held.chunk);
10874: }
10875: }
10876: heldContinuationEvents.length = 0;
10877: deferredContinuationBytes = 0;
10878: };
10879: let continuationRecallBytes = 0;
10880: const promoteContinuationCandidate = (
10881: outputIndex: number,
10882: ): void => {
10883: const bytes =
10884: contUnresolvedToolBytes.get(outputIndex) ?? 0;
10885: ...
<path>/home/byk/Code/opencode-lore-provider-error/packages/gateway/src/pipeline.ts</path>
<type>file</type>
<content>
11250: ce === "response.created" ||
11251: ce === "response.in_progress"
11252: ) {
11253: continue;
11254: }
11255: if (ci !== undefined) {
11256: const shifted = encoder.encode(
11257: formatResponsesEvent(
11258: ce,
11259: JSON.stringify({
11260: ...cparsed,
11261: output_index: shiftedOutputIndex(
11262: ci,
11263: contIndex,
11264: ),
11265: }),
11266: ...
<path>/home/byk/Code/opencode-lore-provider-error/packages/gateway/src/pipeline.ts</path>
<type>file</type>
<content>
11620: }
11621: }
11622: if (
11623: !(await safeEnqueue(
11624: encoder.encode(buildTerminal(visibleResp)),
11625: () => {
11626: terminalDelivered = true;
11627: const successful =
11628: state.terminalEvent === "response.completed";
11629: let transactionSettled = false;
11630: const transaction = {
11631: commit: () => {
11632: if (transactionSettled) return;
11633: try {
11634: for (const commit of pendingCommits) commit();
11635: transactionSettled = true;
11636: pendingCommits.length = 0;
11637: ...
<path>/home/byk/Code/opencode-lore-provider-error/packages/gateway/src/pipeline.ts</path>
<type>file</type>
<content>
11950: reason: PRINCIPAL_TRANSPORT_INCOMPLETE_REASON,
11951: },
11952: }
11953: : {}),
11954: error: {
11955: type: "server_error",
11956: code: "server_error",
11957: message: recallFailure
11958: ? "Lore could not continue the response after recall"
11959: : "Gateway request failed",
11960: },
11961: },
11962: }),
11963: ),
11964: ),
11965: () => {
11966: if (!providerFailureSeen && !continuationProviderFailureSeen) {
11967: finish(failedResponse, false);
11968: }
11969: },
11970: ...
M packages/gateway/src/pipeline.ts
M packages/gateway/src/stream/openai-responses.ts
M packages/gateway/test/openai-responses-recall-aware-stream.test.ts
M packages/gateway/test/openai-responses-stream.test.ts
Commit ID: 0dd569b520bad37adbaea230f32100c7f83f463c
Change ID: lpmvqrurxwlmrmwnyllmxlvkmplvwnlz
Bookmarks: fix/responses-provider-failures fix/responses-provider-failures@git
Author : Burak Yigit Kaya <ben@byk.im> (2026-09-16 11:49:37)
Committer: Burak Yigit Kaya <ben@byk.im> (2026-09-16 12:50:50)
fix(responses): unify provider failure handling
packages/gateway/src/pipeline.ts | 38 +++--
packages/gateway/src/stream/openai-responses.ts | 98 ++++++++++---
...est/openai-responses-recall-aware-stream.test.ts | 93 ++++++++++++
...ges/gateway/test/openai-responses-stream.test.ts | 162 +++++++++++++++++++++-
4 files changed, 364 insertions(+), 27 deletions(-)
No files found
Success. Updated the following files: M ../opencode-lore-provider-error/packages/gateway/test/openai-responses-stream.test.ts M ../opencode-lore-provider-error/packages/gateway/test/openai-responses-recall-aware-stream.test.ts
RUN v4.1.8 /home/byk/Code/opencode-lore-provider-error
stderr | packages/gateway/test/openai-responses-stream.test.ts > accumulateResponsesSSEStream > contains a throwing failure log sink in the plain passthrough settlement path
[lore] openai-responses provider failure
❯ Module.error packages/core/src/log.ts:499:38
❯ accumulateResponsesSSEStream packages/gateway/src/stream/openai-responses.ts:2223:13
❯ pump packages/gateway/src/stream/openai-responses.ts:2844:31
stderr | packages/gateway/test/openai-responses-stream.test.ts > accumulateResponsesSSEStream > contains a throwing failure log sink in the plain passthrough settlement path
[lore] openai-responses passthrough stream error: Error: private-plain-logger-failure
at Object.error (/home/byk/Code/opencode-lore-provider-error/packages/gateway/test/openai-responses-stream.test.ts:701:17)
at Module.error (/home/byk/Code/opencode-lore-provider-error/packages/core/src/log.ts:500:9)
at accumulateResponsesSSEStream ...
Success. Updated the following files: M ../opencode-lore-provider-error/packages/gateway/src/stream/openai-responses.ts M ../opencode-lore-provider-error/packages/gateway/src/pipeline.ts
RUN v4.1.8 /home/byk/Code/opencode-lore-provider-error stderr | packages/gateway/test/openai-responses-recall-aware-stream.test.ts > streamResponsesRecallAware > contains a throwing failure log sink in the recall-aware continuation settlement path [lore] openai-responses provider failure ❯ Module.error packages/core/src/log.ts:499:38 ❯ reportResponsesProviderFailure packages/gateway/src/stream/openai-responses.ts:605:9 ❯ runPrincipalAttempt packages/gateway/src/pipeline.ts:10994:29 ❯ packages/gateway/src/pipeline.ts:11710:15 stderr | packages/gateway/test/openai-responses-recall-aware-stream.test.ts > streamResponsesRecallAware > contains a throwing failure log sink in the recall-aware continuation settlement path [lore] recall follow-up stream failed category=follow_up_failed ❯ Module.error packages/core/src/log.ts:499:38 ❯ runPrincipalAttempt packages/gateway/src/pipeline.ts:11580:25 ❯ packages/gateway/src/pipeline.ts:11710:15 stderr | ...
Success. Updated the following files: M ../opencode-lore-provider-error/packages/gateway/test/openai-responses-recall-aware-stream.test.ts
RUN v4.1.8 /home/byk/Code/opencode-lore-provider-error
Test Files 2 passed (2)
Tests 3 passed | 442 skipped (445)
Start at 20:41:00
Duration 15.68s (transform 15.97s, setup 2.31s, import 27.30s, tests 506ms, environment 0ms)
Success. Updated the following files: M ../opencode-lore-provider-error/packages/gateway/src/stream/openai-responses.ts
RUN v4.1.8 /home/byk/Code/opencode-lore-provider-error
stderr | packages/gateway/test/openai-responses-stream.test.ts > accumulateResponsesSSEStream > contains a throwing failure log sink in the plain passthrough settlement path
[lore] openai-responses provider failure
❯ Module.error packages/core/src/log.ts:499:38
❯ reportResponsesProviderFailure packages/gateway/src/stream/openai-responses.ts:604:7
❯ accumulateResponsesSSEStream packages/gateway/src/stream/openai-responses.ts:2228:9
❯ pump packages/gateway/src/stream/openai-responses.ts:2849:31
stderr | packages/gateway/test/openai-responses-stream.test.ts > accumulateResponsesSSEStream > contains a throwing failure log sink in the plain passthrough settlement path
[lore] openai-responses passthrough stream error: Error: private-plain-logger-failure
at Object.error (/home/byk/Code/opencode-lore-provider-error/packages/gateway/test/openai-responses-stream.test.ts:701:17)
at Module.error ...
Success. Updated the following files: M ../opencode-lore-provider-error/packages/gateway/src/stream/openai-responses.ts
RUN v4.1.8 /home/byk/Code/opencode-lore-provider-error
Test Files 2 passed (2)
Tests 3 passed | 442 skipped (445)
Start at 20:42:57
Duration 13.39s (transform 13.58s, setup 1.68s, import 23.89s, tests 309ms, environment 0ms)
Found 100 matches (more matches available)
/home/byk/Code/opencode-lore-provider-error/packages/gateway/test/codex-usage-metadata.test.ts:
Line 6: streamResponsesPassthrough,
Line 144: const response = streamResponsesPassthrough(
/home/byk/Code/opencode-lore-provider-error/packages/gateway/test/openai-responses-stream.test.ts:
Line 21: streamResponsesPassthrough,
Line 635: const output = await streamResponsesPassthrough(
Line 711: const output = await streamResponsesPassthrough(
Line 781: const output = await streamResponsesPassthrough(
Line 4044: // streamResponsesPassthrough — true streaming (Responses → Responses client)
Line 4092: describe("streamResponsesPassthrough", () => {
Line 4094: const downstream = streamResponsesPassthrough(
Line 4134: const downstream = streamResponsesPassthrough(
Line 4182: const downstream = streamResponsesPassthrough(
Line 4210: const downstream = ...
packages/gateway/test/codex-usage-metadata.test.ts packages/gateway/test/openai-responses-stream.test.ts packages/gateway/test/openai-responses-recall-aware-stream.test.ts
<path>/home/byk/Code/opencode-lore-provider-error/packages/gateway/package.json</path>
<type>file</type>
<content>
1: {
2: "name": "@loreai/gateway",
3: "version": "0.40.0",
4: "type": "module",
5: "license": "FSL-1.1-Apache-2.0",
6: "description": "Lore as a transparent LLM proxy — context management for any AI coding client",
7: "main": "./dist/index.cjs",
8: "types": "./dist/index.d.cts",
9: "exports": {
10: ".": {
11: "types": "./dist/index.d.cts",
12: "bun": "./dist/index.bun.js",
13: "require": "./dist/index.cjs",
14: "default": "./dist/index.cjs"
15: }
16: },
17: "bin": {
18: "lore": "./dist/bin.cjs",
19: "lore-gateway": "./dist/bin.cjs"
20: },
21: "scripts": {
22: "typecheck": "tsc --noEmit",
23: "build": "tsx script/build.ts",
24: "bundle": "tsx script/bundle.ts",
25: "build:binary": "tsx script/build.ts --binary",
26: "build:binary:sea": "tsx script/build-binary-sea.ts",
27: "start": "tsx ...
> lore-monorepo@ format /home/byk/Code/opencode-lore-provider-error > oxfmt Finished in 1223ms on 874 files using 4 threads.
Working copy changes: M packages/gateway/src/pipeline.ts M packages/gateway/src/stream/openai-responses.ts M packages/gateway/test/openai-responses-recall-aware-stream.test.ts M packages/gateway/test/openai-responses-stream.test.ts Working copy (@) : qzwttkwl 46fe40e4 fix(responses): isolate failure telemetry Parent commit (@-): lpmvqrur 0dd569b5 fix/responses-provider-failures | fix(responses): unify provider failure handling Warning: These bookmarks have conflicts: fix/responses-private-references Hint: Use `jj bookmark list` to see details. Use `jj bookmark set <name> -r <rev>` to resolve. M packages/gateway/src/pipeline.ts M packages/gateway/src/stream/openai-responses.ts M packages/gateway/test/openai-responses-recall-aware-stream.test.ts M packages/gateway/test/openai-responses-stream.test.ts packages/gateway/src/pipeline.ts | 6 +- packages/gateway/src/stream/openai-responses.ts | 11 +- ...est/openai-responses-recall-aware-stream.test.ts | 194 ...
diff --git a/packages/gateway/src/pipeline.ts b/packages/gateway/src/pipeline.ts
index a03a58d8da..b6c101d538 100644
--- a/packages/gateway/src/pipeline.ts
+++ b/packages/gateway/src/pipeline.ts
@@ -217,7 +217,7 @@
restoreResponsesAccState,
normalizeCodexResponsesEvent,
projectResponsesInProgressEvent,
- RESPONSES_PROVIDER_FAILURE_LOG,
+ reportResponsesProviderFailure,
sanitizeResponsesProviderFailureTerminal,
validateResponsesProviderFailureTerminal,
validateResponsesSourceSequence,
@@ -10312,7 +10312,7 @@
? providerFailureTerminal.parsed
: parsed,
);
- log.error(RESPONSES_PROVIDER_FAILURE_LOG);
+ reportResponsesProviderFailure();
rollbackPendingPrincipalTerminal = undefined;
providerFailureSeen = true;
const finalResponse = finalizeUnsuccessfulResponsesAcc(state);
@@ -10991,7 +10991,7 @@
? ...
RUN v4.1.8 /home/byk/Code/opencode-lore-provider-error
Test Files 2 passed (2)
Tests 445 passed (445)
Start at 20:44:59
Duration 20.55s (transform 16.38s, setup 2.76s, import 27.62s, tests 7.94s, environment 0ms)
RUN v4.1.8 /home/byk/Code/opencode-lore-provider-error
Test Files 6 passed (6)
Tests 529 passed (529)
Start at 20:45:31
Duration 43.20s (transform 34.24s, setup 5.35s, import 89.41s, tests 24.79s, environment 1ms)
> @loreai/gateway@0.40.0 typecheck /home/byk/Code/opencode-lore-provider-error/packages/gateway > tsc --noEmit
> lore-monorepo@ format:check /home/byk/Code/opencode-lore-provider-error > oxfmt --check Checking formatting... All matched files use the correct format. Finished in 1647ms on 874 files using 4 threads.
Success. Updated the following files: M ../opencode-lore-provider-error/packages/gateway/test/openai-responses-stream.test.ts M ../opencode-lore-provider-error/packages/gateway/test/openai-responses-recall-aware-stream.test.ts
RUN v4.1.8 /home/byk/Code/opencode-lore-provider-error
Test Files 2 passed (2)
Tests 3 passed | 442 skipped (445)
Start at 20:48:24
Duration 13.07s (transform 13.28s, setup 3.07s, import 21.80s, tests 209ms, environment 0ms)
RUN v4.1.8 /home/byk/Code/opencode-lore-provider-error
Test Files 2 passed (2)
Tests 445 passed (445)
Start at 20:49:05
Duration 21.22s (transform 19.69s, setup 4.05s, import 31.22s, tests 4.21s, environment 0ms)
RUN v4.1.8 /home/byk/Code/opencode-lore-provider-error
Test Files 6 passed (6)
Tests 529 passed (529)
Start at 20:49:38
Duration 36.34s (transform 23.37s, setup 3.95s, import 74.51s, tests 22.53s, environment 1ms)
> @loreai/gateway@0.40.0 typecheck /home/byk/Code/opencode-lore-provider-error/packages/gateway > tsc --noEmit
> lore-monorepo@ format:check /home/byk/Code/opencode-lore-provider-error > oxfmt --check Checking formatting... All matched files use the correct format. Finished in 1119ms on 874 files using 4 threads.
Found 7 matches
/home/byk/Code/opencode-lore-provider-error/packages/gateway/src/stream/openai-responses.ts:
Line 599: export const RESPONSES_PROVIDER_FAILURE_LOG =
Line 603: export function reportResponsesProviderFailure(): void {
Line 605: log.error(RESPONSES_PROVIDER_FAILURE_LOG);
Line 2232: reportResponsesProviderFailure();
/home/byk/Code/opencode-lore-provider-error/packages/gateway/src/pipeline.ts:
Line 220: reportResponsesProviderFailure,
Line 10315: reportResponsesProviderFailure();
Line 10994: reportResponsesProviderFailure();
Working copy changes: M packages/gateway/src/pipeline.ts M packages/gateway/src/stream/openai-responses.ts M packages/gateway/test/openai-responses-recall-aware-stream.test.ts M packages/gateway/test/openai-responses-stream.test.ts Working copy (@) : qzwttkwl 90332d0b fix(responses): isolate failure telemetry Parent commit (@-): lpmvqrur 0dd569b5 fix/responses-provider-failures | fix(responses): unify provider failure handling Warning: These bookmarks have conflicts: fix/responses-private-references Hint: Use `jj bookmark list` to see details. Use `jj bookmark set <name> -r <rev>` to resolve. qzwttkwltwzr 90332d0bf6e3 fix(responses): isolate failure telemetry lpmvqrurxwlm 0dd569b520ba fix(responses): unify provider failure handling M packages/gateway/src/pipeline.ts M packages/gateway/src/stream/openai-responses.ts M packages/gateway/test/openai-responses-recall-aware-stream.test.ts M ...
Implemented in additive child qzwttkwl over lpmvqrur/0dd569b5.
packages/gateway/src/pipeline.tspackages/gateway/src/stream/openai-responses.tspackages/gateway/test/openai-responses-recall-aware-stream.test.tspackages/gateway/test/openai-responses-stream.test.tsResidual risk: unrelated logging sites remain unchanged; containment is intentionally limited to accepted provider-failure reporting. No commit, push, rebase, bookmark, server, network, or production database access occurred. The required repo-setup skill was unavailable, so I read AGENTS.md, quality/REVIEW.md, and package scripts directly.