File size: 10,333 Bytes
22be9ef
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
from typing import Any, Optional
from smolagents.tools import Tool
import os
import requests

class GetVisaRequirementsTool(Tool):
    name = "get_visa_requirements"
    description = "Checks visa requirements for traveling to a destination."
    inputs = {
        'nationality': {'type': 'string', 'description': "Traveler's passport country (e.g., 'US', 'UK', 'Canada')"},
        'destination': {'type': 'string', 'description': "Country to visit (e.g., 'Japan', 'France', 'Brazil')"}
    }
    output_type = "string"

    def __init__(self, api_key=None):
        super().__init__()
        # You can set an API key for a real visa API service
        self.api_key = api_key or os.environ.get("VISA_API_KEY")
        
        # Map of common country names to their normalized forms
        self.country_mapping = {
            "us": "united states", "usa": "united states", "united states of america": "united states",
            "uk": "united kingdom", "britain": "united kingdom", "great britain": "united kingdom",
            "uae": "united arab emirates", "emirates": "united arab emirates",
            "china": "china", "prc": "china",
            "japan": "japan", 
            "korea": "south korea", "south korea": "south korea", "republic of korea": "south korea",
            "india": "india",
            "germany": "germany",
            "france": "france",
            "italy": "italy",
            "spain": "spain",
            "mexico": "mexico",
            "brazil": "brazil",
            "australia": "australia", "aus": "australia",
            "new zealand": "new zealand", "nz": "new zealand",
            "canada": "canada", "can": "canada",
            "russia": "russia", "russian federation": "russia",
            "south africa": "south africa", "sa": "south africa",
            "thailand": "thailand",
            "vietnam": "vietnam",
            "indonesia": "indonesia",
            "malaysia": "malaysia",
            "philippines": "philippines", "ph": "philippines",
            "singapore": "singapore", "sg": "singapore",
            "egypt": "egypt",
            "turkey": "turkey", "türkiye": "turkey"
        }
        
        # Sample visa requirement data for frequently traveled routes
        self.visa_data = {
            "united states": {
                "european union": "No visa required for stays up to 90 days in the Schengen Area",
                "united kingdom": "No visa required for stays up to 6 months",
                "japan": "No visa required for stays up to 90 days",
                "australia": "Electronic Travel Authority (ETA) required",
                "china": "Visa required, must apply in advance",
                "india": "e-Visa available, apply online before travel",
                "brazil": "No visa required for stays up to 90 days",
                "mexico": "No visa required for stays up to 180 days",
                "south africa": "No visa required for stays up to 90 days",
                "thailand": "No visa required for stays up to 30 days",
                "canada": "No visa required for US citizens"
            },
            "united kingdom": {
                "european union": "No visa required for stays up to 90 days in the Schengen Area",
                "united states": "ESTA required for entry",
                "japan": "No visa required for stays up to 90 days",
                "australia": "eVisitor visa required",
                "china": "Visa required, must apply in advance",
                "india": "e-Visa available, apply online before travel",
                "brazil": "No visa required for stays up to 90 days",
                "mexico": "No visa required for stays up to 180 days",
                "south africa": "No visa required for stays up to 90 days",
                "thailand": "No visa required for stays up to 30 days",
                "canada": "eTA required for British citizens"
            },
            "canada": {
                "european union": "No visa required for stays up to 90 days in the Schengen Area",
                "united states": "No visa required for Canadian citizens",
                "japan": "No visa required for stays up to 90 days",
                "australia": "eVisitor visa required",
                "china": "Visa required, must apply in advance",
                "india": "e-Visa available, apply online before travel",
                "brazil": "No visa required for stays up to 90 days",
                "mexico": "No visa required for stays up to 180 days",
                "south africa": "No visa required for stays up to 90 days",
                "thailand": "No visa required for stays up to 30 days",
                "united kingdom": "No visa required for stays up to 6 months"
            },
            "japan": {
                "european union": "No visa required for stays up to 90 days in the Schengen Area",
                "united states": "ESTA required for entry",
                "australia": "eVisitor visa required",
                "china": "Visa required, must apply in advance",
                "india": "e-Visa available, apply online before travel",
                "brazil": "Visa required for Japanese citizens",
                "mexico": "No visa required for stays up to 180 days",
                "south africa": "No visa required for stays up to 90 days",
                "thailand": "No visa required for stays up to 30 days",
                "united kingdom": "No visa required for stays up to 6 months",
                "canada": "eTA required for Japanese citizens"
            },
            "australia": {
                "european union": "No visa required for stays up to 90 days in the Schengen Area",
                "united states": "ESTA required for entry",
                "japan": "No visa required for stays up to 90 days",
                "china": "Visa required, must apply in advance",
                "india": "e-Visa available, apply online before travel",
                "brazil": "Visa required for Australian citizens",
                "mexico": "No visa required for stays up to 180 days",
                "south africa": "No visa required for stays up to 90 days",
                "thailand": "No visa required for stays up to 30 days",
                "united kingdom": "No visa required for stays up to 6 months",
                "canada": "eTA required for Australian citizens"
            }
        }

    def forward(self, nationality: str, destination: str) -> str:
        try:
            # Normalize inputs
            nationality = nationality.lower().strip()
            destination = destination.lower().strip()
            
            # Apply mappings if available
            nationality = self.country_mapping.get(nationality, nationality)
            destination = self.country_mapping.get(destination, destination)
            
            # Try to use a real visa API if the API key is available
            if self.api_key:
                try:
                    # This would be the API call in a real implementation
                    # For now, we'll fall back to stored data
                    pass
                except:
                    # Fall back to stored data if API call fails
                    return self._check_with_stored_data(nationality, destination)
            
            # If no API key is available, use the stored data
            return self._check_with_stored_data(nationality, destination)
        
        except Exception as e:
            return f"Error retrieving visa information: {str(e)}"
    
    def _check_with_stored_data(self, nationality: str, destination: str) -> str:
        # Skip if same country (generally no visa needed for citizens)
        if nationality == destination:
            return f"As a citizen of {nationality.title()}, you generally don't need a visa to visit your own country."
        
        # Check if we have data for this nationality
        if nationality not in self.visa_data:
            # Try to search web for information if available
            try:
                import importlib
                if importlib.util.find_spec("duckduckgo_search"):
                    from duckduckgo_search import DDGS
                    ddgs = DDGS()
                    results = ddgs.text(f"visa requirements for {nationality} citizens traveling to {destination}")
                    if results:
                        return f"Based on web search, for {nationality.title()} citizens traveling to {destination.title()}: {results[0]['body']}\n\n(Note: Always verify visa requirements with the official embassy or consulate before travel.)"
            except:
                pass
                
            return f"I don't have specific visa information for citizens of {nationality.title()}. Please check with the embassy of {destination.title()} for accurate visa requirements."
        
        # Check if we have data for this destination
        if destination not in self.visa_data[nationality]:
            # Try to search web for information if available
            try:
                import importlib
                if importlib.util.find_spec("duckduckgo_search"):
                    from duckduckgo_search import DDGS
                    ddgs = DDGS()
                    results = ddgs.text(f"visa requirements for {nationality} citizens traveling to {destination}")
                    if results:
                        return f"Based on web search, for {nationality.title()} citizens traveling to {destination.title()}: {results[0]['body']}\n\n(Note: Always verify visa requirements with the official embassy or consulate before travel.)"
            except:
                pass
                
            return f"I don't have specific visa information for {nationality.title()} citizens traveling to {destination.title()}. Please check with the embassy of {destination.title()} for accurate visa requirements."
        
        # Get the visa requirements
        requirements = self.visa_data[nationality][destination]
        
        return f"🛂 Visa requirements for {nationality.title()} citizens traveling to {destination.title()}:\n\n{requirements}\n\n(Note: Visa requirements may change. Always verify with the official embassy or consulate before travel.)"