interactive run · simulated

Watch a run pause. Then decide what happens.

Step through a recorded example and see what Psych knows after each event. At the approval gate, choose either path and follow the run to its answer.

run_9b7c · tenant=acme · gpt-4o-minisimulated · records from a real Run, no live model

customerrefund order A1, it arrived broken

  1. 01run_admittedversion_hash=950e…6a43 input={"message":"refund order A1, it arrived broken"} deadline_at=+120s
  2. 02attempt_startedworker_id=w-01 attempt_number=1 reclaimed_expired_lease=false
  3. 03turn_startedturn=1
  4. 04model_call_startedmodel=gpt-4o-mini tool_names=[issue_refund, lookup_order, load_skill, remember, forget]
  5. 05model_call_finishedfinish_reason=tool_calls text="Checking the order." usage={input: 412, output: 23, cache_read: 0} cost=$0.00007560
  6. 06tool_call_startedtool=lookup_order arguments={"order_id":"A1"} interruptible=true
  7. 07tool_call_finishedlookup_ordercall_id=call_1 outcome=ok result={"order_id":"A1","status":"delivered","total_cents":"4200"}
  8. 08turn_startedturn=2
  9. 09model_call_startedmodel=gpt-4o-mini tool_names=[issue_refund, lookup_order, load_skill, remember, forget]
  10. 10model_call_finishedfinish_reason=tool_calls usage={input: 61, output: 14, cache_read: 430} cost=$0.00004980
  11. 11tool_call_startedtool=load_skill arguments={"name":"refund-policy"} interruptible=true
  12. 12tool_call_finishedload_skillcall_id=call_2 outcome=ok result={"found":true,"name":"refund-policy","body":"Refunds are allowed within 30 days of delivery.\nAnything over 10000 cents needs a manager, whatever the customer says.\nAlways state the amount back to the customer before issuing.","already_loaded":false}
  13. 13turn_startedturn=3
  14. 14model_call_startedmodel=gpt-4o-mini tool_names=[issue_refund, lookup_order, load_skill, remember, forget]
  15. 15model_call_finishedfinish_reason=tool_calls text="That is within policy." usage={input: 96, output: 31, cache_read: 491} cost=$0.00006982
  16. 16tool_call_startedtool=issue_refund arguments={"order_id":"A1","cents":4200} interruptible=false
  17. 17suspendedreason=approval pending_call_id=call_3 expires_at=+24h

Three things to catch. tool_call_started is written at record 16, before the suspension at record 17: the call is opened, then the gate stops it, and the same call_id is settled at record 20 by a different Worker. Denying settles that same call as an error the model reads and answers around, so the Run completes either way. And cost only moves on a model call, because usage is recorded per call and priced as it is written.

What is real and what is not. No model is called to draw this page. The records are the log of a Run executed against the scripted fake model with these tools and this approval rule, read back with records() and checked into the repository; the token counts were scripted, and the runtime priced them itself. The panel on the right is folded from the records on the left the way status() folds a real log, and the build fails if that fold disagrees with report().

the example console

The same decision, in the console.

Screenshots of the application in examples/playground/, running locally against a scripted provider. The agent, the tools and the approval rule are the ones the command below gives you.

The console holding a refund for approval: the tool issue_refund, its arguments order_id A1 and cents 4200, and Approve and Decline buttons.
The Run stopped before issue_refund and is waiting. The card names the call and its exact arguments, because approving a tool by name alone is approving something you cannot see.
The same conversation after approval: a line reading Approved by sam, then the agent's reply confirming the refund.
After approving. Who decided is on the log, not just on the screen, and the agent carries on from where it stopped.

the example console

Run the console locally.

An example application in the repository. It supplies the HTTP server and the UI that Psych does not, so you can see an agent published, talked to, and read back.

run itshell
git clone https://github.com/psych-systems/psych-runtime && cd psych-runtime
docker compose up --build        # then http://localhost:3000

Nothing else to install. It works before you configure a provider. Compose adds PostgreSQL and Jaeger, where a Run shows up as a span tree.

ScreenFor
ChatTalking to an agent, one conversation at a time.
AgentsWhat you can talk to, and building another.
ConnectionsMCP servers, their live state, credentials by name.
ActivityEvery conversation, its outcome, its trace and usage.
CapabilitiesThe definition-of-done scenarios, run against the live runtime.
SettingsModel access, secrets, appearance.