Commit Graph
2853 Commits
Author SHA1 Message Date
can1357 fccc0ed3ce chore: bump version to 16.2.12 2026-07-01 05:29:19 +02:00
can1357 05c09f6191 chore: update chanelogs 2026-07-01 05:27:25 +02:00
can1357 763f950b7f fix: streamlined tool-call cloning and validation in the stream pipeline
- Improved the leaked-thinking stream projector to clone and sync native tool-call blocks directly.
- Eliminated the need for placeholder IDs and complex rekeying logic in the event controller and argument reveal module.
- Simplified native tool-call validation in owned-stream processing by requiring only a non-empty name.
- Added comprehensive unit tests to ensure tool-call IDs and partial JSON parameters remain intact during healing.
2026-07-01 05:25:27 +02:00
can1357 8e8c3e92ce Merge remote-tracking branch 'origin/farm/e0aafd27/cross-turn-tool-call-loop-guard' 2026-07-01 05:08:41 +02:00
can1357 d6e62591cf chore: update chanelogs 2026-07-01 04:47:55 +02:00
roboomp cf52840c18 fix(agent): detected repeated tool-call turns
Added a cross-turn tool-call loop guard that hashes canonical tool names and arguments, ignores intent metadata, and injects a hidden redirect when identical calls reach the configured threshold.

Fixes #3971
2026-07-01 02:47:08 +00:00
can1357 db8c79cc93 style: apply formatter and fix devin test enum
biome + cargo fmt over merge-sweep eval-fix commits; correct StopReason.END_TURN (nonexistent) to StopReason.FUNCTION_CALL in devin streaming test
2026-07-01 04:45:28 +02:00
can1357 ea36c7256a chore(changelog): normalize merge-sweep entries 2026-07-01 04:41:38 +02:00
can1357 eba952f027 test(ai): cover pi-native timeout progress reset 2026-07-01 04:40:55 +02:00
can1357 24a105377a test(ai): cover Devin arg parse throttling 2026-07-01 04:40:55 +02:00
can1357 7cb19a2d7f merge PR #3955: fix(ai): added pi-native stream timeouts 2026-07-01 04:40:39 +02:00
can1357 60530e20a1 merge PR #3952: fix(ai/providers): throttle Cursor and Devin tool-call arg parsing 2026-07-01 04:40:39 +02:00
roboomp 87575cf803 fix(ai): added pi-native stream timeouts
Added first-event and idle watchdogs to pi-native SSE reads and covered stalled gateway bodies.\n\nFixes #3947
2026-07-01 01:09:48 +00:00
roboomp 61fb0e41e9 style: bun run fix 2026-07-01 01:07:06 +00:00
roboomp df975796b8 fix(ai/providers): throttle Cursor and Devin tool-call arg parsing
Cursor and Devin called parseStreamingJson(accumulated) on every
tool-call argument delta, re-parsing the entire accumulated buffer each
chunk. For a payload of N bytes arriving as M small deltas this gave
~M full parses of an ever-growing buffer — O(N^2) total work — so
sizeable write/apply_patch arg blobs stalled streaming with visible
CPU cost and delayed toolcall_delta events.

Both providers now mirror the Anthropic / Bedrock / OpenAI pattern:
parseStreamingJsonThrottled with kStreamingLastParseLen persisted per
tool-call block, bounding mid-stream parse work to O(N). The
authoritative end-of-stream parse is unchanged (Devin's toolcall_end
loop; Cursor's toolCallCompleted mcp branch now runs a full
parseStreamingJson of the accumulated buffer before merging with the
completion frame, so the throttled tail is finalized correctly).

Fixes #3946
2026-07-01 01:06:54 +00:00
can1357 b2a859a7c5 chore: bump version to 16.2.11 2026-07-01 03:06:34 +02:00
can1357 4903ed5fe3 test(ai): updated tool call ID generation test for empty normalization scenarios
- Updated tests to verify tool_call_id generation when assistant and tool IDs normalize to empty strings.
- Added test assertions to ensure raw non-empty malformed IDs containing pipes do not leak through and instead use generated fallbacks prefixed with call_.
2026-07-01 03:06:10 +02:00
can1357 b92bd7d02c chore: update chanelogs 2026-07-01 02:58:17 +02:00
can1357 f2f62f9b8a Merge remote-tracking branch 'origin/farm/8b3cc0d0/increase-openai-stream-timeout' 2026-07-01 02:57:28 +02:00
can1357 c30526fe39 fix(ai): required non-empty name and id for native streaming tool calls
- Added `hasUsableNativeToolCall` helper to verify that a streaming tool call has non-empty, trimmed name and id values.
- Retain projection initialization and updates on subsequent deltas if the provider emits native tool identifiers late.
- Guard tool call synchronization and late salvage logic to prevent empty or invalid placeholders from corrupting streaming state.
2026-07-01 02:54:42 +02:00
roboomp db3acc6630 fix(catalog): widened local openai stream watchdogs
Widened local OpenAI-compatible stream watchdog defaults so llama.cpp and loopback providers can cold-load models without hitting the first-event abort.

Added regression coverage for both chat-completions and Responses compat.

Fixes #3940
2026-07-01 00:00:26 +00:00
can1357 ebdc7280cb chore: bump version to 16.2.10 2026-07-01 00:54:29 +02:00
can1357 92394f5c07 feat(ai): enabled streaming tool call argument deltas and validated identifier formats
- Streamed parameter chunk deltas as `toolArgDelta` events during execution for Anthropic and DeepSeek dialects.
- Integrated streaming tool call tracking in `InbandStreamProjector` to preserve native tool identifiers and partial JSON arguments.
- Added message validation functions to detect and drop malformed tool calls with empty or whitespace-only IDs.
- Introduced comprehensive suite of integration and unit tests validating argument delta streaming and tool-call sanitization.
2026-07-01 00:54:01 +02:00
can1357 cd81cc3967 fix(ai/dialect): prevented premature termination of nested thinking blocks
- Introduced the `FencedThinkingScanner` class to track nested Markdown code fences inside thinking blocks.
- Integrated the new scanner into Gemini and generic inband thinking parsers to prevent premature termination of thinking blocks.
- Added comprehensive unit and integration tests to validate nested fence retention and inline close resolution during stream parsing.
2026-06-30 21:27:12 +02:00
can1357 490662ab2e feat(ai/utils): increased the Gemini header runaway threshold
- Raised `GEMINI_HEADER_RUNAWAY_THRESHOLD` from 10 to 24 to avoid false-positive interrupts on legitimate, complex reasoning blocks.
- Added a regression test verifying that 10 distinct, progressing headers do not trip the detector while 24 headers still trigger it.
2026-06-30 20:27:52 +02:00
can1357 b6c9747d45 chore: bump version to 16.2.9 2026-06-30 18:01:59 +02:00
can1357 ac19fc1050 chore: update changelogs 2026-06-30 17:59:58 +02:00
can1357 224000ea1a Merge remote-tracking branch 'origin/farm/bfaba2dc/fix-mcp-oauth-escape-cancel' 2026-06-30 16:18:39 +02:00
can1357 51dbf94bc6 Merge remote-tracking branch 'origin/farm/40204cd0/harden-tool-call-json-parse-errors' 2026-06-30 16:17:31 +02:00
can1357 2c75ee5d38 Merge remote-tracking branch 'origin/farm/bcae1c50/fix-mcp-oauth-port-fallback' 2026-06-30 16:15:56 +02:00
roboomp 83f901d05f fix(ai): stripped transient flag for llama.cpp tool-call parse errors
- Added LLAMA_CPP_TOOL_CALL_PARSE_PATTERN and cleared Flag.Transient inside classifyMessage so the agent-level auto-retry no longer replays the same prompt against the same broken model state.

- Consolidated the duplicated detection pattern in the Ollama provider and the user-facing error rewrite to reuse the shared flags constant.

- Added a regression assertion that the finalized errorId is not Transient and not AIError.retriable for the malformed tool-call response.
2026-06-30 13:34:33 +00:00
roboomp cd6ba0214f fix(ai): hardened ollama malformed tool-call handling
- Added a fetchWithRetry response-body gate so deterministic 5xx provider failures can skip retry delays.

- Stopped retrying llama.cpp malformed tool-call JSON responses from local Ollama and surfaced recovery guidance.

- Covered the Ollama parse-failure path and generic retry gate behavior.

Fixes #3899
2026-06-30 13:20:11 +00:00
roboomp 3106a15f7d fix(mcp): raced oauth login against cancellation
Esc and wizard abort signals now race the MCP OAuth login promise directly, so cancellation wins even before OAuthCallbackFlow reaches its callback wait and registers an abort listener. OAuthCallbackFlow also checks pre-aborted signals before opening/waiting on the callback server and its wait path handles already-aborted signals.

Threaded the abort signal into MCP OAuth fetches so dynamic client registration, metadata discovery, authorization probes, and token exchange unblock promptly when the user cancels.

Added a regression test where MCPOAuthFlow.login never observes ctrl.signal, matching the pre-wait race called out in review.

Fixes #3888
2026-06-30 10:21:26 +00:00
roboomp 6f65772093 fix(mcp/oauth): preserved random-port fallback for fresh dynamic-client-registration flows
PR review pointed out that the unconditional opt-out blocks the safe case: when no static `client_id` is set, `MCPOAuthFlow.#tryRegisterClient` does DCR with whichever loopback URI we actually bound, so the provider issues a `client_id` tied to the fallback port and the authorize request is accepted. First-install users whose default port 3000 is busy could no longer authenticate.

Gate `allowPortFallback` on `staticClientIdFromConfig(config) === undefined`: pinned client ids (config-supplied or embedded in the authorization URL) keep the strict-port behavior that fixes #3887; unresolved client ids fall back as before. Factored the static client-id resolution into a module-level helper so `MCPOAuthFlow.#resolveClientId` and `resolveCallbackOptions` share the same logic.

Added an oauth-flow.test.ts case that wires a mock registration endpoint + occupies the preferred port and asserts the fallback URI is what DCR registers and what the authorize request advertises. Tightened the existing strict-port test's title to call out the static-clientId trigger.
2026-06-30 10:13:38 +00:00
roboomp d2c767507b fix(mcp/oauth): failed fast when callback port is busy instead of advertising a random one
When the MCP OAuth callback server's preferred port (default 3000) was unavailable, `OAuthCallbackFlow.#startCallbackServer` silently bound a random port and forwarded the mismatched `redirect_uri` to the authorization server. Providers that validate redirect URIs against a registered callback (e.g. Atlassian) returned an opaque HTTP 500, leaving the local flow waiting for a callback that never arrived until the 5-minute timeout fired.

Added `OAuthCallbackFlowOptions.allowPortFallback` (default `true`, preserving every existing AI-provider flow) and threaded `allowPortFallback: false` through `MCPOAuthFlow`'s `resolveCallbackOptions`. With fallback disabled, login now throws a `ConfigurationError` that names the busy port and the remediation (free the port, or set `oauth.callbackPort`/`oauth.redirectUri` in `mcp.json`) before opening the browser. The existing `oauth.redirectUri`-strict path is reworded along the same lines so callers see one consistent message family.

Fixes #3887
2026-06-30 10:05:24 +00:00
can1357 5bc68f57cd chore: bump version to 16.2.8 2026-06-30 11:58:55 +02:00
can1357 38250ce88b chore: bump version to 16.2.7 2026-06-30 07:20:23 +02:00
can1357 b704ac698a chore: update changelogs 2026-06-30 06:55:13 +02:00
can1357 093660f8b7 fix(ai): restricted reasoning context all_turns option to openai models v5.4 and newer
- Guarded the `all_turns` reasoning context value to OpenAI models version 5.4 or greater.
- Suppressed `reasoning.context` defaults and explicit overrides when `all_turns` is requested on unsupported models to prevent server rejection.
- Introduced `supportsAllTurnsReasoningContext` helper in `@oh-my-pi/pi-catalog/identity` using semver classification.
- Updated request-transformer and response-options logic to conditionalize the request payload shaping.
- Expanded test coverage to verify correct fallback behavior and explicit overrides across gpt-5.x versions.
2026-06-30 06:42:46 +02:00
can1357 bebdd22e64 fix(ai): healed leaked reasoning fences live for every provider
- Added `leaked-thinking-stream.ts` whose `wrapLeakedThinkingStream`/`LeakedThinkingProjector` re-projects any provider stream, splitting leaked ```thinking`/`<think>` fences out of the visible-text channel into structured thinking blocks live while preserving text/thinking/tool signatures.
- Wrapped the shared `withProviderInFlightLimit` dispatch (both the unlimited and queued paths) and the standalone GitLab Duo path in `stream.ts` so healing covers every provider exit idempotently.
- Reworked `google-gemini-cli.ts` visible-text emission onto `StreamMarkupHealing` with `feedVisibleText`/`flushVisibleText` and explicit block bookkeeping, lifting leaked Gemini fences ahead of native tool calls.
- Added `leaked-thinking-stream` coverage and a gemini-cli healing case, and updated `stream-auth-retry`/`google-gemini-cli-alignment` expectations for the healed event sequence and dropped empty-text residue.
- Recorded the changelog `### Fixed` entry (whose run also carries the adjacent Codex `all_turns` line).
2026-06-30 06:38:25 +02:00
can1357 d01bf079ef feat(ai): added google interactions api transport
- Added `google-interactions.ts` streaming the Gemini Interactions API (model-mode steps, thought/tool/text deltas, usage, `previous_interaction_id` lineage) shared by the direct Google and Vertex providers.
- Routed `streamGoogle` and `streamGoogleVertex` through `resolveInteractionDispatch`, defaulting Gemini 3+ onto Interactions (official endpoint for direct Google, bearer/ADC for Vertex) with transparent `:streamGenerateContent` fallback and a `useInteractionsApi: false` opt-out.
- Added explicit Vertex bearer support in `google-auth.ts` via `GOOGLE_CLOUD_ACCESS_TOKEN`/`CLOUDSDK_AUTH_ACCESS_TOKEN` plus a `hasVertexBearerCredentialsHint` probe gating the auto-default.
- Added `useInteractionsApi`/`storeInteraction`/`previousInteractionId` to `StreamOptions` and `GoogleSharedStreamOptions`, threading them through `mapOptionsForApi`.
- Added `google-interactions` coverage and pinned the existing generateContent assertions with `useInteractionsApi: false`.
2026-06-30 06:37:04 +02:00
can1357 b87110c66b fix(ai): preferred explicit env api key over stored static key
- Reordered `AuthStorage.getApiKey` and its async session variant to resolve stored OAuth, then an env var, then a stored static api_key — so an explicit `GEMINI_API_KEY`-style env var now wins over a stale broker-migrated key.
- Reworked `getCredentialOrigin` and `getApiKeySource` to mirror that precedence via a `describeStored` helper, reporting `oauth`/`env`/`api_key` in the new order.
- Updated `auth-storage-api-key-login` to neutralize ambient env keys with a `getEnvApiKey` spy, and `auth-storage-credential-origin` to assert OAuth outranks api_key and env outranks a stored api_key.
2026-06-30 06:34:07 +02:00
can1357 a8381f4945 Merge remote-tracking branch 'origin/farm/f4507d84/cerebras-gemma-vision' 2026-06-30 06:33:47 +02:00
roboomp 2b944114fb fix(catalog): marked cerebras gemma vision capable
Mapped Cerebras gemma-4-31b dynamic discovery to include image input capability and covered the OpenAI Chat Completions image_url serialization path.

Fixes #3854
2026-06-30 02:48:08 +00:00
can1357 6b64ed0ff6 feat(ai/providers): added global fallback for regional vertex endpoints
- Introduce `fallbackUrl` to allow retrying requests on the global Vertex endpoint when a 404 is encountered on a regional endpoint.
- Correctly track tool call names to facilitate accurate function response mapping.
- Update `serviceTier` type definitions to accurately reflect allowed values.
- Refine vertex endpoint location resolution to ensure better compatibility with ambient regional settings.
2026-06-30 04:48:01 +02:00
can1357 f18368d1f7 Merge remote-tracking branch 'origin/farm/5ff08fcf/fix-kimi-title-thinking' 2026-06-30 04:46:18 +02:00
roboomp 7cab14d963 fix(catalog): gated kimi K2.7 Code thinking-required policy on native Moonshot/Kimi-code host
Reviewer flagged that the omit/forced-tool gate matched every public id, regressing Fireworks and OpenRouter Kimi K2.7 Code (non-zai dialects).

Added Fireworks + OpenRouter regression coverage.
2026-06-30 02:30:40 +00:00
roboomp fa2e3a807f style: bun run fix 2026-06-30 02:26:10 +00:00
can1357 d20e6c0829 feat: migrated service tier settings to a per-model-family architecture
- Migrated global service tier settings to a per-model-family architecture (OpenAI, Anthropic, Google).
- Implemented `ServiceTierByFamily` mapping to allow independent configuration and resolution per provider.
- Added automatic migration logic for legacy service tier and fast-mode application settings.
- Updated telemetry, session management, and task execution to support provider-specific tier resolution.
2026-06-30 04:14:48 +02:00
roboomp 1db1e9e200 fix(catalog): omitted disabled thinking for kimi code
Kimi K2.7 Code rejects disabled thinking on native Kimi endpoints, so route caller disable requests through the omit mode and let the model default to required thinking.

Added regression coverage for the title-generator-style Kimi Code request, Moonshot K2.7 Code variants, and K2.6's still-supported disabled-thinking path.

Fixes #3852
2026-06-30 02:12:51 +00:00