Charles Grandjean commited on
Commit
8cc8e89
·
1 Parent(s): ed3da7d

solve tests

Browse files
tests/test_bug_fixes.py CHANGED
@@ -1,4 +1,4 @@
1
- #!/usr/bin/env python3
2
  """
3
  Test script to verify bug fixes for document editor tools
4
  Tests that:
@@ -20,7 +20,7 @@ def test_internal_functions_exist():
20
  print("TEST 1: Internal Functions Exist and Have __name__")
21
  print("=" * 80)
22
 
23
- from utils.doc_editor_tools import (
24
  _replace_html, _add_html, _delete_html, _inspect_document, _attempt_completion
25
  )
26
 
@@ -52,7 +52,7 @@ def test_tools_real_are_functions():
52
 
53
  # Import agent - this will fail if tools_real has StructuredTools
54
  try:
55
- from subagents.doc_editor import DocumentEditorAgent
56
 
57
  # We need a mock LLM to initialize
58
  class MockLLM:
@@ -95,7 +95,7 @@ def test_workflow_builds():
95
  print("=" * 80)
96
 
97
  try:
98
- from subagents.doc_editor import DocumentEditorAgent
99
 
100
  class MockLLM:
101
  def bind_tools(self, tools):
@@ -127,7 +127,7 @@ def test_tools_callable():
127
  print("TEST 4: Internal Tools Are Callable")
128
  print("=" * 80)
129
 
130
- from utils.doc_editor_tools import (
131
  _replace_html, _add_html, _delete_html, _inspect_document, _attempt_completion
132
  )
133
 
 
1
+ s#!/usr/bin/env python3
2
  """
3
  Test script to verify bug fixes for document editor tools
4
  Tests that:
 
20
  print("TEST 1: Internal Functions Exist and Have __name__")
21
  print("=" * 80)
22
 
23
+ from utils.editor_tools import (
24
  _replace_html, _add_html, _delete_html, _inspect_document, _attempt_completion
25
  )
26
 
 
52
 
53
  # Import agent - this will fail if tools_real has StructuredTools
54
  try:
55
+ from agents.doc_editor import DocumentEditorAgent
56
 
57
  # We need a mock LLM to initialize
58
  class MockLLM:
 
95
  print("=" * 80)
96
 
97
  try:
98
+ from agents.doc_editor import DocumentEditorAgent
99
 
100
  class MockLLM:
101
  def bind_tools(self, tools):
 
127
  print("TEST 4: Internal Tools Are Callable")
128
  print("=" * 80)
129
 
130
+ from utils.editor_tools import (
131
  _replace_html, _add_html, _delete_html, _inspect_document, _attempt_completion
132
  )
133
 
tests/test_create_draft_document.py ADDED
@@ -0,0 +1,148 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ """
3
+ Test script for create_draft_document tool
4
+ """
5
+
6
+ import asyncio
7
+ import os
8
+ import sys
9
+ from pathlib import Path
10
+
11
+ # Add parent directory to path
12
+ sys.path.insert(0, str(Path(__file__).parent.parent))
13
+
14
+ from utils.tools import create_draft_document, _create_draft_document
15
+
16
+
17
+ async def test_tool_facade():
18
+ """Test the facade version of the tool"""
19
+ print("🧪 Testing create_draft_document (facade)...")
20
+
21
+ # This should return immediately (facade just returns)
22
+ result = await create_draft_document.ainvoke({
23
+ "title": "Test Document",
24
+ "content": "<h1>Test</h1><p>This is a test document</p>",
25
+ "path": "Test/"
26
+ })
27
+
28
+ print(f"✅ Facade test passed: {result}")
29
+ return result
30
+
31
+
32
+ async def test_tool_real():
33
+ """Test the real implementation of the tool"""
34
+ print("\n🧪 Testing _create_draft_document (real implementation)...")
35
+
36
+ # Mock user_id
37
+ test_user_id = os.getenv("TEST_USER_ID", "test-user-uuid-123")
38
+
39
+ # Test with various paths
40
+ test_cases = [
41
+ {
42
+ "title": "Contract de bail",
43
+ "content": "<h1>Contrat de bail</h1><p>Ce contrat est conclu entre...</p>",
44
+ "path": "Contracts/",
45
+ "expected_path": "./Contracts/Contract de bail.pdf"
46
+ },
47
+ {
48
+ "title": "Mon document",
49
+ "content": "<h1>Document</h1><p>Contenu...</p>",
50
+ "path": "",
51
+ "expected_path": "./Mon document.pdf"
52
+ },
53
+ {
54
+ "title": "Note juridique",
55
+ "content": "<h1>Note</h1><p>Contenu juridique...</p>",
56
+ "path": "Drafts/Legal/",
57
+ "expected_path": "./Drafts/Legal/Note juridique.pdf"
58
+ }
59
+ ]
60
+
61
+ for i, test_case in enumerate(test_cases, 1):
62
+ print(f"\n Test case {i}: {test_case['title']}")
63
+ print(f" Path: {test_case['path']}")
64
+ print(f" Expected: {test_case['expected_path']}")
65
+
66
+ result = await _create_draft_document.ainvoke({
67
+ "user_id": test_user_id,
68
+ "title": test_case["title"],
69
+ "content": test_case["content"],
70
+ "path": test_case["path"]
71
+ })
72
+
73
+ print(f" Result: {result}")
74
+
75
+ # Check if the path is correct in the result
76
+ if test_case["expected_path"] in result:
77
+ print(f" ✅ Path is correct")
78
+ else:
79
+ print(f" ⚠️ Expected path not found in result")
80
+
81
+ print("\n✅ Real implementation test completed")
82
+ return True
83
+
84
+
85
+ async def test_path_normalization():
86
+ """Test path normalization logic"""
87
+ print("\n🧪 Testing path normalization...")
88
+
89
+ test_cases = [
90
+ ("Contracts/", "./Contracts/"),
91
+ ("Contracts", "./Contracts/"),
92
+ ("", "./"),
93
+ ("./Contracts/", "./Contracts/"),
94
+ ("Drafts/Legal/", "./Drafts/Legal/"),
95
+ ("./Drafts/Legal", "./Drafts/Legal/")
96
+ ]
97
+
98
+ for input_path, expected_suffix in test_cases:
99
+ # Simulate the path normalization logic
100
+ path = input_path
101
+ if path:
102
+ if path.startswith('./'):
103
+ path = path[2:]
104
+ if not path.endswith('/'):
105
+ path += '/'
106
+ else:
107
+ path = ''
108
+
109
+ full_path = f"./{path}Test.pdf"
110
+
111
+ print(f" Input: '{input_path}' → Output: '{full_path}'")
112
+ if full_path.startswith(expected_suffix):
113
+ print(f" ✅ Correct")
114
+ else:
115
+ print(f" ⚠️ Expected to start with: {expected_suffix}")
116
+
117
+ print("\n✅ Path normalization test completed")
118
+ return True
119
+
120
+
121
+ async def main():
122
+ """Run all tests"""
123
+ print("=" * 80)
124
+ print("🚀 Testing create_draft_document tool")
125
+ print("=" * 80)
126
+
127
+ try:
128
+ # Test facade
129
+ await test_tool_facade()
130
+
131
+ # Test real implementation
132
+ await test_tool_real()
133
+
134
+ # Test path normalization
135
+ await test_path_normalization()
136
+
137
+ print("\n" + "=" * 80)
138
+ print("✅ All tests completed successfully!")
139
+ print("=" * 80)
140
+
141
+ except Exception as e:
142
+ print(f"\n❌ Test failed with error: {str(e)}")
143
+ import traceback
144
+ traceback.print_exc()
145
+
146
+
147
+ if __name__ == "__main__":
148
+ asyncio.run(main())
tests/test_doc_creator_endpoint.py CHANGED
@@ -17,7 +17,7 @@ load_dotenv(dotenv_path=".env", override=False)
17
  sys.path.insert(0, str(Path(__file__).parent.parent))
18
 
19
  from structured_outputs.api_models import DocCreatorRequest, DocCreatorResponse, Message
20
- from subagents.doc_editor import DocumentEditorAgent
21
  from langchain_openai import ChatOpenAI
22
 
23
 
 
17
  sys.path.insert(0, str(Path(__file__).parent.parent))
18
 
19
  from structured_outputs.api_models import DocCreatorRequest, DocCreatorResponse, Message
20
+ from agents.doc_editor import DocumentEditorAgent
21
  from langchain_openai import ChatOpenAI
22
 
23
 
tests/test_doc_editor.py CHANGED
@@ -16,7 +16,7 @@ load_dotenv()
16
  sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..')))
17
 
18
  from langchain_openai import ChatOpenAI
19
- from subagents.doc_editor import DocumentEditorAgent
20
 
21
 
22
  # Example HTML document - Service Contract
@@ -80,7 +80,7 @@ async def test_document_editor():
80
  )
81
 
82
  # Initialize document editor agent
83
- doc_editor = DocumentEditorAgent(llm=llm)
84
 
85
  print("=" * 80)
86
  print("📄 ORIGINAL DOCUMENT (HTML)")
@@ -139,7 +139,7 @@ async def test_document_editor():
139
 
140
  async def test_tools_directly():
141
  """Test document editor tools directly without the agent."""
142
- from utils.doc_editor_tools import replace_html, add_html, delete_html, inspect_document, attempt_completion
143
 
144
  print("=" * 80)
145
  print("🔧 TESTING TOOLS DIRECTLY")
@@ -192,14 +192,13 @@ async def test_tools_directly():
192
  else:
193
  print(f"❌ Delete failed: {result['error']}")
194
 
195
- print("\n4️⃣ Testing 'inspect_document' tool...")
196
- # Note: In direct testing, we can pass doc_text for backward compatibility
197
- # But in agent mode, it will be called without arguments
198
- result = await inspect_document.ainvoke({"doc_text": current_doc})
199
  if result['ok']:
200
- print(f"✅ inspect_document works! Document size: {len(result['content'])} bytes")
201
  else:
202
- print(f"❌ inspect_document failed")
203
 
204
  print("\n5️⃣ Final document after tool tests:")
205
  print(current_doc)
 
16
  sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..')))
17
 
18
  from langchain_openai import ChatOpenAI
19
+ from agents.doc_editor import DocumentEditorAgent
20
 
21
 
22
  # Example HTML document - Service Contract
 
80
  )
81
 
82
  # Initialize document editor agent
83
+ doc_editor = DocumentEditorAgent(llm=llm, llm_tool_calling=llm)
84
 
85
  print("=" * 80)
86
  print("📄 ORIGINAL DOCUMENT (HTML)")
 
139
 
140
  async def test_tools_directly():
141
  """Test document editor tools directly without the agent."""
142
+ from utils.editor_tools import replace_html, add_html, delete_html, view_current_document, attempt_completion
143
 
144
  print("=" * 80)
145
  print("🔧 TESTING TOOLS DIRECTLY")
 
192
  else:
193
  print(f"❌ Delete failed: {result['error']}")
194
 
195
+ print("\n4️⃣ Testing 'view_current_document' tool...")
196
+ # Note: The tool now has no parameters - document is injected by the workflow
197
+ result = await view_current_document.ainvoke()
 
198
  if result['ok']:
199
+ print(f"✅ view_current_document works!")
200
  else:
201
+ print(f"❌ view_current_document failed")
202
 
203
  print("\n5️⃣ Final document after tool tests:")
204
  print(current_doc)
tests/test_fake_inspect_doc.py ADDED
@@ -0,0 +1,107 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ """
3
+ Test pour vérifier que le faux view_current_document initial fonctionne
4
+ """
5
+
6
+ import asyncio
7
+ import os
8
+ import sys
9
+ from dotenv import load_dotenv
10
+
11
+ # Load environment variables
12
+ load_dotenv()
13
+
14
+ # Add parent directory to path
15
+ sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..')))
16
+
17
+ from langchain_openai import ChatOpenAI
18
+ from agents.doc_editor import DocumentEditorAgent
19
+
20
+
21
+ # Simple HTML document
22
+ TEST_HTML = """<!DOCTYPE html>
23
+ <html>
24
+ <head>
25
+ <title>Test Document</title>
26
+ </head>
27
+ <body>
28
+ <h1>Test Contract</h1>
29
+ <p>This is a test paragraph with some text.</p>
30
+ </body>
31
+ </html>"""
32
+
33
+
34
+ async def test_fake_view_current_document():
35
+ """
36
+ Test que le document est fourni via un faux view_current_document au démarrage.
37
+ L'agent devrait pouvoir faire des modifications sans appeler view_current_document.
38
+ """
39
+
40
+ # Initialize LLMs
41
+ api_key = os.getenv("OPENAI_API_KEY") or os.getenv("CEREBRAS_API_KEY")
42
+ if not api_key:
43
+ print("❌ Error: OPENAI_API_KEY or CEREBRAS_API_KEY environment variable not set")
44
+ return
45
+
46
+ # Pour les tests, on peut utiliser le même LLM pour les deux
47
+ llm_summary = ChatOpenAI(
48
+ model=os.getenv("LLM_MODEL", "gpt-4o-mini"),
49
+ temperature=0,
50
+ api_key=api_key,
51
+ base_url=os.getenv("OPENAI_API_BASE", None)
52
+ )
53
+
54
+ llm_tool_calling = ChatOpenAI(
55
+ model=os.getenv("LLM_MODEL", "gpt-4o-mini"),
56
+ temperature=0,
57
+ api_key=api_key,
58
+ base_url=os.getenv("OPENAI_API_BASE", None)
59
+ )
60
+
61
+ # Initialize document editor agent avec les deux LLMs
62
+ doc_editor = DocumentEditorAgent(llm=llm_summary, llm_tool_calling=llm_tool_calling)
63
+
64
+ print("=" * 80)
65
+ print("🔧 TEST: Fake view_current_document initial")
66
+ print("=" * 80)
67
+ print("\n📄 DOCUMENT ORIGINAL:")
68
+ print(TEST_HTML)
69
+ print()
70
+
71
+ # Test simple: changer "test paragraph" en "modified paragraph"
72
+ print("=" * 80)
73
+ print("🔧 INSTRUCTION: Change 'test paragraph' to 'modified paragraph'")
74
+ print("=" * 80)
75
+
76
+ result = await doc_editor.edit_document(
77
+ doc_text=TEST_HTML,
78
+ user_instruction="Change the text 'test paragraph' to 'modified paragraph'",
79
+ max_iterations=5
80
+ )
81
+
82
+ print(f"\n✅ Success: {result['success']}")
83
+ print(f"📝 Message: {result['message']}")
84
+ print(f"🔄 Iterations: {result['iteration_count']}")
85
+
86
+ if result['success']:
87
+ print("\n📄 DOCUMENT MODIFIÉ:")
88
+ print(result['doc_text'])
89
+
90
+ # Vérifier que le texte a été modifié
91
+ if "modified paragraph" in result['doc_text']:
92
+ print("\n✅ VERIFICATION PASSED: Texte modifié avec succès!")
93
+ else:
94
+ print("\n❌ VERIFICATION FAILED: Le texte n'a pas été modifié")
95
+ else:
96
+ print("\n❌ ERREUR: L'édition a échoué")
97
+ print(result.get('error', 'No error details'))
98
+
99
+ print("\n" + "=" * 80)
100
+ print("🎯 POINT CLÉ: L'agent ne devrait PAS appeler view_current_document")
101
+ print(" car le document est déjà disponible via le faux tool call initial")
102
+ print("=" * 80)
103
+
104
+
105
+ if __name__ == "__main__":
106
+ print("🚀 Test du faux view_current_document initial\n")
107
+ asyncio.run(test_fake_view_current_document())
tests/test_gemini_tool_calling.py CHANGED
@@ -95,7 +95,7 @@ async def test_llm_config():
95
  # Test DocumentEditorAgent initialization
96
  print(f"\n🧪 Testing DocumentEditorAgent initialization...")
97
  try:
98
- from subagents.doc_editor import DocumentEditorAgent
99
 
100
  doc_editor = DocumentEditorAgent(
101
  llm=llm_config.openai_llm,
 
95
  # Test DocumentEditorAgent initialization
96
  print(f"\n🧪 Testing DocumentEditorAgent initialization...")
97
  try:
98
+ from agents.doc_editor import DocumentEditorAgent
99
 
100
  doc_editor = DocumentEditorAgent(
101
  llm=llm_config.openai_llm,
tests/test_jpg.py CHANGED
@@ -8,7 +8,7 @@ import asyncio
8
  from dotenv import load_dotenv
9
  from langchain_openai import ChatOpenAI
10
  from mistralai import Mistral
11
- from subagents.pdf_analyzer import PDFAnalyzerAgent
12
 
13
  load_dotenv()
14
 
 
8
  from dotenv import load_dotenv
9
  from langchain_openai import ChatOpenAI
10
  from mistralai import Mistral
11
+ from agents.pdf_analyzer import PDFAnalyzerAgent
12
 
13
  load_dotenv()
14
 
tests/test_logging_doc_editor.py CHANGED
@@ -14,8 +14,8 @@ from pathlib import Path
14
  # Add parent directory to path for imports
15
  sys.path.insert(0, str(Path(__file__).parent.parent))
16
 
17
- from utils.doc_editor_tools import replace, add, delete, attempt_completion
18
- from subagents.doc_editor import DocumentEditorAgent
19
  from langchain_openai import ChatOpenAI
20
 
21
  # Configure detailed logging
 
14
  # Add parent directory to path for imports
15
  sys.path.insert(0, str(Path(__file__).parent.parent))
16
 
17
+ from utils.editor_tools import replace, add, delete, attempt_completion
18
+ from agents.doc_editor import DocumentEditorAgent
19
  from langchain_openai import ChatOpenAI
20
 
21
  # Configure detailed logging
tests/test_pdf_analyzer.py CHANGED
@@ -9,7 +9,7 @@ from dotenv import load_dotenv
9
  from langchain_openai import ChatOpenAI
10
  from mistralai import Mistral
11
 
12
- from subagents.pdf_analyzer import PDFAnalyzerAgent
13
 
14
  load_dotenv()
15
 
 
9
  from langchain_openai import ChatOpenAI
10
  from mistralai import Mistral
11
 
12
+ from agents.pdf_analyzer import PDFAnalyzerAgent
13
 
14
  load_dotenv()
15
 
tests/test_tools_ainvoke.py CHANGED
@@ -10,7 +10,7 @@ import os
10
  # Add parent directory to path
11
  sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..')))
12
 
13
- from utils.doc_editor_tools import replace_html, add_html, delete_html, inspect_document, attempt_completion
14
 
15
 
16
  async def test_tool_ainvoke():
 
10
  # Add parent directory to path
11
  sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..')))
12
 
13
+ from utils.editor_tools import replace_html, add_html, delete_html, inspect_document, attempt_completion
14
 
15
 
16
  async def test_tool_ainvoke():
tests/test_update_notifier.py CHANGED
@@ -11,7 +11,7 @@ from dotenv import load_dotenv
11
  # Add parent directory to path
12
  sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..')))
13
 
14
- from utils.update_notifier import push_document_update
15
 
16
  # Load environment variables
17
  load_dotenv(dotenv_path=".env", override=False)
 
11
  # Add parent directory to path
12
  sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..')))
13
 
14
+ from utils.utils_fn import push_document_update
15
 
16
  # Load environment variables
17
  load_dotenv(dotenv_path=".env", override=False)