Skip to content

openBody ​

Function, in @jr2/orchestrator/src/open-body.ts. It is an export of @jr2/orchestrator, on the Authoring surface page, in Charts.

ts
function openBody(decl: OpenBodyDeclaration): OpenBodyLogic

Make an Open body: the actor slot that a Chart binds. Put it in actors, and invoke it from a state with { chart, ...input }. chart is the text of a Chart, or { name } for a named Chart of this wrapper. The other keys are the input of the Chart, which it reads as {{input.<key>}}. A Machine with an Open body is a Chart wrapper.

Each Agent Turn of the Chart runs where the Open body runs: in the Sandbox of its workspace(), or on the Instance Harness. The Open body ends with an OpenBodyOutput.

It refuses a declaration that is not correct: openBody: <problem>; <problem>, for example ceilings.turns: missing; an Open body states every ceiling. createMachine refuses a lent name that the Machine does not have: machine "<id>": Open body "<slot>": lends.agents: "<name>" is no actor slot of this Machine; its actors: <slots>.

Parameters

Returns: The actor logic of the slot.

Example

ts
import { assign } from "xstate";
import { z } from "zod";
import { agent, chartSchema, fail, jr2Setup, openBody, type OpenBodyOutput } from "@jr2/orchestrator";

// `chart` is a Chart, so a run input can carry one, and Charts can have names.
const door = z.object({ topic: z.string(), chart: chartSchema });
type Input = z.infer<typeof door>;
type Context = Input & { result?: OpenBodyOutput };

export const machine = jr2Setup({
  types: {} as { context: Context; input: Input },
  actors: {
    writer: agent({
      model: "anthropic/claude-haiku-5-5",
      workspace: "none",
      instructions: "You write clear, short text for engineers.",
    }),
    body: openBody({
      lends: { agents: ["writer"] },
      allows: { models: [], workspace: [] },
      ceilings: { turns: 6, wallClock: "15m", transitions: 200, fanOut: 1, size: 65536 },
    }),
    fail: fail(),
  },
}).createMachine({
  id: "notes",
  input: door,
  context: ({ input }) => ({ ...input }),
  // The fault of `writer` when a Chart does not route it: the Open body sends it here.
  on: { "agent.fault": ".failed" },
  initial: "running",
  states: {
    running: {
      invoke: {
        src: "body",
        input: ({ context }: { context: Context }) => ({ chart: context.chart, topic: context.topic }),
        onDone: { target: "done", actions: assign({ result: ({ event }) => event.output as OpenBodyOutput }) },
      },
    },
    done: { type: "final" },
    failed: { invoke: { src: "fail", input: { reason: "the Agent's Turn could not go on" } } },
  },
});

See also

The docs of Kit version 0.5.1. Each page is also at its .md URL.