Core
The core module contains the runtime primitives you use in almost every project. It is intentionally small and dependency-light, so it can be the stable foundation for both simple scripts and larger multi-agent systems.
If you are unsure where to start, start in core: create an LLMClient, build an Agent, and add tools only as needed.
LLMClient
LLMClient is the provider-agnostic HTTP client for chat completions and embeddings.
Use it directly when you need low-level model calls, or pass it to Agent and Orchestrator for higher-level workflows.
llm_framework.core.llm.LLMClient
LLMClient(base_url: str, api_key: str, model: str, timeout: float = 120.0, verify: str | bool = True)
Async HTTP client for OpenAI-compatible chat completion and embeddings endpoints.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
base_url
|
str
|
Base URL of the OpenAI-compatible API endpoint. |
required |
api_key
|
str
|
API key; sent as both Bearer token and x-api-key for cross-provider compatibility. |
required |
model
|
str
|
Model identifier to use for all requests. |
required |
timeout
|
float
|
HTTP request timeout in seconds (default 120). |
120.0
|
verify
|
str | bool
|
TLS verification — True for system CAs, False to skip, or a path to a CA bundle. |
True
|
from_env
classmethod
Construct from env vars; reads LLM_BASE_URL, LLM_API_KEY, LLM_MODEL, CA_BUNDLE_PATH.
chat_completions
async
chat_completions(messages: list[dict[str, Any]], tools: list[dict[str, Any]] | None = None, temperature: float = 0.7, max_tokens: int = 1024, max_retries: int = 3, response_format: dict[str, Any] | None = None) -> dict[str, Any]
Send a chat completion request with exponential backoff on transient server errors.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
messages
|
list[dict[str, Any]]
|
Conversation history in OpenAI message format. |
required |
tools
|
list[dict[str, Any]] | None
|
Optional list of JSON function schemas to expose to the model. |
None
|
temperature
|
float
|
Sampling temperature (default 0.7); use 0.0 for deterministic output. |
0.7
|
max_tokens
|
int
|
Maximum tokens in the response. |
1024
|
max_retries
|
int
|
Retry attempts on 429/5xx errors with exponential backoff. |
3
|
response_format
|
dict[str, Any] | None
|
Optional structured output schema (e.g. a json_schema object). |
None
|
Returns:
| Type | Description |
|---|---|
dict[str, Any]
|
Raw OpenAI-compatible response dict with choices, usage, and model fields. |
embeddings
async
Return one embedding vector per input text.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
input_texts
|
list[str]
|
List of strings to embed. |
required |
max_retries
|
int
|
Retry attempts on 429/5xx errors with exponential backoff. |
3
|
Returns:
| Type | Description |
|---|---|
list[list[float]]
|
List of embedding vectors, one per input string, in the same order. |
Agent
Agent implements the ReAct loop: reason, call tools, observe, and iterate to a final answer.
It is the main entry point for tool-using assistants and supports approvals, guardrails, and auth-aware tool filtering.
llm_framework.core.agent.Agent
Agent(client: object, tools: list | None = None, max_steps: int = 10, max_tokens: int = 4096, temperature: float = 0.7, max_retries: int = 3, system_prompt: str | None = None, input_guards: list | None = None, output_guards: list | None = None, on_event: Callable[[AgentEvent], object] | None = None, approval_callback: object | None = None, approval_tools: list[str] | None = None, auth_gate: object | None = None)
ReAct agent that iterates tool calls until it reaches a final text answer.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
client
|
object
|
An |
required |
tools
|
list | None
|
List of |
None
|
max_steps
|
int
|
Maximum reasoning iterations before returning a fallback answer (default 10). |
10
|
max_tokens
|
int
|
Maximum tokens per LLM response (default 4096). Increase when the model must reproduce large tool results verbatim. |
4096
|
temperature
|
float
|
Sampling temperature (default 0.7). Use 0.0 for deterministic tasks like structured extraction or KQL generation. |
0.7
|
max_retries
|
int
|
LLM request retry attempts with exponential backoff on 429/5xx errors (default 3). |
3
|
system_prompt
|
str | None
|
Persistent persona injected as the system message on every |
None
|
input_guards
|
list | None
|
List of callables |
None
|
output_guards
|
list | None
|
List of callables |
None
|
on_event
|
Callable[[AgentEvent], object] | None
|
Callable receiving structured event dicts at each step. |
None
|
approval_callback
|
object | None
|
Sync or async |
None
|
approval_tools
|
list[str] | None
|
Set of tool names that require approval. If |
None
|
auth_gate
|
object | None
|
An |
None
|
run
async
run(prompt: str, system_prompt: str | None = None, prior_messages: list[dict] | None = None, auth_context: object | None = None) -> dict
Run the agent on a prompt and return the final answer with cumulative token usage.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
prompt
|
str
|
The user's task or question. |
required |
system_prompt
|
str | None
|
Override the agent's default persona for this call only. |
None
|
prior_messages
|
list[dict] | None
|
Previous conversation turns to prepend; use with |
None
|
auth_context
|
object | None
|
An |
None
|
Returns:
| Type | Description |
|---|---|
dict
|
Dict with keys: |
dict
|
|
Orchestrator
Orchestrator is a supervisor/delegate layer for multi-agent task routing.
Use it when one prompt should be split across specialized agents with different prompts, tools, or responsibilities.
llm_framework.core.orchestrator.Orchestrator
Orchestrator(client: object, sub_agents: dict[str, Agent], max_steps: int = 10, max_tokens: int = 4096, max_retries: int = 3, history_max_tokens: int = 8000, on_event: object | None = None)
Supervisor agent that delegates tasks to named sub-agents via an injected delegate() tool.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
client
|
object
|
An |
required |
sub_agents
|
dict[str, Agent]
|
Mapping of agent name to |
required |
max_steps
|
int
|
Maximum supervisor reasoning iterations (default 10). |
10
|
max_tokens
|
int
|
Maximum tokens per supervisor response (default 4096). |
4096
|
max_retries
|
int
|
Retry attempts on transient API errors forwarded to the supervisor agent (default 3). |
3
|
history_max_tokens
|
int
|
Token budget for the supervisor history buffer (default 8000). |
8000
|
on_event
|
object | None
|
Event callback forwarded to the supervisor agent. |
None
|
HistoryBuffer
HistoryBuffer maintains rolling multi-turn context with token-budget trimming.
Use it to keep conversations coherent while controlling prompt growth and cost.
llm_framework.core.history.HistoryBuffer
Rolling message buffer that preserves the system message while trimming oldest history.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
max_messages
|
int | None
|
Maximum number of messages to retain. Oldest action/observation pairs are evicted first. |
None
|
max_tokens
|
int | None
|
Soft token budget (char÷4 approximation with a 20% safety margin). The buffer trims to 80% of this value. |
None
|
extend
Append messages (from an agent.run() result) and trim to configured limits.
run
async
Run the agent with buffered history, then extend the buffer automatically.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
agent
|
object
|
The |
required |
prompt
|
str
|
The user's task or question. |
required |
**kwargs
|
object
|
Forwarded to |
{}
|
Returns:
| Type | Description |
|---|---|
dict
|
The agent's result dict (same shape as |
Decorators
The decorators define how Python callables become model-callable tools.
Use @tool for schema generation from type hints and docstrings, and @cached_tool when deterministic tool calls should reuse prior results.
llm_framework.core.tools.tool
Decorator that attaches a JSON schema to a function, making it usable as an agent tool.