# Agents and runs An agent is a saved set of steps that works on your data, on a schedule or when something happens. Every agent belongs to a project. New to agents? Start with [Create an agent](/docs/agents/create-an-agent). ## Before you start [#before-you-start] - You have the **project ID** of the project the agent lives in, and you can edit that project. - Taking an agent live needs a workspace owner or admin, because a live agent spends credits. - Every example assumes `nexus = Nexus.connect()`. ## Find agents [#find-agents] ```python for agent in nexus.agents.list(project_id): print(agent) for agent in nexus.agents.list_all(): # every project you can open print(agent) ``` ## Save and test a draft [#save-and-test-a-draft] An agent is a file `agents/.yaml` with its Python code in `agents//`, inside your project's code. `save()` stores both from a local folder as a draft: ```python title="test_agent.py" from pathlib import Path from klarety import KlaretyError, Nexus PROJECT = "your-project-id" with Nexus.connect() as nexus: try: version_id = nexus.agents.save(PROJECT, "daily-summary", root=Path(".")) run_id = nexus.agents.start(PROJECT, "daily-summary", draft=True, inputs={"days": 1}) except KlaretyError as failed: raise SystemExit(f"Could not test the agent: {failed}") print("Draft", version_id, "running as", run_id) ``` `nexus.agents.check(project_id, text)` checks the YAML text without saving it. A draft never runs on its own; `start(..., draft=True)` runs it once. ## Take it live [#take-it-live] ```python nexus.agents.ask_to_publish(PROJECT, "daily-summary", version_id) ``` A person decides in the app. An owner or admin can publish directly with `nexus.agents.publish(PROJECT, "daily-summary", version_id)`; anyone else is refused. `unpublish()` takes it offline, and `publish()` with an earlier `version_id` brings that version back. `nexus.agents.version(project_id, version_id)` shows a saved version. ## Start a run and follow it [#start-a-run-and-follow-it] Each run reports its state and steps: ```python title="run_and_wait.py" import time from klarety import Nexus PROJECT = "your-project-id" with Nexus.connect() as nexus: run_id = nexus.agents.start(PROJECT, "daily-summary") run = nexus.agents.run(PROJECT, run_id) while run["state"] == "running": time.sleep(10) run = nexus.agents.run(PROJECT, run_id) print(run["state"], run["reason"], run["credits"], "credits") for step in run["steps"]: print(step["id"], step["state"], step["reason"]) ``` A run ends as `done`, `failed`, `declined` or `stopped`. Each step has its own state: `waiting`, `running`, `asking`, `done`, `failed`, `declined`, `stopped` or `skipped`, among others. ## Answer an approval step [#answer-an-approval-step] A step in the `asking` state waits for a person to say yes: ```python for step in run["steps"]: if step["state"] == "asking": nexus.agents.answer(PROJECT, run_id, step["id"], yes=True) ``` `yes=True` continues the run. `yes=False` stops it at that step. ## Read what a run produced [#read-what-a-run-produced] ```python result = nexus.agents.result(PROJECT, run_id) print(result["value"]) # up to 1 MiB print(result["files"]) # files the run left names = nexus.agents.outputs(PROJECT, run_id, step_id) data = nexus.agents.output(PROJECT, run_id, step_id, names[0]) # bytes print(nexus.agents.log(PROJECT, run_id, step_id)) ``` For a step that runs once per item, pass `item=` to `outputs()`, `output()` and `log()` to read one item. ## List runs, stop and rerun [#list-runs-stop-and-rerun] ```python for one in nexus.agents.runs(PROJECT, agent="daily-summary"): # newest first, page by page print(one["run_id"], one["state"]) nexus.agents.stop(PROJECT, run_id) new_run = nexus.agents.rerun(PROJECT, run_id, from_step="summarise") print(nexus.agents.stats(PROJECT, days=7)) # runs per day: count, outcomes, cost ``` `rerun()` starts a new run from one step, reusing earlier steps' output. To page from another process, use `runs_page()` and pass its `next` back as `after`. ## Delete an agent [#delete-an-agent] ```python nexus.agents.delete(PROJECT, "daily-summary") ``` The agent is paused and removed from the list. Its runs stay on record. ## What can go wrong [#what-can-go-wrong] | Exception | Cause | What to do | | --- | --- | --- | | `KlaretyError: agents/.yaml does not exist` | `save()` could not find the file under `root`. | Run from the project's folder or pass `root=`. | | `RefusedError` | You cannot edit the project, or you are not an admin and tried to `publish()`. | Use `ask_to_publish()`, or ask for access. | | `NotFoundError` | No such project, agent or run. | Check the IDs. | | `InsufficientCreditsError` | The workspace cannot pay for the run. | Add credits. | ## Next steps [#next-steps] - [Try, go live and pause](/docs/agents/go-live) for the same steps in the app. - [CLI](/docs/developers/cli) for `klarety agent` commands. - [Jobs and batch jobs](/docs/developers/jobs) for background work without an agent.