monoloop-loop 0.1.1

Minimal extensible Loop: lossless canonical subscription, empty-capable tools
Documentation

monoloop-loop

Component 03 — The Loop: transaction admission/composition plus the inner lossless tool runtime.

Owns DefaultTransactionRuntime, Channel registry, outbound encoders, MCP gateway shell, and linked-tool dispatch. Inner LoopRuntime stays dialect-neutral.

Prefer the façade crate monoloop unless you need this crate as a direct dependency.

License: AGPL-3.0-or-later. Commercial: https://frogfish.io

What this crate is / is not

Is Is not
RuntimeBootstrapDefaultTransactionRuntime Context/prompt engine
ChannelBinding / ChannelRegistry Test Driver / Console (→ monoloop-testkit)
Empty-tool path (tool_unavailable, zero effects) Ambient “current session”
Production profile encoders + TestTextEncoder smoke helper Host UI

Agent assembly recipe

1. Build ChannelBinding {
     id, kind, tool_mode,
     connector_factory, encoder, interpreter,
     endpoint_ref, credential_ref,
     defaults, capabilities (incl. option_policy + dialects), limits
   }
2. ChannelRegistry::build(vec![binding])  // fails closed on duplicate ids
3. DefaultTransactionRuntime::start(RuntimeBootstrap {
     config: RuntimeConfig { enable_mcp_listener: false, ..Default::default() },
     channels, tools: HostToolRegistry::empty(), executor: Handle::current()
   })
4. TransactionRuntime::submit(TransactionRequest { … })
5. Await completion callback; destroy is automatic at terminal

RuntimeConfig::default() enables the MCP listener — turn it off for smoke hosts unless you want that shell.

Minimal DirectLlm smoke sample (FakeConnector, no network):

cargo run -p monoloop-loop --example fake_echo
# preferred for hosts:
cargo run -p monoloop --example fake_echo

examples/fake_echo.rs is the component-level twin of the façade example (same behaviour, direct imports).

Pieces for FakeConnector / test_raw smoke

Field Smoke value
connector_factory Arc::new(FakeConnectorFactory::direct_llm())
encoder Arc::new(TestTextEncoder) — loop-owned deterministic encoder for test_raw only
interpreter Arc::new(DefaultInterpreterFactory::new())
capabilities.option_policy OptionPolicy::direct_llm()
capabilities.input/output_dialect DialectDescriptor::test_raw()
tool_mode ToolExecutionMode::ModelToolCalls

Live profiles replace factory/encoder/dialects via *_channel_binding helpers in monoloop-connector-* (also behind monoloop features). Do not treat TestTextEncoder as a production dialect encoder; it is not the testkit fixture encoder family either — it stays in this crate so product smoke/tests need no testkit dependency.

Empty tools

With HostToolRegistry::empty() and model tool calls, Monoloop must still complete without external effects (unavailable / rejection paths). That is required qualification, not a failure of The Loop. See tests/empty_loop.rs for the tool_unavailable exercise; fake_echo only proves text completion with empty tools.

Dependency rule

This product crate must not depend on monoloop-testkit. Hosts that only need assembly use monoloop or this crate + connector/interpreter/contracts.

Normative: doc/THE_LOOP.md, doc/TRANSACTION_RUNTIME_IMPLEMENTATION.md.