Schema Definition
An Agentlang app is organized into modules that define data models, relationships, workflows, and LLM-powered agents.
1. Module
A module is the fundamental unit of organization in Agentlang. Each module defines a namespace and can contain definitions for:
- Records
- Entities
- Relationships
- Events
- Workflows
- Agents
Syntax
module <name>Example
module school.coreThe fully qualified name (FQN) of any element is constructed as:
<module-name>$<definition-name>2. Records and Entities
Overview
record and entity definitions describe structured data types composed of attributes.
- A record defines a data structure that is not persisted by default.
- An entity defines a persisted structure, automatically managed by the Agentlang runtime.
Syntax
record <name> [extends <parent-record>] {
<attribute-list>
}
entity <name> [extends <parent-record-or-entity>] {
<attribute-list>
}Attributes
Each attribute has:
- A name
- A type
- Optional annotations (tags)
<name> <Type> [@annotation]Example
record Person {
firstName String,
lastName String,
dateOfBirth Date,
gender @enum("male", "female", "other")
}
entity Teacher extends Person {
employeeId Int @id,
dateOfJoining Date,
email Email
}Notes
-
Every entity has an internal attribute called
path(of typePath), automatically generated by the runtime. -
The
pathuniquely identifies an entity instance using the pattern:<fully-qualified-entity-name>/<id-value>Example:
school.core$teacher/101 -
The
@idannotation marks the identifier attribute for that entity. -
An entity may inherit attributes from a parent record or entity.
3. Attribute Types
The following types are supported:
| Type | Description |
|---|---|
String | Text data |
Int | Integer value |
Number / Float / Decimal | Numeric types |
Boolean | True/False |
Email | Valid email address |
Date, Time, DateTime | Temporal types |
UUID | Universally unique identifier |
URL | Web address |
Path | Internal entity path |
Password | Secret string |
Map | Key-value map |
Any | Arbitrary value type |
Array attributes
An attribute can be specified to be an array of a base type.
entity Student {
id UUID @id,
name String,
courses String[] // array of course names
}Attribute Properties
Agentlang allows attributes within entity and record definitions to be annotated with special decorators that control their behavior, constraints, and persistence.
These decorators define schema-level metadata similar to database constraints or type-system refinements.
General Syntax
entity Example {
id UUID @id @default(uuid()),
name String @indexed @unique,
createdAt DateTime @default(now()) @readonly,
status String @enum("draft", "published", "archived") @default("draft"),
category String @oneof(Category.name),
description String @optional
}List of Supported Attribute Properties
| Property | Description | Example |
|---|---|---|
| @id | Marks the attribute as the primary identifier of the entity or record. Each entity must have one. | id UUID @id |
| @indexed | Indexes the attribute for faster lookup during queries. Can be applied to frequently queried fields. | email String @indexed |
| @default(value) | Assigns a default value when a new instance is created without an explicit value. The value can be a literal, an expression, or a built-in function. | createdAt DateTime @default(now()) |
| @optional | Marks the attribute as optional. Such fields may be omitted when creating or updating instances. | photo URL @optional |
| @check(functionName) | Provides a validation predicate (a JavaScript function) that must return true for the value to be accepted. Used for advanced custom checks. | age Int @check(isAdult) |
| @unique | Ensures all instances of the entity have a unique value for this attribute. | email Email @unique |
| @readonly | Indicates that the value is system-generated or immutable. Cannot be modified by users or workflows. | id UUID @id @readonly @default(uuid()) |
| @enum(value1, value2, …) | Restricts the attribute to a fixed set of string values (enumeration). | status String @enum("draft", "published", "archived") |
| @oneof(Entity.Attribute) | Enforces referential constraint — the value must exist in another entity’s attribute list. | category String @oneof(Category.name) |
Built-in Default Functions
| Function | Description | Example |
|---|---|---|
uuid() | Generates a new universally unique identifier (UUID). | id UUID @id @default(uuid()) |
now() | Returns the current system timestamp (for DateTime attributes). | createdAt DateTime @default(now()) |
Example: Full Entity Definition
entity Product {
id UUID @id @default(uuid()),
name String @unique @indexed,
category String @oneof(Category.name),
price Decimal @check(isPositive),
status String @enum("draft", "published", "archived") @default("draft"),
createdAt DateTime @default(now()) @readonly,
updatedAt DateTime @default(now())
}This definition ensures:
- Each product has a unique
idgenerated automatically. nameis unique and searchable.categorymust refer to an existingCategory.name.pricepasses a validation predicateisPositive.statusdefaults to"draft".createdAtis set automatically and cannot be changed later.
Meta Settings
An entity definition can have some meta settings which can be used to control certain behavior related to persistence.
| Settings | Description |
|---|---|
| audit | if true, all CRUD on the entity will be audited (in a separate table) |
| fullTextSearch | an array of attribute names that needs to be indexed for full text search. |
See the section on configuration for more details on enabling audit.
If the fullTextSearch setting in *, all attributes will be indexed.
An example of fullTextSearch:
entity Person {
email Email @id,
name String,
address String,
@meta {"fullTextSearch": [address]}
}
// search all persons that match a given, partial-address
{Person? "Queens, New York"}4. Relationships
A relationship defines how two entities are connected.
Types of Relationships
| Type | Description |
|---|---|
between | Defines a many-to-many association between two entities |
contains | Defines a hierarchical (parent-child) relationship; defaults to one-to-one, but can be made one-to-many with @one_many |
Syntax
relationship <name> between(<entityA>, <entityB>)
relationship <name> contains(<parentEntity>, <childEntity>) [@one_many]Example
entity Grade {
name String @id,
section String
}
relationship GradeTeacher between(Grade, Teacher)
relationship GradeStudent contains(Grade, Student) @one_manySemantics
between
-
Creates a many-to-many link between two entities.
-
Each entity can reference multiple instances of the other.
-
Example:
GradeTeachermeans:- A teacher can teach multiple grades.
- A grade can have multiple teachers.
contains
- Creates a hierarchical containment relationship.
- By default, it represents a 1–1 relationship.
- When tagged with
@one_many, it becomes 1–N. - The child’s
pathreflects the hierarchy.
Example:
school.core$grade/3A/school.core$gradeStudent/school.core$student/198Here:
Gradeis the parentStudentis the child- The hierarchy is encoded in the
path
5. Example Module
module school.core
record Person {
firstName String,
lastName String,
dateOfBirth Date,
gender @enum("male", "female", "other")
}
entity Teacher extends Person {
employeeId Int @id,
dateOfJoining Date,
email Email
}
entity Student extends Person {
studentId Int @id
}
entity Grade {
name String @id,
section String
}
relationship GradeTeacher between(Grade, Teacher)
relationship GradeStudent contains(Grade, Student) @one_many6. Runtime Behavior Summary
| Concept | Behavior |
|---|---|
| Record | In-memory structured data |
| Entity | Persistent record with path |
| @id | Marks unique identifier for entity instances |
| @enum(…) | Restricts values to given options |
| relationship between | Many-to-many link |
| relationship contains | Parent-child link (1–1 or 1–N) |
| path | Uniquely identifies each persisted instance, reflects hierarchy |