RuntimeClient exposes every runtime unary RPC. Connect via Connect to the runtime. For agent runs, prefer Phrony.
Version and sessions
getVersion(request?)
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.
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.
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)
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.
const { session } = await client.inspectSession({
sessionId: "sess_abc123",
});
// session.timeline — unified chronological audit view
// session.children — delegated child sessions (same shape, recursive)cancelSession(request)
await client.cancelSession({ sessionId: "sess_abc123" });completeSession(request)
await client.completeSession({ sessionId: "sess_abc123" });Publish and deploy — agents
publish(request)
manifest is the raw agent.yaml bytes.
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)
await client.deploy({
agentRef: { namespace: "default", name: "my-agent", version: "0.2.0" },
actor: "ci@example.com",
});rollback(request)
await client.rollback({
agentRef: { namespace: "default", name: "my-agent", version: "" },
toVersion: "0.1.0",
actor: "ops@example.com",
});getActiveVersion(request)
const active = await client.getActiveVersion({
agentRef: { namespace: "default", name: "my-agent", version: "" },
});
console.log(active.version);listDeployments(request)
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)
const record = await client.getAgentVersion({
agentRef: { namespace: "default", name: "my-agent", version: "0.2.0" },
});retireAgentVersion(request)
await client.retireAgentVersion({
agentRef: { namespace: "default", name: "my-agent", version: "0.1.0" },
});deprecateAgentVersion(request)
await client.deprecateAgentVersion({
agentRef: { namespace: "default", name: "my-agent", version: "0.1.0" },
});archiveAgent(request)
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.
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.
import { parseBundleRefVersionRequired } from "@phrony/sdk";
await client.deployBundle({
bundleRef: parseBundleRefVersionRequired("demo/payment-desk@1.0.0"),
actor: "ci@example.com",
});getActiveBundle(request)
const active = await client.getActiveBundle({
bundleRef: { namespace: "demo", name: "payment-desk", version: "" },
});
console.log(active.version, active.lockHash);listBundleDeployments(request)
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?)
const { agents } = await client.listAgents();
for (const a of agents) console.log(a.namespace, a.name);listAgentVersions(request)
const { versions } = await client.listAgentVersions({
agentRef: { namespace: "default", name: "my-agent", version: "" },
});listBundles(request?)
const { bundles } = await client.listBundles();
for (const b of bundles) console.log(b.namespace, b.name);listBundleVersions(request)
const { versions } = await client.listBundleVersions({
bundleRef: { namespace: "demo", name: "payment-desk", version: "" },
});Approvals
getApproval(request)
const approval = await client.getApproval({ approvalId: "appr_xyz" });listApprovals(request?)
const { approvals } = await client.listApprovals({
status: "pending",
sessionId: "",
route: "",
});decideApproval(request)
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.
const raw = client.work(); // grpc-js ClientDuplexStream — prefer WorkerrunSessionInteractive(metadata?, options?)
Returns InteractiveSession — see Interactive sessions.
const session = client.runSessionInteractive();Typical usage wraps the client in try/finally:
Pattern
import { RuntimeClient } from "@phrony/sdk";
const client = await RuntimeClient.connect();
try {
// examples below
} finally {
client.close();
}