summaryrefslogtreecommitdiff
path: root/Omni/Agent/Tools
diff options
context:
space:
mode:
Diffstat (limited to 'Omni/Agent/Tools')
-rw-r--r--Omni/Agent/Tools/AvaLogs.hs65
1 files changed, 39 insertions, 26 deletions
diff --git a/Omni/Agent/Tools/AvaLogs.hs b/Omni/Agent/Tools/AvaLogs.hs
index 84c9db8..4c8ce11 100644
--- a/Omni/Agent/Tools/AvaLogs.hs
+++ b/Omni/Agent/Tools/AvaLogs.hs
@@ -24,6 +24,7 @@ import qualified Data.Text as Text
import qualified Data.Time as Time
import qualified Omni.Agent.AuditLog as AuditLog
import qualified Omni.Agent.Engine as Engine
+import qualified Omni.Agent.Memory as Memory
main :: IO ()
main = putText "Omni.Agent.Tools.AvaLogs - no standalone execution"
@@ -114,9 +115,9 @@ searchChatHistoryTool =
Engine.Tool
{ Engine.toolName = "search_chat_history",
Engine.toolDescription =
- "Search your conversation history for specific content. "
+ "Search your conversation history using semantic similarity. "
<> "Use this to find what was said in past conversations, recall context, "
- <> "or find when something was discussed. Searches message content.",
+ <> "or find when something was discussed. Finds semantically related messages.",
Engine.toolJsonSchema =
Aeson.object
[ "type" .= ("object" :: Text),
@@ -125,12 +126,7 @@ searchChatHistoryTool =
[ "query"
.= Aeson.object
[ "type" .= ("string" :: Text),
- "description" .= ("Text to search for in chat history" :: Text)
- ],
- "days_back"
- .= Aeson.object
- [ "type" .= ("integer" :: Text),
- "description" .= ("How many days back to search (default: 7)" :: Text)
+ "description" .= ("What to search for (semantic search)" :: Text)
],
"max_results"
.= Aeson.object
@@ -151,12 +147,6 @@ executeSearchHistory v = do
_ -> ""
_ -> ""
- let daysBack = case v of
- Aeson.Object obj -> case KeyMap.lookup "days_back" obj of
- Just (Aeson.Number n) -> round n
- _ -> 7
- _ -> 7
-
let maxResults = case v of
Aeson.Object obj -> case KeyMap.lookup "max_results" obj of
Just (Aeson.Number n) -> round n
@@ -166,18 +156,41 @@ executeSearchHistory v = do
if Text.null query
then pure <| Aeson.object ["error" .= ("query is required" :: Text)]
else do
- today <- Time.utctDay </ Time.getCurrentTime
- let days = [Time.addDays (negate i) today | i <- [0 .. daysBack - 1]]
- allEntries <- concat </ traverse AuditLog.readAvaLogs days
- let matches = filter (matchesQuery query) allEntries
- limited = take maxResults matches
- pure
- <| Aeson.object
- [ "query" .= query,
- "days_searched" .= daysBack,
- "total_matches" .= length matches,
- "results" .= map formatSearchResult limited
- ]
+ (_total, indexed) <- Memory.getChatHistoryStats
+ if indexed > 0
+ then do
+ results <- Memory.searchChatHistorySemantic query maxResults
+ pure
+ <| Aeson.object
+ [ "query" .= query,
+ "search_type" .= ("semantic" :: Text),
+ "indexed_messages" .= indexed,
+ "results" .= map formatSemanticResult results
+ ]
+ else do
+ today <- Time.utctDay </ Time.getCurrentTime
+ let days = [Time.addDays (negate i) today | i <- [0 .. 6]]
+ allEntries <- concat </ traverse AuditLog.readAvaLogs days
+ let matches = filter (matchesQuery query) allEntries
+ limited = take maxResults matches
+ pure
+ <| Aeson.object
+ [ "query" .= query,
+ "search_type" .= ("keyword_fallback" :: Text),
+ "note" .= ("no indexed history - run backfill" :: Text),
+ "total_matches" .= length matches,
+ "results" .= map formatSearchResult limited
+ ]
+
+formatSemanticResult :: (Memory.ChatHistoryEntry, Float) -> Aeson.Value
+formatSemanticResult (entry, score) =
+ Aeson.object
+ [ "timestamp" .= Time.formatTime Time.defaultTimeLocale "%Y-%m-%d %H:%M:%S" (Memory.cheCreatedAt entry),
+ "role" .= Memory.cheRole entry,
+ "sender" .= Memory.cheSenderName entry,
+ "similarity" .= score,
+ "content" .= Text.take 500 (Memory.cheContent entry)
+ ]
matchesQuery :: Text -> AuditLog.AuditLogEntry -> Bool
matchesQuery query entry =