seq (Sequence)

The root atom for all agent programs. Executes steps in order.

// AsyncJS compiles to seq at the top level
const x = 1
const y = 2
return { sum: x + y }

if (Conditional)

Conditional branching based on expression evaluation.

if (count > 0) {
  console.log("Has items")
} else {
  console.log("Empty")
}

while (Loop)

Repeats body while condition is truthy. Consumes fuel each iteration.

let i = 0
while (i < 10) {
  console.log(i)
  i = i + 1
}

Note: No break/continue. Use condition variables instead.

return

Ends execution and returns values from state. The schema defines which state variables to include in the output.

const result = compute()
return { result }  // Returns { result: <computed value> }

try/catch

Error handling with monadic error flow. When an error occurs, subsequent steps are skipped until caught.

try {
  const data = fetch(url)
  processData(data)
} catch (err) {
  console.warn("Failed: " + err)
  return { error: err }
}

The catch block receives:

for...of / map

Transforms each item in an array. The result variable in each iteration becomes the new item value.

const doubled = items.map(x => x * 2)

// Or with for...of:
const results = []
for (const item of items) {
  results.push(process(item))
}

filter

Keeps items that match a condition.

const adults = users.filter(u => u.age >= 18)

reduce

Accumulates a single value from an array.

const sum = numbers.reduce((acc, n) => acc + n, 0)

find

Returns first item matching condition, or null.

const admin = users.find(u => u.role === "admin")

fetch

HTTP requests. Requires fetch capability or uses global fetch with SSRF protection.

const data = fetch("https://api.example.com/data")
const posted = fetch("https://api.example.com/items", {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: { name: "New Item" }
})

Response types: "json" (default for JSON content-type), "text", "dataUrl" (for images)

Security:

storeGet / storeSet

Persistent key-value storage. Requires store capability.

// Save data
storeSet("user:123", { name: "Alice", prefs: {} })

// Retrieve later
const user = storeGet("user:123")

Warning: Default in-memory store is not suitable for production.

storeQueryWhere (predicate pushdown)

Send the predicate to the data instead of dragging rows to the code.

predicate is a canonical verified predicate — build it at author/transpile time with canonicalizePredicate() from tjs-lang/lang, then pass the resulting object. Because it is verified pure and canonical, it is safe to ship, cheap to compare, and carries a stable key the store can cache on (two spellings of the same predicate hit the same cache entry).

// canonical form produced outside the VM; the VM forwards it as data
const rows = storeQueryWhere({ collection: 'users', predicate: adultPredicate })

Requires a store that implements queryPredicate. If it doesn't, this fails with a message pointing at the ordinary storeQuery + filter path rather than silently returning everything — a filter that silently doesn't filter is an authorization bug.

llmPredict

Call language model. Requires llm capability with predict method.

const response = llmPredict("Summarize this: " + text)

// With options
const structured = llmPredict(prompt, {
  model: "gpt-4",
  temperature: 0.7,
  responseFormat: { type: "json_object" }
})

transpileCode (Code to AST)

Transpiles AsyncJS code to an AST without executing it. Useful for generating agents to send to other services via fetch.

// Generate an agent and send it to a worker
let code = llmPredict({ prompt: 'Write an AsyncJS data processor' })
let ast = transpileCode({ code })
let result = httpFetch({
  url: 'https://worker.example.com/run',
  method: 'POST',
  body: JSON.stringify({ ast, args: { data: myData } })
})

Security: Only available when the code.transpile capability is provided.

runCode (Dynamic Code Execution)

Transpiles and executes AsyncJS code at runtime. The generated code runs in the same context, sharing fuel budget, capabilities, and trace.

This enables agents to write and execute code to solve problems.

// Agent writes code to solve a problem
let code = llmPredict({ prompt: 'Write AsyncJS to calculate fibonacci(10)' })
let result = runCode({ code, args: {} })
return { answer: result }

The code must be a valid AsyncJS function. The function's return value becomes the result of runCode.

Security: Only available when the code.transpile capability is provided. The transpiled code runs with the same permissions as the parent. Recursion depth is limited to prevent stack overflow.

memoize

In-memory caching within a single execution. Same key returns cached result.

// Expensive computation cached by key
const result = memoize("expensive-" + id, () => {
  return heavyComputation(data)
})

cache

Persistent caching across executions using store capability.

// Cache API result for 1 hour (3600000 ms)
const weather = cache("weather-" + city, 3600000, () => {
  return fetch("https://api.weather.com/" + city)
})

console.log / console.warn / console.error

Logging utilities that integrate with trace and error flow.

console.log("Debug info: " + value)   // Adds to trace
console.warn("Potential issue")        // Adds to trace + warnings summary
console.error("Fatal: " + msg)         // Triggers monadic error flow