Artificial Intelligence
Tourbillon provides AI Agent and MCP Tool capabilities that can integrate seemlessly into your existing development process and codebase, providing determinism and fault tolerance guarantees without any additional developer overhead.
Durable Agents
Write your AI Agents with all the durability guarantees that Tourbillon provides.
AgentService.star
load("error", "codes")
load("fs", "fs")
load("http", "http")
load("openapi", "openapi")
def AgentExample(ctx, input)!:
spec = try fs.read_all("//openapi/specs/openapi.yml")
http_client = http.client()
client = openapi.new_client(spec = spec, http_client = http_client)
prompt = "Provide five interesting facts about {}.".format(input.topic)
messages = [{ "role":"system", "content": prompt }]
facts = []
while True:
# Perform our LLM prompt
response = client.create_chat_completion(
messages = messages,
model = "qwen2.5:3b",
max_tokens = 1024,
) catch e:
return codes.INTERNAL(message = e.message)
# Retrieve each choice from the response
for choice in response.choices:
message = choice.message
messages.append(message)
# Collect our facts for returning
facts.append(message.content)
# Check if we should stop
if choice.finish_reason == "stop":
break
# Return the facts
pkg = proto.package("agent", contracts=ctx.contracts)
return pkg.ExampleResponse(facts = facts)
Durable Tools
Tourbillon Agents can utilise other Tourbillon Durable executions as Tools for the LLM to use when evaluating a given prompt.
AgentService.star
# Register each given method as an LLM Tool
def tools_for(registry):
return [
{
"type": "function",
"function": {
"name": name,
"description": method.description,
"input_schema": method.input_type.json_schema(),
},
},
for name, method in registry.items()
]
# Agent for generating verified facts about a given topic
def AgentExample(ctx, input)!:
client = openapi.new_client(spec = spec, http_client = http_client)
prompt = "Provide five facts about {}. Verify each fact.".format(input.topic)
messages = [{ "role":"system", "content": prompt }]
# Specify the Tools the LLM can utilise
tools = { "verify_fact": pkg.AgentService.VerifyFact }
while True:
# Perform our LLM prompt, providing our Tools
response = client.create_chat_completion(
messages = messages,
model = "qwen2.5:3b",
max_tokens = 1024,
tools = tools_for(tools)
) catch e:
return codes.INTERNAL(message = e.message)
choice = response.choices[0]
message = choice.message
finish_reason = choice.finish_reason
assistant_message = {"role": "assistant", "content": message.content}
if finish_reason == "tool_calls":
assistant_message["tool_calls"] = message.tool_calls
messages.append(assistant_message)
if finish_reason == "stop":
# Stop the process if we are finished
break
if finish_reason == "tool_calls":
# Call each tool requested by the LLM
for call in message.tool_calls:
tool_name = call.function.name
tool_args = json.decode(call.function.arguments)
# Fetch the reference to the Durable Execution
tool = tools.get(tool_name)
# Trigger the Durable Execution via a Child Workflow
result = try workflow.execute_child_workflow(method = tool, input = tool.method_type(**tool_args))
# Add the Tool result to the messages for re-evaluation by the LLM
messages.append({ "role": "tool", "tool_call_id": call.id, "content": json.encode(result) })
# Your Durable Execution implementation for verifying a fact
def VerifyFact(ctx, input)!:
...
Tourbillon MCP Tools
Tourbillon provides MCP tools, that can be used with your existing AI Agent (e.g Claude, ChatGPT), providing developers and operators the ability to administer their Tourbillon instances and namespaces directly from their AI Agent.
.mcp.json
{
"mcpServers": {
"tourbillon-admin": {
"type": "http",
"url": "http://localhost:2424/mcp",
"headers": {
"Authorization": "Basic <base64(\"admin:<api-key>\")>"
}
},
"tourbillon": {
"type": "http",
"url": "http://localhost:4242/mcp",
"headers": {
"Authorization": "Basic <base64(\"<namespace-name>:<namespace-api-key>\")>"
}
}
}
}