jbl2024 commited on
Commit
d1967f6
·
verified ·
1 Parent(s): 0d785a3

Upload folder using huggingface_hub

Browse files
Files changed (5) hide show
  1. .gitignore +123 -0
  2. .gradio/certificate.pem +31 -0
  3. README.md +2 -8
  4. app.py +172 -0
  5. requirements.txt +1 -0
.gitignore ADDED
@@ -0,0 +1,123 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Byte-compiled / optimized / DLL files
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+
6
+ # C extensions
7
+ *.so
8
+
9
+ # Distribution / packaging
10
+ .Python
11
+ build/
12
+ develop-eggs/
13
+ dist/
14
+ downloads/
15
+ eggs/
16
+ .eggs/
17
+ lib/
18
+ lib64/
19
+ parts/
20
+ sdist/
21
+ var/
22
+ wheels/
23
+ share/python-wheels/
24
+ *.egg-info/
25
+ .installed.cfg
26
+ *.egg
27
+ MANIFEST
28
+
29
+ # Virtual environment
30
+ venv/
31
+ ENV/
32
+ env/
33
+ .venv/
34
+ .env/
35
+ env.bak/
36
+ venv.bak/
37
+
38
+ # PyInstaller
39
+ # Usually these files are written by a python script from a template
40
+ # before PyInstaller builds the exe, so as to inject date/other infos into it.
41
+ *.manifest
42
+ *.spec
43
+
44
+ # Installer logs
45
+ pip-log.txt
46
+ pip-delete-this-directory.txt
47
+
48
+ # Unit test / coverage reports
49
+ htmlcov/
50
+ .tox/
51
+ .nox/
52
+ .coverage
53
+ .coverage.*
54
+ .cache
55
+ nosetests.xml
56
+ coverage.xml
57
+ *.cover
58
+ *.py,cover
59
+ .hypothesis/
60
+ .pytest_cache/
61
+ cover/
62
+
63
+ # Translations
64
+ *.mo
65
+ *.pot
66
+
67
+ # Django stuff:
68
+ *.log
69
+ local_settings.py
70
+ db.sqlite3
71
+ db.sqlite3-journal
72
+
73
+ # Flask stuff:
74
+ instance/
75
+ .webassets-cache
76
+
77
+ # Scrapy stuff:
78
+ .scrapy
79
+
80
+ # Sphinx documentation
81
+ docs/_build/
82
+
83
+ # PyBuilder
84
+ target/
85
+
86
+ # Jupyter Notebook
87
+ .ipynb_checkpoints
88
+
89
+ # IPython
90
+ profile_default/
91
+ ipython_config.py
92
+
93
+ # pyenv
94
+ .python-version
95
+
96
+ # celery beat schedule file
97
+ celerybeat-schedule
98
+ celerybeat.pid
99
+
100
+ # SageMath parsed files
101
+ *.sage.py
102
+
103
+ # Environments
104
+ .env
105
+ .venv
106
+ env/
107
+ venv/
108
+ ENV/
109
+ env.bak/
110
+ venv.bak/
111
+ .spyderproject
112
+ .spyproject
113
+
114
+ # mkdocs documentation
115
+ /site
116
+
117
+ # mypy
118
+ .mypy_cache/
119
+ .dmypy.json
120
+ dmypy.json
121
+
122
+ # Pyre type checker
123
+ .pyre/
.gradio/certificate.pem ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ -----BEGIN CERTIFICATE-----
2
+ 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
31
+ -----END CERTIFICATE-----
README.md CHANGED
@@ -1,12 +1,6 @@
1
  ---
2
- title: Firefox Chat
3
- emoji: 🚀
4
- colorFrom: yellow
5
- colorTo: red
6
  sdk: gradio
7
  sdk_version: 5.20.0
8
- app_file: app.py
9
- pinned: false
10
  ---
11
-
12
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
1
  ---
2
+ title: firefox-chat
3
+ app_file: app.py
 
 
4
  sdk: gradio
5
  sdk_version: 5.20.0
 
 
6
  ---
 
 
app.py ADDED
@@ -0,0 +1,172 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import json
3
+ from urllib.parse import parse_qs, urlparse
4
+
5
+ # Function to process messages with context
6
+ def process_message(message, history, context_json):
7
+ # Parse context from JSON string
8
+ try:
9
+ context = json.loads(context_json)
10
+ except:
11
+ context = {"error": "Invalid context data"}
12
+
13
+ # Here you would connect to your chatbot backend
14
+ # and provide both the message and the context
15
+
16
+ # For demo purposes, we'll just echo the message with context info
17
+ response = f"Received: {message}\n\nContext summary: Page titled '{context.get('title', 'Unknown')}'"
18
+
19
+ # Format response for Gradio Chatbot using the newer messages format
20
+ history.append({"role": "user", "content": message})
21
+ history.append({"role": "assistant", "content": response})
22
+ return history
23
+
24
+ # Create Gradio interface
25
+ with gr.Blocks(css="#chatbot {height: 400px; overflow-y: auto;}") as demo:
26
+ gr.HTML("<h2>Contextual Chatbot</h2>")
27
+
28
+ # Hidden context state - will be updated via JavaScript
29
+ context_json = gr.State('{}')
30
+
31
+ # Optional: Show context for debugging
32
+ with gr.Accordion("Page Context", open=False):
33
+ context_display = gr.JSON(value={})
34
+ update_button = gr.Button("Request Full Context")
35
+
36
+ # Main chatbot interface
37
+ chatbot = gr.Chatbot(value=[], type="messages")
38
+ msg = gr.Textbox(placeholder="Ask about this page...")
39
+ clear = gr.Button("Clear")
40
+
41
+ # Handle sending messages
42
+ msg.submit(process_message, [msg, chatbot, context_json], [chatbot])
43
+
44
+ # Clear chat history
45
+ clear.click(lambda: [], None, chatbot, queue=False)
46
+
47
+ # JavaScript to handle context
48
+ gr.HTML("""
49
+ <script>
50
+ // Debug function
51
+ function logDebug(message, data) {
52
+ console.log(`[DEBUG] ${message}`, data);
53
+ }
54
+
55
+ // Function to update the context state in Gradio
56
+ function updateContextState(contextData) {
57
+ logDebug("Updating context state with:", contextData);
58
+
59
+ // Find the hidden state element for context
60
+ const stateElements = Array.from(document.querySelectorAll('input[type="hidden"]'));
61
+ const contextStateElem = stateElements.find(el => el.name && el.name.includes('context_json'));
62
+
63
+ if (contextStateElem) {
64
+ // Update the hidden input value
65
+ contextStateElem.value = JSON.stringify(contextData);
66
+
67
+ // Create and dispatch a change event
68
+ const event = new Event('change', { bubbles: true });
69
+ contextStateElem.dispatchEvent(event);
70
+
71
+ logDebug("Context state updated", contextStateElem.value);
72
+ return true;
73
+ } else {
74
+ console.error("Could not find context state element");
75
+ return false;
76
+ }
77
+ }
78
+
79
+ // Function to update the visible JSON display
80
+ function updateJsonDisplay(contextData) {
81
+ logDebug("Updating JSON display with:", contextData);
82
+
83
+ // Find the JSON component's textarea
84
+ const jsonTextarea = document.querySelector('.json-component textarea');
85
+ if (jsonTextarea) {
86
+ jsonTextarea.value = JSON.stringify(contextData, null, 2);
87
+
88
+ // Find and click the submit button to update the value
89
+ const submitButton = jsonTextarea.closest('.json-component').querySelector('button');
90
+ if (submitButton) {
91
+ submitButton.click();
92
+ logDebug("JSON display updated");
93
+ return true;
94
+ }
95
+ }
96
+
97
+ console.error("Could not update JSON display");
98
+ return false;
99
+ }
100
+
101
+ // Function to request full context
102
+ function requestFullContext() {
103
+ logDebug("Requesting full context from parent");
104
+ window.parent.postMessage({type: 'getFullContext'}, '*');
105
+ }
106
+
107
+ // Try to get context from URL parameters
108
+ function getContextFromUrl() {
109
+ const urlParams = new URLSearchParams(window.location.search);
110
+ const contextParam = urlParams.get('context');
111
+ if (contextParam) {
112
+ try {
113
+ const parsedContext = JSON.parse(decodeURIComponent(contextParam));
114
+ logDebug("Got context from URL:", parsedContext);
115
+ return parsedContext;
116
+ } catch (e) {
117
+ console.error("Failed to parse context from URL:", e);
118
+ }
119
+ }
120
+ return null;
121
+ }
122
+
123
+ // Listen for messages from parent (extension)
124
+ window.addEventListener('message', function(event) {
125
+ logDebug("Received message from parent:", event.data);
126
+
127
+ if (event.data.type === 'fullContext') {
128
+ // We got context data from the parent
129
+ const contextData = event.data.content;
130
+
131
+ // Update both the hidden state and visible display
132
+ updateContextState(contextData);
133
+ updateJsonDisplay(contextData);
134
+ }
135
+ });
136
+
137
+ // Initialize when the page is fully loaded
138
+ document.addEventListener('DOMContentLoaded', function() {
139
+ logDebug("DOM fully loaded");
140
+
141
+ // Wait for Gradio to fully initialize
142
+ setTimeout(function() {
143
+ logDebug("Initializing context handling");
144
+
145
+ // Set up the update button
146
+ const updateButton = document.querySelector('button.update-button');
147
+ if (updateButton) {
148
+ updateButton.addEventListener('click', requestFullContext);
149
+ logDebug("Update button handler attached");
150
+ }
151
+
152
+ // First try to get context from URL
153
+ const urlContext = getContextFromUrl();
154
+ if (urlContext) {
155
+ updateContextState(urlContext);
156
+ updateJsonDisplay(urlContext);
157
+ } else {
158
+ // If no URL context, request from parent
159
+ requestFullContext();
160
+ }
161
+ }, 2000); // Wait longer for Gradio to initialize
162
+ });
163
+ </script>
164
+ """)
165
+
166
+ # Add class to update button for JavaScript selection
167
+ update_button.elem_classes = ["update-button"]
168
+
169
+ # Launch the app
170
+ if __name__ == "__main__":
171
+ demo.launch(share=True)
172
+
requirements.txt ADDED
@@ -0,0 +1 @@
 
 
1
+ gradio>=4.0.0