steps
Build a factory's own agent step. createAgentRunner opens a harness the way the built-in agent step does and hands back the live provider model.
Call these inside a factory-owned "use step" function, never from a workflow. Driver, DriverContext, AgentRunner and the types they reach are a published contract: a change to any of them is a breaking release.
Classes
AgentSessionError
A durable agent session is missing or cannot be resumed by this harness.
Extends
Error
Properties
| Property | Type | Default value |
|---|---|---|
name | "AgentSessionError" | "AgentSessionError" |
Interfaces
AgentRunner
A harness ready to run in a worktree, from createAgentRunner. Pass model to the AI SDK's generateText, read the session reference from its result with sessionFrom, and call close when the call is done.
Properties
| Property | Type | Description |
|---|---|---|
model | LanguageModel | The live provider model, with jigs' policy already applied. |
Methods
close()
close(): Promise<void>;Release the worktree lock and stop what the harness started. Safe to call twice.
Returns
Promise<void>
sessionFrom()
sessionFrom(result): AgentSessionRef | undefined;The session reference in a generateText result, for a later step to resume.
Parameters
| Parameter | Type |
|---|---|
result | { providerMetadata?: Record<string, Record<string, unknown>> | null; } |
result.providerMetadata? | Record<string, Record<string, unknown>> | null |
Returns
AgentSessionRef | undefined
AgentRunnerOptions
Where createAgentRunner runs a harness, and the session it resumes.
Properties
| Property | Type | Description |
|---|---|---|
cwd | string | The worktree the agent works in. |
resume? | AgentSessionRef | A session reference from an earlier call to resume. |
run | RunMetadata | The run the step belongs to: getWorkflowMetadata() inside the step. |
Check
One requirement check with a stable id and a label for reports.
Properties
| Property | Type |
|---|---|
id | string |
label | string |
Methods
run()
run(): Promise<CheckResult>;Returns
Promise<CheckResult>
Driver
How jigs runs one harness or model-source kind: its checks, the environment it may see, and how it asks, runs or opens a provider model. Each kind a descriptor can name has exactly one driver inside jigs; a factory cannot register another.
Remarks
A factory reads this to know what createAgentRunner does before it hands back a model. The shape is a published contract: changing it is a breaking release.
Type Parameters
| Type Parameter |
|---|
K extends HarnessKind | ModelKind |
Properties
Methods
ask()?
optional ask(request, context): Promise<ExecutorGeneration>;Parameters
| Parameter | Type |
|---|---|
request | | AgentRequest | ModelRequest |
context | DriverContext |
Returns
Promise<ExecutorGeneration>
decide()?
optional decide<QUESTIONS>(request, context): Promise<DecisionGeneration<QUESTIONS>>;Type Parameters
| Type Parameter |
|---|
QUESTIONS extends JevQuestions |
Parameters
| Parameter | Type |
|---|---|
request | AskJevOptions<QUESTIONS> |
context | DriverContext |
Returns
Promise<DecisionGeneration<QUESTIONS>>
descriptorChecks()?
optional descriptorChecks(source): Check[];Parameters
| Parameter | Type |
|---|---|
source | | Extract<OpenrouterSource, { kind: K; }> | Extract<OpenaiCompatibleSource, { kind: K; }> | Extract<OpenaiCodexSource, { kind: K; }> |
Returns
Check[]
envAllowlist()
envAllowlist(request): readonly string[];Parameters
| Parameter | Type |
|---|---|
request | DriverRequest |
Returns
readonly string[]
installationChecks()
installationChecks(): Check[];Returns
Check[]
jitChecks()?
optional jitChecks(target): Check[];Parameters
| Parameter | Type |
|---|---|
target | HarnessTarget |
Returns
Check[]
open()?
optional open(target, context): Promise<OpenedModel>;Build the live provider model for a run. Drivers without a provider model implement run.
Parameters
| Parameter | Type |
|---|---|
target | HarnessTarget |
context | OpenContext |
Returns
Promise<OpenedModel>
requestChecks()
requestChecks(request): Check[];Parameters
| Parameter | Type |
|---|---|
request | DriverRequest |
Returns
Check[]
resolveExecutable()?
optional resolveExecutable(env): string;Parameters
| Parameter | Type |
|---|---|
env | ProcessEnv |
Returns
string
run()?
optional run(request, context): Promise<ExecutorGeneration>;Parameters
| Parameter | Type |
|---|---|
request | Omit<RunAgentOptions<undefined>, "output"> & object |
context | DriverContext |
Returns
Promise<ExecutorGeneration>
DriverContext
What a driver receives for one call: the run it belongs to, the harness environment jigs built for it, and, for a structured call, the output spec a provider model consumes. deps is jigs' own wiring, not part of the contract.
Properties
| Property | Type |
|---|---|
env | Record<string, string> |
metadata | RunMetadata |
output? | Output<unknown, unknown, never> |
OpenContext
What a driver's open receives: the run and the harness environment jigs built.
Properties
| Property | Type |
|---|---|
env | Record<string, string> |
metadata | RunMetadata |
OpenedModel
A live provider model and what closing it releases.
Properties
| Property | Type |
|---|---|
model | LanguageModel |
Methods
close()
close(): Promise<void>;Returns
Promise<void>
Type Aliases
CheckResult
type CheckResult =
| {
detail?: string;
ok: true;
}
| {
ok: false;
reason: string;
repair: string;
};A check's outcome: a pass with an optional detail, or a failure with its repair.
DecisionGeneration
type DecisionGeneration<QUESTIONS> = object;What a driver's decide returns: one answer per question.
Type Parameters
| Type Parameter | Default type |
|---|---|
QUESTIONS extends JevQuestions | JevQuestions |
Properties
| Property | Type |
|---|---|
answers | JevAnswers<QUESTIONS> |
DriverRequest
type DriverRequest =
| AgentRequest
| ModelRequest
| AskJevOptions<JevQuestions>
| HarnessTarget;Any request a driver's checks and environment allowlist are asked about.
ExecutorGeneration
type ExecutorGeneration = ModelGeneration & object;What a driver's call returns: the reply text, provider metadata and any structured output.
Type Declaration
| Name | Type |
|---|---|
output? | unknown |
HarnessTarget
type HarnessTarget = object;A harness to open in a worktree, resuming a session when one is given.
Properties
| Property | Type |
|---|---|
cwd | string |
harness | Harness |
resume? | AgentSessionRef |
RunMetadata
type RunMetadata = Pick<WorkflowMetadata, "workflowRunId">;The run a step belongs to: getWorkflowMetadata() inside the step.
RunRequest
type RunRequest = Extract<AgentRequest, {
cwd: string;
}>;An agent request that runs in a worktree.
Functions
createAgentRunner()
function createAgentRunner(harness, options): Promise<AgentRunner>;Open a Claude Code or Codex harness inside a factory's own step, the way the built-in agent step does: the environment allowlist with the factory's agents.env, the request and just-in-time checks, the worktree lock, Codex's private home and app server, and the Claude spawn hook. The returned model is the live provider, ready for generateText.
Parameters
| Parameter | Type |
|---|---|
harness | Harness |
options | AgentRunnerOptions |
Returns
Promise<AgentRunner>
Remarks
Call it inside a "use step" function, never in a workflow. The step can hand the provider a function, such as a tool-approval hook or a logger, because a step runs where functions are allowed; pass it through the AI SDK call.
It throws JitCheckError when a just-in-time check fails, and AgentSessionError when resume names a session this harness cannot resume. Pi has no provider model, so a Pi descriptor throws: run Pi with runAgent.
Example
import type { AgentSessionRef, Harness } from "@jigs-ai/jigs";
import { createAgentRunner } from "@jigs-ai/jigs/steps";
import { generateText } from "ai";
import { getWorkflowMetadata } from "workflow";
export async function runWithTemperature(request: {
harness: Harness;
cwd: string;
prompt: string;
resume?: AgentSessionRef | undefined;
}) {
"use step";
const runner = await createAgentRunner(request.harness, {
cwd: request.cwd,
run: getWorkflowMetadata(),
resume: request.resume,
});
try {
const result = await generateText({ model: runner.model, prompt: request.prompt, temperature: 0 });
return { text: result.text, session: runner.sessionFrom(result) };
} finally {
await runner.close();
}
}