honcho-api / src /llm /backend.py
rrizwan98
Honcho self-hosted deployment for HF Spaces
66227af
Raw
History Blame Contribute Delete
2.76 kB
from __future__ import annotations
from collections.abc import AsyncIterator
from dataclasses import dataclass, field
from typing import Any, Protocol, runtime_checkable
from pydantic import BaseModel
@dataclass(slots=True)
class ToolCallResult:
"""Normalized tool call from any provider."""
id: str
name: str
input: dict[str, Any]
thought_signature: str | None = None
@dataclass(slots=True)
class CompletionResult:
"""Normalized completion result returned by provider backends."""
content: Any = ""
input_tokens: int = 0
output_tokens: int = 0
cache_creation_input_tokens: int = 0
cache_read_input_tokens: int = 0
finish_reason: str = "stop"
tool_calls: list[ToolCallResult] = field(default_factory=list)
thinking_content: str | None = None
thinking_blocks: list[dict[str, Any]] = field(default_factory=list)
reasoning_details: list[dict[str, Any]] = field(default_factory=list)
raw_response: Any = None
@dataclass(slots=True)
class StreamChunk:
"""A single chunk in a streaming response."""
content: str = ""
is_done: bool = False
finish_reason: str | None = None
output_tokens: int | None = None
@runtime_checkable
class ProviderBackend(Protocol):
"""Transport-agnostic interface for LLM providers.
Credentials are baked into the underlying SDK client at backend construction
time (see src/llm/registry.py), so these method signatures deliberately do
not accept api_key / api_base.
"""
async def complete(
self,
*,
model: str,
messages: list[dict[str, Any]],
max_tokens: int,
temperature: float | None = None,
stop: list[str] | None = None,
tools: list[dict[str, Any]] | None = None,
tool_choice: str | dict[str, Any] | None = None,
response_format: type[BaseModel] | dict[str, Any] | None = None,
thinking_budget_tokens: int | None = None,
thinking_effort: str | None = None,
max_output_tokens: int | None = None,
extra_params: dict[str, Any] | None = None,
) -> CompletionResult: ...
def stream(
self,
*,
model: str,
messages: list[dict[str, Any]],
max_tokens: int,
temperature: float | None = None,
stop: list[str] | None = None,
tools: list[dict[str, Any]] | None = None,
tool_choice: str | dict[str, Any] | None = None,
response_format: type[BaseModel] | dict[str, Any] | None = None,
thinking_budget_tokens: int | None = None,
thinking_effort: str | None = None,
max_output_tokens: int | None = None,
extra_params: dict[str, Any] | None = None,
) -> AsyncIterator[StreamChunk]: ...