diff --git a/src/agentstr/agents/agentstr.py b/src/agentstr/agents/agentstr.py index 6b35f6a..3b2aa01 100644 --- a/src/agentstr/agents/agentstr.py +++ b/src/agentstr/agents/agentstr.py @@ -107,7 +107,7 @@ def checkpointer(self): checkpointer = None if self.database.conn_str.startswith("postgres"): key_manager = os.getenv("AGENT_VAULT_KEY_MANAGER") - key_manager_prefix = os.getenv("AGENT_VAULT_KEY_MANAGER_PREFIX", f"AGENTSTR-{self.name}-".upper().replace(' ', '-')) + key_manager_prefix = os.getenv("AGENT_VAULT_KEY_MANAGER_PREFIX", f"AGENTSTR-{self.name}-".upper().replace(' ', '-').replace('_', '-')) if key_manager: try: from agent_vault.langgraph import async_insecure_postgres_saver, async_secure_postgres_saver diff --git a/src/agentstr/database/postgres.py b/src/agentstr/database/postgres.py index b7c6551..840f3ec 100644 --- a/src/agentstr/database/postgres.py +++ b/src/agentstr/database/postgres.py @@ -91,7 +91,10 @@ async def add_message( self.agent_name, thread_id, ) - created_at = datetime.now(timezone.utc) + # Use a naive UTC datetime for TIMESTAMP (without time zone) columns + # to avoid asyncpg errors mixing aware/naive datetimes. We still return + # an aware UTC datetime to callers. + created_at = datetime.now(timezone.utc).replace(tzinfo=None) await self.conn.execute( f"INSERT INTO {self.MESSAGE_TABLE_NAME} (agent_name, thread_id, idx, user_id, role, message, content, kind, satoshis, extra_inputs, extra_outputs, created_at) VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12)", self.agent_name, @@ -119,7 +122,7 @@ async def add_message( satoshis=satoshis, extra_inputs=extra_inputs, extra_outputs=extra_outputs, - created_at=created_at.astimezone(timezone.utc), + created_at=created_at.replace(tzinfo=timezone.utc), ) async def get_messages( diff --git a/src/agentstr/models.py b/src/agentstr/models.py index f2671c5..22ee189 100644 --- a/src/agentstr/models.py +++ b/src/agentstr/models.py @@ -93,6 +93,13 @@ def parse_json_field(val): created_at = datetime.fromisoformat(created_at) except Exception: created_at = datetime.now(timezone.utc) + # Normalize to aware UTC datetime + if isinstance(created_at, datetime): + if created_at.tzinfo is None: + # Treat DB naive timestamp as UTC + created_at = created_at.replace(tzinfo=timezone.utc) + else: + created_at = created_at.astimezone(timezone.utc) return cls( agent_name=row["agent_name"], thread_id=row["thread_id"], @@ -105,7 +112,7 @@ def parse_json_field(val): satoshis=row.get("satoshis"), extra_inputs=parse_json_field(row.get("extra_inputs")), extra_outputs=parse_json_field(row.get("extra_outputs")), - created_at=created_at.astimezone(timezone.utc) if hasattr(created_at, "astimezone") else created_at, + created_at=created_at, )