mirror of
				https://github.com/open-webui/bot
				synced 2025-06-26 18:16:24 +00:00 
			
		
		
		
	feat: ai bot example
This commit is contained in:
		
							parent
							
								
									7f356751bb
								
							
						
					
					
						commit
						be50962884
					
				| @ -10,15 +10,15 @@ This repository provides an experimental boilerplate for building bots compatibl | ||||
| ## 🛠️ Getting Started with Examples | ||||
| This repository includes an `/examples` folder containing runnable example bots that demonstrate basic functionality.  | ||||
| 
 | ||||
| To run an example, execute the corresponding module using the `-m` flag in Python. For example, to run the `ollama` example: | ||||
| To run an example, execute the corresponding module using the `-m` flag in Python. For example, to run the `ai` example: | ||||
| 
 | ||||
| ```bash | ||||
| python -m examples.ollama | ||||
| python -m examples.ai | ||||
| ``` | ||||
| 
 | ||||
| > **Note**: Ensure that your current working directory (PWD) is the root of this repository when running examples, as this is required for proper execution. | ||||
| 
 | ||||
| Replace `ollama` in the command above with the specific example you’d like to execute from the `/examples` folder. | ||||
| Replace `ai` in the command above with the specific example you’d like to execute from the `/examples` folder. | ||||
| 
 | ||||
| ## 🚧 Disclaimer | ||||
| This project is an early-stage proof of concept. **APIs will break** and existing functionality may change as Open WebUI evolves to include native bot support. This repository is not production-ready and primarily serves experimental and exploratory purposes. | ||||
|  | ||||
							
								
								
									
										129
									
								
								examples/ai.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										129
									
								
								examples/ai.py
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,129 @@ | ||||
| import asyncio | ||||
| import socketio | ||||
| from env import WEBUI_URL, TOKEN | ||||
| from utils import send_message, send_typing | ||||
| 
 | ||||
| 
 | ||||
| MODEL_ID = "llama3.2:latest" | ||||
| 
 | ||||
| # Create an asynchronous Socket.IO client instance | ||||
| sio = socketio.AsyncClient(logger=False, engineio_logger=False) | ||||
| 
 | ||||
| 
 | ||||
| # Event handlers | ||||
| @sio.event | ||||
| async def connect(): | ||||
|     print("Connected!") | ||||
| 
 | ||||
| 
 | ||||
| @sio.event | ||||
| async def disconnect(): | ||||
|     print("Disconnected from the server!") | ||||
| 
 | ||||
| 
 | ||||
| import aiohttp | ||||
| import asyncio | ||||
| 
 | ||||
| 
 | ||||
| async def openai_chat_completion(messages): | ||||
|     payload = { | ||||
|         "model": MODEL_ID, | ||||
|         "messages": messages, | ||||
|         "stream": False, | ||||
|     } | ||||
| 
 | ||||
|     async with aiohttp.ClientSession() as session: | ||||
|         async with session.post( | ||||
|             f"{WEBUI_URL}/api/chat/completions", | ||||
|             headers={"Authorization": f"Bearer {TOKEN}"}, | ||||
|             json=payload, | ||||
|         ) as response: | ||||
|             if response.status == 200: | ||||
|                 return await response.json() | ||||
|             else: | ||||
|                 # Optional: Handle errors or return raw response text | ||||
|                 return {"error": await response.text(), "status": response.status} | ||||
| 
 | ||||
| 
 | ||||
| # Define a function to handle channel events | ||||
| def events(user_id): | ||||
|     @sio.on("channel-events") | ||||
|     async def channel_events(data): | ||||
|         if data["user"]["id"] == user_id: | ||||
|             # Ignore events from the bot itself | ||||
|             return | ||||
| 
 | ||||
|         if data["data"]["type"] == "message": | ||||
|             print(f'{data["user"]["name"]}: {data["data"]["data"]["content"]}') | ||||
|             await send_typing(sio, data["channel_id"]) | ||||
| 
 | ||||
|             async def send_typing_until_complete(channel_id, coro): | ||||
|                 """ | ||||
|                 Sends typing indicators every second until the provided coroutine completes. | ||||
|                 """ | ||||
|                 task = asyncio.create_task(coro)  # Begin the provided coroutine task | ||||
|                 try: | ||||
|                     # While the task is running, send typing indicators every second | ||||
|                     while not task.done(): | ||||
|                         await send_typing(sio, channel_id) | ||||
|                         await asyncio.sleep(1) | ||||
|                     # Await the actual result of the coroutine | ||||
|                     return await task | ||||
|                 except Exception as e: | ||||
|                     task.cancel() | ||||
|                     raise e  # Propagate any exceptions that occurred in the coroutine | ||||
| 
 | ||||
|             # OpenAI API coroutine | ||||
|             openai_task = openai_chat_completion( | ||||
|                 [ | ||||
|                     {"role": "system", "content": "You are a friendly AI."}, | ||||
|                     {"role": "user", "content": data["data"]["data"]["content"]}, | ||||
|                 ] | ||||
|             ) | ||||
| 
 | ||||
|             try: | ||||
|                 # Run OpenAI coroutine while showing typing indicators | ||||
|                 response = await send_typing_until_complete( | ||||
|                     data["channel_id"], openai_task | ||||
|                 ) | ||||
| 
 | ||||
|                 if response.get("choices"): | ||||
|                     completion = response["choices"][0]["message"]["content"] | ||||
|                     await send_message(data["channel_id"], completion) | ||||
|                 else: | ||||
|                     await send_message( | ||||
|                         data["channel_id"], "I'm sorry, I don't understand." | ||||
|                     ) | ||||
|             except Exception: | ||||
|                 await send_message( | ||||
|                     data["channel_id"], | ||||
|                     "Something went wrong while processing your request.", | ||||
|                 ) | ||||
| 
 | ||||
| 
 | ||||
| # Define an async function for the main workflow | ||||
| async def main(): | ||||
|     try: | ||||
|         print(f"Connecting to {WEBUI_URL}...") | ||||
|         await sio.connect( | ||||
|             WEBUI_URL, socketio_path="/ws/socket.io", transports=["websocket"] | ||||
|         ) | ||||
|         print("Connection established!") | ||||
|     except Exception as e: | ||||
|         print(f"Failed to connect: {e}") | ||||
|         return | ||||
| 
 | ||||
|     # Callback function for user-join | ||||
|     async def join_callback(data): | ||||
|         events(data["id"])  # Attach the event handlers dynamically | ||||
| 
 | ||||
|     # Authenticate with the server | ||||
|     await sio.emit("user-join", {"auth": {"token": TOKEN}}, callback=join_callback) | ||||
| 
 | ||||
|     # Wait indefinitely to keep the connection open | ||||
|     await sio.wait() | ||||
| 
 | ||||
| 
 | ||||
| # Actually run the async `main` function using `asyncio` | ||||
| if __name__ == "__main__": | ||||
|     asyncio.run(main()) | ||||
| @ -1,61 +0,0 @@ | ||||
| import asyncio | ||||
| import socketio | ||||
| from env import WEBUI_URL, TOKEN | ||||
| from utils import send_message, send_typing | ||||
| 
 | ||||
| # Create an asynchronous Socket.IO client instance | ||||
| sio = socketio.AsyncClient(logger=False, engineio_logger=False) | ||||
| 
 | ||||
| 
 | ||||
| # Event handlers | ||||
| @sio.event | ||||
| async def connect(): | ||||
|     print("Connected!") | ||||
| 
 | ||||
| 
 | ||||
| @sio.event | ||||
| async def disconnect(): | ||||
|     print("Disconnected from the server!") | ||||
| 
 | ||||
| 
 | ||||
| # Define a function to handle channel events | ||||
| def events(user_id): | ||||
|     @sio.on("channel-events") | ||||
|     async def channel_events(data): | ||||
|         if data["user"]["id"] == user_id: | ||||
|             # Ignore events from the bot itself | ||||
|             return | ||||
| 
 | ||||
|         if data["data"]["type"] == "message": | ||||
|             print(f'{data["user"]["name"]}: {data["data"]["data"]["content"]}') | ||||
|             await send_typing(sio, data["channel_id"]) | ||||
|             await asyncio.sleep(1)  # Simulate a delay | ||||
|             await send_message(data["channel_id"], "Pong!") | ||||
| 
 | ||||
| 
 | ||||
| # Define an async function for the main workflow | ||||
| async def main(): | ||||
|     try: | ||||
|         print(f"Connecting to {WEBUI_URL}...") | ||||
|         await sio.connect( | ||||
|             WEBUI_URL, socketio_path="/ws/socket.io", transports=["websocket"] | ||||
|         ) | ||||
|         print("Connection established!") | ||||
|     except Exception as e: | ||||
|         print(f"Failed to connect: {e}") | ||||
|         return | ||||
| 
 | ||||
|     # Callback function for user-join | ||||
|     async def join_callback(data): | ||||
|         events(data["id"])  # Attach the event handlers dynamically | ||||
| 
 | ||||
|     # Authenticate with the server | ||||
|     await sio.emit("user-join", {"auth": {"token": TOKEN}}, callback=join_callback) | ||||
| 
 | ||||
|     # Wait indefinitely to keep the connection open | ||||
|     await sio.wait() | ||||
| 
 | ||||
| 
 | ||||
| # Actually run the async `main` function using `asyncio` | ||||
| if __name__ == "__main__": | ||||
|     asyncio.run(main()) | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user