// The `agent` generator: scaffold a moonkoog agent from a `.api` spec — each
// service operation becomes an agent `Tool`, assembled into an `AIAgent`. goctl
// has no agent target; this is the moon-heke suite extending mctl to scaffold its
// agent layer (moonkoog). The output compiles against `Lfan-ke/moonkoog`.
///|
/// Generate a moonkoog agent scaffold from `spec`. Every route becomes a `Tool`
/// whose descriptor advertises the operation (a single string `input` parameter to
/// fill out) and whose `execute_raw` is a stub, and `build_agent` assembles them
/// into an `AIAgent` with the service's name in its system prompt. The output
/// compiles against `Lfan-ke/moonkoog`; fill in each `execute_raw` to make it run.
pub fn generate_agent(spec : Spec) -> String {
let mut out = "// Code generated by moonctl. DO NOT EDIT.\n\n"
for r in spec.routes {
let type_name = to_pascal(r.handler) + "Tool"
out = out +
"///|\n/// A tool wrapping the `" +
r.handler +
"` operation (" +
r.verb +
" " +
r.path +
").\npriv struct " +
type_name +
" {}\n\n"
out = out +
"///|\nimpl @tools.Tool for " +
type_name +
" with fn descriptor(_self) {\n" +
" {\n name: \"" +
r.handler +
"\",\n description: \"" +
r.verb +
" " +
r.path +
"\",\n required_parameters: [\n" +
" { name: \"input\", description: \"operation input\", ptype: @tools.TString },\n" +
" ],\n optional_parameters: [],\n }\n}\n\n"
out = out +
"///|\nimpl @tools.Tool for " +
type_name +
" with fn execute_raw(_self, args) {\n let _ = args\n \"TODO: implement " +
r.handler +
"\"\n}\n\n"
}
out = out +
"///|\n/// Assemble the `" +
spec.service +
"` agent: the service's operations exposed as tools.\n" +
"pub fn build_agent(\n executor : &@agent.LLMClient,\n model : @llm.LLModel,\n) -> @agent.AIAgent {\n" +
" let registry = @tools.ToolRegistry::new()"
for r in spec.routes {
out = out + "\n .add(" + to_pascal(r.handler) + "Tool::{ })"
}
out = out +
"\n @agent.AIAgent::new(\n executor,\n model=model,\n tool_registry=registry,\n system_prompt=Some(\"You are the " +
spec.service +
" assistant.\"),\n )\n}\n"
out
}