FragolaFragola
Agentic SDK
An event-driven SDK for building AI agents. Interoperable with OpenAI SDK.

Core Primitives
Define agents, tools, events, and state transitions as first‑class building blocks.
Event-Driven Model
Drive agents through explicit events for easier debugging and observability.
Lightweight & Extensible
Bring only what you need; extend primitives to match your architecture.
OpenAI Interoperable
Fully interoperable with the OpenAI SDK and OpenAI compatible APIs, allowing you to use familiar tools and models.
Core Primitives
A small set of powerful building blocks for any AI architecture. Scroll to explore each primitive in detail.
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 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"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
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]
});Hooks
Reusable, composable behaviors that extend agent capabilities. Package complex logic for sharing across agents and projects.
- MCP client integration
- Multi-agent orchestration
- Guardrails & persistence
// 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 hookEvents
A rich subscription system for observability and control. Hook into every stage of the agent loop.
- Message interception
- Tool call wrapping
- Model invocation tracing
// 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();
}
});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
// 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 };
}
});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
// 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();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);Ready to Build?
Start building powerful AI agents with Fragola today. Sweet, simple, and incredibly powerful.