API reference

Every public item of every package, generated from the interfaces the compiler writes. 435 public items across 13 packages.

#The facade moonbitstack/moonkoog

What importing the module root gives you: the agent, the built-in middleware, the planner, the team builder and the shipped tools, all re-exported from the package that owns them.

Values

Values

pub fn answer_only(name? : String) -> @agent.Strategy

Values

pub fn calculator() -> @agent.ToolSpec

Values

pub fn chat() -> @agent.Strategy

Values

pub fn create_agent(&@moonmuse.Provider, @agent.AgentConfig, saver? : &@moonstate.Saver, store? : &@moonstate.Store, executor? : &@moonstate.Executor) -> @agent.Agent raise @moonstate.Refused

Values

pub let default_limits : @agent.Limits

Values

pub let default_options : @agent.Options

Values

pub fn describe(@agent.AgentError) -> String

Values

pub fn handoff_tool(Array[String]) -> @agent.ToolSpec

Values

pub fn plan_and_execute(@agent.AgentConfig, limit? : Int32, replan? : Bool) -> @agent.AgentConfig

Values

pub fn react(reasoning_prompt? : String, interval? : Int32) -> @agent.Strategy

Values

pub fn[S : Eq + Hash] search(Array[@plan.GoapAction[S]], S, @plan.GoapGoal[S]) -> Array[String]?

Values

pub fn single_run() -> @agent.Strategy

Values

pub fn supervisor(@agent.AgentConfig, Array[@agent.Agent], instruction? : String, max_turns? : Int32) -> @agent.AgentConfig

Values

pub fn swarm(@agent.AgentConfig, Array[@agent.Agent]) -> @agent.AgentConfig

Type aliases

Type aliases

pub using @agent {type Agent}

Type aliases

pub using @agent {type AgentConfig}

Type aliases

pub using @agent {type AgentError}

Type aliases

pub using @agent {type AgentState}

Type aliases

pub using @middleware {type ContextEditing}

Type aliases

pub using @middleware {type EditingStrategy}

Type aliases

pub using @agent {type Event}

Type aliases

pub using @agent {type EventHandler}

Type aliases

pub using @middleware {type FileSearch}

Type aliases

pub using @plan {type GoapAction}

Type aliases

pub using @plan {type GoapGoal}

Type aliases

pub using @middleware {type HumanInTheLoop}

Type aliases

pub using @agent {type Limits}

Type aliases

pub using @middleware {type ModelCallLimit}

Type aliases

pub using @middleware {type ModelFallback}

Type aliases

pub using @agent {type ModelOutcome}

Type aliases

pub using @middleware {type ModelRetry}

Type aliases

pub using @agent {type NodeKind}

Type aliases

pub using @agent {type Options}

Type aliases

pub using @middleware {type Pii}

Type aliases

pub using @middleware {type PiiRule}

Type aliases

pub using @agent {type RequestMode}

Type aliases

pub using @agent {type RunContext}

Type aliases

pub using @middleware {type ShellTool}

Type aliases

pub using @agent {type Strategy}

Type aliases

pub using @middleware {type Summarization}

Type aliases

pub using @middleware {type TodoList}

Type aliases

pub using @middleware {type ToolCallLimit}

Type aliases

pub using @agent {type ToolOutcome}

Type aliases

pub using @middleware {type ToolRetry}

Type aliases

pub using @middleware {type ToolSelection}

Type aliases

pub using @agent {type ToolSpec}

Type aliases

pub using @agent {type Tools}

Type aliases

pub using @agent {type Update}

Type aliases

pub using @agent {trait Middleware}

#The agent moonbitstack/moonkoog/agent

The run itself: the state a graph checkpoints, the strategy that decides which node runs, the middleware chain around each model and tool call, and the events a run reports.

Values

Values

pub async fn after_agent_hooks(Runtime, RunContext, AgentState) -> Array[Update]

Values

pub let agent_node : String

The node an agent run starts from: it seeds the system message, runs the middleware's run-start hooks, and hands over to the model node.

Values

pub fn answer_only(name? : String) -> Strategy

A strategy with a single model call: no tools, one answer. Useful as a judge, a classifier or the planner half of a plan-and-execute run.

Values

pub async fn before_agent_hooks(Runtime, RunContext) -> Array[Update]

Values

pub fn chat() -> Strategy

The chat loop: the model must call a tool rather than answer in prose, and the run ends when it calls the exit tool. `exit_tool` is what the run watches for.

Values

pub async fn compress(Runtime, RunContext, Array[@moonmuse.Message], HistoryPolicy) -> Compressed

Values

pub fn create_agent(&@moonmuse.Provider, AgentConfig, saver? : &@moonstate.Saver, store? : &@moonstate.Store, executor? : &@moonstate.Executor) -> Agent raise @moonstate.Refused

Build an agent. The strategy defaults to [`single_run`]; tools from the config are installed first, then whatever the middleware contributes, so a middleware can replace a default tool of the same name.

Values

pub let default_limits : Limits

The default caps.

Values

pub let default_options : Options

Nothing pinned: the provider's defaults, tools left to the model's judgement, no stop sequences.

Values

pub fn describe(AgentError) -> String

A failure as a line of text, for hooks that only report.

Values

pub let error_key : String

The storage key a run records its own failure under. The graph cannot raise a library error from a node, so the node records what went wrong and the walk ends; the agent turns that record back into the error a caller expects.

Values

pub fn error_text(Error) -> String

The text of an error, without the type path a `suberror`'s `to_string` prepends.

Values

pub let finish_node : String

The node a run ends on.

Values

pub let handoff_key : String

The storage key a tool writes to ask the run to hand over to another agent. The value is the node name of the agent to continue with.

Values

pub fn install_tools(Runtime) -> Unit

Let every middleware add its tools. Done once, when the agent is built.

Values

pub fn merge(AgentState, Update) -> AgentState

Apply one update.

Values

pub fn message_from_json(@json.Json, @json.JsonPath) -> @moonmuse.Message raise @json.JsonDecodeError

A message from its JSON form; the error names the field that did not read.

Values

pub fn message_to_json(@moonmuse.Message) -> @json.Json

A message as JSON. The conversation is part of a checkpoint, so it has to survive a round trip through the saver: `role`, then one entry per part, each tagged with the part's kind.

Values

pub let model_node : String

The node that makes one model call.

Values

pub async fn node_agent(Runtime, String, AgentState, @moonstate.Run) -> Array[@moonstate.Step[AgentState, Update]]

Values

pub async fn node_compress(Runtime, HistoryPolicy, AgentState, @moonstate.Run) -> Array[@moonstate.Step[AgentState, Update]]

Values

pub async fn node_custom(Runtime, String, AgentState, @moonstate.Run) -> Array[@moonstate.Step[AgentState, Update]]

Values

pub async fn node_execute(Runtime, ExecuteMode, AgentState, @moonstate.Run) -> Array[@moonstate.Step[AgentState, Update]]

Values

pub async fn node_finish(Runtime, AgentState, @moonstate.Run) -> Array[@moonstate.Step[AgentState, Update]]

Values

pub async fn node_request(Runtime, RequestMode, AgentState, @moonstate.Run) -> Array[@moonstate.Step[AgentState, Update]]

Values

pub async fn node_request_to(Runtime, RequestMode, String, AgentState, @moonstate.Run) -> Array[@moonstate.Step[AgentState, Update]]

Values

pub async fn node_think(Runtime, AgentState, @moonstate.Run, prompt~ : String, every~ : Int32) -> Array[@moonstate.Step[AgentState, Update]]

Values

pub fn part_from_json(@json.Json, @json.JsonPath) -> @moonmuse.Part raise @json.JsonDecodeError

One part from its JSON form.

Values

pub fn part_to_json(@moonmuse.Part) -> @json.Json

One part as JSON, tagged with its kind.

Values

pub async fn pipeline_model(Runtime, RunContext, ModelCall, RequestMode) -> ModelOutcome

Values

pub async fn pipeline_tool(Runtime, RunContext, ToolCall) -> ToolOutcome

Values

pub fn react(reasoning_prompt? : String, interval? : Int32) -> Strategy

Reason-and-act: after each round of tools the model is asked to think about what it learned, without tools in reach, before it acts again. `interval` spaces the thinking out, so a long loop does not pay for a reasoning call on every round.

Values

pub fn role_code(@moonmuse.Role) -> String

The wire name of a role, the same spelling the providers use.

Values

pub fn role_of(String) -> @moonmuse.Role?

A role from its wire name.

Values

pub fn single_run() -> Strategy

The one-run loop: ask, run whatever was asked for, ask again until the model answers in prose. This is the strategy an agent gets when nothing else is asked for.

Values

pub fn[T : @json.ToJson] store(String, T) -> Update

Values

pub let tools_node : String

The node that executes the calls a reply asked for.

Errors

Errors

pub(all) suberror AgentError {

A run that went wrong, or one that was interrupted and can be resumed. `Engine` carries the graph engine's own error unchanged so that an interrupt, a step limit and a backend failure stay distinguishable to the caller.

Types and methods

Types and methods

pub struct Agent {

An agent: a runtime, the graph its strategy compiled to, and the operations a caller runs. The graph is the same engine a plain state machine uses — an agent is a graph whose nodes happen to talk to a model, which is what keeps checkpoints, interrupts, resumption and multi-agent composition available without a second mechanism.

Types and methods

pub fn Agent::graph(Self) -> @moonstate.Graph[AgentState, Update]

An agent: a runtime, the graph its strategy compiled to, and the operations a caller runs. The graph is the same engine a plain state machine uses — an agent is a graph whose nodes happen to talk to a model, which is what keeps checkpoints, interrupts, resumption and multi-agent composition available without a second mechanism.

Types and methods

pub async fn Agent::history(Self, String) -> Array[@moonstate.Snapshot[AgentState]] raise AgentError

Types and methods

pub fn Agent::model(Self) -> String

An agent: a runtime, the graph its strategy compiled to, and the operations a caller runs. The graph is the same engine a plain state machine uses — an agent is a graph whose nodes happen to talk to a model, which is what keeps checkpoints, interrupts, resumption and multi-agent composition available without a second mechanism.

Types and methods

pub fn Agent::name(Self) -> String

An agent: a runtime, the graph its strategy compiled to, and the operations a caller runs. The graph is the same engine a plain state machine uses — an agent is a graph whose nodes happen to talk to a model, which is what keeps checkpoints, interrupts, resumption and multi-agent composition available without a second mechanism.

Types and methods

pub async fn Agent::resume_from(Self, String, @json.Json) -> String raise AgentError

Types and methods

pub async fn Agent::run(Self, String, thread? : String) -> String raise AgentError

Types and methods

pub fn Agent::runtime(Self) -> Runtime

An agent: a runtime, the graph its strategy compiled to, and the operations a caller runs. The graph is the same engine a plain state machine uses — an agent is a graph whose nodes happen to talk to a model, which is what keeps checkpoints, interrupts, resumption and multi-agent composition available without a second mechanism.

Types and methods

pub async fn Agent::state(Self, String) -> @moonstate.Snapshot[AgentState]? raise AgentError

Types and methods

pub fn Agent::strategy_name(Self) -> String

An agent: a runtime, the graph its strategy compiled to, and the operations a caller runs. The graph is the same engine a plain state machine uses — an agent is a graph whose nodes happen to talk to a model, which is what keeps checkpoints, interrupts, resumption and multi-agent composition available without a second mechanism.

Types and methods

pub async fn Agent::stream(Self, String, (Event) -> Unit, thread? : String) -> String raise AgentError

Types and methods

pub(all) struct AgentConfig {

Everything an agent is configured with, short of the provider and the checkpoint stores. A config is data plus a strategy: copying it and changing one field is how a second agent is made, and the presets are the three shapes a run usually takes.

Types and methods

pub fn AgentConfig::chat(String, name? : String) -> Self

Everything an agent is configured with, short of the provider and the checkpoint stores. A config is data plus a strategy: copying it and changing one field is how a second agent is made, and the presets are the three shapes a run usually takes.

Types and methods

pub fn AgentConfig::exit_tool_spec() -> ToolSpec

Everything an agent is configured with, short of the provider and the checkpoint stores. A config is data plus a strategy: copying it and changing one field is how a second agent is made, and the presets are the three shapes a run usually takes.

Types and methods

pub fn AgentConfig::new(String, name? : String) -> Self

Everything an agent is configured with, short of the provider and the checkpoint stores. A config is data plus a strategy: copying it and changing one field is how a second agent is made, and the presets are the three shapes a run usually takes.

Types and methods

pub fn AgentConfig::react(String, name? : String, reasoning_prompt? : String, interval? : Int32) -> Self

Everything an agent is configured with, short of the provider and the checkpoint stores. A config is data plus a strategy: copying it and changing one field is how a second agent is made, and the presets are the three shapes a run usually takes.

Types and methods

pub fn AgentConfig::with_events(Self, EventHandler) -> Self

Everything an agent is configured with, short of the provider and the checkpoint stores. A config is data plus a strategy: copying it and changing one field is how a second agent is made, and the presets are the three shapes a run usually takes.

Types and methods

pub fn AgentConfig::with_instructions(Self, String) -> Self

Everything an agent is configured with, short of the provider and the checkpoint stores. A config is data plus a strategy: copying it and changing one field is how a second agent is made, and the presets are the three shapes a run usually takes.

Types and methods

pub fn AgentConfig::with_limits(Self, Limits) -> Self

Everything an agent is configured with, short of the provider and the checkpoint stores. A config is data plus a strategy: copying it and changing one field is how a second agent is made, and the presets are the three shapes a run usually takes.

Types and methods

pub fn AgentConfig::with_middleware(Self, &Middleware) -> Self

Everything an agent is configured with, short of the provider and the checkpoint stores. A config is data plus a strategy: copying it and changing one field is how a second agent is made, and the presets are the three shapes a run usually takes.

Types and methods

pub fn AgentConfig::with_node(Self, String, async (Runtime, AgentState, @moonstate.Run) -> Array[@moonstate.Step[AgentState, Update]]) -> Self

Everything an agent is configured with, short of the provider and the checkpoint stores. A config is data plus a strategy: copying it and changing one field is how a second agent is made, and the presets are the three shapes a run usually takes.

Types and methods

pub fn AgentConfig::with_options(Self, Options) -> Self

Everything an agent is configured with, short of the provider and the checkpoint stores. A config is data plus a strategy: copying it and changing one field is how a second agent is made, and the presets are the three shapes a run usually takes.

Types and methods

pub fn AgentConfig::with_strategy(Self, Strategy) -> Self

Everything an agent is configured with, short of the provider and the checkpoint stores. A config is data plus a strategy: copying it and changing one field is how a second agent is made, and the presets are the three shapes a run usually takes.

Types and methods

pub fn AgentConfig::with_structured(Self, Structured) -> Self

Everything an agent is configured with, short of the provider and the checkpoint stores. A config is data plus a strategy: copying it and changing one field is how a second agent is made, and the presets are the three shapes a run usually takes.

Types and methods

pub fn AgentConfig::with_tools(Self, Array[ToolSpec]) -> Self

Everything an agent is configured with, short of the provider and the checkpoint stores. A config is data plus a strategy: copying it and changing one field is how a second agent is made, and the presets are the three shapes a run usually takes.

Types and methods

pub(all) struct AgentState {

What a run carries between nodes: the conversation, the run's own scratch space, how many model and tool calls it has spent, and the answer once one is set. The whole value is the graph's state, so it round-trips through JSON for the saver — a checkpoint restores the conversation and the counters, which is what lets a run resume with the budgets it had already spent.

Types and methods

pub fn AgentState::from_json(@json.Json, @json.JsonPath) -> Self raise @json.JsonDecodeError

What a run carries between nodes: the conversation, the run's own scratch space, how many model and tool calls it has spent, and the answer once one is set. The whole value is the graph's state, so it round-trips through JSON for the saver — a checkpoint restores the conversation and the counters, which is what lets a run resume with the budgets it had already spent.

Types and methods

pub fn[T : @json.FromJson] AgentState::get(Self, String) -> T?

Types and methods

pub fn AgentState::messages(Self) -> Array[@moonmuse.Message]

What a run carries between nodes: the conversation, the run's own scratch space, how many model and tool calls it has spent, and the answer once one is set. The whole value is the graph's state, so it round-trips through JSON for the saver — a checkpoint restores the conversation and the counters, which is what lets a run resume with the budgets it had already spent.

Types and methods

pub fn AgentState::new() -> Self

What a run carries between nodes: the conversation, the run's own scratch space, how many model and tool calls it has spent, and the answer once one is set. The whole value is the graph's state, so it round-trips through JSON for the saver — a checkpoint restores the conversation and the counters, which is what lets a run resume with the budgets it had already spent.

Types and methods

pub fn AgentState::raw(Self, String) -> @json.Json?

What a run carries between nodes: the conversation, the run's own scratch space, how many model and tool calls it has spent, and the answer once one is set. The whole value is the graph's state, so it round-trips through JSON for the saver — a checkpoint restores the conversation and the counters, which is what lets a run resume with the budgets it had already spent.

Types and methods

pub fn AgentState::text(Self) -> String

What a run carries between nodes: the conversation, the run's own scratch space, how many model and tool calls it has spent, and the answer once one is set. The whole value is the graph's state, so it round-trips through JSON for the saver — a checkpoint restores the conversation and the counters, which is what lets a run resume with the budgets it had already spent.

Types and methods

pub fn AgentState::to_json(Self) -> @json.Json

What a run carries between nodes: the conversation, the run's own scratch space, how many model and tool calls it has spent, and the answer once one is set. The whole value is the graph's state, so it round-trips through JSON for the saver — a checkpoint restores the conversation and the counters, which is what lets a run resume with the budgets it had already spent.

Types and methods

pub fn AgentState::with_messages(Self, Array[@moonmuse.Message]) -> Self

What a run carries between nodes: the conversation, the run's own scratch space, how many model and tool calls it has spent, and the answer once one is set. The whole value is the graph's state, so it round-trips through JSON for the saver — a checkpoint restores the conversation and the counters, which is what lets a run resume with the budgets it had already spent.

Types and methods

pub impl @json.FromJson for AgentState

Types and methods

pub impl @json.ToJson for AgentState

Types and methods

pub(all) enum Compressed {

The result of compressing a conversation: the messages to carry on with, or why the summary could not be written.

Types and methods

pub(all) enum Event {

What a run broadcasts: one variant per boundary worth observing. The stream is data so it can be rendered as log lines, counted in tests, or translated into OpenTelemetry spans without the observer reaching into the graph.

Types and methods

pub struct EventHandler {

Hooks over an agent run: observers that watch, and interceptors that rewrite the value in flight. Every registration chains after what was registered before, so several handlers fire and several interceptors compose left to right. The interceptors are the only way to change what is sent, what comes back and what a tool receives, which keeps a run's conversation and a hook's edits in one place. Hooks are synchronous; anything that has to await belongs in middleware, whose hooks are async.

Types and methods

pub fn EventHandler::intercept_llm_call_completed(Self, (@moonmuse.Reply) -> @moonmuse.Reply) -> Self

Hooks over an agent run: observers that watch, and interceptors that rewrite the value in flight. Every registration chains after what was registered before, so several handlers fire and several interceptors compose left to right. The interceptors are the only way to change what is sent, what comes back and what a tool receives, which keeps a run's conversation and a hook's edits in one place. Hooks are synchronous; anything that has to await belongs in middleware, whose hooks are async.

Types and methods

pub fn EventHandler::intercept_llm_call_starting(Self, (@moonmuse.Request) -> @moonmuse.Request) -> Self

Hooks over an agent run: observers that watch, and interceptors that rewrite the value in flight. Every registration chains after what was registered before, so several handlers fire and several interceptors compose left to right. The interceptors are the only way to change what is sent, what comes back and what a tool receives, which keeps a run's conversation and a hook's edits in one place. Hooks are synchronous; anything that has to await belongs in middleware, whose hooks are async.

Types and methods

pub fn EventHandler::intercept_tool_call_completed(Self, (String, String) -> String) -> Self

Hooks over an agent run: observers that watch, and interceptors that rewrite the value in flight. Every registration chains after what was registered before, so several handlers fire and several interceptors compose left to right. The interceptors are the only way to change what is sent, what comes back and what a tool receives, which keeps a run's conversation and a hook's edits in one place. Hooks are synchronous; anything that has to await belongs in middleware, whose hooks are async.

Types and methods

pub fn EventHandler::intercept_tool_call_starting(Self, (String, @json.Json) -> @json.Json) -> Self

Hooks over an agent run: observers that watch, and interceptors that rewrite the value in flight. Every registration chains after what was registered before, so several handlers fire and several interceptors compose left to right. The interceptors are the only way to change what is sent, what comes back and what a tool receives, which keeps a run's conversation and a hook's edits in one place. Hooks are synchronous; anything that has to await belongs in middleware, whose hooks are async.

Types and methods

pub fn EventHandler::new() -> Self

Hooks over an agent run: observers that watch, and interceptors that rewrite the value in flight. Every registration chains after what was registered before, so several handlers fire and several interceptors compose left to right. The interceptors are the only way to change what is sent, what comes back and what a tool receives, which keeps a run's conversation and a hook's edits in one place. Hooks are synchronous; anything that has to await belongs in middleware, whose hooks are async.

Types and methods

pub fn EventHandler::observe(Self, (Event) -> Unit) -> Self

Hooks over an agent run: observers that watch, and interceptors that rewrite the value in flight. Every registration chains after what was registered before, so several handlers fire and several interceptors compose left to right. The interceptors are the only way to change what is sent, what comes back and what a tool receives, which keeps a run's conversation and a hook's edits in one place. Hooks are synchronous; anything that has to await belongs in middleware, whose hooks are async.

Types and methods

pub fn EventHandler::on_agent_completed(Self, (String) -> Unit) -> Self

Hooks over an agent run: observers that watch, and interceptors that rewrite the value in flight. Every registration chains after what was registered before, so several handlers fire and several interceptors compose left to right. The interceptors are the only way to change what is sent, what comes back and what a tool receives, which keeps a run's conversation and a hook's edits in one place. Hooks are synchronous; anything that has to await belongs in middleware, whose hooks are async.

Types and methods

pub fn EventHandler::on_agent_execution_failed(Self, (String) -> Unit) -> Self

Hooks over an agent run: observers that watch, and interceptors that rewrite the value in flight. Every registration chains after what was registered before, so several handlers fire and several interceptors compose left to right. The interceptors are the only way to change what is sent, what comes back and what a tool receives, which keeps a run's conversation and a hook's edits in one place. Hooks are synchronous; anything that has to await belongs in middleware, whose hooks are async.

Types and methods

pub fn EventHandler::on_agent_starting(Self, (String) -> Unit) -> Self

Hooks over an agent run: observers that watch, and interceptors that rewrite the value in flight. Every registration chains after what was registered before, so several handlers fire and several interceptors compose left to right. The interceptors are the only way to change what is sent, what comes back and what a tool receives, which keeps a run's conversation and a hook's edits in one place. Hooks are synchronous; anything that has to await belongs in middleware, whose hooks are async.

Types and methods

pub fn EventHandler::on_llm_call_completed(Self, (@moonmuse.Reply) -> Unit) -> Self

Hooks over an agent run: observers that watch, and interceptors that rewrite the value in flight. Every registration chains after what was registered before, so several handlers fire and several interceptors compose left to right. The interceptors are the only way to change what is sent, what comes back and what a tool receives, which keeps a run's conversation and a hook's edits in one place. Hooks are synchronous; anything that has to await belongs in middleware, whose hooks are async.

Types and methods

pub fn EventHandler::on_llm_call_starting(Self, (@moonmuse.Request) -> Unit) -> Self

Hooks over an agent run: observers that watch, and interceptors that rewrite the value in flight. Every registration chains after what was registered before, so several handlers fire and several interceptors compose left to right. The interceptors are the only way to change what is sent, what comes back and what a tool receives, which keeps a run's conversation and a hook's edits in one place. Hooks are synchronous; anything that has to await belongs in middleware, whose hooks are async.

Types and methods

pub fn EventHandler::on_llm_streaming_completed(Self, (@moonmuse.Reply) -> Unit) -> Self

Hooks over an agent run: observers that watch, and interceptors that rewrite the value in flight. Every registration chains after what was registered before, so several handlers fire and several interceptors compose left to right. The interceptors are the only way to change what is sent, what comes back and what a tool receives, which keeps a run's conversation and a hook's edits in one place. Hooks are synchronous; anything that has to await belongs in middleware, whose hooks are async.

Types and methods

pub fn EventHandler::on_llm_streaming_frame(Self, (String) -> Unit) -> Self

Hooks over an agent run: observers that watch, and interceptors that rewrite the value in flight. Every registration chains after what was registered before, so several handlers fire and several interceptors compose left to right. The interceptors are the only way to change what is sent, what comes back and what a tool receives, which keeps a run's conversation and a hook's edits in one place. Hooks are synchronous; anything that has to await belongs in middleware, whose hooks are async.

Types and methods

pub fn EventHandler::on_llm_streaming_starting(Self, (@moonmuse.Request) -> Unit) -> Self

Hooks over an agent run: observers that watch, and interceptors that rewrite the value in flight. Every registration chains after what was registered before, so several handlers fire and several interceptors compose left to right. The interceptors are the only way to change what is sent, what comes back and what a tool receives, which keeps a run's conversation and a hook's edits in one place. Hooks are synchronous; anything that has to await belongs in middleware, whose hooks are async.

Types and methods

pub fn EventHandler::on_node_execution_completed(Self, (String) -> Unit) -> Self

Hooks over an agent run: observers that watch, and interceptors that rewrite the value in flight. Every registration chains after what was registered before, so several handlers fire and several interceptors compose left to right. The interceptors are the only way to change what is sent, what comes back and what a tool receives, which keeps a run's conversation and a hook's edits in one place. Hooks are synchronous; anything that has to await belongs in middleware, whose hooks are async.

Types and methods

pub fn EventHandler::on_node_execution_failed(Self, (String, String) -> Unit) -> Self

Hooks over an agent run: observers that watch, and interceptors that rewrite the value in flight. Every registration chains after what was registered before, so several handlers fire and several interceptors compose left to right. The interceptors are the only way to change what is sent, what comes back and what a tool receives, which keeps a run's conversation and a hook's edits in one place. Hooks are synchronous; anything that has to await belongs in middleware, whose hooks are async.

Types and methods

pub fn EventHandler::on_node_execution_starting(Self, (String) -> Unit) -> Self

Hooks over an agent run: observers that watch, and interceptors that rewrite the value in flight. Every registration chains after what was registered before, so several handlers fire and several interceptors compose left to right. The interceptors are the only way to change what is sent, what comes back and what a tool receives, which keeps a run's conversation and a hook's edits in one place. Hooks are synchronous; anything that has to await belongs in middleware, whose hooks are async.

Types and methods

pub fn EventHandler::on_strategy_completed(Self, (String, String) -> Unit) -> Self

Hooks over an agent run: observers that watch, and interceptors that rewrite the value in flight. Every registration chains after what was registered before, so several handlers fire and several interceptors compose left to right. The interceptors are the only way to change what is sent, what comes back and what a tool receives, which keeps a run's conversation and a hook's edits in one place. Hooks are synchronous; anything that has to await belongs in middleware, whose hooks are async.

Types and methods

pub fn EventHandler::on_strategy_starting(Self, (String) -> Unit) -> Self

Hooks over an agent run: observers that watch, and interceptors that rewrite the value in flight. Every registration chains after what was registered before, so several handlers fire and several interceptors compose left to right. The interceptors are the only way to change what is sent, what comes back and what a tool receives, which keeps a run's conversation and a hook's edits in one place. Hooks are synchronous; anything that has to await belongs in middleware, whose hooks are async.

Types and methods

pub fn EventHandler::on_subgraph_execution_completed(Self, (String, String) -> Unit) -> Self

Hooks over an agent run: observers that watch, and interceptors that rewrite the value in flight. Every registration chains after what was registered before, so several handlers fire and several interceptors compose left to right. The interceptors are the only way to change what is sent, what comes back and what a tool receives, which keeps a run's conversation and a hook's edits in one place. Hooks are synchronous; anything that has to await belongs in middleware, whose hooks are async.

Types and methods

pub fn EventHandler::on_subgraph_execution_starting(Self, (String) -> Unit) -> Self

Hooks over an agent run: observers that watch, and interceptors that rewrite the value in flight. Every registration chains after what was registered before, so several handlers fire and several interceptors compose left to right. The interceptors are the only way to change what is sent, what comes back and what a tool receives, which keeps a run's conversation and a hook's edits in one place. Hooks are synchronous; anything that has to await belongs in middleware, whose hooks are async.

Types and methods

pub fn EventHandler::on_tool_call_completed(Self, (String, String) -> Unit) -> Self

Hooks over an agent run: observers that watch, and interceptors that rewrite the value in flight. Every registration chains after what was registered before, so several handlers fire and several interceptors compose left to right. The interceptors are the only way to change what is sent, what comes back and what a tool receives, which keeps a run's conversation and a hook's edits in one place. Hooks are synchronous; anything that has to await belongs in middleware, whose hooks are async.

Types and methods

pub fn EventHandler::on_tool_call_failed(Self, (String, String) -> Unit) -> Self

Hooks over an agent run: observers that watch, and interceptors that rewrite the value in flight. Every registration chains after what was registered before, so several handlers fire and several interceptors compose left to right. The interceptors are the only way to change what is sent, what comes back and what a tool receives, which keeps a run's conversation and a hook's edits in one place. Hooks are synchronous; anything that has to await belongs in middleware, whose hooks are async.

Types and methods

pub fn EventHandler::on_tool_call_starting(Self, (String, @json.Json) -> Unit) -> Self

Hooks over an agent run: observers that watch, and interceptors that rewrite the value in flight. Every registration chains after what was registered before, so several handlers fire and several interceptors compose left to right. The interceptors are the only way to change what is sent, what comes back and what a tool receives, which keeps a run's conversation and a hook's edits in one place. Hooks are synchronous; anything that has to await belongs in middleware, whose hooks are async.

Types and methods

pub fn EventHandler::on_tool_validation_failed(Self, (String, @json.Json, String) -> Unit) -> Self

Hooks over an agent run: observers that watch, and interceptors that rewrite the value in flight. Every registration chains after what was registered before, so several handlers fire and several interceptors compose left to right. The interceptors are the only way to change what is sent, what comes back and what a tool receives, which keeps a run's conversation and a hook's edits in one place. Hooks are synchronous; anything that has to await belongs in middleware, whose hooks are async.

Types and methods

pub fn EventHandler::report(Self, Event) -> Unit

Hooks over an agent run: observers that watch, and interceptors that rewrite the value in flight. Every registration chains after what was registered before, so several handlers fire and several interceptors compose left to right. The interceptors are the only way to change what is sent, what comes back and what a tool receives, which keeps a run's conversation and a hook's edits in one place. Hooks are synchronous; anything that has to await belongs in middleware, whose hooks are async.

Types and methods

pub(all) enum ExecuteMode {

Which calls an execution node runs.

Types and methods

pub struct FirstChoice {

Take the first candidate.

Types and methods

pub async fn FirstChoice::choose(Self, Array[@moonmuse.Reply]) -> @moonmuse.Reply

Types and methods

pub fn FirstChoice::new() -> Self

Take the first candidate.

Types and methods

pub impl Chooser for FirstChoice

Types and methods

pub(all) enum HistoryPolicy {

Which part of the conversation a compression node folds into a summary.

Types and methods

pub(all) struct Limits {

What a run may spend. `iterations` counts model calls, `tool_calls` counts executions, and `steps` bounds the graph walk itself so a strategy that loops on its own still terminates. The numbers follow the agent frameworks this one is built for: 50 model calls is the cap their default agent uses, and a thousand node visits is the walk limit a compiled graph gets. Raise them for a run that legitimately needs more, lower them in a test.

Types and methods

pub fn Limits::new() -> Self

What a run may spend. `iterations` counts model calls, `tool_calls` counts executions, and `steps` bounds the graph walk itself so a strategy that loops on its own still terminates. The numbers follow the agent frameworks this one is built for: 50 model calls is the cap their default agent uses, and a thousand node visits is the walk limit a compiled graph gets. Raise them for a run that legitimately needs more, lower them in a test.

Types and methods

pub fn Limits::with_iterations(Self, Int32) -> Self

What a run may spend. `iterations` counts model calls, `tool_calls` counts executions, and `steps` bounds the graph walk itself so a strategy that loops on its own still terminates. The numbers follow the agent frameworks this one is built for: 50 model calls is the cap their default agent uses, and a thousand node visits is the walk limit a compiled graph gets. Raise them for a run that legitimately needs more, lower them in a test.

Types and methods

pub fn Limits::with_steps(Self, Int32) -> Self

What a run may spend. `iterations` counts model calls, `tool_calls` counts executions, and `steps` bounds the graph walk itself so a strategy that loops on its own still terminates. The numbers follow the agent frameworks this one is built for: 50 model calls is the cap their default agent uses, and a thousand node visits is the walk limit a compiled graph gets. Raise them for a run that legitimately needs more, lower them in a test.

Types and methods

pub fn Limits::with_tool_calls(Self, Int32) -> Self

What a run may spend. `iterations` counts model calls, `tool_calls` counts executions, and `steps` bounds the graph walk itself so a strategy that loops on its own still terminates. The numbers follow the agent frameworks this one is built for: 50 model calls is the cap their default agent uses, and a thousand node visits is the walk limit a compiled graph gets. Raise them for a run that legitimately needs more, lower them in a test.

Types and methods

pub(all) struct ModelCall {

One model call about to be made.

Types and methods

pub struct ModelChoice {

Ask a model which candidate answers best, and keep that one.

Types and methods

pub async fn ModelChoice::choose(Self, Array[@moonmuse.Reply]) -> @moonmuse.Reply

Types and methods

pub fn ModelChoice::new(&@moonmuse.Provider, String) -> Self

Ask a model which candidate answers best, and keep that one.

Types and methods

pub impl Chooser for ModelChoice

Types and methods

pub(all) enum ModelOutcome {

What a model call came to. `Halted` is a middleware refusing to spend the call, carrying the text the run ends with — the shape a call limit takes.

Types and methods

pub(all) enum NodeKind {

One position in a strategy graph. Four kinds cover the twenty-six node functions the graph DSL of the framework this one is designed after exposes: every request variant is one `Request` mode, every tool-result variant folds into the request that follows it, tool execution is one node, history compression and the exit are one each. The moderation nodes are a middleware here, because what they do — inspect or rewrite messages on the way through — is a pipeline concern.

Types and methods

pub(all) struct Options {

The request settings every call from this agent carries. The provider's own defaults apply to anything left unset, so an empty record means "let the model decide".

Types and methods

pub struct Passthrough {

A middleware that changes nothing, for a caller that wants one hook and no others.

Types and methods

pub async fn Passthrough::after_agent(Self, RunContext, AgentState) -> Array[Update]

Types and methods

pub async fn Passthrough::before_agent(Self, RunContext) -> Array[Update]

Types and methods

pub fn Passthrough::install(Self, Tools) -> Unit

A middleware that changes nothing, for a caller that wants one hook and no others.

Types and methods

pub fn Passthrough::name(Self) -> String

A middleware that changes nothing, for a caller that wants one hook and no others.

Types and methods

pub fn Passthrough::new(String) -> Self

A middleware that changes nothing, for a caller that wants one hook and no others.

Types and methods

pub async fn Passthrough::wrap_model(Self, RunContext, ModelCall, async (ModelCall) -> ModelOutcome) -> ModelOutcome

Types and methods

pub async fn Passthrough::wrap_tool(Self, RunContext, ToolCall, async (ToolCall) -> ToolOutcome) -> ToolOutcome

Types and methods

pub impl Middleware for Passthrough

Types and methods

pub(all) enum RequestMode {

Which way a request node asks the model. This is the whole of the request side: the many request nodes a Kotlin-style DSL spells out separately differ only in what they put in the request — the tools, the choice, the number of candidates, whether the answer is streamed or shaped by a schema.

Types and methods

pub(all) struct RunContext {

What a middleware is handed about the run it is taking part in: the agent's identity, the thread it belongs to, the step it is on, and the state as of this node. The state is a snapshot — a middleware that wants to change it returns updates, so every change goes through the graph and lands in the checkpoint like a node's own write.

Types and methods

pub struct Runtime {

The request this node sends: the conversation so far, the tools the mode allows, and the agent's options.

Types and methods

pub fn Runtime::context(Self, @moonstate.Run, AgentState) -> RunContext

The request this node sends: the conversation so far, the tools the mode allows, and the agent's options.

Types and methods

pub fn Runtime::has_node(Self, String) -> Bool

The request this node sends: the conversation so far, the tools the mode allows, and the agent's options.

Types and methods

pub fn Runtime::provider(Self) -> &@moonmuse.Provider

The request this node sends: the conversation so far, the tools the mode allows, and the agent's options.

Types and methods

pub fn Runtime::request_for(Self, RequestMode, AgentState) -> @moonmuse.Request

The request this node sends: the conversation so far, the tools the mode allows, and the agent's options.

Types and methods

pub fn Runtime::tool(Self, String) -> ToolSpec?

The request this node sends: the conversation so far, the tools the mode allows, and the agent's options.

Types and methods

pub fn Runtime::tool_specs(Self) -> Array[@moonmuse.Tool]

The request this node sends: the conversation so far, the tools the mode allows, and the agent's options.

Types and methods

pub(all) struct Strategy {

A strategy as data: named positions, what each one does, and the edges between them. Keeping it data means a strategy can be inspected, compared and documented without a provider in hand, and compiled against whichever runtime an agent was built with. A node that decides where to go next does so by returning a `Goto`, so edges only describe the fixed part of the flow.

Types and methods

pub fn Strategy::compile(Self, Runtime, saver? : &@moonstate.Saver, store? : &@moonstate.Store, executor? : &@moonstate.Executor) -> @moonstate.Graph[AgentState, Update] raise @moonstate.Refused

A strategy as data: named positions, what each one does, and the edges between them. Keeping it data means a strategy can be inspected, compared and documented without a provider in hand, and compiled against whichever runtime an agent was built with. A node that decides where to go next does so by returning a `Goto`, so edges only describe the fixed part of the flow.

Types and methods

pub fn Strategy::edge(Self, String, String) -> Self

A strategy as data: named positions, what each one does, and the edges between them. Keeping it data means a strategy can be inspected, compared and documented without a provider in hand, and compiled against whichever runtime an agent was built with. A node that decides where to go next does so by returning a `Goto`, so edges only describe the fixed part of the flow.

Types and methods

pub fn Strategy::new(String, limit? : Int32) -> Self

A strategy as data: named positions, what each one does, and the edges between them. Keeping it data means a strategy can be inspected, compared and documented without a provider in hand, and compiled against whichever runtime an agent was built with. A node that decides where to go next does so by returning a `Goto`, so edges only describe the fixed part of the flow.

Types and methods

pub fn Strategy::node(Self, String, NodeKind) -> Self

A strategy as data: named positions, what each one does, and the edges between them. Keeping it data means a strategy can be inspected, compared and documented without a provider in hand, and compiled against whichever runtime an agent was built with. A node that decides where to go next does so by returning a `Goto`, so edges only describe the fixed part of the flow.

Types and methods

pub fn Strategy::node_names(Self) -> Array[String]

A strategy as data: named positions, what each one does, and the edges between them. Keeping it data means a strategy can be inspected, compared and documented without a provider in hand, and compiled against whichever runtime an agent was built with. A node that decides where to go next does so by returning a `Goto`, so edges only describe the fixed part of the flow.

Types and methods

pub(all) struct Structured {

Ask the model for an object that matches `schema`, in a call that advertises a single tool of that shape. The model's answer is the tool call's arguments, which is how a provider without a `response_format` field can still be held to a schema.

Types and methods

pub fn Structured::new(String, @json.Json) -> Self

Ask the model for an object that matches `schema`, in a call that advertises a single tool of that shape. The model's answer is the tool call's arguments, which is how a provider without a `response_format` field can still be held to a schema.

Types and methods

pub(all) struct ToolCall {

One tool call about to be made.

Types and methods

pub(all) enum ToolOutcome {

What a tool call came to. `Failed` records the reason as an error result, which is what the model reads and what a retry policy looks at.

Types and methods

pub(all) struct ToolSpec {

A tool the model may call and the function behind it. The descriptor is what the model sees; the function is handed the arguments object and the run it belongs to, and returns the text the model reads back. The run context is what makes a stateful tool possible — a todo list remembers itself, a retrieval tool can see what the run already looked at — without a second tool interface.

Types and methods

pub fn ToolSpec::new(name~ : String, description~ : String, run~ : async (@json.Json, RunContext) -> String, schema? : @json.Json) -> Self

A tool the model may call and the function behind it. The descriptor is what the model sees; the function is handed the arguments object and the run it belongs to, and returns the text the model reads back. The run context is what makes a stateful tool possible — a todo list remembers itself, a retrieval tool can see what the run already looked at — without a second tool interface.

Types and methods

pub fn ToolSpec::of(@moonmuse.Tool, async (@json.Json, RunContext) -> String) -> Self

A tool the model may call and the function behind it. The descriptor is what the model sees; the function is handed the arguments object and the run it belongs to, and returns the text the model reads back. The run context is what makes a stateful tool possible — a todo list remembers itself, a retrieval tool can see what the run already looked at — without a second tool interface.

Types and methods

pub struct Tools {

The tools being collected for an agent: what the config brings, and what each middleware adds when the agent is built.

Types and methods

pub fn Tools::add(Self, ToolSpec) -> Unit

The tools being collected for an agent: what the config brings, and what each middleware adds when the agent is built.

Types and methods

pub fn Tools::new() -> Self

The tools being collected for an agent: what the config brings, and what each middleware adds when the agent is built.

Types and methods

pub fn Tools::register(Self, name~ : String, description~ : String, run~ : async (@json.Json, RunContext) -> String, schema? : @json.Json) -> Unit

The tools being collected for an agent: what the config brings, and what each middleware adds when the agent is built.

Types and methods

pub fn Tools::specs(Self) -> Array[ToolSpec]

The tools being collected for an agent: what the config brings, and what each middleware adds when the agent is built.

Types and methods

pub(all) enum Update {

One change a node makes to the state. A node returns these as `Step::Write`, and the graph applies them in order through [`merge`]; they are also what a checkpoint's pending writes replay.

Types and methods

pub fn Update::from_json(@json.Json, @json.JsonPath) -> Self raise @json.JsonDecodeError

One change a node makes to the state. A node returns these as `Step::Write`, and the graph applies them in order through [`merge`]; they are also what a checkpoint's pending writes replay.

Types and methods

pub fn Update::to_json(Self) -> @json.Json

One change a node makes to the state. A node returns these as `Step::Write`, and the graph applies them in order through [`merge`]; they are also what a checkpoint's pending writes replay.

Types and methods

pub impl @json.FromJson for Update

Types and methods

pub impl @json.ToJson for Update

Type aliases

Type aliases

pub type Listener = (Event) -> Unit

The subscriber a run reports to. Every run has one; the default drops what it is told.

Type aliases

pub type NodeFn = async (Runtime, AgentState, @moonstate.Run) -> Array[@moonstate.Step[AgentState, Update]]

A node body: what a custom position in a strategy does.

Traits

Traits

pub(open) trait Chooser {

Picks one reply out of several candidates for the same request. Asking more than once and choosing is how a run buys diversity without asking the provider for `n` completions it may not support: every candidate is a normal call, so middleware, limits and retries apply to each of them.

Traits

pub(open) trait Middleware {

A hook into a run, between the graph and the provider. Four places to act: before the run starts, around each model call, around each tool call, and after the run ends. The around-hooks take the next step as a function, so a middleware can retry it, replace it, or skip it — and the pipeline nesting is the composition order, first registered outermost. A middleware may also install tools, which is how a feature that is best expressed as something the model calls (a todo list, a shell, a file search) joins a run.

#Middleware moonbitstack/moonkoog/middleware

The built-in pipeline. Each one wraps the model call, the tool call, or both.

Values

Values

pub let cleared : String

What stands in for a cleared tool result.

Values

pub fn format_todos(Array[@json.Json]) -> String

The list as the model reads it back: one line per item, with its status.

Values

pub let os_shell : Array[String]

No process and no file system on this target: the tools that need one say so instead of pretending to run. The functions stay asynchronous so their callers are written once, and the yield keeps the signature honest rather than nominal.

Values

pub let read_tool : String

Values

pub let search_tool : String

The tools the middleware installs.

Values

pub let shell_tool : String

The tool the middleware installs.

Values

pub let todo_key : String

The storage key the list lives under.

Values

pub let todo_note : String

What the model is told about the list, once, at the start of the run.

Values

pub let todo_tool : String

The tool the middleware installs.

Values

pub fn todos(@agent.AgentState) -> Array[@json.Json]

The list a run recorded, when it has one.

Values

pub fn tool_count(@agent.AgentState, String) -> Int32

How many times a tool has run in this thread so far. The tool node records it after each round, which is why the count survives a checkpoint.

Types and methods

Types and methods

pub struct ContextEditing {

Trim a conversation without asking the model to summarise it. Cheap and lossless in structure: nothing is invented, so nothing can be wrong. It is the right policy when the older turns are scaffolding — tool results the model has already used — rather than decisions worth keeping.

Types and methods

pub async fn ContextEditing::after_agent(Self, @agent.RunContext, @agent.AgentState) -> Array[@agent.Update]

Types and methods

pub async fn ContextEditing::before_agent(Self, @agent.RunContext) -> Array[@agent.Update]

Types and methods

pub fn ContextEditing::install(Self, @agent.Tools) -> Unit

Trim a conversation without asking the model to summarise it. Cheap and lossless in structure: nothing is invented, so nothing can be wrong. It is the right policy when the older turns are scaffolding — tool results the model has already used — rather than decisions worth keeping.

Types and methods

pub fn ContextEditing::name(Self) -> String

Trim a conversation without asking the model to summarise it. Cheap and lossless in structure: nothing is invented, so nothing can be wrong. It is the right policy when the older turns are scaffolding — tool results the model has already used — rather than decisions worth keeping.

Types and methods

pub fn ContextEditing::new(EditingStrategy) -> Self

Trim a conversation without asking the model to summarise it. Cheap and lossless in structure: nothing is invented, so nothing can be wrong. It is the right policy when the older turns are scaffolding — tool results the model has already used — rather than decisions worth keeping.

Types and methods

pub async fn ContextEditing::wrap_model(Self, @agent.RunContext, @agent.ModelCall, async (@agent.ModelCall) -> @agent.ModelOutcome) -> @agent.ModelOutcome

Types and methods

pub async fn ContextEditing::wrap_tool(Self, @agent.RunContext, @agent.ToolCall, async (@agent.ToolCall) -> @agent.ToolOutcome) -> @agent.ToolOutcome

Types and methods

pub impl @agent.Middleware for ContextEditing

Types and methods

pub(all) enum EditingStrategy {

How a conversation is trimmed when it is too long.

Types and methods

pub(all) struct Fallback {

One alternative to fall back to: another provider, another model, or both.

Types and methods

pub fn Fallback::new(&@moonmuse.Provider, String) -> Self

One alternative to fall back to: another provider, another model, or both.

Types and methods

pub struct FileSearch {

Give the model a way to look around a directory tree. Two tools, both read-only: `search_files` expands a glob under the root, and `read_file` opens one file. The root is the whole of the permission model — a path that leaves it is refused before anything is opened, which is what keeps a prompt-injected instruction from reading the host's files.

Types and methods

pub async fn FileSearch::after_agent(Self, @agent.RunContext, @agent.AgentState) -> Array[@agent.Update]

Types and methods

pub async fn FileSearch::before_agent(Self, @agent.RunContext) -> Array[@agent.Update]

Types and methods

pub fn FileSearch::install(Self, @agent.Tools) -> Unit

Give the model a way to look around a directory tree. Two tools, both read-only: `search_files` expands a glob under the root, and `read_file` opens one file. The root is the whole of the permission model — a path that leaves it is refused before anything is opened, which is what keeps a prompt-injected instruction from reading the host's files.

Types and methods

pub fn FileSearch::name(Self) -> String

Give the model a way to look around a directory tree. Two tools, both read-only: `search_files` expands a glob under the root, and `read_file` opens one file. The root is the whole of the permission model — a path that leaves it is refused before anything is opened, which is what keeps a prompt-injected instruction from reading the host's files.

Types and methods

pub fn FileSearch::new(String, limit? : Int32, read_limit? : Int32) -> Self

Give the model a way to look around a directory tree. Two tools, both read-only: `search_files` expands a glob under the root, and `read_file` opens one file. The root is the whole of the permission model — a path that leaves it is refused before anything is opened, which is what keeps a prompt-injected instruction from reading the host's files.

Types and methods

pub async fn FileSearch::wrap_model(Self, @agent.RunContext, @agent.ModelCall, async (@agent.ModelCall) -> @agent.ModelOutcome) -> @agent.ModelOutcome

Types and methods

pub async fn FileSearch::wrap_tool(Self, @agent.RunContext, @agent.ToolCall, async (@agent.ToolCall) -> @agent.ToolOutcome) -> @agent.ToolOutcome

Types and methods

pub impl @agent.Middleware for FileSearch

Types and methods

pub struct HumanInTheLoop {

Ask the host whether a tool may run, by stopping the run on a question. The run stops at the tool call; the host answers with `true` or `false` when it resumes. An approval is remembered for the rest of the thread, so a tool called five times asks once. A denial comes back to the model as a failed call, which lets it choose another way instead of ending the run.

Types and methods

pub async fn HumanInTheLoop::after_agent(Self, @agent.RunContext, @agent.AgentState) -> Array[@agent.Update]

Types and methods

pub async fn HumanInTheLoop::before_agent(Self, @agent.RunContext) -> Array[@agent.Update]

Types and methods

pub fn HumanInTheLoop::install(Self, @agent.Tools) -> Unit

Ask the host whether a tool may run, by stopping the run on a question. The run stops at the tool call; the host answers with `true` or `false` when it resumes. An approval is remembered for the rest of the thread, so a tool called five times asks once. A denial comes back to the model as a failed call, which lets it choose another way instead of ending the run.

Types and methods

pub fn HumanInTheLoop::name(Self) -> String

Ask the host whether a tool may run, by stopping the run on a question. The run stops at the tool call; the host answers with `true` or `false` when it resumes. An approval is remembered for the rest of the thread, so a tool called five times asks once. A denial comes back to the model as a failed call, which lets it choose another way instead of ending the run.

Types and methods

pub fn HumanInTheLoop::new(Array[String], reason? : String) -> Self

Ask the host whether a tool may run, by stopping the run on a question. The run stops at the tool call; the host answers with `true` or `false` when it resumes. An approval is remembered for the rest of the thread, so a tool called five times asks once. A denial comes back to the model as a failed call, which lets it choose another way instead of ending the run.

Types and methods

pub async fn HumanInTheLoop::wrap_model(Self, @agent.RunContext, @agent.ModelCall, async (@agent.ModelCall) -> @agent.ModelOutcome) -> @agent.ModelOutcome

Types and methods

pub async fn HumanInTheLoop::wrap_tool(Self, @agent.RunContext, @agent.ToolCall, async (@agent.ToolCall) -> @agent.ToolOutcome) -> @agent.ToolOutcome

Types and methods

pub impl @agent.Middleware for HumanInTheLoop

Types and methods

pub struct ModelCallLimit {

Stop a run before it makes more model calls than the budget allows. The cap is checked against what the run has already spent, which the state carries, so a resumed run does not get a fresh budget. Reaching it ends the run with a line of text saying so rather than failing: a caller that wanted an error can look at the answer.

Types and methods

pub async fn ModelCallLimit::after_agent(Self, @agent.RunContext, @agent.AgentState) -> Array[@agent.Update]

Types and methods

pub async fn ModelCallLimit::before_agent(Self, @agent.RunContext) -> Array[@agent.Update]

Types and methods

pub fn ModelCallLimit::install(Self, @agent.Tools) -> Unit

Stop a run before it makes more model calls than the budget allows. The cap is checked against what the run has already spent, which the state carries, so a resumed run does not get a fresh budget. Reaching it ends the run with a line of text saying so rather than failing: a caller that wanted an error can look at the answer.

Types and methods

pub fn ModelCallLimit::name(Self) -> String

Stop a run before it makes more model calls than the budget allows. The cap is checked against what the run has already spent, which the state carries, so a resumed run does not get a fresh budget. Reaching it ends the run with a line of text saying so rather than failing: a caller that wanted an error can look at the answer.

Types and methods

pub fn ModelCallLimit::new(limit? : Int32) -> Self

Stop a run before it makes more model calls than the budget allows. The cap is checked against what the run has already spent, which the state carries, so a resumed run does not get a fresh budget. Reaching it ends the run with a line of text saying so rather than failing: a caller that wanted an error can look at the answer.

Types and methods

pub async fn ModelCallLimit::wrap_model(Self, @agent.RunContext, @agent.ModelCall, async (@agent.ModelCall) -> @agent.ModelOutcome) -> @agent.ModelOutcome

Types and methods

pub async fn ModelCallLimit::wrap_tool(Self, @agent.RunContext, @agent.ToolCall, async (@agent.ToolCall) -> @agent.ToolOutcome) -> @agent.ToolOutcome

Types and methods

pub impl @agent.Middleware for ModelCallLimit

Types and methods

pub struct ModelFallback {

Try the alternatives in order when the primary model call fails. The order is the point: a smaller local model first, a larger one second, and the primaries' own retry policy already applied inside. Fallbacks call their provider directly — a fallback is a different endpoint, not the same one with different arguments — so the middleware inside them is skipped deliberately.

Types and methods

pub async fn ModelFallback::after_agent(Self, @agent.RunContext, @agent.AgentState) -> Array[@agent.Update]

Types and methods

pub async fn ModelFallback::before_agent(Self, @agent.RunContext) -> Array[@agent.Update]

Types and methods

pub fn ModelFallback::install(Self, @agent.Tools) -> Unit

Try the alternatives in order when the primary model call fails. The order is the point: a smaller local model first, a larger one second, and the primaries' own retry policy already applied inside. Fallbacks call their provider directly — a fallback is a different endpoint, not the same one with different arguments — so the middleware inside them is skipped deliberately.

Types and methods

pub fn ModelFallback::name(Self) -> String

Try the alternatives in order when the primary model call fails. The order is the point: a smaller local model first, a larger one second, and the primaries' own retry policy already applied inside. Fallbacks call their provider directly — a fallback is a different endpoint, not the same one with different arguments — so the middleware inside them is skipped deliberately.

Types and methods

pub fn ModelFallback::new(Array[Fallback]) -> Self

Try the alternatives in order when the primary model call fails. The order is the point: a smaller local model first, a larger one second, and the primaries' own retry policy already applied inside. Fallbacks call their provider directly — a fallback is a different endpoint, not the same one with different arguments — so the middleware inside them is skipped deliberately.

Types and methods

pub async fn ModelFallback::wrap_model(Self, @agent.RunContext, @agent.ModelCall, async (@agent.ModelCall) -> @agent.ModelOutcome) -> @agent.ModelOutcome

Types and methods

pub async fn ModelFallback::wrap_tool(Self, @agent.RunContext, @agent.ToolCall, async (@agent.ToolCall) -> @agent.ToolOutcome) -> @agent.ToolOutcome

Types and methods

pub impl @agent.Middleware for ModelFallback

Types and methods

pub struct ModelRetry {

Retry a model call that failed in a way the provider itself calls retryable: a rate limit, a gateway error, a timeout. A rejected request is not retried, because the same request would be rejected again.

Types and methods

pub async fn ModelRetry::after_agent(Self, @agent.RunContext, @agent.AgentState) -> Array[@agent.Update]

Types and methods

pub async fn ModelRetry::before_agent(Self, @agent.RunContext) -> Array[@agent.Update]

Types and methods

pub fn ModelRetry::install(Self, @agent.Tools) -> Unit

Retry a model call that failed in a way the provider itself calls retryable: a rate limit, a gateway error, a timeout. A rejected request is not retried, because the same request would be rejected again.

Types and methods

pub fn ModelRetry::name(Self) -> String

Retry a model call that failed in a way the provider itself calls retryable: a rate limit, a gateway error, a timeout. A rejected request is not retried, because the same request would be rejected again.

Types and methods

pub fn ModelRetry::new(attempts? : Int32, base_ms? : Int32, factor? : Double, cap_ms? : Int32) -> Self

Retry a model call that failed in a way the provider itself calls retryable: a rate limit, a gateway error, a timeout. A rejected request is not retried, because the same request would be rejected again.

Types and methods

pub async fn ModelRetry::wrap_model(Self, @agent.RunContext, @agent.ModelCall, async (@agent.ModelCall) -> @agent.ModelOutcome) -> @agent.ModelOutcome

Types and methods

pub async fn ModelRetry::wrap_tool(Self, @agent.RunContext, @agent.ToolCall, async (@agent.ToolCall) -> @agent.ToolOutcome) -> @agent.ToolOutcome

Types and methods

pub impl @agent.Middleware for ModelRetry

Types and methods

pub struct Pii {

Scrub personal data out of what the model is about to read. The rules run over the request as it is being sent, so the conversation the run keeps is untouched: a later step still has the real value if the host put it there, while the provider never sees it. Rules are regular expressions, which is what makes them auditable — the policy is data a reviewer can read.

Types and methods

pub async fn Pii::after_agent(Self, @agent.RunContext, @agent.AgentState) -> Array[@agent.Update]

Types and methods

pub async fn Pii::before_agent(Self, @agent.RunContext) -> Array[@agent.Update]

Types and methods

pub fn Pii::install(Self, @agent.Tools) -> Unit

Scrub personal data out of what the model is about to read. The rules run over the request as it is being sent, so the conversation the run keeps is untouched: a later step still has the real value if the host put it there, while the provider never sees it. Rules are regular expressions, which is what makes them auditable — the policy is data a reviewer can read.

Types and methods

pub fn Pii::name(Self) -> String

Scrub personal data out of what the model is about to read. The rules run over the request as it is being sent, so the conversation the run keeps is untouched: a later step still has the real value if the host put it there, while the provider never sees it. Rules are regular expressions, which is what makes them auditable — the policy is data a reviewer can read.

Types and methods

pub fn Pii::new(Array[PiiRule], action? : PiiAction) -> Self

Scrub personal data out of what the model is about to read. The rules run over the request as it is being sent, so the conversation the run keeps is untouched: a later step still has the real value if the host put it there, while the provider never sees it. Rules are regular expressions, which is what makes them auditable — the policy is data a reviewer can read.

Types and methods

pub fn Pii::standard() -> Self

Scrub personal data out of what the model is about to read. The rules run over the request as it is being sent, so the conversation the run keeps is untouched: a later step still has the real value if the host put it there, while the provider never sees it. Rules are regular expressions, which is what makes them auditable — the policy is data a reviewer can read.

Types and methods

pub async fn Pii::wrap_model(Self, @agent.RunContext, @agent.ModelCall, async (@agent.ModelCall) -> @agent.ModelOutcome) -> @agent.ModelOutcome

Types and methods

pub async fn Pii::wrap_tool(Self, @agent.RunContext, @agent.ToolCall, async (@agent.ToolCall) -> @agent.ToolOutcome) -> @agent.ToolOutcome

Types and methods

pub impl @agent.Middleware for Pii

Types and methods

pub(all) enum PiiAction {

What to do with a value a policy recognises as personal data.

Types and methods

pub(all) struct PiiRule {

One recogniser: a regular expression and the label that stands in for what it matches.

Types and methods

pub fn PiiRule::new(String, String) -> Self

One recogniser: a regular expression and the label that stands in for what it matches.

Types and methods

pub fn PiiRule::standard() -> Array[Self]

One recogniser: a regular expression and the label that stands in for what it matches.

Types and methods

pub struct ShellTool {

Give the model a shell. A shell is the broadest capability a run can have, so the tool is explicit about where it runs: the middleware carries the working directory it is allowed in, the shell it hands the line to, and the wall-clock limit after which the process is stopped. Output is cut so one command cannot flood the conversation.

Types and methods

pub async fn ShellTool::after_agent(Self, @agent.RunContext, @agent.AgentState) -> Array[@agent.Update]

Types and methods

pub async fn ShellTool::before_agent(Self, @agent.RunContext) -> Array[@agent.Update]

Types and methods

pub fn ShellTool::install(Self, @agent.Tools) -> Unit

Give the model a shell. A shell is the broadest capability a run can have, so the tool is explicit about where it runs: the middleware carries the working directory it is allowed in, the shell it hands the line to, and the wall-clock limit after which the process is stopped. Output is cut so one command cannot flood the conversation.

Types and methods

pub fn ShellTool::name(Self) -> String

Give the model a shell. A shell is the broadest capability a run can have, so the tool is explicit about where it runs: the middleware carries the working directory it is allowed in, the shell it hands the line to, and the wall-clock limit after which the process is stopped. Output is cut so one command cannot flood the conversation.

Types and methods

pub fn ShellTool::new(prefix? : Array[String], cwd? : String, timeout_ms? : Int32) -> Self

Give the model a shell. A shell is the broadest capability a run can have, so the tool is explicit about where it runs: the middleware carries the working directory it is allowed in, the shell it hands the line to, and the wall-clock limit after which the process is stopped. Output is cut so one command cannot flood the conversation.

Types and methods

pub async fn ShellTool::wrap_model(Self, @agent.RunContext, @agent.ModelCall, async (@agent.ModelCall) -> @agent.ModelOutcome) -> @agent.ModelOutcome

Types and methods

pub async fn ShellTool::wrap_tool(Self, @agent.RunContext, @agent.ToolCall, async (@agent.ToolCall) -> @agent.ToolOutcome) -> @agent.ToolOutcome

Types and methods

pub impl @agent.Middleware for ShellTool

Types and methods

pub struct Summarization {

Fold a conversation that has grown past a limit into a summary before sending it. The budget is counted in messages rather than tokens: a message count is exact on every provider, needs no tokenizer, and is what a caller can reason about. The newest messages are kept word for word, because that is what the next step depends on.

Types and methods

pub async fn Summarization::after_agent(Self, @agent.RunContext, @agent.AgentState) -> Array[@agent.Update]

Types and methods

pub async fn Summarization::before_agent(Self, @agent.RunContext) -> Array[@agent.Update]

Types and methods

pub fn Summarization::install(Self, @agent.Tools) -> Unit

Fold a conversation that has grown past a limit into a summary before sending it. The budget is counted in messages rather than tokens: a message count is exact on every provider, needs no tokenizer, and is what a caller can reason about. The newest messages are kept word for word, because that is what the next step depends on.

Types and methods

pub fn Summarization::name(Self) -> String

Fold a conversation that has grown past a limit into a summary before sending it. The budget is counted in messages rather than tokens: a message count is exact on every provider, needs no tokenizer, and is what a caller can reason about. The newest messages are kept word for word, because that is what the next step depends on.

Types and methods

pub fn Summarization::new(max_messages? : Int32, keep? : Int32) -> Self

Fold a conversation that has grown past a limit into a summary before sending it. The budget is counted in messages rather than tokens: a message count is exact on every provider, needs no tokenizer, and is what a caller can reason about. The newest messages are kept word for word, because that is what the next step depends on.

Types and methods

pub async fn Summarization::wrap_model(Self, @agent.RunContext, @agent.ModelCall, async (@agent.ModelCall) -> @agent.ModelOutcome) -> @agent.ModelOutcome

Types and methods

pub async fn Summarization::wrap_tool(Self, @agent.RunContext, @agent.ToolCall, async (@agent.ToolCall) -> @agent.ToolOutcome) -> @agent.ToolOutcome

Types and methods

pub impl @agent.Middleware for Summarization

Types and methods

pub struct TodoList {

Give the model a todo list it can write to. A long task goes better when the model states its plan and updates it: the list is in the conversation, so the next step sees it, and in the state, so a resumed run sees it too. The middleware contributes both the tool and the note that tells the model to use it.

Types and methods

pub async fn TodoList::after_agent(Self, @agent.RunContext, @agent.AgentState) -> Array[@agent.Update]

Types and methods

pub async fn TodoList::before_agent(Self, @agent.RunContext) -> Array[@agent.Update]

Types and methods

pub fn TodoList::install(Self, @agent.Tools) -> Unit

Give the model a todo list it can write to. A long task goes better when the model states its plan and updates it: the list is in the conversation, so the next step sees it, and in the state, so a resumed run sees it too. The middleware contributes both the tool and the note that tells the model to use it.

Types and methods

pub fn TodoList::name(Self) -> String

Give the model a todo list it can write to. A long task goes better when the model states its plan and updates it: the list is in the conversation, so the next step sees it, and in the state, so a resumed run sees it too. The middleware contributes both the tool and the note that tells the model to use it.

Types and methods

pub fn TodoList::new() -> Self

Give the model a todo list it can write to. A long task goes better when the model states its plan and updates it: the list is in the conversation, so the next step sees it, and in the state, so a resumed run sees it too. The middleware contributes both the tool and the note that tells the model to use it.

Types and methods

pub async fn TodoList::wrap_model(Self, @agent.RunContext, @agent.ModelCall, async (@agent.ModelCall) -> @agent.ModelOutcome) -> @agent.ModelOutcome

Types and methods

pub async fn TodoList::wrap_tool(Self, @agent.RunContext, @agent.ToolCall, async (@agent.ToolCall) -> @agent.ToolOutcome) -> @agent.ToolOutcome

Types and methods

pub impl @agent.Middleware for TodoList

Types and methods

pub struct ToolCallLimit {

Stop a run from executing more tool calls than the budget allows, in total or for one tool. A refused call comes back to the model as a failure rather than ending the run: the model can then answer with what it has, which is usually better than ending mid-task.

Types and methods

pub async fn ToolCallLimit::after_agent(Self, @agent.RunContext, @agent.AgentState) -> Array[@agent.Update]

Types and methods

pub async fn ToolCallLimit::before_agent(Self, @agent.RunContext) -> Array[@agent.Update]

Types and methods

pub fn ToolCallLimit::install(Self, @agent.Tools) -> Unit

Stop a run from executing more tool calls than the budget allows, in total or for one tool. A refused call comes back to the model as a failure rather than ending the run: the model can then answer with what it has, which is usually better than ending mid-task.

Types and methods

pub fn ToolCallLimit::name(Self) -> String

Stop a run from executing more tool calls than the budget allows, in total or for one tool. A refused call comes back to the model as a failure rather than ending the run: the model can then answer with what it has, which is usually better than ending mid-task.

Types and methods

pub fn ToolCallLimit::new(limit? : Int32, tool? : String) -> Self

Stop a run from executing more tool calls than the budget allows, in total or for one tool. A refused call comes back to the model as a failure rather than ending the run: the model can then answer with what it has, which is usually better than ending mid-task.

Types and methods

pub async fn ToolCallLimit::wrap_model(Self, @agent.RunContext, @agent.ModelCall, async (@agent.ModelCall) -> @agent.ModelOutcome) -> @agent.ModelOutcome

Types and methods

pub async fn ToolCallLimit::wrap_tool(Self, @agent.RunContext, @agent.ToolCall, async (@agent.ToolCall) -> @agent.ToolOutcome) -> @agent.ToolOutcome

Types and methods

pub impl @agent.Middleware for ToolCallLimit

Types and methods

pub struct ToolRetry {

Retry a tool call that failed. Whether a failure is worth another attempt is the tool's business — a network read is, a rejected argument is not — so the policy looks at the reason the tool gave and retries everything unless told otherwise.

Types and methods

pub async fn ToolRetry::after_agent(Self, @agent.RunContext, @agent.AgentState) -> Array[@agent.Update]

Types and methods

pub async fn ToolRetry::before_agent(Self, @agent.RunContext) -> Array[@agent.Update]

Types and methods

pub fn ToolRetry::install(Self, @agent.Tools) -> Unit

Retry a tool call that failed. Whether a failure is worth another attempt is the tool's business — a network read is, a rejected argument is not — so the policy looks at the reason the tool gave and retries everything unless told otherwise.

Types and methods

pub fn ToolRetry::name(Self) -> String

Retry a tool call that failed. Whether a failure is worth another attempt is the tool's business — a network read is, a rejected argument is not — so the policy looks at the reason the tool gave and retries everything unless told otherwise.

Types and methods

pub fn ToolRetry::new(attempts? : Int32, base_ms? : Int32, factor? : Double, cap_ms? : Int32) -> Self

Retry a tool call that failed. Whether a failure is worth another attempt is the tool's business — a network read is, a rejected argument is not — so the policy looks at the reason the tool gave and retries everything unless told otherwise.

Types and methods

pub async fn ToolRetry::wrap_model(Self, @agent.RunContext, @agent.ModelCall, async (@agent.ModelCall) -> @agent.ModelOutcome) -> @agent.ModelOutcome

Types and methods

pub async fn ToolRetry::wrap_tool(Self, @agent.RunContext, @agent.ToolCall, async (@agent.ToolCall) -> @agent.ToolOutcome) -> @agent.ToolOutcome

Types and methods

pub impl @agent.Middleware for ToolRetry

Types and methods

pub struct ToolSelection {

Pick the tools worth advertising for the next call. A large toolbox costs tokens on every request and confuses a small model. This middleware asks the model, once per call, which of the named tools it needs for what the user just asked, and advertises only those — always keeping the ones a policy pins.

Types and methods

pub async fn ToolSelection::after_agent(Self, @agent.RunContext, @agent.AgentState) -> Array[@agent.Update]

Types and methods

pub async fn ToolSelection::before_agent(Self, @agent.RunContext) -> Array[@agent.Update]

Types and methods

pub fn ToolSelection::install(Self, @agent.Tools) -> Unit

Pick the tools worth advertising for the next call. A large toolbox costs tokens on every request and confuses a small model. This middleware asks the model, once per call, which of the named tools it needs for what the user just asked, and advertises only those — always keeping the ones a policy pins.

Types and methods

pub fn ToolSelection::name(Self) -> String

Pick the tools worth advertising for the next call. A large toolbox costs tokens on every request and confuses a small model. This middleware asks the model, once per call, which of the named tools it needs for what the user just asked, and advertises only those — always keeping the ones a policy pins.

Types and methods

pub fn ToolSelection::new(max_tools? : Int32, always? : Array[String]) -> Self

Pick the tools worth advertising for the next call. A large toolbox costs tokens on every request and confuses a small model. This middleware asks the model, once per call, which of the named tools it needs for what the user just asked, and advertises only those — always keeping the ones a policy pins.

Types and methods

pub async fn ToolSelection::wrap_model(Self, @agent.RunContext, @agent.ModelCall, async (@agent.ModelCall) -> @agent.ModelOutcome) -> @agent.ModelOutcome

Types and methods

pub async fn ToolSelection::wrap_tool(Self, @agent.RunContext, @agent.ToolCall, async (@agent.ToolCall) -> @agent.ToolOutcome) -> @agent.ToolOutcome

Types and methods

pub impl @agent.Middleware for ToolSelection

#Planning moonbitstack/moonkoog/plan

Goal-oriented search over world states, and the plan-and-execute strategy.

Values

Values

pub fn advance(@agent.Runtime, @agent.AgentState, @moonstate.Run, replan~ : Bool) -> Array[@moonstate.Step[@agent.AgentState, @agent.Update]]

The advance node: mark the step done, and plan again when it failed.

Values

pub let advance_node : String

The node that records a step as done, and decides whether to plan again.

Values

pub fn done(@agent.AgentState) -> Int32

How many steps the state has finished.

Values

pub let index_key : String

How many steps are done.

Values

pub fn parse_steps(String, Int32) -> Array[String]

Read a list of steps out of a model reply: the JSON array when there is one, otherwise the lines that look like steps. A model that answers with a numbered list instead of JSON is common enough that refusing it would make the feature unusable.

Values

pub fn plan_and_execute(@agent.AgentConfig, limit? : Int32, replan? : Bool) -> @agent.AgentConfig

Turn the config into a plan-and-execute agent: a planner writes the steps, the model works through them with its tools, and a failed step sends the run back to the planner. The loop lives in the graph, so a run that stops — for approval, for a checkpoint, for a cap — resumes at the step it was on with the plan it had.

Values

pub let plan_key : String

The steps a run is working through, in order.

Values

pub async fn planner(@agent.Runtime, @agent.AgentState, @moonstate.Run, limit~ : Int32) -> Array[@moonstate.Step[@agent.AgentState, @agent.Update]]

Values

pub let planner_node : String

The names of the nodes a plan-and-execute run adds to a graph.

Values

pub fn planning_prompt(String, Int32) -> String

The prompt that turns a task into steps.

Values

pub fn[S : Eq + Hash] search(Array[GoapAction[S]], S, GoapGoal[S]) -> Array[String]?

Values

pub fn step(@agent.Runtime, @agent.AgentState, @moonstate.Run) -> Array[@moonstate.Step[@agent.AgentState, @agent.Update]]

The step node: put the next step in front of the model, or finish when the plan is done.

Values

pub let step_node : String

The node that hands the next step to the model.

Values

pub fn steps(@agent.AgentState) -> Array[String]

The plan a state holds.

Types and methods

Types and methods

pub(all) struct GoapAction[S] {

One action of a goal-oriented plan: when it applies, what it changes, and what it costs. A GOAP plan is searched over world states, so an action has to be a pure function of the state it runs in — that is what lets the search try it without side effects.

Types and methods

pub fn[S] GoapAction::new(name~ : String, applies~ : (S) -> Bool, effect~ : (S) -> S, cost? : (S) -> Double) -> Self[S]

Types and methods

pub(all) struct GoapGoal[S] {

What a plan is for: a test for "done", and an estimate of how far away that is.

Types and methods

pub fn[S] GoapGoal::new(reached~ : (S) -> Bool, estimate? : (S) -> Double) -> Self[S]

#Teams moonbitstack/moonkoog/multi

Agents as nodes of one graph: handovers, a swarm that follows them, and a supervisor that chooses.

Values

Values

pub fn handoff_tool(Array[String]) -> @agent.ToolSpec

A tool that hands the conversation to another peer of the team. The tool records the destination in the run's state rather than jumping: the peer's own graph has no node for an agent outside it, so it ends its turn and the team's router reads the marker. That is what makes a handover work across a graph boundary, and it is why a peer does not need to know how the team is wired.

Values

pub let handoff_tool_name : String

The tool a peer calls to pass the conversation to another peer.

Values

pub let route_node : String

The node a team's router lives on.

Values

pub fn supervisor(@agent.AgentConfig, Array[@agent.Agent], instruction? : String, max_turns? : Int32) -> @agent.AgentConfig

A team with a lead that decides which peer acts next. The router asks the model — the agent's own model, with the conversation in hand — which peer should act, and stops when it answers `FINISH`. A supervisor costs one model call per turn and buys a plan nobody has to write; a swarm costs nothing and only goes where the members send it.

Values

pub fn swarm(@agent.AgentConfig, Array[@agent.Agent]) -> @agent.AgentConfig

A team whose members hand the conversation to each other through the handoff tool. Each peer runs as a nested graph over the same conversation, so a peer sees what the ones before it said. The run starts with the first peer and ends when a peer answers without handing over. Nothing decides the order but the members themselves, which is what makes a swarm different from a supervisor.

#Observability moonbitstack/moonkoog/otel

A run as GenAI spans.

Values

Values

pub fn agent_span_name(String) -> String

The span name for an agent run. The GenAI conventions put the operation first and the subject after it.

Values

pub fn tool_span_name(String) -> String

The span name for a tool call.

Types and methods

Types and methods

pub struct Otel {

Translate an agent's run into OpenTelemetry spans. Two signals are all a GenAI trace needs: an `invoke_agent` span around the run, with the agent's name and the tokens it spent, and an `execute_tool` span around each tool call. Both take their attribute names from the semantic conventions, so a collector that understands GenAI — Langfuse, Phoenix, Grafana — reads the trace without a mapping table. The library never reads a clock of its own: `now` supplies the nanosecond timestamps, so a replay can be traced on a timeline the caller chose.

Types and methods

pub fn Otel::install(Self, @agent.EventHandler) -> @agent.EventHandler

Translate an agent's run into OpenTelemetry spans. Two signals are all a GenAI trace needs: an `invoke_agent` span around the run, with the agent's name and the tokens it spent, and an `execute_tool` span around each tool call. Both take their attribute names from the semantic conventions, so a collector that understands GenAI — Langfuse, Phoenix, Grafana — reads the trace without a mapping table. The library never reads a clock of its own: `now` supplies the nanosecond timestamps, so a replay can be traced on a timeline the caller chose.

Types and methods

pub fn Otel::new(tracer~ : @trace.Tracer, now~ : () -> Int64) -> Self

Translate an agent's run into OpenTelemetry spans. Two signals are all a GenAI trace needs: an `invoke_agent` span around the run, with the agent's name and the tokens it spent, and an `execute_tool` span around each tool call. Both take their attribute names from the semantic conventions, so a collector that understands GenAI — Langfuse, Phoenix, Grafana — reads the trace without a mapping table. The library never reads a clock of its own: `now` supplies the nanosecond timestamps, so a replay can be traced on a timeline the caller chose.

#Tools moonbitstack/moonkoog/tools

The tools this module ships.

Values

Values

pub fn all() -> Array[@agent.ToolSpec]

The tools this package ships.

Values

pub fn calculator() -> @agent.ToolSpec

A tool that does arithmetic on two numbers. Models are unreliable at arithmetic and good at deciding that arithmetic is needed, which is exactly the division of labour a tool exists for. Division by zero is refused rather than answered with infinity: a wrong number that looks like a number is worse than an error.

#MCP moonbitstack/moonkoog/mcp

An agent as an MCP server, and another server's tools as this agent's tools.

Values

Values

pub let chat_tool : String

The tool a served agent answers on.

Values

pub fn serve(@agent.Agent, name? : String, version? : String) -> @server.Server raise @exceptions.FastMCPError

Expose an agent as an MCP server: one tool, `chat`, that takes a message and returns the agent's answer. A server is the right shape for an agent other programs drive — an editor, a desktop app, an orchestrator that speaks MCP already — because it needs no HTTP surface of its own and can run over stdio.

Values

pub fn text_of(@types.CallToolResult) -> String

The text of a tool result: every text block, in order. A result with no text — an image, say — is reported as such rather than silently becoming an empty string.

Values

pub async fn tools(@client.Client, prefix? : String) -> Array[@agent.ToolSpec]

#A2A moonbitstack/moonkoog/a2a

An agent behind A2A, and a remote agent as a tool.

Values

Values

pub fn executor(@agent.Agent) -> @moona2a.CallableExecutor

An agent's answer to one A2A message. The executor is the whole bridge: a request arrives as a message, the agent runs on its text, and the answer goes back as a reply part. Everything else — discovery, task storage, push notifications — belongs to the protocol's own server, which this adapter does not duplicate.

Values

pub fn remote_tool(&@moona2a.Transport, name~ : String, description~ : String) -> @agent.ToolSpec

A remote agent as a tool: the model calls another agent the way it calls any tool. This is the direction that makes a fleet of agents useful — one agent delegates to another over the network — and it costs a single tool rather than a second orchestration layer.

#ACP moonbitstack/moonkoog/acp

An agent behind ACP.

Values

Values

pub fn message_update(String) -> @moonacp.SessionUpdate

One agent message as a session update.

Values

pub fn prompt_text(@moonacp.Prompt) -> String

The text of a prompt: every text block, in order.

Values

pub fn updates(@agent.Event) -> Array[@moonacp.SessionUpdate]

A session update for each agent event worth reporting: the tool a run starts, the tool it finishes, and the answer it settles on. The translation is the whole of the ACP bridge on the streaming side: the protocol sends `session/update` notifications, the agent already reports events, so an adapter is a mapping and not a second event system.

Types and methods

Types and methods

pub struct Acp {

An agent exported over ACP. The protocol part is small: one initialize, one session per conversation, one prompt per turn. The interest is in the translation — the run's events become `session/update` notifications, and the protocol's own client renders them. A session update is sent once the turn has settled rather than as it happens, because this runtime's hooks are synchronous while the protocol's writes are not; the order of the notifications is the order the run produced them.

Types and methods

pub async fn Acp::authenticate(Self, @moonacp.Authenticate) -> Unit raise @moonacp.Refused

Types and methods

pub async fn Acp::cancel(Self, String) -> Unit

Types and methods

pub async fn Acp::close_session(Self, @moonacp.CloseSession) -> Unit raise @moonacp.Refused

Types and methods

pub async fn Acp::delete_session(Self, @moonacp.DeleteSession) -> Unit raise @moonacp.Refused

Types and methods

pub async fn Acp::initialize(Self, @moonacp.Initialize) -> @moonacp.Initialized raise @moonacp.Refused

Types and methods

pub async fn Acp::list_sessions(Self, @moonacp.ListSessions) -> @moonacp.SessionList raise @moonacp.Refused

Types and methods

pub async fn Acp::load_session(Self, @moonacp.LoadSession, @moonacp.Session) -> @moonacp.SessionStarted raise @moonacp.Refused

Types and methods

pub async fn Acp::logout(Self) -> Unit raise @moonacp.Refused

Types and methods

pub fn Acp::new(@agent.Agent) -> Self

An agent exported over ACP. The protocol part is small: one initialize, one session per conversation, one prompt per turn. The interest is in the translation — the run's events become `session/update` notifications, and the protocol's own client renders them. A session update is sent once the turn has settled rather than as it happens, because this runtime's hooks are synchronous while the protocol's writes are not; the order of the notifications is the order the run produced them.

Types and methods

pub async fn Acp::new_session(Self, @moonacp.NewSession) -> @moonacp.SessionStarted raise @moonacp.Refused

Types and methods

pub async fn Acp::prompt(Self, @moonacp.Prompt, @moonacp.Session) -> @moonacp.StopReason raise @moonacp.Refused

Types and methods

pub async fn Acp::resume_session(Self, @moonacp.ResumeSession, @moonacp.Session) -> @moonacp.SessionStarted raise @moonacp.Refused

Types and methods

pub async fn Acp::set_config_option(Self, @moonacp.SetConfigOption) -> Array[@moonacp.ConfigOption] raise @moonacp.Refused

Types and methods

pub async fn Acp::set_mode(Self, @moonacp.SetMode) -> Unit raise @moonacp.Refused

Types and methods

pub impl @moonacp.Agent for Acp

#Retrieval moonbitstack/moonkoog/rag

Retrieval as a tool, and retrieval as middleware.

Values

Values

pub fn passage(Int32, @moonrag.Scored) -> String

How a retrieved passage is written into the conversation.

Values

pub fn passages(Array[@moonrag.Scored]) -> String

The passages from `hits`, numbered, for a prompt or a tool result.

Values

pub fn retrieval_tool(&@moonrag.Retriever, limit? : Int32, name? : String) -> @agent.ToolSpec

Retrieval as a tool: the model decides when to look, and reads what came back. The alternative — retrieving before every call — buys recall at the cost of tokens and can drown a question that did not need a document. Handing retrieval to the model keeps the decision where the question is.

Values

pub let search_tool : String

The tool a retrieval provider exposes to the model.

Types and methods

Types and methods

pub struct Rag {

Retrieval as middleware: look up what the user just asked, and put the passages in front of the model. One retrieval per model call, on the last user message. That is the shape a knowledge assistant wants — the answer is grounded whether or not the model thought to search — and it is why the two forms both exist rather than one replacing the other.

Types and methods

pub async fn Rag::after_agent(Self, @agent.RunContext, @agent.AgentState) -> Array[@agent.Update]

Types and methods

pub async fn Rag::before_agent(Self, @agent.RunContext) -> Array[@agent.Update]

Types and methods

pub fn Rag::install(Self, @agent.Tools) -> Unit

Retrieval as middleware: look up what the user just asked, and put the passages in front of the model. One retrieval per model call, on the last user message. That is the shape a knowledge assistant wants — the answer is grounded whether or not the model thought to search — and it is why the two forms both exist rather than one replacing the other.

Types and methods

pub fn Rag::name(Self) -> String

Retrieval as middleware: look up what the user just asked, and put the passages in front of the model. One retrieval per model call, on the last user message. That is the shape a knowledge assistant wants — the answer is grounded whether or not the model thought to search — and it is why the two forms both exist rather than one replacing the other.

Types and methods

pub fn Rag::new(&@moonrag.Retriever, limit? : Int32, label? : String) -> Self

Retrieval as middleware: look up what the user just asked, and put the passages in front of the model. One retrieval per model call, on the last user message. That is the shape a knowledge assistant wants — the answer is grounded whether or not the model thought to search — and it is why the two forms both exist rather than one replacing the other.

Types and methods

pub async fn Rag::wrap_model(Self, @agent.RunContext, @agent.ModelCall, async (@agent.ModelCall) -> @agent.ModelOutcome) -> @agent.ModelOutcome

Types and methods

pub async fn Rag::wrap_tool(Self, @agent.RunContext, @agent.ToolCall, async (@agent.ToolCall) -> @agent.ToolOutcome) -> @agent.ToolOutcome

Types and methods

pub impl @agent.Middleware for Rag

#Skills moonbitstack/moonkoog/skills

Progressive loading of skill documents.

Values

Values

pub fn catalog(Array[@moonskill.Skill]) -> String

The listing an agent carries: one line per skill, name then description, which is what the model needs to decide whether a skill is worth loading.

Values

pub fn enable(@agent.AgentConfig, Array[@moonskill.Skill]) -> @agent.AgentConfig

Turn the config into a skill-enabled agent: the listing goes in the instructions, the loading tool goes in the toolbox.

Values

pub let load_tool : String

The tool a skill-enabled agent uses to read a skill's body.

Values

pub fn load_tool_spec(Array[@moonskill.Skill]) -> @agent.ToolSpec

The tool that reads one skill's body. Progressive loading is the whole point: the listing costs a line per skill, the body costs what it costs, and only the skills the run actually reaches are paid for.

#Agent Protocol moonbitstack/moonkoog/serve

The Agent Protocol's threads and runs over moonapi.

Values

Values

pub fn app(Server) -> @moonapi.App

The routes an Agent Protocol client expects: create a thread, read it, run on it, read the run. The handlers are the protocol; serving them is `moonapi`'s job, and which server it is — moonapi's own, mooncat, a cloud runtime — is a deployment decision this package does not make.

Types and methods

Types and methods

pub(all) struct Run {

One execution of an agent on a thread.

Types and methods

pub fn Run::to_json(Self) -> @json.Json

One execution of an agent on a thread.

Types and methods

pub struct Server {

The Agent Protocol's two resources: threads and the runs that use them. The store is in memory and per server; a deployment that needs runs to outlive the process passes a saver to the agent instead, because the conversation is checkpointed there and the protocol's records are a view of it.

Types and methods

pub async fn Server::create_run(Self, String, String) -> Run raise @agent.AgentError

Types and methods

pub fn Server::create_thread(Self, @json.Json) -> Thread

The Agent Protocol's two resources: threads and the runs that use them. The store is in memory and per server; a deployment that needs runs to outlive the process passes a saver to the agent instead, because the conversation is checkpointed there and the protocol's records are a view of it.

Types and methods

pub fn Server::new(@agent.Agent) -> Self

The Agent Protocol's two resources: threads and the runs that use them. The store is in memory and per server; a deployment that needs runs to outlive the process passes a saver to the agent instead, because the conversation is checkpointed there and the protocol's records are a view of it.

Types and methods

pub fn Server::run(Self, String) -> Run?

The Agent Protocol's two resources: threads and the runs that use them. The store is in memory and per server; a deployment that needs runs to outlive the process passes a saver to the agent instead, because the conversation is checkpointed there and the protocol's records are a view of it.

Types and methods

pub fn Server::thread(Self, String) -> Thread?

The Agent Protocol's two resources: threads and the runs that use them. The store is in memory and per server; a deployment that needs runs to outlive the process passes a saver to the agent instead, because the conversation is checkpointed there and the protocol's records are a view of it.

Types and methods

pub(all) struct Thread {

A conversation the protocol keeps: an identifier, when it started, and whatever the client wants remembered about it.

Types and methods

pub fn Thread::to_json(Self) -> @json.Json

A conversation the protocol keeps: an identifier, when it started, and whatever the client wants remembered about it.