Merge branch 'master' of github.com:Significant-Gravitas/AutoGPT into dev

This commit is contained in:
Zamil Majdy
2026-03-26 07:30:56 +07:00
5 changed files with 52 additions and 40 deletions

View File

@@ -9,6 +9,7 @@ from datetime import datetime, timezone
from typing import Optional
import pydantic
from prisma.errors import UniqueViolationError
from prisma.models import UserWorkspace, UserWorkspaceFile
from prisma.types import UserWorkspaceFileWhereInput
@@ -75,22 +76,23 @@ async def get_or_create_workspace(user_id: str) -> Workspace:
"""
Get user's workspace, creating one if it doesn't exist.
Uses upsert to handle race conditions when multiple concurrent requests
attempt to create a workspace for the same user.
Args:
user_id: The user's ID
Returns:
Workspace instance
"""
workspace = await UserWorkspace.prisma().upsert(
where={"userId": user_id},
data={
"create": {"userId": user_id},
"update": {}, # No updates needed if exists
},
)
workspace = await UserWorkspace.prisma().find_unique(where={"userId": user_id})
if workspace:
return Workspace.from_db(workspace)
try:
workspace = await UserWorkspace.prisma().create(data={"userId": user_id})
except UniqueViolationError:
# Concurrent request already created it
workspace = await UserWorkspace.prisma().find_unique(where={"userId": user_id})
if workspace is None:
raise
return Workspace.from_db(workspace)

View File

@@ -21,6 +21,31 @@ class DiscordChannel(str, Enum):
PRODUCT = "product" # For product alerts (low balance, zero balance, etc.)
_USER_AUTH_KEYWORDS = [
"incorrect api key",
"invalid x-api-key",
"invalid api key",
"missing authentication header",
"invalid api token",
"authentication_error",
"bad credentials",
"unauthorized",
"insufficient authentication scopes",
"http 401 error",
"http 403 error",
]
_AMQP_KEYWORDS = [
"amqpconnection",
"amqpconnector",
"connection_forced",
"channelinvalidstateerror",
"no active transport",
]
_AMQP_INDICATORS = ["aio_pika", "aiormq", "amqp", "pika", "rabbitmq"]
def _before_send(event, hint):
"""Filter out expected/transient errors from Sentry to reduce noise."""
if "exc_info" in hint:
@@ -28,36 +53,21 @@ def _before_send(event, hint):
exc_msg = str(exc_value).lower() if exc_value else ""
# AMQP/RabbitMQ transient connection errors — expected during deploys
amqp_keywords = [
"amqpconnection",
"amqpconnector",
"connection_forced",
"channelinvalidstateerror",
"no active transport",
]
if any(kw in exc_msg for kw in amqp_keywords):
if any(kw in exc_msg for kw in _AMQP_KEYWORDS):
return None
# "connection refused" only for AMQP-related exceptions (not other services)
if "connection refused" in exc_msg:
exc_module = getattr(exc_type, "__module__", "") or ""
exc_name = getattr(exc_type, "__name__", "") or ""
amqp_indicators = ["aio_pika", "aiormq", "amqp", "pika", "rabbitmq"]
if any(
ind in exc_module.lower() or ind in exc_name.lower()
for ind in amqp_indicators
) or any(kw in exc_msg for kw in ["amqp", "pika", "rabbitmq"]):
for ind in _AMQP_INDICATORS
) or any(kw in exc_msg for kw in _AMQP_INDICATORS):
return None
# User-caused credential/auth errors — not platform bugs
user_auth_keywords = [
"incorrect api key",
"invalid x-api-key",
"missing authentication header",
"invalid api token",
"authentication_error",
]
if any(kw in exc_msg for kw in user_auth_keywords):
# User-caused credential/auth/integration errors — not platform bugs
if any(kw in exc_msg for kw in _USER_AUTH_KEYWORDS):
return None
# Expected business logic — insufficient balance
@@ -93,18 +103,18 @@ def _before_send(event, hint):
)
if event.get("logger") and log_msg:
msg = log_msg.lower()
noisy_patterns = [
noisy_log_patterns = [
"amqpconnection",
"connection_forced",
"unclosed client session",
"unclosed connector",
]
if any(p in msg for p in noisy_patterns):
if any(p in msg for p in noisy_log_patterns):
return None
# "connection refused" in logs only when AMQP-related context is present
if "connection refused" in msg and any(
ind in msg for ind in ("amqp", "pika", "rabbitmq", "aio_pika", "aiormq")
):
if "connection refused" in msg and any(ind in msg for ind in _AMQP_INDICATORS):
return None
# Same auth keywords — errors logged via logger.error() bypass exc_info
if any(kw in msg for kw in _USER_AUTH_KEYWORDS):
return None
return event

View File

@@ -290,12 +290,12 @@ export function ChatSidebar() {
<div className="flex min-h-[30rem] items-center justify-center py-4">
<LoadingSpinner size="small" className="text-neutral-600" />
</div>
) : sessions.length === 0 ? (
) : !sessions?.length ? (
<p className="py-4 text-center text-sm text-neutral-500">
No conversations yet
</p>
) : (
sessions.map((session) => (
sessions?.map((session) => (
<div
key={session.id}
className={cn(

View File

@@ -20,7 +20,7 @@ export function UsageLimits() {
},
});
if (isLoading || !usage) return null;
if (isLoading || !usage?.daily || !usage?.weekly) return null;
if (usage.daily.limit <= 0 && usage.weekly.limit <= 0) return null;
return (

View File

@@ -34,7 +34,7 @@ function CoPilotUsageSection() {
},
});
if (isLoading || !usage) return null;
if (isLoading || !usage?.daily || !usage?.weekly) return null;
if (usage.daily.limit <= 0 && usage.weekly.limit <= 0) return null;
return (