Spaces:
Sleeping
Sleeping
Recent updates (WIP)
Browse files- Gradio_UI.py +1 -1
- app.py +3 -5
- config.py +5 -2
- list_models.py +33 -0
- run_single_agent.py +3 -3
- test_analysis.py +68 -0
- test_formatting.py +85 -0
- tools/analysis_tools.py +3 -3
Gradio_UI.py
CHANGED
@@ -178,7 +178,7 @@ def stream_to_gradio(
|
|
178 |
content={"path": final_answer.to_string(), "mime_type": "audio/wav"},
|
179 |
)
|
180 |
else:
|
181 |
-
yield gr.ChatMessage(role="assistant", content=f"**Final answer:** {str(final_answer)}")
|
182 |
|
183 |
|
184 |
class GradioUI:
|
|
|
178 |
content={"path": final_answer.to_string(), "mime_type": "audio/wav"},
|
179 |
)
|
180 |
else:
|
181 |
+
yield gr.ChatMessage(role="assistant", content=f"**Final answer:** \n{str(final_answer)}")
|
182 |
|
183 |
|
184 |
class GradioUI:
|
app.py
CHANGED
@@ -54,7 +54,7 @@ def main():
|
|
54 |
# Determine if we're in test mode (local) or production (HuggingFace)
|
55 |
# HuggingFace environment has SPACE_ID environment variable
|
56 |
|
57 |
-
|
58 |
if use_localhost:
|
59 |
launch_kwargs = {
|
60 |
"debug": True,
|
@@ -63,14 +63,12 @@ def main():
|
|
63 |
"server_port": 3000
|
64 |
}
|
65 |
else:
|
66 |
-
# Configuration for production (HuggingFace)
|
67 |
launch_kwargs = {
|
68 |
"debug": True,
|
69 |
-
"share":
|
70 |
-
# No server_name or server_port for HuggingFace deployment
|
71 |
}
|
72 |
|
73 |
-
#
|
74 |
GradioUI(single_agent).launch(**launch_kwargs)
|
75 |
logger.success("Server started successfully")
|
76 |
|
|
|
54 |
# Determine if we're in test mode (local) or production (HuggingFace)
|
55 |
# HuggingFace environment has SPACE_ID environment variable
|
56 |
|
57 |
+
|
58 |
if use_localhost:
|
59 |
launch_kwargs = {
|
60 |
"debug": True,
|
|
|
63 |
"server_port": 3000
|
64 |
}
|
65 |
else:
|
|
|
66 |
launch_kwargs = {
|
67 |
"debug": True,
|
68 |
+
"share": False
|
|
|
69 |
}
|
70 |
|
71 |
+
# Инструкции агенту настраиваются непосредственно в GradioUI.py
|
72 |
GradioUI(single_agent).launch(**launch_kwargs)
|
73 |
logger.success("Server started successfully")
|
74 |
|
config.py
CHANGED
@@ -43,10 +43,13 @@ def get_model_id(provider="gemini"):
|
|
43 |
elif provider == "gemini":
|
44 |
return "gemini/gemini-2.0-flash"
|
45 |
elif provider == "openrouter":
|
46 |
-
return "openrouter/google/gemini-2.0-flash-lite-preview-02-05:free"
|
47 |
# return "openrouter/mistralai/mistral-small-3.1-24b-instruct:free"
|
48 |
-
#return "openrouter/rekaai/reka-flash-3:free"
|
49 |
# return "openrouter/deepseek/deepseek-chat:free"
|
|
|
|
|
|
|
|
|
50 |
|
51 |
def get_ollama_api_base():
|
52 |
"""Get the API base URL for Ollama."""
|
|
|
43 |
elif provider == "gemini":
|
44 |
return "gemini/gemini-2.0-flash"
|
45 |
elif provider == "openrouter":
|
46 |
+
# return "openrouter/google/gemini-2.0-flash-lite-preview-02-05:free"
|
47 |
# return "openrouter/mistralai/mistral-small-3.1-24b-instruct:free"
|
|
|
48 |
# return "openrouter/deepseek/deepseek-chat:free"
|
49 |
+
# return "openrouter/thudm/glm-z1-32b:free"
|
50 |
+
# return "openrouter/rekaai/reka-flash-3:free"
|
51 |
+
# return "openrouter/google/gemini-2.5-pro-exp-03-25:free"
|
52 |
+
return "openrouter/google/gemini-2.0-flash-exp:free"
|
53 |
|
54 |
def get_ollama_api_base():
|
55 |
"""Get the API base URL for Ollama."""
|
list_models.py
ADDED
@@ -0,0 +1,33 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
#!/usr/bin/env python3
|
2 |
+
"""List available Gemini models"""
|
3 |
+
|
4 |
+
import os
|
5 |
+
import google.generativeai as genai
|
6 |
+
from dotenv import load_dotenv
|
7 |
+
|
8 |
+
load_dotenv()
|
9 |
+
|
10 |
+
try:
|
11 |
+
# Настройка API ключа
|
12 |
+
api_key = os.environ.get("GEMINI_API_KEY")
|
13 |
+
if not api_key:
|
14 |
+
print("GEMINI_API_KEY not found in environment variables")
|
15 |
+
exit(1)
|
16 |
+
|
17 |
+
genai.configure(api_key=api_key)
|
18 |
+
|
19 |
+
# Получение списка моделей
|
20 |
+
models = list(genai.list_models())
|
21 |
+
print(f"Found {len(models)} models:")
|
22 |
+
for model in models:
|
23 |
+
print(f"\nModel name: {model.name}")
|
24 |
+
print(f"Display name: {model.display_name}")
|
25 |
+
print(f"Description: {model.description}")
|
26 |
+
print(f"Generation methods: {', '.join(model.supported_generation_methods) if hasattr(model, 'supported_generation_methods') else 'Not specified'}")
|
27 |
+
print(f"Input token limit: {model.input_token_limit}")
|
28 |
+
print(f"Output token limit: {model.output_token_limit}")
|
29 |
+
print(f"Temperature: {model.temperature}")
|
30 |
+
print("=" * 80)
|
31 |
+
|
32 |
+
except Exception as e:
|
33 |
+
print(f"Error listing models: {e}")
|
run_single_agent.py
CHANGED
@@ -30,12 +30,12 @@ else:
|
|
30 |
# model_id='https://pflgm2locj2t89co.us-east-1.aws.endpoints.huggingface.cloud'
|
31 |
|
32 |
# Prompt the user for the song name
|
33 |
-
song_data = "
|
34 |
|
35 |
agent = create_single_agent(model)
|
36 |
prompt = f"""1. Find and extract the lyrics of the song: {song_data}.
|
37 |
-
2. Perform deep lyrics analysis and
|
38 |
-
|
39 |
"""
|
40 |
# Agent execution
|
41 |
agent.run(prompt)
|
|
|
30 |
# model_id='https://pflgm2locj2t89co.us-east-1.aws.endpoints.huggingface.cloud'
|
31 |
|
32 |
# Prompt the user for the song name
|
33 |
+
song_data = "Ascending - Unna notte che non passa"
|
34 |
|
35 |
agent = create_single_agent(model)
|
36 |
prompt = f"""1. Find and extract the lyrics of the song: {song_data}.
|
37 |
+
2. Perform deep lyrics analysis and add translation in case it is not in English.
|
38 |
+
3. Return full lyrics and analysis results in a pretty human-readable format.
|
39 |
"""
|
40 |
# Agent execution
|
41 |
agent.run(prompt)
|
test_analysis.py
ADDED
@@ -0,0 +1,68 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
#!/usr/bin/env python3
|
2 |
+
"""
|
3 |
+
Test script for the lyrics analysis tool.
|
4 |
+
This script demonstrates the usage of AnalyzeLyricsTool with sample lyrics.
|
5 |
+
"""
|
6 |
+
|
7 |
+
from tools.analysis_tools import AnalyzeLyricsTool
|
8 |
+
|
9 |
+
# Sample lyrics for testing
|
10 |
+
SAMPLE_LYRICS = """
|
11 |
+
Walking alone through empty streets
|
12 |
+
The silence echoes what my heart repeats
|
13 |
+
Shadows dance across the walls
|
14 |
+
As night descends and darkness calls
|
15 |
+
|
16 |
+
But I'll keep moving forward
|
17 |
+
Even when the path is unclear
|
18 |
+
There's strength in the journey
|
19 |
+
And meaning in the tears
|
20 |
+
|
21 |
+
The morning light breaks through the clouds
|
22 |
+
Illuminating what was hidden in shrouds
|
23 |
+
Each step I take leaves footprints behind
|
24 |
+
Marking the path for others to find
|
25 |
+
|
26 |
+
But I'll keep moving forward
|
27 |
+
Even when the path is unclear
|
28 |
+
There's strength in the journey
|
29 |
+
And meaning in the tears
|
30 |
+
"""
|
31 |
+
|
32 |
+
def test_lyrics_analysis():
|
33 |
+
"""Test the lyrics analysis tool with sample lyrics."""
|
34 |
+
print("\n=== TESTING LYRICS ANALYSIS TOOL ===\n")
|
35 |
+
|
36 |
+
# Create an instance of the analysis tool
|
37 |
+
analyzer = AnalyzeLyricsTool()
|
38 |
+
|
39 |
+
# Analyze the sample lyrics
|
40 |
+
song_title = "The Journey"
|
41 |
+
artist = "Example Artist"
|
42 |
+
|
43 |
+
# Test with formatting enabled (default)
|
44 |
+
print("\n--- WITH RICH FORMATTING ---\n")
|
45 |
+
formatted_analysis = analyzer.forward(
|
46 |
+
song_title=song_title,
|
47 |
+
artist=artist,
|
48 |
+
lyrics=SAMPLE_LYRICS,
|
49 |
+
format_output=True
|
50 |
+
)
|
51 |
+
print(formatted_analysis)
|
52 |
+
|
53 |
+
# Test with formatting disabled (raw JSON)
|
54 |
+
print("\n--- WITHOUT FORMATTING (RAW JSON) ---\n")
|
55 |
+
raw_analysis = analyzer.forward(
|
56 |
+
song_title=song_title,
|
57 |
+
artist=artist,
|
58 |
+
lyrics=SAMPLE_LYRICS,
|
59 |
+
format_output=False
|
60 |
+
)
|
61 |
+
print(raw_analysis)
|
62 |
+
|
63 |
+
return formatted_analysis, raw_analysis
|
64 |
+
|
65 |
+
if __name__ == "__main__":
|
66 |
+
print("Testing AnalyzeLyricsTool with sample lyrics...")
|
67 |
+
formatted_result, raw_result = test_lyrics_analysis()
|
68 |
+
print("\nAnalysis test completed successfully!")
|
test_formatting.py
ADDED
@@ -0,0 +1,85 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
#!/usr/bin/env python3
|
2 |
+
"""
|
3 |
+
Test script for the formatting tools.
|
4 |
+
This script demonstrates the usage of FormatAnalysisResultsTool with sample lyrics analysis.
|
5 |
+
"""
|
6 |
+
|
7 |
+
from tools.formatting_tools import FormatAnalysisResultsTool
|
8 |
+
|
9 |
+
# Sample lyrics analysis in JSON format
|
10 |
+
SAMPLE_ANALYSIS = {
|
11 |
+
"summary": "This song explores themes of isolation, introspection, and the search for meaning in a chaotic world. It combines melancholic imagery with moments of hope and resilience.",
|
12 |
+
"main_themes": ["Isolation", "Self-discovery", "Resilience", "Nature as metaphor"],
|
13 |
+
"mood": "Melancholic yet hopeful",
|
14 |
+
"sections_analysis": [
|
15 |
+
{
|
16 |
+
"section_type": "verse",
|
17 |
+
"section_number": 1,
|
18 |
+
"lines": [
|
19 |
+
"Walking alone through empty streets",
|
20 |
+
"The silence echoes what my heart repeats",
|
21 |
+
"Shadows dance across the walls",
|
22 |
+
"As night descends and darkness calls"
|
23 |
+
],
|
24 |
+
"analysis": "The opening verse establishes the solitary mood through imagery of empty streets and silence. The speaker appears to be in a state of introspection, with external elements (shadows, darkness) reflecting their internal emotional state."
|
25 |
+
},
|
26 |
+
{
|
27 |
+
"section_type": "chorus",
|
28 |
+
"section_number": 1,
|
29 |
+
"lines": [
|
30 |
+
"But I'll keep moving forward",
|
31 |
+
"Even when the path is unclear",
|
32 |
+
"There's strength in the journey",
|
33 |
+
"And meaning in the tears"
|
34 |
+
],
|
35 |
+
"analysis": "The chorus shifts to a more resilient tone, introducing the central theme of perseverance despite uncertainty. It suggests that the process of struggling itself has value, contrasting with the melancholy of the verse."
|
36 |
+
},
|
37 |
+
{
|
38 |
+
"section_type": "verse",
|
39 |
+
"section_number": 2,
|
40 |
+
"lines": [
|
41 |
+
"The morning light breaks through the clouds",
|
42 |
+
"Illuminating what was hidden in shrouds",
|
43 |
+
"Each step I take leaves footprints behind",
|
44 |
+
"Marking the path for others to find"
|
45 |
+
],
|
46 |
+
"analysis": "The second verse introduces imagery of dawn and light, symbolizing hope and clarity emerging from darkness. There's a suggestion that the speaker's personal journey might serve as guidance for others, adding a layer of purpose to their struggles."
|
47 |
+
}
|
48 |
+
],
|
49 |
+
"significant_lines": [
|
50 |
+
{
|
51 |
+
"line": "There's strength in the journey, And meaning in the tears",
|
52 |
+
"significance": "This line encapsulates the central message of finding value in difficult experiences and emotional pain."
|
53 |
+
},
|
54 |
+
{
|
55 |
+
"line": "Each step I take leaves footprints behind, Marking the path for others to find",
|
56 |
+
"significance": "This suggests that personal struggles can have broader meaning by helping others navigate similar challenges."
|
57 |
+
}
|
58 |
+
],
|
59 |
+
"conclusion": "The song ultimately presents a nuanced view of personal struggle, suggesting that periods of isolation and difficulty are not merely obstacles to overcome but meaningful parts of human experience. Through its imagery of darkness giving way to light, it offers a message of hope without dismissing the reality of pain."
|
60 |
+
}
|
61 |
+
|
62 |
+
def test_rich_formatting():
|
63 |
+
"""Test the rich formatting output."""
|
64 |
+
formatter = FormatAnalysisResultsTool()
|
65 |
+
rich_output = formatter.forward(SAMPLE_ANALYSIS, pretty=True)
|
66 |
+
print("\n=== RICH FORMATTING OUTPUT ===\n")
|
67 |
+
print(rich_output)
|
68 |
+
return rich_output
|
69 |
+
|
70 |
+
def test_simple_formatting():
|
71 |
+
"""Test the simple text formatting output."""
|
72 |
+
formatter = FormatAnalysisResultsTool()
|
73 |
+
simple_output = formatter.forward(SAMPLE_ANALYSIS, pretty=False)
|
74 |
+
print("\n=== SIMPLE TEXT FORMATTING OUTPUT ===\n")
|
75 |
+
print(simple_output)
|
76 |
+
return simple_output
|
77 |
+
|
78 |
+
if __name__ == "__main__":
|
79 |
+
print("Testing FormatAnalysisResultsTool with sample lyrics analysis...")
|
80 |
+
|
81 |
+
# Test both formatting options
|
82 |
+
rich_result = test_rich_formatting()
|
83 |
+
simple_result = test_simple_formatting()
|
84 |
+
|
85 |
+
print("\nFormatting test completed successfully!")
|
tools/analysis_tools.py
CHANGED
@@ -1,12 +1,12 @@
|
|
1 |
"""
|
2 |
Analysis tools for understanding and interpreting song lyrics.
|
3 |
"""
|
4 |
-
|
5 |
from loguru import logger
|
6 |
from smolagents import Tool
|
7 |
import json
|
8 |
from typing import Dict
|
9 |
-
|
10 |
from api_utils import make_api_call_with_retry
|
11 |
|
12 |
|
@@ -24,7 +24,7 @@ class AnalyzeLyricsTool(Tool):
|
|
24 |
|
25 |
def __init__(self, model_id=None):
|
26 |
super().__init__()
|
27 |
-
self.model_id =
|
28 |
|
29 |
def forward(self, song_title: str, artist: str, lyrics: str) -> str:
|
30 |
"""
|
|
|
1 |
"""
|
2 |
Analysis tools for understanding and interpreting song lyrics.
|
3 |
"""
|
4 |
+
import os
|
5 |
from loguru import logger
|
6 |
from smolagents import Tool
|
7 |
import json
|
8 |
from typing import Dict
|
9 |
+
from config import get_model_id
|
10 |
from api_utils import make_api_call_with_retry
|
11 |
|
12 |
|
|
|
24 |
|
25 |
def __init__(self, model_id=None):
|
26 |
super().__init__()
|
27 |
+
self.model_id = get_model_id(provider='openrouter')
|
28 |
|
29 |
def forward(self, song_title: str, artist: str, lyrics: str) -> str:
|
30 |
"""
|