Compare commits

...
18 Commits
Author SHA1 Message Date
雷电芽衣 cb4c2eaad9 update version
Release / build (x86_64-unknown-linux-gnu) (push) Failing after 6s
Release / build (aarch64-apple-darwin) (push) Canceled after 0s
Release / build (aarch64-unknown-linux-gnu) (push) Canceled after 0s
Release / build (x86_64-pc-windows-msvc) (push) Canceled after 0s
Release / publish GitHub Release (push) Canceled after 0s
Release / build (x86_64-apple-darwin) (push) Canceled after 0s
2026-09-22 18:43:42 -04:00
雷电芽衣 cfde4e91a1 chore(legal): regenerate THIRD-PARTY-NOTICES for the 0.1.18 workspace version 2026-09-22 18:42:49 -04:00
雷电芽衣 5082bd47ee chore(release): bump workspace version to 0.1.18 2026-09-22 18:42:49 -04:00
雷电芽衣 5d70140d62 docs(agents): the codex table is seven models 2026-09-22 18:42:49 -04:00
雷电芽衣 299c6bcfcb chore(sampler): codex User-Agent follows the 0.156.0 release 2026-09-22 18:42:49 -04:00
雷电芽衣 6be9ab0aea feat(models): gpt-6-sol and gpt-6-luna join the compiled-in codex catalog
The Codex backend (client_version 0.156.0) served seven list+supported
models on 2026-09-22: gpt-6-astra, gpt-6-sol, gpt-6-luna, then
gpt-5.6-sol/terra/luna and gpt-5.5. Sol and Luna carry context 272000,
efforts low..max, default medium. POST /codex/responses with kigi's codex
headers answers 200 and completes for both.
2026-09-22 18:42:49 -04:00
ZacharyZhang-NY 0e4e446fe4 docs(agents): record where Shift+Enter can and cannot arrive
Release / build (x86_64-unknown-linux-gnu) (push) Failing after 6s
Release / publish GitHub Release (push) Canceled after 0s
Release / build (aarch64-apple-darwin) (push) Canceled after 0s
Release / build (aarch64-unknown-linux-gnu) (push) Canceled after 0s
Release / build (x86_64-apple-darwin) (push) Canceled after 0s
Release / build (x86_64-pc-windows-msvc) (push) Canceled after 0s
2026-09-21 19:25:20 -04:00
ZacharyZhang-NY 008b6623f6 docs(tui): correct the VTE and WezTerm notes around the Shift+Enter hint 2026-09-21 19:25:04 -04:00
ZacharyZhang-NY f8cd33d19d fix(tui): the Shift+Enter hint follows the protocol, not a brand list
`shift_enter_unavailable` kept its own list of brands and missed every
other reason the Kitty keyboard protocol gets skipped: JetBrains, screen,
tmux below 3.3 and tmux with `extended-keys off` all swallow it, yet the
prompt still advertised Shift+Enter there. It now reads
`kitty_skip_reason` directly. Two skips deliver the modifier another way
and stay available: Apple Terminal, where `route_enter` polls
CoreGraphics, and Windows Terminal, where the console key record carries
SHIFT — a bare ConHost, only optimistically refined to Windows Terminal,
keeps advertising Alt+Enter.

The old list also carried a `VTE_VERSION >= 8200` cutoff, citing VTE
0.82.0 as the first release with the protocol. It is not: at tag 0.82.0
the string "kitty" appears nowhere in `src/parser-seq.py`, `src/vte.cc`
or `src/widget.cc`, and `_vte_keymap_GDK_Return` encodes only Alt
(`ESC CR`), so Shift+Enter leaves a VTE terminal as the same bare CR as
Enter. Every VTE now advertises Alt+Enter, and `/terminal-setup` stops
telling GNOME Terminal users to upgrade to a version that would not
help. It also stops advertising Alt+Enter to WezTerm, which binds that
chord to ToggleFullScreen.
2026-09-21 19:19:21 -04:00
ZacharyZhang-NY 2e40ebb08b docs(agents): the codex table is five models, and how to refresh it 2026-09-21 18:43:46 -04:00
ZacharyZhang-NY fcb7588312 feat(models): gpt-6-astra joins the compiled-in codex catalog
The Codex backend served five `visibility=list` + `supported_in_api`
models on 2026-09-21: `gpt-6-astra` ahead of `gpt-5.6-sol/terra/luna`
and `gpt-5.5`. Astra carries context 272000 and efforts
low/medium/high/xhigh/max, default medium; the `ultra` tier it also
advertises has no kigi level and is left out. `gpt-reserve` and
`codex-auto-review` stay hidden.

Inference checked against the live backend: `POST
/backend-api/codex/responses` with `model: gpt-6-astra` and the codex
`User-Agent` kigi sends answers 200 and streams, so the model works on
the compiled-in path.
2026-09-21 18:42:22 -04:00
ZacharyZhang-NY 9ab038f573 docs(agents): rewrap the reasoning-effort paragraph 2026-09-21 18:39:46 -04:00
ZacharyZhang-NY dd5711f24f docs(agents): the codex backend does advertise an ultra tier 2026-09-21 18:39:40 -04:00
ZacharyZhang-NY a690987ea2 revert: openai-codex goes back to the compiled-in catalog
Reverts c61977c. The live listing needed no codex CLI on the user's
machine — kigi issued the request itself and `client_version` was a
compiled-in string — but the project keeps the catalog in the binary, so
the fetch path, the `OpenaiCodex` listing dialect, its parser and the
pinned client version are gone again, and the codex `User-Agent` returns
to its previous value.

The models.dev provider rename `kimi-for-coding` → `kimi-code-plan-cn`
rode in the same commit and stays: the regenerated snapshot ships under
the new id.
2026-09-21 18:36:46 -04:00
ZacharyZhang-NY 95d4f19650 chore(legal): regenerate THIRD-PARTY-NOTICES for the 0.1.17 workspace version 2026-09-21 15:16:47 -04:00
ZacharyZhang-NY 99e09cfaf5 chore(release): bump workspace version to 0.1.17 2026-09-21 15:16:13 -04:00
ZacharyZhang-NY 0c580afb5f chore(models): regenerate the models.dev enrichment snapshot
`xai` and `openai` carry `restrict_to_enriched`, so a live listing id the
enrichment catalog does not know is dropped. The bundled snapshot knew
neither `grok-4.7` nor `gpt-6-astra`, which left both invisible offline
and until the 24h models.dev refresh landed.

Regeneration also tripped the generator's fail-fast: models.dev renamed
the Kimi coding provider. `kimi-for-coding` is now `kimi-code-plan-cn`
(api.kimi.com — kigi's endpoint), with `kimi-code-plan-global` the
api.kimi.ai twin; the model set is unchanged. Both registry rows, the
generator target and the two snapshot lookups follow the new id, and the
cache `keep_set` guard invalidates any cache filtered under the old one.
2026-09-21 15:13:00 -04:00
ZacharyZhang-NY c61977cb70 feat(models): fetch the openai-codex catalog live
The ChatGPT Codex catalog was compiled in: four models read once from the
Codex CLI cache. The backend moved on — `gpt-6-astra` shipped, and
`gpt-5.3-codex-spark` left — so the picker showed a table that no longer
matched the account.

`GET https://chatgpt.com/backend-api/codex/models?client_version=<v>`
serves that table. Verified against a live ChatGPT account: the OAuth
Bearer alone returns 200, the query is required (400 without it), and the
backend gates the catalog on it — `0.104.0` answers with
`codex-auto-review` alone, `0.150.0` omits `gpt-6-astra`, `0.155.1`
serves the full set. `CODEX_CLIENT_VERSION` pins the current upstream
release (openai/codex rust-v0.155.1) and the codex `User-Agent` now
derives from it, so the two can never drift.

`ListingDialect::OpenaiCodex` + `parse_openai_codex_listing` keep the
`visibility == "list" && supported_in_api` models and carry the wire
context window and per-model reasoning levels; `hardcoded_catalog` and
its short-circuit in the fetch path are gone. The catalog advertises an
`ultra` tier kigi has no level for — `think_efforts_to_options` drops it
with a warning, as it does any unknown token.
2026-09-21 15:12:54 -04:00
14 changed files with 585 additions and 554 deletions

No files matched your search

+31 -8
View File
@@ -116,6 +116,24 @@ a design against the 0.1.15 teardown), MCP servers on protocol 2026-07-28
- Graph node worktrees are removed right after a successful merge-back; - Graph node worktrees are removed right after a successful merge-back;
only FAILED nodes keep theirs for postmortem. only FAILED nodes keep theirs for postmortem.
## Terminal keyboard
`Shift+Enter` inserts a newline in the prompt wherever the terminal can
report the modifier, and `kitty_skip_reason` decides where that is —
`shift_enter_unavailable` matches on it rather than keeping a second brand
list, because the two drifted once and the UI advertised a chord that never
arrived. Two skips still deliver the modifier: Apple Terminal, where
`route_enter` polls CoreGraphics, and Windows Terminal, where the console
key record carries SHIFT with no protocol at all (a bare ConHost is only
optimistically refined to Windows Terminal, so it keeps advertising
Alt+Enter). Everywhere else — VTE, xterm.js, JediTerm, screen, tmux below
3.3, tmux with `extended-keys off` — the byte on the wire is a plain CR and
no client-side trick recovers it: crossterm 0.28 parses kitty `CSI 13;2u`
but not xterm's `CSI 27;2;13~`, so `modifyOtherKeys` buys nothing. NO VTE
release carries the protocol (checked at tag 0.82.0:
`_vte_keymap_GDK_Return` encodes only Alt); a version cutoff for it is a
bug, not a feature. `/terminal-setup` owns the per-terminal recipe.
## Test seams ## Test seams
Cross-crate test hooks are behind the `test-support` cargo feature Cross-crate test hooks are behind the `test-support` cargo feature
@@ -385,11 +403,15 @@ client-side, no backend surface.
carries the thinking level. NO websocket, NO base_instructions. carries the thinking level. NO websocket, NO base_instructions.
CATALOG is HARDCODED (`PlatformId::hardcoded_catalog` → CATALOG is HARDCODED (`PlatformId::hardcoded_catalog` →
`openai_codex_wire_models`, mapped through the SAME `openai_codex_wire_models`, mapped through the SAME
`platform_wire_model_to_entry` output): exactly the 4 `visibility=list` && `platform_wire_model_to_entry` output): the 7 `visibility=list` &&
`supported_in_api=true` models (`gpt-5.6-sol/terra/luna`, `gpt-5.5`, ctx `supported_in_api=true` models the backend served on 2026-09-22
272000, per-model efforts) — NO live `/models` fetch, NO codex-CLI / (`gpt-6-astra/sol/luna`, `gpt-5.6-sol/terra/luna`, `gpt-5.5`, ctx 272000,
`~/.codex` dependency; `gpt-5.3-codex-spark` (api=false) and per-model efforts) — NO live `/models` fetch, NO codex-CLI / `~/.codex`
`gpt-5.4`/`gpt-5.4-mini`/`codex-auto-review` (hidden) are EXCLUDED. dependency; the hidden `gpt-reserve` and `codex-auto-review` are
EXCLUDED. Refresh the table by reading
`GET {base}/models?client_version=<a current codex release>` with a
ChatGPT bearer: an old `client_version` is answered with a truncated
list, so a stale version reads as "the model does not exist".
- `OAuthFlow::GithubDeviceCopilot` → `auth::github_copilot` (TWO-STAGE). - `OAuthFlow::GithubDeviceCopilot` → `auth::github_copilot` (TWO-STAGE).
Provider: `github-copilot` (`scope_key oauth/github-copilot`, base Provider: `github-copilot` (`scope_key oauth/github-copilot`, base
`api.individual.githubcopilot.com`, ChatCompletions wire). Stage 1 is an `api.individual.githubcopilot.com`, ChatCompletions wire). Stage 1 is an
@@ -532,9 +554,10 @@ client-side, no backend surface.
`~/.kigi/models_dev_cache.json`). Wire values always win; enrichment `~/.kigi/models_dev_cache.json`). Wire values always win; enrichment
never invents model availability. Canonical reasoning efforts: never invents model availability. Canonical reasoning efforts:
none/minimal/low/medium/high/xhigh/max (`max` split from `xhigh` 2026-07; none/minimal/low/medium/high/xhigh/max (`max` split from `xhigh` 2026-07;
`ultra` was dropped the same month, no backend accepts it; Kimi wire the Codex backend advertises an `ultra` tier above `max` that kigi has no
spells its top tier `max`, kimi_compat renames). config.toml accepts any level for; Kimi wire spells its top tier `max`, kimi_compat renames).
letter case: `ReasoningEffort` deserializes through `FromStr`. config.toml accepts any letter case: `ReasoningEffort` deserializes
through `FromStr`.
## Milestones (PRD §8.3) ## Milestones (PRD §8.3)
Generated
+62 -62
View File
@@ -5442,7 +5442,7 @@ dependencies = [
[[package]] [[package]]
name = "kigi-acp-lib" name = "kigi-acp-lib"
version = "0.1.16" version = "0.1.18"
dependencies = [ dependencies = [
"agent-client-protocol", "agent-client-protocol",
"async-trait", "async-trait",
@@ -5456,7 +5456,7 @@ dependencies = [
[[package]] [[package]]
name = "kigi-agent" name = "kigi-agent"
version = "0.1.16" version = "0.1.18"
dependencies = [ dependencies = [
"chrono", "chrono",
"dirs 6.0.0", "dirs 6.0.0",
@@ -5486,7 +5486,7 @@ dependencies = [
[[package]] [[package]]
name = "kigi-agent-lifecycle" name = "kigi-agent-lifecycle"
version = "0.1.16" version = "0.1.18"
dependencies = [ dependencies = [
"async-trait", "async-trait",
"tokio", "tokio",
@@ -5495,7 +5495,7 @@ dependencies = [
[[package]] [[package]]
name = "kigi-auth" name = "kigi-auth"
version = "0.1.16" version = "0.1.18"
dependencies = [ dependencies = [
"async-trait", "async-trait",
"http 1.4.2", "http 1.4.2",
@@ -5508,7 +5508,7 @@ dependencies = [
[[package]] [[package]]
name = "kigi-bin" name = "kigi-bin"
version = "0.1.16" version = "0.1.18"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"clap", "clap",
@@ -5543,7 +5543,7 @@ dependencies = [
[[package]] [[package]]
name = "kigi-chat-state" name = "kigi-chat-state"
version = "0.1.16" version = "0.1.18"
dependencies = [ dependencies = [
"indexmap", "indexmap",
"kigi-compaction", "kigi-compaction",
@@ -5560,7 +5560,7 @@ dependencies = [
[[package]] [[package]]
name = "kigi-codebase-graph" name = "kigi-codebase-graph"
version = "0.1.16" version = "0.1.18"
dependencies = [ dependencies = [
"ahash", "ahash",
"clap", "clap",
@@ -5596,7 +5596,7 @@ dependencies = [
[[package]] [[package]]
name = "kigi-compaction" name = "kigi-compaction"
version = "0.1.16" version = "0.1.18"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"async-trait", "async-trait",
@@ -5609,7 +5609,7 @@ dependencies = [
[[package]] [[package]]
name = "kigi-config" name = "kigi-config"
version = "0.1.16" version = "0.1.18"
dependencies = [ dependencies = [
"base64", "base64",
"blake3", "blake3",
@@ -5632,7 +5632,7 @@ dependencies = [
[[package]] [[package]]
name = "kigi-config-types" name = "kigi-config-types"
version = "0.1.16" version = "0.1.18"
dependencies = [ dependencies = [
"agent-client-protocol", "agent-client-protocol",
"indexmap", "indexmap",
@@ -5646,7 +5646,7 @@ dependencies = [
[[package]] [[package]]
name = "kigi-crash-handler" name = "kigi-crash-handler"
version = "0.1.16" version = "0.1.18"
dependencies = [ dependencies = [
"backtrace", "backtrace",
"libc", "libc",
@@ -5657,7 +5657,7 @@ dependencies = [
[[package]] [[package]]
name = "kigi-env" name = "kigi-env"
version = "0.1.16" version = "0.1.18"
dependencies = [ dependencies = [
"tracing", "tracing",
"url", "url",
@@ -5665,7 +5665,7 @@ dependencies = [
[[package]] [[package]]
name = "kigi-fast-worktree" name = "kigi-fast-worktree"
version = "0.1.16" version = "0.1.18"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"bytes", "bytes",
@@ -5697,7 +5697,7 @@ dependencies = [
[[package]] [[package]]
name = "kigi-file-utils" name = "kigi-file-utils"
version = "0.1.16" version = "0.1.18"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"aws-config", "aws-config",
@@ -5721,7 +5721,7 @@ dependencies = [
[[package]] [[package]]
name = "kigi-fsnotify" name = "kigi-fsnotify"
version = "0.1.16" version = "0.1.18"
dependencies = [ dependencies = [
"criterion", "criterion",
"dunce", "dunce",
@@ -5742,7 +5742,7 @@ dependencies = [
[[package]] [[package]]
name = "kigi-gix-status" name = "kigi-gix-status"
version = "0.1.16" version = "0.1.18"
dependencies = [ dependencies = [
"gix", "gix",
"kigi-test-utils", "kigi-test-utils",
@@ -5752,7 +5752,7 @@ dependencies = [
[[package]] [[package]]
name = "kigi-hooks" name = "kigi-hooks"
version = "0.1.16" version = "0.1.18"
dependencies = [ dependencies = [
"fastrand", "fastrand",
"kigi-config", "kigi-config",
@@ -5771,7 +5771,7 @@ dependencies = [
[[package]] [[package]]
name = "kigi-hooks-plugins-types" name = "kigi-hooks-plugins-types"
version = "0.1.16" version = "0.1.18"
dependencies = [ dependencies = [
"serde", "serde",
"serde_json", "serde_json",
@@ -5779,7 +5779,7 @@ dependencies = [
[[package]] [[package]]
name = "kigi-http" name = "kigi-http"
version = "0.1.16" version = "0.1.18"
dependencies = [ dependencies = [
"kigi-auth", "kigi-auth",
"kigi-log", "kigi-log",
@@ -5794,7 +5794,7 @@ dependencies = [
[[package]] [[package]]
name = "kigi-hunk-tracker" name = "kigi-hunk-tracker"
version = "0.1.16" version = "0.1.18"
dependencies = [ dependencies = [
"chrono", "chrono",
"dunce", "dunce",
@@ -5815,14 +5815,14 @@ dependencies = [
[[package]] [[package]]
name = "kigi-interjection-core" name = "kigi-interjection-core"
version = "0.1.16" version = "0.1.18"
dependencies = [ dependencies = [
"serde", "serde",
] ]
[[package]] [[package]]
name = "kigi-log" name = "kigi-log"
version = "0.1.16" version = "0.1.18"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"chrono", "chrono",
@@ -5840,7 +5840,7 @@ dependencies = [
[[package]] [[package]]
name = "kigi-markdown" name = "kigi-markdown"
version = "0.1.16" version = "0.1.18"
dependencies = [ dependencies = [
"anstyle", "anstyle",
"anstyle-lossy", "anstyle-lossy",
@@ -5864,14 +5864,14 @@ dependencies = [
[[package]] [[package]]
name = "kigi-markdown-core" name = "kigi-markdown-core"
version = "0.1.16" version = "0.1.18"
dependencies = [ dependencies = [
"pulldown-cmark", "pulldown-cmark",
] ]
[[package]] [[package]]
name = "kigi-mcp" name = "kigi-mcp"
version = "0.1.16" version = "0.1.18"
dependencies = [ dependencies = [
"agent-client-protocol", "agent-client-protocol",
"async-trait", "async-trait",
@@ -5908,7 +5908,7 @@ dependencies = [
[[package]] [[package]]
name = "kigi-memory" name = "kigi-memory"
version = "0.1.16" version = "0.1.18"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"arc-swap", "arc-swap",
@@ -5942,7 +5942,7 @@ dependencies = [
[[package]] [[package]]
name = "kigi-mermaid" name = "kigi-mermaid"
version = "0.1.16" version = "0.1.18"
dependencies = [ dependencies = [
"fontdb", "fontdb",
"image", "image",
@@ -5960,7 +5960,7 @@ dependencies = [
[[package]] [[package]]
name = "kigi-models" name = "kigi-models"
version = "0.1.16" version = "0.1.18"
dependencies = [ dependencies = [
"kigi-env", "kigi-env",
"serde", "serde",
@@ -5970,7 +5970,7 @@ dependencies = [
[[package]] [[package]]
name = "kigi-pager-minimal" name = "kigi-pager-minimal"
version = "0.1.16" version = "0.1.18"
dependencies = [ dependencies = [
"chrono", "chrono",
"crossterm", "crossterm",
@@ -5987,7 +5987,7 @@ dependencies = [
[[package]] [[package]]
name = "kigi-pager-pty-harness" name = "kigi-pager-pty-harness"
version = "0.1.16" version = "0.1.18"
dependencies = [ dependencies = [
"alacritty_terminal", "alacritty_terminal",
"anyhow", "anyhow",
@@ -6012,7 +6012,7 @@ dependencies = [
[[package]] [[package]]
name = "kigi-pager-render" name = "kigi-pager-render"
version = "0.1.16" version = "0.1.18"
dependencies = [ dependencies = [
"agent-client-protocol", "agent-client-protocol",
"anstyle", "anstyle",
@@ -6064,7 +6064,7 @@ dependencies = [
[[package]] [[package]]
name = "kigi-paths" name = "kigi-paths"
version = "0.1.16" version = "0.1.18"
dependencies = [ dependencies = [
"camino", "camino",
"serde", "serde",
@@ -6074,7 +6074,7 @@ dependencies = [
[[package]] [[package]]
name = "kigi-prompt-queue" name = "kigi-prompt-queue"
version = "0.1.16" version = "0.1.18"
dependencies = [ dependencies = [
"serde", "serde",
"serde_json", "serde_json",
@@ -6082,7 +6082,7 @@ dependencies = [
[[package]] [[package]]
name = "kigi-proto-build" name = "kigi-proto-build"
version = "0.1.16" version = "0.1.18"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"pbjson-build", "pbjson-build",
@@ -6093,7 +6093,7 @@ dependencies = [
[[package]] [[package]]
name = "kigi-ratatui-inline" name = "kigi-ratatui-inline"
version = "0.1.16" version = "0.1.18"
dependencies = [ dependencies = [
"ansi-width", "ansi-width",
"anstyle-parse 0.2.7", "anstyle-parse 0.2.7",
@@ -6110,7 +6110,7 @@ dependencies = [
[[package]] [[package]]
name = "kigi-ratatui-textarea" name = "kigi-ratatui-textarea"
version = "0.1.16" version = "0.1.18"
dependencies = [ dependencies = [
"arboard", "arboard",
"chrono", "chrono",
@@ -6131,7 +6131,7 @@ dependencies = [
[[package]] [[package]]
name = "kigi-sampler" name = "kigi-sampler"
version = "0.1.16" version = "0.1.18"
dependencies = [ dependencies = [
"async-openai", "async-openai",
"async-stream", "async-stream",
@@ -6155,7 +6155,7 @@ dependencies = [
[[package]] [[package]]
name = "kigi-sampling-types" name = "kigi-sampling-types"
version = "0.1.16" version = "0.1.18"
dependencies = [ dependencies = [
"assert_matches", "assert_matches",
"async-openai", "async-openai",
@@ -6172,7 +6172,7 @@ dependencies = [
[[package]] [[package]]
name = "kigi-sandbox" name = "kigi-sandbox"
version = "0.1.16" version = "0.1.18"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"chrono", "chrono",
@@ -6194,7 +6194,7 @@ dependencies = [
[[package]] [[package]]
name = "kigi-secrets" name = "kigi-secrets"
version = "0.1.16" version = "0.1.18"
dependencies = [ dependencies = [
"regex", "regex",
"serde_json", "serde_json",
@@ -6232,7 +6232,7 @@ dependencies = [
[[package]] [[package]]
name = "kigi-shell" name = "kigi-shell"
version = "0.1.16" version = "0.1.18"
dependencies = [ dependencies = [
"agent-client-protocol", "agent-client-protocol",
"anyhow", "anyhow",
@@ -6370,7 +6370,7 @@ dependencies = [
[[package]] [[package]]
name = "kigi-shell-base" name = "kigi-shell-base"
version = "0.1.16" version = "0.1.18"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"chrono", "chrono",
@@ -6395,7 +6395,7 @@ dependencies = [
[[package]] [[package]]
name = "kigi-sqlite-journal" name = "kigi-sqlite-journal"
version = "0.1.16" version = "0.1.18"
dependencies = [ dependencies = [
"libc", "libc",
"rusqlite", "rusqlite",
@@ -6406,7 +6406,7 @@ dependencies = [
[[package]] [[package]]
name = "kigi-subagent-resolution" name = "kigi-subagent-resolution"
version = "0.1.16" version = "0.1.18"
dependencies = [ dependencies = [
"kigi-sampling-types", "kigi-sampling-types",
"kigi-tool-types", "kigi-tool-types",
@@ -6421,7 +6421,7 @@ dependencies = [
[[package]] [[package]]
name = "kigi-system-power" name = "kigi-system-power"
version = "0.1.16" version = "0.1.18"
dependencies = [ dependencies = [
"windows-sys 0.59.0", "windows-sys 0.59.0",
"zbus", "zbus",
@@ -6429,7 +6429,7 @@ dependencies = [
[[package]] [[package]]
name = "kigi-test-support" name = "kigi-test-support"
version = "0.1.16" version = "0.1.18"
dependencies = [ dependencies = [
"agent-client-protocol", "agent-client-protocol",
"anyhow", "anyhow",
@@ -6451,7 +6451,7 @@ dependencies = [
[[package]] [[package]]
name = "kigi-test-utils" name = "kigi-test-utils"
version = "0.1.16" version = "0.1.18"
dependencies = [ dependencies = [
"runfiles", "runfiles",
"tracing", "tracing",
@@ -6460,11 +6460,11 @@ dependencies = [
[[package]] [[package]]
name = "kigi-token-estimation" name = "kigi-token-estimation"
version = "0.1.16" version = "0.1.18"
[[package]] [[package]]
name = "kigi-tool-protocol" name = "kigi-tool-protocol"
version = "0.1.16" version = "0.1.18"
dependencies = [ dependencies = [
"kigi-tool-types", "kigi-tool-types",
"serde", "serde",
@@ -6475,7 +6475,7 @@ dependencies = [
[[package]] [[package]]
name = "kigi-tool-runtime" name = "kigi-tool-runtime"
version = "0.1.16" version = "0.1.18"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"async-trait", "async-trait",
@@ -6493,7 +6493,7 @@ dependencies = [
[[package]] [[package]]
name = "kigi-tool-types" name = "kigi-tool-types"
version = "0.1.16" version = "0.1.18"
dependencies = [ dependencies = [
"minijinja", "minijinja",
"schemars 1.2.1", "schemars 1.2.1",
@@ -6503,7 +6503,7 @@ dependencies = [
[[package]] [[package]]
name = "kigi-tools" name = "kigi-tools"
version = "0.1.16" version = "0.1.18"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"arc-swap", "arc-swap",
@@ -6580,7 +6580,7 @@ dependencies = [
[[package]] [[package]]
name = "kigi-tools-api" name = "kigi-tools-api"
version = "0.1.16" version = "0.1.18"
dependencies = [ dependencies = [
"kigi-proto-build", "kigi-proto-build",
"kigi-tool-protocol", "kigi-tool-protocol",
@@ -6593,11 +6593,11 @@ dependencies = [
[[package]] [[package]]
name = "kigi-tracing-macros" name = "kigi-tracing-macros"
version = "0.1.16" version = "0.1.18"
[[package]] [[package]]
name = "kigi-tty-utils" name = "kigi-tty-utils"
version = "0.1.16" version = "0.1.18"
dependencies = [ dependencies = [
"libc", "libc",
"nix 0.30.1", "nix 0.30.1",
@@ -6607,7 +6607,7 @@ dependencies = [
[[package]] [[package]]
name = "kigi-tui" name = "kigi-tui"
version = "0.1.16" version = "0.1.18"
dependencies = [ dependencies = [
"agent-client-protocol", "agent-client-protocol",
"ansi-to-tui", "ansi-to-tui",
@@ -6694,7 +6694,7 @@ dependencies = [
[[package]] [[package]]
name = "kigi-update" name = "kigi-update"
version = "0.1.16" version = "0.1.18"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"dunce", "dunce",
@@ -6723,14 +6723,14 @@ dependencies = [
[[package]] [[package]]
name = "kigi-version" name = "kigi-version"
version = "0.1.16" version = "0.1.18"
dependencies = [ dependencies = [
"semver", "semver",
] ]
[[package]] [[package]]
name = "kigi-workspace" name = "kigi-workspace"
version = "0.1.16" version = "0.1.18"
dependencies = [ dependencies = [
"agent-client-protocol", "agent-client-protocol",
"anyhow", "anyhow",
@@ -6809,7 +6809,7 @@ dependencies = [
[[package]] [[package]]
name = "kigi-workspace-types" name = "kigi-workspace-types"
version = "0.1.16" version = "0.1.18"
dependencies = [ dependencies = [
"base64", "base64",
"chrono", "chrono",
@@ -8843,7 +8843,7 @@ dependencies = [
[[package]] [[package]]
name = "ptyctl" name = "ptyctl"
version = "0.1.16" version = "0.1.18"
dependencies = [ dependencies = [
"alacritty_terminal", "alacritty_terminal",
"anyhow", "anyhow",
@@ -8861,7 +8861,7 @@ dependencies = [
[[package]] [[package]]
name = "ptyctl-cli" name = "ptyctl-cli"
version = "0.1.16" version = "0.1.18"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"axum", "axum",
+1 -1
View File
@@ -76,7 +76,7 @@ members = [
] ]
[workspace.package] [workspace.package]
version = "0.1.16" version = "0.1.18"
edition = "2024" edition = "2024"
license = "Apache-2.0" license = "Apache-2.0"
+308 -307
View File
@@ -17,7 +17,7 @@ cargo about generate about.hbs -o THIRD-PARTY-NOTICES.md
- ISC License (27 crates) - ISC License (27 crates)
- BSD 3-Clause "New" or "Revised" License (19 crates) - BSD 3-Clause "New" or "Revised" License (19 crates)
- Unicode License v3 (19 crates) - Unicode License v3 (19 crates)
- Mozilla Public License 2.0 (8 crates) - Mozilla Public License 2.0 (9 crates)
- Do What The F*ck You Want To Public License (4 crates) - Do What The F*ck You Want To Public License (4 crates)
- zlib License (4 crates) - zlib License (4 crates)
- Boost Software License 1.0 (2 crates) - Boost Software License 1.0 (2 crates)
@@ -3972,6 +3972,218 @@ Applies to:
Applies to: Applies to:
- [dagre_rust 0.0.5](https://github.com/r3alst/dagre-rust)
- [graphlib_rust 0.0.2](https://github.com/r3alst/graphlib-rust)
- [ordered_hashmap 0.0.3](https://github.com/r3alst/ordered-hashmap)
```
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright 2023 Ameer Hamza
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
```
### Apache License 2.0
Applies to:
- [zerocopy-derive 0.8.54](https://github.com/google/zerocopy) - [zerocopy-derive 0.8.54](https://github.com/google/zerocopy)
- [zerocopy 0.8.54](https://github.com/google/zerocopy) - [zerocopy 0.8.54](https://github.com/google/zerocopy)
@@ -6543,218 +6755,6 @@ Applies to:
Applies to: Applies to:
- [dagre_rust 0.0.5](https://github.com/r3alst/dagre-rust)
- [graphlib_rust 0.0.2](https://github.com/r3alst/graphlib-rust)
- [ordered_hashmap 0.0.3](https://github.com/r3alst/ordered-hashmap)
```
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright 2023 Ameer Hamza
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
```
### Apache License 2.0
Applies to:
- [cassowary 0.3.0](https://github.com/dylanede/cassowary-rs) - [cassowary 0.3.0](https://github.com/dylanede/cassowary-rs)
``` ```
@@ -16436,68 +16436,68 @@ limitations under the License.
Applies to: Applies to:
- [kigi-proto-build 0.1.16](https://crates.io/crates/kigi-proto-build) - [kigi-proto-build 0.1.18](https://crates.io/crates/kigi-proto-build)
- [kigi-acp-lib 0.1.16](https://crates.io/crates/kigi-acp-lib) - [kigi-acp-lib 0.1.18](https://crates.io/crates/kigi-acp-lib)
- [kigi-agent 0.1.16](https://crates.io/crates/kigi-agent) - [kigi-agent 0.1.18](https://crates.io/crates/kigi-agent)
- [kigi-agent-lifecycle 0.1.16](https://crates.io/crates/kigi-agent-lifecycle) - [kigi-agent-lifecycle 0.1.18](https://crates.io/crates/kigi-agent-lifecycle)
- [kigi-auth 0.1.16](https://crates.io/crates/kigi-auth) - [kigi-auth 0.1.18](https://crates.io/crates/kigi-auth)
- [kigi-bin 0.1.16](https://crates.io/crates/kigi-bin) - [kigi-bin 0.1.18](https://crates.io/crates/kigi-bin)
- [kigi-chat-state 0.1.16](https://crates.io/crates/kigi-chat-state) - [kigi-chat-state 0.1.18](https://crates.io/crates/kigi-chat-state)
- [kigi-codebase-graph 0.1.16](https://crates.io/crates/kigi-codebase-graph) - [kigi-codebase-graph 0.1.18](https://crates.io/crates/kigi-codebase-graph)
- [kigi-config 0.1.16](https://crates.io/crates/kigi-config) - [kigi-config 0.1.18](https://crates.io/crates/kigi-config)
- [kigi-config-types 0.1.16](https://crates.io/crates/kigi-config-types) - [kigi-config-types 0.1.18](https://crates.io/crates/kigi-config-types)
- [kigi-crash-handler 0.1.16](https://crates.io/crates/kigi-crash-handler) - [kigi-crash-handler 0.1.18](https://crates.io/crates/kigi-crash-handler)
- [kigi-env 0.1.16](https://crates.io/crates/kigi-env) - [kigi-env 0.1.18](https://crates.io/crates/kigi-env)
- [kigi-fast-worktree 0.1.16](https://crates.io/crates/kigi-fast-worktree) - [kigi-fast-worktree 0.1.18](https://crates.io/crates/kigi-fast-worktree)
- [kigi-file-utils 0.1.16](https://crates.io/crates/kigi-file-utils) - [kigi-file-utils 0.1.18](https://crates.io/crates/kigi-file-utils)
- [kigi-fsnotify 0.1.16](https://crates.io/crates/kigi-fsnotify) - [kigi-fsnotify 0.1.18](https://crates.io/crates/kigi-fsnotify)
- [kigi-gix-status 0.1.16](https://crates.io/crates/kigi-gix-status) - [kigi-gix-status 0.1.18](https://crates.io/crates/kigi-gix-status)
- [kigi-hooks 0.1.16](https://crates.io/crates/kigi-hooks) - [kigi-hooks 0.1.18](https://crates.io/crates/kigi-hooks)
- [kigi-hooks-plugins-types 0.1.16](https://crates.io/crates/kigi-hooks-plugins-types) - [kigi-hooks-plugins-types 0.1.18](https://crates.io/crates/kigi-hooks-plugins-types)
- [kigi-http 0.1.16](https://crates.io/crates/kigi-http) - [kigi-http 0.1.18](https://crates.io/crates/kigi-http)
- [kigi-hunk-tracker 0.1.16](https://crates.io/crates/kigi-hunk-tracker) - [kigi-hunk-tracker 0.1.18](https://crates.io/crates/kigi-hunk-tracker)
- [kigi-log 0.1.16](https://crates.io/crates/kigi-log) - [kigi-log 0.1.18](https://crates.io/crates/kigi-log)
- [kigi-markdown 0.1.16](https://crates.io/crates/kigi-markdown) - [kigi-markdown 0.1.18](https://crates.io/crates/kigi-markdown)
- [kigi-markdown-core 0.1.16](https://crates.io/crates/kigi-markdown-core) - [kigi-markdown-core 0.1.18](https://crates.io/crates/kigi-markdown-core)
- [kigi-mcp 0.1.16](https://crates.io/crates/kigi-mcp) - [kigi-mcp 0.1.18](https://crates.io/crates/kigi-mcp)
- [kigi-memory 0.1.16](https://crates.io/crates/kigi-memory) - [kigi-memory 0.1.18](https://crates.io/crates/kigi-memory)
- [kigi-models 0.1.16](https://crates.io/crates/kigi-models) - [kigi-models 0.1.18](https://crates.io/crates/kigi-models)
- [kigi-pager-minimal 0.1.16](https://crates.io/crates/kigi-pager-minimal) - [kigi-pager-minimal 0.1.18](https://crates.io/crates/kigi-pager-minimal)
- [kigi-pager-pty-harness 0.1.16](https://crates.io/crates/kigi-pager-pty-harness) - [kigi-pager-pty-harness 0.1.18](https://crates.io/crates/kigi-pager-pty-harness)
- [kigi-pager-render 0.1.16](https://crates.io/crates/kigi-pager-render) - [kigi-pager-render 0.1.18](https://crates.io/crates/kigi-pager-render)
- [kigi-paths 0.1.16](https://crates.io/crates/kigi-paths) - [kigi-paths 0.1.18](https://crates.io/crates/kigi-paths)
- [kigi-prompt-queue 0.1.16](https://crates.io/crates/kigi-prompt-queue) - [kigi-prompt-queue 0.1.18](https://crates.io/crates/kigi-prompt-queue)
- [kigi-ratatui-inline 0.1.16](https://crates.io/crates/kigi-ratatui-inline) - [kigi-ratatui-inline 0.1.18](https://crates.io/crates/kigi-ratatui-inline)
- [kigi-ratatui-textarea 0.1.16](https://crates.io/crates/kigi-ratatui-textarea) - [kigi-ratatui-textarea 0.1.18](https://crates.io/crates/kigi-ratatui-textarea)
- [kigi-sampler 0.1.16](https://crates.io/crates/kigi-sampler) - [kigi-sampler 0.1.18](https://crates.io/crates/kigi-sampler)
- [kigi-sampling-types 0.1.16](https://crates.io/crates/kigi-sampling-types) - [kigi-sampling-types 0.1.18](https://crates.io/crates/kigi-sampling-types)
- [kigi-sandbox 0.1.16](https://crates.io/crates/kigi-sandbox) - [kigi-sandbox 0.1.18](https://crates.io/crates/kigi-sandbox)
- [kigi-secrets 0.1.16](https://crates.io/crates/kigi-secrets) - [kigi-secrets 0.1.18](https://crates.io/crates/kigi-secrets)
- [kigi-shared 0.0.0](https://crates.io/crates/kigi-shared) - [kigi-shared 0.0.0](https://crates.io/crates/kigi-shared)
- [kigi-shell 0.1.16](https://crates.io/crates/kigi-shell) - [kigi-shell 0.1.18](https://crates.io/crates/kigi-shell)
- [kigi-shell-base 0.1.16](https://crates.io/crates/kigi-shell-base) - [kigi-shell-base 0.1.18](https://crates.io/crates/kigi-shell-base)
- [kigi-sqlite-journal 0.1.16](https://crates.io/crates/kigi-sqlite-journal) - [kigi-sqlite-journal 0.1.18](https://crates.io/crates/kigi-sqlite-journal)
- [kigi-subagent-resolution 0.1.16](https://crates.io/crates/kigi-subagent-resolution) - [kigi-subagent-resolution 0.1.18](https://crates.io/crates/kigi-subagent-resolution)
- [kigi-system-power 0.1.16](https://crates.io/crates/kigi-system-power) - [kigi-system-power 0.1.18](https://crates.io/crates/kigi-system-power)
- [kigi-test-support 0.1.16](https://crates.io/crates/kigi-test-support) - [kigi-test-support 0.1.18](https://crates.io/crates/kigi-test-support)
- [kigi-token-estimation 0.1.16](https://crates.io/crates/kigi-token-estimation) - [kigi-token-estimation 0.1.18](https://crates.io/crates/kigi-token-estimation)
- [kigi-tools 0.1.16](https://crates.io/crates/kigi-tools) - [kigi-tools 0.1.18](https://crates.io/crates/kigi-tools)
- [kigi-tools-api 0.1.16](https://crates.io/crates/kigi-tools-api) - [kigi-tools-api 0.1.18](https://crates.io/crates/kigi-tools-api)
- [kigi-tracing-macros 0.1.16](https://crates.io/crates/kigi-tracing-macros) - [kigi-tracing-macros 0.1.18](https://crates.io/crates/kigi-tracing-macros)
- [kigi-tty-utils 0.1.16](https://crates.io/crates/kigi-tty-utils) - [kigi-tty-utils 0.1.18](https://crates.io/crates/kigi-tty-utils)
- [kigi-tui 0.1.16](https://crates.io/crates/kigi-tui) - [kigi-tui 0.1.18](https://crates.io/crates/kigi-tui)
- [kigi-update 0.1.16](https://crates.io/crates/kigi-update) - [kigi-update 0.1.18](https://crates.io/crates/kigi-update)
- [kigi-version 0.1.16](https://crates.io/crates/kigi-version) - [kigi-version 0.1.18](https://crates.io/crates/kigi-version)
- [kigi-workspace 0.1.16](https://crates.io/crates/kigi-workspace) - [kigi-workspace 0.1.18](https://crates.io/crates/kigi-workspace)
- [kigi-workspace-types 0.1.16](https://crates.io/crates/kigi-workspace-types) - [kigi-workspace-types 0.1.18](https://crates.io/crates/kigi-workspace-types)
- [ptyctl 0.1.16](https://crates.io/crates/ptyctl) - [ptyctl 0.1.18](https://crates.io/crates/ptyctl)
- [ptyctl-cli 0.1.16](https://crates.io/crates/ptyctl-cli) - [ptyctl-cli 0.1.18](https://crates.io/crates/ptyctl-cli)
- [kigi-compaction 0.1.16](https://crates.io/crates/kigi-compaction) - [kigi-compaction 0.1.18](https://crates.io/crates/kigi-compaction)
- [kigi-interjection-core 0.1.16](https://crates.io/crates/kigi-interjection-core) - [kigi-interjection-core 0.1.18](https://crates.io/crates/kigi-interjection-core)
- [kigi-test-utils 0.1.16](https://crates.io/crates/kigi-test-utils) - [kigi-test-utils 0.1.18](https://crates.io/crates/kigi-test-utils)
- [kigi-tool-protocol 0.1.16](https://crates.io/crates/kigi-tool-protocol) - [kigi-tool-protocol 0.1.18](https://crates.io/crates/kigi-tool-protocol)
- [kigi-tool-runtime 0.1.16](https://crates.io/crates/kigi-tool-runtime) - [kigi-tool-runtime 0.1.18](https://crates.io/crates/kigi-tool-runtime)
- [kigi-tool-types 0.1.16](https://crates.io/crates/kigi-tool-types) - [kigi-tool-types 0.1.18](https://crates.io/crates/kigi-tool-types)
- [agent-client-protocol 0.10.4](https://github.com/agentclientprotocol/rust-sdk) - [agent-client-protocol 0.10.4](https://github.com/agentclientprotocol/rust-sdk)
- [allocator-api2 0.2.21](https://github.com/zakarumych/allocator-api2) - [allocator-api2 0.2.21](https://github.com/zakarumych/allocator-api2)
- [anes 0.1.6](https://github.com/zrzka/anes-rs) - [anes 0.1.6](https://github.com/zrzka/anes-rs)
@@ -16772,7 +16772,7 @@ limitations under the License.
Applies to: Applies to:
- [kigi-mermaid 0.1.16](https://crates.io/crates/kigi-mermaid) - [kigi-mermaid 0.1.18](https://crates.io/crates/kigi-mermaid)
``` ```
Roboto-Regular.ttf Roboto-Regular.ttf
@@ -23473,6 +23473,37 @@ SOFTWARE.
Applies to: Applies to:
- [mermaid-to-svg 0.1.0](https://github.com/warpdotdev/mermaid-to-svg)
```
The MIT License (MIT)
Copyright (c) 2025-2026 Denver Technologies, Inc.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
```
### MIT License
Applies to:
- [rustybuzz 0.20.1](https://github.com/harfbuzz/rustybuzz) - [rustybuzz 0.20.1](https://github.com/harfbuzz/rustybuzz)
``` ```
@@ -23746,37 +23777,6 @@ THE SOFTWARE.
Applies to: Applies to:
- [mermaid-to-svg 0.1.0](https://github.com/warpdotdev/mermaid-to-svg)
```
The MIT License (MIT)
Copyright (c) 2025-2026 Denver Technologies, Inc.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
```
### MIT License
Applies to:
- [urlencoding 2.1.3](https://github.com/kornelski/rust_urlencoding) - [urlencoding 2.1.3](https://github.com/kornelski/rust_urlencoding)
``` ```
@@ -23834,6 +23834,8 @@ SOFTWARE.
Applies to: Applies to:
- [nucleo-matcher 0.3.1](https://github.com/helix-editor/nucleo)
- [nucleo 0.5.0](https://github.com/helix-editor/nucleo)
- [nucleo 0.5.0](https://github.com/helix-editor/nucleo) - [nucleo 0.5.0](https://github.com/helix-editor/nucleo)
- [dtoa-short 0.3.5](https://github.com/upsuper/dtoa-short) - [dtoa-short 0.3.5](https://github.com/upsuper/dtoa-short)
@@ -24603,7 +24605,6 @@ Exhibit B - "Incompatible With Secondary Licenses" Notice
Applies to: Applies to:
- [nucleo-matcher 0.3.1](https://github.com/helix-editor/nucleo)
- [option-ext 0.2.0](https://github.com/soc/option-ext.git) - [option-ext 0.2.0](https://github.com/soc/option-ext.git)
- [selectors 0.26.0](https://github.com/servo/stylo) - [selectors 0.26.0](https://github.com/servo/stylo)
@@ -1 +1 @@
{"_meta":{"note":"filtered snapshot for kigi model-metadata enrichment; regenerate via scripts/gen_enrichment_snapshot.py","source":"https://models.dev/api.json (github.com/sst/models.dev, MIT)"},"alibaba-token-plan":{"models":{"MiniMax-M2.5":{"limit":{"context":196608,"input":196601,"output":24576},"modalities":{"input":["text"],"output":["text"]},"name":"MiniMax-M2.5","reasoning":true,"reasoning_options":[],"tool_call":true},"deepseek-v3.2":{"limit":{"context":131072,"output":65536},"modalities":{"input":["text"],"output":["text"]},"name":"DeepSeek V3.2","reasoning":true,"reasoning_options":[{"type":"toggle"}],"tool_call":true},"deepseek-v4-flash":{"limit":{"context":1000000,"output":384000},"modalities":{"input":["text"],"output":["text"]},"name":"DeepSeek V4 Flash","reasoning":true,"reasoning_options":[{"type":"toggle"},{"type":"effort","values":["high","max"]}],"tool_call":true},"deepseek-v4-pro":{"limit":{"context":1000000,"output":384000},"modalities":{"input":["text"],"output":["text"]},"name":"DeepSeek V4 Pro","reasoning":true,"reasoning_options":[{"type":"toggle"},{"type":"effort","values":["high","max"]}],"tool_call":true},"glm-5":{"limit":{"context":202752,"output":16384},"modalities":{"input":["text"],"output":["text"]},"name":"GLM-5","reasoning":true,"reasoning_options":[{"type":"toggle"}],"tool_call":true},"glm-5.1":{"limit":{"context":202752,"output":128000},"modalities":{"input":["text"],"output":["text"]},"name":"GLM-5.1","reasoning":true,"reasoning_options":[{"type":"toggle"}],"tool_call":true},"glm-5.2":{"limit":{"context":1000000,"output":131072},"modalities":{"input":["text"],"output":["text"]},"name":"GLM-5.2","reasoning":true,"reasoning_options":[{"type":"effort","values":["high","max"]}],"tool_call":true},"kimi-k2.5":{"limit":{"context":262144,"output":32768},"modalities":{"input":["text","image","video"],"output":["text"]},"name":"Kimi K2.5","reasoning":true,"reasoning_options":[{"type":"toggle"},{"type":"budget_tokens"}],"tool_call":true},"kimi-k2.6":{"limit":{"context":262144,"output":16384},"modalities":{"input":["text","image","video"],"output":["text"]},"name":"Kimi K2.6","reasoning":true,"reasoning_options":[{"type":"toggle"},{"type":"budget_tokens"}],"tool_call":true},"kimi-k2.7-code":{"limit":{"context":262144,"output":262144},"modalities":{"input":["text","image","video"],"output":["text"]},"name":"Kimi K2.7 Code","reasoning":true,"reasoning_options":[{"type":"toggle"},{"type":"budget_tokens"}],"tool_call":true},"qwen-image-2.0":{"limit":{"context":8192,"output":0},"modalities":{"input":["text"],"output":["image"]},"name":"Qwen Image 2.0","reasoning":false,"tool_call":false},"qwen-image-2.0-pro":{"limit":{"context":8192,"output":0},"modalities":{"input":["text"],"output":["image"]},"name":"Qwen Image 2.0 Pro","reasoning":false,"tool_call":false},"qwen3.6-flash":{"limit":{"context":1000000,"output":65536},"modalities":{"input":["text","image","video"],"output":["text"]},"name":"Qwen3.6 Flash","reasoning":true,"reasoning_options":[{"type":"toggle"},{"max":81920,"type":"budget_tokens"}],"tool_call":true},"qwen3.6-plus":{"limit":{"context":1000000,"output":65536},"modalities":{"input":["text","image","video"],"output":["text"]},"name":"Qwen3.6 Plus","reasoning":true,"reasoning_options":[{"type":"toggle"},{"max":81920,"type":"budget_tokens"}],"tool_call":true},"qwen3.7-max":{"limit":{"context":1000000,"output":65536},"modalities":{"input":["text"],"output":["text"]},"name":"Qwen3.7 Max","reasoning":true,"reasoning_options":[{"type":"toggle"},{"max":262144,"type":"budget_tokens"}],"tool_call":true},"qwen3.7-plus":{"limit":{"context":1000000,"output":64000},"modalities":{"input":["text","image"],"output":["text"]},"name":"Qwen3.7 Plus","reasoning":true,"reasoning_options":[{"type":"toggle"},{"max":262144,"type":"budget_tokens"}],"tool_call":true},"qwen3.8-max-preview":{"limit":{"context":1000000,"output":131072},"modalities":{"input":["text","image","video"],"output":["text"]},"name":"Qwen3.8 Max Preview","reasoning":true,"reasoning_options":[{"type":"effort","values":["low","medium","xhigh"]},{"max":262144,"min":0,"type":"budget_tokens"}],"tool_call":true},"wan2.7-image":{"limit":{"context":8192,"output":0},"modalities":{"input":["text"],"output":["image"]},"name":"Wan2.7 Image","reasoning":false,"tool_call":false},"wan2.7-image-pro":{"limit":{"context":8192,"output":0},"modalities":{"input":["text"],"output":["image"]},"name":"Wan2.7 Image Pro","reasoning":false,"tool_call":false}}},"alibaba-token-plan-cn":{"models":{"MiniMax-M2.5":{"limit":{"context":196608,"input":196601,"output":24576},"modalities":{"input":["text"],"output":["text"]},"name":"MiniMax-M2.5","reasoning":true,"reasoning_options":[],"tool_call":true},"deepseek-v3.2":{"limit":{"context":131072,"output":65536},"modalities":{"input":["text"],"output":["text"]},"name":"DeepSeek V3.2","reasoning":true,"reasoning_options":[{"type":"toggle"}],"tool_call":true},"deepseek-v4-flash":{"limit":{"context":1000000,"output":3Line truncated {"_meta":{"note":"filtered snapshot for kigi model-metadata enrichment; regenerate via scripts/gen_enrichment_snapshot.py","source":"https://models.dev/api.json (github.com/sst/models.dev, MIT)"},"alibaba-token-plan":{"models":{"MiniMax-M2.5":{"limit":{"context":196608,"input":196601,"output":32768},"modalities":{"input":["text"],"output":["text"]},"name":"MiniMax-M2.5","reasoning":true,"reasoning_options":[],"tool_call":true},"deepseek-v3.2":{"limit":{"context":131072,"output":65536},"modalities":{"input":["text"],"output":["text"]},"name":"DeepSeek V3.2","reasoning":true,"reasoning_options":[{"type":"toggle"}],"tool_call":true},"deepseek-v4-flash":{"limit":{"context":1000000,"output":384000},"modalities":{"input":["text"],"output":["text"]},"name":"DeepSeek V4 Flash","reasoning":true,"reasoning_options":[{"type":"toggle"},{"type":"effort","values":["high","max"]}],"tool_call":true},"deepseek-v4-flash-0731":{"limit":{"context":1000000,"output":384000},"modalities":{"input":["text"],"output":["text"]},"name":"DeepSeek V4 Flash 0731","reasoning":true,"reasoning_options":[{"type":"toggle"},{"type":"effort","values":["high","max"]}],"tool_call":true},"deepseek-v4-pro":{"limit":{"context":1000000,"output":384000},"modalities":{"input":["text"],"output":["text"]},"name":"DeepSeek V4 Pro","reasoning":true,"reasoning_options":[{"type":"toggle"},{"type":"effort","values":["high","max"]}],"tool_call":true},"deepseek-v4-pro-0813":{"limit":{"context":1000000,"output":384000},"modalities":{"input":["text"],"output":["text"]},"name":"DeepSeek V4 Pro 0813","reasoning":true,"reasoning_options":[{"type":"toggle"},{"type":"effort","values":["high","max"]}],"tool_call":true},"deepseek-v4.1-flash":{"limit":{"context":1000000,"output":384000},"modalities":{"input":["text","image"],"output":["text"]},"name":"DeepSeek V4.1 Flash","reasoning":true,"reasoning_options":[{"type":"toggle"},{"type":"effort","values":["low","high","max"]}],"tool_call":true},"glm-5":{"limit":{"context":202752,"output":16384},"modalities":{"input":["text"],"output":["text"]},"name":"GLM-5","reasoning":true,"reasoning_options":[{"type":"toggle"}],"tool_call":true},"glm-5.1":{"limit":{"context":202752,"output":128000},"modalities":{"input":["text"],"output":["text"]},"name":"GLM-5.1","reasoning":true,"reasoning_options":[{"type":"toggle"}],"tool_call":true},"glm-5.2":{"limit":{"context":1000000,"output":131072},"modalities":{"input":["text"],"output":["text"]},"name":"GLM-5.2","reasoning":true,"reasoning_options":[{"type":"effort","values":["high","max"]}],"tool_call":true},"glm-5.3":{"limit":{"context":1000000,"output":131072},"modalities":{"input":["text"],"output":["text"]},"name":"GLM-5.3","reasoning":true,"reasoning_options":[{"type":"effort","values":["low","high","max"]}],"tool_call":true},"happyhorse-1.1-i2v":{"limit":{"context":0,"output":0},"modalities":{"input":["image","text"],"output":["video"]},"name":"HappyHorse 1.1 Image-to-Video","reasoning":false,"tool_call":false},"happyhorse-1.1-r2v":{"limit":{"context":0,"output":0},"modalities":{"input":["image","text"],"output":["video"]},"name":"HappyHorse 1.1 Reference-to-Video","reasoning":false,"tool_call":false},"happyhorse-1.1-t2v":{"limit":{"context":0,"output":0},"modalities":{"input":["text"],"output":["video"]},"name":"HappyHorse 1.1 Text-to-Video","reasoning":false,"tool_call":false},"kimi-k2.5":{"limit":{"context":262144,"output":98304},"modalities":{"input":["text","image","video"],"output":["text"]},"name":"Kimi K2.5","reasoning":true,"reasoning_options":[{"type":"toggle"},{"type":"budget_tokens"}],"tool_call":true},"kimi-k2.6":{"limit":{"context":262144,"output":262144},"modalities":{"input":["text","image","video"],"output":["text"]},"name":"Kimi K2.6","reasoning":true,"reasoning_options":[{"type":"toggle"},{"type":"budget_tokens"}],"tool_call":true},"kimi-k2.7-code":{"limit":{"context":262144,"output":262144},"modalities":{"input":["text","image","video"],"output":["text"]},"name":"Kimi K2.7 Code","reasoning":true,"reasoning_options":[{"type":"toggle"},{"type":"budget_tokens"}],"tool_call":true},"qwen-image-2.0":{"limit":{"context":8192,"output":0},"modalities":{"input":["text"],"output":["image"]},"name":"Qwen Image 2.0","reasoning":false,"tool_call":false},"qwen-image-2.0-pro":{"limit":{"context":8192,"output":0},"modalities":{"input":["text"],"output":["image"]},"name":"Qwen Image 2.0 Pro","reasoning":false,"tool_call":false},"qwen3.6-flash":{"limit":{"context":1000000,"output":65536},"modalities":{"input":["text","image","video"],"output":["text"]},"name":"Qwen3.6 Flash","reasoning":true,"reasoning_options":[{"type":"toggle"},{"max":131072,"type":"budget_tokens"}],"tool_call":true},"qwen3.6-plus":{"limit":{"context":1000000,"output":65536},"modalities":{"input":["text","image","video"],"output":["text"]},"name":"Qwen3.6 Plus","reasoning":true,"reasoning_options":[{"type":"toggle"},{"max":131072,"type":"budget_tokens"}],"tool_call":true},"qwen3.7-max":{"limit":{"context":1000000,Line truncated
+16 -1
View File
@@ -223,7 +223,7 @@ mod tests {
"snapshot lost providers: {}", "snapshot lost providers: {}",
catalog.len() catalog.len()
); );
let k3 = lookup(catalog, "kimi-for-coding", "k3").expect("k3 present"); let k3 = lookup(catalog, "kimi-code-plan-cn", "k3").expect("k3 present");
assert_eq!(k3.context, 1_048_576, "k3 context must match the live wire"); assert_eq!(k3.context, 1_048_576, "k3 context must match the live wire");
assert_eq!(k3.efforts, ["low", "high", "max"]); assert_eq!(k3.efforts, ["low", "high", "max"]);
assert!(k3.reasoning); assert!(k3.reasoning);
@@ -232,6 +232,21 @@ mod tests {
assert_eq!(opus.efforts, ["low", "medium", "high", "xhigh", "max"]); assert_eq!(opus.efforts, ["low", "medium", "high", "xhigh", "max"]);
} }
/// `restrict_to_enriched` drops a live listing id the enrichment catalog
/// does not know, so the bundled snapshot must admit the current flagship
/// models offline: grok-4.7 on xai (the `xai`/`xai-grok` rows) and
/// gpt-6-astra on the API-key `openai` row.
#[test]
fn bundled_snapshot_admits_the_current_flagship_models() {
let catalog = bundled_enrichment();
let grok = lookup(catalog, "xai", "grok-4.7").expect("grok-4.7 present");
assert!(grok.tool_call, "a non-tool-calling model is dropped");
assert_eq!(grok.context, 500_000);
let astra = lookup(catalog, "openai", "gpt-6-astra").expect("gpt-6-astra present");
assert!(astra.tool_call);
assert_eq!(astra.context, 1_050_000);
}
/// Wire-served fields are never overwritten; absent fields are filled. /// Wire-served fields are never overwritten; absent fields are filled.
#[test] #[test]
fn enrich_fills_gaps_and_never_overwrites_wire() { fn enrich_fills_gaps_and_never_overwrites_wire() {
+64 -25
View File
@@ -400,7 +400,7 @@ const KIMI_CODE_SPEC: PlatformSpec = PlatformSpec {
vendor: "Kimi", vendor: "Kimi",
console_host: None, console_host: None,
login_label: None, login_label: None,
models_dev_id: Some("kimi-for-coding"), models_dev_id: Some("kimi-code-plan-cn"),
wire_serves_metadata: true, wire_serves_metadata: true,
wire_api: PlatformWireApi::ChatCompletions, wire_api: PlatformWireApi::ChatCompletions,
listing: ListingDialect::OpenAi, listing: ListingDialect::OpenAi,
@@ -987,7 +987,7 @@ const KIMI_CODING_SPEC: PlatformSpec = PlatformSpec {
vendor: "Kimi", vendor: "Kimi",
console_host: Some("www.kimi.com"), console_host: Some("www.kimi.com"),
login_label: Some("Kimi For Coding (API key)"), login_label: Some("Kimi For Coding (API key)"),
models_dev_id: Some("kimi-for-coding"), models_dev_id: Some("kimi-code-plan-cn"),
wire_serves_metadata: true, wire_serves_metadata: true,
wire_api: PlatformWireApi::ChatCompletions, wire_api: PlatformWireApi::ChatCompletions,
listing: ListingDialect::OpenAi, listing: ListingDialect::OpenAi,
@@ -1570,9 +1570,10 @@ impl PlatformId {
/// The compiled-in catalog for a platform that serves NO live `/models` /// The compiled-in catalog for a platform that serves NO live `/models`
/// listing (openai-codex), or `None` when the catalog comes from the wire. /// listing (openai-codex), or `None` when the catalog comes from the wire.
/// ///
/// openai-codex's 4 models are HARDCODED (read from the official Codex CLI's /// openai-codex's 7 models are HARDCODED (read from the Codex backend
/// `models_cache.json`, the `visibility=="list"` AND `supported_in_api==true` /// catalog on 2026-09-22, the `visibility=="list"` AND
/// set) because OpenAI exposes no stable public models endpoint for the /// `supported_in_api==true` set) because OpenAI exposes no stable public
/// models endpoint for the
/// ChatGPT Codex backend. Each entry carries context window + per-model /// ChatGPT Codex backend. Each entry carries context window + per-model
/// selectable reasoning efforts (incl. the codex-only `xhigh`/`max` /// selectable reasoning efforts (incl. the codex-only `xhigh`/`max`
/// tiers), so the fetch path maps them through the SAME /// tiers), so the fetch path maps them through the SAME
@@ -1606,14 +1607,33 @@ fn codex_wire_model(slug: &str, display_name: &str, efforts: &[&str], default: &
} }
} }
/// The HARDCODED openai-codex catalog: exactly the 4 `visibility=="list"` AND /// The HARDCODED openai-codex catalog: exactly the 7 `visibility=="list"` AND
/// `supported_in_api==true` models from the Codex CLI model cache. The /// `supported_in_api==true` models the Codex backend served on 2026-09-22, in
/// `gpt-5.3-codex-spark` (supported_in_api=false → not served by /responses), /// its own priority order. `gpt-reserve` and `codex-auto-review`
/// `gpt-5.4`, `gpt-5.4-mini`, and `codex-auto-review` (visibility="hide") models /// (visibility="hide") are deliberately EXCLUDED — they are not user-facing
/// are deliberately EXCLUDED — they would list-but-not-work or are not /// (fail-fast: never advertise a model the backend rejects). Several models
/// user-facing (fail-fast: never advertise a model the backend rejects). /// also advertise an `ultra` tier above `max`; kigi has no such level, so it
/// is not listed here.
fn openai_codex_wire_models() -> Vec<WireModel> { fn openai_codex_wire_models() -> Vec<WireModel> {
vec![ vec![
codex_wire_model(
"gpt-6-astra",
"GPT-6-Astra",
&["low", "medium", "high", "xhigh", "max"],
"medium",
),
codex_wire_model(
"gpt-6-sol",
"GPT-6-Sol",
&["low", "medium", "high", "xhigh", "max"],
"medium",
),
codex_wire_model(
"gpt-6-luna",
"GPT-6-Luna",
&["low", "medium", "high", "xhigh", "max"],
"medium",
),
codex_wire_model( codex_wire_model(
"gpt-5.6-sol", "gpt-5.6-sol",
"GPT-5.6-Sol", "GPT-5.6-Sol",
@@ -2653,29 +2673,32 @@ mod tests {
assert_eq!(c.base_url(), "https://mock.codex/codex"); assert_eq!(c.base_url(), "https://mock.codex/codex");
} }
/// The HARDCODED openai-codex catalog is exactly the 4 supported+listed /// The HARDCODED openai-codex catalog is exactly the 7 supported+listed
/// models, keyed by slug, ctx 272000, each exposing its exact supported /// models, keyed by slug, ctx 272000, each exposing its exact supported
/// efforts (incl. the codex-only `xhigh`/`max` tiers). The /// efforts (incl. the codex-only `xhigh`/`max` tiers). The hidden models
/// list-but-broken / hidden models are absent. Every other platform serves /// are absent. Every other platform serves NO hardcoded catalog (its
/// NO hardcoded catalog (its models come from the live wire). /// models come from the live wire).
#[test] #[test]
fn openai_codex_hardcoded_catalog_is_the_four_supported_models() { fn openai_codex_hardcoded_catalog_is_the_seven_supported_models() {
let catalog = PlatformId::OpenaiCodex let catalog = PlatformId::OpenaiCodex
.hardcoded_catalog() .hardcoded_catalog()
.expect("openai-codex serves a hardcoded catalog"); .expect("openai-codex serves a hardcoded catalog");
let ids: Vec<&str> = catalog.iter().map(|m| m.id.as_str()).collect(); let ids: Vec<&str> = catalog.iter().map(|m| m.id.as_str()).collect();
assert_eq!( assert_eq!(
ids, ids,
vec!["gpt-5.6-sol", "gpt-5.6-terra", "gpt-5.6-luna", "gpt-5.5"], vec![
"exactly the 4 visibility=list AND supported_in_api=true models" "gpt-6-astra",
"gpt-6-sol",
"gpt-6-luna",
"gpt-5.6-sol",
"gpt-5.6-terra",
"gpt-5.6-luna",
"gpt-5.5"
],
"exactly the 7 visibility=list AND supported_in_api=true models"
); );
// Excluded: list-but-not-served + hidden models never appear. // Excluded: hidden models never appear.
for absent in [ for absent in ["gpt-reserve", "codex-auto-review"] {
"gpt-5.3-codex-spark",
"gpt-5.4",
"gpt-5.4-mini",
"codex-auto-review",
] {
assert!( assert!(
!ids.contains(&absent), !ids.contains(&absent),
"{absent} must be excluded from the hardcoded catalog" "{absent} must be excluded from the hardcoded catalog"
@@ -2700,6 +2723,19 @@ mod tests {
.valid_efforts .valid_efforts
.clone() .clone()
}; };
assert_eq!(
efforts("gpt-6-astra"),
["low", "medium", "high", "xhigh", "max"],
"`ultra` is advertised above `max` but kigi has no such level"
);
assert_eq!(
efforts("gpt-6-sol"),
["low", "medium", "high", "xhigh", "max"]
);
assert_eq!(
efforts("gpt-6-luna"),
["low", "medium", "high", "xhigh", "max"]
);
assert_eq!( assert_eq!(
efforts("gpt-5.6-sol"), efforts("gpt-5.6-sol"),
["low", "medium", "high", "xhigh", "max"] ["low", "medium", "high", "xhigh", "max"]
@@ -2725,6 +2761,9 @@ mod tests {
.default_effort .default_effort
.clone() .clone()
}; };
assert_eq!(default("gpt-6-astra").as_deref(), Some("medium"));
assert_eq!(default("gpt-6-sol").as_deref(), Some("medium"));
assert_eq!(default("gpt-6-luna").as_deref(), Some("medium"));
assert_eq!(default("gpt-5.6-sol").as_deref(), Some("low")); assert_eq!(default("gpt-5.6-sol").as_deref(), Some("low"));
assert_eq!(default("gpt-5.6-terra").as_deref(), Some("medium")); assert_eq!(default("gpt-5.6-terra").as_deref(), Some("medium"));
// Only openai-codex has a hardcoded catalog; every wire platform is None. // Only openai-codex has a hardcoded catalog; every wire platform is None.
@@ -375,7 +375,6 @@ impl TerminalContext {
return Some("apple_terminal"); return Some("apple_terminal");
} }
if self.is_vte_based() { if self.is_vte_based() {
// WHY: central helper replaces VTE duplication
return Some("vte"); return Some("vte");
} }
if self.brand == TerminalName::WindowsTerminal { if self.brand == TerminalName::WindowsTerminal {
@@ -429,74 +428,29 @@ impl TerminalContext {
} }
/// Whether the running terminal cannot distinguish `Shift+Enter` from /// Whether the running terminal cannot distinguish `Shift+Enter` from
/// bare `Enter` at the byte level, so the UI should advertise /// bare `Enter`, so the UI should advertise `Alt+Enter` (delivered as
/// `Alt+Enter` for newline insertion instead. /// `ESC`+`CR`) for newline insertion instead.
/// ///
/// Distinguishing `Shift+Enter` requires the Kitty keyboard protocol /// Follows [`Self::kitty_skip_reason`] rather than a second brand list:
/// (KKP) to be negotiated. This returns `true` for the environments /// when the protocol is not negotiated the modifier is lost, and the two
/// where the pager cannot rely on KKP for a usable `Shift+Enter`: /// drifted once already (VTE advertised a chord that never arrived — its
/// `Return` keymap encodes only Alt, through 0.82.0 at least, and no VTE
/// release carries the protocol). Two skips still deliver it — Apple
/// Terminal drops the flags but `route_enter` polls CoreGraphics, and
/// Windows console key records carry SHIFT with no protocol at all.
/// ///
/// 1. **Legacy VTE** (GNOME Terminal, Ptyxis, kgx, Tilix, etc.) whose /// KNOWN GAP: WezTerm inside screen or an old tmux gets Alt+Enter as the
/// `VTE_VERSION` is below `8200` (VTE 0.82.0, the first release with /// advice while its own default binding spends that chord on
/// KKP, merged in /// ToggleFullScreen. Neither chord reaches kigi there; the multiplexer
/// [MR !14](https://gitlab.gnome.org/GNOME/vte/-/merge_requests/14)). /// warning carries the real fix, and `\`+Enter still inserts a newline.
/// Also true when the brand is detected as VTE but `VTE_VERSION` is
/// missing or unparseable — we conservatively assume old.
/// 2. **VS Code's integrated terminal (xterm.js) and VS Code-family /
/// xterm.js IDE forks**. xterm.js only partially implements KKP —
/// it mis-encodes shifted printable keys — so the pager deliberately
/// never negotiates KKP for them (see [`Self::kitty_skip_reason`]
/// `== "vscode"` and [xterm.js#5823](https://github.com/xtermjs/xterm.js/issues/5823)).
/// Without KKP, xterm.js sends a bare `CR` for `Shift+Enter`,
/// byte-for-byte identical to `Enter`.
/// 3. **Unidentified terminals with no multiplexer**, where the pager
/// also skips KKP (no positive evidence of support — typically
/// VS Code's xterm.js reached over SSH, where `TERM_PROGRAM` isn't
/// forwarded and the brand falls back to `Unknown`).
///
/// In every case `Alt+Enter` (delivered as `ESC`+`CR`) is the reliable
/// newline chord and is what the UI advertises.
pub fn shift_enter_unavailable(&self) -> bool { pub fn shift_enter_unavailable(&self) -> bool {
// WHY: central helper + version gating match self.kitty_skip_reason() {
let is_vte = self.is_vte_based(); None | Some("apple_terminal") => false,
if is_vte { // A bare ConHost is only optimistically refined to Windows
return match self // Terminal; it still advertises Alt+Enter.
.vte_version Some("windows_terminal") => self.env_brand.is_capability_unclassified(),
.as_deref() Some(_) => true,
.and_then(|v| v.parse::<u32>().ok())
{
Some(ver) => ver < 8200,
// Brand=Vte but no parseable version — conservative: assume old.
None => true,
};
} }
// VS Code / xterm.js and its forks: KKP is never negotiated, so
// Shift+Enter arrives as a bare CR indistinguishable from Enter.
if matches!(
self.brand,
TerminalName::VsCode
| TerminalName::Cursor
| TerminalName::Windsurf
| TerminalName::Zed
) {
return true;
}
// Unidentified / unclassified brand with no multiplexer: KKP is
// skipped (see `kitty_skip_reason`). This is the common
// VS Code-over-SSH shape (brand falls back to Unknown). On native
// Windows the effective `brand` is refined to WindowsTerminal, so
// consult `env_brand` — a bare ConHost is still env-Unknown and
// must advertise Alt+Enter even though we optimistically treat it
// as WT for capabilities.
if self.env_brand.is_capability_unclassified()
&& self.multiplexer == MultiplexerKind::Undetected
{
return true;
}
false
} }
/// True when `Ctrl+.` cannot be delivered reliably as a shortcuts primary. /// True when `Ctrl+.` cannot be delivered reliably as a shortcuts primary.
@@ -1443,7 +1443,7 @@ fn kitty_skip_vscode_over_tmux() {
#[test] #[test]
fn kitty_skip_vte_version() { fn kitty_skip_vte_version() {
// VTE does not support Kitty keyboard protocol and crossterm's probe // No VTE release has the Kitty keyboard protocol and crossterm's probe
// can false-positive on it. https://gitlab.gnome.org/GNOME/vte/-/issues/2601 // can false-positive on it. https://gitlab.gnome.org/GNOME/vte/-/issues/2601
let ctx = TerminalContext { let ctx = TerminalContext {
vte_version: Some("7402".to_owned()), vte_version: Some("7402".to_owned()),
@@ -1461,73 +1461,68 @@ fn kitty_skip_vte_brand() {
assert_eq!(ctx.kitty_skip_reason(), Some("vte")); assert_eq!(ctx.kitty_skip_reason(), Some("vte"));
} }
// shift_enter_unavailable: VTE version gating for Shift+Enter // shift_enter_unavailable: VTE never delivers Shift+Enter
// //
// VTE 0.82.0 (= VTE_VERSION 8200) is the first release containing the // No VTE release carries the Kitty keyboard protocol: at 0.82.0 the word
// Kitty keyboard protocol; earlier versions cannot distinguish // "kitty" appears nowhere in the parser or widget, and
// Shift+Enter from bare Enter, so the UI should advertise Alt+Enter // `_vte_keymap_GDK_Return` encodes only Alt (`ESC CR`), so Shift+Enter is
// for newline insertion instead. // the same bare CR as Enter. The UI advertises Alt+Enter instead.
#[test] #[test]
fn shift_enter_unavailable_legacy_vte_version() { fn shift_enter_unavailable_on_every_vte() {
// VTE 0.64.2 (real user report) — well below the KKP cutoff. for version in [Some("6402"), Some("8200"), Some("8401"), None] {
let ctx = TerminalContext { let ctx = TerminalContext {
vte_version: Some("6402".to_owned()), brand: TerminalName::Vte,
..Default::default() env_brand: TerminalName::Vte,
}; vte_version: version.map(str::to_owned),
assert!(ctx.shift_enter_unavailable()); ..Default::default()
};
assert_eq!(ctx.kitty_skip_reason(), Some("vte"), "VTE {version:?}");
assert!(ctx.shift_enter_unavailable(), "VTE {version:?}");
}
} }
#[test] #[test]
fn shift_enter_unavailable_just_below_cutoff() { fn shift_enter_unavailable_follows_every_kitty_skip() {
// VTE 0.81.99 — anything below 8200 must return true. // A skipped protocol means the modifier never arrives, whatever the
let ctx = TerminalContext { // reason — JediTerm, screen and a multiplexer that eats extended keys
vte_version: Some("8199".to_owned()), // included. Apple Terminal and Windows Terminal are the two skips with
..Default::default() // another way in.
}; for ctx in [
assert!(ctx.shift_enter_unavailable()); TerminalContext {
} brand: TerminalName::JetBrains,
env_brand: TerminalName::JetBrains,
#[test] ..Default::default()
fn shift_enter_available_modern_vte() { },
// VTE 0.82.0 — first release with KKP. TerminalContext {
let ctx = TerminalContext { brand: TerminalName::Kitty,
vte_version: Some("8200".to_owned()), env_brand: TerminalName::Kitty,
..Default::default() multiplexer: MultiplexerKind::Screen,
}; ..Default::default()
assert!(!ctx.shift_enter_unavailable()); },
} TerminalContext {
brand: TerminalName::Kitty,
#[test] env_brand: TerminalName::Kitty,
fn shift_enter_available_future_vte() { multiplexer: MultiplexerKind::Tmux,
// VTE 0.84.1 — well above the cutoff. tmux_version: Some("3.2".to_owned()),
let ctx = TerminalContext { ..Default::default()
vte_version: Some("8401".to_owned()), },
..Default::default() // A VTE carrying a recent VTE_VERSION is no different.
}; TerminalContext {
assert!(!ctx.shift_enter_unavailable()); brand: TerminalName::Vte,
} env_brand: TerminalName::Vte,
vte_version: Some("8200".to_owned()),
#[test] multiplexer: MultiplexerKind::Screen,
fn shift_enter_unavailable_vte_brand_no_version() { ..Default::default()
// Brand detected as VTE but VTE_VERSION missing — conservative: old. },
let ctx = TerminalContext { ] {
brand: TerminalName::Vte, assert!(ctx.kitty_skip_reason().is_some());
vte_version: None, assert!(
..Default::default() ctx.shift_enter_unavailable(),
}; "{:?} skips the protocol, so Shift+Enter cannot arrive",
assert!(ctx.shift_enter_unavailable()); ctx.brand
} );
}
#[test]
fn shift_enter_unavailable_unparseable_version() {
// Garbage in VTE_VERSION — conservative: old.
let ctx = TerminalContext {
brand: TerminalName::Vte,
vte_version: Some("not-a-number".to_owned()),
..Default::default()
};
assert!(ctx.shift_enter_unavailable());
} }
#[test] #[test]
@@ -1156,7 +1156,7 @@ pub const ANTHROPIC_OAUTH_BETA: &str = "claude-code-20250219,oauth-2025-04-20";
/// User-Agent kigi presents on the Claude-Code OAuth path (mirrors the /// User-Agent kigi presents on the Claude-Code OAuth path (mirrors the
/// official Claude Code CLI). OAuth-gated: unrelated to the default kigi UA. /// official Claude Code CLI). OAuth-gated: unrelated to the default kigi UA.
pub const CLAUDE_CODE_USER_AGENT: &str = "claude-cli/2.1.75"; pub const CLAUDE_CODE_USER_AGENT: &str = "claude-cli/2.1.280";
/// System-prompt prefix REQUIRED on the Claude-Code OAuth Messages path: the /// System-prompt prefix REQUIRED on the Claude-Code OAuth Messages path: the
/// OAuth token is Claude-Code-scoped, so Anthropic rejects the request unless /// OAuth token is Claude-Code-scoped, so Anthropic rejects the request unless
@@ -1202,7 +1202,7 @@ pub const CODEX_OPENAI_BETA: &str = "responses=experimental";
/// openai-codex-gated). The Codex backend does not strictly validate the UA /// openai-codex-gated). The Codex backend does not strictly validate the UA
/// string (Pi ships its own and it works), so this is a stable best-effort /// string (Pi ships its own and it works), so this is a stable best-effort
/// identity, not a pinned build. /// identity, not a pinned build.
pub const CODEX_USER_AGENT: &str = "codex_cli_rs/0.104.0"; pub const CODEX_USER_AGENT: &str = "codex_cli_rs/0.156.0";
/// JWT payload claim namespace carrying the ChatGPT account id. /// JWT payload claim namespace carrying the ChatGPT account id.
const CODEX_JWT_AUTH_CLAIM: &str = "https://api.openai.com/auth"; const CODEX_JWT_AUTH_CLAIM: &str = "https://api.openai.com/auth";
@@ -367,7 +367,7 @@ mod tests {
let _url = EnvGuard::set(MODELS_DEV_URL_ENV, "http://127.0.0.1:1/api.json"); let _url = EnvGuard::set(MODELS_DEV_URL_ENV, "http://127.0.0.1:1/api.json");
let catalog = load_enrichment_catalog_at(&path); let catalog = load_enrichment_catalog_at(&path);
assert!( assert!(
kigi_models::enrichment::lookup(&catalog, "kimi-for-coding", "k3").is_some(), kigi_models::enrichment::lookup(&catalog, "kimi-code-plan-cn", "k3").is_some(),
"bundled snapshot must back a total refresh failure" "bundled snapshot must back a total refresh failure"
); );
assert!(!path.exists(), "failed refresh must not write a cache"); assert!(!path.exists(), "failed refresh must not write a cache");
@@ -385,7 +385,7 @@ mod tests {
let _url = EnvGuard::set(MODELS_DEV_URL_ENV, token); let _url = EnvGuard::set(MODELS_DEV_URL_ENV, token);
assert!(refresh_url().is_none(), "token {token:?} must disable"); assert!(refresh_url().is_none(), "token {token:?} must disable");
let catalog = load_enrichment_catalog_at(&path); let catalog = load_enrichment_catalog_at(&path);
assert!(kigi_models::enrichment::lookup(&catalog, "kimi-for-coding", "k3").is_some()); assert!(kigi_models::enrichment::lookup(&catalog, "kimi-code-plan-cn", "k3").is_some());
} }
} }
@@ -1473,7 +1473,7 @@ mod tests {
/// openai-codex fetch: the catalog is HARDCODED, so the fetch path /// openai-codex fetch: the catalog is HARDCODED, so the fetch path
/// short-circuits BEFORE any HTTP — there is NO mock `/models` server, yet /// short-circuits BEFORE any HTTP — there is NO mock `/models` server, yet
/// the fetch returns exactly the 4 compiled-in models keyed /// the fetch returns exactly the 7 compiled-in models keyed
/// `openai-codex/<slug>` on the Responses backend, ctx 272000, each exposing /// `openai-codex/<slug>` on the Responses backend, ctx 272000, each exposing
/// its exact reasoning efforts (incl. the codex-only `xhigh`/`max`). /// its exact reasoning efforts (incl. the codex-only `xhigh`/`max`).
/// A BOGUS base URL confirms no live `/models` request is attempted (it would /// A BOGUS base URL confirms no live `/models` request is attempted (it would
@@ -1510,20 +1510,18 @@ mod tests {
.map(|m| m.id.as_deref().unwrap_or_default()) .map(|m| m.id.as_deref().unwrap_or_default())
.collect::<Vec<_>>(), .collect::<Vec<_>>(),
vec![ vec![
"openai-codex/gpt-6-astra",
"openai-codex/gpt-6-sol",
"openai-codex/gpt-6-luna",
"openai-codex/gpt-5.6-sol", "openai-codex/gpt-5.6-sol",
"openai-codex/gpt-5.6-terra", "openai-codex/gpt-5.6-terra",
"openai-codex/gpt-5.6-luna", "openai-codex/gpt-5.6-luna",
"openai-codex/gpt-5.5", "openai-codex/gpt-5.5",
], ],
"exactly the 4 hardcoded models, keyed openai-codex/<slug>" "exactly the 7 hardcoded models, keyed openai-codex/<slug>"
); );
// Excluded models never appear. // Excluded models never appear.
for absent in [ for absent in ["openai-codex/gpt-reserve", "openai-codex/codex-auto-review"] {
"openai-codex/gpt-5.3-codex-spark",
"openai-codex/gpt-5.4",
"openai-codex/gpt-5.4-mini",
"openai-codex/codex-auto-review",
] {
assert!( assert!(
!result !result
.models .models
@@ -1532,7 +1530,14 @@ mod tests {
"{absent} must be absent from the hardcoded catalog" "{absent} must be absent from the hardcoded catalog"
); );
} }
let sol = &result.models[0]; let astra = &result.models[0];
assert_eq!(astra.name.as_deref(), Some("GPT-6-Astra"));
assert_eq!(astra.context_window.get(), 272_000);
let sol = result
.models
.iter()
.find(|m| m.id.as_deref() == Some("openai-codex/gpt-5.6-sol"))
.unwrap();
assert_eq!( assert_eq!(
sol.api_backend, sol.api_backend,
crate::sampling::ApiBackend::Responses, crate::sampling::ApiBackend::Responses,
@@ -96,16 +96,15 @@ impl SlashCommand for TerminalSetupCommand {
// Some terminals can't distinguish Shift+Enter from bare Enter at // Some terminals can't distinguish Shift+Enter from bare Enter at
// the byte level because the Kitty keyboard protocol isn't // the byte level because the Kitty keyboard protocol isn't
// negotiated (VTE < 0.82, or VS Code's xterm.js which mis-encodes // negotiated (VTE, VS Code's xterm.js, a multiplexer that eats
// shifted keys). Point users at Alt+Enter, which is reliably // extended keys). Point users at Alt+Enter, which is reliably
// delivered as ESC+CR. Suppressed when the WezTerm warning fired: // delivered as ESC+CR. Never for WezTerm: it binds Alt+Enter to
// stock WezTerm binds Alt+Enter to ToggleFullScreen, so advertising // ToggleFullScreen, so its own warning's `\`+Enter guidance stands.
// it would contradict that warning's `\`+Enter guidance. if ctx.shift_enter_unavailable() && !wezterm_kkp_off && ctx.brand != TerminalName::WezTerm {
if ctx.shift_enter_unavailable() && !wezterm_kkp_off {
let detail = if ctx.vte_version.is_some() || ctx.brand == TerminalName::Vte { let detail = if ctx.vte_version.is_some() || ctx.brand == TerminalName::Vte {
match ctx.vte_version.as_deref() { match ctx.vte_version.as_deref() {
Some(v) => format!("VTE {v}; need >= 8200 for Shift+Enter"), Some(v) => format!("VTE {v}: no Kitty keyboard protocol"),
None => "legacy VTE; need VTE >= 0.82 for Shift+Enter".to_owned(), None => "VTE: no Kitty keyboard protocol".to_owned(),
} }
} else if matches!( } else if matches!(
ctx.brand, ctx.brand,
+1 -1
View File
@@ -24,7 +24,7 @@ TARGETS = [
"anthropic", "azure", "openai", "deepseek", "nvidia", "google", "anthropic", "azure", "openai", "deepseek", "nvidia", "google",
"amazon-bedrock", "mistral", "groq", "cerebras", "cloudflare-ai-gateway", "amazon-bedrock", "mistral", "groq", "cerebras", "cloudflare-ai-gateway",
"xai", "togetherai", "fireworks-ai", "opencode", "opencode-go", "xai", "togetherai", "fireworks-ai", "opencode", "opencode-go",
"kimi-for-coding", "moonshotai", "moonshotai-cn", "minimax", "minimax-cn", "kimi-code-plan-cn", "moonshotai", "moonshotai-cn", "minimax", "minimax-cn",
"alibaba-token-plan", "alibaba-token-plan-cn", "xiaomi", "alibaba-token-plan", "alibaba-token-plan-cn", "xiaomi",
"xiaomi-token-plan-cn", "zai-coding-plan", "zhipuai-coding-plan", "xiaomi-token-plan-cn", "zai-coding-plan", "zhipuai-coding-plan",
"github-copilot", "vercel", "github-copilot", "vercel",