OSOCONSULT commited on
Commit
0cdae6c
·
verified ·
1 Parent(s): e95de10

Upload 14 files

Browse files
Files changed (14) hide show
  1. README.md +12 -0
  2. app (3).py +37 -0
  3. avatar.py +25 -0
  4. conversation_storage.py +26 -0
  5. emotion_detection.py +24 -0
  6. gitattributes +35 -0
  7. index.html +715 -0
  8. memory.py +43 -0
  9. prompts.txt +1 -0
  10. requirements (1).txt +13 -0
  11. style.css +28 -0
  12. tts_worker.py +18 -0
  13. utils.py +69 -0
  14. vector_memory.py +30 -0
README.md ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ title: agent-shark-v2
3
+ emoji: 🐳
4
+ colorFrom: blue
5
+ colorTo: gray
6
+ sdk: static
7
+ pinned: false
8
+ tags:
9
+ - deepsite
10
+ ---
11
+
12
+ Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
app (3).py ADDED
@@ -0,0 +1,37 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ with gr.Blocks() as demo:
2
+ gr.Markdown("# 🦈 AgentShark AI Assistant\nWelcome to your advanced business growth partner!")
3
+
4
+ with gr.Row():
5
+ audio_in = gr.Audio(type="file", label="🎤 Upload audio (optional)")
6
+ text_in = gr.Textbox(label="💬 Or type your message", placeholder="What can we help with today?", lines=1)
7
+
8
+ with gr.Row():
9
+ avatar_in = gr.Image(type="file", label="🖼️ Upload Avatar Image (optional)")
10
+
11
+ with gr.Accordion("⚙️ Advanced Settings", open=False):
12
+ model_choice = gr.Radio(["OpenAI GPT-4o", "Claude 3 Opus", "Mistral-7B"], value="OpenAI GPT-4o", label="Select LLM")
13
+ tone = gr.Dropdown(["advisor", "hype", "soft", "playful"], value="advisor", label="Assistant Tone")
14
+
15
+ lead_stage_display = gr.Textbox(label="🧭 Current Lead Stage", interactive=False)
16
+ response_out = gr.Textbox(label="💡 Agent Response", interactive=False)
17
+ audio_out = gr.Audio(label="🔊 Voice Response")
18
+ video_out = gr.Video(label="🎥 Avatar Video")
19
+ state = gr.State({})
20
+
21
+ send_btn = gr.Button("💬 Send Message")
22
+ send_btn.click(
23
+ process_input,
24
+ inputs=[audio_in, text_in, model_choice, tone, avatar_in, state],
25
+ outputs=[response_out, audio_out, video_out, lead_stage_display, state]
26
+ )
27
+
28
+ with gr.Row():
29
+ gr.Markdown("### 📤 Export your conversation")
30
+ export_json_btn = gr.Button("Export as JSON")
31
+ export_csv_btn = gr.Button("Export as CSV")
32
+
33
+ export_json_btn.click(export_json, inputs=[state], outputs=[gr.File(label="Download JSON")])
34
+ export_csv_btn.click(export_csv, inputs=[state], outputs=[gr.File(label="Download CSV")])
35
+
36
+ if __name__ == "__main__":
37
+ demo.launch()
avatar.py ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import subprocess
2
+ import uuid
3
+ import os
4
+
5
+ def generate_avatar_video(audio_path, avatar_image, emotion="neutral"):
6
+ # Placeholder for generating a video avatar (e.g., SadTalker or ffmpeg with image+audio)
7
+ output_filename = f"avatar_{uuid.uuid4().hex}.mp4"
8
+
9
+ # Using ffmpeg to create a simple video combining static image and audio
10
+ ffmpeg_cmd = [
11
+ "ffmpeg",
12
+ "-loop", "1",
13
+ "-i", avatar_image,
14
+ "-i", audio_path,
15
+ "-c:v", "libx264",
16
+ "-tune", "stillimage",
17
+ "-c:a", "aac",
18
+ "-b:a", "192k",
19
+ "-shortest",
20
+ "-pix_fmt", "yuv420p",
21
+ output_filename
22
+ ]
23
+ subprocess.run(ffmpeg_cmd, check=True)
24
+
25
+ return output_filename
conversation_storage.py ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import json
2
+ import pandas as pd
3
+ import os
4
+ from datetime import datetime
5
+
6
+ def save_conversation_to_json(user_id, conversation, folder="conversations"):
7
+ os.makedirs(folder, exist_ok=True)
8
+ filename = f"{folder}/conversation_{user_id}_{datetime.now().strftime('%Y%m%d_%H%M%S')}.json"
9
+ with open(filename, "w") as f:
10
+ json.dump(conversation, f, indent=2)
11
+ return filename
12
+
13
+ def save_conversation_to_csv(user_id, conversation, folder="conversations"):
14
+ os.makedirs(folder, exist_ok=True)
15
+ filename = f"{folder}/conversation_{user_id}_{datetime.now().strftime('%Y%m%d_%H%M%S')}.csv"
16
+ rows = []
17
+ for msg in conversation:
18
+ rows.append({
19
+ "timestamp": datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
20
+ "user_id": user_id,
21
+ "role": msg["role"],
22
+ "content": msg["content"]
23
+ })
24
+ df = pd.DataFrame(rows)
25
+ df.to_csv(filename, index=False)
26
+ return filename
emotion_detection.py ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import torch
2
+ from transformers import pipeline
3
+ import logging
4
+
5
+ logger = logging.getLogger("emotion_detection")
6
+ logger.setLevel(logging.INFO)
7
+
8
+ try:
9
+ # Using a popular emotion detection model from Hugging Face
10
+ emotion_classifier = pipeline("text-classification", model="j-hartmann/emotion-english-distilroberta-base", return_all_scores=False)
11
+ logger.info("Emotion detection model initialized successfully")
12
+ except Exception as e:
13
+ logger.warning(f"Failed to load emotion detection model: {e}")
14
+ emotion_classifier = None
15
+
16
+ def get_primary_emotion(text):
17
+ if not emotion_classifier:
18
+ return "neutral"
19
+ try:
20
+ result = emotion_classifier(text)
21
+ return result[0]["label"].lower()
22
+ except Exception as e:
23
+ logger.warning(f"Emotion detection failed: {e}")
24
+ return "neutral"
gitattributes ADDED
@@ -0,0 +1,35 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ *.7z filter=lfs diff=lfs merge=lfs -text
2
+ *.arrow filter=lfs diff=lfs merge=lfs -text
3
+ *.bin filter=lfs diff=lfs merge=lfs -text
4
+ *.bz2 filter=lfs diff=lfs merge=lfs -text
5
+ *.ckpt filter=lfs diff=lfs merge=lfs -text
6
+ *.ftz filter=lfs diff=lfs merge=lfs -text
7
+ *.gz filter=lfs diff=lfs merge=lfs -text
8
+ *.h5 filter=lfs diff=lfs merge=lfs -text
9
+ *.joblib filter=lfs diff=lfs merge=lfs -text
10
+ *.lfs.* filter=lfs diff=lfs merge=lfs -text
11
+ *.mlmodel filter=lfs diff=lfs merge=lfs -text
12
+ *.model filter=lfs diff=lfs merge=lfs -text
13
+ *.msgpack filter=lfs diff=lfs merge=lfs -text
14
+ *.npy filter=lfs diff=lfs merge=lfs -text
15
+ *.npz filter=lfs diff=lfs merge=lfs -text
16
+ *.onnx filter=lfs diff=lfs merge=lfs -text
17
+ *.ot filter=lfs diff=lfs merge=lfs -text
18
+ *.parquet filter=lfs diff=lfs merge=lfs -text
19
+ *.pb filter=lfs diff=lfs merge=lfs -text
20
+ *.pickle filter=lfs diff=lfs merge=lfs -text
21
+ *.pkl filter=lfs diff=lfs merge=lfs -text
22
+ *.pt filter=lfs diff=lfs merge=lfs -text
23
+ *.pth filter=lfs diff=lfs merge=lfs -text
24
+ *.rar filter=lfs diff=lfs merge=lfs -text
25
+ *.safetensors filter=lfs diff=lfs merge=lfs -text
26
+ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
27
+ *.tar.* filter=lfs diff=lfs merge=lfs -text
28
+ *.tar filter=lfs diff=lfs merge=lfs -text
29
+ *.tflite filter=lfs diff=lfs merge=lfs -text
30
+ *.tgz filter=lfs diff=lfs merge=lfs -text
31
+ *.wasm filter=lfs diff=lfs merge=lfs -text
32
+ *.xz filter=lfs diff=lfs merge=lfs -text
33
+ *.zip filter=lfs diff=lfs merge=lfs -text
34
+ *.zst filter=lfs diff=lfs merge=lfs -text
35
+ *tfevents* filter=lfs diff=lfs merge=lfs -text
index.html ADDED
@@ -0,0 +1,715 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>AgentSharkDemo | Multimodal AI Agent</title>
7
+ <script src="https://cdn.tailwindcss.com"></script>
8
+ <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
9
+ <style>
10
+ @keyframes sharkSwim {
11
+ 0% { transform: translateX(0) rotate(0deg); }
12
+ 25% { transform: translateX(50px) rotate(5deg); }
13
+ 50% { transform: translateX(100px) rotate(0deg); }
14
+ 75% { transform: translateX(50px) rotate(-5deg); }
15
+ 100% { transform: translateX(0) rotate(0deg); }
16
+ }
17
+ .shark-animation {
18
+ animation: sharkSwim 8s infinite ease-in-out;
19
+ }
20
+ .gradient-bg {
21
+ background: linear-gradient(135deg, #f9a8d4 0%, #93c5fd 100%);
22
+ }
23
+ .chat-bubble:before {
24
+ content: '';
25
+ position: absolute;
26
+ left: -8px;
27
+ top: 15px;
28
+ width: 0;
29
+ height: 0;
30
+ border-top: 8px solid transparent;
31
+ border-right: 16px solid #e2e8f0;
32
+ border-bottom: 8px solid transparent;
33
+ }
34
+ .agent-bubble:before {
35
+ left: auto;
36
+ right: -8px;
37
+ border-right: none;
38
+ border-left: 16px solid #3b82f6;
39
+ }
40
+ .waveform {
41
+ display: flex;
42
+ height: 40px;
43
+ align-items: flex-end;
44
+ gap: 2px;
45
+ }
46
+ .waveform-bar {
47
+ width: 3px;
48
+ background: #3b82f6;
49
+ border-radius: 3px;
50
+ transition: height 0.2s ease-in-out;
51
+ }
52
+ .lead-stage {
53
+ transition: all 0.3s ease;
54
+ }
55
+ .lead-stage.active {
56
+ transform: scale(1.1);
57
+ box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1);
58
+ }
59
+ </style>
60
+ </head>
61
+ <body class="bg-gray-50 min-h-screen font-sans">
62
+ <!-- Header -->
63
+ <header class="gradient-bg text-white shadow-lg">
64
+ <div class="container mx-auto px-4 py-6">
65
+ <div class="flex flex-col md:flex-row justify-between items-center">
66
+ <div class="flex items-center space-x-4 mb-4 md:mb-0">
67
+ <div class="relative w-16 h-16">
68
+ <img src="https://em-content.zobj.net/thumbs/160/apple/325/shark_1f988.png"
69
+ class="shark-animation absolute w-full h-full object-contain"
70
+ alt="AgentShark Logo">
71
+ </div>
72
+ <h1 class="text-2xl md:text-3xl font-bold">Agent<span class="text-blue-200">Shark</span>Demo</h1>
73
+ </div>
74
+ <div class="flex space-x-4">
75
+ <a href="#features" class="px-4 py-2 rounded-lg hover:bg-white/20 transition">Features</a>
76
+ <a href="#demo" class="px-4 py-2 rounded-lg hover:bg-white/20 transition">Demo</a>
77
+ <a href="#about" class="px-4 py-2 rounded-lg hover:bg-white/20 transition">About</a>
78
+ </div>
79
+ </div>
80
+ </div>
81
+ </header>
82
+
83
+ <!-- Hero Section -->
84
+ <section class="gradient-bg text-white py-16">
85
+ <div class="container mx-auto px-4 text-center">
86
+ <h2 class="text-4xl md:text-5xl font-bold mb-6">Multimodal AI for Business Growth</h2>
87
+ <p class="text-xl md:text-2xl mb-8 max-w-3xl mx-auto">
88
+ Engage leads with voice, text, and animated avatar responses in real-time
89
+ </p>
90
+ <div class="flex flex-wrap justify-center gap-4 mb-12">
91
+ <div class="bg-white/10 backdrop-blur-md rounded-full px-6 py-2 flex items-center">
92
+ <i class="fas fa-microphone-alt mr-2 text-blue-200"></i> Voice I/O
93
+ </div>
94
+ <div class="bg-white/10 backdrop-blur-md rounded-full px-6 py-2 flex items-center">
95
+ <i class="fas fa-comment-dots mr-2 text-pink-200"></i> Text Chat
96
+ </div>
97
+ <div class="bg-white/10 backdrop-blur-md rounded-full px-6 py-2 flex items-center">
98
+ <i class="fas fa-robot mr-2 text-indigo-200"></i> Animated Avatar
99
+ </div>
100
+ <div class="bg-white/10 backdrop-blur-md rounded-full px-6 py-2 flex items-center">
101
+ <i class="fas fa-chart-line mr-2 text-green-200"></i> Lead Tracking
102
+ </div>
103
+ </div>
104
+ <button id="tryDemoBtn" class="bg-white text-pink-600 hover:bg-gray-100 font-bold py-3 px-8 rounded-full text-lg transition-all transform hover:scale-105 shadow-lg">
105
+ Try Live Demo <i class="fas fa-play ml-2"></i>
106
+ </button>
107
+ </div>
108
+ </section>
109
+
110
+ <!-- Features Section -->
111
+ <section id="features" class="py-16 bg-white">
112
+ <div class="container mx-auto px-4">
113
+ <h2 class="text-3xl font-bold text-center mb-12 text-gray-800">Powerful Features for Business Growth</h2>
114
+
115
+ <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8">
116
+ <!-- Feature 1 -->
117
+ <div class="bg-gray-50 rounded-xl p-6 border border-gray-200 hover:border-blue-300 transition-all hover:shadow-lg">
118
+ <div class="w-14 h-14 bg-blue-100 rounded-full flex items-center justify-center mb-4">
119
+ <i class="fas fa-brain text-blue-600 text-2xl"></i>
120
+ </div>
121
+ <h3 class="text-xl font-bold mb-2 text-gray-800">Agentic Behavior</h3>
122
+ <p class="text-gray-600">
123
+ Understands context and intent with vector memory, adapting dynamically to lead conversion stages in real-time.
124
+ </p>
125
+ </div>
126
+
127
+ <!-- Feature 2 -->
128
+ <div class="bg-gray-50 rounded-xl p-6 border border-gray-200 hover:border-pink-300 transition-all hover:shadow-lg">
129
+ <div class="w-14 h-14 bg-pink-100 rounded-full flex items-center justify-center mb-4">
130
+ <i class="fas fa-exchange-alt text-pink-600 text-2xl"></i>
131
+ </div>
132
+ <h3 class="text-xl font-bold mb-2 text-gray-800">Multimodal I/O</h3>
133
+ <p class="text-gray-600">
134
+ Voice and text input with emotional detection, plus animated avatar video responses for engaging interactions.
135
+ </p>
136
+ </div>
137
+
138
+ <!-- Feature 3 -->
139
+ <div class="bg-gray-50 rounded-xl p-6 border border-gray-200 hover:border-indigo-300 transition-all hover:shadow-lg">
140
+ <div class="w-14 h-14 bg-indigo-100 rounded-full flex items-center justify-center mb-4">
141
+ <i class="fas fa-rocket text-indigo-600 text-2xl"></i>
142
+ </div>
143
+ <h3 class="text-xl font-bold mb-2 text-gray-800">Model Flexibility</h3>
144
+ <p class="text-gray-600">
145
+ Choose between GPT-4o, Claude 3 Opus, or Mistral API with seamless fallback to local LLMs for reliability.
146
+ </p>
147
+ </div>
148
+
149
+ <!-- Feature 4 -->
150
+ <div class="bg-gray-50 rounded-xl p-6 border border-gray-200 hover:border-green-300 transition-all hover:shadow-lg">
151
+ <div class="w-14 h-14 bg-green-100 rounded-full flex items-center justify-center mb-4">
152
+ <i class="fas fa-user-tie text-green-600 text-2xl"></i>
153
+ </div>
154
+ <h3 class="text-xl font-bold mb-2 text-gray-800">Lead Conversion</h3>
155
+ <p class="text-gray-600">
156
+ Tracks visitors through awareness, interest, decision, and action stages with tailored guidance at each step.
157
+ </p>
158
+ </div>
159
+
160
+ <!-- Feature 5 -->
161
+ <div class="bg-gray-50 rounded-xl p-6 border border-gray-200 hover:border-purple-300 transition-all hover:shadow-lg">
162
+ <div class="w-14 h-14 bg-purple-100 rounded-full flex items-center justify-center mb-4">
163
+ <i class="fas fa-file-export text-purple-600 text-2xl"></i>
164
+ </div>
165
+ <h3 class="text-xl font-bold mb-2 text-gray-800">Data Export</h3>
166
+ <p class="text-gray-600">
167
+ Export conversations to JSON or CSV with full analytics and no database dependencies - simple file-based memory.
168
+ </p>
169
+ </div>
170
+
171
+ <!-- Feature 6 -->
172
+ <div class="bg-gray-50 rounded-xl p-6 border border-gray-200 hover:border-yellow-300 transition-all hover:shadow-lg">
173
+ <div class="w-14 h-14 bg-yellow-100 rounded-full flex items-center justify-center mb-4">
174
+ <i class="fas fa-sliders-h text-yellow-600 text-2xl"></i>
175
+ </div>
176
+ <h3 class="text-xl font-bold mb-2 text-gray-800">Customizable</h3>
177
+ <p class="text-gray-600">
178
+ Modular codebase with beautiful Gradio interface and advanced settings for easy extension and customization.
179
+ </p>
180
+ </div>
181
+ </div>
182
+ </div>
183
+ </section>
184
+
185
+ <!-- Demo Section -->
186
+ <section id="demo" class="py-16 bg-gray-100">
187
+ <div class="container mx-auto px-4">
188
+ <h2 class="text-3xl font-bold text-center mb-12 text-gray-800">Interactive Demo</h2>
189
+
190
+ <div class="bg-white rounded-xl shadow-lg overflow-hidden">
191
+ <div class="md:flex">
192
+ <!-- Chat Interface -->
193
+ <div class="md:w-2/3 p-6">
194
+ <div class="flex items-center justify-between mb-6">
195
+ <h3 class="text-xl font-bold text-gray-800">Conversation with AgentShark</h3>
196
+ <div class="flex items-center space-x-2">
197
+ <div class="h-3 w-3 rounded-full bg-green-500"></div>
198
+ <span class="text-sm text-gray-500">Online</span>
199
+ </div>
200
+ </div>
201
+
202
+ <!-- Lead Stages -->
203
+ <div class="flex justify-between mb-6">
204
+ <div class="lead-stage bg-blue-50 text-blue-800 rounded-lg px-4 py-2 text-center w-1/4 mx-1 cursor-pointer" data-stage="awareness">
205
+ <div class="text-xs font-semibold">Awareness</div>
206
+ <div class="h-1 w-full bg-gray-200 mt-1 rounded-full">
207
+ <div class="h-1 bg-blue-300 rounded-full w-1/4"></div>
208
+ </div>
209
+ </div>
210
+ <div class="lead-stage bg-blue-50 text-blue-800 rounded-lg px-4 py-2 text-center w-1/4 mx-1 cursor-pointer" data-stage="interest">
211
+ <div class="text-xs font-semibold">Interest</div>
212
+ <div class="h-1 w-full bg-gray-200 mt-1 rounded-full">
213
+ <div class="h-1 bg-blue-300 rounded-full w-0"></div>
214
+ </div>
215
+ </div>
216
+ <div class="lead-stage bg-blue-50 text-blue-800 rounded-lg px-4 py-2 text-center w-1/4 mx-1 cursor-pointer" data-stage="decision">
217
+ <div class="text-xs font-semibold">Decision</div>
218
+ <div class="h-1 w-full bg-gray-200 mt-1 rounded-full">
219
+ <div class="h-1 bg-blue-300 rounded-full w-0"></div>
220
+ </div>
221
+ </div>
222
+ <div class="lead-stage bg-blue-50 text-blue-800 rounded-lg px-4 py-2 text-center w-1/4 mx-1 cursor-pointer" data-stage="action">
223
+ <div class="text-xs font-semibold">Action</div>
224
+ <div class="h-1 w-full bg-gray-200 mt-1 rounded-full">
225
+ <div class="h-1 bg-blue-300 rounded-full w-0"></div>
226
+ </div>
227
+ </div>
228
+ </div>
229
+
230
+ <!-- Chat Area -->
231
+ <div class="h-96 overflow-y-auto mb-4 space-y-4" id="chatArea">
232
+ <div class="flex justify-start">
233
+ <div class="max-w-xs md:max-w-md lg:max-w-lg bg-gray-100 rounded-xl p-4 relative chat-bubble">
234
+ <p class="text-gray-800">Hello! I'm AgentShark, your AI business growth assistant. How can I help you today?</p>
235
+ </div>
236
+ </div>
237
+ </div>
238
+
239
+ <!-- Input Area -->
240
+ <div class="border-t pt-4">
241
+ <div class="flex items-center space-x-2 mb-2">
242
+ <button class="bg-blue-100 hover:bg-blue-200 text-blue-600 p-2 rounded-full transition" id="voiceBtn">
243
+ <i class="fas fa-microphone"></i>
244
+ </button>
245
+ <div class="relative flex-grow">
246
+ <input type="text" id="userInput" placeholder="Type your message here..."
247
+ class="w-full border border-gray-300 rounded-full py-2 px-4 focus:outline-none focus:ring-2 focus:ring-blue-300 focus:border-transparent">
248
+ <button class="absolute right-3 top-1/2 transform -translate-y-1/2 text-gray-400 hover:text-blue-500">
249
+ <i class="far fa-smile"></i>
250
+ </button>
251
+ </div>
252
+ <button class="bg-blue-600 hover:bg-blue-700 text-white p-2 rounded-full transition" id="sendBtn">
253
+ <i class="fas fa-paper-plane"></i>
254
+ </button>
255
+ </div>
256
+ <div class="flex items-center justify-between text-sm text-gray-500 px-2">
257
+ <div id="voiceStatus" class="hidden items-center">
258
+ <div class="waveform mr-2" id="waveform">
259
+ <div class="waveform-bar h-5"></div>
260
+ <div class="waveform-bar h-8"></div>
261
+ <div class="waveform-bar h-12"></div>
262
+ <div class="waveform-bar h-6"></div>
263
+ <div class="waveform-bar h-10"></div>
264
+ <div class="waveform-bar h-7"></div>
265
+ <div class="waveform-bar h-4"></div>
266
+ </div>
267
+ <span>Listening...</span>
268
+ </div>
269
+ <div class="flex items-center">
270
+ <span class="mr-1">Model:</span>
271
+ <select class="bg-gray-100 rounded px-2 py-1 border border-gray-200 text-xs">
272
+ <option>GPT-4o</option>
273
+ <option>Claude 3 Opus</option>
274
+ <option>Mistral API</option>
275
+ <option>Local LLM</option>
276
+ </select>
277
+ </div>
278
+ </div>
279
+ </div>
280
+ </div>
281
+
282
+ <!-- Avatar & Settings -->
283
+ <div class="md:w-1/3 bg-gray-800 text-white p-6">
284
+ <div class="text-center mb-6">
285
+ <h3 class="text-xl font-bold mb-4">Animated Avatar</h3>
286
+ <div class="bg-black aspect-square rounded-lg overflow-hidden flex items-center justify-center mb-4 bg-gradient-to-br from-blue-900 to-purple-900">
287
+ <div class="relative w-40 h-40">
288
+ <img src="https://em-content.zobj.net/thumbs/160/apple/325/shark_1f988.png"
289
+ class="w-full h-full object-contain filter brightness-125"
290
+ id="avatarImage">
291
+ <div class="absolute inset-0 bg-blue-400 opacity-10 rounded-full animate-pulse"></div>
292
+ </div>
293
+ </div>
294
+ <div class="flex justify-center space-x-4 mb-4">
295
+ <button class="bg-blue-600 hover:bg-blue-700 text-white px-4 py-2 rounded-lg">
296
+ <i class="fas fa-play mr-1"></i> Generate
297
+ </button>
298
+ <button class="bg-gray-700 hover:bg-gray-600 text-white px-4 py-2 rounded-lg">
299
+ <i class="fas fa-download mr-1"></i> Save
300
+ </button>
301
+ </div>
302
+ </div>
303
+
304
+ <div class="mb-6">
305
+ <h4 class="font-bold mb-2">Response Type</h4>
306
+ <div class="grid grid-cols-3 gap-2">
307
+ <button class="bg-blue-600 text-white py-2 rounded-lg">Text</button>
308
+ <button class="bg-gray-700 hover:bg-gray-600 text-white py-2 rounded-lg">Voice</button>
309
+ <button class="bg-gray-700 hover:bg-gray-600 text-white py-2 rounded-lg">Both</button>
310
+ </div>
311
+ </div>
312
+
313
+ <div class="mb-6">
314
+ <h4 class="font-bold mb-2">Personality</h4>
315
+ <select class="w-full bg-gray-700 text-white rounded-lg px-3 py-2 border border-gray-600">
316
+ <option>Professional</option>
317
+ <option>Friendly</option>
318
+ <option>Enthusiastic</option>
319
+ <option>Technical</option>
320
+ <option>Consultative</option>
321
+ </select>
322
+ </div>
323
+
324
+ <div>
325
+ <h4 class="font-bold mb-2">Export Conversation</h4>
326
+ <div class="flex space-x-2">
327
+ <button class="flex-1 bg-green-600 hover:bg-green-700 text-white py-2 rounded-lg">
328
+ <i class="fas fa-file-code mr-1"></i> JSON
329
+ </button>
330
+ <button class="flex-1 bg-green-600 hover:bg-green-700 text-white py-2 rounded-lg">
331
+ <i class="fas fa-file-csv mr-1"></i> CSV
332
+ </button>
333
+ </div>
334
+ </div>
335
+ </div>
336
+ </div>
337
+ </div>
338
+ </div>
339
+ </section>
340
+
341
+ <!-- About Section -->
342
+ <section id="about" class="py-16 bg-white">
343
+ <div class="container mx-auto px-4">
344
+ <div class="max-w-4xl mx-auto">
345
+ <h2 class="text-3xl font-bold text-center mb-8 text-gray-800">About AgentSharkDemo</h2>
346
+
347
+ <div class="bg-gray-50 rounded-xl p-6 md:p-8 shadow-md border border-gray-200">
348
+ <p class="text-gray-700 mb-4">
349
+ <span class="font-bold">AgentSharkDemo</span> is a cutting-edge multimodal AI agent developed for the <span class="text-blue-600">Hugging Face MCP Agents Hackathon</span>. It combines advanced natural language processing with voice interaction capabilities and animated avatar responses to create an engaging, human-like conversational experience.
350
+ </p>
351
+
352
+ <p class="text-gray-700 mb-4">
353
+ Built with a focus on <span class="text-pink-600">business growth and lead conversion</span>, AgentSharkDemo intelligently guides visitors through the customer journey from initial awareness to final action. The system tracks conversation context, emotional tone, and progress through sales funnel stages to deliver tailored responses.
354
+ </p>
355
+
356
+ <div class="bg-blue-50 border-l-4 border-blue-500 p-4 mb-6">
357
+ <p class="text-blue-800 font-semibold">
358
+ <i class="fas fa-lightbulb text-blue-500 mr-2"></i> The project demonstrates real-time multimodal AI in a single, fully integrated interface - no external databases required with its innovative file-based memory system.
359
+ </p>
360
+ </div>
361
+
362
+ <p class="text-gray-700">
363
+ Whether deployed on Hugging Face Spaces for easy sharing or integrated into business workflows, AgentSharkDemo offers a flexible solution for engaging customers with the latest advancements in AI technology.
364
+ </p>
365
+ </div>
366
+
367
+ <div class="mt-8 text-center">
368
+ <a href="https://github.com/yourusername/agentsharkdemo"
369
+ class="inline-flex items-center bg-gray-800 hover:bg-gray-700 text-white px-6 py-3 rounded-lg transition">
370
+ <i class="fab fa-github mr-2"></i> View on GitHub
371
+ </a>
372
+ </div>
373
+ </div>
374
+ </div>
375
+ </section>
376
+
377
+ <!-- Footer -->
378
+ <footer class="bg-gray-900 text-white py-8">
379
+ <div class="container mx-auto px-4">
380
+ <div class="flex flex-col md:flex-row justify-between items-center">
381
+ <div class="flex items-center mb-4 md:mb-0">
382
+ <div class="w-10 h-10 mr-2">
383
+ <img src="https://em-content.zobj.net/thumbs/160/apple/325/shark_1f988.png"
384
+ class="w-full h-full object-contain"
385
+ alt="Shark Logo">
386
+ </div>
387
+ <div>
388
+ <h3 class="font-bold text-xl">Agent<span class="text-blue-300">Shark</span>Demo</h3>
389
+ <p class="text-sm text-gray-400">Multimodal AI for Business Growth</p>
390
+ </div>
391
+ </div>
392
+
393
+ <div class="flex space-x-4 mb-4 md:mb-0">
394
+ <a href="#" class="text-gray-400 hover:text-white transition">
395
+ <i class="fab fa-twitter text-xl"></i>
396
+ </a>
397
+ <a href="#" class="text-gray-400 hover:text-white transition">
398
+ <i class="fab fa-linkedin text-xl"></i>
399
+ </a>
400
+ <a href="#" class="text-gray-400 hover:text-white transition">
401
+ <i class="fab fa-github text-xl"></i>
402
+ </a>
403
+ <a href="#" class="text-gray-400 hover:text-white transition">
404
+ <i class="fab fa-discord text-xl"></i>
405
+ </a>
406
+ </div>
407
+
408
+ <div class="text-gray-400 text-sm">
409
+ &copy; 2023 AgentSharkDemo. Built for Hugging Face MCP Agents Hackathon.
410
+ </div>
411
+ </div>
412
+ </div>
413
+ </footer>
414
+
415
+ <!-- Modal -->
416
+ <div id="demoModal" class="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50 hidden">
417
+ <div class="bg-white rounded-xl shadow-2xl w-full max-w-4xl max-h-[90vh] overflow-hidden">
418
+ <div class="flex justify-between items-center border-b p-4">
419
+ <h3 class="text-xl font-bold text-gray-800">Live Demo Instructions</h3>
420
+ <button id="closeModalBtn" class="text-gray-500 hover:text-gray-700">
421
+ <i class="fas fa-times"></i>
422
+ </button>
423
+ </div>
424
+ <div class="p-6 overflow-y-auto" style="max-height: calc(90vh - 120px)">
425
+ <div class="flex flex-col md:flex-row gap-6">
426
+ <div class="md:w-1/2">
427
+ <h4 class="font-bold text-lg mb-3 text-gray-700">How to Interact</h4>
428
+ <div class="space-y-4">
429
+ <div class="flex items-start">
430
+ <div class="bg-blue-100 text-blue-800 rounded-full w-8 h-8 flex items-center justify-center flex-shrink-0 mr-3">
431
+ <i class="fas fa-microphone-alt"></i>
432
+ </div>
433
+ <div>
434
+ <h5 class="font-semibold text-gray-800">Voice Interaction</h5>
435
+ <p class="text-gray-600 text-sm">Click the microphone button to speak. AgentShark will transcribe and respond instantly.</p>
436
+ </div>
437
+ </div>
438
+ <div class="flex items-start">
439
+ <div class="bg-indigo-100 text-indigo-800 rounded-full w-8 h-8 flex items-center justify-center flex-shrink-0 mr-3">
440
+ <i class="fas fa-keyboard"></i>
441
+ </div>
442
+ <div>
443
+ <h5 class="font-semibold text-gray-800">Text Input</h5>
444
+ <p class="text-gray-600 text-sm">Type your message and hit send for text-based conversation with the AI agent.</p>
445
+ </div>
446
+ </div>
447
+ <div class="flex items-start">
448
+ <div class="bg-green-100 text-green-800 rounded-full w-8 h-8 flex items-center justify-center flex-shrink-0 mr-3">
449
+ <i class="fas fa-robot"></i>
450
+ </div>
451
+ <div>
452
+ <h5 class="font-semibold text-gray-800">Avatar Response</h5>
453
+ <p class="text-gray-600 text-sm">Watch the animated avatar respond with synchronized lip movements and expressions.</p>
454
+ </div>
455
+ </div>
456
+ </div>
457
+ </div>
458
+ <div class="md:w-1/2">
459
+ <h4 class="font-bold text-lg mb-3 text-gray-700">Business Features</h4>
460
+ <div class="space-y-3">
461
+ <div class="bg-gray-50 p-3 rounded-lg">
462
+ <h5 class="font-semibold text-gray-800 flex items-center">
463
+ <span class="w-4 h-4 bg-blue-500 rounded-full mr-2"></span>
464
+ Lead Stage Tracking
465
+ </h5>
466
+ <p class="text-gray-600 text-sm mt-1">
467
+ The progress bar shows movement through awareness, interest, decision, and action stages.
468
+ </p>
469
+ </div>
470
+ <div class="bg-gray-50 p-3 rounded-lg">
471
+ <h5 class="font-semibold text-gray-800 flex items-center">
472
+ <span class="w-4 h-4 bg-purple-500 rounded-full mr-2"></span>
473
+ Multimodal Analytics
474
+ </h5>
475
+ <p class="text-gray-600 text-sm mt-1">
476
+ Export full conversation logs with voice transcripts, text history, and lead stage data.
477
+ </p>
478
+ </div>
479
+ <div class="bg-gray-50 p-3 rounded-lg">
480
+ <h5 class="font-semibold text-gray-800 flex items-center">
481
+ <span class="w-4 h-4 bg-yellow-500 rounded-full mr-2"></span>
482
+ Model Switching
483
+ </h5>
484
+ <p class="text-gray-600 text-sm mt-1">
485
+ Toggle between different AI models to find the best fit for your business needs.
486
+ </p>
487
+ </div>
488
+ </div>
489
+ </div>
490
+ </div>
491
+ </div>
492
+ <div class="border-t p-4 bg-gray-50 flex justify-end">
493
+ <button id="startDemoBtn" class="bg-blue-600 hover:bg-blue-700 text-white px-6 py-2 rounded-lg transition">
494
+ Start Demo <i class="fas fa-arrow-right ml-2"></i>
495
+ </button>
496
+ </div>
497
+ </div>
498
+ </div>
499
+
500
+ <script>
501
+ document.addEventListener('DOMContentLoaded', function() {
502
+ // Modal handling
503
+ const demoModal = document.getElementById('demoModal');
504
+ const tryDemoBtn = document.getElementById('tryDemoBtn');
505
+ const closeModalBtn = document.getElementById('closeModalBtn');
506
+ const startDemoBtn = document.getElementById('startDemoBtn');
507
+
508
+ tryDemoBtn.addEventListener('click', function() {
509
+ demoModal.classList.remove('hidden');
510
+ });
511
+
512
+ closeModalBtn.addEventListener('click', function() {
513
+ demoModal.classList.add('hidden');
514
+ });
515
+
516
+ startDemoBtn.addEventListener('click', function() {
517
+ demoModal.classList.add('hidden');
518
+ document.getElementById('demo').scrollIntoView({ behavior: 'smooth' });
519
+ });
520
+
521
+ // Voice button animation
522
+ const voiceBtn = document.getElementById('voiceBtn');
523
+ const voiceStatus = document.getElementById('voiceStatus');
524
+ const waveformBars = document.querySelectorAll('.waveform-bar');
525
+
526
+ voiceBtn.addEventListener('click', function() {
527
+ voiceBtn.classList.toggle('bg-red-500');
528
+ voiceBtn.classList.toggle('hover:bg-red-600');
529
+ voiceBtn.classList.toggle('text-white');
530
+
531
+ if (voiceBtn.classList.contains('bg-red-500')) {
532
+ voiceStatus.classList.remove('hidden');
533
+ voiceBtn.innerHTML = '<i class="fas fa-microphone-slash"></i>';
534
+
535
+ // Animate waveform bars
536
+ waveformBars.forEach(bar => {
537
+ setInterval(() => {
538
+ bar.style.height = `${Math.random() * 30 + 5}px`;
539
+ }, 200);
540
+ });
541
+ } else {
542
+ voiceStatus.classList.add('hidden');
543
+ voiceBtn.innerHTML = '<i class="fas fa-microphone"></i>';
544
+ }
545
+ });
546
+
547
+ // Chat functionality
548
+ const sendBtn = document.getElementById('sendBtn');
549
+ const userInput = document.getElementById('userInput');
550
+ const chatArea = document.getElementById('chatArea');
551
+
552
+ function sendMessage() {
553
+ const message = userInput.value.trim();
554
+ if (message === '') return;
555
+
556
+ // Add user message
557
+ const userHtml = `
558
+ <div class="flex justify-end">
559
+ <div class="max-w-xs md:max-w-md lg:max-w-lg bg-blue-600 text-white rounded-xl p-4 relative agent-bubble">
560
+ <p>${message}</p>
561
+ </div>
562
+ </div>
563
+ `;
564
+ chatArea.insertAdjacentHTML('beforeend', userHtml);
565
+
566
+ // Clear input
567
+ userInput.value = '';
568
+
569
+ // Show typing indicator
570
+ const typingHtml = `
571
+ <div class="flex justify-start">
572
+ <div class="max-w-xs md:max-w-md lg:max-w-lg bg-gray-100 rounded-xl p-4 relative chat-bubble">
573
+ <div class="flex space-x-2">
574
+ <div class="w-2 h-2 bg-gray-400 rounded-full animate-bounce"></div>
575
+ <div class="w-2 h-2 bg-gray-400 rounded-full animate-bounce" style="animation-delay: 0.2s"></div>
576
+ <div class="w-2 h-2 bg-gray-400 rounded-full animate-bounce" style="animation-delay: 0.4s"></div>
577
+ </div>
578
+ </div>
579
+ </div>
580
+ `;
581
+ chatArea.insertAdjacentHTML('beforeend', typingHtml);
582
+
583
+ // Scroll to bottom
584
+ chatArea.scrollTop = chatArea.scrollHeight;
585
+
586
+ // Simulate response after delay
587
+ setTimeout(() => {
588
+ // Remove typing indicator
589
+ chatArea.removeChild(chatArea.lastChild);
590
+
591
+ // Add response
592
+ const responses = [
593
+ "I understand your question about our services. We offer several packages that might suit your needs.",
594
+ "That's an excellent point. Based on what you've said, I'd recommend our premium solution for your business size.",
595
+ "Thank you for your inquiry! I've analyzed your requirements and our Enterprise package seems most appropriate.",
596
+ "I notice you're in the 'Interest' stage of our funnel. Would you like me to send you some case studies?",
597
+ "Based on our conversation, you're making great progress toward a decision. Shall we discuss pricing options now?"
598
+ ];
599
+
600
+ const randomResponse = responses[Math.floor(Math.random() * responses.length)];
601
+
602
+ const responseHtml = `
603
+ <div class="flex justify-start">
604
+ <div class="max-w-xs md:max-w-md lg:max-w-lg bg-gray-100 rounded-xl p-4 relative chat-bubble">
605
+ <p>${randomResponse}</p>
606
+ </div>
607
+ </div>
608
+ `;
609
+ chatArea.insertAdjacentHTML('beforeend', responseHtml);
610
+
611
+ // Scroll to bottom again
612
+ chatArea.scrollTop = chatArea.scrollHeight;
613
+
614
+ // Randomly animate avatar
615
+ if (Math.random() > 0.5) {
616
+ const avatar = document.getElementById('avatarImage');
617
+ avatar.classList.add('animate-bounce');
618
+ setTimeout(() => {
619
+ avatar.classList.remove('animate-bounce');
620
+ }, 2000);
621
+ }
622
+
623
+ // Randomly advance lead stage
624
+ if (Math.random() > 0.7) {
625
+ advanceLeadStage();
626
+ }
627
+ }, 1500 + Math.random() * 2000);
628
+ }
629
+
630
+ sendBtn.addEventListener('click', sendMessage);
631
+
632
+ userInput.addEventListener('keypress', function(e) {
633
+ if (e.key === 'Enter') {
634
+ sendMessage();
635
+ }
636
+ });
637
+
638
+ // Lead stage functionality
639
+ const leadStages = document.querySelectorAll('.lead-stage');
640
+
641
+ function advanceLeadStage() {
642
+ let foundCurrent = false;
643
+ let nextElement = null;
644
+
645
+ leadStages.forEach((stage, index) => {
646
+ if (!foundCurrent && stage.classList.contains('active')) {
647
+ stage.classList.remove('active');
648
+ foundCurrent = true;
649
+ const progress = stage.querySelector('.bg-blue-300');
650
+ progress.style.width = '100%';
651
+
652
+ if (index < leadStages.length - 1) {
653
+ nextElement = leadStages[index + 1];
654
+ }
655
+ }
656
+ });
657
+
658
+ if (!foundCurrent) {
659
+ nextElement = leadStages[0];
660
+ }
661
+
662
+ if (nextElement) {
663
+ nextElement.classList.add('active');
664
+ const progress = nextElement.querySelector('.bg-blue-300');
665
+ progress.style.width = '25%';
666
+
667
+ // Update avatar for stage change
668
+ const avatar = document.getElementById('avatarImage');
669
+ avatar.classList.add('animate-pulse');
670
+ setTimeout(() => {
671
+ avatar.classList.remove('animate-pulse');
672
+ }, 1000);
673
+ }
674
+ }
675
+
676
+ // Initialize first lead stage
677
+ leadStages[0].classList.add('active');
678
+ const firstProgress = leadStages[0].querySelector('.bg-blue-300');
679
+ firstProgress.style.width = '25%';
680
+
681
+ // Click on lead stages
682
+ leadStages.forEach(stage => {
683
+ stage.addEventListener('click', function() {
684
+ leadStages.forEach(s => s.classList.remove('active'));
685
+ this.classList.add('active');
686
+ });
687
+ });
688
+
689
+ // Mobile menu toggle (if needed)
690
+ const mobileMenuBtn = document.querySelector('.mobile-menu-button');
691
+ const mobileMenu = document.querySelector('.mobile-menu');
692
+
693
+ if (mobileMenuBtn) {
694
+ mobileMenuBtn.addEventListener('click', function() {
695
+ mobileMenu.classList.toggle('hidden');
696
+ });
697
+ }
698
+
699
+ // Animate shark logo in header on hover
700
+ const headerShark = document.querySelector('header .shark-animation');
701
+ if (headerShark) {
702
+ headerShark.addEventListener('mouseover', function() {
703
+ this.style.animationPlayState = 'running';
704
+ });
705
+
706
+ headerShark.addEventListener('animationiteration', function() {
707
+ if (!this.matches(':hover')) {
708
+ this.style.animationPlayState = 'paused';
709
+ }
710
+ });
711
+ }
712
+ });
713
+ </script>
714
+ <p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=OSOCONSULT/agent-shark-v2" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body>
715
+ </html>
memory.py ADDED
@@ -0,0 +1,43 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import json
3
+
4
+ class FileMemory:
5
+ def __init__(self, base_path="memory_data"):
6
+ self.base_path = base_path
7
+ os.makedirs(self.base_path, exist_ok=True)
8
+
9
+ def _get_file_path(self, user_id):
10
+ return os.path.join(self.base_path, f"{user_id}.json")
11
+
12
+ def get_memory(self, user_id):
13
+ path = self._get_file_path(user_id)
14
+ if os.path.exists(path):
15
+ with open(path, "r") as f:
16
+ return json.load(f)
17
+ return []
18
+
19
+ def store_user_message(self, user_id, message):
20
+ memory = self.get_memory(user_id)
21
+ memory.append({"role": "user", "content": message})
22
+ self._save_memory(user_id, memory)
23
+
24
+ def store_agent_message(self, user_id, message):
25
+ memory = self.get_memory(user_id)
26
+ memory.append({"role": "assistant", "content": message})
27
+ self._save_memory(user_id, memory)
28
+
29
+ def clear_memory(self, user_id):
30
+ path = self._get_file_path(user_id)
31
+ if os.path.exists(path):
32
+ os.remove(path)
33
+
34
+ def _save_memory(self, user_id, memory):
35
+ path = self._get_file_path(user_id)
36
+ with open(path, "w") as f:
37
+ json.dump(memory, f, indent=2)
38
+
39
+ def get_context(self, user_id, max_turns=10):
40
+ memory = self.get_memory(user_id)
41
+ return "\n".join([f"{m['role'].upper()}: {m['content']}" for m in memory[-max_turns:]])
42
+
43
+ memory = FileMemory()
prompts.txt ADDED
@@ -0,0 +1 @@
 
 
1
+ --- title: AGENTSHARKDEMO emoji: ⚡ colorFrom: pink colorTo: blue sdk: gradio sdk_version: 5.33.0 app_file: app.py pinned: false license: apache-2.0 short_description: ' multimodal, agentic AI demo for business growth and leads' --- # 🦈 AgentSharkDemo: Multimodal AI Agent for Business Growth **AgentSharkDemo** is a cutting-edge, multimodal AI agent built for the **Hugging Face MCP Agents Hackathon**! It combines voice, text, and animated avatar responses to deliver an engaging, human-like conversational experience for business growth and lead conversion. --- ## 🚀 Demo Overview ✅ **Agentic Behavior** - Understands voice and text input - Detects emotion and intent in real-time - Uses vector memory for context-aware responses - Dynamically adapts to lead conversion stages - Generates dynamic audio and animated avatar video responses ✅ **Multimodal Power** - 🎤 Voice input with real-time transcription (Whisper) - 💬 Text input and conversational context - 🔊 Voice output via XTTS/Bark TTS - 🎥 Animated avatar videos (AnimateDiff-ready) ✅ **Model Choice Flexibility** - **OpenAI GPT-4o** - **Claude 3 Opus (Anthropic)** - **Hugging Face Mistral Inference API** - Local LLM fallback for reliable answers ✅ **File-Based Export & Analytics** - Exports conversations to JSON and CSV - No database needed — file-based memory for simplicity! --- ## 💡 Key Features for Judges - 🏆 Demonstrates **real-time multimodal AI** in a single, fully integrated Gradio app - 📈 **Business-focused**: tracks and guides visitors through lead stages - 💡 Uses **streaming responses** for faster interactions - 🪄 AnimateDiff-ready avatar video generation - 🗂️ Clean and modular codebase for easy extension - 🎨 Beautiful Gradio interface with advanced settings in accordions --- ## 🌐 Deployment ✅ **Hugging Face Spaces** (Gradio template) ✅ **No YAML needed** — just upload your `.env` secrets and these files! --- ## ⚙️ Local Testing ```bash pip install -r requirements.txt python app.py
requirements (1).txt ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ gradio>=3.41.2
2
+ openai
3
+ requests
4
+ numpy
5
+ pandas
6
+ pydub
7
+ librosa
8
+ opencv-python-headless
9
+ Pillow
10
+ chromadb
11
+ python-dotenv
12
+ transformers
13
+ torch
style.css ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ body {
2
+ padding: 2rem;
3
+ font-family: -apple-system, BlinkMacSystemFont, "Arial", sans-serif;
4
+ }
5
+
6
+ h1 {
7
+ font-size: 16px;
8
+ margin-top: 0;
9
+ }
10
+
11
+ p {
12
+ color: rgb(107, 114, 128);
13
+ font-size: 15px;
14
+ margin-bottom: 10px;
15
+ margin-top: 5px;
16
+ }
17
+
18
+ .card {
19
+ max-width: 620px;
20
+ margin: 0 auto;
21
+ padding: 16px;
22
+ border: 1px solid lightgray;
23
+ border-radius: 16px;
24
+ }
25
+
26
+ .card p:last-child {
27
+ margin-bottom: 0;
28
+ }
tts_worker.py ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from pydub import AudioSegment
2
+ from gtts import gTTS
3
+ import os
4
+ import uuid
5
+
6
+ def save_tts(text, emotion="neutral"):
7
+ # Use Google TTS as a simple fallback for demonstration.
8
+ tts = gTTS(text, lang="en")
9
+ output_filename = f"output_{uuid.uuid4().hex}.mp3"
10
+ tts.save(output_filename)
11
+
12
+ # Convert to WAV (if needed)
13
+ audio = AudioSegment.from_file(output_filename, format="mp3")
14
+ wav_filename = output_filename.replace(".mp3", ".wav")
15
+ audio.export(wav_filename, format="wav")
16
+ os.remove(output_filename)
17
+
18
+ return wav_filename
utils.py ADDED
@@ -0,0 +1,69 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import requests
3
+ from dotenv import load_dotenv
4
+ from pydub import AudioSegment
5
+ import tempfile
6
+ from openai import OpenAI
7
+
8
+ load_dotenv()
9
+ HF_API_URL = os.getenv("HF_API_URL")
10
+ HF_API_KEY = os.getenv("HF_API_KEY")
11
+ OPENAI_API_KEY = os.getenv("OPENAI_API_KEY")
12
+ openai_client = OpenAI(api_key=OPENAI_API_KEY)
13
+
14
+ def transcribe_audio(file_path):
15
+ try:
16
+ audio = AudioSegment.from_file(file_path)
17
+ audio = audio.set_frame_rate(16000).set_channels(1)
18
+ temp_wav = tempfile.NamedTemporaryFile(suffix=".wav", delete=False)
19
+ audio.export(temp_wav.name, format="wav")
20
+ with open(temp_wav.name, "rb") as f:
21
+ response = openai_client.audio.transcriptions.create(
22
+ file=f,
23
+ model="whisper-1"
24
+ )
25
+ os.remove(temp_wav.name)
26
+ return response.text
27
+ except Exception as e:
28
+ return f"Error in transcription: {e}"
29
+
30
+ def generate_response(prompt, tone="advisor", model="OpenAI GPT-4o", stream=False):
31
+ try:
32
+ if model == "OpenAI GPT-4o":
33
+ completion = openai_client.chat.completions.create(
34
+ model="gpt-4o",
35
+ messages=[
36
+ {"role": "system", "content": f"You are an {tone} expert assistant."},
37
+ {"role": "user", "content": prompt}
38
+ ]
39
+ )
40
+ return completion.choices[0].message.content.strip()
41
+
42
+ elif model == "Claude 3 Opus":
43
+ headers = {
44
+ "x-api-key": os.getenv("CLAUDE_API_KEY"),
45
+ "anthropic-version": "2023-06-01"
46
+ }
47
+ data = {
48
+ "model": "claude-3-opus-20240229",
49
+ "messages": [{"role": "user", "content": prompt}]
50
+ }
51
+ response = requests.post(
52
+ "https://api.anthropic.com/v1/messages",
53
+ headers=headers,
54
+ json=data
55
+ )
56
+ return response.json()["content"][0]["text"].strip()
57
+
58
+ elif model == "Mistral-7B":
59
+ headers = {"Authorization": f"Bearer {HF_API_KEY}"}
60
+ data = {"inputs": prompt}
61
+ response = requests.post(HF_API_URL, headers=headers, json=data)
62
+ response.raise_for_status()
63
+ return response.json()[0]["generated_text"].strip()
64
+
65
+ else:
66
+ return "⚠️ Invalid model selection."
67
+
68
+ except Exception as e:
69
+ return f"Error generating response: {e}"
vector_memory.py ADDED
@@ -0,0 +1,30 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import logging
3
+
4
+ try:
5
+ import chromadb
6
+ from chromadb.config import Settings
7
+ CHROMADB_AVAILABLE = True
8
+ except ImportError:
9
+ CHROMADB_AVAILABLE = False
10
+
11
+ logger = logging.getLogger("vector_memory")
12
+ logger.setLevel(logging.INFO)
13
+
14
+ def add_to_vector_memory(user_id, text, metadata=None):
15
+ if not CHROMADB_AVAILABLE:
16
+ logger.warning("ChromaDB not available. Skipping vector memory storage.")
17
+ return
18
+ # Placeholder: Implement vector memory logic here.
19
+ logger.info(f"Storing vector memory for user: {user_id}")
20
+
21
+ def get_relevant_context(user_id, query, top_k=3):
22
+ if not CHROMADB_AVAILABLE:
23
+ logger.warning("ChromaDB not available. Returning empty relevant context.")
24
+ return ""
25
+ # Placeholder: Implement search for relevant context.
26
+ return ""
27
+
28
+ def clear_vector_memory(user_id):
29
+ if not CHROMADB_AVAILABLE:
30
+ logger.warning("ChromaDB not available. Skipping vector memory clear.")