{"_id":"@earendil-works/pi-ai","_rev":"30-f8691e247afa3908c2068f5b2f42dab3","name":"@earendil-works/pi-ai","dist-tags":{"legacy-node20":"0.74.2","latest":"0.80.7"},"versions":{"0.74.0":{"name":"@earendil-works/pi-ai","version":"0.74.0","keywords":["ai","llm","openai","anthropic","gemini","bedrock","unified","api"],"author":{"name":"Mario Zechner"},"license":"MIT","_id":"@earendil-works/pi-ai@0.74.0","maintainers":[{"name":"mitsuhiko","email":"armin.ronacher@active-4.com"},{"name":"badlogic","email":"mario@badlogicgames.com"}],"homepage":"https://github.com/earendil-works/pi-mono#readme","bugs":{"url":"https://github.com/earendil-works/pi-mono/issues"},"bin":{"pi-ai":"dist/cli.js"},"dist":{"shasum":"68ab0e83c42215c6764bdf6cd5e4316915bb0ea9","tarball":"https://registry.npmjs.org/@earendil-works/pi-ai/-/pi-ai-0.74.0.tgz","fileCount":178,"integrity":"sha512-7M7qcrZY/KEkH4wFkX3eqzvmKru4O88wezNKoN0KD2m4aAOmp9tdW2xCmUgSTSWlKB7b2Xw9QtAgrzHtg6t6iw==","signatures":[{"sig":"MEUCIQCfM4RtwsSYYV5nTEJOlwZrfdj8Sm3GUUz2jDB6neNJdgIgJbznaqvUJa8xdh//4Z1GOs3lLKwShxeIT3Oi8WA/Vlg=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":4256458},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=20.0.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./oauth":{"types":"./dist/oauth.d.ts","import":"./dist/oauth.js"},"./google":{"types":"./dist/providers/google.d.ts","import":"./dist/providers/google.js"},"./mistral":{"types":"./dist/providers/mistral.d.ts","import":"./dist/providers/mistral.js"},"./anthropic":{"types":"./dist/providers/anthropic.d.ts","import":"./dist/providers/anthropic.js"},"./google-vertex":{"types":"./dist/providers/google-vertex.d.ts","import":"./dist/providers/google-vertex.js"},"./bedrock-provider":{"types":"./dist/bedrock-provider.d.ts","import":"./dist/bedrock-provider.js"},"./openai-responses":{"types":"./dist/providers/openai-responses.d.ts","import":"./dist/providers/openai-responses.js"},"./openai-completions":{"types":"./dist/providers/openai-completions.d.ts","import":"./dist/providers/openai-completions.js"},"./azure-openai-responses":{"types":"./dist/providers/azure-openai-responses.d.ts","import":"./dist/providers/azure-openai-responses.js"},"./openai-codex-responses":{"types":"./dist/providers/openai-codex-responses.d.ts","import":"./dist/providers/openai-codex-responses.js"}},"gitHead":"1eee081e29c1323c40b98db11d0a62b919831881","scripts":{"dev":"tsgo -p tsconfig.build.json --watch --preserveWatchOutput","test":"vitest --run","build":"npm run generate-models && tsgo -p tsconfig.build.json","clean":"shx rm -rf dist","dev:tsc":"tsgo -p tsconfig.build.json --watch --preserveWatchOutput","prepublishOnly":"npm run clean && npm run build","generate-models":"npx tsx scripts/generate-models.ts"},"_npmUser":{"name":"badlogic","email":"mario@badlogicgames.com"},"repository":{"url":"git+https://github.com/earendil-works/pi-mono.git","type":"git","directory":"packages/ai"},"_npmVersion":"11.10.0","description":"Unified LLM API with automatic model discovery and provider configuration","directories":{},"_nodeVersion":"25.2.1","dependencies":{"chalk":"^5.6.2","openai":"6.26.0","undici":"^7.19.1","typebox":"^1.1.24","proxy-agent":"^6.5.0","partial-json":"^0.1.7","@google/genai":"^1.40.0","@anthropic-ai/sdk":"^0.91.1","zod-to-json-schema":"^3.24.6","@mistralai/mistralai":"^2.2.0","@aws-sdk/client-bedrock-runtime":"^3.1030.0"},"_hasShrinkwrap":false,"devDependencies":{"canvas":"^3.2.0","vitest":"^3.2.4","@types/node":"^24.3.0"},"_npmOperationalInternal":{"tmp":"tmp/pi-ai_0.74.0_1778166937280_0.8820072883594583","host":"s3://npm-registry-packages-npm-production"}},"0.74.1":{"name":"@earendil-works/pi-ai","version":"0.74.1","keywords":["ai","llm","openai","anthropic","gemini","bedrock","unified","api"],"author":{"name":"Mario Zechner"},"license":"MIT","_id":"@earendil-works/pi-ai@0.74.1","maintainers":[{"name":"mitsuhiko","email":"armin.ronacher@active-4.com"},{"name":"badlogic","email":"mario@badlogicgames.com"}],"homepage":"https://github.com/earendil-works/pi-mono#readme","bugs":{"url":"https://github.com/earendil-works/pi-mono/issues"},"bin":{"pi-ai":"dist/cli.js"},"dist":{"shasum":"0cbb2a800e8ee5dccead07decde4595cfcc17ba1","tarball":"https://registry.npmjs.org/@earendil-works/pi-ai/-/pi-ai-0.74.1.tgz","fileCount":206,"integrity":"sha512-xBgJnsrB+eCIsEB2rQ+aD/goGDo/YJMzQoICyL+ltHSB0SVQDgawjCzNF1IuRCzvUFceqZGJETUiejfWRDUe0Q==","signatures":[{"sig":"MEQCIFK+PGp57uinOMYCI0A9og1CieE6oihAxo2KNJ8U8ncIAiBU3gBIGVSzYeVZ3wzStLn1tfJoD/JMCYiKS4Tzrm9XzA==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":4390102},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=20.0.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./oauth":{"types":"./dist/oauth.d.ts","import":"./dist/oauth.js"},"./google":{"types":"./dist/providers/google.d.ts","import":"./dist/providers/google.js"},"./mistral":{"types":"./dist/providers/mistral.d.ts","import":"./dist/providers/mistral.js"},"./anthropic":{"types":"./dist/providers/anthropic.d.ts","import":"./dist/providers/anthropic.js"},"./google-vertex":{"types":"./dist/providers/google-vertex.d.ts","import":"./dist/providers/google-vertex.js"},"./bedrock-provider":{"types":"./dist/bedrock-provider.d.ts","import":"./dist/bedrock-provider.js"},"./openai-responses":{"types":"./dist/providers/openai-responses.d.ts","import":"./dist/providers/openai-responses.js"},"./openai-completions":{"types":"./dist/providers/openai-completions.d.ts","import":"./dist/providers/openai-completions.js"},"./azure-openai-responses":{"types":"./dist/providers/azure-openai-responses.d.ts","import":"./dist/providers/azure-openai-responses.js"},"./openai-codex-responses":{"types":"./dist/providers/openai-codex-responses.d.ts","import":"./dist/providers/openai-codex-responses.js"}},"gitHead":"a015c15f5f1b572bbe8cdc00eda907193f986b53","scripts":{"dev":"tsgo -p tsconfig.build.json --watch --preserveWatchOutput","test":"vitest --run","build":"npm run generate-models && npm run generate-image-models && tsgo -p tsconfig.build.json","clean":"shx rm -rf dist","dev:tsc":"tsgo -p tsconfig.build.json --watch --preserveWatchOutput","prepublishOnly":"npm run clean && npm run build","generate-models":"npx tsx scripts/generate-models.ts","generate-image-models":"npx tsx scripts/generate-image-models.ts"},"_npmUser":{"name":"badlogic","email":"mario@badlogicgames.com"},"repository":{"url":"git+https://github.com/earendil-works/pi-mono.git","type":"git","directory":"packages/ai"},"_npmVersion":"11.10.0","description":"Unified LLM API with automatic model discovery and provider configuration","directories":{},"_nodeVersion":"25.2.1","dependencies":{"openai":"6.26.0","typebox":"^1.1.24","partial-json":"^0.1.7","@google/genai":"^1.40.0","http-proxy-agent":"^7.0.2","@anthropic-ai/sdk":"^0.91.1","https-proxy-agent":"^7.0.6","@mistralai/mistralai":"^2.2.0","@aws-sdk/client-bedrock-runtime":"^3.1030.0"},"_hasShrinkwrap":false,"devDependencies":{"canvas":"^3.2.0","vitest":"^3.2.4","@types/node":"^24.3.0"},"_npmOperationalInternal":{"tmp":"tmp/pi-ai_0.74.1_1778974490586_0.5821870326825604","host":"s3://npm-registry-packages-npm-production"}},"0.75.0":{"name":"@earendil-works/pi-ai","version":"0.75.0","keywords":["ai","llm","openai","anthropic","gemini","bedrock","unified","api"],"author":{"name":"Mario Zechner"},"license":"MIT","_id":"@earendil-works/pi-ai@0.75.0","maintainers":[{"name":"mitsuhiko","email":"armin.ronacher@active-4.com"},{"name":"badlogic","email":"mario@badlogicgames.com"}],"homepage":"https://github.com/earendil-works/pi-mono#readme","bugs":{"url":"https://github.com/earendil-works/pi-mono/issues"},"bin":{"pi-ai":"dist/cli.js"},"dist":{"shasum":"61764ce26a3860636fd06f2c719c587a77967e19","tarball":"https://registry.npmjs.org/@earendil-works/pi-ai/-/pi-ai-0.75.0.tgz","fileCount":206,"integrity":"sha512-mWSYHAjGQPs8fr+OjWXC/HvPAgybzuwqe4aFy69DZpc6a19NlaNvHLEUjqzMqQwS1vaQE36kPn0yk7CZE2aznw==","signatures":[{"sig":"MEYCIQCSHRqTdWL//LJitjNbeRIXYfLhzkOgbM8pltoEenIDKgIhAOx04ZcoX38lpiCxz0jWTyIL+SpdjVrhglAvaJ10ey29","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":4389703},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=22.19.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./oauth":{"types":"./dist/oauth.d.ts","import":"./dist/oauth.js"},"./google":{"types":"./dist/providers/google.d.ts","import":"./dist/providers/google.js"},"./mistral":{"types":"./dist/providers/mistral.d.ts","import":"./dist/providers/mistral.js"},"./anthropic":{"types":"./dist/providers/anthropic.d.ts","import":"./dist/providers/anthropic.js"},"./google-vertex":{"types":"./dist/providers/google-vertex.d.ts","import":"./dist/providers/google-vertex.js"},"./bedrock-provider":{"types":"./dist/bedrock-provider.d.ts","import":"./dist/bedrock-provider.js"},"./openai-responses":{"types":"./dist/providers/openai-responses.d.ts","import":"./dist/providers/openai-responses.js"},"./openai-completions":{"types":"./dist/providers/openai-completions.d.ts","import":"./dist/providers/openai-completions.js"},"./azure-openai-responses":{"types":"./dist/providers/azure-openai-responses.d.ts","import":"./dist/providers/azure-openai-responses.js"},"./openai-codex-responses":{"types":"./dist/providers/openai-codex-responses.d.ts","import":"./dist/providers/openai-codex-responses.js"}},"gitHead":"12f5c00cc1332e04d18e2120b71731627174bcc7","scripts":{"dev":"tsgo -p tsconfig.build.json --watch --preserveWatchOutput","test":"vitest --run","build":"npm run generate-models && npm run generate-image-models && tsgo -p tsconfig.build.json","clean":"shx rm -rf dist","dev:tsc":"tsgo -p tsconfig.build.json --watch --preserveWatchOutput","prepublishOnly":"npm run clean && npm run build","generate-models":"npx tsx scripts/generate-models.ts","generate-image-models":"npx tsx scripts/generate-image-models.ts"},"_npmUser":{"name":"badlogic","email":"mario@badlogicgames.com"},"repository":{"url":"git+https://github.com/earendil-works/pi-mono.git","type":"git","directory":"packages/ai"},"_npmVersion":"11.10.0","description":"Unified LLM API with automatic model discovery and provider configuration","directories":{},"_nodeVersion":"25.2.1","dependencies":{"openai":"6.26.0","typebox":"^1.1.24","partial-json":"^0.1.7","@google/genai":"^1.40.0","http-proxy-agent":"^7.0.2","@anthropic-ai/sdk":"^0.91.1","https-proxy-agent":"^7.0.6","@mistralai/mistralai":"^2.2.0","@aws-sdk/client-bedrock-runtime":"^3.1030.0"},"_hasShrinkwrap":false,"devDependencies":{"canvas":"^3.2.0","vitest":"^3.2.4","@types/node":"^24.3.0"},"_npmOperationalInternal":{"tmp":"tmp/pi-ai_0.75.0_1779044607294_0.2932761040987837","host":"s3://npm-registry-packages-npm-production"}},"0.75.1":{"name":"@earendil-works/pi-ai","version":"0.75.1","keywords":["ai","llm","openai","anthropic","gemini","bedrock","unified","api"],"author":{"name":"Mario Zechner"},"license":"MIT","_id":"@earendil-works/pi-ai@0.75.1","maintainers":[{"name":"mitsuhiko","email":"armin.ronacher@active-4.com"},{"name":"badlogic","email":"mario@badlogicgames.com"}],"homepage":"https://github.com/earendil-works/pi-mono#readme","bugs":{"url":"https://github.com/earendil-works/pi-mono/issues"},"bin":{"pi-ai":"dist/cli.js"},"dist":{"shasum":"49ab8bdb6e937921d59ccf014268781693efd81b","tarball":"https://registry.npmjs.org/@earendil-works/pi-ai/-/pi-ai-0.75.1.tgz","fileCount":206,"integrity":"sha512-/bhCWS2R+qHLBDnN+d1t1QRUxtZk7sZpMcrlexPq3W++3bJ0Df0GjhM2FToTubhoCsjOBdBOuRYcV8FNPfRUVQ==","signatures":[{"sig":"MEUCICDDCyNjPtj20SSHSU1jklFPSQ1ri1FWI4cQsfDvh7m4AiEA0EoTS1Q86bFhLTTQ5y6MOLHBGstA3xp6R/4slJh0Hn8=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":4386155},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=22.19.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./oauth":{"types":"./dist/oauth.d.ts","import":"./dist/oauth.js"},"./google":{"types":"./dist/providers/google.d.ts","import":"./dist/providers/google.js"},"./mistral":{"types":"./dist/providers/mistral.d.ts","import":"./dist/providers/mistral.js"},"./anthropic":{"types":"./dist/providers/anthropic.d.ts","import":"./dist/providers/anthropic.js"},"./google-vertex":{"types":"./dist/providers/google-vertex.d.ts","import":"./dist/providers/google-vertex.js"},"./bedrock-provider":{"types":"./dist/bedrock-provider.d.ts","import":"./dist/bedrock-provider.js"},"./openai-responses":{"types":"./dist/providers/openai-responses.d.ts","import":"./dist/providers/openai-responses.js"},"./openai-completions":{"types":"./dist/providers/openai-completions.d.ts","import":"./dist/providers/openai-completions.js"},"./azure-openai-responses":{"types":"./dist/providers/azure-openai-responses.d.ts","import":"./dist/providers/azure-openai-responses.js"},"./openai-codex-responses":{"types":"./dist/providers/openai-codex-responses.d.ts","import":"./dist/providers/openai-codex-responses.js"}},"gitHead":"73a61654af52f8b02439d697a3b74126fa6b6782","scripts":{"dev":"tsgo -p tsconfig.build.json --watch --preserveWatchOutput","test":"vitest --run","build":"npm run generate-models && npm run generate-image-models && tsgo -p tsconfig.build.json","clean":"shx rm -rf dist","dev:tsc":"tsgo -p tsconfig.build.json --watch --preserveWatchOutput","prepublishOnly":"npm run clean && npm run build","generate-models":"npx tsx scripts/generate-models.ts","generate-image-models":"npx tsx scripts/generate-image-models.ts"},"_npmUser":{"name":"badlogic","email":"mario@badlogicgames.com"},"repository":{"url":"git+https://github.com/earendil-works/pi-mono.git","type":"git","directory":"packages/ai"},"_npmVersion":"11.10.0","description":"Unified LLM API with automatic model discovery and provider configuration","directories":{},"_nodeVersion":"25.2.1","dependencies":{"openai":"6.26.0","typebox":"^1.1.24","partial-json":"^0.1.7","@google/genai":"^1.40.0","http-proxy-agent":"^7.0.2","@anthropic-ai/sdk":"^0.91.1","https-proxy-agent":"^7.0.6","@mistralai/mistralai":"^2.2.0","@aws-sdk/client-bedrock-runtime":"^3.1030.0"},"_hasShrinkwrap":false,"devDependencies":{"canvas":"^3.2.0","vitest":"^3.2.4","@types/node":"^24.3.0"},"_npmOperationalInternal":{"tmp":"tmp/pi-ai_0.75.1_1779062502284_0.40741117596490617","host":"s3://npm-registry-packages-npm-production"}},"0.75.2":{"name":"@earendil-works/pi-ai","version":"0.75.2","keywords":["ai","llm","openai","anthropic","gemini","bedrock","unified","api"],"author":{"name":"Mario Zechner"},"license":"MIT","_id":"@earendil-works/pi-ai@0.75.2","maintainers":[{"name":"mitsuhiko","email":"armin.ronacher@active-4.com"},{"name":"badlogic","email":"mario@badlogicgames.com"}],"homepage":"https://github.com/earendil-works/pi-mono#readme","bugs":{"url":"https://github.com/earendil-works/pi-mono/issues"},"bin":{"pi-ai":"dist/cli.js"},"dist":{"shasum":"1756df00c136a606175fb8d8274cdf3705ebd98f","tarball":"https://registry.npmjs.org/@earendil-works/pi-ai/-/pi-ai-0.75.2.tgz","fileCount":206,"integrity":"sha512-OjMXTrNDMwIDJ6GN3u5AtJ/ML0gsc9BrlyIpcWrYy22ebamLJC+SXi1xESvLsoFFRcLXSN7tULOZ1ZGIPJklew==","signatures":[{"sig":"MEUCIQDSstogyoHjFpGsQ5Ilha2uB6fCbJbVX+kfai2ZvmTavgIgM9qV052pYfnMJq39170IEFG4ln4YSz6zPD358uj3LzE=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":4396755},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=22.19.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./oauth":{"types":"./dist/oauth.d.ts","import":"./dist/oauth.js"},"./google":{"types":"./dist/providers/google.d.ts","import":"./dist/providers/google.js"},"./mistral":{"types":"./dist/providers/mistral.d.ts","import":"./dist/providers/mistral.js"},"./anthropic":{"types":"./dist/providers/anthropic.d.ts","import":"./dist/providers/anthropic.js"},"./google-vertex":{"types":"./dist/providers/google-vertex.d.ts","import":"./dist/providers/google-vertex.js"},"./bedrock-provider":{"types":"./dist/bedrock-provider.d.ts","import":"./dist/bedrock-provider.js"},"./openai-responses":{"types":"./dist/providers/openai-responses.d.ts","import":"./dist/providers/openai-responses.js"},"./openai-completions":{"types":"./dist/providers/openai-completions.d.ts","import":"./dist/providers/openai-completions.js"},"./azure-openai-responses":{"types":"./dist/providers/azure-openai-responses.d.ts","import":"./dist/providers/azure-openai-responses.js"},"./openai-codex-responses":{"types":"./dist/providers/openai-codex-responses.d.ts","import":"./dist/providers/openai-codex-responses.js"}},"gitHead":"ea713ba1744e5cf1c5a1914a8d7e7328583042e1","scripts":{"dev":"tsgo -p tsconfig.build.json --watch --preserveWatchOutput","test":"vitest --run","build":"npm run generate-models && npm run generate-image-models && tsgo -p tsconfig.build.json","clean":"shx rm -rf dist","dev:tsc":"tsgo -p tsconfig.build.json --watch --preserveWatchOutput","prepublishOnly":"npm run clean && npm run build","generate-models":"npx tsx scripts/generate-models.ts","generate-image-models":"npx tsx scripts/generate-image-models.ts"},"_npmUser":{"name":"badlogic","email":"mario@badlogicgames.com"},"repository":{"url":"git+https://github.com/earendil-works/pi-mono.git","type":"git","directory":"packages/ai"},"_npmVersion":"11.10.0","description":"Unified LLM API with automatic model discovery and provider configuration","directories":{},"_nodeVersion":"25.2.1","dependencies":{"openai":"6.26.0","typebox":"^1.1.24","partial-json":"^0.1.7","@google/genai":"^1.40.0","http-proxy-agent":"^7.0.2","@anthropic-ai/sdk":"^0.91.1","https-proxy-agent":"^7.0.6","@mistralai/mistralai":"^2.2.0","@aws-sdk/client-bedrock-runtime":"^3.1030.0"},"_hasShrinkwrap":false,"devDependencies":{"canvas":"^3.2.0","vitest":"^3.2.4","@types/node":"^24.3.0"},"_npmOperationalInternal":{"tmp":"tmp/pi-ai_0.75.2_1779097622356_0.9642443351287178","host":"s3://npm-registry-packages-npm-production"}},"0.75.3":{"name":"@earendil-works/pi-ai","version":"0.75.3","keywords":["ai","llm","openai","anthropic","gemini","bedrock","unified","api"],"author":{"name":"Mario Zechner"},"license":"MIT","_id":"@earendil-works/pi-ai@0.75.3","maintainers":[{"name":"mitsuhiko","email":"armin.ronacher@active-4.com"},{"name":"badlogic","email":"mario@badlogicgames.com"}],"homepage":"https://github.com/earendil-works/pi-mono#readme","bugs":{"url":"https://github.com/earendil-works/pi-mono/issues"},"bin":{"pi-ai":"dist/cli.js"},"dist":{"shasum":"a82793dd4ee601d3ff0a09156154a8b934792cfd","tarball":"https://registry.npmjs.org/@earendil-works/pi-ai/-/pi-ai-0.75.3.tgz","fileCount":206,"integrity":"sha512-UKccS+ADlkSVJ49a00346jUfXmUi6zzzB+pPWotsyA6SxhKr2ejjkGQksGyR1DyNVrsEP/WWlsOSTUUwVlzNaA==","signatures":[{"sig":"MEYCIQCDbDxb9/Bxg/xNT4sm+3a9qVO58fw0kFtlvpc23JZ4IQIhAOozk/qIfG+C14+pG1OU2b9I7jRm5F9dx5MvkemcYM2W","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":4396755},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=22.19.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./oauth":{"types":"./dist/oauth.d.ts","import":"./dist/oauth.js"},"./google":{"types":"./dist/providers/google.d.ts","import":"./dist/providers/google.js"},"./mistral":{"types":"./dist/providers/mistral.d.ts","import":"./dist/providers/mistral.js"},"./anthropic":{"types":"./dist/providers/anthropic.d.ts","import":"./dist/providers/anthropic.js"},"./google-vertex":{"types":"./dist/providers/google-vertex.d.ts","import":"./dist/providers/google-vertex.js"},"./bedrock-provider":{"types":"./dist/bedrock-provider.d.ts","import":"./dist/bedrock-provider.js"},"./openai-responses":{"types":"./dist/providers/openai-responses.d.ts","import":"./dist/providers/openai-responses.js"},"./openai-completions":{"types":"./dist/providers/openai-completions.d.ts","import":"./dist/providers/openai-completions.js"},"./azure-openai-responses":{"types":"./dist/providers/azure-openai-responses.d.ts","import":"./dist/providers/azure-openai-responses.js"},"./openai-codex-responses":{"types":"./dist/providers/openai-codex-responses.d.ts","import":"./dist/providers/openai-codex-responses.js"}},"gitHead":"a7d8dd3d5db7d66aa5cc6886e32768b1196ce91f","scripts":{"dev":"tsgo -p tsconfig.build.json --watch --preserveWatchOutput","test":"vitest --run","build":"npm run generate-models && npm run generate-image-models && tsgo -p tsconfig.build.json","clean":"shx rm -rf dist","dev:tsc":"tsgo -p tsconfig.build.json --watch --preserveWatchOutput","prepublishOnly":"npm run clean && npm run build","generate-models":"npx tsx scripts/generate-models.ts","generate-image-models":"npx tsx scripts/generate-image-models.ts"},"_npmUser":{"name":"badlogic","email":"mario@badlogicgames.com"},"repository":{"url":"git+https://github.com/earendil-works/pi-mono.git","type":"git","directory":"packages/ai"},"_npmVersion":"11.10.0","description":"Unified LLM API with automatic model discovery and provider configuration","directories":{},"_nodeVersion":"25.2.1","dependencies":{"openai":"6.26.0","typebox":"^1.1.24","partial-json":"^0.1.7","@google/genai":"^1.40.0","http-proxy-agent":"^7.0.2","@anthropic-ai/sdk":"^0.91.1","https-proxy-agent":"^7.0.6","@mistralai/mistralai":"^2.2.0","@aws-sdk/client-bedrock-runtime":"^3.1030.0"},"_hasShrinkwrap":false,"devDependencies":{"canvas":"^3.2.0","vitest":"^3.2.4","@types/node":"^24.3.0"},"_npmOperationalInternal":{"tmp":"tmp/pi-ai_0.75.3_1779098350970_0.059442559183249255","host":"s3://npm-registry-packages-npm-production"}},"0.75.4":{"name":"@earendil-works/pi-ai","version":"0.75.4","keywords":["ai","llm","openai","anthropic","gemini","bedrock","unified","api"],"author":{"name":"Mario Zechner"},"license":"MIT","_id":"@earendil-works/pi-ai@0.75.4","maintainers":[{"name":"mitsuhiko","email":"armin.ronacher@active-4.com"},{"name":"badlogic","email":"mario@badlogicgames.com"}],"homepage":"https://github.com/earendil-works/pi-mono#readme","bugs":{"url":"https://github.com/earendil-works/pi-mono/issues"},"bin":{"pi-ai":"dist/cli.js"},"dist":{"shasum":"4e5d67b40192d78b800787e95524bdfb1dd6305e","tarball":"https://registry.npmjs.org/@earendil-works/pi-ai/-/pi-ai-0.75.4.tgz","fileCount":210,"integrity":"sha512-m/w8Hh3vQ0rAycwJiJWdzkypkn4295f4eq/966lDRy8aX5sk6bgYXH8TQmL16TO7Uwc7MbJG0QoyFHgX8RqXUQ==","signatures":[{"sig":"MEYCIQCUEVdTn2Ka2JutX2/Cq0dgJdMznErun5Licjmj/Ca+wAIhAISdigLltke8fTkENNGS6d4F6S8pvSUBkskNW6et4wX4","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":4421046},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=22.19.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./oauth":{"types":"./dist/oauth.d.ts","import":"./dist/oauth.js"},"./google":{"types":"./dist/providers/google.d.ts","import":"./dist/providers/google.js"},"./mistral":{"types":"./dist/providers/mistral.d.ts","import":"./dist/providers/mistral.js"},"./anthropic":{"types":"./dist/providers/anthropic.d.ts","import":"./dist/providers/anthropic.js"},"./google-vertex":{"types":"./dist/providers/google-vertex.d.ts","import":"./dist/providers/google-vertex.js"},"./bedrock-provider":{"types":"./dist/bedrock-provider.d.ts","import":"./dist/bedrock-provider.js"},"./openai-responses":{"types":"./dist/providers/openai-responses.d.ts","import":"./dist/providers/openai-responses.js"},"./openai-completions":{"types":"./dist/providers/openai-completions.d.ts","import":"./dist/providers/openai-completions.js"},"./azure-openai-responses":{"types":"./dist/providers/azure-openai-responses.d.ts","import":"./dist/providers/azure-openai-responses.js"},"./openai-codex-responses":{"types":"./dist/providers/openai-codex-responses.d.ts","import":"./dist/providers/openai-codex-responses.js"}},"gitHead":"3533843dd781dcd233f51854fc883ec246a6a919","scripts":{"test":"vitest --run","build":"npm run generate-models && npm run generate-image-models && tsgo -p tsconfig.build.json","clean":"shx rm -rf dist","prepublishOnly":"npm run clean && npm run build","generate-models":"node scripts/generate-models.ts","generate-image-models":"node scripts/generate-image-models.ts"},"_npmUser":{"name":"badlogic","email":"mario@badlogicgames.com"},"repository":{"url":"git+https://github.com/earendil-works/pi-mono.git","type":"git","directory":"packages/ai"},"_npmVersion":"11.10.0","description":"Unified LLM API with automatic model discovery and provider configuration","directories":{},"_nodeVersion":"25.2.1","dependencies":{"openai":"6.26.0","typebox":"1.1.38","partial-json":"0.1.7","@google/genai":"1.52.0","http-proxy-agent":"7.0.2","@anthropic-ai/sdk":"0.91.1","https-proxy-agent":"7.0.6","@mistralai/mistralai":"2.2.1","@aws-sdk/client-bedrock-runtime":"3.1048.0"},"_hasShrinkwrap":false,"devDependencies":{"canvas":"3.2.3","vitest":"3.2.4","@types/node":"24.12.4"},"_npmOperationalInternal":{"tmp":"tmp/pi-ai_0.75.4_1779287049830_0.6895584685848424","host":"s3://npm-registry-packages-npm-production"}},"0.74.2":{"name":"@earendil-works/pi-ai","version":"0.74.2","keywords":["ai","llm","openai","anthropic","gemini","bedrock","unified","api"],"author":{"name":"Mario Zechner"},"license":"MIT","_id":"@earendil-works/pi-ai@0.74.2","maintainers":[{"name":"mitsuhiko","email":"armin.ronacher@active-4.com"},{"name":"badlogic","email":"mario@badlogicgames.com"}],"homepage":"https://github.com/earendil-works/pi-mono#readme","bugs":{"url":"https://github.com/earendil-works/pi-mono/issues"},"bin":{"pi-ai":"dist/cli.js"},"dist":{"shasum":"fa8680d5b452a593b717aa6f08a0d6e1838ae092","tarball":"https://registry.npmjs.org/@earendil-works/pi-ai/-/pi-ai-0.74.2.tgz","fileCount":206,"integrity":"sha512-ukQBHGDm20k9ZUS2cGjNN9vDJp/48r35xmvgSx3paCaC06r2N/PLuRZoJmwQ1ZM7f8T3072odv9YPWn+77w0LA==","signatures":[{"sig":"MEUCIQDdhlMlbDFBiiJ9cYhm87y5aZtUtYSSAo/UCnqBZVDOiAIgSh7Y6bluIJ+x5aSodLffcEzdb3PpK62TxKnkk5zYMgk=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":4378594},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=20.0.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./oauth":{"types":"./dist/oauth.d.ts","import":"./dist/oauth.js"},"./google":{"types":"./dist/providers/google.d.ts","import":"./dist/providers/google.js"},"./mistral":{"types":"./dist/providers/mistral.d.ts","import":"./dist/providers/mistral.js"},"./anthropic":{"types":"./dist/providers/anthropic.d.ts","import":"./dist/providers/anthropic.js"},"./google-vertex":{"types":"./dist/providers/google-vertex.d.ts","import":"./dist/providers/google-vertex.js"},"./bedrock-provider":{"types":"./dist/bedrock-provider.d.ts","import":"./dist/bedrock-provider.js"},"./openai-responses":{"types":"./dist/providers/openai-responses.d.ts","import":"./dist/providers/openai-responses.js"},"./openai-completions":{"types":"./dist/providers/openai-completions.d.ts","import":"./dist/providers/openai-completions.js"},"./azure-openai-responses":{"types":"./dist/providers/azure-openai-responses.d.ts","import":"./dist/providers/azure-openai-responses.js"},"./openai-codex-responses":{"types":"./dist/providers/openai-codex-responses.d.ts","import":"./dist/providers/openai-codex-responses.js"}},"gitHead":"8b57630bc91a0c8f18ad3dcfa8fcf0f67623d780","scripts":{"dev":"tsgo -p tsconfig.build.json --watch --preserveWatchOutput","test":"vitest --run","build":"npm run generate-models && npm run generate-image-models && tsgo -p tsconfig.build.json","clean":"shx rm -rf dist","dev:tsc":"tsgo -p tsconfig.build.json --watch --preserveWatchOutput","prepublishOnly":"npm run clean && npm run build","generate-models":"npx tsx scripts/generate-models.ts","generate-image-models":"npx tsx scripts/generate-image-models.ts"},"_npmUser":{"name":"badlogic","email":"mario@badlogicgames.com"},"repository":{"url":"git+https://github.com/earendil-works/pi-mono.git","type":"git","directory":"packages/ai"},"_npmVersion":"11.10.0","description":"Unified LLM API with automatic model discovery and provider configuration","directories":{},"_nodeVersion":"25.2.1","dependencies":{"openai":"6.26.0","typebox":"^1.1.24","partial-json":"^0.1.7","@google/genai":"^1.40.0","http-proxy-agent":"^7.0.2","@anthropic-ai/sdk":"^0.91.1","https-proxy-agent":"^7.0.6","@mistralai/mistralai":"^2.2.0","@aws-sdk/client-bedrock-runtime":"^3.1030.0"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"canvas":"^3.2.0","vitest":"^3.2.4","@types/node":"^24.3.0"},"_npmOperationalInternal":{"tmp":"tmp/pi-ai_0.74.2_1779402115241_0.12205902651924605","host":"s3://npm-registry-packages-npm-production"}},"0.75.5":{"name":"@earendil-works/pi-ai","version":"0.75.5","keywords":["ai","llm","openai","anthropic","gemini","bedrock","unified","api"],"author":{"name":"Mario Zechner"},"license":"MIT","_id":"@earendil-works/pi-ai@0.75.5","maintainers":[{"name":"mitsuhiko","email":"armin.ronacher@active-4.com"},{"name":"badlogic","email":"mario@badlogicgames.com"}],"homepage":"https://github.com/earendil-works/pi-mono#readme","bugs":{"url":"https://github.com/earendil-works/pi-mono/issues"},"bin":{"pi-ai":"dist/cli.js"},"dist":{"shasum":"93d29b83ac1d4d2cf6d0fa1b5f368f79b1b4dbcb","tarball":"https://registry.npmjs.org/@earendil-works/pi-ai/-/pi-ai-0.75.5.tgz","fileCount":214,"integrity":"sha512-zf1F5kXk1pqZeFShXOqq9ibUk8QdtRoLCDPAjO+hj44e3EUs9/GFO2qnhTC5+JA2uwVCx+WCNe1PiCjlBYWm5w==","signatures":[{"sig":"MEYCIQCKoEShwcW+REXdkXY69HnXNhzTv+XhqExRZfi6f4D1IgIhANr0irIQqfzhJHRCzZnqK0DGeIOuvIuJ7BRe3d+fGuU+","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":4387529},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=22.19.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./oauth":{"types":"./dist/oauth.d.ts","import":"./dist/oauth.js"},"./google":{"types":"./dist/providers/google.d.ts","import":"./dist/providers/google.js"},"./mistral":{"types":"./dist/providers/mistral.d.ts","import":"./dist/providers/mistral.js"},"./anthropic":{"types":"./dist/providers/anthropic.d.ts","import":"./dist/providers/anthropic.js"},"./google-vertex":{"types":"./dist/providers/google-vertex.d.ts","import":"./dist/providers/google-vertex.js"},"./bedrock-provider":{"types":"./dist/bedrock-provider.d.ts","import":"./dist/bedrock-provider.js"},"./openai-responses":{"types":"./dist/providers/openai-responses.d.ts","import":"./dist/providers/openai-responses.js"},"./openai-completions":{"types":"./dist/providers/openai-completions.d.ts","import":"./dist/providers/openai-completions.js"},"./azure-openai-responses":{"types":"./dist/providers/azure-openai-responses.d.ts","import":"./dist/providers/azure-openai-responses.js"},"./openai-codex-responses":{"types":"./dist/providers/openai-codex-responses.d.ts","import":"./dist/providers/openai-codex-responses.js"}},"gitHead":"83a227aed3f6f7d2f8a63bdd66df0bdb80cd21e2","scripts":{"test":"vitest --run","build":"npm run generate-models && npm run generate-image-models && tsgo -p tsconfig.build.json","clean":"shx rm -rf dist","prepublishOnly":"npm run clean && npm run build","generate-models":"node scripts/generate-models.ts","generate-image-models":"node scripts/generate-image-models.ts"},"_npmUser":{"name":"badlogic","email":"mario@badlogicgames.com"},"repository":{"url":"git+https://github.com/earendil-works/pi-mono.git","type":"git","directory":"packages/ai"},"_npmVersion":"11.10.0","description":"Unified LLM API with automatic model discovery and provider configuration","directories":{},"_nodeVersion":"25.2.1","dependencies":{"openai":"6.26.0","typebox":"1.1.38","partial-json":"0.1.7","@google/genai":"1.52.0","http-proxy-agent":"7.0.2","@anthropic-ai/sdk":"0.91.1","https-proxy-agent":"7.0.6","@mistralai/mistralai":"2.2.1","@smithy/node-http-handler":"4.7.3","@aws-sdk/client-bedrock-runtime":"3.1048.0"},"_hasShrinkwrap":false,"devDependencies":{"canvas":"3.2.3","vitest":"3.2.4","@types/node":"24.12.4"},"_npmOperationalInternal":{"tmp":"tmp/pi-ai_0.75.5_1779530793531_0.5207650594733377","host":"s3://npm-registry-packages-npm-production"}},"0.76.0":{"name":"@earendil-works/pi-ai","version":"0.76.0","keywords":["ai","llm","openai","anthropic","gemini","bedrock","unified","api"],"author":{"name":"Mario Zechner"},"license":"MIT","_id":"@earendil-works/pi-ai@0.76.0","maintainers":[{"name":"mitsuhiko","email":"armin.ronacher@active-4.com"},{"name":"badlogic","email":"mario@badlogicgames.com"},{"name":"rwachtler","email":"r.wachtler@outlook.com"}],"homepage":"https://github.com/earendil-works/pi-mono#readme","bugs":{"url":"https://github.com/earendil-works/pi-mono/issues"},"bin":{"pi-ai":"dist/cli.js"},"dist":{"shasum":"e96126ac8f557c72abda61c714accbebac14c89b","tarball":"https://registry.npmjs.org/@earendil-works/pi-ai/-/pi-ai-0.76.0.tgz","fileCount":218,"integrity":"sha512-RO/L80iTxkK/nM2s5IVuirjH04UBsVzFfAT0qVcP/VwtDe9pjpqL+BVqb3XTyfitTD9tBo/hQuKmagN8Ep5qZA==","signatures":[{"sig":"MEUCIQDDxKYbBKD0R5Iu+gNIiGzMTlYsEKaiOqCSQmcz1/R70AIgT+h0O/ZFzKa6dGPzo4ztzLuS8RvAOL0GlqAq/hNuOeg=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":4404666},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=22.19.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./oauth":{"types":"./dist/oauth.d.ts","import":"./dist/oauth.js"},"./google":{"types":"./dist/providers/google.d.ts","import":"./dist/providers/google.js"},"./mistral":{"types":"./dist/providers/mistral.d.ts","import":"./dist/providers/mistral.js"},"./anthropic":{"types":"./dist/providers/anthropic.d.ts","import":"./dist/providers/anthropic.js"},"./google-vertex":{"types":"./dist/providers/google-vertex.d.ts","import":"./dist/providers/google-vertex.js"},"./bedrock-provider":{"types":"./dist/bedrock-provider.d.ts","import":"./dist/bedrock-provider.js"},"./openai-responses":{"types":"./dist/providers/openai-responses.d.ts","import":"./dist/providers/openai-responses.js"},"./openai-completions":{"types":"./dist/providers/openai-completions.d.ts","import":"./dist/providers/openai-completions.js"},"./azure-openai-responses":{"types":"./dist/providers/azure-openai-responses.d.ts","import":"./dist/providers/azure-openai-responses.js"},"./openai-codex-responses":{"types":"./dist/providers/openai-codex-responses.d.ts","import":"./dist/providers/openai-codex-responses.js"}},"gitHead":"706f8720f8cfe75f562b4e488681486cb70bbe9b","scripts":{"test":"vitest --run","build":"npm run generate-models && npm run generate-image-models && tsgo -p tsconfig.build.json","clean":"shx rm -rf dist","prepublishOnly":"npm run clean && npm run build","generate-models":"node scripts/generate-models.ts","generate-image-models":"node scripts/generate-image-models.ts"},"_npmUser":{"name":"mitsuhiko","email":"armin.ronacher@active-4.com"},"repository":{"url":"git+https://github.com/earendil-works/pi-mono.git","type":"git","directory":"packages/ai"},"_npmVersion":"11.11.0","description":"Unified LLM API with automatic model discovery and provider configuration","directories":{},"_nodeVersion":"25.8.1","dependencies":{"openai":"6.26.0","typebox":"1.1.38","partial-json":"0.1.7","@google/genai":"1.52.0","http-proxy-agent":"7.0.2","@anthropic-ai/sdk":"0.91.1","https-proxy-agent":"7.0.6","@mistralai/mistralai":"2.2.1","@smithy/node-http-handler":"4.7.3","@aws-sdk/client-bedrock-runtime":"3.1048.0"},"_hasShrinkwrap":false,"devDependencies":{"canvas":"3.2.3","vitest":"3.2.4","@types/node":"24.12.4"},"_npmOperationalInternal":{"tmp":"tmp/pi-ai_0.76.0_1779912231846_0.360236672926892","host":"s3://npm-registry-packages-npm-production"}},"0.77.0":{"name":"@earendil-works/pi-ai","version":"0.77.0","keywords":["ai","llm","openai","anthropic","gemini","bedrock","unified","api"],"author":{"name":"Mario Zechner"},"license":"MIT","_id":"@earendil-works/pi-ai@0.77.0","maintainers":[{"name":"mitsuhiko","email":"armin.ronacher@active-4.com"},{"name":"badlogic","email":"mario@badlogicgames.com"},{"name":"rwachtler","email":"r.wachtler@outlook.com"}],"homepage":"https://github.com/earendil-works/pi#readme","bugs":{"url":"https://github.com/earendil-works/pi/issues"},"bin":{"pi-ai":"dist/cli.js"},"dist":{"shasum":"f56a8236ca10ae0b78b9e4464c081588c050e254","tarball":"https://registry.npmjs.org/@earendil-works/pi-ai/-/pi-ai-0.77.0.tgz","fileCount":218,"integrity":"sha512-H21BrQDPf3ydaeBmS5maNDHxUGFMiKBF/n3WnE+OTWloIZSayeL+/NVEgG3aKQw8fZL6HAMYAGpUIVJgFuKtnw==","signatures":[{"sig":"MEYCIQC2bo3mpl/8XYy6biJqqMT70COCN1489FIvuTsrOyWclAIhANPHrH/UPFJjCU+8J2vgUpquoj04rirOUWn5qa2Xf/Y2","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@earendil-works%2fpi-ai@0.77.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":4454755},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=22.19.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./oauth":{"types":"./dist/oauth.d.ts","import":"./dist/oauth.js"},"./google":{"types":"./dist/providers/google.d.ts","import":"./dist/providers/google.js"},"./mistral":{"types":"./dist/providers/mistral.d.ts","import":"./dist/providers/mistral.js"},"./anthropic":{"types":"./dist/providers/anthropic.d.ts","import":"./dist/providers/anthropic.js"},"./google-vertex":{"types":"./dist/providers/google-vertex.d.ts","import":"./dist/providers/google-vertex.js"},"./bedrock-provider":{"types":"./dist/bedrock-provider.d.ts","import":"./dist/bedrock-provider.js"},"./openai-responses":{"types":"./dist/providers/openai-responses.d.ts","import":"./dist/providers/openai-responses.js"},"./openai-completions":{"types":"./dist/providers/openai-completions.d.ts","import":"./dist/providers/openai-completions.js"},"./azure-openai-responses":{"types":"./dist/providers/azure-openai-responses.d.ts","import":"./dist/providers/azure-openai-responses.js"},"./openai-codex-responses":{"types":"./dist/providers/openai-codex-responses.d.ts","import":"./dist/providers/openai-codex-responses.js"}},"gitHead":"93600d89802a253decdf2d8c3cd56fb362538f38","scripts":{"test":"vitest --run","build":"npm run generate-models && npm run generate-image-models && tsgo -p tsconfig.build.json","clean":"shx rm -rf dist","prepublishOnly":"npm run clean && npm run build","generate-models":"node scripts/generate-models.ts","generate-image-models":"node scripts/generate-image-models.ts"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:975b2765-9d44-42ba-a322-c1cbbce03f36"}},"repository":{"url":"git+https://github.com/earendil-works/pi.git","type":"git","directory":"packages/ai"},"_npmVersion":"11.16.0","description":"Unified LLM API with automatic model discovery and provider configuration","directories":{},"_nodeVersion":"22.22.3","dependencies":{"openai":"6.26.0","typebox":"1.1.38","partial-json":"0.1.7","@google/genai":"1.52.0","http-proxy-agent":"7.0.2","@anthropic-ai/sdk":"0.91.1","https-proxy-agent":"7.0.6","@mistralai/mistralai":"2.2.1","@smithy/node-http-handler":"4.7.3","@aws-sdk/client-bedrock-runtime":"3.1048.0"},"_hasShrinkwrap":false,"devDependencies":{"canvas":"3.2.3","vitest":"3.2.4","@types/node":"24.12.4"},"_npmOperationalInternal":{"tmp":"tmp/pi-ai_0.77.0_1780008532853_0.6300958544220825","host":"s3://npm-registry-packages-npm-production"}},"0.78.0":{"name":"@earendil-works/pi-ai","version":"0.78.0","keywords":["ai","llm","openai","anthropic","gemini","bedrock","unified","api"],"author":{"name":"Mario Zechner"},"license":"MIT","_id":"@earendil-works/pi-ai@0.78.0","maintainers":[{"name":"mitsuhiko","email":"armin.ronacher@active-4.com"},{"name":"badlogic","email":"mario@badlogicgames.com"},{"name":"rwachtler","email":"r.wachtler@outlook.com"}],"homepage":"https://github.com/earendil-works/pi#readme","bugs":{"url":"https://github.com/earendil-works/pi/issues"},"bin":{"pi-ai":"dist/cli.js"},"dist":{"shasum":"f6befb7c84e1cb04ab66eb0a19f497670d4f2b0f","tarball":"https://registry.npmjs.org/@earendil-works/pi-ai/-/pi-ai-0.78.0.tgz","fileCount":218,"integrity":"sha512-q0hUrvT6ngT6cgBX0oIbzfQfmzztgdkZobP8OTL+sCOOBlnG6+1YRt8g7zO9CC/4NdeYEqa7uGqWdQhH0fjCLA==","signatures":[{"sig":"MEUCIDmhQh/dJrrnpMdqg2s9gmBfpfhnxnXkbZHA1vTespUkAiEAhfYKd+E8UabcPK+ZkI5Kltd0Gs+xs4TVNHxN/lQr16o=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@earendil-works%2fpi-ai@0.78.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":4464634},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=22.19.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./oauth":{"types":"./dist/oauth.d.ts","import":"./dist/oauth.js"},"./google":{"types":"./dist/providers/google.d.ts","import":"./dist/providers/google.js"},"./mistral":{"types":"./dist/providers/mistral.d.ts","import":"./dist/providers/mistral.js"},"./anthropic":{"types":"./dist/providers/anthropic.d.ts","import":"./dist/providers/anthropic.js"},"./google-vertex":{"types":"./dist/providers/google-vertex.d.ts","import":"./dist/providers/google-vertex.js"},"./bedrock-provider":{"types":"./dist/bedrock-provider.d.ts","import":"./dist/bedrock-provider.js"},"./openai-responses":{"types":"./dist/providers/openai-responses.d.ts","import":"./dist/providers/openai-responses.js"},"./openai-completions":{"types":"./dist/providers/openai-completions.d.ts","import":"./dist/providers/openai-completions.js"},"./azure-openai-responses":{"types":"./dist/providers/azure-openai-responses.d.ts","import":"./dist/providers/azure-openai-responses.js"},"./openai-codex-responses":{"types":"./dist/providers/openai-codex-responses.d.ts","import":"./dist/providers/openai-codex-responses.js"}},"gitHead":"0897f175e4d46592c0f59b3a2d399f11b8d078af","scripts":{"test":"vitest --run","build":"npm run generate-models && npm run generate-image-models && tsgo -p tsconfig.build.json","clean":"shx rm -rf dist","prepublishOnly":"npm run clean && npm run build","generate-models":"node scripts/generate-models.ts","generate-image-models":"node scripts/generate-image-models.ts"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:975b2765-9d44-42ba-a322-c1cbbce03f36"}},"repository":{"url":"git+https://github.com/earendil-works/pi.git","type":"git","directory":"packages/ai"},"_npmVersion":"11.16.0","description":"Unified LLM API with automatic model discovery and provider configuration","directories":{},"_nodeVersion":"22.22.3","dependencies":{"openai":"6.26.0","typebox":"1.1.38","partial-json":"0.1.7","@google/genai":"1.52.0","http-proxy-agent":"7.0.2","@anthropic-ai/sdk":"0.91.1","https-proxy-agent":"7.0.6","@mistralai/mistralai":"2.2.1","@smithy/node-http-handler":"4.7.3","@aws-sdk/client-bedrock-runtime":"3.1048.0"},"_hasShrinkwrap":false,"devDependencies":{"canvas":"3.2.3","vitest":"3.2.4","@types/node":"24.12.4"},"_npmOperationalInternal":{"tmp":"tmp/pi-ai_0.78.0_1780098688497_0.9715674418805678","host":"s3://npm-registry-packages-npm-production"}},"0.78.1":{"name":"@earendil-works/pi-ai","version":"0.78.1","keywords":["ai","llm","openai","anthropic","gemini","bedrock","unified","api"],"author":{"name":"Mario Zechner"},"license":"MIT","_id":"@earendil-works/pi-ai@0.78.1","maintainers":[{"name":"mitsuhiko","email":"armin.ronacher@active-4.com"},{"name":"badlogic","email":"mario@badlogicgames.com"},{"name":"rwachtler","email":"r.wachtler@outlook.com"}],"homepage":"https://github.com/earendil-works/pi#readme","bugs":{"url":"https://github.com/earendil-works/pi/issues"},"bin":{"pi-ai":"dist/cli.js"},"dist":{"shasum":"8822913921db86db788f54a736726fc866c605f4","tarball":"https://registry.npmjs.org/@earendil-works/pi-ai/-/pi-ai-0.78.1.tgz","fileCount":218,"integrity":"sha512-CM2pkTs1iupG/maw381lC9Q/Y/aQaMGK7GILc28ttImD0ci3LDwKroDsGkWbly5JIy3iqxdRxB9JlG7vvzCzTg==","signatures":[{"sig":"MEUCIQCNxt+xC3YKYn9clHxMgU6Lzzr3lZY2uSkydacsqsy+RAIgaeOAUhfBqMHutj9qZCl/4pYKe7po6oQd0ZJ2LHqDiJA=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@earendil-works%2fpi-ai@0.78.1","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":4605181},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=22.19.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./oauth":{"types":"./dist/oauth.d.ts","import":"./dist/oauth.js"},"./google":{"types":"./dist/providers/google.d.ts","import":"./dist/providers/google.js"},"./mistral":{"types":"./dist/providers/mistral.d.ts","import":"./dist/providers/mistral.js"},"./anthropic":{"types":"./dist/providers/anthropic.d.ts","import":"./dist/providers/anthropic.js"},"./google-vertex":{"types":"./dist/providers/google-vertex.d.ts","import":"./dist/providers/google-vertex.js"},"./bedrock-provider":{"types":"./dist/bedrock-provider.d.ts","import":"./dist/bedrock-provider.js"},"./openai-responses":{"types":"./dist/providers/openai-responses.d.ts","import":"./dist/providers/openai-responses.js"},"./openai-completions":{"types":"./dist/providers/openai-completions.d.ts","import":"./dist/providers/openai-completions.js"},"./azure-openai-responses":{"types":"./dist/providers/azure-openai-responses.d.ts","import":"./dist/providers/azure-openai-responses.js"},"./openai-codex-responses":{"types":"./dist/providers/openai-codex-responses.d.ts","import":"./dist/providers/openai-codex-responses.js"}},"gitHead":"592c34c05643d115d6eed08a6f615999651cfaa3","scripts":{"test":"vitest --run","build":"npm run generate-models && npm run generate-image-models && tsgo -p tsconfig.build.json","clean":"shx rm -rf dist","prepublishOnly":"npm run clean && npm run build","generate-models":"node scripts/generate-models.ts","generate-image-models":"node scripts/generate-image-models.ts"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:975b2765-9d44-42ba-a322-c1cbbce03f36"}},"repository":{"url":"git+https://github.com/earendil-works/pi.git","type":"git","directory":"packages/ai"},"_npmVersion":"11.16.0","description":"Unified LLM API with automatic model discovery and provider configuration","directories":{},"_nodeVersion":"22.22.3","dependencies":{"openai":"6.26.0","typebox":"1.1.38","partial-json":"0.1.7","@google/genai":"1.52.0","http-proxy-agent":"7.0.2","@anthropic-ai/sdk":"0.91.1","https-proxy-agent":"7.0.6","@mistralai/mistralai":"2.2.1","@smithy/node-http-handler":"4.7.3","@aws-sdk/client-bedrock-runtime":"3.1048.0"},"_hasShrinkwrap":false,"devDependencies":{"canvas":"3.2.3","vitest":"3.2.4","@types/node":"24.12.4"},"_npmOperationalInternal":{"tmp":"tmp/pi-ai_0.78.1_1780590933034_0.836282499905235","host":"s3://npm-registry-packages-npm-production"}},"0.79.0":{"name":"@earendil-works/pi-ai","version":"0.79.0","keywords":["ai","llm","openai","anthropic","gemini","bedrock","unified","api"],"author":{"name":"Mario Zechner"},"license":"MIT","_id":"@earendil-works/pi-ai@0.79.0","maintainers":[{"name":"mitsuhiko","email":"armin.ronacher@active-4.com"},{"name":"badlogic","email":"mario@badlogicgames.com"},{"name":"rwachtler","email":"r.wachtler@outlook.com"}],"homepage":"https://github.com/earendil-works/pi#readme","bugs":{"url":"https://github.com/earendil-works/pi/issues"},"bin":{"pi-ai":"dist/cli.js"},"dist":{"shasum":"a1ee8251fb77df00182f9cb925405729771b3ff4","tarball":"https://registry.npmjs.org/@earendil-works/pi-ai/-/pi-ai-0.79.0.tgz","fileCount":218,"integrity":"sha512-D/2aDoe9vcCbqAztALQcKkdqXGuaQcqAzLm8LfUhNaorwoIHkwnaAuDVlo+OkF5clpEwS8Z1bk2o8NiSrwEdsA==","signatures":[{"sig":"MEQCICSl0JJHMLGKdybrrlnkoU43fbpY+rQLNNoxPetMuovQAiAKcLiI8yyn9dcnKxIGsS95nythiCsqdvgjgZlXgDC2ow==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@earendil-works%2fpi-ai@0.79.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":4615888},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=22.19.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./oauth":{"types":"./dist/oauth.d.ts","import":"./dist/oauth.js"},"./google":{"types":"./dist/providers/google.d.ts","import":"./dist/providers/google.js"},"./mistral":{"types":"./dist/providers/mistral.d.ts","import":"./dist/providers/mistral.js"},"./anthropic":{"types":"./dist/providers/anthropic.d.ts","import":"./dist/providers/anthropic.js"},"./google-vertex":{"types":"./dist/providers/google-vertex.d.ts","import":"./dist/providers/google-vertex.js"},"./bedrock-provider":{"types":"./dist/bedrock-provider.d.ts","import":"./dist/bedrock-provider.js"},"./openai-responses":{"types":"./dist/providers/openai-responses.d.ts","import":"./dist/providers/openai-responses.js"},"./openai-completions":{"types":"./dist/providers/openai-completions.d.ts","import":"./dist/providers/openai-completions.js"},"./azure-openai-responses":{"types":"./dist/providers/azure-openai-responses.d.ts","import":"./dist/providers/azure-openai-responses.js"},"./openai-codex-responses":{"types":"./dist/providers/openai-codex-responses.d.ts","import":"./dist/providers/openai-codex-responses.js"}},"gitHead":"c10fb95fd993a1f6a92d5f770258fada1a20b55a","scripts":{"test":"vitest --run","build":"npm run generate-models && npm run generate-image-models && tsgo -p tsconfig.build.json","clean":"shx rm -rf dist","prepublishOnly":"npm run clean && npm run build","generate-models":"node scripts/generate-models.ts","generate-image-models":"node scripts/generate-image-models.ts"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:975b2765-9d44-42ba-a322-c1cbbce03f36"}},"repository":{"url":"git+https://github.com/earendil-works/pi.git","type":"git","directory":"packages/ai"},"_npmVersion":"11.16.0","description":"Unified LLM API with automatic model discovery and provider configuration","directories":{},"_nodeVersion":"22.22.3","dependencies":{"openai":"6.26.0","typebox":"1.1.38","partial-json":"0.1.7","@google/genai":"1.52.0","http-proxy-agent":"7.0.2","@anthropic-ai/sdk":"0.91.1","https-proxy-agent":"7.0.6","@mistralai/mistralai":"2.2.1","@smithy/node-http-handler":"4.7.3","@aws-sdk/client-bedrock-runtime":"3.1048.0"},"_hasShrinkwrap":false,"devDependencies":{"canvas":"3.2.3","vitest":"3.2.4","@types/node":"24.12.4"},"_npmOperationalInternal":{"tmp":"tmp/pi-ai_0.79.0_1780932007381_0.37474090247616587","host":"s3://npm-registry-packages-npm-production"}},"0.79.1":{"name":"@earendil-works/pi-ai","version":"0.79.1","keywords":["ai","llm","openai","anthropic","gemini","bedrock","unified","api"],"author":{"name":"Mario Zechner"},"license":"MIT","_id":"@earendil-works/pi-ai@0.79.1","maintainers":[{"name":"mitsuhiko","email":"armin.ronacher@active-4.com"},{"name":"badlogic","email":"mario@badlogicgames.com"},{"name":"rwachtler","email":"r.wachtler@outlook.com"}],"homepage":"https://github.com/earendil-works/pi#readme","bugs":{"url":"https://github.com/earendil-works/pi/issues"},"bin":{"pi-ai":"dist/cli.js"},"dist":{"shasum":"3928fcde9248456bd5c242025fa8a2003641765b","tarball":"https://registry.npmjs.org/@earendil-works/pi-ai/-/pi-ai-0.79.1.tgz","fileCount":218,"integrity":"sha512-UnORwrcsTNLm4StEvoM8iEom0u87Te7BXEWxhec3iNXygWD6eEBosUoq9ddcveqtj/QpUZBMPWUu81cCtZxzkQ==","signatures":[{"sig":"MEQCICdOgRt4rSCMdKwYAJrW9C3bdJ+E8Foi65ju7Q214InqAiAxFDxa9vBAVTsVHa1ls4s64rjUBCdsBDtAbTx1PohAHw==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@earendil-works%2fpi-ai@0.79.1","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":4655837},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=22.19.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./oauth":{"types":"./dist/oauth.d.ts","import":"./dist/oauth.js"},"./google":{"types":"./dist/providers/google.d.ts","import":"./dist/providers/google.js"},"./mistral":{"types":"./dist/providers/mistral.d.ts","import":"./dist/providers/mistral.js"},"./anthropic":{"types":"./dist/providers/anthropic.d.ts","import":"./dist/providers/anthropic.js"},"./google-vertex":{"types":"./dist/providers/google-vertex.d.ts","import":"./dist/providers/google-vertex.js"},"./bedrock-provider":{"types":"./dist/bedrock-provider.d.ts","import":"./dist/bedrock-provider.js"},"./openai-responses":{"types":"./dist/providers/openai-responses.d.ts","import":"./dist/providers/openai-responses.js"},"./openai-completions":{"types":"./dist/providers/openai-completions.d.ts","import":"./dist/providers/openai-completions.js"},"./azure-openai-responses":{"types":"./dist/providers/azure-openai-responses.d.ts","import":"./dist/providers/azure-openai-responses.js"},"./openai-codex-responses":{"types":"./dist/providers/openai-codex-responses.d.ts","import":"./dist/providers/openai-codex-responses.js"}},"gitHead":"dacb367e9e51a649eb16aee17ddece7ada896ee9","scripts":{"test":"vitest --run","build":"npm run generate-models && npm run generate-image-models && tsgo -p tsconfig.build.json","clean":"shx rm -rf dist","prepublishOnly":"npm run clean && npm run build","generate-models":"node scripts/generate-models.ts","generate-image-models":"node scripts/generate-image-models.ts"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:975b2765-9d44-42ba-a322-c1cbbce03f36"}},"repository":{"url":"git+https://github.com/earendil-works/pi.git","type":"git","directory":"packages/ai"},"_npmVersion":"11.16.0","description":"Unified LLM API with automatic model discovery and provider configuration","directories":{},"_nodeVersion":"22.22.3","dependencies":{"openai":"6.26.0","typebox":"1.1.38","partial-json":"0.1.7","@google/genai":"1.52.0","http-proxy-agent":"7.0.2","@anthropic-ai/sdk":"0.91.1","https-proxy-agent":"7.0.6","@mistralai/mistralai":"2.2.1","@smithy/node-http-handler":"4.7.3","@aws-sdk/client-bedrock-runtime":"3.1048.0"},"_hasShrinkwrap":false,"devDependencies":{"canvas":"3.2.3","vitest":"3.2.4","@types/node":"24.12.4"},"_npmOperationalInternal":{"tmp":"tmp/pi-ai_0.79.1_1781040328507_0.10693514080482336","host":"s3://npm-registry-packages-npm-production"}},"0.79.2":{"name":"@earendil-works/pi-ai","version":"0.79.2","keywords":["ai","llm","openai","anthropic","gemini","bedrock","unified","api"],"author":{"name":"Mario Zechner"},"license":"MIT","_id":"@earendil-works/pi-ai@0.79.2","maintainers":[{"name":"mitsuhiko","email":"armin.ronacher@active-4.com"},{"name":"badlogic","email":"mario@badlogicgames.com"},{"name":"rwachtler","email":"r.wachtler@outlook.com"}],"homepage":"https://github.com/earendil-works/pi#readme","bugs":{"url":"https://github.com/earendil-works/pi/issues"},"bin":{"pi-ai":"dist/cli.js"},"dist":{"shasum":"c6c2d11af6ce4fd787c7dda71d0eda4c337a0d6b","tarball":"https://registry.npmjs.org/@earendil-works/pi-ai/-/pi-ai-0.79.2.tgz","fileCount":218,"integrity":"sha512-ydZ19dWqhw4KrkKXtLByFXdNPusRTpXYAElbnCMX0iSX+m59+SUJG0RgEQ6H7sIIV6LvGSEnnQsP6tm1vwcrLA==","signatures":[{"sig":"MEYCIQDmoQ3JDQzlVBfIZ6pL5bliuGsKloKGyYQB3EQLEZkArAIhAOwfYA5QB9xC3HbvaCmdrdmgcYfdbiS95nK4KnlLuDJ5","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@earendil-works%2fpi-ai@0.79.2","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":4620320},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=22.19.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./oauth":{"types":"./dist/oauth.d.ts","import":"./dist/oauth.js"},"./google":{"types":"./dist/providers/google.d.ts","import":"./dist/providers/google.js"},"./mistral":{"types":"./dist/providers/mistral.d.ts","import":"./dist/providers/mistral.js"},"./anthropic":{"types":"./dist/providers/anthropic.d.ts","import":"./dist/providers/anthropic.js"},"./google-vertex":{"types":"./dist/providers/google-vertex.d.ts","import":"./dist/providers/google-vertex.js"},"./bedrock-provider":{"types":"./dist/bedrock-provider.d.ts","import":"./dist/bedrock-provider.js"},"./openai-responses":{"types":"./dist/providers/openai-responses.d.ts","import":"./dist/providers/openai-responses.js"},"./openai-completions":{"types":"./dist/providers/openai-completions.d.ts","import":"./dist/providers/openai-completions.js"},"./azure-openai-responses":{"types":"./dist/providers/azure-openai-responses.d.ts","import":"./dist/providers/azure-openai-responses.js"},"./openai-codex-responses":{"types":"./dist/providers/openai-codex-responses.d.ts","import":"./dist/providers/openai-codex-responses.js"}},"gitHead":"f21f3c4bbdd3868ce2a7a68019d7920b838f663b","scripts":{"test":"vitest --run","build":"npm run generate-models && npm run generate-image-models && tsgo -p tsconfig.build.json","clean":"shx rm -rf dist","prepublishOnly":"npm run clean && npm run build","generate-models":"node scripts/generate-models.ts","generate-image-models":"node scripts/generate-image-models.ts"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:975b2765-9d44-42ba-a322-c1cbbce03f36"}},"repository":{"url":"git+https://github.com/earendil-works/pi.git","type":"git","directory":"packages/ai"},"_npmVersion":"11.16.0","description":"Unified LLM API with automatic model discovery and provider configuration","directories":{},"_nodeVersion":"22.22.3","dependencies":{"openai":"6.26.0","typebox":"1.1.38","partial-json":"0.1.7","@google/genai":"1.52.0","http-proxy-agent":"7.0.2","@anthropic-ai/sdk":"0.91.1","https-proxy-agent":"7.0.6","@mistralai/mistralai":"2.2.1","@smithy/node-http-handler":"4.7.3","@aws-sdk/client-bedrock-runtime":"3.1048.0"},"_hasShrinkwrap":false,"devDependencies":{"canvas":"3.2.3","vitest":"3.2.4","@types/node":"24.12.4"},"_npmOperationalInternal":{"tmp":"tmp/pi-ai_0.79.2_1781303375346_0.1961492137504286","host":"s3://npm-registry-packages-npm-production"}},"0.79.3":{"name":"@earendil-works/pi-ai","version":"0.79.3","keywords":["ai","llm","openai","anthropic","gemini","bedrock","unified","api"],"author":{"name":"Mario Zechner"},"license":"MIT","_id":"@earendil-works/pi-ai@0.79.3","maintainers":[{"name":"mitsuhiko","email":"armin.ronacher@active-4.com"},{"name":"badlogic","email":"mario@badlogicgames.com"},{"name":"rwachtler","email":"r.wachtler@outlook.com"}],"homepage":"https://github.com/earendil-works/pi#readme","bugs":{"url":"https://github.com/earendil-works/pi/issues"},"bin":{"pi-ai":"dist/cli.js"},"dist":{"shasum":"c0ae2987df112d7eb0ab2d4fa4db7e225530222a","tarball":"https://registry.npmjs.org/@earendil-works/pi-ai/-/pi-ai-0.79.3.tgz","fileCount":218,"integrity":"sha512-lMSput/haP5uZAGbXhS5rAYd3GB7GYdJkoAUxg3VFummBeqGqGqllaTWrbHFN12kVGyVfWHhdySNXkiqVh65Iw==","signatures":[{"sig":"MEUCIARCTbhSBZk9BAJC0D9zDUC2MehnflHUdKpox5CseW16AiEA3ZOzPPcsQLsRFNccgGVbAbJsaubpwxy4214KMQK/Gt8=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@earendil-works%2fpi-ai@0.79.3","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":4621856},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=22.19.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./oauth":{"types":"./dist/oauth.d.ts","import":"./dist/oauth.js"},"./google":{"types":"./dist/providers/google.d.ts","import":"./dist/providers/google.js"},"./mistral":{"types":"./dist/providers/mistral.d.ts","import":"./dist/providers/mistral.js"},"./anthropic":{"types":"./dist/providers/anthropic.d.ts","import":"./dist/providers/anthropic.js"},"./google-vertex":{"types":"./dist/providers/google-vertex.d.ts","import":"./dist/providers/google-vertex.js"},"./bedrock-provider":{"types":"./dist/bedrock-provider.d.ts","import":"./dist/bedrock-provider.js"},"./openai-responses":{"types":"./dist/providers/openai-responses.d.ts","import":"./dist/providers/openai-responses.js"},"./openai-completions":{"types":"./dist/providers/openai-completions.d.ts","import":"./dist/providers/openai-completions.js"},"./azure-openai-responses":{"types":"./dist/providers/azure-openai-responses.d.ts","import":"./dist/providers/azure-openai-responses.js"},"./openai-codex-responses":{"types":"./dist/providers/openai-codex-responses.d.ts","import":"./dist/providers/openai-codex-responses.js"}},"gitHead":"6f29450e1339b37582796775749de3957936cd8d","scripts":{"test":"vitest --run","build":"npm run generate-models && npm run generate-image-models && tsgo -p tsconfig.build.json","clean":"shx rm -rf dist","prepublishOnly":"npm run clean && npm run build","generate-models":"node scripts/generate-models.ts","generate-image-models":"node scripts/generate-image-models.ts"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:975b2765-9d44-42ba-a322-c1cbbce03f36"}},"repository":{"url":"git+https://github.com/earendil-works/pi.git","type":"git","directory":"packages/ai"},"_npmVersion":"11.16.0","description":"Unified LLM API with automatic model discovery and provider configuration","directories":{},"_nodeVersion":"22.22.3","dependencies":{"openai":"6.26.0","typebox":"1.1.38","partial-json":"0.1.7","@google/genai":"1.52.0","http-proxy-agent":"7.0.2","@anthropic-ai/sdk":"0.91.1","https-proxy-agent":"7.0.6","@mistralai/mistralai":"2.2.1","@smithy/node-http-handler":"4.7.3","@aws-sdk/client-bedrock-runtime":"3.1048.0"},"_hasShrinkwrap":false,"devDependencies":{"canvas":"3.2.3","vitest":"3.2.4","@types/node":"24.12.4"},"_npmOperationalInternal":{"tmp":"tmp/pi-ai_0.79.3_1781342505000_0.4946293201172982","host":"s3://npm-registry-packages-npm-production"}},"0.79.4":{"name":"@earendil-works/pi-ai","version":"0.79.4","keywords":["ai","llm","openai","anthropic","gemini","bedrock","unified","api"],"author":{"name":"Mario Zechner"},"license":"MIT","_id":"@earendil-works/pi-ai@0.79.4","maintainers":[{"name":"mitsuhiko","email":"armin.ronacher@active-4.com"},{"name":"badlogic","email":"mario@badlogicgames.com"},{"name":"rwachtler","email":"r.wachtler@outlook.com"}],"homepage":"https://github.com/earendil-works/pi#readme","bugs":{"url":"https://github.com/earendil-works/pi/issues"},"bin":{"pi-ai":"dist/cli.js"},"dist":{"shasum":"4278ab29ce0e73f865657b2af251e2182ededd11","tarball":"https://registry.npmjs.org/@earendil-works/pi-ai/-/pi-ai-0.79.4.tgz","fileCount":218,"integrity":"sha512-Z1j+YP+6ZyPBKDUoc5m0GO/o1hPK17fWeErtDgegCTpm2dcKzuFvL/7GTqHeJkVkfpeXRwO37xOfgozQbK6EUw==","signatures":[{"sig":"MEQCIDmR8O+ts9d2bfgMYdinAvYsqAfDzSi5FIz1em2DlyPLAiBgwkhSCEQ2JBfb5s4OxJcj4c5xyFxSy77rNEkmFm8+3A==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@earendil-works%2fpi-ai@0.79.4","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":4640964},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=22.19.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./oauth":{"types":"./dist/oauth.d.ts","import":"./dist/oauth.js"},"./google":{"types":"./dist/providers/google.d.ts","import":"./dist/providers/google.js"},"./mistral":{"types":"./dist/providers/mistral.d.ts","import":"./dist/providers/mistral.js"},"./anthropic":{"types":"./dist/providers/anthropic.d.ts","import":"./dist/providers/anthropic.js"},"./google-vertex":{"types":"./dist/providers/google-vertex.d.ts","import":"./dist/providers/google-vertex.js"},"./bedrock-provider":{"types":"./dist/bedrock-provider.d.ts","import":"./dist/bedrock-provider.js"},"./openai-responses":{"types":"./dist/providers/openai-responses.d.ts","import":"./dist/providers/openai-responses.js"},"./openai-completions":{"types":"./dist/providers/openai-completions.d.ts","import":"./dist/providers/openai-completions.js"},"./azure-openai-responses":{"types":"./dist/providers/azure-openai-responses.d.ts","import":"./dist/providers/azure-openai-responses.js"},"./openai-codex-responses":{"types":"./dist/providers/openai-codex-responses.d.ts","import":"./dist/providers/openai-codex-responses.js"}},"gitHead":"bba6af2c71c5004546007cde59995d15efe8465b","scripts":{"test":"vitest --run","build":"npm run generate-models && npm run generate-image-models && tsgo -p tsconfig.build.json","clean":"shx rm -rf dist","prepublishOnly":"npm run clean && npm run build","generate-models":"node scripts/generate-models.ts","generate-image-models":"node scripts/generate-image-models.ts"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:975b2765-9d44-42ba-a322-c1cbbce03f36"}},"repository":{"url":"git+https://github.com/earendil-works/pi.git","type":"git","directory":"packages/ai"},"_npmVersion":"11.16.0","description":"Unified LLM API with automatic model discovery and provider configuration","directories":{},"_nodeVersion":"22.22.3","dependencies":{"openai":"6.26.0","typebox":"1.1.38","partial-json":"0.1.7","@google/genai":"1.52.0","http-proxy-agent":"7.0.2","@anthropic-ai/sdk":"0.91.1","https-proxy-agent":"7.0.6","@mistralai/mistralai":"2.2.1","@smithy/node-http-handler":"4.7.3","@aws-sdk/client-bedrock-runtime":"3.1048.0"},"_hasShrinkwrap":false,"devDependencies":{"canvas":"3.2.3","vitest":"3.2.4","@types/node":"24.12.4"},"_npmOperationalInternal":{"tmp":"tmp/pi-ai_0.79.4_1781512345935_0.02275608039449506","host":"s3://npm-registry-packages-npm-production"}},"0.79.5":{"name":"@earendil-works/pi-ai","version":"0.79.5","keywords":["ai","llm","openai","anthropic","gemini","bedrock","unified","api"],"author":{"name":"Mario Zechner"},"license":"MIT","_id":"@earendil-works/pi-ai@0.79.5","maintainers":[{"name":"mitsuhiko","email":"armin.ronacher@active-4.com"},{"name":"badlogic","email":"mario@badlogicgames.com"},{"name":"rwachtler","email":"r.wachtler@outlook.com"}],"homepage":"https://github.com/earendil-works/pi#readme","bugs":{"url":"https://github.com/earendil-works/pi/issues"},"bin":{"pi-ai":"dist/cli.js"},"dist":{"shasum":"d3ebc0403b2996abe384de859c43d76c6eba51d5","tarball":"https://registry.npmjs.org/@earendil-works/pi-ai/-/pi-ai-0.79.5.tgz","fileCount":222,"integrity":"sha512-LwZfV8HNvT90A9n5foA/a6/JMh5n/1lh1rRzOn+68kiFitf/tz3HTBpeSNFnUL4KLIdwp1lczjl4U2EJX0egvQ==","signatures":[{"sig":"MEYCIQD8EY1DBYrFmmgEaWY+MiaeV0mHhogKMJGkrdWD3AUfUQIhAIw587vJi8JTCnhnvUkdslTHnVvcLfOU39Dvm9AT9zZG","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@earendil-works%2fpi-ai@0.79.5","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":4673158},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=22.19.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./oauth":{"types":"./dist/oauth.d.ts","import":"./dist/oauth.js"},"./google":{"types":"./dist/providers/google.d.ts","import":"./dist/providers/google.js"},"./mistral":{"types":"./dist/providers/mistral.d.ts","import":"./dist/providers/mistral.js"},"./anthropic":{"types":"./dist/providers/anthropic.d.ts","import":"./dist/providers/anthropic.js"},"./google-vertex":{"types":"./dist/providers/google-vertex.d.ts","import":"./dist/providers/google-vertex.js"},"./bedrock-provider":{"types":"./dist/bedrock-provider.d.ts","import":"./dist/bedrock-provider.js"},"./openai-responses":{"types":"./dist/providers/openai-responses.d.ts","import":"./dist/providers/openai-responses.js"},"./openai-completions":{"types":"./dist/providers/openai-completions.d.ts","import":"./dist/providers/openai-completions.js"},"./azure-openai-responses":{"types":"./dist/providers/azure-openai-responses.d.ts","import":"./dist/providers/azure-openai-responses.js"},"./openai-codex-responses":{"types":"./dist/providers/openai-codex-responses.d.ts","import":"./dist/providers/openai-codex-responses.js"}},"gitHead":"a78cd7ccb18952c3139c086c54b488a87c6e32e4","scripts":{"test":"vitest --run","build":"npm run generate-models && npm run generate-image-models && tsgo -p tsconfig.build.json","clean":"shx rm -rf dist","prepublishOnly":"npm run clean && npm run build","generate-models":"node scripts/generate-models.ts","generate-image-models":"node scripts/generate-image-models.ts"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:975b2765-9d44-42ba-a322-c1cbbce03f36"}},"repository":{"url":"git+https://github.com/earendil-works/pi.git","type":"git","directory":"packages/ai"},"_npmVersion":"11.16.0","description":"Unified LLM API with automatic model discovery and provider configuration","directories":{},"_nodeVersion":"22.22.3","dependencies":{"openai":"6.26.0","typebox":"1.1.38","partial-json":"0.1.7","@google/genai":"1.52.0","http-proxy-agent":"7.0.2","@anthropic-ai/sdk":"0.91.1","https-proxy-agent":"7.0.6","@mistralai/mistralai":"2.2.1","@smithy/node-http-handler":"4.7.3","@aws-sdk/client-bedrock-runtime":"3.1048.0"},"_hasShrinkwrap":false,"devDependencies":{"canvas":"3.2.3","vitest":"3.2.4","@types/node":"24.12.4"},"_npmOperationalInternal":{"tmp":"tmp/pi-ai_0.79.5_1781633219590_0.3321577553873132","host":"s3://npm-registry-packages-npm-production"}},"0.79.6":{"name":"@earendil-works/pi-ai","version":"0.79.6","keywords":["ai","llm","openai","anthropic","gemini","bedrock","unified","api"],"author":{"name":"Mario Zechner"},"license":"MIT","_id":"@earendil-works/pi-ai@0.79.6","maintainers":[{"name":"mitsuhiko","email":"armin.ronacher@active-4.com"},{"name":"badlogic","email":"mario@badlogicgames.com"},{"name":"rwachtler","email":"r.wachtler@outlook.com"}],"homepage":"https://github.com/earendil-works/pi#readme","bugs":{"url":"https://github.com/earendil-works/pi/issues"},"bin":{"pi-ai":"dist/cli.js"},"dist":{"shasum":"f3a1e8bb2de32653ee0a125a6ca26b4096ead853","tarball":"https://registry.npmjs.org/@earendil-works/pi-ai/-/pi-ai-0.79.6.tgz","fileCount":222,"integrity":"sha512-KGepEdgEeWDs7Imwlp96tBsO8TjSIpcDBvazsCDtHRa81+uwJI/YGetTegI52pMlKhVpJFLIGajRi4PCGC5MUg==","signatures":[{"sig":"MEUCIAyKoXxeUejBiHfdSORqycaBW0GNrE2tS13TjrMiB9hQAiEAmrW7bReS1xm2N4kQModMTSmwV+7xAFV9NMshLmpotwE=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@earendil-works%2fpi-ai@0.79.6","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":4673474},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=22.19.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./oauth":{"types":"./dist/oauth.d.ts","import":"./dist/oauth.js"},"./google":{"types":"./dist/providers/google.d.ts","import":"./dist/providers/google.js"},"./mistral":{"types":"./dist/providers/mistral.d.ts","import":"./dist/providers/mistral.js"},"./anthropic":{"types":"./dist/providers/anthropic.d.ts","import":"./dist/providers/anthropic.js"},"./google-vertex":{"types":"./dist/providers/google-vertex.d.ts","import":"./dist/providers/google-vertex.js"},"./bedrock-provider":{"types":"./dist/bedrock-provider.d.ts","import":"./dist/bedrock-provider.js"},"./openai-responses":{"types":"./dist/providers/openai-responses.d.ts","import":"./dist/providers/openai-responses.js"},"./openai-completions":{"types":"./dist/providers/openai-completions.d.ts","import":"./dist/providers/openai-completions.js"},"./azure-openai-responses":{"types":"./dist/providers/azure-openai-responses.d.ts","import":"./dist/providers/azure-openai-responses.js"},"./openai-codex-responses":{"types":"./dist/providers/openai-codex-responses.d.ts","import":"./dist/providers/openai-codex-responses.js"}},"gitHead":"31bfb2f16f7a1dd707876e970f0f80caa61f8435","scripts":{"test":"vitest --run","build":"npm run generate-models && npm run generate-image-models && tsgo -p tsconfig.build.json","clean":"shx rm -rf dist","prepublishOnly":"npm run clean && npm run build","generate-models":"node scripts/generate-models.ts","generate-image-models":"node scripts/generate-image-models.ts"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:975b2765-9d44-42ba-a322-c1cbbce03f36"}},"repository":{"url":"git+https://github.com/earendil-works/pi.git","type":"git","directory":"packages/ai"},"_npmVersion":"11.16.0","description":"Unified LLM API with automatic model discovery and provider configuration","directories":{},"_nodeVersion":"22.22.3","dependencies":{"openai":"6.26.0","typebox":"1.1.38","partial-json":"0.1.7","@google/genai":"1.52.0","http-proxy-agent":"7.0.2","@anthropic-ai/sdk":"0.91.1","https-proxy-agent":"7.0.6","@mistralai/mistralai":"2.2.1","@smithy/node-http-handler":"4.7.3","@aws-sdk/client-bedrock-runtime":"3.1048.0"},"_hasShrinkwrap":false,"devDependencies":{"canvas":"3.2.3","vitest":"3.2.4","@types/node":"24.12.4"},"_npmOperationalInternal":{"tmp":"tmp/pi-ai_0.79.6_1781647398892_0.9274129029148666","host":"s3://npm-registry-packages-npm-production"}},"0.79.7":{"name":"@earendil-works/pi-ai","version":"0.79.7","keywords":["ai","llm","openai","anthropic","gemini","bedrock","unified","api"],"author":{"name":"Mario Zechner"},"license":"MIT","_id":"@earendil-works/pi-ai@0.79.7","maintainers":[{"name":"mitsuhiko","email":"armin.ronacher@active-4.com"},{"name":"badlogic","email":"mario@badlogicgames.com"},{"name":"rwachtler","email":"r.wachtler@outlook.com"}],"homepage":"https://github.com/earendil-works/pi#readme","bugs":{"url":"https://github.com/earendil-works/pi/issues"},"bin":{"pi-ai":"dist/cli.js"},"dist":{"shasum":"0b4529a8c6fe61e17677912cf30beea3f3199b4e","tarball":"https://registry.npmjs.org/@earendil-works/pi-ai/-/pi-ai-0.79.7.tgz","fileCount":222,"integrity":"sha512-KTe2euBoBEmFb0W+KR05Im8Qq4coU+eo46++UgNAfT3L8OIBv3QU+/pif9EqaFQ1QUmirv8kgy4TQltvrCu7iQ==","signatures":[{"sig":"MEYCIQCDluVbprS731aIWNpZmsMdiExaHImd/yQSzy1vru4DwgIhAJCUXZ44fxcYxeZrp/ZHetvAAJ/Zh0ZScZBgl9Vctpjz","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@earendil-works%2fpi-ai@0.79.7","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":4689917},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=22.19.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./oauth":{"types":"./dist/oauth.d.ts","import":"./dist/oauth.js"},"./google":{"types":"./dist/providers/google.d.ts","import":"./dist/providers/google.js"},"./mistral":{"types":"./dist/providers/mistral.d.ts","import":"./dist/providers/mistral.js"},"./anthropic":{"types":"./dist/providers/anthropic.d.ts","import":"./dist/providers/anthropic.js"},"./google-vertex":{"types":"./dist/providers/google-vertex.d.ts","import":"./dist/providers/google-vertex.js"},"./bedrock-provider":{"types":"./dist/bedrock-provider.d.ts","import":"./dist/bedrock-provider.js"},"./openai-responses":{"types":"./dist/providers/openai-responses.d.ts","import":"./dist/providers/openai-responses.js"},"./openai-completions":{"types":"./dist/providers/openai-completions.d.ts","import":"./dist/providers/openai-completions.js"},"./azure-openai-responses":{"types":"./dist/providers/azure-openai-responses.d.ts","import":"./dist/providers/azure-openai-responses.js"},"./openai-codex-responses":{"types":"./dist/providers/openai-codex-responses.d.ts","import":"./dist/providers/openai-codex-responses.js"}},"gitHead":"c4ab61dcbf719e75018f0ae90eb900b78a881603","scripts":{"test":"vitest --run","build":"npm run generate-models && npm run generate-image-models && tsgo -p tsconfig.build.json","clean":"shx rm -rf dist","prepublishOnly":"npm run clean && npm run build","generate-models":"node scripts/generate-models.ts","generate-image-models":"node scripts/generate-image-models.ts"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:975b2765-9d44-42ba-a322-c1cbbce03f36"}},"repository":{"url":"git+https://github.com/earendil-works/pi.git","type":"git","directory":"packages/ai"},"_npmVersion":"11.16.0","description":"Unified LLM API with automatic model discovery and provider configuration","directories":{},"_nodeVersion":"22.22.3","dependencies":{"openai":"6.26.0","typebox":"1.1.38","partial-json":"0.1.7","@google/genai":"1.52.0","http-proxy-agent":"7.0.2","@anthropic-ai/sdk":"0.91.1","https-proxy-agent":"7.0.6","@mistralai/mistralai":"2.2.1","@smithy/node-http-handler":"4.7.3","@aws-sdk/client-bedrock-runtime":"3.1048.0"},"_hasShrinkwrap":false,"devDependencies":{"canvas":"3.2.3","vitest":"3.2.4","@types/node":"24.12.4"},"_npmOperationalInternal":{"tmp":"tmp/pi-ai_0.79.7_1781800302444_0.1751770023099779","host":"s3://npm-registry-packages-npm-production"}},"0.79.8":{"name":"@earendil-works/pi-ai","version":"0.79.8","keywords":["ai","llm","openai","anthropic","gemini","bedrock","unified","api"],"author":{"name":"Mario Zechner"},"license":"MIT","_id":"@earendil-works/pi-ai@0.79.8","maintainers":[{"name":"mitsuhiko","email":"armin.ronacher@active-4.com"},{"name":"badlogic","email":"mario@badlogicgames.com"},{"name":"rwachtler","email":"r.wachtler@outlook.com"}],"homepage":"https://github.com/earendil-works/pi#readme","bugs":{"url":"https://github.com/earendil-works/pi/issues"},"bin":{"pi-ai":"dist/cli.js"},"dist":{"shasum":"06da2d45367dcac0dc4d638059ebf5add1d01250","tarball":"https://registry.npmjs.org/@earendil-works/pi-ai/-/pi-ai-0.79.8.tgz","fileCount":222,"integrity":"sha512-ZpSwaD7oNpsjn9vtEatZQNT9PSdDJXi6rFeY5Qv+OHQGFDKlmcrfJE4ypm4SAc/fBECPs4Rdi3l+YjVtXYrkKw==","signatures":[{"sig":"MEUCIFZZC3egwt+cpSG1CXXhuLqelF4+xtAP+PXyO6X0ZtW4AiEA2EYd9PHz6GcDYlX/TQ+pyggXuSqCH7w6OZCl+Pv7PZY=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@earendil-works%2fpi-ai@0.79.8","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":4691177},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=22.19.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./base":{"types":"./dist/base.d.ts","import":"./dist/base.js"},"./oauth":{"types":"./dist/oauth.d.ts","import":"./dist/oauth.js"},"./google":{"types":"./dist/providers/google.d.ts","import":"./dist/providers/google.js"},"./mistral":{"types":"./dist/providers/mistral.d.ts","import":"./dist/providers/mistral.js"},"./anthropic":{"types":"./dist/providers/anthropic.d.ts","import":"./dist/providers/anthropic.js"},"./google-vertex":{"types":"./dist/providers/google-vertex.d.ts","import":"./dist/providers/google-vertex.js"},"./amazon-bedrock":{"types":"./dist/providers/amazon-bedrock.d.ts","import":"./dist/providers/amazon-bedrock.js"},"./bedrock-provider":{"types":"./dist/bedrock-provider.d.ts","import":"./dist/bedrock-provider.js"},"./openai-responses":{"types":"./dist/providers/openai-responses.d.ts","import":"./dist/providers/openai-responses.js"},"./openrouter-images":{"types":"./dist/providers/images/openrouter.d.ts","import":"./dist/providers/images/openrouter.js"},"./openai-completions":{"types":"./dist/providers/openai-completions.d.ts","import":"./dist/providers/openai-completions.js"},"./azure-openai-responses":{"types":"./dist/providers/azure-openai-responses.d.ts","import":"./dist/providers/azure-openai-responses.js"},"./openai-codex-responses":{"types":"./dist/providers/openai-codex-responses.d.ts","import":"./dist/providers/openai-codex-responses.js"}},"gitHead":"8eb9704b3e75391dcc4f584b7fc1a03c9e04e383","scripts":{"test":"vitest --run","build":"npm run generate-models && npm run generate-image-models && tsgo -p tsconfig.build.json","clean":"shx rm -rf dist","prepublishOnly":"npm run clean && npm run build","generate-models":"node scripts/generate-models.ts","generate-image-models":"node scripts/generate-image-models.ts"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:975b2765-9d44-42ba-a322-c1cbbce03f36"}},"repository":{"url":"git+https://github.com/earendil-works/pi.git","type":"git","directory":"packages/ai"},"_npmVersion":"11.16.0","description":"Unified LLM API with automatic model discovery and provider configuration","directories":{},"_nodeVersion":"22.22.3","dependencies":{"openai":"6.26.0","typebox":"1.1.38","partial-json":"0.1.7","@google/genai":"1.52.0","http-proxy-agent":"7.0.2","@anthropic-ai/sdk":"0.91.1","https-proxy-agent":"7.0.6","@opentelemetry/api":"1.9.0","@mistralai/mistralai":"2.2.6","@smithy/node-http-handler":"4.7.3","@aws-sdk/client-bedrock-runtime":"3.1048.0"},"_hasShrinkwrap":false,"devDependencies":{"canvas":"3.2.3","vitest":"4.1.9","@types/node":"24.12.4"},"_npmOperationalInternal":{"tmp":"tmp/pi-ai_0.79.8_1781855857218_0.795024474392551","host":"s3://npm-registry-packages-npm-production"}},"0.79.9":{"name":"@earendil-works/pi-ai","version":"0.79.9","keywords":["ai","llm","openai","anthropic","gemini","bedrock","unified","api"],"author":{"name":"Mario Zechner"},"license":"MIT","_id":"@earendil-works/pi-ai@0.79.9","maintainers":[{"name":"mitsuhiko","email":"armin.ronacher@active-4.com"},{"name":"badlogic","email":"mario@badlogicgames.com"},{"name":"rwachtler","email":"r.wachtler@outlook.com"}],"homepage":"https://github.com/earendil-works/pi#readme","bugs":{"url":"https://github.com/earendil-works/pi/issues"},"bin":{"pi-ai":"dist/cli.js"},"dist":{"shasum":"cbe7fa825e4674db949bb5dd035cccdb7dd26914","tarball":"https://registry.npmjs.org/@earendil-works/pi-ai/-/pi-ai-0.79.9.tgz","fileCount":222,"integrity":"sha512-fHmgNMONwCCE7bQAKbcz76sgm3iQuA7km1mpIc4H5xXd9+zhPh/faULz6ARkgjQE0EufHnfZPJY39+lNf8Sa9g==","signatures":[{"sig":"MEUCIQC8xDO2lZIsTwDXBx0YnFkhrmAj6B9TaUqkyMM+kL8bWwIgJbqkcKLMmmXjs0H0kLG5W+7PIm8c+/IE7acjDDNFrEM=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@earendil-works%2fpi-ai@0.79.9","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":4704026},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=22.19.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./base":{"types":"./dist/base.d.ts","import":"./dist/base.js"},"./oauth":{"types":"./dist/oauth.d.ts","import":"./dist/oauth.js"},"./google":{"types":"./dist/providers/google.d.ts","import":"./dist/providers/google.js"},"./mistral":{"types":"./dist/providers/mistral.d.ts","import":"./dist/providers/mistral.js"},"./anthropic":{"types":"./dist/providers/anthropic.d.ts","import":"./dist/providers/anthropic.js"},"./google-vertex":{"types":"./dist/providers/google-vertex.d.ts","import":"./dist/providers/google-vertex.js"},"./amazon-bedrock":{"types":"./dist/providers/amazon-bedrock.d.ts","import":"./dist/providers/amazon-bedrock.js"},"./bedrock-provider":{"types":"./dist/bedrock-provider.d.ts","import":"./dist/bedrock-provider.js"},"./openai-responses":{"types":"./dist/providers/openai-responses.d.ts","import":"./dist/providers/openai-responses.js"},"./openrouter-images":{"types":"./dist/providers/images/openrouter.d.ts","import":"./dist/providers/images/openrouter.js"},"./openai-completions":{"types":"./dist/providers/openai-completions.d.ts","import":"./dist/providers/openai-completions.js"},"./azure-openai-responses":{"types":"./dist/providers/azure-openai-responses.d.ts","import":"./dist/providers/azure-openai-responses.js"},"./openai-codex-responses":{"types":"./dist/providers/openai-codex-responses.d.ts","import":"./dist/providers/openai-codex-responses.js"}},"gitHead":"615bf2f87444c0f48756d487323519349304906c","scripts":{"test":"vitest --run","build":"npm run generate-models && npm run generate-image-models && tsgo -p tsconfig.build.json","clean":"shx rm -rf dist","prepublishOnly":"npm run clean && npm run build","generate-models":"node scripts/generate-models.ts","generate-image-models":"node scripts/generate-image-models.ts"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:975b2765-9d44-42ba-a322-c1cbbce03f36"}},"repository":{"url":"git+https://github.com/earendil-works/pi.git","type":"git","directory":"packages/ai"},"_npmVersion":"11.16.0","description":"Unified LLM API with automatic model discovery and provider configuration","directories":{},"_nodeVersion":"22.22.3","dependencies":{"openai":"6.26.0","typebox":"1.1.38","partial-json":"0.1.7","@google/genai":"1.52.0","http-proxy-agent":"7.0.2","@anthropic-ai/sdk":"0.91.1","https-proxy-agent":"7.0.6","@opentelemetry/api":"1.9.0","@mistralai/mistralai":"2.2.6","@smithy/node-http-handler":"4.7.3","@aws-sdk/client-bedrock-runtime":"3.1048.0"},"_hasShrinkwrap":false,"devDependencies":{"canvas":"3.2.3","vitest":"4.1.9","@types/node":"24.12.4"},"_npmOperationalInternal":{"tmp":"tmp/pi-ai_0.79.9_1781986783008_0.4806789094122499","host":"s3://npm-registry-packages-npm-production"}},"0.79.10":{"name":"@earendil-works/pi-ai","version":"0.79.10","keywords":["ai","llm","openai","anthropic","gemini","bedrock","unified","api"],"author":{"name":"Mario Zechner"},"license":"MIT","_id":"@earendil-works/pi-ai@0.79.10","maintainers":[{"name":"mitsuhiko","email":"armin.ronacher@active-4.com"},{"name":"badlogic","email":"mario@badlogicgames.com"},{"name":"rwachtler","email":"r.wachtler@outlook.com"}],"homepage":"https://github.com/earendil-works/pi#readme","bugs":{"url":"https://github.com/earendil-works/pi/issues"},"bin":{"pi-ai":"dist/cli.js"},"dist":{"shasum":"e3f3ccfa00009b273339f2b116db9b7703cc6767","tarball":"https://registry.npmjs.org/@earendil-works/pi-ai/-/pi-ai-0.79.10.tgz","fileCount":222,"integrity":"sha512-9jR23tOl0BIUdQMn70Gr72xYBpM7Xgl9Lyv7gAnU1USfkNRuYG/f/edLl+n/Dp/RafDW3JI4DF7y/GhgkORuew==","signatures":[{"sig":"MEUCIGQBHds8B4ZTURgyRQEXk1z+r4TgBoITAlJ9pj0SWf2xAiEAzsTYReZDfx8LS1HxIhs614no6AGKgsEF4m4XUvw/AOA=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@earendil-works%2fpi-ai@0.79.10","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":4708128},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=22.19.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./base":{"types":"./dist/base.d.ts","import":"./dist/base.js"},"./oauth":{"types":"./dist/oauth.d.ts","import":"./dist/oauth.js"},"./google":{"types":"./dist/providers/google.d.ts","import":"./dist/providers/google.js"},"./mistral":{"types":"./dist/providers/mistral.d.ts","import":"./dist/providers/mistral.js"},"./anthropic":{"types":"./dist/providers/anthropic.d.ts","import":"./dist/providers/anthropic.js"},"./google-vertex":{"types":"./dist/providers/google-vertex.d.ts","import":"./dist/providers/google-vertex.js"},"./amazon-bedrock":{"types":"./dist/providers/amazon-bedrock.d.ts","import":"./dist/providers/amazon-bedrock.js"},"./bedrock-provider":{"types":"./dist/bedrock-provider.d.ts","import":"./dist/bedrock-provider.js"},"./openai-responses":{"types":"./dist/providers/openai-responses.d.ts","import":"./dist/providers/openai-responses.js"},"./openrouter-images":{"types":"./dist/providers/images/openrouter.d.ts","import":"./dist/providers/images/openrouter.js"},"./openai-completions":{"types":"./dist/providers/openai-completions.d.ts","import":"./dist/providers/openai-completions.js"},"./azure-openai-responses":{"types":"./dist/providers/azure-openai-responses.d.ts","import":"./dist/providers/azure-openai-responses.js"},"./openai-codex-responses":{"types":"./dist/providers/openai-codex-responses.d.ts","import":"./dist/providers/openai-codex-responses.js"}},"gitHead":"8e1900666f3cb83c281297d8f787fae6ee2bd0e6","scripts":{"test":"vitest --run","build":"npm run generate-models && npm run generate-image-models && tsgo -p tsconfig.build.json","clean":"shx rm -rf dist","prepublishOnly":"npm run clean && npm run build","generate-models":"node scripts/generate-models.ts","generate-image-models":"node scripts/generate-image-models.ts"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:975b2765-9d44-42ba-a322-c1cbbce03f36"}},"repository":{"url":"git+https://github.com/earendil-works/pi.git","type":"git","directory":"packages/ai"},"_npmVersion":"11.16.0","description":"Unified LLM API with automatic model discovery and provider configuration","directories":{},"_nodeVersion":"22.22.3","dependencies":{"openai":"6.26.0","typebox":"1.1.38","partial-json":"0.1.7","@google/genai":"1.52.0","http-proxy-agent":"7.0.2","@anthropic-ai/sdk":"0.91.1","https-proxy-agent":"7.0.6","@opentelemetry/api":"1.9.0","@mistralai/mistralai":"2.2.6","@smithy/node-http-handler":"4.7.3","@aws-sdk/client-bedrock-runtime":"3.1048.0"},"_hasShrinkwrap":false,"devDependencies":{"canvas":"3.2.3","vitest":"4.1.9","@types/node":"24.12.4"},"_npmOperationalInternal":{"tmp":"tmp/pi-ai_0.79.10_1782119926081_0.00012654102592413174","host":"s3://npm-registry-packages-npm-production"}},"0.80.1":{"name":"@earendil-works/pi-ai","version":"0.80.1","keywords":["ai","llm","openai","anthropic","gemini","bedrock","unified","api"],"author":{"name":"Mario Zechner"},"license":"MIT","_id":"@earendil-works/pi-ai@0.80.1","maintainers":[{"name":"mitsuhiko","email":"armin.ronacher@active-4.com"},{"name":"badlogic","email":"mario@badlogicgames.com"},{"name":"rwachtler","email":"r.wachtler@outlook.com"}],"homepage":"https://github.com/earendil-works/pi#readme","bugs":{"url":"https://github.com/earendil-works/pi/issues"},"bin":{"pi-ai":"dist/cli.js"},"dist":{"shasum":"befbfe15c8d1c6602bbc5fbb4d7f4f08aa394af9","tarball":"https://registry.npmjs.org/@earendil-works/pi-ai/-/pi-ai-0.80.1.tgz","fileCount":578,"integrity":"sha512-qsHmuoBRu7a6rkOis/Elwl8jEhA9T884H/mXMP3tbz1slEBI+dHaY3zJ0nlEqUl+jcTz1FJNdgOVLG4sQHOPXQ==","signatures":[{"sig":"MEQCIDMWXDuumJkUy9tnNdyWjVWVFIeQfG3lUEi1ty7psI8gAiAgk0d72+i8aSiQ9FDLan2IoU62G10WE1svWFa9O/nGAw==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@earendil-works%2fpi-ai@0.80.1","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":5709400},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=22.19.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./api/*":{"types":"./dist/api/*.d.ts","import":"./dist/api/*.js"},"./oauth":{"types":"./dist/oauth.d.ts","import":"./dist/oauth.js"},"./compat":{"types":"./dist/compat.d.ts","import":"./dist/compat.js"},"./providers/*":{"types":"./dist/providers/*.d.ts","import":"./dist/providers/*.js"},"./bedrock-provider":{"types":"./dist/bedrock-provider.d.ts","import":"./dist/bedrock-provider.js"}},"gitHead":"1c4a9ba7c80c2b0d7f3ab57d38ed4ba1f671cb90","scripts":{"test":"vitest --run","build":"npm run generate-models && npm run generate-image-models && tsgo -p tsconfig.build.json","clean":"shx rm -rf dist","prepublishOnly":"npm run clean && npm run build","generate-models":"node scripts/generate-models.ts","generate-image-models":"node scripts/generate-image-models.ts"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:975b2765-9d44-42ba-a322-c1cbbce03f36"}},"repository":{"url":"git+https://github.com/earendil-works/pi.git","type":"git","directory":"packages/ai"},"_npmVersion":"11.16.0","description":"Unified LLM API with automatic model discovery and provider configuration","directories":{},"sideEffects":["./dist/compat.js","./dist/images.js","./dist/providers/images/register-builtins.js"],"_nodeVersion":"22.22.3","dependencies":{"openai":"6.26.0","typebox":"1.1.38","partial-json":"0.1.7","@google/genai":"1.52.0","http-proxy-agent":"7.0.2","@anthropic-ai/sdk":"0.91.1","https-proxy-agent":"7.0.6","@opentelemetry/api":"1.9.0","@mistralai/mistralai":"2.2.6","@smithy/node-http-handler":"4.7.3","@aws-sdk/client-bedrock-runtime":"3.1048.0"},"_hasShrinkwrap":false,"devDependencies":{"canvas":"3.2.3","vitest":"4.1.9","@types/node":"24.12.4"},"_npmOperationalInternal":{"tmp":"tmp/pi-ai_0.80.1_1782238113796_0.1782084148682963","host":"s3://npm-registry-packages-npm-production"}},"0.80.2":{"name":"@earendil-works/pi-ai","version":"0.80.2","keywords":["ai","llm","openai","anthropic","gemini","bedrock","unified","api"],"author":{"name":"Mario Zechner"},"license":"MIT","_id":"@earendil-works/pi-ai@0.80.2","maintainers":[{"name":"mitsuhiko","email":"armin.ronacher@active-4.com"},{"name":"badlogic","email":"mario@badlogicgames.com"},{"name":"rwachtler","email":"r.wachtler@outlook.com"}],"homepage":"https://github.com/earendil-works/pi#readme","bugs":{"url":"https://github.com/earendil-works/pi/issues"},"bin":{"pi-ai":"dist/cli.js"},"dist":{"shasum":"c2892241cdcbae7a34fccabf4639f746db470ada","tarball":"https://registry.npmjs.org/@earendil-works/pi-ai/-/pi-ai-0.80.2.tgz","fileCount":582,"integrity":"sha512-5GNKfdrRJ4uZ5Zd9iudoXggi/BbUcKnD/xfRHtdR+7q4vWqPvfx8auFuaT+ewGBVI8K4wj87eigFQ/iCSuy9RQ==","signatures":[{"sig":"MEUCIQC2h0+WZhYoiCviKs2zjEKRShGJZa5mDGtQrZ0OHp6rAwIgBavw8LQmk/rEcSQz40kA6di6sZCxU5O/cSO1Jn5r/JE=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@earendil-works%2fpi-ai@0.80.2","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":5748068},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=22.19.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./api/*":{"types":"./dist/api/*.d.ts","import":"./dist/api/*.js"},"./oauth":{"types":"./dist/oauth.d.ts","import":"./dist/oauth.js"},"./compat":{"types":"./dist/compat.d.ts","import":"./dist/compat.js"},"./providers/*":{"types":"./dist/providers/*.d.ts","import":"./dist/providers/*.js"},"./bedrock-provider":{"types":"./dist/bedrock-provider.d.ts","import":"./dist/bedrock-provider.js"}},"gitHead":"ec6311beb5b24fc918e5031173608447582d7262","scripts":{"test":"vitest --run","build":"npm run generate-models && npm run generate-image-models && tsgo -p tsconfig.build.json","clean":"shx rm -rf dist","prepublishOnly":"npm run clean && npm run build","generate-models":"node scripts/generate-models.ts","generate-image-models":"node scripts/generate-image-models.ts"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:975b2765-9d44-42ba-a322-c1cbbce03f36"}},"repository":{"url":"git+https://github.com/earendil-works/pi.git","type":"git","directory":"packages/ai"},"_npmVersion":"11.16.0","description":"Unified LLM API with automatic model discovery and provider configuration","directories":{},"sideEffects":["./dist/compat.js","./dist/images.js","./dist/providers/images/register-builtins.js"],"_nodeVersion":"22.22.3","dependencies":{"openai":"6.26.0","typebox":"1.1.38","partial-json":"0.1.7","@google/genai":"1.52.0","http-proxy-agent":"7.0.2","@anthropic-ai/sdk":"0.91.1","https-proxy-agent":"7.0.6","@opentelemetry/api":"1.9.0","@mistralai/mistralai":"2.2.6","@smithy/node-http-handler":"4.7.3","@aws-sdk/client-bedrock-runtime":"3.1048.0"},"_hasShrinkwrap":false,"devDependencies":{"canvas":"3.2.3","vitest":"4.1.9","@types/node":"24.12.4"},"_npmOperationalInternal":{"tmp":"tmp/pi-ai_0.80.2_1782252209669_0.8213411334563034","host":"s3://npm-registry-packages-npm-production"}},"0.80.3":{"name":"@earendil-works/pi-ai","version":"0.80.3","keywords":["ai","llm","openai","anthropic","gemini","bedrock","unified","api"],"author":{"name":"Mario Zechner"},"license":"MIT","_id":"@earendil-works/pi-ai@0.80.3","maintainers":[{"name":"mitsuhiko","email":"armin.ronacher@active-4.com"},{"name":"badlogic","email":"mario@badlogicgames.com"},{"name":"rwachtler","email":"r.wachtler@outlook.com"}],"homepage":"https://github.com/earendil-works/pi#readme","bugs":{"url":"https://github.com/earendil-works/pi/issues"},"bin":{"pi-ai":"dist/cli.js"},"dist":{"shasum":"bdc2ea9dd336722deb5f6cc32a7d42c931233ddf","tarball":"https://registry.npmjs.org/@earendil-works/pi-ai/-/pi-ai-0.80.3.tgz","fileCount":594,"integrity":"sha512-jPZLMeGL5kkMSEAwAklfXTMHqZvfhsJtCCpKGIr5Duk7mc0n4skjB1dugk7y0z3z8ZHIUCmPAWHdyDqgUz5vdA==","signatures":[{"sig":"MEUCIQCBuLbF+W//JtD0gnkvQ5lxjQP+3TTNk8hUxhKL4sOfjAIgTkedcajRw5VYHYpQyB7UVAB4DIQzDRM6AOyId8lwI2g=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@earendil-works%2fpi-ai@0.80.3","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":5895313},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=22.19.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./api/*":{"types":"./dist/api/*.d.ts","import":"./dist/api/*.js"},"./oauth":{"types":"./dist/oauth.d.ts","import":"./dist/oauth.js"},"./compat":{"types":"./dist/compat.d.ts","import":"./dist/compat.js"},"./providers/*":{"types":"./dist/providers/*.d.ts","import":"./dist/providers/*.js"},"./bedrock-provider":{"types":"./dist/bedrock-provider.d.ts","import":"./dist/bedrock-provider.js"}},"gitHead":"a23abe4a695df8b69b613f73e9fdda2a8af894d4","scripts":{"test":"vitest --run","build":"npm run generate-models && npm run generate-image-models && tsgo -p tsconfig.build.json","clean":"shx rm -rf dist","prepublishOnly":"npm run clean && npm run build","generate-models":"node scripts/generate-models.ts","generate-image-models":"node scripts/generate-image-models.ts"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:975b2765-9d44-42ba-a322-c1cbbce03f36"}},"repository":{"url":"git+https://github.com/earendil-works/pi.git","type":"git","directory":"packages/ai"},"_npmVersion":"11.16.0","description":"Unified LLM API with automatic model discovery and provider configuration","directories":{},"sideEffects":["./dist/compat.js","./dist/images.js","./dist/providers/images/register-builtins.js"],"_nodeVersion":"22.23.0","dependencies":{"openai":"6.26.0","typebox":"1.1.38","partial-json":"0.1.7","@google/genai":"1.52.0","http-proxy-agent":"7.0.2","@anthropic-ai/sdk":"0.91.1","https-proxy-agent":"7.0.6","@opentelemetry/api":"1.9.0","@mistralai/mistralai":"2.2.6","@smithy/node-http-handler":"4.7.3","@aws-sdk/client-bedrock-runtime":"3.1048.0"},"_hasShrinkwrap":false,"devDependencies":{"canvas":"3.2.3","vitest":"4.1.9","@types/node":"24.12.4"},"_npmOperationalInternal":{"tmp":"tmp/pi-ai_0.80.3_1782851650568_0.557539248052211","host":"s3://npm-registry-packages-npm-production"}},"0.80.5":{"name":"@earendil-works/pi-ai","version":"0.80.5","keywords":["ai","llm","openai","anthropic","gemini","bedrock","unified","api"],"author":{"name":"Mario Zechner"},"license":"MIT","_id":"@earendil-works/pi-ai@0.80.5","maintainers":[{"name":"mitsuhiko","email":"armin.ronacher@active-4.com"},{"name":"badlogic","email":"mario@badlogicgames.com"},{"name":"rwachtler","email":"r.wachtler@outlook.com"}],"homepage":"https://github.com/earendil-works/pi#readme","bugs":{"url":"https://github.com/earendil-works/pi/issues"},"bin":{"pi-ai":"dist/cli.js"},"dist":{"shasum":"a53735c45f070ea72c487a6d0b10590f4127b97d","tarball":"https://registry.npmjs.org/@earendil-works/pi-ai/-/pi-ai-0.80.5.tgz","fileCount":594,"integrity":"sha512-+7UODYKu4o/X8sxTHG8HEV3+O+dOYKg5MeO3MJIFQ+wu65pIWDhjZGc759uWsRr79AhV7MSJEe4GWnFn4l68gw==","signatures":[{"sig":"MEQCIEYM2iriYmTHxs8U0vHyzGnag97qoaezuzggaRzUnoOqAiBkW91UpdQEpV1w7FXMINJAWdIOhrfr+zbTYeHWf148SQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@earendil-works%2fpi-ai@0.80.5","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":6012643},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=22.19.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./api/*":{"types":"./dist/api/*.d.ts","import":"./dist/api/*.js"},"./oauth":{"types":"./dist/oauth.d.ts","import":"./dist/oauth.js"},"./compat":{"types":"./dist/compat.d.ts","import":"./dist/compat.js"},"./providers/*":{"types":"./dist/providers/*.d.ts","import":"./dist/providers/*.js"},"./bedrock-provider":{"types":"./dist/bedrock-provider.d.ts","import":"./dist/bedrock-provider.js"}},"gitHead":"cc62baa442b5c0333923fdfdcc1d7264f445b5b0","scripts":{"test":"vitest --run","build":"npm run generate-models && npm run generate-image-models && tsgo -p tsconfig.build.json","clean":"shx rm -rf dist","prepublishOnly":"npm run clean && npm run build","generate-models":"node scripts/generate-models.ts","generate-image-models":"node scripts/generate-image-models.ts"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:975b2765-9d44-42ba-a322-c1cbbce03f36"}},"repository":{"url":"git+https://github.com/earendil-works/pi.git","type":"git","directory":"packages/ai"},"_npmVersion":"11.16.0","description":"Unified LLM API with automatic model discovery and provider configuration","directories":{},"sideEffects":["./dist/compat.js","./dist/images.js","./dist/providers/images/register-builtins.js"],"_nodeVersion":"22.23.1","dependencies":{"openai":"6.26.0","typebox":"1.1.38","partial-json":"0.1.7","@google/genai":"1.52.0","http-proxy-agent":"7.0.2","@anthropic-ai/sdk":"0.91.1","https-proxy-agent":"7.0.6","@opentelemetry/api":"1.9.0","@mistralai/mistralai":"2.2.6","@smithy/node-http-handler":"4.7.3","@aws-sdk/client-bedrock-runtime":"3.1048.0"},"_hasShrinkwrap":false,"devDependencies":{"canvas":"3.2.3","vitest":"4.1.9","@types/node":"24.12.4"},"_npmOperationalInternal":{"tmp":"tmp/pi-ai_0.80.5_1783624123293_0.7008989676715074","host":"s3://npm-registry-packages-npm-production"}},"0.80.6":{"name":"@earendil-works/pi-ai","version":"0.80.6","keywords":["ai","llm","openai","anthropic","gemini","bedrock","unified","api"],"author":{"name":"Mario Zechner"},"license":"MIT","_id":"@earendil-works/pi-ai@0.80.6","maintainers":[{"name":"mitsuhiko","email":"armin.ronacher@active-4.com"},{"name":"badlogic","email":"mario@badlogicgames.com"},{"name":"rwachtler","email":"r.wachtler@outlook.com"}],"homepage":"https://github.com/earendil-works/pi#readme","bugs":{"url":"https://github.com/earendil-works/pi/issues"},"bin":{"pi-ai":"dist/cli.js"},"dist":{"shasum":"5a3a4e4e39cc62ce3d7fe8291fdb11ff16efd0e7","tarball":"https://registry.npmjs.org/@earendil-works/pi-ai/-/pi-ai-0.80.6.tgz","fileCount":594,"integrity":"sha512-7xfLk8sANBp+bpPEbjoOZTbPxsa+++b1JXAoSJsNa3vbs9AHHEclmvg54XLQcxH+fuwaeti/g2jeIfJ+mVYLpA==","signatures":[{"sig":"MEYCIQDj3xUcJ1L8WFLkpjP2JUZatv0GGMCwpZI3VYp/dqkdwgIhAPTtuFAqNefJFH7OPo9oDtBHaFJ6WF1odnnrNUdaqL6l","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@earendil-works%2fpi-ai@0.80.6","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":6040038},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=22.19.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./api/*":{"types":"./dist/api/*.d.ts","import":"./dist/api/*.js"},"./oauth":{"types":"./dist/oauth.d.ts","import":"./dist/oauth.js"},"./compat":{"types":"./dist/compat.d.ts","import":"./dist/compat.js"},"./providers/*":{"types":"./dist/providers/*.d.ts","import":"./dist/providers/*.js"},"./bedrock-provider":{"types":"./dist/bedrock-provider.d.ts","import":"./dist/bedrock-provider.js"}},"gitHead":"2b3fda9921b5590f285165287bd442a25817f17b","scripts":{"test":"vitest --run","build":"npm run generate-models && npm run generate-image-models && tsgo -p tsconfig.build.json","clean":"shx rm -rf dist","prepublishOnly":"npm run clean && npm run build","generate-models":"node scripts/generate-models.ts","generate-image-models":"node scripts/generate-image-models.ts"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:975b2765-9d44-42ba-a322-c1cbbce03f36"}},"repository":{"url":"git+https://github.com/earendil-works/pi.git","type":"git","directory":"packages/ai"},"_npmVersion":"11.16.0","description":"Unified LLM API with automatic model discovery and provider configuration","directories":{},"sideEffects":["./dist/compat.js","./dist/images.js","./dist/providers/images/register-builtins.js"],"_nodeVersion":"22.23.1","dependencies":{"openai":"6.26.0","typebox":"1.1.38","partial-json":"0.1.7","@google/genai":"1.52.0","http-proxy-agent":"7.0.2","@anthropic-ai/sdk":"0.91.1","https-proxy-agent":"7.0.6","@opentelemetry/api":"1.9.0","@mistralai/mistralai":"2.2.6","@smithy/node-http-handler":"4.7.3","@aws-sdk/client-bedrock-runtime":"3.1048.0"},"_hasShrinkwrap":false,"devDependencies":{"canvas":"3.2.3","vitest":"4.1.9","@types/node":"24.12.4"},"_npmOperationalInternal":{"tmp":"tmp/pi-ai_0.80.6_1783639304437_0.924792504608964","host":"s3://npm-registry-packages-npm-production"}},"0.80.7":{"name":"@earendil-works/pi-ai","version":"0.80.7","description":"Unified LLM API with automatic model discovery and provider configuration","type":"module","main":"./dist/index.js","types":"./dist/index.d.ts","sideEffects":["./dist/compat.js","./dist/images.js","./dist/providers/images/register-builtins.js"],"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./compat":{"types":"./dist/compat.d.ts","import":"./dist/compat.js"},"./providers/*":{"types":"./dist/providers/*.d.ts","import":"./dist/providers/*.js"},"./api/*":{"types":"./dist/api/*.d.ts","import":"./dist/api/*.js"},"./oauth":{"types":"./dist/oauth.d.ts","import":"./dist/oauth.js"},"./bedrock-provider":{"types":"./dist/bedrock-provider.d.ts","import":"./dist/bedrock-provider.js"}},"bin":{"pi-ai":"dist/cli.js"},"scripts":{"clean":"shx rm -rf dist","generate-models":"node scripts/generate-models.ts","generate-image-models":"node scripts/generate-image-models.ts","build":"npm run generate-models && npm run generate-image-models && tsgo -p tsconfig.build.json","test":"vitest --run","prepublishOnly":"npm run clean && npm run build"},"dependencies":{"@anthropic-ai/sdk":"0.91.1","@aws-sdk/client-bedrock-runtime":"3.1048.0","@google/genai":"1.52.0","@mistralai/mistralai":"2.2.6","@opentelemetry/api":"1.9.0","@smithy/node-http-handler":"4.7.3","http-proxy-agent":"7.0.2","https-proxy-agent":"7.0.6","openai":"6.26.0","partial-json":"0.1.7","typebox":"1.1.38"},"keywords":["ai","llm","openai","anthropic","gemini","bedrock","unified","api"],"author":{"name":"Mario Zechner"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/earendil-works/pi.git","directory":"packages/ai"},"engines":{"node":">=22.19.0"},"devDependencies":{"@types/node":"24.12.4","canvas":"3.2.3","vitest":"4.1.9"},"gitHead":"818d67457cdd6b60bce6b121d16b23141c252dd8","_id":"@earendil-works/pi-ai@0.80.7","bugs":{"url":"https://github.com/earendil-works/pi/issues"},"homepage":"https://github.com/earendil-works/pi#readme","_nodeVersion":"22.23.1","_npmVersion":"11.16.0","dist":{"integrity":"sha512-8RLKLwe5TFM9kKFMNu/lTzveduq4GxZbnlG6ba8FAhLeb5wJP4zbj1eBumKBRvggpFQnW5R/Vo2a8zTlHsV9SQ==","shasum":"6125379d71fe8314c2166e7cddb6e4b847213562","tarball":"https://registry.npmjs.org/@earendil-works/pi-ai/-/pi-ai-0.80.7.tgz","fileCount":610,"unpackedSize":6262600,"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@earendil-works%2fpi-ai@0.80.7","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQDjeKIIYzk8IqlYDWWjJmMk6YbwNS6YIAW1fZrXlt4GggIgQoQ7nRlIU62AfWE+e5z5iQREsPaMl6x3HC0obhlWaR4="}]},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:975b2765-9d44-42ba-a322-c1cbbce03f36"}},"directories":{},"maintainers":[{"name":"mitsuhiko","email":"armin.ronacher@active-4.com"},{"name":"badlogic","email":"mario@badlogicgames.com"},{"name":"rwachtler","email":"r.wachtler@outlook.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/pi-ai_0.80.7_1784047291165_0.052876757986674905"},"_hasShrinkwrap":false}},"time":{"created":"2026-05-07T15:15:37.162Z","modified":"2026-07-14T16:41:31.769Z","0.74.0":"2026-05-07T15:15:37.460Z","0.74.1":"2026-05-16T23:34:50.791Z","0.75.0":"2026-05-17T19:03:27.479Z","0.75.1":"2026-05-18T00:01:42.521Z","0.75.2":"2026-05-18T09:47:02.489Z","0.75.3":"2026-05-18T09:59:11.135Z","0.75.4":"2026-05-20T14:24:10.038Z","0.74.2":"2026-05-21T22:21:55.412Z","0.75.5":"2026-05-23T10:06:33.703Z","0.76.0":"2026-05-27T20:03:51.992Z","0.77.0":"2026-05-28T22:48:53.272Z","0.78.0":"2026-05-29T23:51:28.729Z","0.78.1":"2026-06-04T16:35:33.240Z","0.79.0":"2026-06-08T15:20:07.607Z","0.79.1":"2026-06-09T21:25:28.677Z","0.79.2":"2026-06-12T22:29:35.567Z","0.79.3":"2026-06-13T09:21:45.178Z","0.79.4":"2026-06-15T08:32:26.105Z","0.79.5":"2026-06-16T18:06:59.800Z","0.79.6":"2026-06-16T22:03:19.072Z","0.79.7":"2026-06-18T16:31:42.639Z","0.79.8":"2026-06-19T07:57:37.419Z","0.79.9":"2026-06-20T20:19:43.306Z","0.79.10":"2026-06-22T09:18:46.214Z","0.80.1":"2026-06-23T18:08:34.024Z","0.80.2":"2026-06-23T22:03:29.852Z","0.80.3":"2026-06-30T20:34:10.778Z","0.80.5":"2026-07-09T19:08:43.457Z","0.80.6":"2026-07-09T23:21:44.666Z","0.80.7":"2026-07-14T16:41:31.407Z"},"bugs":{"url":"https://github.com/earendil-works/pi/issues"},"author":{"name":"Mario Zechner"},"license":"MIT","homepage":"https://github.com/earendil-works/pi#readme","keywords":["ai","llm","openai","anthropic","gemini","bedrock","unified","api"],"repository":{"type":"git","url":"git+https://github.com/earendil-works/pi.git","directory":"packages/ai"},"description":"Unified LLM API with automatic model discovery and provider configuration","maintainers":[{"name":"mitsuhiko","email":"armin.ronacher@active-4.com"},{"name":"badlogic","email":"mario@badlogicgames.com"},{"name":"rwachtler","email":"r.wachtler@outlook.com"}],"readme":"# @earendil-works/pi-ai\n\nUnified LLM API with provider collections, automatic auth resolution, token and cost tracking, and simple context persistence and hand-off to other models mid-session.\n\n**Note**: This library only includes models that support tool calling (function calling), as this is essential for agentic workflows.\n\n## Table of Contents\n\n- [Supported Providers](#supported-providers)\n- [Installation](#installation)\n- [Quick Start](#quick-start)\n- [Providers and Models](#providers-and-models)\n  - [Provider Factories](#provider-factories)\n  - [All Built-in Providers](#all-built-in-providers)\n  - [Querying Models](#querying-models)\n  - [Static Catalog Reads](#static-catalog-reads)\n  - [Dynamic Providers](#dynamic-providers)\n- [Auth](#auth)\n  - [How Auth Resolves](#how-auth-resolves)\n  - [Credential Store](#credential-store)\n  - [Environment Variables](#environment-variables)\n- [Tools](#tools)\n  - [Defining Tools](#defining-tools)\n  - [Handling Tool Calls](#handling-tool-calls)\n  - [Streaming Tool Calls with Partial JSON](#streaming-tool-calls-with-partial-json)\n  - [Validating Tool Arguments](#validating-tool-arguments)\n  - [Complete Event Reference](#complete-event-reference)\n- [Image Input](#image-input)\n- [Image Generation](#image-generation)\n- [Thinking/Reasoning](#thinkingreasoning)\n  - [Unified Interface](#unified-interface-streamsimplecompletesimple)\n  - [Provider-Specific Options](#provider-specific-options-streamcomplete)\n  - [Streaming Thinking Content](#streaming-thinking-content)\n- [Stop Reasons](#stop-reasons)\n- [Error Handling](#error-handling)\n  - [Aborting Requests](#aborting-requests)\n  - [Continuing After Abort](#continuing-after-abort)\n  - [Debugging Provider Payloads](#debugging-provider-payloads)\n- [Custom Providers](#custom-providers)\n  - [createProvider()](#createprovider)\n  - [Calling API Implementations Directly](#calling-api-implementations-directly)\n  - [OpenAI Compatibility Settings](#openai-compatibility-settings)\n- [Faux Provider for Tests](#faux-provider-for-tests)\n- [Cross-Provider Handoffs](#cross-provider-handoffs)\n- [Context Serialization](#context-serialization)\n- [Browser Usage](#browser-usage)\n- [Bundling and Tree Shaking](#bundling-and-tree-shaking)\n- [OAuth Providers](#oauth-providers)\n  - [Vertex AI](#vertex-ai)\n  - [CLI Login](#cli-login)\n  - [Programmatic OAuth](#programmatic-oauth)\n- [Migrating from the Old Global API](#migrating-from-the-old-global-api)\n- [Development](#development)\n- [License](#license)\n\n## Supported Providers\n\n- **OpenAI**\n- **Ant Ling**\n- **Azure OpenAI (Responses)**\n- **OpenAI Codex** (ChatGPT Plus/Pro subscription, requires OAuth, see below)\n- **DeepSeek**\n- **NVIDIA NIM**\n- **Anthropic**\n- **Google**\n- **Vertex AI** (Gemini via Vertex AI)\n- **Mistral**\n- **Groq**\n- **Cerebras**\n- **Cloudflare AI Gateway**\n- **Cloudflare Workers AI**\n- **xAI**\n- **OpenRouter**\n- **Vercel AI Gateway**\n- **ZAI Coding Plan (Global)** (with separate China provider)\n- **MiniMax** (with separate China provider)\n- **Together AI**\n- **Hugging Face**\n- **Moonshot AI** (with separate China provider)\n- **GitHub Copilot** (requires OAuth, see below)\n- **Amazon Bedrock**\n- **OpenCode Zen**\n- **OpenCode Go**\n- **Fireworks** (uses OpenAI- and Anthropic-compatible APIs)\n- **Kimi For Coding** (Moonshot AI subscription endpoint, uses Anthropic-compatible API)\n- **Xiaomi MiMo** (defaults to API billing endpoint, with separate Token Plan providers for `cn`/`ams`/`sgp` regions)\n- **Any OpenAI-compatible API**: Ollama, vLLM, LM Studio, etc.\n\n## Installation\n\n```bash\nnpm install @earendil-works/pi-ai\n```\n\nTypeBox exports are re-exported from `@earendil-works/pi-ai`: `Type`, `Static`, and `TSchema`.\n\n## Quick Start\n\nYou build a `Models` collection of providers and stream through it. The quickest start registers every built-in provider; apps that care about bundle size register individual providers instead (see [Provider Factories](#provider-factories) and [Bundling and Tree Shaking](#bundling-and-tree-shaking)).\n\n```typescript\nimport { Type, type Context, type Tool } from '@earendil-works/pi-ai';\nimport { builtinModels } from '@earendil-works/pi-ai/providers/all';\n\n// A Models collection with every built-in provider registered\nconst models = builtinModels();\n\n// Sync lookup against the collection\nconst model = models.getModel('openai', 'gpt-4o-mini')!;\n\n// Define tools with TypeBox schemas for type safety and validation\nconst tools: Tool[] = [{\n  name: 'get_time',\n  description: 'Get the current time',\n  parameters: Type.Object({\n    timezone: Type.Optional(Type.String({ description: 'Optional timezone (e.g., America/New_York)' }))\n  })\n}];\n\n// Build a conversation context (easily serializable and transferable between models)\nconst context: Context = {\n  systemPrompt: 'You are a helpful assistant.',\n  messages: [{ role: 'user', content: 'What time is it?', timestamp: Date.now() }],\n  tools\n};\n\n// Option 1: Streaming with all event types.\n// Auth resolves through the provider (OPENAI_API_KEY from the environment here).\nconst s = models.stream(model, context);\n\nfor await (const event of s) {\n  switch (event.type) {\n    case 'start':\n      console.log(`Starting with ${event.partial.model}`);\n      break;\n    case 'text_start':\n      console.log('\\n[Text started]');\n      break;\n    case 'text_delta':\n      process.stdout.write(event.delta);\n      break;\n    case 'text_end':\n      console.log('\\n[Text ended]');\n      break;\n    case 'thinking_start':\n      console.log('[Model is thinking...]');\n      break;\n    case 'thinking_delta':\n      process.stdout.write(event.delta);\n      break;\n    case 'thinking_end':\n      console.log('[Thinking complete]');\n      break;\n    case 'toolcall_start':\n      console.log(`\\n[Tool call started: index ${event.contentIndex}]`);\n      break;\n    case 'toolcall_delta':\n      // Partial tool arguments are being streamed\n      const partialCall = event.partial.content[event.contentIndex];\n      if (partialCall.type === 'toolCall') {\n        console.log(`[Streaming args for ${partialCall.name}]`);\n      }\n      break;\n    case 'toolcall_end':\n      console.log(`\\nTool called: ${event.toolCall.name}`);\n      console.log(`Arguments: ${JSON.stringify(event.toolCall.arguments)}`);\n      break;\n    case 'done':\n      console.log(`\\nFinished: ${event.reason}`);\n      break;\n    case 'error':\n      console.error(`Error: ${event.error.errorMessage}`);\n      break;\n  }\n}\n\n// Get the final message after streaming, add it to the context\nconst finalMessage = await s.result();\ncontext.messages.push(finalMessage);\n\n// Handle tool calls if any\nconst toolCalls = finalMessage.content.filter(b => b.type === 'toolCall');\nfor (const call of toolCalls) {\n  const result = call.name === 'get_time'\n    ? new Date().toLocaleString('en-US', {\n        timeZone: call.arguments.timezone || 'UTC',\n        dateStyle: 'full',\n        timeStyle: 'long'\n      })\n    : 'Unknown tool';\n\n  // Add tool result to context (supports text and images)\n  context.messages.push({\n    role: 'toolResult',\n    toolCallId: call.id,\n    toolName: call.name,\n    content: [{ type: 'text', text: result }],\n    isError: false,\n    timestamp: Date.now()\n  });\n}\n\n// Continue if there were tool calls\nif (toolCalls.length > 0) {\n  const continuation = await models.complete(model, context);\n  context.messages.push(continuation);\n  console.log('After tool execution:', continuation.content);\n}\n\nconsole.log(`Total tokens: ${finalMessage.usage.input} in, ${finalMessage.usage.output} out`);\nconsole.log(`Cost: $${finalMessage.usage.cost.total.toFixed(4)}`);\n\n// Option 2: Get complete response without streaming\nconst response = await models.complete(model, context);\n\nfor (const block of response.content) {\n  if (block.type === 'text') {\n    console.log(block.text);\n  } else if (block.type === 'toolCall') {\n    console.log(`Tool: ${block.name}(${JSON.stringify(block.arguments)})`);\n  }\n}\n```\n\nSnippets in the rest of this README assume a `models` collection set up like this (with the relevant providers registered).\n\n## Providers and Models\n\nA **provider** is the runtime unit: it owns its model catalog, its auth (API key resolution, OAuth flows), and its stream behavior. A `Models` collection holds providers and routes every request to the provider that owns the model.\n\nProviders internally share **API implementations** (the wire protocols): Anthropic models use `anthropic-messages`, OpenAI uses `openai-responses`, while xAI, Groq, Cerebras, OpenRouter, and most others share `openai-completions`. Mixed-API providers (GitHub Copilot, OpenCode Zen) dispatch per model.\n\n### Provider Factories\n\nFor apps that only need specific providers, there is one factory per built-in provider, each a subpath import that pulls only that provider's catalog:\n\n```typescript\nimport { anthropicProvider } from '@earendil-works/pi-ai/providers/anthropic';\nimport { openaiProvider } from '@earendil-works/pi-ai/providers/openai';\nimport { openrouterProvider } from '@earendil-works/pi-ai/providers/openrouter';\nimport { amazonBedrockProvider } from '@earendil-works/pi-ai/providers/amazon-bedrock';\n// ...one module per provider in the Supported Providers list\n\nconst models = createModels();\nmodels.setProvider(anthropicProvider());\nmodels.setProvider(openrouterProvider());\n```\n\nProvider factories import their model catalog and a lazy API wrapper. They do not import other providers. With bundler code splitting, SDK implementations (`@anthropic-ai/sdk`, `openai`, `@google/genai`, etc.) stay in lazy chunks loaded on the first request to a model of that API.\n\n### All Built-in Providers\n\nFor apps that want everything (as in Quick Start):\n\n```typescript\nimport { builtinModels } from '@earendil-works/pi-ai/providers/all';\n\nconst models = builtinModels(); // a Models collection with every built-in provider registered\n```\n\nThis imports all catalogs and every built-in provider factory. It is the heavy, explicit entrypoint. `builtinModels()` accepts the same options as `createModels()` (`credentials`, `authContext`); `builtinProviders()` returns the provider array if you want to register them on your own collection.\n\n### Querying Models\n\nReads are synchronous and return the last-known lists:\n\n```typescript\nconst providers = models.getProviders();           // registered Provider objects\nconst provider = models.getProvider('anthropic');  // one provider\n\nconst all = models.getModels();                    // every model across providers\nconst anthropicModels = models.getModels('anthropic');\nconst model = models.getModel('anthropic', 'claude-sonnet-4-5');\n\nfor (const m of anthropicModels) {\n  console.log(`${m.id}: ${m.name}`);\n  console.log(`  API: ${m.api}`);\n  console.log(`  Context: ${m.contextWindow} tokens`);\n  console.log(`  Vision: ${m.input.includes('image')}`);\n  console.log(`  Reasoning: ${m.reasoning}`);\n}\n```\n\nDynamically listed models are typed `Model<Api>`. Narrow with the `hasApi()` guard when you need API-specific option typing:\n\n```typescript\nimport { hasApi } from '@earendil-works/pi-ai';\n\nconst m = models.getModel('anthropic', 'claude-sonnet-4-5');\nif (m && hasApi(m, 'anthropic-messages')) {\n  // m: Model<'anthropic-messages'> — stream options fully typed\n  models.stream(m, context, { thinkingEnabled: true, thinkingBudgetTokens: 2048 });\n}\n```\n\n### Static Catalog Reads\n\nFor tooling that wants the generated built-in catalog with full literal typing (provider and model IDs auto-complete), independent of any collection:\n\n```typescript\nimport { getBuiltinModel, getBuiltinModels, getBuiltinProviders } from '@earendil-works/pi-ai/providers/all';\n\nconst model = getBuiltinModel('openai', 'gpt-4o-mini'); // typed Model<'openai-responses'>\nconst providers = getBuiltinProviders();\nconst anthropic = getBuiltinModels('anthropic');\n```\n\n### Dynamic Providers\n\nProviders may have dynamic model lists (a llama.cpp server, a live OpenRouter listing). Reads stay sync; fetching is an explicit async verb:\n\n```typescript\n// getModels() returns the last-known list (empty before the first refresh)\nawait models.refresh('llamacpp');        // fetch one provider's list; rejects on failure\nawait models.refresh();                  // refresh all providers concurrently, best-effort\nconst fresh = models.getModel('llamacpp', 'qwen3-30b');\n```\n\nStatic built-in providers are no-ops for `refresh()`. See [createProvider()](#createprovider) for building a dynamic provider.\n\n## Auth\n\nEvery provider owns its auth: how API keys resolve (stored credentials, environment variables, ambient sources like AWS profiles or gcloud ADC) and, where supported, OAuth login/refresh flows.\n\n### How Auth Resolves\n\nWhen you call `models.stream()`, the collection resolves auth through the owning provider and merges it into the request. Explicit per-request values always win:\n\n```typescript\n// Resolved through the provider (env var, stored credential, OAuth token):\nawait models.complete(model, context);\n\n// Explicit key wins over anything the provider would resolve:\nawait models.complete(model, context, { apiKey: 'sk-explicit' });\n```\n\nYou can inspect resolution without making a request — useful for status UIs:\n\n```typescript\nconst auth = await models.getAuth(model);\nif (auth) {\n  console.log(`configured via ${auth.source}`); // e.g. \"ANTHROPIC_API_KEY\", \"OAuth\", \"stored credential\"\n} else {\n  console.log('not configured');\n}\n```\n\n`getAuth()` resolves `undefined` for unconfigured providers and rejects with `ModelsError` when something is actually broken (`\"oauth\"`: token refresh failed, credential preserved for re-login; `\"auth\"`: key resolution or credential store failure). Request paths surface the same failures as stream errors.\n\n### Credential Store\n\nStored credentials (API keys entered interactively, OAuth tokens) live in a `CredentialStore` — one type-tagged credential per provider. pi-ai ships an in-memory default; apps inject persistent storage:\n\n```typescript\nimport { createModels, type CredentialStore } from '@earendil-works/pi-ai';\n\nconst models = createModels({ credentials: myFileBackedStore });\n// builtinModels() takes the same options:\n// const models = builtinModels({ credentials: myFileBackedStore });\n```\n\nThe contract is small: `read(providerId)`, `modify(providerId, fn)` (the only write path — a serialized read-modify-write), and `delete(providerId)`. OAuth token refresh runs inside `modify`, so concurrent requests and processes cannot double-refresh a rotated token. A stored credential *owns* its provider: environment variables are only consulted when nothing is stored, and a failed refresh never silently falls back to an env key.\n\nAPI-key credentials use the same discriminator as pi's `auth.json` and can carry provider-scoped env/config values:\n\n```typescript\nconst credential = {\n  type: 'api_key',\n  key: '...',\n  env: {\n    CLOUDFLARE_ACCOUNT_ID: 'account-id',\n    CLOUDFLARE_GATEWAY_ID: 'gateway-id'\n  }\n} as const;\n```\n\n### Environment Variables\n\nBuilt-in providers resolve these env vars (Node.js; in browsers pass `apiKey` explicitly):\n\n| Provider | Environment Variable(s) |\n|----------|------------------------|\n| OpenAI | `OPENAI_API_KEY` |\n| Ant Ling | `ANT_LING_API_KEY` |\n| Azure OpenAI | `AZURE_OPENAI_API_KEY` + `AZURE_OPENAI_BASE_URL` (e.g. `https://{resource}.ai.azure.com`) or `AZURE_OPENAI_RESOURCE_NAME`. Supports `*.openai.azure.com`, `*.cognitiveservices.azure.com` and `*.ai.azure.com`; root endpoints auto-normalize to `/openai/v1`. Optional: `AZURE_OPENAI_API_VERSION` (default `v1`), `AZURE_OPENAI_DEPLOYMENT_NAME_MAP`. |\n| Anthropic | `ANTHROPIC_API_KEY` or `ANTHROPIC_OAUTH_TOKEN` |\n| DeepSeek | `DEEPSEEK_API_KEY` |\n| NVIDIA NIM | `NVIDIA_API_KEY` |\n| Google | `GEMINI_API_KEY` |\n| Vertex AI | `GOOGLE_CLOUD_API_KEY` or `GOOGLE_CLOUD_PROJECT` (or `GCLOUD_PROJECT`) + `GOOGLE_CLOUD_LOCATION` + ADC |\n| Mistral | `MISTRAL_API_KEY` |\n| Groq | `GROQ_API_KEY` |\n| Cerebras | `CEREBRAS_API_KEY` |\n| Cloudflare AI Gateway | `CLOUDFLARE_API_KEY` + `CLOUDFLARE_ACCOUNT_ID` + `CLOUDFLARE_GATEWAY_ID` |\n| Cloudflare Workers AI | `CLOUDFLARE_API_KEY` + `CLOUDFLARE_ACCOUNT_ID` |\n| xAI | `XAI_API_KEY` |\n| Fireworks | `FIREWORKS_API_KEY` |\n| Together AI | `TOGETHER_API_KEY` |\n| OpenRouter | `OPENROUTER_API_KEY` |\n| Vercel AI Gateway | `AI_GATEWAY_API_KEY` |\n| ZAI Coding Plan (Global) | `ZAI_API_KEY` |\n| ZAI Coding Plan (China) | `ZAI_CODING_CN_API_KEY` |\n| MiniMax (Global) | `MINIMAX_API_KEY` |\n| MiniMax (China) | `MINIMAX_CN_API_KEY` |\n| Moonshot AI / Moonshot AI (China) | `MOONSHOT_API_KEY` |\n| Hugging Face | `HF_TOKEN` |\n| OpenCode Zen / OpenCode Go | `OPENCODE_API_KEY` |\n| Kimi For Coding | `KIMI_API_KEY` |\n| Xiaomi MiMo (API billing) | `XIAOMI_API_KEY` |\n| Xiaomi MiMo Token Plan (China) | `XIAOMI_TOKEN_PLAN_CN_API_KEY` |\n| Xiaomi MiMo Token Plan (Amsterdam) | `XIAOMI_TOKEN_PLAN_AMS_API_KEY` |\n| Xiaomi MiMo Token Plan (Singapore) | `XIAOMI_TOKEN_PLAN_SGP_API_KEY` |\n| GitHub Copilot | `COPILOT_GITHUB_TOKEN` |\n\nAmazon Bedrock resolves ambient AWS credentials (`AWS_PROFILE`, access key pairs, `AWS_BEARER_TOKEN_BEDROCK`, ECS task roles, web identity tokens). Vertex AI resolves either an explicit key or gcloud Application Default Credentials plus project/location.\n\n## Tools\n\nTools enable LLMs to interact with external systems. This library uses TypeBox schemas for type-safe tool definitions with automatic validation using TypeBox's built-in validator and value conversion utilities. TypeBox schemas can be serialized and deserialized as plain JSON, making them ideal for distributed systems.\n\n### Defining Tools\n\n```typescript\nimport { Type, type Tool, StringEnum } from '@earendil-works/pi-ai';\n\n// Define tool parameters with TypeBox\nconst weatherTool: Tool = {\n  name: 'get_weather',\n  description: 'Get current weather for a location',\n  parameters: Type.Object({\n    location: Type.String({ description: 'City name or coordinates' }),\n    units: StringEnum(['celsius', 'fahrenheit'], { default: 'celsius' })\n  })\n};\n\n// Note: For Google API compatibility, use StringEnum helper instead of Type.Enum\n// Type.Enum generates anyOf/const patterns that Google doesn't support\n\nconst bookMeetingTool: Tool = {\n  name: 'book_meeting',\n  description: 'Schedule a meeting',\n  parameters: Type.Object({\n    title: Type.String({ minLength: 1 }),\n    startTime: Type.String({ format: 'date-time' }),\n    endTime: Type.String({ format: 'date-time' }),\n    attendees: Type.Array(Type.String({ format: 'email' }), { minItems: 1 })\n  })\n};\n```\n\n### Handling Tool Calls\n\nTool results use content blocks and can include both text and images:\n\n```typescript\nimport { readFileSync } from 'fs';\n\nconst context: Context = {\n  messages: [{ role: 'user', content: 'What is the weather in London?', timestamp: Date.now() }],\n  tools: [weatherTool]\n};\n\nconst response = await models.complete(model, context);\n\n// Check for tool calls in the response\nfor (const block of response.content) {\n  if (block.type === 'toolCall') {\n    // Execute your tool with the arguments\n    // See \"Validating Tool Arguments\" section for validation\n    const result = await executeWeatherApi(block.arguments);\n\n    // Add tool result with text content\n    context.messages.push({\n      role: 'toolResult',\n      toolCallId: block.id,\n      toolName: block.name,\n      content: [{ type: 'text', text: JSON.stringify(result) }],\n      isError: false,\n      timestamp: Date.now()\n    });\n  }\n}\n\n// Tool results can also include images (for vision-capable models)\nconst imageBuffer = readFileSync('chart.png');\ncontext.messages.push({\n  role: 'toolResult',\n  toolCallId: 'tool_xyz',\n  toolName: 'generate_chart',\n  content: [\n    { type: 'text', text: 'Generated chart showing temperature trends' },\n    { type: 'image', data: imageBuffer.toString('base64'), mimeType: 'image/png' }\n  ],\n  isError: false,\n  timestamp: Date.now()\n});\n```\n\n### Streaming Tool Calls with Partial JSON\n\nDuring streaming, tool call arguments are progressively parsed as they arrive. This enables real-time UI updates before the complete arguments are available:\n\n```typescript\nconst s = models.stream(model, context);\n\nfor await (const event of s) {\n  if (event.type === 'toolcall_delta') {\n    const toolCall = event.partial.content[event.contentIndex];\n\n    // toolCall.arguments contains partially parsed JSON during streaming\n    // This allows for progressive UI updates\n    if (toolCall.type === 'toolCall' && toolCall.arguments) {\n      // BE DEFENSIVE: arguments may be incomplete\n      // Example: Show file path being written even before content is complete\n      if (toolCall.name === 'write_file' && toolCall.arguments.path) {\n        console.log(`Writing to: ${toolCall.arguments.path}`);\n\n        // Content might be partial or missing\n        if (toolCall.arguments.content) {\n          console.log(`Content preview: ${toolCall.arguments.content.substring(0, 100)}...`);\n        }\n      }\n    }\n  }\n\n  if (event.type === 'toolcall_end') {\n    // Here toolCall.arguments is complete (but not yet validated)\n    const toolCall = event.toolCall;\n    console.log(`Tool completed: ${toolCall.name}`, toolCall.arguments);\n  }\n}\n```\n\n**Important notes about partial tool arguments:**\n- During `toolcall_delta` events, `arguments` contains the best-effort parse of partial JSON\n- Fields may be missing or incomplete - always check for existence before use\n- String values may be truncated mid-word\n- Arrays may be incomplete\n- Nested objects may be partially populated\n- At minimum, `arguments` will be an empty object `{}`, never `undefined`\n- The Google provider does not support function call streaming. Instead, you will receive a single `toolcall_delta` event with the full arguments.\n\n### Validating Tool Arguments\n\nWhen implementing your own tool execution loop, use `validateToolCall` to validate arguments before passing them to your tools:\n\n```typescript\nimport { validateToolCall, type Tool } from '@earendil-works/pi-ai';\n\nconst tools: Tool[] = [weatherTool, calculatorTool];\nconst s = models.stream(model, { messages, tools });\n\nfor await (const event of s) {\n  if (event.type === 'toolcall_end') {\n    const toolCall = event.toolCall;\n\n    try {\n      // Validate arguments against the tool's schema (throws on invalid args)\n      const validatedArgs = validateToolCall(tools, toolCall);\n      const result = await executeMyTool(toolCall.name, validatedArgs);\n      // ... add tool result to context\n    } catch (error) {\n      // Validation failed - return error as tool result so model can retry\n      context.messages.push({\n        role: 'toolResult',\n        toolCallId: toolCall.id,\n        toolName: toolCall.name,\n        content: [{ type: 'text', text: error.message }],\n        isError: true,\n        timestamp: Date.now()\n      });\n    }\n  }\n}\n```\n\n### Complete Event Reference\n\nAll streaming events emitted during assistant message generation:\n\n| Event Type | Description | Key Properties |\n|------------|-------------|----------------|\n| `start` | Stream begins | `partial`: Initial assistant message structure |\n| `text_start` | Text block starts | `contentIndex`: Position in content array |\n| `text_delta` | Text chunk received | `delta`: New text, `contentIndex`: Position |\n| `text_end` | Text block complete | `content`: Full text, `contentIndex`: Position |\n| `thinking_start` | Thinking block starts | `contentIndex`: Position in content array |\n| `thinking_delta` | Thinking chunk received | `delta`: New text, `contentIndex`: Position |\n| `thinking_end` | Thinking block complete | `content`: Full thinking, `contentIndex`: Position |\n| `toolcall_start` | Tool call begins | `contentIndex`: Position in content array |\n| `toolcall_delta` | Tool arguments streaming | `delta`: JSON chunk, `partial.content[contentIndex].arguments`: Partial parsed args |\n| `toolcall_end` | Tool call complete | `toolCall`: Complete validated tool call with `id`, `name`, `arguments` |\n| `done` | Stream complete | `reason`: Stop reason (\"stop\", \"length\", \"toolUse\"), `message`: Final assistant message |\n| `error` | Error occurred | `reason`: Error type (\"error\" or \"aborted\"), `error`: AssistantMessage with partial content |\n\nStreaming events for different content blocks are not guaranteed to be contiguous. Providers may emit deltas for text, thinking, and tool calls in the same upstream chunk, and pi may surface corresponding events interleaved, for example `text_start`, `text_delta`, `toolcall_start`, `text_delta`, `toolcall_delta`. Consumers must use `contentIndex` to associate each delta/end event with its block and must not assume that a block's `*_start`/`*_delta`/`*_end` sequence is uninterrupted by events for other blocks.\n\n## Image Input\n\nModels with vision capabilities can process images. You can check if a model supports images via the `input` property. If you pass images to a non-vision model, they are silently ignored.\n\n```typescript\nimport { readFileSync } from 'fs';\n\nconst model = models.getModel('openai', 'gpt-4o-mini')!;\n\n// Check if model supports images\nif (model.input.includes('image')) {\n  console.log('Model supports vision');\n}\n\nconst imageBuffer = readFileSync('image.png');\nconst base64Image = imageBuffer.toString('base64');\n\nconst response = await models.complete(model, {\n  messages: [{\n    role: 'user',\n    content: [\n      { type: 'text', text: 'What is in this image?' },\n      { type: 'image', data: base64Image, mimeType: 'image/png' }\n    ],\n    timestamp: Date.now()\n  }]\n});\n\n// Access the response\nfor (const block of response.content) {\n  if (block.type === 'text') {\n    console.log(block.text);\n  }\n}\n```\n\n## Image Generation\n\nImage generation uses a separate API surface from text/chat generation, mirroring the chat-side design: an `ImagesModels` collection holds `ImagesProvider`s, reads are sync, and auth resolves through the owning provider. Image generation is a one-shot API: `generateImages()` waits for the provider response and returns the final `AssistantImages` result — do not use the chat/stream APIs for it.\n\n### Basic Image Generation\n\n```typescript\nimport { builtinImagesModels } from '@earendil-works/pi-ai/providers/all';\n\n// Every built-in image-generation provider; accepts the same options as createModels()\nconst imagesModels = builtinImagesModels();\n\nconst model = imagesModels.getModel('openrouter', 'google/gemini-2.5-flash-image')!;\n\n// Auth resolves through the provider (OPENROUTER_API_KEY here); explicit apiKey wins\nconst result = await imagesModels.generateImages(model, {\n  input: [{ type: 'text', text: 'Generate a red circle on a plain white background.' }]\n});\n\nfor (const block of result.output) {\n  if (block.type === 'text') {\n    console.log(block.text);\n  } else if (block.type === 'image') {\n    console.log(block.mimeType);\n    console.log(block.data.substring(0, 32));\n  }\n}\n```\n\nLike the chat side, you can build the collection from parts: `createImagesModels({ credentials?, authContext? })`, the `openrouterImagesProvider()` factory from `@earendil-works/pi-ai/providers/openrouter-images`, and `createImagesProvider({ id, auth, models, refreshModels?, api })` for custom image providers (with `imagesModels.refresh(provider?)` for dynamic lists). Failures never reject — they return an `AssistantImages` with `stopReason: \"error\"`. The collection's `getAuth(model)` works exactly like the chat-side one.\n\nThe old global API (`getImageModel()` / `getImageModels()` / `getImageProviders()` / `generateImages()`) remains available on the [compat entrypoint](#migrating-from-the-old-global-api):\n\n```typescript\nimport { getImageModel, generateImages } from '@earendil-works/pi-ai/compat';\n\nconst model = getImageModel('openrouter', 'google/gemini-2.5-flash-image');\nconst result = await generateImages(model, {\n  input: [{ type: 'text', text: 'Generate a red circle on a plain white background.' }]\n}, {\n  apiKey: process.env.OPENROUTER_API_KEY\n});\n```\n\nSome models also support image input:\n\n```typescript\nimport { readFileSync } from 'fs';\n\nconst imageBuffer = readFileSync('input.png');\nconst result = await imagesModels.generateImages(model, {\n  input: [\n    { type: 'text', text: 'Create a variation of this image with a blue background.' },\n    { type: 'image', data: imageBuffer.toString('base64'), mimeType: 'image/png' }\n  ]\n});\n```\n\nCheck capabilities on the model metadata:\n\n```typescript\nconsole.log(model.input);   // ['text', 'image']\nconsole.log(model.output);  // ['image'] or ['image', 'text']\n```\n\n### Notes and Limitations\n\n- Image models live in `ImagesModels` collections, chat models in `Models` collections; the two are separate surfaces.\n- Use `generateImages()`, not the chat/stream APIs.\n- Image-generation models do not participate in tool calling.\n- Outputs are returned in `AssistantImages.output` and can include both base64-encoded `ImageContent` blocks and `TextContent` blocks.\n- Some models return only images, others return images plus text. Check `model.output`.\n- Some models accept image input, others are text-to-image only. Check `model.input`.\n- Like the streaming APIs, image generation supports options such as `apiKey`, `signal`, `headers`, `onPayload`, and `onResponse`, and results may include `stopReason`, `responseId`, and `usage`.\n- If you want a model to analyze images in a conversation or call tools, use the regular chat APIs with a model that supports image input.\n- At the moment, image generation is available through only one provider, OpenRouter.\n\n## Thinking/Reasoning\n\nMany models support thinking/reasoning capabilities where they can show their internal thought process. You can check if a model supports reasoning via the `reasoning` property. If you pass reasoning options to a non-reasoning model, they are silently ignored.\n\n### Unified Interface (streamSimple/completeSimple)\n\n```typescript\n// Many models across providers support thinking/reasoning\nconst model = models.getModel('anthropic', 'claude-sonnet-4-5')!;\n// or models.getModel('openai', 'gpt-5-mini');\n// or models.getModel('google', 'gemini-2.5-flash');\n// or models.getModel('xai', 'grok-code-fast-1');\n\n// Check if model supports reasoning\nif (model.reasoning) {\n  console.log('Model supports reasoning/thinking');\n}\n\n// Use the simplified reasoning option\nconst response = await models.completeSimple(model, {\n  messages: [{ role: 'user', content: 'Solve: 2x + 5 = 13', timestamp: Date.now() }]\n}, {\n  reasoning: 'medium'  // 'minimal' | 'low' | 'medium' | 'high' | 'xhigh' | 'max'\n});\n\n// Access thinking and text blocks\nfor (const block of response.content) {\n  if (block.type === 'thinking') {\n    console.log('Thinking:', block.thinking);\n  } else if (block.type === 'text') {\n    console.log('Response:', block.text);\n  }\n}\n```\n\n`xhigh` and `max` are model-specific, opt-in levels. Use `getSupportedThinkingLevels(model)` to determine whether a concrete model exposes either level; models such as GPT-5.6 can expose both.\n\n### Provider-Specific Options (stream/complete)\n\n`models.stream()`/`complete()` accept the owning API's full option set. Use `hasApi()` to narrow a dynamically looked-up model to its API for full option typing:\n\n```typescript\nimport { hasApi } from '@earendil-works/pi-ai';\n\n// OpenAI Reasoning (o1, o3, gpt-5)\nconst openaiModel = models.getModel('openai', 'gpt-5-mini')!;\nif (hasApi(openaiModel, 'openai-responses')) {\n  await models.complete(openaiModel, context, {\n    reasoningEffort: 'medium',\n    reasoningSummary: 'detailed'  // OpenAI Responses API only\n  });\n}\n\n// Anthropic Thinking\nconst anthropicModel = models.getModel('anthropic', 'claude-sonnet-4-5')!;\nif (hasApi(anthropicModel, 'anthropic-messages')) {\n  await models.complete(anthropicModel, context, {\n    thinkingEnabled: true,\n    thinkingBudgetTokens: 8192  // Optional token limit\n  });\n}\n\n// Google Gemini Thinking\nconst googleModel = models.getModel('google', 'gemini-2.5-flash')!;\nif (hasApi(googleModel, 'google-generative-ai')) {\n  await models.complete(googleModel, context, {\n    thinking: {\n      enabled: true,\n      budgetTokens: 8192  // -1 for dynamic, 0 to disable\n    }\n  });\n}\n```\n\n### Streaming Thinking Content\n\nWhen streaming, thinking content is delivered through specific events:\n\n```typescript\nconst s = models.streamSimple(model, context, { reasoning: 'high' });\n\nfor await (const event of s) {\n  switch (event.type) {\n    case 'thinking_start':\n      console.log('[Model started thinking]');\n      break;\n    case 'thinking_delta':\n      process.stdout.write(event.delta);  // Stream thinking content\n      break;\n    case 'thinking_end':\n      console.log('\\n[Thinking complete]');\n      break;\n  }\n}\n```\n\n## Stop Reasons\n\nEvery `AssistantMessage` includes a `stopReason` field that indicates how the generation ended:\n\n- `\"stop\"` - Normal completion, the model finished its response\n- `\"length\"` - Output hit the maximum token limit\n- `\"toolUse\"` - Model is calling tools and expects tool results\n- `\"error\"` - An error occurred during generation\n- `\"aborted\"` - Request was cancelled via abort signal\n\n`AssistantMessage` may also include `responseId`, a provider-specific upstream response or message identifier when the underlying API exposes one. Do not assume it is always present across providers.\n\n## Error Handling\n\nRequest failures never throw out of the stream functions: when a request ends with an error (including aborts and tool call validation errors), the streaming API emits an error event and the final message carries the details:\n\n```typescript\n// In streaming\nfor await (const event of s) {\n  if (event.type === 'error') {\n    // event.reason is either \"error\" or \"aborted\"\n    // event.error is the AssistantMessage with partial content\n    console.error(`Error (${event.reason}):`, event.error.errorMessage);\n    console.log('Partial content:', event.error.content);\n  }\n}\n\n// The final message will have the error details\nconst message = await s.result();\nif (message.stopReason === 'error' || message.stopReason === 'aborted') {\n  console.error('Request failed:', message.errorMessage);\n  // message.content contains any partial content received before the error\n  // message.usage contains partial token counts and costs\n}\n```\n\nAuth failures (no key configured, OAuth refresh failed, unknown provider) surface the same way: as a stream error with `stopReason: \"error\"`.\n\n### Aborting Requests\n\nThe abort signal allows you to cancel in-progress requests. Aborted requests have `stopReason === 'aborted'`:\n\n```typescript\nconst controller = new AbortController();\n\n// Abort after 2 seconds\nsetTimeout(() => controller.abort(), 2000);\n\nconst s = models.stream(model, {\n  messages: [{ role: 'user', content: 'Write a long story', timestamp: Date.now() }]\n}, {\n  signal: controller.signal\n});\n\nfor await (const event of s) {\n  if (event.type === 'text_delta') {\n    process.stdout.write(event.delta);\n  } else if (event.type === 'error') {\n    // event.reason tells you if it was \"error\" or \"aborted\"\n    console.log(`${event.reason === 'aborted' ? 'Aborted' : 'Error'}:`, event.error.errorMessage);\n  }\n}\n\n// Get results (may be partial if aborted)\nconst response = await s.result();\nif (response.stopReason === 'aborted') {\n  console.log('Request was aborted:', response.errorMessage);\n  console.log('Partial content received:', response.content);\n  console.log('Tokens used:', response.usage);\n}\n```\n\n### Continuing After Abort\n\nAborted messages can be added to the conversation context and continued in subsequent requests:\n\n```typescript\nconst context = {\n  messages: [\n    { role: 'user', content: 'Explain quantum computing in detail', timestamp: Date.now() }\n  ]\n};\n\n// First request gets aborted after 2 seconds\nconst controller1 = new AbortController();\nsetTimeout(() => controller1.abort(), 2000);\n\nconst partial = await models.complete(model, context, { signal: controller1.signal });\n\n// Add the partial response to context\ncontext.messages.push(partial);\ncontext.messages.push({ role: 'user', content: 'Please continue', timestamp: Date.now() });\n\n// Continue the conversation\nconst continuation = await models.complete(model, context);\n```\n\n### Debugging Provider Payloads\n\nUse the `onPayload` callback to inspect the request payload sent to the provider. This is useful for debugging request formatting issues or provider validation errors.\n\n```typescript\nconst response = await models.complete(model, context, {\n  onPayload: (payload) => {\n    console.log('Provider payload:', JSON.stringify(payload, null, 2));\n  }\n});\n```\n\nThe callback is supported by `stream`, `complete`, `streamSimple`, and `completeSimple`.\n\n## Custom Providers\n\n### createProvider()\n\n`createProvider()` builds a provider from parts: identity, auth, a model list, and an API implementation. Use it for local inference servers, proxies, or any OpenAI/Anthropic-compatible endpoint:\n\n```typescript\nimport { createModels, createProvider, envApiKeyAuth, type Model } from '@earendil-works/pi-ai';\nimport { openAICompletionsApi } from '@earendil-works/pi-ai/api/openai-completions.lazy';\n\nconst ollamaModel: Model<'openai-completions'> = {\n  id: 'llama-3.1-8b',\n  name: 'Llama 3.1 8B (Ollama)',\n  api: 'openai-completions',\n  provider: 'ollama',\n  baseUrl: 'http://localhost:11434/v1',\n  reasoning: false,\n  input: ['text'],\n  cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },\n  contextWindow: 128000,\n  maxTokens: 32000\n};\n\nconst ollama = createProvider({\n  id: 'ollama',\n  name: 'Ollama',\n  baseUrl: 'http://localhost:11434/v1',\n  // Every provider declares auth; keyless local servers resolve as configured with no key.\n  auth: { apiKey: { name: 'Ollama', resolve: async () => ({ auth: {} }) } },\n  models: [ollamaModel],\n  api: openAICompletionsApi(),\n});\n\nconst models = createModels();\nmodels.setProvider(ollama);\n\nawait models.complete(models.getModel('ollama', 'llama-3.1-8b')!, context);\n```\n\nFor providers with real keys, `envApiKeyAuth(displayName, envVars)` gives the standard behavior (stored credential wins, then the first set env var):\n\n```typescript\nconst proxy = createProvider({\n  id: 'my-proxy',\n  auth: { apiKey: envApiKeyAuth('My proxy API key', ['MY_PROXY_API_KEY']) },\n  models: [/* ... */],\n  api: openAICompletionsApi(),\n});\n```\n\nMixed-API providers pass a map keyed by `model.api`; each model dispatches to its API's implementation:\n\n```typescript\nimport { anthropicMessagesApi } from '@earendil-works/pi-ai/api/anthropic-messages.lazy';\nimport { openAIResponsesApi } from '@earendil-works/pi-ai/api/openai-responses.lazy';\n\nconst gateway = createProvider({\n  id: 'my-gateway',\n  auth: { apiKey: envApiKeyAuth('Gateway key', ['GATEWAY_API_KEY']) },\n  models: [/* models with api: 'anthropic-messages' or 'openai-responses' */],\n  api: {\n    'anthropic-messages': anthropicMessagesApi(),\n    'openai-responses': openAIResponsesApi(),\n  },\n});\n```\n\nDynamic model lists use `refreshModels`; the provider lists empty until the first `models.refresh()`:\n\n```typescript\nconst llamacpp = createProvider({\n  id: 'llamacpp',\n  auth: { apiKey: { name: 'llama.cpp', resolve: async () => ({ auth: {} }) } },\n  models: [],\n  refreshModels: async () => fetchModelsFromServer('http://localhost:8080'),\n  api: openAICompletionsApi(),\n});\n\nmodels.setProvider(llamacpp);\nawait models.refresh('llamacpp');\n```\n\nCustom models can carry `headers` (e.g. proxies behind bot detection) and `compat` flags — see [OpenAI Compatibility Settings](#openai-compatibility-settings).\n\nSome OpenAI-compatible servers do not understand the `developer` role used for reasoning-capable models. For those providers, set `compat.supportsDeveloperRole` to `false` so the system prompt is sent as a `system` message instead. If the server also does not support `reasoning_effort`, set `compat.supportsReasoningEffort` to `false` too. This commonly applies to Ollama, vLLM, SGLang, and similar OpenAI-compatible servers.\n\nUse model-level `thinkingLevelMap` to describe model-specific thinking controls. Keys are pi thinking levels (`off`, `minimal`, `low`, `medium`, `high`, `xhigh`, `max`). Missing standard levels through `high` use provider defaults; `xhigh` and `max` are opt-in and require a non-null map entry. String values are sent to the provider, `null` marks a level unsupported, and maps may skip levels.\n\n```typescript\nconst ollamaReasoningModel: Model<'openai-completions'> = {\n  id: 'gpt-oss:20b',\n  name: 'GPT-OSS 20B (Ollama)',\n  api: 'openai-completions',\n  provider: 'ollama',\n  baseUrl: 'http://localhost:11434/v1',\n  reasoning: true,\n  input: ['text'],\n  cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },\n  contextWindow: 131072,\n  maxTokens: 32000,\n  thinkingLevelMap: {\n    minimal: null,\n    low: null,\n    medium: null,\n    high: 'high',\n    xhigh: null,\n  },\n  compat: {\n    supportsDeveloperRole: false,\n    supportsReasoningEffort: false,\n  }\n};\n```\n\n### Calling API Implementations Directly\n\nThe API implementations are importable on their own. Each module exports exactly `stream` and `streamSimple` with that API's full option typing. Direct calls bypass provider auth — pass `apiKey` explicitly:\n\n```typescript\nimport { stream } from '@earendil-works/pi-ai/api/anthropic-messages';\n\nconst s = stream(claudeModel, context, {\n  apiKey: process.env.ANTHROPIC_API_KEY,\n  thinkingEnabled: true,\n  thinkingBudgetTokens: 2048,\n});\n```\n\nBuilt-in API implementations live under `./api/<api-id>`:\n\n| API id | Options type |\n|--------|--------------|\n| `anthropic-messages` | `AnthropicOptions` |\n| `openai-completions` | `OpenAICompletionsOptions` |\n| `openai-responses` | `OpenAIResponsesOptions` |\n| `openai-codex-responses` | `OpenAICodexResponsesOptions` |\n| `azure-openai-responses` | `AzureOpenAIResponsesOptions` |\n| `google-generative-ai` | `GoogleOptions` |\n| `google-vertex` | `GoogleVertexOptions` |\n| `mistral-conversations` | `MistralOptions` |\n| `bedrock-converse-stream` | `BedrockOptions` |\n\nImporting an implementation module loads its SDK. The `./api/<id>.lazy` wrappers (used by the provider factories) defer that load to the first request when the runtime or bundler supports dynamic import chunking. Legacy raw API subpaths from older releases (`./anthropic`, `./google`, `./mistral`, `./openai-completions`, ...) were removed; use `@earendil-works/pi-ai/api/<api-id>`.\n\n### OpenAI Compatibility Settings\n\nThe `openai-completions` API is implemented by many providers with minor differences. By default, the library auto-detects compatibility settings based on `baseUrl` for a small set of known OpenAI-compatible providers (Cerebras, xAI, Chutes, DeepSeek, NVIDIA NIM, Together AI, zAi, OpenCode, Cloudflare Workers AI, etc.). For custom proxies or unknown endpoints, you can override these settings via the `compat` field. For `openai-responses` models, the compat field supports Responses-specific flags.\n\n```typescript\ninterface OpenAICompletionsCompat {\n  supportsStore?: boolean;           // Whether provider supports the `store` field (default: true)\n  supportsDeveloperRole?: boolean;   // Whether provider supports `developer` role vs `system` (default: true)\n  supportsReasoningEffort?: boolean; // Whether provider supports `reasoning_effort` (default: true)\n  supportsUsageInStreaming?: boolean; // Whether provider supports `stream_options: { include_usage: true }` (default: true)\n  supportsStrictMode?: boolean;      // Whether provider supports `strict` in tool definitions (default: true)\n  sendSessionAffinityHeaders?: boolean; // Send session-affinity data from `sessionId` (default: false)\n  sessionAffinityFormat?: 'openai' | 'openai-nosession' | 'openrouter'; // Format for session affinity: 'openai' uses `prompt_cache_key`, `session_id`, `x-client-request-id`, and `x-session-affinity`; 'openai-nosession' uses `prompt_cache_key`, `x-client-request-id`, and `x-session-affinity`; 'openrouter' uses `x-session-id` (default: auto-detected)\n  maxTokensField?: 'max_completion_tokens' | 'max_tokens';  // Which field name to use (default: max_completion_tokens)\n  requiresToolResultName?: boolean;  // Whether tool results require the `name` field (default: false)\n  requiresAssistantAfterToolResult?: boolean; // Whether tool results must be followed by an assistant message (default: false)\n  requiresThinkingAsText?: boolean;  // Whether thinking blocks must be converted to text (default: false)\n  requiresReasoningContentOnAssistantMessages?: boolean; // Whether all replayed assistant messages must include empty reasoning_content when reasoning is enabled (default: auto-detected for DeepSeek)\n  thinkingFormat?: 'openai' | 'openrouter' | 'deepseek' | 'together' | 'zai' | 'qwen' | 'chat-template' | 'qwen-chat-template' | 'string-thinking' | 'ant-ling'; // Format for reasoning param: 'openai' uses reasoning_effort, 'openrouter' uses reasoning: { effort }, 'deepseek' uses thinking: { type } plus reasoning_effort when supported, 'together' uses reasoning: { enabled } plus reasoning_effort when supported, 'zai' uses thinking: { type }, 'qwen' uses enable_thinking, 'chat-template' uses configurable chat_template_kwargs, 'qwen-chat-template' uses chat_template_kwargs.enable_thinking and preserve_thinking, 'string-thinking' uses top-level thinking, 'ant-ling' uses reasoning: { effort } only for mapped efforts (default: openai)\n  chatTemplateKwargs?: Record<string, string | number | boolean | null | { '$var': 'thinking.enabled' | 'thinking.effort'; omitWhenOff?: boolean }>; // chat_template_kwargs values; use $var for pi-controlled thinking values\n  cacheControlFormat?: 'anthropic';  // Anthropic-style cache_control on system prompt, last tool, and last user/assistant text content\n  openRouterRouting?: OpenRouterRouting; // OpenRouter routing preferences (default: {})\n  vercelGatewayRouting?: VercelGatewayRouting; // Vercel AI Gateway routing preferences (default: {})\n}\n\ninterface OpenAIResponsesCompat {\n  supportsDeveloperRole?: boolean;   // Whether provider supports `developer` role vs `system` (default: true)\n  sessionAffinityFormat?: 'openai' | 'openai-nosession' | 'openrouter'; // Session-affinity header format: 'openai' sends `session_id` and `x-client-request-id`; 'openai-nosession' sends `x-client-request-id`; 'openrouter' sends `x-session-id`. Does not affect the `prompt_cache_key` body param (default: auto-detected)\n  supportsLongCacheRetention?: boolean; // Whether provider supports `prompt_cache_retention: \"24h\"` (default: true)\n}\n```\n\nIf `compat` is not set, the library falls back to URL-based detection. If `compat` is partially set, unspecified fields use the detected defaults. This is useful for:\n\n- **LiteLLM proxies**: May not support `store` field\n- **Custom inference servers**: May use non-standard field names\n- **Self-hosted endpoints**: May have different feature support\n\n## Faux Provider for Tests\n\n`fauxProvider()` builds an in-memory provider with scripted responses for tests and demos:\n\n```typescript\nimport {\n  createModels,\n  fauxAssistantMessage,\n  fauxProvider,\n  fauxText,\n  fauxThinking,\n  fauxToolCall,\n} from '@earendil-works/pi-ai';\n\nconst faux = fauxProvider({\n  tokensPerSecond: 50 // optional\n});\n\nconst models = createModels();\nmodels.setProvider(faux.provider);\n\nconst model = faux.getModel();\nconst context = {\n  messages: [{ role: 'user', content: 'Summarize package.json and then call echo', timestamp: Date.now() }]\n};\n\nfaux.setResponses([\n  fauxAssistantMessage([\n    fauxThinking('Need to inspect package metadata first.'),\n    fauxToolCall('echo', { text: 'package.json' })\n  ], { stopReason: 'toolUse' })\n]);\n\nconst first = await models.complete(model, context, {\n  sessionId: 'session-1',\n  cacheRetention: 'short'\n});\ncontext.messages.push(first);\n\ncontext.messages.push({\n  role: 'toolResult',\n  toolCallId: first.content.find((block) => block.type === 'toolCall')!.id,\n  toolName: 'echo',\n  content: [{ type: 'text', text: 'package.json contents here' }],\n  isError: false,\n  timestamp: Date.now()\n});\n\nfaux.setResponses([\n  fauxAssistantMessage([\n    fauxThinking('Now I can summarize the tool output.'),\n    fauxText('Here is the summary.')\n  ])\n]);\n\nconst s = models.stream(model, context);\nfor await (const event of s) {\n  console.log(event.type);\n}\n\n// Optional: multiple faux models for model-switching tests\nconst multiModel = fauxProvider({\n  provider: 'faux-multi',\n  models: [\n    { id: 'faux-fast', reasoning: false },\n    { id: 'faux-thinker', reasoning: true }\n  ]\n});\nmodels.setProvider(multiModel.provider);\nconst thinker = multiModel.getModel('faux-thinker');\n\nconsole.log(thinker?.reasoning);\nconsole.log(faux.getPendingResponseCount());\nconsole.log(faux.state.callCount);\n```\n\nNotes:\n- Responses are consumed from a queue in request start order.\n- If the queue is empty, the faux provider returns an assistant error message with `errorMessage: \"No more faux responses queued\"`.\n- Use `faux.setResponses([...])` to replace the remaining queue and `faux.appendResponses([...])` to add more responses.\n- `faux.models` exposes all faux models. `faux.getModel()` returns the first one, and `faux.getModel(id)` returns a specific one.\n- Use `fauxAssistantMessage(...)` for scripted assistant replies. Use `fauxText(...)`, `fauxThinking(...)`, and `fauxToolCall(...)` to build content blocks without filling in low-level fields manually.\n- Usage is estimated at roughly 1 token per 4 characters. When `sessionId` is present and `cacheRetention` is not `\"none\"`, prompt cache reads and writes are simulated automatically.\n- Tool call arguments stream incrementally via `toolcall_delta` chunks.\n- By default, each streamed chunk is emitted on its own microtask. Set `tokensPerSecond` to pace chunk delivery in real time.\n- The intended use is one deterministic scripted flow per handle. If you need independent concurrent flows, create separate faux providers with distinct `provider` ids.\n\n## Cross-Provider Handoffs\n\nThe library supports seamless handoffs between different LLM providers within the same conversation. This allows you to switch models mid-conversation while preserving context, including thinking blocks, tool calls, and tool results.\n\nWhen messages from one provider are sent to a different provider, the library automatically transforms them for compatibility:\n\n- **User and tool result messages** are passed through unchanged\n- **Assistant messages from the same provider/API** are preserved as-is\n- **Assistant messages from different providers** have their thinking blocks converted to text with `<thinking>` tags\n- **Tool calls and regular text** are preserved unchanged\n\n```typescript\nimport { createModels, type Context } from '@earendil-works/pi-ai';\nimport { anthropicProvider } from '@earendil-works/pi-ai/providers/anthropic';\nimport { openaiProvider } from '@earendil-works/pi-ai/providers/openai';\nimport { googleProvider } from '@earendil-works/pi-ai/providers/google';\n\nconst models = createModels();\nmodels.setProvider(anthropicProvider());\nmodels.setProvider(openaiProvider());\nmodels.setProvider(googleProvider());\n\nconst context: Context = { messages: [] };\n\n// Start with Claude\nconst claude = models.getModel('anthropic', 'claude-sonnet-4-5')!;\ncontext.messages.push({ role: 'user', content: 'What is 25 * 18?', timestamp: Date.now() });\ncontext.messages.push(await models.completeSimple(claude, context, { reasoning: 'medium' }));\n\n// Switch to GPT-5 - it will see Claude's thinking as <thinking> tagged text\nconst gpt5 = models.getModel('openai', 'gpt-5-mini')!;\ncontext.messages.push({ role: 'user', content: 'Is that calculation correct?', timestamp: Date.now() });\ncontext.messages.push(await models.complete(gpt5, context));\n\n// Switch to Gemini\nconst gemini = models.getModel('google', 'gemini-2.5-flash')!;\ncontext.messages.push({ role: 'user', content: 'What was the original question?', timestamp: Date.now() });\nconst geminiResponse = await models.complete(gemini, context);\n```\n\nAll providers can handle messages from other providers — text, tool calls and results (including images), thinking blocks (transformed to tagged text), and aborted messages with partial content. This enables flexible workflows: start with a fast model, switch to a more capable one for complex reasoning, or maintain continuity across provider outages.\n\n## Context Serialization\n\nThe `Context` object can be easily serialized and deserialized using standard JSON methods, making it simple to persist conversations, implement chat history, or transfer contexts between services:\n\n```typescript\nconst context: Context = {\n  systemPrompt: 'You are a helpful assistant.',\n  messages: [\n    { role: 'user', content: 'What is TypeScript?', timestamp: Date.now() }\n  ]\n};\n\nconst model = models.getModel('openai', 'gpt-4o-mini')!;\nconst response = await models.complete(model, context);\ncontext.messages.push(response);\n\n// Serialize the entire context\nconst serialized = JSON.stringify(context);\n\n// Save to database, localStorage, file, etc.\nlocalStorage.setItem('conversation', serialized);\n\n// Later: deserialize and continue the conversation\nconst restored: Context = JSON.parse(localStorage.getItem('conversation')!);\nrestored.messages.push({ role: 'user', content: 'Tell me more about its type system', timestamp: Date.now() });\n\n// Continue with any model\nconst newModel = models.getModel('anthropic', 'claude-3-5-haiku-20241022')!;\nconst continuation = await models.complete(newModel, restored);\n```\n\nModels are plain serializable data too — no functions or implementations attached — so persisting \"which model was this conversation using\" is a `JSON.stringify` away.\n\n> **Note**: If the context contains images (encoded as base64 as shown in the Image Input section), those will also be serialized.\n\n## Browser Usage\n\nThe library supports browser environments. The core entrypoint and provider factories are side-effect free and bundle cleanly. Environment variables are not available in browsers, so pass API keys explicitly — or inject a `CredentialStore` (e.g. localStorage-backed) and let provider auth resolve from stored credentials:\n\n```typescript\nimport { createModels } from '@earendil-works/pi-ai';\nimport { anthropicProvider } from '@earendil-works/pi-ai/providers/anthropic';\n\nconst models = createModels();\nmodels.setProvider(anthropicProvider());\n\nconst model = models.getModel('anthropic', 'claude-3-5-haiku-20241022')!;\nconst response = await models.complete(model, {\n  messages: [{ role: 'user', content: 'Hello!', timestamp: Date.now() }]\n}, {\n  apiKey: 'your-api-key'\n});\n```\n\n> **Security Warning**: Exposing API keys in frontend code is dangerous. Anyone can extract and abuse your keys. Only use this approach for internal tools or demos. For production applications, use a backend proxy that keeps your API keys secure.\n\nBrowser compatibility notes:\n\n- Amazon Bedrock (`bedrock-converse-stream`) is not supported in browser environments. It can still appear in model lists; calls fail at runtime.\n- OAuth login flows are Node-only. They are lazy-loaded behind bundler-opaque imports, so registering an OAuth-capable provider does not pull Node-only code into a browser bundle — only actually logging in would.\n- Use a server-side proxy or backend service if you need Bedrock or OAuth-based auth from a web app.\n\n## Bundling and Tree Shaking\n\nFor small bundles, import only the providers you need:\n\n```typescript\nimport { createModels } from '@earendil-works/pi-ai';\nimport { openaiProvider } from '@earendil-works/pi-ai/providers/openai';\n\nconst models = createModels();\nmodels.setProvider(openaiProvider());\n```\n\nRules:\n\n- `@earendil-works/pi-ai` is the core entrypoint and does not import built-in catalogs, provider factories, or SDK implementations.\n- `@earendil-works/pi-ai/providers/<provider>` imports that provider's catalog and lazy API wrapper only.\n- `@earendil-works/pi-ai/providers/all` imports every built-in provider factory and all catalogs. Use it only when you want the full built-in set.\n- With code splitting, provider SDKs stay in lazy chunks and load on first request.\n- Without code splitting, bundlers fold reachable lazy API implementations into the single bundle. A single-provider bundle then includes that provider's SDK; `providers/all` includes all statically visible SDKs. Bedrock is the exception: its AWS SDK implementation is loaded through a bundler-opaque Node-only import.\n- Importing `@earendil-works/pi-ai/api/<api-id>` directly loads that API implementation and its SDK immediately.\n\nAvoid `@earendil-works/pi-ai/compat` in new bundled apps; it preserves the old global API and imports the full built-in catalog surface.\n\nFor single-file Node ESM bundles, some SDK dependencies may still use dynamic CommonJS `require()` internally. If you see errors such as `Dynamic require of \"child_process\" is not supported`, add a Node `require` shim to the bundle. With esbuild:\n\n```bash\nesbuild app.js --bundle --platform=node --format=esm \\\n  --banner:js='import { createRequire } from \"module\";const require = createRequire(import.meta.url);' \\\n  --outfile=app.bundle.js\n```\n\nThis is only for Node bundles; it is not a browser or Cloudflare Workers workaround.\n\nBedrock is Node-only. Add it like any other provider:\n\n```typescript\nimport { createModels } from '@earendil-works/pi-ai';\nimport { amazonBedrockProvider } from '@earendil-works/pi-ai/providers/amazon-bedrock';\n\nconst models = createModels();\nmodels.setProvider(amazonBedrockProvider());\n```\n\nIn normal Node package usage and code-split bundles, Bedrock loads its AWS SDK implementation lazily. For a standalone single-file bundle that must include Bedrock support, register the implementation module explicitly:\n\n```typescript\nimport { setBedrockProviderModule } from '@earendil-works/pi-ai/api/bedrock-converse-stream.lazy';\nimport { bedrockProviderModule } from '@earendil-works/pi-ai/bedrock-provider';\n\nsetBedrockProviderModule(bedrockProviderModule);\n```\n\nThat explicit override bundles the AWS SDK. Without it, Bedrock's opaque runtime import expects the package's Bedrock implementation file to be available at runtime.\n\n### Provider-Scoped Environment Overrides\n\nPass `env` in stream options to scope provider configuration to a request. Values in `env` are used before process environment variables for provider auth and configuration such as Cloudflare account IDs, Azure OpenAI settings, Vertex project/location, Bedrock settings, `PI_CACHE_RETENTION`, and `HTTP_PROXY`/`HTTPS_PROXY`.\n\n```typescript\nconst models = builtinModels();\nconst model = models.getModel('cloudflare-ai-gateway', 'workers-ai/@cf/moonshotai/kimi-k2.6')!;\n\nconst response = await models.complete(model, context, {\n  env: {\n    CLOUDFLARE_API_KEY: '...',\n    CLOUDFLARE_ACCOUNT_ID: 'account-id',\n    CLOUDFLARE_GATEWAY_ID: 'gateway-id'\n  }\n});\n```\n\nUse this when one process needs different provider settings per request, or when ambient environment variables should not leak into a provider call.\n\n## OAuth Providers\n\nSeveral providers support OAuth authentication instead of static API keys:\n\n- **Anthropic** (Claude Pro/Max subscription)\n- **OpenAI Codex** (ChatGPT Plus/Pro subscription, access to GPT-5.x Codex models)\n- **GitHub Copilot** (Copilot subscription)\n\nEach of these providers carries an `OAuthAuth` on `provider.auth.oauth` with three operations: `login(callbacks)` runs the interactive flow and returns a credential, `refresh(credential)` exchanges the refresh token, and `toAuth(credential)` derives request auth (GitHub Copilot's per-account base URL comes from here). Refresh is automatic: `models.getAuth()` and the request paths refresh expired tokens under a credential-store lock, so concurrent requests and processes cannot double-refresh.\n\n```typescript\nimport { createModels } from '@earendil-works/pi-ai';\nimport { anthropicProvider } from '@earendil-works/pi-ai/providers/anthropic';\n\nconst models = createModels({ credentials: myStore }); // persistent CredentialStore\nmodels.setProvider(anthropicProvider());\n\n// Login: drive the flow with prompt()/notify() callbacks, persist the credential\nconst provider = models.getProvider('anthropic')!;\nconst credential = await provider.auth.oauth!.login({\n  prompt: async (p) => {\n    // p.type: 'text' | 'secret' | 'select' | 'manual_code'\n    // manual_code prompts race a local callback server; p.signal aborts them when the server wins\n    return await askUser(p.message);\n  },\n  notify: (event) => {\n    // event.type: 'auth_url' | 'device_code' | 'progress'\n    if (event.type === 'auth_url') console.log(`Open: ${event.url}`);\n    if (event.type === 'device_code') console.log(`Code: ${event.userCode} at ${event.verificationUri}`);\n    if (event.type === 'progress') console.log(event.message);\n  },\n});\nawait myStore.modify('anthropic', async () => credential);\n\n// From here on, requests resolve and refresh the token automatically\nconst model = models.getModel('anthropic', 'claude-sonnet-4-5')!;\nawait models.complete(model, context);\n\n// Logout\nawait myStore.delete('anthropic');\n```\n\n### Vertex AI\n\nVertex AI models support either a Google Cloud API key or Application Default Credentials (ADC):\n\n- **API key**: Set `GOOGLE_CLOUD_API_KEY` or pass `apiKey` in the call options.\n- **Local development (ADC)**: Run `gcloud auth application-default login`\n- **CI/Production (ADC)**: Set `GOOGLE_APPLICATION_CREDENTIALS` to point to a service account JSON key file\n\nWhen using ADC, also set `GOOGLE_CLOUD_PROJECT` (or `GCLOUD_PROJECT`) and `GOOGLE_CLOUD_LOCATION`. You can also pass `project`/`location` in the call options. When using `GOOGLE_CLOUD_API_KEY`, `project` and `location` are not required.\n\n```bash\n# Local (uses your user credentials)\ngcloud auth application-default login\nexport GOOGLE_CLOUD_PROJECT=\"my-project\"\nexport GOOGLE_CLOUD_LOCATION=\"us-central1\"\n\n# CI/Production (service account key file)\nexport GOOGLE_APPLICATION_CREDENTIALS=\"/path/to/service-account.json\"\n```\n\nOfficial docs: [Application Default Credentials](https://cloud.google.com/docs/authentication/application-default-credentials)\n\n### CLI Login\n\nThe quickest way to authenticate:\n\n```bash\nnpx @earendil-works/pi-ai login              # interactive provider selection\nnpx @earendil-works/pi-ai login anthropic    # login to specific provider\nnpx @earendil-works/pi-ai list               # list available providers\n```\n\nCredentials are saved to `auth.json` in the current directory.\n\n### Programmatic OAuth\n\nThe legacy flow functions remain available via the `@earendil-works/pi-ai/oauth` entry point (`loginAnthropic`, `loginOpenAICodex`, `loginGitHubCopilot`, `refreshOAuthToken`, `getOAuthApiKey`); credential storage is the caller's responsibility there. New code should prefer the provider-owned `OAuthAuth` shown above — it composes with the credential store and gets locked auto-refresh for free.\n\nProvider notes:\n\n**OpenAI Codex**: Requires a ChatGPT Plus or Pro subscription. Provides access to GPT-5.x Codex models with extended context windows and reasoning capabilities. The library automatically handles session-based prompt caching when `sessionId` is provided in stream options. You can set `transport` in stream options to `\"sse\"`, `\"websocket\"`, or `\"auto\"` for Codex Responses transport selection. When using WebSocket with a `sessionId`, connections are reused per session and expire after 5 minutes of inactivity.\n\n**Azure OpenAI (Responses)**: Uses the Responses API only. Set `AZURE_OPENAI_API_KEY` and either `AZURE_OPENAI_BASE_URL` or `AZURE_OPENAI_RESOURCE_NAME`. `AZURE_OPENAI_BASE_URL` supports both `https://<resource>.openai.azure.com` and `https://<resource>.cognitiveservices.azure.com`; root endpoints are normalized to `.../openai/v1` automatically. Use `AZURE_OPENAI_API_VERSION` (defaults to `v1`) to override the API version if needed. Deployment names are treated as model IDs by default, override with `azureDeploymentName` or `AZURE_OPENAI_DEPLOYMENT_NAME_MAP` using comma-separated `model-id=deployment` pairs (for example `gpt-4o-mini=my-deployment,gpt-4o=prod`). Legacy deployment-based URLs are intentionally unsupported.\n\n**GitHub Copilot**: If you get \"The requested model is not supported\" error, enable the model manually in VS Code: open Copilot Chat, click the model selector, select the model (warning icon), and click \"Enable\".\n\n## Migrating from the Old Global API\n\nOlder versions exposed a global API: `stream()`/`complete()` dispatching on `model.api` via a global registry, sync `getModel()`/`getModels()`/`getProviders()` catalog reads, `registerApiProvider()`, `getEnvApiKey()`, and per-API lazy stream functions. That surface lives unchanged on the **compat entrypoint**:\n\n```typescript\n// Before\nimport { getModel, complete } from '@earendil-works/pi-ai';\n\n// After (verbatim behavior, one import-path change)\nimport { getModel, complete } from '@earendil-works/pi-ai/compat';\n```\n\nCompat is a strict superset of the root entrypoint, so a file can switch its import path wholesale. It will be removed in a future release; migrate to `createModels()` + provider factories:\n\n| Old | New |\n|-----|-----|\n| `getModel('openai', 'gpt-4o-mini')` | `models.getModel('openai', 'gpt-4o-mini')` or `getBuiltinModel()` from `providers/all` |\n| `getModels('anthropic')` / `getProviders()` | `models.getModels('anthropic')` / `models.getProviders()` or `getBuiltin*` |\n| `stream(model, ctx, opts)` (env-key injection) | `models.stream(model, ctx, opts)` (provider auth resolution) |\n| `registerApiProvider({ api, stream, streamSimple })` | `createProvider({ id, auth, models, api })` + `models.setProvider()` |\n| `getEnvApiKey('openai')` | `await models.getAuth(model)` |\n| `streamAnthropic(model, ctx, opts)` | `stream` from `@earendil-w","readmeFilename":"README.md"}