Send input and read output
Send one JSON value to an open Session:
helmr actor send SESSION_ID \
--project agents --env development \
--data-json '{"type":"instruction","text":"also update the tests"}' \
--idempotency-key slack:T123:C456:1712345678.000100
Use a stable upstream event identifier as the idempotency key. A retry then
replays the original admission instead of adding duplicate work. send routes to
the active Turn before settlement or enqueues when idle; use enqueue to always
queue a new Turn. Messages accepted before handler registration wait for delivery
to that same Turn. Acceptance does not mean the application has handled the message;
inspect message outcomes in the Session timeline. A held Session rejects send.
For an answer or approval tied to existing work, use session.turn(turnId).send
or helmr actor turn send SESSION_ID TURN_ID. These never retarget a late reply.
Read one finite event page:
helmr actor events SESSION_ID \
--project agents --env development \
--after 0 --limit 50 --json
Each event has a durable sequence, kind, data, timestamp, nullable Turn ID
and nullable Run provenance. Pass next_after as --after to continue. Multiple
readers can keep independent cursors. Output EOF is not a terminal Turn outcome.
With the SDK:
const session = client.sessions.ref("SESSION_ID")
await session.send(
{ type: "instruction", text: "also update the tests" },
{ idempotencyKey: "slack:T123:C456:1712345678.000100" },
)
const page = await session.events.list({
after: 0,
limit: 50,
})
for (const record of page.records) {
console.log(record.sequence, record.data)
}
Run logs are execution telemetry. Session output is the Actor’s durable application protocol; do not substitute one for the other.