LlamaIndex adapter
For LlamaIndex agents — ReActAgent, OpenAIAgent, FunctionAgent, etc. Returns llama_index.core.tools.FunctionTool instances whose sync and async paths both run through the governance pipeline, so it doesn't matter which agent flavour or worker you're using.
Module name
The Python package is llama_index (with underscore), but Kite Logik's adapter import is kitelogik.adapters.llamaindex (no underscore) — matching the module file llamaindex.py.
Install
pip install kitelogik llama-indexllama-index is not a hard dependency — only imported when you call llamaindex_tools().
Setup
from kitelogik import OPAClient, PolicyGate, SessionContext
from kitelogik.adapters.llamaindex import LlamaIndexAdapter
gate = PolicyGate(opa_client=OPAClient())
context = SessionContext(
session_id="sess_001",
user_role="analyst",
session_scopes=["read_customer", "search_docs"],
)
adapter = LlamaIndexAdapter(gate=gate, context=context)Register tools
register(name, fn, description="", action=None) — chainable.
def get_customer(customer_id: str) -> str:
"""Look up a customer record by ID."""
return f"Customer {customer_id}: Acme Corp"
async def search_docs(query: str) -> str:
return f"Top results for: {query}"
adapter.register("get_customer", get_customer, description="Look up a customer")
adapter.register("search_docs", search_docs, description="Search internal docs")Both sync and async functions work. The adapter builds a single governed async wrapper per tool and exposes it through both the sync (fn=) and async (async_fn=) parameters of FunctionTool.from_defaults — so an agent that calls tool.call(...) and one that calls await tool.acall(...) both flow through the same policy gate.
Pass governed tools to a LlamaIndex agent
from llama_index.core.agent import ReActAgent
from llama_index.llms.openai import OpenAI
agent = ReActAgent.from_tools(
adapter.llamaindex_tools(), # ← governed FunctionTool list
llm=OpenAI(model="gpt-4o"),
)
response = agent.chat("Look up customer cust_001 and summarise.")Or the newer FunctionAgent flow — same tools= argument shape.
What happens on a deny
Denied calls return a JSON string {"blocked": true, "reason": "..."} from the tool — the agent loop continues; the model sees the structured denial.
To customise, pass deny_message= to the adapter constructor.
Constructor parameters
LlamaIndexAdapter extends BaseGovernedAdapter:
LlamaIndexAdapter(
gate: PolicyGate,
context: SessionContext,
sanitize: bool = True,
deny_message: str | None = None,
)| Param | Default | Purpose |
|---|---|---|
sanitize | True | Run prompt-injection sanitiser on string return values |
deny_message | "Action blocked by governance policy." | Surfaced to the model on deny |
Source
kitelogik/adapters/llamaindex.py on GitHub.