Imported from joakim-brannstrom/llmfun (
AGENTS.md). Install upstream withnpx skills add joakim-brannstrom/llmfun. Copyright stays with the author.
llmfun
LLM agent harness — a CLI tool that orchestrates AI agents with tool calling, RAG, pipelines, metrics, skills, and a terminal UI. Supports both remote API and local llama.cpp model inference.
Tech Stack
- Language: D (primary), C (vendor: sqlite3, sqlite3-vec, imtui), C++17 (cpp_tui, imgui_markdown, llama.cpp)
- Build: Dub (
dub.sdl) + Makefiles for C/C++ components - Database: SQLite3 with FTS5 and sqlite3-vec (vector search)
- Local Inference: llama.cpp
- Terminal UI: imtui (Dear ImGui for terminals) + custom C++ TUI library
- Key Libraries: argparse, requests, dyaml, colorlog, mylib, miniorm
Directory Layout
llmfun/
├── source/
│ ├── app.d # Thin command dispatcher
│ ├── utility_app.d # Test utility entry point
│ └── llm/ # Main package
│ ├── agent/ # Agent package
│ │ ├── package.d # Core Agent class (module llm.agent)
│ │ └── context.d # Tool-execution context (AgentContext, VisionImage)
│ ├── agent_pool.d # Thread pool for agent execution
│ ├── app_agent/ # Agent subcommand handler + TUI
│ │ ├── package.d # AgentApp + appMain (module llm.app_agent)
│ │ ├── slash.d # Slash command registry + plugin API
│ │ ├── slash_core.d # Core commands (/help, /quit, /stop, ...)
│ │ ├── slash_session.d # Session commands + /delete state machine
│ │ ├── slash_model.d # /model command
│ │ ├── slash_pipeline.d # /plan, /code commands
│ │ ├── slash_skills.d # /skills, /refresh-agent-md commands
│ │ ├── ui.d # UiMessenger + stream updaters
│ │ └── tests.d # Unit tests (golden help, built-ins)
│ ├── app_rag.d # RAG subcommand handler
│ ├── app_mcp.d # MCP server subcommand handler
│ ├── app_tool_metrics.d # Tool metrics subcommand handler
│ ├── config.d # Multi-layer configuration
│ ├── chat.d # Chat history / message management
│ ├── query.d # HTTP client with retry, streaming
│ ├── skill.d # Skill management system
│ ├── summary_agent.d # Context compression / summarization
│ ├── memory.d # Memory consolidation orchestrator
│ ├── session/ # Chat session persistence (SessionStore)
│ ├── pipeline/ # Pipeline engine & DAG
│ ├── rag/ # RAG database and query logic
│ ├── tool_call/ # Tool registration and implementations
│ ├── mcp_server/ # MCP server (JSON-RPC 2.0 over stdio)
│ ├── metric/ # Metrics aggregation and monitoring
│ └── tui/ # TUI D bindings
├── common/ # Shared embedder interface and config types
├── local_model/ # Local model inference via llama.cpp
├── cpp_tui/ # C++ TUI library with C API for D interop
├── vendor/ # Vendored C/C++ libraries
├── config/ # Runtime configuration templates
└── doc/ # Documentation (database, sessions, skills, TUI design)
If your identity is llmfun then:
- when accessing the source code through tools such as listDirectories, read/write/edit the source code is located at "./llmfun".
- when using the tool executeCommand the working directory is /workarea. The absolute path to the source code is /workarea/llmfun.
Commands
Important: The container image to use when running the tool executeCommand is llmfun/app:latest.
Example of using executeCommand: executeCommand(environmentTag="llmfun", command=["cd", "llmfun", "&&", "dub", "build", "--config=application"])
cd llmfun
dub test # Run all unit tests
dub build --config=application # Build main app (remote API only)
dub build --config=application-with-local-model # Build with llama.cpp support
dub build --config=llmfun_util # Build test utility (manual testing)
./build/llmfun agent # Run interactive agent
./build/llmfun rag add <path> # Add file to RAG index
./build/llmfun rag --dialogue # Report per-session dialogue history databases (read-only)
./build/llmfun rag query "question" # Query RAG knowledge base
./build/llmfun tool_metrics # View tool metrics
./build/llmfun mcp --stdio # Run MCP server over stdio
./build/llmfun mcp --list-tools # List available MCP tools
Code Conventions
Comments
- Use ddoc comments, NOT doxygen comments. Ddoc forms:
/** ... */,///,/+ ... +/. - Module header: Every module must start with a brief ddoc comment (1-3 lines) introducing the module and what it does, placed before the
moduledeclaration. - Comments explain why, not what. If the code is self-documenting, the comment is redundant.
- Concise: 1-2 lines max. Break longer explanations into separate short comments.
- No hard-wrapping: Do not wrap to a fixed column width. Let lines flow naturally.
- No mid-sentence breaks: Each comment line should be a complete thought.
- Simple language: Short words, short sentences.
- Write code first, then add comments only where genuinely needed.
- Never add comments to copied code that weren't there originally.
String Handling
-
Prefer interpolated strings over
std.format.format/formattedWrite:// Good auto msg = i"Found $(count) results for $(query)".text; // Bad auto msg = format!"Found %s results for %s"(count, query); -
Prefer backtick-strings when embedding
"or\:// Good auto path = `foo "embed" bar`; // Bad auto path = "foo \"embed\" bar";
Variable Initialization
-
NEVER initialize
stringwith= "". D auto-initializes all locals:// Good string name; // Bad string name = ""; -
Prefer local function initialization over unnecessary variable declarations:
// Good auto status = () { if (isOk) return "ok"; if (isWarning) return "warn"; return "error"; }(); // Bad string status; if (isOk) status = "ok"; else if (isWarning) status = "warn"; else status = "error"; -
Floating point initialization should be zero initialized. The default initialization in D is NaN.
auto x = new float[42]; // NaN x[] = 0; // zero init
Naming & Formatting
- K&R brace style (opening brace on the same line)
- Local imports inside functions/structs where symbols are not pervasive
- No magic numbers without named constants
- No wrapper functions for stdlib symbols — use local imports at point of use
Error Handling
-
No empty catch blocks. Always log or handle caught exceptions:
catch (Exception e) { import std.logger : trace; trace(e.msg); } -
Logging: Use
std.logger(notstderr) for diagnostic output. -
Silent catches for @safe: When
.collectExceptioncannot be used (e.g., due to@safeviolations), wrap the throwing code in try/catch and nest another try/catch around the logging call. The innermost catch may be empty — this is the only place where an empty catch block is allowed:try { // code that may throw } catch (Exception e) { try { import std.logger : trace; trace(e.msg); } catch (Exception innerE) { // Empty inner catch allowed — keeps the parent @safe and nothrow } } -
NEVER catch an Error or Throwable exception.
Attributes
-
@safe: Mark functions
@safewhenever possible. If the compiler rejects it, fix the underlying issue rather than downgrading the safety level.// Good — simple, obviously safe bool isAgentMdTopic(string topic) @safe pure nothrow { ... } // Bad — unmarked function that could be @safe bool isAgentMdTopic(string topic) { ... } -
@trusted: Use only when
@safeis not feasible.@trustedbridges@safeand@system— it must verify all inputs and ensure operations are memory-safe before exposing a@safeinterface. Keep@trustedcode minimal. -
@system: The default safety level. Avoid unless dealing with low-level operations (raw pointers, assembly, C interop). Never expose
@systemthrough a@safeinterface without@trustedwrapping. -
pure: Add
pureto functions that do not access or modify global/mutable state beyond their parameters. -
nothrow: Mark functions
nothrowwhen they do not throw exceptions. Use it to signal error-return patterns (returningSumType, error codes, etc.) and let the compiler enforce the contract.
General
- ASCII only. Avoid emdash, unicode arrows, or any non-ASCII characters. Use
-,->,x,.... - Do not split lines mid-sentence or force lines to fit a fixed character width.
- Prefer reusing existing infrastructure over introducing new components.
Architecture & Patterns
Entry Point
app.d is an ultra-thin dispatcher. It parses CLI args via argparse and routes to appMain overloads in app_agent/package.d, app_rag.d, app_mcp.d, and app_tool_metrics.d.
Agent System
Agentclass inagent/package.d(modulellm.agent) is the core. Handles vision, streaming, feedback, and stuck-loop detection.AgentContextinagent/context.dis the tool-execution context; it is decoupled fromAgentand can be constructed standalone with injected RAG/metrics dependencies.AgentPoolmanages concurrent agent execution via a thread pool.- Agents communicate through a
Chathistory with role-based messages.
Chat Sessions
- Multi-history chat storage: one JSON file per session under
<dataDir>/chat/<id>.jsonwith header{title, createdAt, updatedAt, messages}. - Implementation:
source/llm/session/package (modulellm.session).package.dre-exportstypes.d(SessionMeta,SessionFile, theSessionIdstrong type, id generation/validation),store.d(SessionStore: create/load/save/rename/remove/list),resolve.d(resolveSessionRef: index -> id -> title, pure),tests.d(unit tests). - Chat-free by design: the module only speaks JSON.
app_agent/package.dbridgesSessionFile.doctoagent_.chat.load()/agent_.chat.toSaveJson(). - Naming rule: "session" already means app-launch in
config.d(sessionCountdrives memory consolidation). The chat-history concept usesSessionStore/SessionMeta/SessionFileonly. SessionIdis aNamedType!stringstrong type (mylib): a session id is not interchangeable with titles, previews, or other strings.state.jsonstill stores the plain string (activeChatSessionId); conversion happens at the config boundary.- Session id = filename (immutable), format
<YYYYMMDD-HHMMSS>-<4hex>; regex validation at every store entry point prevents path traversal. Title lives in the header; rename edits the header only. - The store resolves its directory to an
AbsolutePath(independent of the CWD); file paths are built asAbsolutePath. - Unknown header keys round-trip through
SessionMeta.extra, so future per-session settings need no format migration. - Active session id is persisted in
state.jsonasactiveChatSessionIdand reopened on startup. One-shot mode (-p) appends to the last active session. - Slash commands are registered in
app_agent/slash*.d(registry inslash.d, one group module per command family) and dispatch throughAgentApp.slashCommands_. Session commands (/sessions,/switch <n|id|title>,/new,/rename <title>,/delete <n>(repeat to confirm),/clear) reuse the sameAgentAppmethods (doListSessions,switchToSession, etc.) as the TUI sidebar. - System-prompt entries are stripped from
messagesbefore save; the prompt is re-set at startup. - Single writer (the agent thread); all writes are atomic (tmp file + rename).
- Full documentation:
doc/sessions.md. - TUI sidebar: a left session panel (
ChatTabSessionPanelincpp_tui/tui.h) with switch / new / rename / delete. Messages:UiSessionList(D -> UI snapshot) andUiSessionSelect/UiSessionNew/UiSessionRename/UiSessionDelete(UI -> D actions) intui/package.d; the agent handlersdoSidebarSelect/doSidebarNew/doSidebarRename/doSidebarDeletereuse the existing session methods.isValidIdis public (session/types.d) for UI-boundary validation. - Sidebar C API additions (
TUI_API_VERSION2, documentation marker):SessionItem,SessionAction,tuiSetSessionList,tuiIsSessionActionReady,tuiGetSessionAction. The session panel and the pipeline panel share one left slot:leftPanelWidth(state)resolves the output offset; the pipeline wins whenever it has agents. - TUI search/filter (C++-only;
TUI_API_VERSIONstays 2): single-line filter input in the session panel header; fzf-style case-insensitive byte-level subsequence match against title + preview (title weighted 2x) with simplified-fzf ranking (per-byte base / word-boundary / consecutive bonuses, gap penalty, score clamped to >= 0); per-frame filter + rank of the local snapshot (no D or C API change); Enter selects the top match, Escape clears (rename box wins while open), row click selects; busy selection defers in the pending-switch slot; the filter clears on selection and persists across snapshot refreshes, panel close/reopen, and pipeline occupancy; matched title words highlighted;no matchesindicator; rename box closes when its row is filtered out. Matcher:cpp_tui/session_fuzzy.h(pure, standalone-tested); tests:test_session_fuzzy+test_session_filter_smoke(headless harness). Deferred: keyboard list navigation, query operators, DP scoring. Seedoc/sessions.md(TUI Search/Filter) anddoc/tui_design.md(Filter Input).
Turn IDs and Compression Checkpoints
- Every chat-history entry carries a typed
turnId(mixinTurnIdMixininllm/chat.d); 0 = no turn. A turn is one user query plus everything produced while answering it. - Turn boundaries are decided inside
Chat.addonly: a user-queryMessageopens a new turn (allocating from the per-Chat counternextTurnId_), every other insertion continues the current turn, andsetSystemPromptstamps 0. Call sites never allocate turns themselves; vision chats open a turn explicitly withchat.beginNewTurn(). - Counter state is per-Chat (
nextTurnId_/currentTurnId_, no static/shared/atomic state). The high-water mark is persisted as the session-header keynext_turn_id; on disk the stamp lives inside each message'ssave_data["turn_id"](typed field in memory,save_dataon disk — no new top-level message keys). Invariants I1–I4 (history sorted by(turn_id, position), active-turn stamps > 0, counter never decreases, no ID reuse within a session — including across restarts,clear()/reload never recycle IDs) are pinned by unittests inllm/chat.d; legacy files are reconstructed on load (reconstructTurnIds). - Projections:
getDialogueHistory()(Facts) andgetReasoningTrace()(Trace) inllm/chat.d. Harness control traffic (user-role messages withuserQuery == false) appears in neither projection. - Compression is observable:
SummaryAgentmulticasts aCompressionCheckpointviaaddCheckpointListenerexactly once per compression that actually evicts verbatim content, carrying the session id, the evicted message arrays, the evicted turn range, and the final context size. Listeners must not block (the compressing thread is usually the UI thread) and must not throw (throwing listeners are caught and logged).
Searchable Dialogue History (Phase 1)
DialogueIndex(llm/rag/dialogue_index.d) is owned by the agent thread; it spawns an actor worker (llm/rag/dialogue_worker.d) on its own thread. The worker owns its own embedder (never the shared agent embedder) and all communication is via value messages only.- Episodes are indexed into per-session SQLite WAL databases under
dialogueDir(config keydialogueDir, defaultllmfun/data/dialogue): one<sessionId>.dbper session, opened/created with theopenDatabase/addToDatabaseseam as Topic sources namedd_<sess>__t<turnStart>_<turnEnd>__<epochMillis>(encodeTopicName/decodeTopicName; hyphens → underscores in the name). - Dialogue dedup identity is topic + content: the worker passes the episode
topic name as the
addToDatabasededup salt, so byte-identical exchanges in two different turns are indexed separately under their own turn metadata, while re-indexing the same topic+content stays a no-op. A turn split across two compression checkpoints merges: the worker reconstructs the existing episode text (Database.sourceText) and indexesexistingText + "\n" + new pieceunder the same topic name. The FTS index is rebuilt synchronously after every job that committed chunks (no coalescing). Known no-fix: changing the embedding model or dimensions makes the write path drop and recreate a dialogue DB (all indexed history for that session is lost) — intentional, the loss is the operator's responsibility. - Turn metadata is always derived by decoding the DB topic names, never from worker memory (F5). The
queryDialogueHistorytool (llm/tool_call/dialogue.d) takesmaxTurnAge: 0/negative = no filtering, positive N keeps episodes withturnEnd >= maxTurn - N(maxTurncomputed from the DB). - Indexing is asynchronous with a small lag (~2-3 s, R3 — documented in the tool description). Indexing itself is triggered in code at each compression checkpoint (F1). The F7 trigger rule — when the main agent should call
queryDialogueHistory— lives inconfig/prompt/AGENT.md("# Dialogue History Retrieval"), user-tunable, with no code-side constant. - Admin/reporting:
llmfun rag --dialogueproduces a read-only report over the session databases (per-session source count, indexed turn range, totals). It dispatches beforecreateRag(no embedder/local model/primary RAG DB needed), probes each DB'sVersionTblfor model/dimensions before the read-only open, and only considers D12-valid session file names (path-traversal guard). A session whose read-only open fails (e.g. WAL recovery after an abnormal shutdown, or a read-only directory where-shmcannot be created) is skipped with a warning. No destructiveragsubcommands in Phase 1.
Slash Commands
- Delegate-based command registry (
app_agent/slash.d): commands are registeredSlashCommandstructs with name, aliases, help lines,SlashArgMode, helporder, and a handlerAgentStatus delegate(ref AgentApp, string). - Five group modules register the built-ins:
slash_core.d(help/quit/stop/compact/debug),slash_session.d(sessions/switch/new/rename/delete/clear + the delete confirm state machine),slash_model.d,slash_pipeline.d(plan/code),slash_skills.d. - Help text is generated from the registry (order asc, registration index asc); a golden unit test in
tests.dlocks byte parity with the pre-refactorbuildHelpText(). - Plugin API (public):
addStartupSlashCommand(module-level hook, registered inAgentApp's constructor),AgentApp.registerSlashCommand,AgentApp.slashCommands(),AgentApp.sendChatMessage, plusSlashCommand/SlashArgMode/AgentStatus. Package-private: the five group registrars andAgentAppinternals. - Full documentation:
doc/slash_commands.md.
Tool Call System
- Tools are registered via
@Functionattribute andRegisterLlmFunctions!()mixin intool_call/package.d. - Each tool module implements functions that take a
Contextand a params struct. - Tools carry optional tags (
@Function(..., tags: ["workarea"])): untagged tools are always visible (alwaysOn); tagged tools are hidden until the model activates their tag vialistToolTags/toolSearch(the tool broker; sticky activation, pruned only at compression points). The tag vocabulary is theKnownToolTagenum (tool_call/tags.d) plus configtoolBroker.toolTagDescriptions; kill switchtoolBroker.enabled. Full guide:doc/tool_authoring.md. tool_call/io.dis the largest module — file system operations with advanced editing (searchAndReplace, applyDiff, editFileByMarker).
Pipeline System
- DAG-based pipeline engine in
pipeline/package.dwith topological sorting inpipeline/graph.d. - Pipelines orchestrate multi-step agent workflows with node output propagation.
RAG System
- SQLite-backed with FTS5 full-text search and sqlite3-vec for vector similarity.
- Schema version v6 in
rag/database.d. - Embedder factory pattern: HTTP (OpenAI-compatible) and local (llama.cpp) backends.
Skill System
- Implements Agent Skills open standard. Skills are directories with
SKILL.md,references/,scripts/,assets/. - 13 built-in skills (create-skill, code-review, debugging, dlang, etc.).
- Skills are loaded at runtime by copying into the sandbox workarea.
Configuration
- Multi-layer config in
config.d: CLI args override file config, file config overrides defaults. - Two-layer loading: base config from
LLMFUN_SYSTEM_CONFIG/ system path, overlay from--config/.llmfun.yamlin CWD. - Security: CWD config skipped when workarea == CWD unless
--trusted-configis used. - Supports
ToolLimits,RagConfig,SandboxConfigwith execution environments, skill paths, consolidation settings, and endpoint types (llamaCpp,deepseek). - Magic word substitution:
@{llmfun_workarea}and@{llmfun}in container options.
TUI
- C++ TUI library (
cpp_tui/) provides Dear ImGui-based terminal UI with markdown rendering. - D bindings in
tui/package.dhandle streaming and inter-thread message passing. - Exposed via pure C API (
tui_api.h/tui_api.cpp) for D interop. - Session sidebar (
ChatTabSessionPanel): session rows with active marker and[N]count, rename toggle + input on the active row, two-step delete, busy gating (guard-and-skip; the vendored ImGui 1.81 has noBeginDisabled). A filter input in the panel header with fzf-style fuzzy subsequence matching + ranking against title + preview (session_fuzzy.h, pure), Esc/Enter/click selection with busy-defer, whole-word match highlighting, and the headlesstest_session_filter_smokeharness. Mutually exclusive with the pipeline panel (the pipeline wins the left slot whenever it has agents);leftPanelWidth(state)resolves the output offset. Seedoc/tui_design.md. - D can import
.cas they are, no binding is required, noextern(C)is required. See the D specification for more details. - Max width (
TuiConfig/ YAMLtui.maxWidth): caps the TUI's rendered width in terminal columns (0 = unlimited, default; valid 0 or [40, 10000], enforced invalidateConfig). The C++ core clamps at the top oftuiRenderevery frame (TuiState.maxWidth,tuiSetMaxWidth,TUI_API_VERSION3); the margin right of the cap is never written (terminal-managed). Standalonecpp_tuiexecutable:LLMFUN_TUI_MAX_WIDTHenv var (no CLI flag). Seedoc/tui_design.md.
MCP Server
- Implements the Model Context Protocol (MCP) over stdio using JSON-RPC 2.0.
mcp_server/package:types.d(JSON-RPC types),protocol.d(parsing/serialization),transport.d(stdio transport),package.d(MCPServer class + actor).- Bridges MCP's JSON-RPC protocol to llmfun's existing tool infrastructure via
descAllFunctions()andexecuteFunc(). - Uses
ReFilterfor tool visibility control (--include/--excludeCLI flags). - Runs as a
std.concurrencyactor: the main thread spawnsrunMcpServerand communicates via messages (McpServerConfig,McpShutdown,McpStarted,McpStopped,McpFailed). - No shared state between threads; termination signals (SIGINT/SIGTERM) are blocked and consumed by the main thread via
sigtimedwait. - Stdio transport uses unbuffered POSIX reads to avoid the poll/FILE buffering race that causes stalls.
- Supports MCP methods:
initialize,tools/list,tools/call,ping,resources/list(empty),prompts/list(empty). - See
doc/mcp.mdfor protocol details and usage examples.
Testing
The unit test runner is nusilly (dub dependency, a fork of silly). It replaces the default unittest runner in dub test: every argument after -- is passed to the test binary. Run dub test -- -h to see the options.
- Run all unit tests:
dub test(no configuration parameter). This compiles and runs all inlineunittestblocks across all modules. This is the primary test command. - Build test utility:
dub build --config=llmfun_util. This configuration builds a separate test utility binary (utility_app.d) for manually testing implementation details. It does NOT run the unit test suite. Entry point:source/utility_app.d. - Inline unit tests exist in most modules (e.g.,
rag/rag.d,llm/tool_call/io/tests.d). New code should include inlineunittestblocks.
Runtime
dub testtakes about 30 seconds wall clock: recompiling and relinking the test binary plus about 7 seconds to run the ~500 tests. That is the normal cost of the regression gate; do not avoiddub testbecause it takes a while. Run it after changes to tested code and treat a green run as the acceptance gate.- A failing test makes
dub testexit non-zero (Error Program exited with code 1); a green run ends withSummary: N passed, 0 failed in X ms. - Tests run multithreaded by default (one worker thread per CPU). If a failure looks dependent on parallel execution, re-run with
-t 1.
Filtering options (passed after dub test --)
--no-colours- disable colour output (automatically disabled when stdout is not a tty).-t <n>/--threads <n>- number of worker threads; 0 = auto-detect (default).-i <regexp>/--include <regexp>- run only the tests whose name matches the regular expression.-e <regexp>/--exclude <regexp>- skip the tests whose name matches the regular expression.--fail-fast- stop executing tests when a test fails. Note: only a failure that throws anErroror bareThrowablestops the run; a plainassertfailure (AssertError) or a thrownExceptiondoes not.-v/--verbose- per-test durations, source locations, full stack traces.-h/--help- print the options and exit without running tests.
The -i / -e regular expressions (std.regex syntax, unanchored) are matched against the test's fully qualified name and its test name, so both module-wide and per-test filtering work:
dub test -- -i '.*llm\.rag.*' # all unittests in llm.rag modules
dub test -- -i '.*my_experiment.*' # the single named test "my_experiment"
Do not use -i and -e at the same time (results are unexpected).
Naming tests and the experiment pattern
A string user-defined attribute on a unittest names the test (with multiple string UDAs, the first wins). Unnamed unittests are reported as <module> __unittest_L<line>_C<col>; named ones as <module> <name>.
A good way of experimenting with llmfun internal code is to add a temporary named unittest with the experimental code to any module (remove the >):
> @("my_experiment")
> unittest {
> // experimental code
> }
and then run only that test:
dub test -- -i '.*my_experiment.*'
Remove the temporary unittest when the experiment is done.
Agent Rules
- Always verify facts using RAG search or memory before asserting them. Internal knowledge is not sufficient for specific names, technical details, or version-specific information.
- Read relevant source files before writing any code. Your changes must blend with the existing codebase.
- Run
dub buildafter making changes to verify compilation. - Run
dub testafter changes to tested code. It takes about 30 seconds; do not avoid it or replace it with partial checks. - Never write PR descriptions, commit messages, or reviewer responses on behalf of the user.
- Never commit or push without explicit human approval. If committing on behalf of the user, use
Assisted-by:in the commit message, neverCo-authored-by:. - Track known gaps in
doc/todo.md.
Code Comment Examples
// GOOD (code is self-explanatory, no comment needed)
auto count = items.length;
// BAD (too verbose, restates what the code already says)
// Get the number of items in the items array and store it in count
auto count = items.length;
// GOOD (explains a non-obvious invariant)
accept();
bool hasClient = listen(idleInterval);
if (hasClient) {
taskQueue.onIdle(); // also signal child disconnection
}
// BAD (too verbose, restates what the code already says)
// Instead of blocking indefinitely on accept(), the server polls the listening
// socket with idleInterval as a timeout. If no new client connects within that
// interval, it fires taskQueue.onIdle() and loops back
// GOOD (generic, useful to any future reader)
// reset here, as we will release the slot below
nTokens = 0;
// ... (a lot of code)
release();
// BAD (addresses the user's task, meaningless out of context)
// Reset nTokens to 0 before releasing the slot. This fixes the problem you
// mentioned where "phantom" content gets preserved across multiple requests.
nTokens = 0;
// GOOD (comment is kept concise and useful)
// one decode step of codePredictor
// at stepIdx g:
// - read code from outCodeCache[g], then embed it with codebook table g-1
// - write new kv at cache row g+1, sample with lmHead[g]
// - write result to outCodeCache[g+1]
// BAD (long, hard-wrapped to fixed column, annoying to read)
// one autoregressive decode step of the 5-layer codePredictor. See the
// comment in models.h for the cache/tensor conventions this relies on.
//
// index mapping (derived from the reference pipeline-tts.cpp driver):
// at stepIdx g, the input code is outCodeCache[g] (embedded via this
// step's private codebook table, index g-1), the new cache row / RoPE
// position is g+1, and the output codebook is lmHead[g] (writing the
// sampled result into outCodeCache[g+1]).
References
doc/database.md— Database schema and RAG detailsdoc/tool_authoring.md— Tool authoring and the tool broker (tagging guide)doc/sessions.md— Chat session storage and agent integrationdoc/skills.md— Skills system documentationdoc/tui_design.md— TUI architecturedoc/todo.md— Task tracking and known gaps
