Skip to content

Releases: dsaad68/ripple

0.7.0

Choose a tag to compare

@github-actions github-actions released this 09 Aug 14:42
1ff49fc

Added

  • /config → Lazy Tools: choose which tools are worth prefilling. A new tab with the feature
    switch, the retriever, how many matches a search returns, and a core / auxiliary tier per toolset
    and per configured MCP server. Core tools are in the model's prompt from the first token and are paid
    for on every query; auxiliary tools are not in the prompt at all - the agent finds them with
    search_tools and then calls them normally, so they cost nothing until they are needed, at the price
    of one extra round the first time. The tab carries a short explanation of that trade, and every row
    below the switch is visibly locked (and says why) until the feature is on.

    Off by default, and stored in settings.json under toolPolicy (toolSearch,
    auxiliaryMiddleware, auxiliaryTools, coreMCPServers, toolSearchModel, toolSearchLimit), so
    an existing project is unaffected until you open the tab. The MCP tier lives there rather than in
    mcp.json, which may be a shared .mcp.json that other tools read.

  • Retriever choice, with its download state. Space cycles lexical (no model)ColBERT 350M (8-bit)ColBERT 350M (bf16), each showing ready or not downloaded, 410 MB. The ColBERT
    encoders score every query token against every tool token (late interaction), which reads intent
    considerably better than term overlap; lexical needs no model at all. Both models appear in /model
    Local like any other, so they can be pulled ahead of time (ripple model pull mlx-community/LFM2.5-ColBERT-350M-8bit) and deleted. They can never be selected as a planner.

  • The launch banner reports lazy tools with a tool search row next to main agent / vision,
    naming the retriever and how many tools are held back (ColBERT 350M (8-bit) · 18 tools on demand).
    The count comes from the live agent, so a toolset tiered auxiliary but also disabled is not counted as
    available. No row when the feature is off.

  • /tools and /mcp show each tool's tier. A filled for a core tool, a hollow plus an
    [auxiliary] tag for one the agent has to search for, and a note on a toolset that is entirely
    auxiliary; /mcp shows tier: core|auxiliary beside each server's approval mode. Without this an
    auxiliary tool looked identical to a core one, which made a configured tier indistinguishable from a
    setting that had been lost.

Changed

  • Every /config tab says what it is for. Each one now opens with a blue ⓘ box naming what that
    tab governs and the trade-off you are making there - what a capability costs in prompt tokens, why
    a container is slower than the local shell, why the compaction threshold rather than the model's
    window is what keeps a session inside your memory, that the prefill cache is pure disk-for-speed.
    Only Lazy Tools had one before, as plain grey text; the rows' own summaries are unchanged.

  • /model → Local and Remote are the same view now. Local was a flat twenty-one-row list with the
    family repeated on every row, the repo id printed for all of them, no search, and nothing about the
    two numbers that decide whether a model fits. It has the Remote tab's two levels instead: model
    families
    first - split into LLM and Embedding, because a retrieval encoder has no LM head
    and picking one as a planner only fails at load - then that family's models when you press enter,
    under a heading per role (Text, Vision, Text + Vision for a unified VLM like Ornith
    that plans and sees images). A family is the model line, so LFM2.5's vision conversions sit
    inside it under the Vision heading rather than in a family of their own.

    Each model row is one line of aligned columns: ✓ on disk / ○ not yet, the weight format, the
    download size, the context window, and the tokens one turn may generate. The Hugging Face
    id, what the model is for, and the "default" note move to a subtitle under the highlighted row,
    which halves the list's height. Above it, the same context line the Remote tab carries.

  • Remote model rows carry what Local's do. The same ✓/○ marker, context window and output budget,
    in the same cells, grouped by the same role headings - so comparing a free remote model with one
    you could download is reading across rather than translating. Where a local row prices itself in
    gigabytes a remote one is simply free; the output budget comes from the catalog's
    max_completion_tokens, newly decoded.

  • Every list overlay says what it is. /model's three tabs, /tools and /mcp open with the
    same blue ⓘ box the /config tabs carry - what the list is, and what enter does to a row (which on
    Local and Remote changes as you drill in).

  • The Sandbox tab says it needs Apple Containers. A second amber ⚠ box under the explanation,
    titled needs apple containers: the sandbox runs on Apple's container tool, which is not part of
    macOS, and nothing on the tab hinted that its one switch depends on something you have to install.
    It names the install and container system start, and spells out what happens without it -
    failover falls back to the local shell, so commands still run, just unsandboxed. The README and
    docs carry the same prerequisite.

  • Lazy tools is flagged experimental. Its /config tab opens with an amber ⚠ box titled
    lazy tools - EXPERIMENTAL! rather than the blue ⓘ the settled tabs carry, and the text leads with
    why: a tool the model cannot see is a tool it may not think to look for, so a tiering that suits
    one project can quietly change how the agent behaves in another. The docs and README say so too.

  • The Local tab is searchable, like the Remote one. It carries the same bordered input: type to
    narrow the list, backspace to edit, ctrl-u to clear. The query matches a model's name, family, id,
    weight format and role, so thinking, gemma, 4-bit, vision and embedding all work, and the
    highlighted model stays highlighted as the query is refined. esc clears the query before it
    closes the overlay. Because printable keys are now the search, removing a model is ctrl-x, not
    x.

  • The banner wraps instead of clipping. In a narrow terminal the left pane cut its values off at
    an ellipsis - tool search ColBERT 350M (8-bit) · 35 tools o…, available mcps: deepwiki, … -
    which is exactly the text the banner exists to show. Values now wrap onto continuation lines
    indented under the label, and when the label leaves under ~18 columns beside it (a 58-column
    terminal) the value takes the whole pane on its own lines rather than being broken mid-word.

  • The banner and status line name the model family-first. LFM2.5 · 1.2B Instruct rather than a
    bare 1.2B Instruct, which said nothing about which 1.2B once several families were downloaded.
    Same in the vision row and the model-switch notes.

  • The Select tab's model picker and ripple model list carry the same facts. Picking a main agent
    or vision model shows each local option's purpose, weight format, size and context window; ripple model list is grouped by family and lists the context window and output budget alongside the size.

  • Lazy tools says what it costs on a small planner, and which toolset to move first. The /config
    tab and the docs now warn that the feature wants a capable planner - the smallest models search less
    reliably and one was seen answering from a tool's description instead of calling it, inventing a note
    it had never read (fixed upstream in DeepAgents, which now tells the model after every search that it
    received definitions rather than results). Both also name filesystem as the toolset worth making
    auxiliary first: a small planner surface-matches the request against the schema in front of it, so
    "list my apple notes" reaches for ls and "read my clipboard" for read_file, and taking those out of
    the prompt removes the wrong answer instead of arguing with it - 3/8 to 4/5 on a 2.6B, after three
    rewrites of the prompt had barely moved it. See STEPS/ISSUES/tool-search-small-planners.md.

  • --model no longer accepts a retrieval encoder. Planner ids are validated against the language
    catalog rather than the whole model catalog, so a ColBERT id is rejected up front instead of booting
    into a model that cannot load.

Fixed

  • The context meter read far below the truth. The status line's percentage was a running tally of
    what the UI watched stream past - the user's prompt, plus one per generated token - so it counted
    neither the tool schemas (paid on every request, and never streamed) nor any tool result (a file
    read, shell output, a search), which is most of a real context. An empty session showed 0% when the
    prompt already cost thousands of tokens, a turn that read a large file barely moved the needle, and
    automatic compaction fired at what looked like a fraction of the window. /fresh didn't reset it
    either. The meter is now measured from the agent - the new ReactAgent.contextTokens(threadId:),
    the same number the compaction trigger tests itself against - after every turn, compaction, model
    switch, /config rebuild and /fresh, and seeded at launch (so a resumed session opens with its
    real size). Per-token nudges still move it mid-turn; the measurement settles it at the end. This is
    the behaviour the compaction docs already described.

0.6.0

Choose a tag to compare

@dsaad68 dsaad68 released this 08 Aug 21:54
3f3f7b0

Added

  • A /config Context tab sets when the conversation is compacted, cycling 20-90% with
    space and showing what the threshold costs on the loaded model (20% - 52k tokens). Persisted as
    compactionPercent in settings.json (default 80, accepted range 10-99, project settings then
    ~/.ripple). Each model now reports the context window its own card documents instead of a
    pre-shrunk one - 131,072 on LFM2.5-2.6B, 128,000 on 8B-A1B and Gemma 4, 262,144 on Ornith and
    Qwen3.6 - so this threshold, not a smaller declared window, is what decides how large a
    conversation may get. It matters most on those large-window models: 80% of 262k is past what a
    laptop will carry, so lower it there and on any memory-tight machine.
  • Tools that ran at the same time are marked ∥N on their cards. A round's read-only tools
    (grep, ls, tree, reads, git_*) now execute concurrently in DeepAgents, but three cards
    each reading 0.1s are indistinguishable from three sequential calls - the round costs one wait
    instead of three and nothing said so. The marker rides the card's top border next to the
    duration, in the accent color, and shows the size of the group. A call that ran on its own shows
    nothing, so ordinary rounds are unchanged.
  • stream-json lines carry callID, and tool_started lines a batchID. A round's parallel
    calls interleave - three tool_started for read_file, then their tool_completed lines in
    whatever order the reads finish - so a consumer must pair on callID rather than on name.
    batchID is shared by the calls that ran together and absent from those that ran alone.

Changed

  • Vision is off by default; turn it on in /model's Select tab. The vision subagent is a
    second model to download, load and keep resident, and most sessions never delegate a screenshot
    to it - so a fresh project now starts without one and fetches no VLM. A preset still suggests the
    VLM that pairs with it; the Select tab offers that suggestion rather than enabling it unasked.
    Projects that already set visionModel in settings.json are unaffected. The banner reports
    vision none until a model is picked, and ripple model download default fetches the planner
    only.
  • deepagents-swift 0.5.0 -> 0.6.0. Brings the round's parallel tool calls, the search tools no
    longer reporting a truncated walk as "no matches", the agent being told which folder it works in,
    a run never ending on an empty answer, and each model reporting the context window and output
    budget its card documents.

Fixed

  • A failed tool call is drawn as failed. Tool cards showed a green success tick on calls that
    had done nothing - read_file given a URL rendered as ✓ beside Error: no file at "https://…" -
    because most built-in tools return their errors rather than throwing, and the runtime reported
    those as completions. Ripple's rendering was already right; it was being told the wrong thing.
    Fixed in DeepAgents (ToolOutput.failure), so the card, the ∥N grouping and the stream-json
    tool_failed lines now agree with what happened.
  • A tool's result reaches the card it belongs to. The transcript matched a result to "the last
    unfinished step", which was unambiguous only while a round's tools ran one at a time. With
    several open at once it attached results, streamed progress and failures to whichever card
    happened to be last. Steps now route on the tool call's id, falling back to the old rule for a
    step restored from a saved session, which has no call to name.

0.5.0

Choose a tag to compare

@dsaad68 dsaad68 released this 08 Aug 21:54
33dd193

Added

  • A Cache tab in /config, for the on-disk prefill cache. The Prefill cache toggle moves here
    from Capabilities, and joins two limits and a listing of what the store is actually holding:
    Snapshots per model (2/4/6/8/12) and a total Size limit (1/2/4/8/16 GB, or no limit),
    both cycled with space, plus a row per model showing its size - x deletes that model's saved
    prefixes, or all of them on the "All models" row. Lowering a limit prunes immediately rather than
    at the next save. Persisted as prefixKVSnapshotsPerModel and prefixKVMaxGigabytes in
    settings.json, and honored by headless runs.

Fixed

  • /mcp grouped tools by name prefix, so two similarly named servers showed each other's
    tools.
    The dispatch prefix is normalized, so parallel-search and parallel_search both yield
    parallel_search__ and matching on it cannot tell their tools apart. Grouping now asks the tool
    which server contributed it (deepagents-swift's ServerScopedTool).

Changed

  • deepagents-swift 0.4.0 -> 0.5.0. MCP tool names are now normalized in both directions, so a
    hyphenated server is reachable: a parallel-search server's tools dispatch as
    parallel_search__*, and a call the model spells differently still finds its tool. /mcp and
    /tools show the normalized names.

0.4.0

Choose a tag to compare

@github-actions github-actions released this 04 Aug 22:43
5070272

Added

  • LFM2.5 2.6B in the catalog, the /model picker, and --model - a general-purpose 2.69B
    instruct planner in four precisions: LiquidAI/LFM2.5-2.6B-MLX/mxfp4 (~1.6 GB), /mxfp8
    (~2.8 GB), /8bit (~2.9 GB) and /bf16 (~5.4 GB). It runs at its full 128k context window and
    the card's repetition_penalty 1.1. It reasons before answering, and that reasoning is surfaced
    on Ripple's separate reasoning channel rather than mixed into the reply. No new DeepAgent preset -
    select it with --model <id> or the /model Local tab.
  • Model ids can now name a precision subfolder. LiquidAI publishes all four 2.6B precisions in
    one repo, so those ids carry a third component (LiquidAI/LFM2.5-2.6B-MLX/mxfp4). Each precision
    pulls, lists, and removes independently; ripple model pull on the bare repo is rejected, since
    it names eight precisions rather than a model.

Changed

  • ripple model pull <precision> downloads only that precision (previously the glob would have
    matched every precision in a shared repo), and ripple model rm <precision> removes only that
    one - reclaiming its disk space while leaving any sibling precisions installed and loadable.

0.3.0

Choose a tag to compare

@github-actions github-actions released this 07 Jul 23:38
48536ea

Added

  • New on-device reasoning models in the catalog, the /model picker, and --model:
    • Ornith-1.0-9B (mlx-community/Ornith-1.0-9B-4bit / -8bit) - plans with <think>
      reasoning and native tool calls, and sees images, so it appears in both the planner and
      vision pickers plus a new DeepAgent (Ornith) preset that uses it for both roles.
    • Qwen3.6 (mlx-community/Qwen3.6-27B-OptiQ-4bit ~20 GB, Qwen3.6-35B-A3B-OptiQ-4bit
      MoE ~24.7 GB) - the strongest local planners in the catalog; text-only.
    • Gemma 4 E4B (mlx-community/gemma-4-e4b-it-8bit ~9 GB, gemma-4-e4b-it-OptiQ-4bit
      ~7.5 GB) - reasons in Gemma's thought channel with native tool calls; a new
      DeepAgent (Gemma 4) preset pairs it with the LFM2.5 VLM for vision.
      All run with their model cards' recommended sampling and a 40k on-device context window.
  • Prefill cache. The agent prompt's computed state is reused across rounds, queries, and now
    processes - the base snapshot persists to disk, so a fresh ripple launch resumes it instead
    of re-prefilling the ~10k-token system+tools prompt (cold prompt processing ~14 s → ~0.2 s
    measured on Ornith 9B). Toggleable in /config ▸ Capabilities as Prefill cache
    (prefixKVCache in settings.json), honored by the REPL and headless runs.
  • Apple Notes tools. The agent can list, read, create, and update Apple Notes
    (apple_notes toolset; writes are approval-gated, reads are not).
  • /tools browser - a two-level browser of the agent's tools grouped by toolset, with each
    tool's description, parameters, and a [needs approval] badge.
  • ripple works in its launch directory. Filesystem tools and the @ picker root at the
    directory ripple was started in, and each session's transcript is written to
    .ripple/sessions/ inside it (--log <dir> overrides).
  • Bordered three-choice approval prompt (Approve / Reject / Always allow, arrow keys or
    a/r/A) and a gradient ASCII-art launch wordmark.

Fixed

  • Failures are never silent. A turn that dies mid-generation ends with a red
    ✗ turn failed - <reason> line under whatever streamed (the loader's real reason included),
    instead of an empty answer. A broken planner no longer keeps ripple chat from starting:
    launch falls back to the default model when it's on disk, or opens on the chosen model anyway
    and retries on the first message - either way a transcript note says what happened. A failed
    /model switch notes the failure and keeps the current planner. Headless runs print the
    loader's recorded reason and exit non-zero.
  • Download progress is real. Multi-GB pulls no longer sit at 0% (the hub's Xet transport
    reports no incremental progress; the bar now blends live in-flight bytes), the /model Local
    tab draws its progress bar inside the panel (it was hidden behind the menu) with esc to
    cancel, and a cold (re)load names its phase - loading <model> into memory…,
    prefilling the prompt… - instead of a bare "working…".
  • The tokens/sec readout measures real decode speed - every generated token (reasoning +
    answer) over active decoding time, excluding prefill, tool runs, and round transitions.
  • A turn renders in the order it happened. Reasoning / tool / plan / answer blocks keep
    their streamed sequence instead of being grouped by type.
  • ask_user (and every tool with nested array/object parameters) works on the Ornith,
    Qwen3.6, and Gemma 4 planners
    - tool schemas are now passed into generation so nested
    values arrive typed.

0.2.5

Choose a tag to compare

@github-actions github-actions released this 29 Jun 15:01
0380bd6

Added

  • AWS Bedrock API keys (bearer-token auth). A bedrock model can now authenticate with an Amazon
    Bedrock API key instead of AWS SigV4 credentials. Put the token in the model's apiKey field (e.g.
    "$AWS_BEARER_TOKEN_BEDROCK") and set a baseURL; requests are then sent with
    Authorization: Bearer <token>. Resolution order is apiKey -> the AWS_BEARER_TOKEN_BEDROCK
    environment variable -> SigV4 access-key credentials, so existing SigV4 setups keep working
    unchanged. See the Bedrock section of the remote-models docs for both configurations.

0.2.4

Choose a tag to compare

@github-actions github-actions released this 26 Jun 10:51
f9b4e9f

Fixed

  • Up/Down arrows move between the lines of a multi-line prompt. In the ripple chat input box the
    arrow keys now move the caret one visual row up or down -- across hard newlines and soft-wrapped rows
    alike -- and fall back to prompt-history recall only at the top/bottom edge (the familiar shell
    behavior). The column is preserved per press. Single-line and empty input keep history recall, and
    the ask_user card's choice navigation is unchanged.

Packaging

  • Homebrew tap. ripple is now installable as a prebuilt Apple Silicon binary -- no Xcode
    required:
    brew install dsaad68/tap/ripple
    Each release is built on a self-hosted runner, attached to the GitHub Release as a macos-arm64
    artifact, and the tap formula is bumped automatically. Building from source via
    brew install --HEAD ./Formula/ripple.rb still works.