fix(backend): use timezone-aware UTC in memory modules (fix pytest DeprecationWarnings) (#1992)
* fix(backend): use timezone-aware UTC in memory modules Replace datetime.utcnow() with datetime.now(timezone.utc) and a shared utc_now_iso_z() helper so persisted ISO timestamps keep the trailing Z suffix without triggering Python 3.12+ deprecation warnings. Made-with: Cursor * refactor(backend): use removesuffix for utc_now_iso_z suffix Makes the +00:00 -> Z transform explicit for the trailing offset only (Copilot review on PR #1992). Made-with: Cursor * style(backend): satisfy ruff UP017 with datetime.UTC in memory queue Made-with: Cursor --------- Co-authored-by: Willem Jiang <willem.jiang@gmail.com>
This commit is contained in:
parent
e5b149068c
commit
29817c3b34
|
|
@ -4,7 +4,7 @@ import logging
|
||||||
import threading
|
import threading
|
||||||
import time
|
import time
|
||||||
from dataclasses import dataclass, field
|
from dataclasses import dataclass, field
|
||||||
from datetime import datetime
|
from datetime import UTC, datetime
|
||||||
from typing import Any
|
from typing import Any
|
||||||
|
|
||||||
from deerflow.config.memory_config import get_memory_config
|
from deerflow.config.memory_config import get_memory_config
|
||||||
|
|
@ -18,7 +18,7 @@ class ConversationContext:
|
||||||
|
|
||||||
thread_id: str
|
thread_id: str
|
||||||
messages: list[Any]
|
messages: list[Any]
|
||||||
timestamp: datetime = field(default_factory=datetime.utcnow)
|
timestamp: datetime = field(default_factory=lambda: datetime.now(UTC))
|
||||||
agent_name: str | None = None
|
agent_name: str | None = None
|
||||||
correction_detected: bool = False
|
correction_detected: bool = False
|
||||||
reinforcement_detected: bool = False
|
reinforcement_detected: bool = False
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ import abc
|
||||||
import json
|
import json
|
||||||
import logging
|
import logging
|
||||||
import threading
|
import threading
|
||||||
from datetime import datetime
|
from datetime import UTC, datetime
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import Any
|
from typing import Any
|
||||||
|
|
||||||
|
|
@ -15,11 +15,16 @@ from deerflow.config.paths import get_paths
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
def utc_now_iso_z() -> str:
|
||||||
|
"""Current UTC time as ISO-8601 with ``Z`` suffix (matches prior naive-UTC output)."""
|
||||||
|
return datetime.now(UTC).isoformat().removesuffix("+00:00") + "Z"
|
||||||
|
|
||||||
|
|
||||||
def create_empty_memory() -> dict[str, Any]:
|
def create_empty_memory() -> dict[str, Any]:
|
||||||
"""Create an empty memory structure."""
|
"""Create an empty memory structure."""
|
||||||
return {
|
return {
|
||||||
"version": "1.0",
|
"version": "1.0",
|
||||||
"lastUpdated": datetime.utcnow().isoformat() + "Z",
|
"lastUpdated": utc_now_iso_z(),
|
||||||
"user": {
|
"user": {
|
||||||
"workContext": {"summary": "", "updatedAt": ""},
|
"workContext": {"summary": "", "updatedAt": ""},
|
||||||
"personalContext": {"summary": "", "updatedAt": ""},
|
"personalContext": {"summary": "", "updatedAt": ""},
|
||||||
|
|
@ -137,7 +142,7 @@ class FileMemoryStorage(MemoryStorage):
|
||||||
|
|
||||||
try:
|
try:
|
||||||
file_path.parent.mkdir(parents=True, exist_ok=True)
|
file_path.parent.mkdir(parents=True, exist_ok=True)
|
||||||
memory_data["lastUpdated"] = datetime.utcnow().isoformat() + "Z"
|
memory_data["lastUpdated"] = utc_now_iso_z()
|
||||||
|
|
||||||
temp_path = file_path.with_suffix(".tmp")
|
temp_path = file_path.with_suffix(".tmp")
|
||||||
with open(temp_path, "w", encoding="utf-8") as f:
|
with open(temp_path, "w", encoding="utf-8") as f:
|
||||||
|
|
|
||||||
|
|
@ -5,14 +5,17 @@ import logging
|
||||||
import math
|
import math
|
||||||
import re
|
import re
|
||||||
import uuid
|
import uuid
|
||||||
from datetime import datetime
|
|
||||||
from typing import Any
|
from typing import Any
|
||||||
|
|
||||||
from deerflow.agents.memory.prompt import (
|
from deerflow.agents.memory.prompt import (
|
||||||
MEMORY_UPDATE_PROMPT,
|
MEMORY_UPDATE_PROMPT,
|
||||||
format_conversation_for_update,
|
format_conversation_for_update,
|
||||||
)
|
)
|
||||||
from deerflow.agents.memory.storage import create_empty_memory, get_memory_storage
|
from deerflow.agents.memory.storage import (
|
||||||
|
create_empty_memory,
|
||||||
|
get_memory_storage,
|
||||||
|
utc_now_iso_z,
|
||||||
|
)
|
||||||
from deerflow.config.memory_config import get_memory_config
|
from deerflow.config.memory_config import get_memory_config
|
||||||
from deerflow.models import create_chat_model
|
from deerflow.models import create_chat_model
|
||||||
|
|
||||||
|
|
@ -86,7 +89,7 @@ def create_memory_fact(
|
||||||
|
|
||||||
normalized_category = category.strip() or "context"
|
normalized_category = category.strip() or "context"
|
||||||
validated_confidence = _validate_confidence(confidence)
|
validated_confidence = _validate_confidence(confidence)
|
||||||
now = datetime.utcnow().isoformat() + "Z"
|
now = utc_now_iso_z()
|
||||||
memory_data = get_memory_data(agent_name)
|
memory_data = get_memory_data(agent_name)
|
||||||
updated_memory = dict(memory_data)
|
updated_memory = dict(memory_data)
|
||||||
facts = list(memory_data.get("facts", []))
|
facts = list(memory_data.get("facts", []))
|
||||||
|
|
@ -376,7 +379,7 @@ class MemoryUpdater:
|
||||||
Updated memory data.
|
Updated memory data.
|
||||||
"""
|
"""
|
||||||
config = get_memory_config()
|
config = get_memory_config()
|
||||||
now = datetime.utcnow().isoformat() + "Z"
|
now = utc_now_iso_z()
|
||||||
|
|
||||||
# Update user sections
|
# Update user sections
|
||||||
user_updates = update_data.get("user", {})
|
user_updates = update_data.get("user", {})
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue