- Migrated 288 lines of scattered error classification logic from `utils/error-id.ts` into a cohesive `packages/ai/src/error/` module with 13 specialized submodules covering flags, classes, OAuth, providers, rate-limiting, and finalization.
- Replaced 100+ generic `Error` throws across 60+ provider and registry files with semantic `AIError.*` classes (e.g., `AIError.MissingApiKeyError`, `AIError.OAuthError`, `AIError.ProviderResponseError`), improving error diagnostics and retry logic.
- Consolidated error utility imports from `pi-utils` and scattered classification functions into a single `AIError` namespace, reducing coupling and simplifying error handling across all packages.
Recognized the empty Ollama finish_reason:length guidance as context overflow so coding-agent promotion and compaction recovery still run after surfacing the actionable error.
Added overflow utility coverage for the Ollama prompt-filled-context wording.
The regex in isContextOverflow used a start-of-string anchor (^) to match
the Cerebras/Mistral pattern '400/413 status code (no body)'. When the
synthetic provider (api.synthetic.new) receives a context-overflow rejection
from the upstream HF inference backend it wraps it in a JSON envelope:
{"error": "Error from inference backend: 400 status code (no body)"}
finalizeErrorMessage then builds:
400 status code: {"error":"Error from inference backend: 400 status code (no body)"}
The '^' anchor fails to match because the outer HTTP status is followed by
': {JSON}', not '(no body)'. Changed to '\b' so the substring match finds
the phrase anywhere in the error string.
Also fixed formatCapturedHttpError to extract the error string from
{"error": "string"} bodies instead of falling back to the raw JSON.
Fixes#1251