When the consumer (readLines) hits the line/byte cap and destroys the
PassThrough, the underlying createReadStream had no link back and would
keep reading chunks to EOF in the background, defeating the early-exit
optimisation for large files.
Optimistically stream the file as UTF-8 -- the common case -- using a
fatal-mode TextDecoder so the read tool can stop pulling bytes from
disk once the line / 50KB byte cap is hit. Only fall back to a
full-buffer iconv decode when the bytes turn out not to be valid UTF-8.
The streaming + retry logic lives in a new kilo helper
(packages/opencode/src/kilocode/text-stream.ts) so the read tool's
`lines` function stays close to upstream OpenCode shape.
The existing apply_patch encoding test only checked final file bytes,
which were correct because Patch.deriveNewContentsFromChunks does its
own encoding-aware read. The diff and additions/deletions counts
returned to the user (and shown in the permission prompt) were
nonetheless garbled because the surrounding tool reused a hard-coded
UTF-8 decoder. Pin the diff metadata to catch that regression.
Bom.readFile uses a hard-coded UTF-8 TextDecoder, so the oldContent
captured for the diff, additions/deletions counts, and permission-prompt
metadata was mojibake for any non-UTF-8 file. The actual bytes written
were correct because deriveNewContentsFromChunks already does
encoding-aware reads, but the user-visible diff did not reflect the real
file contents. Switch to EncodedIO.read to match.
Picks up expanded blocking of exploitable git config keys (core.fsmonitor,
--template, merge-related) and GIT_CONFIG_COUNT env var. No breaking API
changes for our usage — the only removed export (ParsedVulnerabilities)
is not referenced anywhere in the repo.
Kilo isn't always BYOK; what matters here is that Kilo doesn't charge a
per-request fee on top of the upstream inference cost. So for the Kilo
provider, the gateway/marketplace `cost` would understate the user's true
spend — always prefer the upstream/market cost when present.
* feat: support Kilo-hosted indexing embeddings
* fix: format indexing settings
* fix: serialize local model persistence
* fix: annotate local model persistence
* fix: stabilize MCP OAuth browser test
* fix: annotate MCP OAuth test wait
* fix: keep KiloProvider under line cap
* fix: align Kilo indexing auth defaults
* fix(vscode): add missing indexing translations
* feat(indexing): fetch Kilo embedding model catalog
* fix(indexing): align Kilo embedding metadata fallback
* fix(gateway): remove unused indexing dependency
* fix(indexing): keep fallback catalog webview safe
* fix(agent-manager): include embedding model provider
* fix(vscode): provide embedding models in stories
* refactor(indexing): rely on Cloud embedding catalog
* fix(indexing): hydrate Kilo model metadata from Cloud
* fix(indexing): clear model when switching provider
Move the new Anthropic Messages, OpenAI Responses and Vercel AI Gateway
cost-extraction tests out of the shared upstream `test/session/compaction.test.ts`
file into `test/kilocode/provider-cost.test.ts` to keep Kilo-specific test
coverage in a Kilo-owned location and minimize merge conflicts with upstream.
Refactor providerCost to read `usage.raw.cost_details.upstream_inference_cost`,
which both `@ai-sdk/anthropic` (`convertAnthropicUsage`) and `@ai-sdk/openai`
(`convertOpenAIResponsesUsage`) populate with the verbatim OpenRouter usage
object. This unifies the Anthropic Messages and OpenAI Responses cost paths
through a single branch and removes the redundant `metadata.anthropic.usage`
branch (the SDK exposes the same data under both keys for Anthropic, and only
under `raw` for Responses).
They're upstream opencode comments, not kilo changes, so they
shouldn't live inside kilocode_change markers — and outside the
markers they add noise to this PR's diff. Drop them.
Move KILO_CONFIG_DIR profile fallback tests out of the shared upstream
instruction.test.ts into packages/opencode/test/kilocode/instruction.test.ts
to reduce future merge conflicts with opencode.
Add missing kilocode_change marker to the editorContext param in
the environment Effect.fn implementation; the interface signature
already had a marker but the implementation didn't.
For the Anthropic Messages API (via OpenRouter or Vercel AI Gateway), the
top-level `cost` field is the gateway fee that Kilo paid (typically 0 for
BYOK), not the user's true spend. Only use `upstream_inference_cost` /
`marketCost`; fall back to the token-based calculation when those are
absent.
Allow Azure provider connections to capture resource names or endpoint URLs so GPT-5 deployments can use the native Azure path instead of generic OpenAI-compatible setup.
Cost reporting already worked when Kilo used OpenRouter chat completions
internally. Extend providerCost to also read cost from the Anthropic
Messages API stream metadata, covering both OpenRouter (Anthropic-style
`usage.cost` / `cost_details.upstream_inference_cost`) and Vercel AI
Gateway (`gateway.cost` / `gateway.marketCost`).
Revert the file-wide marker shape fixes from fix-kilocode-markers.ts
since they touch unrelated code. Scope this PR to the two review
findings in the gpt-5 block:
- Replace nativeOpenAI refactor with upstream's if (===||===) form
plus inline // kilocode_change markers on the added npm entries;
restores the upstream reasoningSummary comment.
- Restore the upstream textVerbosity comments, keep the new provider
gate wrapped in kilocode_change start/end.
- Reverts the nativeOpenAI refactor; restores upstream's reasoningSummary
guard structure + comment so added npm entries stay inside a single
marker block.
- Includes the opencode textVerbosity comment that was dropped.
- Also fixes pre-existing marker shape issues elsewhere in the same file
flagged by script/upstream/fix-kilocode-markers.ts.