SDKs

SDKs · TypeScript

Runtime client

RuntimeClient unary RPCs for agent and bundle lifecycle, sessions, approvals, and catalog.

RuntimeClient exposes every runtime unary RPC. Connect via Connect to the runtime. For agent runs, prefer Phrony.

Version and sessions

getVersion(request?)

TypeScript
const version = await client.getVersion();
console.log(version.version, version.schemaVersion);

runSession(request)

Unary session start. Set agentRef or bundleRef (mutually exclusive). Encode input and secrets with jsonBytes / jsonBytesMap.

TypeScript
import { jsonBytes, jsonBytesMap } from "@phrony/sdk";

const response = await client.runSession({
  agentRef: { namespace: "default", name: "my-agent", version: "" },
  input: jsonBytes({ claimId: "CLM-48219" }),
  resolvedSecrets: jsonBytesMap({ openai: process.env.OPENAI_API_KEY }),
});

console.log(response.sessionId, response.status);

runSession({ bundleRef })

Start a session on a deployed bundle root member.

TypeScript
import { jsonBytes, jsonBytesMap } from "@phrony/sdk";

const response = await client.runSession({
  bundleRef: { namespace: "demo", name: "payment-desk", version: "" },
  input: jsonBytes({ message: "Pay 500 USD to Acme" }),
  resolvedSecrets: jsonBytesMap({ stripe: process.env.STRIPE_API_KEY }),
});

console.log(response.sessionId, response.status);

listSessions(request)

TypeScript
const { sessions } = await client.listSessions({
  agentRef: { namespace: "default", name: "my-agent", version: "" },
  status: "running",
  kind: "", // optional: "agent" or "bundle"
});

inspectSession(request)

Full persisted session dump: history, timeline, invocations, approvals, and delegated children.

TypeScript
const { session } = await client.inspectSession({
  sessionId: "sess_abc123",
});
// session.timeline — unified chronological audit view
// session.children — delegated child sessions (same shape, recursive)

cancelSession(request)

TypeScript
await client.cancelSession({ sessionId: "sess_abc123" });

completeSession(request)

TypeScript
await client.completeSession({ sessionId: "sess_abc123" });

Publish and deploy — agents

publish(request)

manifest is the raw agent.yaml bytes.

TypeScript
import { readFileSync } from "node:fs";

const manifest = readFileSync("agent.yaml");
const published = await client.publish({
  manifest,
  actor: "ci@example.com",
});

console.log(published.versionId, published.contentHash);

deploy(request)

TypeScript
await client.deploy({
  agentRef: { namespace: "default", name: "my-agent", version: "0.2.0" },
  actor: "ci@example.com",
});

rollback(request)

TypeScript
await client.rollback({
  agentRef: { namespace: "default", name: "my-agent", version: "" },
  toVersion: "0.1.0",
  actor: "ops@example.com",
});

getActiveVersion(request)

TypeScript
const active = await client.getActiveVersion({
  agentRef: { namespace: "default", name: "my-agent", version: "" },
});
console.log(active.version);

listDeployments(request)

TypeScript
const history = await client.listDeployments({
  agentRef: { namespace: "default", name: "my-agent", version: "" },
});
for (const d of history.deployments) console.log(d.version, d.deployedAtUnixMs);

getAgentVersion(request)

TypeScript
const record = await client.getAgentVersion({
  agentRef: { namespace: "default", name: "my-agent", version: "0.2.0" },
});

retireAgentVersion(request)

TypeScript
await client.retireAgentVersion({
  agentRef: { namespace: "default", name: "my-agent", version: "0.1.0" },
});

deprecateAgentVersion(request)

TypeScript
await client.deprecateAgentVersion({
  agentRef: { namespace: "default", name: "my-agent", version: "0.1.0" },
});

archiveAgent(request)

TypeScript
await client.archiveAgent({
  agentRef: { namespace: "default", name: "my-agent", version: "" },
});

Publish and deploy — bundles

Bundle lifecycle RPCs mirror the CLI bundles commands. Publish requires the committed bundle.lock.json bytes alongside the bundle manifest.

publishBundle(request)

bundleManifest and committedLock are raw bytes; members lists vendored closure packages.

TypeScript
import { readFileSync } from "node:fs";

const bundleManifest = readFileSync("support/bundle.yaml");
const committedLock = readFileSync("support/bundle.lock.json");

const published = await client.publishBundle({
  bundleManifest,
  committedLock,
  members: [
  // BundleMemberPackage entries for each vendored closure member
  ],
  actor: "ci@example.com",
});

console.log(published.bundleVersionId, published.lockHash);

deployBundle(request)

bundleRef must include @version — use parseBundleRefVersionRequired for deploy-by-hash.

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

await client.deployBundle({
  bundleRef: parseBundleRefVersionRequired("demo/payment-desk@1.0.0"),
  actor: "ci@example.com",
});

getActiveBundle(request)

TypeScript
const active = await client.getActiveBundle({
  bundleRef: { namespace: "demo", name: "payment-desk", version: "" },
});
console.log(active.version, active.lockHash);

listBundleDeployments(request)

TypeScript
const history = await client.listBundleDeployments({
  bundleRef: { namespace: "demo", name: "payment-desk", version: "" },
});
for (const d of history.deployments) console.log(d.version, d.lockHash, d.deployedAt);

Catalog

listAgents(request?)

TypeScript
const { agents } = await client.listAgents();
for (const a of agents) console.log(a.namespace, a.name);

listAgentVersions(request)

TypeScript
const { versions } = await client.listAgentVersions({
  agentRef: { namespace: "default", name: "my-agent", version: "" },
});

listBundles(request?)

TypeScript
const { bundles } = await client.listBundles();
for (const b of bundles) console.log(b.namespace, b.name);

listBundleVersions(request)

TypeScript
const { versions } = await client.listBundleVersions({
  bundleRef: { namespace: "demo", name: "payment-desk", version: "" },
});

Approvals

getApproval(request)

TypeScript
const approval = await client.getApproval({ approvalId: "appr_xyz" });

listApprovals(request?)

TypeScript
const { approvals } = await client.listApprovals({
  status: "pending",
  sessionId: "",
  route: "",
});

decideApproval(request)

TypeScript
import { ApprovalDecision, jsonBytes } from "@phrony/sdk";

await client.decideApproval({
  approvalId: "appr_xyz",
  decision: ApprovalDecision.APPROVAL_DECISION_APPROVE,
  comment: "Looks good",
  args: jsonBytes({ city: "Oslo" }),
  comprehensionAcknowledged: true,
  actor: "ops@example.com",
});

Streams

work(metadata?, options?)

Raw grpc-js duplex stream — prefer Worker or WorkStream.

TypeScript
const raw = client.work(); // grpc-js ClientDuplexStream — prefer Worker

runSessionInteractive(metadata?, options?)

Returns InteractiveSession — see Interactive sessions.

TypeScript
const session = client.runSessionInteractive();

Typical usage wraps the client in try/finally:

Pattern

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

const client = await RuntimeClient.connect();
try {
  // examples below
} finally {
  client.close();
}