| title | Python API | |||
|---|---|---|---|---|
| summary | The kohakuterrarium package surface — Agent, AgentSession, TerrariumRuntime, compose, and testing helpers. | |||
| tags |
|
Every public class, function, and protocol in the kohakuterrarium
Python package. Entries are grouped by module package. Signatures use
modern type hints.
For the architecture, read concepts/README. For task walkthroughs, see guides/programmatic-usage and guides/custom-modules.
| When you want | Use |
|---|---|
| The easiest streaming chat wrapper | kohakuterrarium.serving.agent_session.AgentSession |
| Direct agent control | kohakuterrarium.core.agent.Agent |
| Multi-agent runtime | kohakuterrarium.terrarium.runtime.TerrariumRuntime |
| Transport-agnostic manager | kohakuterrarium.serving.manager.KohakuManager |
| Config loading | kohakuterrarium.core.config.load_agent_config / kohakuterrarium.terrarium.config.load_terrarium_config |
| Persistence / search | kohakuterrarium.session.store.SessionStore, kohakuterrarium.session.memory.SessionMemory |
| Extension author | kohakuterrarium.modules.{tool,input,output,trigger,subagent}.base |
| Pipeline composition | kohakuterrarium.compose |
| Tests | kohakuterrarium.testing |
Module: kohakuterrarium.core.agent.
Main orchestrator: wires LLM, controller, executor, triggers, I/O, and
plugins together. Subclasses AgentInitMixin, AgentHandlersMixin,
and AgentMessagesMixin.
Classmethod factory:
Agent.from_path(
config_path: str,
*,
input_module: InputModule | None = None,
output_module: OutputModule | None = None,
session: Session | None = None,
environment: Environment | None = None,
llm_override: str | None = None,
pwd: str | None = None,
) -> AgentLifecycle:
async start() -> None— start I/O, output, triggers, LLM, plugins.async stop() -> None— stop all modules cleanly.async run() -> None— full event loop. Callsstart()if not already started.interrupt() -> None— non-blocking; safe to call from any thread.
Input and events:
async inject_input(content: str | list[ContentPart], source: str = "programmatic") -> Noneasync inject_event(event: TriggerEvent) -> None
Runtime controls:
switch_model(profile_name: str) -> str— returns the canonicalprovider/name[@variations]identifier.llm_identifier() -> str— return the currently-bound canonical model identifier.async add_trigger(trigger: BaseTrigger, trigger_id: str | None = None) -> strasync remove_trigger(trigger_id_or_trigger: str | BaseTrigger) -> boolupdate_system_prompt(content: str, replace: bool = False) -> Noneget_system_prompt() -> strattach_session_store(store: Any) -> Noneset_output_handler(handler: Any, replace_default: bool = False) -> Noneget_state() -> dict[str, Any]— name, running, tools, subagents, message count, pending jobs.
Properties:
is_running: booltools: list[str]subagents: list[str]conversation_history: list[dict]
Attributes:
config: AgentConfigllm: LLMProvidercontroller: Controllerexecutor: Executorregistry: Registrysession: Sessionenvironment: Environment | Noneinput: InputModuleoutput_router: OutputRoutertrigger_manager: TriggerManagersession_store: Anycompact_manager: Anyplugins: Anyskills: SkillRegistry | None
Notes:
environmentis provided byTerrariumRuntimefor multi-agent;Nonefor standalone.- An
Agentinstance is not reusable afterstop(); build a new one to resume from aSessionStore.
agent = Agent.from_path("creatures/my_agent", llm_override="claude-opus-4.7")
await agent.start()
await agent.inject_input("Hello")
await agent.stop()Module: kohakuterrarium.core.config_types. Dataclass.
Every creature configuration field. See configuration.md for the YAML form.
Fields:
name: strversion: str = "1.0"base_config: str | None = Nonellm_profile: str = ""model: str = ""provider: str = ""variation_selections: dict[str, str]variation: str = ""auth_mode: str = ""api_key_env: str = ""base_url: str = ""temperature: float = 0.7max_tokens: int | None = Nonereasoning_effort: str = "medium"service_tier: str | None = Noneextra_body: dict[str, Any]system_prompt: str = "You are a helpful assistant."system_prompt_file: str | None = Noneprompt_context_files: dict[str, str]skill_mode: str = "dynamic"include_tools_in_prompt: bool = Trueinclude_hints_in_prompt: bool = Truemax_messages: int = 0ephemeral: bool = Falseinput: InputConfigtriggers: list[TriggerConfig]tools: list[ToolConfigItem]subagents: list[SubAgentConfigItem]output: OutputConfigcompact: dict[str, Any] | None = Nonestartup_trigger: dict[str, Any] | None = Nonetermination: dict[str, Any] | None = Nonemax_subagent_depth: int = 3tool_format: str | dict = "bracket"agent_path: Path | None = Nonesession_key: str | None = Nonemcp_servers: list[dict[str, Any]]plugins: list[dict[str, Any]]memory: dict[str, Any]output_wiring: list[Any]disable_provider_tools: list[str]max_iterations: int | None = Nonesanitize_orphan_tool_calls: bool = Trueskills: list[str]skill_index_budget_bytes: int = 4096framework_hint_overrides: dict[str, str]
Methods:
get_api_key() -> str | None— read the configured env var.
Module: kohakuterrarium.core.config_types. Dataclasses.
InputConfig
type: str = "cli"— input module type (cli,cli_nonblocking,tui,whisper,none,custom,package).module: str | None = Noneclass_name: str | None = None— populated from the YAML keyclass.prompt: str = "> "options: dict[str, Any]
TriggerConfig
type: str— built-ins aretimer,context,channel; custom/package triggers usemodule+ YAMLclass.module, class_name: str | Noneprompt: str | None = Noneoptions: dict[str, Any]name: str | None = None
ToolConfigItem
name: strtype: str = "builtin"—builtin,trigger,custom, orpackage.module, class_name: str | Nonedoc: str | None = None— override skill doc path.options: dict[str, Any]
OutputConfigItem
type: str = "stdout"module, class_name: str | Noneoptions: dict[str, Any]
OutputConfig
Inherits OutputConfigItem plus:
controller_direct: bool = Truenamed_outputs: dict[str, OutputConfigItem]
SubAgentConfigItem
name: strtype: str = "builtin"module, class_name, config_name, description: str | None—class_name/config_nameare populated from YAMLclass/config.tools: list[str]can_modify: bool = Falseinteractive: bool = Falseoptions: dict[str, Any]
Module: kohakuterrarium.core.config.
load_agent_config(config_path: str) -> AgentConfigResolves YAML/JSON/TOML (config.yaml → .yml → .json → .toml),
applies base_config inheritance, env-var interpolation, and path
resolution.
Module: kohakuterrarium.core.conversation.
Conversation manages message history and OpenAI-format serialisation.
Methods:
append(role, content, **kwargs) -> Messageappend_message(message: Message) -> Noneto_messages() -> list[dict]get_messages() -> MessageListget_context_length() -> intget_image_count() -> intget_system_message() -> Message | Noneget_last_message() -> Message | Noneget_last_assistant_message() -> Message | Nonetruncate_from(index: int) -> list[Message]find_last_user_index() -> intclear(keep_system: bool = True) -> Noneto_json() -> strfrom_json(json_str: str) -> Conversation
ConversationConfig:
max_messages: int = 0keep_system: bool = True
ConversationMetadata:
created_at, updated_at: datetimemessage_count: int = 0total_chars: int = 0
Module: kohakuterrarium.core.events.
Universal event carried between inputs, triggers, tools, sub-agents.
Fields:
type: strcontent: EventContent = ""(strorlist[ContentPart])context: dict[str, Any]timestamp: datetimejob_id: str | None = Noneprompt_override: str | None = Nonestackable: bool = True
Methods:
get_text_content() -> stris_multimodal() -> boolwith_context(**kwargs) -> TriggerEvent— non-mutating.
EventType constants: USER_INPUT, IDLE, TIMER,
CONTEXT_UPDATE, TOOL_COMPLETE, SUBAGENT_OUTPUT,
CHANNEL_MESSAGE, MONITOR, ERROR, STARTUP, SHUTDOWN.
Factories:
create_user_input_event(content, source="cli", **extra_context) -> TriggerEventcreate_tool_complete_event(job_id, content, exit_code=None, error=None, **extra_context) -> TriggerEventcreate_error_event(error_type, message, job_id=None, **extra_context) -> TriggerEvent(stackable=False).
Module: kohakuterrarium.core.channel.
ChannelMessage
sender: strcontent: str | dict | list[dict]metadata: dict[str, Any]timestamp: datetimemessage_id: strreply_to: str | None = Nonechannel: str | None = None
BaseChannel (abstract)
async send(message: ChannelMessage) -> Noneon_send(callback) -> Noneremove_on_send(callback) -> Nonechannel_type: str—"queue"or"broadcast".empty: boolqsize: int
SubAgentChannel (point-to-point queue)
async receive(timeout: float | None = None) -> ChannelMessagetry_receive() -> ChannelMessage | None
AgentChannel (broadcast)
subscribe(subscriber_id: str) -> ChannelSubscriptionunsubscribe(subscriber_id: str) -> Nonesubscriber_count: int
ChannelSubscription
async receive(timeout=None) -> ChannelMessagetry_receive() -> ChannelMessage | Noneunsubscribe() -> Noneempty, qsize
ChannelRegistry
get_or_create(name, channel_type="queue", maxsize=0, description="") -> BaseChannelget(name) -> BaseChannel | Nonelist_channels() -> list[str]remove(name) -> boolget_channel_info() -> list[dict]— for prompt injection.
Module: kohakuterrarium.core.session, core.scratchpad, core.environment.
Session
Dataclass of per-creature shared state.
key: strchannels: ChannelRegistryscratchpad: Scratchpadtui: Any | None = Noneextra: dict[str, Any]
Module-level functions:
get_session(key=None) -> Sessionset_session(session, key=None) -> Noneremove_session(key=None) -> Nonelist_sessions() -> list[str]get_scratchpad() -> Scratchpadget_channel_registry() -> ChannelRegistry
Scratchpad
Key-value string store.
set(key, value) -> Noneget(key) -> str | Nonedelete(key) -> boollist_keys() -> list[str]clear() -> Noneto_dict() -> dict[str, str]to_prompt_section() -> str__len__,__contains__
Environment
Shared execution context for a terrarium.
env_id: strshared_channels: ChannelRegistryget_session(key) -> Session— creature-private.list_sessions() -> list[str]register(key, value) -> Noneget(key, default=None) -> Any
Module: kohakuterrarium.core.job.
JobType enum: TOOL, SUBAGENT, COMMAND.
JobState enum: PENDING, RUNNING, DONE, ERROR, CANCELLED.
JobStatus
job_id: strjob_type: JobTypetype_name: strstate: JobState = PENDINGstart_time: datetimeend_time: datetime | None = Noneoutput_lines: int = 0output_bytes: int = 0preview: str = ""error: str | None = Nonecontext: dict[str, Any]
Properties: duration, is_complete, is_running.
Methods: to_context_string() -> str.
JobResult
job_id: stroutput: str = ""exit_code: int | None = Noneerror: str | None = Nonemetadata: dict[str, Any]success: boolproperty.get_lines(start=0, count=None) -> list[str]truncated(max_chars=1000) -> str
JobStore
register(status) -> Noneget_status(job_id) -> JobStatus | Noneupdate_status(job_id, state=None, output_lines=None, ...) -> JobStatus | Nonestore_result(result) -> Noneget_result(job_id) -> JobResult | Noneget_running_jobs() -> list[JobStatus]get_pending_jobs() -> list[JobStatus]get_completed_jobs() -> list[JobStatus]get_all_statuses() -> list[JobStatus]format_context(include_completed=False) -> str
Utilities:
generate_job_id(prefix="job") -> str
Module: kohakuterrarium.core.termination.
TerminationConfig
max_turns: int = 0max_tokens: int = 0(reserved)max_duration: float = 0idle_timeout: float = 0keywords: list[str]
TerminationChecker
start() -> Nonerecord_turn() -> Nonerecord_activity() -> Nonerecord_tool_result(result) -> Noneattach_plugins(manager) -> Noneattach_scratchpad(scratchpad) -> Noneshould_terminate(last_output: str = "") -> boolforce_terminate(reason: str) -> Nonereason, turn_count, elapsed, is_activeproperties.
TerminationDecision — should_stop: bool, reason: str = "".
TerminationContext — turn_count, elapsed, idle_time, last_output, scratchpad, recent_tool_results.
Module: kohakuterrarium.llm.base.
Async protocol:
async chat(messages, *, stream=True, tools=None, **kwargs) -> AsyncIterator[str]async chat_complete(messages, **kwargs) -> ChatResponse- property
last_tool_calls: list[NativeToolCall]
Subclass BaseLLMProvider to implement:
async _stream_chat(messages, *, tools=None, **kwargs)async _complete_chat(messages, **kwargs) -> ChatResponse
Base attributes: config: LLMConfig, last_usage: dict[str, int].
Module: kohakuterrarium.llm.base / kohakuterrarium.llm.message.
LLMConfig
model: strtemperature: float = 0.7max_tokens: int | None = Nonetop_p: float = 1.0stop: list[str] | None = Noneextra: dict[str, Any] | None = None
ChatChunk
content: str = ""finish_reason: str | None = Noneusage: dict[str, int] | None = None
ChatResponse
content, finish_reason, model: strusage: dict[str, int]
ToolSchema
name, description: strparameters: dict[str, Any]to_api_format() -> dict
NativeToolCall
id, name, arguments: strparsed_arguments() -> dict
Message
role: Role("system","user","assistant","tool")content: str | list[ContentPart]name, tool_call_id: str | Nonetool_calls: list[dict] | Nonemetadata: dictto_dict() / from_dict(data)get_text_content() -> strhas_images() -> boolget_images() -> list[ImagePart]is_multimodal() -> bool
Subclasses SystemMessage, UserMessage, AssistantMessage,
ToolMessage enforce role.
TextPart — text: str, type: "text".
ImagePart — url, detail ("auto"|"low"|"high"), source_type, source_name;
get_description() -> str.
FilePart — file reference counterpart.
Factories:
create_message(role, content, **kwargs) -> Messagemake_multimodal_content(text, images=None, prepend_images=False) -> str | list[ContentPart]normalize_content_parts(content) -> str | list[ContentPart] | None
Aliases: Role, MessageContent, ContentPart, MessageList.
Module: kohakuterrarium.llm.profiles, kohakuterrarium.llm.profile_types.
LLMBackend — name, backend_type, base_url, api_key_env, provider_name, provider_native_tools.
LLMPreset — name, model, provider, max_context, max_output, temperature, reasoning_effort, service_tier, extra_body.
LLMProfile — resolved runtime merge of preset + backend:
name, model, provider, backend_type, max_context, max_output, base_url, api_key_env, temperature, reasoning_effort, service_tier, extra_body.
Module-level functions:
load_backends() -> dict[str, LLMBackend]load_presets() -> dict[str, LLMPreset]load_profiles() -> dict[str, LLMProfile]save_backend(backend) -> Nonedelete_backend(name) -> boolsave_profile(profile) -> Nonedelete_profile(name) -> boolget_profile(name) -> LLMProfile | Noneget_preset(name) -> LLMProfile | Noneget_default_model() -> strset_default_model(model_name) -> Noneresolve_controller_llm(controller_config, llm_override=None) -> LLMProfile | Nonelist_all() -> list[dict]
Built-in provider names: codex, openai, openrouter, anthropic,
gemini, mimo.
Module: kohakuterrarium.llm.api_keys.
save_api_key(provider, key) -> Noneget_api_key(provider_or_env) -> strlist_api_keys() -> dict[str, str](masked).KT_DIR: PathKEYS_PATH: PathPROVIDER_KEY_MAP: dict[str, str]
Module: kohakuterrarium.session.store. SQLite-backed (KohakuVault).
Tables: meta, state, events, channels, subagents, jobs,
conversation, fts.
Events:
append_event(agent, event_type, data) -> strget_events(agent) -> list[dict]get_resumable_events(agent) -> list[dict]get_all_events() -> list[tuple[str, dict]]
Conversation snapshots:
save_conversation(agent, messages) -> Noneload_conversation(agent) -> list[dict] | None
State:
save_state(agent, *, scratchpad=None, turn_count=None, token_usage=None, triggers=None, compact_count=None) -> Noneload_scratchpad(agent) -> dict[str, str]load_turn_count(agent) -> intload_token_usage(agent) -> dict[str, int]load_triggers(agent) -> list[dict]
Channels:
save_channel_message(channel, data) -> strget_channel_messages(channel) -> list[dict]
Sub-agents:
next_subagent_run(parent, name) -> intsave_subagent(parent, name, run, meta, conv_json=None) -> Noneload_subagent_meta(parent, name, run) -> dict | Noneload_subagent_conversation(parent, name, run) -> str | None
Jobs:
save_job(job_id, data) -> Noneload_job(job_id) -> dict | None
Metadata:
init_meta(session_id, config_type, config_path, pwd, agents, config_snapshot=None, terrarium_name=None, terrarium_channels=None, terrarium_creatures=None) -> Noneupdate_status(status) -> Nonetouch() -> Noneload_meta() -> dict[str, Any]
Misc:
search(query, k=10) -> list[dict]— FTS5 BM25.flush() -> Noneclose(update_status=True) -> Nonepath: strproperty.
Module: kohakuterrarium.session.artifacts.
Helpers for binary artifacts stored beside a session file:
artifacts_dir_for(session_path: Path) -> Pathresolve_artifact_relpath(filename: str) -> Pathwrite_artifact_bytes(artifacts_dir: Path, filename: str, data: bytes) -> Path
Module: kohakuterrarium.session.memory.
Indexed search (FTS + vector + hybrid).
index_events(agent) -> Noneasync search(query, mode="hybrid", k=5) -> list[SearchResult]
SearchResult
content: strround_num, block_num: intagent: strblock_type: str—"text","tool","trigger","user".score: floatts: floattool_name, channel: str
Module: kohakuterrarium.session.embedding.
Provider types: model2vec, sentence-transformer, api. API
providers include GeminiEmbedder. Aliases: @tiny, @base,
@retrieval, @best, @multilingual, @multilingual-best,
@science, @nomic, @gemma.
Module: kohakuterrarium.terrarium.runtime. Multi-agent orchestrator;
subclasses HotPlugMixin.
Lifecycle:
async start() -> Noneasync stop() -> Noneasync run() -> None
Hot-plug:
async add_creature(name, creature: Agent, ...) -> CreatureHandleasync remove_creature(name) -> boolasync add_channel(name, channel_type) -> Noneasync wire_channel(creature_name, channel_name, direction) -> None
Properties: api: TerrariumAPI, observer: ChannelObserver.
Attributes: config: TerrariumConfig, environment: Environment,
_creatures: dict[str, CreatureHandle].
Module: kohakuterrarium.terrarium.config. Dataclasses.
TerrariumConfig
name: strcreatures: list[CreatureConfig]channels: list[ChannelConfig]root: RootConfig | None = None
CreatureConfig
name: strconfig_data: dictbase_dir: Pathlisten_channels: list[str]send_channels: list[str]output_log: bool = Falseoutput_log_size: int = 100
ChannelConfig
name: strchannel_type: str = "queue"description: str = ""
RootConfig
config_data: dictbase_dir: Path
Functions:
load_terrarium_config(config_path: str) -> TerrariumConfigbuild_channel_topology_prompt(config, creature) -> str
Programmatic control surfaces. TerrariumAPI mirrors the terrarium
tools available to the root agent. ChannelObserver provides
non-destructive observation. CreatureHandle wraps an Agent plus
its terrarium wiring.
Module: kohakuterrarium.serving.manager. Transport-agnostic manager;
used by the HTTP API and any custom transport.
Agent methods:
async agent_create(config_path=None, config=None, llm_override=None, pwd=None) -> strasync agent_stop(agent_id) -> Noneasync agent_chat(agent_id, message) -> AsyncIterator[str]agent_status(agent_id) -> dictagent_list() -> list[dict]agent_interrupt(agent_id) -> Noneagent_get_jobs(agent_id) -> list[dict]async agent_cancel_job(agent_id, job_id) -> boolagent_switch_model(agent_id, profile_name) -> strasync agent_execute_command(agent_id, command, args="") -> dict
Terrarium methods:
async terrarium_create(config_path, ...) -> strasync terrarium_stop(terrarium_id) -> Noneasync terrarium_run(terrarium_id) -> AsyncIterator[str]- creature / channel / observer operations mirroring the HTTP surface.
Module: kohakuterrarium.serving.agent_session. Thin wrapper around
Agent with concurrent input-injection and output streaming.
get_status() now includes both the raw model id and llm_name, the
canonical provider/name[@variations] identifier used by UI and /model.
Factories:
async from_path(config_path, llm_override=None, pwd=None) -> AgentSessionasync from_config(config: AgentConfig) -> AgentSessionasync from_agent(agent: Agent) -> AgentSession
Methods:
async start() / async stop()async chat(message: str | list[dict]) -> AsyncIterator[str]get_status() -> dict
Attributes: agent_id: str, agent: Agent.
Module: kohakuterrarium.modules.tool.base.
Protocol / BaseTool base class.
async execute(args: dict, context: ToolContext | None = None) -> ToolResult— required.needs_context: bool = Falseis_provider_native: bool = Falseprovider_support: frozenset[str]is_concurrency_safe: bool = Trueprompt_contribution_bucket: str = "normal"prompt_contribution() -> str | Noneprovider_native_options() -> dict[str, Any]
Module: kohakuterrarium.modules.input.base. BaseInputModule
provides user-command dispatch.
async start() / async stop()async get_input() -> TriggerEvent | None
Module: kohakuterrarium.modules.output.base. BaseOutputModule
base class.
async start() / async stop()async write(content: str) -> Noneasync write_stream(chunk: str) -> Noneasync flush() -> Noneasync on_processing_start() / async on_processing_end()on_activity(activity_type: str, detail: str) -> Noneasync on_user_input(text: str) -> None(optional)async on_resume(events: list[dict]) -> None(optional)
Activity types: tool_start, tool_done, tool_error,
subagent_start, subagent_done, subagent_error.
Module: kohakuterrarium.modules.trigger.base.
async wait_for_trigger() -> TriggerEvent | None— required.async _on_start() / async _on_stop()— optional._on_context_update(context: dict) -> None— optional.resumable: bool = Falseuniversal: bool = Falseto_resume_dict() -> dict/from_resume_dict(data) -> BaseTrigger__init__(prompt: str | None = None, **options)
Module: kohakuterrarium.modules.subagent.base.
async run(input_text: str) -> SubAgentResultasync cancel() -> Noneget_status() -> SubAgentJobget_pending_count() -> int
Attributes: config: SubAgentConfig, llm, registry, executor,
conversation.
Support classes in kohakuterrarium.modules.subagent:
SubAgentResult, SubAgentJob, SubAgentManager,
InteractiveSubAgent, InteractiveManagerMixin, SubAgentConfig.
Module: kohakuterrarium.modules.plugin. See
plugin-hooks.md for every hook, signature, and
timing.
Pipeline algebra for composing agents and pure functions.
async run(input) -> Anyasync __call__(input) -> Any__rshift__(other)—>>sequence.__and__(other)—¶llel.__or__(other)—|fallback.__mul__(n)—*retry.iterate(initial_input) -> PipelineIteratormap(fn) -> BaseRunnable— post-transform output.contramap(fn) -> BaseRunnable— pre-transform input.fails_when(predicate) -> BaseRunnable
Module: kohakuterrarium.compose.core.
Pure(fn)/pure(fn)— wrap sync or async callable.Sequence(*stages)— chain.Product(*stages)— parallel (asyncio.gather).Fallback(*stages)Retry(stage, attempts)Router(mapping)— dict-based dispatch.Iterator(...)— iteration over async source.effects.Effects()— side-effect logging handle.
Module: kohakuterrarium.compose.agent.
async agent(config_path: str) -> AgentRunnable— persistent agent, reused across calls (async context manager).factory(config: AgentConfig) -> AgentRunnable— ephemeral factory; a fresh agent per call.
Operator precedence: * > | > & > >>.
from kohakuterrarium.compose import agent, pure
async with await agent("@kt-biome/creatures/swe") as swe:
async with await agent("@kt-biome/creatures/researcher") as reviewer:
pipeline = swe >> pure(extract_code) >> reviewer
result = await pipeline("Implement feature")Module: kohakuterrarium.testing.agent. Fluent builder for
deterministic agent tests.
Builder methods (return self):
with_llm_script(script)with_llm(llm: ScriptedLLM)with_output(output: OutputRecorder)with_system_prompt(prompt)with_session(key)with_builtin_tools(tool_names)with_tool(tool)with_named_output(name, output)with_ephemeral(ephemeral=True)build() -> TestAgentEnv
TestAgentEnv:
- Properties:
llm: ScriptedLLM,output: OutputRecorder,session: Session. - Methods:
async inject(content),async chat(content) -> str.
Module: kohakuterrarium.testing.llm.
Constructor: ScriptedLLM(script: list[ScriptEntry] | list[str] | None = None).
ScriptEntry: response: str, match: str | None = None,
delay_per_chunk: float = 0, chunk_size: int = 10.
Methods: async chat, async chat_complete.
Assertion surface: call_count: int, call_log: list[list[dict]].
Module: kohakuterrarium.testing.output.
all_text: strchunks: list[str]writes: list[str]activities: list[tuple[str, str]]
Module: kohakuterrarium.testing.events.
record(event) -> Noneget_all() -> list[TriggerEvent]get_by_type(event_type) -> list[TriggerEvent]clear() -> None
Module: kohakuterrarium.packages.
is_package_ref(path: str) -> boolresolve_package_path(ref: str) -> Pathlist_packages() -> list[dict]install_package(source, name=None, editable=False) -> Noneupdate_package(name) -> struninstall_package(name) -> boolresolve_package_tool(name) -> tuple[str, str] | Noneresolve_package_io(name) -> tuple[str, str] | Noneresolve_package_trigger(name) -> tuple[str, str] | Noneresolve_package_command(name) -> dict | Noneresolve_package_user_command(name) -> dict | Noneresolve_package_prompt(name) -> Path | Noneresolve_package_skills(name) -> list[dict] | Nonefind_package_root_for_path(path) -> Path | Noneget_package_framework_hints(pkg_root) -> dict[str, str]
Package root: ~/.kohakuterrarium/packages/. Editable installs use
<name>.link pointers instead of copies.
- Concepts: composing an agent, modules/tool, modules/sub-agent, impl-notes/session-persistence.
- Guides: programmatic usage, custom modules, plugins.
- Reference: cli, http, configuration, builtins, plugin-hooks.