Skip to content
ZHIVEXDocs

Agents, tools, and sessions

Build a tool-using agent, add durable multi-turn sessions, and introduce approval boundaries.

TypeScriptStable
Source baseline · reviewed Aug 20, 2026

Use Agent when the model should choose whether to call tools or delegate work. Wrap it in Runner + SessionService when the experience belongs to a user-facing, multi-turn product.

Create an agent

import { Agent, tool } from "@zhivex-ai/sdk";
import { createOpenAI } from "@zhivex-ai/openai";
import { z } from "zod";

const openai = createOpenAI({ apiKey: process.env.OPENAI_API_KEY });

const agent = new Agent({
  model: openai("gpt-4o-mini"),
  instructions: "Answer with verified account facts and keep replies short.",
  maxSteps: 3,
  tools: {
    lookupAccount: tool({
      name: "lookupAccount",
      schema: z.object({ accountId: z.string() }),
      execute: async ({ accountId }) => loadAccount(accountId)
    })
  }
});

const result = await agent.run({
  prompt: "Check account acct_123."
});

console.log(result.outputText);
console.log(result.state);

Every run returns serializable state with messages, steps, tool results, approvals, usage, status, schema version, and revision. Persist that state or attach an SDK run store when a process restart must not lose the run.

Add multi-turn sessions

import {
  createFileSessionService,
  createRunner
} from "@zhivex-ai/sdk";

const runner = createRunner({
  appName: "support-copilot",
  agent,
  sessionService: createFileSessionService({
    directory: ".zhivex/sessions"
  })
});

const first = await runner.run({
  userId: "user_123",
  sessionId: "demo",
  prompt: "Remember that I prefer short answers."
});

const second = await runner.run({
  userId: "user_123",
  sessionId: first.session.sessionId,
  prompt: "Summarize the account status."
});

File-backed sessions are useful for local development. Use Postgres for shared or serverless production deployments.

Pause before a side effect

Local tools can interrupt the run and wait for an application-owned approval decision:

const deploy = tool({
  name: "deploy",
  schema: z.object({ target: z.string() }),
  requiresApproval: true,
  approvalMode: "interrupt",
  approvalVersion: "2026-07-29",
  execute: async ({ target }, context) =>
    deployRelease(target, {
      signal: context?.abortSignal,
      idempotencyKey: context?.idempotencyKey
    })
});

The SDK can bind and persist approval state, but your application still owns identity, role checks, queue-token validation, expiration, audit records, and one-time consumption.

For a governed application boundary, TypeScript 1.5 exposes the Stable @zhivex-ai/agents/control-plane entrypoint. It composes capsules, tool policy, approval queues, ledgers, capability routing, inspectable runs, and durable single-consumer approval resume. This is a library contract, not a hosted control plane: the application still owns IAM, tenancy, secrets, storage, network policy, and the approval UI.

Agent or workflow?

  • Use an agent when the model chooses the next action.
  • Use a workflow when the application already knows the sequence.
  • Use subagents when the model should decide whether to delegate.
  • Use a parallel workflow group when application code always fans out.

For a product UI and server route, continue with the Next.js integration.

For model-directed delegation, continue with subagents. If application code already knows the order, use a workflow instead.

For low-latency audio or text sessions, use the Stable shared realtime lifecycle and streamLiveAgent() described in multimodal and realtime. Provider model IDs and preview availability remain provider-scoped even though the shared SDK contract is Stable.

Zhivex AI SDKsPortable by default. Native when needed.
Copied