> ## Documentation Index
> Fetch the complete documentation index at: https://user-docs.olyrosstudios.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Agents

> An agent is an assistant you set up once with a name, instructions and a personality, powered by your own account with an AI provider of your choice.

An agent is a named assistant a company configures once and talks to from the web
chat and from Slack: a persona and system prompt, a default LLM provider and model
backed by the company's own API key, a set of tools, knowledge documents, memories that
accumulate across conversations, and a list of who may use it. Agents live
in the client app under the **Agents** sidebar group as **Agents** (`/agents`): a list,
a builder (`/agents/new`, `/agents/:agentId/edit`), the chat (`/agents/:agentId/chat`)
and a detail shell with the tabs `overview`, `access`, `instructions`, `knowledge`,
`memory`, `tools`, `mcp-servers`, `skills`, `slack` and `versions`. Company tools have
their own pages under **Tools** (`/tools`). This page covers the in-server chat agent;
long-lived sandboxed agents (`sandbox_type` set) are in [Sandboxes](https://user-docs.olyrosstudios.com/sandboxes.md), one-shot
task execution in [Cloud tasks and executors](https://user-docs.olyrosstudios.com/cloud-tasks-and-executors.md).

## What it does

**Defines the agent.** `createAgent` takes a name (slug derived or given, unique per
company), description, avatar, `personaConfig`, `systemPrompt`, `defaultProvider`,
`defaultModel`, `defaultIntegrationId` and optional default executor and environment for
tasks. The persona is rendered into the prompt from four keys: `tone`, `verbosity`
(`terse`, `balanced`, `detailed`), `expertise` (list) and `approach` (`react`,
`plan-and-execute`, `reflection`). A new agent starts `active` with version 1 published
to `production`, and every active built-in tool is bound to it automatically.

**Runs on the company's LLM key.** Each turn resolves credentials from the integration
named by `defaultIntegrationId`, else the first active integration whose provider slug
equals `defaultProvider` (`anthropic`, `openai`, `google`, `mistral`, `cohere`,
`deepseek`, `bedrock`; see [Generic and provider integrations](https://user-docs.olyrosstudios.com/generic-integration.md)).
Optional `temperature` (0.0 to 2.0) is passed through. The billing gate runs before each
model call. Every interaction is stamped `llm_key_source = byo`; no Olyros-provided key
path exists yet.

**Keeps a version history.** Every `updateAgent` save writes a new `AgentVersion`
(`published_env = draft`) with optional `changeNotes`. `publishAgentVersion(targetEnv)`
sets the latest version to `draft`, `staging` or `production`; publishing to
`production` moves a `draft` or `paused` agent to `active`, demoting to `draft` moves an
`active` agent back to `draft`. `archiveAgent` hides the agent; `restoreAgent` returns
it to `active` when a production version exists, else `draft`. Status values:
`draft`, `active`, `paused`, `archived`; only `active` and `draft` agents can chat.

**Tools in three types** (`Tool.tool_type`): `built_in` (platform-wide, `company_id`
null, seeded on startup), `http_api` (a company-defined outbound HTTP call) and
`custom_code` (a company script run in the skill sandbox). A tool is offered to the
model only through an active `AgentTool` binding, filtered by environment: the binding's
`environmentOverrides`, else the tool's `allowedEnvironments`, else everywhere (`web_chat`,
`slack`, `api`, `github_action`, `container`). Tool names starting with `mcp__` are
reserved for [MCP servers](https://user-docs.olyrosstudios.com/mcp-servers.md). Built-ins today:

| Built-in tool | What it does |
| - | - |
| `olyros_get_time` | Current date and time in an IANA timezone. |
| `olyros_search_knowledge` | Hybrid search over the agent's indexed knowledge (top 5). |
| `olyros_store_memory` | Saves a memory (`memory_type`, importance default 0.7, source `tool_call`). |
| `olyros_search_content`, `olyros_propose_source` | Search ingested content and propose sources for monitoring (content domain). |
| `olyros_web_search` | Google search grounding; only honoured on the `google` provider, stripped elsewhere. |
| `olyros_list_workflow_capabilities`, `olyros_trigger_workflow` | List and start discoverable [workflows](https://user-docs.olyrosstudios.com/workflows.md). |
| `olyros_list_mcp_connections`, `olyros_disconnect_mcp_server` | The user's own MCP connections. |
| `olyros_ask_user`, `olyros_get_ask_user_instructions` | Structured question to the person (HITL, below). |
| `olyros_skill_read`, `olyros_skill_run` | Added at run time when the agent has model-invocable [skills](https://user-docs.olyrosstudios.com/skills.md). |

An `http_api` tool stores `execution_config` with a URL, method, headers and body
templates; `{{argument}}` placeholders are filled from the model's arguments, the URL and
headers are validated against the safe-HTTP rules on save, responses are truncated to
4000 characters and the default timeout is 10 s. Auth can come from an integration
(`resolve_integration_auth`). A `custom_code` tool holds `runtime` (`python3.12` or
`node22`), `entrypoint` and `files`; arguments arrive as `/work/in/arguments.json` and
stdout is the result. `requiresApproval` is stored on every tool; see Known gaps for
what it does today.

**Knowledge documents.** Items (`title`, `contentType` in `markdown`, `json`, `yaml`,
`code`, `qa_pair`, `pdf`; inline `content` up to 500 KB) are chunked (500 tokens, 100
overlap) and embedded with the company's embedding integration (Settings -> Memory,
`/settings/memory`). Each item carries `indexingStatus` `pending`, `indexing`, `indexed`
or `failed`, `chunkCount` and `indexingError`; `reindexKnowledgeItem` retries. At chat
time, if any chunk is indexed, semantic plus keyword search (reciprocal rank fusion,
15 candidates) is reranked to 5 chunks and injected with `[Source: title, section n]`
citations; with nothing indexed, items are injected whole in `sortOrder`. The `done`
event lists the `knowledge_sources` used.

**Memories.** Types: `learned_preference`, `episodic`, `user_specific`, `team`,
`procedural`; each has `importance` (0.0 to 1.0), `isPinned`, `expiresAt`, `accessCount`
and provenance (`sourceEnv`, `sourceUserId`, `sourceInteractionId`). Three writers: the
`olyros_store_memory` tool, the Memory tab (`createMemory`, source `manual`), and
automatic post-turn extraction, a second LLM call that runs after the `done` event and
is on only when both the agent's `memoryExtractionEnabled` and the company-wide switch
are on. A new memory whose embedding is at least `memoryDedupThreshold` (default 0.95)
similar to an existing one overwrites that memory instead of adding a row. Retrieval
(`memoryRetrievalEnabled`) injects every pinned memory plus the top 10 unexpired
memories scored 0.4 similarity + 0.3 recency (30-day decay) + 0.2 importance + 0.1
access frequency.

**Access control.** An agent's Access tab lists who may chat with it: Olyros users, Slack
users and Slack groups (`access.olyrosUserIds`, `slackUserIds`, `slackGroupIds`). **No
grants at all means everyone; any grant means only the listed people and groups, in web
chat and on Slack alike.** A Slack user is also admitted when linked to a listed Olyros
user who is still an active member, and a member is admitted on the web when their linked
Slack identity is listed or in a listed group. System actors (workflow, schedule, webhook)
are never checked and there is no admin bypass. `AgentType.myAbilities` (`["agent.chat"]`
or `[]`) tells the caller; a denied caller gets the same `error` event as an agent that
cannot chat. Slack user and group management is on the [Slack](https://user-docs.olyrosstudios.com/slack.md) page.

Agent access is the one-ability case (`agent.chat`, shown as **Chat**) of the access
model that [workflows](https://user-docs.olyrosstudios.com/workflows.md#access) use for Run and View: the same subjects and the
same rule. Slack users in a grant are keyed by workspace and user id, so the same Slack id
in another workspace does not match. Editors and admins hold the class-scoped
`agent.manage` ability (`me.abilities`) that gates the Access tab; the roles table is on
[Company settings](https://user-docs.olyrosstudios.com/company-settings.md).

**Web chat.** `GET /api/agents/{agent_id}/chat/stream?session_id&message` streams
Server-Sent Events: `thinking`, `token`, `tool_start`, `tool_progress`, `tool_result`,
`hitl_request`, `error` and `done` (interaction id, tokens, cost, memories and knowledge
used, tool calls, `hitl_request_id`, skills used). The session id is chosen by the
client; history is the last interaction of that session, trimmed to its budget. Each
turn is an `AgentInteraction` row written at start and finalised at the end with
messages, tool calls, tokens, cost, actor attribution and cost tags.
`agentConversations` / `agentConversation` list past sessions; `submitFeedback` stores a
thumbs up or down with a comment on an interaction. Slack turns run the same executor
with `environment_type = slack`.

**Structured questions to the person (HITL).** With `olyros_ask_user` bound, the agent
asks one `single_choice` (2 to 10 options, optional free text), `confirm` or `free_text`
question; the turn suspends, later tool calls in the same batch are skipped, and the
question is rendered as a card in the web chat (`hitl_request` event, re-mounted on
reload via `hitlRequests`) or as a Slack Block Kit message. The answer comes back on the
same SSE endpoint, either as a card click (`hitl_request_id`, `hitl_value`) or as typed
text parsed against the options; typed text that is not an answer cancels the question
(`not_an_answer`). Only the person asked may answer; one `pending` question per session
(a newer one supersedes). Statuses: `pending`, `answered`, `expired`, `cancelled`,
`delivery_failed`. Requester kinds written today: `server_agent` (this page),
`sandbox_agent` (see [Sandboxes](https://user-docs.olyrosstudios.com/sandboxes.md), answered with `answerHitlRequest`).

**Default repositories for tasks.** `setAgentDefaultRepositories` attaches GitHub
repositories (access level, branch, `/workspace/<name>` mount path, one working
directory) that tasks created for the agent inherit ([Cloud tasks and executors](https://user-docs.olyrosstudios.com/cloud-tasks-and-executors.md)).

## Who can use it

* Create, edit, archive, restore, publish versions, manage knowledge and memories,
  bind or unbind tools, chat, read conversations, submit feedback, answer questions:
  **any company member** (membership only).
* Edit the access lists (`setAgentAccess`): **editor or admin** (`agent.manage`); each change writes an `agent.access_updated` audit event.
* Create a tool: **editor or admin** for `built_in` and `custom_code`, **company admin**
  for `http_api`; `updateTool` and `deleteTool` are editor or admin, and admin again when
  the tool is `http_api`. `testTool` is editor or admin.
* Agent creation runs a per-tenant `max_agents` entitlement check; today it only logs
  when over the cap and still creates the agent. No other plan or tier gate exists.

## How to configure it

1. **Prerequisite:** an active LLM integration for the provider (Integrations), and for
   knowledge or memories an embedding integration under Settings -> Memory
   (`updateCompanySettings`), which also holds the company-wide extraction switch,
   extraction model and `ragRerankingEnabled`.
2. **Create** the agent (Agents -> New): `createAgent(name, systemPrompt, personaConfig,
   defaultProvider, defaultModel, defaultIntegrationId, ...)`. The slug must be non-empty
   and unique; a default executor or environment must belong to the company.
3. **Tune** in the builder: `updateAgent(... temperature, maxToolIterations,
   skillCallTimeoutS, skillTurnBudgetS, memoryDedupThreshold, memoryExtractionEnabled,
   memoryRetrievalEnabled, changeNotes)`. Values above the platform ceilings are clamped,
   not rejected; `agentRuntimeLimits` returns the ceilings for the form.
4. **Tools** tab: `bindToolToAgent`, `unbindToolFromAgent`,
   `updateToolBindingEnvironments`. Company tools are made under Tools (`createTool`,
   `updateTool`, `deleteTool`, `testTool`); `testTool` on an `http_api` tool is limited to
   60 calls per company per hour.
5. **Knowledge** tab: `createKnowledgeItem`, `updateKnowledgeItem` (a content change bumps
   `version` and re-indexes), `reorderKnowledgeItems`, `deleteKnowledgeItem`,
   `reindexKnowledgeItem`.
6. **Memory** tab: `createMemory`, `updateMemory`, `pinMemory`, `unpinMemory`,
   `expireMemory`, `deleteMemory`, `deleteMemories`; `setAgentMemorySettings` flips the two
   switches without creating a version.
7. **Access** tab: `setAgentAccess(userIds, slackUserIds, slackGroupIds)`; `null` leaves
   a list unchanged, users must be company members, Slack ids must match `U…`/`W…`, groups
   must exist. Ids not yet in the Slack cache are saved with a warning.
8. **Versions** tab: `publishAgentVersion(agentId, targetEnv)`; **Overview** toggles
   status through `updateAgent(status)`.
9. **Chat** at `/agents/:agentId/chat`; connect Slack from the **Slack** tab
   ([Slack](https://user-docs.olyrosstudios.com/slack.md)).

## Limits and defaults

| Setting | Default | Where enforced |
| - | - | - |
| `status` on create | `active`, version 1 `published_env = production` | `createAgent` |
| `maxToolIterations` | 10; platform ceiling 300 (hard cap 1000) | clamped on save and at run time |
| `skillCallTimeoutS` / `skillTurnBudgetS` | 90 s / 240 s; ceilings 120 s / 270 s (hard caps 300 / 600) | same |
| `temperature` | unset; 0.0 to 2.0 | `updateAgent` |
| `memoryDedupThreshold` | 0.95; 0.70 to 1.00 | `updateAgent`, `store_memory` |
| `memoryExtractionEnabled`, `memoryRetrievalEnabled` | on | executor, context assembly |
| Context budget | 128k tokens: 10% system, 30% knowledge, 35% history, 15% memories | `assemble_context` |
| Knowledge item content | 500 KB; chunks 500 tokens, 100 overlap | `createKnowledgeItem`, `chunk_document` |
| Knowledge retrieval | 15 candidates, reranked to 5 | `assemble_context` |
| Memory retrieval | all pinned + top 10 | `retrieve_memories` |
| `agentMemories` page / `deleteMemories` batch | at most 200 / 500 | resolvers |
| Access list size | 1000 ids per list | `apply_agent_access` |
| HITL question lifetime | 24 h; 60 s to 7 d | `clamp_timeout`; `hitl-expire-sweep` every 60 s |
| HITL options | 2 to 10; title 150 chars | question schema |
| `http_api` response / timeout | 4000 chars / 10 s | HTTP tool executor |
| `testTool` on `http_api` | 60 per company per hour | per-company rate limit |
| `max_agents` entitlement | per tenant; logs only today | structural billing gate on `createAgent` |

## What it emits

* `AgentInteraction` rows per turn (messages, tool calls, tokens, `cost_usd`, provider
  and model, `agent_version_id`, actor, tags, `environment_type`): the basis of usage
  and cost reporting and of the conversations list.
* `AgentMemory` rows from tools, manual entry and extraction; `AgentKnowledgeChunk` rows
  from indexing; `HitlRequest` rows for every structured question with answer and answerer.
* Audit events `agent.access_updated` (before and after lists) and
  `tool.skill_code_enabled.updated`; HTTP tool calls are recorded by the tool bridge audit.
* SSE events to the chat client, including `mcp_auth_required` when an MCP server needs
  the user's connection.

## Known gaps

* `requiresApproval` has no approval step: an `http_api` tool flagged this way runs
  immediately (the flag only classifies the call as a write for audit), and a
  `custom_code` tool flagged this way is refused at run time.
* Versions are history, not what runs: the executor always uses the live agent row,
  `publishAgentVersion` acts only on the latest version, there is no rollback to an
  earlier version, and `staging` has no runtime effect.
* Memories are shared across everyone who talks to the agent, including `user_specific`
  ones; retrieval never filters by user. Dedup overwrites the matched memory regardless
  of its type or pinned state. `maxMemoriesPerAgent` is stored but never enforced, and
  extraction leaves no cost row.
* A knowledge item with only a `storageUrl` is never indexed; indexing works on inline
  `content` only, and `pdf` is treated as markdown text.
* `AgentTool.configOverrides` is stored but not read anywhere.
* `olyros_web_search` silently disappears from the tool list on non-Google providers.
* `custom_code` tools have no authoring UI; `execution_config` is validated at run time.
* Object access has no access requests and no admin bypass; HITL offers no multi-field
  forms and only one pending question per session.
* A router agent fronting many agents behind one Slack app exists (`kind = router`) and has
  its own page, [Routers](https://user-docs.olyrosstudios.com/routers.md); routing by channel, group or content is not built.

## Customer-safe summary

An agent is an assistant you set up once with a name, instructions and a personality,
powered by your own account with an AI provider of your choice. You can give it tools
to call, upload reference documents it will cite, and let it remember preferences and
facts from past conversations, with controls to turn remembering on or off and to pin,
edit or delete what it has learned. You decide who in your company may talk to each
agent on the web and in Slack. The agent can ask you a structured question with buttons
when it needs a decision, and every conversation is kept with its history and cost.
Changes to an agent are versioned so you can see what changed and when.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.