Advanced Features
Multi-agent systems, LLM integration, observability, memory, and scheduling — Syntecnia's power features for production-grade agentic programs.
1. Multi-Agent Coordination
Syntecnia lets you define and spawn multiple independent agents that collaborate through a shared blackboard and signal-based messaging. Each agent runs in its own thread with its own interpreter; only the blackboard and signal queue cross boundaries.
agent Researcher
require net("*.wikipedia.org")
task search(query)
let data be fetch(query)
share data as "research"
agent Writer
observe "research" as data
let report be generate "report" given data
spawn Researcher with query = "AI safety"
Blackboard (shared state)
The blackboard is thread-safe shared state that agents write to with share and read from with observe. It is the only memory that crosses agent boundaries.
- Each agent has its own interpreter and local variable scope.
- Only named blackboard keys are visible across agents.
observeblocks until the named key is available.
share the same key concurrently, the last write wins. Coordinate writes explicitly or use unique keys per worker.
Signals (messaging)
Signals provide lightweight one-shot messaging between agents using a queue-based mechanism.
signal "done"— post a named signal, optionally with a value.wait_for "done" as result— block until the signal arrives and bind its value.- Signals are queue-based: each posted signal is consumed by exactly one waiter.
signal calls — one per consumer — for fan-out delivery.
Resource Locks
Syntecnia performs preventive conflict detection on resources declared by agents. The runtime can identify potential write conflicts before they occur and surface them as diagnostics rather than silent data races.
require at the top of an agent body. This enables both safety checks and the capability permission system.
Agent Lifecycle
Agents must be defined before they are spawned. The runtime tracks each agent through a well-defined state machine:
- STARTING — agent thread is initialising.
- WORKING — actively executing a task.
- WAITING — blocked on
observeorwait_for. - DONE — task completed successfully.
- ERROR — an unhandled failure occurred.
2. LLM Integration
Syntecnia treats language model calls as first-class expressions. The runtime manages prompt construction, provider routing, validation, and retries transparently.
let analysis be analyze sales_data for "trends"
let action be decide between ["refund", "replace"] given complaint
let response be generate "email" given ticket with tone = "empathetic"
Providers
Select the backend model at launch time via the CLI flag:
| Provider | Models | Notes |
|---|---|---|
anthropic |
Claude family | Default for production |
openai |
GPT family | Requires OPENAI_API_KEY |
ollama |
Any local model | No network required; runs locally |
minimax |
MiniMax models | Requires MINIMAX_API_KEY |
mock |
— | Deterministic stub for tests |
Pass the flag at runtime: syntecnia run program.syn --provider anthropic
Response Validation
The decide expression enforces that the LLM returns exactly one of the provided options. The runtime automatically retries with corrective feedback on invalid responses.
decideaccepts only values from the supplied list — any other output triggers a retry.- Up to 3 retries are attempted; each retry sends the LLM its prior invalid response along with an explanation of the constraint.
- On each call, the LLM receives full program context: intent, current variables, active rules, memory, and execution progress.
decide over raw generate wherever you need a constrained choice. The validation loop is automatic and surfaces errors clearly if all retries fail.
3. Human Interaction
Syntecnia provides built-in primitives for pausing execution and requesting human input or approval at critical decision points.
approve "Deploy to production?"
let choice be ask "Which environment?" with ["staging", "prod"]
confirm "Send email to 500 customers?"
show preview as "Email Preview"
approve— presents a yes/no gate; execution halts until a human confirms or rejects.ask— prompts for a selection from a list of options and binds the result.confirm— similar toapprove, used for explicit acknowledgement of consequential actions.show … as— renders a value for human review with a labelled title, without requiring a response.
approve and confirm calls are auto-approved and ask selects the first option. Pass the appropriate flag to opt in.
4. Observability
Syntecnia has structured tracing, measurement, and checkpointing built into the language. No external instrumentation library is required.
trace "payment_processing"
log "Processing order " + order_id
measure "db_query"
let result be query(sql)
checkpoint "after_query"
trace— opens a named span. All nested operations are attributed to this span in the output.log— emits a structured log line with timestamp and active span context.measure— wraps a block and records its wall-clock duration as a named metric.checkpoint— marks a named point in execution, usable for progress recovery and debugging.
Rich Error Diagnostics
When a runtime error occurs, Syntecnia surfaces a structured diagnostic that includes everything needed to understand and fix the failure:
- Location — file, line, and column of the failing expression.
- Source line — the exact Syntecnia source text that failed.
- Intent — the high-level goal the agent was pursuing at the time of failure.
- Variables at failure — a snapshot of all in-scope variable bindings.
- Suggestions — concrete, contextual hints for resolution.
- Error category and recoverability — whether the error is transient, permanent, or requires human escalation.
Automatic Recovery
Syntecnia's runtime attempts recovery before surfacing an error to the program. The recovery strategies are applied in order:
- Retry with backoff — transient failures (network, rate limits) are retried with exponential backoff.
- Fallback to cached or default data — if a fetch fails and cached data exists, it is used transparently.
- Partial results — when a collection operation partially succeeds, the successful subset is returned with a warning.
- Speculative alternatives — the runtime may attempt a semantically equivalent alternative path.
- Human escalation — if all automated recovery strategies fail, execution pauses and the human interaction handler is invoked.
try/recover blocks to define custom recovery logic. Relying solely on automatic recovery means unhandled permanent failures will escalate to the human handler or terminate the agent.
5. Agent Memory System
Beyond the blackboard, Syntecnia provides a durable memory layer that persists across agent restarts and program runs. It covers progress tracking, semantic memory, and business rule enforcement.
Progress Tracking
Progress tracking lets a multi-step task survive crashes and resume from the last completed step rather than starting over.
create_progress("sync", ["fetch", "validate", "update"])
start_step("sync", "fetch")
complete_step("sync", "fetch", "100 items")
create_progress(id, steps)— registers a named task with an ordered list of step names.start_step(id, step)— marks a step as in-progress.complete_step(id, step, result)— marks a step done and stores its output.resume_point(id)— returns the name of the next incomplete step; use this at startup to skip already-completed work after a crash.
resume_point returns the first step whose status is not complete. If all steps are complete it returns null, signalling that the task is finished.
Persistent Memory
Agents can store and retrieve semantic memories organised by category. Memory persists across runs and is surfaced to LLM calls as context.
remember("preference", "Customer prefers formal tone", ["communication"])
let prefs be recall("preference", ["communication"])
forget_memory(entry_id)
remember(category, text, tags)— stores a memory entry with a category and optional tags for retrieval filtering.recall(category, tags)— retrieves matching memory entries; tags narrow the search.forget_memory(entry_id)— permanently removes a specific memory entry by its ID.
Valid categories (must be written in English):
Owner Rules
Owner rules let the operator or application embed hard constraints and soft preferences that are evaluated against agent decisions at runtime.
add_rule("max_discount", "must", "discount <= 0.20", "pricing")
let violations be check_rules("pricing", {discount: 0.25})
add_rule(name, level, expression, category)— registers a named rule with an enforcement level and a logical expression.check_rules(category, context)— evaluates all rules in a category against the provided context object and returns any violations.
Enforcement levels:
| Level | Behaviour |
|---|---|
must | Hard block — a violation raises an error and halts execution. |
should | Warning — a violation is logged but execution continues. |
avoid | Preference against — surfaces as a low-priority advisory. |
prefer | Preference for — guides LLM generation toward the desired outcome. |
6. Cron / Scheduling
Syntecnia includes a lightweight in-process scheduler for running tasks on a delay or recurring interval — no external cron daemon required.
cron_every(60, my_task)
cron_after(300, cleanup)
cron_cancel("my_task")
cron_every(seconds, task)— schedulestaskto run repeatedly everysecondsseconds. The first run occurs after one full interval.cron_after(seconds, task)— schedulestaskto run once after a delay ofsecondsseconds.cron_cancel(name)— cancels a scheduled task by its name, preventing any future executions.
cron_every with progress tracking so tasks can self-resume.
7. Common Anti-Patterns
Avoid these patterns to keep agents reliable, safe, and correct.
No try/recover around I/O
try/recover blocks and define explicit fallback behaviour.
Relying on intent to restrict actions
require declarations to define hard capability constraints. An agent without explicit require net(...) should not be able to make network calls regardless of its stated intent.
One signal for N consumers
signal "done" is consumed by exactly one waiting agent. If N agents are waiting on the same signal name, only one will unblock. Post N signals — one per consumer — for broadcast delivery.
Sharing from N workers with a common key
share data under the same blackboard key, the last write wins and earlier values are silently overwritten. Use unique per-agent keys (e.g., "result_" + agent_id) and aggregate them in a coordinator agent.