feat: add updated_at timestamp to provider and bump on write (#574)

This commit is contained in:
cthomas 2025-01-10 11:16:53 -08:00 committed by GitHub
parent 2a92c578b9
commit b80af68eaf
9 changed files with 36 additions and 18 deletions

View File

@ -17,6 +17,16 @@ class CommonSqlalchemyMetaMixins(Base):
updated_at: Mapped[Optional[datetime]] = mapped_column(DateTime(timezone=True), server_default=func.now(), server_onupdate=func.now())
is_deleted: Mapped[bool] = mapped_column(Boolean, server_default=text("FALSE"))
def set_updated_at(self, timestamp: Optional[datetime] = None) -> None:
"""
Set the updated_at timestamp for the model instance.
Args:
timestamp (Optional[datetime]): The timestamp to set.
If None, uses the current UTC time.
"""
self.updated_at = timestamp or datetime.utcnow()
def _set_created_and_updated_by_fields(self, actor_id: str) -> None:
"""Populate created_by_id and last_updated_by_id based on actor."""
if not self.created_by_id:

View File

@ -4,7 +4,7 @@ from sqlalchemy.orm import Mapped, mapped_column, relationship
from letta.orm.mixins import OrganizationMixin
from letta.orm.sqlalchemy_base import SqlalchemyBase
from letta.providers import Provider as PydanticProvider
from letta.schemas.providers import Provider as PydanticProvider
if TYPE_CHECKING:
from letta.orm.organization import Organization

View File

@ -275,6 +275,8 @@ class SqlalchemyBase(CommonSqlalchemyMetaMixins, Base):
if actor:
self._set_created_and_updated_by_fields(actor.id)
self.set_updated_at()
with db_session as session:
session.add(self)
session.commit()

View File

@ -1,3 +1,4 @@
from datetime import datetime
from typing import List, Optional
from pydantic import Field, model_validator
@ -20,6 +21,7 @@ class Provider(ProviderBase):
name: str = Field(..., description="The name of the provider")
api_key: Optional[str] = Field(None, description="API key used for requests to the provider.")
organization_id: Optional[str] = Field(OrganizationManager.DEFAULT_ORG_ID, description="The organization id of the user")
updated_at: Optional[datetime] = Field(None, description="The update date of the provider.")
def resolve_identifier(self):
if not self.id:

View File

@ -1,6 +1,6 @@
from fastapi import APIRouter, Depends
from letta.providers import Provider, ProviderCreate, ProviderUpdate
from letta.schemas.providers import Provider, ProviderCreate, ProviderUpdate
from letta.server.rest_api.utils import get_letta_server
if TYPE_CHECKING:

View File

@ -25,19 +25,6 @@ from letta.log import get_logger
from letta.offline_memory_agent import OfflineMemoryAgent
from letta.orm import Base
from letta.orm.errors import NoResultFound
from letta.providers import (
AnthropicProvider,
AzureProvider,
GoogleAIProvider,
GroqProvider,
LettaProvider,
OllamaProvider,
OpenAIProvider,
Provider,
TogetherProvider,
VLLMChatCompletionsProvider,
VLLMCompletionsProvider,
)
from letta.schemas.agent import AgentState, AgentType, CreateAgent
from letta.schemas.block import BlockUpdate
from letta.schemas.embedding_config import EmbeddingConfig
@ -52,6 +39,19 @@ from letta.schemas.memory import ArchivalMemorySummary, ContextWindowOverview, M
from letta.schemas.message import Message, MessageCreate, MessageRole, MessageUpdate
from letta.schemas.organization import Organization
from letta.schemas.passage import Passage
from letta.schemas.providers import (
AnthropicProvider,
AzureProvider,
GoogleAIProvider,
GroqProvider,
LettaProvider,
OllamaProvider,
OpenAIProvider,
Provider,
TogetherProvider,
VLLMChatCompletionsProvider,
VLLMCompletionsProvider,
)
from letta.schemas.sandbox_config import SandboxType
from letta.schemas.source import Source
from letta.schemas.tool import Tool

View File

@ -1,8 +1,8 @@
from typing import List, Optional
from letta.orm.provider import Provider as ProviderModel
from letta.providers import Provider as PydanticProvider
from letta.providers import ProviderUpdate
from letta.schemas.providers import Provider as PydanticProvider
from letta.schemas.providers import ProviderUpdate
from letta.utils import enforce_types

View File

@ -19,6 +19,7 @@ from letta.orm import (
Job,
Message,
Organization,
Provider,
SandboxConfig,
SandboxEnvironmentVariable,
Source,
@ -92,6 +93,7 @@ def clear_tables(server: SyncServer):
session.execute(delete(Tool)) # Clear all records from the Tool table
session.execute(delete(Agent))
session.execute(delete(User)) # Clear all records from the user table
session.execute(delete(Provider))
session.execute(delete(Organization)) # Clear all records from the organization table
session.commit() # Commit the deletion
@ -563,9 +565,11 @@ def test_update_agent(server: SyncServer, comprehensive_test_agent_fixture, othe
tool_exec_environment_variables={"test_env_var_key_a": "a", "new_tool_exec_key": "n"},
)
last_updated_timestamp = agent.updated_at
updated_agent = server.agent_manager.update_agent(agent.id, update_agent_request, actor=default_user)
comprehensive_agent_checks(updated_agent, update_agent_request, actor=default_user)
assert updated_agent.message_ids == update_agent_request.message_ids
assert updated_agent.updated_at > last_updated_timestamp
# ======================================================================================================================

View File

@ -1,6 +1,6 @@
import os
from letta.providers import (
from letta.schemas.providers import (
AnthropicProvider,
AzureProvider,
GoogleAIProvider,