From 458271b78d34ea9b05bb67fc168b6f072fa549d1 Mon Sep 17 00:00:00 2001 From: Zack Jackson <25274700+ScriptedAlchemy@users.noreply.github.com> Date: Sun, 8 Nov 2026 13:01:26 -0800 Subject: [PATCH 1/2] fix(memory): skip extraction when provider allowance is exhausted --- .../src/textGeneration/TextGeneration.test.ts | 40 +++++++++++++++++++ .../src/textGeneration/TextGeneration.ts | 12 ++++++ 2 files changed, 52 insertions(+) diff --git a/apps/server/src/textGeneration/TextGeneration.test.ts b/apps/server/src/textGeneration/TextGeneration.test.ts index 62ad4769ef12c..3f3537028fc94 100644 --- a/apps/server/src/textGeneration/TextGeneration.test.ts +++ b/apps/server/src/textGeneration/TextGeneration.test.ts @@ -187,3 +187,43 @@ it.effect( expect(test.getInstance.mock.calls).toEqual([[selected]]); }), ); + +it.effect.each([undefined, "2999-01-01T00:00:00.000Z", "1970-01-01T00:00:00.000Z"])( + "avoids automatic memory calls until an exhausted allowance resets (%s)", + (reset) => + Effect.gen(function* () { + const generateKnowledgeCandidates = vi.fn(() => Effect.succeed({ candidates: [] })); + const test = make( + { + ...fromRunner("Fixture", () => Effect.die("Unexpected generation operation")), + supportedOperations: ["generateKnowledgeCandidates"], + generateKnowledgeCandidates, + }, + { + ...providerSnapshot, + usageLimits: { + checkedAt: "1970-01-01T00:00:00.000Z", + windows: [ + { + id: "session", + kind: "session", + label: "Session", + usedPercent: 100, + resetsAt: reset, + }, + ], + }, + }, + ); + const service = yield* test.service; + const result = yield* service + .generateKnowledgeCandidates({ ...input, runOutcome: "completed" }) + .pipe(Effect.result); + if (reset === "1970-01-01T00:00:00.000Z") { + expect(generateKnowledgeCandidates).toHaveBeenCalledOnce(); + } else { + expect(result._tag).toBe("Failure"); + expect(generateKnowledgeCandidates).not.toHaveBeenCalled(); + } + }), +); diff --git a/apps/server/src/textGeneration/TextGeneration.ts b/apps/server/src/textGeneration/TextGeneration.ts index c8e4e9fcc4c88..f15cdb229b092 100644 --- a/apps/server/src/textGeneration/TextGeneration.ts +++ b/apps/server/src/textGeneration/TextGeneration.ts @@ -53,6 +53,7 @@ const resolveInstance = Effect.fn("TextGeneration.resolveInstance")(function* ( registry: ProviderInstanceRegistry.ProviderInstanceRegistry["Service"], operation: TextGenerationOperation, instanceId: ProviderInstanceId, + model?: string, ): Effect.fn.Return { const instance = yield* registry.getInstance(instanceId); if (!instance) { @@ -67,6 +68,16 @@ const resolveInstance = Effect.fn("TextGeneration.resolveInstance")(function* ( detail: `Provider '${instanceId}' does not support this text generation operation. Choose a model from a provider that supports it.`, }); } + if (operation === "generateKnowledgeCandidates") { + const snapshot = yield* instance.snapshot.getSnapshot; + if (exhaustedUsageWindow(snapshot, DateTime.toEpochMillis(yield* DateTime.now), model)) { + return yield* new TextGenerationError({ + operation, + detail: + "Automatic memory skipped because the selected provider's usage allowance is exhausted.", + }); + } + } if (operation === "generateModelEvaluation") { const snapshot = yield* instance.snapshot.getSnapshot; if ( @@ -185,6 +196,7 @@ export const make = Effect.gen(function* () { registry, "generateKnowledgeCandidates", input.modelSelection.instanceId, + input.modelSelection.model, ).pipe( Effect.flatMap((textGeneration) => textGeneration.generateKnowledgeCandidates(input)), ); From 8eb20eafbcaff021d8ec45b8ca8b19c0e0592fcb Mon Sep 17 00:00:00 2001 From: Zack Jackson <25274700+ScriptedAlchemy@users.noreply.github.com> Date: Sun, 8 Nov 2026 13:08:17 -0800 Subject: [PATCH 2/2] fix(memory): omit checkout instructions from Codex fact extraction --- .../textGeneration/CodexTextGeneration.test.ts | 17 +++++++++++++++++ .../src/textGeneration/CodexTextGeneration.ts | 4 ++++ 2 files changed, 21 insertions(+) diff --git a/apps/server/src/textGeneration/CodexTextGeneration.test.ts b/apps/server/src/textGeneration/CodexTextGeneration.test.ts index b4e77656511e7..7a32cd0f3fdaa 100644 --- a/apps/server/src/textGeneration/CodexTextGeneration.test.ts +++ b/apps/server/src/textGeneration/CodexTextGeneration.test.ts @@ -372,6 +372,23 @@ it.layer(layerCodexTextGenerationTest)("CodexTextGeneration", (it) => { ), ); + it.effect("keeps checkout instructions out of automatic memory extraction", () => + withFakeCodexEnv( + { + output: JSON.stringify({ candidates: [] }), + requireArg: "--config project_doc_max_bytes=0", + requiredCwd: process.cwd(), + }, + (textGeneration) => + textGeneration.generateKnowledgeCandidates({ + cwd: process.cwd(), + modelSelection: createModelSelection(ProviderInstanceId.make("codex"), "gpt-6-luna"), + runOutcome: "completed", + messages: [{ ref: "M1", role: "user", text: "Use the shared test runner." }], + }), + ), + ); + it.effect("preserves custom PR instructions while allowing checkout inspection", () => withFakeCodexEnv( { diff --git a/apps/server/src/textGeneration/CodexTextGeneration.ts b/apps/server/src/textGeneration/CodexTextGeneration.ts index 8b7146f36deb4..7fc418d4d2f2e 100644 --- a/apps/server/src/textGeneration/CodexTextGeneration.ts +++ b/apps/server/src/textGeneration/CodexTextGeneration.ts @@ -304,6 +304,10 @@ export const makeCodexTextGeneration = Effect.fn("makeCodexTextGeneration")(func ...execLaunchArgs, // A user's MCP server could act on the text-generation prompt. ...CODEX_NO_PLUGIN_ARGS, + // Memory candidates cite the supplied exchange; checkout instructions add unrelated input. + ...(operation === "generateKnowledgeCandidates" + ? ["--config", "project_doc_max_bytes=0"] + : []), ...(mcpServersOff ? ["--config", mcpServersOff] : []), "--ephemeral", "--skip-git-repo-check",