import ast
import operator
import os
from langchain_openai import ChatOpenAI
from langchain.agents import AgentExecutor, create_tool_calling_agent
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.tools import tool
POLICY_SNIPPETS = {
"retention": "Data is retained for 7 years; PII is deleted on request within 30 days.",
"access": "Access is RBAC + least-privilege; all reads are logged and reviewed weekly.",
}
OPS = {
ast.Add: operator.add,
ast.Sub: operator.sub,
ast.Mult: operator.mul,
ast.Div: operator.truediv,
}
def safe_arithmetic(expr: str) -> float:
"""Evaluate simple arithmetic without eval."""
def visit(node):
if isinstance(node, ast.Expression):
return visit(node.body)
if isinstance(node, ast.Constant) and isinstance(node.value, (int, float)):
return node.value
if isinstance(node, ast.BinOp) and type(node.op) in OPS:
return OPS[type(node.op)](visit(node.left), visit(node.right))
if isinstance(node, ast.UnaryOp) and isinstance(node.op, ast.USub):
return -visit(node.operand)
if isinstance(node, ast.UnaryOp) and isinstance(node.op, ast.UAdd):
return visit(node.operand)
raise ValueError("Unsupported expression.")
parsed = ast.parse(expr, mode="eval")
return visit(parsed)
@tool
def search_policy(topic: str) -> str:
"""Lookup a short internal policy snippet by topic."""
return POLICY_SNIPPETS.get(topic.lower(), "No policy found for that topic.")
@tool
def calc(expr: str) -> str:
"""Evaluate simple arithmetic like '1200*0.18'."""
try:
return str(safe_arithmetic(expr))
except Exception:
return "Rejected: unsupported arithmetic expression."
tools = [search_policy, calc]
llm = ChatOpenAI(model=os.getenv("OPENAI_MODEL", "gpt-5"), temperature=0)
prompt = ChatPromptTemplate.from_messages([
("system", "You are a compliance-aware enterprise AI agent. Use tools when needed."),
("human", "{input}"),
("placeholder", "{agent_scratchpad}"),
])
agent = create_tool_calling_agent(llm, tools, prompt)
executor = AgentExecutor(agent=agent, tools=tools, verbose=True)
result = executor.invoke({"input": "Summarize our retention policy and compute GST on 1200 at 18%."})
print(result["output"])