Fix API URL (api.greenpt.ai), add models command, remove debug logging

This commit is contained in:
2026-08-16 23:07:29 -05:00
parent 4028f8ef20
commit ca541c2e82
+88 -13
View File
@@ -1,11 +1,8 @@
import logging
import aiohttp import aiohttp
import discord import discord
from redbot.core import commands, Config, checks from redbot.core import commands, Config, checks
from redbot.core.bot import Red from redbot.core.bot import Red
log = logging.getLogger("red.assistant")
class APIKeyModal(discord.ui.Modal): class APIKeyModal(discord.ui.Modal):
def __init__(self, config): def __init__(self, config):
@@ -38,7 +35,7 @@ class APIKeyButton(discord.ui.View):
class Assistant(commands.Cog): class Assistant(commands.Cog):
"""AI chatbot assistant. Set a chat channel or get responses when the bot is pinged.""" """AI chatbot assistant. Set a chat channel or get responses when the bot is pinged."""
BASE_URL = "https://greenpt.com/v1" BASE_URL = "https://api.greenpt.ai/v1"
def __init__(self, bot: Red): def __init__(self, bot: Red):
self.bot = bot self.bot = bot
@@ -75,19 +72,12 @@ class Assistant(commands.Cog):
guild = message.guild guild = message.guild
if self.bot.user in message.mentions:
log.info("[ASSISTANT DEBUG] Mention detected from %s in #%s", message.author, message.channel)
enabled = await self.config.guild(guild).enabled() enabled = await self.config.guild(guild).enabled()
if not enabled: if not enabled:
if self.bot.user in message.mentions:
log.info("[ASSISTANT DEBUG] Guild %s is disabled", guild.id)
return return
api_key = await self.config.api_key() api_key = await self.config.api_key()
if not api_key: if not api_key:
if self.bot.user in message.mentions:
log.info("[ASSISTANT DEBUG] No API key set")
return return
chat_channel_id = await self.config.guild(guild).chat_channel() chat_channel_id = await self.config.guild(guild).chat_channel()
@@ -99,8 +89,6 @@ class Assistant(commands.Cog):
if not is_chat_channel and not is_ping: if not is_chat_channel and not is_ping:
return return
log.info("[ASSISTANT DEBUG] Processing message, is_ping=%s, is_chat_channel=%s", is_ping, is_chat_channel)
content = message.content content = message.content
if is_ping: if is_ping:
for mention in (f"<@{self.bot.user.id}>", f"<@!{self.bot.user.id}>"): for mention in (f"<@{self.bot.user.id}>", f"<@!{self.bot.user.id}>"):
@@ -225,6 +213,93 @@ class Assistant(commands.Cog):
await self.config.guild(ctx.guild).model.set(model) await self.config.guild(ctx.guild).model.set(model)
await ctx.send(f"Model set to **{model}**.") await ctx.send(f"Model set to **{model}**.")
@assistant.command(name="models")
async def assistant_models(self, ctx: commands.Context):
"""List available models sorted by cost (cheapest first)."""
# Pricing per 1M tokens (EUR) from GreenPT docs
MODEL_PRICING = {
"deepseek-v4-flash-0731": {"input": 0.14, "output": 0.35},
"minimax-m2.5": {"input": 0.17, "output": 0.99},
"mistral-small-3.2-24b-instruct-2506": {"input": 0.20, "output": 0.40},
"gpt-oss-120b": {"input": 0.20, "output": 0.70},
"voxtral-small-24b-2507": {"input": 0.20, "output": 0.45},
"green-l": {"input": 0.25, "output": 0.80},
"green-l-raw": {"input": 0.25, "output": 0.80},
"qwen3-coder-30b-a3b-instruct": {"input": 0.25, "output": 0.95},
"gemma-3-27b-it": {"input": 0.30, "output": 0.60},
"qwen3.6-35b-a3b": {"input": 0.30, "output": 1.80},
"green-r": {"input": 0.35, "output": 0.95},
"green-r-raw": {"input": 0.35, "output": 0.95},
"gemma4": {"input": 0.50, "output": 1.50},
"devstral-2-123b-instruct-2512": {"input": 0.50, "output": 2.40},
"kimi-k2.6": {"input": 0.66, "output": 3.75},
"qwen3.5-397b-a17b": {"input": 0.70, "output": 4.35},
"kimi-k2.7-code": {"input": 0.79, "output": 3.85},
"qwen3-235b-a22b-instruct-2507": {"input": 0.90, "output": 2.70},
"glm-5.2": {"input": 1.10, "output": 4.40},
"llama-3.3-70b-instruct": {"input": 1.10, "output": 1.10},
"mistral-medium-3.5-128b": {"input": 1.80, "output": 9.00},
"kimi-k3": {"input": 3.30, "output": 16.50},
}
api_key = await self.config.api_key()
if not api_key or not self.session:
await ctx.send("API key not set. Use `[p]assistant setkey` first.")
return
# Fetch live model list from API
try:
async with self.session.get(
f"{self.BASE_URL}/models",
headers={"Authorization": f"Bearer {api_key}"},
timeout=aiohttp.ClientTimeout(total=15),
) as resp:
if resp.status != 200:
await ctx.send(f"Failed to fetch models (HTTP {resp.status}).")
return
data = await resp.json()
except Exception as exc:
await ctx.send(f"Request failed: {exc}")
return
models = data.get("data", [])
if not models:
await ctx.send("No models returned by the API.")
return
# Build list with pricing, sorted by combined cost (input + output)
current_model = await self.config.guild(ctx.guild).model()
lines = []
model_entries = []
for m in models:
model_id = m["id"]
pricing = MODEL_PRICING.get(model_id)
if pricing:
total = pricing["input"] + pricing["output"]
model_entries.append((total, model_id, pricing))
else:
# Unknown pricing, put at the end
model_entries.append((9999, model_id, None))
model_entries.sort(key=lambda x: x[0])
for total, model_id, pricing in model_entries:
marker = " ◀" if model_id == current_model else ""
if pricing:
lines.append(
f"`{model_id}` — €{pricing['input']:.2f} in / €{pricing['output']:.2f} out{marker}"
)
else:
lines.append(f"`{model_id}` — pricing unknown{marker}")
embed = discord.Embed(
title="Available Models (cheapest first)",
description="\n".join(lines),
color=await ctx.embed_color(),
)
embed.set_footer(text="Prices in EUR per 1M tokens. ◀ = current model.")
await ctx.send(embed=embed)
@assistant.command(name="temp") @assistant.command(name="temp")
async def assistant_temp(self, ctx: commands.Context, temperature: float): async def assistant_temp(self, ctx: commands.Context, temperature: float):
"""Set the temperature (0.0 - 2.0).""" """Set the temperature (0.0 - 2.0)."""