moonorm

An ORM / SQL toolkit for MoonBit — a parameterized, injection-safe query builder, the way SQLAlchemy Core is for Python. Bound values become ? placeholders, never spliced into the SQL string.

CItestsGitHublicense
$moon add moonbitstack/moonkoog

The contract at a glance

let agent = AIAgent::new(client, model=@llm.deepseek_v4_flash, tool_registry=tools)
let answer = agent.run("what is 2+3?")
// requests a completion, runs every tool the model asks for, feeds the results
// back, and returns the first plain-text reply - Koog's singleRunStrategy, walked
// as a graph.

§Prompts and messages

The conversation model every client speaks: typed messages (system, user, assistant, tool call, tool result) and the builder that assembles them into the Prompt an LLM request carries.

enum
enum Role

A conversation role. Koog 1.1.1 collapses to three: a tool exchange is carried as parts inside a user/assistant message, not as a fourth top-level role.

enum
enum MessagePart

One typed piece of a message's content. Koog 1.1.1 moved off flat string content to an ordered list of MessageParts. A ToolCall carries its arguments as a JSON value (Koog keeps the raw JSON string; we keep it parsed); a ToolResult carries the exact string the model is shown.

struct
struct Message

A single message: a role and its ordered content parts. finish_reason is the provider's stop reason on an assistant reply, None on a request message.

fn
fn Message::system(text : String) -> Message

A plain system message.

fn
fn Message::user(text : String) -> Message

A plain user message.

fn
fn Message::assistant(text : String) -> Message

A plain assistant message.

fn
fn Message::tool_result( tool~ : String, output~ : String, id? : String? = None, is_error? : Bool = false) -> Message

A user message carrying a single tool result (a ToolResult is a request part, so it rides a user message). What the agent loop appends after running a tool.

fn
fn Message::text_content( self : Message, separator? : String = "\n") -> String

The concatenated text of every Text part, joined by separator (Koog's Message.textContent). Non-text parts contribute nothing.

fn
fn Message::tool_calls(self : Message) -> Array[MessagePart]

The tool calls this message requests: its ToolCall parts, in order. Empty when the message is a plain text reply — the loop's signal to finish.

enum
enum ToolChoice

How the model should use tools this request (Koog LLMParams.ToolChoice).

enum
enum Schema

A structured-output schema the model must produce (Koog LLMParams.Schema): a named JSON schema, in the provider's basic or the JSON-Schema-standard dialect.

struct
struct LLMParams

Per-request LLM parameters (Koog LLMParams). None means "let the provider default apply". This carries the full Koog surface; each client maps the subset its provider supports.

fn
fn LLMParams::default() -> LLMParams

The empty params: no overrides.

struct
struct Prompt

The immutable request object handed to an LLM: an ordered message list, an identifier, and the params. Koog builds it through a DSL; here it is built through the fluent PromptBuilder.

fn
fn Prompt::append(self : Prompt, message : Message) -> Prompt

A copy of this prompt with message appended — the immutable-append the agent loop uses to grow the conversation without mutating a shared value.

struct
struct PromptBuilder

A mutable builder for a Prompt. MoonBit has no receiver-lambda DSL, so the Koog prompt { system(...); user(...) } block becomes a fluent chain PromptBuilder::new().system(...).user(...).build().

fn
fn PromptBuilder::new( id? : String = "prompt", params? : LLMParams = LLMParams::default()) -> PromptBuilder

A fresh builder.

fn
fn PromptBuilder::system( self : PromptBuilder, text : String) -> PromptBuilder

Append a system message.

fn
fn PromptBuilder::user( self : PromptBuilder, text : String) -> PromptBuilder

Append a user message.

fn
fn PromptBuilder::assistant( self : PromptBuilder, text : String) -> PromptBuilder

Append an assistant message.

fn
fn PromptBuilder::message( self : PromptBuilder, message : Message) -> PromptBuilder

Append a whole pre-built message (e.g. an assistant reply carrying tool calls).

fn
fn PromptBuilder::tool_result( self : PromptBuilder, tool~ : String, output~ : String, id? : String? = None, is_error? : Bool = false) -> PromptBuilder

Append a user message carrying a single tool result (Koog's toolResult; a ToolResult is a request part, so it rides a user message).

fn
fn PromptBuilder::params( self : PromptBuilder, params : LLMParams) -> PromptBuilder

Set the LLM params.

fn
fn PromptBuilder::build(self : PromptBuilder) -> Prompt

Finish building.

§Models and the client contract

LLModel and the LLMClient trait an executor implements, plus the catalogues of published OpenAI, Anthropic, Google, DeepSeek and Mistral models with their capabilities.

struct
struct LLMProvider

An LLM provider identity. Koog models LLMProvider as an *open* class, not a closed enum, because a user can define their own provider — so moonkoog uses a struct plus named constants rather than a variant set. Source: prompt/prompt-llm/.../llm/LLMProvider.kt.

let
let openai : LLMProvider =
let
let anthropic : LLMProvider =
let
let google : LLMProvider =
let
let deepseek : LLMProvider =
let
let alibaba : LLMProvider =
let
let meta : LLMProvider =
let
let ollama : LLMProvider =
let
let openrouter : LLMProvider =
let
let mistralai : LLMProvider =
enum
enum LLMCapability

A capability a model may declare. Koog's LLMCapability is a sealed hierarchy; this flattens its leaves (the two JSON-schema levels become SchemaJsonBasic / SchemaJsonStandard; the two OpenAI endpoints become OpenAIEndpointCompletions / OpenAIEndpointResponses; Vision is a single leaf here rather than its image/video subtypes — those land when multimodal does). Source: prompt/prompt-llm/.../llm/LLMCapability.kt.

struct
struct LLModel

A specific model: which provider serves it, its provider-side id, its declared capabilities, and the optional context / output-token limits. Source: prompt/prompt-llm/.../llm/LLModel.kt.

fn
fn LLModel::supports(self : LLModel, capability : LLMCapability) -> Bool

Whether the model declares capability (Koog LLModel.supports).

let
let gpt_4o : LLModel =

GPT-4o — the versatile omni flagship (128k context, 16k output).

let
let gpt_4o_mini : LLModel =

GPT-4o mini — the cost-optimised 4o (128k context, 16k output).

let
let gpt_4_1 : LLModel =

GPT-4.1 — complex-task model (1,047,576 context, 32k output).

let
let gpt_4_1_nano : LLModel =

GPT-4.1 nano — smallest, cheapest 4.1 (1,047,576 context, 32k output).

let
let gpt_4_1_mini : LLModel =

GPT-4.1 mini — balanced 4.1 (1,047,576 context, 32k output).

let
let o1 : LLModel =

o1 — the reasoning model (200k context, 100k output).

let
let o3 : LLModel =

o3 — well-rounded reasoning across domains (200k context, 100k output).

let
let o3_mini : LLModel =

o3-mini — small reasoning model, no vision (200k context, 100k output).

let
let o4_mini : LLModel =

o4-mini — cost-effective reasoning (200k context, 100k output).

let
let gpt_5 : LLModel =

GPT-5 — flagship for coding, reasoning, agentic tasks (400k context, 128k output).

let
let gpt_5_mini : LLModel =

GPT-5 mini — faster, cheaper GPT-5 (400k context, 128k output).

let
let gpt_5_nano : LLModel =

GPT-5 nano — fastest, cheapest GPT-5 (400k context, 128k output).

let
let gpt_5_codex : LLModel =

GPT-5-Codex — agentic coding, Responses API only (400k context, 128k output).

let
let gpt_5_pro : LLModel =

GPT-5 pro — highest-compute reasoning, Responses API only (400k context, 272k output).

let
let gpt_5_1 : LLModel =

GPT-5.1 — flagship with configurable reasoning effort (400k context, 128k output).

let
let gpt_5_1_codex : LLModel =

GPT-5.1-Codex — agentic coding, Responses API only (400k context, 128k output).

let
let gpt_5_1_codex_max : LLModel =

GPT-5.1-Codex-Max — purpose-built agentic coding, Responses API only (400k context, 128k output).

let
let gpt_5_2 : LLModel =

GPT-5.2 — flagship for coding and agentic tasks (400k context, 128k output).

let
let gpt_5_2_pro : LLModel =

GPT-5.2 pro — Responses API only, no JSON schema (400k context, 128k output).

let
let gpt_5_2_codex : LLModel =

GPT-5.2-Codex — agentic coding, Responses API only, no JSON schema (400k context, 128k output).

let
let gpt_5_3_codex : LLModel =

GPT-5.3-Codex — agentic coding, Responses API only, no JSON schema (400k context, 128k output).

let
let gpt_5_4 : LLModel =

GPT-5.4 — frontier model for complex professional work (1,050,000 context, 128k output).

let
let gpt_5_4_mini : LLModel =

GPT-5.4 mini — faster GPT-5.4 for high-volume workloads (400k context, 128k output).

let
let gpt_5_4_nano : LLModel =

GPT-5.4 nano — speed/cost model for classification and sub-agents (400k context, 128k output).

let
let gpt_5_4_pro : LLModel =

GPT-5.4 pro — highest-compute GPT-5.4, Responses API only (1,050,000 context, 128k output).

let
let gpt_5_5 : LLModel =

GPT-5.5 — newest frontier model (1,050,000 context, 128k output).

let
let gpt_5_5_pro : LLModel =

GPT-5.5 pro — highest-compute GPT-5.5, Responses API only (1,050,000 context, 128k output).

let
let gpt_audio : LLModel =

GPT Audio — audio in and out (128k context, 16k output).

let
let gpt_4o_mini_audio : LLModel =

GPT-4o mini Audio — cheaper audio model (128k context, 16k output).

let
let gpt_4o_audio : LLModel =

GPT-4o Audio — audio in and out (128k context, 16k output).

let
let text_embedding_3_small : LLModel =

text-embedding-3-small — cost-effective embeddings (8191 context).

let
let text_embedding_3_large : LLModel =

text-embedding-3-large — highest-quality embeddings (8191 context).

let
let text_embedding_ada_002 : LLModel =

text-embedding-ada-002 — the older ada embeddings (8191 context).

let
let omni_moderation : LLModel =

omni-moderation — the most capable moderation model, text + image (32768 context).

fn
fn openai_models() -> Array[LLModel]

The OpenAI models supported out of the box (Koog OpenAIModels.supportedModels), in the source's grouping order.

let
let claude_3_opus : LLModel =

Claude 3 Opus.

let
let claude_3_haiku : LLModel =

Claude 3 Haiku.

let
let claude_3_5_sonnet : LLModel =

Claude 3.5 Sonnet.

let
let claude_3_5_haiku : LLModel =

Claude 3.5 Haiku.

let
let claude_3_7_sonnet : LLModel =

Claude 3.7 Sonnet.

let
let claude_sonnet_4 : LLModel =

Claude Sonnet 4.

let
let claude_opus_4 : LLModel =

Claude Opus 4.

let
let claude_opus_4_1 : LLModel =

Claude Opus 4.1.

let
let claude_sonnet_4_5 : LLModel =

Claude Sonnet 4.5.

let
let gemini_2_0_flash_lite_001 : LLModel =

Gemini 2.0 Flash-Lite (specific version).

let
let gemini_2_5_pro : LLModel =

Gemini 2.5 Pro — advanced capabilities for complex tasks.

let
let gemini_2_5_flash : LLModel =

Gemini 2.5 Flash — a balance of speed and capability.

let
let gemini_2_5_flash_lite : LLModel =

Gemini 2.5 Flash-Lite — cost-efficient, high throughput.

let
let gemini_3_flash_preview : LLModel =

Gemini 3 Flash Preview — Pro-level intelligence at Flash speed.

let
let gemini_3_1_pro_preview : LLModel =

Gemini 3.1 Pro Preview — advanced reasoning.

let
let gemini_3_1_flash_lite_preview : LLModel =

Gemini 3.1 Flash-Lite Preview — low latency.

let
let gemini_3_1_flash_lite : LLModel =

Gemini 3.1 Flash-Lite — low latency.

let
let gemini_3_5_flash : LLModel =

Gemini 3.5 Flash — fast multimodal generation.

let
let gemini_embedding_001 : LLModel =

Gemini embedding model (text embeddings).

fn
fn google_models() -> Array[LLModel]

The Google models supported out of the box (Koog GoogleModels.supportedModels), in the source's order.

let
let deepseek_v4_flash : LLModel =

DeepSeek V4 Flash — fast, cost-effective generation (also moonkoog's default smoke-test model).

let
let deepseek_v4_pro : LLModel =

DeepSeek V4 Pro — advanced reasoning and agentic tasks.

fn
fn deepseek_models() -> Array[LLModel]

The DeepSeek models supported out of the box (Koog DeepSeekModels.supportedModels).

let
let mistral_medium_3 : LLModel =

Mistral Medium 3 — frontier-class multimodal (128k context).

let
let mistral_large_2_1 : LLModel =

Mistral Large 2.1 — top-tier model for high-complexity tasks (128k context).

let
let mistral_small_2 : LLModel =

Mistral Small 2 — efficient model for standard tasks (32k context).

let
let magistral_medium_1_2 : LLModel =

Magistral Medium 1.2 — frontier reasoning model with vision (128k context).

let
let codestral : LLModel =

Codestral — coding model for low-latency fill-in-the-middle and corrections (256k context).

let
let devstral_medium : LLModel =

Devstral Medium — enterprise coding model for software-engineering agents (128k context).

let
let mistral_embed : LLModel =

Mistral Embed — text embedding model (8k context).

let
let codestral_embed : LLModel =

Codestral Embed — code embedding model (8k context).

let
let mistral_moderation : LLModel =

Mistral Moderation — content-safety moderation model (8k context).

fn
fn mistral_models() -> Array[LLModel]

The Mistral AI models supported out of the box (Koog MistralAIModels.supportedModels).

§Tools

A tool states its JSON schema through an explicit descriptor - MoonBit has no reflection to derive one from - and a ToolRegistry is what an agent is handed. The prebuilt file, shell and search tools are ready to register.

enum
enum ToolParameterType

The JSON-schema type of a tool parameter. Koog's ToolParameterType is a sealed hierarchy; this is a faithful 1:1 sum. TList/TObject/TAnyOf recur. Source: agents/agents-tools/.../tools/ToolDescriptor.kt.

struct
struct ToolParameterDescriptor

One named tool parameter: its name, human description, and schema type. Source: agents/agents-tools/.../tools/ToolDescriptor.kt.

struct
struct ToolDescriptor

A tool's schema as the LLM is shown it (Koog ToolDescriptor): the name it is called by, a description, and the required / optional parameter lists. Source: agents/agents-tools/.../tools/ToolDescriptor.kt.

fn
fn ToolParameterType::to_json_schema(self : ToolParameterType) -> Json

This parameter type as a JSON Schema fragment — what a tool/function definition advertises to the model, and what a structured-output request constrains the reply to. Koog derives the schema from the Kotlin type via kotlinx.serialization; with no reflection here it is rendered from the explicit ToolParameterType.

item
pub(open) trait Tool

A callable tool. Koog's Tool<TArgs, TResult> derives its schema from the argument type via kotlinx.serialization + a TypeToken; MoonBit has no reflection, so a tool states its descriptor() explicitly and execute_raw decodes the JSON arguments, runs, and encodes the result to the string the model is shown — Koog's decodeArgs + execute + encodeResultToString collapsed to the SimpleTool<TArgs> : String shape. Source: agents/agents-tools/.../tools/{ToolBase,Tool,SimpleTool}.kt.

struct
struct ToolRegistry

A set of tools addressable by name. Koog ToolRegistry. Source: agents/agents-tools/.../tools/ToolRegistry.kt.

fn
fn ToolRegistry::new() -> ToolRegistry

An empty registry (Koog ToolRegistry.EMPTY).

fn
fn ToolRegistry::add(self : ToolRegistry, tool : &Tool) -> ToolRegistry

Register a tool and return the registry, so registration chains (MoonBit has no receiver-lambda DSL for Koog's ToolRegistry { tool(...) }).

fn
fn ToolRegistry::get_tool(self : ToolRegistry, name : String) -> &Tool?

The tool named name, or None (Koog getToolOrNull).

fn
fn ToolRegistry::descriptors(self : ToolRegistry) -> Array[ToolDescriptor]

Every registered tool's descriptor — what a request advertises to the model.

struct
struct ExitTool

End the agent run and return result as the final answer (Koog ExitTool).

fn
fn ExitTool::new() -> ExitTool

The exit tool.

item
impl Tool for ExitTool with fn descriptor(_self)
item
impl Tool for ExitTool with fn execute_raw(_self, args)
struct
struct SayToUser

Show a message to the user through the configured sink (Koog SayToUser).

fn
fn SayToUser::new(sink : (String) -> Unit) -> SayToUser

A say-to-user tool that writes messages to sink.

item
impl Tool for SayToUser with fn descriptor(_self)
item
impl Tool for SayToUser with fn execute_raw(self, args)
struct
struct AskUser

Ask the user a question and return their reply from the configured responder (Koog AskUser).

fn
fn AskUser::new(responder : (String) -> String) -> AskUser

An ask-user tool that reads replies from responder.

item
impl Tool for AskUser with fn descriptor(_self)
item
impl Tool for AskUser with fn execute_raw(self, args)
item
pub(open) trait FileSystem

The filesystem a file tool reads and writes through (Koog FileSystemProvider).

struct
struct MemFileSystem

An in-memory filesystem: a map of path to contents; list returns the paths under a directory prefix.

fn
fn MemFileSystem::new() -> MemFileSystem

An empty in-memory filesystem.

item
impl FileSystem for MemFileSystem with fn read(self, path)
item
impl FileSystem for MemFileSystem with fn write(self, path, content)
item
impl FileSystem for MemFileSystem with fn list(self, path)
struct
struct ReadFileTool

Read a file's contents (Koog ReadFileTool).

fn
fn ReadFileTool::new(fs : &FileSystem) -> ReadFileTool

A read-file tool over fs.

item
impl Tool for ReadFileTool with fn descriptor(_self)
item
impl Tool for ReadFileTool with fn execute_raw(self, args)
struct
struct WriteFileTool

Write contents to a file (Koog WriteFileTool).

fn
fn WriteFileTool::new(fs : &FileSystem) -> WriteFileTool

A write-file tool over fs.

item
impl Tool for WriteFileTool with fn descriptor(_self)
item
impl Tool for WriteFileTool with fn execute_raw(self, args)
struct
struct ListDirectoryTool

List the files under a directory (Koog ListDirectoryTool).

fn
fn ListDirectoryTool::new(fs : &FileSystem) -> ListDirectoryTool

A list-directory tool over fs.

item
impl Tool for ListDirectoryTool with fn descriptor(_self)
item
impl Tool for ListDirectoryTool with fn execute_raw(self, args)
item
pub(open) trait ShellExecutor

Runs a shell command line and returns its output (Koog ShellCommandExecutor).

struct
struct ExecuteShellCommandTool

Run a shell command through the configured executor (Koog ExecuteShellCommandTool).

fn
fn ExecuteShellCommandTool::new( executor : &ShellExecutor) -> ExecuteShellCommandTool

A shell-command tool over executor.

item
impl Tool for ExecuteShellCommandTool with fn descriptor(_self)
item
impl Tool for ExecuteShellCommandTool with fn execute_raw(self, args)
struct
struct RegexSearchTool

Search the files under a path for pattern, listing those whose contents match (Koog RegexSearchTool).

fn
fn RegexSearchTool::new(fs : &FileSystem) -> RegexSearchTool

A regex-search tool over fs.

item
impl Tool for RegexSearchTool with fn descriptor(_self)
item
impl Tool for RegexSearchTool with fn execute_raw(self, args)

§The agent

AIAgent and the strategy graph it walks. run is not a special-cased loop, it is run_strategy wired with single_run_strategy. A RunHandle stops a run between nodes, so a tool call in progress always finishes. EventHandler observes every step.

item
suberror AgentError

What ends a run other than an answer: AgentError when the loop runs longer than max_iterations without the model producing a final text answer, AgentStopped when the run was asked to stop through its [RunHandle], carrying the text it had reached by then.

struct
struct RunHandle

A handle for stopping a run from outside it. Koog cancels the agent's coroutine, which can land in the middle of a tool call; a graph walk can stop more politely than that, so a run holding one of these finishes the node it is in and stops at the next boundary. Hand the same handle to run or run_strategy and call stop from anywhere — a supervisor, a signal handler, a deadline.

fn
fn RunHandle::new() -> RunHandle

A handle that has not been asked to stop.

fn
fn RunHandle::stop(self : RunHandle) -> Unit

Ask the run to stop at its next node boundary. Calling this more than once, or after the run has finished, does nothing further.

fn
fn RunHandle::stopping(self : RunHandle) -> Bool

Whether a stop has been requested.

struct
struct AIAgent

A single-run agent — Koog's AIAgent as built by its ergonomic factory over the default singleRunStrategy. It pairs an LLM executor + model with a tool registry and an optional system prompt, and runs the tool-calling loop. params is what Koog's AIAgentConfig carries inside its whole Prompt: every request a run makes starts from it, so temperature, tool choice, token cap and the rest reach the provider. Source: agents/agents-core/.../agent/{AIAgent,AIAgentFactory,AIAgentConfig}.kt.

fn
fn AIAgent::new( executor : &LLMClient, model~ : @llm.LLModel, tool_registry? : @tools.ToolRegistry = @tools.ToolRegistry::new(), system_prompt? : String? = None, params? : @prompt.LLMParams = @prompt.LLMParams::default(), max_iterations? : Int = 50, events? : EventHandler = EventHandler::new()) -> AIAgent

Build an agent. params defaults to the provider's own defaults (Koog's empty LLMParams); max_iterations to Koog's 50; events to a no-op handler (install one to observe the run).

item
async fn AIAgent::run( self : AIAgent, input : String, stop? : RunHandle, checkpoints? : Checkpointer, resume_from? : AgentCheckpoint) -> String

Run the agent on input, returning the final assistant text. Koog's default singleRunStrategy: request a completion; return it if it is plain text; otherwise run every requested tool, feed the results back, and request again, bounded by max_iterations. This delegates to run_strategy with single_run_strategy — the loop is not special-cased, it is one wiring of the strategy graph (see strategy.mbt), the way Koog builds singleRunStrategy from the same graph DSL. Source: agents/agents-core/.../agent/AIAgentSimpleStrategies.kt (singleRunStrategy).

enum
enum NodeValue

The value passed between strategy nodes: the text that enters at the start and leaves at the finish, an LLM assistant reply, the JSON a structured request parsed, a moderation verdict, or a bare token from a node whose effect is on the conversation (tools executed) rather than on a carried value.

fn
fn NodeValue::text(self : NodeValue) -> String

The text a NodeValue carries: the raw text, an assistant reply's text, the JSON re-serialized, a moderation verdict as harmful / safe, or empty.

fn
fn NodeValue::to_json(self : NodeValue) -> Json

The value as Json, tagged by variant, so a checkpoint can carry what was in flight between two nodes.

fn
fn NodeValue::from_json(json : Json) -> NodeValue raise AgentError

Read back a value written by to_json. Raises AgentError on a tag or payload that does not belong to a NodeValue — a checkpoint that cannot be decoded cannot be resumed from, and saying so beats resuming at the right node with the wrong value.

enum
enum NodeKind

A standard node's behaviour (Koog's nodeStart / nodeFinish / nodeLLMRequest / nodeExecuteTool / nodeLLMSendToolResult). NodeExecuteTools runs every tool call in the reply (Koog's multiple-tool variant), matching the conversation the loop builds.

enum
enum EdgeCondition

When an edge fires, tested against the source node's output. Always is an unconditional edge; OnAssistantMessage fires on a plain-text reply (no tool calls); OnToolCalls fires on a reply that requests tools; OnPredicate fires on any test of the value at all. Koog's onCondition / onAssistantMessage / onToolCall.

struct
struct StrategyEdge

A directed edge from -> to that fires when condition holds.

struct
struct AIAgentStrategy

A strategy graph: named nodes, edges between them, and the start / finish node names. max_steps bounds node visits, a backstop against a cyclic graph that never reaches finish (the per-agent max_iterations bounds LLM calls).

let
let start_node : String = "__start__"

The canonical start / finish node names.

let
let finish_node : String = "__finish__"
fn
fn AIAgentStrategy::new( name : String, max_steps? : Int = 1000) -> AIAgentStrategy

A strategy seeded with the start and finish nodes, ready to have nodes and edges added. max_steps defaults to a generous backstop.

fn
fn AIAgentStrategy::node( self : AIAgentStrategy, name : String, kind : NodeKind) -> AIAgentStrategy

Add a named node, returning the strategy so calls chain.

fn
fn AIAgentStrategy::custom_node( self : AIAgentStrategy, name : String, handler : async (NodeSession, NodeValue) -> NodeValue) -> AIAgentStrategy

Add a custom node name whose behaviour is handler — an arbitrary step run against a NodeSession (Koog's node<In, Out> { ... }). Returns the strategy so calls chain.

fn
fn AIAgentStrategy::subgraph( self : AIAgentStrategy, name : String, strategy : AIAgentStrategy) -> AIAgentStrategy

Add node name that runs the whole of strategy and carries its finish value on (Koog's subgraph). Returns the strategy so calls chain.

fn
fn AIAgentStrategy::subgraph_retry( self : AIAgentStrategy, name : String, strategy : AIAgentStrategy, until~ : (NodeValue) -> Bool, max_retries? : Int = 2) -> AIAgentStrategy

Add node name that runs strategy and re-runs it while until rejects the result, at most max_retries extra times (Koog's SubgraphWithRetry). Returns the strategy so calls chain.

fn
fn AIAgentStrategy::parallel( self : AIAgentStrategy, name : String, nodes : Array[String], merge~ : (Array[NodeValue]) -> NodeValue) -> AIAgentStrategy

Add node name that runs every node in nodes at once on the same input and hands their results, in that order, to merge (Koog's parallel). Returns the strategy so calls chain.

fn
fn AIAgentStrategy::edge( self : AIAgentStrategy, from : String, to : String, condition? : EdgeCondition = Always, transform? : ((NodeValue) -> NodeValue)? = None) -> AIAgentStrategy

Add an edge from -> to firing on condition (unconditional by default), returning the strategy so calls chain. transform rewrites the value the next node sees.

fn
fn single_run_strategy(max_steps? : Int = 1000) -> AIAgentStrategy

Koog's singleRunStrategy expressed as a graph: request the LLM; on a plain-text reply finish, on a tool-call reply execute the tools, feed the results back, and request again — looping until the model answers in text.

fn
fn chat_agent_strategy(max_steps? : Int = 1000) -> AIAgentStrategy

Koog's chatAgentStrategy expressed as a graph: request the LLM; a tool call is executed, but a plain-text reply is nudged ("call a tool instead of chatting") and the LLM re-requested until it calls a tool; the loop finishes when the model calls the exit tool (__exit__), whose edge carries "Chat finished" as the result.

fn
fn react_strategy( reasoning_interval? : Int = 1, reasoning_prompt? : String = "Please give your thoughts about the task and plan the next steps.", max_steps? : Int = 1000) -> AIAgentStrategy

Koog's reActStrategy: alternate reasoning and action. Each round reasons (a tools-off request seeded with reasoning_prompt), then acts (a request with tools); a tool call is executed and, every reasoning_interval rounds, the results are reasoned over before the next action; a plain-text reply finishes. Built on custom nodes carrying a reasoning-step counter in the session's per-run store.

struct
struct NodeSession

The session a custom node runs against (Koog's AIAgentLLMWriteSession receiver): the request/append/storage operations a node closure needs, without exposing the whole context. This is the MoonBit stand-in for Kotlin's receiver-lambda node DSL.

fn
fn NodeSession::append_user(self : NodeSession, text : String) -> Unit

Append a user message to the conversation.

fn
fn NodeSession::append( self : NodeSession, message : @prompt.Message) -> Unit

Append a ready message to the conversation.

item
async fn NodeSession::request_llm(self : NodeSession) -> @prompt.Message

Request the model with the advertised tools (Koog requestLLM).

item
async fn NodeSession::request_llm_no_tools( self : NodeSession) -> @prompt.Message

Request the model with no tools — a reasoning step (Koog requestLLMWithoutTools).

fn
fn NodeSession::storage(self : NodeSession) -> AgentStorage

The run's AIAgentStorage — what a node reaches for when it wants the whole store rather than one entry (contains, remove, a snapshot).

item
fn[T : @json.FromJson] NodeSession::get( self : NodeSession, key : String) -> T?

Read the value stored under key at the type the call site asks for; None when the key is unset or its Json does not decode to that type.

item
fn[T : ToJson] NodeSession::set( self : NodeSession, key : String, value : T) -> Unit

Store any ToJson value under key, replacing what was there.

fn
fn NodeSession::tool_names(self : NodeSession) -> Array[String]

The names of the tools advertised to the model.

item
async fn AIAgent::run_strategy( self : AIAgent, strategy : AIAgentStrategy, input : String, stop? : RunHandle, checkpoints? : Checkpointer, resume_from? : AgentCheckpoint) -> String

Run strategy on input, returning the finish node's text. Seeds the prompt with the agent's params and system message, then walks the graph. LLM requests are bounded by the agent's max_iterations (Koog's iteration cap) across the whole run, nested subgraphs and parallel branches included; node visits by each strategy's max_steps. With checkpoints, every top-level node boundary is snapshotted into the given store before the node runs. Passing one of those snapshots back as resume_from replays its conversation, storage and spent-iteration count and re-enters the walk at the node it was taken before, so a run picks up where it stopped instead of starting over; input is then unused, the value in flight coming from the checkpoint.

struct
struct EventHandler

Lifecycle hooks over an agent run (← Koog's agents-features-event-handler EventHandlerConfig): observe the agent starting and completing, each LLM call, each tool call, and each strategy node as it runs. The transcribed core of Koog's hook set — enough for logging, tracing, and token accounting to sit outside the agent loop. Registering a handler *chains* it after any already registered for that hook, so several observers all fire (Koog composes the previous handler with the new one). Hooks are synchronous; an async observer is a later refinement, as Koog's suspend hooks are.

fn
fn EventHandler::new() -> EventHandler

An event handler with every hook a no-op — the default an agent carries when no observer is installed.

fn
fn EventHandler::on_agent_starting( self : EventHandler, handler : (String) -> Unit) -> EventHandler

Observe the agent starting, on its input. Chains after any prior handler.

fn
fn EventHandler::on_agent_completed( self : EventHandler, handler : (String) -> Unit) -> EventHandler

Observe the agent completing, with its final text. Chains.

fn
fn EventHandler::on_llm_call_starting( self : EventHandler, handler : (@prompt.Prompt) -> Unit) -> EventHandler

Observe each LLM request just before it is sent, with the prompt. Chains.

fn
fn EventHandler::on_llm_call_completed( self : EventHandler, handler : (@prompt.Message) -> Unit) -> EventHandler

Observe each LLM reply, with the assistant message. Chains.

fn
fn EventHandler::on_tool_call_starting( self : EventHandler, handler : (String, Json) -> Unit) -> EventHandler

Observe each tool call before it runs, with the tool name and JSON arguments. Chains.

fn
fn EventHandler::on_tool_call_completed( self : EventHandler, handler : (String, String) -> Unit) -> EventHandler

Observe each tool call after it runs, with the tool name and its result string. Chains.

fn
fn EventHandler::on_node_execution_starting( self : EventHandler, handler : (String) -> Unit) -> EventHandler

Observe each strategy node before it runs, by name. Chains.

fn
fn EventHandler::on_node_execution_completed( self : EventHandler, handler : (String) -> Unit) -> EventHandler

Observe each strategy node after it runs, by name. Chains.

item
pub(open) trait LLMClient

The LLM client contract (Koog LLMClientAPI, collapsed for the MVP with the single-LLM PromptExecutor — a single-provider executor is a one-line delegate to its client). execute sends a prompt with the tool descriptors the model may call and returns the assistant reply; any tool calls come back inside the reply's parts as ToolCalls. moderate checks a prompt against the provider's safety categories; its default reports nothing harmful, and a client that supports moderation overrides it. execute_multiple returns one reply per requested choice (Koog executeMultipleChoices, the count being prompt.params.number_of_choices); a provider without multi-choice returns a single-element list. Streaming is deferred to the async-stream layer. Source: prompt/prompt-executor/prompt-executor-clients/.../LLMClientAPI.kt.

struct
struct MockClient

A deterministic in-memory client for tests: it replays a scripted list of assistant replies, one per execute call, ignoring the prompt. This is what lets the agent loop be tested without a network or a real model — the loop's control flow is exercised by scripting "reply with a tool call", then "reply with the final text".

fn
fn MockClient::new( scripted : Array[@prompt.Message], provider? : @llm.LLMProvider = @llm.openai) -> MockClient

A mock that will hand back scripted replies in order.

item
impl LLMClient for MockClient with fn execute(self, prompt~, model~, tools~)
item
impl LLMClient for MockClient with fn provider(self)
item
impl LLMClient for MockClient with fn moderate(self, prompt~, model~)
item
impl LLMClient for MockClient with fn execute_multiple( self, prompt~, model~, tools~)

The scripted equivalent of a multi-choice request: hand back the next prompt.params.number_of_choices scripted replies, one per candidate, the way a provider returns one completion per requested choice.

struct
struct AgentResponse

An HTTP response: a status code and a JSON body.

struct
struct AgentEndpoint

An HTTP endpoint that runs agent for each request (Koog RoutingContext.aiAgent).

fn
fn AgentEndpoint::new(agent : AIAgent) -> AgentEndpoint

An endpoint serving agent.

item
async fn AgentEndpoint::handle( self : AgentEndpoint, body : String) -> AgentResponse

Handle a request body {"message": "..."}: run the agent and answer {"output": "..."} with status 200, or 400 when the body is not a valid request.

item
async fn AgentEndpoint::handle_sse( self : AgentEndpoint, body : String) -> String

Handle a request and stream the answer as one Server-Sent Event data: frame (Koog's sse helper), or an error event when the body is invalid.

§Strategies built on the graph

Planning, self-criticism, GOAP, node choice, multi-agent delegation and schema-constrained output - each one a wiring of the same graph rather than a loop of its own.

struct
struct PlanStep

One step of a plan: what to do, and whether it is already done (Koog PlanStep).

struct
struct SimplePlan

A plan: the overall goal and the ordered steps that reach it (Koog SimplePlan).

enum
enum PlanAssessment

A verdict on the current plan before a step runs (Koog SimplePlanAssessment): keep going, throw it away and replan with a reason, or there is no plan yet.

struct
struct LLMPlanner

A planner backed by client / model. With with_critic set it re-judges the plan with the model before each step (Koog SimpleLLMWithCriticPlanner); otherwise it keeps any existing plan (Koog SimpleLLMPlanner).

fn
fn LLMPlanner::new(client : &LLMClient, model : @llm.LLModel) -> LLMPlanner

A planner over client / model that keeps its plan once built.

fn
fn LLMPlanner::with_critic(self : LLMPlanner) -> LLMPlanner

The same planner with the LLM critic enabled (Koog Planners.llmBasedWithCritic).

item
async fn LLMPlanner::assess_plan( self : LLMPlanner, state : String, plan : SimplePlan?) -> PlanAssessment

Judge the current plan. With no plan there is nothing to judge; without the critic the plan is always kept; with the critic the model replies CONTINUE to keep it or REPLAN: <reason> to discard it.

item
async fn LLMPlanner::build_plan( self : LLMPlanner, state : String, plan : SimplePlan?) -> SimplePlan

Produce the plan to execute next: keep the current one if the assessment says so, otherwise ask the model for a fresh plan (feeding it the failed plan and the reason when replanning).

item
async fn LLMPlanner::execute_step( self : LLMPlanner, state : String, plan : SimplePlan) -> String

Execute the first not-yet-done step of plan against state, mark it done, and return the model's output as the new state. When every step is done the plan is complete.

fn
fn LLMPlanner::is_plan_completed( self : LLMPlanner, plan : SimplePlan) -> Bool

Whether every step of plan is done (Koog isPlanCompleted).

item
async fn LLMPlanner::run( self : LLMPlanner, input : String, max_steps? : Int = 32) -> String

Run the planner end to end (Koog AIAgentPlanner.execute): build a plan, execute its steps one by one re-judging before each, and return the final state. max_steps bounds the loop the way Koog's maxAgentIterations does.

struct
struct CriticVerdict

A critic's verdict on a solution: whether it passed, and any feedback (Koog CriticResult).

struct
struct LLMCritic

An LLM critic that judges solutions with client / model.

fn
fn LLMCritic::new(client : &LLMClient, model : @llm.LLModel) -> LLMCritic

A critic backed by client / model.

item
async fn LLMCritic::judge( self : LLMCritic, task : String, solution : String) -> CriticVerdict

Ask the model whether solution correctly solves task. A reply beginning CORRECT passes; otherwise it fails, and the text after the first colon is the feedback.

struct
struct GoapAction[S]

An action: its name, when it applies, the state it produces, and its cost.

struct
struct GoapGoal[S]

A goal: whether a state satisfies it, and a heuristic estimate of the cost still to go.

item
fn[S : Eq + Hash] goap_plan( actions : Array[GoapAction[S]], initial : S, goal : GoapGoal[S]) -> Array[String]?

Plan the least-cost action-name sequence from initial to a state satisfying goal with A* over the state space, or None when the goal is unreachable.

item
pub(open) trait ChoiceSelectionStrategy

A strategy for choosing one reply among several candidates for a prompt.

struct
struct FirstChoice

Take the first candidate (Koog ChoiceSelectionStrategy.Default).

fn
fn FirstChoice::new() -> FirstChoice

The first-choice selector.

item
impl ChoiceSelectionStrategy for FirstChoice with fn choose( _self, _prompt, choices)
struct
struct LLMChoiceSelector

Ask a model to judge which candidate is best and return it (Koog's LLM-backed choice selection).

fn
fn LLMChoiceSelector::new( client : &LLMClient, model : @llm.LLModel) -> LLMChoiceSelector

A selector that judges with client / model.

item
impl ChoiceSelectionStrategy for LLMChoiceSelector with fn choose( self, _prompt, choices)
struct
struct MultiLLMClient

One LLMClient over several providers (← Koog's MultiLLMPromptExecutor): register a client per provider, and every request routes to the client whose provider matches the request's model.provider. An optional fallback client serves any provider that was not registered. Because MoonBit's LLMClient.execute does not raise, a request for a provider with neither a client nor a fallback gets a plain assistant message naming the miss, rather than a crash — an honest, visible degradation of Koog's IllegalArgumentException.

fn
fn MultiLLMClient::new( default_provider? : @llm.LLMProvider = @llm.openai) -> MultiLLMClient

An empty router. default_provider is what the router reports as its own provider() (Koog executors are provider-agnostic; a value is still required).

fn
fn MultiLLMClient::register( self : MultiLLMClient, provider : @llm.LLMProvider, client : &LLMClient) -> MultiLLMClient

Register client for provider, returning the router so registrations chain.

fn
fn MultiLLMClient::with_fallback( self : MultiLLMClient, client : &LLMClient) -> MultiLLMClient

Set the fallback client used for any provider without its own registration.

item
impl LLMClient for MultiLLMClient with fn execute( self, prompt~, model~, tools~)
item
impl LLMClient for MultiLLMClient with fn provider(self)
item
impl LLMClient for MultiLLMClient with fn moderate(self, prompt~, model~)
item
impl LLMClient for MultiLLMClient with fn execute_multiple( self, prompt~, model~, tools~)
struct
struct StructuredSchema[T]

A structured-response request: the schema the reply must match and the parser that turns its JSON into a T.

struct
struct StructuredResponse[T]

A structured request's result: the parsed value and the raw model text it came from.

item
async fn[T] AIAgent::request_structured( self : AIAgent, input : String, schema : StructuredSchema[T], max_fixes? : Int = 2) -> StructuredResponse[T]

Request a structured response to input, retrying up to max_fixes times when the reply does not parse. Asks through the provider's own structured-output format when the model declares a JSON-schema capability, and states the schema in the prompt as well, so a provider that ignores response_format still has the shape in front of it. On each malformed reply it appends the bad output and a fixing instruction and asks again — Koog's StructureFixingParser. Raises AgentError if no reply parses within the budget.

§Around the run

Retry, response caching, moderation, history compression, checkpointing and the storage behind them.

enum
enum RetryPattern

What marks an error as worth retrying (Koog RetryablePattern): a substring of the error's described message, matched case-insensitively, or an HTTP status code appearing in it.

fn
fn RetryPattern::matches(self : RetryPattern, message : String) -> Bool

Whether message matches this pattern.

struct
struct RetryConfig

How a retry is paced (Koog RetryConfig): how many attempts in total, the wait before the first retry, the ceiling that wait grows to, the factor it grows by, and how far the wait is randomly spread either side of its nominal value to keep concurrent clients from retrying in lockstep. patterns is what makes an error retryable at all.

fn
fn RetryConfig::default() -> RetryConfig

Koog's RetryConfig.DEFAULT: three attempts, 1s growing by 2× to a 30s ceiling, 10% jitter, retrying the transient provider failures — rate limits, 5xx, timeouts, dropped connections.

fn
fn RetryConfig::disabled() -> RetryConfig

Koog's RetryConfig.DISABLED: one attempt, so nothing is ever retried.

fn
fn RetryConfig::matches(self : RetryConfig, message : String) -> Bool

Whether any configured pattern claims message.

fn
fn RetryConfig::delay_ms(self : RetryConfig, attempt : Int) -> Int

The nominal wait before retry number attempt (1 for the first retry): the initial delay grown by backoff_multiplier once per earlier retry, capped at max_delay_ms. Jitter is applied on top of this by the client, which owns the randomness.

fn
fn default_describe(error : Error) -> String

What a bare Error says about itself: its constructor's qualified name, and nothing of the payload. The fallback describer, and the reason a caller wants to replace it.

struct
struct RetryingClient

A client that retries execute on a retryable failure, backing off between attempts.

fn
fn RetryingClient::new( inner : &LLMClient, config? : RetryConfig = RetryConfig::default(), describe? : (Error) -> String = default_describe, retryable? : ((Error) -> Bool)? = None, wait? : async (Int) -> Unit = @async.sleep, seed? : Bytes? = None) -> RetryingClient

Wrap inner. config paces the retries and holds the patterns; describe turns a caught error into the message those patterns are matched against — the default sees only the error's type name, so pass the describer for the client's own error type (@client.describe_llm_error for the OpenAI-compatible and Anthropic clients) or nothing will look retryable. retryable replaces that classification outright. wait is the sleep — the default is real time, a test passes a recorder. seed seeds the jitter: MoonBit has no ambient entropy, so without one every client jitters the same sequence.

item
impl LLMClient for RetryingClient with fn execute( self, prompt~, model~, tools~)
item
impl LLMClient for RetryingClient with fn provider(self)
item
impl LLMClient for RetryingClient with fn moderate(self, prompt~, model~)
item
impl LLMClient for RetryingClient with fn execute_multiple( self, prompt~, model~, tools~)
struct
struct CachingClient

A client that caches execute replies by prompt + model.

fn
fn CachingClient::new(inner : &LLMClient) -> CachingClient

Wrap inner with an in-memory reply cache.

fn
fn CachingClient::size(self : CachingClient) -> Int

The number of distinct prompts currently cached.

item
impl LLMClient for CachingClient with fn execute( self, prompt~, model~, tools~)
item
impl LLMClient for CachingClient with fn provider(self)
item
impl LLMClient for CachingClient with fn moderate(self, prompt~, model~)
item
impl LLMClient for CachingClient with fn execute_multiple( self, prompt~, model~, tools~)
struct
struct ModerationCategoryResult

One safety category's verdict (Koog ModerationCategoryResult): whether the category was detected in the content and, when the provider gives one, its confidence score.

struct
struct ModerationResult

A moderation verdict (Koog ModerationResult): whether the content is harmful overall and the per-category detections a provider's moderation endpoint returned.

fn
fn ModerationResult::safe() -> ModerationResult

A verdict that flags nothing — what a client without moderation support returns.

fn
fn ModerationResult::is_category_detected( self : ModerationResult, category : String) -> Bool

Whether category was detected in the moderated content.

enum
enum HistoryCompression

Which part of the history to compress (Koog's default strategies).

struct
struct HistoryCompressor

Compresses a conversation with client / model.

fn
fn HistoryCompressor::new( client : &LLMClient, model : @llm.LLModel) -> HistoryCompressor

A compressor backed by client / model.

item
async fn HistoryCompressor::compress( self : HistoryCompressor, messages : Array[@prompt.Message], strategy : HistoryCompression) -> Array[@prompt.Message]

Compress messages per strategy, returning the new message list: the summary first, then any kept messages. A list with nothing to summarise is returned unchanged.

item
using @persistence

The checkpoint record and its in-memory store, re-exported under @agent.

struct
struct Checkpointer

Where a run's node-boundary snapshots go: the store, the session id they are filed under, and the clock that stamps them. MoonBit has no ambient clock, so a caller that cares about wall time supplies one; without it a checkpoint is stamped with its sequence number, which orders a session's checkpoints correctly and keeps tests deterministic.

fn
fn Checkpointer::new( store : &@persistence.PersistenceStorageProvider, session~ : String, clock? : (() -> Int64)? = None) -> Checkpointer

Snapshot every node boundary of a run into store under session.

struct
struct AgentStorage

A per-agent key-value store of Json-serialized values.

fn
fn AgentStorage::new() -> AgentStorage

A fresh empty store.

item
fn[T : ToJson] AgentStorage::set( self : AgentStorage, key : String, value : T) -> Unit

Serialize value and store it under key, replacing any existing value.

item
fn[T : @json.FromJson] AgentStorage::get( self : AgentStorage, key : String) -> T?

The value stored under key, deserialized to T, or None if the key is absent or its stored Json does not decode to T.

fn
fn AgentStorage::contains(self : AgentStorage, key : String) -> Bool

Whether a value is stored under key.

fn
fn AgentStorage::remove(self : AgentStorage, key : String) -> Bool

Remove key; returns whether it was present.

fn
fn AgentStorage::clear(self : AgentStorage) -> Unit

Remove every entry.

fn
fn AgentStorage::size(self : AgentStorage) -> Int

The number of stored entries.

fn
fn AgentStorage::snapshot(self : AgentStorage) -> Json

A Json snapshot of the whole store — every entry as a field of a Json object (Koog's toSerializedMap). This is what a checkpoint persists.

fn
fn AgentStorage::restore(self : AgentStorage, snapshot : Json) -> Unit

Replace the store's contents from a snapshot Json object, for restoring from a checkpoint.

§LLM clients

The OpenAI and Anthropic executors, and the embedding client. Native-only: they reach the network.

struct
struct OpenAiCompatibleClient

An OpenAI-compatible LLM client (Koog OpenAILLMClient and its provider siblings). It implements moonkoog's LLMClient by mapping Koog's prompt/message/tool model onto moonllm's request/response types and back; moonllm carries the actual HTTPS transport. One client talks to any OpenAI-compatible endpoint by its base_url. Source: prompt/prompt-executor/prompt-executor-clients/prompt-executor-openai-client/.../OpenAILLMClient.kt.

fn
fn OpenAiCompatibleClient::new( api_key~ : String, base_url~ : String, provider~ : @llm.LLMProvider, timeout_ms? : Int = 60000) -> OpenAiCompatibleClient

Build a client for base_url, authenticating with a bearer api_key.

item
impl @agent.LLMClient for OpenAiCompatibleClient with fn execute( self, prompt~, model~, tools~)
item
impl @agent.LLMClient for OpenAiCompatibleClient with fn execute_streaming( self, prompt~, model~, tools~, on_chunk~)

Stream the OpenAI-compatible chat completion (Koog OpenAILLMClient.executeStreaming): send with stream: true, invoke on_chunk for each text_delta off the SSE feed, and assemble the full reply (text plus any streamed tool calls) once the stream ends.

item
impl @agent.LLMClient for OpenAiCompatibleClient with fn provider(self)
item
impl @agent.LLMClient for OpenAiCompatibleClient with fn moderate( self, prompt~, model~)

Moderate the prompt through the OpenAI-compatible /moderations endpoint (Koog OpenAILLMClient.moderate): the prompt's text is sent to the moderation model and the returned per-category flags and confidence scores are mapped back to a Koog ModerationResult.

item
impl @agent.LLMClient for OpenAiCompatibleClient with fn execute_multiple( self, prompt~, model~, tools~)

Request number_of_choices completions (Koog executeMultipleChoices) and map each returned choice to a Koog message. The count comes from the prompt's params (default 1); OpenAI-compatible endpoints carry it as the n field.

fn
fn to_anthropic_request( prompt : @prompt.Prompt, model : @llm.LLModel, tools : Array[@tools.ToolDescriptor]) -> Json

Build an Anthropic Messages API request from a Koog prompt, model, and tools. System messages are lifted to the top-level system field; max_tokens (required by Anthropic) comes from the params, then the model's output limit, then a default of 4096.

fn
fn from_anthropic_response(response : Json) -> @prompt.Message

Parse an Anthropic Messages API response into a Koog assistant message: each text content block becomes a Text part, each tool_use block a ToolCall (its input the arguments), and stop_reason the finish reason.

struct
struct AnthropicClient

An Anthropic Messages API client (Koog AnthropicLLMClient) — the second wire format alongside the OpenAI-compatible client. It implements moonkoog's LLMClient by mapping Koog's prompt/message/tool model onto the Anthropic request/response JSON (to_anthropic_request / from_anthropic_response) and POSTing to /messages; moonllm carries the HTTPS transport, configured for Anthropic's x-api-key auth and required anthropic-version header. Source: prompt/.../clients/anthropic/AnthropicLLMClient.kt.

fn
fn AnthropicClient::new( api_key~ : String, base_url? : String = "https://api.anthropic.com/v1", version? : String = "2023-06-01", timeout_ms? : Int = 60000) -> AnthropicClient

Build a client for the Anthropic Messages API, authenticating with api_key via x-api-key and sending the anthropic-version. base_url defaults to Anthropic's public API; point it at a compatible gateway to override.

item
impl @agent.LLMClient for AnthropicClient with fn execute( self, prompt~, model~, tools~)
item
impl @agent.LLMClient for AnthropicClient with fn provider(self)
item
impl @agent.LLMClient for AnthropicClient with fn moderate( self, prompt~, model~)

Anthropic exposes no standalone moderation endpoint (unlike OpenAI's /moderations), so this honours the moderation contract by reporting nothing harmful; callers needing real moderation route it through a provider that offers it.

item
impl @agent.LLMClient for AnthropicClient with fn execute_multiple( self, prompt~, model~, tools~)

The Anthropic Messages API returns a single completion (there is no n), so multiple choices collapse to a single-element list.

struct
struct LLMEmbedder

An embedder that calls an OpenAI-compatible /embeddings endpoint. model is the embedding model id (e.g. text-embedding-3-small); moonllm carries the HTTPS transport.

fn
fn LLMEmbedder::new( api_key~ : String, base_url~ : String, model~ : String, timeout_ms? : Int = 60000) -> LLMEmbedder

Build an embedder for base_url, authenticating with a bearer api_key and requesting model.

item
impl @embeddings.Embedder for LLMEmbedder with fn embed(self, text)
item
impl @embeddings.Embedder for LLMEmbedder with fn diff( self, embedding1, embedding2)

§Embeddings and retrieval

Vectors and their similarity, the embedder contract, and the vector store a retrieval step queries.

item
suberror VectorError

A dimension mismatch in an operation that requires two vectors of equal length.

struct
struct Vector

A vector of floating-point values — the embedding of a piece of text.

fn
fn Vector::dimension(self : Vector) -> Int

The number of components in the vector.

fn
fn Vector::is_null(self : Vector) -> Bool

Whether every component is 0.0.

fn
fn Vector::magnitude(self : Vector) -> Double

The Euclidean norm — the square root of the sum of squared components.

fn
fn Vector::dot_product(self : Vector, other : Vector) -> Double

The dot product with other — the sum of products of corresponding components (over the shorter length when the dimensions differ, matching Koog's zip).

fn
fn Vector::cosine_similarity(self : Vector, other : Vector) -> Double raise

The cosine similarity with other, in [-1, 1]: 1 for identical directions, 0 for orthogonal (or either vector null), -1 for opposite. Raises VectorError on a dimension mismatch.

fn
fn Vector::euclidean_distance( self : Vector, other : Vector) -> Double raise

The Euclidean distance to other0 for identical vectors. Raises VectorError on a dimension mismatch.

item
pub(open) trait Embedder

Turns text into an embedding vector and scores the difference between two embeddings.

struct
struct MockEmbedder

A deterministic embedder for tests and offline use: it maps text to a fixed 4-dimensional vector by bucketing each code unit, so equal text yields equal vectors and shared characters pull two texts' vectors together — no network. diff is the cosine distance (1 - cosine similarity).

fn
fn MockEmbedder::new(dimension? : Int = 4) -> MockEmbedder

A fresh deterministic embedder producing dimension-component vectors (default 4).

item
impl Embedder for MockEmbedder with fn embed(self, text)
item
impl Embedder for MockEmbedder with fn diff(self, embedding1, embedding2)
enum
enum ScoreMetric

The metric a similarity score was computed with (Koog ScoreMetric).

struct
struct Score

A similarity score and the metric it was computed with (Koog Score).

struct
struct SearchResult[Doc]

A search hit: a stored document and the score it earned against the query (Koog SearchResult).

struct
struct VectorStore[Doc]

An in-memory store of documents keyed by a generated id, each paired with its embedding vector (Koog InMemoryVectorStorageBackend). Ids are sequential (doc-0, doc-1, …) rather than random UUIDs, so the store is deterministic.

item
fn[Doc] VectorStore::new() -> VectorStore[Doc]

A fresh empty store.

item
fn[Doc] VectorStore::store( self : VectorStore[Doc], document : Doc, vector : @embeddings.Vector) -> String

Store document with its vector, returning the id assigned to it.

item
fn[Doc] VectorStore::get(self : VectorStore[Doc], id : String) -> Doc?

The document stored under id, or None.

item
fn[Doc] VectorStore::delete(self : VectorStore[Doc], id : String) -> Bool

Remove the document under id; returns whether it was present.

item
fn[Doc] VectorStore::size(self : VectorStore[Doc]) -> Int

The number of stored documents.

item
fn[Doc] VectorStore::pairs( self : VectorStore[Doc]) -> Array[(Doc, @embeddings.Vector)]

Every stored (document, vector) pair — the input a similarity search ranks over.

item
fn[Doc] rank_by_similarity( query : @embeddings.Vector, documents : Array[(Doc, @embeddings.Vector)], limit? : Int = 10, offset? : Int = 0, min_score? : Double = 0.0) -> Array[SearchResult[Doc]] raise

Rank documents (each a document paired with its embedding) against query by cosine similarity (Koog EmbeddingStorage.search): score each, keep those at or above min_score, sort by score descending, then skip offset and keep at most limit. Raises @embeddings.VectorError on a dimension mismatch.

struct
struct EmbeddingStorage[Doc]

A document store that embeds documents on insertion and queries on search (Koog EmbeddingStorage): to_text extracts the text to embed from a document, the Embedder turns text into vectors, and the VectorStore holds them for cosine-similarity retrieval.

item
fn[Doc] EmbeddingStorage::new( embedder : &@embeddings.Embedder, to_text : (Doc) -> String) -> EmbeddingStorage[Doc]

A fresh storage over embedder, extracting embeddable text from each document with to_text.

item
async fn[Doc] EmbeddingStorage::add( self : EmbeddingStorage[Doc], documents : Array[Doc]) -> Array[String]

Embed each document and store it, returning the assigned ids (Koog EmbeddingStorage.add).

item
async fn[Doc] EmbeddingStorage::search( self : EmbeddingStorage[Doc], query_text : String, limit? : Int = 10, offset? : Int = 0, min_score? : Double = 0.0) -> Array[SearchResult[Doc]]

Embed query_text and return the stored documents most similar to it, ranked by cosine similarity (Koog EmbeddingStorage.search). Raises @embeddings.VectorError on a dimension mismatch between the query and a stored document.

item
fn[Doc] EmbeddingStorage::get( self : EmbeddingStorage[Doc], id : String) -> Doc?

The document stored under id, or None.

item
fn[Doc] EmbeddingStorage::delete( self : EmbeddingStorage[Doc], id : String) -> Bool

Remove the document under id; returns whether it was present.

item
fn[Doc] EmbeddingStorage::size(self : EmbeddingStorage[Doc]) -> Int

The number of stored documents.

§Memory and persistence

What an agent remembers between runs, and where a run's checkpoints live.

enum
enum FactType

Whether a concept holds one fact or many (Koog FactType).

struct
struct Concept

A concept the agent remembers facts about: a short keyword, a description the model is shown, and whether it carries one fact or many. Transcribed from the koog Concept data class.

enum
enum Fact

A fact about a concept, timestamped when captured (Koog's sealed Fact: SingleFact carries one value, MultipleFacts a list of values). The timestamp is caller-supplied — MoonBit has no ambient clock — the explicit equivalent of Koog threading a Clock into fact retrieval.

fn
fn Fact::concept(self : Fact) -> Concept

The concept a fact is about, whichever variant it is.

struct
struct MemorySubject

Who or what a fact is about (Koog MemorySubject): a name, and a priority for ordering when subjects overlap. The predefined subjects mirror Koog's.

let
let subject_everything : MemorySubject =
let
let subject_user : MemorySubject =
let
let subject_machine : MemorySubject =
let
let subject_organization : MemorySubject =
enum
enum MemoryScope

How widely a fact is shared (Koog MemoryScope): to a single agent, a single feature, the whole product, or across products.

item
pub(open) trait MemoryProvider

The save/load contract for agent memory (Koog AgentMemoryProvider): store a fact under a subject and scope, load a concept's facts back, or load everything in a bucket.

struct
struct InMemoryProvider

An in-memory MemoryProvider: facts kept in a map keyed by (scope, subject). The faithful equivalent of Koog's LocalFileMemoryProvider without the file backend — enough to run and test the memory contract in process.

fn
fn InMemoryProvider::new() -> InMemoryProvider

An empty in-memory provider.

item
impl MemoryProvider for InMemoryProvider with fn save( self, fact, subject, scope)
item
impl MemoryProvider for InMemoryProvider with fn load( self, concept, subject, scope)
item
impl MemoryProvider for InMemoryProvider with fn load_all( self, subject, scope)
struct
struct AgentCheckpoint

A snapshot of an agent's run at a node boundary (Koog AgentCheckpointData with its GraphCheckpointProperties): the conversation so far, the LLM configuration that produced it, the serialized AIAgentStorage, and where the strategy graph had reached — the node about to run (node_id) and the value flowing into it (last_input). Restoring replays message_history and resumes the walk at node_id. created_at is caller-supplied: MoonBit has no ambient clock, and a supplied one keeps a test's checkpoints deterministic.

fn
fn AgentCheckpoint::new( checkpoint_id~ : String, created_at~ : Int64, node_id~ : String, message_history? : Array[@prompt.Message] = [], llm_params? : @prompt.LLMParams? = None, llm_model? : @llm.LLModel? = None, tools? : Array[String]? = None, storage? : Json = Json::object(

A checkpoint with only the fields a resume needs stated; the rest carry empty defaults, so a caller that keeps no LLM configuration or storage need not spell them out.

item
pub(open) trait PersistenceStorageProvider

The checkpoint storage contract (Koog PersistenceStorageProvider): save a checkpoint under a session, list a session's checkpoints, or fetch its latest.

struct
struct InMemoryPersistence

An in-memory PersistenceStorageProvider (Koog InMemoryPersistencyStorageProvider): checkpoints kept per session in save order.

fn
fn InMemoryPersistence::new() -> InMemoryPersistence

An empty in-memory checkpoint store.

fn
fn InMemoryPersistence::save_checkpoint( self : InMemoryPersistence, session_id : String, checkpoint : AgentCheckpoint) -> Unit

Save checkpoint under session_id.

fn
fn InMemoryPersistence::get_checkpoints( self : InMemoryPersistence, session_id : String) -> Array[AgentCheckpoint]

Every checkpoint saved for session_id, in save order.

fn
fn InMemoryPersistence::get_latest_checkpoint( self : InMemoryPersistence, session_id : String) -> AgentCheckpoint?

The most recent checkpoint for session_id — the highest created_at, ties going to the last saved — or None when the session has none.

item
impl PersistenceStorageProvider for InMemoryPersistence with fn save_checkpoint( self, session_id, checkpoint)
item
impl PersistenceStorageProvider for InMemoryPersistence with fn get_checkpoints( self, session_id)
item
impl PersistenceStorageProvider for InMemoryPersistence with fn get_latest_checkpoint( self, session_id)

§MCP

Model Context Protocol both ways: expose this agent's tools to an MCP client, or call another server's tools as if they were local.

item
pub(open) trait McpTransport

A synchronous MCP transport: send one JSON-RPC request, get its response (Koog Transport).

struct
struct McpClient

An MCP client over transport, issuing JSON-RPC 2.0 calls with monotonically increasing ids.

fn
fn McpClient::new(transport : &McpTransport) -> McpClient

A client that talks to an MCP server through transport.

fn
fn McpClient::initialize(self : McpClient) -> Json raise

The MCP initialize handshake, advertising the client name and protocol version.

fn
fn McpClient::list_tools(self : McpClient) -> Array[Json] raise

List the tools the MCP server exposes (tools/list), returning each tool definition's JSON.

fn
fn McpClient::call_tool( self : McpClient, name : String, arguments : Json) -> Json raise

Call the MCP tool name with arguments (tools/call), returning the CallToolResult JSON.

struct
struct McpServer

An MCP server exposing the tools in registry.

fn
fn McpServer::new(registry : @tools.ToolRegistry) -> McpServer

A server advertising registry's tools over MCP.

fn
fn McpServer::handle(self : McpServer, request : Json) -> Json

Handle one JSON-RPC request, returning the response — a result, or an error object when the method itself fails (a tool's own failure is a normal isError result, not a protocol error).

struct
struct McpTool

A moonkoog tool backed by an MCP server tool (Koog McpTool).

fn
fn McpTool::new( client : McpClient, desc : @tools.ToolDescriptor) -> McpTool

An MCP-backed tool calling desc.name on client.

item
impl @tools.Tool for McpTool with fn descriptor(self)
item
impl @tools.Tool for McpTool with fn execute_raw(self, args)
fn
fn mcp_tool_registry(client : McpClient) -> @tools.ToolRegistry raise

Build a ToolRegistry from every tool an MCP server advertises (Koog McpToolRegistryProvider): initialize the connection, list the tools, parse each descriptor, and register a wrapping tool.

item
suberror McpError

Raised on a malformed MCP tool schema or JSON-RPC response (Koog throws IllegalArgumentException).

fn
fn parse_tool(tool : Json) -> @tools.ToolDescriptor raise

Parse an MCP tool definition into a ToolDescriptor (Koog DefaultMcpToolDescriptorParser.parse). The required names decide which parsed parameters are required and which are optional.

§A2A

Agent-to-Agent: the task model, the JSON-RPC dispatcher an executor sits behind, the agent card that advertises it, and the streaming and push-notification transports.

item
suberror A2AError

Raised on a malformed A2A payload.

enum
enum Role

Who authored a message (A2A Role).

enum
enum FileContent

A file attachment, carried either inline as base64 bytes or by URI (A2A FileWithBytes / FileWithUri).

enum
enum Part

One piece of a message: plain text, a file, or a structured data object (A2A Part).

struct
struct Message

A message exchanged with an agent (A2A Message).

fn
fn Message::user_text(message_id : String, text : String) -> Message

A user message with a single text part (the common case).

struct
struct Artifact

A file/data artifact an agent produced while working a task (A2A Artifact).

enum
enum TaskState

The lifecycle state of a task (A2A TaskState); terminal states admit no further transitions.

fn
fn TaskState::terminal(self : TaskState) -> Bool

Whether the state is terminal (Koog TaskState.terminal): completed, canceled, failed, rejected.

fn
fn TaskState::wire(self : TaskState) -> String

The wire (kebab-case @SerialName) form of the state.

fn
fn TaskState::from_wire(s : String) -> TaskState

The state named by its wire form (unrecognised names map to Unknown).

struct
struct TaskStatus

The status of a task: its state, an optional status message, and a timestamp (A2A TaskStatus).

struct
struct Task

A unit of work an agent runs on a caller's behalf (A2A Task).

fn
fn Part::to_json(self : Part) -> Json
fn
fn Message::to_json(self : Message) -> Json
fn
fn Artifact::to_json(self : Artifact) -> Json
fn
fn TaskStatus::to_json(self : TaskStatus) -> Json
fn
fn Task::to_json(self : Task) -> Json
fn
fn Part::from_json(j : Json) -> Part raise
fn
fn Message::from_json(j : Json) -> Message raise
fn
fn Artifact::from_json(j : Json) -> Artifact raise
fn
fn TaskStatus::from_json(j : Json) -> TaskStatus raise
fn
fn Task::from_json(j : Json) -> Task raise
item
pub(open) trait A2ATransport

A synchronous A2A transport: send one JSON-RPC request, get its response (Koog ClientTransport).

enum
enum SendResult

The outcome of message/send: the agent either opened a task or replied with a message directly (A2A's result is a Task | Message union, discriminated by kind).

struct
struct A2AClient

A client for a remote agent over transport, issuing JSON-RPC 2.0 calls with increasing ids.

fn
fn A2AClient::new(transport : &A2ATransport) -> A2AClient

A client talking to the agent behind transport.

fn
fn A2AClient::send_message( self : A2AClient, message : Message) -> SendResult raise

Send message to the agent (message/send), returning the task it opened or its direct reply.

fn
fn A2AClient::get_task( self : A2AClient, task_id : String, history_length? : Int) -> Task raise

Fetch the current state of a task (tasks/get), optionally bounding the returned history.

fn
fn A2AClient::cancel_task(self : A2AClient, task_id : String) -> Task raise

Request cancellation of a task (tasks/cancel), returning its updated state.

struct
struct RequestContext

The context an executor runs a request in (Koog RequestContext): the incoming message, the task and context ids it belongs to, and the existing task when the message continues one.

item
pub(open) trait AgentExecutor

The agent's logic behind a server (Koog AgentExecutor): run a request to a result, or cancel a task.

item
pub(open) trait TaskStore

Where a server keeps tasks between requests (Koog task storage).

struct
struct InMemoryTaskStore

An in-memory task store (Koog InMemoryMessageStorage).

fn
fn InMemoryTaskStore::new() -> InMemoryTaskStore

A fresh in-memory store.

item
impl TaskStore for InMemoryTaskStore with fn get(self, task_id)
item
impl TaskStore for InMemoryTaskStore with fn save(self, task)
struct
struct A2AServer

An A2A server dispatching JSON-RPC requests to executor, persisting tasks in store and push-notification configs per task.

fn
fn A2AServer::new( executor : &AgentExecutor, store : &TaskStore) -> A2AServer

A server backed by executor and store.

fn
fn A2AServer::handle(self : A2AServer, request : Json) -> Json

Handle one JSON-RPC request, returning the JSON-RPC response — a result on success, or an error object when the method fails (a server answers, it does not throw at the transport).

struct
struct AgentInterface

A transport endpoint the agent also serves on (A2A AgentInterface).

struct
struct AgentProvider

The organization behind an agent (A2A AgentProvider).

struct
struct AgentExtension

A protocol extension an agent supports (A2A AgentExtension).

struct
struct AgentCapabilities

What optional protocol features an agent supports (A2A AgentCapabilities).

struct
struct AgentSkill

One capability an agent advertises (A2A AgentSkill).

struct
struct AgentCard

An agent's public description and discovery document (A2A AgentCard).

item
pub(open) trait CardSource

Where an agent card is fetched from (Koog AgentCardResolver): typically an HTTP GET of the agent's well-known card URL, injectable so tests can supply a card without a network.

fn
fn resolve_agent_card(source : &CardSource) -> AgentCard raise

Resolve and parse an agent's card from source (Koog A2AClient.getAgentCard).

fn
fn AgentInterface::to_json(self : AgentInterface) -> Json
fn
fn AgentProvider::to_json(self : AgentProvider) -> Json
fn
fn AgentExtension::to_json(self : AgentExtension) -> Json
fn
fn AgentCapabilities::to_json(self : AgentCapabilities) -> Json
fn
fn AgentSkill::to_json(self : AgentSkill) -> Json
fn
fn AgentCard::to_json(self : AgentCard) -> Json
fn
fn AgentInterface::from_json(j : Json) -> AgentInterface raise
fn
fn AgentProvider::from_json(j : Json) -> AgentProvider raise
fn
fn AgentExtension::from_json(j : Json) -> AgentExtension raise
fn
fn AgentCapabilities::from_json(j : Json) -> AgentCapabilities raise
fn
fn AgentSkill::from_json(j : Json) -> AgentSkill raise
fn
fn AgentCard::from_json(j : Json) -> AgentCard raise
struct
struct TaskStatusUpdateEvent

A task's status changed while streaming (A2A TaskStatusUpdateEvent); is_final ends the stream.

struct
struct TaskArtifactUpdateEvent

The agent produced (part of) an artifact while streaming (A2A TaskArtifactUpdateEvent).

enum
enum StreamEvent

One event of a streamed response (A2A streaming Event union, discriminated by kind).

item
pub(open) trait EventStream

Where a streamed response body comes from (the SSE side of Koog's ClientTransport): send the request, get back the whole SSE body. Injectable so the parsing is testable without a live socket.

fn
fn TaskStatusUpdateEvent::to_json(self : TaskStatusUpdateEvent) -> Json
fn
fn TaskStatusUpdateEvent::from_json( j : Json) -> TaskStatusUpdateEvent raise
fn
fn TaskArtifactUpdateEvent::to_json(self : TaskArtifactUpdateEvent) -> Json
fn
fn TaskArtifactUpdateEvent::from_json( j : Json) -> TaskArtifactUpdateEvent raise
fn
fn StreamEvent::from_json(j : Json) -> StreamEvent raise

Parse a streamed event from its JSON, dispatching on kind.

fn
fn stream_message( source : &EventStream, message : Message) -> Array[StreamEvent] raise

Send message and collect the streamed events (message/stream): open the SSE stream, parse each data: frame as a JSON-RPC response, and turn each result into a StreamEvent.

struct
struct SseEvent

One dispatched SSE event: its type (default message), its data payload, and the last seen id.

fn
fn parse_sse(text : String) -> Array[SseEvent]

Parse an SSE stream body into its dispatched events (WHATWG EventSource interpretation).

struct
struct PushAuthInfo

How the agent authenticates its callback to the caller (A2A PushNotificationAuthenticationInfo).

struct
struct PushNotificationConfig

A webhook the agent calls on task updates (A2A PushNotificationConfig).

struct
struct TaskPushConfig

A push-notification config bound to a task (A2A TaskPushNotificationConfig).

fn
fn PushAuthInfo::to_json(self : PushAuthInfo) -> Json
fn
fn PushAuthInfo::from_json(j : Json) -> PushAuthInfo raise
fn
fn PushNotificationConfig::to_json(self : PushNotificationConfig) -> Json
fn
fn PushNotificationConfig::from_json( j : Json) -> PushNotificationConfig raise
fn
fn TaskPushConfig::to_json(self : TaskPushConfig) -> Json
fn
fn TaskPushConfig::from_json(j : Json) -> TaskPushConfig raise
fn
fn A2AClient::set_push_config( self : A2AClient, config : TaskPushConfig) -> TaskPushConfig raise

Register a push-notification webhook for a task (tasks/pushNotificationConfig/set).

fn
fn A2AClient::get_push_config( self : A2AClient, task_id : String, config_id? : String) -> TaskPushConfig raise

Read a task's push-notification config (tasks/pushNotificationConfig/get).

fn
fn A2AClient::list_push_configs( self : A2AClient, task_id : String) -> Array[TaskPushConfig] raise

List a task's push-notification configs (tasks/pushNotificationConfig/list).

fn
fn A2AClient::delete_push_config( self : A2AClient, task_id : String, config_id : String) -> Unit raise

Delete a task's push-notification config (tasks/pushNotificationConfig/delete).