pushing updates for bot
All checks were successful
OpenWebUI Discord Bot / Build-and-Push (push) Successful in 1m0s

This commit is contained in:
Josh Knapp 2025-01-02 19:38:42 -08:00
parent 6c57a8591f
commit 91bbe303ba
4 changed files with 160 additions and 15 deletions

1
.gitignore vendored
View File

@ -1 +1,2 @@
scripts/.env scripts/.env
v2/.env

View File

@ -0,0 +1,100 @@
"""
title: Bedrock Image Description
author: Josh Knapp
version: 0.1.0
description="Provide Direct Bedrock call for image generation"
"""
import subprocess
import json
from pydantic import BaseModel, Field
# Try to import boto3, install if not present
try:
import boto3
except ImportError:
print("boto3 package not found. Attempting to install...")
try:
subprocess.check_call([sys.executable, "-m", "pip", "install", "boto3"])
import boto3
print("boto3 package installed successfully")
except subprocess.CalledProcessError as e:
print(f"Failed to install boto3 package: {str(e)}")
class Tools:
class Valves(BaseModel):
AWS_ACCESS_KEY: str = Field(
default="",
description="AWS Access Key",
)
AWS_SECRET_KEY: str = Field(
default="",
description="AWS Secret Key",
)
AWS_BEDROCK_MODEL: str = Field(
default="",
description="AWS Bedrock Model to use"
)
def __init__(self):
self.valves = self.Valves()
pass
def analyze_image(self, base64_image: str) -> str:
"""
Analyze an image using AWS Bedrock's vision model
Args:
base64_image (str): Base64 encoded image string
Returns:
str: Description of the image
"""
try:
# Initialize Bedrock runtime client
bedrock = boto3.client(
service_name="bedrock-runtime",
aws_access_key_id=self.valves.AWS_ACCESS_KEY,
aws_secret_access_key=self.valves.AWS_SECRET_KEY,
region_name="us-east-1" # or your preferred region
)
# Prepare the request body
request_body = {
"anthropic_version": "bedrock-2023-05-31",
"max_tokens": 1000,
"messages": [
{
"role": "user",
"content": [
{
"type": "image",
"source": {
"type": "base64",
"media_type": "image/jpeg",
"data": base64_image
}
},
{
"type": "text",
"text": "Please describe this image in detail."
}
]
}
]
}
# Invoke the model
response = bedrock.invoke_model(
modelId=self.valves.AWS_BEDROCK_MODEL,
body=json.dumps(request_body)
)
# Parse and return the response
response_body = json.loads(response['body'].read())
return response_body['messages'][0]['content'][0]['text']
except Exception as e:
print(f"Error analyzing image: {str(e)}")
return f"Error analyzing image: {str(e)}"

View File

@ -0,0 +1,5 @@
For any model to use this tool, you must set the valve values, and add something to the model to let it know to use the tool.
```
You have access to a tool that allows you to get descriptions of images called "Bedrock Image Description". Any image handling should be sent through this tool.
```

View File

@ -1,9 +1,10 @@
import os import os
import discord import discord
from discord.ext import commands from discord.ext import commands
import openai
from openai import OpenAI from openai import OpenAI
import base64
import requests
from io import BytesIO
from collections import deque from collections import deque
from dotenv import load_dotenv from dotenv import load_dotenv
@ -35,28 +36,55 @@ bot = commands.Bot(command_prefix='!', intents=intents)
# Message history cache # Message history cache
channel_history = {} channel_history = {}
async def download_image(url):
response = requests.get(url)
if response.status_code == 200:
image_data = BytesIO(response.content)
base64_image = base64.b64encode(image_data.read()).decode('utf-8')
return base64_image
return None
async def get_chat_history(channel, limit=100): async def get_chat_history(channel, limit=100):
messages = [] messages = []
async for message in channel.history(limit=limit): async for message in channel.history(limit=limit):
messages.append(f"{message.author.name}: {message.content}") content = f"{message.author.name}: {message.content}"
# Handle attachments (images)
for attachment in message.attachments:
if any(attachment.filename.lower().endswith(ext) for ext in ['.png', '.jpg', '.jpeg', '.gif', '.webp']):
content += f" [Image: {attachment.url}]"
messages.append(content)
return "\n".join(reversed(messages)) return "\n".join(reversed(messages))
async def get_ai_response(context, user_message): async def get_ai_response(context, user_message, image_urls=None):
formatted_prompt = f"##CONTEXT##\n{context}\n##ENDCONTEXT##\n\n{user_message}" messages = [{"role": "user", "content": []}]
# Add text content
text_content = f"##CONTEXT##\n{context}\n##ENDCONTEXT##\n\n{user_message}"
messages[0]["content"].append({"type": "text", "text": text_content})
# Add image content if present
if image_urls:
for url in image_urls:
base64_image = await download_image(url)
if base64_image:
messages[0]["content"].append({
"type": "image_url",
"image_url": {
"url": f"data:image/jpeg;base64,{base64_image}"
}
})
try: try:
response = client.chat.completions.create(model=MODEL_NAME, response = client.chat.completions.create(
messages=[ model=MODEL_NAME,
{"role": "user", "content": formatted_prompt} messages=messages
]) )
return response.choices[0].message.content return response.choices[0].message.content
except Exception as e: except Exception as e:
return f"Error: {str(e)}" return f"Error: {str(e)}"
@bot.event
async def on_ready():
print(f'{bot.user} has connected to Discord!')
@bot.event @bot.event
async def on_message(message): async def on_message(message):
# Ignore messages from the bot itself # Ignore messages from the bot itself
@ -81,14 +109,25 @@ async def on_message(message):
# Remove bot mention from the message # Remove bot mention from the message
user_message = message.content.replace(f'<@{bot.user.id}>', '').strip() user_message = message.content.replace(f'<@{bot.user.id}>', '').strip()
# Collect image URLs from the message
image_urls = []
for attachment in message.attachments:
if any(attachment.filename.lower().endswith(ext) for ext in ['.png', '.jpg', '.jpeg', '.gif', '.webp']):
image_urls.append(attachment.url)
# Get AI response # Get AI response
response = await get_ai_response(history, user_message) response = await get_ai_response(history, user_message, image_urls)
# Send response # Send response
await message.reply(response) await message.reply(response)
await bot.process_commands(message) await bot.process_commands(message)
@bot.event
async def on_ready():
print(f'{bot.user} has connected to Discord!')
def main(): def main():
if not all([DISCORD_TOKEN, OPENAI_API_KEY, OPENWEBUI_API_BASE, MODEL_NAME]): if not all([DISCORD_TOKEN, OPENAI_API_KEY, OPENWEBUI_API_BASE, MODEL_NAME]):
print("Error: Missing required environment variables") print("Error: Missing required environment variables")