Skip to content

1.29.0

Choose a tag to compare

@github-actions github-actions released this 28 Oct 03:08
· 85 commits to main since this release
97bd4d0

🌟 Karpathy LLM Wiki v1.29.0

Highlights

  • Ingest no longer dies when the model thinks. One output ceiling pays for reasoning, the answer, and formatting together, so a budget sized from the answer alone starves on any model that reasons. Extraction now declares the model's own ceiling — 128,000 by default — and lets the model stop when it is done. Reported against MiniMax during this release's own testing and fixed inside it.
  • The query path reads the page bodies now. The lexical stage used to score titles, aliases and summaries; it scores body text too, through BM25F. This is the single largest recall change in the project's history, and it is on by default.
  • Two-stage query expansion, with the claim its own measurement narrowed. The corpus supplies candidate terms, the model picks from them, and the second pass reads the new results. The weighted form is not measurably better than plain concatenation, so the simpler one shipped.
  • One hub can no longer capture every related list. Related-page shaping, plus hub-link distinctiveness, so a page linked from everywhere stops dragging every other page toward it.
  • An escape hatch, because a default-on ranking change deserves one. legacyScorer in Advanced settings restores the old ordering for a vault where the new one misfits.

What's in this release

Added

  • Body-aware lexical scoring (PR #837). BM25F over title, aliases, summary and body, with a length-normalised body term so long pages do not win on volume alone.
  • Two-stage Rocchio query expansion (PR #855, Issue #729). Corpus-derived candidate terms, model selection, then a second retrieval pass on the expanded query.
  • Related-page shaping and hub-link distinctiveness (PR #841). Shaping caps a single hub's pull on a related list; distinctiveness discounts links that every page carries.
  • legacyScorer switch in Advanced settings, in all eleven locales (PR #842). The previous ranking, restorable without a rollback.
  • The answer budget is 16,000 tokens, and the pipeline says when it runs out (PR #852). Doubled from 8,000, with an explicit Notice at the ceiling instead of silent truncation.
  • The term index is built once per session (PR #843), and re-scored when a page body changes (PR #844). 4.4 s per question became a one-time cost.
  • Two measurement instruments in tools/ (PRs #875, #881). Conversation-history evaluation and answer-context cost, both driving production code rather than a reimplementation of it.

Changed

  • Extraction asks for the model's own output ceiling instead of 16,000 (PR #905, Issue #904). While thinking is possible the request declares the ceiling and the model stops early; an unused ceiling costs nothing and a short one costs the whole batch. 128,000 is the starting assumption — OpenAI GPT-6 and Anthropic Opus/Sonnet 5.5 all publish 128K, Gemini 3.5 Flash publishes 65K. A provider whose real limit is lower is learned by halving twice inside the first batch, and only when the rejection names the output ceiling. With thinking switched off the request narrows to the answer need, exactly as before.
  • Three new controls, all in LLM Advanced Parameters (PR #905). Max output tokens per call was already there for local-model users and is now visible to every provider — it had been gated to ollama / lmstudio / custom / anthropic-compatible, which is exactly the set that did not include the provider that failed. Model context window is new and bounds the ceiling, so a 4K local model never receives a 128K request. Thinking level is new and offers default / low / medium / high.
  • The AI SDK translates the thinking level, and the plugin no longer does (PR #905). A level now travels as one call option; @ai-sdk/anthropic maps it through its own effort table and downgrades a request to stop thinking into effort: 'low' with a warning on models that always think, and @ai-sdk/openai validates it against each model's supported set. The hand-written thinking: disabled this replaces was a guaranteed 400 on Claude Opus 5.5.
  • AI SDK v7 and provider spec v4, together (Issue #764, PR #859, first attempt PR #786). All five packages crossed a major version at once, because a partial bump left the @ai-sdk/* packages on a spec that no longer matched ai.
  • Citations read in academic form, the composer grows with its content, and "clear history" clears the record (PR #857).
  • legacyScorer is the documented way back (PR #842). If the new ordering misranks your vault, flip it and open an issue with the query; that is how the next round gets measured.

Fixed

  • A reasoning failure is reported as one, not as a context-window failure (PR #905, Issue #904). The first-batch classifier tested for the word token before anything else, and the reasoning guard's message says "spent 16,000 of 16,000 output tokens on reasoning" — so the accurate sentence was replaced by advice to find a model with a bigger context window, which cannot fix a reasoning runaway. It is now classified by a marker, most specific first. The same block also pointed at Settings → LLM Configuration → Context Window, a control this plugin has never had.
  • Ingest stops logging three placeholder warnings per source (PR #905, Issue #904). The extraction prompt is rendered twice on purpose, and the first pass deliberately leaves three markers for the second. They were being reported as unknown on every run.
  • The automatic watcher honours Obsidian's excluded-files list (PRs #865, #879, Issue #503, #872). A file in an excluded folder no longer triggers ingest.
  • A custom Anthropic base URL resolves against the models the gateway actually carries (PR #851). Three defects on one MiniMax custom endpoint, including a probe that asked for a model the gateway did not host.
  • Dead-link fixes no longer disappear while the log reports them applied (PR #823). Same-page fixes are serialized per source and every write outcome is checked.
  • SDK errors are classified by their marker, not by instanceof (PR #893, Issue #892). A duplicated AI SDK instance used to make every error unrecognisable.
  • The log header's command hint refreshes (PRs #866, #887, Issue #876), the legacy log-header cut keeps its first entry (PR #889, Issue #888), and machine-identifier entity names are dropped (PR #894).
  • Lint's fix path: self-pairs, orphan links and duplicate verification (PRs #829, #864, Issues #823, #824, #826, #827).
  • cancelIngestion aborts in-flight model calls (PR #867, Issue #703).
  • The settings panel no longer jumps to the top (PR #794, Issue #752). Long-standing report from a user who also wrote the fix.
  • Two Notices pointed at settings that did not exist (PRs #820, #871).
  • Two HIGH dependency advisories (PRs #813, #884), and vite 8.3.5 in both lockfiles (PR #901). The npm lockfile had been pinned to 8.2.1 since #861, because that PR moved vite in pnpm-lock.yaml only, and CI runs pnpm audit alone.

Dependencies

  • ai 6.0.230 → 7.0.142, @ai-sdk/openai 3.0.86 → 4.0.91, @ai-sdk/anthropic 3.0.98 → 4.0.65, @ai-sdk/openai-compatible 2.0.62 → 3.0.57, zod 4.6.5 → 4.6.7. Dependabot: vite (#861), fast-uri (#868), eslint (#869).

Upgrading from v1.28.0

One-click update via Obsidian Settings → Community plugins. Your wiki, your settings and your data.json are untouched: no setting was renamed or removed, and no page needs rewriting.

The ranking changed, and it is on by default. That is the point of the release, and it is also the one thing you may want to undo. legacyScorer in Advanced settings restores the previous ordering instantly.

If you sync plugins with Obsidian Sync Standard, this release matters. v1.28.0's main.js was 4,583,585 bytes; the AI SDK v7 upgrade pushed it to 5,188,175, over the 5 MB per-file cap Sync Standard applies. It is 4,876,194 here, and a test now holds it under 5,000,000 so the next dependency bump fails the build instead of reaching your vault.

What's accepted (and why)

  • The 5 MB figure is a Sync transport cap, not a submission rule. Obsidian's plugin submission requirements and developer policies state no size limit, and the directory review passed while the bundle was over the cap. It affects Sync Standard users who enabled community-plugin sync, which is opt-in per file type. It is fixed regardless.
  • charset: 'utf8' is the fix rather than minification. Non-ASCII characters had been shipping as \uXXXX escapes — six bytes where UTF-8 needs two or three — and the plugin carries eleven UI locales inline. The change is byte-level only: both builds were parsed and compared node by node, 1,904,515 AST nodes, no semantic difference. Minification would have bought more room and cost readable stack frames.
  • This release's own code is a tenth of its size growth. 63 KB against the AI SDK's 678 KB. The guard exists because nothing chose the total.
  • AI SDK v7 has tests, not a live endpoint. 5,096 tests pass, and no request was sent to a real provider from CI. If you hit a provider-specific failure, it is worth an issue with the request shape.
  • 128,000 is an assumption about your model, not a fact. It is the current-generation mode, and the first batch halves it twice if your provider refuses it. The alternative — sizing the ceiling from the answer — is what failed here, twice, on a model whose real limit nobody had written down.
  • pnpm lint:tools-bot had never run. It threw an ESLint ConfigError on every invocation since ESLint began rejecting a config that registers the same plugin twice. Its first real run found 15 findings in dev-only tooling; four are fixed here.
  • #895 (extraction focus and content requirements) is not in this release. It carries a real decision: the setting can promise a section the write path then deletes, and that is a question about what it may promise, recorded in #902. Merge wiring for the other half is agreed and will follow.

Installation

  1. From Obsidian — Settings → Community plugins → Browse → search "Karpathy LLM Wiki" → Install (or Update, if you already have it). Then toggle Enable.
  2. From the marketplace — community.obsidian.md/plugins/karpathywiki → Add to Obsidian.
  3. Manual — only needed for a specific version or without the in-app marketplace. Take main.js, manifest.json and styles.css from this release.

Configuration

Nothing needs configuring. The new ranking is on by default, and the release adds one switch plus three controls:

  • Advanced settings → legacyScorer — restores the pre-1.29.0 ordering for a vault where the new one misranks.
  • LLM Advanced Parameters → Max output tokens per call — default Auto, which asks for the model's own ceiling. Lower it only if your provider rejects large values or bills reserved tokens.
  • LLM Advanced Parameters → Model context window — default Auto. Set it when you know the real window and it is small, so the output ceiling cannot exceed it.
  • LLM Advanced Parameters → Thinking level — default sends nothing and lets the model choose. Shown only while thinking is enabled; the existing toggle owns on and off.

The 16,000-token answer ceiling for questions is a built-in constant (TOKENS_QUERY_ANSWER), not a field. It was raised from 8,000 and the pipeline now posts a Notice when a question reaches it, instead of truncating in silence.

Tests

5,096 tests passing (369 files). Up from 4,372 / 313 at v1.28.0 — +724, including the ones that pin the body-aware scorer against a fixture vault, the expansion's narrowing claim, the size guard, the reasoning-budget rule in both directions, and a translation guard that fails when a locale still holds English text.

Contributors

  • @green-dalii (Greener-Dalii) — Maintainer. Most of this cycle: the #729 read and write tracks (#837, #841, #842, #855), the term-index cache (#843) and its body-keying fix (#844), the answer budget (#852), the AI SDK v7 coordination (#859), and the release preparation.
  • @DocTpoint — Architect-level contributor and co-maintainer. Three PRs: #806 (one tag list shape), #809 (stub frontmatter through the serializer), #818 (a successful Codex connection test leaves the plugin ready). Also reported the excluded-files gap (#503).
  • @NotAFlightRisk — Two PRs: #820 (the quick fixes Notice pointed at the setting that hides it) and #871 (the debounce clamp Notice states its real range). Both are the kind of detail that makes a settings panel trustworthy.
  • @juliasadler — PR #867: cancelIngestion now aborts model calls already in flight, which is #703's hang.
  • @Noumenon-ai — PR #833: same-page dead-link fixes are serialized and their writes verified.
  • @konstantinopolka — Four reports in the lint fix path (#823, #824, #826, #827), each with the failure mode named. Three of them are fixed here.
  • @abhinav-neander — PR #794: the settings panel keeps its scroll position across a rebuild (#752).
  • @iveteamorim — PR #786: the first AI SDK v7 upgrade attempt. It is why the coordinated version (#859) knew what to bump together.
  • @aisahpA — Reported the settings jump (#752) and the query panel layout (#756).
  • @issaqua — Reported that changes to schema/config.md were ignored (#317), now fixed.
  • @wstczyw — Reported a dead link resolving to its own source (#676).
  • @newdeme — Reported the LM Studio model dropdown dropping Hub-managed models (#758).
  • @weqoocu — The machine-identifier entity-name guard that shipped as #894, and the prompt-customisation work in #895, which carries a decision and is not in this release.
  • @dependabot — PRs #861, #868, #869.

Full Changelog

1.28.0...1.29.0