Preserve opaque source strings across tool-result replay while retaining masking for direct .env reads, registered or recognizable secrets, structured sensitive fields, and payment data.
Responses replay parsed persisted thinking signatures without validating their JSON shape, so corrupt or unrelated values could prevent every later turn in a session.
Parse signatures in the shared replay owner and accept only reasoning records. Cover malformed syntax, null, arrays, and wrong item types through both provider- and transport-style converters.
The default OpenAI Responses compact_threshold was 70% of contextWindow alone; for gpt-5.6-sol (1.05M window, 272k active budget) that resolved to 735,000, above the ~252k prompt budget the runtime admits, so provider compaction never fired before local overflow handling. Threshold now uses 0.7 x min(contextTokens, contextWindow) (190,400 for Sol) on both the payload-policy and host-preflight paths; explicit responsesCompactThreshold still wins.
Classify text interrupted by resumed reasoning at the OpenAI-completions producer boundary, so channels deliver only the confirmed final answer.
Defer phase-ambiguous replies until terminal classification while preserving live partial delivery for ordinary completions.
Co-authored-by: Ayaan Zaidi <hi@obviy.us>
* refactor(ai): give transport streams an honest writer type
* test(ai): use canonical transport stream fixtures
* fix(ai): preserve partial-less stream deltas
* fix(ai): preserve provider terminal error message in stream transports
The managed OpenAI Responses transport (and the mistral/google-shared
providers) threw a literal "An unknown error occurred" on terminal
error stop reasons, discarding the provider's terminal fact (for example
"Provider incomplete_reason: content_filter"). The catch-side
projectProviderError() then overwrote output.errorMessage with the
generic string, so users saw an unknown error and failover classified
the deterministic failure as a transient timeout, rotating models and
re-sending the same filtered prompt.
Align all three sites with the canonical siblings
(openai-responses-shared.ts, transport-stream-shared.ts) by preserving
output.errorMessage when present.
* test(ai): await the transport stream factory before result()
* fix(ai): narrow the repair to the managed OpenAI transport
ClawSweeper correctly noted the mistral and google-shared edits were
no-ops: streamMistral never assigns output.errorMessage and the Google
path throws its own constructed terminal error before this fallback.
Revert both to keep the PR scoped to the proven managed-transport
repair.
* fix(ai): recover rejected WebSocket compaction
Native OpenAI WebSocket turns now rebuild full history over SSE when a replayed encrypted checkpoint is explicitly rejected, then suppress that checkpoint on later turns.
* ci: refresh merge check
* fix(ai): managed OpenAI transport understates gpt-5.5 priority pricing by 20%
The managed Responses transport carried its own copy of the service-tier
pricing table in openai-responses-debug.ts (flat 2x for priority). The
canonical helper applyResponsesServiceTierPricing in
openai-responses-shared.ts was updated to 2.5x for gpt-5.5 priority
(#117298) but the transport copy was never touched, so UI cost for
managed-transport fast-mode turns understated the real spend.
Delete the duplicated table and delegate the transport's pricingOptions
to the canonical model-aware helper. Azure intentionally remains
tier-unpriced (it sets no pricingOptions).
* test(ai): pin managed-transport gpt-5.5 priority pricing at the transport boundary
ClawSweeper correctly flagged that the helper-only test also passes on
unfixed main. Add a mocked managed-transport run with a priority
response and nonzero model cost asserting the final usage cost is 2.5x
(fails at 24 vs 30 on the pre-fix flat table).
Treat <internal> blocks as private reasoning in the shared parser and remove Telegram raw-reasoning fallbacks. This keeps model reflections out of user-visible replies while preserving surrounding answer text.
Closes#122623
Co-authored-by: Ayaan Zaidi <hi@obviy.us>
Co-authored-by: WangYan <wang.yan29@xydigit.com>
* feat(ai): continue stateful OpenAI SSE turns
Use the prior OpenAI Responses ID for native stateful HTTP/SSE turns, retry missing server state with full history in the same turn, and keep stateless/custom routes unchanged.
Co-authored-by: Markus Hartung <mail@hartmark.se>
* test(ai): assert Responses retry attempt metadata
---------
Co-authored-by: Peter Steinberger <steipete@gmail.com>
* refactor: consolidate coercion ownership
Centralize four canonical coercion helpers, migrate exact core and plugin duplicates through narrow Plugin SDK facades, and enforce declaration and plugin-normalization ownership boundaries.
The sweep adds eight focused SDK exports while deleting more production and tooling code than it adds. User-visible behavior is unchanged except for safer equivalent object and UI parsing at existing boundaries.
* fix: guard integer option ownership
Register resolveIntegerOption with the canonical function owner and extend the declaration-guard fixture so future local duplicates fail validation.
* fix: keep integer helpers on numeric facade
Remove the unshipped duplicate string-coerce exports and route every affected plugin consumer through the existing number-runtime contract.
* fix: point numeric coercion to number runtime
Make boundary and declaration diagnostics recommend the canonical numeric facade, with failing-before coverage for both guidance paths.