Skip to content

Add OpenAI prompt cache breakpoints - #6833

Open
brandon-julio-t wants to merge 1 commit into
Effect-TS:mainfrom
brandon-julio-t:codex/openai-prompt-cache-breakpoint
Open

Add OpenAI prompt cache breakpoints#6833
brandon-julio-t wants to merge 1 commit into
Effect-TS:mainfrom
brandon-julio-t:codex/openai-prompt-cache-breakpoint

Conversation

@brandon-julio-t

Copy link
Copy Markdown

RFC status

Implementation complete, locally validated, and independently reviewed with no findings. This is a ready-for-review PR. RFC feedback is specifically requested on the provider-option/public API shape before merge.

Closes #6831.

Summary

Adds content-level prompt_cache_breakpoint support to the handwritten OpenAI Responses API path:

options: {
  openai: {
    promptCacheBreakpoint: { mode: "explicit" }
  }
}

The marker is represented in OpenAiSchema and emitted only on the OpenAI-documented Responses content blocks: input_text, input_image, and input_file.

This PR intentionally does not add or duplicate request-level safety_identifier, prompt_cache_key, prompt_cache_retention, or prompt_cache_options work from #6830. Explicit breakpoints work with OpenAI's default implicit request policy.

API design and precedent

Anthropic and OpenRouter already expose cache controls through provider options at both message and part level. Their converters prefer a part-level marker and use a message-level marker as a fallback on translated content. OpenRouter also places a system-message marker on the text block produced from the system string.

This implementation follows that established Effect shape:

  • SystemMessageOptions.openai.promptCacheBreakpoint is placed on the system/developer input_text block.
  • TextPartOptions and FilePartOptions support exact block placement. A file part maps to input_image or input_file according to its media type.
  • UserMessageOptions is an ergonomic fallback placed on the last content part.
  • Part-level placement takes precedence over message-level fallback. The marker currently has a single legal value, { mode: "explicit" }; the precedence test verifies that the message fallback is not read when the last part defines its own marker.
  • Assistant and tool content are deliberately excluded because OpenAI documents the Responses placements only on input_text, input_image, and input_file.

Adding genuinely message-specific OpenAI options exposed a pre-existing MessageConstructorParams typo: it selected Part["options"] rather than M["options"]. The one-line correction aligns the helper with makeMessage's existing role-specific signature and avoids falsely adding ignored breakpoint fields to reasoning/tool parts.

Official contract:

Tradeoffs

  • Message fallback is convenient and consistent with existing provider integrations, but exact placement remains clearest at part level.
  • Exporting OpenAiSchema.PromptCacheBreakpoint gives provider augmentations and handwritten transport schemas one source of truth, at the cost of one small public schema/type addition.
  • The provider does not gate the option by model name. Older models may reject it, matching normal provider-specific option behavior and avoiding a stale local capability table.
  • Request policy remains untouched: without Expose OpenAI Responses safety and prompt-cache request options through OpenAiLanguageModel.Config #6830-style request options, OpenAI keeps its documented default implicit breakpoint in addition to explicit markers.

Focused maintainer questions

  1. Is promptCacheBreakpoint under options.openai the preferred public name and nesting?
  2. Should user-message fallback remain, or should OpenAI require exact part-level placement except for system messages?
  3. Is the narrow MessageConstructorParams<M>["options"] correction acceptable here, or would maintainers prefer it split into a prerequisite PR?

Validation

  • pnpm test --run packages/ai/openai/test/OpenAiLanguageModel.test.ts packages/ai/openai/test/OpenAiSchema.test.ts — 64 tests passed
  • pnpm check — passed
  • pnpm lint — passed
  • pnpm docgen in packages/ai/openai — passed
  • Independent review agent — clean after re-review

Positive coverage includes system/input text, user text, image, file, message fallback, part precedence, and absence behavior.

@github-project-automation github-project-automation Bot moved this to Discussion Ongoing in PR Backlog Aug 1, 2026
@changeset-bot

changeset-bot Bot commented Aug 1, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 41a6e19

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 30 packages
Name Type
@effect/ai-openai Patch
effect Patch
@effect/opentelemetry Patch
@effect/platform-browser Patch
@effect/platform-bun Patch
@effect/platform-deno Patch
@effect/platform-node-shared Patch
@effect/platform-node Patch
@effect/vitest Patch
@effect/ai-anthropic Patch
@effect/ai-openai-compat Patch
@effect/ai-openrouter Patch
@effect/atom-react Patch
@effect/atom-solid Patch
@effect/atom-vue Patch
@effect/sql-clickhouse Patch
@effect/sql-d1 Patch
@effect/sql-libsql Patch
@effect/sql-mssql Patch
@effect/sql-mysql2 Patch
@effect/sql-pg Patch
@effect/sql-pglite Patch
@effect/sql-sqlite-bun Patch
@effect/sql-sqlite-do Patch
@effect/sql-sqlite-node Patch
@effect/sql-sqlite-react-native Patch
@effect/sql-sqlite-wasm Patch
@effect/docgen Patch
@effect/doctest Patch
@effect/openapi-generator Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

✅ No new issues found.

Reviewed changes

  • PromptCacheBreakpoint schema and type — added to OpenAiSchema with the single valid value { mode: "explicit" }; wired into InputTextContent, InputImageContent, and InputFileContent as Schema.optionalKey.
  • Provider option augmentationsSystemMessageOptions, UserMessageOptions, FilePartOptions, and TextPartOptions all gain openai.promptCacheBreakpoint following the established Anthropic/OpenRouter pattern.
  • Converter logicprepareMessages emits prompt_cache_breakpoint on system input_text, user text parts, input_image, and input_file blocks. User message fallback targets the last content part; part-level takes precedence.
  • MessageConstructorParams fixPart["options"]M["options"] corrects the constructor params type so message-level provider augmentations are reflected.
  • Tests — 6 well-constructed cases covering system, user text, image, file fallback, part precedence, and absence. The precedence test uses a throwing getter to verify the message fallback is never read when a part defines its own breakpoint.

Pullfrog  | View workflow run | Using DeepSeek Pro (free via Pullfrog for OSS) (Kimi K2 not used — the program covers this model; add its provider key to run your pick) | 𝕏

@github-actions

github-actions Bot commented Aug 1, 2026

Copy link
Copy Markdown
Contributor

Bundle Size Analysis

Generated from PR build output; treat the content below as untrusted.

File Name Current Size Previous Size Difference
basic.ts 6.63 KB 6.63 KB 0.00 KB (0.00%)
batching.ts 9.42 KB 9.42 KB 0.00 KB (0.00%)
brand.ts 6.31 KB 6.31 KB 0.00 KB (0.00%)
cache.ts 10.16 KB 10.16 KB 0.00 KB (0.00%)
config.ts 20.32 KB 20.32 KB 0.00 KB (0.00%)
differ.ts 19.93 KB 19.93 KB 0.00 KB (0.00%)
http-client.ts 21.02 KB 21.02 KB 0.00 KB (0.00%)
logger.ts 10.32 KB 10.32 KB 0.00 KB (0.00%)
metric.ts 8.55 KB 8.55 KB 0.00 KB (0.00%)
optic.ts 7.33 KB 7.33 KB 0.00 KB (0.00%)
pubsub.ts 14.46 KB 14.46 KB 0.00 KB (0.00%)
queue.ts 11.13 KB 11.13 KB 0.00 KB (0.00%)
schedule.ts 10.31 KB 10.31 KB 0.00 KB (0.00%)
schema-class.ts 18.86 KB 18.86 KB 0.00 KB (0.00%)
schema-fromJsonSchemaDocument.ts 28.67 KB 28.67 KB 0.00 KB (0.00%)
schema-representation-roundtrip.ts 24.99 KB 24.99 KB 0.00 KB (0.00%)
schema-string-transformation.ts 12.99 KB 12.99 KB 0.00 KB (0.00%)
schema-string.ts 10.65 KB 10.65 KB 0.00 KB (0.00%)
schema-template-literal.ts 14.85 KB 14.85 KB 0.00 KB (0.00%)
schema-toArbitraryLazy.ts 21.66 KB 21.66 KB 0.00 KB (0.00%)
schema-toCodeDocument.ts 24.08 KB 24.08 KB 0.00 KB (0.00%)
schema-toCodecJson.ts 18.91 KB 18.91 KB 0.00 KB (0.00%)
schema-toEquivalence.ts 18.73 KB 18.73 KB 0.00 KB (0.00%)
schema-toFormatter.ts 18.59 KB 18.59 KB 0.00 KB (0.00%)
schema-toJsonSchemaDocument.ts 22.33 KB 22.33 KB 0.00 KB (0.00%)
schema-toRepresentation.ts 19.25 KB 19.25 KB 0.00 KB (0.00%)
schema.ts 18.12 KB 18.12 KB 0.00 KB (0.00%)
stm.ts 12.11 KB 12.11 KB 0.00 KB (0.00%)
stream.ts 9.37 KB 9.37 KB 0.00 KB (0.00%)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

4.0 enhancement New feature or request

Projects

Status: Discussion Ongoing

Development

Successfully merging this pull request may close these issues.

Support OpenAI prompt_cache_breakpoint on Responses API input content

1 participant