feat(memory, model): update multi-modal memory write and model list API
- Adjust multi-modal memory write behavior for text and visual data - Mask API keys in model list response to prevent exposure - Add capability-based filtering to the model list API
This commit is contained in:
@@ -1,16 +1,19 @@
|
||||
from typing import List, Optional
|
||||
|
||||
from app.core.logging_config import get_logger
|
||||
from app.core.memory.models.graph_models import DialogueNode, StatementNode, ChunkNode, MemorySummaryNode
|
||||
from app.repositories.neo4j.cypher_queries import DIALOGUE_NODE_SAVE, STATEMENT_NODE_SAVE, CHUNK_NODE_SAVE, \
|
||||
MEMORY_SUMMARY_NODE_SAVE, PERCEPTUAL_NODE_SAVE, PERCEPTUAL_DIALOGUE_EDGE_SAVE
|
||||
MEMORY_SUMMARY_NODE_SAVE
|
||||
# 使用新的仓储层
|
||||
from app.repositories.neo4j.neo4j_connector import Neo4jConnector
|
||||
|
||||
logger = get_logger(__name__)
|
||||
|
||||
|
||||
async def delete_all_nodes(end_user_id: str, connector: Neo4jConnector):
|
||||
"""Delete all nodes in the database."""
|
||||
result = await connector.execute_query(f"MATCH (n {{end_user_id: '{end_user_id}'}}) DETACH DELETE n")
|
||||
print(f"All end_user_id: {end_user_id} node and edge deleted successfully")
|
||||
logger.warning(f"All end_user_id: {end_user_id} node and edge deleted successfully")
|
||||
return result
|
||||
|
||||
|
||||
@@ -25,7 +28,7 @@ async def add_dialogue_nodes(dialogues: List[DialogueNode], connector: Neo4jConn
|
||||
List of created node UUIDs or None if failed
|
||||
"""
|
||||
if not dialogues:
|
||||
print("No dialogues to save")
|
||||
logger.info("No dialogues to save")
|
||||
return []
|
||||
|
||||
try:
|
||||
@@ -50,11 +53,11 @@ async def add_dialogue_nodes(dialogues: List[DialogueNode], connector: Neo4jConn
|
||||
)
|
||||
|
||||
created_uuids = [record["uuid"] for record in result]
|
||||
print(f"Successfully created {len(created_uuids)} dialogue nodes: {created_uuids}")
|
||||
logger.info(f"Successfully created {len(created_uuids)} dialogue nodes: {created_uuids}")
|
||||
return created_uuids
|
||||
|
||||
except Exception as e:
|
||||
print(f"Error creating dialogue nodes: {e}")
|
||||
logger.info(f"Error creating dialogue nodes: {e}")
|
||||
return None
|
||||
|
||||
|
||||
@@ -69,7 +72,7 @@ async def add_statement_nodes(statements: List[StatementNode], connector: Neo4jC
|
||||
List of created node UUIDs or None if failed
|
||||
"""
|
||||
if not statements:
|
||||
print("No statements to save")
|
||||
logger.info("No statements to save")
|
||||
return []
|
||||
|
||||
try:
|
||||
@@ -122,11 +125,11 @@ async def add_statement_nodes(statements: List[StatementNode], connector: Neo4jC
|
||||
)
|
||||
|
||||
created_uuids = [record["uuid"] for record in result]
|
||||
print(f"Successfully created {len(created_uuids)} statement nodes")
|
||||
logger.info(f"Successfully created {len(created_uuids)} statement nodes")
|
||||
return created_uuids
|
||||
|
||||
except Exception as e:
|
||||
print(f"Error creating statement nodes: {e}")
|
||||
logger.info(f"Error creating statement nodes: {e}")
|
||||
return None
|
||||
|
||||
|
||||
@@ -141,7 +144,7 @@ async def add_chunk_nodes(chunks: List[ChunkNode], connector: Neo4jConnector) ->
|
||||
List of created chunk UUIDs or None if failed
|
||||
"""
|
||||
if not chunks:
|
||||
print("No chunk nodes to add")
|
||||
logger.info("No chunk nodes to add")
|
||||
return []
|
||||
|
||||
try:
|
||||
@@ -174,16 +177,18 @@ async def add_chunk_nodes(chunks: List[ChunkNode], connector: Neo4jConnector) ->
|
||||
)
|
||||
|
||||
created_uuids = [record["uuid"] for record in result]
|
||||
print(f"Successfully created {len(created_uuids)} chunk nodes")
|
||||
logger.info(f"Successfully created {len(created_uuids)} chunk nodes")
|
||||
return created_uuids
|
||||
|
||||
except Exception as e:
|
||||
print(f"Error creating chunk nodes: {e}")
|
||||
logger.info(f"Error creating chunk nodes: {e}")
|
||||
return None
|
||||
|
||||
|
||||
async def add_memory_summary_nodes(summaries: List[MemorySummaryNode], connector: Neo4jConnector) -> Optional[
|
||||
List[str]]:
|
||||
async def add_memory_summary_nodes(
|
||||
summaries: List[MemorySummaryNode],
|
||||
connector: Neo4jConnector
|
||||
) -> Optional[List[str]]:
|
||||
"""Add memory summary nodes to Neo4j in batch.
|
||||
|
||||
Args:
|
||||
@@ -194,7 +199,7 @@ async def add_memory_summary_nodes(summaries: List[MemorySummaryNode], connector
|
||||
List of created summary node ids or None if failed
|
||||
"""
|
||||
if not summaries:
|
||||
print("No memory summary nodes to add")
|
||||
logger.info("No memory summary nodes to add")
|
||||
return []
|
||||
|
||||
try:
|
||||
@@ -220,110 +225,8 @@ async def add_memory_summary_nodes(summaries: List[MemorySummaryNode], connector
|
||||
summaries=flattened
|
||||
)
|
||||
created_ids = [record.get("uuid") for record in result]
|
||||
print(f"Successfully saved {len(created_ids)} MemorySummary nodes to Neo4j")
|
||||
logger.info(f"Successfully saved {len(created_ids)} MemorySummary nodes to Neo4j")
|
||||
return created_ids
|
||||
except Exception as e:
|
||||
print(f"Failed to save MemorySummary nodes to Neo4j: {e}")
|
||||
return None
|
||||
|
||||
|
||||
async def add_perceptual_nodes(
|
||||
perceptuals: list,
|
||||
connector: Neo4jConnector,
|
||||
embedder_client=None,
|
||||
) -> Optional[List[str]]:
|
||||
"""Add perceptual memory nodes to Neo4j in batch.
|
||||
|
||||
Args:
|
||||
perceptuals: List of MemoryPerceptualModel objects from PostgreSQL
|
||||
connector: Neo4j connector instance
|
||||
embedder_client: Optional embedder client for generating summary embeddings
|
||||
|
||||
Returns:
|
||||
List of created node UUIDs or None if failed
|
||||
"""
|
||||
if not perceptuals:
|
||||
print("No perceptual nodes to add")
|
||||
return []
|
||||
|
||||
try:
|
||||
flattened = []
|
||||
for p in perceptuals:
|
||||
meta = p.meta_data or {}
|
||||
content_meta = meta.get("content", {})
|
||||
|
||||
# 生成 summary embedding(如果有 embedder_client)
|
||||
summary_embedding = None
|
||||
if embedder_client and p.summary:
|
||||
try:
|
||||
summary_embedding = (await embedder_client.response([p.summary]))[0]
|
||||
except Exception as emb_err:
|
||||
print(f"Failed to embed perceptual summary: {emb_err}")
|
||||
|
||||
flattened.append({
|
||||
"id": str(p.id),
|
||||
"end_user_id": str(p.end_user_id),
|
||||
"perceptual_type": p.perceptual_type,
|
||||
"file_path": p.file_path or "",
|
||||
"file_name": p.file_name or "",
|
||||
"file_ext": p.file_ext or "",
|
||||
"summary": p.summary or "",
|
||||
"keywords": content_meta.get("keywords", []),
|
||||
"topic": content_meta.get("topic", ""),
|
||||
"domain": content_meta.get("domain", ""),
|
||||
"created_at": p.created_time.isoformat() if p.created_time else None,
|
||||
"summary_embedding": summary_embedding,
|
||||
})
|
||||
|
||||
result = await connector.execute_query(
|
||||
PERCEPTUAL_NODE_SAVE,
|
||||
perceptuals=flattened,
|
||||
)
|
||||
created_uuids = [record.get("uuid") for record in result]
|
||||
print(f"Successfully saved {len(created_uuids)} Perceptual nodes to Neo4j")
|
||||
return created_uuids
|
||||
|
||||
except Exception as e:
|
||||
print(f"Failed to save Perceptual nodes to Neo4j: {e}")
|
||||
return None
|
||||
|
||||
|
||||
async def add_perceptual_dialogue_edges(
|
||||
perceptuals: list,
|
||||
dialog_id: str,
|
||||
connector: Neo4jConnector,
|
||||
) -> Optional[List[str]]:
|
||||
"""Add edges between Perceptual nodes and Dialogue nodes.
|
||||
|
||||
Args:
|
||||
perceptuals: List of MemoryPerceptualModel objects
|
||||
dialog_id: The dialogue ID (or ref_id) to link to
|
||||
connector: Neo4j connector instance
|
||||
|
||||
Returns:
|
||||
List of created edge element IDs or None if failed
|
||||
"""
|
||||
if not perceptuals or not dialog_id:
|
||||
return []
|
||||
|
||||
try:
|
||||
edges = []
|
||||
for p in perceptuals:
|
||||
edges.append({
|
||||
"perceptual_id": str(p.id),
|
||||
"dialog_id": dialog_id,
|
||||
"end_user_id": str(p.end_user_id),
|
||||
"created_at": p.created_time.isoformat() if p.created_time else None,
|
||||
})
|
||||
|
||||
result = await connector.execute_query(
|
||||
PERCEPTUAL_DIALOGUE_EDGE_SAVE,
|
||||
edges=edges,
|
||||
)
|
||||
created_ids = [record.get("uuid") for record in result]
|
||||
print(f"Successfully saved {len(created_ids)} Perceptual-Dialogue edges to Neo4j")
|
||||
return created_ids
|
||||
|
||||
except Exception as e:
|
||||
print(f"Failed to save Perceptual-Dialogue edges: {e}")
|
||||
logger.info(f"Failed to save MemorySummary nodes to Neo4j: {e}")
|
||||
return None
|
||||
|
||||
Reference in New Issue
Block a user