minimaxir / simpleaichat

Python package for easily interfacing with chat apps, with robust features and minimal code complexity.
MIT License
3.43k stars 224 forks source link

`ai.get_session().messages` is ambiguous #23

Open keyboardAnt opened 1 year ago

keyboardAnt commented 1 year ago
>>> ai = AIChat(api_key=OPENAI_API_KEY, console=False, params={"temperature": 0, "max_tokens": 100})
>>> ai("Hi")
>>> ai("Write me a poem over 4 lines.")
>>> ai.get_session().messages
[Hi,
 Hello! How can I assist you today?,
 Write me a poem over 4 lines.,
 Sure, here's a short poem for you:

 The sun sets in the west,
 As the birds fly to their nest,
 The world slows down to rest,
 And dreams come to manifest.]

Comparing to ai.get_session().dict()["messages"]:

[{'role': 'user',
  'content': 'Hi',
  'received_at': datetime.datetime(2023, 6, 20, 21, 59, 46, 826026, tzinfo=datetime.timezone.utc),
  'prompt_length': None,
  'completion_length': None,
  'total_length': None},
 {'role': 'assistant',
  'content': 'Hello! How can I assist you today?',
  'received_at': datetime.datetime(2023, 6, 20, 21, 59, 47, 774669, tzinfo=datetime.timezone.utc),
  'prompt_length': 20,
  'completion_length': 9,
  'total_length': 29},
 {'role': 'user',
  'content': 'Write me a poem over 4 lines.',
  'received_at': datetime.datetime(2023, 6, 20, 22, 0, 14, 373825, tzinfo=datetime.timezone.utc),
  'prompt_length': None,
  'completion_length': None,
  'total_length': None},
 {'role': 'assistant',
  'content': "Sure, here's a short poem for you:\n\nThe sun sets in the west,\nAs the birds fly to their nest,\nThe world slows down to rest,\nAnd dreams come to manifest.",
  'received_at': datetime.datetime(2023, 6, 20, 22, 0, 16, 531229, tzinfo=datetime.timezone.utc),
  'prompt_length': 48,
  'completion_length': 38,
  'total_length': 86}]

Would it be safer to rename messages to _messages to communicate you shouldn't access it directly?

minimaxir commented 1 year ago

No, the reason it's different is due to:

https://github.com/minimaxir/simpleaichat/blob/d8f04a5c0414356337beb0c392236ee48c38b865/simpleaichat/models.py#L35-L36

Printing the messages without that decorator results in the full Pydantic object being printed, which is ugly.

You should access it directly, I'm not sure how to best display it since displaying the full ChatMessage is ugly.

A compromise might be to do

def __str__(self) -> str:
    return self.dict(exclude_none=True)