Skip to content

Commit

Permalink
Merge pull request #131 from rgbkrk/tool-call-2-tool-caller
Browse files Browse the repository at this point in the history
migrate over to a simple tool view model
  • Loading branch information
rgbkrk authored Feb 27, 2024
2 parents 7b18f9c + 38248a0 commit 2b0e0cc
Show file tree
Hide file tree
Showing 16 changed files with 886 additions and 1,276 deletions.
2 changes: 1 addition & 1 deletion chatlab/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
tool_result
)
from .registry import FunctionRegistry
from .views.markdown import Markdown
from spork import Markdown


# Deprecate Session in favor of Chat
Expand Down
2 changes: 1 addition & 1 deletion chatlab/builtins/files.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

import aiofiles

from chatlab.decorators import expose_exception_to_llm
from ..decorators import expose_exception_to_llm


@expose_exception_to_llm
Expand Down
2 changes: 1 addition & 1 deletion chatlab/builtins/python.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from repr_llm import register_llm_formatter
from repr_llm.pandas import format_dataframe_for_llm, format_series_for_llm

from chatlab.decorators import expose_exception_to_llm
from ..decorators import expose_exception_to_llm

from ._mediatypes import pluck_richest_text, redisplay_superrich

Expand Down
47 changes: 22 additions & 25 deletions chatlab/chat.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,11 @@
from openai.types.chat import ChatCompletion, ChatCompletionChunk, ChatCompletionMessageParam
from pydantic import BaseModel

from chatlab.views.assistant_function_call import AssistantFunctionCallView

from ._version import __version__
from .display import ChatFunctionCall
from .errors import ChatLabError
from .messaging import human
from .registry import FunctionRegistry, PythonHallucinationFunction
from .views.assistant import AssistantMessageView
from .views import ToolArguments, AssistantMessageView

logger = logging.getLogger(__name__)

Expand Down Expand Up @@ -145,9 +142,9 @@ async def __call__(self, *messages: Union[ChatCompletionMessageParam, str], stre

async def __process_stream(
self, resp: AsyncStream[ChatCompletionChunk]
) -> Tuple[str, Optional[AssistantFunctionCallView]]:
) -> Tuple[str, Optional[ToolArguments]]:
assistant_view: AssistantMessageView = AssistantMessageView()
function_view: Optional[AssistantFunctionCallView] = None
function_view: Optional[ToolArguments] = None
finish_reason = None

async for result in resp: # Go through the results of the stream
Expand All @@ -162,37 +159,41 @@ async def __process_stream(
# Is stream choice?
if choice.delta is not None:
if choice.delta.content is not None:
assistant_view.display_once()
assistant_view.append(choice.delta.content)
elif choice.delta.function_call is not None:
function_call = choice.delta.function_call
if function_call.name is not None:
if assistant_view.in_progress():
if not assistant_view.finished:
# Flush out the finished assistant message
message = assistant_view.flush()
message = assistant_view.get_message()
self.append(message)
function_view = AssistantFunctionCallView(function_call.name)
# IDs are for the tool calling apparatus from newer versions of the API
# We will make use of it later.
function_view = ToolArguments(id="TBD", name=function_call.name)
function_view.display()
if function_call.arguments is not None:
if function_view is None:
raise ValueError("Function arguments provided without function name")
function_view.append(function_call.arguments)
function_view.append_arguments(function_call.arguments)
if choice.finish_reason is not None:
finish_reason = choice.finish_reason
break

# Wrap up the previous assistant
# Note: This will also wrap up the assistant's message when it ran out of tokens
if assistant_view.in_progress():
message = assistant_view.flush()
if not assistant_view.finished:
message = assistant_view.get_message()
self.append(message)

if finish_reason is None:
raise ValueError("No finish reason provided by OpenAI")

return (finish_reason, function_view)

async def __process_full_completion(self, resp: ChatCompletion) -> Tuple[str, Optional[AssistantFunctionCallView]]:
async def __process_full_completion(self, resp: ChatCompletion) -> Tuple[str, Optional[ToolArguments]]:
assistant_view: AssistantMessageView = AssistantMessageView()
function_view: Optional[AssistantFunctionCallView] = None
function_view: Optional[ToolArguments] = None

if len(resp.choices) == 0:
logger.warning(f"Result has no choices: {resp}")
Expand All @@ -203,12 +204,13 @@ async def __process_full_completion(self, resp: ChatCompletion) -> Tuple[str, Op
message = choice.message

if message.content is not None:
assistant_view.display_once()
assistant_view.append(message.content)
self.append(assistant_view.flush())
self.append(assistant_view.get_message())
if message.function_call is not None:
function_call = message.function_call
function_view = AssistantFunctionCallView(function_name=function_call.name)
function_view.append(function_call.arguments)
function_view = ToolArguments(id="TBD", name=function_call.name, arguments=function_call.arguments)
function_view.display()

return choice.finish_reason, function_view

Expand Down Expand Up @@ -286,17 +288,12 @@ async def submit(self, *messages: Union[ChatCompletionMessageParam, str], stream
"Function call was the stated function_call reason without having a complete function call. If you see this, report it as an issue to https://github.com/rgbkrk/chatlab/issues" # noqa: E501
)
# Record the attempted call from the LLM
self.append(function_call_request.get_message())
self.append(function_call_request.get_function_message())

chat_function = ChatFunctionCall(
**function_call_request.finalize(),
function_registry=self.function_registry,
)
function_called = await function_call_request.call(function_registry=self.function_registry)

# Make the call
fn_message = await chat_function.call()
# Include the response (or error) for the model
self.append(fn_message)
self.append(function_called.get_function_called_message())

# Reply back to the LLM with the result of the function call, allow it to continue
await self.submit(stream=stream, **kwargs)
Expand Down
109 changes: 0 additions & 109 deletions chatlab/display.py

This file was deleted.

7 changes: 3 additions & 4 deletions chatlab/views/__init__.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
"""Views for ChatLab."""
from .assistant import AssistantMessageView
from .assistant_function_call import AssistantFunctionCallView
from .markdown import Markdown
from .tools import ToolArguments, ToolCalled

__all__ = [
"AssistantMessageView",
"AssistantFunctionCallView",
"Markdown",
"ToolArguments",
"ToolCalled"
]
101 changes: 0 additions & 101 deletions chatlab/views/abstracts.py

This file was deleted.

Loading

0 comments on commit 2b0e0cc

Please sign in to comment.