Spaces:
No application file
No application file
Liss, Alex (NYC-HUG)
commited on
Commit
·
207499a
1
Parent(s):
33f621e
Remove z_utils from git tracking while preserving local files
Browse files- .gitignore +1 -1
- z_utils/neo4j_cleanup.py +0 -69
- z_utils/persona_session_ids.json +0 -4
- z_utils/persona_uuids.json +0 -4
- z_utils/restart_space.py +0 -50
- z_utils/set_secrets.py +0 -77
- z_utils/zep_setup.py +0 -445
- z_utils/zep_test.py +0 -97
.gitignore
CHANGED
@@ -64,5 +64,5 @@ logs/
|
|
64 |
**/niners_output/schedule_with_result_embedding.csv
|
65 |
**/niners_output/schedule_with_result_embedding.gsheet
|
66 |
|
67 |
-
|
68 |
z_utils/
|
|
|
64 |
**/niners_output/schedule_with_result_embedding.csv
|
65 |
**/niners_output/schedule_with_result_embedding.gsheet
|
66 |
|
67 |
+
# Utility files
|
68 |
z_utils/
|
z_utils/neo4j_cleanup.py
DELETED
@@ -1,69 +0,0 @@
|
|
1 |
-
#!/usr/bin/env python
|
2 |
-
"""
|
3 |
-
Script to perform Neo4j cleanup: Remove the 'embedding' property from all :Game nodes.
|
4 |
-
This is part of Task 1.3 housekeeping.
|
5 |
-
|
6 |
-
Run once: python ifx-sandbox/z_utils/neo4j_cleanup.py
|
7 |
-
"""
|
8 |
-
|
9 |
-
import os
|
10 |
-
import sys
|
11 |
-
|
12 |
-
# Adjust path to import graph object from the parent directory (ifx-sandbox)
|
13 |
-
# Assumes script is run from the workspace root directory
|
14 |
-
workspace_root = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..'))
|
15 |
-
ifx_sandbox_path = os.path.join(workspace_root, 'ifx-sandbox')
|
16 |
-
|
17 |
-
if ifx_sandbox_path not in sys.path:
|
18 |
-
print(f"Adding {ifx_sandbox_path} to sys.path")
|
19 |
-
sys.path.insert(0, ifx_sandbox_path)
|
20 |
-
|
21 |
-
try:
|
22 |
-
# Import the configured graph instance from ifx-sandbox directory
|
23 |
-
from gradio_graph import graph
|
24 |
-
print("Successfully imported graph object from gradio_graph.")
|
25 |
-
except ImportError as e:
|
26 |
-
print(f"Error importing gradio_graph: {e}")
|
27 |
-
print("Please ensure gradio_graph.py exists in the 'ifx-sandbox' directory and is configured correctly.")
|
28 |
-
print("Make sure you are running this script from the workspace root directory.")
|
29 |
-
sys.exit(1)
|
30 |
-
except Exception as e:
|
31 |
-
print(f"An unexpected error occurred during import: {e}")
|
32 |
-
sys.exit(1)
|
33 |
-
|
34 |
-
def cleanup_game_embeddings():
|
35 |
-
"""Removes the embedding property from all Game nodes in Neo4j."""
|
36 |
-
print("Starting Neo4j cleanup: Removing 'embedding' property from :Game nodes...")
|
37 |
-
|
38 |
-
cleanup_query = """
|
39 |
-
MATCH (g:Game)
|
40 |
-
WHERE g.embedding IS NOT NULL
|
41 |
-
REMOVE g.embedding
|
42 |
-
RETURN count(g) as removed_count
|
43 |
-
"""
|
44 |
-
|
45 |
-
try:
|
46 |
-
result = graph.query(cleanup_query)
|
47 |
-
|
48 |
-
if result and isinstance(result, list) and len(result) > 0 and 'removed_count' in result[0]:
|
49 |
-
count = result[0]['removed_count']
|
50 |
-
print(f"Successfully removed 'embedding' property from {count} :Game node(s).")
|
51 |
-
else:
|
52 |
-
# Query might return empty list if no nodes matched or had the property
|
53 |
-
print("Cleanup query executed. No 'embedding' properties found or removed from :Game nodes (or query result format unexpected).")
|
54 |
-
print(f"Raw query result: {result}")
|
55 |
-
|
56 |
-
except Exception as e:
|
57 |
-
print(f"Error executing Neo4j cleanup query: {e}")
|
58 |
-
print("Cleanup failed.")
|
59 |
-
|
60 |
-
if __name__ == "__main__":
|
61 |
-
print("Running Neo4j Game Embedding Cleanup script...")
|
62 |
-
# Basic check: Does 'ifx-sandbox' exist relative to script location?
|
63 |
-
if not os.path.isdir(ifx_sandbox_path):
|
64 |
-
print("Error: Cannot find 'ifx-sandbox' directory.")
|
65 |
-
print("Please ensure you run this script from the workspace root directory.")
|
66 |
-
sys.exit(1)
|
67 |
-
|
68 |
-
cleanup_game_embeddings()
|
69 |
-
print("Script execution complete.")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
z_utils/persona_session_ids.json
DELETED
@@ -1,4 +0,0 @@
|
|
1 |
-
{
|
2 |
-
"Casual Fan": "241b3478c7634492abee9f178b5341cb",
|
3 |
-
"Super Fan": "dedcf5cb0d71475f976f4f66d98d6400"
|
4 |
-
}
|
|
|
|
|
|
|
|
|
|
z_utils/persona_uuids.json
DELETED
@@ -1,4 +0,0 @@
|
|
1 |
-
{
|
2 |
-
"Casual Fan": "bdfc78a0-069a-48bf-af11-a843b7c6844e",
|
3 |
-
"Super Fan": "2e28be0a-8e2f-4480-8caf-975f58db0bca"
|
4 |
-
}
|
|
|
|
|
|
|
|
|
|
z_utils/restart_space.py
DELETED
@@ -1,50 +0,0 @@
|
|
1 |
-
#!/usr/bin/env python
|
2 |
-
import os
|
3 |
-
import time
|
4 |
-
import subprocess
|
5 |
-
from huggingface_hub import HfApi
|
6 |
-
|
7 |
-
# Get token from environment or from stored token
|
8 |
-
def get_token():
|
9 |
-
# Try to get token from cached location
|
10 |
-
try:
|
11 |
-
token_path = os.path.expanduser("~/.cache/huggingface/token")
|
12 |
-
if os.path.exists(token_path):
|
13 |
-
with open(token_path, "r") as f:
|
14 |
-
return f.read().strip()
|
15 |
-
except:
|
16 |
-
pass
|
17 |
-
|
18 |
-
# If that fails, try using the huggingface-cli to print the token
|
19 |
-
try:
|
20 |
-
result = subprocess.run(["huggingface-cli", "whoami", "--token"],
|
21 |
-
capture_output=True, text=True, check=True)
|
22 |
-
if result.stdout:
|
23 |
-
return result.stdout.strip()
|
24 |
-
except:
|
25 |
-
pass
|
26 |
-
|
27 |
-
return None
|
28 |
-
|
29 |
-
# Get the token
|
30 |
-
token = get_token()
|
31 |
-
if not token:
|
32 |
-
print("No Hugging Face token found. Please login using 'huggingface-cli login'")
|
33 |
-
exit(1)
|
34 |
-
|
35 |
-
# Hugging Face repo ID
|
36 |
-
repo_id = "aliss77777/IFX-sandbox"
|
37 |
-
|
38 |
-
# Initialize the Hugging Face API with the token
|
39 |
-
api = HfApi(token=token)
|
40 |
-
|
41 |
-
print(f"Restarting Space: {repo_id}")
|
42 |
-
|
43 |
-
try:
|
44 |
-
# Restart the Space
|
45 |
-
api.restart_space(repo_id=repo_id)
|
46 |
-
print(f"✓ Space restart request sent!")
|
47 |
-
print(f"The Space should restart shortly. You can check its status at: https://huggingface.co/spaces/{repo_id}")
|
48 |
-
except Exception as e:
|
49 |
-
print(f"Error restarting Space: {str(e)}")
|
50 |
-
exit(1)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
z_utils/set_secrets.py
DELETED
@@ -1,77 +0,0 @@
|
|
1 |
-
#!/usr/bin/env python
|
2 |
-
import os
|
3 |
-
import subprocess
|
4 |
-
from dotenv import load_dotenv
|
5 |
-
from huggingface_hub import HfApi
|
6 |
-
|
7 |
-
# Load environment variables from .env file
|
8 |
-
load_dotenv()
|
9 |
-
|
10 |
-
# Get Neo4j credentials
|
11 |
-
AURA_CONNECTION_URI = os.environ.get("AURA_CONNECTION_URI")
|
12 |
-
AURA_USERNAME = os.environ.get("AURA_USERNAME")
|
13 |
-
AURA_PASSWORD = os.environ.get("AURA_PASSWORD")
|
14 |
-
|
15 |
-
# Get OpenAI credentials
|
16 |
-
OPENAI_API_KEY = os.environ.get("OPENAI_API_KEY")
|
17 |
-
OPENAI_MODEL = os.environ.get("OPENAI_MODEL")
|
18 |
-
|
19 |
-
# Get token from environment or from stored token
|
20 |
-
def get_token():
|
21 |
-
# Try to get token from cached location
|
22 |
-
try:
|
23 |
-
token_path = os.path.expanduser("~/.cache/huggingface/token")
|
24 |
-
if os.path.exists(token_path):
|
25 |
-
with open(token_path, "r") as f:
|
26 |
-
return f.read().strip()
|
27 |
-
except:
|
28 |
-
pass
|
29 |
-
|
30 |
-
# If that fails, try using the huggingface-cli to print the token
|
31 |
-
try:
|
32 |
-
result = subprocess.run(["huggingface-cli", "whoami", "--token"],
|
33 |
-
capture_output=True, text=True, check=True)
|
34 |
-
if result.stdout:
|
35 |
-
return result.stdout.strip()
|
36 |
-
except:
|
37 |
-
pass
|
38 |
-
|
39 |
-
return None
|
40 |
-
|
41 |
-
# Get the token
|
42 |
-
token = get_token()
|
43 |
-
if not token:
|
44 |
-
print("No Hugging Face token found. Please login using 'huggingface-cli login'")
|
45 |
-
exit(1)
|
46 |
-
|
47 |
-
# Hugging Face repo ID
|
48 |
-
repo_id = "aliss77777/IFX-sandbox"
|
49 |
-
|
50 |
-
# Initialize the Hugging Face API with the token
|
51 |
-
api = HfApi(token=token)
|
52 |
-
|
53 |
-
print("Setting secrets for", repo_id)
|
54 |
-
|
55 |
-
# Set each secret
|
56 |
-
try:
|
57 |
-
# Set Neo4j credentials
|
58 |
-
api.add_space_secret(repo_id=repo_id, key="AURA_CONNECTION_URI", value=AURA_CONNECTION_URI)
|
59 |
-
print("✓ Set AURA_CONNECTION_URI")
|
60 |
-
|
61 |
-
api.add_space_secret(repo_id=repo_id, key="AURA_USERNAME", value=AURA_USERNAME)
|
62 |
-
print("✓ Set AURA_USERNAME")
|
63 |
-
|
64 |
-
api.add_space_secret(repo_id=repo_id, key="AURA_PASSWORD", value=AURA_PASSWORD)
|
65 |
-
print("✓ Set AURA_PASSWORD")
|
66 |
-
|
67 |
-
# Set OpenAI credentials
|
68 |
-
api.add_space_secret(repo_id=repo_id, key="OPENAI_API_KEY", value=OPENAI_API_KEY)
|
69 |
-
print("✓ Set OPENAI_API_KEY")
|
70 |
-
|
71 |
-
api.add_space_secret(repo_id=repo_id, key="OPENAI_MODEL", value=OPENAI_MODEL)
|
72 |
-
print("✓ Set OPENAI_MODEL")
|
73 |
-
|
74 |
-
print("\nAll secrets set successfully!")
|
75 |
-
except Exception as e:
|
76 |
-
print(f"Error setting secrets: {str(e)}")
|
77 |
-
exit(1)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
z_utils/zep_setup.py
DELETED
@@ -1,445 +0,0 @@
|
|
1 |
-
# file: z_utils/zep_setup.py
|
2 |
-
"""
|
3 |
-
Create two persona users in Zep Cloud and preload their memory graphs.
|
4 |
-
Run once: python z_utils/zep_setup.py
|
5 |
-
"""
|
6 |
-
|
7 |
-
import asyncio, os, uuid, json
|
8 |
-
from datetime import datetime, timezone
|
9 |
-
from dotenv import load_dotenv
|
10 |
-
from pathlib import Path
|
11 |
-
from zep_cloud.client import AsyncZep
|
12 |
-
from zep_cloud.errors import NotFoundError
|
13 |
-
from zep_cloud.types import User, Message
|
14 |
-
|
15 |
-
# Define the path for the UUIDs file relative to this script
|
16 |
-
UUID_FILE_PATH = Path(__file__).parent / "persona_uuids.json"
|
17 |
-
SESSION_ID_FILE_PATH = Path(__file__).parent / "persona_session_ids.json"
|
18 |
-
|
19 |
-
# Load environment variables from .env file
|
20 |
-
load_dotenv(dotenv_path=os.path.join(os.path.dirname(__file__), '..', '.env')) # Look for .env in parent dir
|
21 |
-
API_KEY = os.getenv("ZEP_API_KEY")
|
22 |
-
BASE_URL = os.getenv("ZEP_API_URL") # optional for self-hosted
|
23 |
-
|
24 |
-
if not API_KEY:
|
25 |
-
raise RuntimeError("ZEP_API_KEY missing in environment variables. Please ensure it's in ifx-sandbox/.env")
|
26 |
-
|
27 |
-
# Initialize AsyncZep client, handling optional base_url
|
28 |
-
zep_client_args = {"api_key": API_KEY}
|
29 |
-
if BASE_URL:
|
30 |
-
zep_client_args["base_url"] = BASE_URL
|
31 |
-
zep = AsyncZep(**zep_client_args)
|
32 |
-
|
33 |
-
# -------- persona blue-prints -------------------------------------------------
|
34 |
-
# Removed FactRatingExamples definition as it's not part of the SDK
|
35 |
-
# FACT_EXAMPLES = FactRatingExamples(
|
36 |
-
# high="Brock Purdy led the 49ers to the Super Bowl in 2024.",
|
37 |
-
# medium="The 49ers play in the NFC West.",
|
38 |
-
# low="Football games are played on a field."
|
39 |
-
# )
|
40 |
-
|
41 |
-
PERSONAS = {
|
42 |
-
"Casual Fan": {
|
43 |
-
"user_id": None, # Will be generated or loaded
|
44 |
-
"session_id": None, # Will be generated or loaded
|
45 |
-
"email": "[email protected]",
|
46 |
-
"first_name": "Casual",
|
47 |
-
"last_name": "Fan",
|
48 |
-
"metadata": {"fan_type": "casual"}
|
49 |
-
},
|
50 |
-
"Super Fan": {
|
51 |
-
"user_id": None, # Will be generated or loaded
|
52 |
-
"session_id": None, # Will be generated or loaded
|
53 |
-
"email": "[email protected]",
|
54 |
-
"first_name": "Super",
|
55 |
-
"last_name": "Fan",
|
56 |
-
"metadata": {"fan_type": "super"}
|
57 |
-
}
|
58 |
-
}
|
59 |
-
|
60 |
-
# --- Message histories for each persona based on their knowledge ---
|
61 |
-
|
62 |
-
CASUAL_FAN_MESSAGES = [
|
63 |
-
{"role": "user", "content": "Who are the 49ers?"},
|
64 |
-
{"role": "assistant", "content": "The San Francisco 49ers are a professional football team in the NFL. They play at Levi's Stadium in Santa Clara."},
|
65 |
-
{"role": "user", "content": "Who is their quarterback?"},
|
66 |
-
{"role": "assistant", "content": "Brock Purdy is the current starting quarterback for the 49ers. He emerged as the starter after being the final pick in the 2022 NFL Draft, often called 'Mr. Irrelevant.'"},
|
67 |
-
{"role": "user", "content": "Who are their best players?"},
|
68 |
-
{"role": "assistant", "content": "The 49ers have several star players! Christian McCaffrey (often called CMC) is their key running back and an offensive weapon. George Kittle is their star tight end known for his catching and blocking abilities. On defense, Nick Bosa is a dominant defensive end who frequently pressures quarterbacks."},
|
69 |
-
{"role": "user", "content": "Did they do well last season?"},
|
70 |
-
{"role": "assistant", "content": "Yes! The 49ers have been very competitive recently, making several playoff runs. They've established themselves as one of the stronger teams in the NFC."},
|
71 |
-
{"role": "user", "content": "What was their most exciting game?"},
|
72 |
-
{"role": "assistant", "content": "While there have been several exciting games, casual fans often remember the big moments - like playoff victories and games with spectacular, highlight-reel plays. The 49ers have had many memorable comeback wins and offensive explosions that got fans on their feet!"}
|
73 |
-
]
|
74 |
-
|
75 |
-
SUPER_FAN_MESSAGES = [
|
76 |
-
{"role": "user", "content": "Explain the 49ers' offensive scheme"},
|
77 |
-
{"role": "assistant", "content": "The 49ers primarily run Kyle Shanahan's offensive scheme, which heavily features the outside zone run, play-action passing, and pre-snap motion. This system relies on precise timing, versatile players who can both block and catch, and a strong offensive line. Trent Williams, their All-Pro left tackle, is particularly crucial for their run game success, creating lanes for their zone running attack."},
|
78 |
-
{"role": "user", "content": "What defensive system do they use?"},
|
79 |
-
{"role": "assistant", "content": "Under their defensive coordinator, the 49ers utilize a scheme that emphasizes pressure from their front four, led by Nick Bosa, without excessive blitzing. This allows them to drop seven defenders into coverage while still disrupting the quarterback. Fred Warner is the key middle linebacker who orchestrates the defense, handling both run stops and pass coverage responsibilities."},
|
80 |
-
{"role": "user", "content": "What's happening with their salary cap situation?"},
|
81 |
-
{"role": "assistant", "content": "The 49ers' salary cap management is a constant challenge. Currently, they're navigating extensions for key players like Brandon Aiyuk while planning for Brock Purdy's future contract when he becomes eligible for an extension. They've become adept at structuring contracts to maintain their core while finding value in mid-round draft picks and undrafted free agents who fit their systems perfectly."},
|
82 |
-
{"role": "user", "content": "What's their draft strategy been like?"},
|
83 |
-
{"role": "assistant", "content": "Their draft strategy often focuses on finding scheme fits rather than just raw talent or conventional wisdom. They prioritize specific traits that work in their systems and aren't afraid to draft players earlier than consensus would suggest if they believe in the fit. They've been particularly good at replenishing depth on both lines and finding mid-round receivers who thrive in Shanahan's offense."},
|
84 |
-
{"role": "user", "content": "Tell me about some of their role players beyond the stars"},
|
85 |
-
{"role": "assistant", "content": "Beyond the stars, the 49ers get significant contributions from role players like their nickel cornerback, rotational defensive linemen who keep the pass rush fresh, and versatile offensive weapons. Players like Jauan Jennings (clutch third-down receiver), Tashaun Gipson (veteran safety presence), and Elijah Mitchell (change-of-pace running back) may not make headlines but are crucial to the team's success and highly valued by die-hard fans who understand their specific contributions."},
|
86 |
-
{"role": "user", "content": "How does their current team compare historically?"},
|
87 |
-
{"role": "assistant", "content": "The current 49ers team continues their tradition of innovative coaching and physical play that dates back to their dynasty years. While they haven't yet matched the Super Bowl success of the teams led by Joe Montana, Jerry Rice, and Steve Young, they've returned to being perennial contenders. The current team emphasizes a strong run game and defense, similar to their historical identity, though the specific schemes have evolved with the modern NFL."}
|
88 |
-
]
|
89 |
-
|
90 |
-
CASUAL_FAN_KNOWLEDGE = [
|
91 |
-
{
|
92 |
-
"type": "text",
|
93 |
-
"data": """
|
94 |
-
General knowledge about the San Francisco 49ers for a casual fan.
|
95 |
-
Focuses on major stars and recent performance.
|
96 |
-
- The 49ers play at Levi's Stadium in Santa Clara.
|
97 |
-
- Brock Purdy is the current starting quarterback.
|
98 |
-
- Christian McCaffrey (CMC) is a key running back and offensive weapon.
|
99 |
-
- George Kittle is a star tight end.
|
100 |
-
- Nick Bosa is a dominant defensive end.
|
101 |
-
- The team has been competitive recently, often making playoff runs.
|
102 |
-
- Big plays and game outcomes are the main interest.
|
103 |
-
"""
|
104 |
-
}
|
105 |
-
]
|
106 |
-
|
107 |
-
SUPER_FAN_KNOWLEDGE = [
|
108 |
-
{
|
109 |
-
"type": "text",
|
110 |
-
"data": """
|
111 |
-
Detailed knowledge base for a San Francisco 49ers super fan.
|
112 |
-
Includes strategic insights, player roles, and historical context.
|
113 |
-
- The 49ers primarily run a Kyle Shanahan offensive scheme, heavily featuring the outside zone run, play-action passing, and pre-snap motion.
|
114 |
-
- Key offensive line players are crucial for the run game's success (e.g., Trent Williams).
|
115 |
-
- Defensive scheme under Steve Wilks (or current DC) utilizes a strong front four, led by Nick Bosa, aiming for pressure without excessive blitzing.
|
116 |
-
- Fred Warner is the crucial middle linebacker, orchestrating the defense.
|
117 |
-
- Salary cap management is a constant discussion point, especially regarding extensions for players like Brandon Aiyuk or Brock Purdy's future contract.
|
118 |
-
- Draft strategy often focuses on finding scheme fits and replenishing depth.
|
119 |
-
- Understanding specific player roles beyond stars (e.g., slot corner, rotational defensive linemen) is important.
|
120 |
-
- Historical context, like past Super Bowl appearances or legendary players (Montana, Rice, Young), is frequently referenced.
|
121 |
-
"""
|
122 |
-
},
|
123 |
-
{
|
124 |
-
"type": "json",
|
125 |
-
"data": json.dumps({
|
126 |
-
"team_focus": "49ers Strategy and Depth",
|
127 |
-
"key_concepts": [
|
128 |
-
"Shanahan Offense",
|
129 |
-
"Outside Zone Scheme",
|
130 |
-
"Defensive Line Pressure",
|
131 |
-
"Salary Cap Implications",
|
132 |
-
"Draft Capital Management",
|
133 |
-
"Player Contract Negotiations"
|
134 |
-
],
|
135 |
-
"recent_topics": [
|
136 |
-
"Brandon Aiyuk contract situation",
|
137 |
-
"Ricky Pearsall draft pick impact",
|
138 |
-
"Defensive coordinator adjustments",
|
139 |
-
"Offensive line performance analysis"
|
140 |
-
]
|
141 |
-
})
|
142 |
-
}
|
143 |
-
]
|
144 |
-
|
145 |
-
PERSONA_KNOWLEDGE_MAP = {
|
146 |
-
"Casual Fan": CASUAL_FAN_KNOWLEDGE,
|
147 |
-
"Super Fan": SUPER_FAN_KNOWLEDGE,
|
148 |
-
}
|
149 |
-
|
150 |
-
# Add mapping for persona message histories
|
151 |
-
PERSONA_MESSAGES_MAP = {
|
152 |
-
"Casual Fan": CASUAL_FAN_MESSAGES,
|
153 |
-
"Super Fan": SUPER_FAN_MESSAGES,
|
154 |
-
}
|
155 |
-
|
156 |
-
def load_or_generate_uuids():
|
157 |
-
"""Loads existing UUIDs from file or generates new ones if file doesn't exist."""
|
158 |
-
uuids_changed = False
|
159 |
-
if UUID_FILE_PATH.exists():
|
160 |
-
try:
|
161 |
-
with open(UUID_FILE_PATH, 'r') as f:
|
162 |
-
saved_uuids = json.load(f)
|
163 |
-
# Check if saved_uuids is a dict mapping names to strings
|
164 |
-
if isinstance(saved_uuids, dict):
|
165 |
-
for name in PERSONAS:
|
166 |
-
if name in saved_uuids and isinstance(saved_uuids[name], str):
|
167 |
-
PERSONAS[name]["user_id"] = saved_uuids[name]
|
168 |
-
print(f"Loaded existing UUID for {name}: {saved_uuids[name]}")
|
169 |
-
else:
|
170 |
-
# Generate new if name missing, value isn't string, or empty
|
171 |
-
PERSONAS[name]["user_id"] = str(uuid.uuid4())
|
172 |
-
print(f"UUID for {name} not found or invalid in file, generated new: {PERSONAS[name]['user_id']}")
|
173 |
-
uuids_changed = True
|
174 |
-
else:
|
175 |
-
# Invalid format, generate all new
|
176 |
-
print(f"UUID file ({UUID_FILE_PATH}) has unexpected format. Generating new UUIDs.")
|
177 |
-
for name in PERSONAS:
|
178 |
-
PERSONAS[name]["user_id"] = str(uuid.uuid4())
|
179 |
-
print(f"Generated new UUID for {name}: {PERSONAS[name]['user_id']}")
|
180 |
-
uuids_changed = True
|
181 |
-
|
182 |
-
except (json.JSONDecodeError, IOError) as e:
|
183 |
-
print(f"Error loading UUID file ({UUID_FILE_PATH}): {e}. Generating new UUIDs.")
|
184 |
-
for name in PERSONAS:
|
185 |
-
PERSONAS[name]["user_id"] = str(uuid.uuid4())
|
186 |
-
print(f"Generated new UUID for {name}: {PERSONAS[name]['user_id']}")
|
187 |
-
uuids_changed = True
|
188 |
-
else:
|
189 |
-
# File doesn't exist, generate all new UUIDs
|
190 |
-
print(f"UUID file ({UUID_FILE_PATH}) not found. Generating new UUIDs.")
|
191 |
-
for name in PERSONAS:
|
192 |
-
PERSONAS[name]["user_id"] = str(uuid.uuid4())
|
193 |
-
print(f"Generated new UUID for {name}: {PERSONAS[name]['user_id']}")
|
194 |
-
uuids_changed = True
|
195 |
-
|
196 |
-
if uuids_changed:
|
197 |
-
save_persona_uuids() # Save if any UUIDs were generated or changed
|
198 |
-
|
199 |
-
|
200 |
-
def load_or_generate_session_ids():
|
201 |
-
"""Loads existing session IDs from file or generates new ones if file doesn't exist."""
|
202 |
-
session_ids_changed = False
|
203 |
-
|
204 |
-
# Use the specific session IDs from the task document for these personas
|
205 |
-
hardcoded_session_ids = {
|
206 |
-
"Casual Fan": "241b3478c7634492abee9f178b5341cb",
|
207 |
-
"Super Fan": "dedcf5cb0d71475f976f4f66d98d6400"
|
208 |
-
}
|
209 |
-
|
210 |
-
if SESSION_ID_FILE_PATH.exists():
|
211 |
-
try:
|
212 |
-
with open(SESSION_ID_FILE_PATH, 'r') as f:
|
213 |
-
saved_session_ids = json.load(f)
|
214 |
-
# Check if saved_session_ids is a dict mapping names to strings
|
215 |
-
if isinstance(saved_session_ids, dict):
|
216 |
-
for name in PERSONAS:
|
217 |
-
# Use hardcoded session IDs regardless of what's in the file
|
218 |
-
PERSONAS[name]["session_id"] = hardcoded_session_ids[name]
|
219 |
-
print(f"Using required session ID for {name}: {PERSONAS[name]['session_id']}")
|
220 |
-
|
221 |
-
# If the saved value differs from hardcoded, we'll need to update the file
|
222 |
-
if name not in saved_session_ids or saved_session_ids[name] != hardcoded_session_ids[name]:
|
223 |
-
session_ids_changed = True
|
224 |
-
else:
|
225 |
-
# Invalid format, use hardcoded IDs
|
226 |
-
print(f"Session ID file ({SESSION_ID_FILE_PATH}) has unexpected format. Using required session IDs.")
|
227 |
-
for name in PERSONAS:
|
228 |
-
PERSONAS[name]["session_id"] = hardcoded_session_ids[name]
|
229 |
-
print(f"Using required session ID for {name}: {PERSONAS[name]['session_id']}")
|
230 |
-
session_ids_changed = True
|
231 |
-
except (json.JSONDecodeError, IOError) as e:
|
232 |
-
print(f"Error loading session ID file ({SESSION_ID_FILE_PATH}): {e}. Using required session IDs.")
|
233 |
-
for name in PERSONAS:
|
234 |
-
PERSONAS[name]["session_id"] = hardcoded_session_ids[name]
|
235 |
-
print(f"Using required session ID for {name}: {PERSONAS[name]['session_id']}")
|
236 |
-
session_ids_changed = True
|
237 |
-
else:
|
238 |
-
# File doesn't exist, use hardcoded IDs
|
239 |
-
print(f"Session ID file ({SESSION_ID_FILE_PATH}) not found. Using required session IDs.")
|
240 |
-
for name in PERSONAS:
|
241 |
-
PERSONAS[name]["session_id"] = hardcoded_session_ids[name]
|
242 |
-
print(f"Using required session ID for {name}: {PERSONAS[name]['session_id']}")
|
243 |
-
session_ids_changed = True
|
244 |
-
|
245 |
-
if session_ids_changed:
|
246 |
-
save_persona_session_ids() # Save if any session IDs were updated
|
247 |
-
|
248 |
-
|
249 |
-
def save_persona_uuids():
|
250 |
-
"""Saves the current persona UUIDs (name -> user_id string) to the JSON file."""
|
251 |
-
# Ensure we only save the user_id string
|
252 |
-
uuids_to_save = {name: data["user_id"] for name, data in PERSONAS.items() if isinstance(data.get("user_id"), str)}
|
253 |
-
if len(uuids_to_save) != len(PERSONAS):
|
254 |
-
print("Warning: Not all personas had valid string UUIDs during save.")
|
255 |
-
# Potentially raise an error or handle more robustly
|
256 |
-
|
257 |
-
try:
|
258 |
-
with open(UUID_FILE_PATH, 'w') as f:
|
259 |
-
json.dump(uuids_to_save, f, indent=4)
|
260 |
-
print(f"Persona UUIDs saved to {UUID_FILE_PATH}")
|
261 |
-
except IOError as e:
|
262 |
-
print(f"Error saving UUIDs to {UUID_FILE_PATH}: {e}")
|
263 |
-
|
264 |
-
|
265 |
-
def save_persona_session_ids():
|
266 |
-
"""Saves the current persona session IDs (name -> session_id string) to the JSON file."""
|
267 |
-
# Ensure we only save the session_id string
|
268 |
-
session_ids_to_save = {name: data["session_id"] for name, data in PERSONAS.items() if isinstance(data.get("session_id"), str)}
|
269 |
-
if len(session_ids_to_save) != len(PERSONAS):
|
270 |
-
print("Warning: Not all personas had valid string session IDs during save.")
|
271 |
-
# Potentially raise an error or handle more robustly
|
272 |
-
|
273 |
-
try:
|
274 |
-
with open(SESSION_ID_FILE_PATH, 'w') as f:
|
275 |
-
json.dump(session_ids_to_save, f, indent=4)
|
276 |
-
print(f"Persona session IDs saved to {SESSION_ID_FILE_PATH}")
|
277 |
-
except IOError as e:
|
278 |
-
print(f"Error saving session IDs to {SESSION_ID_FILE_PATH}: {e}")
|
279 |
-
|
280 |
-
|
281 |
-
async def create_zep_user(client: AsyncZep, user_data: dict):
|
282 |
-
"""Creates or updates a Zep user, checking if they exist first."""
|
283 |
-
user_id = user_data["user_id"]
|
284 |
-
try:
|
285 |
-
# Check if user exists
|
286 |
-
await client.user.get(user_id)
|
287 |
-
print(f"User {user_id} ({user_data.get('first_name', '')}) already exists. Updating...")
|
288 |
-
# Update existing user (optional, could just skip)
|
289 |
-
await client.user.update(
|
290 |
-
user_id=user_id,
|
291 |
-
email=user_data.get("email"),
|
292 |
-
first_name=user_data.get("first_name"),
|
293 |
-
last_name=user_data.get("last_name"),
|
294 |
-
metadata=user_data.get("metadata")
|
295 |
-
)
|
296 |
-
print(f"User {user_id} updated.")
|
297 |
-
except NotFoundError:
|
298 |
-
# User does not exist, create them
|
299 |
-
print(f"User {user_id} ({user_data.get('first_name', '')}) not found. Creating...")
|
300 |
-
try:
|
301 |
-
await client.user.add(**user_data)
|
302 |
-
print(f"User {user_id} created successfully.")
|
303 |
-
except Exception as e:
|
304 |
-
print(f"Error creating user {user_id}: {e}")
|
305 |
-
except Exception as e:
|
306 |
-
print(f"Error checking or updating user {user_id}: {e}")
|
307 |
-
|
308 |
-
|
309 |
-
async def preload_knowledge(client: AsyncZep, user_id: str, knowledge_items: list):
|
310 |
-
"""Preloads foundational knowledge into the user's graph using graph.add."""
|
311 |
-
print(f"Preloading knowledge for user {user_id}...")
|
312 |
-
success_count = 0
|
313 |
-
for i, item in enumerate(knowledge_items):
|
314 |
-
try:
|
315 |
-
print(f" Adding knowledge item {i+1}/{len(knowledge_items)} (type: {item['type']})...")
|
316 |
-
await client.graph.add(
|
317 |
-
user_id=user_id,
|
318 |
-
type=item["type"],
|
319 |
-
data=item["data"] # Expects string data, JSON already dumped
|
320 |
-
)
|
321 |
-
success_count += 1
|
322 |
-
print(f" Item {i+1} added successfully.")
|
323 |
-
# Add a small delay to avoid overwhelming the API if adding many items
|
324 |
-
await asyncio.sleep(0.5)
|
325 |
-
except Exception as e:
|
326 |
-
print(f" Error adding knowledge item {i+1} for user {user_id}: {e}")
|
327 |
-
# Decide whether to continue or stop on error
|
328 |
-
# break # Uncomment to stop on first error
|
329 |
-
print(f"Knowledge preloading completed for user {user_id}. {success_count}/{len(knowledge_items)} items added.")
|
330 |
-
|
331 |
-
|
332 |
-
async def preload_message_history(client: AsyncZep, user_id: str, session_id: str, messages: list):
|
333 |
-
"""Preloads message history for a user in a specific session."""
|
334 |
-
print(f"Preloading message history for user {user_id} in session {session_id}...")
|
335 |
-
|
336 |
-
try:
|
337 |
-
# First, ensure the session exists or create it
|
338 |
-
try:
|
339 |
-
# Try to get the session to see if it exists
|
340 |
-
await client.memory.get_session(session_id=session_id)
|
341 |
-
print(f"Session {session_id} already exists.")
|
342 |
-
except NotFoundError:
|
343 |
-
# Session does not exist, create it
|
344 |
-
await client.memory.add_session(
|
345 |
-
session_id=session_id,
|
346 |
-
user_id=user_id
|
347 |
-
)
|
348 |
-
print(f"Created new session {session_id} for user {user_id}")
|
349 |
-
|
350 |
-
# Then add messages to the session
|
351 |
-
zep_messages = []
|
352 |
-
for msg in messages:
|
353 |
-
# Map 'role' field to proper Zep role_type
|
354 |
-
role_type = msg["role"]
|
355 |
-
# If role is 'user', set role_type to 'user'
|
356 |
-
# If role is 'assistant', keep role_type as 'assistant'
|
357 |
-
|
358 |
-
zep_messages.append(
|
359 |
-
Message(
|
360 |
-
role_type=role_type, # Use the role directly as role_type
|
361 |
-
content=msg["content"],
|
362 |
-
role=None # Using default role
|
363 |
-
)
|
364 |
-
)
|
365 |
-
|
366 |
-
# Add the messages to the session
|
367 |
-
await client.memory.add(
|
368 |
-
session_id=session_id,
|
369 |
-
messages=zep_messages
|
370 |
-
)
|
371 |
-
print(f"Added {len(zep_messages)} messages to session {session_id}")
|
372 |
-
|
373 |
-
except Exception as e:
|
374 |
-
print(f"Error preloading message history: {e}")
|
375 |
-
|
376 |
-
|
377 |
-
async def main():
|
378 |
-
"""Main function to set up Zep users and preload knowledge."""
|
379 |
-
print("Starting Zep setup...")
|
380 |
-
load_dotenv()
|
381 |
-
|
382 |
-
api_key = os.environ.get("ZEP_API_KEY")
|
383 |
-
api_url = os.environ.get("ZEP_API_URL") # Optional
|
384 |
-
|
385 |
-
if not api_key:
|
386 |
-
print("Error: ZEP_API_KEY environment variable not set.")
|
387 |
-
return
|
388 |
-
|
389 |
-
client_params = {"api_key": api_key}
|
390 |
-
if api_url:
|
391 |
-
client_params["api_url"] = api_url
|
392 |
-
|
393 |
-
client = None # Initialize client variable
|
394 |
-
try:
|
395 |
-
# Instantiate client directly, remove async with
|
396 |
-
client = AsyncZep(**client_params)
|
397 |
-
print("Zep client initialized.")
|
398 |
-
|
399 |
-
# Load or generate UUIDs and update PERSONAS dict
|
400 |
-
load_or_generate_uuids()
|
401 |
-
|
402 |
-
# Load or use hardcoded session IDs from the task document
|
403 |
-
load_or_generate_session_ids()
|
404 |
-
|
405 |
-
# Create/Update users
|
406 |
-
for persona_name, data in PERSONAS.items():
|
407 |
-
await create_zep_user(client, data)
|
408 |
-
|
409 |
-
# Preload knowledge for each persona
|
410 |
-
for persona_name, data in PERSONAS.items():
|
411 |
-
user_id = data["user_id"]
|
412 |
-
knowledge = PERSONA_KNOWLEDGE_MAP.get(persona_name, [])
|
413 |
-
if knowledge:
|
414 |
-
await preload_knowledge(client, user_id, knowledge)
|
415 |
-
else:
|
416 |
-
print(f"No knowledge defined for persona: {persona_name}")
|
417 |
-
|
418 |
-
# Preload message history for each persona
|
419 |
-
for persona_name, data in PERSONAS.items():
|
420 |
-
user_id = data["user_id"]
|
421 |
-
session_id = data["session_id"]
|
422 |
-
messages = PERSONA_MESSAGES_MAP.get(persona_name, [])
|
423 |
-
if messages:
|
424 |
-
await preload_message_history(client, user_id, session_id, messages)
|
425 |
-
else:
|
426 |
-
print(f"No message history defined for persona: {persona_name}")
|
427 |
-
|
428 |
-
except Exception as e:
|
429 |
-
print(f"An error occurred during Zep client initialization or operation: {e}")
|
430 |
-
# finally:
|
431 |
-
# Optional: Add any explicit cleanup if the client required it,
|
432 |
-
# but typically SDK clients manage their own connections.
|
433 |
-
# if client and hasattr(client, 'close') and asyncio.iscoroutinefunction(client.close):
|
434 |
-
# await client.close()
|
435 |
-
# print("Zep client closed.")
|
436 |
-
|
437 |
-
print("Zep setup finished.")
|
438 |
-
|
439 |
-
|
440 |
-
if __name__ == "__main__":
|
441 |
-
# Ensure the script runs in an environment where asyncio is available
|
442 |
-
# If running in a Jupyter notebook, you might need nest_asyncio
|
443 |
-
# import nest_asyncio
|
444 |
-
# nest_asyncio.apply()
|
445 |
-
asyncio.run(main())
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
z_utils/zep_test.py
DELETED
@@ -1,97 +0,0 @@
|
|
1 |
-
"""
|
2 |
-
Simple Zep test script to retrieve chat history from a pre-defined session.
|
3 |
-
This follows step 2 of Task 1.3 Memory & Persona Implementation.
|
4 |
-
"""
|
5 |
-
import os
|
6 |
-
import json
|
7 |
-
import argparse
|
8 |
-
from dotenv import load_dotenv
|
9 |
-
from zep_cloud.client import Zep
|
10 |
-
from langchain_core.messages import HumanMessage, AIMessage
|
11 |
-
|
12 |
-
# Load environment variables from .env file
|
13 |
-
load_dotenv()
|
14 |
-
|
15 |
-
# Get Zep API key
|
16 |
-
ZEP_API_KEY = os.environ.get("ZEP_API_KEY")
|
17 |
-
if not ZEP_API_KEY:
|
18 |
-
raise RuntimeError("ZEP_API_KEY missing in environment variables.")
|
19 |
-
|
20 |
-
# Initialize Zep client
|
21 |
-
zep = Zep(api_key=ZEP_API_KEY)
|
22 |
-
|
23 |
-
def retrieve_chat_history(session_id):
|
24 |
-
"""
|
25 |
-
Retrieve chat history for a specific session from Zep.
|
26 |
-
|
27 |
-
Args:
|
28 |
-
session_id (str): The session ID to retrieve history for
|
29 |
-
|
30 |
-
Returns:
|
31 |
-
dict: The memory object containing context and messages
|
32 |
-
"""
|
33 |
-
try:
|
34 |
-
# Use Zep's memory.get API to retrieve chat history
|
35 |
-
memory = zep.memory.get(session_id=session_id)
|
36 |
-
return memory
|
37 |
-
except Exception as e:
|
38 |
-
print(f"Error retrieving chat history: {e}")
|
39 |
-
return None
|
40 |
-
|
41 |
-
def get_zep_history(session_id):
|
42 |
-
"""
|
43 |
-
Retrieve chat history directly from Zep using the client.
|
44 |
-
|
45 |
-
Args:
|
46 |
-
session_id (str): The session ID to retrieve history for
|
47 |
-
|
48 |
-
Returns:
|
49 |
-
list: Formatted messages for LangChain
|
50 |
-
"""
|
51 |
-
try:
|
52 |
-
zep = Zep(api_key=os.environ.get("ZEP_API_KEY"))
|
53 |
-
memory = zep.memory.get(session_id=session_id)
|
54 |
-
|
55 |
-
# Convert Zep messages to LangChain format
|
56 |
-
formatted_messages = []
|
57 |
-
if memory and memory.messages:
|
58 |
-
for msg in memory.messages:
|
59 |
-
if msg.role_type == "user":
|
60 |
-
formatted_messages.append(HumanMessage(content=msg.content))
|
61 |
-
elif msg.role_type == "assistant":
|
62 |
-
formatted_messages.append(AIMessage(content=msg.content))
|
63 |
-
|
64 |
-
return formatted_messages
|
65 |
-
except Exception as e:
|
66 |
-
print(f"Error retrieving Zep history: {e}")
|
67 |
-
return []
|
68 |
-
|
69 |
-
def main():
|
70 |
-
# Set up command line argument parsing
|
71 |
-
parser = argparse.ArgumentParser(description='Retrieve chat history from Zep')
|
72 |
-
parser.add_argument('--session_id', type=str,
|
73 |
-
default="241b3478c7634492abee9f178b5341cb",
|
74 |
-
help='Session ID to retrieve (default: Casual Fan)')
|
75 |
-
args = parser.parse_args()
|
76 |
-
|
77 |
-
session_id = args.session_id
|
78 |
-
|
79 |
-
print(f"Retrieving chat history for session ID: {session_id}")
|
80 |
-
|
81 |
-
# Get the memory for the session
|
82 |
-
memory = retrieve_chat_history(session_id)
|
83 |
-
|
84 |
-
if memory:
|
85 |
-
print("\n===== MEMORY CONTEXT =====")
|
86 |
-
print(memory.context)
|
87 |
-
|
88 |
-
print("\n===== CHAT MESSAGES =====")
|
89 |
-
for msg in memory.messages:
|
90 |
-
print(f"{msg.role_type} ({msg.role}): {msg.content}")
|
91 |
-
|
92 |
-
print("\nSuccessfully retrieved chat history!")
|
93 |
-
else:
|
94 |
-
print("Failed to retrieve chat history.")
|
95 |
-
|
96 |
-
if __name__ == "__main__":
|
97 |
-
main()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|