claude-self-reflect 5.0.7 → 6.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/agents/open-source-maintainer.md +1 -1
- package/.claude/agents/reflection-specialist.md +2 -2
- package/Dockerfile.async-importer +6 -4
- package/Dockerfile.importer +6 -6
- package/Dockerfile.safe-watcher +8 -8
- package/Dockerfile.streaming-importer +8 -1
- package/Dockerfile.watcher +8 -16
- package/docker-compose.yaml +12 -6
- package/installer/.claude/agents/README.md +138 -0
- package/package.json +5 -26
- package/src/__init__.py +0 -0
- package/src/cli/__init__.py +0 -0
- package/src/runtime/__init__.py +0 -0
- package/src/runtime/import-latest.py +124 -0
- package/{scripts → src/runtime}/precompact-hook.sh +1 -1
- package/src/runtime/streaming-importer.py +995 -0
- package/{scripts → src/runtime}/watcher-loop.sh +1 -1
- package/.claude/agents/claude-self-reflect-test.md +0 -1274
- package/.claude/agents/reflect-tester.md +0 -300
- package/scripts/add-timestamp-indexes.py +0 -134
- package/scripts/ast_grep_final_analyzer.py +0 -338
- package/scripts/ast_grep_unified_registry.py +0 -710
- package/scripts/check-collections.py +0 -29
- package/scripts/debug-august-parsing.py +0 -80
- package/scripts/debug-import-single.py +0 -91
- package/scripts/debug-project-resolver.py +0 -82
- package/scripts/debug-temporal-tools.py +0 -135
- package/scripts/import-conversations-enhanced.py +0 -672
- package/scripts/migrate-to-unified-state.py +0 -426
- package/scripts/session_quality_tracker.py +0 -671
- package/scripts/update_patterns.py +0 -334
- /package/{scripts → src}/importer/__init__.py +0 -0
- /package/{scripts → src}/importer/__main__.py +0 -0
- /package/{scripts → src}/importer/core/__init__.py +0 -0
- /package/{scripts → src}/importer/core/config.py +0 -0
- /package/{scripts → src}/importer/core/exceptions.py +0 -0
- /package/{scripts → src}/importer/core/models.py +0 -0
- /package/{scripts → src}/importer/embeddings/__init__.py +0 -0
- /package/{scripts → src}/importer/embeddings/base.py +0 -0
- /package/{scripts → src}/importer/embeddings/fastembed_provider.py +0 -0
- /package/{scripts → src}/importer/embeddings/validator.py +0 -0
- /package/{scripts → src}/importer/embeddings/voyage_provider.py +0 -0
- /package/{scripts → src}/importer/main.py +0 -0
- /package/{scripts → src}/importer/processors/__init__.py +0 -0
- /package/{scripts → src}/importer/processors/ast_extractor.py +0 -0
- /package/{scripts → src}/importer/processors/chunker.py +0 -0
- /package/{scripts → src}/importer/processors/concept_extractor.py +0 -0
- /package/{scripts → src}/importer/processors/conversation_parser.py +0 -0
- /package/{scripts → src}/importer/processors/tool_extractor.py +0 -0
- /package/{scripts → src}/importer/state/__init__.py +0 -0
- /package/{scripts → src}/importer/state/state_manager.py +0 -0
- /package/{scripts → src}/importer/storage/__init__.py +0 -0
- /package/{scripts → src}/importer/storage/qdrant_storage.py +0 -0
- /package/{scripts → src}/importer/utils/__init__.py +0 -0
- /package/{scripts → src}/importer/utils/logger.py +0 -0
- /package/{scripts → src}/importer/utils/project_normalizer.py +0 -0
- /package/{scripts → src/runtime}/delta-metadata-update-safe.py +0 -0
- /package/{scripts → src/runtime}/delta-metadata-update.py +0 -0
- /package/{scripts → src/runtime}/doctor.py +0 -0
- /package/{scripts → src/runtime}/embedding_service.py +0 -0
- /package/{scripts → src/runtime}/force-metadata-recovery.py +0 -0
- /package/{scripts → src/runtime}/import-conversations-unified.py +0 -0
- /package/{scripts → src/runtime}/import_strategies.py +0 -0
- /package/{scripts → src/runtime}/message_processors.py +0 -0
- /package/{scripts → src/runtime}/metadata_extractor.py +0 -0
- /package/{scripts → src/runtime}/streaming-watcher.py +0 -0
- /package/{scripts → src/runtime}/unified_state_manager.py +0 -0
- /package/{scripts → src/runtime}/utils.py +0 -0
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env python3
|
|
2
|
-
"""Check Qdrant collections."""
|
|
3
|
-
|
|
4
|
-
import os
|
|
5
|
-
from qdrant_client import QdrantClient
|
|
6
|
-
|
|
7
|
-
# Configuration
|
|
8
|
-
QDRANT_URL = os.getenv("QDRANT_URL", "http://localhost:6333")
|
|
9
|
-
|
|
10
|
-
def main():
|
|
11
|
-
"""List all collections."""
|
|
12
|
-
client = QdrantClient(url=QDRANT_URL)
|
|
13
|
-
|
|
14
|
-
# Get all collections
|
|
15
|
-
collections = client.get_collections()
|
|
16
|
-
|
|
17
|
-
print("Qdrant Collections:")
|
|
18
|
-
print("-" * 60)
|
|
19
|
-
|
|
20
|
-
voyage_collections = []
|
|
21
|
-
for collection in collections.collections:
|
|
22
|
-
print(f"- {collection.name}")
|
|
23
|
-
if collection.name.endswith("_voyage"):
|
|
24
|
-
voyage_collections.append(collection.name)
|
|
25
|
-
|
|
26
|
-
print(f"\nFound {len(voyage_collections)} Voyage collections")
|
|
27
|
-
|
|
28
|
-
if __name__ == "__main__":
|
|
29
|
-
main()
|
|
@@ -1,80 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env python3
|
|
2
|
-
"""Debug why August files aren't parsing properly."""
|
|
3
|
-
|
|
4
|
-
import json
|
|
5
|
-
import sys
|
|
6
|
-
|
|
7
|
-
def parse_jsonl_file(file_path):
|
|
8
|
-
"""Parse JSONL file and extract messages."""
|
|
9
|
-
messages = []
|
|
10
|
-
|
|
11
|
-
with open(file_path, 'r', encoding='utf-8') as f:
|
|
12
|
-
for line_num, line in enumerate(f, 1):
|
|
13
|
-
line = line.strip()
|
|
14
|
-
if not line:
|
|
15
|
-
continue
|
|
16
|
-
|
|
17
|
-
try:
|
|
18
|
-
data = json.loads(line)
|
|
19
|
-
|
|
20
|
-
# Skip summary messages
|
|
21
|
-
if data.get('type') == 'summary':
|
|
22
|
-
print(f"Line {line_num}: Skipping summary")
|
|
23
|
-
continue
|
|
24
|
-
|
|
25
|
-
# Handle messages with type user/assistant at root level
|
|
26
|
-
if data.get('type') in ['user', 'assistant']:
|
|
27
|
-
if 'message' in data and data['message']:
|
|
28
|
-
msg = data['message']
|
|
29
|
-
if msg.get('role') and msg.get('content'):
|
|
30
|
-
content = msg['content']
|
|
31
|
-
if isinstance(content, list):
|
|
32
|
-
text_parts = []
|
|
33
|
-
for item in content:
|
|
34
|
-
if isinstance(item, dict) and item.get('type') == 'text':
|
|
35
|
-
text_parts.append(item.get('text', ''))
|
|
36
|
-
elif isinstance(item, str):
|
|
37
|
-
text_parts.append(item)
|
|
38
|
-
content = '\n'.join(text_parts)
|
|
39
|
-
|
|
40
|
-
if content:
|
|
41
|
-
messages.append({
|
|
42
|
-
'role': msg['role'],
|
|
43
|
-
'content': content[:200] + '...' if len(content) > 200 else content,
|
|
44
|
-
'line': line_num
|
|
45
|
-
})
|
|
46
|
-
print(f"Line {line_num}: Extracted {msg['role']} message ({len(content)} chars)")
|
|
47
|
-
else:
|
|
48
|
-
print(f"Line {line_num}: Empty content for {msg['role']}")
|
|
49
|
-
else:
|
|
50
|
-
print(f"Line {line_num}: Missing role or content in message field")
|
|
51
|
-
else:
|
|
52
|
-
print(f"Line {line_num}: No message field for type={data.get('type')}")
|
|
53
|
-
else:
|
|
54
|
-
print(f"Line {line_num}: Unknown type={data.get('type')}")
|
|
55
|
-
|
|
56
|
-
except Exception as e:
|
|
57
|
-
print(f"Line {line_num}: Parse error - {e}")
|
|
58
|
-
|
|
59
|
-
return messages
|
|
60
|
-
|
|
61
|
-
if __name__ == "__main__":
|
|
62
|
-
# Use home directory path
|
|
63
|
-
from pathlib import Path
|
|
64
|
-
home = Path.home()
|
|
65
|
-
file_path = home / ".claude" / "projects" / f"-{home}-projects-claude-self-reflect" / "7b3354ed-d6d2-4eab-b328-1fced4bb63bb.jsonl"
|
|
66
|
-
file_path = str(file_path)
|
|
67
|
-
|
|
68
|
-
print(f"Parsing: {file_path}")
|
|
69
|
-
print("=" * 60)
|
|
70
|
-
|
|
71
|
-
messages = parse_jsonl_file(file_path)
|
|
72
|
-
|
|
73
|
-
print("\n" + "=" * 60)
|
|
74
|
-
print(f"Total messages extracted: {len(messages)}")
|
|
75
|
-
|
|
76
|
-
if messages:
|
|
77
|
-
print("\nFirst 5 messages:")
|
|
78
|
-
for i, msg in enumerate(messages[:5]):
|
|
79
|
-
print(f"\n{i+1}. Line {msg['line']}: {msg['role']}")
|
|
80
|
-
print(f" Content: {msg['content'][:100]}...")
|
|
@@ -1,91 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env python3
|
|
2
|
-
"""
|
|
3
|
-
Debug import of a single file with summary messages
|
|
4
|
-
"""
|
|
5
|
-
|
|
6
|
-
import json
|
|
7
|
-
from pathlib import Path
|
|
8
|
-
|
|
9
|
-
# Target file
|
|
10
|
-
test_file = Path.home() / '.claude/projects/-Users-ramakrishnanannaswamy-projects-claude-self-reflect/c072a61e-aebb-4c85-960b-c5ffeafa7115.jsonl'
|
|
11
|
-
|
|
12
|
-
print(f"Analyzing: {test_file.name}\n")
|
|
13
|
-
|
|
14
|
-
# Read and analyze the file
|
|
15
|
-
all_messages = []
|
|
16
|
-
summary_count = 0
|
|
17
|
-
user_count = 0
|
|
18
|
-
assistant_count = 0
|
|
19
|
-
other_count = 0
|
|
20
|
-
|
|
21
|
-
with open(test_file, 'r') as f:
|
|
22
|
-
for i, line in enumerate(f, 1):
|
|
23
|
-
if line.strip():
|
|
24
|
-
try:
|
|
25
|
-
data = json.loads(line)
|
|
26
|
-
msg_type = data.get('type', 'unknown')
|
|
27
|
-
|
|
28
|
-
print(f"Line {i}: type={msg_type}", end="")
|
|
29
|
-
|
|
30
|
-
# Check what would be extracted
|
|
31
|
-
if msg_type == 'summary':
|
|
32
|
-
summary_count += 1
|
|
33
|
-
print(f" -> SKIPPED (summary)")
|
|
34
|
-
continue
|
|
35
|
-
|
|
36
|
-
# Check for messages with type user/assistant
|
|
37
|
-
if msg_type in ['user', 'assistant']:
|
|
38
|
-
if 'message' in data and data['message']:
|
|
39
|
-
msg = data['message']
|
|
40
|
-
if msg.get('role') and msg.get('content'):
|
|
41
|
-
all_messages.append(msg)
|
|
42
|
-
if msg_type == 'user':
|
|
43
|
-
user_count += 1
|
|
44
|
-
else:
|
|
45
|
-
assistant_count += 1
|
|
46
|
-
|
|
47
|
-
# Extract a preview of content
|
|
48
|
-
content = msg.get('content', '')
|
|
49
|
-
if isinstance(content, list) and len(content) > 0:
|
|
50
|
-
first_item = content[0]
|
|
51
|
-
if isinstance(first_item, dict):
|
|
52
|
-
preview = str(first_item.get('content', first_item.get('text', '')))[:50]
|
|
53
|
-
else:
|
|
54
|
-
preview = str(first_item)[:50]
|
|
55
|
-
else:
|
|
56
|
-
preview = str(content)[:50]
|
|
57
|
-
|
|
58
|
-
print(f" -> EXTRACTED (role={msg['role']}, preview: {preview}...)")
|
|
59
|
-
else:
|
|
60
|
-
print(f" -> NO role/content in message")
|
|
61
|
-
else:
|
|
62
|
-
print(f" -> NO message field")
|
|
63
|
-
else:
|
|
64
|
-
other_count += 1
|
|
65
|
-
print(f" -> OTHER TYPE")
|
|
66
|
-
|
|
67
|
-
except json.JSONDecodeError as e:
|
|
68
|
-
print(f"Line {i}: INVALID JSON - {e}")
|
|
69
|
-
|
|
70
|
-
print(f"\n=== SUMMARY ===")
|
|
71
|
-
print(f"Total lines: {i}")
|
|
72
|
-
print(f"Summaries (skipped): {summary_count}")
|
|
73
|
-
print(f"User messages: {user_count}")
|
|
74
|
-
print(f"Assistant messages: {assistant_count}")
|
|
75
|
-
print(f"Other types: {other_count}")
|
|
76
|
-
print(f"Total extracted messages: {len(all_messages)}")
|
|
77
|
-
|
|
78
|
-
# Check for Memento content
|
|
79
|
-
memento_found = False
|
|
80
|
-
for msg in all_messages:
|
|
81
|
-
content = str(msg.get('content', ''))
|
|
82
|
-
if 'memento' in content.lower():
|
|
83
|
-
memento_found = True
|
|
84
|
-
break
|
|
85
|
-
|
|
86
|
-
print(f"\nMemento content found in messages: {memento_found}")
|
|
87
|
-
|
|
88
|
-
if len(all_messages) > 0:
|
|
89
|
-
print(f"\n✅ File SHOULD be importable with {len(all_messages)} messages")
|
|
90
|
-
else:
|
|
91
|
-
print(f"\n❌ File would result in ZERO messages imported")
|
|
@@ -1,82 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env python3
|
|
2
|
-
"""Test ProjectResolver to see if it's finding collections correctly."""
|
|
3
|
-
|
|
4
|
-
import sys
|
|
5
|
-
from pathlib import Path
|
|
6
|
-
sys.path.insert(0, str(Path(__file__).parent.parent / 'mcp-server' / 'src'))
|
|
7
|
-
|
|
8
|
-
from qdrant_client import QdrantClient
|
|
9
|
-
from project_resolver import ProjectResolver
|
|
10
|
-
|
|
11
|
-
# Connect to Qdrant
|
|
12
|
-
client = QdrantClient(url="http://localhost:6333")
|
|
13
|
-
|
|
14
|
-
# Create resolver
|
|
15
|
-
resolver = ProjectResolver(client)
|
|
16
|
-
|
|
17
|
-
# Test projects
|
|
18
|
-
test_projects = [
|
|
19
|
-
"claude-self-reflect",
|
|
20
|
-
"memento",
|
|
21
|
-
"cc-enhance",
|
|
22
|
-
"all"
|
|
23
|
-
]
|
|
24
|
-
|
|
25
|
-
print("=== Testing ProjectResolver ===\n")
|
|
26
|
-
|
|
27
|
-
for project in test_projects:
|
|
28
|
-
print(f"Project: '{project}'")
|
|
29
|
-
collections = resolver.find_collections_for_project(project)
|
|
30
|
-
print(f" Found {len(collections)} collections")
|
|
31
|
-
|
|
32
|
-
if collections:
|
|
33
|
-
# Show first 3 collections
|
|
34
|
-
for coll in collections[:3]:
|
|
35
|
-
try:
|
|
36
|
-
info = client.get_collection(coll)
|
|
37
|
-
suffix = "_local" if coll.endswith("_local") else "_voyage"
|
|
38
|
-
print(f" - {coll}: {info.points_count} points ({suffix})")
|
|
39
|
-
except:
|
|
40
|
-
print(f" - {coll}: <error getting info>")
|
|
41
|
-
else:
|
|
42
|
-
print(" - No collections found!")
|
|
43
|
-
print()
|
|
44
|
-
|
|
45
|
-
# Also test the normalization directly
|
|
46
|
-
print("\n=== Testing Direct Normalization ===")
|
|
47
|
-
from shared.normalization import normalize_project_name
|
|
48
|
-
import hashlib
|
|
49
|
-
|
|
50
|
-
test_paths = [
|
|
51
|
-
str(Path.home() / "projects" / "claude-self-reflect"),
|
|
52
|
-
str(Path.home() / "projects" / "memento"),
|
|
53
|
-
str(Path.home() / "projects" / "cc-enhance")
|
|
54
|
-
]
|
|
55
|
-
|
|
56
|
-
for path in test_paths:
|
|
57
|
-
normalized = normalize_project_name(path)
|
|
58
|
-
name_hash = hashlib.md5(normalized.encode()).hexdigest()[:8]
|
|
59
|
-
collection_local = f"conv_{name_hash}_local"
|
|
60
|
-
collection_voyage = f"conv_{name_hash}_voyage"
|
|
61
|
-
|
|
62
|
-
print(f"Path: {path}")
|
|
63
|
-
print(f" Normalized: {normalized}")
|
|
64
|
-
print(f" Hash: {name_hash}")
|
|
65
|
-
print(f" Expected collections:")
|
|
66
|
-
print(f" - {collection_local}")
|
|
67
|
-
print(f" - {collection_voyage}")
|
|
68
|
-
|
|
69
|
-
# Check if these exist
|
|
70
|
-
all_collections = [c.name for c in client.get_collections().collections]
|
|
71
|
-
if collection_local in all_collections:
|
|
72
|
-
info = client.get_collection(collection_local)
|
|
73
|
-
print(f" ✓ {collection_local} exists with {info.points_count} points")
|
|
74
|
-
else:
|
|
75
|
-
print(f" ✗ {collection_local} not found")
|
|
76
|
-
|
|
77
|
-
if collection_voyage in all_collections:
|
|
78
|
-
info = client.get_collection(collection_voyage)
|
|
79
|
-
print(f" ✓ {collection_voyage} exists with {info.points_count} points")
|
|
80
|
-
else:
|
|
81
|
-
print(f" ✗ {collection_voyage} not found")
|
|
82
|
-
print()
|
|
@@ -1,135 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env python3
|
|
2
|
-
"""
|
|
3
|
-
Debug script for testing temporal tools in Claude Self Reflect.
|
|
4
|
-
This script directly tests the temporal tools that should be available via MCP.
|
|
5
|
-
"""
|
|
6
|
-
|
|
7
|
-
import os
|
|
8
|
-
import sys
|
|
9
|
-
import asyncio
|
|
10
|
-
import json
|
|
11
|
-
import traceback
|
|
12
|
-
from pathlib import Path
|
|
13
|
-
|
|
14
|
-
# Add the mcp-server source to Python path
|
|
15
|
-
sys.path.append(str(Path(__file__).parent.parent / "mcp-server" / "src"))
|
|
16
|
-
|
|
17
|
-
os.environ["QDRANT_URL"] = "http://localhost:6333"
|
|
18
|
-
|
|
19
|
-
async def test_temporal_tools():
|
|
20
|
-
"""Test all temporal tools."""
|
|
21
|
-
print("=== TEMPORAL TOOLS DEBUG SCRIPT ===")
|
|
22
|
-
|
|
23
|
-
try:
|
|
24
|
-
# Import required modules
|
|
25
|
-
from server import (
|
|
26
|
-
get_recent_work, search_by_recency, get_timeline,
|
|
27
|
-
get_all_collections, QDRANT_URL
|
|
28
|
-
)
|
|
29
|
-
from fastmcp import Context
|
|
30
|
-
|
|
31
|
-
print(f"✅ Successfully imported temporal tools")
|
|
32
|
-
print(f"✅ Qdrant URL: {QDRANT_URL}")
|
|
33
|
-
|
|
34
|
-
# Check if Qdrant is available
|
|
35
|
-
collections = await get_all_collections()
|
|
36
|
-
print(f"✅ Found {len(collections)} collections: {collections[:5]}...")
|
|
37
|
-
|
|
38
|
-
# Create a mock context for testing
|
|
39
|
-
class MockContext(Context):
|
|
40
|
-
def __init__(self):
|
|
41
|
-
pass
|
|
42
|
-
async def debug(self, message):
|
|
43
|
-
print(f"DEBUG: {message}")
|
|
44
|
-
async def error(self, message):
|
|
45
|
-
print(f"ERROR: {message}")
|
|
46
|
-
|
|
47
|
-
ctx = MockContext()
|
|
48
|
-
|
|
49
|
-
# Test 1: get_recent_work with default parameters
|
|
50
|
-
print("\n--- Test 1: get_recent_work (default) ---")
|
|
51
|
-
try:
|
|
52
|
-
result = await get_recent_work(ctx)
|
|
53
|
-
print(f"✅ get_recent_work succeeded")
|
|
54
|
-
print(f"Result length: {len(result) if result else 0} characters")
|
|
55
|
-
if result and len(result) < 500:
|
|
56
|
-
print(f"Result: {result}")
|
|
57
|
-
except Exception as e:
|
|
58
|
-
print(f"❌ get_recent_work failed: {e}")
|
|
59
|
-
traceback.print_exc()
|
|
60
|
-
|
|
61
|
-
# Test 2: get_recent_work with project='all'
|
|
62
|
-
print("\n--- Test 2: get_recent_work (project=all) ---")
|
|
63
|
-
try:
|
|
64
|
-
result = await get_recent_work(ctx, project="all", limit=5)
|
|
65
|
-
print(f"✅ get_recent_work (project=all) succeeded")
|
|
66
|
-
print(f"Result length: {len(result) if result else 0} characters")
|
|
67
|
-
except Exception as e:
|
|
68
|
-
print(f"❌ get_recent_work (project=all) failed: {e}")
|
|
69
|
-
traceback.print_exc()
|
|
70
|
-
|
|
71
|
-
# Test 3: get_recent_work with different group_by options
|
|
72
|
-
for group_by in ["conversation", "day", "session"]:
|
|
73
|
-
print(f"\n--- Test 3.{group_by}: get_recent_work (group_by={group_by}) ---")
|
|
74
|
-
try:
|
|
75
|
-
result = await get_recent_work(ctx, limit=3, group_by=group_by)
|
|
76
|
-
print(f"✅ get_recent_work (group_by={group_by}) succeeded")
|
|
77
|
-
print(f"Result length: {len(result) if result else 0} characters")
|
|
78
|
-
except Exception as e:
|
|
79
|
-
print(f"❌ get_recent_work (group_by={group_by}) failed: {e}")
|
|
80
|
-
traceback.print_exc()
|
|
81
|
-
|
|
82
|
-
# Test 4: search_by_recency with time_range
|
|
83
|
-
print("\n--- Test 4: search_by_recency (time_range) ---")
|
|
84
|
-
try:
|
|
85
|
-
result = await search_by_recency(
|
|
86
|
-
ctx,
|
|
87
|
-
query="testing debugging",
|
|
88
|
-
time_range="last week",
|
|
89
|
-
limit=5
|
|
90
|
-
)
|
|
91
|
-
print(f"✅ search_by_recency (time_range) succeeded")
|
|
92
|
-
print(f"Result length: {len(result) if result else 0} characters")
|
|
93
|
-
except Exception as e:
|
|
94
|
-
print(f"❌ search_by_recency (time_range) failed: {e}")
|
|
95
|
-
traceback.print_exc()
|
|
96
|
-
|
|
97
|
-
# Test 5: search_by_recency with since/until
|
|
98
|
-
print("\n--- Test 5: search_by_recency (since/until) ---")
|
|
99
|
-
try:
|
|
100
|
-
result = await search_by_recency(
|
|
101
|
-
ctx,
|
|
102
|
-
query="python script",
|
|
103
|
-
since="yesterday",
|
|
104
|
-
limit=3
|
|
105
|
-
)
|
|
106
|
-
print(f"✅ search_by_recency (since/until) succeeded")
|
|
107
|
-
print(f"Result length: {len(result) if result else 0} characters")
|
|
108
|
-
except Exception as e:
|
|
109
|
-
print(f"❌ search_by_recency (since/until) failed: {e}")
|
|
110
|
-
traceback.print_exc()
|
|
111
|
-
|
|
112
|
-
# Test 6: get_timeline with different granularities
|
|
113
|
-
for granularity in ["day", "week"]:
|
|
114
|
-
print(f"\n--- Test 6.{granularity}: get_timeline (granularity={granularity}) ---")
|
|
115
|
-
try:
|
|
116
|
-
result = await get_timeline(
|
|
117
|
-
ctx,
|
|
118
|
-
time_range="last week",
|
|
119
|
-
granularity=granularity,
|
|
120
|
-
include_stats=True
|
|
121
|
-
)
|
|
122
|
-
print(f"✅ get_timeline (granularity={granularity}) succeeded")
|
|
123
|
-
print(f"Result length: {len(result) if result else 0} characters")
|
|
124
|
-
except Exception as e:
|
|
125
|
-
print(f"❌ get_timeline (granularity={granularity}) failed: {e}")
|
|
126
|
-
traceback.print_exc()
|
|
127
|
-
|
|
128
|
-
print("\n=== TEMPORAL TOOLS TEST COMPLETE ===")
|
|
129
|
-
|
|
130
|
-
except Exception as e:
|
|
131
|
-
print(f"❌ Critical error during setup: {e}")
|
|
132
|
-
traceback.print_exc()
|
|
133
|
-
|
|
134
|
-
if __name__ == "__main__":
|
|
135
|
-
asyncio.run(test_temporal_tools())
|