LLMService: add on_function_calls_started event

This commit is contained in:
Aleix Conchillo Flaqué
2025-05-30 09:18:01 -07:00
parent 40b52cadde
commit f0cbdc4e68
2 changed files with 24 additions and 1 deletions

View File

@@ -9,6 +9,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Added
- Added LLM services `on_function_calls_started` event. This event will be
triggered when the LLM service receives function calls from the model and is
going to start executing them.
- Function calls can now be executed sequentially (in the order received in the
completion) by passing `run_in_parallel=False` when creating your LLM
service. By default, if the LLM completion returns 2 or more function calls

View File

@@ -124,7 +124,23 @@ class FunctionCallRunnerItem:
class LLMService(AIService):
"""This class is a no-op but serves as a base class for LLM services."""
"""This is the base class for all LLM services. It handles function calling
registration and execution. The class also provides event handlers.
An event to know when an LLM service completion timeout occurs:
@task.event_handler("on_completion_timeout")
async def on_completion_timeout(service):
...
And an event to know that function calls have been received from the LLM
service and that we are going to start executing them:
@task.event_handler("on_function_calls_started")
async def on_function_calls_started(service, function_calls: Sequence[FunctionCallFromLLM]):
...
"""
# OpenAILLMAdapter is used as the default adapter since it aligns with most LLM implementations.
# However, subclasses should override this with a more specific adapter when necessary.
@@ -139,6 +155,7 @@ class LLMService(AIService):
self._function_call_tasks: Dict[asyncio.Task, FunctionCallRunnerItem] = {}
self._sequential_runner_task: Optional[asyncio.Task] = None
self._register_event_handler("on_function_calls_started")
self._register_event_handler("on_completion_timeout")
def get_llm_adapter(self) -> BaseLLMAdapter:
@@ -219,6 +236,8 @@ class LLMService(AIService):
return function_name in self._functions.keys()
async def run_function_calls(self, function_calls: Sequence[FunctionCallFromLLM]):
await self._call_event_handler("on_function_calls_started", function_calls)
total_function_calls = len(function_calls)
for index, function_call in enumerate(function_calls):
if function_call.function_name in self._functions.keys():