Files
wehub-resource-sync 6b7e6b44f1
Python Build and Type Check / python-ci (ubuntu-latest, 3.11) (push) Has been cancelled
Python Build and Type Check / python-ci (ubuntu-latest, 3.13) (push) Has been cancelled
Python Build and Type Check / python-ci (windows-latest, 3.11) (push) Has been cancelled
Python Build and Type Check / python-ci (windows-latest, 3.13) (push) Has been cancelled
Python Integration Tests / python-ci (ubuntu-latest, 3.13) (push) Has been cancelled
Python Integration Tests / python-ci (windows-latest, 3.13) (push) Has been cancelled
Python Notebook Tests / python-ci (ubuntu-latest, 3.13) (push) Has been cancelled
Python Notebook Tests / python-ci (windows-latest, 3.13) (push) Has been cancelled
Python Smoke Tests / python-ci (ubuntu-latest, 3.13) (push) Has been cancelled
Python Smoke Tests / python-ci (windows-latest, 3.13) (push) Has been cancelled
Python Unit Tests / python-ci (ubuntu-latest, 3.13) (push) Has been cancelled
Python Unit Tests / python-ci (windows-latest, 3.13) (push) Has been cancelled
gh-pages / build (push) Has been cancelled
Python Publish (pypi) / Upload release to PyPI (push) Has been cancelled
Spellcheck / spellcheck (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 12:37:31 +08:00

266 lines
10 KiB
Python

# Copyright (c) 2024 Microsoft Corporation.
# Licensed under the MIT License
"""Completion Abstract Base Class."""
from abc import ABC, abstractmethod
from contextlib import contextmanager
from typing import TYPE_CHECKING, Any, Unpack
from graphrag_llm.threading.completion_thread_runner import completion_thread_runner
if TYPE_CHECKING:
from collections.abc import AsyncIterator, Iterator
from graphrag_cache import Cache, CacheKeyCreator
from graphrag_llm.config import ModelConfig
from graphrag_llm.metrics import MetricsProcessor, MetricsStore
from graphrag_llm.rate_limit import RateLimiter
from graphrag_llm.retry import Retry
from graphrag_llm.threading.completion_thread_runner import (
ThreadedLLMCompletionFunction,
ThreadedLLMCompletionResponseHandler,
)
from graphrag_llm.tokenizer import Tokenizer
from graphrag_llm.types import (
LLMCompletionArgs,
LLMCompletionChunk,
LLMCompletionResponse,
ResponseFormat,
)
class LLMCompletion(ABC):
"""Abstract base class for language model completions."""
@abstractmethod
def __init__(
self,
*,
model_id: str,
model_config: "ModelConfig",
tokenizer: "Tokenizer",
metrics_store: "MetricsStore",
metrics_processor: "MetricsProcessor | None" = None,
rate_limiter: "RateLimiter | None" = None,
retrier: "Retry | None" = None,
cache: "Cache | None" = None,
cache_key_creator: "CacheKeyCreator",
**kwargs: Any,
):
"""Initialize the LLMCompletion.
Args
----
model_id: str
The model ID, e.g., "openai/gpt-4o".
model_config: ModelConfig
The configuration for the language model.
tokenizer: Tokenizer
The tokenizer to use.
metrics_store: MetricsStore | None (default=None)
The metrics store to use.
metrics_processor: MetricsProcessor | None (default: None)
The metrics processor to use.
rate_limiter: RateLimiter | None (default=None)
The rate limiter to use.
retrier: Retry | None (default=None)
The retry strategy to use.
cache: Cache | None (default=None)
Optional cache for embeddings.
cache_key_creator: CacheKeyCreator | None (default=None)
Optional cache key creator function.
(dict[str, Any]) -> str
**kwargs: Any
Additional keyword arguments.
"""
raise NotImplementedError
@abstractmethod
def completion(
self,
/,
**kwargs: Unpack["LLMCompletionArgs[ResponseFormat]"],
) -> "LLMCompletionResponse[ResponseFormat] | Iterator[LLMCompletionChunk]":
"""Sync completion method.
Args
----
messages: LLMCompletionMessagesParam
The messages to send to the LLM.
Can be str | list[dict[str, str]] | list[ChatCompletionMessageParam].
response_format: BaseModel | None (default=None)
The structured response format.
Must extend pydantic BaseModel.
stream: bool (default=False)
Whether to stream the response.
streaming is not supported when using response_format.
max_completion_tokens: int | None (default=None)
The maximum number of tokens to generate in the completion.
temperature: float | None (default=None)
The temperature to control how deterministic vs. creative the responses are.
top_p: float | None (default=None)
top_p for nucleus sampling, where the model considers tokens with
cumulative probabilities up to top_p. Values range from 0 to 1.
n: int | None (default=None)
The number of completions to generate for each prompt.
tools: list[Tool] | None (default=None)
Optional tools to use during completion.
https://docs.litellm.ai/docs/completion/function_call
**kwargs: Any
Additional keyword arguments.
Returns
-------
LLMCompletionResponse[ResponseFormat] | Iterator[LLMCompletionChunk]:
The completion response or an iterator of completion chunks if streaming.
"""
raise NotImplementedError
@abstractmethod
async def completion_async(
self,
/,
**kwargs: Unpack["LLMCompletionArgs[ResponseFormat]"],
) -> "LLMCompletionResponse[ResponseFormat] | AsyncIterator[LLMCompletionChunk]":
"""Async completion method.
Args
----
messages: LLMCompletionMessagesParam
The messages to send to the LLM.
Can be str | list[dict[str, str]] | list[ChatCompletionMessageParam].
response_format: BaseModel | None (default=None)
The structured response format.
Must extend pydantic BaseModel.
stream: bool (default=False)
Whether to stream the response.
streaming is not supported when using response_format.
max_completion_tokens: int | None (default=None)
The maximum number of tokens to generate in the completion.
temperature: float | None (default=None)
The temperature to control how deterministic vs. creative the responses are.
top_p: float | None (default=None)
top_p for nucleus sampling, where the model considers tokens with
cumulative probabilities up to top_p. Values range from 0 to 1.
n: int | None (default=None)
The number of completions to generate for each prompt.
tools: list[Tool] | None (default=None)
Optional tools to use during completion.
https://docs.litellm.ai/docs/completion/function_call
**kwargs: Any
Additional keyword arguments.
Returns
-------
LLMCompletionResponse[ResponseFormat] | Iterator[LLMCompletionChunk]:
The completion response or an iterator of completion chunks if streaming.
"""
raise NotImplementedError
@contextmanager
def completion_thread_pool(
self,
*,
response_handler: "ThreadedLLMCompletionResponseHandler",
concurrency: int,
queue_limit: int = 0,
) -> "Iterator[ThreadedLLMCompletionFunction]":
"""Run a completion thread pool.
Args
----
response_handler: ThreadedLLMCompletionResponseHandler
The callback function to handle completion responses.
(request_id, response|exception) -> Awaitable[None] | None
concurrency: int
The number of threads to spin up in a thread pool.
queue_limit: int (default=0)
The maximum number of items allowed in the input queue.
0 means unlimited.
Set this to a value to create backpressure on the caller.
Yields
------
ThreadedLLMCompletionFunction:
A function that can be used to submit completion requests to the thread pool.
(messages, request_id, **kwargs) -> None
The thread pool will process the requests and invoke the provided callback
with the responses.
same signature as LLMCompletionFunction but requires a `request_id` parameter
to identify the request and does not return anything.
"""
with completion_thread_runner(
completion=self.completion,
response_handler=response_handler,
concurrency=concurrency,
queue_limit=queue_limit,
metrics_store=self.metrics_store,
) as completion:
yield completion
def completion_batch(
self,
completion_requests: list["LLMCompletionArgs[ResponseFormat]"],
*,
concurrency: int,
queue_limit: int = 0,
) -> list[
"LLMCompletionResponse[ResponseFormat] | Iterator[LLMCompletionChunk] | Exception"
]:
"""Process a batch of completion requests using a thread pool.
Args
----
completion_requests: list[LLMCompletionArgs]
A list of completion request arguments to process in parallel.
concurrency: int
The number of threads to spin up in a thread pool.
queue_limit: int (default=0)
The maximum number of items allowed in the input queue.
0 means unlimited.
Set this to a value to create backpressure on the caller.
Returns
-------
list[LLMCompletionResponse[ResponseFormat] | Iterator[LLMCompletionChunk] | Exception]:
A list of completion responses or exceptions corresponding to all the requests.
"""
responses: list[
LLMCompletionResponse[ResponseFormat]
| Iterator[LLMCompletionChunk]
| Exception
] = [None] * len(completion_requests) # type: ignore
def handle_response(
request_id: str,
resp: "LLMCompletionResponse[ResponseFormat] | Iterator[LLMCompletionChunk] | Exception",
):
responses[int(request_id)] = resp
with self.completion_thread_pool(
response_handler=handle_response,
concurrency=concurrency,
queue_limit=queue_limit,
) as threaded_completion:
for idx, request in enumerate(completion_requests):
threaded_completion(request_id=str(idx), **request)
return responses
@property
@abstractmethod
def metrics_store(self) -> "MetricsStore":
"""Metrics store."""
raise NotImplementedError
@property
@abstractmethod
def tokenizer(self) -> "Tokenizer":
"""Tokenizer."""
raise NotImplementedError