Skip to content
TriedDocs
Voice agents

Agent copilot

Ask Conductor for changes to an agent and get them back as proposals with diffs.

POSThttps://api.tried.com.au/agents/{agent_id}/copilot

Sends a conversation about one agent to Conductor and returns a reply plus proposed edits. This is the Conductor edit panel in the agent builder. Nothing is changed: each proposal is a patch you apply yourself. See Conductor.

Conductor reads the agent's current configuration, including its Retell LLM or conversation flow, and proposes top-level field replacements on the agent, the LLM or the flow.

Needs keys Proposals come from OpenAI. Without an OpenAI key the endpoint runs in mock mode and only understands a few requests: a friendlier tone, shorter replies, adding a transfer tool to a number, adding an end call tool, and speaking faster or slower.

Request#

Path parameters#

Parameter Type Required Description
agent_id string Yes The agent.

Body#

Field Type Required Description
messages array Yes The conversation so far, oldest first, 1 to 40 items.
messages[].role string Yes user or assistant.
messages[].content string Yes Up to 8000 characters.

Send earlier reply values back as assistant messages to keep context. In mock mode only the last user message is read.

Example request#

curl -X POST "https://api.tried.com.au/agents/agent_3f9a1c0b2d4e5f6a7b8c9d0e/copilot" \
  -H "Authorization: Bearer $TRIED_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "messages": [
    { "role": "user", "content": "Make replies shorter" }
  ]
}'
const res = await fetch("https://api.tried.com.au/agents/agent_3f9a1c0b2d4e5f6a7b8c9d0e/copilot", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.TRIED_API_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    messages: [{ role: "user", content: "Make replies shorter" }],
  }),
});
const data = await res.json();
import os, requests

res = requests.post(
    "https://api.tried.com.au/agents/agent_3f9a1c0b2d4e5f6a7b8c9d0e/copilot",
    headers={"Authorization": f"Bearer {os.environ['TRIED_API_KEY']}"},
    json={
        "messages": [{"role": "user", "content": "Make replies shorter"}],
    },
)
data = res.json()

Response#

200 OK

{
  "reply": "Here is a change for Front Desk. Review the diff and accept or reject it.",
  "proposals": [
    {
      "proposal_id": "prop_4e1a9c2b7d3f",
      "title": "Shorter replies",
      "target": "llm",
      "target_id": "llm_9b2c4d6e8f0a1b3c5d7e9f1a",
      "patch": { "general_prompt": "You are the receptionist for Harbour Dental.\n\nKeep every reply to one or two short sentences. Ask one question at a time." },
      "changes": [
        { "path": "general_prompt", "kind": "changed", "before": "You are the receptionist for Harbour Dental.", "after": "You are the receptionist for Harbour Dental.\n\nKeep every reply to one or two short sentences. Ask one question at a time." }
      ],
      "summary": ["Prompt edited (+77 characters)"]
    }
  ]
}
Field Type Description
reply string Conductor's answer to show the user.
proposals array Proposed edits. Empty when Conductor has no change to suggest.
proposals[].proposal_id string Starts with prop_. Not stored.
proposals[].title string Short label for the change.
proposals[].target string agent, llm or flow.
proposals[].target_id string The agent_id, llm_id or conversation_flow_id to update.
proposals[].patch object Top-level fields with their new values. Array fields such as general_tools hold the full new list.
proposals[].changes array Field diff between the current values and patch. Each item has path, kind (added, removed or changed), and before and after where they apply.
proposals[].summary string[] Readable lines, for example Added function: transfer_to_human.

Apply a proposal#

Send patch to the update endpoint for its target:

The dashboard does the same when you choose Accept.

Errors#

Status When
400 Validation failed, for example no messages, more than 40, an unknown role or content over 8000 characters.
401 Missing or invalid API key.
403 The key's IP allowlist or scopes reject the request. This route needs the agents scope.
404 The agent does not exist.
429 Rate limit exceeded. See Rate limits.

See Errors for the body format.