Learn
POST /v1/agents/learn. Turn recorded turns into Simulang code, or repair that code (research preview).
View as MarkdownTurns what Sai did in one or more turns into a Simulang function you own, async function main(params = { ... }), which your program then runs on a computer through direct control. Given code you already have, the same call repairs it. Learned code walks through the whole loop.
Research preview: the request and response may change.
Request
POST /v1/agents/learn{
"turns": ["turn_vzjz62w7j7jvOilZ6zBL"],
"template": "Open {{site}} and read the title of the top story"
}¹ Optional when repairing: send initialCode with evaluations, feedback or new turns. New turns are the usual input: the code failed on a case, you sent the same template to POST /message with recordTrajectory, Sai solved it, and that turn shows what the code is missing.
An evaluation:
The call does the work before it answers, about two minutes for a conversion. Set your client's timeout to at least 10 minutes. If your side times out, send the same request with the same idempotency_key, or read the result with GET /v1/agents/learn/{learnId}.
Response
200:
{
"learnId": "learn_3Fq9cT1kZ0aJ",
"mode": "convert",
"status": "succeeded",
"title": "Read the top story title",
"template": "Open {{site}} and read the title of the top story",
"parameters": [{ "name": "site", "defaultValue": "https://news.ycombinator.com" }],
"code": "async function main(params = { site: \"https://news.ycombinator.com\" }) {\n ...\n}",
"validation": { "errors": [], "warnings": [] },
"sourceTurns": ["turn_vzjz62w7j7jvOilZ6zBL"],
"usage": { "inputTokens": 61240, "outputTokens": 3120 },
"researchPreview": true
}A repeated idempotency_key returns the earlier result plus "idempotent_replay": true.
Run the code
Run it in a control lease with the call to main as the block's last line; the block's result is what main returns. Pass every input: an argument to main replaces its whole default object, so merge your inputs over parameters' defaults.
POST /v1/machines/{machineId}/control/exec
{ "code": "<code>\nawait main({\"site\": \"https://lobste.rs\"})", "timeoutMs": 300000 }The SDKs do this for you: lease.run(learned, inputs).
Read a result later
GET /v1/agents/learn/{learnId}Returns the same object. A call that stopped mid-way reads as failed with error: "interrupted".