Syntax Overview
Orca uses an HCL-like block syntax. Files use the .oc extension.
Blocks
Everything in Orca is defined as a named block:
block_type name {
field = value
}Available block types: model, agent, tool, workflow, knowledge, cron, webhook, input, schema, and let.
Comments
// This is a comment
model gpt4 {
provider = "openai" // inline comment
model_name = "gpt-4o"
}Types
Primitives
| Type | Description |
|---|---|
str | String |
int | Integer |
float | Floating-point number |
bool | Boolean (true / false) |
null | Null value |
any | Matches any type |
Collections
// List
tools = [search, calculator, browser]
// Map
headers = {
content_type: "application/json",
authorization: "Bearer token"
}- Lists:
list[T]— ordered collection of typeT(e.g.,list[tool]). - Maps:
map[T]— key-value pairs where keys are strings and values are typeT.
Unions
Use the pipe operator | to allow multiple types:
model_name = str | model // accepts a string or a model reference
temperature = float | null // optional field (null means it can be omitted)A field with | null in its type is optional.
References
Unquoted identifiers reference other blocks:
model gpt4 {
provider = "openai"
model_name = "gpt-4o"
}
agent writer {
model = gpt4 // references the model block above
}Member access
Use dot notation to access fields on referenced blocks:
agent writer {
model = gpt4
persona = "You write for " + config.audience
}Subscript access
Use brackets for list or map indexing:
first_tool = my_tools[0]Expressions
Literals
name = "hello" // string
count = 42 // integer
rate = 0.7 // float
enabled = true // boolean
nothing = null // nullArithmetic
let vars {
total = base_price * quantity
with_tax = vars.total + tax
}Supported operators: +, -, *, /.
Function calls
result = transform(input, "format")Annotations
Annotations use the @ prefix and can decorate blocks or fields:
@suppress("unknown-field")
agent researcher {
@desc("The AI model to use")
model = gpt4
}@suppress
Suppresses compiler diagnostics:
@suppress // suppress all diagnostics
@suppress("type-mismatch") // suppress specific code
@suppress("unknown-field", "missing-field") // suppress multiple codes@desc
Adds a description to a field (used in schema definitions):
schema report {
@desc("The report title")
title = str
@desc("Word count limit")
max_words = int | null
}Diagnostic codes
| Code | Description |
|---|---|
syntax | Parse errors |
duplicate-block | Two blocks with the same name |
duplicate-field | Repeated field name in a block |
missing-field | Required field not provided |
unknown-field | Field not defined in the block's schema |
type-mismatch | Value type doesn't match field's expected type |
undefined-ref | Identifier not found |
unknown-member | Member not found on referenced block |
invalid-subscript | Non-integer subscript on a list |
invalid-value | Field value not in allowed set |
invalid-workflow-node | Block kind not allowed as a workflow node |
Strings
Orca has two string types: double-quoted strings for single-line values and raw strings (triple-backtick) for multi-line content.
Double-quoted strings
Single-line strings with escape sequence support:
provider = "openai"
greeting = "hello\nworld"| Sequence | Result |
|---|---|
\n | Newline |
\t | Tab |
\\ | Literal \ |
\" | Literal " |
Raw strings (triple-backtick)
Multi-line strings use triple backticks with an optional language tag:
agent researcher {
persona = ```md
You are a research assistant.
You search the web for information.
Always cite your sources.
```
}The value of persona is:
You are a research assistant.
You search the web for information.
Always cite your sources.The language tag (md, py, json, yaml, etc.) is optional and enables syntax highlighting in editors.
How indentation stripping works
The closing ```'s column defines the baseline. That many leading spaces are stripped from every content line.
Rule: baseline = closing_backtick_column - 1 (columns are 1-based).
persona = ```md
Hello ← 4 spaces before content
Indented ← 6 spaces (2 extra will remain)
World ← 4 spaces before content
``` ← closing ``` at column 5 → baseline = 4Result:
Hello
Indented
World- Lines indented more than the baseline keep their extra indentation.
- Empty lines in the middle are preserved.
- The last line (whitespace before the closing
```) is removed.