Define an Agent
Use defineAgent() to declare the purpose, permissions, workflow shape, and triggers of an Iron Gorilla agent.
defineAgent() is the entry point for authoring an Iron Gorilla agent. It describes what the agent
is for, what it can access, how it is triggered, and how the run is broken into durable steps.
The point of the definition is clarity. A good agent definition makes it obvious what the agent is allowed to do and what job it owns.
What belongs in the definition
identitygives the agent a stable purpose and authority context.toolsanddatadefine the governed surface available during execution.triggersdescribe how work enters the agent.manualInputdefines the exact manual-run form and screen order when a person starts the agent.workflowcaptures the intended action sequence.trustsets the starting posture for the run.stepsdefines the durable execution boundaries.
A minimal but realistic shape
import { defineAgent, step } from '@forge/sdk';
import { z } from 'zod';
const IntakePayload = z.object({
customerId: z.string(),
requestSummary: z.string(),
});
const TriageResult = z.object({
queue: z.string(),
priority: z.enum(['low', 'medium', 'high']),
});
export default defineAgent({
identity: {
name: 'support_triage',
scope: 'dept/support',
authority: 'support-operations',
},
tools: ['ticketing'],
data: {
permitted: ['support'],
prohibited: ['PHI'],
llmExcluded: ['PII'],
},
triggers: [{ id: 'manual-entry', type: 'manual', enabled: true }],
manualInput: {
fields: {
customerId: { type: 'string', label: 'Customer ID', required: true },
requestSummary: {
type: 'string',
label: 'Request summary',
},
},
screens: [
{
id: 'request',
title: 'Request',
fields: ['customerId', 'requestSummary'],
},
],
},
workflow: ['triage_request', 'route_ticket'],
trust: { initialTier: 'medium' },
steps: [
step('triage-request', IntakePayload, TriageResult, async (input) => {
// Read context, classify the request, and return a structured decision.
return {
queue: 'billing-review',
priority: 'medium',
};
}),
],
});What customer developers should optimize for
- A narrow business job instead of a broad assistant.
- Explicit trigger choices instead of “run somehow.”
- Minimal tools and data access.
- Step outputs that are easy for downstream systems or humans to inspect.
Step input context
Each step receives a canonical runtime input object. Manual and webhook object payload fields are
copied to the top level of input, and the original trigger payload is always available as
input.payload. Primitive payloads are available only as input.payload.
input.triggercontains trigger metadata such as id, type, source, and fired time.input.stepscontains completed step outputs keyed by step name.input.previouscontains the immediately preceding completed step output.input.workflow.completedStepscontains lightweight metadata for completed steps.
The top-level names payload, trigger, steps, previous, and workflow are reserved for the
runtime. If a payload object contains one of those fields, the runtime-owned value wins at the top
level and the original field remains available under input.payload.
Use those fields when one durable step needs to summarize, transform, or save the output of an earlier step.
Design advice
Treat the definition as a contract, not as incidental setup. If the shape is vague here, the run will be vague in production too.
For manual triggers, keep manualInput literal and simple. The GUI edits this exact block and the
API validates manual payloads against it before a job is created.
Supported manualInput leaf fields are string, number, boolean, and select.
Fields are optional by default. Add required: true when a run must include a value before it
can be queued.
Use select when the operator should choose from a small fixed set of safe modes, such as block
vs redact, instead of typing freeform text.
Source-mode agents can also pass dlpPolicy into kernel.callLLM() for per-call DLP behavior.
That override is intentionally code-authored today; the visual graph subset does not encode it.
For the exact public types, use the reference: