Skip to content

fix(query): honour clientContext when codeSystemPrompt=false#526

Open
ilie-neacsu wants to merge 1 commit into
rynfar:mainfrom
ilie-neacsu:fix/codeSystemPrompt-discards-client-system-prompt
Open

fix(query): honour clientContext when codeSystemPrompt=false#526
ilie-neacsu wants to merge 1 commit into
rynfar:mainfrom
ilie-neacsu:fix/codeSystemPrompt-discards-client-system-prompt

Conversation

@ilie-neacsu
Copy link
Copy Markdown

Problem

When codeSystemPrompt is explicitly set to false via
PATCH /settings/api/features/:adapter, the function resolveSystemPrompt()
returns { systemPrompt: "" } unconditionally at line 208, discarding the
client's own system prompt before it is used.

Any non-coding API client (Open WebUI, curl, any OpenAI-compatible tool) that
disables the Claude Code preset via the settings API gets an empty system prompt —
the model ignores their instructions and falls back to the Claude Code persona
from Anthropic's prompt cache.

Root Cause

The defensive empty-string return added in #489 fires before clientContext
is evaluated:

// Before — clientContext is computed but never used in this branch
if (codeSystemPrompt === false) return { systemPrompt: "" }

Fix

// After — passes client system prompt through when present
if (codeSystemPrompt === false) return { systemPrompt: clientContext ?? "" }

The ?? "" preserves the original defensive behaviour: when no system prompt
is provided, an explicit empty string prevents the SDK from reintroducing the
claude_code preset downstream.

Test Results

All 55 existing assertions in query.test.ts pass with no modifications:

55 pass / 0 fail / 86 expect() calls

The existing test forces systemPrompt='' when codeSystemPrompt false and no systemContext continues to pass because clientContext ?? "" evaluates to
"" when clientContext is undefined.

Reproduction

  1. PATCH /settings/api/features/opencode with {"codeSystemPrompt": false}
  2. Send any /v1/chat/completions request with a system message
  3. Observe: prompt_tokens: 3 (system prompt not counted), response reflects
    Claude Code persona instead of your system prompt

resolveSystemPrompt() was returning { systemPrompt: '' } unconditionally
when codeSystemPrompt === false, discarding the client's system prompt
before it could be used.

Fix: return { systemPrompt: clientContext ?? '' } so the client system
prompt passes through when present, while still forcing an empty string
(not undefined) when absent — preserving the defensive preset-suppression
behaviour introduced in rynfar#489.

Fixes: non-coding API clients (Open WebUI, curl, etc.) receiving the
Claude Code persona despite codeSystemPrompt=false in sdk-features.json.

All 55 query.test.ts assertions pass.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant