Imported from whanyu1212/Krill.jl (
AGENTS.md). Install upstream withnpx skills add whanyu1212/Krill.jl. Copyright stays with the author.
Repository Guidelines
Purpose
- This file is the root onboarding guide for Codex and other coding agents working in this repository.
- Prefer reading the current code over inferring architecture from stale comments.
src/Krill.jlis the authoritative include order for the package. - Treat this repo as a Julia-native agent runtime, not a thin bot wrapper: most changes touch prompt assembly, tool dispatch, persistence, or channel/runtime wiring.
Start Here
README.mdexplains the product surface and top-level config shape.src/Krill.jlshows module load order and public exports.src/runtime.jlshows how channels, session processing, tools, MCP, cron, memory, and subagents are wired intoRuntimeState.src/agent.jldefines the configuration surface that feature work usually extends:MemoryConfig,BuiltinToolsConfig,SkillsConfig,ClaudeCodeConfig,CodexConfig,PromptContextConfig,SubagentConfig, andRetryConfig.src/prompt_context.jlshows how system instructions are composed from bootstrap docs, skill metadata, always-on skills, session memory, global memory, tool-safety guidance, and runtime metadata.test/runtests.jlis the map of what the suite actually covers.
Architecture Map
bin/krill.jlis the runtime entry point.src/Krill.jlis the package entry point and include-order source of truth. Include order matters in this codebase.src/transport/owns normalized message types and queueing:types.jlmessage_hub.jlmanager.jldedup.jlchannels.jldurable_queue.jl
src/sessions/owns persistence and long-lived conversation state:sessions.jlfor history persistencememory.jlfor session memory filesmemory_consolidation.jlfor LLM-driven session-memory summarizationglobal_memory.jlfor user-wide cross-session memoryconsumer.jlfor per-session FIFO processing and cancellationecho.jlfor the non-LLM processor path
src/tools/owns the tool system:registry.jlforToolDef,ToolRegistry, and dispatchskills.jlfor workspace and builtinSKILL.mddiscoverymcp.jlfor MCP client registration and namespacingbuiltin/for local tools: file, web, shell, GitHub, Google Workspace, cron, message, Claude Code, and Codex
src/llm/owns provider integration and the tool loop:providers.jl,api.jl,chat_completion.jlparsing.jlfor provider payload conversiontool_loop.jlfor iterative tool executionprocessor.jlfor session processor constructioncontext.jlandllm.jlfor provider-facing assembly
src/scheduling/owns background execution:cron.jlsubagent.jl
src/channels/owns Telegram and Discord adapters.src/config/owns config parsing, environment expansion, provider creation, MCP config, and channel construction.src/runtime.jlwires everything together intoRuntimeState.
Runtime Flow
- Inbound channel payloads are normalized into
InboundMessage. BoundedDedupsuppresses repeat deliveries before they hit the hub.MessageHubStatefeeds the session consumer.run_session_loop!enforces per-session FIFO while allowing concurrent sessions.- The processor is either echo or an LLM-backed processor from
make_llm_processor. - LLM turns may call local builtins, MCP tools, cron tools, Claude Code, or Codex through the tool loop.
- Turn history is persisted to the session store, and outbound messages are dispatched through
ChannelManagerState. - Cron jobs inject synthetic inbound messages; subagents run background tasks with their own bounded iteration limits.
Prompt And Memory Model
- Prompt composition lives in
src/prompt_context.jl; do not collapse it back into one static prompt string. - Bootstrap docs are loaded from the workspace in this order:
AGENTS.md,SOUL.md,USER.md,TOOLS.md. - Missing bootstrap docs are skipped, not treated as errors.
- Skills come from
context/skills/plus optional builtin skill directories. Workspace skills override builtin skills with the same name. - Skills with
always: truefrontmatter are injected into every turn if their requirements are met. - The composed instruction stack can include:
- base system prompt
- workspace bootstrap docs
- available-skills summary
- always-on skill content
- global user memory
- per-session memory
- tool-output safety guidance
- runtime metadata such as UTC timestamp, channel, session key, chat id, and user id
- Session history persists under
<data_dir>/sessions/<session>/history.jsonl. - Session memory persists under
<data_dir>/memory/<session>/asMEMORY.md,HISTORY.md, andstate.json. - Global memory persists under
<data_dir>/global_memory/<user_id>/MEMORY.md. - Cron jobs persist under
<data_dir>/cron/jobs.json. - Dead letters persist under
<data_dir>/dead_letters.jsonl.
Project Structure And Files To Touch
- Add or change tool behavior in
src/tools/builtin/*.jland check registration insrc/tools/builtin/registration.jl. - Add MCP behavior in
src/tools/mcp.jl. MCP tools are namespaced asmcp_<server>_<tool>. - Add provider behavior in
src/llm/providers.jl,src/llm/parsing.jl,src/llm/chat_completion.jl, and corresponding runtime tests. - Add prompt or instruction behavior in
src/prompt_context.jlandtest/test_prompt_context.jl. - Add memory behavior in
src/sessions/memory.jl,src/sessions/memory_consolidation.jl,src/sessions/global_memory.jl, and runtime-memory tests. - Add cron or subagent behavior in
src/scheduling/cron.jlorsrc/scheduling/subagent.jlplus their focused tests. - Add channel behavior in
src/channels/telegram.jlorsrc/channels/discord.jlplus normalization, webhook, and connector tests. - Add config surface area in
src/config/config.jl,src/config/provider.jl,src/config/mcp_config.jl, orsrc/config/channels_config.jl.
Build, Test, And Development Commands
julia --project=. -e 'using Pkg; Pkg.instantiate()'Install project dependencies.julia --project=. --threads=auto bin/krill.jlRun the main agent using repositorykrill.toml.julia --project=. --threads=auto bin/krill.jl --config /path/to/krill.tomlRun with an explicit config path.bash scripts/test.shPreferred full-suite command. RunsPkg.test()and removes macOS._*artifacts on exit.bash scripts/test_fast.shFast local iteration path withKRILL_FAST_TESTS=1.bash scripts/test_channels.shbash scripts/test_tools_mcp.shbash scripts/test_skills.shbash scripts/test_cron.shbash scripts/test_subagent.shbash scripts/test_dispatch.shbash scripts/test_claude_code.shFocused wrappers for subsystem work.julia --project=. test/test_<name>.jlWorks for many focused files, but some tests assume imports fromtest/runtests.jl.julia --project=. -e 'using Krill; using Test; using UUIDs; using Dates; include("test/test_types.jl")'Safer pattern for single-file execution when a test relies on shared imports.julia --project=docs docs/make.jlBuild docs.npm --prefix docs run docs:devRun local docs preview.
Test Map
test/runtests.jlincludes the full suite and shared imports.- Core transport coverage:
test/test_types.jltest/test_message_hub.jltest/test_durable_queue.jl
- Channel coverage:
test/test_telegram_connector.jltest/test_normalize.jltest/test_channels.jltest/test_webhook.jl
- Runtime and provider coverage:
test/test_runtime.jltest/test_openai.jltest/test_gemini.jltest/test_runtime_openai.jltest/test_runtime_gemini.jltest/test_runtime_sessions.jltest/test_runtime_memory.jl
- Session and memory coverage:
test/test_sessions.jltest/test_memory.jltest/test_session_consumer.jltest/test_global_memory.jl
- Tool and prompt coverage:
test/test_builtin_tools.jltest/test_tools_mcp.jltest/test_prompt_context.jltest/test_skills.jltest/test_claude_code.jltest/test_subagent.jltest/test_cron.jltest/test_dispatch.jl
- Safety and regression coverage:
test/test_context_window.jltest/test_security.jltest/test_gap_fixes.jl
- Code quality:
- Aqua runs from
test/runtests.jl.
- Aqua runs from
Coding Style And Naming Conventions
- Use 4-space indentation and no tabs.
- Julia naming:
UpperCamelCasefor modules and typessnake_casefor functions, variables, and files
- Mutating functions should use a
!suffix. - Keep JSON and provider payload boundaries as
Dict{String,Any}unless there is a strong reason not to. - Prefer small helpers around prompt assembly, provider mapping, persistence, and tool dispatch rather than large monolithic functions.
- Validate boundary inputs with
ArgumentErrorand keep fallback behavior explicit. - Extend grouped agent config structs before adding new flat runtime flags.
- Preserve include ordering when moving code across files; this package is assembled by
include, not by isolated modules with automatic load resolution.
Working Safely In This Repo
- Check
git status --shortbefore editing. The worktree may be dirty. - Never revert unrelated local changes unless the user explicitly asks.
- macOS metadata files like
._*may appear;scripts/test.shcleans them up. - Mock HTTP, WebSocket, subprocess, and MCP boundaries in tests. Do not rely on live external services.
- Prefer
mktempdir()or explicit temporaryworkspace=anddata_dir=values in tests instead of writing into repositorycontext/. - When changing prompt construction or memory behavior, verify both direct unit tests and runtime tests. Those regressions often only show up once components are wired together.
Security And Configuration Tips
- Never commit secrets; keep API keys only in
.env. - Common env vars:
TELEGRAM_BOT_TOKENDISCORD_BOT_TOKENOPENAI_API_KEYGEMINI_API_KEYGH_PATKRILL_DATA_DIR
krill.tomlsupports$VARand${VAR}interpolation throughload_config.- At least one channel must be enabled in config.
- Provider-native tools are controlled by
[profile.tools].provider_builtins. - When provider-native search is enabled, the local DuckDuckGo-style
web_searchis intentionally not registered;web_fetchstill is. - If file tools are enabled, prefer
llm.builtin_restrict_to_workspace = trueunless cross-directory access is a conscious requirement. - Codex delegation is controlled through
[profile.tools].codexand related Codex config inAgent.
Change Readiness
- Add regression tests for every behavior change.
- A change touching tools, prompt context, channels, runtime wiring, persistence, or provider payload mapping is not complete without tests.
- The default merge bar is
bash scripts/test.shpassing.
