Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
504 changes: 114 additions & 390 deletions Cargo.lock

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ B2_VAULT_PATH=~/notes make app # open the desktop app on a folder of Markdow

Point it at an existing Obsidian vault or any folder of `.md` files. Without `B2_VAULT_PATH`,
the app asks you to pick a folder and remembers it. For chat, install
[Ollama](https://ollama.com) and run `ollama pull llama3.2`.
[Ollama](https://ollama.com) and run `ollama pull gemma4:e2b`.

The same engine runs from the terminal:

Expand Down
4 changes: 2 additions & 2 deletions crates/b2-cli/src/args.rs
Original file line number Diff line number Diff line change
Expand Up @@ -230,8 +230,8 @@ pub struct LlmArgs {
#[arg(long = "llm-url", value_name = "URL")]
pub llm_url: Option<String>,
/// The chat model id, as the server names it
/// [env: B2_LLM_MODEL, default: llama3.2]. Pull it first, e.g. `ollama pull
/// llama3.2`.
/// [env: B2_LLM_MODEL, default: gemma4:e2b]. Pull it first, e.g. `ollama pull
/// gemma4:e2b`.
#[arg(long = "llm-model", value_name = "MODEL")]
pub llm_model: Option<String>,
}
Expand Down
12 changes: 6 additions & 6 deletions crates/b2-embed/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@ description = "B2's real local embedder — candle-backed inference behind the b

[dependencies]
b2-core = { path = "../b2-core" }
candle-core = "0.9"
candle-nn = "0.9"
candle-transformers = "0.9"
candle-core = "0.11"
candle-nn = "0.11"
candle-transformers = "0.11"
# Download seam for `b2 init`. No default features (GH #174): the `tokio` default pulls the
# whole async HTTP stack for an API B2 never calls (we use `hf_hub::api::sync`). This also
# drops `native-tls`, so TLS is ureq's rustls + webpki-roots rather than the OS trust store:
Expand All @@ -29,9 +29,9 @@ thiserror = "2.0.18"
# On macOS, link Accelerate for candle's CPU matmuls; without it bge-base inference is
# ~10-100× slower. Other targets are unaffected.
[target.'cfg(target_os = "macos")'.dependencies]
candle-core = { version = "0.9", features = ["accelerate"] }
candle-nn = { version = "0.9", features = ["accelerate"] }
candle-transformers = { version = "0.9", features = ["accelerate"] }
candle-core = { version = "0.11", features = ["accelerate"] }
candle-nn = { version = "0.11", features = ["accelerate"] }
candle-transformers = { version = "0.11", features = ["accelerate"] }

# Run the forward pass on the Metal GPU (GH #40), additive over `accelerate`, with a CPU
# fallback (`model.rs::select_device`). Switching device is a model swap (the model id gains
Expand Down
9 changes: 5 additions & 4 deletions crates/b2-llm/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,10 @@ pub fn probed_provider(config: LlmConfig) -> Result<Box<dyn LlmProvider>, LlmErr
/// Ollama's OpenAI-compatible surface, the guided default (GH #151).
pub const DEFAULT_BASE_URL: &str = "http://localhost:11434/v1";

/// The default chat model: a 3B-class model that runs on the smallest supported (8 GB)
/// machine. Never downloaded by B2; an absent model is an error the adapters phrase (E4).
pub const DEFAULT_MODEL: &str = "llama3.2";
/// The default chat model: Gemma 4 E2B (about 2B active parameters), which runs on the
/// smallest supported (8 GB) machine and cleared `make eval-chat` on every question. Never
/// downloaded by B2; an absent model is an error the adapters phrase (E4).
pub const DEFAULT_MODEL: &str = "gemma4:e2b";

/// Environment variable naming the OpenAI-compatible base URL.
pub const ENV_URL: &str = "B2_LLM_URL";
Expand Down Expand Up @@ -114,7 +115,7 @@ pub enum ApiKeySource {
pub struct LlmConfig {
/// The OpenAI-compatible base URL, e.g. `http://localhost:11434/v1`.
pub base_url: String,
/// The model id as the server names it, e.g. `llama3.2`.
/// The model id as the server names it, e.g. `gemma4:e2b`.
pub model: String,
/// Bearer token for a cloud endpoint; `None` for a local runtime.
pub api_key: Option<String>,
Expand Down
18 changes: 6 additions & 12 deletions crates/b2-llm/src/setup.rs
Original file line number Diff line number Diff line change
Expand Up @@ -127,24 +127,18 @@ pub struct ModelTier {

/// The tiers, smallest first. Illustrative and non-binding: a starting point, not a
/// hardware floor.
pub const MODEL_TIERS: [ModelTier; 3] = [
pub const MODEL_TIERS: [ModelTier; 2] = [
ModelTier {
min_ram_gb: 0,
ram: "8 GB",
size: "3–4B (4-bit)",
model: "llama3.2",
size: "2–4B (4-bit)",
model: "gemma4:e2b",
},
ModelTier {
min_ram_gb: 16,
ram: "16 GB",
ram: "16 GB or more",
size: "7–8B",
model: "llama3.1:8b",
},
ModelTier {
min_ram_gb: 32,
ram: "32 GB or more",
size: "12–14B and up",
model: "gemma3:12b",
model: "gemma4:e4b",
},
];

Expand Down Expand Up @@ -589,7 +583,7 @@ mod tests {
assert_eq!(tier_for_ram(15).model, MODEL_TIERS[0].model);
assert_eq!(tier_for_ram(16).model, MODEL_TIERS[1].model);
assert_eq!(tier_for_ram(24).model, MODEL_TIERS[1].model);
assert_eq!(tier_for_ram(64).model, MODEL_TIERS[2].model);
assert_eq!(tier_for_ram(64).model, MODEL_TIERS[1].model);
assert_eq!(tier_for_ram(0).model, MODEL_TIERS[0].model);
}

Expand Down
2 changes: 1 addition & 1 deletion docs/evals.md
Original file line number Diff line number Diff line change
Expand Up @@ -310,7 +310,7 @@ moved or changed meaning.

## `make eval-chat`: the grounded-chat scores

Needs a model server (`ollama serve` + `ollama pull llama3.2`, or `B2_LLM_URL` /
Needs a model server (`ollama serve` + `ollama pull gemma4:e2b`, or `B2_LLM_URL` /
`B2_LLM_MODEL` at any OpenAI-compatible endpoint). Builds a throwaway vault from the
retrieval eval's corpus (chat is scored over notes whose retrieval behavior is already
characterized, so a surprise is attributable) and asks the labelled questions in
Expand Down
4 changes: 2 additions & 2 deletions docs/quickstart.md
Original file line number Diff line number Diff line change
Expand Up @@ -333,7 +333,7 @@ in your Markdown.
`b2 ask` streams an answer grounded in your own notes. B2 retrieves the most relevant
passages with the same hybrid search as step 6, hands the model only those, and the answer
cites them by `[n]`. It needs a model server: Ollama by default (`ollama serve`, then
`ollama pull llama3.2`); any OpenAI-compatible endpoint works via `--llm-url`/`--llm-model`.
`ollama pull gemma4:e2b`); any OpenAI-compatible endpoint works via `--llm-url`/`--llm-model`.

```console
$ b2 ask "why does spacing out reviews beat cramming?"
Expand Down Expand Up @@ -486,7 +486,7 @@ they are, `search` refuses rather than mixing embedding spaces.
| `B2_VAULT_PATH` | Vault root, so commands find it without `-C`. An explicit `-C`/`--vault` overrides it. Read-only commands fall back to the current dir; commands that write (`reindex`/`add`/`write`/`mv`/`rm`/`link`) require it explicitly |
| `B2_EMBEDDER=fake` | Offline mode: deterministic non-semantic embedder. Search runs keyword-only |
| `HF_ENDPOINT` | The standard Hugging Face mirror setting: the endpoint `b2 init` downloads from when the config's `source` names none |
| `B2_LLM_URL` / `B2_LLM_MODEL` | The OpenAI-compatible chat endpoint + model for `ask`/`chat` (defaults: `http://localhost:11434/v1`, Ollama's, and `llama3.2`). The `--llm-url`/`--llm-model` flags beat the env, which beats the default |
| `B2_LLM_URL` / `B2_LLM_MODEL` | The OpenAI-compatible chat endpoint + model for `ask`/`chat` (defaults: `http://localhost:11434/v1`, Ollama's, and `gemma4:e2b`). The `--llm-url`/`--llm-model` flags beat the env, which beats the default |
| `B2_LLM_API_KEY` | Bearer token for a cloud chat endpoint. An env var, never a flag, because a key in a flag is a key in `ps`. The desktop stores its key in the macOS Keychain instead |
| `B2_LLM=fake` | The deterministic chat provider: `B2_EMBEDDER=fake`'s sibling for `ask`/`chat` |
| `B2_LLM_MAX_TOOL_CALLS` | The most tool calls one model reply may carry in `b2 why` (default 64, allowed 1 to 4096). A reply over the cap fails with its own message rather than being cut short. An invalid value keeps the default and logs a warning. The desktop's Settings → Chat field overrides it |
Expand Down
18 changes: 9 additions & 9 deletions ui/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion ui/src/settingsview.ts
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ function chatModelFieldHtml(state: AppState, setup: ChatSetup | null): string {
: "";
return `<label class="field">Model
<input id="settings-chat-model" type="text" autocomplete="off" spellcheck="false"
value="${escapeHtml(current)}" placeholder="llama3.2" />
value="${escapeHtml(current)}" placeholder="gemma4:e2b" />
</label>
${pick}`;
}
Expand Down
Loading