Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions apps/server/src/textGeneration/CodexTextGeneration.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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(
{
Expand Down
4 changes: 4 additions & 0 deletions apps/server/src/textGeneration/CodexTextGeneration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
40 changes: 40 additions & 0 deletions apps/server/src/textGeneration/TextGeneration.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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();
}
}),
);
12 changes: 12 additions & 0 deletions apps/server/src/textGeneration/TextGeneration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ const resolveInstance = Effect.fn("TextGeneration.resolveInstance")(function* (
registry: ProviderInstanceRegistry.ProviderInstanceRegistry["Service"],
operation: TextGenerationOperation,
instanceId: ProviderInstanceId,
model?: string,
): Effect.fn.Return<ProviderInstance["textGeneration"], TextGenerationError> {
const instance = yield* registry.getInstance(instanceId);
if (!instance) {
Expand All @@ -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 (
Expand Down Expand Up @@ -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)),
);
Expand Down
Loading