Studio previewSelf-host Studio locally.Run it

Main API Surface (kortyx)

Updated 3 days ago • October 4, 2026

packages/kortyx/src/index.ts is the public facade.

Re-export groups

Agent

export { createAgent } from "@kortyx/agent"; export type { CreateAgentArgs } from "@kortyx/agent";

Created agent methods:

  • agent.streamChat(messages, options?) → AsyncIterable<StreamChunk>

Conversation evals

import { createEvals, createEvalJudge, createStudioEvalJudge, createEvalRouteHandler, defineSuite, parseEvalSuite, getEvalSuiteRevision, type EvalSuite, type EvalJudge, } from "kortyx";

createEvals({ agent, suites, setup?, execute?, responders?, references?, judge?, teardown?, paramsSchema?, defaults? }) returns run, listSuites and describe. It runs sequential conversational cases through the existing agent, including expected interrupt/resume steps. createEvalJudge({ model, id?, version? }) grades each criterion using a configured provider. judge is optional for Studio-triggered execution: Studio selects its backend judge or the app's code judge per run. Direct SDK runs with semantic criteria require a code judge. defineSuite({ id, cases }) checks the authoring shape without adding runtime behavior. createStudioEvalJudge({ url, apiKey, environment }) asynchronously discovers a Studio-hosted judge for explicit use from server code. createEvalRouteHandler({ evals, serviceKey, ...limits }) mounts an authenticated GET manifest and POST NDJSON execution endpoint.

Suite and wire schemas are browser-safe from @kortyx/agent/evals; execution helpers belong in server code. See Conversation Evals for typed app setup, a complete example, lifecycle limits and observable scope.

Core workflow/state contracts

export { defineWorkflow, loadWorkflow, validateWorkflow, } from "@kortyx/core";

Plus types like GraphState, NodeResult, WorkflowDefinition, WorkflowId.

Hooks

export { createWorkflowHooks, defineOutputContract, parallel, ParallelError, reportError, useWorkflow, WorkflowCallError, useInterrupt, useReason, useTool, useNodeState, useStructuredData, useWorkflowState, } from "@kortyx/hooks";

useTool({tool, input, id?, abortSignal?}) executes a shared tool immediately and returns its inferred result. It creates observations without adding a model call or MCP transport. UseToolArgs, KortyxExecutableTool, ToolOutcomes, ToolOutcomeDescriptor, ToolTelemetry and ToolErrorDetails are exported types. See Hooks.

defineOutputContract({ description, schemaId, schemaVersion, schema, stream? }) creates a reusable typed output contract. Pass named contracts to useReason({ outputs: { emit, return } }) or use one directly with useStructuredData({ contract, data }). See Hooks and Stream Protocol.

reportError(error, {severity?, metadata?, tags?}) records a handled error on the active workflow span without stopping execution. Thrown errors are recorded automatically and retain their ordinary retry/failure behavior. ReportErrorOptions is exported for wrappers and custom hooks.

useWorkflow({ id, workflow, input }) returns a promise of { data }. Typed definitions and bound registries infer input/output from the child's schemas; dynamic unbound strings return Record<string, unknown>. WorkflowCallError represents a rejected child invocation. See Call Child Workflows.

parallel([useWorkflow(...), useWorkflow(...)]) returns an inferred result tuple in input order. It joins independent children under shared execution control and preserves their snapshots before suspension. ParallelError.results exposes terminal fulfilled/rejected outcomes; interrupts, cancellation and limits remain control flow. The parent exposes approval only after every sibling finishes, fails or suspends, so a still-running sibling delays the request. Multiple child questions use the existing parent resume handle one at a time; immediate and batched approval delivery are not supported. See parallel child workflows.

Providers

export * from "@kortyx/providers";

Install provider implementation packages separately (for example @kortyx/google).

Runtime + registries + framework adapters

export { clearRegisteredNodes, createFileWorkflowRegistry, createFrameworkAdapterFromEnv, createInMemoryFrameworkAdapter, createInMemoryWorkflowRegistry, createRedisFrameworkAdapter, getRegisteredNode, listRegisteredNodes, registerNode, } from "@kortyx/runtime";

Stream helpers

export { collectBufferedStream, collectStream, consumeStream, createStreamResponse, readStream, summarizeStreamChunks, toSSE, } from "@kortyx/stream"; export type { BufferedStreamResult, StreamChunk } from "@kortyx/stream";
  • collectStream(...): raw chunk array
  • collectBufferedStream(...): { chunks, text, structured }

Browser entry

packages/kortyx/src/browser.ts exports browser-safe pieces:

  • readStream
  • StreamChunk type

Use this entry for client-only bundles where you want to avoid Node-only runtime exports.

Workflow execution

agent.execute({ workflow, input, sessionId?, context? }) returns a typed ExecutionResult for a registered workflow with input/output schemas. agent.resume({ workflow, resume, response }) continues a suspended execution, including nested children. Outcomes are completed, suspended, cancelled, or failed; invalid commands reject with ExecutionRequestError. See Execute and Resume Workflows.

Response completion and pending interrupts

  • completeResponse(options?: { message?: string; data?: unknown }): Promise<void>: close chat output from a root node, continuing execution.
  • agent.listInterrupts({ sessionId?, runId?, context?, status?: "pending", afterResponseCompleted? }): list ready, unexpired public interrupt summaries. Supply at least one nonempty authorized scope.
  • agent.getInterrupt(id, { sessionId?, runId?, context? }): lookup within scope; returns null or the summary plus a private server-only resume handle.
  • agent.streamChat(messages, { onExecution?, executionSignal?, clientTurnId?, onResponseFinalized?, continueOnDisconnect?, ... }): observe attempt completion and optionally collect a finalized visible message independent of HTTP consumption.
  • createChatRouteHandler({ agent, onExecution?, disconnect?, onTurnAccepted?, onResponseFinalized?, onLifecycleError? }): connect host lifetime and optional app-owned transcript persistence. Hooks require sessionId and clientTurnId; disconnect: "continue" requires onExecution.
  • createCheckpointRouteHandler({ agent, onForked?, onRolledBack?, onLifecycleError? }): report successful runtime fork and rollback facts so the app can update its transcript. The hooks do not make runtime and app writes atomic.

Existing useInterrupt and agent.resume APIs remain unchanged. See the complete guide for ordering, checkpoints, scope authorization, parallel branches, and Studio's optional read-only role. For the server-owned transcript callback contract, see Server-Owned Chat Transcripts.

Tool faults automatically include their error type and bounded message, with no extra wiring. An optional tool.telemetry.error(error) override returns {type, message} or null to replace or suppress diagnostics before export. Stack traces, exception causes/custom fields and raw tool inputs/results remain excluded.

KortyxErrorDetails and KortyxTraceErrorProjection are exported tracing types. Configured Studio/OpenTelemetry adapters automatically capture bounded exception type/message/stack/cause diagnostics; their optional error projection can replace or suppress that diagnostic. JSON/schema parsing errors remain separately diagnosable even when the provider stopped normally. This does not change client-facing execution/HTTP failure descriptors.