Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 8 additions & 55 deletions packages/ui/src/components/CreateAgentModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,10 @@

import { useState, useEffect, useMemo } from 'react';
import { LoadingSpinner } from './LoadingSpinner';
import { agentsApi, modelsApi, toolsApi } from '../api';
import { GroupedToolSelector } from './GroupedToolSelector';
import { agentsApi, modelsApi } from '../api';
import { useModalClose } from '../hooks';
import type { Agent, Tool, ModelInfo } from '../types';
import type { Agent, ModelInfo } from '../types';

export interface CreateAgentModalProps {
onClose: () => void;
Expand All @@ -22,15 +23,14 @@ export function CreateAgentModal({ onClose, onCreated }: CreateAgentModalProps)
const [selectedModel, setSelectedModel] = useState<ModelInfo | null>(null);
const [selectedTools, setSelectedTools] = useState<string[]>([]);
const [models, setModels] = useState<ModelInfo[]>([]);
const [tools, setTools] = useState<Tool[]>([]);
const [configuredProviders, setConfiguredProviders] = useState<string[]>([]);
const [isLoading, setIsLoading] = useState(true);
const [isSubmitting, setIsSubmitting] = useState(false);
const [error, setError] = useState<string | null>(null);
const [step, setStep] = useState<'info' | 'model' | 'tools'>('info');

useEffect(() => {
Promise.all([fetchModels(), fetchTools()]).finally(() => setIsLoading(false));
fetchModels().finally(() => setIsLoading(false));
}, []);

const fetchModels = async () => {
Expand All @@ -46,15 +46,6 @@ export function CreateAgentModal({ onClose, onCreated }: CreateAgentModalProps)
}
};

const fetchTools = async () => {
try {
const data = await toolsApi.list();
setTools(data);
} catch {
// API client handles error reporting
}
};

const handleSubmit = async () => {
if (!name.trim() || !selectedModel) return;

Expand All @@ -78,12 +69,6 @@ export function CreateAgentModal({ onClose, onCreated }: CreateAgentModalProps)
}
};

const toggleTool = (toolName: string) => {
setSelectedTools((prev) =>
prev.includes(toolName) ? prev.filter((t) => t !== toolName) : [...prev, toolName]
);
};

// Group models by provider
const modelsByProvider = useMemo(
() =>
Expand Down Expand Up @@ -216,42 +201,10 @@ export function CreateAgentModal({ onClose, onCreated }: CreateAgentModalProps)
)}
</div>
) : (
<div className="space-y-4">
<p className="text-sm text-text-muted dark:text-dark-text-muted">
Select tools this agent can use:
</p>
{tools.length === 0 ? (
<p className="text-text-muted dark:text-dark-text-muted text-center py-8">
No tools available.
</p>
) : (
<div className="grid gap-2">
{tools.map((tool) => (
<button
key={tool.name}
onClick={() => toggleTool(tool.name)}
className={`p-3 rounded-lg border text-left transition-all ${
selectedTools.includes(tool.name)
? 'border-primary bg-primary/5'
: 'border-border dark:border-dark-border hover:border-primary/50'
}`}
>
<div className="flex items-center justify-between">
<span className="font-medium text-text-primary dark:text-dark-text-primary">
{tool.name}
</span>
{selectedTools.includes(tool.name) && (
<span className="text-xs text-primary">Selected</span>
)}
</div>
<p className="text-xs text-text-muted dark:text-dark-text-muted mt-1">
{tool.description}
</p>
</button>
))}
</div>
)}
</div>
<GroupedToolSelector
selectedTools={selectedTools}
onSelectionChange={setSelectedTools}
/>
)}

{error && <p className="text-sm text-error mt-4">{error}</p>}
Expand Down
63 changes: 8 additions & 55 deletions packages/ui/src/components/EditAgentModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,10 @@

import { useState, useEffect, useMemo } from 'react';
import { LoadingSpinner } from './LoadingSpinner';
import { agentsApi, modelsApi, toolsApi } from '../api';
import { GroupedToolSelector } from './GroupedToolSelector';
import { agentsApi, modelsApi } from '../api';
import { useModalClose } from '../hooks';
import type { Agent, Tool, ModelInfo, AgentDetail } from '../types';
import type { Agent, ModelInfo, AgentDetail } from '../types';

export interface EditAgentModalProps {
agentId: string;
Expand All @@ -28,15 +29,14 @@ export function EditAgentModal({ agentId, onClose, onUpdated }: EditAgentModalPr
const [maxTurns, setMaxTurns] = useState(50);
const [maxToolCalls, setMaxToolCalls] = useState(200);
const [models, setModels] = useState<ModelInfo[]>([]);
const [tools, setTools] = useState<Tool[]>([]);
const [configuredProviders, setConfiguredProviders] = useState<string[]>([]);
const [isLoading, setIsLoading] = useState(true);
const [isSubmitting, setIsSubmitting] = useState(false);
const [error, setError] = useState<string | null>(null);
const [step, setStep] = useState<'info' | 'model' | 'tools' | 'config'>('info');

useEffect(() => {
Promise.all([fetchAgentDetail(), fetchModels(), fetchTools()]).finally(() =>
Promise.all([fetchAgentDetail(), fetchModels()]).finally(() =>
setIsLoading(false)
);
}, [agentId]);
Expand Down Expand Up @@ -67,15 +67,6 @@ export function EditAgentModal({ agentId, onClose, onUpdated }: EditAgentModalPr
}
};

const fetchTools = async () => {
try {
const data = await toolsApi.list();
setTools(data);
} catch {
// API client handles error reporting
}
};

// Set selected model once both agent detail and models are loaded
useEffect(() => {
if (agentDetail && models.length > 0) {
Expand Down Expand Up @@ -115,12 +106,6 @@ export function EditAgentModal({ agentId, onClose, onUpdated }: EditAgentModalPr
}
};

const toggleTool = (toolName: string) => {
setSelectedTools((prev) =>
prev.includes(toolName) ? prev.filter((t) => t !== toolName) : [...prev, toolName]
);
};

// Group models by provider
const modelsByProvider = useMemo(
() =>
Expand Down Expand Up @@ -256,42 +241,10 @@ export function EditAgentModal({ agentId, onClose, onUpdated }: EditAgentModalPr
)}
</div>
) : step === 'tools' ? (
<div className="space-y-4">
<p className="text-sm text-text-muted dark:text-dark-text-muted">
Select tools this agent can use:
</p>
{tools.length === 0 ? (
<p className="text-text-muted dark:text-dark-text-muted text-center py-8">
No tools available.
</p>
) : (
<div className="grid gap-2">
{tools.map((tool) => (
<button
key={tool.name}
onClick={() => toggleTool(tool.name)}
className={`p-3 rounded-lg border text-left transition-all ${
selectedTools.includes(tool.name)
? 'border-primary bg-primary/5'
: 'border-border dark:border-dark-border hover:border-primary/50'
}`}
>
<div className="flex items-center justify-between">
<span className="font-medium text-text-primary dark:text-dark-text-primary">
{tool.name}
</span>
{selectedTools.includes(tool.name) && (
<span className="text-xs text-primary">Selected</span>
)}
</div>
<p className="text-xs text-text-muted dark:text-dark-text-muted mt-1">
{tool.description}
</p>
</button>
))}
</div>
)}
</div>
<GroupedToolSelector
selectedTools={selectedTools}
onSelectionChange={setSelectedTools}
/>
) : (
<div className="space-y-4">
<div>
Expand Down
Loading