Skip to content

Commit 09d671a

Browse files
authored
enhance: More robut time setting and skip empty message for ChatAgent (#2582)
1 parent 5491604 commit 09d671a

File tree

2 files changed

+25
-10
lines changed

2 files changed

+25
-10
lines changed

camel/agents/chat_agent.py

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919
import threading
2020
import uuid
2121
from collections import defaultdict
22-
from datetime import datetime
2322
from pathlib import Path
2423
from typing import (
2524
TYPE_CHECKING,
@@ -509,15 +508,15 @@ def update_memory(
509508
memory record. If None, current timestamp will be used.
510509
(default: :obj:`None`)
511510
"""
512-
from datetime import timezone
511+
import time
513512

514513
self.memory.write_record(
515514
MemoryRecord(
516515
message=message,
517516
role_at_backend=role,
518517
timestamp=timestamp
519518
if timestamp is not None
520-
else datetime.now(timezone.utc).timestamp(),
519+
else time.time_ns() / 1_000_000_000, # Nanosecond precision
521520
agent_id=self.agent_id,
522521
)
523522
)
@@ -1331,6 +1330,13 @@ def _handle_batch_response(
13311330
"""
13321331
output_messages: List[BaseMessage] = []
13331332
for choice in response.choices:
1333+
# Skip messages with no meaningful content
1334+
if (
1335+
choice.message.content is None
1336+
or choice.message.content.strip() == ""
1337+
) and not choice.message.tool_calls:
1338+
continue
1339+
13341340
meta_dict = {}
13351341
if logprobs_info := handle_logprobs(choice):
13361342
meta_dict["logprobs_info"] = logprobs_info
@@ -1623,17 +1629,24 @@ def _record_tool_calling(
16231629
tool_call_id=tool_call_id,
16241630
)
16251631

1626-
# Use slightly different timestamps to ensure correct ordering
1632+
# Use precise timestamps to ensure correct ordering
16271633
# This ensures the assistant message (tool call) always appears before
16281634
# the function message (tool result) in the conversation context
1629-
current_time = datetime.now().timestamp()
1635+
# Use time.time_ns() for nanosecond precision to avoid collisions
1636+
import time
1637+
1638+
current_time_ns = time.time_ns()
1639+
base_timestamp = current_time_ns / 1_000_000_000 # Convert to seconds
1640+
16301641
self.update_memory(
1631-
assist_msg, OpenAIBackendRole.ASSISTANT, timestamp=current_time
1642+
assist_msg, OpenAIBackendRole.ASSISTANT, timestamp=base_timestamp
16321643
)
1644+
1645+
# Add minimal increment to ensure function message comes after
16331646
self.update_memory(
16341647
func_msg,
16351648
OpenAIBackendRole.FUNCTION,
1636-
timestamp=current_time + 0.001,
1649+
timestamp=base_timestamp + 1e-9,
16371650
)
16381651

16391652
# Record information about this tool call

camel/memories/records.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@
1515
# Enables postponed evaluation of annotations (for string-based type hints)
1616
from __future__ import annotations
1717

18+
import time
1819
from dataclasses import asdict
19-
from datetime import datetime, timezone
2020
from typing import Any, ClassVar, Dict
2121
from uuid import UUID, uuid4
2222

@@ -53,7 +53,8 @@ class MemoryRecord(BaseModel):
5353
uuid: UUID = Field(default_factory=uuid4)
5454
extra_info: Dict[str, str] = Field(default_factory=dict)
5555
timestamp: float = Field(
56-
default_factory=lambda: datetime.now(timezone.utc).timestamp()
56+
default_factory=lambda: time.time_ns()
57+
/ 1_000_000_000 # Nanosecond precision
5758
)
5859
agent_id: str = Field(default="")
5960

@@ -109,5 +110,6 @@ class ContextRecord(BaseModel):
109110
memory_record: MemoryRecord
110111
score: float
111112
timestamp: float = Field(
112-
default_factory=lambda: datetime.now(timezone.utc).timestamp()
113+
default_factory=lambda: time.time_ns()
114+
/ 1_000_000_000 # Nanosecond precision
113115
)

0 commit comments

Comments
 (0)