Skip to content

fix(pi): accept an array systemPrompt and keep the documentation-paragraph relocation - #213

Open
iceteaSA wants to merge 2 commits into
cortexkit:mainfrom
iceteaSA:rv/patch-2
Open

fix(pi): accept an array systemPrompt and keep the documentation-paragraph relocation#213
iceteaSA wants to merge 2 commits into
cortexkit:mainfrom
iceteaSA:rv/patch-2

Conversation

@iceteaSA

@iceteaSA iceteaSA commented Sep 11, 2026

Copy link
Copy Markdown
Contributor

Summary

Pi-compatible hosts (oh-my-pi) pass context.systemPrompt as an array of segments; buildAnthropicRequest only handled a string, so the prompt was dropped. This accepts the array form.

The array is joined with \n\n and routed through the same path the string branch uses (splitPiSystemPromptprependCachedPromptBlock), so Pi's documentation paragraph still moves out of top-level system[] into the first user message's cached block. An earlier shape of this change pushed each segment straight into system[], which would have reintroduced the OAuth billing rejection that relocation exists to avoid — the new test pins byte-equivalence between the array and string paths, and it fails if the array takes a separate branch.

Credit: original patch by randomvariable (CortexKit Discord, 2026-09-03), who could not open the PR themselves. Reviewed, reworked to share the relocation path, and re-authored here with Co-authored-by.

Changes

  • packages/pi/src/convert.tscontext.systemPrompt: string | readonly string[]; array segments are trimmed, empties dropped (isNonEmptyText, shared with the string branch), joined, and handed to the existing relocation path. The SDK type declares string; the array form is a host divergence, noted at the branch.
  • packages/pi/src/tests/convert.test.ts — array happy paths, empty/whitespace segments, empty array, and the relocation contract: arrayBody.system and arrayBody.messages equal the string path's output; the docs paragraph is not in system[].

Verification

  • packages/pi: 98 pass / 0 fail · root typecheck 0 · format/biome clean.
  • Red-first: the relocation test failed on the per-segment shape (docs paragraph at system[4]); reverting to that shape reddens it again.

Base: upstream/main 360b68e (v1.22.0).


View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need. Autofix is disabled.


Summary by cubic

Fixes buildAnthropicRequest dropping Pi-compatible hosts' array systemPrompt values, which previously only handled strings. Array segments are now joined and routed through the same docs-paragraph relocation path as string prompts, keeping Pi's documentation paragraph out of top-level system[] to avoid OAuth billing rejection.

  • Normalizes array segments by trimming and dropping empty/whitespace-only entries before joining with \n\n.
  • Adds tests covering array happy paths, empty/whitespace segments, empty arrays, and byte-equivalence between array and string paths.

Written for commit 7da8919. Summary will update on new commits.

Review in cubic

iceteaSA and others added 2 commits September 11, 2026 07:18
Pi's context.systemPrompt permits an array of segments, but
buildAnthropicRequest only handled a single string. Each non-empty
segment now becomes its own sanitized text block in top-level system[],
with empty and whitespace-only entries skipped.

Co-authored-by: randomvariable <redacted@localhost>
Normalize host-provided prompt segments into the same paragraph-aware path as string prompts so Pi documentation stays out of top-level system[]. Update array expectations for the shared relocation and add byte-equivalence coverage.

Co-authored-by: randomvariable <redacted@localhost>

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No issues found across 2 files

Confidence score: 5/5

  • Automated review surfaced no issues in the provided summaries.
  • No files require special attention.
Architecture diagram
sequenceDiagram
    participant Host as Pi Host (oh-my-pi)
    participant Convert as buildAnthropicRequest
    participant Split as splitPiSystemPrompt
    participant Cache as Cache Control Logic
    participant API as Anthropic API

    Note over Host,API: System Prompt Normalization Flow

    Host->>Convert: context.systemPrompt (string | readonly string[])

    alt Array systemPrompt
        Convert->>Convert: Filter non-empty segments (isNonEmptyText)
        Convert->>Convert: Trim each segment
        Convert->>Convert: Join with '\n\n'
    else String systemPrompt
        Convert->>Convert: Pass through as-is
    end

    Convert->>Split: normalizedSystemPrompt
    Split-->>Convert: { systemText, cachedBlock }

    alt systemText exists
        Convert->>Convert: Push text block to system[]
    end

    alt cachedBlock exists
        Convert->>Convert: Prepend cached prompt block to first user message
        Convert->>Cache: Add cache_control: { type: 'ephemeral' }
    end

    Convert->>API: Request body with system[] + messages[]
    
    Note over API: Documentation paragraph NOT in system[]<br/>(avoids OAuth billing rejection)

    alt Happy Path (valid request)
        API-->>Convert: 200 OK
    else Documentation paragraph in system[]
        API-->>Convert: 400/401 (billing rejection)
    end
Loading

Re-trigger cubic

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