Skip to content
SurogateDocs

Copilot (⌘+/)

The Copilot drives the platform itself on your behalf. Press ⌘+/ (Mac) or Ctrl+/ anywhere in ops.surogate.ai. For the operator’s introduction, see Work mode → Copilot.

This chapter covers what builders should know that operators don’t need: where it slots into automation, what it can and can’t do, and the safety pattern that wraps destructive operations.

The Surogate Copilot panel

It exposes the platform’s tools as natural-language commands. Instead of clicking through CONFIG / KNOWLEDGE & TOOLS / channels, you describe what you want and the Copilot calls the corresponding tools. There are over 150 of them (served by the ops MCP server at /api/copilot/mcp). The Copilot’s agent definition lists exactly the tools below, and a tool not on that list is not shown to the model. The areas, with the main tools in each:

AreaMain tools
Agentslist_agents, get_agent, create_agent, update_agent, start_agent, stop_agent, delete_agent, plus env vars and attach_ / detach_ for skills, MCP servers and knowledge bases
Skillslist_skills, get_skill, create_skill, update_skill, delete_skill, import_skill_from_workspace, plus tools for the skill’s files
Knowledge baseslist_knowledge_bases, create_knowledge_base, create_kb_source, add_workspace_file_to_kb, compile_knowledge_base, get_kb_compile_status, read_kb_wiki_page, and others for sources, wiki pages and deletion
MCP serverslist_mcp_servers, register_mcp_server, update_mcp_server, delete_mcp_server, list_composio_toolkits
Sub-agentslist_sub_agents, get_sub_agent, create_sub_agent, update_sub_agent, delete_sub_agent
Programsget_programs_overview, create_journey, add_journey_step, simulate_journey, activate_journey, get_journey_funnel, and others for journeys, WhatsApp templates and escalations
Simulatesimulation_plan, simulation_start, simulation_get, simulation_end, simulation_review, simulation_recheck, propose_simulation_fix, apply_simulation_fix, undo_simulation_fix
WhatsApp formslist_whatsapp_flows, create_whatsapp_flow, update_whatsapp_flow, publish_whatsapp_flow, retire_whatsapp_flow, make_form_sendable, remove_sendable_form, list_whatsapp_forms
People and teamfind_people, add_person, update_person, delete_person, bind_person_slack, bind_person_whatsapp, enroll_person, message_person, get_person_timeline, set_team_member, and others for program settings, Telegram start links and Slack lookups
Monetize and landing pageget_monetize, create_plan, update_plan, update_monetize_settings, get_landing_page, update_landing_page, and others for replacing and deleting plans
Voiceget_agent_voice, list_voice_calls, list_voice_options, set_agent_voice, release_agent_voice
Inbox, insights and reportslist_inbox, update_inbox_item, get_agent_insights, get_user_reports, generate_user_report, set_user_report_guidance, get_cohort_report, generate_cohort_report, find_sessions
Missions and scheduled worklist_missions, get_mission, pause_mission, resume_mission, cancel_mission, list_scheduled_work, run_scheduled_work_now, pause_scheduled_work, resume_scheduled_work, update_scheduled_work, cancel_scheduled_work
Datasetslist_datasets, get_dataset, read_dataset, delete_dataset, upload_dataset_from_workspace
Models and traininglist_models, get_model, deploy_model, stop_serving, list_training_runs, get_training_run, get_training_metrics, get_training_rollouts, list_experiments, start_training, start_saved_run, update_saved_run, cancel_training, delete_training_run
RL environmentslist_environments, list_environment_catalogue, add_catalogue_environment, create_environment, get_environment, list_environment_files, read_environment_file, write_environment_file, delete_environment_file, update_environment, validate_environment, get_environment_validation, list_environment_versions, publish_environment, delete_environment
Evaluationslist_eval_benchmarks, list_eval_runs, get_eval_run, get_eval_samples, get_eval_logs, get_eval_leaderboard, get_eval_score_history, create_eval_run, update_eval_run, copy_eval_run, start_eval_run, stop_eval_run, delete_eval_run, create_custom_benchmark, archive_eval_benchmark, restore_eval_benchmark
Computelist_compute, get_compute_costs
Workspaceget_current_project, list_my_projects, search, recent_failures, create_project
Billing and membersget_project_billing, get_project_usage, list_project_members, add_project_member, update_project_member_role, remove_project_member
Documentationsearch_docs, read_doc, list_docs, read_guide

Besides those, it can use a few built-in tools: ask_user_question, create_artifact (for plans, documents and tables), todo, and the sandbox file and terminal tools (read_file, write_file, patch, search_files, list_files, terminal), which let it read documents you attach in chat. Its browser tools are switched off.

search_docs ranks sections of the product documentation. Its top results carry the matching section’s text, so most answers need no second call. read_doc reads a page or one section of it by path, and list_docs lists every page. The documentation is a bundled snapshot of the Work and Develop pages, so it can lag the live site. When you ask from a Studio page that has a doc, the page tells the Copilot which doc covers it. Pages without one give no doc hint.

find_sessions finds conversations by what was said in them. With no agent named it searches the current project’s agents; with an agent named, only that agent. Either way you need the editor or owner role on the project (or to be a platform admin); a viewer gets no results. search looks across resources in the current project, or in every project you are a member of. It matches the name Studio shows, the internal name and the ID, ignoring case, among the first 100 items of each kind; in a larger project, narrow it with kinds. Its results, like the agent, skill, dataset and model lists, include display_name. list_skills with scope="mine" lists only the skills you wrote, a full page at a time.

get_agent returns the agent’s settings with the skills, knowledge bases and MCP servers attached to it. Long fields such as the system prompt come back shortened; with full=true it returns them whole (environment variable values stay hidden either way), and update_agent refuses a value that still carries the shortening marker, so a cut-off prompt can’t be saved back over the real one. list_knowledge_bases lists the project’s knowledge bases, to find one to attach.

attach_kb_to_agent takes a mode: grounding (the default for a new attach: the agent answers from the knowledge base and cites it), grounding_nocite (the same authority, in plain prose without citations) or reference (optional material it consults when it judges useful). On a knowledge base that is already attached, a given mode changes it and leaving it out keeps it. get_agent shows each attached knowledge base with its mode.

attach_skill_to_agent attaches a skill’s main unless you name a version. A named version must be one the skill has published; otherwise the tool refuses and lists the published versions it finds. If the Hub can’t be read, it says so instead.

start_agent, stop_agent and delete_agent run the same checks and steps as the buttons in Studio and wait for the result. Start is refused at the plan’s limit for running agents or workspace storage. If delete removes the agent but a clean-up step fails (its workspace files, session data, API keys or service account), the result names that step so the Copilot can tell you.

Agents can’t be scaled: they run on the shared runtime with no replicas, CPU or memory to set, and update_agent refuses a resources field. Only model deployments have replicas.

create_skill makes a skill from a name, description and instructions (and max_iterations). An expert, the license, requires_tools and fallback_for_tools come from importing a skill folder with import_skill_from_workspace, which also reads max_iterations; the other fields are set in Studio. An imported expert has no model until one is chosen in Studio.

The voice tools read and change an agent’s phone line (see Voice) through the same checks as the Voice screen: reading needs the viewer role, changing needs the editor role, and the Copilot changes a system agent’s line only for an administrator.

  • get_agent_voice returns the agent’s number (none when it has no line), its settings and the free numbers in the pool. list_voice_calls lists recent calls, and list_voice_options lists what a line can be set to: Surogate’s speech models and languages, the default lines, and the background scenes and hold music.
  • set_agent_voice gives the agent a free number and/or changes its settings. Only what you name changes; the rest is kept. Pronunciations are added word by word, and a word set to null is removed. With no line and no number named, it refuses and lists the free numbers rather than picking one; a number that is taken or retired is refused before you are asked anything.
  • release_agent_voice returns the number to the pool and keeps the settings for next time.

The Copilot can’t switch a line to another speech provider: that needs your account’s key, so it sends you to the Voice screen. Surogate’s own speech is Romanian only, so on a line that uses it the language stays Romanian. On a line already set to another provider in Studio, it can still change the other settings. Adding numbers to the pool is for administrators.

get_project_billing reads the active project’s plan and limits, its credit balances and its workspace storage (measured about hourly). get_project_usage reads the last 1 to 90 days (default 30): the project’s platform-credit compute spend per workload, and the asking user’s own token usage across all their projects. Runs billed to the user’s own cloud or Modal account are not in it; get_compute_costs reads those. A serving row’s credits are the deployment’s running total, not only the period’s spend. Neither tool pays, changes the plan or buys credits.

list_project_members needs the viewer role. add_project_member, update_project_member_role and remove_project_member are for owners, as in Members, and act on the active project only. A member is added by the exact username or email of an existing account, and nothing is sent. Making someone a viewer pauses their running work; removing them pauses it and, if this was their default project, moves their default to another. Leaving no owner is refused. create_project makes a project owned by the user, on the account’s default plan, and needs no active project; in an enterprise deployment only administrators can create projects.

The mission tools see only the missions the chat user started from Work chat (/mission), the same rows the Missions page shows that user. The scheduled-work tools see every schedule of the agent, whoever made it, and say who in created_by (Scheduled work). Any other id comes back not_found. They refuse system agents. list_missions returns the first 50 missions (the total counted up to 100); get_mission returns the mission’s first 50 agents with their total (agents_total). pause_mission leaves running agents going; cancel_mission can’t be undone, refunds nothing and, with stop_workers, stops the running agents and the agents they started. run_scheduled_work_now runs the item’s prompt as a normal run, counting as one of its repeats; cancel_scheduled_work refuses an item that already ended. pause_scheduled_work and resume_scheduled_work pause and resume an item; update_scheduled_work edits its name, prompt, schedule, browser profile or run time limit, and a new schedule is planned again from now. None of these tools starts a mission or a schedule.

generate_user_report starts or refreshes one end-user’s report (force_full rebuilds it from the whole history) and answers that it is generating, or that nothing changed. set_user_report_guidance sets what that user’s next report focuses on. generate_cohort_report rebuilds the overview across 1 to 200 users and replaces the current one; get_cohort_report reads it. Reports use the platform’s base model and spend no credits; starting one needs the editor role.

update_person renames a person at once; changing whether they may be messaged first on a channel (whatsapp, slack, telegram, discord, teams) needs a yes. It never takes a password. bind_person_slack and bind_person_whatsapp replace the person’s existing binding (a member or number bound to another person is refused) and keep their contact permission unless one is given. delete_person removes the person from the agent and its Programs; their account and history are kept unless they are bound to no agent at all, not even this one, in which case the account is deleted for good, and the question says which.

The form tools follow Meta’s lifecycle (see WhatsApp forms): create_whatsapp_flow makes a draft and never publishes it, and a name already on the account is refused. update_whatsapp_flow edits a draft and returns Meta’s validation errors. publish_whatsapp_flow freezes the form for good. make_form_sendable lets the agent send a published form (cta at most 20 characters), and remove_sendable_form takes it back off. retire_whatsapp_flow deprecates it. Meta has no delete here, and retiring or removing a form that an active Program’s template opens is refused. If a create fails after Meta already made the draft, the error carries its flow_id, so the Copilot fixes that draft instead of making a second one. list_whatsapp_flows lists the account’s flows on Meta (the first 100) with their status and errors; list_whatsapp_forms lists only the forms the agent may send.

get_current_project returns your_role: owner, editor or viewer (a platform admin who is a member counts as owner, since admins pass every role check). The Copilot checks it before any build, including a playbook such as /build-agent. A viewer can use the Copilot to look things up, from the side panel or the Work page, where its sessions are listed too. Asked to change something, it says at once that a viewer can only read, without an interview or a plan, and it never offers to change your role: only a project owner can, in Settings, Members. Its suggestions on each page offer a viewer only what reads.

Every write acts only in the project open in Studio. Each item lookup that writes (agents, skills, knowledge bases, MCP servers, datasets, training runs, models) checks your role on the item’s project and then that it is the open project. Writes that go through Studio’s routes (journeys and steps, plans, the Inbox, people, WhatsApp forms, voice, missions, user reports and the rest) are checked the same way before the route runs: every id the call carries (agent, step, plan, training or evaluation run, model, environment, benchmark, project) must resolve to the open project, and a write whose project can’t be determined is refused rather than let through (creating a project is the one exception). The check runs before a tool that takes a confirmation code answers needs_confirmation; a question the Copilot asks on its own instructions (for example before any delete_*) can still come first. Refused, the tool names the item’s project, and the Copilot asks you to switch.

Someone who isn’t a member of the item’s project gets <item> not found, the same answer as for an id that doesn’t exist (a platform admin, who passes every role check, is told the item’s project instead). Attaching a skill, MCP server or knowledge base from another project to an agent also answers not found, even when you are a member there. Reads still reach your other projects: get_* by id, and list_* with all_projects=true (list_knowledge_bases lists only the open project). A platform admin managing a system agent is not held to the open project.

For each kind of build the Copilot has a playbook: build-agent, build-skill, build-knowledge-base, build-sub-agent, connect-mcp, build-program, build-dataset, build-environment, run-training, run-evaluation and deploy-model. It opens the guide with read_guide before building, along with the checklists and templates the guide cites. The loop is interview, inspect, plan (as an artifact you approve), build in dependency order, read each piece back, summarise with links and a test script. Its instructions forbid creating or updating an agent’s prompt before an interview and an approved plan.

The five ML guides cover what the tools allow:

  • build-dataset uploads one workspace file of up to 50 MB with upload_dataset_from_workspace, then shows you real rows and the stats with read_dataset (at most 20 rows, long values and lists cut).
  • run-training reads the project’s compute with list_compute, which says per compute what it can train on: the exact GPUs on Modal, live offers on a cloud, the fleet’s own GPUs on SSH (see Supported GPUs), and starts SFT, DPO, distillation and GRPO runs with start_training. A GRPO run trains on a published environment version, or in RULER mode on a project dataset with a judge: colocated by default, which needs three GPUs instead of two. RULER’s system prompt goes to the model being trained; the judge’s criteria go in its rubric. With an external judge the run is saved, not started, and you paste the judge’s key on the run’s Config tab; the Copilot never takes it. Before any start it asks a yes on the whole plan. get_training_rollouts reads a GRPO run’s sampled rollouts. A refused start leaves the run saved: the Copilot edits it with update_saved_run (settings, a GPU on its own compute, a Hugging Face subset; a GRPO run takes learning rate, group size, max steps, checkpoint interval and precision) and starts it with start_saved_run instead of creating another. get_training_metrics samples a run’s metrics evenly (over the latest 20,000 rows of a kind, which covers almost every run) and says whether it is still going.
  • build-environment creates an environment from a template or forks a catalogue entry, writes its code, validates it and, on your yes, publishes a version. Validation shows that the environment loads, not that its reward is right, so the Copilot shows you the reward code and the real preview samples first, and publishes only once validation has passed. If you ask it to publish before that, the confirmation says the code has not passed validation yet. A file longer than a read returns whole is edited in Studio instead, so its end is never lost. It never changes the platform’s own RULER environment.
  • run-evaluation evaluates a model, a trained adapter (get_training_run names a finished run’s adapter) or an agent on benchmarks, optionally against a serving comparison model. It creates the run as a draft and starts it after your yes; a copy of a past run keeps its MCP credentials, and its stored judge key as long as the judge’s base URL is unchanged. Each score comes with the number of samples it rests on, or says that number is unknown when the runner stored no samples, and a score’s delta is measured against the comparison model, or, with none, against the model’s previous score on that benchmark. A judge key or MCP credential is never taken in chat: the draft is created without it and you paste it on the run’s Config tab.
  • deploy-model starts and stops serving an entry already on Models and switches an agent onto it. deploy_model, stop_serving and cancel_training run Studio’s own start, stop and run-stop routes and return their answer: the status after the call, or Studio’s refusal (payment_required for too few credits, with Studio’s hint to top up or upgrade the plan; invalid_args for missing Compute or Engine). A launch that ends failed comes back as an upstream error pointing at the model page and its job logs. A call that outlives the runtime’s 120 s tool timeout still completes in Studio; the Copilot is told not to call it again and to tell you Studio hasn’t confirmed it yet. cancel_training refuses a run that has already ended, and stop_serving a model that isn’t serving. list_models and get_model show each entry’s engine; proxy entries and the platform models surogate and surogate-pro read available and are never deployed.

Two mechanisms apply.

It asks in the chat. The Copilot’s instructions have it ask with ask_user_question before spend and risky changes: start_training, deploy_model, compile_knowledge_base, any delete_*, start_agent on an error agent, set_agent_env_vars, update_agent on policy or browser_enabled, register_mcp_server with stdio, and overwriting a skill or sub-agent. This is an instruction to the model. The tools themselves do not check for it.

An unanswered question is not an answer. A cancelled ask_user_question (for example when nobody answers) is neither a yes nor a no, for an interview question, a plan approval or a confirmation alike, and the instructions forbid acting on it. If a message or step arrived meanwhile, the Copilot deals with that first and asks again only for what is still missing; otherwise it says in one line that it is waiting and stops, without asking again in that turn.

The tool refuses without confirmed=true and its code. For actions that message people, start or stop what they receive, spend money or change who can do what, the tool takes confirmed and confirmation. A tool that acts on an agent first checks your role on its project, so a viewer is refused there and never asked to confirm; update_monetize_settings and the member tools need the owner role, as in Studio, and create_project needs none, since anyone can create a project. Called without a valid code, the tool changes nothing and returns needs_confirmation with the action. The Copilot then asks you, quoting the action (and the exact text, for a message), and calls again with confirmed=true only after your yes. These tools are:

  • activate_journey, pause_journey, delete_journey, remove_journey_step, send_journey_test, create_whatsapp_template
  • enroll_person, update_person_enrollment (status changes), manage_person_contacts (add, confirm, remove), message_person
  • set_team_member, remove_team_member, update_program_settings (team, senders, destinations)
  • create_plan, update_plan, replace_plan, delete_plan, update_monetize_settings (when changing the mode)
  • start_saved_run, update_saved_run, delete_training_run
  • add_catalogue_environment, publish_environment, delete_environment
  • start_eval_run, delete_eval_run
  • set_agent_voice, release_agent_voice (every change to a phone line, including a settings-only edit on a connected line)
  • update_person (contact permission changes), delete_person, bind_person_slack, bind_person_whatsapp
  • create_whatsapp_flow, publish_whatsapp_flow, retire_whatsapp_flow, make_form_sendable, remove_sendable_form
  • create_project, add_project_member, update_project_member_role, remove_project_member, update_landing_page (when publishing or unpublishing)
  • pause_mission, resume_mission, cancel_mission, run_scheduled_work_now, cancel_scheduled_work, pause_scheduled_work, resume_scheduled_work, update_scheduled_work, generate_cohort_report

Every tool on this list answers needs_confirmation with a code tied to you, the chat and what is about to happen, and acts only when called again with that code. For the journey, people, team and plan tools it covers what is being approved: a message’s text, a plan’s terms, the guarded settings, the journey, step or person it acts on. For a run it covers the run’s current state (and, for an edit, the exact change), so the code stops working once the run starts or changes. For an environment publish it covers main’s commit and the published version, so an edit after the yes voids it; a catalogue fork’s code covers the project and the copy’s name, so one yes makes one copy. For an evaluation start it covers the run’s status, targets, benchmarks and settings; for a delete, when the run last started and ended, so a re-run voids it. For a phone-line change it covers the number now, the number after and the settings as they will be stored; for a disconnect, the number being released. For the others it covers the exact change and the state it would act on, such as a member’s current role, a person’s current bindings, a form’s status or contents, a mission’s or scheduled item’s status, or the landing page’s published state with the blocks and theme sent alongside, so a change in between voids the code. confirmed=true alone changes nothing, and a yes doesn’t carry over to other values. So the Copilot always receives the tool’s own wording (for a delete, that a Modal run’s storage and unpublished weights go too); showing it to you is still up to its instructions.

An approved plan does not cover these. Each one needs its own yes.

For each of these the Copilot says plainly that it can’t, and names the page and control where it is done.

Secrets, keys and payments: it guides, you act

Section titled “Secrets, keys and payments: it guides, you act”

Anything that needs a secret or moves money is yours to do. The Copilot links the place and explains the steps.

WhatWhere
Channel credentials (WhatsApp, Slack, Telegram, Discord, Microsoft Teams)Publish > Channels, the channel’s row
An agent’s API keys, webhook secrets and the OpenAI-compatible APIPublish > Channels, the Web chat & API row
The WhatsApp number, Meta webhook and subscriptionPublish > Channels, the WhatsApp row
The Teams app packagePublish > Channels, the Microsoft Teams row, Download app package
Composio sign-inConfigure > Tools, Connect on the toolkit
The git token, repositories and coding-agent credentialsConfigure > Coding
SSH keys and targetsConfigure > Governance, SSH remote access
Browser profilesSettings, Profile
Saved keysVault
Stripe Connect onboardingPublish > Monetize
Payments, plan changes and top-upsSettings, Billing (the Copilot can read the plan, credits and usage)
Inviting someone who has no account yetSettings (the Copilot adds existing accounts as members)

This is an instruction, not a missing tool: set_agent_env_vars can write an agent’s environment variables, which carry channel keys, and the Copilot is instructed to ask you first and never echo secret values back.

Agents, channels and Programs

  • Which channels are live: Publish > Channels (the Copilot can read only the voice line).
  • An agent user’s password (Publish > Users) and memory (Publish > Insights, Memory).
  • The agent-wide report prompts: Publish > Insights, Prompts. One person’s report focus it sets itself with set_user_report_guidance.
  • Turning Programs on or off: Configure > Capabilities, Programs.
  • The per-user usage limit and the Free trial card for people who haven’t bought: Publish > Monetize. A paid plan’s trial days it sets itself with update_plan.
  • Answering a question an agent asked: the agent’s Inbox, Submit answer.
  • The Programs API scopes and webhook: Publish > Channels, the Web chat & API row.
  • Queued outreach and sending a held message now: Programs, Team tab, Send now.
  • Switching a phone line to another speech provider: the Voice screen. Adding numbers to the phone pool is for an administrator, in Settings, Phone numbers.

Knowledge bases, templates and skills

  • Knowledge-base settings, removing a source or file, and stopping or rebuilding a compile (compile_knowledge_base has no stop or rebuild).
  • Creating an agent from a template: it links Templates, or offers to build one with /build-agent, without the template’s skills.
  • Publishing skill versions, the skill canvas, test runs and optimization.

Models, data and training

  • Models beyond starting, stopping and redeploying. deploy_model starts a model, and on one that is running or starting it stops it and starts it again. No tool adds, edits, scales or deletes a model, merges or promotes an adapter, or publishes a run to the Hub.
  • The Data Hub. It can’t browse or change repositories, branches, tags or files; it links Data Hub and explains from its doc.
  • Some RL work. It cannot start PPO, write a coded reward over a project dataset (it offers RULER mode instead; an environment can’t read a project dataset), or run an environment’s reward on the preview samples, since validation never runs the reward. The GRPO settings beyond the new-run form’s five are on the run’s RL Config tab.
  • Some evaluation work. Ingesting external results, exporting a run, and deleting a custom benchmark for good are done in Evaluations; the Copilot archives and restores benchmarks. A judge key or MCP credential for a run is pasted on its Config tab, never in chat.
  • Reading a whole past conversation. It gives the session link find_sessions returns; the session’s Thread tab has the full conversation.
  • Whether Stripe is connected, and who bought. get_monetize returns a buyer count only; Publish > Monetize has Stripe Connect and Subscribers.
  • No browser tool. It works from the platform’s own tools, not the open web. It is not a research agent.
  • No governance decisions. Approvals stay in the Inbox.
  • No images or videos.

Every Copilot operation maps to a REST API endpoint, except the docs and guide tools (search_docs, read_doc, list_docs, read_guide), which read the documentation and build guides bundled with the Copilot. If you’re building automation, prefer the API directly: the Copilot is for interactive use, not headless pipelines. See the API reference sections under each feature (Agents, Skills & Experts, Datasets, etc.).

401 “Invalid base LLM token” — the platform’s default LLM credential isn’t provisioned for your tenant. Admin-side fix.

Copilot returned {error: ...} and gave up — by design. It won’t retry blindly on errors. Read the error, fix the underlying issue, re-ask.

  • ⌘+/ / Ctrl+/ — open the drawer
  • Esc — close
  • Enter — submit
  • Shift+Enter — newline

The drawer’s header has a history menu (clock icon) — switch between past Copilot conversations, rename them, or start a new chat. Each conversation is its own session and resumes where you left off.