Core Building Blocks / AI Agent

Agent Workflows

Compose agents through PURISTA boundaries or wrap harness workflow definitions.

Agent workflows can be modeled at two levels:

LevelUse when
PURISTA levelEach agent needs its own queue, retry policy, model binding, sandbox, ownership boundary, or deployment surface.
Harness levelSeveral reasoning steps should run inside one @purista/harness workflow definition with shared session and sandbox semantics.

Prefer PURISTA-level orchestration when the workflow crosses business boundaries. Use harness-level workflow definitions for tightly coupled inner reasoning steps.

PURISTA-level orchestration

Use canInvokeAgent(...) to allow one agent to call another attached PURISTA agent:

export const reviewCoordinatorAgentBuilder = projectV1ServiceBuilder
  .getAgentQueueBuilder('reviewCoordinator', 'Coordinates project review agents')
  .addPayloadSchema(reviewInputSchema)
  .addOutputSchema(reviewOutputSchema)
  .addModel('primary', {
    model: 'gpt-4.1-mini',
    capabilities: ['object'],
  })
  .canInvokeAgent('requirementsReview', '1', {
    payloadSchema: reviewInputSchema,
    outputSchema: reviewFindingSchema,
  })
  .canInvokeAgent('securityReview', '1', {
    payloadSchema: reviewInputSchema,
    outputSchema: reviewFindingSchema,
  })
  .setRunFunction(async context => {
    const [requirements, security] = await Promise.all([
      context.invoke.agents['requirementsReview.1'].run(context.payload),
      context.invoke.agents['securityReview.1'].run(context.payload),
    ])

    return reviewOutputSchema.parse({
      findings: [...requirements.findings, ...security.findings],
    })
  })

Each child agent keeps its own generated queue, worker, command, stream, execution policy, and runtime binding.

Harness-level workflows

Use setHarnessWorkflow(...) only when you already have a workflow definition from @purista/harness and want to expose it as one PURISTA agent:

import { incidentReviewWorkflow } from './incidentReviewWorkflow.js'

export const incidentWorkflowAgentBuilder = incidentV1ServiceBuilder
  .getAgentQueueBuilder('incidentReview', 'Reviews incident evidence')
  .addPayloadSchema(incidentReviewWorkflow.input)
  .addOutputSchema(incidentReviewWorkflow.output)
  .addModel('primary', {
    model: 'gpt-4.1-mini',
    capabilities: ['object', 'tool_use'],
  })
  .setHarnessWorkflow(incidentReviewWorkflow)

In this shape, PURISTA owns the outer queue, command, stream, HTTP exposure, and runtime wiring. The harness workflow owns the inner reasoning loop.

Streaming workflow output

The HTTP response shape is still selected with streamingMode:

.exposeAsHttpEndpoint('POST', 'agents/incident-review', {
  streamingMode: 'stream',
})

Use aggregate for a final JSON response and stream for server-sent events while the workflow runs.