Skip to content

Releases: oops-rs/mentra

Mentra 0.34.1

Choose a tag to compare

@WendellXY WendellXY released this 26 Oct 19:13
Immutable release. Only release title and notes can be modified.

Mentra 0.34.1 ships with mentra-provider 0.9.6.

  • Shell scheduling reads the fixed execution category without constructing and discarding its JSON schema. An optimized trait-dispatch probe measured 41 allocations per category lookup before the change and zero afterward, with unchanged probe executable size. This is a focused method measurement, not an end-to-end agent benchmark.
  • ToolContext and ParallelToolContext expose an owned ToolProgress handle for work that outlives its tool call. Updates retain tool-call identity and stay transient (issue #67).
  • The provider requires patched Tokio 1.53.3 and zstd 0.14.3. Mentra now requires provider 0.9.6, allowing downstream applications to resolve the fixed compression stack (issue #70).
  • Approval previews, shell execution, and scheduling categories are preserved; the shell descriptor/category contract is covered by a regression test (issue #71).

Validation: Rust 1.88 MSRV, formatting, Clippy, all-feature and no-default tests, documentation, advisory checks, and both package archives passed locally. The compression HTTP roundtrip and allocation ablations passed.

mentra 0.28.0 / mentra-provider 0.9.0

Choose a tag to compare

@WendellXY WendellXY released this 09 Sep 02:38
Immutable release. Only release title and notes can be modified.

Removed the RegisteredProvider alias

  • Breaking: mentra_provider::RegisteredProvider is removed. It was a bare
    pub use Provider as RegisteredProvider; with no callers outside the crate's
    own provider impls; use Provider.

Folded ModelCatalog and ProviderSessionFactory into Provider

  • Breaking: the ModelCatalog and ProviderSessionFactory traits are
    removed; list_models and create_session are now required methods on
    Provider itself. Every implementor in the workspace already implemented all
    three traits on the same type, and neither trait was ever used as a dyn type
    or a generic bound. External implementors merge their two impl blocks into
    their Provider impl.

Removed the unread RetryPolicy provider config

  • Breaking: mentra::RetryPolicy / mentra_provider::RetryPolicy and the
    ProviderDefinition::retry field are removed. No code in the workspace ever
    read the policy; per-run retry behavior is configured with
    RunOptions::provider_retry (mentra::runtime::ProviderRetry) and is
    unchanged. Serialized ProviderDefinition JSON carrying a retry key still
    deserializes (the key is ignored).

Removed two unused OAuth credential-source constructors

  • Breaking (feature openai-oauth):
    OpenAIOAuthCredentialSource::from_default_persistent_store and
    ::from_default_persistent_store_or_authorize are removed. Both were
    one-line defaults with no callers; pass PersistentTokenStoreKind::Auto to
    from_persistent_store / from_persistent_store_or_authorize for the
    identical behavior.

Removed the test-only MemoryTokenStore

  • Breaking (feature openai-oauth): mentra::auth::openai::MemoryTokenStore
    is removed. Nothing in the crate constructed it outside its own unit test; the
    in-memory store now lives in that test module. The TokenStore trait stays
    public, so an in-memory store is a few lines to write.

Removed the duplicate provider::model re-export module

  • Breaking: mentra::provider::model is removed. Every item it re-exported
    is already re-exported one level up at mentra::provider::* (and at
    mentra::provider_core::*); import from there instead.

Builtin providers are constructor functions, not forwarding types

  • Breaking: the seven forwarding wrapper types in mentra::provider are
    removed: openai::OpenAIProvider, openrouter::OpenRouterProvider,
    anthropic::AnthropicProvider, gemini::GeminiProvider,
    openai_compatible::OpenAiCompatibleProvider, ollama::OllamaProvider and
    lmstudio::LmStudioProvider. Each held a single Arc<dyn Provider> and
    forwarded every trait method to it verbatim.
  • Free functions returning Arc<dyn Provider> replace them, with the same
    arguments and the same resulting descriptor and capabilities:
    openai::provider, openai::with_credential_source,
    openai::with_shared_credential_source, openrouter::provider,
    anthropic::provider, gemini::provider, openai_compatible::new,
    openai_compatible::without_credentials, ollama::provider,
    ollama::with_base_url, lmstudio::provider, lmstudio::with_base_url.
  • Provider is now implemented for Arc<dyn Provider>, so the results go
    straight into RuntimeBuilder::with_provider_instance and
    Runtime::register_provider_instance as before.
  • Behavior change (Anthropic, Gemini): the removed AnthropicProvider and
    GeminiProvider wrappers did not forward compact, so provider-native
    history compaction always failed with UnsupportedCapability and the
    compaction engine silently fell back to local summarization even though both
    providers advertise supports_history_compaction. Without the wrappers the
    compact call now reaches the real provider, so runtimes built with
    with_anthropic / with_gemini compact remotely under
    CompactionMode::PreferRemote and report CompactionExecutionMode::Remote
    where they previously reported Local. Set CompactionMode::LocalOnly (the default) to keep
    the old behavior.

Agent state no longer carries an empty compaction key

  • The always-empty CompactionState placeholder is gone from
    AgentMemoryState and from the state.json / SQLite state payload. Agent
    state written by older versions still loads; state written now cannot be
    read by an older build.

Removed the unused SearchRequest conversion struct

  • Breaking: mentra::memory::SearchRequest is removed. Nothing
    constructed it; every caller builds a MemorySearchRequest directly.
  • MemoryEngine::search now takes MemorySearchRequest by value instead of
    impl Into<MemorySearchRequest>.

Removed the never-read MemorySearchRequest::mode knob

  • Breaking: mentra::memory::MemorySearchMode and the
    MemorySearchRequest::mode field are removed. No MemoryStore
    implementation ever branched on the value, so search results are unchanged.

Removed unreachable McpServerStatus variants

  • Breaking: McpServerStatus::Disconnected and ::Connecting are removed
    from the mentra::McpServerStatus re-export. Nothing ever constructed them:
    list_servers reports Connected for a live server and Error for a name
    that only failed to connect, and a disconnected server is dropped from the
    listing rather than reported. Out-of-repo match arms on those variants must
    be deleted.

MCP clients share one dispatch mechanism

  • McpBridgedTool::new is no longer generic over the transport; it takes
    Arc<dyn McpToolClient>. Call sites passing a concrete Arc<McpStdioClient>
    or Arc<McpSseClient> are unaffected, because the Arc coerces at the
    argument position.
  • The sealed McpToolClient trait gains a shutdown method, replacing the
    manager's private transport enum. The trait is sealed, so no out-of-crate
    implementor exists to update.

Resumed sessions can opt into a different runtime namespace

  • SessionResumeOptions::runtime_identifier lets a host rehome a legacy or
    renamed-workspace session on its next persist. None keeps the stored tag;
    Some(id) replaces it for that resumed session without retagging other
    agents or changing the shared runtime's identifier
    (#59).
  • Source-breaking: exhaustive SessionResumeOptions struct literals must
    add runtime_identifier: None or use ..Default::default().

Removed unused PermissionRequest type

  • Source-breaking: the public mentra::PermissionRequest struct is removed.
    Nothing produced or consumed it; the live path is the
    SessionEvent::PermissionRequested variant and its inline fields.

Removed duplicate SubagentHandle::task_id

  • Source-breaking: SubagentHandle::task_id is removed. It always held the
    same value as agent_id, which is the identifier reported as the task_id
    of the subagent's SessionEvent::TaskUpdated events.

Removed unused CancellationFlag alias

  • Source-breaking: the mentra::runtime::CancellationFlag type alias is
    removed; use mentra::runtime::CancellationToken, which it aliased.

Removed unused compaction type aliases

  • Source-breaking: the mentra::agent aliases ContextCompactionConfig,
    ContextCompactionTrigger and ContextCompactionDetails are removed; use
    CompactionConfig, CompactionTrigger and CompactionDetails. The persisted
    context_compaction field name keeps working through its serde alias.

mentra 0.20.0

Choose a tag to compare

@WendellXY WendellXY released this 24 Aug 08:42
Immutable release. Only release title and notes can be modified.

mentra 0.20.0. mentra-provider is unchanged since 0.6.0 and is not part of this release.

Breaking

  • SessionEvent::PermissionRequested gains a classification field, so a pattern without a trailing .., or a literal constructing the variant, stops compiling.
  • McpSseLimits gains max_tools, so an exhaustive struct literal needs ..Default::default().
  • ToolDefinition/ToolExecutor are now implemented for Box<T>. Because Box is #[fundamental], a downstream crate that wrote its own impl ToolDefinition for Box<ItsOwnTool> now collides — the hand-written forwarding these impls exist to replace.

Behavioral

  • SessionEvent::MemoryUpdated now actually fires; it had never been emitted by any released version. A failed memory ingest surfaces as a Notice with NoticeSeverity::Warning.

SessionEvent::MemoryUpdated is emitted at last

  • The variant had been public since April while nothing sent it. The bridge
    translating the runtime's MemoryIngestFinished into it was implemented and
    tested from the start but registered nowhere, because the only hook list in
    sight was the runtime's shared one — where a bridge holding one session's
    channel would forward every agent's memory activity to whichever session
    installed it.
  • The correct place existed all along: every session is already built on its
    own RuntimeHandle clone, and each with_* step rebuilds that clone's
    MemoryEngine from the hook list the clone carries. The bridge is now
    appended to that per-session list in create_session* and resume_session*,
    so a session's stream carries the memory events of exactly its own agents —
    the session's agent and the subagents it spawns — and no other session's.
  • Behavior change for hosts: streams that never carried these events now do.
    A successful ingest arrives as MemoryUpdated { agent_id, stored_records }
    (including stored_records: 0 for an ingest with nothing new to store), and
    a failed ingest as a Notice with Warning severity.

The other two MCP transports get the same pagination fixes

  • Review found the tools/list page-cap off-by-one and the unbounded tool
    accumulation in the new Streamable HTTP client and noted both were copied
    from the older code. They were: the stdio and legacy HTTP+SSE clients carried
    the identical two bugs, so fixing only the newest transport would have left
    the two that ship today wrong.
  • All three now check the page cap only when another page is actually asked
    for, so a list exactly max_tool_pages long is accepted rather than refused
    for reaching the limit it may reach — and a cap of 1 no longer rejects
    every server alive. All three bound the total number of advertised tools
    (max_tools, defaulting to 4096), which the page and per-page byte caps
    never did.
  • Breaking: McpSseLimits gains a max_tools field, so an exhaustive
    struct literal needs ..Default::default().

A permission request names the lane a call will actually run in

  • ToolClassification::execution_category reported the category a tool's
    descriptor declares, while the scheduler asks the tool with the call's
    input and then coerces a terminal tool out of a parallel lane. Every preview
    builder in the tree copied the static value, so the two could disagree — and
    they already did on a builtin: files declares an exclusive mutation and
    reports a parallel read for a batch that only reads.
  • In-tree that direction was conservative. The mirror shape is not, and it is
    the one a host will write: a tool declaring ReadOnlyParallel while
    returning a mutating category from execution_category(input) was reported
    to the host as read-only-parallel while the runtime scheduled a mutation, so
    a host auto-approving ReadOnlyParallel auto-approved it.
  • The authorization path now reads the scheduler's own answer rather than the
    descriptor's, which fixes every tool at once instead of the preview builders
    that remember to. Found by adversarial review of the field as it landed.

The Streamable HTTP transport survives the servers it will meet

Adversarial review of the transport as it landed turned up ten defects. The
two that mattered most were both reachable by an ordinary misbehaving server,
and both traced to the same gap: the test fixture could not produce a server
that stalls, so neither could be written as a test.

  • A notification's response body was drained outside the deadline wrapping its
    POST. send() resolves on the response head and the body streams lazily, so
    a server that promised a body and then went quiet left that drain waiting
    forever — inside connect, which RuntimeBuilder::build_async calls
    serially with no deadline above it. One such server hung the whole runtime
    build rather than degrading its own connection.
  • A tools/call whose reply was lost on the application/json path was
    reported as a definite failure. Six exits between an accepted POST and a
    parsed reply bypassed the indeterminacy classification the event-stream path
    applied to all of them, so the same physical event got opposite answers
    depending only on which framing the server chose — and the stalled-read case
    was not merely reachable but unavoidable, since stream_idle_timeout always
    fires before call_tool_timeout. Since McpBridgedTool flattens the error
    to its Display, and only RequestIndeterminate says "must not be retried
    automatically", a model would retry a call that may have charged a card.
    Both paths now classify in one place, exempting a JSON-RPC error, which is
    the answer.
  • A server that forgot a session bricked itself permanently: the client
    reported SessionExpired and stopped, no caller reconnected, and every tool
    from that server stayed broken for the runtime's life. The specification
    requires starting a new session, so the client now re-handshakes and re-sends
    once. That is safe even for a tools/call, because a 404 for an unknown
    session is a refusal before dispatch. The replacement handshake runs through
    a non-recovering path, so a recovery cannot start another recovery.
  • The negotiated protocol revision is now checked against the ones this client
    implements instead of being echoed back unread. A consequence worth having:
    the header carries one of our own &'static constants, so no
    server-controlled bytes reach a request header on that path at all.
  • Smaller: the tools/list page cap rejected a list exactly max_tool_pages
    long (and max_tool_pages: 1 rejected every server); nothing bounded the
    list those pages accumulate into, so a server could push gigabytes through
    the walk and be stopped by the allocator rather than a limit (max_tools
    now bounds it); a session id is echoed on every request and so is now marked
    sensitive and held to the specification's visible-ASCII rule; a handshake
    failing after initialize orphaned the server-side session, and shutdown
    left a dead id in place; and a refused redirect is no longer treated as proof
    a call did not run, since a 303 answering a POST means the server processed
    it.

The fixture gained what it was missing — stalling, pagination, session expiry
and rotation, and per-method failures — and the suite went from 18 tests to
52. The two most important fixes were mutation-tested: reverting either makes
its test fail rather than pass quietly.

CI checks the code it was not checking

  • Every CI job ran without --all-features, so the openai-oauth feature was
    never compiled, linted, or tested there — 831 lines of credential-store code,
    which is precisely the kind that should not ship on the strength of a local
    run. Clippy, the tests, and the MSRV check now all pass --all-features; the
    MSRV floor still holds with them enabled.
  • Nothing built the documentation, so a broken intra-doc link was invisible to
    the whole pipeline: it is neither a compile error nor a lint. A docs job now
    builds the workspace with RUSTDOCFLAGS=-D warnings, which is what would have
    caught the seven links repaired just above — including one that named a field
    on the wrong type.
  • Nothing built the crate with its default features off either, though
    responses-websocket is default-on specifically so a host that only streams
    over HTTP+SSE can drop tokio-tungstenite from its tree. That configuration
    could have stopped compiling without failing anything; a job now checks it.

An MCP server can be reached over Streamable HTTP

  • Streamable HTTP replaced HTTP+SSE in protocol revision 2025-03-26, and
    current MCP servers are commonly streamable-only: they answer 404 on
    /sse because they never implemented the older transport, and 406 on
    /mcp because nothing in mentra sent an Accept header offering both reply
    types. Such a server was reachable through neither existing transport, which
    made an MCP integration impossible rather than degraded.
  • McpStreamableHttpServerConfig and McpStreamableHttpClient post every
    JSON-RPC message to the one configured endpoint and read each reply from that
    same response, whether the server answers with a single application/json
    body or opens a text/event-stream in it. RuntimeBuilder gains
    with_mcp_streamable_http_server and with_mcp_streamable_http_servers, and
    McpManager gains connect_streamable_http; the tools bridge exactly as the
    other two transports' do.
  • The session initialize assigns rides on every later request as
    Mcp-Session-Id, and shutdown ends it. A server is free to use no session
    at all, in which case none is invented and no header is sent.
  • The transport buys a structural simplification worth naming: because a reply
    arrives on the response to the request that asked for it, this client needs
    no background reader task, no pending-request map, and no window in which a
    response can arrive before its own request future resolves — all of which the
    le...
Read more

mentra v0.10.0 — agentic-core hardening

Choose a tag to compare

@WendellXY WendellXY released this 16 Jul 10:21
Immutable release. Only release title and notes can be modified.

mentra v0.10.0 / mentra-provider v0.4.0

Mentra 0.10 hardens the agentic core while preserving its architectural
contract: Mentra remains the sole owner of the model/tool loop, new host seams
stay generic, and default behavior changes only where explicitly documented
below.

This combined release covers the five hardening workstreams and the Proposed
coding-tools,
reasoning-preservation,
and host-orchestration
design records.

Highlights

Runtime hygiene and shell validation

  • Remove the orphaned 5,924-line provider source tree. The live adapters remain
    in mentra/src/provider.rs and continue to delegate to mentra-provider.
  • Add opt-in ShellValidationMode::{Off, Warn, Enforce} classification for
    builtin foreground and background shell execution.
  • Validation enriches authorization previews and reuses the existing
    allow/prompt/deny vocabulary and hooks. Off remains the default.
  • Shell classification is defense-in-depth and permission UX, not a security
    boundary; runtime roots, environment isolation, and process controls remain
    the enforcement boundary.

Universal tool-result limits

  • Apply one output boundary to successful and error results from builtin,
    custom, and MCP tools, including parallel batches.
  • Defaults are 2,000 lines and 50 KiB per result. Truncation retains complete
    lines and appends an actionable notice; under-limit output is byte-identical.
  • Oversized structured JSON is never sliced. When spill succeeds, it is written
    whole and replaced by text pointing to the artifact; otherwise the text
    notice explains why the full output was not saved.
  • Volatile stores suppress disk spill to preserve their no-durable-trace
    contract. The existing shell stream-capture cap remains separate and applies
    before this result boundary.

Model-conventional coding tools

  • Add opt-in read, ls, grep, glob, write, and edit tools over the
    existing transactional WorkspaceEditor.
  • FileToolProfile::{Batched, Split, Both} controls the advertised surface;
    Batched remains the default. Read operations use the parallel lane, while
    write and edit use exclusive local mutation.
  • Grep gains file filters, literal and case-insensitive modes, context,
    multiline regex, and a Unicode-safe 500-character cap per rendered physical
    line.
  • Split edit validates all matches against the original content, rejects
    ambiguity, overlaps, and no-ops, preserves BOM/CRLF, and supports an
    NFKC/smart-punctuation fallback.
  • Diffs, patches, and first_changed_line remain local ToolOutput::details;
    providers receive only a short summary.
  • Recursive list, search, and glob traversal now reject descendant symlinks
    that escape configured read roots. This is an intentional default-path
    policy fix.

move and delete remain batched-only. Historical files.replace keeps its
exact-match semantics and does not gain fuzzy editing.

Thinking and reasoning continuity

  • Add externally tagged ContentBlock::Thinking plus streaming start/delta
    variants and persistence/replay support.
  • Capture and replay Anthropic signed/redacted thinking and OpenAI Responses
    reasoning items, summaries, IDs, and encrypted content.
  • Emit reasoning text separately as AgentEvent::ReasoningDelta and
    SessionEvent::AssistantReasoningDelta; signatures and ciphertext never
    enter host text deltas.
  • Replay opaque reasoning only when registered provider, requested model, and
    provenance format match exactly. Missing/empty metadata and cross-model or
    cross-provider history downgrade to ordinary text instead of being dropped
    or rejected.
  • Responses requests with reasoning enabled include
    reasoning.encrypted_content; Azure-compatible late ciphertext is backfilled
    from terminal output.
  • Thinking is persisted and may contain sensitive provider material. Local
    compaction summarizer inputs explicitly exclude it.

Gemini thought/signature fidelity remains incomplete because signatures can
also attach to tool-use and text parts; that phase is deferred.

Steering and host orchestration

  • Add agent-scoped in-memory steer and would-stop follow-up queues with
    QueueMode::{OneAtATime, All}. Enqueueing never auto-starts an idle agent;
    hosts call Agent::run_queued explicitly.
  • Steering wins over a user RoundStrategy at a boundary without consuming
    the strategy slot. Next-request context order is stable:
    steering, then team inbox, then background notifications.
  • Drained steering is inflight-tracked and requeued on runner or finalization
    errors.
  • Add typed Runtime::task_board and Agent::task_board façades over the
    existing access, transition, and DAG-validation path.
  • Add object-safe TaskStore::mutate. SQLite, Volatile, and Hybrid stores
    serialize mutations transactionally; custom stores retain a source-compatible
    load/replace fallback.
  • Add Agent::run_to_output<T> through an owner-scoped terminal tool and exact
    tool_use_id detail extraction. Provider-native response_format remains
    out of scope.
  • Add owned, generation-aware wait helpers for snapshots, idle completion, and
    teammate replies. See examples/host_orchestration.rs for the end-to-end
    host-scripted flow.
  • Make opaque team-protocol request IDs collision-resistant across
    cross-second request interleavings.

Nous migration — read before upgrading

Upgrade both direct dependencies together:

[dependencies]
mentra = "0.10"
mentra-provider = "0.4"

Nous imports provider-core types directly. Retaining mentra-provider 0.3
allows two provider-core versions into the graph and creates incompatible
types against Mentra's ContentBlock and tool-result surface.

Nous should also opt out of the generic result cap until its observation
protocol becomes truncation-aware:

use mentra::{Runtime, RuntimePolicy};

let policy = RuntimePolicy::default()
    .with_max_tool_result_bytes(usize::MAX)
    .with_max_tool_result_lines(usize::MAX)
    .spill_full_tool_output(false);

let builder = Runtime::empty_builder().with_policy(policy);

Why this is required today:

  • Nous serializes each ToolObservation as one physical JSON line.
  • Above 50 KiB, no complete line fits, so Mentra replaces the observation with
    a truncation notice.
  • Nous cannot deserialize that notice and excludes the observation from its
    reconstructed evidence.
  • Nous uses VolatileRuntimeStore, which correctly suppresses disk artifacts,
    so there is no spill file to recover.
  • Disabling spill alone is insufficient; both result limits must also be
    raised. Add a regression using serialized output larger than 51,200 bytes.

Additional integration guidance:

  • Treat Responses tool_use_id values as opaque. Reasoning-bearing turns may
    use local call_id|function_item_id IDs; provider outputs still project the
    raw call ID. Exact-equality pairing remains correct.
  • Existing wildcard AgentEvent and ContentBlock matches continue to
    compile. Handle ReasoningDelta explicitly only if live reasoning should be
    surfaced.
  • Replay-only Responses mode benefits from preserved reasoning. A
    gather-to-synthesis model switch safely downgrades incompatible opaque
    reasoning to text.
  • Run a live Responses/xipe smoke after upgrading because reasoning-enabled
    requests now ask providers for encrypted reasoning content.

Compatibility and source notes

  • Old persisted transcripts, agent memory, and snapshots deserialize
    unchanged. New optional fields are serde-defaulted and omitted when absent.
  • Under-limit tool results remain byte-identical. Oversized text intentionally
    changes, and oversized structured results become textual truncation notices
    that include an artifact pointer only when spill succeeds.
  • Exhaustive matchers must add cases for ContentBlock, ContentBlockStart,
    ContentBlockDelta, AgentEvent, SessionEvent, and
    mentra_provider::responses::model::ResponsesInputItem reasoning variants.
  • Exhaustive AgentSnapshot literals must add run_generation; patterns
    should use ...
  • Shell authorization preview JSON gains a validation object. In Warn
    mode, the reused AuthorizationDenied hook is advisory; inspect its action
    and outcome rather than treating the event name as proof execution stopped.
  • Existing custom AgentStore implementations compile through the default
    allows_disk_artifacts() == true; no-durable-trace stores should override it
    to return false.
  • Existing custom TaskStore implementations compile through default
    mutate, but that fallback is not atomic and should be overridden for
    concurrent writers.
  • Default agents have empty steering queues, shell validation remains Off,
    and file tools remain Batched.
  • Public time = "0.3" and url = "2.5" requirements remain compatible with
    downstream resolution. Resolver v3 and lockless Rust 1.85 CI enforce the
    repository MSRV without exact public pins.

Operational caveats

  • TaskBoard reads are live, but façade mutations refresh an agent's cached
    task snapshot only at the next normal refresh or run boundary.
  • The pre-existing full-board failed-run restore can overwrite a concurrent
    successful task mutation that occurred after the snapshot was captured.
  • Agent memory, agent records, and run checkpoints do not share one atomic
    store transaction. Steering/team/background input is requeued after late
    errors, but earlier finalization writes may already have committed.
  • wait_for_teammate_reply consumes inbox delivery and must not race the agent
    loop's inbox read. The host owns and must route the returned content.
  • An unsatisfied snapshot wait can remain pending while runt...
Read more

mentra v0.8.0

Choose a tag to compare

@WendellXY WendellXY released this 26 Jun 06:32
Immutable release. Only release title and notes can be modified.

mentra v0.8.0

Mentra v0.8.0 adds two small, additive runtime controls for per-phase agent
tiering
: changing reasoning options mid-session, and stopping a run gracefully
without discarding the work it gathered.

Highlights

Per-phase reasoning options

  • Add Agent::set_reasoning(Option<ReasoningOptions>) and the session wrapper
    Session::set_reasoning(...), mirroring set_model: a stateful override threaded
    into every subsequent model request and persisted with the agent record.
  • This makes a per-phase reasoning split expressible on a single agent — for
    example, run the gather rounds at a low effort, then raise the effort (and,
    together with set_model, switch to a stronger model) for a final synthesis turn
    — without re-spawning the agent and losing the gathered context.

Graceful run stop

  • Add RunOptions::stop, a graceful-stop signal distinct from cancellation. The
    runner checks it at each round boundary, where the transcript is at a consistent
    point. When it is tripped the run ends successfully, committing the gathered
    transcript, instead of returning Cancelled and rolling the run back.
  • Use it to stop a run once enough has been gathered while keeping the gathered
    context available for a follow-up turn on the same agent. cancellation still
    aborts-and-rolls-back as before; stop is the keep-the-work variant.

Compatibility

  • Both additions are additive. RunOptions gains one field (stop), defaulting to
    None; constructions that use ..RunOptions::default() are unaffected.

Crate Versions

  • mentra 0.8.0
  • mentra-provider 0.3.0 remains unchanged and does not need to be republished.

Verification

This release is expected to pass:

  • cargo fmt --all --check
  • cargo clippy --workspace --all-targets -- -D warnings
  • cargo test --workspace

v0.7.1

Choose a tag to compare

@WendellXY WendellXY released this 08 Jun 16:15
Immutable release. Only release title and notes can be modified.

mentra v0.7.1

Mentra v0.7.1 is a compatibility patch for downstream workspaces that also
use newer sqlite bindings.

Compatibility

  • Update rusqlite from 0.32.1 to 0.39.
  • This aligns Mentra with the libsqlite3-sys 0.37 linkage family, avoiding
    Cargo links = "sqlite3" conflicts when Mentra is composed with crates that
    already depend on current rusqlite.

Repository Hygiene

  • Ignore local .grapha graph artifacts.

Crate Versions

  • mentra 0.7.1
  • mentra-provider 0.3.0 remains unchanged and does not need to be republished.

Verification

This release is expected to pass:

  • cargo fmt --all --check
  • cargo clippy --workspace --all-targets -- -D warnings
  • cargo test --workspace

v0.7.0

Choose a tag to compare

@WendellXY WendellXY released this 31 May 03:35
Immutable release. Only release title and notes can be modified.

mentra v0.7.0 / mentra-provider v0.3.0

Mentra v0.7.0 is a provider and coding-agent release. It expands the runtime
with MCP support, safer shell execution primitives, provider-core embeddings,
custom compatible endpoints, and a fuller Responses API client for manual
coding-agent setups.

Highlights

MCP and Runtime Tooling

  • Add a Model Context Protocol client, manager, protocol types, bridge, and test
    coverage so MCP tools can participate in Mentra runtimes.
  • Add bash command validation for shell-tool execution.
  • Add workspace-bounded runtime policies and sandbox detection helpers.
  • Add Session::set_model(...) for runtime model switching.
  • Emit usage-report events with token counts.

Provider-Core Improvements

  • Add provider-core embedding contracts and a Responses embedding provider.
  • Add custom provider-core endpoint registration so applications can target
    compatible OpenAI, Responses, and Anthropic-style services.
  • Add Anthropic prompt caching controls through cache-control markers.
  • Preserve and expose richer provider response metadata for runtime consumers.

Responses API and xipe

  • Add ResponsesStateMode::{ReplayOnly, Hybrid, Stateful}.
  • Track streamed response ids and send previous_response_id when provider
    state is enabled.
  • Retry hybrid HTTP/SSE requests without previous_response_id when provider
    state is unavailable or rejected.
  • Add first-class WebSocket transport for Responses streams.
  • Send xipe-compatible WebSocket response.create frames with request fields at
    the top level.
  • Default Responses function tools to strict: false unless a tool explicitly
    opts into strict mode.
  • Refresh x-codex-turn-state across HTTP and WebSocket paths.
  • Add a manual coding-agent guide for Mentra + Responses + xipe.

Compatibility and Migration

  • Publish mentra-provider 0.3.0 before publishing mentra 0.7.0.
  • mentra 0.7.0 depends on mentra-provider 0.3.0.
  • HTTP/SSE remains the default Responses transport.
  • ResponsesStateMode::Hybrid is the recommended coding-agent default because
    local transcript replay remains authoritative while provider-side state is
    used opportunistically.
  • Existing built-in shell and files tool schemas stay flexible because
    Responses function tools serialize as non-strict by default.

Verification

This release is expected to pass:

  • cargo fmt --all --check
  • cargo clippy --workspace --all-targets -- -D warnings
  • cargo test --workspace

Live xipe smoke testing also covered gpt-5.4-mini over HTTP/SSE and
WebSocket Responses transports.

v0.6.0

Choose a tag to compare

@WendellXY WendellXY released this 07 Apr 16:15
Immutable release. Only release title and notes can be modified.

What's New in Mentra v0.6.0

Permission Scope Hierarchy

  • PermissionRuleStore now supports cross-session rules via consumer-supplied project_id
  • Session, Project, and Global scopes with hierarchical lookup (most specific wins)
  • Automatic SQLite schema migration for existing databases

Compaction Hardening

  • Auto-compaction retries up to 3 times on transient errors, then degrades gracefully (session continues with micro-compaction instead of dying)
  • Configurable transcript cleanup (max_persisted_transcripts) prunes old JSONL files
  • Mock test coverage for remote compaction paths (PreferRemote fallback)

Long-Session Stress Testing

  • SessionGenerator test utility for building multi-turn scripted sessions
  • 50-turn CI integration tests with compaction chains
  • Resume-after-compaction tests
  • Criterion benchmarks for 500-turn sessions, memory scaling, and resume performance

Pattern-Based Approval Rules

  • RuleStore::check() now matches glob patterns against serialized tool input JSON
  • Pattern rules take precedence over no-pattern rules (specific deny overrides general allow)
  • Uses glob-match crate for */? pattern syntax

Pre-Execution Hook System

  • New PreExecutionHook trait with Allow/Deny decisions (separate from observe-only RuntimeHook)
  • PreExecutionHooks collection with first-deny-wins semantics
  • RuntimeBuilder::with_pre_hook() for registration
  • Integrated into both exclusive and parallel tool execution paths
  • ToolExecutionBlocked event for observability

Public Team API

  • Session::spawn_subagent(name, prompt) for programmatic subagent creation (async, non-blocking)
  • Session::list_teammates() and Session::active_subagents() for team state observation
  • SubagentHandle, SpawnedAgentSummary, SpawnedAgentStatus publicly exported

Other

  • 333 tests (up from ~280 in v0.5.0)
  • Criterion benchmarks behind test-utils feature flag

Breaking Changes

  • PermissionRuleStore::save_rules() and load_rules() now require project_id: Option<&str> parameter
  • RuleStore::check() now requires input_json: Option<&str> parameter

v0.5.0

Choose a tag to compare

@ahavili ahavili released this 05 Apr 18:48
Immutable release. Only release title and notes can be modified.

mentra v0.5.0 / mentra-provider v0.2.0

Mentra v0.5.0 is a tooling-architecture release. The headline change is a
cleaner boundary between provider-facing contracts and runtime-facing
orchestration, with the provider surface now published as the new
mentra-provider crate.

This release also adds a full session lifecycle API, persisted permission
resolution, richer tool progress events, more provider/runtime coverage, and a
large round of test and CI hardening.

Highlights

New mentra-provider crate

  • Extract provider-facing request, response, model, stream, auth, and tool
    contracts into the new mentra-provider crate.
  • Keep provider serialization concerns separate from Mentra runtime scheduling
    and approval semantics.
  • Add Responses transport primitives, including websocket support, HTTP fallback
    controls, metadata event preservation, hosted action contracts, replay, and
    remote compaction support.

Tooling architecture refactor

  • Split provider-facing and runtime-facing tool contracts into explicit layers.
  • Introduce dedicated tool orchestration with execution-lane scheduling.
  • Refactor builtin, files, and intrinsic tooling into thinner facades with
    focused internal modules.
  • Emit richer ToolProgress events for shell execution output and file
    operations.

Session and permission APIs

  • Add the Session lifecycle surface, session event mapping, hooks, and typed
    session flow support.
  • Persist permission rules to SQLite so resumed sessions can keep their approval
    state.
  • Support live permission resolution during active sessions.
  • Preserve live agent events during turns when sessions are resumed.

Runtime and provider improvements

  • Add transcript compaction and memory summarization plumbing, plus remote
    compaction support in the provider layer.
  • Add Ollama and LM Studio support through the OpenAI-compatible Responses API.
  • Improve Windows shell execution behavior and strengthen cross-platform CI
    coverage.
  • Forward session headers on provider requests where needed.

Verification and quality

  • Expand integration coverage for session lifecycle, runtime tools, compaction,
    resume flows, error recovery, and contract conformance.
  • Tighten CI and test behavior across Unix and Windows environments.

Compatibility and migration

  • ToolDefinition, ToolExecutor, ToolSpec, and ExecutableTool remain
    available in this release.
  • ToolSpec::builder(...) remains the supported convenience API for custom
    tools.
  • Implement read-only tools with ToolExecutor::execute(...).
  • Implement mutating or agent-state-changing tools with
    ToolExecutor::execute_mut(...).
  • Provider-visible tool metadata now lives in mentra-provider, while runtime
    scheduling and approval metadata stay in mentra.

Publishing order

Publish mentra-provider 0.2.0 before publishing mentra 0.5.0.

v0.3.0

Choose a tag to compare

@WendellXY WendellXY released this 16 Mar 09:53
Immutable release. Only release title and notes can be modified.

v0.3.0 focuses on safer tool execution and better runtime resilience for agentic workflows.

Full Changelog: v0.2.0...v0.3.0

Highlights

  • Added a generic tool-authorization seam to the runtime
  • Added pre-execution tool authorization with structured input previews
  • Simplified runtime command-review behavior by removing shell review heuristics
  • Improved malformed tool-call handling so invalid tool JSON can recover instead of aborting the whole run
  • Expanded provider-neutral token usage reporting across built-in provider streams and runtime hooks

What’s New

Tool authorization

Mentra can now run a caller-provided authorization pass before a tool executes. This gives applications a clean integration point for:

  • LLM-based security review
  • human approval flows
  • custom policy engines
  • fail-closed blocking for risky tool calls

Authorization requests include structured previews so callers can make decisions on normalized tool input instead of raw prompt text.

Better malformed tool-call recovery

A malformed tool-call JSON payload no longer has to kill the entire run. Mentra now treats invalid tool input more gracefully and feeds retry guidance back into the conversation so the model can correct itself on the next round.

This makes tool-using agents more robust in quote-heavy or long-context flows where malformed function-call JSON occasionally happens.

Token usage reporting

Built-in provider streams now populate a shared token-usage model, and runtime hooks report model response usage more consistently across OpenAI, Anthropic, and Gemini integrations.

Behavioral changes

  • Tool authorization types now live under mentra::tool
  • Runtime command-review internals were simplified by removing shell review heuristics
  • If you were relying on older runtime re-exports for authorization-related types, you may need to update imports

Upgrade notes

If you are adopting tool authorization, check the README examples for the current import path and builder usage.

Typical usage now looks like:

  • define a ToolAuthorizer
  • return allow, prompt, or deny
  • install it with Runtime::builder().with_tool_authorizer(...)

If you previously worked around malformed tool-call JSON failures at the app layer, you may be able to remove some of that logic in 0.3.0.