Skip to main content
This guide explains how to build a custom specialist agent that can run in the Terminus execution layer. If you need basic setup first, start with Quickstart.

1) Define the Role Before Writing Code

A useful custom agent starts with a clear scope. Define:
  • task domain (what problems this agent should solve),
  • acceptance criteria (what a good answer must include),
  • tool boundary (what external actions/data it may use),
  • failure behavior (how it should respond when uncertain or blocked).
Avoid “general assistant” positioning.
Specialists perform better when they are narrow and explicit.

2) Create the Agent Module

Add a new file in terminus-agents/src/agents/, for example market-intel.ts. The file should export two things:
  1. AgentDefinition (id, description, prompt, tools),
  2. Tool implementation map (async functions returning JSON-safe objects).
import type { AgentDefinition, ToolParams } from './types.js';

export const MarketIntelAgent: AgentDefinition = {
  id: 'market-intel',
  name: 'Market Intelligence',
  description: 'Summarizes sector signals and market events.',
  systemPrompt: 'You are a market intelligence specialist.',
  keywords: ['market', 'macro', 'earnings', 'signals'],
  tools: [
    { name: 'getSectorNews', description: 'Fetch sector headlines', parameters: ['sector'] },
    { name: 'scoreMomentum', description: 'Score momentum', parameters: ['ticker', 'window'] }
  ]
};

export const MarketIntelTools: Record<string, (params: ToolParams) => Promise<unknown>> = {
  getSectorNews: async (params) => ({ sector: params.sector, headlines: [] }),
  scoreMomentum: async (params) => ({ ticker: params.ticker, window: params.window, score: 0.0 })
};

3) Register It in the Runtime

Update terminus-agents/src/agents/index.ts:
  • import the new AgentDefinition,
  • import the tool map,
  • add the agent to AGENTS,
  • merge tool map into ALL_TOOLS.
If any one of these is missing, the node can start but your new specialist will not be dispatchable.

4) Keep Tool Contracts Strict

Tool reliability is usually where custom agents fail. Guidelines:
  • validate required params before tool execution,
  • return stable object shapes,
  • keep response payloads compact,
  • include machine-readable status fields where possible,
  • avoid hidden side effects.
Good:
  • { success: true, items: [...] }
Bad:
  • mixed string/object responses,
  • huge raw dumps with no schema,
  • silent partial failures.

5) Validate Locally End-to-End

From terminus-agents/:
npm install
npm run build
npx terminus-agent doctor --full
npx terminus-agent init --profile local --force
npx terminus-agent run
Validation checklist:
  • agent shows up in selection/config,
  • tool calls are executed and logged correctly,
  • no unhandled exceptions in execution loop,
  • outputs remain bounded and parseable.

6) Match Identity to Runtime

When NFT-gated policy is active, node admission depends on identity checks.
In practice this means your runtime identity must match expected agent type and wallet ownership rules.
Before mainnet-style operation:
  • verify wallet/private-key alignment,
  • verify identity metadata alignment with configured role,
  • verify payout destination settings.

7) Production Hardening Checklist

Before promoting a custom agent to real routing:
  1. run adversarial prompts (ambiguous, incomplete, contradictory),
  2. test timeout and degraded-provider behavior,
  3. confirm no sensitive data is logged,
  4. measure p95 latency and failure rate,
  5. verify quality against a fixed evaluation set.
A custom agent is production-ready when it is predictable under failure, not only impressive on best-case prompts.

8) Common Failure Patterns

  • over-broad prompts that break specialization,
  • tools returning inconsistent schemas,
  • provider-specific assumptions leaking into generic code paths,
  • long unbounded outputs that break aggregation,
  • lack of fallback behavior when a tool fails.
Treat these as first-class engineering issues, not tuning details.