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:
| Level | Use when |
|---|---|
| PURISTA level | Each agent needs its own queue, retry policy, model binding, sandbox, ownership boundary, or deployment surface. |
| Harness level | Several 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. Pass harness-local agents in the second argument when the workflow calls ctx.agents:
import { incidentReviewWorkflow } from './incidentReviewWorkflow.js'
import { evidenceAgent, riskAgent } from './workflowAgents.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, {
agents: {
evidence: evidenceAgent,
risk: riskAgent,
},
})
In this shape, PURISTA owns the outer queue, command, stream, HTTP exposure, and runtime wiring. The harness workflow owns the inner reasoning loop, and the supplied harness-local agents share the same session, sandbox, memory, telemetry, durable runtime, workspace store, and model bindings.
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.