What's Changed
* Use Ellipses in functions with docstrings by jackmpcollins in https://github.com/jackmpcollins/magentic/pull/109
* Use function instead of FunctionCall in FunctionResultMessage by jackmpcollins in https://github.com/jackmpcollins/magentic/pull/110
* Add format method to Message. Allow registering new types with message_to_openai_message by jackmpcollins in https://github.com/jackmpcollins/magentic/pull/114
* poetry update by jackmpcollins in https://github.com/jackmpcollins/magentic/pull/115
* Add last_message property to Chat by jackmpcollins in https://github.com/jackmpcollins/magentic/pull/117
**Full Changelog**: https://github.com/jackmpcollins/magentic/compare/v0.14.1...v0.15.0
---
`Message` subclasses now have a `format` method to customize their value using the function arguments when used with the `chatprompt` decorator. This allows for more complex templating than just the string templating that is currently supported. For a real use case with GPT-4-vision see in-progress PR https://github.com/jackmpcollins/magentic/pull/116
python
from typing import Any
from magentic import chatprompt
from magentic.chat_model.message import Message
class UppercaseMessage(Message[str]):
def format(self, **kwargs: Any) -> "UppercaseMessage":
upper_kwargs = {k: str(v).upper() for k, v in kwargs.items()}
return UppercaseMessage(self.content.format(**upper_kwargs))
chatprompt(
UppercaseMessage("hello {x}"),
)
def say_hello(x: str) -> str:
...
say_hello.format("world")
[UppercaseMessage('hello WORLD')]
In addition, the openai JSON serialization for custom `Message` subclasses can be added without modifying `magentic` itself! This uses [the functools.singledispatch decorator](https://docs.python.org/3/library/functools.html#functools.singledispatch). Together, these changes will allow users to create `Message` classes that they can template exactly as needed, which will be useful as the variety of types of inputs to LLMs increases.
python
from typing import Any
from magentic.chat_model.openai_chat_model import OpenaiMessageRole, message_to_openai_message
from magentic.chat_model.message import Message
from openai.types.chat import ChatCompletionMessageParam
class CustomMessage(Message[str]):
def format(self, **kwargs: Any) -> "CustomMessage":
return CustomMessage(self.content)
message_to_openai_message.register
def _(message: CustomMessage) -> ChatCompletionMessageParam:
return {"role": OpenaiMessageRole.USER.value, "content": message.content}
message_to_openai_message(CustomMessage("hello"))
{'role': 'user', 'content': 'hello'}
PR https://github.com/jackmpcollins/magentic/pull/114
---
> [!WARNING]
> Breaking Change: `FunctionResultMessage` init param `function_call: FunctionCall` replaced by `function: Callable`
Only the name of the function is needed when serializing the `FunctionResultMessage` so we do not need the whole `FunctionCall`. This simplifies creating `chatprompt` function where the chat contains a function call. e.g.
python
from magentic import (
chatprompt,
AssistantMessage,
UserMessage,
FunctionCall,
FunctionResultMessage,
)
def plus(a: int, b: int) -> int:
return a + b
chatprompt(
UserMessage("Use the plus function to add 1 and 2."),
AssistantMessage(FunctionCall(plus, 1, 2)),
FunctionResultMessage(3, plus),
)
def do_math() -> str:
...
do_math()
'The sum of 1 and 2 is 3.'
PR https://github.com/jackmpcollins/magentic/pull/110