AnythingLLM: who decides what

Read the one-page summary first · The gallery · Make a map of your own system · The repository

The AnythingLLM server's agent and chat decisions (its agent loop and tools, chat and agent endpoints, retrieval and memory, agent flows, MCP bridge, scheduled jobs, Telegram bot and model providers) in Mintplex-Labs/anything-llm, read at commit d7d68e75. The web frontend and document collector are outside this map except where a decision reaches the server. Claims about how the code behaves refer to that commit. Their code is MIT-licensed; this page quotes short identifiers and cites files and lines at that commit.

How to read this page

A seat is a judgment the system makes over and over: is this message a command, what the model sees, may this action run, is the work done. Each card records the question, how it is answered, and who or what holds it, with the code that implements or exposes that decision. Seat ids (A1, B12 …) are links.

The chip on each card has two words. The first is about the question: a RULE has one right answer given its inputs, so a run that answers differently is a bug; a RULING is one that competent people could answer differently. Enforcing a limit someone set is a RULE; choosing what to keep, what to trust or when the work is done is a RULING, even when code holds it.

The second word is who holds it: llm = a language-model call; model = another learned model; code = code in their repository; human = a person; external = code outside the repository that the system hands the decision to.

Paths are relative to the repository root. A bare :120-140 means lines in the file named just before it.

Counts

117 seats across 9 stages: A 14, B 15, C 11, D 36, E 20, F 13, G 5, H 0, I 3.

Kind of question · holderSeats
RULE · code60
RULING · code24
RULING · human15
RULING · llm10
RULING · model4
RULING · external2
RULE · external2

What this edition does not have

There is no list of gaps. No coverage figure: this edition does not say how many of AnythingLLM's model calls and decision points the seats leave out. Each card shows the question, the answer and its holder; for most seats we also recorded what checks the judgment and how it has failed, but those notes are not shown here.

What is left out of this edition

11 of the 117 cards are left out of this edition. The counts above include them.

A. Intake and routing (14 seats)

A1 Is this web-chat message a built-in command (/reset, /img), and which of the user's saved slash-command presets get swapped into it? RULE · code
Answered how

Code tests the message against the built-in command names with a case-insensitive "starts with, not followed by [a-z0-9_-]" regex and returns the command name if one matches; otherwise it replaces every occurrence of each of the user's preset commands (at the start or after a space) with the preset's prompt text.

Held by

server/utils/chats/index.js:25 (called at server/utils/chats/stream.js:38; dispatch to VALID_COMMANDS at stream.js:40-52)

A3 Does this message go to the agent loop instead of the plain chat pipeline? RULE · code
Answered how

Code sends the message to the agent when it starts with @agent (then every @-word is taken as a handle), or when the workspace's chat mode is automatic and the workspace's model reports native tool calling (A4); otherwise plain chat. If the invocation record cannot be created it tells the user "could not be called. Chat will be handled as default chat." and falls through to plain chat.

Held by

server/utils/chats/agents.js:56 (handle parse at server/models/workspaceAgentInvocation.js:7-10; called at server/utils/chats/stream.js:55)

A4 Can this workspace's model call tools natively (which in automatic mode sends every message to the agent)? RULE · code
Answered how

Code builds the agent provider for agentProvider ?? chatProvider ?? LLM_PROVIDER with model agentModel ?? chatModel ?? provider default (for the router, the router's fallback model) and asks it; the base provider answers yes unless its tag is listed in PROVIDER_DISABLE_NATIVE_TOOL_CALLING, and local providers (Ollama, LM Studio, others) ask their inference server for the model's capabilities.

Held by

server/models/workspace.js:666 (base answer server/utils/agents/aibitat/providers/ai-provider.js:231-234; Ollama override providers/ollama.js:70-77; LM Studio providers/lmstudio.js:69-76)

A5 Should this Telegram message go to the agent because the conversation was agentic before? RULE · code
Answered how

Code, for a workspace in chat mode, sends the message to the agent if any user message in the loaded recent history (up to openAiHistory, default 20) starts with @agent; otherwise it applies A3.

Held by

server/utils/telegramBot/chat/stream.js:30 (used at :78-85)

A6 With the workspace in query mode, is there any workspace context at all, or does the user get the refusal text instead of a model answer? RULE · code
Answered how

Code returns the workspace's queryRefusalResponse (or a built-in sentence) without calling the model when the mode is query and either the vector namespace is empty, or no pinned, attached, searched or backfilled text was found.

Held by

server/utils/chats/stream.js:111 (second check :244)

A7 Which LLM connector answers this chat: the workspace's own model, the system default, or the model router? RULE · code
Answered how

Code uses the workspace's chatProvider/chatModel (else LLM_PROVIDER and its default model) with the workspace temperature or a per-request override; when the effective provider is anythingllm-router, it gathers routing context and asks the router (A8-A10) for the delegate connector.

Held by

server/utils/helpers/index.js:726 (called at server/utils/chats/stream.js:72 via resolveLLMConnector :377)

A8 Does this message match one of the router's admin-written calculated rules (keyword, regex, token count, message count, hour, image attached)? RULE · code
Answered how

Code evaluates the enabled calculated rules in priority order, each an AND/OR of conditions over the prompt text, the conversation's token and message counts, the server's current hour and whether an image is attached, and routes to the first match.

Held by

server/utils/router/index.js:426 (called at server/utils/AiProviders/modelRouter/index.js:56)

A9 Which of the router's described categories (LLM rules) does this message belong to, if any? RULING · llm
Answered how

A language model (the router's fallback provider/model) is run as a one-round headless agent with a single select_category tool whose category enum is the rule titles plus none; code maps the returned title back to its rule, and anything else means no match.

Held by

server/utils/agents/aibitat/plugins/router-classifier.js:71 (called at server/utils/router/index.js:469); model setting: the router record's fallback_provider / fallback_model (router-classifier.js:87-89)

A10 When no rule matches this message, does the conversation stay on the model a rule chose earlier, or go back to the router's fallback model? RULE · code
Answered how

Code keeps the last rule-chosen route if it was set or refreshed within the router's cooldown (cooldown_seconds, default 300 s), refreshing it on access; otherwise it uses the router's fallback provider/model.

Held by

server/utils/AiProviders/modelRouter/index.js:38 (sticky lookup server/utils/router/index.js:122-144)

A11 Which provider and model does the agent run on for this turn? RULE · code
Answered how

Code uses the workspace's agentProvider with agentModel (or, if no agent model, the provider's env default or a hard-coded base model); with no agent provider it falls back to the workspace chat provider and model, then to LLM_PROVIDER and its default; for the router it resolves the route like A8-A10; it re-resolves on every agent turn after the first.

Held by

server/utils/agents/index.js:487 (#fetchModel :468, #getFallbackProvider :425, providerDefault :327, per-turn resolveRoute :934-970)

A12 At what reasoning effort is this request sent? RULE · code
Answered how

Code sends the effort the user chose for the session only if it is a known level and the target model's capability list (from the provider's model API, cached) includes it; otherwise no effort is sent; routed workspaces never send one.

Held by

server/utils/helpers/reasoningEffort.js:303 (router check :287-292; called at server/utils/chats/stream.js:293 and server/utils/agents/index.js:875)

A13 Which workspace and thread does a message from this Telegram chat go to? RULE · code
Answered how

Code keeps per-Telegram-chat state in memory (restored from the saved connector config at start); a chat with no state goes to the connector's default_workspace and the workspace's default thread (threadSlug: null); the person can change it with the bot's workspace and thread menus.

Held by

server/utils/telegramBot/index.js:352 (restore :114-121; used at :492, :514-515; resolved in the worker at server/jobs/handle-telegram-chat.js:32-44)

A14 What message does a non-text Telegram input (voice, photo, document) become before it reaches the model? RULE · code
Answered how

Code transcribes voice and audio and sends the transcript; sends a photo as an image attachment with its caption or "Describe this image."; and sends a document as one message holding its extracted full text wrapped in a fixed frame plus the caption or "Summarize this document.".

Held by

server/utils/telegramBot/index.js:690

B. Context: what the model sees (15 seats)

B1 What system prompt does the model get this turn? RULE · code
Answered how

Code takes the workspace's prompt (else the built-in default), expands {…} variables (user, workspace, system and static ones), and appends the user's selected memories (B2) unless the caller says to skip them; the agent path uses a copy of the same assembly and appends one fixed sentence when clarifying questions are enabled.

Held by

server/utils/chats/index.js:122 (variables server/models/systemPromptVariables.js:240; called at server/utils/chats/stream.js:278, via routing at server/utils/router/index.js:355)

B2 Which of the user's stored memories are put into the system prompt this turn? RULING · model
Answered how

Code includes all the user's global memories and, for this workspace, all workspace memories when there are at most 5; with more than 5 a cross-encoder reranker (Xenova/ms-marco-MiniLM-L-6-v2) scores them against the prompt plus the last three user prompts and the top 5 are kept; nothing is injected when memories are disabled.

Held by

server/utils/memories/index.js:26 (rerank :68-95; limit MAX_INJECTED_WORKSPACE_LIMIT: 5 at server/models/memory.js:25; model id server/utils/EmbeddingRerankers/native/index.js:23)

B3 How much earlier conversation does plain chat send, and from whose rows? RULE · code
Answered how

Code loads the newest openAiHistory (default 20) saved exchanges for this workspace, user, thread and API session that are still marked include: true, oldest first.

Held by

server/utils/chats/index.js:83 (limit read at server/utils/chats/stream.js:105)

B4 How much earlier conversation does the agent start with? RULE · code
Answered how

Code loads the newest 20 saved exchanges for the invocation's workspace, user and thread (API session null), fixed, regardless of the workspace's openAiHistory.

Held by

server/utils/agents/index.js:89 (limit fixed at :908, chats: await this.#chatHistory(20),)

B5 Which pinned documents go into the context in full, and up to what token cap? RULE · code
Answered how

Code reads every pinned document of the workspace from disk in database order and adds each one whole while the running token estimate is still below the cap (the provider's full prompt window when the caller passes one, otherwise no cap); documents outside the documents folder or without pageContent/token_count_estimate are skipped.

Held by

server/utils/DocumentManager/index.js:30 (cap check :60-65; capped call at server/utils/chats/stream.js:161-164)

B6 Which files attached to this chat are put into the context in full? RULE · code
Answered how

Code loads every parsed file recorded for this workspace and thread (and this user, when one is given), reads its stored text from disk, and adds it whole, with no token cap.

Held by

server/models/workspaceParsedFiles.js:232 (called at server/utils/chats/stream.js:179-183)

B7 A file being attached would push the chat past 80% of the model's context window: should it be embedded into the workspace instead, attached whole anyway, or dropped? RULING · human
Answered how

The person decides in the "Context Window Warning" dialog (Cancel, attach anyway, or "Embed File"); choosing embed sends the server request that moves the parsed file into the workspace's vector store, so it is retrieved by search (B8) rather than sent whole (B6).

Held by

server/endpoints/workspacesParsedFiles.js:71 (the server request the chatting user's choice answers; the Embed button is hidden for multi-user default role users, frontend/src/components/WorkspaceChat/ChatContainer/DnDWrapper/FileUploadWarningModal/index.jsx:25)

B8 Which chunks of the workspace's embedded documents are relevant enough to put in the context? RULING · model
Answered how

An embedding model embeds the user's message; the vector database returns the topN (default 4) nearest chunks by cosine distance; code drops those whose similarity (1 − distance, floored at 0) is below the workspace's similarityThreshold (default 0.25) and those from a pinned document.

Held by

server/utils/vectorDbProviders/lance/index.js:417 (LanceDB, the default; non-rerank branch similarityResponse :183-224; similarity conversion :50-55); model setting: the workspace/system embedding engine (EMBEDDING_ENGINE)

B9 In "Accuracy Optimized" search mode, which of the candidate chunks are most relevant to the question? RULING · model
Answered how

Code fetches a wider candidate set (10% of the namespace, at least 10 and at most 50 chunks); a cross-encoder reranker (Xenova/ms-marco-MiniLM-L-6-v2, local) scores each against the message and keeps the top topN; code then drops any whose original vector similarity is below the threshold or whose source is pinned.

Held by

server/utils/vectorDbProviders/lance/index.js:99 (scoring server/utils/EmbeddingRerankers/native/index.js:229-275; mode read at server/utils/chats/stream.js:203)

B10 When the search returns fewer than topN chunks, which earlier citations from this conversation are added back into the context? RULING · code
Answered how

Code walks the loaded history from the newest exchange back, and adds that exchange's saved citations (those with a score and text, not from a currently pinned document, not already present) until the window holds topN (default 4); the added text goes to the model but not to the citations shown for this answer.

Held by

server/utils/helpers/chat/index.js:436 (called at server/utils/chats/stream.js:225-230)

B11 The assembled prompt does not fit the model's window: what is cut, and from where? RULING · code
Answered how

Code does nothing if prompt plus a 600-token reply buffer fits; otherwise, if the user message alone exceeds 70% of the window it sends only that message, middle-truncated to 80% of the window, and drops the system prompt, context and history; else it middle-truncates the system prompt (instruction part to 25% and context part to 75% of a 15% budget), keeps history pairs newest-first within a 15% budget, truncating only the three most recent if they do not fit, and passes the user message through. That is the message-array path; the string-completion variant cuts the whole system prompt to its budget instead of splitting it.

Held by

server/utils/helpers/chat/index.js:49 (string-completion variant :220; truncation cannonball :349; budgets per provider, e.g. server/utils/AiProviders/openAi/index.js:33-37; called at server/utils/chats/stream.js:282-291)

B12 In agent mode, which pinned documents and attached files are added to the user's message, every turn? RULE · code
Answered how

Code, at the start of each agent turn, loads all parsed files for the invocation's workspace, thread and user plus all pinned documents, with no token cap, and appends them as <attached_documents> to the last user message; the model calls that follow a tool call in the same turn reuse them. They are also registered as citations.

Held by

server/utils/agents/index.js:804 (invoked per turn at server/utils/agents/aibitat/index.js:898-912)

B13 Which tools does the agent have this run? RULE · code
Answered how

Code assembles the list from the four default-on skills minus those the admin disabled, the admin-enabled configurable skills (multi-tool skills expanded into children, minus disabled children and minus skills whose integration is unavailable, and minus create-scheduled-job in multi-user mode), the clarifying-question tools when enabled, active imported custom skills, active agent flows, and every tool of every running MCP server minus suppressed ones.

Held by

server/utils/agents/defaults.js:131 (assembly in WORKSPACE_AGENT.getDefinition :72-102; imported server/utils/agents/imported.js:66; flows server/utils/agentFlows/index.js:188; MCP server/utils/MCP/index.js:17, :28-56; attach server/utils/agents/index.js:590-729)

B14 Of the tools available, which does the model actually see for this message? RULING · model
Answered how

When there are more tools than the limit (default 15, AGENT_SKILL_RERANKER_TOP_N) and selection is on (default on unless AGENT_SKILL_RERANKER_ENABLED=false), a local cross-encoder reranker scores each tool's name, description, parameter descriptions and example prompts against the user's last message (both truncated to 1,000 characters) and only the top-scoring tools are sent; if the reranker fails, every tool is sent.

Held by

server/utils/agents/aibitat/utils/toolReranker.js:125 (called at server/utils/agents/aibitat/index.js:928-931)

B15 Should this tool be turned on or off for the rest of this running agent session? RULING · human
Answered how

The person (in multi-user mode only an admin; in single-user mode anyone with the socket) toggles a tool in the chat UI; code resolves the identifier and loads or removes the tool, effective from the next turn.

Held by

role: admin (multi-user) or the single user; read at server/utils/agents/aibitat/plugins/websocket.js:197, applied by server/utils/agents/index.js:742

C. Choosing the next action (11 seats)

C1 Which tool, if any, does the agent call next (models with native tool calling)? RULING · llm
Answered how

the workspace's agent model, given the agent role, the chat history and the offered tool schemas, returns either text or a tool call; code keeps the first call and parses its arguments.

Held by

server/utils/agents/aibitat/providers/helpers/tooled.js:248 (OpenAI-compatible path; the agent model setting resolved by server/utils/agents/aibitat/index.js:954)

C2 Which function does the prompt-based selector pick (models without native tool calling)? RULING · llm
Answered how

a separate completion with a fixed "pick a function" system prompt and the conversation (user and assistant turns only) returns JSON naming one function and its arguments, or plain text.

Held by

server/utils/agents/aibitat/providers/helpers/untooled.js:161 (agent model setting)

C3 Is the selector's call a valid call of an offered function? RULE · code
Answered how

code checks the call has name and arguments, names an offered function, includes every required argument and no argument outside the schema.

Held by

server/utils/agents/aibitat/providers/helpers/untooled.js:83

C4 Does a model reply that contains JSON count as a tool call? RULING · code
Answered how

code tries strict JSON, then jsonrepair when the text starts with [ or {, then the first JSON object found anywhere in the text; any result is treated as an attempted call.

Held by

server/utils/agents/aibitat/providers/helpers/untooled.js:163 (logic in server/utils/http/index.js:78-97)

C5 Has the agent already made this exact call, so it should stop calling tools? RULING · code
Answered how

code hashes tool name plus arguments and refuses an exact repeat within one turn; MCP tools also get a 30-second name-level cooldown; a tool marked unique refuses a second call.

Held by

server/utils/agents/aibitat/utils/dedupe.js:57 (called at providers/helpers/untooled.js:173 and :247)

C6 Does this model get native tool calling or the prompt-based selector? RULING · code
Answered how

code decides per provider: some always native (OpenAI, Anthropic), some never (NVIDIA NIM, Perplexity), many ask the inference server for the model's "tools" capability, and an env list can force any provider tag to the selector.

Held by

server/utils/agents/aibitat/providers/ai-provider.js:231 (overrides e.g. providers/ollama.js:70, providers/nvidiaNim.js:42, providers/openai.js:51)

C8 A native tool call's arguments are not valid JSON (non-streaming): what happens? RULING · code
Answered how

code appends a "Failed to parse tool call arguments as JSON" tool message and asks the model again.

Held by

server/utils/agents/aibitat/providers/helpers/tooled.js:456 (re-ask at e.g. providers/groq.js:142; the same two lines appear in 31 provider files under providers/ plus server/utils/AiProviders/embeddedLemonade/agentProvider.js:204-205, grep retryWithError)

C9 A native tool call's arguments are not valid JSON (streaming): what happens? RULING · code
Answered how

code replaces the arguments with an empty object and runs the tool.

Held by

server/utils/agents/aibitat/providers/helpers/tooled.js:376 (same at anthropicTooled.js:257-260, responsesTooled.js:122, ai-provider.js:899-902)

C10 When the model asks for several tools at once, which run? RULING · code
Answered how

code runs only the first (lowest stream index; tool_calls[0] when not streaming) and drops the rest without telling the model.

Held by

server/utils/agents/aibitat/providers/helpers/tooled.js:372 (non-streaming :455)

C11 What does the assistant answer to this message in ordinary (non-agent) chat? RULING · llm
Answered how

The workspace's chat model writes the reply from the assembled messages (system prompt, history, retrieved context, the user's message), streamed or in one piece. The same call is made per channel: web chat, embed widget, developer API, OpenAI-compatible API and Telegram.

Held by

server/utils/chats/stream.js:326 (streaming; non-streaming :305; same call in chats/embed.js:203/:219, chats/apiChatHandler.js:453/:850/:869, chats/openaiCompatible.js:179/:449, telegramBot/chat/stream.js:276/:291)

D. Gatekeeping: may this action run? (36 seats)

D1 Should this tool call skip the person because the operator pre-approved the skill for everyone? RULE · code
Answered how

Code splits the AGENT_AUTO_APPROVED_SKILLS env list on commas and returns yes when the list holds <all> or the exact skill name; both approval channels call it first.

Held by

server/utils/helpers/agents.js:11, called at server/utils/agents/aibitat/plugins/websocket.js:227 and server/utils/agents/aibitat/plugins/http-socket.js:123

D2 Has this person already said "always allow" for this skill? RULE · code
Answered how

Code reads a JSON list of skill names from system_settings (per user in multi-user mode, one shared list otherwise) and returns yes when the name is in it.

Held by

server/models/agentSkillWhitelist.js:75; called at websocket.js:242 (with the session userId) and http-socket.js:133 (always with null)

D3 Should this tool action run right now? (web chat approval card) RULING · human
Answered how

The person in the chat sees a card (skill name, the tool's description line, a collapsed payload) and clicks approve or reject; the server waits on a websocket reply with the matching requestId.

Held by

server/utils/agents/aibitat/plugins/websocket.js:283 (the chat user's answer is read here; the request is sent at websocket.js:308-317)

D4 Should this skill be allowed without asking from now on? RULING · human
Answered how

The person ticks "Always allow" on the approval card and approves; the frontend posts the skill name and the server appends it to that user's (or the shared) whitelist.

Held by

the chat user; stored by server/endpoints/agentSkillWhitelist.js:86 (route :66-67, flexUserRoleValid(ROLES.all)), sent from ToolApprovalRequest/index.jsx:42-43

D5 When nobody answers an approval in time, or the session is stopped, does the action run? RULE · code
Answered how

Code: a timer (TOOL_CALL_APPROVAL_TIMEOUT_MS, default 120 000 ms) settles the wait as a denial on both channels; only the web channel also installs an abort listener, so stopping a web session denies at once, while a pending Telegram approval waits for its reply or the timer.

Held by

server/utils/agents/aibitat/plugins/websocket.js:319-330 (web) and http-socket.js:216-228 (Telegram) — consolidated

D6 When no person can be reached (developer API, mobile app, any non-Telegram HTTP agent run), does a gated tool run? RULE · code
Answered how

Code: after the env list and whitelist checks, the http-socket approval returns a denial unless a Telegram chat id and a worker IPC channel exist.

Held by

server/utils/agents/aibitat/plugins/http-socket.js:149

D10 In an unattended scheduled run, may each gated tool call go ahead? RULING · code
Answered how

Code: the scheduled-job worker overwrites the agent's approval function with one that always returns approved.

Held by

server/jobs/run-scheduled-job.js:77

D11 Should the agent be allowed to set up this recurring job (this prompt, schedule and tools)? RULING · human
Answered how

The person sees the standard approval card for create-scheduled-job, whose payload now carries name, local cron, prompt and tool list, and approves or rejects; only then is the job stored and registered with the scheduler.

Held by

the chat user; request at server/utils/agents/aibitat/plugins/create-scheduled-job/index.js:155

D12 Which tools may a newly created scheduled job be given? RULE · code
Answered how

On the agent path code rejects any tool id that is not in the "ready" catalog (configured, set up); on the settings-UI path the create endpoint only checks that a non-empty tools is an array, and the edit endpoint stores tools unchecked.

Held by

server/utils/agents/aibitat/plugins/create-scheduled-job/index.js:140 (agent path, with cronUtils.js:230 readyToolsCatalog)

D13 At run time, which tools does a scheduled run actually load? RULE · code
Answered how

Code replaces the agent's whole function list with the job's stored tools array and loads each name through the normal plugin loader, without re-reading which skills the admin currently has enabled.

Held by

server/utils/agents/ephemeral.js:598 (the override), fed by server/jobs/run-scheduled-job.js:70

D14 May a scheduled job run now? RULE · code
Answered how

Code: the scheduler skips a firing when the instance is in multi-user mode (and unregisters the job), when the job was edited since the timer was armed, or when a run is already in flight; an active-job cap exists but is unset.

Held by

server/utils/BackgroundWorkers/index.js:401 (with :279 at boot, :405, :407-409); cap at server/models/scheduledJob.js:188-191

D15 Who may switch an agent's tools on or off in the middle of a session? RULE · code
Answered how

Code: in single-user mode anyone on the socket; in multi-user mode only a user whose role is admin. A non-admin's toggle is claimed and silently ignored.

Held by

server/utils/agents/aibitat/plugins/websocket.js:15 (userCanToggleTools), applied at websocket.js:197

D16 May the agent be offered create-scheduled-job on this instance? RULE · code
Answered how

Code drops the skill from the list loaded at session start when the instance is in multi-user mode; a skill an admin switches on mid-chat is loaded without this check.

Held by

server/utils/agents/defaults.js:176 (set at :18)

D17 When a custom (imported) skill asks for approval, under which name does the request go out, and what happens if no channel exists? RULE · code
Answered how

Code wraps the platform approval in a closure that forces skillName to the skill's plugin.json name, and returns "approved" when the aibitat instance has no approval function. Asking at all is the skill author's choice.

Held by

server/utils/agents/imported.js:178 (createToolApprovalFn), bound at imported.js:243-246

D18 May this imported skill's code be loaded into the agent? RULE · code
Answered how

Code loads handler.js only from a folder inside storage/plugins/agent-skills; a chat session lists a custom skill only when its plugin.json says active: true (hub imports are written active: false), but a scheduled job's stored @@hubId and an admin's mid-session toggle load it with no active check.

Held by

server/utils/agents/imported.js:78 (active filter), with path containment at imported.js:20 and :47, and the import-time reset at imported.js:345

D19 May this Community Hub item be downloaded and imported? RULE · code
Answered how

Code refuses unless COMMUNITY_HUB_BUNDLE_DOWNLOADS_ENABLED is set; then it allows items the hub marks verified or private, and everything when the variable is allow_all. The trust judgment itself is the hub's verified flag.

Held by

server/utils/middleware/communityHubDownloadsEnabled.js:34 (env gate :23), route server/endpoints/communityHub.js:131-137 (admin only, :134)

D20 What environment, and so which secrets, does a local MCP server process receive? RULING · code
Answered how

Code builds the child's environment from the whole server process.env (via patchShellEnvironmentPath, which returns process.env on every path) plus PATH/NODE_PATH defaults, then lays the server's own env block on top.

Held by

server/utils/MCP/hypervisor/index.js:311 (in #buildMCPServerENV, :300-337); server/utils/helpers/shell.js:10, :16, :19

D21 May this MCP tool call run? RULING · code
Answered how

Code runs it: once a server's tools are loaded (minus any the admin suppressed), each call goes straight to callTool with the model's arguments; nothing asks a person.

Held by

server/utils/MCP/index.js:94

D22 May this SQL statement run against the connected database? RULE · external
Answered how

The database account the admin configured decides; the tool asks the model for read-only SELECTs in its description and then runs whatever string it gets.

Held by

server/utils/agents/aibitat/plugins/sql-agent/query.js:81 (raw pass-through to Postgresql.js:35, MySQL.js:43, MSSQL.js:77)

D23 May an agent flow's API-call step send this request? RULING · code
Answered how

Code sends it: the step fetches the configured URL with method, headers and body (after the flow substitutes variables, some set by the model); no URL guard and no approval.

Held by

server/utils/agentFlows/executors/api-call.js:46

D24 May the collector fetch this URL for the agent? RULE · code
Answered how

Code accepts http/https and rejects only literal IPv4 hosts whose first octet is 10, 127, 169, 172 or 192 (allowing 127.0.0.1 and 0.0.0.0), unless the admin turned the check off.

Held by

collector/utils/url/index.js:64 (with isInvalidIp :27-54); reached from the agent's web-scraping via CollectorApi().getLinkContent(url) (server/utils/agents/aibitat/plugins/web-scraping.js:102) → collector/processLink/index.js:42-43

D25 Is this file path inside the folder the filesystem agent may touch? RULE · code
Answered how

Code resolves the path (relative paths against the allowed root), checks it is under STORAGE_DIR/anythingllm-fs, then re-checks the real path (symlinks) or, for a new file, the real parent.

Held by

server/utils/agents/aibitat/plugins/filesystem/lib.js:412 (validatePath), decision at :425

D26 Which local files may be attached to an outgoing email? RULE · code
Answered how

Code accepts any absolute path to an existing non-empty file the server can read (refused entirely in Docker), up to 20 MB in total for Gmail and 25 MB for Outlook; for each attachment it calls the installed approval check, which may ask the person or answer automatically.

Held by

server/utils/agents/aibitat/plugins/gmail/lib.js:18 and the copy server/utils/agents/aibitat/plugins/outlook/lib.js:221 — consolidated

D27 After the first three sections of a long document, should summarizing continue? RULING · human
Answered how

Code calls the installed approval check once (skill name content-summarization, sections remaining), which may ask the person or answer automatically; approving runs to the end, rejecting stops, and with no approval check installed summarizing simply continues.

Held by

the installed approval check (the person, or an automatic answer); called at server/utils/agents/aibitat/utils/summarize.js:145 (CHUNKS_BEFORE_APPROVAL = 3, :33)

D28 May this request reach a chat or agent endpoint at all? RULE · code
Answered how

Code: in multi-user mode a valid JWT for an existing, non-suspended user is required; in single-user mode a valid password JWT is required only when both AUTH_TOKEN and JWT_SECRET are set (and never in development).

Held by

server/utils/middleware/validatedRequest.js:8

D29 Does this user's role allow this route? RULE · code
Answered how

Code: when multi-user mode is on, the user's role must be in the route's list; when it is off, every caller passes (flexUserRoleValid); isSingleUserMode refuses every caller in multi-user mode.

Held by

server/utils/middleware/multiUserProtected.js:58 (flexUserRoleValid), with :16 (isSingleUserMode) and :29 (strictMultiUserRoleValid) — consolidated

D30 May this user use this workspace (chat, agent, mobile)? RULE · code
Answered how

Code: admins and managers see every workspace; default users only workspaces they are a member of; single-user mode looks the workspace up by slug with no membership check.

Held by

server/models/workspace.js:294 (getWithUser), applied at server/utils/middleware/validWorkspace.js:9-11 and :26-28, and in server/endpoints/mobile/utils/index.js:155-157 (and the other mobile commands) — consolidated

D32 May this socket join and drive this agent session? RULE · code
Answered how

Code accepts any websocket that names an existing, not-closed invocation UUID; the route itself has no auth middleware.

Held by

server/utils/agents/index.js:561 (#validInvocation), route server/endpoints/agentWebsocket.js:28

D33 May this embedded-widget request be answered? RULE · code
Answered how

Code: the embed must be enabled, the request's Origin header must be on the embed's allowlist (or the allowlist empty, unless EMBED_REQUIRE_ALLOWLIST is set), the session id must be a UUID, and per-embed and per-session 24-hour counts must be under their caps.

Held by

server/utils/middleware/embedMiddleware.js:43 (canRespond)

D34 May this mobile device use the instance? RULE · code
Answered how

Code requires the x-anythingllm-mobile-device-token header to match a stored device that an admin has marked approved, and its user (if any) not suspended.

Held by

server/endpoints/mobile/middleware/index.js:12 (validDeviceToken), decision at :24

D35 Should this mobile device be approved? RULING · human
Answered how

An admin flips approved on the device in Settings.

Held by

admin, via server/endpoints/mobile/index.js:46 (route :40-42, flexUserRoleValid([ROLES.admin]))

D36 May this API key reach the developer API (chat, agent and OpenAI-compatible routes)? RULE · code
Answered how

Code: the second space-delimited field of the Authorization header must match a stored API key (:8-9, :17); the scheme is not checked, and there is no user, role or workspace check at this gate (claims1 C5).

Held by

server/utils/middleware/validApiKey.js:4 (refusals :10-15, :17-22; applied as [validApiKey] at e.g. server/endpoints/api/workspace/index.js:605, :739, server/endpoints/api/workspaceThread/index.js:331, :488, server/endpoints/api/openai/index.js:78)

E. Execution and observation (20 seats)

E2 On Anthropic models, what does an empty tool result say? RULING · code
Answered how

code replaces an empty or falsy result with the text "Tool executed successfully." and silently drops a tool result that has no matching tool_use block before it.

Held by

server/utils/agents/aibitat/providers/helpers/anthropicTooled.js:55 (copy at server/utils/agents/aibitat/providers/anthropic.js:156)

E3 Does a long web page or document go to the model whole, or summarized? RULING · code
Answered how

code counts the content's tokens and returns it whole when it is under the model's FULL context window; otherwise it summarizes it. An agent-flow web-scraping step with summarization turned off returns the content whole at any length.

Held by

server/utils/agents/aibitat/plugins/web-scraping.js:124 (copies: plugins/summarize.js:151, server/utils/agentFlows/executors/web-scraping.js:56)

E4 What are the key points of a document too long to read whole? RULING · llm
Answered how

a model reads the content in chunks of 45% of the context window, listing bullet points per chunk with the last 5% of earlier points as context; before the fourth chunk it calls the installed approval check, which may ask the person or answer automatically, on whether to continue.

Held by

server/utils/agents/aibitat/utils/summarize.js:174 (the workspace agent model, via getLLMProvider, :124-127)

E5 How much of a file the agent reads reaches the model? RULING · code
Answered how

code keeps the head of the content up to 75% of the model's context window, cut at the last line break when one falls in the final fifth of that span (otherwise at the estimated character position), and appends a note telling the model to read smaller portions.

Held by

server/utils/agents/aibitat/plugins/filesystem/lib.js:708 (ratio lib.js:14; callers filesystem/read-text-file.js:108, read-multiple-files.js:122, search-files.js:451)

E6 Which lines does a file edit replace when the old text is not found exactly? RULING · code
Answered how

code replaces the first exact occurrence; failing that, the first block of lines that matches after trimming whitespace on each line, re-indenting the first new line to the match (later lines are re-indented only when both their old and new text carry indentation).

Held by

server/utils/agents/aibitat/plugins/filesystem/lib.js:560

E7 What search results does the agent see? RULING · external
Answered how

the search engine an admin chose (default: You.com's keyless tier, falling back to DuckDuckGo on any failure) ranks results; code keeps each engine's top results (mostly 10) as JSON.

Held by

server/utils/agents/aibitat/plugins/web-browsing.js:128

E8 What does the agent get back from a SQL query? RULING · code
Answered how

code runs the model's SQL text on the named connection and returns every row as JSON, or the database's error text.

Held by

server/utils/agents/aibitat/plugins/sql-agent/query.js:81

E9 What does the model see of an MCP tool's result? RULING · code
Answered how

code returns joined text blocks as-is, the full envelope for errors, structuredContent when there are no blocks, and the whole result JSON (images included as base64 text) otherwise.

Held by

server/utils/MCP/index.js:261

E10 What does the model get back from an agent flow? RULING · code
Answered how

On success, code returns the direct-output value when a step set a truthy one; otherwise the whole run record as JSON: every step result and EVERY flow variable, including "static" ones. A failed flow returns only a fixed "Flow execution failed" sentence with the last error.

Held by

server/utils/agentFlows/index.js:294

E11 Does a flow keep going after a step fails? RULE · code
Answered how

code runs steps in order and stops at the first step that throws, or at the first step marked direct output.

Held by

server/utils/agentFlows/executor.js:242

E12 How are earlier results and the model's arguments spliced into a flow step? RULE · code
Answered how

code replaces each ${path} with the variable's value (JSON-stringified for objects), escaping it when an odd count of unescaped quotes precedes it in a JSON body, and leaves unknown placeholders literally.

Held by

server/utils/agentFlows/executor.js:142

E13 What does a flow's LLM-instruction step answer? RULING · llm
Answered how

the workspace agent model answers the admin's instruction text (with variables filled in) as a single user message, with no tools; the text becomes a variable for later steps.

Held by

server/utils/agentFlows/executors/llm-instruction.js:29 (non-streaming :35)

E14 What does a flow's API-call step hand to the next step? RULE · code
Answered how

code sends the admin-configured request and returns the response parsed as JSON when it parses, otherwise the raw text; a non-2xx status throws.

Held by

server/utils/agentFlows/executors/api-call.js:59

E16 May the agent draw more than one chart in a reply, and what is it told? RULE · code
Answered how

code renders the first chart and marks the tool unique; any further chart call in the same reply is refused but told "The chart was generated and returned to the user."

Held by

server/utils/agents/aibitat/plugins/rechart.js:63

E18 What does a mail or calendar connector do and send back? RULE · external
Answered how

the person's Google Apps Script deployment (Gmail, Google Calendar) or Microsoft Graph (Outlook) performs the action; code returns a success summary or the service's error text, and returns message and event bodies to the model as data.

Held by

server/utils/agents/aibitat/plugins/gmail/lib.js:346 (copies of the shape: google-calendar/lib.js:142, outlook/lib.js:906)

E19 What does the person answer when the agent asks a clarifying question? RULING · human
Answered how

the person fills in a form card (free text or choices) or skips; after 2 minutes with no engagement (15 once they start typing) the agent is told to "proceed using your best judgment".

Held by

the chat user, through server/utils/agents/aibitat/plugins/websocket.js:348 (tool plugins/request-user-input.js:243)

E20 What does an imported custom skill do and return? RULING · external
Answered how

the skill's own handler.js (community-hub download or user-written) runs with the model's arguments; whatever it returns is passed back as the tool result unchanged, after which a model provider's adapter may transform it (Anthropic's replaces any falsy result with a success sentence).

Held by

server/utils/agents/imported.js:238

E21 Which workspace document did the model mean by this filename? RULE · code
Answered how

code lists the workspace's documents and takes the one whose stored title equals the model's filename exactly.

Held by

server/utils/agents/aibitat/plugins/summarize.js:115

F. Limits and memory (13 seats)

F2 Has the conversation between the person and the agent reached its message cap, so the session must end? RULE · code
Answered how

Code counts successful messages between the two nodes in the in-memory history and terminates the session once the count reaches maxRounds.

Held by

server/utils/agents/aibitat/index.js:833 (count), applied at :676-680 after every reply and at :1354-1356 in continue()

F6 Should the memory skill refuse a search or store whose exact text it has already handled in this agent session? RULING · code
Answered how

Code: the memory plugin keeps its own Deduplicator and refuses an exact repeat of {action, content} for the life of the agent session, returning a refusal string instead of results.

Held by

server/utils/agents/aibitat/plugins/memory.js:71 (check :66-71), tracker created once at :19, recorded at :77

F8 When the agent finishes a reply, what is written to the workspace's chat record, and what is dropped? RULING · code
Answered how

Code saves the person's prompt and the agent's final text with sources, file outputs, clarifying-question answers and usage metrics; intermediate tool calls and results are not saved; if the session was aborted the final record is skipped (the prompt was already written as a hidden placeholder row).

Held by

server/utils/agents/aibitat/plugins/chat-history.js:107-122 (_store), :143-162 (_storeSpecial, used when a skill sets _replySpecialAttributes, e.g. charts plugins/rechart.js:85-95); abort skip at :64; regenerate pruning at :35-47

F9 Does the person want the conversation so far dropped from what the assistant carries forward? RULING · human
Answered how

The person types /reset in chat (or uses Telegram's reset or the API reset); the server marks that workspace or thread's chats include: false, which removes them from later history windows and from memory extraction.

Held by

server/utils/chats/commands/reset.js:17 (command resetMemory, :3-17), routed from server/utils/chats/index.js:10; Telegram server/utils/telegramBot/utils/commands/handlers/handleReset.js:19; API server/utils/chats/apiChatHandler.js:157

F10 Is this person's recent conversation in this workspace ready for automatic memory extraction, and once looked at, is it finished with for good? RULING · code
Answered how

A background job every 3 hours groups unprocessed visible chats by user and workspace, skips a group with fewer than 5 chats or any chat in the last 20 minutes, skips a group already at both memory caps, and otherwise runs the model passes on the latest 20 chats (stopping early if the workspace, chats or model are missing, or the first pass finds nothing); every group that got past the first two checks is then marked processed, whatever happened.

Held by

server/jobs/extract-memories.js:181 (mark processed, in processGroup :65-183): thresholds at :18-23, size check :69, idle check :76/:189-192, capacity check :107-114, mark-processed :180-182; window server/jobs/helpers/memory-extraction-utils.js:83-95 (loadLatestChats, 20 chats) and :114-128 (1,500 characters per message); schedule server/utils/BackgroundWorkers/index.js:47-52

F11 From the person's recent conversations, which facts about them would help future answers? RULING · llm
Answered how

A language model (the workspace's chat model) reads up to 20 recent exchanges and is asked to call a submit-observations tool with at most three one-sentence facts, each tagged high, medium or low confidence; if it calls the tool, code keeps well-formed items and the first three.

Held by

server/jobs/helpers/memory-extraction-utils.js:135-216 (runObserver); model from resolveLLM :101-110

F12 Of the candidate facts, which are new and worth keeping, which update an existing memory, and does each belong to this workspace or to the person everywhere? RULING · llm
Answered how

A second model call reads the candidates and every existing global and workspace memory with ids, and is asked to call save-memories with up to three items, each scoped WORKSPACE or GLOBAL and marked create, update (with an id) or skip; if it does, code drops skips and malformed items, then applies creates within the memory caps and updates only to the person's own matching memories.

Held by

server/jobs/helpers/memory-extraction-utils.js:263-356 (runReflector); applied by server/models/memory.js:345-440 (applyExtractedMemories)

F13 How many global and per-workspace memories may a person have, and what happens to new ones past the cap? RULE · code
Answered how

Code caps global memories at 5 and workspace memories at 20 per person; extraction only offers the Reflector the free global slots and drops creates past either cap; manual creates and promotions return an error message at the cap.

Held by

server/models/memory.js:375 (extraction slots, :375-385), :23-25 (limits), :107-109 (manual create), :190-194 and :231-235 (promote/demote); server/jobs/extract-memories.js:107-114 (skip a full group)

F14 During an agent run, should something be stored as long-term memory, and what exactly? RULING · llm
Answered how

The agent model decides by calling the rag-memory skill with action: "store" and the text; code embeds that text as a new document in the workspace's vector namespace, where every later search of that workspace can retrieve it.

Held by

server/utils/agents/aibitat/plugins/memory.js:75 (dispatch), :126-160 (store); skill on by default (server/utils/agents/defaults.js:10-15)

F15 How long may an unattended scheduled agent run go on before it is recorded as timed out? RULE · code
Answered how

Code races the agent run against a timer (5 minutes unless SCHEDULED_JOB_TIMEOUT_MS is set); if the timer wins, the run is recorded as timed out and the worker concludes.

Held by

server/jobs/run-scheduled-job.js:102 (race :98-110), limit at server/jobs/helpers/scheduled-job-helper.js:8-9; concurrency server/utils/BackgroundWorkers/index.js:20-22

G. Judging the result (5 seats)

G1 Has the agent finished working on the person's message, so its text goes back as the answer? RULING · llm
Answered how

The agent model decides: the first completion that comes back without a tool call ends the loop, and its text is the reply. Code adds one literal check: a reply that is exactly TERMINATE ends the whole session.

Held by

server/utils/agents/aibitat/index.js:1056 (streaming: no functionCall means done, text returned at :1168-1176); :1223 and :1324-1331 (non-streaming); :676 (literal TERMINATE)

G2 Did the model stop because it ran out of output tokens rather than because it finished? RULE · code
Answered how

Code watches each completion or stream for the provider's "length" / "max_tokens" stop reason and sets a truncated flag on the run's usage metrics, which the interface uses to say why the reply stopped.

Held by

server/utils/agents/aibitat/providers/ai-provider.js:818 (agent side, in watchTokenLimit :816-819, reported by getCumulativeUsage :834-839); detector server/utils/helpers/chat/LLMPerformanceMonitor.js:33-82 (hitTokenLimit, watchTokenLimit); plain chat side LLMPerformanceMonitor.js:147

G3 Did this unattended scheduled agent run succeed, fail or time out? RULE · code
Answered how

Code marks the run "success" whenever the agent run resolves before the timer, stores the last agent text with thoughts and tool calls, and sends a push notification; it marks "failed" only when something throws.

Held by

server/jobs/run-scheduled-job.js:117-129 (success), :130-152 (failed / timed out / not found)

G4 Having read a scheduled run's result, does the person accept it, carry it on in a chat, or stop a run still going? RULING · human
Answered how

The person opens the run, marks it read, continues it into a new thread in a "Scheduled Jobs" workspace (the stored text, sources and outputs become the first exchange), or kills a queued or running run.

Held by

server/endpoints/scheduledJobs.js:70 (route /scheduled-jobs/runs/:runId/:action, :63-112, single-user mode only via isSingleUserMode at :65); server/models/scheduledJobRun.js:329-384 (continueInThread)

G5 Did the presentation section builder return slides, or should the deck use a stub section instead? RULE · code
Answered how

Code takes the slides the child agent submitted through its tool; if the child threw, or submitted nothing or an empty array, it substitutes a fallback of a section divider plus the section's key points.

Held by

server/utils/agents/aibitat/plugins/create-files/pptx/section-agent.js:189 (accept-or-fallback :179-194); fallback builder :236-255

H. Delegation (0 seats)

This map records no seats in this stage.

I. Learning and feedback (3 seats)

I1 Does the person mark this answer as good? RULING · human
Answered how

The person clicks the thumbs-up on a reply (clicking it again clears the rating); the server checks the chat belongs to them in this workspace and stores the score on the chat row. The server also accepts false, but the pinned UI renders no thumbs-down.

Held by

server/endpoints/workspaces.js:587 (route handler :575-590); stored by server/models/workspaceChats.js:268-283 (updateFeedbackScore)

I2 Should a stored memory about the person be kept, corrected, deleted, made global, or moved back to one workspace? RULING · human
Answered how

The person edits memories in the interface; the server lets them list, add, edit, delete, promote to global or demote to a workspace, scoped to their own memories in multi-user mode.

Held by

server/endpoints/memory.js:112 (edit, route :100-123); create :84, delete :136, promote :156, demote :181; ownership check :22-39

I3 When an admin exports chats in a fine-tuning format, which conversations go in? RULING · code
Answered how

Code exports every workspace chat (or every embed chat) in id order, with the workspace's system prompt and each prompt/response pair, in JSONL ("recommended for fine-tuning") or Alpaca form; it does not filter by thumbs rating or by /reset visibility.

Held by

server/utils/helpers/chat/convertTo.js:53 (query, in prepareChatsForExport :47-213); JSONL shape :158-212; Alpaca :142-156

How this map was made

Four readers each took a part of the system and wrote seat cards from the source. Four other readers, none re-reading its own part, then re-read every seat that existed at that stage against the cited lines and corrected what the source did not support; the map's author later added two seats and ruled on the cards they proposed to merge. One review by a model from another family (read-only, at the same commit) checked the seat data, and a claims pass checked the corrections it led to; each finding was checked against the code before anything changed. A checker confirms that each seat's holder line exists at the pinned commit and carries its anchor text. Nothing on this page was produced by running their code.