1- import json
21import logging
3- from datetime import datetime , timezone
4- from typing import Any
52
6- from vektori .models .base import LLMProvider , EmbeddingProvider
7- from vektori .storage .base import StorageBackend
83from vektori .ingestion .extractor import _parse_json_response
4+ from vektori .models .base import EmbeddingProvider , LLMProvider
5+ from vektori .storage .base import StorageBackend
96
107logger = logging .getLogger (__name__ )
118
@@ -45,17 +42,17 @@ def __init__(
4542 async def synthesize (self , user_id : str , agent_id : str | None = None ) -> int :
4643 # Get active facts for the user
4744 facts = await self .db .get_active_facts (user_id = user_id , agent_id = agent_id , limit = 300 )
48-
45+
4946 # Filter out existing synthesis facts so we don't synthesize the syntheses too much,
5047 # or maybe we do want to? For now, let's keep it simple: filter them out to avoid feedback loops unless needed.
5148 # Actually, let's just feed them all, but maybe limit to non-synthesis for base patterns.
5249 base_facts = [f for f in facts if f .get ("metadata" , {}).get ("source" ) != "synthesis" ]
53-
50+
5451 if len (base_facts ) < 5 :
5552 return 0 # Not enough facts to form a pattern
56-
53+
5754 facts_list = "\n " .join (f"- { f ['text' ]} (Session: { f .get ('session_id' , 'unknown' )} , Date: { f .get ('created_at' , 'unknown' )} )" for f in base_facts )
58-
55+
5956 prompt = SYNTHESIS_PROMPT .format (facts_list = facts_list , max_facts = 5 )
6057 try :
6158 response = await self .llm .generate (prompt , max_tokens = 1000 )
@@ -64,18 +61,18 @@ async def synthesize(self, user_id: str, agent_id: str | None = None) -> int:
6461 except Exception as e :
6562 logger .warning ("Synthesis LLM call failed: %s" , e )
6663 return 0
67-
64+
6865 if not new_facts :
6966 return 0
70-
67+
7168 texts = [f ["text" ] for f in new_facts ]
7269 try :
7370 embeddings = await self .embedder .embed_batch (texts )
7471 except Exception as e :
7572 logger .error ("Synthesis batch embed failed: %s" , e )
7673 return 0
7774
78- now = datetime . now ( timezone . utc )
75+
7976 inserted = 0
8077
8178 for fact_dict , emb in zip (new_facts , embeddings ):
@@ -86,22 +83,22 @@ async def synthesize(self, user_id: str, agent_id: str | None = None) -> int:
8683 agent_id = agent_id ,
8784 limit = 1
8885 )
89-
86+
9087 skip = False
9188 if existing :
9289 best = existing [0 ]
9390 sim = 1.0 - best .get ("distance" , 1.0 )
9491 if sim > 0.85 :
9592 # We already have this synthesis, let's just skip it
9693 skip = True
97-
94+
9895 if skip :
9996 continue
100-
97+
10198 try :
10299 # Need to link the synthesis to the facts that generated it if we want graph traversal
103100 # But for now we just insert it
104- synthesis_id = await self .db .insert_synthesis (
101+ _ = await self .db .insert_synthesis (
105102 text = fact_dict ["text" ],
106103 embedding = emb ,
107104 user_id = user_id ,
@@ -111,5 +108,5 @@ async def synthesize(self, user_id: str, agent_id: str | None = None) -> int:
111108 inserted += 1
112109 except Exception as e :
113110 logger .warning ("Failed to insert synthesis: %s" , e )
114-
111+
115112 return inserted
0 commit comments