#![allow(dead_code, unused_imports, unused_variables, unused_mut)]
#![allow(non_camel_case_types, ambiguous_glob_reexports, hidden_glob_reexports)]
#![allow(unexpected_cfgs, unused_assignments)]
extern crate proc_macro;
use proc_macro::TokenStream;
use syn::{Expr, Ident, LitStr, Token, parse::{Parse, ParseStream}};
mod parser;
mod tool_macro;
mod agent_macro;
mod workflow;
mod rag;
mod eval;
mod mcp;
mod agent;
mod tools;
mod lumos;
#[proc_macro_attribute]
pub fn tool(attr: TokenStream, item: TokenStream) -> TokenStream {
tool_macro::tool_macro(attr, item)
}
struct ToolAttributes {
name: LitStr,
description: LitStr,
}
impl Parse for ToolAttributes {
fn parse(input: ParseStream) -> syn::Result<Self> {
let mut name = None;
let mut description = None;
while !input.is_empty() {
let ident: Ident = input.parse()?;
input.parse::<Token![=]>()?;
if ident == "name" {
name = Some(input.parse()?);
} else if ident == "description" {
description = Some(input.parse()?);
} else {
return Err(syn::Error::new(ident.span(), "Unknown attribute"));
}
if input.peek(Token![,]) {
input.parse::<Token![,]>()?;
}
}
let name = name.ok_or_else(|| syn::Error::new(input.span(), "Missing name attribute"))?;
let description = description.ok_or_else(|| syn::Error::new(input.span(), "Missing description attribute"))?;
Ok(ToolAttributes { name, description })
}
}
struct ParameterAttributes {
name: LitStr,
description: LitStr,
type_: LitStr,
required: bool,
}
impl Parse for ParameterAttributes {
fn parse(input: ParseStream) -> syn::Result<Self> {
let mut name = None;
let mut description = None;
let mut type_ = None;
let mut required = None;
let content;
syn::parenthesized!(content in input);
let input = &content;
while !input.is_empty() {
let ident: Ident = input.parse()?;
input.parse::<Token![=]>()?;
if ident == "name" {
name = Some(input.parse()?);
} else if ident == "description" {
description = Some(input.parse()?);
} else if ident == "r#type" || ident == "type" {
type_ = Some(input.parse()?);
} else if ident == "required" {
let expr: Expr = input.parse()?;
if let Expr::Lit(lit) = &expr {
if let syn::Lit::Bool(b) = &lit.lit {
required = Some(b.value);
}
}
} else {
return Err(syn::Error::new(ident.span(), "Unknown parameter attribute"));
}
if input.peek(Token![,]) {
input.parse::<Token![,]>()?;
}
}
let name = name.ok_or_else(|| syn::Error::new(input.span(), "Missing name attribute"))?;
let description = description.ok_or_else(|| syn::Error::new(input.span(), "Missing description attribute"))?;
let type_ = type_.ok_or_else(|| syn::Error::new(input.span(), "Missing type attribute"))?;
let required = required.unwrap_or(false);
Ok(ParameterAttributes { name, description, type_, required })
}
}
#[proc_macro_attribute]
pub fn agent_attr(attr: TokenStream, item: TokenStream) -> TokenStream {
agent_macro::agent_impl(attr, item)
}
struct AgentAttributes {
name: LitStr,
instructions: LitStr,
model: LitStr,
}
impl Parse for AgentAttributes {
fn parse(input: ParseStream) -> syn::Result<Self> {
let mut name = None;
let mut instructions = None;
let mut model = None;
while !input.is_empty() {
let ident: Ident = input.parse()?;
input.parse::<Token![=]>()?;
if ident == "name" {
name = Some(input.parse()?);
} else if ident == "instructions" {
instructions = Some(input.parse()?);
} else if ident == "model" {
model = Some(input.parse()?);
} else {
return Err(syn::Error::new(ident.span(), "Unknown attribute"));
}
if input.peek(Token![,]) {
input.parse::<Token![,]>()?;
}
}
let name = name.ok_or_else(|| syn::Error::new(input.span(), "Missing name attribute"))?;
let instructions = instructions.ok_or_else(|| syn::Error::new(input.span(), "Missing instructions attribute"))?;
let model = model.ok_or_else(|| syn::Error::new(input.span(), "Missing model attribute"))?;
Ok(AgentAttributes { name, instructions, model })
}
}
#[proc_macro_derive(LlmAdapter)]
pub fn derive_llm_adapter(input: TokenStream) -> TokenStream {
agent_macro::derive_llm_adapter(input)
}
#[proc_macro]
pub fn lumos_execute_tool(input: TokenStream) -> TokenStream {
tool_macro::lumos_execute_tool(input)
}
struct ToolExecuteArgs {
tool: Expr,
params: Expr,
}
impl Parse for ToolExecuteArgs {
fn parse(input: ParseStream) -> syn::Result<Self> {
let mut tool = None;
let mut params = None;
while !input.is_empty() {
let ident: Ident = input.parse()?;
input.parse::<Token![:]>()?;
if ident == "tool" {
tool = Some(input.parse()?);
} else if ident == "params" {
params = Some(input.parse()?);
} else {
return Err(syn::Error::new(ident.span(), "Unknown field"));
}
if input.peek(Token![,]) {
input.parse::<Token![,]>()?;
}
}
let tool = tool.ok_or_else(|| syn::Error::new(input.span(), "Missing tool field"))?;
let params = params.ok_or_else(|| syn::Error::new(input.span(), "Missing params field"))?;
Ok(ToolExecuteArgs { tool, params })
}
}
#[proc_macro]
pub fn workflow(input: TokenStream) -> TokenStream {
workflow::workflow_impl(input)
}
#[proc_macro]
pub fn rag_pipeline(input: TokenStream) -> TokenStream {
rag::rag_pipeline_impl(input)
}
#[proc_macro]
pub fn eval_suite(input: TokenStream) -> TokenStream {
eval::eval_suite_impl(input)
}
#[proc_macro]
pub fn mcp_client(input: TokenStream) -> TokenStream {
mcp::mcp_client_impl(input)
}
#[proc_macro]
pub fn agent(input: TokenStream) -> TokenStream {
agent::agent(input)
}
#[proc_macro]
pub fn tools(input: TokenStream) -> TokenStream {
tools::tools(input)
}
#[proc_macro]
pub fn tool_nom(input: TokenStream) -> TokenStream {
tool_macro::tool_nom_macro(input)
}
#[proc_macro]
pub fn lumos(input: TokenStream) -> TokenStream {
lumos::lumos(input)
}