SDKs

SDKs · TypeScript

Interactive sessions

Stream RunSessionInteractive events, send user messages, and decide tool approvals.

InteractiveSession wraps RunSessionInteractive. Open it from RuntimeClient.runSessionInteractive() or PhronyAgent.runInteractive() or PhronyBundle.runInteractive(). The first client message must be start or attach.

Methods

start(options)

New session: agentRef or bundleRef (mutually exclusive), JSON input, optional resolvedSecrets.

TypeScript
import { RuntimeClient } from "@phrony/sdk";

const client = await RuntimeClient.connect();
const session = client.runSessionInteractive();

session.start({
  agentRef: { namespace: "default", name: "my-agent", version: "" },
  input: { question: "Hello" },
  resolvedSecrets: { openai: process.env.OPENAI_API_KEY },
});

start({ bundleRef })

Start an interactive session on a deployed bundle.

TypeScript
import { RuntimeClient } from "@phrony/sdk";

const client = await RuntimeClient.connect();
const session = client.runSessionInteractive();

session.start({
  bundleRef: { namespace: "demo", name: "payment-desk", version: "" },
  input: { message: "Pay 500 USD to Acme" },
  resolvedSecrets: { stripe: process.env.STRIPE_API_KEY },
});

attach(options)

Reconnect to an existing sessionId.

TypeScript
session.attach({ sessionId: "sess_abc123" });

sendUserMessage(text)

Send a user turn after an awaiting_input event.

TypeScript
// After an awaiting_input event:
session.sendUserMessage("Use a shorter summary.");

decideToolApproval(options)

Respond to approval_required: approvalId, approved, optional comment and replacement args.

TypeScript
// Inside your events() loop when event.type === "approval_required":
session.decideToolApproval({
  approvalId: event.approval.approvalId,
  approved: true,
  comment: "Approved by operator",
  args: { city: "Oslo" },
});

events()

Async iterable of InteractiveEvent until the stream ends or errors.

TypeScript
for await (const event of session.events()) {
  switch (event.type) {
    case "session_started":
      console.log(event.session.sessionId);
      break;
    case "text_delta":
      process.stdout.write(event.delta);
      break;
    case "completed":
      console.log(event.output);
      break;
    case "failed":
      throw new Error(event.message);
  }
}

close()

Half-close the client side of the stream.

TypeScript
session.close();
client.close();

InteractiveEvent types

Server events are a discriminated union on type:

Lifecycle

session_started, completed, failed, cancelled, stream_end

Streaming

text_delta, awaiting_input

Tools

tool_call, tool_result, approval_required