Agentlang Syntax Reference (v1.0)
Agentlang is a declarative, schema-first language for defining intelligent agent systems, workflows, and data models. It combines structured data modeling, event-driven workflows, and agentic logic into a unified syntax.
1. Lexical Structure
1.1 Modules and Imports
module <ModuleName>
import "<path>" @as <alias>Modules provide namespaces for all entities, agents, and workflows.
Example:
module acme.erp
import "emailClient.js" @as email2. Top-Level Declarations
Each Agentlang file may contain one or more of the following top-level constructs:
<ModuleDecl> |
<RecordDecl> |
<EntityDecl> |
<RelationshipDecl> |
<EventDecl> |
<WorkflowDecl> |
<DecisionDecl> |
<AgentDecl> |
<ScenarioDecl> |
<DirectiveDecl> |
<GlossaryDecl> |
<FlowDecl>3. Data Model Definitions
3.1 Records
A record defines a reusable structure — similar to a value object.
record <Name> {
<FieldList>
}Example
record Address {
street String,
city String,
pincode Int
}3.2 Entities
An entity represents a persistent model with identity and optional relationships.
entity <Name> [extends <Base>] {
<FieldList>
}Example
entity Employee {
email Email @id,
name String,
salary Decimal
}3.3 Attributes and Properties
Each field in an entity or record can include attribute properties (prefixed with @):
| Attribute | Description |
|---|---|
@id | Marks the unique identifier for an entity |
@indexed | Creates an index for faster lookup |
@default(value) | Provides a default value (supports uuid() and now()) |
@optional | Field may be omitted |
@unique | Value must be unique |
@readonly | System-generated value |
@check(<functionName>) | JavaScript predicate function for validation |
@enum("a", "b", ...) | Restricts values to one of the listed strings |
@oneof(<Entity.Attribute>) | Value must exist in referenced entity attribute |
Example
entity Invoice {
id UUID @id @default(uuid()),
createdAt DateTime @default(now()),
amount Decimal @check(isPositive),
status @enum("draft", "sent", "paid"),
customerId UUID @oneof(Customer.id)
}3.4 Relationships
Relationships define semantic links between entities.
relationship <Name> {
<EntityA> <Verb> <EntityB>
}Example
relationship EmployeeReportsTo {
Employee reports_to Manager
}4. Events
Events are transient, data-bearing triggers.
event <Name> {
<FieldList>
}Example
event giveIncrementToEmployee {
employeeEmail Email,
increment Decimal
}5. Workflows
A workflow defines a procedural or reactive process.
workflow <Name> {
<WorkflowBody>
}5.1 Workflow Patterns
{<Entity> {<field> <value>, ...}}Example:
{Employee {email "jane@acme.com", salary 50000}}5.2 Query Syntax
Use ? to query entities:
{Employee {email? "john@acme.com"}}Query all:
{Employee? {}}The default query operator is = (is-equals) which need not be specified. You can attach other comparison operators to ?.
For instance, to query all students who is older than 10 years:
{Student {age?> 10}}The full list of query-operators:
=, <>, !=, <, <=, >, >=, in, like, betweenSome examples:
{Student {age?between [10, 15]}}
{Student {name?like "Mat%"}}5.3 Delete and Upsert
delete {E {id? 1}}
{E {id 1, v 10}, @upsert}5.4 Control Flow
if (<condition>) { ... } else { ... }
for (<x> in <collection>) { ... }5.5 CRUD Hooks
workflow @before create:<Entity> { ... }
workflow @after update:<Entity> { ... }Example:
workflow @after create:Employee {
console.log("Employee created: " + this.email)
}5.6 JavaScript Integration
import "emailClient.js" @as email
workflow sendMail {
email.sendMail(sendMail.to, sendMail.body)
}6. Decisions
A decision defines conditional logic as discrete cases.
decision <Name> {
case (<condition>) { <Result> }
case (<condition>) { <Result> }
}Example
decision classifyOrder {
case (carType == "EV" and segment == "economy") { EconomyEV }
case (carType == "SUV" and segment == "luxury") { LuxurySUV }
}7. Agents
An agent represents an intelligent autonomous process.
Agents can be chat or planner types.
agent <Name> {
role "<string>",
instruction "<template-string>",
tools [<WorkflowName>, ...],
directives [<DirectiveList>],
scenarios [<ScenarioList>],
glossary [<GlossaryList>],
type "chat" | "planner"
}Example
agent employeeIncrement {
role "You decide salary increments",
instruction "Based on total sales {{totalSales}} of {{employeeEmail}}, give the right increment",
tools [giveIncrementToEmployee],
directives [
{"if": "sales > 5000", "then": "increment .5"},
{"if": "sales between 2000 and 5000", "then": "increment .2"}
],
scenarios [
{"user": "sales 5600 for jake@acme.com", "ai": "[{acme.core/giveIncrementToEmployee {email \"jake@acme.com\", increment .5}}]"}
]
}7.1 Glossary Entries
glossary <AgentName>.<id> {
"name": "<term>",
"meaning": "<definition>",
"synonyms": "<comma-separated synonyms>"
}7.2 Directives and Scenarios
directive <AgentName>.<id> {"if": "<condition>", "then": "<action>"}
scenario <AgentName>.<id> {"user": "<input>", "ai": "<response>"}8. Flows
A flow defines the orchestration between multiple agents or events.
flow <Name> {
<Source> --> <Target>
...
}
@public agent <FlowName> {
instruction "<role description>"
}Example:
flow incrementProcess {
findEmployeeSales --> employeeIncrement
}
@public agent incrementProcess {
role "You manage employee increments"
}9. Scratchpad and Context
- The scratchpad is an in-memory data context populated during a flow.
- Template placeholders (
{{...}}) in agent instructions resolve values from the scratchpad. thisrefers to the current entity or event context.
10. Expression Syntax
| Operator | Meaning |
|---|---|
== | equality |
!= | inequality |
> / < / >= / <= | numeric comparisons |
and / or / not | logical operators |
+, -, *, / | arithmetic |
. | field access |
? | query marker |
11. Comments
// Single-line comment
/* Multi-line comment */12. Reserved Keywords
module, import, record, entity, relationship, event, workflow, agent,
decision, flow, delete, if, else, for, in, let, case, role, instruction,
tools, directives, scenarios, glossary, @before, @after, @on, @public,
extends, @id, @indexed, @optional, @default, @unique, @readonly,
@check, @enum, @oneof13. Example — Full Agentlang Module
module acme.erp
entity Employee {
email Email @id,
name String,
salary Decimal
}
entity EmployeeSales {
id UUID @default(uuid()),
employee Email,
totalSales Decimal
}
event giveIncrementToEmployee {
employeeEmail Email,
increment Decimal
}
workflow giveIncrementToEmployee {
{Employee {email? giveIncrementToEmployee.employeeEmail,
salary salary + salary * giveIncrementToEmployee.increment}}
}
agent employeeIncrement {
role "You decide increments for employees",
instruction "Based on {{totalSales}} for {{employeeEmail}}, decide increment",
tools [giveIncrementToEmployee],
directives [{"if": "sales > 5000", "then": "increment .5"}]
}
flow incrementProcess {
findEmployeeSales --> employeeIncrement
}
@public agent incrementProcess {
role "Manage the salary increment process"
}14. Grammar (EBNF Summary)
Module = "module" Identifier { TopLevelDecl } ;
TopLevelDecl = RecordDecl | EntityDecl | RelationshipDecl |
EventDecl | WorkflowDecl | AgentDecl | DecisionDecl | FlowDecl ;
RecordDecl = "record" Identifier "{" FieldList "}" ;
EntityDecl = "entity" Identifier [ "extends" Identifier ] "{" FieldList "}" ;
FieldList = { Identifier Type [ AttributeList ] "," } ;
AttributeList = { "@" Identifier [ "(" Expression ")" ] } ;
EventDecl = "event" Identifier "{" FieldList "}" ;
WorkflowDecl = "workflow" [ WorkflowQualifier ] Identifier "{" WorkflowBody "}" ;
WorkflowQualifier = "@" Identifier [ ":" Identifier ] ;
WorkflowBody = { WorkflowStmt } ;
WorkflowStmt = Pattern | DeletePattern | IfStmt | ForStmt | JsCall ;
Pattern = "{" Identifier "{" FieldAssignments "}" [ "," "@" "upsert" ] "}" ;
DeletePattern = "delete" Pattern ;
DecisionDecl = "decision" Identifier "{" { CaseClause } "}" ;
CaseClause = "case" "(" Expression ")" "{" Identifier "}" ;
AgentDecl = "agent" Identifier "{" AgentBody "}" ;
AgentBody = { AgentField } ;
AgentField = "role" StringLiteral |
"instruction" StringLiteral |
"tools" "[" Identifier { "," Identifier } "]" |
"directives" "[" JsonList "]" |
"scenarios" "[" JsonList "]" |
"glossary" "[" JsonList "]" |
"type" StringLiteral ;
FlowDecl = "flow" Identifier "{" { FlowEdge } "}" ;
FlowEdge = Identifier "-->" Identifier ;