Skip to content

Releases: BolivarTech/magi

v0.6.0

09 Jun 18:20

Choose a tag to compare

BREAKING: the default backend with no magi.toml/env changed from Anthropic
to Ollama (http://localhost:11434/v1, kimi-k2.6:cloud + the qwen3.5/gpt-oss/deepseek
trio). Anthropic still works but is now opt-in (provider = "anthropic" or
MAGI_PROVIDER=anthropic).

Added

  • src/defaults.rs — single source of truth for the built-in default profile.
  • --init-config CLI flag and /init-config TUI command to scaffold a default magi.toml.
  • Startup notice (when no magi.toml) and an actionable error (when Ollama is unreachable),
    both DRY-interpolated from the default constants.

Changed

  • resolve_provider/resolve_openai_base_url defaults → Ollama-first.
  • resolve_openai_model no longer errors when unset — returns the built-in default.
  • The MAGI trio defaults to qwen3.5/gpt-oss/deepseek on the openai path when [magi] is absent.

Known limitations

  • The built-in defaults assume Ollama. If you point provider=openai at real OpenAI
    (or another non-Ollama service) WITHOUT setting OPENAI_MODEL / [openai].model / [magi],
    the defaults (kimi-k2.6:cloud + the :cloud trio) will not exist there — set them
    explicitly.
  • The default :cloud model tags reflect the Ollama catalog at release time and may rot over
    time; refresh per release. They live in one place (src/defaults.rs) for easy maintenance.

Full Changelog: v0.5.2...v0.6.0

v0.5.2

09 Jun 04:37

Choose a tag to compare

Reasoning-model streaming (#24). Reasoning models (e.g. kimi-k2.6:cloud,
deepseek-r1) stream their chain-of-thought in delta.reasoning with empty
delta.content; the OpenAI-compatible parser previously ignored it, so the TUI
showed a frozen blank during a long reasoning phase. TUI/provider only — the agent
loop, persistence, crypto, and /consult are unchanged.

Added

  • Live "thinking" feedback for reasoning models. By default a compact
    🤔 MAGI Pensando… indicator with an animated spinner shows while the model
    reasons, instead of a frozen blank. The reasoning text itself is never
    persisted
    to the encrypted store.
  • /toggle-show-thinking switches between the compact indicator (default) and
    a verbose mode that streams the full chain-of-thought inline (useful for
    debugging). Added to /help.

Fixed

  • Reasoning-model chats no longer appear frozen: the parser now surfaces
    delta.reasoning as a distinct stream instead of dropping it.

Known limitations

  • In the verbose mode (/toggle-show-thinking), the reasoning and the answer are
    streamed into the same message bubble and can visually run together; the default
    compact mode is unaffected.

Full Changelog: v0.5.1...v0.5.2

v0.5.1

09 Jun 02:27

Choose a tag to compare

TUI usability patch — makes long output (notably the /consult report) readable.
TUI-only; the agent loop, providers, persistence, and crypto are unchanged.

Added

  • Conversation scrollback. Scroll the history line-by-line with /, by page
    with PgUp/PgDn, and to the top/bottom with Home/End. The pane follows the
    tail by default and snaps back to the newest content on a new/streaming reply.

Fixed

  • Tall messages were truncated. A single message taller than the pane (e.g. a
    MAGI consult report) previously showed only its tail with no way to scroll up; it
    is now fully reachable via the new scrollback.
  • Markdown/table indentation was lost. wrap_message now returns a fitting line
    unchanged, preserving leading indentation and internal alignment spaces (bullets,
    ASCII tables, box-drawing). Wrapping is measured in terminal display columns, so
    CJK/emoji (2-column) glyphs no longer wrap a column early.
  • Long prompts were cut off at the right border. The input box now grows (up to
    6 rows) and wraps long/multi-line prompts instead of truncating them.

Known limitations

  • wrap_message still collapses internal whitespace when reflowing a line that is
    wider than the terminal (word-boundary wrap); fitting lines are untouched. Mid-
    prompt cursor placement in an input taller than 6 rows is approximate (exact while
    typing at the end).

Full Changelog: v0.5.0...v0.5.1

v0.5.0

08 Jun 19:35

Choose a tag to compare

Per-agent model selection for the three MAGI perspectives (Melchior / Balthasar /
Caspar). Additive and backward-compatible — the Provider trait, the agent loop,
config discovery, the consult tool, MagiCoreProviderAdapter, and encrypted
memory are unchanged; with no [magi] configuration the behavior is identical to
v0.4.0.

Added

  • Per-agent MAGI model selection via magi.toml [magi] section and
    MAGI_MODEL_{MELCHIOR,BALTHASAR,CASPAR} env vars. Opt-in; absent = all three
    perspectives share the principal model (backward compatible). Overrides reuse
    the principal backend's endpoint/key and vary only the model — true
    cross-family lineage diversity requires an Ollama-style multi-family endpoint.

Full Changelog: v0.4.0...v0.5.0

v0.4.0

07 Jun 10:18

Choose a tag to compare

First step of the multi-backend MAGI integration: the magi-core crate (already
declared but unused) is now wired in, giving the agent a three-perspective
consensus
capability (Melchior / Balthasar / Caspar). Additive only — the
Provider trait, the agent loop, config discovery, and encrypted memory are
unchanged.

Added

  • consult tool — exposes magi-core's 3-perspective consensus as a tool the main LLM can invoke autonomously when a question has genuine trade-offs. Routing emerges from the existing tool loop (no separate classifier); each call passes the inline approval gate, which doubles as cost control for the ≈ 3 model calls.
  • /consult <question> command — forces a MAGI consensus directly in the TUI, bypassing the router and approval, rendering the verbatim report (three perspectives + verdict). Runs analyze in a joined task so a panic in magi-core surfaces as a recoverable error instead of killing the runner; blocks the session while it runs, like a normal turn.
  • MagiCoreProviderAdapter (src/agent/magi_adapter.rs) — bridges magi-rs's resolved Provider to magi_core::provider::LlmProvider, so the consensus reuses the same backend + credentials (Anthropic or any OpenAI-compatible endpoint). No second LLM config layer.
  • StaticProvider guardconsult is registered (and /consult works) only when a real provider is configured; on the static/no-key path the tool is absent and /consult reports that a provider is required.
  • Degraded surfacing — a consult that completes with fewer than three agents is prefixed [DEGRADED: …] so a low-quality consensus is never silent.
  • New tests for the adapter (assembled text, role-fold delimiter, error mapping), the tool (contract + consensus + invalid-args + empty-query + oversized-query + backend-error via magi-core's RoutingMockProvider), and the /consult parser + a full-report render-safety test. Total tests: 147 (was 136).

Changed

  • magi-core dependency bumped 1.01.1 (no features enabled; reqwest 0.12 is not pulled — the adapter reuses magi-rs's existing reqwest 0.11 stack). test-utils enabled as a dev-dependency for RoutingMockProvider.

Security

  • The verbatim consult report (LLM-generated) is run through sanitize_text before rendering — strips ANSI escapes / control characters, matching the streaming-delta path. Consult input is length-capped (8192 bytes) on both the tool and forced /consult paths, and empty queries are rejected before any model call.

Known limitations

  • System-prompt fold. magi-core differentiates its three personas via distinct system prompts, but magi-rs's Provider has no system-role channel yet, so the system text is folded into the user turn (behind an explicit delimiter). On weak / small local models this can weaken persona divergence and JSON adherence. Revisit when magi-rs gains a system-prompt channel.
  • CompletionConfig not applied. The adapter does not forward max_tokens / temperature to the backend (the Provider trait exposes no per-call knobs). Deferred.
  • Deferred follow-ups (internal dev-docs): repetitive-call detection keyed on the consult query argument, and an InputTooLarge early-rejection UX for oversized /consult input.

Full Changelog: v0.3.1...v0.4.0

v0.3.1

26 May 06:58

Choose a tag to compare

TUI rendering hotfix — two pre-existing UX bugs found during the 0.3.0
end-to-end smoke (long-reply truncation + new-message scroll-off). Both
affect all providers (Anthropic, OpenAI-compatible, Static). Render-only,
no API / trait / contract changes.

Fixed

  • Conversation pane truncated long messages at the panel's right border instead of wrapping. New wrap_message helper (src/tui/mod.rs) word-wraps each message by chars().count() (UTF-8 char-safe) to the panel's inner width, preserves existing \n as hard breaks, and hard-splits absurdly long words. One message stays one ListItem so Selection / Visual navigation (app.selected_index → app.messages[i]) is unchanged.
  • Conversation pane did not auto-scroll when new messages overflowed the bottom. New effective_selection / effective_highlight_symbol helpers pin the last message as the selected row in Normal mode (ratatui's List auto-scrolls to keep the selected item visible) while suppressing the ">> " highlight prefix so the pin is invisible. Selection / Visual modes still show the prefix and use the user-chosen index.
  • Streaming tail of a tall response stayed off-screen (and on some terminals "jumped/reset" when the message exceeded the conversation pane). The follow-tail fix now tail-truncates the rendered last message in Normal mode to its trailing viewport_inner_height wrapped lines, so streaming visibly scrolls line-by-line. Selection / Visual modes still render every wrapped line so the full message remains reviewable via Ctrl+S → ↑.

Added

  • 15 new tests covering the four render-time helpers (wrap_message: word wrap normal / multibyte / oversized word / embedded newlines / width-0 / empty; effective_selection: follow-tail in Normal mode / chosen index in Selection / Visual / empty messages; effective_highlight_symbol: by mode; tail_lines: keeps last N / unchanged when max≥len / max=0 no-op / empty / shift-by-one streaming tick). Total tests: 136 (was 121).

Known limitations

  • Leading indentation and internal whitespace runs are collapsed when a message is wrapped. wrap_message uses split_whitespace, which drops leading spaces and multi-space gaps. Markdown bullets like " - item" render as "- item"; preformatted blocks lose alignment. Tracked for a follow-up patch (preserve per-line indentation via a different tokenizer).
  • Wrap width is measured in chars().count(), not terminal display width. CJK / emoji glyphs that occupy two cells will wrap one column early; combining marks may wrap one column late. Tracked for a follow-up that switches to unicode-width.

Full Changelog: v0.3.0...v0.3.1

v0.3.0

26 May 03:41

Choose a tag to compare

First multi-backend release. Magi can now talk to any OpenAI-compatible Chat
Completions endpoint — local Ollama, OpenAI, Groq, OpenRouter — selected by
a new magi.toml, alongside the existing Anthropic Messages API path. No
regression: the Anthropic surface and all its tests are byte-equivalent.

Added

  • OpenAiCompatibleProvider (src/agent/provider.rs) — Chat Completions over {base_url}/chat/completions with stream:true, a stream::unfold SSE state machine that finalizes on finish_reason / [DONE] / stream-end with an idempotent done guard (MessageDone emitted exactly once), data: prefix tolerant of optional space, malformed lines swallowed, HTTP non-2xx surfaced as Err, MAX_SSE_BUFFER_BYTES (8 MiB) cap. Constructor takes a named-field OpenAiSettings struct (no positional same-type swap).
  • magi.toml configuration (src/config.rs) — MagiConfig / OpenAiConfig / AnthropicConfig, serde(deny_unknown_fields) so typos (and api_key) fail at parse time, env > TOML > defaults precedence (MAGI_PROVIDER / OPENAI_BASE_URL / OPENAI_MODEL). MagiConfig::load distinguishes NotFound (silent default) from other I/O errors (surfaced as a TUI startup notice). Reference magi.toml.example is committed; user-local magi.toml is gitignored.
  • Coalesced map_messages / map_tools. Same-turn parallel Content::ToolUse blocks collapse into ONE assistant message with a tool_calls array; User Text/ToolResult are emitted in content order (each block as its own OpenAI message). Tool::input_schema forwards as tools:[{type:"function",function:{…}}].
  • Bounded tool-call accumulator. MAX_TOOL_CALL_SLOTS = 64 caps streamed tool_calls[].index; over-cap warns (eprintln) instead of dropping silently (RF-8). Orphan arguments fragments (slot has neither id nor name yet) are skipped with a warning to prevent mis-attribution.
  • tests-121 (was 95). 26 new tests — config parsing & precedence; coalesced message mapping; mixed-content User ordering; OpenAI text streaming (with [DONE], without [DONE]/finish_reason, malformed line, HTTP error, stream-end-only finalize); fragmented tool_calls assembly; bounded index; post-stop TextDelta suppression; args-before-id skip; resolve_provider wiring.

Security

  • OPENAI_API_KEY from environment only. Never read from magi.toml; deny_unknown_fields rejects an api_key field at parse time. The dummy "ollama" fallback for local Ollama is documented inline; real backends fail loudly with 401 if the env var is unset.
  • Keyring separation unchanged. The Anthropic key (magi-rs) and DB master key (magi-rs-internal) remain in separate keyring services; test_agent_history_resilience_to_key_rotation is untouched.

Documentation

  • README "Configuration: magi.toml" section — full precedence table for the four settings (MAGI_PROVIDER/OPENAI_BASE_URL/OPENAI_MODEL/ANTHROPIC_MODEL), keys-never-in-TOML invariant (and the deny_unknown_fields parse-error consequence), Ollama quickstart.
  • reqwest::Client no-timeout rationale documented — local Ollama can spend tens of seconds on cold-load before the first SSE event; a total-request timeout would truncate healthy long streams. Stream-side termination is handled by the three finalize triggers + MAX_SSE_BUFFER_BYTES.

Full Changelog: v0.2.1...v0.3.0

v0.2.1

25 May 05:31

Choose a tag to compare

Changed

  • Docs/UX: the README and the static-mode startup hint now recommend a standard API key (ANTHROPIC_API_KEY / key.txt) as the supported path, and mark /login (OAuth) as best-effort — it reuses Anthropic's Claude Code OAuth client, so it may be rate-limited or blocked. No behavior change.

Full Changelog: v0.2.0...v0.2.1

v0.2.0

25 May 04:49

Choose a tag to compare

First public release — the repository is now open-source (MIT OR Apache-2.0). Functionally identical to 0.1.2, promoted to the semver-correct minor version for the breaking on-disk format change made during the 0.1.x security hardening (a pre-0.1.1 .magi-rs-memory.db resets on upgrade). See [0.1.1] for the security-audit remediation and [0.1.2] for the docs + release-pipeline work this consolidates.

Full Changelog: v0.1.2...v0.2.0

v0.1.2

25 May 04:15

Choose a tag to compare

Changed

  • Internal development docs are no longer shipped. The audit, strategy, and roadmap notes moved to a gitignored dev-docs/ directory — excluded from the repository and the published crate.

Added

  • docs/OVERVIEW.md — a public overview of Magi, the magi-core foundation, and the multi-perspective (MAGI) philosophy.
  • Windows binary in releases. Tagged releases now attach magi-rs-vX.Y.Z-windows-x86_64.zip (the compiled magi-rs.exe + README + licenses) alongside the source archives.

Full Changelog: v0.1.1...v0.1.2