fix(vercel-ai): strip retry suffix from UI `errorText` and preserve LLM cache

Closed
TI
3mo ago
+37-31

Summary

RetryPromptPart.model_response() appends "\n\nFix the errors and try again." — an instruction meant for the LLM, not for end users. This suffix was leaking into Vercel AI errorText in both the streaming and dump paths, breaking frontend logic that checks errorText values (e.g. errorText === "Cancelled" to distinguish cancelled vs failed state).

Core change: Add RetryPromptPart.error_description() — returns the error text without the retry suffix. model_response() now delegates to it, so all existing callers are unaffected.

Vercel AI adapter:

  • Dump path: Uses error_description() for UI-facing error_text; stores the full model_response() in call_provider_metadata.pydantic_ai.model_response for round-trip cache fidelity
  • Load path: Prefers provider_meta['model_response'] for ToolReturnPart.content, falls back to error_text — LLM prompt cache is preserved after dump → load
  • Streaming path: Uses error_description() directly

This ensures the LLM sees identical text before and after a dump/load round-trip (no cache break), while the UI gets clean error text without the retry instruction.

Test plan

  • All 106 test_vercel_ai.py tests pass
  • Snapshot tests updated for new metadata field and round-trip content
  • ruff check / ruff format / pyright clean on changed files
  • Verify errorText in Vercel AI frontend no longer contains suffix
  • Verify dump → load → next LLM turn produces identical prompt (cache hit)