scripts/generate-models.ts: moved the Groq Qwen reasoning-level compatibility override from the removedqwen/qwen3-32bcatalog entry to the active multimodalqwen/qwen3.6-27breplacement.test/openai-completions-tool-choice.test.ts: moved the focusedreasoning_effortrequest regression to the same generated model ID.src/providers/data/*.json: refreshed the reviewed live provider snapshots so strict release generation and checked-in model-ID types agree.
- models.dev removed Qwen 3.2 after Groq's first-party model endpoint replaced it with Qwen 3.6. The release
generator therefore removed the old typed ID, while the compatibility regression still referenced it, causing
the
2026.8.4-2release to fail during root TypeScript validation before any commit or tag was created. - Groq documents Qwen 3.6 thinking mode as
reasoning_effort: "default"and non-thinking mode as"none", so the existing compatibility mapping remains required on the replacement model.
- Model inventory and provider-specific reasoning metadata are generated before the coding-agent extension runtime loads, and the typed built-in model IDs are consumed by the AI package itself.
scripts/generate-models.tstest/openai-completions-tool-choice.test.tssrc/providers/data/*.json
- MEDIUM: the Groq branch of
applyThinkingLevelMetadata()when upstream changes Qwen reasoning controls. - MEDIUM: generated provider JSON whenever models.dev, OpenRouter, or OpenCode metadata changes again.
- Restored
getOpenAICompletionsCompatas the single compatibility resolver used and exported by the OpenAI Completions adapter. - Ported upstream Z.AI
max_tokensselection into the shared resolver. - Preserved both automatically detected and explicitly configured
toolSchemaFlavorvalues, with focused Moonshot coverage.
- The merge restored an upstream-local adapter resolver beside the fork's shared browser-safe resolver. The duplicate omitted Moonshot schema flavor selection, so wire-bound tool schemas retained an unsupported root
anyOfwrapper. - Keeping one resolver prevents API and browser-safe compatibility decisions from diverging again.
- Provider compatibility selection and final wire-payload schema normalization occur inside the provider adapter before extension hooks can safely compensate.
src/api/openai-completions.ts,src/utils/prompt-cache-ttl.ts, OpenAI compatibility types, and tool-schema/prompt-cache tests.
test/live-api-gates.ts: owns Ollama discovery behind a gate that short-circuits before probing unlessPI_ENABLE_LOCAL_LLM=1orPI_ENABLE_LIVE_API_TESTS=1, usingwhere ollamaon Windows andwhich ollamaelsewhere.test/live-api-gates.test.ts: mocks the command boundary and covers the default no-probe behavior, both explicit opt-in paths, and both platform-specific lookup commands.test/stream.test.ts: uses the gated Ollama discovery function instead of treating the absence ofPI_NO_LOCAL_LLMas permission to probe and run the live suite.../../test.sh: clears the two opt-in flags instead of exporting the retiredPI_NO_LOCAL_LLMopt-out flag.
- A normal
npm teston a machine with Ollama installed could enter the live suite, pullgpt-oss:20b, start a local server, and load a large model without explicit consent. Default workspace tests must not probe or start local model infrastructure.
- This behavior occurs during
packages/aiVitest discovery and setup, before the coding-agent extension surface is involved.
test/live-api-gates.test.tstest/live-api-gates.tstest/stream.test.ts../../test.sh
- LOW:
test/live-api-gates.tsand its tests may conflict if upstream changes live-test activation helpers. - MEDIUM: the Ollama discovery and setup block in
test/stream.test.tsmay conflict if upstream changes how the local OpenAI-compatible test server is detected or started. - LOW:
../../test.shmay conflict if upstream changes its isolated live-test environment variables.
- Shared
xhigh/maxmodel-family constants are hoisted inmodels.ts, and map-less inference now uses one case-normalized, boundary-aware family matcher instead of unbounded substring checks. getSupportedThinkingLevelsdelegates extended-tier precedence to the exportedsupportsXhighandsupportsMaxpredicates rather than duplicating their map-omission andnull-veto rules.
- Capability inference for custom map-less models should reject unrelated ids and case-normalize legitimate aliases while keeping one precedence implementation. Generated catalog models retain their explicit maps, so behavior for real catalog models is intentionally unchanged.
src/utils/prompt-cache-ttl.ts(new):resolvePromptCacheTtlSeconds(model, env?) -> number | undefinedplusPROMPT_CACHE_TTL_SHORT_SECONDS(300) /PROMPT_CACHE_TTL_LONG_SECONDS(3600). It mirrors EACH target API's ownresolveCacheRetentionprecedence verbatim rather than inventing a unified one: anthropic-messages falls back to"long"and honors the bareprocess.env.PI_CACHE_RETENTIONset-but-not-long branch; openai-completions / openai-responses / bedrock fall back to"short"; pi-messages returnsundefined(backend default). Retention"none"and every API with unknown cache semantics (google, mistral, pi-messages, unknown) resolve toundefined.- The pure compat predicates the resolver needs moved INTO that browser-safe utility and the API modules now
import them from there and re-export for their existing consumers:
getAnthropicCompat+isAnthropicApiBaseUrl(fromsrc/api/anthropic-messages.ts), the resolved-compat getter (fromsrc/api/openai-completions.ts), andsupportsPromptCaching(fromsrc/api/bedrock-converse-stream.ts). src/index.tsexports the new module from the browser-safe root surface.
- senpi sizes how long its
bashtool and omo'stasktool may block in the foreground on the active model's prompt-cache lifetime. That lifetime is already decided per provider inside this package, so one shared resolver here is the single source of truth instead of a table duplicated in every consumer.
- The root surface is browser-safe. Importing
supportsPromptCachingdirectly fromsrc/api/bedrock-converse-stream.tspulled the AWS SDK (@smithy/node-http-handler,agent-base,http-proxy-agent) into the browser bundle and brokenpm run check:browser-smokewith 18 unresolvednode:*errors. Moving the pure predicates into the utility and re-exporting from the API modules keeps one definition with no divergence risk, and keeps the root import graph free of Node-only dependencies.
src/api/anthropic-messages.tssrc/api/bedrock-converse-stream.tssrc/api/openai-completions.tssrc/index.ts
- MEDIUM: each API module's
resolveCacheRetention/ compat-getter region, where the local definition became an import + re-export. If upstream edits those predicates, port the edit intosrc/utils/prompt-cache-ttl.tsso the resolver and the adapters stay in agreement.
scripts/generate-models.ts:isAnthropicAdaptiveThinkingModelandisAnthropicTemperatureUnsupportedModelnow match Opus 5 ids, and Opus 5 joins the nativexhigh/maxeffort ladder alongside Opus 4.7/4.8 and Sonnet 5.src/api/anthropic-messages.ts:ADAPTIVE_THINKING_MODEL_MARKERSgainedopus-4-8andopus-5, andmapThinkingLevelToEffortmaps Opus 5xhigh/maxto native efforts instead of collapsing them tohigh.src/providers/data/*.json: regenerated so every provider that serves Opus 5 (anthropic, github-copilot, opencode, vercel-ai-gateway, openrouter, amazon-bedrock) carriesforceAdaptiveThinking,supportsTemperature: false, and thexhigh/maxthinking level map.
- Opus 5 is adaptive-thinking only. Sending it the legacy
thinking: { type: "enabled", budget_tokens }payload is accepted by the API but produces a thinking block with no thinking text, so the model answers as if reasoning were disabled. Measured against the live API: legacy payload returned 0 thinking characters, whilethinking: { type: "adaptive" }on the same prompt returned real thinking content. - Without markers or catalog metadata,
supportsAdaptiveThinking()fell through to the legacy branch for every provider whose Opus 5 entry had nocompat, including proxy providers. - Opus 5 also honors native
xhighandmaxeffort, and they scale reasoning materially (measured on one prompt: high 849 thinking chars, xhigh 1123, max 3217). Mapping both down tohighsilently capped the model.
- Adaptive-thinking detection and effort mapping happen while building the Anthropic Messages payload inside
packages/ai, below any extension-visible surface, and the model catalog is generated build-time data.
scripts/generate-models.tssrc/api/anthropic-messages.tssrc/providers/data/*.json
- LOW: marker/predicate lists are append-only additions next to existing Opus/Sonnet entries.
- MEDIUM: regenerated provider data files conflict textually whenever upstream regenerates the same catalogs.
src/context-provenance.ts: added request-local, non-enumerable message/item provenance tokens.src/api/openai-responses-shared.ts: preserves those tokens while converting messages to Responses input items.src/types.tsandsrc/index.ts: expose the typed provenance helpers needed by coding-agent's replay boundary.src/utils/openai-codex-auth.ts: centralizes browser-safe ChatGPT account-ID extraction so normal Codex requests and remote compaction canonicalize the same wire tenant across bearer-token refreshes.
- Provider-wire value equality cannot distinguish duplicated messages after filtering or injection. Replay slicing now requires the exact checkpoint-origin identities to survive the canonical context pipeline.
- The provenance must survive conversion inside
packages/ai, below extension-visible provider payloads.
src/api/openai-responses-shared.tssrc/index.tssrc/types.tssrc/utils/openai-codex-auth.ts
- MEDIUM: Responses message conversion and shared public types.
src/index.ts: exportsconvertResponsesMessagesfrom the browser-safe root so coding-agent remote-compaction replay can locate checkpoint boundaries with the exact conversion semantics used by the real provider pipeline.
- Counting checkpoint items with a separate converter could drop or duplicate the current prompt when errored/aborted assistants, orphaned tool results, empty users, or provider-native blocks changed item cardinality.
- The boundary is defined by the provider wire conversion in
packages/ai, below the coding-agent extension layer.
src/index.ts
- LOW: root exports if upstream reorganizes OpenAI Responses helpers.
../../.gitignore: removed thepackages/ai/src/providers/data/ignore rule so generated catalog JSON is committed, reviewed source, matchingsrc/models.generated.ts.package.json: the ordinarybuildno longer runsgenerate-models; it compiles, restores the CLI executable bit, and copies the committedsrc/providers/data/intodist. Networked regeneration stays explicit via thegenerate-modelsscript, the rootgenerate:modelsworkflow, release tooling, andprepublishOnly.../../scripts/build-all.test.mjs: the AI build config regression now asserts the ordinary build skips networked generation, keeps the committed-data copy step, retains the explicit generator workflow, and leaves catalog JSON unignored.README.md: model-generation guidance now describessrc/providers/data/as committed generated values.
- The ordinary AI build fetched models.dev and provider APIs to regenerate ignored JSON catalog data, so a build could
emit an unreviewed or different catalog and failed entirely offline. The committed
.models.tsshards import the JSON at compile time, so the catalog must be committed generated source for the build to be reproducible.
- Model inventory is generated before the coding-agent extension runtime is loaded, and package build scripts run before any extension hook exists.
package.jsonREADME.md../../.gitignore../../scripts/build-all.test.mjs
- LOW: AI package build scripts if upstream changes the compiler command or bin generation flow.
scripts/generate-models.ts: added fallback metadata forkimi-for-codingandkimi-k2-thinkingthat livemodels.devmetadata can override but cannot silently remove.
- Senpi's public model catalog and provider regressions still support these IDs. A transient upstream catalog omission caused release-time model regeneration to remove them and fail static validation.
- Model inventory is generated before the coding-agent extension runtime is loaded.
scripts/generate-models.ts
- MEDIUM: the Kimi Coding generation block if upstream changes alias or fallback handling.
package.json: ordinary AI builds now restore the executable bit ondist/cli.js, matching the existing publish-only safeguard.../../scripts/build-all.test.mjs: added a regression assertion for the executable-bit build step.
- TypeScript can rewrite
dist/cli.jswith mode0644when AI sources change. The release workflow runs an ordinary build before staging its release commit, so that rewrite could silently reverse the tracked executable mode.
- This is package build and release behavior that runs before the coding-agent extension system is loaded.
package.json../../scripts/build-all.test.mjs
- LOW: AI package build scripts if upstream changes the compiler command or bin generation flow.
scripts/generate-models.ts: accepted upstream removal of stale model metadata fallbacks, including Copilot Sonnet 5 fallback cleanup.- Updated focused AI regression tests covering Fireworks model routing, GitHub Copilot OAuth, delayed device-code polling, and OpenAI Codex stream request-body handling.
- The fork should now rely on live/generated model metadata instead of keeping stale fallback entries, while preserving coverage for provider behavior touched by the upstream sync.
- Model generation is a build-time catalog script, and the changed tests assert provider/library behavior outside the coding-agent extension runtime.
scripts/generate-models.tstest/fireworks-models.test.tstest/github-copilot-oauth.test.tstest/oauth-device-code.test.tstest/openai-codex-stream.test.ts
- MEDIUM:
scripts/generate-models.tsif upstream changes provider metadata fetch or fallback handling again. - LOW: focused provider tests if upstream changes request decoding, OAuth polling timing, or Fireworks model mappings.
test/live-api-gates.ts: Added shared live-test gate helpers. Ambient provider keys and local model probes are ignored unlessPI_ENABLE_LIVE_API_TESTS=1or the provider-specific flag is set.test/oauth.ts: OAuth tokens from~/.pi/agent/auth.jsonnow resolve only for explicitly enabled live OAuth test providers.- OpenRouter live suites in image, streaming, context-overflow, total-token, and thinking-disable tests now require
PI_ENABLE_OPENROUTER_LIVE=1in addition to a key. - Local context-overflow suites now require
PI_ENABLE_LOCAL_LLM=1, matching the existing fork policy that local model servers must be explicit opt-in.
npm test --workspaces --if-presentmust pass in developer environments that contain stale or unrelated credentials and local model daemons. An invalid ambientOPENROUTER_API_KEY, stale Anthropic OAuth token, and empty LM Studio server caused live suites to run and fail for reasons unrelated to the code under test.
- These are
packages/aiintegration-test activation rules. Extension hooks are not involved in test discovery or live provider credential resolution.
test/oauth.tstest/context-overflow.test.tstest/google-thinking-disable.test.tstest/image-tool-result.test.tstest/images.test.tstest/live-api-gates.test.tstest/live-api-gates.tstest/stream.test.tstest/total-tokens.test.ts
- Upstream currently gates many live suites directly on credential presence. Rebase conflicts are likely in any live provider test that changes
describe.skipIf(!process.env.<KEY>)conditions or OAuth token bootstrapping.
test/tool-call-id-normalization.test.ts: the OpenRoutergpt-5.2-codexcases now passreasoning: "high"so the live regression test still exercises tool-call ID normalization against the endpoint's current reasoning requirement.test/cross-provider-handoff.test.ts: the minimum-fixture assertion now exits early when fewer than two live fixtures are actually generated, so the suite skips gracefully in environments without enough working provider credentials.test/bedrock-utils.ts: Bedrock live tests now require both credentials and an explicit AWS region before enabling.test/context-overflow.test.ts: the OpenRouter Anthropic overflow case now accepts the provider's current managed-overflow behavior, and LM Studio overflow tests only auto-enable whenPI_ENABLE_LOCAL_LLM=1.test/openrouter-cache-write-repro.test.ts: the narrow OpenRouter cache-write regression is now explicit opt-in viaPI_ENABLE_OPENROUTER_CACHE_WRITE_REPRO=1.test/total-tokens.test.ts: the unstable OpenRouterdeepseek/deepseek-chattotal-token regression is now explicit opt-in viaPI_ENABLE_OPENROUTER_DEEPSEEK_TOTAL_TOKENS=1.
- OpenRouter now rejects
openai/gpt-5.2-codexrequests when reasoning is omitted or disabled, which broke the normalization regression for reasons unrelated to tool-call ID handling. - The cross-provider handoff suite assumes multiple working live providers, but
npm test --workspaces --if-presentmust pass even when the environment has no valid API keys (or only a partial/invalid live setup). - Ambient Bedrock tokens without a region and auto-detected local model servers were causing unrelated live E2E suites to run in non-reproducible environments.
- A few narrow OpenRouter regressions are currently backend-specific and unstable in shared environments, so they now require explicit opt-in instead of making the default workspace test command flaky.
These failures are in upstream packages/ai live integration tests, not in the coding-agent extension surface. Fixing them required targeted test-only updates in packages/ai/test/.
test/tool-call-id-normalization.test.tstest/cross-provider-handoff.test.tstest/bedrock-utils.tstest/context-overflow.test.tstest/openrouter-cache-write-repro.test.tstest/total-tokens.test.ts
test/tool-call-id-normalization.test.ts: OpenRouter live test options may need re-merging if upstream changes the regression coverage or request options.test/cross-provider-handoff.test.ts: fixture-count gating may need re-merging if upstream restructures the live handoff bootstrap assertions.test/bedrock-utils.ts: credential gating may need re-merging if upstream changes how Bedrock test auth is detected.test/context-overflow.test.ts: OpenRouter overflow handling and local-LM opt-in logic may need re-merging if upstream revises those E2E expectations.test/openrouter-cache-write-repro.test.tsandtest/total-tokens.test.ts: explicit opt-in guards may need re-merging if the affected OpenRouter backends become stable again.
- Replaced the
tsgocompiler invocation withtscin thebuild,build:offline,dev,dev:tsc, andprepublishOnlyscripts; all flags and arguments remain unchanged. - Bumped the root
typescriptpin from6.0.3to7.0.2. - Dropped the
@typescript/native-previewtoolchain dependency. - Added
@typescript/typescript6@6.0.2(Microsoft's official TypeScript-6 API bridge) soscripts/check-ts-relative-imports.mjskeeps working: TypeScript 7 removed the classic programmatic JS API it imported. - Added
@typescript/native: npm:typescript@7.0.2as a scoped alias. Thetypescript6package publicly depends on@typescript/old(typescript 6.x), and npm hoists it; alphabetically@typescript/oldbeatstypescriptfor thenode_modules/.bin/tsclink, which would make every baretscinvocation (root check and all package builds) silently run the TypeScript 6 compiler. The alias sorts after@typescript/old, so it deterministically wins the.bin/tsclink to the 7.0.2 native compiler. It is a bin-ownership pin, not an import target.
- Adopt a stable-first toolchain policy: use the released
typescript@7.0.2native compiler for package builds and typechecks instead of the experimentaltsgodev build. - The
native-previewcompiler has been retired upstream in favor oftypescript@next.
- Build scripts and
devDependenciesare package infrastructure, not runtime behavior; extensions cannot rewrite another package's manifest scripts or compiler selection.
package.jsonscriptsblocks anddevDependenciesanywhere upstream still referencestsgoor@typescript/native-preview.