| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265 |
- #!/usr/bin/env python3
- """
- Diagnostic script to test content serialization and identify the exact issue
- """
- import subprocess
- import json
- import sys
- import os
- import tempfile
- def test_content_serialization():
- """Test content serialization by creating a simple test case"""
-
- # Create a test JSON that matches what the server should send
- test_prompt_response = {
- "jsonrpc": "2.0",
- "id": 2,
- "result": {
- "description": "Test prompt",
- "messages": [
- {
- "role": "user",
- "content": {
- "type": "text",
- "text": "Hello, world!"
- }
- },
- {
- "role": "assistant",
- "content": {
- "type": "image",
- "data": "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg==",
- "mimeType": "image/png"
- }
- },
- {
- "role": "user",
- "content": {
- "type": "resource",
- "resource": {
- "uri": "file:///example.txt",
- "text": "This is a test resource"
- }
- }
- }
- ]
- }
- }
-
- print("Testing JSON structure that should be valid:")
- print(json.dumps(test_prompt_response, indent=2))
-
- # Try to validate this against a simple schema
- try:
- # Basic validation of the structure
- result = test_prompt_response["result"]
- messages = result["messages"]
-
- for i, message in enumerate(messages):
- content = message["content"]
- content_type = content["type"]
-
- print(f"\nMessage {i} - Type: {content_type}")
-
- if content_type == "text":
- if "text" not in content:
- print(f" ✗ Missing 'text' field")
- else:
- print(f" ✓ Has 'text' field")
-
- elif content_type in ["image", "audio"]:
- if "data" not in content:
- print(f" ✗ Missing 'data' field")
- else:
- print(f" ✓ Has 'data' field")
-
- if "mimeType" not in content:
- print(f" ✗ Missing 'mimeType' field")
- else:
- print(f" ✓ Has 'mimeType' field: {content['mimeType']}")
-
- elif content_type == "resource":
- if "resource" not in content:
- print(f" ✗ Missing 'resource' field")
- else:
- resource = content["resource"]
- print(f" ✓ Has 'resource' field with keys: {list(resource.keys())}")
-
- if "uri" not in resource:
- print(f" ✗ Missing 'uri' in resource")
- else:
- print(f" ✓ Has 'uri': {resource['uri']}")
-
- # Check if resource has either text or blob
- has_text = "text" in resource
- has_blob = "blob" in resource
-
- if not (has_text or has_blob):
- print(f" ✗ Resource must have either 'text' or 'blob'")
- elif has_text:
- print(f" ✓ Has 'text' content")
- elif has_blob:
- print(f" ✓ Has 'blob' content")
-
- elif content_type == "resource_link":
- required_fields = ["name", "uri"]
- for field in required_fields:
- if field not in content:
- print(f" ✗ Missing '{field}' field")
- else:
- print(f" ✓ Has '{field}': {content[field]}")
-
- print("\n✓ Basic structure validation passed")
- return True
-
- except Exception as e:
- print(f"\n✗ Validation failed: {e}")
- import traceback
- traceback.print_exc()
- return False
- def test_server_response():
- """Test actual server response if available"""
- if len(sys.argv) != 2:
- print("Usage: python3 diagnose_serialization.py <server-executable>")
- return False
-
- server_path = sys.argv[1]
- if not os.path.exists(server_path):
- print(f"Error: Server executable '{server_path}' not found")
- return False
-
- print(f"\n{'='*60}")
- print(f"Testing server: {server_path}")
- print(f"{'='*60}")
-
- # Test the expected structure first
- if not test_content_serialization():
- print("✗ Basic structure validation failed")
- return False
-
- # Try to test the actual server
- try:
- # Create a simple test script
- test_script = '''
- import json
- import sys
- import subprocess
- # Start the server
- proc = subprocess.Popen([sys.argv[1]],
- stdin=subprocess.PIPE,
- stdout=subprocess.PIPE,
- stderr=subprocess.PIPE,
- text=False)
- # Send initialize
- init_msg = {
- "jsonrpc": "2.0",
- "method": "initialize",
- "id": 0,
- "params": {
- "protocolVersion": "2025-11-25",
- "capabilities": {},
- "clientInfo": {"name": "test", "version": "1.0.0"}
- }
- }
- msg_str = json.dumps(init_msg)
- proc.stdin.write(f"Content-Length: {len(msg_str)}\\r\\n\\r\\n{msg_str}".encode())
- proc.stdin.flush()
- # Read init response
- line = proc.stdout.readline()
- if line.startswith(b"Content-Length:"):
- length = int(line.decode().split(":")[1].strip())
- proc.stdout.readline() # empty line
- data = proc.stdout.read(length)
- response = json.loads(data.decode())
- print("Init response:", "success" if "result" in response else "failed")
- # List prompts
- list_msg = {"jsonrpc": "2.0", "method": "prompts/list", "id": 1, "params": {}}
- msg_str = json.dumps(list_msg)
- proc.stdin.write(f"Content-Length: {len(msg_str)}\\r\\n\\r\\n{msg_str}".encode())
- proc.stdin.flush()
- # Read list response
- line = proc.stdout.readline()
- if line.startswith(b"Content-Length:"):
- length = int(line.decode().split(":")[1].strip())
- proc.stdout.readline() # empty line
- data = proc.stdout.read(length)
- response = json.loads(data.decode())
-
- if "result" in response and "prompts" in response["result"]:
- prompts = response["result"]["prompts"]
- print(f"Found {len(prompts)} prompts")
-
- if prompts:
- # Get first prompt
- get_msg = {"jsonrpc": "2.0", "method": "prompts/get", "id": 2,
- "params": {"name": prompts[0]["name"]}}
- msg_str = json.dumps(get_msg)
- proc.stdin.write(f"Content-Length: {len(msg_str)}\\r\\n\\r\\n{msg_str}".encode())
- proc.stdin.flush()
-
- # Read get response
- line = proc.stdout.readline()
- if line.startswith(b"Content-Length:"):
- length = int(line.decode().split(":")[1].strip())
- proc.stdout.readline() # empty line
- data = proc.stdout.read(length)
- response = json.loads(data.decode())
-
- if "result" in response:
- print("✓ Got prompt result")
- result = response["result"]
- print(json.dumps(result, indent=2))
- elif "error" in response:
- print("✗ Got error:")
- print(json.dumps(response["error"], indent=2))
- else:
- print("✗ No result or error in response")
- proc.terminate()
- '''
-
- # Write test script to temp file
- with tempfile.NamedTemporaryFile(mode='w', suffix='.py', delete=False) as f:
- f.write(test_script)
- temp_script = f.name
-
- # Run the test
- result = subprocess.run([sys.executable, temp_script, server_path],
- capture_output=True, text=True, timeout=10)
-
- print("Server test output:")
- print(result.stdout)
- if result.stderr:
- print("Server test errors:")
- print(result.stderr)
-
- # Clean up
- os.unlink(temp_script)
-
- return result.returncode == 0
-
- except subprocess.TimeoutExpired:
- print("✗ Server test timed out")
- return False
- except Exception as e:
- print(f"✗ Server test failed: {e}")
- import traceback
- traceback.print_exc()
- return False
- if __name__ == "__main__":
- if len(sys.argv) == 2:
- success = test_server_response()
- else:
- success = test_content_serialization()
-
- sys.exit(0 if success else 1)
|