Skip to main content
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, one-shot task execution in Cloud tasks and executors.

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). 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. Built-ins today: 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 page. Agent access is the one-ability case (agent.chat, shown as Chat) of the access model that workflows 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. 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, 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).

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).

Limits and defaults

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; 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.