AI Agents
Build intelligent AI agents that can execute tools, integrate with chat, and stream responses using SSE.
Overview
Eloquent AI Agents provide:
- Tool Execution: Call APIs, query databases, execute code
- Chat Integration: Conversational interfaces with history
- SSE Streaming: Real-time response streaming
- Multi-turn Context: Maintain conversation state
Agent Definition
interface Agent {
id: string;
name: string;
description: string;
systemPrompt: string;
model: "gpt-4" | "gpt-3.5-turbo" | "claude-3";
tools: AgentTool[];
settings: AgentSettings;
}
interface AgentTool {
id: string;
name: string;
description: string;
type: "api_call" | "entity_query" | "kg_search" | "code_exec";
config: ToolConfig;
}
interface AgentSettings {
temperature: number;
maxTokens: number;
streaming: boolean;
}
Creating an Agent
Agent Configuration
const supportAgent: Agent = {
name: "Customer Support Agent",
description: "Handles customer inquiries and support tickets",
systemPrompt: `You are a helpful customer support agent.
Use the available tools to look up customer information,
check order status, and resolve issues.
Be professional and empathetic.`,
model: "gpt-4",
tools: [
{
name: "lookup_customer",
description: "Look up customer by email or ID",
type: "entity_query",
config: {
entityName: "customer",
queryFields: ["email", "id"],
},
},
{
name: "check_order_status",
description: "Check the status of an order",
type: "api_call",
config: {
endpoint: "/api/v1/orders/{orderId}",
method: "GET",
},
},
{
name: "create_ticket",
description: "Create a support ticket",
type: "entity_query",
config: {
entityName: "ticket",
operation: "create",
},
},
],
settings: {
temperature: 0.7,
maxTokens: 1000,
streaming: true,
},
};
Chat Integration
Starting a Chat Session
import { useAgentChat } from "@/hooks/use-agent-chat";
function ChatInterface({ agentId }: { agentId: string }) {
const {
messages,
sendMessage,
isStreaming,
toolCalls,
} = useAgentChat(agentId);
const handleSend = async (content: string) => {
await sendMessage({ content });
};
return (
<div className="chat-container">
<MessageList messages={messages} />
{toolCalls.length > 0 && (
<ToolCallIndicator calls={toolCalls} />
)}
<ChatInput onSend={handleSend} disabled={isStreaming} />
</div>
);
}
Message Types
interface ChatMessage {
id: string;
role: "user" | "assistant" | "system" | "tool";
content: string;
toolCalls?: ToolCall[];
toolResult?: ToolResult;
createdAt: string;
}
interface ToolCall {
id: string;
name: string;
arguments: Record<string, any>;
status: "pending" | "executing" | "completed" | "failed";
}
interface ToolResult {
toolCallId: string;
result: any;
error?: string;
}
SSE Streaming
Streaming Response
function useAgentStream(agentId: string) {
const [chunks, setChunks] = useState<string[]>([]);
const streamMessage = async (content: string) => {
const eventSource = new EventSource(
`/api/v1/agents/${agentId}/chat/stream?message=${encodeURIComponent(content)}`
);
eventSource.onmessage = (event) => {
const data = JSON.parse(event.data);
if (data.type === "token") {
setChunks((prev) => [...prev, data.content]);
}
if (data.type === "tool_call") {
// Handle tool call
}
if (data.type === "done") {
eventSource.close();
}
};
eventSource.onerror = () => {
eventSource.close();
};
};
return { chunks, streamMessage };
}
Tool Execution
Tool Types
| Type | Description | Config |
|---|---|---|
api_call | Call external API | endpoint, method, headers |
entity_query | Query/create entities | entityName, operation |
kg_search | Semantic search in KG | graphId, labels |
code_exec | Execute code snippets | runtime, timeout |
Backend Tool Handler
func (h *Handler) ExecuteTool(ctx context.Context, call ToolCall) (*ToolResult, error) {
tool := h.tools[call.Name]
switch tool.Type {
case "api_call":
return h.executeAPICall(ctx, tool.Config, call.Arguments)
case "entity_query":
return h.executeEntityQuery(ctx, tool.Config, call.Arguments)
case "kg_search":
return h.executeKGSearch(ctx, tool.Config, call.Arguments)
default:
return nil, fmt.Errorf("unknown tool type: %s", tool.Type)
}
}
API Endpoints
| Method | Path | Description |
|---|---|---|
| GET | /api/v1/agents | List agents |
| POST | /api/v1/agents | Create agent |
| GET | /api/v1/agents/{id} | Get agent |
| PUT | /api/v1/agents/{id} | Update agent |
| POST | /api/v1/agents/{id}/chat | Send message |
| GET | /api/v1/agents/{id}/chat/stream | Stream response (SSE) |
| GET | /api/v1/chats/{chatId}/history | Get chat history |
Best Practices
- Clear system prompts - Define agent personality and capabilities
- Descriptive tool names - Help the model choose the right tool
- Handle tool failures - Graceful error handling
- Use streaming - Better UX for long responses
- Limit context - Keep conversation history manageable
Next Steps
- Workflow Engine - Using agents in workflows
- Knowledge Graph - KG-powered agents
- SSE Progress - Real-time streaming patterns