LLM Client
Backend-agnostic LLM client using instructor for structured extraction.
- folderbot.llm_client.trim_history_to_budget(history, max_chars)[source]
Trim history to fit within a character budget.
Drops oldest messages first, in pairs (user+assistant) to avoid orphaned messages. Always keeps at least the most recent pair.
- folderbot.llm_client.build_topic_history(history, max_chars)[source]
Build topic-aware history: recent messages + same-topic backfill.
Always keeps the last RECENCY_WINDOW messages for immediate context. Fills remaining budget with older messages matching the current topic.
- class folderbot.llm_client.ToolCallRequest[source]
Bases:
BaseModelA request from the LLM to call a tool.
- class folderbot.llm_client.AgentResponse[source]
Bases:
BaseModelStructured response from the LLM.
Either provide tool_calls (to request tool execution) or answer (final response). When tool_calls is non-empty, tools will be executed and results fed back. When answer is set and tool_calls is empty, the answer is returned to the user.
- tool_calls: list[ToolCallRequest]
- class folderbot.llm_client.AskUserRequest[source]
Bases:
BaseModelRequest to ask the user a question with interactive UI.
Used by the agent loop when the LLM calls the ask_user tool. The Telegram handler renders this as inline keyboards, location pickers, or text prompts depending on input_type.
- class folderbot.llm_client.TokenUsage[source]
Bases:
objectAccumulated token usage from one chat() call.
- class folderbot.llm_client.LLMClient[source]
Bases:
objectBackend-agnostic LLM client using instructor for structured extraction.
Uses instructor’s from_provider() to support multiple LLM backends (Anthropic, OpenAI, etc.) through a unified interface. The agent loop uses structured extraction (AgentResponse model) to get either tool calls or a final answer from the LLM.
- MAX_TOOL_ITERATIONS = 10
- async chat(user_message, context, history, on_tool_use=None, on_ask_user=None, chat_id=0, images=None)[source]
Send a message and get a response through the agent loop.
- Parameters:
user_message (
str) – The user’s messagecontext (
BotContext) – BotContext with services and user info for tool executionon_tool_use (
Callable[[str],Awaitable[None]] |None) – Optional async callback when tools are being usedon_ask_user (
Callable[[AskUserRequest],Awaitable[str]] |None) – Optional async callback for ask_user tool (returns user answer)chat_id (
int) – Telegram chat ID (for scheduler tools)images (
list[dict[str,str]] |None) – Optional list of image dicts with ‘data’ (base64) and ‘media_type’
- Return type:
- Returns:
Tuple of (response text, list of tools used, topic label, token usage)