Skip to content

Instantly share code, notes, and snippets.

@tslmy
Last active October 13, 2024 02:32
Show Gist options
  • Save tslmy/7e15e93ed76da167f6a0bd663946fa40 to your computer and use it in GitHub Desktop.
Save tslmy/7e15e93ed76da167f6a0bd663946fa40 to your computer and use it in GitHub Desktop.
Together AI API issue

Discovered this unexpected behavior while using Together AI as an OpenAI-compatible API with LlamaIndex:

        Settings.llm = OpenAILike(
            model="meta-llama/Meta-Llama-3.1-70B-Instruct-Turbo",
            api_base="https://api.together.xyz/v1",
            temperature=0.1,
            api_key=api_key,
            is_function_calling_model=True,
            is_chat_model=True,
        )

Summary of steps to reproduce the unexpected behavior:

  1. Create an agent with tools.
  2. Chat with the agent by asking it to run a tool. The agent should successfully execute the tool and respond.
  3. Chat with the agent again. Send any message. Observe that the agent will fail to respond.

Together AI API endpoint will respond with the following response:

  File ".venv/lib/python3.12/site-packages/openai/_base_client.py", line 1080, in _request
    raise self._make_status_error_from_response(err.response) from None
openai.InternalServerError: Error code: 503 - {'error': {'message': 'Server is overloaded.'}}

If we replace Settings.llm with an Ollama-powered OpenAILike instance...

        Settings.llm = OpenAILike(
            model="llama3.1",
            api_base="http://localhost:11434/v1",
            api_key="ollama",
            is_function_calling_model=True,
            is_chat_model=True,
        )

or OpenAI itself:

        Settings.llm = OpenAI(
            model="gpt-4o-mini",
            api_key=api_key,
            is_function_calling_model=True,
            is_chat_model=True,
        )

Things will work -- The agent will be able to respond to your further messages, and the conversation can continue.

To triage the error, we can modify site-packages/openai/_base_client.py by adding a line that says log.setLevel(logging.DEBUG).

Note that the 1st user-facing response from Together AI has an extra 'tool_calls': []}:

  • Together AI: {'role': 'assistant', 'content': 'The outcome of the 7-faced dice roll is 1.', 'tool_calls': []}
  • Ollama: {'role':'assistant', 'content': 'The outcome of rolling a 7-faced dice is: **4**.'}

Is that the issue?

Here's a minimal-reproducible script: https://gist.github.com/tslmy/7e15e93ed76da167f6a0bd663946fa40#file-reproducible_example-pyv

Run it. Observe:

{'error': {'message': 'Server is overloaded.'}}

This is cryptic, so we went the same request to OpenAI ...

-    "model": "meta-llama/Meta-Llama-3.1-70B-Instruct-Turbo",
+    "model": "gpt-4o-mini",
...
if __name__ == "__main__":
    response = requests.post(
-        "https://api.together.xyz/v1/chat/completions",
+        "https://api.openai.com/v1/chat/completions",
        headers={
            "Authorization": "Bearer TOKEN"
...

... and got this message instead:

{'error': {'message': "Invalid 'messages[4].tool_calls': empty array. Expected an array with minimum length 1, but got an empty array instead.", 'type': 'invalid_request_error', 'param': 'messages[4].tool_calls', 'code': 'empty_array'}}

Following this, we removed this line:

        {
            "role": "assistant",
            "content": "The outcome of rolling a 7-faced dice is 5.",
-            "tool_calls": [],
        },

And now Together AI can return something:

{'id': '8d1b84b4981915ca-SJC', 'object': 'chat.completion', 'created': 1728782544, 'model': 'meta-llama/Meta-Llama-3.1-70B-Instruct-Turbo', 'prompt': [], 'choices': [{'finish_reason': 'tool_calls', 'seed': 3333652833605527600, 'logprobs': None, 'index': 0, 'message': {'role': 'assistant', 'content': None, 'tool_calls': [{'index': 0, 'id': 'call_vynjh7tiz4m125r3f5mii8od', 'type': 'function', 'function': {'arguments': '{"n":"7"}', 'name': 'roll_a_dice'}}]}}], 'usage': {'prompt_tokens': 506, 'completion_tokens': 16, 'total_tokens': 522}}

There we see it. The response from Together AI's Chat Completion API seem to assign an empty list as a default value to its assistant responses. That's causing problems.

DEBUG [openai._base_client] Request options: {'method': 'post', 'url': '/chat/completions', 'files': None, 'json_data': {'messages': [{'role': 'system', 'content': "You are the Keeper of a game of _Call of Cthulhu_. The use
r is your player.\n\nIn addition to holding a normal conversation with the user, you may also need to help them create characters, conduct skill checks, and - most importantly - describe the current scene.\n\nIf you need to
, you can break the task down into subtasks and execute them step-by-step.\nYou are only allowed to execute at most 5 steps to complete the task.\nIf you cannot complete the task within the given steps, you should inform th
e user that you cannot answer the query.\nIf you don't cap at 5 steps, you will be penalized.\n"}, {'role': 'user', 'content': "Roll a 7-faced dice just for fun. What's the outcome?"}, {'role': 'assistant', 'content': None,
'tool_calls': [{'id': 'call_4p2br7n87kapalezreamnoua', 'function': {'arguments': '{"n":"7"}', 'name': 'roll_a_dice'}, 'type': 'function', 'index': 0}]}, {'role': 'tool', 'content': '4', 'name': 'roll_a_dice', 'tool_call_id
': 'call_4p2br7n87kapalezreamnoua'}, {'role': 'assistant', 'content': 'The outcome of the 7-faced dice roll is 4.', 'tool_calls': []}, {'role': 'user', 'content': 'Try again.'}], 'model': 'meta-llama/Meta-Llama-3.1-70B-Inst
ruct-Turbo', 'stream': False, 'temperature': 0.1, 'tool_choice': 'auto', 'tools': [{'type': 'function', 'function': {'name': 'search', 'description': 'search(query: str, max_results: Optional[int] = 6) -> List[llama_index.c
ore.schema.Document]\n\n Run query through Tavily Search and return metadata.\n\n Args:\n query: The query to search for.\n max_results: The maximum number of results to return.\n\n
Returns:\n results: A list of dictionaries containing the results:\n url: The url of the result.\n content: The content of the result.\n\n ', 'parameters': {'properties': {'
query': {'title': 'Query', 'type': 'string'}, 'max_results': {'anyOf': [{'type': 'integer'}, {'type': 'null'}], 'default': 6, 'title': 'Max Results'}}, 'required': ['query'], 'type': 'object'}}}, {'type': 'function', 'funct
ion': {'name': 'suggest_choices', 'description': "suggest_choices(situation: str = FieldInfo(annotation=NoneType, required=True, description='a brief description of the situation')) -> str\n\n If the user wants to kn
ow what skills their character can use in a particular situation (and what the possible consequences might be), you can use this tool.\n Note: This tool can only be used when the game is in progress. This is not a to
ol for meta-tasks like character creation.\n ", 'parameters': {'properties': {'situation': {'description': 'a brief description of the situation', 'title': 'Situation', 'type': 'string'}}, 'required': ['situation'],
'type': 'object'}}}, {'type': 'function', 'function': {'name': 'consult_the_game_module', 'description': 'consult_the_game_module(query: str = FieldInfo(annotation=NoneType, required=True, description=\'a brief description
of what you want to consult about\')) -> str\n\n If you feel you need to consult the module ("playbook" / handbook) about:\n\n - how the story should progress,\n - some factual data, or\n - how t
he situation / a particular NPC is set up,\n\n you can use this tool.\n ', 'parameters': {'properties': {'query': {'description': 'a brief description of what you want to consult about', 'title': 'Query', 'typ
e': 'string'}}, 'required': ['query'], 'type': 'object'}}}, {'type': 'function', 'function': {'name': 'roll_a_dice', 'description': "roll_a_dice(n: int = FieldInfo(annotation=NoneType, required=True, description='number of
faces of the dice to roll', metadata=[Gt(gt=0), Le(le=100)])) -> int\n\n Roll an n-faced dice and return the result.\n ", 'parameters': {'properties': {'n': {'description': 'number of faces of the dice to roll', 'excl
usiveMinimum': 0, 'maximum': 100, 'title': 'N', 'type': 'integer'}}, 'required': ['n'], 'type': 'object'}}}, {'type': 'function', 'function': {'name': 'roll_a_skill', 'description': "roll_a_skill(skill_value: int = FieldInf
o(annotation=NoneType, required=True, description='skill value', metadata=[Ge(ge=0), Le(le=100)]), difficulty: tools.Difficulty = FieldInfo(annotation=NoneType, required=False, default=<Difficulty.REGULAR: 0>, description='
difficulty level')) -> str\n\n Roll a skill check and check the result.\n ", 'parameters': {'$defs': {'Difficulty': {'description': 'For tasks:\n> A regular task requires a roll of equal to or less than your skill val
ue on 1D100 (a Regular success).\n> A difficult task requires a roll result equal to or less than half your skill value (a Hard success).\n> A task approaching the limits of human capability requires a roll equal to or less
than one-fifth of your skill\n> value (an Extreme success).\n\n([source](https://cthulhuwiki.chaosium.com/rules/game-system.html#skill-rolls-and-difficulty-levels))\n\n\nFor opposed rolls:\n- Regular: Opposing skill/char
acteristic is below 50.\n- Hard: Opposing skill/characteristic is equal to or above 50.\n- Extreme: Opposing skill/characteristic is equal to or above 90.\n\n([source](https://trpgline.com/en/rules/coc7/summary))', 'enum':
[0, 1, 2], 'title': 'Difficulty', 'type': 'integer'}}, 'properties': {'skill_value': {'description': 'skill value', 'maximum': 100, 'minimum': 0, 'title': 'Skill Value', 'type': 'integer'}, 'difficulty': {'allOf': [{'$ref':
'#/$defs/Difficulty'}], 'default': 0, 'description': 'difficulty level'}}, 'required': ['skill_value'], 'type': 'object'}}}, {'type': 'function', 'function': {'name': 'illustrate_a_scene', 'description': "illustrate_a_scen
e(scene_description: str = FieldInfo(annotation=NoneType, required=True, description='a detailed description of the scene')) -> str\n\n Illustrate a scene based on the description.\n The player may prefer seeing a vis
ual representation of the scene,\n so it may be a good idea to use this tool when you progress the story.\n ", 'parameters': {'properties': {'scene_description': {'description': 'a detailed description of the scene',
'title': 'Scene Description', 'type': 'string'}}, 'required': ['scene_description'], 'type': 'object'}}}, {'type': 'function', 'function': {'name': 'create_character', 'description': 'Create a character.', 'parameters': {'p
roperties': {'year': {'default': 1925, 'description': 'Year of the game, must be an integer starting from 1890.', 'minimum': 1890, 'title': 'Year', 'type': 'integer'}, 'country': {'description': "Country of the character's
origin. Available options: 'US', 'PL', 'ES'.", 'enum': ['US', 'PL', 'ES'], 'title': 'Country', 'type': 'string'}, 'first_name': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None, 'description': "Character's
first name, optional. A random name is used if omitted.", 'title': 'First Name'}, 'last_name': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None, 'description': "Character's last name, optional. A random nam
e is used if omitted.", 'title': 'Last Name'}, 'age': {'anyOf': [{'maximum': 90, 'minimum': 15, 'type': 'integer'}, {'type': 'null'}], 'default': None, 'description': "Character's age. Must be between 15 and 90. If omitted,
a random age is selected.", 'title': 'Age'}, 'sex': {'anyOf': [{'enum': ['M', 'F'], 'type': 'string'}, {'type': 'null'}], 'default': None, 'description': "Character's sex. Available options: 'M', 'F'. If omitted, sex is ch
osen randomly.", 'title': 'Sex'}, 'random_mode': {'default': False, 'description': 'If set to True, characteristics are ignored for random occupation generation.', 'title': 'Random Mode', 'type': 'boolean'}, 'occupation': {
'default': None, 'description': "Character's occupation. Must be a valid occupation or random if omitted.", 'enum': ['antiquarian', 'artist', 'athlete', 'author', 'entertainer', 'soldier', 'lawyer', 'librarian', 'military o
fficer', 'missionary', 'musician', 'parapsychologist', 'pilot', 'clergy', 'criminal', 'dilettante', 'doctor of medicine', 'drifter', 'engineer', 'farmer', 'hacker', 'journalist', 'police detective', 'police officer', 'priva
te investigator', 'professor', 'tribe member', 'zealot', 'sailor, naval', 'sailor, commercial', 'bartender', 'butler/valet', 'chauffeur', 'driver', 'mechanic', 'nurse', 'waiter', 'laborer, unskilled', 'gangster boss', 'depr
ogrammer', 'computer programmer/technician', 'software tester'], 'title': 'Occupation', 'type': 'string'}, 'skills': {'anyOf': [{'type': 'object'}, {'type': 'null'}], 'description': "Dictionary of character's skills. Defaul
ts to an empty dictionary.", 'title': 'Skills'}, 'occup_type': {'default': 'classic', 'description': "Occupation set type. Available options: 'classic', 'expansion', 'custom'.", 'enum': ['classic', 'expansion', 'custom'], '
title': 'Occup Type', 'type': 'string'}, 'era': {'default': 'classic-1920', 'description': "Era for the character. Available options: 'classic-1920', 'modern'.", 'enum': ['classic-1920', 'modern'], 'title': 'Era', 'type': '
string'}, 'tags': {'anyOf': [{'items': {'enum': ['lovecraftian', 'criminal'], 'type': 'string'}, 'type': 'array'}, {'type': 'null'}], 'default': None, 'description': "List of occupation tags. Available options: 'lovecraftia
n', 'criminal'.", 'title': 'Tags'}}, 'required': ['country'], 'type': 'object'}}}]}}
DEBUG [openai._base_client] Sending HTTP Request: POST https://api.together.xyz/v1/chat/completions
DEBUG [openai._base_client] HTTP Response: POST https://api.together.xyz/v1/chat/completions "503 Service Temporarily Unavailable" Headers({'date': 'Sun, 13 Oct 2024 02:00:19 GMT', 'content-type': 'application/json', 'conte
nt-length': '49', 'connection': 'keep-alive', 'strict-transport-security': 'max-age=2592000; includeSubDomains', 'x-frame-options': 'SAMEORIGIN', 'referrer-policy': 'same-origin', 'cache-control': 'private, max-age=0, no-st
ore, no-cache, must-revalidate, post-check=0, pre-check=0', 'expires': 'Thu, 01 Jan 1970 00:00:01 GMT', 'server': 'cloudflare', 'cf-ray': '8d1bbc40bfcbface-SJC', 'alt-svc': 'h3=":443"; ma=86400'})
DEBUG [openai._base_client] request_id: None
DEBUG [openai._base_client] Encountered httpx.HTTPStatusError
Traceback (most recent call last):
File "/Users/lmy/Projects/Cocai/.venv/lib/python3.12/site-packages/openai/_base_client.py", line 1059, in _request
response.raise_for_status()
File "/Users/lmy/Projects/Cocai/.venv/lib/python3.12/site-packages/httpx/_models.py", line 763, in raise_for_status
raise HTTPStatusError(message, request=request, response=self)
httpx.HTTPStatusError: Server error '503 Service Temporarily Unavailable' for url 'https://api.together.xyz/v1/chat/completions'
import requests
data = {
"messages": [
{
"role": "system",
"content": "You are the Keeper of a game of _Call of Cthulhu_. The user is your player.",
},
{
"role": "user",
"content": "Roll a 7-faced dice just for fun. What's the outcome?",
},
{
"role": "assistant",
"content": None,
"tool_calls": [
{
"id": "call_e3rntxdk4vaoq5c4c135uatk",
"function": {"arguments": '{"n":"7"}', "name": "roll_a_dice"},
"type": "function",
"index": 0,
}
],
},
{
"role": "tool",
"content": "5",
"name": "roll_a_dice",
"tool_call_id": "call_e3rntxdk4vaoq5c4c135uatk",
},
{
"role": "assistant",
"content": "The outcome of rolling a 7-faced dice is 5.",
"tool_calls": [],
},
{"role": "user", "content": "Try again?"},
],
"model": "meta-llama/Meta-Llama-3.1-70B-Instruct-Turbo",
"stream": False,
"temperature": 0.1,
"tool_choice": "auto",
"tools": [
{
"type": "function",
"function": {
"name": "roll_a_dice",
"description": "roll_a_dice(n: int = FieldInfo(annotation=NoneType, required=True, description='number of faces of the dice to roll', metadata=[Gt(gt=0), Le(le=100)])) -> int\n\n Roll an n-faced dice and return the result.\n ",
"parameters": {
"properties": {
"n": {
"description": "number of faces of the dice to roll",
"exclusiveMinimum": 0,
"maximum": 100,
"title": "N",
"type": "integer",
}
},
"required": ["n"],
"type": "object",
},
},
}
],
}
if __name__ == "__main__":
response = requests.post(
"https://api.together.xyz/v1/chat/completions",
headers={
"Authorization": "Bearer TOKEN"
},
json=data,
)
print(response.json())
DEBUG [openai._base_client] Request options: {'method': 'post', 'url': '/chat/completions', 'files': None, 'json_data': {'messages': [{'role': 'system', 'content': "You are the Keeper of a game of _Call of Cthulhu_. The use
r is your player.\n\nIn addition to holding a normal conversation with the user, you may also need to help them create characters, conduct skill checks, and - most importantly - describe the current scene.\n\nIf you need to
, you can break the task down into subtasks and execute them step-by-step.\nYou are only allowed to execute at most 5 steps to complete the task.\nIf you cannot complete the task within the given steps, you should inform th
e user that you cannot answer the query.\nIf you don't cap at 5 steps, you will be penalized.\n"}, {'role': 'user', 'content': "Roll a 7-faced dice just for fun. What's the outcome?"}, {'role': 'assistant', 'content': '', '
tool_calls': [{'id': 'call_uzcongje', 'function': {'arguments': '{"n":"7"}', 'name': 'roll_a_dice'}, 'type': 'function'}]}, {'role': 'tool', 'content': '7', 'name': 'roll_a_dice', 'tool_call_id': 'call_uzcongje'}, {'role':
'assistant', 'content': 'The outcome of rolling a 7-faced dice is: **4**.'}, {'role': 'user', 'content': 'Try again.'}], 'model': 'llama3.1', 'stream': False, 'temperature': 0.1, 'tool_choice': 'auto', 'tools': [{'type': 'f
unction', 'function': {'name': 'search', 'description': 'search(query: str, max_results: Optional[int] = 6) -> List[llama_index.core.schema.Document]\n\n Run query through Tavily Search and return metadata.\n\n
Args:\n query: The query to search for.\n max_results: The maximum number of results to return.\n\n Returns:\n results: A list of dictionaries containing the results:\n
url: The url of the result.\n content: The content of the result.\n\n ', 'parameters': {'properties': {'query': {'title': 'Query', 'type': 'string'}, 'max_results': {'anyOf': [{'type': 'integer'}, {
'type': 'null'}], 'default': 6, 'title': 'Max Results'}}, 'required': ['query'], 'type': 'object'}}}, {'type': 'function', 'function': {'name': 'suggest_choices', 'description': "suggest_choices(situation: str = FieldInfo(a
nnotation=NoneType, required=True, description='a brief description of the situation')) -> str\n\n If the user wants to know what skills their character can use in a particular situation (and what the possible conseq
uences might be), you can use this tool.\n Note: This tool can only be used when the game is in progress. This is not a tool for meta-tasks like character creation.\n ", 'parameters': {'properties': {'situatio
n': {'description': 'a brief description of the situation', 'title': 'Situation', 'type': 'string'}}, 'required': ['situation'], 'type': 'object'}}}, {'type': 'function', 'function': {'name': 'consult_the_game_module', 'des
cription': 'consult_the_game_module(query: str = FieldInfo(annotation=NoneType, required=True, description=\'a brief description of what you want to consult about\')) -> str\n\n If you feel you need to consult the mo
dule ("playbook" / handbook) about:\n\n - how the story should progress,\n - some factual data, or\n - how the situation / a particular NPC is set up,\n\n you can use this tool.\n ', 'para
meters': {'properties': {'query': {'description': 'a brief description of what you want to consult about', 'title': 'Query', 'type': 'string'}}, 'required': ['query'], 'type': 'object'}}}, {'type': 'function', 'function': {
'name': 'roll_a_dice', 'description': "roll_a_dice(n: int = FieldInfo(annotation=NoneType, required=True, description='number of faces of the dice to roll', metadata=[Gt(gt=0), Le(le=100)])) -> int\n\n Roll an n-faced di
ce and return the result.\n ", 'parameters': {'properties': {'n': {'description': 'number of faces of the dice to roll', 'exclusiveMinimum': 0, 'maximum': 100, 'title': 'N', 'type': 'integer'}}, 'required': ['n'], 'type'
: 'object'}}}, {'type': 'function', 'function': {'name': 'roll_a_skill', 'description': "roll_a_skill(skill_value: int = FieldInfo(annotation=NoneType, required=True, description='skill value', metadata=[Ge(ge=0), Le(le=100
)]), difficulty: tools.Difficulty = FieldInfo(annotation=NoneType, required=False, default=<Difficulty.REGULAR: 0>, description='difficulty level')) -> str\n\n Roll a skill check and check the result.\n ", 'parameters
': {'$defs': {'Difficulty': {'description': 'For tasks:\n> A regular task requires a roll of equal to or less than your skill value on 1D100 (a Regular success).\n> A difficult task requires a roll result equal to or less t
han half your skill value (a Hard success).\n> A task approaching the limits of human capability requires a roll equal to or less than one-fifth of your skill\n> value (an Extreme success).\n\n([source](https://cthulhuwik
i.chaosium.com/rules/game-system.html#skill-rolls-and-difficulty-levels))\n\n\nFor opposed rolls:\n- Regular: Opposing skill/characteristic is below 50.\n- Hard: Opposing skill/characteristic is equal to or above 50.\n- Ext
reme: Opposing skill/characteristic is equal to or above 90.\n\n([source](https://trpgline.com/en/rules/coc7/summary))', 'enum': [0, 1, 2], 'title': 'Difficulty', 'type': 'integer'}}, 'properties': {'skill_value': {'descrip
tion': 'skill value', 'maximum': 100, 'minimum': 0, 'title': 'Skill Value', 'type': 'integer'}, 'difficulty': {'allOf': [{'$ref': '#/$defs/Difficulty'}], 'default': 0, 'description': 'difficulty level'}}, 'required': ['skil
l_value'], 'type': 'object'}}}, {'type': 'function', 'function': {'name': 'illustrate_a_scene', 'description': "illustrate_a_scene(scene_description: str = FieldInfo(annotation=NoneType, required=True, description='a detail
ed description of the scene')) -> str\n\n Illustrate a scene based on the description.\n The player may prefer seeing a visual representation of the scene,\n so it may be a good idea to use this tool when you progr
ess the story.\n ", 'parameters': {'properties': {'scene_description': {'description': 'a detailed description of the scene', 'title': 'Scene Description', 'type': 'string'}}, 'required': ['scene_description'], 'type': '
object'}}}, {'type': 'function', 'function': {'name': 'create_character', 'description': 'Create a character.', 'parameters': {'properties': {'year': {'default': 1925, 'description': 'Year of the game, must be an integer st
arting from 1890.', 'minimum': 1890, 'title': 'Year', 'type': 'integer'}, 'country': {'description': "Country of the character's origin. Available options: 'US', 'PL', 'ES'.", 'enum': ['US', 'PL', 'ES'], 'title': 'Country',
'type': 'string'}, 'first_name': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None, 'description': "Character's first name, optional. A random name is used if omitted.", 'title': 'First Name'}, 'last_name':
{'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None, 'description': "Character's last name, optional. A random name is used if omitted.", 'title': 'Last Name'}, 'age': {'anyOf': [{'maximum': 90, 'minimum': 15
, 'type': 'integer'}, {'type': 'null'}], 'default': None, 'description': "Character's age. Must be between 15 and 90. If omitted, a random age is selected.", 'title': 'Age'}, 'sex': {'anyOf': [{'enum': ['M', 'F'], 'type': '
string'}, {'type': 'null'}], 'default': None, 'description': "Character's sex. Available options: 'M', 'F'. If omitted, sex is chosen randomly.", 'title': 'Sex'}, 'random_mode': {'default': False, 'description': 'If set to
True, characteristics are ignored for random occupation generation.', 'title': 'Random Mode', 'type': 'boolean'}, 'occupation': {'default': None, 'description': "Character's occupation. Must be a valid occupation or random
if omitted.", 'enum': ['antiquarian', 'artist', 'athlete', 'author', 'entertainer', 'soldier', 'lawyer', 'librarian', 'military officer', 'missionary', 'musician', 'parapsychologist', 'pilot', 'clergy', 'criminal', 'diletta
nte', 'doctor of medicine', 'drifter', 'engineer', 'farmer', 'hacker', 'journalist', 'police detective', 'police officer', 'private investigator', 'professor', 'tribe member', 'zealot', 'sailor, naval', 'sailor, commercial'
, 'bartender', 'butler/valet', 'chauffeur', 'driver', 'mechanic', 'nurse', 'waiter', 'laborer, unskilled', 'gangster boss', 'deprogrammer', 'computer programmer/technician', 'software tester'], 'title': 'Occupation', 'type'
: 'string'}, 'skills': {'anyOf': [{'type': 'object'}, {'type': 'null'}], 'description': "Dictionary of character's skills. Defaults to an empty dictionary.", 'title': 'Skills'}, 'occup_type': {'default': 'classic', 'descrip
tion': "Occupation set type. Available options: 'classic', 'expansion', 'custom'.", 'enum': ['classic', 'expansion', 'custom'], 'title': 'Occup Type', 'type': 'string'}, 'era': {'default': 'classic-1920', 'description': "Er
a for the character. Available options: 'classic-1920', 'modern'.", 'enum': ['classic-1920', 'modern'], 'title': 'Era', 'type': 'string'}, 'tags': {'anyOf': [{'items': {'enum': ['lovecraftian', 'criminal'], 'type': 'string'
}, 'type': 'array'}, {'type': 'null'}], 'default': None, 'description': "List of occupation tags. Available options: 'lovecraftian', 'criminal'.", 'title': 'Tags'}}, 'required': ['country'], 'type': 'object'}}}]}}
DEBUG [openai._base_client] Sending HTTP Request: POST http://localhost:11434/v1/chat/completions
DEBUG [openai._base_client] HTTP Response: POST http://localhost:11434/v1/chat/completions "200 OK" Headers({'content-type': 'application/json', 'date': 'Sun, 13 Oct 2024 02:19:36 GMT', 'content-length': '451'})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment