mirror of https://github.com/kortix-ai/suna.git
Merge branch 'main' into perf/remove-dramatiq-worker-rabbitmq
This commit is contained in:
commit
113c0b6ab7
|
@ -207,6 +207,9 @@ async def get_agent_run_with_access_check(client, agent_run_id: str, user_id: st
|
|||
await verify_thread_access(client, thread_id, user_id)
|
||||
return agent_run_data
|
||||
|
||||
|
||||
|
||||
|
||||
@router.post("/thread/{thread_id}/agent/start")
|
||||
async def start_agent(
|
||||
thread_id: str,
|
||||
|
|
|
@ -567,6 +567,7 @@ async def run_agent(
|
|||
logger.info(f"Agent used XML tool: {xml_tool}")
|
||||
if trace:
|
||||
trace.event(name="agent_used_xml_tool", level="DEFAULT", status_message=(f"Agent used XML tool: {xml_tool}"))
|
||||
|
||||
except json.JSONDecodeError:
|
||||
# Handle cases where content might not be valid JSON
|
||||
logger.warning(f"Warning: Could not parse assistant content JSON: {chunk.get('content')}")
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
import { withSentryConfig } from '@sentry/nextjs';
|
||||
import type { NextConfig } from 'next';
|
||||
|
||||
let nextConfig: NextConfig = {
|
||||
const nextConfig: NextConfig = {
|
||||
webpack: (config) => {
|
||||
// This rule prevents issues with pdf.js and canvas
|
||||
config.externals = [...(config.externals || []), { canvas: 'canvas' }];
|
||||
|
@ -14,19 +13,7 @@ let nextConfig: NextConfig = {
|
|||
|
||||
return config;
|
||||
},
|
||||
productionBrowserSourceMaps: true,
|
||||
};
|
||||
|
||||
/** Removing Sentry for now */
|
||||
if (false && process.env.NEXT_PUBLIC_VERCEL_ENV === 'production') {
|
||||
nextConfig = withSentryConfig(nextConfig, {
|
||||
org: 'kortix-ai',
|
||||
project: 'suna-nextjs',
|
||||
silent: !process.env.CI,
|
||||
widenClientFileUpload: true,
|
||||
tunnelRoute: '/monitoring',
|
||||
disableLogger: true,
|
||||
automaticVercelMonitors: true,
|
||||
});
|
||||
}
|
||||
|
||||
export default nextConfig;
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -37,7 +37,6 @@
|
|||
"@radix-ui/react-tabs": "^1.1.8",
|
||||
"@radix-ui/react-tooltip": "^1.2.3",
|
||||
"@react-pdf/renderer": "^4.3.0",
|
||||
"@sentry/nextjs": "^9.22.0",
|
||||
"@silevis/reactgrid": "^4.1.17",
|
||||
"@supabase/ssr": "latest",
|
||||
"@supabase/supabase-js": "latest",
|
||||
|
|
|
@ -13,7 +13,6 @@ import { checkApiHealth } from '@/lib/api';
|
|||
import { MaintenancePage } from '@/components/maintenance/maintenance-page';
|
||||
import { DeleteOperationProvider } from '@/contexts/DeleteOperationContext';
|
||||
import { StatusOverlay } from '@/components/ui/status-overlay';
|
||||
import { VSentry } from '@/components/sentry';
|
||||
import type { IMaintenanceNotice } from '@/lib/edge-flags';
|
||||
import { MaintenanceNotice } from './maintenance-notice';
|
||||
import { MaintenanceBanner } from './maintenance-banner';
|
||||
|
@ -134,7 +133,6 @@ export default function DashboardLayoutContent({
|
|||
onOpenChange={setShowMaintenanceAlert}
|
||||
closeable={true}
|
||||
/>
|
||||
<VSentry />
|
||||
|
||||
{/* Status overlay for deletion operations */}
|
||||
<StatusOverlay />
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
'use client';
|
||||
|
||||
import * as Sentry from '@sentry/nextjs';
|
||||
import NextError from 'next/error';
|
||||
import { useEffect } from 'react';
|
||||
|
||||
|
@ -10,7 +9,7 @@ export default function GlobalError({
|
|||
error: Error & { digest?: string };
|
||||
}) {
|
||||
useEffect(() => {
|
||||
Sentry.captureException(error);
|
||||
console.error(error);
|
||||
}, [error]);
|
||||
|
||||
return (
|
||||
|
|
|
@ -637,8 +637,7 @@ export function PricingSection({
|
|||
Choose the right plan for your needs
|
||||
</h2>
|
||||
<p className="text-muted-foreground text-center text-balance font-medium">
|
||||
Start with our free plan or upgrade to a premium plan for more
|
||||
usage hours
|
||||
Start with our free plan or upgrade for more AI token credits
|
||||
</p>
|
||||
</SectionHeader>
|
||||
<div className="relative w-full h-full">
|
||||
|
@ -691,6 +690,15 @@ export function PricingSection({
|
|||
))}
|
||||
</div>
|
||||
)}
|
||||
<div className="mt-4 p-4 bg-blue-50 dark:bg-blue-950/20 border border-blue-200 dark:border-blue-800 rounded-lg max-w-2xl mx-auto">
|
||||
<p className="text-sm text-blue-800 dark:text-blue-200 text-center">
|
||||
<strong>What are AI tokens?</strong> Tokens are units of text that AI models process.
|
||||
Your plan includes credits to spend on various AI models - the more complex the task,
|
||||
the more tokens used.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
</section>
|
||||
|
||||
);
|
||||
}
|
||||
|
|
|
@ -1,17 +0,0 @@
|
|||
'use client';
|
||||
|
||||
import { useEffect } from 'react';
|
||||
import * as Sentry from '@sentry/nextjs';
|
||||
import { useAuth } from '../AuthProvider';
|
||||
|
||||
export const VSentry: React.FC = () => {
|
||||
const { user } = useAuth();
|
||||
useEffect(() => {
|
||||
if (!document) return;
|
||||
const scope = Sentry.getCurrentScope();
|
||||
if (!user) scope.setUser(null);
|
||||
else scope.setUser({ email: user.email, id: user.id });
|
||||
}, [user]);
|
||||
|
||||
return null;
|
||||
};
|
|
@ -130,56 +130,54 @@ export function SidebarLeft({
|
|||
</div>
|
||||
</SidebarHeader>
|
||||
<SidebarContent className="[&::-webkit-scrollbar]:hidden [-ms-overflow-style:'none'] [scrollbar-width:'none']">
|
||||
{!flagsLoading && (customAgentsEnabled || marketplaceEnabled) && (
|
||||
<SidebarGroup>
|
||||
<Link href="/dashboard">
|
||||
<SidebarGroup>
|
||||
<Link href="/dashboard">
|
||||
<SidebarMenuButton className={cn({
|
||||
'bg-accent text-accent-foreground font-medium': pathname === '/dashboard',
|
||||
})}>
|
||||
<Plus className="h-4 w-4 mr-2" />
|
||||
<span className="flex items-center justify-between w-full">
|
||||
New Task
|
||||
</span>
|
||||
</SidebarMenuButton>
|
||||
</Link>
|
||||
{!flagsLoading && marketplaceEnabled && (
|
||||
<Link href="/marketplace">
|
||||
<SidebarMenuButton className={cn({
|
||||
'bg-accent text-accent-foreground font-medium': pathname === '/dashboard',
|
||||
'bg-accent text-accent-foreground font-medium': pathname === '/marketplace',
|
||||
})}>
|
||||
<Plus className="h-4 w-4 mr-2" />
|
||||
<Store className="h-4 w-4 mr-2" />
|
||||
<span className="flex items-center justify-between w-full">
|
||||
New Task
|
||||
Marketplace
|
||||
</span>
|
||||
</SidebarMenuButton>
|
||||
</Link>
|
||||
{marketplaceEnabled && (
|
||||
<Link href="/marketplace">
|
||||
<SidebarMenuButton className={cn({
|
||||
'bg-accent text-accent-foreground font-medium': pathname === '/marketplace',
|
||||
})}>
|
||||
<Store className="h-4 w-4 mr-2" />
|
||||
<span className="flex items-center justify-between w-full">
|
||||
Marketplace
|
||||
</span>
|
||||
</SidebarMenuButton>
|
||||
</Link>
|
||||
)}
|
||||
{customAgentsEnabled && (
|
||||
<Link href="/agents">
|
||||
<SidebarMenuButton className={cn({
|
||||
'bg-accent text-accent-foreground font-medium': pathname === '/agents',
|
||||
})}>
|
||||
<Bot className="h-4 w-4 mr-2" />
|
||||
<span className="flex items-center justify-between w-full">
|
||||
Agents
|
||||
</span>
|
||||
</SidebarMenuButton>
|
||||
</Link>
|
||||
)}
|
||||
{customAgentsEnabled && (
|
||||
<Link href="/settings/credentials">
|
||||
<SidebarMenuButton className={cn({
|
||||
'bg-accent text-accent-foreground font-medium': pathname === '/settings/credentials',
|
||||
})}>
|
||||
<Key className="h-4 w-4 mr-2" />
|
||||
<span className="flex items-center justify-between w-full">
|
||||
Credentials
|
||||
</span>
|
||||
</SidebarMenuButton>
|
||||
</Link>
|
||||
)}
|
||||
</SidebarGroup>
|
||||
)}
|
||||
)}
|
||||
{!flagsLoading && customAgentsEnabled && (
|
||||
<Link href="/agents">
|
||||
<SidebarMenuButton className={cn({
|
||||
'bg-accent text-accent-foreground font-medium': pathname === '/agents',
|
||||
})}>
|
||||
<Bot className="h-4 w-4 mr-2" />
|
||||
<span className="flex items-center justify-between w-full">
|
||||
Agents
|
||||
</span>
|
||||
</SidebarMenuButton>
|
||||
</Link>
|
||||
)}
|
||||
{!flagsLoading && customAgentsEnabled && (
|
||||
<Link href="/settings/credentials">
|
||||
<SidebarMenuButton className={cn({
|
||||
'bg-accent text-accent-foreground font-medium': pathname === '/settings/credentials',
|
||||
})}>
|
||||
<Key className="h-4 w-4 mr-2" />
|
||||
<span className="flex items-center justify-between w-full">
|
||||
Credentials
|
||||
</span>
|
||||
</SidebarMenuButton>
|
||||
</Link>
|
||||
)}
|
||||
</SidebarGroup>
|
||||
<NavAgents />
|
||||
</SidebarContent>
|
||||
{state !== 'collapsed' && (
|
||||
|
|
|
@ -1,6 +0,0 @@
|
|||
import * as Sentry from '@sentry/nextjs';
|
||||
import { SentryConfig } from './sentry.config';
|
||||
|
||||
Sentry.init(SentryConfig);
|
||||
|
||||
export const onRouterTransitionStart = Sentry.captureRouterTransitionStart;
|
|
@ -1,8 +0,0 @@
|
|||
import * as Sentry from '@sentry/nextjs';
|
||||
import { SentryConfig } from './sentry.config';
|
||||
|
||||
export async function register() {
|
||||
Sentry.init(SentryConfig);
|
||||
}
|
||||
|
||||
export const onRequestError = Sentry.captureRequestError;
|
|
@ -115,16 +115,17 @@ export const siteConfig = {
|
|||
{
|
||||
name: 'Free',
|
||||
price: '$0',
|
||||
description: 'Get started with',
|
||||
description: 'Perfect for getting started',
|
||||
buttonText: 'Start Free',
|
||||
buttonColor: 'bg-secondary text-white',
|
||||
isPopular: false,
|
||||
/** @deprecated */
|
||||
hours: '60 min',
|
||||
features: [
|
||||
'Free $5/month usage included',
|
||||
'Public Projects',
|
||||
'Limited models',
|
||||
'$5 free AI tokens included',
|
||||
'Public projects',
|
||||
'Basic Models',
|
||||
'Community support',
|
||||
],
|
||||
stripePriceId: config.SUBSCRIPTION_TIERS.FREE.priceId,
|
||||
upgradePlans: [],
|
||||
|
@ -135,17 +136,17 @@ export const siteConfig = {
|
|||
yearlyPrice: '$204',
|
||||
originalYearlyPrice: '$240',
|
||||
discountPercentage: 15,
|
||||
description: 'Everything in Free, plus:',
|
||||
description: 'Best for individuals and small teams',
|
||||
buttonText: 'Start Free',
|
||||
buttonColor: 'bg-primary text-white dark:text-black',
|
||||
isPopular: true,
|
||||
/** @deprecated */
|
||||
hours: '2 hours',
|
||||
features: [
|
||||
'$20/month usage',
|
||||
// '+ $5 free included',
|
||||
'$20 AI token credits/month',
|
||||
'Private projects',
|
||||
'More models',
|
||||
'Premium AI Models',
|
||||
'Community support',
|
||||
],
|
||||
stripePriceId: config.SUBSCRIPTION_TIERS.TIER_2_20.priceId,
|
||||
yearlyStripePriceId: config.SUBSCRIPTION_TIERS.TIER_2_20_YEARLY.priceId,
|
||||
|
@ -157,17 +158,17 @@ export const siteConfig = {
|
|||
yearlyPrice: '$510',
|
||||
originalYearlyPrice: '$600',
|
||||
discountPercentage: 15,
|
||||
description: 'Everything in Free, plus:',
|
||||
description: 'Ideal for growing businesses',
|
||||
buttonText: 'Start Free',
|
||||
buttonColor: 'bg-secondary text-white',
|
||||
isPopular: false,
|
||||
/** @deprecated */
|
||||
hours: '6 hours',
|
||||
features: [
|
||||
'$50/month usage',
|
||||
// '+ $5 free included',
|
||||
'$50 AI token credits/month',
|
||||
'Private projects',
|
||||
'More models',
|
||||
'Premium AI Models',
|
||||
'Community support',
|
||||
],
|
||||
stripePriceId: config.SUBSCRIPTION_TIERS.TIER_6_50.priceId,
|
||||
yearlyStripePriceId: config.SUBSCRIPTION_TIERS.TIER_6_50_YEARLY.priceId,
|
||||
|
@ -179,16 +180,16 @@ export const siteConfig = {
|
|||
yearlyPrice: '$1020',
|
||||
originalYearlyPrice: '$1200',
|
||||
discountPercentage: 15,
|
||||
description: 'Everything in Pro, plus:',
|
||||
description: 'For established businesses',
|
||||
buttonText: 'Start Free',
|
||||
buttonColor: 'bg-secondary text-white',
|
||||
isPopular: false,
|
||||
hours: '12 hours',
|
||||
features: [
|
||||
'$100/month usage',
|
||||
// '+ $5 free included',
|
||||
'$100 AI token credits/month',
|
||||
'Private projects',
|
||||
'Priority support',
|
||||
'Premium AI Models',
|
||||
'Community support',
|
||||
],
|
||||
stripePriceId: config.SUBSCRIPTION_TIERS.TIER_12_100.priceId,
|
||||
yearlyStripePriceId: config.SUBSCRIPTION_TIERS.TIER_12_100_YEARLY.priceId,
|
||||
|
@ -201,16 +202,16 @@ export const siteConfig = {
|
|||
yearlyPrice: '$2040',
|
||||
originalYearlyPrice: '$2400',
|
||||
discountPercentage: 15,
|
||||
description: 'Everything in Free, plus:',
|
||||
description: 'For power users and teams',
|
||||
buttonText: 'Start Free',
|
||||
buttonColor: 'bg-primary text-white dark:text-black',
|
||||
isPopular: false,
|
||||
hours: '25 hours',
|
||||
features: [
|
||||
'$200/month usage',
|
||||
// '+ $5 free included',
|
||||
'$200 AI token credits/month',
|
||||
'Private projects',
|
||||
'More models',
|
||||
'Premium AI Models',
|
||||
'Priority support',
|
||||
],
|
||||
stripePriceId: config.SUBSCRIPTION_TIERS.TIER_25_200.priceId,
|
||||
yearlyStripePriceId: config.SUBSCRIPTION_TIERS.TIER_25_200_YEARLY.priceId,
|
||||
|
@ -222,18 +223,19 @@ export const siteConfig = {
|
|||
yearlyPrice: '$4080',
|
||||
originalYearlyPrice: '$4800',
|
||||
discountPercentage: 15,
|
||||
description: 'Everything in Ultra, plus:',
|
||||
description: 'For large organizations',
|
||||
buttonText: 'Start Free',
|
||||
buttonColor: 'bg-secondary text-white',
|
||||
isPopular: false,
|
||||
hours: '50 hours',
|
||||
features: [
|
||||
'$400/month usage',
|
||||
// '+ $5 free included',
|
||||
'$400 AI token credits/month',
|
||||
'Private projects',
|
||||
'Access to intelligent Model (Full Suna)',
|
||||
'Priority support',
|
||||
'Premium AI Models',
|
||||
'Full Suna AI access',
|
||||
'Community support',
|
||||
'Custom integrations',
|
||||
'Dedicated account manager',
|
||||
],
|
||||
stripePriceId: config.SUBSCRIPTION_TIERS.TIER_50_400.priceId,
|
||||
yearlyStripePriceId: config.SUBSCRIPTION_TIERS.TIER_50_400_YEARLY.priceId,
|
||||
|
@ -246,19 +248,20 @@ export const siteConfig = {
|
|||
yearlyPrice: '$8160',
|
||||
originalYearlyPrice: '$9600',
|
||||
discountPercentage: 15,
|
||||
description: 'Everything in Enterprise, plus:',
|
||||
description: 'For scaling enterprises',
|
||||
buttonText: 'Start Free',
|
||||
buttonColor: 'bg-secondary text-white',
|
||||
isPopular: false,
|
||||
hours: '125 hours',
|
||||
features: [
|
||||
'$800/month usage',
|
||||
// '+ $5 free included',
|
||||
'$800 AI token credits/month',
|
||||
'Private projects',
|
||||
'Access to intelligent Model (Full Suna)',
|
||||
'Priority support',
|
||||
'Premium AI Models',
|
||||
'Full Suna AI access',
|
||||
'Community support',
|
||||
'Custom integrations',
|
||||
'Dedicated account manager',
|
||||
'Custom SLA',
|
||||
],
|
||||
stripePriceId: config.SUBSCRIPTION_TIERS.TIER_125_800.priceId,
|
||||
yearlyStripePriceId: config.SUBSCRIPTION_TIERS.TIER_125_800_YEARLY.priceId,
|
||||
|
@ -271,20 +274,21 @@ export const siteConfig = {
|
|||
yearlyPrice: '$10200',
|
||||
originalYearlyPrice: '$12000',
|
||||
discountPercentage: 15,
|
||||
description: 'Everything in Scale, plus:',
|
||||
description: 'For maximum scale and performance',
|
||||
buttonText: 'Start Free',
|
||||
buttonColor: 'bg-secondary text-white',
|
||||
isPopular: false,
|
||||
hours: '200 hours',
|
||||
features: [
|
||||
'$1000/month usage',
|
||||
// '+ $5 free included',
|
||||
'$1000 AI token credits/month',
|
||||
'Private projects',
|
||||
'Access to intelligent Model (Full Suna)',
|
||||
'Premium AI Models',
|
||||
'Full Suna AI access',
|
||||
'Priority support',
|
||||
'Custom integrations',
|
||||
'Dedicated account manager',
|
||||
'Custom SLA',
|
||||
'White-label options',
|
||||
],
|
||||
stripePriceId: config.SUBSCRIPTION_TIERS.TIER_200_1000.priceId,
|
||||
yearlyStripePriceId: config.SUBSCRIPTION_TIERS.TIER_200_1000_YEARLY.priceId,
|
||||
|
|
|
@ -1,11 +0,0 @@
|
|||
import { consoleLoggingIntegration, type init } from '@sentry/nextjs';
|
||||
|
||||
type SentryConfig = Parameters<typeof init>[0];
|
||||
|
||||
export const SentryConfig: SentryConfig = {
|
||||
dsn: process.env.NEXT_PUBLIC_SENTRY_DSN,
|
||||
tracesSampleRate: 0.1,
|
||||
debug: false,
|
||||
_experiments: { enableLogs: true },
|
||||
integrations: [consoleLoggingIntegration()],
|
||||
};
|
2
start.py
2
start.py
|
@ -63,7 +63,7 @@ def print_manual_instructions():
|
|||
print(f"{Colors.CYAN} cd frontend && npm run dev{Colors.ENDC}\n")
|
||||
|
||||
print(f"{Colors.BOLD}3. Start Backend (in a new terminal):{Colors.ENDC}")
|
||||
print(f"{Colors.CYAN} cd backend && python run api.py{Colors.ENDC}\n")
|
||||
print(f"{Colors.CYAN} cd backend && uv run api.py{Colors.ENDC}\n")
|
||||
|
||||
print("Once all services are running, access Suna at: http://localhost:3000\n")
|
||||
|
||||
|
|
Loading…
Reference in New Issue