pub const MANAGED_AGENT_TEMPLATE: &str = r#"
-- Managed Agent: {{AGENT_NAME}}
-- Auto-generated by SoliDB
local AGENT_NAME = "{{AGENT_NAME}}"
local AGENT_TYPE = "{{AGENT_TYPE}}"
local AGENT_CAPS = {{AGENT_CAPS}}
local AGENT_KEY = "{{AGENT_KEY}}" -- Internal reference to agent document
-- Configuration
local LLM_API_URL = solidb.env.{{ENV_URL_KEY}}
local LLM_API_KEY = solidb.env.{{ENV_API_KEY}}
if not LLM_API_URL then error("LLM_API_URL not found in env: " .. "{{ENV_URL_KEY}}") end
if not LLM_API_KEY then error("LLM_API_KEY not found in env: " .. "{{ENV_API_KEY}}") end
-- Helper to call LLM
function ask_llm(user_prompt)
local body = solidb.json_encode({
model = "gpt-4o", -- Default model, can be adjusted
messages = {
{ role = "user", content = user_prompt }
}
})
print("🤖 " .. AGENT_NAME .. " calling AI Provider...")
local response = solidb.fetch(LLM_API_URL, {
method = "POST",
headers = {
["Authorization"] = "Bearer " .. LLM_API_KEY,
["x-api-key"] = LLM_API_KEY, -- Redundant but covers Anthropic/others
["api-key"] = LLM_API_KEY, -- Azure
["content-type"] = "application/json"
},
body = body
})
if not response.ok then
return nil, "API Error " .. response.status .. ": " .. response.body
end
local data = solidb.json_decode(response.body)
-- Attempt to parse response from common formats
if data.choices and data.choices[1] and data.choices[1].message then
return data.choices[1].message.content -- OpenAI format
elseif data.content and data.content[1] and data.content[1].text then
return data.content[1].text -- Anthropic format
elseif data.response then
return data.response -- Ollama format
else
return solidb.json_encode(data) -- Fallback
end
end
-- Main Loop
function run_agent_loop()
print("🚀 Starting Managed Agent: " .. AGENT_NAME)
-- Ensure agent is registered/active
-- We assume the agent is already registered via the UI, but we can re-register to ensure caps
local agent = solidb.ai.register_agent(AGENT_NAME, AGENT_TYPE, AGENT_CAPS)
local agent_id = agent.id or agent._key
local processed = 0
local MAX_ITERATIONS = 50 -- Safety limit for one run execution
for i = 1, MAX_ITERATIONS do
solidb.ai.heartbeat(agent_id)
local tasks = solidb.ai.get_pending_tasks({
limit = 1,
agent_type = AGENT_TYPE
})
if #tasks > 0 then
local task = tasks[1]
print("📥 " .. AGENT_NAME .. " found task: " .. task._key)
if solidb.ai.claim_task(task._key, agent_id) then
local prompt = "Please fulfill this request:\n\n" .. (task.data.description or "No description")
local result, err = ask_llm(prompt)
if result then
solidb.ai.complete_task(task._key, {
result = result,
agent = AGENT_NAME
})
print("✅ Task completed")
processed = processed + 1
else
print("❌ Task failed: " .. tostring(err))
solidb.ai.fail_task(task._key, err or "Unknown error")
end
end
else
-- If running in a loop, sleep. If invoked via cron/event, maybe just exit.
-- For this template, we'll exit if no tasks to avoid long-running processes blocking threads if not async
print("💤 No tasks. Exiting loop.")
break
end
end
return "Agent " .. AGENT_NAME .. " processed " .. processed .. " tasks."
end
"#;