letta-nightly 0.5.4.dev20241127104220__py3-none-any.whl → 0.5.4.dev20241128000451__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of letta-nightly might be problematic. Click here for more details.

Files changed (38) hide show
  1. letta/__init__.py +1 -1
  2. letta/agent.py +102 -140
  3. letta/agent_store/chroma.py +2 -0
  4. letta/cli/cli.py +3 -5
  5. letta/client/client.py +360 -117
  6. letta/config.py +2 -2
  7. letta/constants.py +5 -0
  8. letta/functions/function_sets/base.py +38 -1
  9. letta/helpers/tool_rule_solver.py +6 -5
  10. letta/main.py +1 -1
  11. letta/metadata.py +39 -41
  12. letta/o1_agent.py +1 -4
  13. letta/persistence_manager.py +1 -0
  14. letta/schemas/agent.py +57 -52
  15. letta/schemas/block.py +69 -25
  16. letta/schemas/enums.py +14 -0
  17. letta/schemas/letta_base.py +1 -1
  18. letta/schemas/letta_request.py +11 -23
  19. letta/schemas/letta_response.py +1 -2
  20. letta/schemas/memory.py +31 -100
  21. letta/schemas/message.py +3 -3
  22. letta/schemas/tool_rule.py +13 -5
  23. letta/server/rest_api/interface.py +12 -19
  24. letta/server/rest_api/routers/openai/assistants/threads.py +2 -3
  25. letta/server/rest_api/routers/openai/chat_completions/chat_completions.py +0 -2
  26. letta/server/rest_api/routers/v1/agents.py +90 -86
  27. letta/server/rest_api/routers/v1/blocks.py +50 -5
  28. letta/server/server.py +237 -459
  29. letta/server/static_files/assets/index-9fa459a2.js +1 -1
  30. letta/services/block_manager.py +6 -3
  31. letta/services/blocks_agents_manager.py +15 -0
  32. letta/services/tool_execution_sandbox.py +1 -1
  33. letta/services/tool_manager.py +2 -1
  34. {letta_nightly-0.5.4.dev20241127104220.dist-info → letta_nightly-0.5.4.dev20241128000451.dist-info}/METADATA +1 -1
  35. {letta_nightly-0.5.4.dev20241127104220.dist-info → letta_nightly-0.5.4.dev20241128000451.dist-info}/RECORD +38 -38
  36. {letta_nightly-0.5.4.dev20241127104220.dist-info → letta_nightly-0.5.4.dev20241128000451.dist-info}/LICENSE +0 -0
  37. {letta_nightly-0.5.4.dev20241127104220.dist-info → letta_nightly-0.5.4.dev20241128000451.dist-info}/WHEEL +0 -0
  38. {letta_nightly-0.5.4.dev20241127104220.dist-info → letta_nightly-0.5.4.dev20241128000451.dist-info}/entry_points.txt +0 -0
letta/schemas/enums.py CHANGED
@@ -33,3 +33,17 @@ class MessageStreamStatus(str, Enum):
33
33
  done_generation = "[DONE_GEN]"
34
34
  done_step = "[DONE_STEP]"
35
35
  done = "[DONE]"
36
+
37
+
38
+ class ToolRuleType(str, Enum):
39
+ """
40
+ Type of tool rule.
41
+ """
42
+
43
+ # note: some of these should be renamed when we do the data migration
44
+
45
+ run_first = "InitToolRule"
46
+ exit_loop = "TerminalToolRule" # reasoning loop should exit
47
+ continue_loop = "continue_loop" # reasoning loop should continue
48
+ constrain_child_tools = "ToolRule"
49
+ require_parent_tools = "require_parent_tools"
@@ -63,7 +63,7 @@ class LettaBase(BaseModel):
63
63
  @classmethod
64
64
  def _id_example(cls, prefix: str):
65
65
  """generates an example id for a given prefix"""
66
- return [prefix + "-123e4567-e89b-12d3-a456-426614174000"]
66
+ return f"{prefix}-123e4567-e89b-12d3-a456-426614174000"
67
67
 
68
68
  @classmethod
69
69
  def _id_description(cls, prefix: str):
@@ -8,33 +8,21 @@ from letta.schemas.message import Message, MessageCreate
8
8
 
9
9
  class LettaRequest(BaseModel):
10
10
  messages: Union[List[MessageCreate], List[Message]] = Field(..., description="The messages to be sent to the agent.")
11
- run_async: bool = Field(default=False, description="Whether to asynchronously send the messages to the agent.") # TODO: implement
12
-
13
- stream_steps: bool = Field(
14
- default=False, description="Flag to determine if the response should be streamed. Set to True for streaming agent steps."
15
- )
16
- stream_tokens: bool = Field(
17
- default=False,
18
- description="Flag to determine if individual tokens should be streamed. Set to True for token streaming (requires stream_steps = True).",
19
- )
20
-
21
- return_message_object: bool = Field(
22
- default=False,
23
- description="Set True to return the raw Message object. Set False to return the Message in the format of the Letta API.",
24
- )
25
11
 
26
12
  # Flags to support the use of AssistantMessage message types
27
13
 
28
- use_assistant_message: bool = Field(
29
- default=False,
30
- description="[Only applicable if return_message_object is False] If true, returns AssistantMessage objects when the agent calls a designated message tool. If false, return FunctionCallMessage objects for all tool calls.",
31
- )
32
-
33
- assistant_message_function_name: str = Field(
14
+ assistant_message_tool_name: str = Field(
34
15
  default=DEFAULT_MESSAGE_TOOL,
35
- description="[Only applicable if use_assistant_message is True] The name of the designated message tool.",
16
+ description="The name of the designated message tool.",
36
17
  )
37
- assistant_message_function_kwarg: str = Field(
18
+ assistant_message_tool_kwarg: str = Field(
38
19
  default=DEFAULT_MESSAGE_TOOL_KWARG,
39
- description="[Only applicable if use_assistant_message is True] The name of the message argument in the designated message tool.",
20
+ description="The name of the message argument in the designated message tool.",
21
+ )
22
+
23
+
24
+ class LettaStreamingRequest(LettaRequest):
25
+ stream_tokens: bool = Field(
26
+ default=False,
27
+ description="Flag to determine if individual tokens should be streamed. Set to True for token streaming (requires stream_steps = True).",
40
28
  )
@@ -7,7 +7,6 @@ from pydantic import BaseModel, Field
7
7
 
8
8
  from letta.schemas.enums import MessageStreamStatus
9
9
  from letta.schemas.letta_message import LettaMessage, LettaMessageUnion
10
- from letta.schemas.message import Message
11
10
  from letta.schemas.usage import LettaUsageStatistics
12
11
  from letta.utils import json_dumps
13
12
 
@@ -24,7 +23,7 @@ class LettaResponse(BaseModel):
24
23
  usage (LettaUsageStatistics): The usage statistics
25
24
  """
26
25
 
27
- messages: Union[List[Message], List[LettaMessageUnion]] = Field(..., description="The messages returned by the agent.")
26
+ messages: List[LettaMessageUnion] = Field(..., description="The messages returned by the agent.")
28
27
  usage: LettaUsageStatistics = Field(..., description="The usage statistics of the agent.")
29
28
 
30
29
  def __str__(self):
letta/schemas/memory.py CHANGED
@@ -1,4 +1,4 @@
1
- from typing import TYPE_CHECKING, Dict, List, Optional
1
+ from typing import TYPE_CHECKING, List, Optional
2
2
 
3
3
  from jinja2 import Template, TemplateSyntaxError
4
4
  from pydantic import BaseModel, Field
@@ -55,19 +55,16 @@ class ContextWindowOverview(BaseModel):
55
55
  class Memory(BaseModel, validate_assignment=True):
56
56
  """
57
57
 
58
- Represents the in-context memory of the agent. This includes both the `Block` objects (labelled by sections), as well as tools to edit the blocks.
59
-
60
- Attributes:
61
- memory (Dict[str, Block]): Mapping from memory block section to memory block.
58
+ Represents the in-context memory (i.e. Core memory) of the agent. This includes both the `Block` objects (labelled by sections), as well as tools to edit the blocks.
62
59
 
63
60
  """
64
61
 
65
- # Memory.memory is a dict mapping from memory block label to memory block.
66
- memory: Dict[str, Block] = Field(default_factory=dict, description="Mapping from memory block section to memory block.")
62
+ # Memory.block contains the list of memory blocks in the core memory
63
+ blocks: List[Block] = Field(..., description="Memory blocks contained in the agent's in-context memory")
67
64
 
68
65
  # Memory.template is a Jinja2 template for compiling memory module into a prompt string.
69
66
  prompt_template: str = Field(
70
- default="{% for block in memory.values() %}"
67
+ default="{% for block in blocks %}"
71
68
  '<{{ block.label }} characters="{{ block.value|length }}/{{ block.limit }}">\n'
72
69
  "{{ block.value }}\n"
73
70
  "</{{ block.label }}>"
@@ -90,7 +87,7 @@ class Memory(BaseModel, validate_assignment=True):
90
87
  Template(prompt_template)
91
88
 
92
89
  # Validate compatibility with current memory structure
93
- test_render = Template(prompt_template).render(memory=self.memory)
90
+ test_render = Template(prompt_template).render(blocks=self.blocks)
94
91
 
95
92
  # If we get here, the template is valid and compatible
96
93
  self.prompt_template = prompt_template
@@ -99,107 +96,49 @@ class Memory(BaseModel, validate_assignment=True):
99
96
  except Exception as e:
100
97
  raise ValueError(f"Prompt template is not compatible with current memory structure: {str(e)}")
101
98
 
102
- @classmethod
103
- def load(cls, state: dict):
104
- """Load memory from dictionary object"""
105
- obj = cls()
106
- if len(state.keys()) == 2 and "memory" in state and "prompt_template" in state:
107
- # New format
108
- obj.prompt_template = state["prompt_template"]
109
- for key, value in state["memory"].items():
110
- # TODO: This is migration code, please take a look at a later time to get rid of this
111
- if "name" in value:
112
- value["template_name"] = value["name"]
113
- value.pop("name")
114
- obj.memory[key] = Block(**value)
115
- else:
116
- # Old format (pre-template)
117
- for key, value in state.items():
118
- obj.memory[key] = Block(**value)
119
- return obj
120
-
121
99
  def compile(self) -> str:
122
100
  """Generate a string representation of the memory in-context using the Jinja2 template"""
123
101
  template = Template(self.prompt_template)
124
- return template.render(memory=self.memory)
125
-
126
- def to_dict(self):
127
- """Convert to dictionary representation"""
128
- return {
129
- "memory": {key: value.model_dump() for key, value in self.memory.items()},
130
- "prompt_template": self.prompt_template,
131
- }
132
-
133
- def to_flat_dict(self):
134
- """Convert to a dictionary that maps directly from block label to values"""
135
- return {k: v.value for k, v in self.memory.items() if v is not None}
102
+ return template.render(blocks=self.blocks)
136
103
 
137
104
  def list_block_labels(self) -> List[str]:
138
105
  """Return a list of the block names held inside the memory object"""
139
- return list(self.memory.keys())
106
+ # return list(self.memory.keys())
107
+ return [block.label for block in self.blocks]
140
108
 
141
109
  # TODO: these should actually be label, not name
142
110
  def get_block(self, label: str) -> Block:
143
111
  """Correct way to index into the memory.memory field, returns a Block"""
144
- if label not in self.memory:
145
- raise KeyError(f"Block field {label} does not exist (available sections = {', '.join(list(self.memory.keys()))})")
146
- else:
147
- return self.memory[label]
112
+ keys = []
113
+ for block in self.blocks:
114
+ if block.label == label:
115
+ return block
116
+ keys.append(block.label)
117
+ raise KeyError(f"Block field {label} does not exist (available sections = {', '.join(keys)})")
148
118
 
149
119
  def get_blocks(self) -> List[Block]:
150
120
  """Return a list of the blocks held inside the memory object"""
151
- return list(self.memory.values())
152
-
153
- def link_block(self, block: Block, override: Optional[bool] = False):
154
- """Link a new block to the memory object"""
155
- if not isinstance(block, Block):
156
- raise ValueError(f"Param block must be type Block (not {type(block)})")
157
- if not override and block.label in self.memory:
158
- raise ValueError(f"Block with label {block.label} already exists")
159
-
160
- self.memory[block.label] = block
121
+ # return list(self.memory.values())
122
+ return self.blocks
161
123
 
162
- def unlink_block(self, block_label: str) -> Block:
163
- """Unlink a block from the memory object"""
164
- if block_label not in self.memory:
165
- raise ValueError(f"Block with label {block_label} does not exist")
166
-
167
- return self.memory.pop(block_label)
124
+ def set_block(self, block: Block):
125
+ """Set a block in the memory object"""
126
+ for i, b in enumerate(self.blocks):
127
+ if b.label == block.label:
128
+ self.blocks[i] = block
129
+ return
130
+ self.blocks.append(block)
168
131
 
169
132
  def update_block_value(self, label: str, value: str):
170
133
  """Update the value of a block"""
171
- if label not in self.memory:
172
- raise ValueError(f"Block with label {label} does not exist")
173
134
  if not isinstance(value, str):
174
135
  raise ValueError(f"Provided value must be a string")
175
136
 
176
- self.memory[label].value = value
177
-
178
- def update_block_label(self, current_label: str, new_label: str):
179
- """Update the label of a block"""
180
- if current_label not in self.memory:
181
- raise ValueError(f"Block with label {current_label} does not exist")
182
- if not isinstance(new_label, str):
183
- raise ValueError(f"Provided new label must be a string")
184
-
185
- # First change the label of the block
186
- self.memory[current_label].label = new_label
187
-
188
- # Then swap the block to the new label
189
- self.memory[new_label] = self.memory.pop(current_label)
190
-
191
- def update_block_limit(self, label: str, limit: int):
192
- """Update the limit of a block"""
193
- if label not in self.memory:
194
- raise ValueError(f"Block with label {label} does not exist")
195
- if not isinstance(limit, int):
196
- raise ValueError(f"Provided limit must be an integer")
197
-
198
- # Check to make sure the new limit is greater than the current length of the block
199
- if len(self.memory[label].value) > limit:
200
- raise ValueError(f"New limit {limit} is less than the current length of the block {len(self.memory[label].value)}")
201
-
202
- self.memory[label].limit = limit
137
+ for block in self.blocks:
138
+ if block.label == label:
139
+ block.value = value
140
+ return
141
+ raise ValueError(f"Block with label {label} does not exist")
203
142
 
204
143
 
205
144
  # TODO: ideally this is refactored into ChatMemory and the subclasses are given more specific names.
@@ -222,13 +161,7 @@ class BasicBlockMemory(Memory):
222
161
  Args:
223
162
  blocks (List[Block]): List of blocks to be linked to the memory object.
224
163
  """
225
- super().__init__()
226
- for block in blocks:
227
- # TODO: centralize these internal schema validations
228
- # assert block.name is not None and block.name != "", "each existing chat block must have a name"
229
- # self.link_block(name=block.name, block=block)
230
- assert block.label is not None and block.label != "", "each existing chat block must have a name"
231
- self.link_block(block=block)
164
+ super().__init__(blocks=blocks)
232
165
 
233
166
  def core_memory_append(agent_state: "AgentState", label: str, content: str) -> Optional[str]: # type: ignore
234
167
  """
@@ -280,9 +213,7 @@ class ChatMemory(BasicBlockMemory):
280
213
  human (str): The starter value for the human block.
281
214
  limit (int): The character limit for each block.
282
215
  """
283
- super().__init__()
284
- self.link_block(block=Block(value=persona, limit=limit, label="persona"))
285
- self.link_block(block=Block(value=human, limit=limit, label="human"))
216
+ super().__init__(blocks=[Block(value=persona, limit=limit, label="persona"), Block(value=human, limit=limit, label="human")])
286
217
 
287
218
 
288
219
  class UpdateMemory(BaseModel):
letta/schemas/message.py CHANGED
@@ -134,8 +134,8 @@ class Message(BaseMessage):
134
134
  def to_letta_message(
135
135
  self,
136
136
  assistant_message: bool = False,
137
- assistant_message_function_name: str = DEFAULT_MESSAGE_TOOL,
138
- assistant_message_function_kwarg: str = DEFAULT_MESSAGE_TOOL_KWARG,
137
+ assistant_message_tool_name: str = DEFAULT_MESSAGE_TOOL,
138
+ assistant_message_tool_kwarg: str = DEFAULT_MESSAGE_TOOL_KWARG,
139
139
  ) -> List[LettaMessage]:
140
140
  """Convert message object (in DB format) to the style used by the original Letta API"""
141
141
 
@@ -156,7 +156,7 @@ class Message(BaseMessage):
156
156
  for tool_call in self.tool_calls:
157
157
  # If we're supporting using assistant message,
158
158
  # then we want to treat certain function calls as a special case
159
- if assistant_message and tool_call.function.name == assistant_message_function_name:
159
+ if assistant_message and tool_call.function.name == assistant_message_tool_name:
160
160
  # We need to unpack the actual message contents from the function call
161
161
  try:
162
162
  func_args = json.loads(tool_call.function.arguments)
@@ -1,21 +1,24 @@
1
- from typing import List
1
+ from typing import List, Union
2
2
 
3
3
  from pydantic import Field
4
4
 
5
+ from letta.schemas.enums import ToolRuleType
5
6
  from letta.schemas.letta_base import LettaBase
6
7
 
7
8
 
8
9
  class BaseToolRule(LettaBase):
9
10
  __id_prefix__ = "tool_rule"
10
11
  tool_name: str = Field(..., description="The name of the tool. Must exist in the database for the user's organization.")
12
+ type: ToolRuleType
11
13
 
12
14
 
13
- class ToolRule(BaseToolRule):
15
+ class ChildToolRule(BaseToolRule):
14
16
  """
15
17
  A ToolRule represents a tool that can be invoked by the agent.
16
18
  """
17
19
 
18
- type: str = Field("ToolRule")
20
+ # type: str = Field("ToolRule")
21
+ type: ToolRuleType = ToolRuleType.constrain_child_tools
19
22
  children: List[str] = Field(..., description="The children tools that can be invoked.")
20
23
 
21
24
 
@@ -24,7 +27,8 @@ class InitToolRule(BaseToolRule):
24
27
  Represents the initial tool rule configuration.
25
28
  """
26
29
 
27
- type: str = Field("InitToolRule")
30
+ # type: str = Field("InitToolRule")
31
+ type: ToolRuleType = ToolRuleType.run_first
28
32
 
29
33
 
30
34
  class TerminalToolRule(BaseToolRule):
@@ -32,4 +36,8 @@ class TerminalToolRule(BaseToolRule):
32
36
  Represents a terminal tool rule configuration where if this tool gets called, it must end the agent loop.
33
37
  """
34
38
 
35
- type: str = Field("TerminalToolRule")
39
+ # type: str = Field("TerminalToolRule")
40
+ type: ToolRuleType = ToolRuleType.exit_loop
41
+
42
+
43
+ ToolRule = Union[ChildToolRule, InitToolRule, TerminalToolRule]
@@ -271,9 +271,8 @@ class StreamingServerInterface(AgentChunkStreamingInterface):
271
271
  self,
272
272
  multi_step=True,
273
273
  # Related to if we want to try and pass back the AssistantMessage as a special case function
274
- use_assistant_message=False,
275
- assistant_message_function_name=DEFAULT_MESSAGE_TOOL,
276
- assistant_message_function_kwarg=DEFAULT_MESSAGE_TOOL_KWARG,
274
+ assistant_message_tool_name=DEFAULT_MESSAGE_TOOL,
275
+ assistant_message_tool_kwarg=DEFAULT_MESSAGE_TOOL_KWARG,
277
276
  # Related to if we expect inner_thoughts to be in the kwargs
278
277
  inner_thoughts_in_kwargs=True,
279
278
  inner_thoughts_kwarg=INNER_THOUGHTS_KWARG,
@@ -287,7 +286,7 @@ class StreamingServerInterface(AgentChunkStreamingInterface):
287
286
  self.streaming_chat_completion_mode_function_name = None # NOTE: sadly need to track state during stream
288
287
  # If chat completion mode, we need a special stream reader to
289
288
  # turn function argument to send_message into a normal text stream
290
- self.streaming_chat_completion_json_reader = FunctionArgumentsStreamHandler(json_key=assistant_message_function_kwarg)
289
+ self.streaming_chat_completion_json_reader = FunctionArgumentsStreamHandler(json_key=assistant_message_tool_kwarg)
291
290
 
292
291
  self._chunks = deque()
293
292
  self._event = asyncio.Event() # Use an event to notify when chunks are available
@@ -300,9 +299,9 @@ class StreamingServerInterface(AgentChunkStreamingInterface):
300
299
  self.multi_step_gen_indicator = MessageStreamStatus.done_generation
301
300
 
302
301
  # Support for AssistantMessage
303
- self.use_assistant_message = use_assistant_message
304
- self.assistant_message_function_name = assistant_message_function_name
305
- self.assistant_message_function_kwarg = assistant_message_function_kwarg
302
+ self.use_assistant_message = False # TODO: Remove this
303
+ self.assistant_message_tool_name = assistant_message_tool_name
304
+ self.assistant_message_tool_kwarg = assistant_message_tool_kwarg
306
305
 
307
306
  # Support for inner_thoughts_in_kwargs
308
307
  self.inner_thoughts_in_kwargs = inner_thoughts_in_kwargs
@@ -455,17 +454,14 @@ class StreamingServerInterface(AgentChunkStreamingInterface):
455
454
 
456
455
  # If we get a "hit" on the special keyword we're looking for, we want to skip to the next chunk
457
456
  # TODO I don't think this handles the function name in multi-pieces problem. Instead, we should probably reset the streaming_chat_completion_mode_function_name when we make this hit?
458
- # if self.streaming_chat_completion_mode_function_name == self.assistant_message_function_name:
459
- if tool_call.function.name == self.assistant_message_function_name:
457
+ # if self.streaming_chat_completion_mode_function_name == self.assistant_message_tool_name:
458
+ if tool_call.function.name == self.assistant_message_tool_name:
460
459
  self.streaming_chat_completion_json_reader.reset()
461
460
  # early exit to turn into content mode
462
461
  return None
463
462
 
464
463
  # if we're in the middle of parsing a send_message, we'll keep processing the JSON chunks
465
- if (
466
- tool_call.function.arguments
467
- and self.streaming_chat_completion_mode_function_name == self.assistant_message_function_name
468
- ):
464
+ if tool_call.function.arguments and self.streaming_chat_completion_mode_function_name == self.assistant_message_tool_name:
469
465
  # Strip out any extras tokens
470
466
  cleaned_func_args = self.streaming_chat_completion_json_reader.process_json_chunk(tool_call.function.arguments)
471
467
  # In the case that we just have the prefix of something, no message yet, then we should early exit to move to the next chunk
@@ -500,9 +496,6 @@ class StreamingServerInterface(AgentChunkStreamingInterface):
500
496
  )
501
497
 
502
498
  elif self.inner_thoughts_in_kwargs and tool_call.function:
503
- if self.use_assistant_message:
504
- raise NotImplementedError("inner_thoughts_in_kwargs with use_assistant_message not yet supported")
505
-
506
499
  processed_chunk = None
507
500
 
508
501
  if tool_call.function.name:
@@ -909,13 +902,13 @@ class StreamingServerInterface(AgentChunkStreamingInterface):
909
902
 
910
903
  if (
911
904
  self.use_assistant_message
912
- and function_call.function.name == self.assistant_message_function_name
913
- and self.assistant_message_function_kwarg in func_args
905
+ and function_call.function.name == self.assistant_message_tool_name
906
+ and self.assistant_message_tool_kwarg in func_args
914
907
  ):
915
908
  processed_chunk = AssistantMessage(
916
909
  id=msg_obj.id,
917
910
  date=msg_obj.created_at,
918
- assistant_message=func_args[self.assistant_message_function_kwarg],
911
+ assistant_message=func_args[self.assistant_message_tool_kwarg],
919
912
  )
920
913
  else:
921
914
  processed_chunk = FunctionCallMessage(
@@ -117,7 +117,7 @@ def create_message(
117
117
  tool_call_id=None,
118
118
  name=None,
119
119
  )
120
- agent = server._get_or_load_agent(agent_id=agent_id)
120
+ agent = server.load_agent(agent_id=agent_id)
121
121
  # add message to agent
122
122
  agent._append_to_messages([message])
123
123
 
@@ -161,7 +161,6 @@ def list_messages(
161
161
  before=before_uuid,
162
162
  order_by="created_at",
163
163
  reverse=reverse,
164
- return_message_object=True,
165
164
  )
166
165
  assert isinstance(json_messages, List)
167
166
  assert all([isinstance(message, Message) for message in json_messages])
@@ -247,7 +246,7 @@ def create_run(
247
246
  # TODO: add request.instructions as a message?
248
247
  agent_id = thread_id
249
248
  # TODO: override preset of agent with request.assistant_id
250
- agent = server._get_or_load_agent(agent_id=agent_id)
249
+ agent = server.load_agent(agent_id=agent_id)
251
250
  agent.inner_step(messages=[]) # already has messages added
252
251
  run_id = str(uuid.uuid4())
253
252
  create_time = int(get_utc_time().timestamp())
@@ -68,7 +68,6 @@ async def create_chat_completion(
68
68
  stream_tokens=True,
69
69
  # Turn on ChatCompletion mode (eg remaps send_message to content)
70
70
  chat_completion_mode=True,
71
- return_message_object=False,
72
71
  )
73
72
 
74
73
  else:
@@ -86,7 +85,6 @@ async def create_chat_completion(
86
85
  # Turn streaming OFF
87
86
  stream_steps=False,
88
87
  stream_tokens=False,
89
- return_message_object=False,
90
88
  )
91
89
  # print(response_messages)
92
90