MCPcopy
hub / github.com/langroid/langroid / LLMMessage

Class LLMMessage

langroid/language_models/base.py:272–361  ·  view source on GitHub ↗

Class representing an entry in the msg-history sent to the LLM API. It could be one of these: - a user message - an LLM ("Assistant") response - a fn-call or tool-call-list from an OpenAI-compatible LLM API response - a result or results from executing a fn or tool-call(s)

Source from the content-addressed store, hash-verified

270
271
272class LLMMessage(BaseModel):
273 """
274 Class representing an entry in the msg-history sent to the LLM API.
275 It could be one of these:
276 - a user message
277 - an LLM ("Assistant") response
278 - a fn-call or tool-call-list from an OpenAI-compatible LLM API response
279 - a result or results from executing a fn or tool-call(s)
280 """
281
282 role: Role
283 name: Optional[str] = None
284 tool_call_id: Optional[str] = None # which OpenAI LLM tool this is a response to
285 tool_id: str = "" # used by OpenAIAssistant
286 content: str
287 files: List[FileAttachment] = []
288 function_call: Optional[LLMFunctionCall] = None
289 tool_calls: Optional[List[OpenAIToolCall]] = None
290 timestamp: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))
291 # link to corresponding chat document, for provenance/rewind purposes
292 chat_document_id: str = ""
293
294 def api_dict(self, model: str, has_system_role: bool = True) -> Dict[str, Any]:
295 """
296 Convert to dictionary for API request, keeping ONLY
297 the fields that are expected in an API call!
298 E.g., DROP the tool_id, since it is only for use in the Assistant API,
299 not the completion API.
300
301 Args:
302 has_system_role: whether the message has a system role (if not,
303 set to "user" role)
304 Returns:
305 dict: dictionary representation of LLM message
306 """
307 d = self.model_dump()
308 files: List[FileAttachment] = d.pop("files")
309 if len(files) > 0 and self.role == Role.USER:
310 # In there are files, then content is an array of
311 # different content-parts
312 d["content"] = [
313 dict(
314 type="text",
315 text=self.content,
316 )
317 ] + [f.to_dict(model) for f in self.files]
318
319 # if there is a key k = "role" with value "system", change to "user"
320 # in case has_system_role is False
321 if not has_system_role and "role" in d and d["role"] == "system":
322 d["role"] = "user"
323 if "content" in d:
324 d["content"] = "[ADDITIONAL SYSTEM MESSAGE:]\n\n" + d["content"]
325 # drop None values since API doesn't accept them
326 dict_no_none = {k: v for k, v in d.items() if v is not None}
327 if "name" in dict_no_none and dict_no_none["name"] == "":
328 # OpenAI API does not like empty name
329 del dict_no_none["name"]

Callers 15

chatMethod · 0.90
achatMethod · 0.90
_prep_chat_completionMethod · 0.90
thread_msg_to_llm_msgMethod · 0.90
_get_thread_messagesMethod · 0.90
to_LLMMessageMethod · 0.90
task_messagesMethod · 0.90
update_historyMethod · 0.90
init_message_historyMethod · 0.90
simulate_failed_callFunction · 0.90

Calls

no outgoing calls

Tested by 15

simulate_failed_callFunction · 0.72
test_openai_gptFunction · 0.72
test_llm_pdf_attachmentFunction · 0.72
test_llm_image_inputFunction · 0.72
test_azure_wrapperFunction · 0.72
test_truncate_messagesFunction · 0.72
test_drop_turns_strategyFunction · 0.72

Used in the wild real call sites across dependent graphs

searching dependent graphs…