forked from retoor/devplacepy
feat: add seo_meta service for AI-generated SEO metadata with CLI management and database layer
Implement a new `SeoMetaService` subservice that generates clean SEO title/description/keywords for published content items, distinct from the existing SEO diagnostics auditor. Add `seo_metadata` polymorphic table with soft-delete support, batch query methods, and usage tracking. Extend the CLI with `seo-meta prune` and `seo-meta clear` commands for job row lifecycle management. Wire `schedule_seo_meta_for_table` into content creation and editing flows in `content.py`. Document the new service in `AGENTS.md` and `README.md`, including the `extra_head` site setting for custom `<head>` injection.
This commit is contained in:
@@ -42,6 +42,7 @@ class VectorStore:
|
||||
self.collection_name = collection_name
|
||||
self._client = None
|
||||
self._collection = None
|
||||
self._dims: int | None = None
|
||||
|
||||
def _ensure(self):
|
||||
if self._collection is not None:
|
||||
@@ -55,9 +56,43 @@ class VectorStore:
|
||||
)
|
||||
return self._collection
|
||||
|
||||
@property
|
||||
def dims(self) -> int | None:
|
||||
if self._dims is not None:
|
||||
return self._dims
|
||||
try:
|
||||
collection = self._ensure()
|
||||
data = collection.get(include=["embeddings"], limit=1)
|
||||
rows = data.get("embeddings") or []
|
||||
if rows and rows[0]:
|
||||
self._dims = len(rows[0])
|
||||
except Exception:
|
||||
return self._dims
|
||||
return self._dims
|
||||
|
||||
def add(self, chunks: list[Chunk], vectors: list[list[float]]) -> None:
|
||||
if not chunks:
|
||||
return
|
||||
keep_chunks: list[Chunk] = []
|
||||
keep_vectors: list[list[float]] = []
|
||||
for chunk, vector in zip(chunks, vectors):
|
||||
if not vector:
|
||||
continue
|
||||
if self._dims is None:
|
||||
self._dims = len(vector)
|
||||
if len(vector) != self._dims:
|
||||
logger.warning(
|
||||
"deepsearch dropping chunk with mismatched embedding dim %d != %d",
|
||||
len(vector),
|
||||
self._dims,
|
||||
)
|
||||
continue
|
||||
keep_chunks.append(chunk)
|
||||
keep_vectors.append(vector)
|
||||
if not keep_chunks:
|
||||
return
|
||||
chunks = keep_chunks
|
||||
vectors = keep_vectors
|
||||
collection = self._ensure()
|
||||
collection.add(
|
||||
ids=[chunk.uid for chunk in chunks],
|
||||
|
||||
Reference in New Issue
Block a user