Skip to content

Commit c39ca5a

Browse files
committed
feat(gui): improve agent creation with AI-assisted function calling
- AI-assisted mode: Uses completions API with function calling to generate complete agent config (name, description, tools, model, prompt) - Manual mode: Removed permission mode selector, focusing on agent description and tool selection - Added optimized system prompt for generating autonomous agents - Agents no longer include tools requiring user interaction/ask
1 parent a85d86f commit c39ca5a

File tree

1 file changed

+92
-42
lines changed

1 file changed

+92
-42
lines changed

cortex-gui/src/components/AgentsManager.tsx

Lines changed: 92 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@ import { createSignal, createEffect, Show, For } from "solid-js";
22
import { Icon } from "./ui/Icon";
33
import { useSDK } from "@/context/SDKContext";
44

5+
// Cortex API base URL for completions
6+
const CORTEX_API_URL = "https://api.cortex.foundation";
7+
58
export interface AgentDefinition {
69
name: string;
710
description: string;
@@ -13,6 +16,40 @@ export interface AgentDefinition {
1316
filePath?: string;
1417
}
1518

19+
// Function definition for agent generation via OpenAI-style function calling
20+
const AGENT_GENERATION_FUNCTION = {
21+
name: "generate_agent_config",
22+
description: "Generate a complete agent configuration based on the user's description",
23+
parameters: {
24+
type: "object",
25+
properties: {
26+
name: {
27+
type: "string",
28+
description: "A short, lowercase, hyphenated name for the agent (e.g., 'code-reviewer', 'test-writer')"
29+
},
30+
description: {
31+
type: "string",
32+
description: "A brief description of when this agent should be used and what it does"
33+
},
34+
tools: {
35+
type: "array",
36+
items: { type: "string" },
37+
description: "List of tools the agent should have access to. Available tools: Read, Create, Edit, Glob, Grep, Execute, LS, WebSearch, FetchUrl, TodoWrite"
38+
},
39+
model: {
40+
type: "string",
41+
enum: ["inherit", "sonnet", "opus", "haiku"],
42+
description: "The model to use for this agent"
43+
},
44+
prompt: {
45+
type: "string",
46+
description: "The system prompt that defines this agent's behavior, expertise, and guidelines"
47+
}
48+
},
49+
required: ["name", "description", "tools", "prompt"]
50+
}
51+
};
52+
1653
interface AgentsManagerProps {
1754
visible: boolean;
1855
onClose: () => void;
@@ -38,13 +75,6 @@ const MODELS = [
3875
{ id: "haiku", label: "Haiku (fastest)" },
3976
];
4077

41-
const PERMISSIONS = [
42-
{ id: "default", label: "Default - normal prompts" },
43-
{ id: "acceptEdits", label: "Accept Edits - auto-accept file changes" },
44-
{ id: "bypassPermissions", label: "Bypass - skip all prompts" },
45-
{ id: "plan", label: "Plan - read-only mode" },
46-
];
47-
4878
export function AgentsManager(props: AgentsManagerProps) {
4979
const { state } = useSDK();
5080
const [agents, setAgents] = createSignal<AgentDefinition[]>([]);
@@ -114,13 +144,44 @@ export function AgentsManager(props: AgentsManagerProps) {
114144
setAiError(null);
115145

116146
try {
117-
const res = await fetch(`${state.serverUrl}/api/v1/agents/generate-prompt`, {
147+
// Use the completions API with function calling to generate agent config
148+
const systemPrompt = `You are an AI assistant that helps create custom agent configurations for Cortex, an AI-powered coding assistant.
149+
150+
When the user describes what kind of agent they want, you must generate a complete agent configuration by calling the generate_agent_config function.
151+
152+
Guidelines for generating agents:
153+
1. Name should be lowercase, hyphenated, and descriptive (e.g., "code-reviewer", "security-auditor")
154+
2. Description should clearly explain when to use this agent
155+
3. Select appropriate tools based on what the agent needs to do:
156+
- Read: For reading file contents
157+
- Create: For creating new files
158+
- Edit: For modifying existing files
159+
- Glob: For finding files by pattern
160+
- Grep: For searching file contents
161+
- Execute: For running shell commands
162+
- LS: For listing directories
163+
- WebSearch: For searching the web
164+
- FetchUrl: For fetching URL content
165+
- TodoWrite: For managing todo lists
166+
4. Do NOT include tools that require user interaction/ask (the agent should work autonomously)
167+
5. The system prompt should be detailed and clearly define the agent's expertise, behavior, and guidelines`;
168+
169+
const res = await fetch(`${CORTEX_API_URL}/v1/chat/completions`, {
118170
method: "POST",
119-
headers: { "Content-Type": "application/json" },
171+
headers: {
172+
"Content-Type": "application/json",
173+
},
120174
body: JSON.stringify({
121-
description: aiPrompt(),
122-
tools: formTools(),
123-
name: formName() || undefined,
175+
model: state.config?.model || "anthropic/claude-sonnet-4",
176+
messages: [
177+
{ role: "system", content: systemPrompt },
178+
{ role: "user", content: `Create an agent with the following description:\n\n${aiPrompt()}` }
179+
],
180+
tools: [{
181+
type: "function",
182+
function: AGENT_GENERATION_FUNCTION
183+
}],
184+
tool_choice: { type: "function", function: { name: "generate_agent_config" } }
124185
}),
125186
});
126187

@@ -131,17 +192,29 @@ export function AgentsManager(props: AgentsManagerProps) {
131192

132193
const data = await res.json();
133194

195+
// Extract the function call result
196+
const choice = data.choices?.[0];
197+
const toolCall = choice?.message?.tool_calls?.[0];
198+
199+
if (!toolCall || toolCall.function?.name !== "generate_agent_config") {
200+
throw new Error("AI did not return a valid agent configuration");
201+
}
202+
203+
// Parse the function arguments
204+
const agentConfig = JSON.parse(toolCall.function.arguments);
205+
134206
// Fill form with generated data
135-
setFormName(data.name);
136-
setFormDescription(data.description);
137-
setFormPrompt(data.prompt);
138-
setFormTools(data.tools || []);
139-
setFormModel(data.model || "inherit");
140-
setFormPermission(data.permission_mode || "default");
207+
setFormName(agentConfig.name || "");
208+
setFormDescription(agentConfig.description || "");
209+
setFormPrompt(agentConfig.prompt || "");
210+
setFormTools(agentConfig.tools || []);
211+
setFormModel(agentConfig.model || "inherit");
212+
setFormPermission("default"); // Default permission mode for safety
141213

142-
// Switch to edit mode to review
214+
// Switch to create mode to review
143215
setMode("create");
144216
} catch (e) {
217+
console.error("AI generation error:", e);
145218
setAiError(e instanceof Error ? e.message : "Failed to generate agent");
146219
} finally {
147220
setGenerating(false);
@@ -628,29 +701,6 @@ export function AgentsManager(props: AgentsManagerProps) {
628701
</select>
629702
</div>
630703

631-
{/* Permission Mode */}
632-
<div>
633-
<label class="block text-xs mb-1" style={{ color: "var(--text-weak)" }}>
634-
Permission Mode
635-
</label>
636-
<select
637-
value={formPermission()}
638-
onChange={(e) => setFormPermission(e.currentTarget.value)}
639-
class="w-full px-3 py-2 rounded border text-sm"
640-
style={{
641-
background: "var(--background-base)",
642-
"border-color": "var(--border-base)",
643-
color: "var(--text-base)"
644-
}}
645-
>
646-
<For each={PERMISSIONS}>
647-
{(perm) => (
648-
<option value={perm.id}>{perm.label}</option>
649-
)}
650-
</For>
651-
</select>
652-
</div>
653-
654704
{/* Prompt */}
655705
<div>
656706
<label class="block text-xs mb-1" style={{ color: "var(--text-weak)" }}>

0 commit comments

Comments
 (0)