Fix missing timezone info on ingested docs. mcp schema requires TZ
This commit is contained in:
parent
f4c657e094
commit
9c56f56660
3 changed files with 23 additions and 12 deletions
|
|
@ -2,7 +2,7 @@ import asyncio
|
||||||
import json
|
import json
|
||||||
import logging
|
import logging
|
||||||
from collections.abc import AsyncGenerator
|
from collections.abc import AsyncGenerator
|
||||||
from datetime import datetime
|
from datetime import UTC, datetime
|
||||||
from typing import TYPE_CHECKING
|
from typing import TYPE_CHECKING
|
||||||
|
|
||||||
from docling_core.types.doc.document import DescriptionMetaField, PictureMeta
|
from docling_core.types.doc.document import DescriptionMetaField, PictureMeta
|
||||||
|
|
@ -531,7 +531,7 @@ async def _flush_rebuild_batch(
|
||||||
if not documents:
|
if not documents:
|
||||||
return
|
return
|
||||||
|
|
||||||
now = datetime.now().isoformat()
|
now = datetime.now(UTC).isoformat()
|
||||||
|
|
||||||
# Batch update documents and document_meta using merge_insert (one LanceDB
|
# Batch update documents and document_meta using merge_insert (one LanceDB
|
||||||
# version per table). Content+blobs go to documents; mutable attributes go
|
# version per table). Content+blobs go to documents; mutable attributes go
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
import json
|
import json
|
||||||
from datetime import datetime
|
from datetime import UTC, datetime
|
||||||
from typing import TYPE_CHECKING
|
from typing import TYPE_CHECKING
|
||||||
|
|
||||||
from pydantic import BaseModel, Field
|
from pydantic import BaseModel, Field, field_validator
|
||||||
|
|
||||||
from haiku.rag.store.compression import compress_docling_split, decompress_json
|
from haiku.rag.store.compression import compress_docling_split, decompress_json
|
||||||
|
|
||||||
|
|
@ -29,8 +29,19 @@ class Document(BaseModel):
|
||||||
docling_document: bytes | None = Field(default=None, exclude=True)
|
docling_document: bytes | None = Field(default=None, exclude=True)
|
||||||
docling_pages: bytes | None = Field(default=None, exclude=True)
|
docling_pages: bytes | None = Field(default=None, exclude=True)
|
||||||
docling_version: str | None = Field(default=None, exclude=True)
|
docling_version: str | None = Field(default=None, exclude=True)
|
||||||
created_at: datetime = Field(default_factory=datetime.now)
|
created_at: datetime = Field(default_factory=lambda: datetime.now(UTC))
|
||||||
updated_at: datetime = Field(default_factory=datetime.now)
|
updated_at: datetime = Field(default_factory=lambda: datetime.now(UTC))
|
||||||
|
|
||||||
|
@field_validator("created_at", "updated_at")
|
||||||
|
@classmethod
|
||||||
|
def _assume_utc(cls, value: datetime) -> datetime:
|
||||||
|
"""Attach UTC to a timezone-less timestamp instead of leaving it ambiguous.
|
||||||
|
|
||||||
|
A row written before timestamps carried an explicit offset parses back
|
||||||
|
with no tzinfo. Treat it as UTC rather than pass it on naive, which the
|
||||||
|
MCP tools' declared JSON schema rejects as an invalid date-time.
|
||||||
|
"""
|
||||||
|
return value if value.tzinfo else value.replace(tzinfo=UTC)
|
||||||
|
|
||||||
def set_docling(self, docling_doc: "DoclingDocument") -> None:
|
def set_docling(self, docling_doc: "DoclingDocument") -> None:
|
||||||
"""Serialize and store a DoclingDocument, splitting structure and pages.
|
"""Serialize and store a DoclingDocument, splitting structure and pages.
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import json
|
import json
|
||||||
from datetime import datetime
|
from datetime import UTC, datetime
|
||||||
from typing import overload
|
from typing import overload
|
||||||
from uuid import uuid4
|
from uuid import uuid4
|
||||||
|
|
||||||
|
|
@ -77,8 +77,8 @@ class DocumentRepository:
|
||||||
docling_document=doc.docling_document,
|
docling_document=doc.docling_document,
|
||||||
docling_pages=doc.docling_pages,
|
docling_pages=doc.docling_pages,
|
||||||
docling_version=doc.docling_version,
|
docling_version=doc.docling_version,
|
||||||
created_at=datetime.fromisoformat(created) if created else datetime.now(),
|
created_at=datetime.fromisoformat(created) if created else datetime.now(UTC),
|
||||||
updated_at=datetime.fromisoformat(updated) if updated else datetime.now(),
|
updated_at=datetime.fromisoformat(updated) if updated else datetime.now(UTC),
|
||||||
)
|
)
|
||||||
|
|
||||||
def _to_documents_record(self, entity: Document, doc_id: str) -> DocumentRecord:
|
def _to_documents_record(self, entity: Document, doc_id: str) -> DocumentRecord:
|
||||||
|
|
@ -138,7 +138,7 @@ class DocumentRepository:
|
||||||
# document_meta) would surface.
|
# document_meta) would surface.
|
||||||
if isinstance(entity, Document):
|
if isinstance(entity, Document):
|
||||||
doc_id = str(uuid4())
|
doc_id = str(uuid4())
|
||||||
now = datetime.now().isoformat()
|
now = datetime.now(UTC).isoformat()
|
||||||
await self.store.document_meta_table.add(
|
await self.store.document_meta_table.add(
|
||||||
[self._to_meta_record(entity, doc_id, now, now)]
|
[self._to_meta_record(entity, doc_id, now, now)]
|
||||||
)
|
)
|
||||||
|
|
@ -159,7 +159,7 @@ class DocumentRepository:
|
||||||
if not documents:
|
if not documents:
|
||||||
return []
|
return []
|
||||||
|
|
||||||
now = datetime.now().isoformat()
|
now = datetime.now(UTC).isoformat()
|
||||||
created_at = datetime.fromisoformat(now)
|
created_at = datetime.fromisoformat(now)
|
||||||
doc_records = []
|
doc_records = []
|
||||||
meta_records = []
|
meta_records = []
|
||||||
|
|
@ -272,7 +272,7 @@ class DocumentRepository:
|
||||||
self.store._assert_writable()
|
self.store._assert_writable()
|
||||||
assert entity.id, "Document ID is required for update"
|
assert entity.id, "Document ID is required for update"
|
||||||
|
|
||||||
now = datetime.now().isoformat()
|
now = datetime.now(UTC).isoformat()
|
||||||
entity.updated_at = datetime.fromisoformat(now)
|
entity.updated_at = datetime.fromisoformat(now)
|
||||||
created = entity.created_at.isoformat() if entity.created_at else now
|
created = entity.created_at.isoformat() if entity.created_at else now
|
||||||
record = self._to_meta_record(entity, entity.id, created, now)
|
record = self._to_meta_record(entity, entity.id, created, now)
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue