Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -7,6 +7,16 @@ from tools.final_answer import FinalAnswerTool
|
|
| 7 |
|
| 8 |
from Gradio_UI import GradioUI
|
| 9 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 10 |
# Below is an example of a tool that does nothing. Amaze us with your creativity !
|
| 11 |
@tool
|
| 12 |
def my_custom_tool(arg1:str, arg2:int)-> str: #it's import to specify the return type
|
|
@@ -20,70 +30,100 @@ def my_custom_tool(arg1:str, arg2:int)-> str: #it's import to specify the return
|
|
| 20 |
|
| 21 |
|
| 22 |
@tool
|
| 23 |
-
def
|
| 24 |
-
"""
|
| 25 |
-
Args:
|
| 26 |
-
book_id: The numeric ID of the book (1-12)
|
| 27 |
-
"""
|
| 28 |
try:
|
| 29 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 30 |
if response.status_code == 200:
|
| 31 |
-
|
| 32 |
-
|
| 33 |
-
|
| 34 |
-
|
| 35 |
-
|
| 36 |
-
|
| 37 |
-
|
| 38 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 39 |
except Exception as e:
|
| 40 |
-
return f"
|
| 41 |
|
| 42 |
@tool
|
| 43 |
-
def
|
| 44 |
-
"""
|
| 45 |
-
Args:
|
| 46 |
-
name: The full name of the character (e.g., 'Jon Snow')
|
| 47 |
-
"""
|
| 48 |
try:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 49 |
response = requests.get(
|
| 50 |
"https://anapioficeandfire.com/api/characters",
|
| 51 |
-
params={"name": name}
|
|
|
|
| 52 |
)
|
|
|
|
| 53 |
if response.status_code == 200:
|
| 54 |
-
|
| 55 |
-
if
|
| 56 |
-
|
| 57 |
-
|
| 58 |
-
|
| 59 |
-
|
| 60 |
-
|
| 61 |
-
|
| 62 |
-
|
| 63 |
-
|
| 64 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 65 |
except Exception as e:
|
| 66 |
-
return f"Search
|
| 67 |
|
| 68 |
@tool
|
| 69 |
-
def
|
| 70 |
-
"""
|
| 71 |
-
Args:
|
| 72 |
-
region: The region to search (e.g., 'The North', 'The Vale')
|
| 73 |
-
"""
|
| 74 |
try:
|
| 75 |
response = requests.get(
|
| 76 |
"https://anapioficeandfire.com/api/houses",
|
| 77 |
-
params={"region":
|
|
|
|
| 78 |
)
|
|
|
|
| 79 |
if response.status_code == 200:
|
| 80 |
houses = response.json()
|
| 81 |
if houses:
|
| 82 |
-
return
|
| 83 |
-
|
| 84 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 85 |
except Exception as e:
|
| 86 |
-
return f"
|
| 87 |
|
| 88 |
@tool
|
| 89 |
def get_current_time_in_timezone(timezone: str) -> str:
|
|
@@ -122,6 +162,16 @@ image_generation_tool = load_tool("agents-course/text-to-image", trust_remote_co
|
|
| 122 |
|
| 123 |
with open("prompts.yaml", 'r') as stream:
|
| 124 |
prompt_templates = yaml.safe_load(stream)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 125 |
|
| 126 |
agent = CodeAgent(
|
| 127 |
model=model,
|
|
|
|
| 7 |
|
| 8 |
from Gradio_UI import GradioUI
|
| 9 |
|
| 10 |
+
#Utility function to help refine the search and use of our api calls
|
| 11 |
+
def normalize_input(text: str) -> str:
|
| 12 |
+
return text.strip().lower().replace("'", "").replace(",", "")
|
| 13 |
+
|
| 14 |
+
def best_match(name: str, options: list) -> str:
|
| 15 |
+
matches = get_close_matches(normalize_input(name),
|
| 16 |
+
[normalize_input(o) for o in options],
|
| 17 |
+
n=1, cutoff=0.8)
|
| 18 |
+
return options[matches[0]] if matches else None
|
| 19 |
+
|
| 20 |
# Below is an example of a tool that does nothing. Amaze us with your creativity !
|
| 21 |
@tool
|
| 22 |
def my_custom_tool(arg1:str, arg2:int)-> str: #it's import to specify the return type
|
|
|
|
| 30 |
|
| 31 |
|
| 32 |
@tool
|
| 33 |
+
def asoiaf_book(query: str) -> str:
|
| 34 |
+
"""Handle book queries by ID or name. Returns JSON with {title, authors, pages, characters}"""
|
|
|
|
|
|
|
|
|
|
| 35 |
try:
|
| 36 |
+
if query.isdigit():
|
| 37 |
+
book_id = int(query)
|
| 38 |
+
response = requests.get(f"https://anapioficeandfire.com/api/books/{book_id}")
|
| 39 |
+
else:
|
| 40 |
+
response = requests.get("https://anapioficeandfire.com/api/books")
|
| 41 |
+
|
| 42 |
if response.status_code == 200:
|
| 43 |
+
books = response.json() if isinstance(response.json(), list) else [response.json()]
|
| 44 |
+
matched = next((b for b in books if normalize_input(b["name"]) == normalize_input(query)), None)
|
| 45 |
+
|
| 46 |
+
if matched:
|
| 47 |
+
return json.dumps({
|
| 48 |
+
"title": matched["name"],
|
| 49 |
+
"authors": matched["authors"],
|
| 50 |
+
"pages": matched["numberOfPages"],
|
| 51 |
+
"characters": len(matched["characters"])
|
| 52 |
+
})
|
| 53 |
+
|
| 54 |
+
return json.dumps({"error": f"No book matching '{query}' found"})
|
| 55 |
+
|
| 56 |
+
return json.dumps({"error": "Book API unavailable"})
|
| 57 |
+
|
| 58 |
except Exception as e:
|
| 59 |
+
return json.dumps({"error": f"Book search failed: {str(e)}"})
|
| 60 |
|
| 61 |
@tool
|
| 62 |
+
def asoiaf_character(query: str) -> str:
|
| 63 |
+
"""Resolve questions about characters. Returns JSON with: {name, aliases, titles, actor, house, error}"""
|
|
|
|
|
|
|
|
|
|
| 64 |
try:
|
| 65 |
+
clean_query = normalize_input(query)
|
| 66 |
+
name_keywords = ["who is", "plays", "actor for", "information about"]
|
| 67 |
+
name = next((clean_query.split(kw)[-1].strip() for kw in name_keywords
|
| 68 |
+
if kw in clean_query), clean_query)
|
| 69 |
+
|
| 70 |
response = requests.get(
|
| 71 |
"https://anapioficeandfire.com/api/characters",
|
| 72 |
+
params={"name": name},
|
| 73 |
+
timeout=5
|
| 74 |
)
|
| 75 |
+
|
| 76 |
if response.status_code == 200:
|
| 77 |
+
chars = response.json()
|
| 78 |
+
if not chars:
|
| 79 |
+
all_chars = requests.get("https://anapioficeandfire.com/api/characters").json()
|
| 80 |
+
aliases = [alias for c in all_chars for alias in c["aliases"]]
|
| 81 |
+
matched = best_match(name, aliases) or best_match(name, [c["name"] for c in all_chars])
|
| 82 |
+
if matched:
|
| 83 |
+
return asoiaf_character(matched)
|
| 84 |
+
return json.dumps({"error": f"No match for '{query}'. Try full names like 'Daenerys Targaryen'"})
|
| 85 |
+
|
| 86 |
+
char = chars[0]
|
| 87 |
+
result = {
|
| 88 |
+
"name": char.get("name"),
|
| 89 |
+
"aliases": char.get("aliases", []),
|
| 90 |
+
"titles": char.get("titles", []),
|
| 91 |
+
"actor": char.get("playedBy", ["Unknown"])[0],
|
| 92 |
+
"house": char.get("allegiances", ["Unknown"])[0].split("/")[-1],
|
| 93 |
+
"source": "book"
|
| 94 |
+
}
|
| 95 |
+
return json.dumps(result, ensure_ascii=False)
|
| 96 |
+
|
| 97 |
+
return json.dumps({"error": "API unavailable"})
|
| 98 |
+
|
| 99 |
except Exception as e:
|
| 100 |
+
return json.dumps({"error": f"Search failed: {str(e)}"})
|
| 101 |
|
| 102 |
@tool
|
| 103 |
+
def asoiaf_house(query: str) -> str:
|
| 104 |
+
"""Resolve house-related queries. Returns JSON with {name, region, words, members}"""
|
|
|
|
|
|
|
|
|
|
| 105 |
try:
|
| 106 |
response = requests.get(
|
| 107 |
"https://anapioficeandfire.com/api/houses",
|
| 108 |
+
params={"region": query},
|
| 109 |
+
timeout=5
|
| 110 |
)
|
| 111 |
+
|
| 112 |
if response.status_code == 200:
|
| 113 |
houses = response.json()
|
| 114 |
if houses:
|
| 115 |
+
return json.dumps({
|
| 116 |
+
"name": houses[0]["name"],
|
| 117 |
+
"region": houses[0]["region"],
|
| 118 |
+
"words": houses[0]["words"],
|
| 119 |
+
"members": len(houses[0]["swornMembers"])
|
| 120 |
+
})
|
| 121 |
+
return json.dumps({"error": f"No houses found matching '{query}'"})
|
| 122 |
+
|
| 123 |
+
return json.dumps({"error": "House API unavailable"})
|
| 124 |
+
|
| 125 |
except Exception as e:
|
| 126 |
+
return json.dumps({"error": f"House search failed: {str(e)}"})
|
| 127 |
|
| 128 |
@tool
|
| 129 |
def get_current_time_in_timezone(timezone: str) -> str:
|
|
|
|
| 162 |
|
| 163 |
with open("prompts.yaml", 'r') as stream:
|
| 164 |
prompt_templates = yaml.safe_load(stream)
|
| 165 |
+
|
| 166 |
+
|
| 167 |
+
# Add JSON parsing instructions to the agent prompt
|
| 168 |
+
prompt_templates['system'] += """
|
| 169 |
+
When using API tools:
|
| 170 |
+
1. Always parse JSON responses first
|
| 171 |
+
2. Check for "error" keys before proceeding
|
| 172 |
+
3. Use get() for optional fields
|
| 173 |
+
4. Handle empty values gracefully
|
| 174 |
+
"""
|
| 175 |
|
| 176 |
agent = CodeAgent(
|
| 177 |
model=model,
|