API Reference
This page is a curated entry point into the public API. For higher-level behavior and composition, start with the guide pages first.
Agent
Krill.AgentModule.Agent Type
Agent(provider; kwargs...)Encapsulates all LLM-related configuration for a Krill agent. Use with RuntimeState(channels, agent) for a cleaner alternative to passing 50+ llm_* keyword arguments directly to RuntimeState.
Basic usage
agent = Agent(OpenAIProvider(api_key=ENV["OPENAI_API_KEY"], model="gpt-4o-mini");
system_prompt = "You are a helpful assistant.",
workspace = "context",
)
rt = RuntimeState(channels, agent)With hooks and custom retry
agent = Agent(provider;
hooks = AgentHooks(
on_tool_call = (name, args) -> @info "Tool" name,
on_tool_result = (name, res) -> @info "Result" name chars=length(res),
should_interrupt = (name, _) -> name == "forbidden_tool",
),
retry = RetryConfig(max_retries=5, base_delay_s=1.0),
)With config structs
agent = Agent(provider;
memory = MemoryConfig(enable=true, enable_consolidation=false),
builtin_tools = BuiltinToolsConfig(enable_exec=true, exec_timeout_s=30.0),
claude_code = ClaudeCodeConfig(enable=true, model="opus"),
)Krill.AgentModule.AgentHooks Type
AgentHooks(; on_turn_start, on_turn_end, on_tool_call, on_tool_result, should_interrupt)Lifecycle callbacks injected into the agent loop. All fields are optional.
| Hook | Signature | Called when |
|---|---|---|
on_turn_start | (msg, history) -> nothing | Before each LLM call, after typing indicator |
on_turn_end | (msg, history) -> nothing | After response is persisted and outbound queued |
on_tool_call | (tool_name, arguments) -> nothing | Before each tool is dispatched |
on_tool_result | (tool_name, result_text) -> nothing | After a successful tool dispatch |
should_interrupt | (tool_name, arguments) -> Bool | Before each tool; return true to stop the loop |
Hook failures are logged with @warn and never propagate. Hooks are not thread-safe by default — close over shared mutable state with care in concurrent sessions.
When should_interrupt returns true, remaining tool calls in the current LLM batch are silently skipped and the loop exits with the current response text.
Krill.AgentModule.RetryConfig Type
RetryConfig(; max_retries, base_delay_s, max_delay_s, multiplier, jitter, retriable_status_codes)Retry policy for LLM API calls. Applies exponential backoff with optional jitter.
| Field | Default | Meaning |
|---|---|---|
max_retries | 3 | Maximum number of retry attempts after the first failure |
base_delay_s | 0.5 | Initial delay in seconds before the first retry |
max_delay_s | 60.0 | Cap on per-attempt sleep duration |
multiplier | 2.0 | Exponential growth factor per attempt |
jitter | true | Randomise sleep by 0.75–1.0× to avoid thundering herd |
retriable_status_codes | {408,429,500,502,503,504,529} | HTTP status codes that trigger a retry |
Sleep formula: clamp(base_delay_s × multiplier^(attempt-1) × jitter_factor, 0, max_delay_s)
Runtime
Krill.RuntimeModule.RuntimeState Type
RuntimeState(channels; hub, consumer, store, processor, workspace, llm_mcp_servers, ...)Top-level runtime that owns the full message pipeline: channel inbound polling, normalization with dedup, session-aware consumer processing (echo by default), and outbound dispatch.
Accepts a single AbstractChannel or a Vector{<:AbstractChannel}.
Use start! and shutdown! to manage the lifecycle.
Krill.RuntimeModule.start! Function
start!(rt::RuntimeState) -> rtStart all channel inbound loops, consumer, and dispatch tasks. No-op if already running.
sourceKrill.RuntimeModule.shutdown! Function
shutdown!(rt::RuntimeState) -> rtGracefully shut down the runtime. Stops all channel inbound loops first (no new messages), then waits for the consumer to drain inbound, then stops outbound dispatch.
sourceMessage Contracts
Krill.Types.ContentPart Type
ContentPartAbstract supertype for message content parts. Concrete subtypes: TextPart, BinaryPart, ToolCallPart, ToolResultPart.
Krill.Types.BinaryPart Type
BinaryPart(media_type, url, bytes, filename)Binary media content (image, audio, document, etc.) within a message.
sourceKrill.Types.ToolCallPart Type
ToolCallPart(tool_name, arguments)Records a tool invocation request within a message.
sourceKrill.Types.ToolResultPart Type
ToolResultPart(tool_name, result, is_error)Records a tool execution result within a message.
sourceKrill.Types.DeliveryPolicy Type
DeliveryPolicy(; max_retries=3, timeout_ms=30_000, priority=0, drop_if_late=false)Controls outbound message delivery behaviour — retry budget, timeout, priority, and whether the message may be silently dropped if delivery is late.
Throws ArgumentError if max_retries or timeout_ms is negative.
Krill.Types.ErrorEnvelope Type
ErrorEnvelope(code, message, retriable, details)Structured error representation propagated through the runtime. retriable indicates whether the caller should attempt a retry.
Krill.Types.InboundMessage Type
InboundMessage(; channel, session_key, user_id, chat_id, text, ...)A message arriving from an external channel (user → runtime).
Required keyword arguments: channel, session_key, user_id, chat_id, text. All other fields have sensible defaults (auto-generated UUIDs, current UTC timestamp, etc.).
Krill.Types.OutboundMessage Type
OutboundMessage(; channel, session_key, chat_id, text, ...)A message leaving the runtime toward an external channel (runtime → user).
Required keyword arguments: channel, session_key, chat_id, text.
Krill.Types.ToolCallEvent Type
ToolCallEvent(; session_key, tool_name, arguments=Dict(), ...)Event recording a tool invocation request within a session.
sourceKrill.Types.ToolResultEvent Type
ToolResultEvent(; session_key, tool_name, result=nothing, error=nothing, ...)Event recording the outcome of a tool execution. Carries either result (on success) or error (ErrorEnvelope).
Krill.Types.message_text Function
message_text(msg::Union{InboundMessage, OutboundMessage}) -> StringExtract and concatenate all TextPart content from a message, joining multiple parts with newlines.
Queues and Dispatch
Krill.MessageHub.MessageHubState Type
MessageHubState(; inbound_capacity=32, outbound_capacity=32)Typed FIFO message queues that decouple producers from consumers. Inbound queue carries InboundMessage, outbound carries OutboundMessage.
Throws ArgumentError if either capacity is not positive.
Krill.MessageHub.publish_inbound! Function
publish_inbound!(hub, msg)Enqueue an InboundMessage. Blocks if the inbound channel is full.
Krill.MessageHub.publish_outbound! Function
publish_outbound!(hub, msg)Enqueue an OutboundMessage. Blocks if the outbound channel is full.
Krill.MessageHub.try_publish_inbound! Function
try_publish_inbound!(hub, msg) -> BoolNon-blocking enqueue. Returns true if the message was published, false if the inbound queue is full. Safe for single-producer use.
Krill.MessageHub.try_publish_outbound! Function
try_publish_outbound!(hub, msg) -> BoolNon-blocking enqueue. Returns true if the message was published, false if the outbound queue is full. Safe for single-producer use.
Krill.MessageHub.take_inbound! Function
take_inbound!(hub) -> InboundMessageDequeue the next inbound message. Blocks until one is available.
sourceKrill.MessageHub.take_outbound! Function
take_outbound!(hub) -> OutboundMessageDequeue the next outbound message. Blocks until one is available.
sourceKrill.MessageHub.try_take_inbound! Function
try_take_inbound!(hub) -> Union{InboundMessage, Nothing}Non-blocking dequeue. Returns nothing if the inbound queue is empty.
Krill.MessageHub.try_take_outbound! Function
try_take_outbound!(hub) -> Union{OutboundMessage, Nothing}Non-blocking dequeue. Returns nothing if the outbound queue is empty.
Krill.ChannelManager.ChannelManagerState Type
ChannelManagerState(hub::MessageHubState; on_dispatch=nothing, dead_letter_path=nothing)Manages channel sender registration and asynchronous outbound message dispatch. Consumes messages from the hub's outbound queue and routes each to the sender registered for that message's channel symbol.
Optional callbacks:
on_dispatch: called with aDispatchEventafter every delivery attemptdead_letter_path: file path for persistent dead-letter log (JSONL)
Use register_sender! to associate a channel name with a send function, then start_dispatch! / stop_dispatch! to control the dispatch loop.
Krill.ChannelManager.DispatchEvent Type
DispatchEventEmitted after each dispatch attempt. Passed to the optional on_dispatch callback.
Fields:
message_id: UUID of the outbound messagecorrelation_id: UUID of the inbound message that triggered this outbound (or nothing)channel: target channel symbolsession_key: session that produced this messagechat_id: target chatoutcome::delivered,:failed,:dropped, or:no_senderreason: human-readable reason (empty on success)attempts: number of send attempts madeelapsed_ms: wall-clock time spent on deliveryerror: the last error (or nothing)timestamp: when the event was recorded
Krill.ChannelManager.register_sender! Function
register_sender!(manager, channel::Symbol, sender::Function)Register sender as the delivery function for channel. sender will be called with a single OutboundMessage argument. Overwrites any previously registered sender for the same channel.
Krill.ChannelManager.start_dispatch! Function
start_dispatch!(manager) -> managerStart the background dispatch loop. Messages on the hub's outbound queue are consumed and routed to the appropriate registered sender.
No-op if dispatch is already running.
sourceKrill.ChannelManager.stop_dispatch! Function
stop_dispatch!(manager) -> managerSignal the dispatch loop to stop. The loop drains any remaining outbound messages before exiting. The hub's outbound channel remains open and usable.
sourceKrill.ChannelManager.dispatch_stats Function
dispatch_stats(manager) -> Dict{String,Any}Return delivery statistics: counts, last success time, dead letter count.
sourceKrill.ChannelManager.dead_letters Function
dead_letters(manager) -> Vector{Dict{String,Any}}Return a copy of the dead-letter log.
sourceKrill.ChannelManager.flush_dead_letters! Function
flush_dead_letters!(manager) -> Vector{Dict{String,Any}}Return and clear the dead-letter log.
sourceKrill.Dedup.BoundedDedup Type
BoundedDedup(capacity=1000)Bounded set for deduplicating integer IDs (e.g. Telegram update_id). Stores up to capacity entries; when full, the oldest entry is evicted.
Use seen! to record an ID and check if it was already known, and has_seen for a read-only membership check.
Krill.Dedup.seen! Function
seen!(d::BoundedDedup, id::Int) -> BoolRecord id and return true if it is new (first time seen). Return false if it was already in the set (duplicate).
Krill.Dedup.has_seen Function
has_seen(d::BoundedDedup, id::Int) -> BoolReturn true if id has been recorded, false otherwise.
Channels
Krill.ChannelInterface.AbstractChannel Type
AbstractChannelAbstract supertype for all channel implementations.
Every concrete channel must implement:
channel_name(ch) -> Symbol— unique channel identifier (e.g.:telegram,:discord)make_sender(ch) -> Function— returns(OutboundMessage) -> Anysender functionnormalize(ch, raw_event) -> Union{InboundMessage, Nothing}— converts raw platform event to InboundMessagestart_channel!(ch, hub, running; dedup, on_message) -> Task— starts the inbound event loop, returns the polling/gateway taskstop_channel!(ch) -> Nothing— stops the channel (cleanup connections, etc.)
Optional:
send_typing(ch, chat_id) -> Nothing— sends typing indicator (default: no-op)send_direct(ch, chat_id, text; kwargs...) -> Any— sends a message directly bypassing the outbound queue (for tools, progress hints)
Krill.ChannelInterface.ChannelState Type
ChannelStateTracks a registered channel within the runtime — holds the channel instance, its sender, and the inbound task.
sourceKrill.ChannelInterface.channel_name Function
channel_name(ch::AbstractChannel) -> SymbolReturn the unique channel identifier symbol (e.g. :telegram, :discord).
Krill.ChannelInterface.make_sender Function
make_sender(ch::AbstractChannel) -> FunctionReturn a sender function (OutboundMessage) -> Any suitable for register_sender!.
Krill.ChannelInterface.normalize Function
normalize(ch::AbstractChannel, raw_event) -> Union{InboundMessage, Nothing}Convert a raw platform event into an InboundMessage. Returns nothing if the event is not a recognizable message.
Krill.ChannelInterface.register_channel! Function
register_channel!(manager::ChannelManagerState, ch::AbstractChannel;
on_send::Union{Nothing,Function}=nothing) -> ChannelStateRegister a channel's sender with the ChannelManager. If on_send is provided, it wraps the sender to call on_send() after each successful send (e.g. to update last_successful_send_at).
Returns a ChannelState ready for start_channel!.
Krill.ChannelInterface.make_inbound_handler Function
make_inbound_handler(ch::AbstractChannel, hub::MessageHubState;
dedup::Union{Nothing,BoundedDedup}=nothing,
on_poll::Union{Nothing,Function}=nothing) -> FunctionCreate a standard inbound handler function that normalizes, deduplicates, and publishes events to the hub. Channels can use this in their start_channel! implementation.
on_poll is called on every raw event before normalization (e.g. to update last_successful_poll_at).
Krill.ChannelInterface.start_channel! Function
start_channel!(ch::AbstractChannel, hub::MessageHubState, running::Ref{Bool};
dedup::Union{Nothing,BoundedDedup}=nothing,
on_message::Union{Nothing,Function}=nothing) -> TaskStart the channel's inbound event loop (polling, WebSocket gateway, etc.). Returns the spawned Task.
The default implementation provides a standard inbound handler that:
Normalizes raw events via
normalize(ch, event)Deduplicates via
dedup(if provided)Publishes to the hub's inbound queue
Channels that need custom event loop behavior should override this method.
sourceKrill.ChannelInterface.stop_channel! Function
stop_channel!(ch::AbstractChannel) -> NothingStop the channel and clean up resources. Called during runtime shutdown. Default implementation is a no-op.
sourceKrill.ChannelInterface.send_typing Function
send_typing(ch::AbstractChannel, chat_id) -> NothingSend a typing indicator to the given chat. Default is a no-op.
sourceKrill.ChannelInterface.send_direct Function
send_direct(ch::AbstractChannel, chat_id, text::AbstractString; kwargs...) -> AnySend a message directly to a chat, bypassing the outbound queue. Used by tools and progress hints. Default throws an error.
sourceKrill.Channels.Telegram.TelegramClient Type
TelegramClient(token; base_url=nothing, request=HTTP.request)HTTP client for the Telegram Bot API. request is injectable for testing (any function with the same signature as HTTP.request).
Krill.Channels.Telegram.TelegramAPIError Type
TelegramAPIError <: ExceptionRaised when a Telegram Bot API call fails at either the HTTP or API level.
sourceKrill.Channels.Telegram.TelegramChannel Type
TelegramChannel(client::TelegramClient; poll_timeout=30, poll_interval=0.1)Channel adapter wrapping a TelegramClient to implement the AbstractChannel interface. Handles polling, normalization, sending, and typing indicators.
Krill.Channels.Telegram.TelegramWebhookChannel Type
TelegramWebhookChannel(client; url, host="0.0.0.0", port=8443, path="/webhook",
secret_token=nothing, set_webhook_on_start=true,
delete_webhook_on_stop=true, drop_pending_updates=false)Channel adapter that receives Telegram updates via webhook HTTP POST instead of long-polling. The channel starts an embedded HTTP server on host:port and optionally registers the webhook URL with Telegram on start_channel!.
secret_token is used for both the setWebhook call and for verifying incoming requests via the X-Telegram-Bot-Api-Secret-Token header.
url is the publicly-reachable HTTPS URL that Telegram will POST to. It must include the path component (e.g. https://example.com/webhook).
Krill.Channels.Telegram.get_updates Function
get_updates(client; offset=0, timeout=30, limit=nothing, allowed_updates=nothing)Long-poll for new updates from the Telegram Bot API. Returns the raw array of update objects.
sourceKrill.Channels.Telegram.send_message Function
send_message(client, chat_id, text; parse_mode="HTML", disable_web_page_preview=false)Send a text message to chat_id. Returns the sent message object from Telegram.
Krill.Channels.Telegram.send_chat_action Function
send_chat_action(client, chat_id, action="typing")Send a chat action (for example "typing") to indicate bot activity. Returns the API result.
Krill.Channels.Telegram.set_webhook Function
set_webhook(client, url; secret_token=nothing, max_connections=nothing, allowed_updates=nothing, drop_pending_updates=false)Register a webhook URL with Telegram. The bot will receive updates via HTTPS POST to this URL instead of via getUpdates long-polling.
secret_token (optional) is sent in the X-Telegram-Bot-Api-Secret-Token header of each webhook request so you can verify authenticity.
Krill.Channels.Telegram.delete_webhook Function
delete_webhook(client; drop_pending_updates=false)Remove the current webhook. After this, you can switch back to getUpdates polling.
Krill.Channels.Telegram.run_polling Function
run_polling(client, handler; offset=0, timeout=30, poll_interval=0.1, max_updates=nothing)Poll for Telegram updates in a loop, calling handler(update) for each one. If max_updates is set, stops after that many updates have been processed.
Handler exceptions are logged and do not terminate the polling loop.
sourceKrill.Channels.Telegram.make_telegram_sender Function
make_telegram_sender(client::TelegramClient) -> FunctionReturn a sender function suitable for register_sender!. The returned function takes an OutboundMessage and sends its text content to the appropriate chat via the Telegram Bot API.
Krill.Channels.Discord.DiscordChannel Type
DiscordChannel(client::DiscordClient; intents=DEFAULT_INTENTS)
DiscordChannel(token; kwargs...)Channel adapter wrapping a DiscordClient to implement the AbstractChannel interface. Connects to the Discord Gateway via WebSocket for receiving events and uses the REST API for sending messages.
Krill.Channels.Discord.discord_send_message Function
discord_send_message(client, channel_id, content; kwargs...) -> AnySend a text message to a Discord channel.
sourceKrill.Channels.Discord.discord_trigger_typing Function
discord_trigger_typing(client, channel_id) -> NothingTrigger the typing indicator in a Discord channel.
sourceSessions and Memory
Krill.Sessions.TurnRecord Type
TurnRecordA single turn in session history. Stored as one JSONL line on disk.
sourceKrill.Sessions.SessionStore Type
SessionStore(; workspace="workspace")Manages per-session locks and JSONL history persistence. Sessions are identified by session_key strings. History files live at workspace/sessions/<sanitized_key>/history.jsonl.
Thread-safe: the lock map is protected by its own ReentrantLock.
Krill.Sessions.get_session_lock! Function
get_session_lock!(store, session_key) -> ReentrantLockGet or create the per-session lock. Thread-safe.
sourceKrill.Sessions.load_history Function
load_history(store, session_key) -> Vector{TurnRecord}Load session history from the JSONL file. Returns empty vector if no file exists. Caller must hold the session lock.
sourceKrill.Sessions.append_turn! Function
append_turn!(store, session_key, turn)Append a single turn to the session's JSONL history file. Caller must hold the session lock.
sourceKrill.Sessions.save_history Function
save_history(store, session_key, history)Overwrite the session's JSONL history file. Useful for truncation/compaction. Caller must hold the session lock.
sourceKrill.Sessions.session_dir Function
session_dir(store, session_key) -> StringReturn the directory path for a session's data files. Creates it if missing.
sourceKrill.Sessions.sanitize_session_key Function
sanitize_session_key(key) -> StringReplace characters invalid in file paths (: / \) with _.
Krill.Memory.MemoryState Type
MemoryStatePer-session memory bookkeeping. last_consolidated tracks the last archived turn index/offset. consolidation_failures counts consecutive LLM failures for fallback logic.
Krill.Memory.MemoryStore Type
MemoryStore(; workspace="workspace")Persists per-session memory files under: workspace/memory/<sanitized_session_key>/.
Krill.Memory.memory_dir Function
memory_dir(store, session_key) -> StringReturn the session memory directory, creating it if needed.
sourceKrill.Memory.load_memory Function
load_memory(store, session_key) -> StringRead MEMORY.md for a session. Returns an empty string if missing.
Krill.Memory.save_memory! Function
save_memory!(store, session_key, content)Overwrite a session's MEMORY.md.
Krill.Memory.append_history! Function
append_history!(store, session_key, entry; timestamp=now(UTC))Append a timestamped block to HISTORY.md.
Krill.Memory.load_memory_state Function
load_memory_state(store, session_key) -> MemoryStateLoad memory state for a session. Missing or invalid files return defaults.
sourceKrill.Memory.save_memory_state! Function
save_memory_state!(store, session_key, state)Persist per-session memory state metadata.
sourceKrill.SessionConsumer.SessionCancelScope Type
SessionCancelScope()Cooperative cancellation registry for mid-turn /stop support. Each session key maps to an Atomic{Bool} flag. The LLM processor's stop_check reads this flag between tool iterations.
Krill.SessionConsumer.request_cancel! Function
request_cancel!(scope, session_key) -> BoolSet the cancellation flag for a session. Returns true if a flag existed (meaning a turn was in progress), false otherwise.
Krill.SessionConsumer.is_cancelled Function
is_cancelled(scope, session_key) -> BoolCheck the cancellation flag for a session without clearing it.
sourceKrill.SessionConsumer.clear_cancel! Function
clear_cancel!(scope, session_key) -> Threads.Atomic{Bool}Clear the cancellation flag and return a fresh atomic for the new turn. Call this at the start of each turn.
sourceKrill.SessionConsumer.run_session_loop! Function
run_session_loop!(hub, running; store, processor, before_process, after_process)Session-aware consumer loop. For each inbound message, spawns a task that processes it under the session lock. Different sessions run in parallel; same-session messages are processed in FIFO order by chaining tasks.
Drains remaining inbound messages sequentially on shutdown. before_process runs before the processor call. after_process runs after user+assistant turns are persisted and outbound is queued.
Krill.SessionConsumer.echo_processor Function
echo_processor(msg, history) -> StringTrivial processor that echoes the inbound message text. Placeholder for the Phase C LLM integration.
sourceKrill.MemoryConsolidation.MemoryConsolidatorConfig Type
MemoryConsolidatorConfig(; unconsolidated_token_threshold=2_000, max_output_tokens=800, max_input_turn_chars=2_000, max_consolidation_turns=50, max_failures=3)Configuration for memory consolidation.
max_consolidation_turns: cap how many turns are sent to the LLM in a single consolidation call. Remaining turns are left for the next round.max_failures: after this many consecutive LLM failures, raw-dump turns to HISTORY.md and advancelast_consolidatedwithout an LLM summary.
Krill.MemoryConsolidation.consolidate_session_memory! Function
consolidate_session_memory!(provider, memory_store, session_key, history; config=MemoryConsolidatorConfig())Consolidate unconsolidated session turns into MEMORY.md when their estimated token count exceeds the configured threshold. Appends raw archived turns into HISTORY.md and advances last_consolidated state.
At most config.max_consolidation_turns turns are processed per call; remaining turns are left for the next invocation.
After config.max_failures consecutive LLM failures, falls back to a raw dump of turns into HISTORY.md (no LLM summary) so that last_consolidated advances and the consolidation prompt doesn't grow unboundedly.
Krill.MemoryConsolidation.make_memory_consolidator Function
make_memory_consolidator(provider, memory_store; kwargs...) -> FunctionCreate an after_process(msg, history) hook for run_session_loop!.
Tools and Skills
Krill.Tools.ToolDef Type
ToolDef(; name, parameters, execute, description=nothing, return_direct=false, max_output_chars=0, strict=nothing)Defines a callable tool with JSON-schema parameters and execution behavior. execute receives a Dict{String,Any} of validated arguments.
Krill.Skills.SkillDef Type
SkillDefA discovered skill with metadata parsed from SKILL.md frontmatter.
Fields:
name: directory namedescription: from frontmatter or first non-heading linepath: absolute path to SKILL.mdsource: "workspace" or "builtin"always: if true, full content is auto-injected into system promptavailable: whether all requirements (bins, env vars) are metmissing_requirements: human-readable list of unmet requirements
Krill.Skills.load_always_skills Function
load_always_skills(skills) -> Union{Nothing, String}Load full content of all always-on, available skills. Returns formatted text for injection into the system prompt, or nothing if no always-on skills exist. Frontmatter is stripped from the content.
sourceKrill.BuiltinTools.register_builtin_tools! Function
register_builtin_tools!(registry; workspace="workspace", enable_exec=false, ...) -> Vector{ToolDef}Register the standard set of built-in tools (file ops, web fetch, exec, github, message, claude_code, codex, google_workspace) into the given ToolRegistry.
Prompt Context
Krill.PromptContext.load_bootstrap_docs Function
load_bootstrap_docs(workspace; doc_names=DEFAULT_BOOTSTRAP_DOCS, max_chars_per_doc=12_000)Load bootstrap docs from workspace, in listed order. Missing files are skipped.
Krill.PromptContext.render_runtime_metadata Function
render_runtime_metadata(msg; now_fn=() -> now(UTC)) -> StringRender runtime metadata for prompt context.
sourceKrill.PromptContext.compose_instructions Function
compose_instructions(base_instructions; bootstrap_docs, skills_summary_text, always_skills_text, memory_text, include_tool_safety, runtime_metadata_text)Compose final instructions by appending non-empty sections with separators. When include_tool_safety is true, appends TOOL_OUTPUT_SAFETY_NOTICE.
Krill.PromptContext.make_prompt_builder Function
make_prompt_builder(; bootstrap_docs, skills_summary_text, always_skills_text, include_runtime_metadata, include_tool_safety, now_fn)Create a prompt builder callback compatible with make_llm_processor(...; instructions_builder=...).
LLM Providers
Krill.LLM.AbstractLLMProvider Type
AbstractLLMProviderAbstract supertype for LLM API providers (OpenAI, Gemini, etc.).
sourceKrill.LLM.OpenAIProvider Type
OpenAIProvider(; api_key, base_url, model, request, max_retries, retry_base_seconds)Minimal OpenAI Responses API provider backed by HTTP.request.
Krill.LLM.OpenAIAPIError Type
OpenAIAPIError <: ExceptionError raised for OpenAI API failures. retriable=true indicates the error is suitable for retry with backoff.
Krill.LLM.GeminiProvider Type
GeminiProvider(; api_key, base_url, model, request, max_retries, retry_base_seconds)Native Gemini API provider backed by HTTP.request and POST /v1beta/models/{model}:generateContent.
Reference: https://ai.google.dev/api/rest/v1beta/models/generateContent
sourceKrill.LLM.GeminiOpenAICompatProvider Type
GeminiOpenAICompatProvider(; api_key, base_url, model, request, max_retries, retry_base_seconds, extra_body)Gemini provider using Google's OpenAI-compatible chat/completions endpoint.
Reference: https://ai.google.dev/gemini-api/docs/openai
sourceKrill.LLM.LLMToolCall Type
LLMToolCallNormalized function/tool call request returned by providers.
sourceKrill.LLM.LLMResponse Type
LLMResponseLLM response payload with extracted text plus raw OpenAI response object.
sourceKrill.LLM.chat_completion Function
chat_completion(provider, input; kwargs...) -> LLMResponseCall OpenAI's POST /v1/responses endpoint. input should be either a string or a Responses API input message array.
Reference: https://platform.openai.com/docs/api-reference/responses
sourceKrill.LLM.make_llm_processor Function
make_llm_processor(provider; kwargs...) -> FunctionCreate a session processor compatible with run_session_loop!. Supports text/image/file inputs (from content_parts) and Responses API tools options. When memory_store is provided, session memory is loaded and appended to context instructions for each turn. When instructions_builder is provided, it receives (msg, base_instructions, memory_text) and can compose per-turn instructions (for runtime metadata/bootstrap docs/memory policy). When enable_history_summarization is true, turns that are dropped due to context window limits are summarized by the LLM and prepended to instructions.
MCP
Krill.MCP.MCPServer Type
MCPServer(; name, transport=:auto, command=nothing, args=String[], env=Dict(), url=nothing,
headers=Dict(), request_timeout_s=30.0, tool_timeout_s=30.0,
enabled_tools=["*"], cache_tools=true)MCP server configuration for either stdio or HTTP transport.
name: logical server name used for namespaced tool IDs.transport::auto,:stdio,:sse, or:streamable_http.enabled_tools: allowlist of tool names; accepts raw names or wrapped names. Use["*"](default) for all tools, orString[]for none.
Cron
Krill.Cron.CronService Type
CronService(; workspace, tick_interval_s, publish_fn)In-process job scheduler. Runs a background tick loop that checks all registered jobs and fires due ones by injecting InboundMessage into the message hub via publish_fn.
publish_fn should be a function (InboundMessage) -> Bool (e.g., try_publish_inbound! bound to a hub).
Subagents
Krill.Subagent.SubagentTask Type
SubagentTaskTracks a single spawned subagent background task.
sourceKrill.Subagent.SubagentManager Type
SubagentManagerManages spawned subagent background tasks. Provides spawn, cancel, and listing operations. Each subagent runs its own LLM conversation loop with a restricted tool set (no spawn, no message, no cron).
sourceKrill.Subagent.spawn_subagent! Function
spawn_subagent!(mgr, task_description; label, origin_channel, origin_session_key, origin_chat_id) -> StringSpawn a background subagent to execute the given task. Returns immediately with a status message. The subagent runs its own LLM conversation loop and announces results back to the origin session via the shared message hub.
sourceKrill.Subagent.cancel_subagents! Function
cancel_subagents!(mgr, session_key) -> IntCancel all running subagents for the given session. Returns the number cancelled.
sourceKrill.Subagent.list_subagents Function
list_subagents(mgr; session_key=nothing) -> Vector{SubagentTask}List subagent tasks, optionally filtered by session.
sourceKrill.Subagent.register_spawn_tools! Function
register_spawn_tools!(registry, mgr; from_subagent=false, replace=false) -> Vector{ToolDef}Register spawn, spawn_list, spawn_cancel tools. If from_subagent=true, tools are not registered (prevents recursive spawning).
Durable Queue
Krill.DurableQueue.DurableQueueState Type
DurableQueueState(; wal_path, auto_compact_threshold=1000)Append-only WAL (write-ahead log) for crash-recoverable message queuing.
Each entry is a JSONL line with op = "enqueue" or "ack". On startup, call replay(dq) to recover unacked messages.
auto_compact_threshold: when the WAL exceeds this many lines, compact! is called automatically on the next ack!.
Krill.DurableQueue.enqueue! Function
enqueue!(dq, msg::Union{InboundMessage, OutboundMessage})Persist a message to the WAL before processing. Returns the message_id.
sourceKrill.DurableQueue.ack! Function
ack!(dq, message_id::UUID)Mark a message as successfully processed. Triggers auto-compaction if threshold exceeded.
sourceKrill.DurableQueue.replay Function
replay(dq) -> (inbound=Vector{InboundMessage}, outbound=Vector{OutboundMessage})Read the WAL and return all unacked messages, preserving original order. Call this on startup to recover messages that were enqueued but not acked.
sourceKrill.DurableQueue.compact! Function
compact!(dq)Rewrite the WAL, removing all acked entries. This reduces file size.
source