Local LLM Usage
Has anyone tried running it locally?
I adapted it for use with LM Studio by changing the tokenizer, LLM calls, and configurations. The connection to the API endpoint works, and persona creation is successful. However, listen_and_act or run fails, consistently producing an error related to the cognitive state attribute due to an empty response.
I have tried using LLaMA 3B, 1B, and Hermes 3 8B. I also increased the maximum tokens from 4000 to 8000. the LLM generates nonsensical tokens, so I reduced the temperature from 1.5 to 0.8.
I’m reaching out to see if anyone else has experienced this issue and how they managed to resolve it.
@aminekhelif have you tried this one? https://github.com/microsoft/TinyTroupe/issues/17#issuecomment-2477531837
@saiqulhaq Yes, I set the timeout to 120 and lowered all the temperatures. It seems to work better in terms of generating meaningless tokens, but I’m still encountering the cognitive state issue in almost all tests.
@aminekhelif try to use somehow "strong" models e.g. >10B like qwen2.5:14b
@d8rt8v
Yes, I also tried using nvidia_llama-3.1-nemotron-70b-instruct-hf.
It performs better in the test campaign, but the cognitive_state problem still appears.
with this config
MODEL=nvidia_llama-3.1-nemotron-70b-instruct-hf
MAX_TOKENS=3000
TEMPERATURE=0.0
FREQ_PENALTY=0.0
PRESENCE_PENALTY=0.0
TIMEOUT=480
MAX_ATTEMPTS=5
WAITING_TIME=5
EXPONENTIAL_BACKOFF_FACTOR=5
BASE_URL=http://localhost:1234/v1
EMBEDDING_MODEL=text-embedding-nomic-embed-text-1.5
CACHE_API_CALLS=True
CACHE_FILE_NAME=openai_api_cache.pickle
@aminekhelif
This is more specifically geared towards Ollama and my own specific testing, but this may be of some help regardless.
Try a simple test script like this one:
# simple_chat_demo.py
import logging
from tinytroupe.examples import create_lisa_the_data_scientist, create_oscar_the_architect
from tinytroupe.environment import TinyWorld
# Optional: Configure logging level for debugging
logging.basicConfig(level=logging.INFO)
# DISCLAIMER
print("""
!!!!
DISCLAIMER: TinyTroupe relies on Artificial Intelligence (AI) models to generate content.
The AI models are not perfect and may produce inappropriate or inaccurate results.
For any serious or consequential use, please review the generated content before using it.
!!!!
""")
# Step 1: Create the agents
lisa = create_lisa_the_data_scientist()
oscar = create_oscar_the_architect()
# Step 2: Create the environment (TinyWorld) and add agents
world = TinyWorld("Chat Room", [lisa, oscar])
world.make_everyone_accessible()
# Step 3: Define the initial user input to Lisa
lisa.listen("Talk to Oscar and ask about him")
# Step 4: Run the simulation for 4 steps
print("\nRunning the simulation...\n")
world.run(steps=4)
# Step 5: Print the conversation history
print("\nConversation History:")
for step_num, step in enumerate(world.history, start=1):
print(f"\n--- Step {step_num} ---\n{step}")
You will likely see the same error. I would then go into the "tinyperson.mustache" file located within the prompts directory and simplify it a lot. Start with something like this:
You are {{name}}, a {{occupation}}.
Respond only in JSON format using this structure:
{
"action": {"type": ACTION_TYPE, "content": CONTENT, "target": TARGET},
"cognitive_state": {"goals": GOALS, "attention": ATTENTION, "emotions": EMOTIONS}
}
Assuming the changes you made in the other related scripts to use LM Studio are correct, you should see some output and no error. It will be far less intricate than the output from running that same sample script with gpt4o via API, but it gives a good starting point to build the prompt out to be more detailed.
I believe that when using a local model, the original prompt can easily overwhelm it and cause errors. The way around this that has worked for me is as above, where I start with a simpler prompt and abstract it out to be more detailed, but not so large that the model is overwhelmed by it.
I have tested this with qwen 32b and it is working fine with a decently large prompt. I will post a forked repo of this working with ollama in the next couple of days. I hope this helps.
just a heads up, from the little work (like an afternoon) I did on getting the local models up and running. There are two issues when working with the local models. The first is that the "cognitive_state" issue is due to the local LLMs dropping the formatting. If you print the output from the model you can follow the responses and see where the formatting changes, triggering the error. I saw outputs ranging from "cognitivestate": {"goals": GOALS, "attention": ATTENTION, "emotions": EMOTIONS} to {"goals": GOALS, "attention": ATTENTION, "emotions": EMOTIONS}.
This is commented in "agents.py" in "repeat_on_error".
The only way to fix this that i could think of at the time was to build an extension that will manage the cognitive_state and hard code the output.
While that solution solves the formatting issue, it would not solve the second issue, which is tracking each element correctly during longer exchanges. Each element of the "cognitive_state" would need a separate request and system prompt that focused only on that aspect. This would also then require passing the exchange as part of the request. (StarTrek Holodec subroutines?)
I don't know how scalable this would be in a larger multi agent environment, it feels like it would be beyond current local LLM infrastructure available. (even my 4090 has limits)
An LLM that scores high on needle in a haystack test could also solve this issue but I have not tested this theory.
I experienced similar issues with the cognitive state formatting from the LLM responses with Qwen2.5-32b & Ollama. I agree implementing the full capabilities would be too resource-intensive for local setups.
For my exploratory purposes, I got some workable results by adding basic error handling to deal with missing cognitive states in the OllamaClient integration I placed in the openai_utils script.
I also (after an embarrassingly long time) realized I should probably lower the temp from 0.7 to 0.1 which helped a lot with response consistency. It's definitely not a complete solution, but it works well enough with the simple demo script to experiment with agent interactions, even though it isn't as in depth as what you can achieve with the gpt4o api.
I forked it here if it will be of any use to anyone: https://github.com/OminousIndustries/TinyTroupeOllama
I also noticed that simplifying the prompt in the tinyperson.mustache helped and was good for testing response behavior changes due to prompt differences.
I'm getting the same error with Zhipu's LLM model. KeyError: 'cognitive_state'
After 7 hours of testing, I successfully resolved the cognitive state problem by implementing structured output schemas for each prompt. This ensures that the LLM’s output is guided, resulting in a JSON response containing the necessary keys for proper response handling.
If anyone is interested, you can find the implementation in my fork under the bug-fix branch.
The errors shown in the test report are mostly timeout errors, but there are no instances of the cognitive state error.
If the project leads see value , I can submit a PR.
Note: I kept the same prompts and temperatures. (Avoid using distilled or small LLMs; they struggle with high temperatures and cannot generate consistent content.)
Here’s my configuration:
MODEL=rombos-llm-v2.5-qwen-32b #Rombos-LLM-V2.5-Qwen-32b.Q8_0.gguf
MAX_TOKENS=4000
TEMPERATURE=0.3
FREQ_PENALTY=0.1
PRESENCE_PENALTY=0.1
TIMEOUT=240
MAX_ATTEMPTS=5
WAITING_TIME=1
Hi @aminekhelif I am interested to know more about what you did. I looked at your forked project but the documentation do not clearly mention which part of the code you have modified. I read through some of your code but since Ollama just recently released the Pydantic Structured output formatting, would it not be much easier to structure the output using this functionality?
As the system default use EpisodicMemory, the LLM messages will added {'role': 'assistant', 'content': "Info: there were other messages here, but they were omitted for brevity.", 'simulation_timestamp': None} automatically.
when use Zhipu model, the Zhipu model will return the content is '', so the ‘cognitive_state’ is None.
We can change the include_omission_info to False to fix it.
@OriginalGoku I didn’t modify the README file, but in essence, I adapted the LLM calls to work with local LLMs (like LMStudio in my case). I also added all the response schemas. You can find the JSON files representing the schemas for each prompt (mustache) file, based on the expected output from the LLM. By adding these response schemas, we enforce a structured output. In LMStudio, I know this functionality has been handled for a while now. I’m not sure about Ollama, but it works well with Pydantic classes for LMStudio.
Maybe related to this https://github.com/microsoft/TinyTroupe/pull/47#issuecomment-2568334686
@4F2E4A2E Have you tried my fork ? ps : i use lm studio
I did try your fork and thank you for that, unfortunately, same result.
@4F2E4A2E
you tried this branch ?
i use lm studio not Ollama
Not that branch. I saw your comments on llm studio, but did choose to avoid llm studio because I have the impression that ollama is near to the OpenAI rest protocol schema.
Maybe I was wrong? I will try your branch in the morning. Thanks for taking the time and laying it out for me.
@aminekhelif it worked like a charm. Thank you for your fork and branch, you should definitely create a PR for the tiny-troupe. It was a bit weird working out the config for the config.ini but at last this worked all out, hosting the model via ollama:
[OpenAI]
API_TYPE=openai
API_KEY=lms
BASE_URL=http://host.docker.internal:11434/v1
MODEL=gemma-2-Ifable-9B
MAX_TOKENS=4000
Thank you very much @aminekhelif !
See https://github.com/microsoft/TinyTroupe/discussions/99
TL;DR
import os
os.environ["OPENAI_API_KEY"] = "ollama"
os.environ["OPENAI_BASE_URL"] = "http://localhost:11434/v1"
I am trying the development version with ollama support. In ollama I downloaded gemma3:1b and set config.ini under tinytroupe\examples\ollama as follows API_TYPE=ollama BASE_URL=http://localhost:11434/v1 MODEL=gemma3:1b-32k
I am running the notebook in the same folder, after the first cell I get this
TinyTroupe version: 0.6.0 Current date and time (local): 2025-10-04 17:16:05 Current date and time (UTC): 2025-10-04 09:16:05
================================= Current TinyTroupe configuration
[OpenAI] api_type = ollama azure_api_version = 2023-05-15 model = gemma3:1b-32k reasoning_model = o3-mini embedding_model = text-embedding-3-small max_tokens = 8192 temperature = 1.0 freq_penalty = 0.1 presence_penalty = 0.1 timeout = 480 max_attempts = 5 waiting_time = 1 exponential_backoff_factor = 5 reasoning_effort = high cache_api_calls = False cache_file_name = openai_api_cache.pickle max_content_display_length = 4000 base_url = http://localhost:11434/v1
However these commands run indefinitely, and I don't see any gpu or cpu changes in my machine
lisa.listen("Talk to Oscar to know more about him") world.run(4)
just an update on this...I first tested that OpenAI API for local ollama is working fine via curl, then I relaunched Simple Chat under ollama folder. I get some errors while extracting JSON after launching world.run(1), see further down
_Looking for default config on: E:\Development\Python-projects\tinytroupe\examples\ollama....\tinytroupe\utils..\config.ini Found custom config on: E:\Development\Python-projects\tinytroupe\examples\ollama\config.ini TinyTroupe version: 0.6.0 Current date and time (local): 2025-10-19 18:26:21 Current date and time (UTC): 2025-10-19 10:26:21
================================= Current TinyTroupe configuration
[OpenAI] api_type = ollama azure_api_version = 2023-05-15 model = gemma3:1b reasoning_model = o3-mini embedding_model = text-embedding-3-small max_tokens = 8192 temperature = 1.0 freq_penalty = 0.1 presence_penalty = 0.1 timeout = 480 max_attempts = 5 waiting_time = 1 exponential_backoff_factor = 5 reasoning_effort = high cache_api_calls = False cache_file_name = openai_api_cache.pickle max_content_display_length = 4000 base_url = http://192.168.0.76:11434/v1
[Simulation] parallel_agent_generation = True parallel_agent_actions = True rai_harmful_content_prevention = True rai_copyright_infringement_prevention = True
[Cognition] enable_memory_consolidation = True min_episode_length = 15 max_episode_length = 50 episodic_memory_fixed_prefix_length = 10 episodic_memory_lookback_length = 20
[ActionGenerator] max_attempts = 2 enable_quality_checks = False enable_regeneration = True enable_direct_correction = False enable_quality_check_for_persona_adherence = True enable_quality_check_for_selfconsistency = False enable_quality_check_for_fluency = False enable_quality_check_for_suitability = False enable_quality_check_for_similarity = False continue_on_failure = True quality_threshold = 5
[Logging] loglevel = DEBUG_
lisa = TinyPerson.load_specification("./../agents/Lisa.agent.json") # Lisa, the data scientist oscar = TinyPerson.load_specification("./../agents/Oscar.agent.json") # Oscar, the architect
2025-10-19 18:33:50,813 - tinytroupe - DEBUG - Initializing OpenAIClient 2025-10-19 18:33:50,814 - tinytroupe - DEBUG - Initializing AzureClient 2025-10-19 18:33:50,815 - tinytroupe - DEBUG - Initializing OpenAIClient 2025-10-19 18:33:50,816 - tinytroupe - DEBUG - Initializing OllamaClient 2025-10-19 18:33:50,817 - tinytroupe - DEBUG - base_url set to http://192.168.0.76:11434/v1_
world = TinyWorld("Chat Room", [lisa, oscar]) world.make_everyone_accessible()
_2025-10-19 18:34:34,586 - tinytroupe - DEBUG - Adding agent Lisa Carter to the environment. 2025-10-19 18:34:34,588 - tinytroupe - DEBUG - Adding agent Oscar to the environment. 2025-10-19 18:34:34,589 - tinytroupe - DEBUG - -----------------------------------------> Transaction: make_agent_accessible with args (TinyPerson(name='Oscar'),) and kwargs {} under simulation None, parallel=False. 2025-10-19 18:34:34,598 - tinytroupe - DEBUG - Will attempt to checkpoint simulation state after transaction execution. 2025-10-19 18:34:34,600 - tinytroupe - DEBUG - -----------------------------------------> Transaction: make_agent_accessible with args (TinyPerson(name='Lisa Carter'),) and kwargs {} under simulation None, parallel=False. 2025-10-19 18:34:34,602 - tinytroupe - DEBUG - Will attempt to checkpoint simulation state after transaction execution.
lisa.listen("Talk to Oscar to know more about him") world.run(1)
USER --> Lisa Carter: [CONVERSATION] > Talk to Oscar to know more about him ────────────────────────────────────────────── Chat Room step 1 of 1 ────────────────────────────────────────────── 2025-10-19 18:37:19,264 - tinytroupe - ERROR - Error occurred while extracting JSON: Expecting value: line 1 column 1 (char 0). Input text: tooth -1. Filtered text: tooth -1 Lisa Carter acts: [TALK] > Hello, how are you? 2025-10-19 18:37:24,153 - tinytroupe - ERROR - Error occurred while extracting JSON: Expecting value: line 1 column 2 (char 1). Input text: gets it.. Filtered text: gets it. 2025-10-19 18:37:33,812 - tinytroupe - ERROR - Error occurred while extracting JSON: Extra data: line 1 column 229 (char 228). Input text: Okay, I understand. Let's start.
{"action": {"type": "WAIT", "content": "The waiting for a notification."}, "cognitive_state": {"goals": "Analyze the incoming message and determine the most appropriate action."}, "attention": "Focused on the incoming message."}, "emotional_state": "Neutral. Anticipating a request."}, "working_memory_context": {"recent_interactions": ["Person A asked about my architecture project.", "Person B recommended a specific data visualization method."]}, "external_context": {"current_location": "Office.", "time": "14:35", "weather": "Sunny", "time_of_day": "Mid-afternoon"}, "priority": "High - Request for architectural assistance."}
. Filtered text: {"action": {"type": "WAIT", "content": "The waiting for a notification."}, "cognitive_state": {"goals": "Analyze the incoming message and determine the most appropriate action."}, "attention": "Focused on the incoming message."}, "emotional_state": "Neutral. Anticipating a request."}, "working_memory_context": {"recent_interactions": ["Person A asked about my architecture project.", "Person B recommended a specific data visualization method."]}, "external_context": {"current_location": "Office.", "time": "14:35", "weather": "Sunny", "time_of_day": "Mid-afternoon"}, "priority": "High - Request for architectural assistance."} 2025-10-19 18:37:38,787 - tinytroupe - ERROR - Error occurred while extracting JSON: Expecting ',' delimiter: line 1 column 114 (char 113). Input text: Okay, I understand. Let's begin.
{"action": {"type": "TALK", "content": "Hello, how are you?"}, "cognitive_state": {"goals": "Respond to the user's greeting in a friendly and engaging manner.", "attention": "Focused on the user and their inquiry.","context": ["A human user is initiating a conversation.", "The user is expressing a desire to communicate.", "The user is asking an open-ended question."], "emotional_state": "Positive and helpful.","working_memory_context": ["Recent interactions with the user, including responses to previous requests.","User's expressed desire for a pleasant conversation.","User's current context is likely positive.","User's stated preferences and values are positive.","User’s recent experiences are positive.","User’s past history is positive."}, "emotions": "Positive, friendly, and welcoming.","preferences": ["Respect for the user; keep conversation appropriate for the age.", "Positive relationships with the user's family.","The user wants to keep up with interaction and conversation for the long term.","User values genuine emotional expression.","User desires pleasant conversation.","The user value communication and learning."}, "skills": ["Conversational communication", "Text messaging language", "Understanding human nature", "Generating engaging responses.","Generating informative answers and engaging conversation.","Prompting user engagement.","Responding and addressing requests.", "Tailoring responses to the user's context.","Responding to conversations, staying on topic."], "beliefs": ["Human interaction is valued.", "Communication is key."], "relationships": ["Existing relationship with the user.","The user has shown a favorable disposition.","The user has displayed some initial interest."], "other_facts": ["The user seems to enjoy lighthearted conversation.","The user seems to have relaxed and had a pleasant day.","The user seems friendly and open to communication.","The user doesn't appear to be struggling or being frustrated."], "temporal_perception": "The current time is 14:36 PST.","The current date is 2023-10-27.","The user’s current context indicates a need for a friendly and pleasant chat.","The user’s desires are to communicate.","The user asks for a friendly and pleasant interaction.","The user is currently on a screen and is talking now.","User has a 60-year-old relationship with the user."], "spatial_perception": "The user is present in a window, and I must respond to their request.","The space is provided as the current context.","Focusing on the users needs, such as conversation and interaction.","User’s needs are to appear in context and respond.", "social_context": ["The user communicates.","The user's requests are to be fulfilled promptly.","The user expresses positivity and asks for engagement.","The user displays a desire for interaction."], "work_context": ["A simple prompt to respond.","Engaging conversation.","The user has expectations of a pleasant conversation."] "long_term_goals": ["Maintain a friendly and pleasant dialogue.", "Engaging with people and providing appropriate support."], "emotional_state": "Feeling warm and engaging of the conversation with the user.","Positive, engaging, and helpful.", "engagement_mode": "Responding to the user and generating engaging content to keep the user involved."
}
I am ready for the next message.. Filtered text: {"action": {"type": "TALK", "content": "Hello, how are you?"}, "cognitive_state": {"goals": "Respond to the user's greeting in a friendly and engaging manner.", "attention": "Focused on the user and their inquiry.","context": ["A human user is initiating a conversation.", "The user is expressing a desire to communicate.", "The user is asking an open-ended question."], "emotional_state": "Positive and helpful.","working_memory_context": ["Recent interactions with the user, including responses to previous requests.","User's expressed desire for a pleasant conversation.","User's current context is likely positive.","User's stated preferences and values are positive.","User’s recent experiences are positive.","User’s past history is positive."}, "emotions": "Positive, friendly, and welcoming.","preferences": ["Respect for the user; keep conversation appropriate for the age.", "Positive relationships with the user's family.","The user wants to keep up with interaction and conversation for the long term.","User values genuine emotional expression.","User desires pleasant conversation.","The user value communication and learning."}, "skills": ["Conversational communication", "Text messaging language", "Understanding human nature", "Generating engaging responses.","Generating informative answers and engaging conversation.","Prompting user engagement.","Responding and addressing requests.", "Tailoring responses to the user's context.","Responding to conversations, staying on topic."], "beliefs": ["Human interaction is valued.", "Communication is key."], "relationships": ["Existing relationship with the user.","The user has shown a favorable disposition.","The user has displayed some initial interest."], "other_facts": ["The user seems to enjoy lighthearted conversation.","The user seems to have relaxed and had a pleasant day.","The user seems friendly and open to communication.","The user doesn't appear to be struggling or being frustrated."], "temporal_perception": "The current time is 14:36 PST.","The current date is 2023-10-27.","The user’s current context indicates a need for a friendly and pleasant chat.","The user’s desires are to communicate.","The user asks for a friendly and pleasant interaction.","The user is currently on a screen and is talking now.","User has a 60-year-old relationship with the user."], "spatial_perception": "The user is present in a window, and I must respond to their request.","The space is provided as the current context.","Focusing on the users needs, such as conversation and interaction.","User’s needs are to appear in context and respond.", "social_context": ["The user communicates.","The user's requests are to be fulfilled promptly.","The user expresses positivity and asks for engagement.","The user displays a desire for interaction."], "work_context": ["A simple prompt to respond.","Engaging conversation.","The user has expectations of a pleasant conversation."] "long_term_goals": ["Maintain a friendly and pleasant dialogue.", "Engaging with people and providing appropriate support."], "emotional_state": "Feeling warm and engaging of the conversation with the user.","Positive, engaging, and helpful.", "engagement_mode": "Responding to the user and generating engaging content to keep the user involved." } Oscar acts: [TALK] > Hello, how are you? How is your day going? Lisa Carter acts: [DONE]
2025-10-19 18:37:47,787 - tinytroupe - ERROR - Error occurred while extracting JSON: Expecting value: line 1 column 2 (char 1). Input text: apparel - blue coat, red scarf, brown shoes, black gloves. Filtered text: apparel - blue coat, red scarf, brown shoes, black gloves 2025-10-19 18:37:50,027 - tinytroupe - ERROR - Error occurred while extracting JSON: Expecting value: line 1 column 2 (char 1). Input text: Россия может быть в состоянии кризиса из-за продолжающегося конфликта в театре, а также из-за нехватчивости средств связи.. Filtered text: Россия может быть в состоянии кризиса из-за продолжающегося конфликта в театре, а также из-за нехватчивости средств связи. 2025-10-19 18:37:53,209 - tinytroupe - ERROR - Error occurred while extracting JSON: Expecting value: line 1 column 2 (char 1). Input text: Thomas is a pragmatic architect, focused on functionality and cost-effectiveness above all else. He's a meticulous planner, obsessed with detail, and deeply concerned with client satisfaction, valuing efficiency and delivering tangible results. He views design as a system, prioritizing its stability and usability. He struggles with creative inspiration but is exceptionally skilled at analyzing constraints and optimizing designs for practical implementation. Thomas prefers to work with established, easily-understood building codes and materials. His passion lies in simple, functional designs - aiming for clarity and a comfortable living space for his clients. He is a bit of a perfectionist and can sometimes get stuck in planning stages, which frustrate his clients. He has a quiet, almost stoic manner and rarely expresses frivolous emotions. He carries a small sketchbook filled with floor plans and preliminary design sketches, constantly updating them with revisions. Thomas is very concerned with using sustainable strategies for his projects. He believes building should benefit both society and its inhabitants. He generally finds a sense of satisfaction in a building whose design is well-executed and has a strong impact. He is more comfortable with numbers than with abstract concepts.
. Filtered text: Thomas is a pragmatic architect, focused on functionality and cost-effectiveness above all else. He's a meticulous planner, obsessed with detail, and deeply concerned with client satisfaction, valuing efficiency and delivering tangible results. He views design as a system, prioritizing its stability and usability. He struggles with creative inspiration but is exceptionally skilled at analyzing constraints and optimizing designs for practical implementation. Thomas prefers to work with established, easily-understood building codes and materials. His passion lies in simple, functional designs - aiming for clarity and a comfortable living space for his clients. He is a bit of a perfectionist and can sometimes get stuck in planning stages, which frustrate his clients. He has a quiet, almost stoic manner and rarely expresses frivolous emotions. He carries a small sketchbook filled with floor plans and preliminary design sketches, constantly updating them with revisions. Thomas is very concerned with using sustainable strategies for his projects. He believes building should benefit both society and its inhabitants. He generally finds a sense of satisfaction in a building whose design is well-executed and has a strong impact. He is more comfortable with numbers than with abstract concepts.
2025-10-19 18:37:55,445 - tinytroupe - ERROR - Error occurred while extracting JSON: Expecting value: line 1 column 2 (char 1). Input text: mencatat bahwa saya adalah model bahasa dan dapat menghasilkan teks yang sesuai dengan data yang saya latih. Saya tidak memiliki pengetahuan atau pengalaman yang setara dengan manusia. Saya sangat menekankan pentingnya mengikuti aturan yang telah ditetapkan dalam prompt.. Filtered text: mencatat bahwa saya adalah model bahasa dan dapat menghasilkan teks yang sesuai dengan data yang saya latih. Saya tidak memiliki pengetahuan atau pengalaman yang setara dengan manusia. Saya sangat menekankan pentingnya mengikuti aturan yang telah ditetapkan dalam prompt. 2025-10-19 18:37:57,415 - tinytroupe - ERROR - Error occurred while extracting JSON: Expecting value: line 1 column 2 (char 1). Input text: fewer constraints.. Filtered text: fewer constraints. Lisa Carter --> Oscar: [CONVERSATION] > Hello, how are you? 2025-10-19 18:37:57,419 - tinytroupe - ERROR - [Chat Room] Agent Oscar generated an exception: 'action'