Project instructions API
Run prompt templates, skills and goals from your own program. The program sends the same commands that you type in a session.
The examples use the Python SDK. To see the same steps as HTTP API requests, select HTTP at the top of the page.
When to use
- Your program must run a saved prompt template or a skill. Run a prompt template or a skill with one message.
- A script must show the commands that a session accepts. List slash commands.
- A batch job must continue until a result is verified. Set a goal with an iteration budget.
- A dashboard must show the progress of a goal. Read the goal state.
- A program must stop or continue a goal. Pause, resume or cancel a goal.
To learn how project rules, prompt templates, skills and goals work, read Project instructions.
Before you start
Python
Connect a GatewayClient as in Connect to a gateway and run a
task. The examples use client and session, a
Session from client.session(session_id).
HTTP
Define the vis_api function from Authenticate requests. The
examples use it. They also use SESSION_ID for the ID of a session that you created or found.
Vis adds the project rules in AGENTS.md and the system prompt files to every message. Your program
does not send them. Project rules: AGENTS.md
explains the files.
Operations
Python
Typed calls check the answers and return records. Generated methods return the JSON answer of one request.
| Task | Typed call | Generated method |
|---|---|---|
| List slash commands | — | get_session_slashes(sid, query=...) |
| Run a prompt template or a skill | session.send(request) |
post_session_turns(sid, body=...) |
| Set a goal | session.goal(objective, ...) |
post_session_turns(sid, body=...) |
| Read the goal state | session.read() |
get_session(sid) |
| Pause, resume or cancel a goal | session.send(request) |
post_session_turns(sid, body=...) |
HTTP
| Task | Method and path |
|---|---|
| List slash commands | GET /v1/sessions/{sid}/slashes |
| Run a prompt template or a skill | POST /v1/sessions/{sid}/turns |
| Set a goal | POST /v1/sessions/{sid}/turns |
| Read the goal state | GET /v1/sessions/{sid} |
| Pause, resume or cancel a goal | POST /v1/sessions/{sid}/turns |
List slash commands
Python
commands = client.get_session_slashes(session.id, query={"channel": "tui"})["commands"]
for command in commands:
print(command["name"], command["doc"])
The list has the commands of the extensions, the commands of the channel and the prompt templates of
the project. The channel is web or tui, web by default. Skills are not in the list. Each
skill has the command /skill:<name>, as Skills explains.
A command with saveable set to true is prompt content, such as /goal. A client can keep it in its
prompt history. Other commands do not have the field.
HTTP
vis_api "$VIS_GATEWAY_URL/v1/sessions/$SESSION_ID/slashes?channel=tui"
The answer has commands, with name and doc for each command. The list has the commands of the
extensions, the commands of the channel and the prompt templates of the project. The channel is
web or tui, web by default. Skills are not in the list. Each skill has the command
/skill:<name>, as Skills explains.
A command with saveable set to true is prompt content, such as /goal. A client can keep it in its
prompt history. Other commands do not have the field.
Run a prompt template or a skill
Python
review = session.send("/review error handling")
print(review.wait(timeout=600)["status"])
checklist = session.send("/skill:release-checklist Prepare the 2.4.0 release")
A template sends its file as the message, with $ARGUMENTS replaced by the text after the name. A
slash command of an extension wins over a template with the same name. A skill command loads the
skill and gives it the task after the name.
HTTP
vis_api -X POST "$VIS_GATEWAY_URL/v1/sessions/$SESSION_ID/turns" -H 'content-type: application/json' \
--data '{"request": "/review error handling", "idempotency_key": "review-1"}'
vis_api -X POST "$VIS_GATEWAY_URL/v1/sessions/$SESSION_ID/turns" -H 'content-type: application/json' \
--data '{"request": "/skill:release-checklist Prepare the 2.4.0 release", "idempotency_key": "release-1"}'
Each answer has the turn_id of the message. A template sends its file as the message, with
$ARGUMENTS replaced by the text after the name. A slash command of an extension wins over a
template with the same name. A skill command loads the skill and gives it the task after the name.
Set a goal
Python
turn = session.goal("Implement the parser fix and run its regression tests", iteration_budget=30)
result = turn.wait(timeout=3600)
print(result["status"])
goal() sends a /goal command and returns the same Turn as send(). A session has one goal at a
time, and a new goal replaces it. iteration_budget limits the model iterations of the goal. Without
it, the goal has no limit of its own. Follow the work with turn.wait() or the event stream in
Follow progress.
HTTP
vis_api -X POST "$VIS_GATEWAY_URL/v1/sessions/$SESSION_ID/turns" -H 'content-type: application/json' \
--data '{"request": "/goal --budget 30 -- Implement the parser fix and run its regression tests", "idempotency_key": "goal-1"}'
A goal is a message with the /goal command. A session has one goal at a time, and a new goal
replaces it. --budget limits the model iterations of the goal. Without it, the goal has no limit of
its own. Read the turn, or follow the event stream as in Follow
progress.
Read the goal state
Python
goal = session.read()["goal"]
if goal:
print(goal["status"], goal["iterations_used"], goal["iteration_budget"])
The session detail and each row of client.list_sessions() have goal, an object or None. The
event stream also sends it in the subscription.ready event, also when the session is idle.
statusisactive,paused,blocked,budget_limited,completeorcancelled. The apps showbudget_limitedas "iteration-limit reached".iteration_budgetis a positive integer orNone.iterations_usedis zero or more.tokens_usedcounts the measured input, output and cached input. It is for statistics and does not limit the work.time_used_msis the active time up toupdated_at. While the goal is active, the elapsed time istime_used_ms + max(0, now - updated_at)milliseconds.
HTTP
vis_api "$VIS_GATEWAY_URL/v1/sessions/$SESSION_ID" |
python3 -c 'import json, sys; print(json.load(sys.stdin)["goal"])'
The session detail and each row of the session list have goal, an object or null. The event
stream also sends it in the subscription.ready event, also when the session is idle.
statusisactive,paused,blocked,budget_limited,completeorcancelled. The apps showbudget_limitedas "iteration-limit reached".iteration_budgetis a positive integer ornull.iterations_usedis zero or more.tokens_usedcounts the measured input, output and cached input. It is for statistics and does not limit the work.time_used_msis the active time up toupdated_at. While the goal is active, the elapsed time istime_used_ms + max(0, now - updated_at)milliseconds.
Pause, resume or cancel a goal
Python
session.send("/goal --pause").wait(timeout=60)
session.send("/goal --resume")
session.send("/goal --cancel")
These commands wait in the normal message queue. To stop the work at once, cancel the running turn as in Queue and cancel messages. The SDK has no other methods to read or change a goal.
HTTP
vis_api -X POST "$VIS_GATEWAY_URL/v1/sessions/$SESSION_ID/turns" -H 'content-type: application/json' \
--data '{"request": "/goal --pause", "idempotency_key": "goal-pause-1"}'
Send /goal --resume or /goal --cancel in the same way. These commands wait in the normal message
queue. To stop the work at once, cancel the running turn as in Queue and cancel
messages. The API has no other requests to read or
change a goal.
See also
- Project instructions — project rules, prompt templates, skills and goals.
- Python SDK — install the SDK, connect a client and handle gateway errors.
- HTTP API — authentication, the OpenAPI document and gateway errors.
