fix(tools): stop forcing empty instructions on Responses requests - #1646
fix(tools): stop forcing empty instructions on Responses requests#1646Agnik47 wants to merge 1 commit into
Conversation
The Responses middleware always set `instructions` on the forwarded
request, even when the caller never passed one and there were no
memories to inject. `replaceMemoryContext("", "")` returns `""`, so
those requests went out with `instructions: ""`.
Sending the field at all tells the Responses API to drop the
instructions carried over from a `previous_response_id` turn, so an
empty string silently wipes the caller's system prompt mid-conversation
instead of leaving it in place.
The no-input early return in the same function already gets this right —
it spreads `instructions` only when the caller supplied a string. Apply
the same rule to the main path, while still injecting when there are
memories to add.
Adds three regression tests to the existing OpenAI middleware unit
suite, which CI already runs on changes to packages/tools.
🔎 TracePull from @yesprasad reviewed this PRReview outcome
Executive summaryThis PR introduces an Verified change flowflowchart LR
A[Caller supplies params.instructions] --> B[instructionsOverride]
C[enhancedInstructions is empty] --> B
B --> D[Empty instructions override]
D --> E[Outbound Responses API request]
E --> F[Instruction behavior changes]
Finding — empty instructions can override caller instructionsChanged code: const instructionsOverride =
enhancedInstructions || typeof params.instructions === 'string'
? { instructions: enhancedInstructions }
: {}Impacted code pathFailure conditionenhancedInstructions === ''
typeof params.instructions === 'string'Because This conflicts with the intended behavior of leaving caller-provided instructions untouched when no enhanced replacement is available. It can replace a meaningful caller instruction with an empty value. Suggested repairconst hasEnhancedInstructions =
typeof enhancedInstructions === 'string' &&
enhancedInstructions.trim().length > 0
const instructionsOverride = hasEnhancedInstructions
? { instructions: enhancedInstructions }
: {}Required regression coverageAdd a test where Review evidence
TracePull is the merge Intelligence Engine for your Pull Requests to help you merge and deploy with confidence. |
Problem
prepareResponsesWithMemorysetsinstructionson every forwarded request:When the caller passed no
instructionsand there are no memories to inject,replaceMemoryContext("", "")returns""— so the request goes out withinstructions: ""where the caller sent nothing.Per the Responses API contract, supplying
instructionsat all discards the instructions carried over from aprevious_response_idturn. An empty string therefore doesn't just add noise: it silently wipes the caller's system prompt partway through a multi-turn chain.The no-input early return in the same function already handles this correctly:
so the two paths in one function disagree about the same field.
Fix
Apply the early return's rule to the main path — spread
instructionsonly when there is something to send or the caller supplied a string:Behaviour by case:
instructions""(wipes carried-over prompt)null""nullpreserved via...paramsOnly the first row changes. The
catchbranch is covered by the same guard, so a failed memory search no longer blanks the field either.Tests
Three cases added to
test/openai-middleware.unit.test.ts, the suite CI already runs whenpackages/toolschanges:previous_response_iduntouched<supermemory>block strippedVerified the first test fails on
mainand passes with the fix; the other two pass either way and are there to catch over-correction. Full file: 4/4 passing.Scope
One file changed plus tests. No API surface change, no new dependencies, no behaviour change for callers that already pass
instructions.