FragolaBuild AI Agents Your Way
An event-driven SDK for building AI-first software. Lightweight, extensible, production-ready.
import { Fragola } from "@fragola-ai/agentic-sdk-core";
const fragola = new Fragola({
apiKey: process.env.OPENAI_API_KEY,
model: "gpt-4o-mini"
});
const agent = fragola.agent({
name: "Assistant",
instructions: "You are a helpful assistant."
});
const state = await agent.userMessage({
content: "Hello!"
});Core Primitives
A small set of powerful building blocks for any AI architecture. Scroll to explore each primitive in detail.
const fragola = new Fragola({
apiKey: process.env.OPENAI_API_KEY,
model: "gpt-4o-mini"
});
const agent = fragola.agent({
name: "CustomerSupport",
description: "Handles customer inquiries",
instructions: "You are a helpful customer support agent.",
modelSettings: {
temperature: 0.7,
max_tokens: 1000
},
stepOptions: {
maxStep: 10,
resetStepCountAfterUserMessage: true
}
});
// Send a message and get the response
const state = await agent.userMessage({
content: "Hello! What can you help me with?",
meta: { userId: "user-123" }
});
console.log(state.messages); // Full conversation history
console.log(state.status); // "idle" | "generating" | "waiting"Agents
Stateful LLM instances that manage conversation history, tool execution, and state updates through a predictable lifecycle.
- Native OpenAI message types
- Configurable model settings
- Step-based execution control
const weatherTool = tool({
name: "get_weather",
description: "Get current weather for a location",
schema: z.object({
location: z.string().describe("City name"),
unit: z.enum(["celsius", "fahrenheit"]).optional()
}),
handler: async (params, context) => {
const weather = await fetchWeather(params.location);
return {
temperature: weather.temp,
conditions: weather.conditions,
location: params.location
};
}
});
// Add tools to agent
const agent = fragola.agent({
name: "Assistant",
instructions: "Help users with weather info.",
description: "Weather assistant",
tools: [weatherTool, dynamicTool]
});Tools
Strongly-typed functions with Zod or JSON Schema validation. Give your agents the ability to take actions and fetch data.
- Zod & JSON Schema support
- Dynamic tool handlers
- Context-aware execution
// Create a custom analytics hook
const analyticsHook = Hook((agent) => {
let userMessages = 0;
let aiMessages = 0;
agent.onUserMessage((message, context) => {
userMessages++;
return message;
});
agent.onAiMessage((message, isPartial, context) => {
if (!isPartial) aiMessages++;
return message;
});
agent.onAfterStateUpdate((context) => {
if (context.state.status === "idle") {
console.log(`Stats: ${userMessages} user, ${aiMessages} AI`);
}
});
});
// Use hook presets along with custom hooks
const agent = fragola.agent({ name: "Assistant", ... })
.use(fileSystemSave("./conversations"))
.use(mcpClient({ name: "tools", url: "http://localhost:3001" }))
.use(guardrail([myGuardrail]))
.use(analyticsHook); // your custom hookHooks
Reusable, composable behaviors that extend agent capabilities. Package complex logic for sharing across agents and projects.
- MCP client integration
- Multi-agent orchestration
- Guardrails & persistence
// Intercept and transform user messages
agent.onUserMessage((message, context) => {
const content = typeof message.content === 'string'
? message.content.trim()
: message.content;
return { ...message, content };
});
// Process AI responses
agent.onAiMessage((message, isPartial, context) => {
if (isPartial) return message; // Skip streaming partials
return {
...message,
content: message.content + '
_Powered by Fragola_'
};
});
// Wrap tool execution with logging
agent.onToolCall(async (params, tool, context) => {
console.log('Calling tool:', tool.name, params);
const result = await tool.handler(params, context);
console.log('Tool result:', result);
return result;
});
// Trace model invocations with retries
agent.onModelInvocation(async (callAPI, context) => {
const start = Date.now();
try {
const response = await callAPI();
console.log('Model took', Date.now() - start, 'ms');
return response;
} catch (e) {
// Implement retry logic
return await callAPI();
}
});Events
A rich subscription system for observability and control. Hook into every stage of the agent loop.
- Message interception
- Tool call wrapping
- Model invocation tracing
// Global store shared across all agents
const globalStore = createStore({
activeTenantId: "tenant-123"
});
const fragola = new Fragola(
{ apiKey: process.env.OPENAI_API_KEY, model: "gpt-4o-mini" },
globalStore
);
// Agent-level store
const agentStore = createStore({ turns: 0 });
const agent = fragola.agent({
name: "Assistant",
instructions: "You are helpful.",
description: "General assistant",
store: agentStore
});
// Access stores from tools
const counterTool = tool({
name: "increment",
description: "increments the counter",
handler: async (params, context) => {
if (!context.store)
return { error: "failed to retrieve store" };
context.store.update(prev => ({
...prev,
turns: prev.turns + 1
}));
return { newCount: context.store.value.turns };
}
});Stores
Simple reactive state management. Share data across agents, tools, and hooks with global or namespaced stores.
- Global & per-agent scopes
- Change subscriptions
- Tool & event access
// Access agent state
const messages = agent.context.state.messages;
const status = agent.context.state.status;
const stepCount = agent.context.state.stepCount;
// Dynamically update tools at runtime
agent.context.updateTools(prev => [
...prev,
newTool
]);
// Remove tools by name
agent.context.updateTools(prev =>
prev.filter(t => t.name !== "deprecated_tool")
);
// Manage instructions with scopes
agent.context.setInstructions("You are concise.", "style");
agent.context.setInstructions("Focus on data.", "task");
agent.context.removeInstructions("style");
// Access stores from context
const mainStore = agent.context.store;
const analyticsStore = agent.context.getStore("analytics");
// Update options at runtime (only when idle)
agent.context.setOptions({
modelSettings: { temperature: 0.5 },
stepOptions: { maxStep: 5 }
});
// Stop agent execution
await agent.context.stop();Context
Unified access to agent state, tools, stores, and configuration. The bridge between your code and agent internals.
- Runtime tool management
- Store access from anywhere
- Instruction updates
Built-in Hook Presets
Ready-to-use integrations for common patterns
Get Started in Minutes
Install
npm install @fragola-ai/agentic-sdk-core
Initialize
import { Fragola } from "@fragola-ai/agentic-sdk-core";
const fragola = new Fragola({
apiKey: process.env.OPENAI_API_KEY,
model: "gpt-4o-mini"
});Create an Agent
const agent = fragola.agent({
name: "QuickstartAgent",
description: "My first Fragola agent",
instructions: "You are a helpful assistant."
});Send a Message
const state = await agent.userMessage({
content: "Hello! What can you do?"
});
console.log(state.messages);