diff --git a/jupyter/stock.py b/jupyter/stock.py index 610e88e..7e452e7 100644 --- a/jupyter/stock.py +++ b/jupyter/stock.py @@ -692,14 +692,8 @@ class WebServer: def setup_routes(self): """Setup Flask routes""" - @self.app.route('/') - def serve(): - return send_from_directory(self.app.static_folder, 'index.html') - def index(): - return render_template('index.html') - # Basic endpoint for chat completions - @self.app.route('/chat', methods=['POST']) + @self.app.route('/api/chat', methods=['POST']) async def chat(): if not irc_bot: return jsonify({ "error": "Bot not initialized" }), 400 @@ -715,29 +709,38 @@ class WebServer: }), 400 # Context requests - @self.app.route('/history', methods=['GET']) + @self.app.route('/api/history', methods=['GET']) def http_history(): if not irc_bot: return jsonify({ "error": "Bot not initialized" }), 400 return jsonify(irc_bot.history), 200 - @self.app.route('/system', methods=['GET']) + @self.app.route('/api/system', methods=['GET']) def http_system(): if not irc_bot: return jsonify({ "error": "Bot not initialized" }), 400 return jsonify(system_log), 200 - @self.app.route('/tools', methods=['GET']) + @self.app.route('/api/tools', methods=['GET']) def http_tools(): if not irc_bot: return jsonify({ "error": "Bot not initialized" }), 400 return jsonify(tool_log), 200 # Health check endpoint - @self.app.route('/health', methods=['GET']) + @self.app.route('/api/health', methods=['GET']) def health(): return jsonify({"status": "healthy"}), 200 + # Serve React app - This catches all routes not matched by API endpoints + @self.app.route('/', defaults={'path': ''}) + @self.app.route('/') + def serve(path): + if path != "" and os.path.exists(self.app.static_folder + '/' + path): + return send_from_directory(self.app.static_folder, path) + else: + return send_from_directory(self.app.static_folder, 'index.html') + def run(self, host='0.0.0.0', port=5000, debug=False, **kwargs): """Run the web server""" # Load documents diff --git a/src/client/app/(tabs)/about.tsx b/src/client/app/(tabs)/about.tsx index 7e1ee63..d446d6d 100644 --- a/src/client/app/(tabs)/about.tsx +++ b/src/client/app/(tabs)/about.tsx @@ -4,13 +4,14 @@ export default function AboutScreen() { return ( -
Welcome to my AI agent. It has live access to websites, weather, and stock information. You can ask it things like: +
Welcome to Ketr-AI. This AI agent has live access to websites, weather, and stock information. You can ask it things like:
    -
  • What's the current weather?
  • +
  • What's the current weather in Kansas?
  • Can you provide the current headlines from http://cnn.com?
  • What is the current value of the 5 most traded companies?
+
Internally, the system is using the LLAMA3.2 large language model, currently running locally in ollama. Various tools have been enabled for the LLM to use.
); diff --git a/src/client/app/(tabs)/index.tsx b/src/client/app/(tabs)/index.tsx index 0fc090f..23f7153 100644 --- a/src/client/app/(tabs)/index.tsx +++ b/src/client/app/(tabs)/index.tsx @@ -28,7 +28,7 @@ const App = () => { useEffect(() => { const fetchHistory = async () => { try { - const response = await fetch(`${url}/history`); + const response = await fetch(`${url}/api/history`); const data = await response.json(); if (conversation.length != data.length) setConversation(data || []); @@ -69,7 +69,7 @@ const App = () => { try { setLoading(true); // Send query to server - const response = await fetch(`${url}/chat`, { + const response = await fetch(`${url}/api/chat`, { method: 'POST', headers: { 'Content-Type': 'application/json', diff --git a/src/client/app/_layout.tsx b/src/client/app/_layout.tsx index 56c0d20..bfec16f 100644 --- a/src/client/app/_layout.tsx +++ b/src/client/app/_layout.tsx @@ -1,10 +1,18 @@ import { Stack } from 'expo-router'; +import { Helmet } from 'react-helmet'; export default function RootLayout() { return ( - - - - + <> + + Ketr-AI for Everyone + + + + + + + + ); } diff --git a/src/client/assets/favicon.ico b/src/client/assets/favicon.ico new file mode 100755 index 0000000..ddf3b88 Binary files /dev/null and b/src/client/assets/favicon.ico differ diff --git a/src/client/assets/images/favicon.ico b/src/client/assets/images/favicon.ico new file mode 100755 index 0000000..ddf3b88 Binary files /dev/null and b/src/client/assets/images/favicon.ico differ diff --git a/src/client/assets/images/favicon.png b/src/client/assets/images/favicon.png index e75f697..9ad6bf3 100644 Binary files a/src/client/assets/images/favicon.png and b/src/client/assets/images/favicon.png differ diff --git a/src/client/package-lock.json b/src/client/package-lock.json index 127ce73..e7d16dc 100644 --- a/src/client/package-lock.json +++ b/src/client/package-lock.json @@ -26,6 +26,7 @@ "react": "18.3.1", "react-dom": "18.3.1", "react-fontawesome": "^1.7.1", + "react-helmet": "^6.1.0", "react-native": "0.76.7", "react-native-gesture-handler": "~2.20.2", "react-native-markdown-display": "^7.0.2", @@ -11169,6 +11170,20 @@ "react": ">=17.0.0" } }, + "node_modules/react-helmet": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/react-helmet/-/react-helmet-6.1.0.tgz", + "integrity": "sha512-4uMzEY9nlDlgxr61NL3XbKRy1hEkXmKNXhjbAIOVw5vcFrsdYbH2FEwcNyWvWinl103nXgzYNlns9ca+8kFiWw==", + "dependencies": { + "object-assign": "^4.1.1", + "prop-types": "^15.7.2", + "react-fast-compare": "^3.1.1", + "react-side-effect": "^2.1.0" + }, + "peerDependencies": { + "react": ">=16.3.0" + } + }, "node_modules/react-helmet-async": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/react-helmet-async/-/react-helmet-async-1.3.0.tgz", @@ -11494,6 +11509,14 @@ "react": "^16.0.0 || ^17.0.0 || ^18.0.0" } }, + "node_modules/react-side-effect": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/react-side-effect/-/react-side-effect-2.1.2.tgz", + "integrity": "sha512-PVjOcvVOyIILrYoyGEpDN3vmYNLdy1CajSFNt4TDsVQC5KpTijDvWVoR+/7Rz2xT978D8/ZtFceXxzsPwZEDvw==", + "peerDependencies": { + "react": "^16.3.0 || ^17.0.0 || ^18.0.0" + } + }, "node_modules/react-spinners": { "version": "0.15.0", "resolved": "https://registry.npmjs.org/react-spinners/-/react-spinners-0.15.0.tgz", diff --git a/src/client/package.json b/src/client/package.json index 7e41ecf..0dff670 100644 --- a/src/client/package.json +++ b/src/client/package.json @@ -33,6 +33,7 @@ "react": "18.3.1", "react-dom": "18.3.1", "react-fontawesome": "^1.7.1", + "react-helmet": "^6.1.0", "react-native": "0.76.7", "react-native-gesture-handler": "~2.20.2", "react-native-markdown-display": "^7.0.2",