Merge branch 'main' into typebox-fallback

This commit is contained in:
Armin Ronacher 2026-04-16 07:25:55 +02:00
commit bd1099f48e
30 changed files with 209 additions and 151 deletions

View file

@ -149,3 +149,5 @@ lucasmeijer pr
Evizero pr
ofa1 pr
crisog issue

168
package-lock.json generated
View file

@ -1395,9 +1395,9 @@
}
},
"node_modules/@google/genai": {
"version": "1.50.0",
"resolved": "https://registry.npmjs.org/@google/genai/-/genai-1.50.0.tgz",
"integrity": "sha512-oHv7JfdI6SLUitERptYoHqpn4Y2wWyPOBfWtpw8kfKTqqEiMJpUC6SEtiQPogb55Ip8fymj4bxGnGBTVV/Z9Ew==",
"version": "1.50.1",
"resolved": "https://registry.npmjs.org/@google/genai/-/genai-1.50.1.tgz",
"integrity": "sha512-YbkX7H9+1Pt8wOt7DDREy8XSoiL6fRDzZQRyaVBarFf8MR3zHGqVdvM4cLbDXqPhxqvegZShgfxb8kw9C7YhAQ==",
"license": "Apache-2.0",
"dependencies": {
"google-auth-library": "^10.3.0",
@ -1809,9 +1809,9 @@
}
},
"node_modules/@napi-rs/canvas": {
"version": "0.1.97",
"resolved": "https://registry.npmjs.org/@napi-rs/canvas/-/canvas-0.1.97.tgz",
"integrity": "sha512-8cFniXvrIEnVwuNSRCW9wirRZbHvrD3JVujdS2P5n5xiJZNZMOZcfOvJ1pb66c7jXMKHHglJEDVJGbm8XWFcXQ==",
"version": "0.1.98",
"resolved": "https://registry.npmjs.org/@napi-rs/canvas/-/canvas-0.1.98.tgz",
"integrity": "sha512-WDg3lxYMqlrg49sDVUlrHVfIEPsd5AjYDRuGD6Fu82K5agJx0UnWA+l5qd53GNLRiMN2WhOw7FLR+Er5QB/0SA==",
"license": "MIT",
"optional": true,
"workspaces": [
@ -1825,23 +1825,23 @@
"url": "https://github.com/sponsors/Brooooooklyn"
},
"optionalDependencies": {
"@napi-rs/canvas-android-arm64": "0.1.97",
"@napi-rs/canvas-darwin-arm64": "0.1.97",
"@napi-rs/canvas-darwin-x64": "0.1.97",
"@napi-rs/canvas-linux-arm-gnueabihf": "0.1.97",
"@napi-rs/canvas-linux-arm64-gnu": "0.1.97",
"@napi-rs/canvas-linux-arm64-musl": "0.1.97",
"@napi-rs/canvas-linux-riscv64-gnu": "0.1.97",
"@napi-rs/canvas-linux-x64-gnu": "0.1.97",
"@napi-rs/canvas-linux-x64-musl": "0.1.97",
"@napi-rs/canvas-win32-arm64-msvc": "0.1.97",
"@napi-rs/canvas-win32-x64-msvc": "0.1.97"
"@napi-rs/canvas-android-arm64": "0.1.98",
"@napi-rs/canvas-darwin-arm64": "0.1.98",
"@napi-rs/canvas-darwin-x64": "0.1.98",
"@napi-rs/canvas-linux-arm-gnueabihf": "0.1.98",
"@napi-rs/canvas-linux-arm64-gnu": "0.1.98",
"@napi-rs/canvas-linux-arm64-musl": "0.1.98",
"@napi-rs/canvas-linux-riscv64-gnu": "0.1.98",
"@napi-rs/canvas-linux-x64-gnu": "0.1.98",
"@napi-rs/canvas-linux-x64-musl": "0.1.98",
"@napi-rs/canvas-win32-arm64-msvc": "0.1.98",
"@napi-rs/canvas-win32-x64-msvc": "0.1.98"
}
},
"node_modules/@napi-rs/canvas-android-arm64": {
"version": "0.1.97",
"resolved": "https://registry.npmjs.org/@napi-rs/canvas-android-arm64/-/canvas-android-arm64-0.1.97.tgz",
"integrity": "sha512-V1c/WVw+NzH8vk7ZK/O8/nyBSCQimU8sfMsB/9qeSvdkGKNU7+mxy/bIF0gTgeBFmHpj30S4E9WHMSrxXGQuVQ==",
"version": "0.1.98",
"resolved": "https://registry.npmjs.org/@napi-rs/canvas-android-arm64/-/canvas-android-arm64-0.1.98.tgz",
"integrity": "sha512-O45Ifr0WZJUrSyg0QgB+67TiC0zYBRkBK+d43ZV4JtlwH3XttiVxLvlxEeULiH5y1MSELruspF0bjF6xXwJNPQ==",
"cpu": [
"arm64"
],
@ -1859,9 +1859,9 @@
}
},
"node_modules/@napi-rs/canvas-darwin-arm64": {
"version": "0.1.97",
"resolved": "https://registry.npmjs.org/@napi-rs/canvas-darwin-arm64/-/canvas-darwin-arm64-0.1.97.tgz",
"integrity": "sha512-ok+SCEF4YejcxuJ9Rm+WWunHHpf2HmiPxfz6z1a/NFQECGXtsY7A4B8XocK1LmT1D7P174MzwPF9Wy3AUAwEPw==",
"version": "0.1.98",
"resolved": "https://registry.npmjs.org/@napi-rs/canvas-darwin-arm64/-/canvas-darwin-arm64-0.1.98.tgz",
"integrity": "sha512-1b/nQhw6Isdv14JokUqat+i5wrAYD+ce3egiotedBGRUjVxYSj4s2uQCh2bFsyX5/9A5iTKVGsWoQhFft+j7Lg==",
"cpu": [
"arm64"
],
@ -1879,9 +1879,9 @@
}
},
"node_modules/@napi-rs/canvas-darwin-x64": {
"version": "0.1.97",
"resolved": "https://registry.npmjs.org/@napi-rs/canvas-darwin-x64/-/canvas-darwin-x64-0.1.97.tgz",
"integrity": "sha512-PUP6e6/UGlclUvAQNnuXCcnkpdUou6VYZfQOQxExLp86epOylmiwLkqXIvpFmjoTEDmPmXrI+coL/9EFU1gKPA==",
"version": "0.1.98",
"resolved": "https://registry.npmjs.org/@napi-rs/canvas-darwin-x64/-/canvas-darwin-x64-0.1.98.tgz",
"integrity": "sha512-oefzfBM8mwnyYp6S+yNXwjCoLdkOalFG24mssHgvrJDS0FulOryyI35Q7GdJGmrzuL4oo1XW3ZTOcTBLdJ8Zkg==",
"cpu": [
"x64"
],
@ -1899,9 +1899,9 @@
}
},
"node_modules/@napi-rs/canvas-linux-arm-gnueabihf": {
"version": "0.1.97",
"resolved": "https://registry.npmjs.org/@napi-rs/canvas-linux-arm-gnueabihf/-/canvas-linux-arm-gnueabihf-0.1.97.tgz",
"integrity": "sha512-XyXH2L/cic8eTNtbrXCcvqHtMX/nEOxN18+7rMrAM2XtLYC/EB5s0wnO1FsLMWmK+04ZSLN9FBGipo7kpIkcOw==",
"version": "0.1.98",
"resolved": "https://registry.npmjs.org/@napi-rs/canvas-linux-arm-gnueabihf/-/canvas-linux-arm-gnueabihf-0.1.98.tgz",
"integrity": "sha512-NDH5QXGmf8wlo5yhijCNGVFiJk7an5GvHwb2LHyfLQWY/6/S48i5+YtY6FPqPVVCUckNGudYOfXEJnb3/FiJGQ==",
"cpu": [
"arm"
],
@ -1919,9 +1919,9 @@
}
},
"node_modules/@napi-rs/canvas-linux-arm64-gnu": {
"version": "0.1.97",
"resolved": "https://registry.npmjs.org/@napi-rs/canvas-linux-arm64-gnu/-/canvas-linux-arm64-gnu-0.1.97.tgz",
"integrity": "sha512-Kuq/M3djq0K8ktgz6nPlK7Ne5d4uWeDxPpyKWOjWDK2RIOhHVtLtyLiJw2fuldw7Vn4mhw05EZXCEr4Q76rs9w==",
"version": "0.1.98",
"resolved": "https://registry.npmjs.org/@napi-rs/canvas-linux-arm64-gnu/-/canvas-linux-arm64-gnu-0.1.98.tgz",
"integrity": "sha512-KBLLM6tu1xs80LSAqdSLBKkgct0S23MCEf/aq8yxzg5imAceqp1ulKeELgWaYm27MgpUhm3Q7jmegX12FfphwA==",
"cpu": [
"arm64"
],
@ -1939,9 +1939,9 @@
}
},
"node_modules/@napi-rs/canvas-linux-arm64-musl": {
"version": "0.1.97",
"resolved": "https://registry.npmjs.org/@napi-rs/canvas-linux-arm64-musl/-/canvas-linux-arm64-musl-0.1.97.tgz",
"integrity": "sha512-kKmSkQVnWeqg7qdsiXvYxKhAFuHz3tkBjW/zyQv5YKUPhotpaVhpBGv5LqCngzyuRV85SXoe+OFj+Tv0a0QXkQ==",
"version": "0.1.98",
"resolved": "https://registry.npmjs.org/@napi-rs/canvas-linux-arm64-musl/-/canvas-linux-arm64-musl-0.1.98.tgz",
"integrity": "sha512-mfMNhjN5zDcJafqQ6sHj4Tc3YMTRxP5UA3MHtp/ssytBR/k6XO0x+1IIPtscnUKwha+ql1++WjDCGEgqu8OfWQ==",
"cpu": [
"arm64"
],
@ -1959,9 +1959,9 @@
}
},
"node_modules/@napi-rs/canvas-linux-riscv64-gnu": {
"version": "0.1.97",
"resolved": "https://registry.npmjs.org/@napi-rs/canvas-linux-riscv64-gnu/-/canvas-linux-riscv64-gnu-0.1.97.tgz",
"integrity": "sha512-Jc7I3A51jnEOIAXeLsN/M/+Z28LUeakcsXs07FLq9prXc0eYOtVwsDEv913Gr+06IRo34gJJVgT0TXvmz+N2VA==",
"version": "0.1.98",
"resolved": "https://registry.npmjs.org/@napi-rs/canvas-linux-riscv64-gnu/-/canvas-linux-riscv64-gnu-0.1.98.tgz",
"integrity": "sha512-nfW8esrcaeuhrO3qGA5cwuyk4Ak6cn2eB0LtEYtqROIl+fz06CNGNCU0M95+Tspw5ZgfSbc98SaigT5r5B3LVQ==",
"cpu": [
"riscv64"
],
@ -1979,9 +1979,9 @@
}
},
"node_modules/@napi-rs/canvas-linux-x64-gnu": {
"version": "0.1.97",
"resolved": "https://registry.npmjs.org/@napi-rs/canvas-linux-x64-gnu/-/canvas-linux-x64-gnu-0.1.97.tgz",
"integrity": "sha512-iDUBe7AilfuBSRbSa8/IGX38Mf+iCSBqoVKLSQ5XaY2JLOaqz1TVyPFEyIck7wT6mRQhQt5sN6ogfjIDfi74tg==",
"version": "0.1.98",
"resolved": "https://registry.npmjs.org/@napi-rs/canvas-linux-x64-gnu/-/canvas-linux-x64-gnu-0.1.98.tgz",
"integrity": "sha512-318UT8j6Gro2bTjtutjQXHWp9SLTNw+WRS4wQ6XIRPAyzBGnGHg7x2ndD+oqkPrrSRIbYLA5WoBcCasaF7lSTQ==",
"cpu": [
"x64"
],
@ -1999,9 +1999,9 @@
}
},
"node_modules/@napi-rs/canvas-linux-x64-musl": {
"version": "0.1.97",
"resolved": "https://registry.npmjs.org/@napi-rs/canvas-linux-x64-musl/-/canvas-linux-x64-musl-0.1.97.tgz",
"integrity": "sha512-AKLFd/v0Z5fvgqBDqhvqtAdx+fHMJ5t9JcUNKq4FIZ5WH+iegGm8HPdj00NFlCSnm83Fp3Ln8I2f7uq1aIiWaA==",
"version": "0.1.98",
"resolved": "https://registry.npmjs.org/@napi-rs/canvas-linux-x64-musl/-/canvas-linux-x64-musl-0.1.98.tgz",
"integrity": "sha512-0vZhI74UxnA4VqlW4UvM0dFRrjE1RLEe/OXSBjzytGIxV+yOG4exlrhGoIpAQaIpQQQXMCdb1EmbvPC1k9vEqQ==",
"cpu": [
"x64"
],
@ -2019,9 +2019,9 @@
}
},
"node_modules/@napi-rs/canvas-win32-arm64-msvc": {
"version": "0.1.97",
"resolved": "https://registry.npmjs.org/@napi-rs/canvas-win32-arm64-msvc/-/canvas-win32-arm64-msvc-0.1.97.tgz",
"integrity": "sha512-u883Yr6A6fO7Vpsy9YE4FVCIxzzo5sO+7pIUjjoDLjS3vQaNMkVzx5bdIpEL+ob+gU88WDK4VcxYMZ6nmnoX9A==",
"version": "0.1.98",
"resolved": "https://registry.npmjs.org/@napi-rs/canvas-win32-arm64-msvc/-/canvas-win32-arm64-msvc-0.1.98.tgz",
"integrity": "sha512-oiC/IxgFEEVcZ7VH7JXXlmgsqRvmFb57PIQ4gQck35IKFZCNUvdNCcN3OeoLP7Hpf5160MWJf9jj/+E5V0bSvw==",
"cpu": [
"arm64"
],
@ -2039,9 +2039,9 @@
}
},
"node_modules/@napi-rs/canvas-win32-x64-msvc": {
"version": "0.1.97",
"resolved": "https://registry.npmjs.org/@napi-rs/canvas-win32-x64-msvc/-/canvas-win32-x64-msvc-0.1.97.tgz",
"integrity": "sha512-sWtD2EE3fV0IzN+iiQUqr/Q1SwqWhs2O1FKItFlxtdDkikpEj5g7DKQpY3x55H/MAOnL8iomnlk3mcEeGiUMoQ==",
"version": "0.1.98",
"resolved": "https://registry.npmjs.org/@napi-rs/canvas-win32-x64-msvc/-/canvas-win32-x64-msvc-0.1.98.tgz",
"integrity": "sha512-ZqstKAJBSyZetU8udUvBQWPlGN9buawFvjuo9mgCAxzbOoJAgXX39ihec/nn42T5Vb6/qyn45eTimx5ND9kMEw==",
"cpu": [
"x64"
],
@ -4364,9 +4364,9 @@
"license": "MIT"
},
"node_modules/basic-ftp": {
"version": "5.2.2",
"resolved": "https://registry.npmjs.org/basic-ftp/-/basic-ftp-5.2.2.tgz",
"integrity": "sha512-1tDrzKsdCg70WGvbFss/ulVAxupNauGnOlgpyjKzeQxzyllBLS0CGLV7tjIXTK3ZQA9/FBEm9qyFFN1bciA6pw==",
"version": "5.3.0",
"resolved": "https://registry.npmjs.org/basic-ftp/-/basic-ftp-5.3.0.tgz",
"integrity": "sha512-5K9eNNn7ywHPsYnFwjKgYH8Hf8B5emh7JKcPaVjjrMJFQQwGpwowEnZNEtHs7DfR7hCZsmaK3VA4HUK0YarT+w==",
"license": "MIT",
"engines": {
"node": ">=10.0.0"
@ -5601,9 +5601,9 @@
}
},
"node_modules/get-tsconfig": {
"version": "4.13.7",
"resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.13.7.tgz",
"integrity": "sha512-7tN6rFgBlMgpBML5j8typ92BKFi2sFQvIdpAqLA2beia5avZDrMs0FLZiM5etShWq5irVyGcGMEA1jcDaK7A/Q==",
"version": "4.14.0",
"resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.14.0.tgz",
"integrity": "sha512-yTb+8DXzDREzgvYmh6s9vHsSVCHeC0G3PI5bEXNBHtmshPnO+S5O7qgLEOn0I5QvMy6kpZN8K1NKGyilLb93wA==",
"devOptional": true,
"license": "MIT",
"dependencies": {
@ -7025,9 +7025,9 @@
}
},
"node_modules/postcss": {
"version": "8.5.9",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.9.tgz",
"integrity": "sha512-7a70Nsot+EMX9fFU3064K/kdHWZqGVY+BADLyXc8Dfv+mTLLVl6JzJpPaCZ2kQL9gIJvKXSLMHhqdRRjwQeFtw==",
"version": "8.5.10",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.10.tgz",
"integrity": "sha512-pMMHxBOZKFU6HgAZ4eyGnwXF/EvPGGqUr0MnZ5+99485wwW41kW91A4LOGxSHhgugZmSChL5AlElNdwlNgcnLQ==",
"funding": [
{
"type": "opencollective",
@ -7107,9 +7107,9 @@
}
},
"node_modules/protobufjs": {
"version": "7.5.4",
"resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.5.4.tgz",
"integrity": "sha512-CvexbZtbov6jW2eXAvLukXjXUW1TzFaivC46BpWc/3BpcCysb5Vffu+B3XHMm8lVEuy2Mm4XGex8hBSg1yapPg==",
"version": "7.5.5",
"resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.5.5.tgz",
"integrity": "sha512-3wY1AxV+VBNW8Yypfd1yQY9pXnqTAN+KwQxL8iYm3/BjKYMNg4i0owhEe26PWDOMaIrzeeF98Lqd5NGz4omiIg==",
"hasInstallScript": true,
"license": "BSD-3-Clause",
"dependencies": {
@ -8555,10 +8555,10 @@
},
"packages/agent": {
"name": "@mariozechner/pi-agent-core",
"version": "0.67.2",
"version": "0.67.3",
"license": "MIT",
"dependencies": {
"@mariozechner/pi-ai": "^0.67.2"
"@mariozechner/pi-ai": "^0.67.3"
},
"devDependencies": {
"@types/node": "^24.3.0",
@ -8588,7 +8588,7 @@
},
"packages/ai": {
"name": "@mariozechner/pi-ai",
"version": "0.67.2",
"version": "0.67.3",
"license": "MIT",
"dependencies": {
"@anthropic-ai/sdk": "^0.73.0",
@ -8636,13 +8636,13 @@
},
"packages/coding-agent": {
"name": "@mariozechner/pi-coding-agent",
"version": "0.67.2",
"version": "0.67.3",
"license": "MIT",
"dependencies": {
"@mariozechner/jiti": "^2.6.2",
"@mariozechner/pi-agent-core": "^0.67.2",
"@mariozechner/pi-ai": "^0.67.2",
"@mariozechner/pi-tui": "^0.67.2",
"@mariozechner/pi-agent-core": "^0.67.3",
"@mariozechner/pi-ai": "^0.67.3",
"@mariozechner/pi-tui": "^0.67.3",
"@silvia-odwyer/photon-node": "^0.3.4",
"ajv": "^8.17.1",
"chalk": "^5.5.0",
@ -8683,22 +8683,22 @@
},
"packages/coding-agent/examples/extensions/custom-provider-anthropic": {
"name": "pi-extension-custom-provider-anthropic",
"version": "1.18.2",
"version": "1.18.3",
"dependencies": {
"@anthropic-ai/sdk": "^0.52.0"
}
},
"packages/coding-agent/examples/extensions/custom-provider-gitlab-duo": {
"name": "pi-extension-custom-provider-gitlab-duo",
"version": "1.18.2"
"version": "1.18.3"
},
"packages/coding-agent/examples/extensions/custom-provider-qwen-cli": {
"name": "pi-extension-custom-provider-qwen-cli",
"version": "1.17.2"
"version": "1.17.3"
},
"packages/coding-agent/examples/extensions/with-deps": {
"name": "pi-extension-with-deps",
"version": "1.31.2",
"version": "1.31.3",
"dependencies": {
"ms": "^2.1.3"
},
@ -8734,13 +8734,13 @@
},
"packages/mom": {
"name": "@mariozechner/pi-mom",
"version": "0.67.2",
"version": "0.67.3",
"license": "MIT",
"dependencies": {
"@anthropic-ai/sandbox-runtime": "^0.0.16",
"@mariozechner/pi-agent-core": "^0.67.2",
"@mariozechner/pi-ai": "^0.67.2",
"@mariozechner/pi-coding-agent": "^0.67.2",
"@mariozechner/pi-agent-core": "^0.67.3",
"@mariozechner/pi-ai": "^0.67.3",
"@mariozechner/pi-coding-agent": "^0.67.3",
"@sinclair/typebox": "^0.34.0",
"@slack/socket-mode": "^2.0.0",
"@slack/web-api": "^7.0.0",
@ -8779,10 +8779,10 @@
},
"packages/pods": {
"name": "@mariozechner/pi",
"version": "0.67.2",
"version": "0.67.3",
"license": "MIT",
"dependencies": {
"@mariozechner/pi-agent-core": "^0.67.2",
"@mariozechner/pi-agent-core": "^0.67.3",
"chalk": "^5.5.0"
},
"bin": {
@ -8795,7 +8795,7 @@
},
"packages/tui": {
"name": "@mariozechner/pi-tui",
"version": "0.67.2",
"version": "0.67.3",
"license": "MIT",
"dependencies": {
"@types/mime-types": "^2.1.4",
@ -8842,12 +8842,12 @@
},
"packages/web-ui": {
"name": "@mariozechner/pi-web-ui",
"version": "0.67.2",
"version": "0.67.3",
"license": "MIT",
"dependencies": {
"@lmstudio/sdk": "^1.5.0",
"@mariozechner/pi-ai": "^0.67.2",
"@mariozechner/pi-tui": "^0.67.2",
"@mariozechner/pi-ai": "^0.67.3",
"@mariozechner/pi-tui": "^0.67.3",
"docx-preview": "^0.3.7",
"jszip": "^3.10.1",
"lucide": "^0.544.0",
@ -8868,7 +8868,7 @@
},
"packages/web-ui/example": {
"name": "pi-web-ui-example",
"version": "1.55.2",
"version": "1.55.3",
"dependencies": {
"@mariozechner/mini-lit": "^0.2.0",
"@mariozechner/pi-ai": "file:../../ai",

View file

@ -2,6 +2,8 @@
## [Unreleased]
## [0.67.3] - 2026-04-15
## [0.67.2] - 2026-04-14
## [0.67.1] - 2026-04-13

View file

@ -1,6 +1,6 @@
{
"name": "@mariozechner/pi-agent-core",
"version": "0.67.2",
"version": "0.67.3",
"description": "General-purpose agent with transport abstraction, state management, and attachment support",
"type": "module",
"main": "./dist/index.js",
@ -17,7 +17,7 @@
"prepublishOnly": "npm run clean && npm run build"
},
"dependencies": {
"@mariozechner/pi-ai": "^0.67.2"
"@mariozechner/pi-ai": "^0.67.3"
},
"keywords": [
"ai",

View file

@ -2,6 +2,12 @@
## [Unreleased]
## [0.67.3] - 2026-04-15
### Fixed
- Fixed `google-vertex` API key resolution to treat `gcp-vertex-credentials` as an Application Default Credentials marker instead of a literal API key, so marker-based setups correctly fall back to ADC ([#3221](https://github.com/badlogic/pi-mono/pull/3221) by [@deepkilo](https://github.com/deepkilo))
## [0.67.2] - 2026-04-14
### Fixed

View file

@ -1,6 +1,6 @@
{
"name": "@mariozechner/pi-ai",
"version": "0.67.2",
"version": "0.67.3",
"description": "Unified LLM API with automatic model discovery and provider configuration",
"type": "module",
"main": "./dist/index.js",

View file

@ -7744,23 +7744,6 @@ export const MODELS = {
contextWindow: 262144,
maxTokens: 32768,
} satisfies Model<"openai-completions">,
"inception/mercury": {
id: "inception/mercury",
name: "Inception: Mercury",
api: "openai-completions",
provider: "openrouter",
baseUrl: "https://openrouter.ai/api/v1",
reasoning: false,
input: ["text"],
cost: {
input: 0.25,
output: 0.75,
cacheRead: 0.024999999999999998,
cacheWrite: 0,
},
contextWindow: 128000,
maxTokens: 32000,
} satisfies Model<"openai-completions">,
"inception/mercury-2": {
id: "inception/mercury-2",
name: "Inception: Mercury 2",
@ -7778,23 +7761,6 @@ export const MODELS = {
contextWindow: 128000,
maxTokens: 50000,
} satisfies Model<"openai-completions">,
"inception/mercury-coder": {
id: "inception/mercury-coder",
name: "Inception: Mercury Coder",
api: "openai-completions",
provider: "openrouter",
baseUrl: "https://openrouter.ai/api/v1",
reasoning: false,
input: ["text"],
cost: {
input: 0.25,
output: 0.75,
cacheRead: 0.024999999999999998,
cacheWrite: 0,
},
contextWindow: 128000,
maxTokens: 32000,
} satisfies Model<"openai-completions">,
"kwaipilot/kat-coder-pro-v2": {
id: "kwaipilot/kat-coder-pro-v2",
name: "Kwaipilot: KAT-Coder-Pro V2",

View file

@ -2,6 +2,17 @@
## [Unreleased]
### Fixed
- Fixed flaky `edit-tool-no-full-redraw` TUI tests by waiting for asynchronous preview and preflight error rendering instead of relying on fixed render ticks.
## [0.67.3] - 2026-04-15
### New Features
- `renderShell: "self"` for custom and built-in tool renderers so tools can own their outer shell instead of the default boxed shell. Useful for stable large previews such as edit diffs. See [docs/extensions.md#custom-rendering](docs/extensions.md#custom-rendering).
- Interactive auto-retry status now shows a live countdown during backoff instead of a static retry delay message.
### Added
- Added `renderShell: "self"` for custom and built-in tool renderers so tools can own their outer shell instead of using the default boxed shell. This is useful for stable large previews such as edit diffs ([#3134](https://github.com/badlogic/pi-mono/issues/3134))
@ -9,7 +20,9 @@
### Fixed
- Fixed edit diff previews to stay visible during edit permission dialogs and session replay without reintroducing large-result redraw flicker ([#3134](https://github.com/badlogic/pi-mono/issues/3134))
- Fixed the `plan-mode` example extension to allow `eza` in the read-only bash allowlist instead of the deprecated `exa` command ([#3160](https://github.com/badlogic/pi-mono/issues/3160))
- Fixed `/reload` to render a static reload status box instead of an animated spinner, avoiding redraw instability during interactive reloads.
- Fixed the `plan-mode` example extension to allow `eza` in the read-only bash allowlist instead of the deprecated `exa` command ([#3240](https://github.com/badlogic/pi-mono/pull/3240) by [@rwachtler](https://github.com/rwachtler))
- Fixed `google-vertex` API key resolution to treat `gcp-vertex-credentials` as an Application Default Credentials marker instead of a literal API key, so marker-based setups correctly fall back to ADC ([#3221](https://github.com/badlogic/pi-mono/pull/3221) by [@deepkilo](https://github.com/deepkilo))
- Fixed RPC `prompt` to wait for prompt preflight success before emitting its single authoritative response, while still treating handled and queued prompts as success ([#3049](https://github.com/badlogic/pi-mono/issues/3049))
- Fixed Alt keybindings inside Zellij by skipping the Kitty keyboard protocol query there and enabling xterm `modifyOtherKeys` mode 2 directly ([#3163](https://github.com/badlogic/pi-mono/issues/3163))
- Fixed `/scoped-models` reordering to propagate into the `/model` scoped tab, preserving the user-defined scoped model order instead of re-sorting it ([#3217](https://github.com/badlogic/pi-mono/issues/3217))

View file

@ -1,12 +1,12 @@
{
"name": "pi-extension-custom-provider",
"version": "1.18.2",
"version": "1.18.3",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "pi-extension-custom-provider",
"version": "1.18.2",
"version": "1.18.3",
"dependencies": {
"@anthropic-ai/sdk": "^0.52.0"
}

View file

@ -1,7 +1,7 @@
{
"name": "pi-extension-custom-provider-anthropic",
"private": true,
"version": "1.18.2",
"version": "1.18.3",
"type": "module",
"scripts": {
"clean": "echo 'nothing to clean'",

View file

@ -1,7 +1,7 @@
{
"name": "pi-extension-custom-provider-gitlab-duo",
"private": true,
"version": "1.18.2",
"version": "1.18.3",
"type": "module",
"scripts": {
"clean": "echo 'nothing to clean'",

View file

@ -1,7 +1,7 @@
{
"name": "pi-extension-custom-provider-qwen-cli",
"private": true,
"version": "1.17.2",
"version": "1.17.3",
"type": "module",
"scripts": {
"clean": "echo 'nothing to clean'",

View file

@ -1,12 +1,12 @@
{
"name": "pi-extension-with-deps",
"version": "1.31.2",
"version": "1.31.3",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "pi-extension-with-deps",
"version": "1.31.2",
"version": "1.31.3",
"dependencies": {
"ms": "^2.1.3"
},

View file

@ -1,7 +1,7 @@
{
"name": "pi-extension-with-deps",
"private": true,
"version": "1.31.2",
"version": "1.31.3",
"type": "module",
"scripts": {
"clean": "echo 'nothing to clean'",

View file

@ -1,6 +1,6 @@
{
"name": "@mariozechner/pi-coding-agent",
"version": "0.67.2",
"version": "0.67.3",
"description": "Coding agent CLI with read, bash, edit, write tools and session management",
"type": "module",
"piConfig": {
@ -40,9 +40,9 @@
},
"dependencies": {
"@mariozechner/jiti": "^2.6.2",
"@mariozechner/pi-agent-core": "^0.67.2",
"@mariozechner/pi-ai": "^0.67.2",
"@mariozechner/pi-tui": "^0.67.2",
"@mariozechner/pi-agent-core": "^0.67.3",
"@mariozechner/pi-ai": "^0.67.3",
"@mariozechner/pi-tui": "^0.67.3",
"@silvia-odwyer/photon-node": "^0.3.4",
"ajv": "^8.17.1",
"chalk": "^5.5.0",

View file

@ -10,7 +10,13 @@ import { keyHint } from "../../modes/interactive/components/keybinding-hints.js"
import { truncateToVisualLines } from "../../modes/interactive/components/visual-truncate.js";
import { theme } from "../../modes/interactive/theme/theme.js";
import { waitForChildProcess } from "../../utils/child-process.js";
import { getShellConfig, getShellEnv, killProcessTree } from "../../utils/shell.js";
import {
getShellConfig,
getShellEnv,
killProcessTree,
trackDetachedChildPid,
untrackDetachedChildPid,
} from "../../utils/shell.js";
import type { ToolDefinition, ToolRenderResultOptions } from "../extensions/types.js";
import { getTextOutput, invalidArgText, str } from "./render-utils.js";
import { wrapToolDefinition } from "./tool-definition-wrapper.js";
@ -81,6 +87,7 @@ export function createLocalBashOperations(): BashOperations {
env: env ?? getShellEnv(),
stdio: ["ignore", "pipe", "pipe"],
});
if (child.pid) trackDetachedChildPid(child.pid);
let timedOut = false;
let timeoutHandle: NodeJS.Timeout | undefined;
// Set timeout if provided.
@ -105,6 +112,7 @@ export function createLocalBashOperations(): BashOperations {
// on inherited stdio handles held by detached descendants.
waitForChildProcess(child)
.then((code) => {
if (child.pid) untrackDetachedChildPid(child.pid);
if (timeoutHandle) clearTimeout(timeoutHandle);
if (signal) signal.removeEventListener("abort", onAbort);
if (signal?.aborted) {
@ -118,6 +126,7 @@ export function createLocalBashOperations(): BashOperations {
resolve({ exitCode: code });
})
.catch((err) => {
if (child.pid) untrackDetachedChildPid(child.pid);
if (timeoutHandle) clearTimeout(timeoutHandle);
if (signal) signal.removeEventListener("abort", onAbort);
reject(err);

View file

@ -70,6 +70,7 @@ import { getChangelogPath, getNewEntries, parseChangelog } from "../../utils/cha
import { copyToClipboard } from "../../utils/clipboard.js";
import { extensionForImageMimeType, readClipboardImage } from "../../utils/clipboard-image.js";
import { parseGitUrl } from "../../utils/git.js";
import { killTrackedDetachedChildren } from "../../utils/shell.js";
import { ensureTool } from "../../utils/tools-manager.js";
import { ArminComponent } from "./components/armin.js";
import { AssistantMessageComponent } from "./components/assistant-message.js";
@ -2941,6 +2942,7 @@ export class InteractiveMode {
for (const signal of signals) {
const handler = () => {
killTrackedDetachedChildren();
void this.shutdown();
};
process.on(signal, handler);

View file

@ -9,6 +9,7 @@
import type { AssistantMessage, ImageContent } from "@mariozechner/pi-ai";
import type { AgentSessionRuntime } from "../core/agent-session-runtime.js";
import { flushRawStdout, writeRawStdout } from "../core/output-guard.js";
import { killTrackedDetachedChildren } from "../utils/shell.js";
/**
* Options for print mode.
@ -51,6 +52,7 @@ export async function runPrintMode(runtimeHost: AgentSessionRuntime, options: Pr
for (const signal of signals) {
const handler = () => {
killTrackedDetachedChildren();
void disposeRuntime().finally(() => {
process.exit(signal === "SIGHUP" ? 129 : 143);
});

View file

@ -19,6 +19,7 @@ import type {
ExtensionWidgetOptions,
} from "../../core/extensions/index.js";
import { takeOverStdout, writeRawStdout } from "../../core/output-guard.js";
import { killTrackedDetachedChildren } from "../../utils/shell.js";
import { type Theme, theme } from "../interactive/theme/theme.js";
import { attachJsonlLineReader, serializeJsonLine } from "./jsonl.js";
import type {
@ -346,6 +347,7 @@ export async function runRpcMode(runtimeHost: AgentSessionRuntime): Promise<neve
for (const signal of signals) {
const handler = () => {
killTrackedDetachedChildren();
void shutdown(signal === "SIGHUP" ? 129 : 143);
};
process.on(signal, handler);

View file

@ -172,6 +172,27 @@ export function sanitizeBinaryOutput(str: string): string {
.join("");
}
/**
* Detached child processes must be tracked so they can be killed on parent
* shutdown signals (SIGHUP/SIGTERM).
*/
const trackedDetachedChildPids = new Set<number>();
export function trackDetachedChildPid(pid: number): void {
trackedDetachedChildPids.add(pid);
}
export function untrackDetachedChildPid(pid: number): void {
trackedDetachedChildPids.delete(pid);
}
export function killTrackedDetachedChildren(): void {
for (const pid of trackedDetachedChildPids) {
killProcessTree(pid);
}
trackedDetachedChildPids.clear();
}
/**
* Kill a process and all its children (cross-platform)
*/

View file

@ -37,6 +37,25 @@ async function waitForRender(): Promise<void> {
await new Promise((resolve) => setTimeout(resolve, 0));
}
async function waitForRenderedText(
getRender: () => string,
expectedText: string,
onRetry?: () => void,
timeoutMs = 2000,
): Promise<string> {
const deadline = Date.now() + timeoutMs;
let lastRender = "";
while (Date.now() < deadline) {
onRetry?.();
await waitForRender();
lastRender = getRender();
if (lastRender.includes(expectedText)) {
return lastRender;
}
}
throw new Error(`Timed out waiting for render to include "${expectedText}". Last render:\n${lastRender}`);
}
function createLargeEdits(lines: string[]): Edit[] {
const targets = [50, 150, 250, 350, 450, 550, 650, 750, 850, 950];
return targets.map((lineNumber) => ({
@ -99,9 +118,12 @@ describe("edit tool TUI rendering", () => {
await waitForRender();
await waitForRender();
const callOnlyRender = component.render(80).join("\n");
const callOnlyRender = await waitForRenderedText(
() => component.render(80).join("\n"),
"line 50 changed",
() => tui.requestRender(true),
);
expect(callOnlyRender).toContain("edit");
expect(callOnlyRender).toContain("line 50 changed");
expect(callOnlyRender).toContain("line 950 changed");
const redrawsBeforeResult = tui.fullRedraws;
@ -201,8 +223,11 @@ describe("edit tool TUI rendering", () => {
await waitForRender();
await waitForRender();
const rendered = component.render(80).join("\n");
expect(rendered).toContain("Could not find");
const rendered = await waitForRenderedText(
() => component.render(80).join("\n"),
"Could not find",
() => tui.requestRender(true),
);
expect(rendered).not.toContain("+1 ");
expect(rendered).not.toContain("-1 ");
});

View file

@ -216,7 +216,9 @@ describe("RPC prompt response semantics", () => {
type: "response",
command: "prompt",
success: false,
error: "No API key found for fake-provider.\n\nUse /login or set an API key environment variable. See /Users/badlogic/workspaces/pi-mono-2/packages/coding-agent/docs/providers.md",
error: expect.stringContaining(
"No API key found for fake-provider.\n\nUse /login or set an API key environment variable. See ",
),
});
});
} finally {

View file

@ -2,6 +2,8 @@
## [Unreleased]
## [0.67.3] - 2026-04-15
## [0.67.2] - 2026-04-14
## [0.67.1] - 2026-04-13

View file

@ -1,6 +1,6 @@
{
"name": "@mariozechner/pi-mom",
"version": "0.67.2",
"version": "0.67.3",
"description": "Slack bot that delegates messages to the pi coding agent",
"type": "module",
"bin": {
@ -20,9 +20,9 @@
},
"dependencies": {
"@anthropic-ai/sandbox-runtime": "^0.0.16",
"@mariozechner/pi-agent-core": "^0.67.2",
"@mariozechner/pi-ai": "^0.67.2",
"@mariozechner/pi-coding-agent": "^0.67.2",
"@mariozechner/pi-agent-core": "^0.67.3",
"@mariozechner/pi-ai": "^0.67.3",
"@mariozechner/pi-coding-agent": "^0.67.3",
"@sinclair/typebox": "^0.34.0",
"@slack/socket-mode": "^2.0.0",
"@slack/web-api": "^7.0.0",

View file

@ -1,6 +1,6 @@
{
"name": "@mariozechner/pi",
"version": "0.67.2",
"version": "0.67.3",
"description": "CLI tool for managing vLLM deployments on GPU pods",
"type": "module",
"bin": {
@ -33,7 +33,7 @@
"node": ">=20.0.0"
},
"dependencies": {
"@mariozechner/pi-agent-core": "^0.67.2",
"@mariozechner/pi-agent-core": "^0.67.3",
"chalk": "^5.5.0"
},
"devDependencies": {}

View file

@ -2,6 +2,8 @@
## [Unreleased]
## [0.67.3] - 2026-04-15
### Fixed
- Fixed Alt keybindings inside Zellij by skipping the Kitty keyboard protocol query there and enabling xterm `modifyOtherKeys` mode 2 directly ([#3163](https://github.com/badlogic/pi-mono/issues/3163))

View file

@ -1,6 +1,6 @@
{
"name": "@mariozechner/pi-tui",
"version": "0.67.2",
"version": "0.67.3",
"description": "Terminal User Interface library with differential rendering for efficient text-based applications",
"type": "module",
"main": "dist/index.js",

View file

@ -2,6 +2,8 @@
## [Unreleased]
## [0.67.3] - 2026-04-15
## [0.67.2] - 2026-04-14
## [0.67.1] - 2026-04-13

View file

@ -1,6 +1,6 @@
{
"name": "pi-web-ui-example",
"version": "1.55.2",
"version": "1.55.3",
"private": true,
"type": "module",
"scripts": {

View file

@ -1,6 +1,6 @@
{
"name": "@mariozechner/pi-web-ui",
"version": "0.67.2",
"version": "0.67.3",
"description": "Reusable web UI components for AI chat interfaces powered by @mariozechner/pi-ai",
"type": "module",
"main": "dist/index.js",
@ -18,8 +18,8 @@
},
"dependencies": {
"@lmstudio/sdk": "^1.5.0",
"@mariozechner/pi-ai": "^0.67.2",
"@mariozechner/pi-tui": "^0.67.2",
"@mariozechner/pi-ai": "^0.67.3",
"@mariozechner/pi-tui": "^0.67.3",
"docx-preview": "^0.3.7",
"jszip": "^3.10.1",
"lucide": "^0.544.0",