Commit Graph

4519 Commits

Author SHA1 Message Date
Mario Zechner 827fe1e2c4 feat(ai): ImagesModels collections mirroring the chat-side design
createImagesModels()/ImagesProvider/createImagesProvider() give image
generation the same shape as chat: sync model reads, explicit async
refresh(provider?) with in-flight dedupe, provider-resolved auth, and
never-rejecting generateImages() (failures return AssistantImages with
stopReason error). Auth resolution is shared with the chat side via the
free-standing resolveProviderAuth() in auth/resolve.ts, which also owns
ModelsError; both collections pass their store/context as arguments.

The OpenRouter implementation moves to api/openrouter-images.ts with a
lazy wrapper; openrouterImagesProvider() factory plus
builtinImagesProviders()/builtinImagesModels() land in providers/all.
The ImagesProvider id type alias is renamed to ImagesProviderId
(mirror of Provider -> ProviderId). The old global image API
(getImageModel*, generateImages, registerImagesApiProvider) stays on
/compat, its registration shim repointed at the moved implementation.

README: Quick Start uses builtinModels(), the full streaming event
switch, image generation and the development checklist are restored in
full, image generation documents the new collections with compat noted
for the old API, plus the review fixes (builtinModels options,
credential-store mention for browsers, ImagesModels notes).
2026-06-11 00:27:43 +02:00
Mario Zechner e1283fc17a docs(ai): rewrite README around the Models API
Quick Start, querying, auth, OAuth, custom providers, faux, handoffs,
browser usage, and the dev checklist now demonstrate createModels() +
provider factories: sync model reads with explicit refresh, provider-
owned auth resolution (getAuth, credential store, env tables),
OAuthAuth login/refresh with prompt()/notify() callbacks, and
createProvider() for custom/dynamic providers (replacing bare Model +
global stream). Direct API implementation calls documented under the
canonical ./api/<id> subpaths with the legacy aliases noted.

The old global API is documented once, in a migration section pointing
at /compat with an old-to-new mapping table. Image generation is
documented as living on compat for now. All import/code claims
verified with a compile-and-run smoke script.
2026-06-10 23:37:11 +02:00
Mario Zechner 6e98573f24 feat(ai): sync model reads, explicit async refresh
Provider.getModels() is sync-only (last-known list; must not throw) with
an optional refreshModels() where dynamic providers fetch. The
sync-or-async union invited latent sync assumptions that would detonate
on the first dynamic provider; async-only reads would force sync
consumer surfaces (extension find/getAll) through Promises. Sync reads
plus an explicit refresh verb keeps the contract single and the
staleness visible.

Models.getModels()/getModel() are sync best-effort reads;
Models.refresh(provider?) rejects with ModelsError(model_source) for a
single provider and is concurrent best-effort across all providers.
createProvider() takes a models array plus an optional refreshModels
fetcher (stored on success, in-flight calls deduped, list unchanged on
rejection). forceRefresh options are gone.

Also finishes the in-progress AuthStorage fallbackResolver removal
(drops the now-unused includeFallback option from getApiKey).
2026-06-10 23:30:04 +02:00
Mario Zechner 9ab1292679 feat(agent): Models is the harness's only auth path
Remove AgentHarnessOptions.getApiKeyAndHeaders: turn streaming,
compaction, and branch summarization resolve auth exclusively through
the injected Models instance. compact()/generateSummary()/
generateBranchSummary() lose their explicit apiKey/headers parameters.
2026-06-10 21:39:13 +02:00
Mario Zechner 10a575b76b docs: changelogs and phase restructure for the models refactor (phase 8)
Breaking-change entries with migration guides: pi-ai (compat
entrypoint, Provider -> ProviderId, api module moves, new Models/
provider/auth API), agent (required AgentHarnessOptions.models,
compaction signatures, structural StreamFn), coding-agent (extension
author note: runtime unaffected via loader compat alias).

models.md: Phase 7 closed out (import switch landed with phase 5; the
gated bullets move to a new Phase 9 ModelManager-migration outline:
per-session Models, AgentSession streaming, AuthStorage replacement,
login UI on OAuthAuth, cloudflare cleanup, internal compat removal,
compat deletion).
2026-06-10 21:31:56 +02:00
Mario Zechner f0ccbbf011 feat(agent): AgentHarness streams through a required Models instance (phase 6)
AgentHarnessOptions.models is required; the harness stream path,
compaction, and branch summarization go through models.streamSimple()/
completeSimple() instead of the compat globals. getApiKeyAndHeaders
stays and wins per-field over provider-resolved auth, but is no longer
required: without it, requests resolve through provider auth.

compact()/generateSummary()/generateBranchSummary() take a Models
parameter; explicit apiKey becomes optional. StreamFn is redefined
structurally (Models.streamSimple satisfies it), dropping the compat
type dependency from agent types.

Harness tests build per-file Models collections with fauxProvider()
and unique provider ids instead of mutating the global api-registry.
2026-06-10 21:27:21 +02:00
Mario Zechner 8a0903ebf2 feat(ai): compat entrypoint, core-only root barrel (phase 5)
The root barrel is now core-only and side-effect free: types,
createModels/createProvider, auth substrate, lazyStream/lazyApi, faux,
utils. Generated catalogs, api-registry, env-api-keys, images, global
stream functions, and per-API lazy wrappers leave the root.

New @earendil-works/pi-ai/compat preserves the old surface verbatim as
a strict superset of the root: api-dispatch stream/complete with env
key injection, the builtin registration side effect (skip-if-present so
it cannot clobber earlier overrides), deprecated getModel/getModels/
getProviders aliases of the new getBuiltin* reads in providers/all,
lazy api wrappers + setBedrockProviderModule, and image generation.
Compat dies with the coding-agent ModelManager migration.

Packaging: exports map gains ./compat, ./providers/*, ./api/*;
sideEffects array lists only the effectful modules.

Old-global imports across agent/coding-agent/examples and pi-ai tests
switch to /compat (path-only; compat is a superset). The coding-agent
extension loader resolves the pi-ai ROOT specifier to compat, so
existing user extensions using the old global API keep working at
runtime until compat is removed. vitest configs alias /compat to src;
browser smoke imports old globals from /compat.
2026-06-10 21:17:12 +02:00
Mario Zechner 4d5c015820 feat(ai): adapt OAuth flows to OAuthAuth (phase 4)
anthropic, openai-codex, and github-copilot flow modules gain OAuthAuth
exports (login/refresh/toAuth) wired to the prompt()/notify() login
callbacks, making the lazyOAuth attachments on the provider factories
functional. Copilot's modifyModels baseUrl rewriting becomes toAuth()
returning ModelAuth.baseUrl derived from the token proxy endpoint.

Callback-server flows race a manual_code prompt and abort it through
AuthPrompt.signal once the flow settles; OAuthAuth has no
usesCallbackServer flag. The old OAuthProviderInterface exports stay
unchanged until the coding-agent migration.
2026-06-10 20:41:29 +02:00
Mario Zechner fec0c3d12f feat(ai): provider factories, per-provider catalogs, createProvider (phase 3)
Auth helpers in src/auth/helpers.ts: envApiKeyAuth() (stored key wins,
then env vars in order, with secret-prompt login) and lazyOAuth()
(flow loads on first use through bundler-opaque dynamic imports in
utils/oauth/load.ts; the OAuthAuth flow exports land in phase 4).
There is no OAuth factory toggle: providers that support OAuth always
attach it, advertising costs nothing until login/refresh runs.

createProvider() in models.ts builds providers from parts: single API
implementation or a map dispatched on model.api (mixed-API providers
like opencode and github-copilot); unknown api yields a stream error.

generate-models.ts now emits one providers/<id>.models.ts catalog per
provider (35 files, biome-excluded like models.generated.ts) and
models.generated.ts becomes a generated aggregator, so importing one
provider factory pulls one catalog. Typed getModel globals unchanged.

One factory per built-in provider under src/providers/: envApiKeyAuth
for standard providers, OAuth for anthropic/openai-codex/github-copilot,
ambient ApiKeyAuth for amazon-bedrock (AWS env/profile/IAM) and
google-vertex (explicit key or ADC+project+location).

providers/all.ts: builtinProviders(), builtinModels(), getBuiltin*
re-exports. fauxProvider() factory returns a real Provider for tests;
legacy registerFauxProvider() unchanged.
2026-06-10 20:33:20 +02:00
Mario Zechner afc2bd370e fix(coding-agent): use physical temp paths in session-id-readonly test
On macOS tmpdir() is a symlink (/var -> /private/var) while the spawned
CLI's process.cwd() is physical, so session cwd filtering never matched
the fixtures and the fork-target rejection test failed locally.
2026-06-10 20:09:18 +02:00
Mario Zechner a46f4e19f0 fix: unset NVIDIA_API_KEY and ANT_LING_API_KEY in test.sh
stream.test.ts gates e2e suites on these env vars; test.sh missed them,
so local runs with the keys present executed live NVIDIA NIM e2e
tests.
2026-06-10 20:09:16 +02:00
Mario Zechner 20a9b82cf9 fix(ai): regenerate model catalog
Picks up the Claude Fable 5 thinking-off metadata (off: null in
thinkingLevelMap) that 9ccfcd7c added to the generator without
regenerating, fixing anthropic-thinking-disable and supports-xhigh
tests. Includes upstream catalog drift; OpenRouter delisted
moonshotai/kimi-k2.6:free, so the kimi compat test now pins only the
listed variant.
2026-06-10 20:09:13 +02:00
Mario Zechner ba93da9a93 feat(ai): move API implementations to src/api with lazy wrappers (phase 2)
Stream implementations move from src/providers/ to src/api/, renamed by
API id (anthropic.ts -> anthropic-messages.ts, google.ts ->
google-generative-ai.ts, mistral.ts -> mistral-conversations.ts,
amazon-bedrock.ts -> bedrock-converse-stream.ts). Every module now
exports exactly stream/streamSimple; shared helpers move alongside.

New ProviderStreams dispatch contract in types.ts, lazyApi() wrapper in
api/lazy.ts, and one .lazy.ts wrapper per API. Bedrock's wrapper keeps
the node-only variable-specifier import and setBedrockProviderModule()
(now taking ProviderStreams).

providers/register-builtins.ts deleted; interim until the compat
entrypoint lands, builtin api-registry registration lives in stream.ts
and lazy wrappers are exported from the root barrel. Old per-API lazy
exports (streamAnthropic, ...) are gone; package.json subpaths retarget
to dist/api/.
2026-06-10 20:08:59 +02:00
Mario Zechner ee276e4db5 Merge remote-tracking branch 'origin/main' into model-registry 2026-06-10 18:49:18 +02:00
Mario Zechner f63095cfff feat(ai): add Models runtime with provider-owned auth (phase 1)
New Models/MutableModels/createModels collection: provider map, async
model listing (best-effort aggregation), getAuth decision tree with
double-checked locked OAuth refresh, stream/complete with per-field
auth merge over lazyStream.

Auth substrate: ProviderAuth { apiKey?, oauth? }, one type-tagged
credential per provider, CredentialStore (read/modify/delete; modify
is the only write path, serialized RMW), OAuthAuth login/refresh/toAuth
split, prompt()/notify() login callbacks, browser-safe default
AuthContext.

types.ts: Provider alias renamed to ProviderId; ApiOptionsMap and
ApiStreamOptions<TApi> for typed per-API stream options; hasApi()
runtime narrowing guard.
2026-06-10 18:49:10 +02:00
Vegard Stikbakke 0ab2aa86af feat(coding-agent): add experimental first-time setup flow (#5587)
Behind PI_EXPERIMENTAL=1, show a first-time setup dialog on interactive startup when the default agent directory is used and settings.json does not exist. The dialog preselects the detected terminal appearance with an explicit dark/light choice (live preview) and asks for opt-in analytics data sharing. Submitting writes settings.json, which serves as the completion marker; opting in stores a generated trackingId. Escape at any point skips out of setup.
2026-06-10 12:11:49 +02:00
Mario Zechner a3cd03e7ff Merge pull request #5585 from haoqixu/fix-editor-cjk-wrap
fix(tui): wrap CJK text at character boundaries in editor
2026-06-10 11:43:42 +02:00
Mario Zechner 2f5066d7a0 Merge pull request #5562 from Perlence/fix-tui-render-loose-lists
fix(tui): separate list items with blank lines in loose lists
2026-06-10 11:42:12 +02:00
Mario Zechner e537dba3de Merge pull request #5561 from unexge/push-lpxyxwstnswr
feat(ai): link AWS data retention docs in Bedrock validation errors
2026-06-10 11:41:29 +02:00
Mario Zechner 9fd75b8acb Merge pull request #5560 from haoqixu/fix-5552
fix(coding-agent): parse :thinking suffix from custom model IDs in fallback path
2026-06-10 11:39:52 +02:00
Mario Zechner a7f9fe681d fix: bump shell-quote to 1.8.4 in lockfile (GHSA-w7jw-789q-3m8p) 2026-06-10 11:01:30 +02:00
Mario Zechner 7498b216d9 fix: bump shell-quote to 1.8.4 in lockfile (GHSA-w7jw-789q-3m8p) 2026-06-10 11:00:48 +02:00
Burak Varli 0b6c95dda0 feat(ai): link AWS data retention docs in Bedrock validation errors
When Bedrock rejects a request with "data retention mode '<mode>' is not
available for this model", append a pointer to the AWS data retention
documentation so users can configure a supported mode.
2026-06-10 07:45:50 +00:00
haoqixu eb01f59dc9 fix(tui): wrap CJK text at character boundaries in editor 2026-06-10 15:39:44 +08:00
Mario Zechner 9f9705173a docs(agent): consolidate models architecture design
Unified auth methods (api-key/oauth discriminated union), single
createProvider() helper, src/api layout, compat entrypoint design,
fixed auth resolution policy, prompt/notify login callbacks, and
checkbox implementation TODOs.
2026-06-10 01:39:11 +02:00
Armin Ronacher 9ccfcd7cfc fix(ai): omit disabled thinking for Claude Fable 5 2026-06-10 00:27:11 +02:00
Armin Ronacher dacb367e9e fix(ai): expect Claude Fable 5 in adaptive thinking model test 2026-06-09 23:20:20 +02:00
Armin Ronacher 82f2b1e908 Add [Unreleased] section for next cycle 2026-06-09 23:14:55 +02:00
Armin Ronacher 28df940f0d Release v0.79.1 2026-06-09 23:14:52 +02:00
Armin Ronacher 4d9f9f455d fix(ai): regenerate image models for upstream Riverflow rename 2026-06-09 23:14:38 +02:00
Armin Ronacher 66f432cae4 fix(ai): regenerate models for Claude Fable 5 and Azure metadata overrides
Also add inherited coding-agent changelog entries for Fable 5 and the
Azure gpt-5.4/5.5 context window and gpt-5-pro maxTokens fixes.
2026-06-09 23:08:05 +02:00
Armin Ronacher 6b5923f107 fix(ai): correct Azure gpt-5.4/5.5 context window and gpt-5-pro maxTokens
Azure Foundry deploys gpt-5.4 and gpt-5.5 with a 1,050,000 context
window, but the Azure provider cloned OpenAI-direct's 272k API limit.
Override the context window in the Azure derivation.

Also fix gpt-5-pro maxTokens, which upstream metadata set to 272000 (a
duplicate of the input sub-limit) instead of the actual 128000 max
output; corrected at the source so OpenAI-direct and Azure both match.

closes #5559
2026-06-09 22:57:20 +02:00
Armin Ronacher 5a9d72ea02 feat(ai): add Claude Fable 5 metadata 2026-06-09 22:42:48 +02:00
Armin Ronacher a0c2465d47 docs: audit unreleased changelogs 2026-06-09 22:33:02 +02:00
Sviatoslav Abakumov dfd4571cb0 fix(tui): separate list items with blank lines in loose lists 2026-06-09 23:53:18 +04:00
haoqixu aa03982169 fix(coding-agent): parse :thinking suffix from custom model IDs in fallback path
Fixes #5552
2026-06-10 02:01:35 +08:00
Mario Zechner c5582102f5 Merge pull request #5553 from dannote/prompt-template-defaults
Add prompt template argument defaults
2026-06-09 14:23:08 +02:00
Mario Zechner 143b251e77 Merge branch 'main' into prompt-template-defaults 2026-06-09 14:23:00 +02:00
Mario Zechner ae7a885da2 Closes #5045, /new should not persist if original session was ephemeral 2026-06-09 14:17:33 +02:00
Mario Zechner b7e721cb38 feat(tui): support autocomplete trigger characters
closes #4703
2026-06-09 14:15:39 +02:00
Mario Zechner 69ea1a6310 docs(coding-agent): clarify model name display docs
closes #4841
2026-06-09 14:14:57 +02:00
Danila Poyarkov d81ac20920 feat(coding-agent): add prompt template argument defaults 2026-06-09 15:12:07 +03:00
Mario Zechner d041b5cc35 Merge pull request #5549 from earendil-works/approval-settings
feat(ui): Improved project approval settings
2026-06-09 13:47:29 +02:00
Armin Ronacher c20ea06d4a fix: --help and --version redirect 2026-06-09 13:43:54 +02:00
Mario Zechner 3d02d1da11 fix(ai): map OpenCode max tokens
closes #5331
2026-06-09 13:41:08 +02:00
Mario Zechner 9632bddd38 fix(coding-agent): stabilize OAuth login prompt rows
closes #5433
2026-06-09 13:41:08 +02:00
Mario Zechner 64b51efb6e fix(ai): use z.ai thinking payload
closes #5330
2026-06-09 13:37:58 +02:00
Armin Ronacher 359a0769f1 fix: simplify help 2026-06-09 13:36:05 +02:00
Armin Ronacher 5cb4f597f7 feat(ui): Improved project approval settings 2026-06-09 13:25:54 +02:00
Vegard Stikbakke 66335d3a49 feat(coding-agent): add experimental feature guard (#5547) 2026-06-09 13:23:07 +02:00