agents-core
The @philschmid/agents-core package provides the foundational primitives for building AI agents with the Gemini Interactions API. It’s designed to be minimal, flexible, and framework-agnostic.
Features
Section titled “Features”- agentLoop: One-shot agent execution with streaming event output
- AgentTool: Flexible tool definition via JSON Schema
- Event Stream: Real-time updates: text deltas, tool calls, errors, completion
This is the low-level building block. For higher-level features like hooks, built-in tools, sessions, and skills, see the @philschmid/agent package.
Installation
Section titled “Installation”bun add @philschmid/agents-corenpm install @philschmid/agents-coreexport GEMINI_API_KEY="your-api-key"When to Use
Section titled “When to Use”Choose agents-core when you need:
- Full control over the agent loop and event handling
- Custom tooling infrastructure
- Minimal dependencies
- Building your own framework layer
Choose @philschmid/agent when you need:
- Built-in tools (read, write, bash, grep)
- Lifecycle hooks for control flow
- Multi-turn session management
- Skills and subagents
agentLoop
Section titled “agentLoop”The core function for executing agent tasks. It runs a complete agentic loop with tool calling and returns an event stream:
import { agentLoop, printStream } from '@philschmid/agents-core';
const stream = agentLoop( [{ type: 'text', text: 'Analyze this code and suggest improvements' }], { model: 'gemini-3-flash-preview', tools: [analyzerTool] });
await printStream(stream, { verbosity: 'verbose' });For multi-turn conversations, use previousInteractionId to chain interactions:
// Turn 1const stream1 = agentLoop([{ type: 'text', text: 'Hello' }], { model: 'gemini-3-flash-preview' });for await (const event of stream1) { /* handle events */ }const result1 = await stream1.result();
// Turn 2 - chain with previous interactionconst stream2 = agentLoop([{ type: 'text', text: 'What did I say?' }], { model: 'gemini-3-flash-preview', previousInteractionId: result1.interactionId,});For a higher-level multi-turn API, see AgentSession in the @philschmid/agent package.
Defining Tools
Section titled “Defining Tools”Tools use JSON Schema for parameters and an async execute function:
import { type AgentTool } from '@philschmid/agents-core';import * as fs from 'node:fs';
const listDirTool: AgentTool = { name: 'list_dir', label: 'List Directory', description: 'Lists the contents of a directory.', parameters: { type: 'object', properties: { directory_path: { type: 'string', description: 'Path to directory' }, }, required: ['directory_path'], }, execute: async (_id, args) => { const items = fs.readdirSync(args.directory_path as string); return { result: items.join(', ') }; },};Event Types
Section titled “Event Types”The agent loop emits events as an async generator:
| Event Type | Description |
|---|---|
agent.start | Agent loop begins |
interaction.start | LLM call begins |
text.start | Text block begins |
text.delta | Streaming text chunk |
text.end | Text block completes |
thought.summary | Thinking summary from model |
tool.start | Tool execution begins |
tool.delta | Streaming tool update |
tool.end | Tool execution completes |
interaction.end | LLM call completes |
agent.end | Agent loop finishes |
for await (const event of stream) { switch (event.type) { case 'text.delta': process.stdout.write(event.delta); break; case 'tool.start': console.log(`Calling: ${event.name}`); break; case 'agent.end': console.log('Done!'); break; }}Learn More
Section titled “Learn More”- Agent Loop: Detailed execution flow
- Tools: Tool interface and patterns
- Session: Multi-turn conversations with
@philschmid/agent - Quickstart: Get started in 5 minutes