Skip to content

Syntax Overview

Orca uses an HCL-like block syntax. Files use the .oc extension.

Blocks

Everything in Orca is defined as a named block:

orca
block_type name {
  field = value
}

Available block types: model, agent, tool, workflow, knowledge, cron, webhook, input, schema, and let.

Comments

orca
// This is a comment
model gpt4 {
  provider   = "openai"    // inline comment
  model_name = "gpt-4o"
}

Types

Primitives

TypeDescription
strString
intInteger
floatFloating-point number
boolBoolean (true / false)
nullNull value
anyMatches any type

Collections

orca
// List
tools = [search, calculator, browser]

// Map
headers = {
  content_type: "application/json",
  authorization: "Bearer token"
}
  • Lists: list[T] — ordered collection of type T (e.g., list[tool]).
  • Maps: map[T] — key-value pairs where keys are strings and values are type T.

Unions

Use the pipe operator | to allow multiple types:

orca
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:

orca
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:

orca
agent writer {
  model = gpt4
  persona = "You write for " + config.audience
}

Subscript access

Use brackets for list or map indexing:

orca
first_tool = my_tools[0]

Expressions

Literals

orca
name     = "hello"       // string
count    = 42            // integer
rate     = 0.7           // float
enabled  = true          // boolean
nothing  = null          // null

Arithmetic

orca
let vars {
  total = base_price * quantity
  with_tax = vars.total + tax
}

Supported operators: +, -, *, /.

Function calls

orca
result = transform(input, "format")

Annotations

Annotations use the @ prefix and can decorate blocks or fields:

orca
@suppress("unknown-field")
agent researcher {
  @desc("The AI model to use")
  model = gpt4
}

@suppress

Suppresses compiler diagnostics:

orca
@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):

orca
schema report {
  @desc("The report title")
  title = str

  @desc("Word count limit")
  max_words = int | null
}

Diagnostic codes

CodeDescription
syntaxParse errors
duplicate-blockTwo blocks with the same name
duplicate-fieldRepeated field name in a block
missing-fieldRequired field not provided
unknown-fieldField not defined in the block's schema
type-mismatchValue type doesn't match field's expected type
undefined-refIdentifier not found
unknown-memberMember not found on referenced block
invalid-subscriptNon-integer subscript on a list
invalid-valueField value not in allowed set
invalid-workflow-nodeBlock 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:

orca
provider = "openai"
greeting = "hello\nworld"
SequenceResult
\nNewline
\tTab
\\Literal \
\"Literal "

Raw strings (triple-backtick)

Multi-line strings use triple backticks with an optional language tag:

orca
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 = 4

Result:

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.

Released under the MIT License.