Skip to content

feat(llm): add prompt caching configuration - #724

Open
Linxiushen wants to merge 2 commits into
alibaba:mainfrom
Linxiushen:fix/prompt-caching-toggle
Open

feat(llm): add prompt caching configuration#724
Linxiushen wants to merge 2 commits into
alibaba:mainfrom
Linxiushen:fix/prompt-caching-toggle

Conversation

@Linxiushen

Copy link
Copy Markdown
Contributor

Summary

  • add a global llm.prompt_caching setting while preserving the current enabled-by-default behavior
  • apply the setting to Anthropic system blocks and tool definitions across provider, legacy, and interactive configuration flows
  • add CLI, resolver, request serialization, persistence, and TUI coverage, plus configuration documentation

Testing

  • go test ./... -count=1 -skip 'TestResolveBackgroundFilePath|TestSaveConfig|TestResolveRuleEntries_SymlinkSafety|TestFinalizeSurfacesWriterCreationErrorWithoutStdout|TestHandleRepos_PermissionDenied|TestDiscoverRepos_SkipsUnreadableSubdir|TestListSessions_SkipsUnreadableFiles'
  • go vet ./...
  • go build -o .tmp/ocr.exe ./cmd/opencodereview

Closes #700

@CLAassistant

CLAassistant commented Aug 5, 2026

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

@github-actions

github-actions Bot commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

🔍 OpenCodeReview found 3 issue(s) in this PR.

  • ✅ Successfully posted inline: 2 comment(s)
  • ❌ Failed to post inline: 1 comment(s)

[bug · medium]

📄 cmd/opencodereview/provider_tui.go (L1100-L1107)

⚠️ GitHub could not post this as an inline comment: Lines 1100-1107 could not be resolved (outside PR diff hunks)

The custom provider form is missing the prompt caching UI step for Anthropic protocol providers. While the official provider flow transitions to stepPromptCaching and the manual provider flow includes manualStepPromptCaching, the custom provider create/edit form skips this entirely. After completing the auth header step, handleCustomFormEnter calls finishCustomProviderForm() directly without checking if the protocol is Anthropic. The promptCaching value is initialized from config and included in the result, but users have no way to modify it through the UI for custom Anthropic providers. This creates an inconsistent experience where two of three provider paths offer the toggle but custom providers do not.

💡 Suggested Change

Before:

	case cpStepAuthHeader:
		raw := m.cpAuthInput.Value()
		if _, err := llm.NormalizeAuthHeader(raw); err != nil {
			m.formError = authHeaderFormError(raw)
			return m, nil
		}
		m.cpAuthInput.Blur()
		return m.finishCustomProviderForm()

After:

	case cpStepAuthHeader:
		raw := m.cpAuthInput.Value()
		if _, err := llm.NormalizeAuthHeader(raw); err != nil {
			m.formError = authHeaderFormError(raw)
			return m, nil
		}
		m.cpAuthInput.Blur()
		if cpProtocols[m.cpProtocolIdx] == llm.ProtocolAnthropic {
			m.cpStep = cpStepPromptCaching
			return m, nil
		}
		return m.finishCustomProviderForm()

Comment thread cmd/opencodereview/provider_cmd.go Outdated
Comment on lines +116 to +118
if result.promptCaching != nil {
cfg.Llm.PromptCaching = result.promptCaching
}

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.

[maintainability · low]
Potential issue: When switching from Anthropic to a non-Anthropic protocol, the old PromptCaching value remains in the config file. While this doesn't cause functional problems (the setting is only used for Anthropic), it leaves stale configuration data. Consider clearing the field when the protocol is not Anthropic:

if result.promptCaching != nil {
    cfg.Llm.PromptCaching = result.promptCaching
} else if llm.NormalizeProtocol(result.protocol) != llm.ProtocolAnthropic {
    cfg.Llm.PromptCaching = nil
}

This same pattern appears in all three apply functions (applyManualConfig, applyCustomProviderConfig, applyOfficialProviderConfig) and should be updated consistently.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Addressed in c07b2a7. The manual, custom, and official apply paths now clear stale prompt-caching state when the effective protocol is not Anthropic. Regression coverage includes all three switch paths and preserves the active Anthropic setting when an inactive OpenAI provider is edited.

Comment thread internal/llm/resolver.go
Comment on lines +436 to 438
PromptCaching: cfg.Llm.PromptCaching,
Timeout: timeout,
}, true, nil

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.

[maintainability · low]
Inconsistent sourcing: PromptCaching is read from cfg.Llm.PromptCaching (the top-level llm block), while other analogous per-provider fields like ExtraBody, ExtraHeaders, and TimeoutSec are sourced from the provider entry. Furthermore, providerEntryConfig has no PromptCaching field, so users cannot configure this setting per-provider.

If PromptCaching is intentionally a global-only setting, this is acceptable, but a brief comment explaining the design decision would prevent future confusion. Otherwise, add PromptCaching *bool to providerEntryConfig and read it from entry (falling back to cfg.Llm.PromptCaching if unset) for consistency.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Confirmed as global by design: the toggle follows whichever Anthropic provider is active rather than being duplicated across provider entries. c07b2a7 documents that contract in both the persisted config and resolver, while keeping provider-specific transport fields on each entry.

@cometkim

cometkim commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

I think this may duplicate #332, which adds a generalized option for prompt caching, for multiple providers.

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.

unrecognizedProperty cache_control

3 participants