Commit Graph
342 Commits
Author SHA1 Message Date
can1357 eb4a02433c refactor: consolidated json parsing and stream utilities
- Centralized JSON parsing and stream processing logic by moving utilities from `packages/ai` to the shared `@oh-my-pi/pi-utils` package.
- Standardized import paths for JSON parsing and streaming across the agent, ai, and coding-agent packages.
- Refactored SSE stream handling to use consolidated `parseStreamingJson` logic and introduced robust error recovery for malformed container-shaped tail events.
- Cleaned up legacy bundled registry references and updated related module exports and tests to reflect the new utility structure.
2026-06-27 00:11:42 +02:00
can1357 1ed343d9a4 Merge PR #3595: fix(agent): stop replaying provider refusals (@roboomp) 2026-06-26 23:27:40 +02:00
can1357 2899ce1bc2 Merge PR #3328: fix(proxy): scrub transient partialJson from final tool calls (@roboomp) 2026-06-26 23:27:38 +02:00
roboomp 22f43b26ae fix(agent): preserved refusals in summaries
Scoped provider-refusal filtering to live replay so compaction and snapcompact summaries retain the refused turn while outbound provider context still drops the refusal.

Fixes #3592
2026-06-26 18:04:34 +00:00
roboomp d68980fe58 fix(agent): stopped replaying provider refusals
API-level refusals now stay visible as terminal errors without being sent back as assistant dialogue on the next provider request. Added core and coding-agent conversion coverage for Anthropic refusal metadata.

Fixes #3592
2026-06-26 17:56:07 +00:00
Alexander Kirilin ab513757f8 fix(agent): preserve tool turn before mid-run compaction 2026-06-26 09:35:24 -04:00
Alexander Kirilin e99b8c4128 docs(agent): clarify mid-turn continuation hook 2026-06-26 09:17:07 -04:00
Alexander Kirilinandcoderred bbe3d98375 fix(agent): compact long tool loops mid-turn
Co-authored-by: coderred <coderredlab@gmail.com>
2026-06-26 09:05:11 -04:00
can1357 415099c420 fix: stripped stale snapcompact archive state during compaction strategy migration
- Fixed stale `preserveData.snapcompact` frames leaking into context-full compaction after switching from `snapcompact` to `context-full` strategy, which inflated context usage and made sessions appear to compact prematurely.
- Added secret redaction for migrated snapcompact archive plaintext (`text`/`textHead`/`textTail`) during the snapcompact->context-full transition, while preserving opaque provider-replay state byte-identical.
- Added `archiveSourceText()` and `stripPreservedArchive()` utilities to snapcompact module for archive extraction and cleanup.
2026-06-26 14:31:50 +02:00
can1357 93b80e5b1b refactor: consolidated duplicate
- Consolidated duplicate `stripSnapcompactPreserveData` functions into `snapcompact.stripPreservedArchive`.
- Added unit tests to verify archive removal and empty state collapse behavior.
2026-06-26 14:28:49 +02:00
OpenAI GPT-5.5 d7fdeb8e2b fix(agent): use static snapcompact archive prompt
Co-Authored-By: OpenAI GPT-5.5 <noreply@openai.com>
2026-06-26 08:21:11 +00:00
OpenAI GPT-5.5 5c4e269900 fix(agent): migrate snapcompact archive on context compaction
Co-Authored-By: OpenAI GPT-5.5 <noreply@openai.com>
2026-06-26 08:15:17 +00:00
roboomp 2b68785e82 fix(agent): include provider payloads in append-only digests
Responses-style providers serialize providerPayload history items instead of the
visible message blocks when replaying native history. Include providerPayload in
the append-only per-message digest so payload-only history rewrites stop the
stable-prefix walk and re-sync the changed message before any later divergent
tail.

Add a regression where an assistant message keeps identical visible content and
id but changes its openaiResponsesHistory providerPayload while a later message
also diverges; syncMessages must preserve the prefix before the assistant and
refresh the assistant payload.

Fixes #3406
2026-06-24 23:11:12 +00:00
roboomp 5b9e009a8b fix(agent): bound append-only stable prefix by log length
Direct callers can clear AppendOnlyContextManager.log without resetting the
private sync cursor. The advisor reset path does this when recycling its helper
agent, leaving lastSyncCount and messageDigests describing the old transcript
while the physical log is empty.

Clamp the stable-prefix reuse count to the current log length before truncating
and appending. A direct log clear now forces the next sync to replay from index 0
instead of starting from a stale private cursor and dropping prefix messages from
the provider context.

Add a regression that clears the public log after syncing two messages, then
resyncs a context with the same first message and a rewritten second; both
messages must be present in the rebuilt append-only log.

Fixes #3406
2026-06-24 23:07:11 +00:00
roboomp cce627ee4b fix(agent): include tool result metadata in append-only digests
Track internal tool-result metadata in append-only per-message digests so
metadata-only rewrites of toolCallId, toolName, or isError stop the stable-prefix
walk and re-sync the changed tool result before any later divergent tail.

This prevents stale tool-result pairing or error state from being preserved when
the text content stays unchanged but provider-serialized metadata changes.

Fixes #3406
2026-06-24 22:42:51 +00:00
roboomp 65a974aa90 fix(agent): preserve append-only log prefix on in-place message rewrites
`AppendOnlyContextManager.syncMessages` hashed a single rolling digest
over the entire synced prefix, so any in-place rewrite of an already-
synced message — per-turn `pruneSupersededToolResults` / `pruneToolOutputs`
collapsing a tool result, image stripping, or a `transformContext` re-render
— triggered `log.clear()` and re-appended the full conversation from
the current (mutated) view. The provider's cached bytes still matched
the prefix, but every position past the divergence had to be re-prefilled.
On llama.cpp / Ollama / LM Studio this re-prefilled tens of thousands
of tokens every few turns (`n_past \u2248 end-of-system-prompt` collapse,
~40k-token full re-prefill, GPU pinned >400W).

Replace the rolling digest with per-message digests in `#messageDigests`,
walk the new sync against them to find the longest byte-stable prefix,
truncate the log down to that prefix via a new `AppendOnlyLog.truncate(count)`,
and only re-append the diverged tail. Genuine compaction (`length <
lastSyncCount`) still clears the log.

- Tail-only rewrite: prefix stays byte-stable; only the trailing message
  re-syncs.
- Deep rewrite: prefix up to the divergence stays byte-stable; the
  provider re-prefills from the divergent message onward (architectural
  minimum).
- True compaction: unchanged, full replay.

Replace the now-misleading `detects in-place rewrite of already-synced
messages` / `detects in-place rewrite via digest mismatch` tests with
`preserves the byte-stable prefix when a deep message is rewritten (#3406)`,
`preserves the prefix when the tail is rewritten (#3406)`, `appended
new messages keep the prefix stable even when the prior tail also
diverged (#3406)`, and `rewriting the first message still re-syncs
from scratch` so each invariant is asserted directly.

Fixes #3406
2026-06-24 22:33:22 +00:00
can1357 1052af5fa6 refactor(agent): restructured yield logic to support deterministic testing
- Extracted yield logic into a configurable YieldGate class to avoid process-global state.
- Injected time and sleep dependencies to support deterministic testing.
- Handled potential negative time progression by forcing a re-anchor instead of gating indefinitely.
- Maintained existing behavior for the public yieldIfDue export via a shared instance.
2026-06-24 15:30:29 +02:00
oldschoola c210bdd391 fix(proxy): scrub partialJson in catch-block error path on stream disconnect
Address review feedback: when the SSE stream disconnects after a
toolcall_delta but before toolcall_end/done/error, the catch-block
at lines 183-192 pushes the partial message as the error result
without calling scrubPartialJson. This leaked the internal partialJson
field into the final error message.

Added scrubPartialJson(partial) call in the catch block, before
pushing the error event.

Added test verifying partialJson does not leak when server disconnects
mid-tool-call (toolcall_start + partial toolcall_delta, no terminal event).
2026-06-23 10:16:06 -07:00
oldschoola 2a2aa9fe59 fix(proxy): preserve partialJson on content during streaming, scrub at terminal events
Address review feedback: downstream renderers (event-controller.ts:535)
read content.partialJson during toolcall_delta to pace streaming
previews (bash env assignments, write/edit smooth streaming).

Revised approach:
- toolcall_start: initialize partialJson on content via typed
  ToolCall & { partialJson: string } intersection (not as any)
- toolcall_delta: accumulate in side-channel Map, write onto content
  via typed intersection cast
- toolcall_end: delete partialJson from content + side-channel map
- done/error: scrubPartialJson() cleans any remaining blocks that
  never got toolcall_end (the original leak bug, now fixed for all
  terminal paths)

Added test verifying partialJson IS present during streaming and
IS absent after completion.
2026-06-23 09:40:32 -07:00
oldschoola 9c795f886e fix(proxy): use side-channel Map for partialJson, eliminating as-any casts
streamProxy stored internal partialJson streaming state directly on typed
ToolCall objects via 4 'as any' casts. If toolcall_end was skipped (stream
error, early done), the field leaked into the final AssistantMessage content,
corrupting downstream serialization.

Replace with a side-channel Map<number, string> keyed by contentIndex:
- toolcall_start initializes the map entry
- toolcall_delta accumulates into it
- toolcall_end cleans it up

The typed ToolCall object never carries non-spec fields. All 4 'as any'
casts are eliminated.

Added 4 contract tests covering argument parsing, partialJson isolation on
normal completion, partialJson isolation when toolcall_end is missing, and
multiple concurrent tool calls with interleaved deltas.
2026-06-23 08:17:29 -07:00
can1357 5c21b28786 feat: optimized handoff generation and harden request safety
- Introduced `generateHandoffFromContext` to enable provider-aware oneshot generation and improved cache hit rates via the live-turn pipeline.
- Updated `buildSideRequestContext` to support pinning custom system prompts, preventing per-turn hook leakage during handoff.
- Added concurrency guards across CLI and RPC modes to block manual `/handoff` requests while a session is actively streaming.
- Standardized handoff execution to force `toolChoice: "none"` and enforce consistent cache-routing behavior.
2026-06-22 20:05:40 +02:00
can1357 0b5e2d8276 fix(ai-providers): normalized Anthropic tool call IDs
- Implemented `normalizeAnthropicTargetToolCallId` to define consistent ID validation and fallback logic.
- Integrated the normalization utility into the `transformMessages` function to ensure API compatibility.
- Refactored `transformMessages` to decouple mapping logic from message loop execution for better maintainability.
- Updated the changelog to reflect the correction of tool call ID handling for Anthropic-compatible models.
2026-06-21 06:04:49 +02:00
can1357 29f7b57fde feat: migrated core rendering and context transformation to async
- Updated `render`, `renderMany`, and native snapcompact methods to return promises, ensuring scalable async execution.
- Refactored `transformProviderContext` and `buildSideRequestContext` to support asynchronous operations in agent loops.
- Integrated `Promise.all` for improved concurrency when processing frame rendering and rendering batch operations.
- Updated all internal call sites, SDK hooks, and test suites to accommodate the asynchronous API signatures.
2026-06-21 00:32:13 +02:00
DarkPhilosophyandcan1357 8c9ae9ef67 fix(compaction): exclude encrypted reasoning from the compaction floor
CI caught that flooring by the raw local estimate falsely triggers compaction on
thinking-heavy turns: estimateTokens counts the opaque thinkingSignature /
redactedThinking payloads (providers bill them on replay, #2275), but their local
byte size diverges wildly from what the provider actually charges — so a turn
with a large encrypted-reasoning blob but small provider usage would trip the
floor (broke agent-session-handoff 'provider-anchored usage' test).

estimateTokens now takes { excludeEncryptedReasoning } and the compaction floor
(#estimateStoredContextTokens) uses it: the floor counts only reliably-countable,
on-wire-compressible content (text, tool results, tool calls), while the provider
usage arm of compactionContextTokens still accounts for encrypted reasoning. This
keeps the encrypted-reasoning case provider-anchored while still flooring upward
when a before_provider_request hook compresses tool results.
2026-06-20 23:21:36 +02:00
DarkPhilosophyandcan1357 7e8450192c fix(compaction): floor context tokens by local estimate so payload compression can't suppress auto-compaction
A before_provider_request extension (a context-compression proxy like Headroom,
an obfuscator, or inline snapcompact) can shrink the outgoing request below the
real stored conversation. The provider then reports deflated prompt tokens, so
the auto-compaction threshold never fires and the stored history grows unbounded
until it overflows the context window and can no longer be compacted at all.

Add compactionContextTokens(provider, storedEstimate) = max(provider, estimate)
and apply it to both the pre-prompt and post-response compaction decisions,
flooring the provider-reported tokens by the agent's own estimate of the stored
conversation. Display and cost accounting still use exact provider usage; only
the compaction trigger takes the floor.
2026-06-20 23:21:36 +02:00
can1357 b5437c2cad feat(coding-agent): improved prompt caching for ephemeral side-channel requests
- Added `buildSideRequestContext` to the `Agent` class to generate prompt-cache-friendly provider contexts.
- Updated ephemeral side-channel turns to forward the full tool catalog to maintain prompt cache hit rates.
- Injected a `developer` role reminder into ephemeral turns to instruct the model to suppress tool calls.
- Implemented automatic post-processing to strip any tool calls from ephemeral turn responses.
- Exported message and dialect helper functions in `agent-loop.ts` to support context construction.
2026-06-20 23:19:10 +02:00
can1357 1afa6ba68a feat(catalog): supported fireworks fast serving path
- Added support for "Fast" serving-path variants for select Fireworks models.
- Updated compatibility logic to route `-fast` suffixes to the appropriate router wire format.
- Extended the model generation catalog to include these Fast variants with their respective pricing.
- Updated AI types to allow the `priority` service tier for Fireworks providers.
2026-06-20 09:21:01 +02:00
roboomp 48a78f278c fix(agent): wire-encode normalizeTools parameters for omit-intent tools
normalizeTools only ran toolWireSchema/zodToWireSchema/arkToWireSchema
inside the if (doInjectIntent) branch, so any tool whose intentMode
resolved to "omit" (function intent, or intent: "omit" like the
builtin eval/resolve) had its live arktype/zod schema object left in
parameters. The pruneDescriptions branch already wire-encoded
unconditionally, so the two branches disagreed; first-party providers
re-encoded with toolWireSchema themselves and never noticed, but any
downstream consumer that serialized parameters as-is ended up with an
invalid schema (arktype AST: object-valued required, domain instead of
type, no properties).

Hoist toolWireSchema(t) out of the inject-intent branch so it always
runs and inject intent on top, mirroring the pruneDescriptions shape.
Drop the now-redundant isZodSchema/isArkSchema/zodToWireSchema/
arkToWireSchema imports.

Fixes #3074
2026-06-19 19:43:45 +00:00
can1357 9478e3cc5c refactor: replaced ReturnType<typeof setTimeout> with Timer type
- Replaced usage of `ReturnType<typeof setTimeout>` and `ReturnType<typeof setInterval>` with the explicit `Timer` type across the codebase.
- Updated several type definitions and function signatures to use concrete types instead of inferred return types for improved clarity and maintainability.
2026-06-19 17:38:07 +02:00
can1357 67f6518e42 feat: enhanced tool robustness, improve authentication flow, and update API parameters
- Implement JSON repair and strict argument validation to sanitize raw payloads and redact sensitive information from agent event logs.
- Add automatic authentication fallback for benchmark model resolution to ensure consistent performance testing across providers.
- Refactor search tool API parameters by replacing `i` with a case-sensitive `case` boolean flag for clarity.
- Update session history formatting to ensure empty objects are consistently serialized as `{}` instead of empty strings.
2026-06-19 16:46:07 +02:00
can1357 7d28c60c86 refactor: renamed intent field from _i to i
- Renamed the global `INTENT_FIELD` constant from `_i` to `i`.
- Updated documentation strings, type annotations, and test expectations across packages to reflect the new field name.
- Ensured consistent usage of the constant in tool schema construction and intent serialization.
2026-06-19 16:42:33 +02:00
can1357 08c4dd2676 perf(agent): avoided redundant cloning of assistant messages
- Optimized `snapshotAssistantMessageEvent` to accept an optional pre-computed partial snapshot.
- Eliminated redundant deep-clones of `partialMessage` during streaming updates by sharing a single immutable snapshot between the message and the event.
2026-06-19 16:06:18 +02:00
can1357 ea7164274c refactor(agent): replaced custom object clone with shared utility
- Removed internal `cloneUnknown` and `cloneToolArguments` functions.
- Switched to `structuredCloneJSON` from shared utils for snapshotting tool call arguments.
2026-06-19 16:06:17 +02:00
can1357 ed73429faa feat: implemented soft tool requirement and escalation system
- Introduced `SoftToolRequirement` to support non-invasive tool enforcement with lifecycle management and escalation.
- Added `ToolChoiceDirective` to coordinate hard and soft tool requirements within the agent loop.
- Optimized preview workflows in `coding-agent` by replacing forced tool choices with non-forcing pending invokers.
- Enhanced `CompactionSummaryMessage` to prioritize structured rendering for tool requirement reminders.
2026-06-19 07:51:27 +02:00
can1357 b137764f0c feat: implemented text-first foveated snapcompact archive layout
- Implemented text-first archive structure that incorporates bounded source text with foveated image frames (HQ edges, LQ middle) to improve context quality.
- Updated snapcompact core logic to use `historyBlocks` for reconstruction, transitioning away from reliance on previous PNG frame inheritance.
- Increased default frame limits to 80 and adjusted token estimation constants (5024) to enhance context budget accuracy.
- Added `pruneToolDescriptions` and improved multi-block summary token estimation to optimize tool spec usage.
2026-06-19 07:38:54 +02:00
can1357 dcb16d86f6 perf(compaction): kept per-turn tool-result pruning inside the warm prompt-cache prefix
- Added `keepBoundaryId` and `cacheWarmSuffixTokens` guards to `pruneToolOutputs` and `pruneSupersededToolResults` so superseded/useless results sitting in the already-sent cached prefix are no longer rewritten mid-session, with new `computeMessageSuffixTokens`/`resolveBoundaryIndex` helpers.
- Added a `keepBoundaryId` floor to `collectShakeRegions` so shake skips entries summarized away by the latest compaction.
- Threaded `firstKeptEntryId`, `PRUNE_CACHE_WARM_SUFFIX_TOKENS` (8k) and `PRUNE_IDLE_FLUSH_MS` (90m, above the 1h cache TTL) from `#pruneToolOutputs`, `#pruneStaleToolResults` and `shake` in `agent-session.ts`.
- Added six boundary tests in `supersede-prune.test.ts` covering warm-prefix protection, tail-case pruning, and the pre-boundary floor.
2026-06-19 06:57:53 +02:00
can1357 96151e6c30 feat: implemented tool description pruning to reduce token usage
- Added utility functions to strip descriptions from JSON schemas and tool definitions for optimized token output.
- Integrated `pruneToolDescriptions` configuration across agent loops and sessions to enable optional schema pruning.
- Updated agent context and snapshot logic to propagate pruning settings and maintain fingerprinting integrity.
- Verified schema structural integrity and removal of annotation descriptions through new unit tests.
2026-06-19 06:55:19 +02:00
can1357 4f03180ae6 refactor(deps): moved intent field constant to pi-wire
- Moved the `INTENT_FIELD` constant from `@oh-my-pi/pi-agent-core` to the specialized `@oh-my-pi/pi-wire` package to permit broader usage across the monorepo.
- Updated all references across `agent`, `ai`, `coding-agent`, `collab-web`, and `snapcompact` packages to import the constant from the new location.
- Added `@oh-my-pi/pi-wire` as a dependency to all affected packages.
2026-06-19 04:58:29 +02:00
can1357 c224ef4df5 feat: standardized elision markers and improve transcript viewer robustness
- Standardized elision markers across all tool outputs and filters to use cohesive `[...N [type] elided...]`, `[...Nln elided...]`, and `[...xB elided...]` syntax.
- Updated documentation, prompts, and test expectations to reflect the unified elision format.
- Improved transcript viewer robustness by preventing content aliasing through path-inclusive signature hashing.
- Added logic to clear stale transcript content when associated session files are deleted, accompanied by verifying test cases.
2026-06-19 04:35:18 +02:00
can1357 67abdb1828 feat(agent): prevented internal URLs from appearing in file summaries
- Added an exclusion check to `extractFileOpsFromMessage` to ignore paths containing URL schemes (e.g., `artifact://`, `conflict://`, `https://`).
- Implemented `isUrlSchemePath` helper to identify non-filesystem resources that cannot be re-grounded by the agent.
- Added comprehensive unit tests to verify exclusion logic for various scheme-prefixed paths.
2026-06-18 19:38:31 +02:00
can1357 291b3c74c2 feat: enhanced model reasoning, schema normalization, and loop guarding
- Integrated comprehensive loop guard support for DeepSeek and assistant prose patterns, including configurable stream checks.
- Implemented Moonshot Flavored JSON Schema (MFJS) normalization for improved tool compatibility and enum type inference.
- Added support for Ollama reasoning effort backfilling and Grok-specific service tier cost tracking across providers.
- Expanded model catalog with new entries and unified compatibility logic for improved OpenRouter API integration.
2026-06-18 04:51:43 +02:00
can1357 3f304ee5a8 refactor(agent-core): isolated token counting into a new local tokenizer
- Extracted native token counting into a new localized `tokenizer.ts` wrapping `@oh-my-pi/pi-natives`.
- Introduced a lightning-fast byte-length estimation logic for token counting when accurate counting is disabled.
- Diverted token calculations to the faster estimator during test environments and when `PI_TOKENIZER_ACCURATE` is falsy.
- Updated agent base and coding-agent sessions to consume the new localized `countTokens` utility.
2026-06-18 01:57:23 +02:00
can1357 6bcba1c730 feat(agent): added transformAssistantMessage hook
- Introduce a `transformAssistantMessage` lifecycle hook to `AgentOptions`, `Agent`, and `AgentLoopConfig`.
- Invoke the hook on finalized assistant messages within the agent streaming loop prior to context updates, UI emission, and tool dispatch.
- Enable mutating the text content and tool-call arguments of assistant messages in place during execution.
2026-06-18 00:59:56 +02:00
can1357 7c295faa52 feat: added native support for ArkType schemas alongside Zod
- Added native support for parsing, normalized validation, and serialization of ArkType schemas throughout the agent pipeline.
- Implemented pruning of unconstrained union branches and normalization helpers to handle unrepresentable strict-mode branches.
- Patched ArkType's schema package to preserve declared object key order during serialization.
- Integrated ArkType schemas into `agent-loop` and migrated coding agent tool parameters to ArkType format.
2026-06-18 00:59:56 +02:00
can1357 d4317d3d20 feat(ai): consolidated OpenAI-family streaming and add OpenRouter API support
This change introduces a new `openrouter` API type and extensively refactors OpenAI-family streaming providers, centralizing shared logic and improving robustness.

Key changes include:
- **Unified OpenAI-family Logic:** Consolidated core utilities, compat resolution, request shaping, and stream processing into `openai-shared.ts`, reducing duplication across `openai-completions`, `openai-responses`, and `openai-codex-responses`.
- **OpenRouter API Type:** Introduced a dedicated `openrouter` API type with dual-surface compatibility, allowing it to dispatch requests as either OpenAI Chat Completions or Responses.
- **Enhanced Provider Integration:**
    - Improved Perplexity search to leverage shared OpenAI streaming transports, including API-key fallback to OpenRouter and support for Perplexity's Responses API.
    - Integrated xAI-specific logic directly into the shared `stream.ts` dispatch, removing the dedicated `xai-responses` provider.
    - Refined credential parsing for Google Gemini CLI and handling of Azure deployment names.
- **Robustness & Consistency:** Improved error handling for Codex, standardized output token parameter resolution, and ensured consistent application of reasoning suppression across all Chat Completions dialects.
- **New Documentation:** Added `provider-endpoint-constraints.md` to detail endpoint-specific behaviors and quirks for various providers.
- **Telemetry & Debugging:** Extended telemetry propagation to advisor calls and overflow compaction tasks. Improved debugging for Codex WebSocket failures and stream error messages.
- **Tooling & Security:** Updated browser stealth scripts to prevent detection and added a new `ts-no-inline-cast-access` TTSR rule.
2026-06-17 21:36:48 +02:00
can1357 0d9ec354e7 fix: fixed Gemini thinking-loop handling across streaming dispatch paths
- Added Gemini thinking-loop detection helpers for near-duplicate and verbatim output checks.
- Wrapped `stream`, `streamPiNative`, and `streamSimple` dispatches with the loop guard.
- Emitted retryable empty-content loop errors and stopped completion events on loop hits.
- Added `enableGeminiThinkingLoopGuard` options for OpenAI compatibility with Gemini defaults and overrides.
2026-06-17 13:44:33 +02:00
can1357 5157de5b16 fix(agent): enforce deadline at tool-execution, yield, and in-flight boundaries
The deadline was only checked at loop entry and the top of the inner loop,
so a provider response returning tool calls after the deadline still
executed them, and a deadline crossed during onBeforeYield could dequeue
then drop queued steering/follow-up messages.

- Re-check the deadline after streamAssistantResponse before running tools;
  pair leftover tool calls with aborted "Deadline exceeded" placeholders to
  keep the tool_use/tool_result contract valid.
- Re-check after emitTurnEnd and after onBeforeYield before draining the
  steering/aside/follow-up queues so queued messages are never dequeued and
  dropped.
- Merge a deadline AbortController into the loop signal so in-flight provider
  requests and tools are cancelled at the boundary.
2026-06-17 12:44:23 +02:00
usr_bin_roygbivandcan1357 39169c8878 feat: add max-time deadline support 2026-06-17 12:44:23 +02:00
Alexander Kirilinandcan1357 89d2ed8f66 fix(minimax): expose owned dialect selectors 2026-06-17 12:24:49 +02:00
can1357 a0cffe4814 feat: updated model-aware API-key resolution and antigravity endpoint failover
- Updated getApiKey signatures to accept a Model and return ApiKey or ApiKeyResolver.
- Updated stream key handling to resolve credentials per model and use seedApiKeyResolver for retries.
- Added antigravityEndpointMode setting with auto/production/sandbox endpoint selection.
- Added 429/5xx endpoint failover for Gemini stream, usage, search, and image calls.
2026-06-17 12:24:21 +02:00