Core Building Blocks / AI Agent

What is an Agent?

Understand agent types, model capabilities, session policies, and runtime requirements.

An agent is an AI-powered service participant. It receives typed input, uses a model to reason, optionally calls allowlisted command tools or child agents, and returns validated output.

Agents are core PURISTA definitions. getAgentQueueBuilder(...) lives on ServiceBuilder from @purista/core; low-level model/provider behavior comes from the bundled @purista/harness runtime and provider packages such as @purista/harness-openai.

AI on normal PURISTA rails

An attached agent expands into a queue, queue worker, command, and stream. It uses the same service, HTTP, queue, logging, OpenTelemetry, and deployment model as the rest of PURISTA.

Execution types

Agents can be defined in three mutually exclusive ways:

TypeMethodUse case
Run functionsetRunFunction(fn)Custom PURISTA logic with direct model, resource, tool, and child-agent access.
Harness agentsetHarnessAgent(definition)Wrap one reusable @purista/harness agent definition.
Harness workflowsetHarnessWorkflow(definition)Wrap one reusable @purista/harness workflow definition.

You must pick exactly one execution type per agent.

Model capabilities

Agents declare model aliases and the capabilities they need:

.addModel('primary', {
  model: 'gpt-4.1-mini',
  capabilities: ['object', 'text'],
  defaults: { temperature: 0.2 },
})

The alias is available as context.harness.models.primary. Runtime startup fails when a declared alias is missing or the bound provider does not satisfy the declared capabilities.

Runtime requirements

Services with attached agents need:

  • a queueBridge
  • ai.models runtime bindings for every declared model alias
  • provider packages for concrete model backends, such as @purista/harness-openai
const service = await supportV1ServiceBuilder.getInstance(eventBridge, {
  queueBridge,
  ai: {
    models: {
      primary: {
        provider,
        model: 'gpt-4.1-mini',
        capabilities: ['object'],
      },
    },
  },
})

Session policy

Agents default to an ephemeral session. Use conversation mode when a payload field should identify a continuing AI conversation:

.setSessionPolicy({
  mode: 'conversation',
  payloadPath: ['conversationId'],
})

Keep transport identifiers (message.id, traceId, correlationId) separate from AI conversation identity.

HTTP response shape

Agents can expose either a simple JSON response or a streamed SSE response:

.exposeAsHttpEndpoint('POST', 'agents/support', {
  streamingMode: 'aggregate', // or 'stream'
})

For long-running agents, use setResponseMode('accepted', ...) so the HTTP call returns a jobId and runId instead of waiting for the final model result.

Tools and skills

Agents can call allowlisted commands and child agents:

.canInvoke('UserService', '1', 'getUser')
.canInvokeAgent('triageAgent', '1')
.useSkills(['customer-support'])
.useBuiltInTools(false)

Keep deterministic business truth in services, commands, stores, resources, queues, and subscriptions. Agent output should become canonical only after deterministic validation and application logic.