Tactus: Lua-based DSL for agentic workflows
Project description
Tactus
Tactus: A Lua-based DSL for defining and executing agentic workflows.
⚠️ Status: Alpha - Tactus is in early development. Only a subset of the specification is currently implemented. See IMPLEMENTATION.md for details on what's complete and what's missing. The API is subject to change.
Tactus implements the "Give an Agent a Tool" programming paradigm: instead of writing explicit code to handle every edge case, you define capabilities (tools) and goals, then let an intelligent agent figure out how to use them to solve the problem.
Philosophy & Research
Tactus is built on the convergence of two critical insights: the necessity of Self-Evolution for future intelligence, and the requirement for Bounded Control in present-day production.
1. The Substrate for Self-Evolution
The path to Artificial Super Intelligence (ASI) lies in Self-Evolving Agents—systems that can adapt and improve their own components over time. A major 2025 survey, A Survey of Self-Evolving Agents, identifies four dimensions where evolution must occur:
- Models: Optimizing prompts and fine-tuning weights.
- Memory: Accumulating and refining experience.
- Tools: Creating and mastering new capabilities.
- Architecture: Rewriting the flow of logic and interaction.
The "Agent as Code" Advantage For an agent to evolve, it must be able to modify itself. In traditional frameworks, logic is locked in compiled code or complex Python class hierarchies. Tactus takes a radical approach: The entire agent is defined as data.
By defining the agent's prompts, tools, and logic in a transparent, editable DSL (YAML + Lua), Tactus makes the agent's own structure accessible to itself. This textual representation allows an agent to read, analyze, and rewrite its own definition, unlocking the potential for true self-evolution across all four dimensions.
2. Production Reality: Control > Autonomy
While evolution is the future, reliability is the present requirement. Research into deployed systems (Measuring Agents in Production) shows that successful agents rely on constrained deployment and human oversight, not open-ended "magic."
Tactus bridges this gap. It offers the evolutionary potential of "Agent as Code" while enforcing the production reliability of a strict Lua runtime. You get:
- Controllability: Explicit loops and conditionals, not black-box planning.
- Human-in-the-Loop: First-class primitives for approval and oversight.
- Bounded Autonomy: The "Give an Agent a Tool" paradigm—defining capabilities and goals—within a controlled environment.
Features
- Declarative Workflows: Define agent workflows in YAML with embedded Lua code
- Multi-Provider Support: Use OpenAI and AWS Bedrock models in the same workflow
- Multi-Model Support: Different agents can use different models (GPT-4o, Claude, etc.)
- Pluggable Backends: Storage, HITL, and chat recording via Pydantic protocols
- Human-in-the-Loop: Built-in support for human approval, input, and review
- LLM Integration: Works with OpenAI and Bedrock via pydantic-ai
- Checkpointing: Automatic workflow checkpointing and resume
- Standalone CLI: Run workflows without any infrastructure
- Type-Safe: Pydantic models throughout for validation and type safety
Note: Some features from the specification are not yet implemented, including guards, dependencies, inline procedure definitions, and advanced HITL configuration. See IMPLEMENTATION.md for the complete status.
Quick Start
Installation
pip install tactus
Your First Procedure: Hello and Done
Here is a minimal example. We give the agent a single tool (done) and a goal ("Greet the user"). The agent decides when and how to call the tool.
Create a file hello.yaml:
name: hello_world
version: 1.0.0
class: LuaDSL
params:
name:
type: string
default: "World"
# 1. Define the Agent and its Tools
agents:
greeter:
system_prompt: |
You are a friendly greeter. Greet the user by name: {params.name}
When done, call the done tool.
initial_message: "Please greet the user."
# The agent uses this tool to signal completion
tools:
- done
# 2. Define the Orchestration Logic (Lua)
procedure: |
-- Loop until the agent decides to use the 'done' tool
repeat
Greeter.turn()
until Tool.called("done")
-- Return the result captured from the tool call
return {
completed = true,
greeting = Tool.last_call("done").args.reason
}
Run it:
export OPENAI_API_KEY=your-key
tactus run hello.yaml
Multi-Model and Multi-Provider Support
Tactus supports multiple LLM providers and models. Every agent must specify a provider: (either directly or via default_provider: at the procedure level).
Supported providers: openai, bedrock
Multiple OpenAI Models:
agents:
researcher:
provider: openai
model: gpt-4o # Use GPT-4o for complex research
system_prompt: "Research the topic..."
tools: [done]
summarizer:
provider: openai
model: gpt-4o-mini # Use GPT-4o-mini for simple summarization
system_prompt: "Summarize the findings..."
tools: [done]
Multiple Providers (OpenAI + Bedrock):
agents:
openai_analyst:
provider: openai
model: gpt-4o
system_prompt: "Analyze the data..."
tools: [done]
bedrock_reviewer:
provider: bedrock
model: anthropic.claude-3-5-sonnet-20240620-v1:0
system_prompt: "Review the analysis..."
tools: [done]
Model-Specific Parameters:
You can configure model-specific parameters like temperature, max_tokens, or openai_reasoning_effort:
agents:
creative_writer:
provider: openai
model:
name: gpt-4o
temperature: 0.9 # Higher creativity
max_tokens: 2000
system_prompt: "Write creatively..."
tools: [done]
reasoning_agent:
provider: openai
model:
name: gpt-5 # Reasoning model
openai_reasoning_effort: high
max_tokens: 4000
system_prompt: "Solve this complex problem..."
tools: [done]
Configuration via .tactus/config.yml:
# OpenAI credentials
openai_api_key: sk-...
# AWS Bedrock credentials
aws_access_key_id: AKIA...
aws_secret_access_key: ...
aws_default_region: us-east-1
# Optional defaults
default_provider: openai
default_model: gpt-4o
See examples/multi-model.tyml and examples/multi-provider.tyml for complete examples.
Architecture
Tactus is built around three core abstractions:
- StorageBackend: Persists procedure state and checkpoints
- HITLHandler: Manages human-in-the-loop interactions
- ChatRecorder: Records conversation history
These are defined as Pydantic protocols, allowing you to plug in any implementation:
from tactus import TactusRuntime
from tactus.adapters.memory import MemoryStorage
from tactus.adapters.cli_hitl import CLIHITLHandler
runtime = TactusRuntime(
procedure_id="my-workflow",
storage_backend=MemoryStorage(),
hitl_handler=CLIHITLHandler(),
chat_recorder=None # Optional
)
result = await runtime.execute(yaml_config, context)
CLI Commands
# Run a workflow
tactus run workflow.yaml
tactus run workflow.yaml --param task="Analyze data"
# ...
Documentation
- Specification (DSL Reference) - The official specification for the Tactus domain-specific language.
- Implementation Guide - Maps the specification to the actual codebase implementation. Shows where each feature is implemented, what's complete, and what's missing relative to the specification.
- Examples - Run additional example procedures to see Tactus in action
- Primitives Reference (See
tactus/primitives/) - Storage Adapters (See
tactus/adapters/)
Integration
Tactus is designed to be integrated into larger systems. You can create custom adapters for your storage backend, HITL system, and chat recording.
Development
# Clone the repository
git clone https://github.com/AnthusAI/Tactus.git
cd Tactus
# Install with dev dependencies
pip install -e ".[dev]"
# Run tests
pytest
# Run with coverage
pytest --cov=tactus --cov-report=html
License
MIT License - see LICENSE file for details.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file tactus-0.1.0.tar.gz.
File metadata
- Download URL: tactus-0.1.0.tar.gz
- Upload date:
- Size: 127.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6076ecaf0dbadbf768009fbb90f6fcd05f491a704fb84b2ee557d0066f3a7cfe
|
|
| MD5 |
9a845232b406fcc8d03a25dac76eeb2e
|
|
| BLAKE2b-256 |
b653358506e31d3b2125911b87953faee00b96ff64ca66dc8b788fe691577070
|
File details
Details for the file tactus-0.1.0-py3-none-any.whl.
File metadata
- Download URL: tactus-0.1.0-py3-none-any.whl
- Upload date:
- Size: 68.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c10dbb7fc285f0d284373d9be4e832861cc3f8bf8939eb8df214cb1b272fe384
|
|
| MD5 |
b19ed72c6610e83bbe0ee1b129754ab5
|
|
| BLAKE2b-256 |
e034f930d165bd47e4141e299fa83a97bf87a7a52e6b2c7412c46daea0073ba6
|