Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added .github/resources/gifs/demo.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
File renamed without changes
139 changes: 85 additions & 54 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@
<div align="center">
<picture>
<source media="(prefers-color-scheme: dark)" srcset=".github/images/logo-light.svg">
<source media="(prefers-color-scheme: light)" srcset=".github/images/logo-dark.svg">
<img alt="TinyGent Logo" src=".github/images/logo-dark.svg" width="80%">
<source media="(prefers-color-scheme: dark)" srcset=".github/resources/images/logo-light.svg">
<source media="(prefers-color-scheme: light)" srcset=".github/resources/images/logo-dark.svg">
<img alt="TinyGent Logo" src=".github/resources/images/logo-dark.svg" width="80%">
</picture>
</div>

<div align="center">
<h3>Tiny platform for amazing agents.</h3>
<h3>Tiny platform for amazing agents</h3>

<h4>
<a href="https://github.com/filchy/tinygent">Homepage</a> | <a href="https://filchy.github.io/tinygent">Documentation</a>
🏠 <a href="https://github.com/filchy/tinygent">Homepage</a> | 📚 <a href="https://filchy.github.io/tinygent">Documentation</a> | 💡 <a href="https://filchy.github.io/tinygent/examples">Examples</a> | 🚀 <a href="https://filchy.github.io/tinygent/examples/quick-start/">Quick Start</a>
</h4>
</div>

Tinygent is a tiny agentic framework - lightweight, easy to use (hopefully), and efficient (also hopefully ;-0) library for building and deploying generative AI applications. It provides a simple interface for working with various models and tools, making it ideal for developers who want to quickly prototype and deploy AI solutions.
🤖 Tinygent is a tiny agentic framework - lightweight, easy to use (hopefully), and efficient (also hopefully ;-0) library for building and deploying generative AI applications. It provides a simple interface for working with various models and tools, making it ideal for developers who want to quickly prototype and deploy AI solutions.

## Create an agent
## 🎯 Create an agent

```python
# uv sync --extra openai
Expand All @@ -38,16 +38,16 @@ agent = build_agent(
print(agent.run('What is the weather like in Prague?'))
```

## Getting Started
## 🚀 Getting Started

### Prerequisites
### 📋 Prerequisites

Before you begin using tinygent, ensure that you meet the following software prerequisites.

- Install [Git](https://git-scm.com/)
- Install [uv](https://docs.astral.sh/uv/getting-started/installation/)

### Install From Source
### 💻 Install From Source

1. Clone the tinygent repository to your local machine.
```bash
Expand Down Expand Up @@ -80,59 +80,90 @@ Before you begin using tinygent, ensure that you meet the following software pre
uv pip install -e .
```

## Examples (Quick Start)
## 🎬 See It In Action

1. Ensure you have set the `OPENAI_API_KEY` environment variable to allow the example to use OpenAI's API. An API key can be obtained from [`openai.com`](https://openai.com/).
<div align="center">
<img alt="TinyChat Demo" src=".github/resources/gifs/demo.gif" width="100%">
</div>

## 🏗️ Architecture

```mermaid
%%{init: {'theme': 'base', 'themeVariables': {'primaryColor': '#e1f5ff', 'primaryTextColor': '#0d47a1', 'primaryBorderColor': '#42a5f5', 'lineColor': '#1976d2', 'secondaryColor': '#fff4e1', 'tertiaryColor': '#f0e1ff'}}}%%
flowchart LR
User[User Code]:::userNode
Factory[Factories]:::factoryNode
Runtime[Runtime Registry]:::runtimeNode
Components[Agents & Tools & Memory]:::componentNode
Packages[Provider Packages]:::packageNode

User a@--> Factory
Factory b@--> Runtime
Runtime c@--> Components
Packages d@-.-> Runtime

a@{animate: true}
b@{animate: true}
c@{animate: true}
d@{animate: true}

linkStyle 0 stroke-width:2px
linkStyle 1 stroke-width:2px
linkStyle 2 stroke-width:2px
linkStyle 3 stroke-width:2px,stroke-dasharray: 5 5

classDef userNode fill:#e1f5ff,stroke:#1976d2,stroke-width:2px,color:#0d47a1
classDef factoryNode fill:#fff4e1,stroke:#f57c00,stroke-width:2px,color:#e65100
classDef runtimeNode fill:#f0e1ff,stroke:#7b1fa2,stroke-width:2px,color:#4a148c
classDef componentNode fill:#e1ffe1,stroke:#388e3c,stroke-width:2px,color:#1b5e20
classDef packageNode fill:#ffe1e1,stroke:#d32f2f,stroke-width:2px,color:#b71c1c
```

Tinygent uses a registry-based plugin architecture: **Packages** register components into the **Runtime**. **Factories** query the Runtime to build **Components** for your code.

## 💡 Examples (Quick Start)

1. 🔑 Ensure you have set the `OPENAI_API_KEY` environment variable to allow the example to use OpenAI's API. An API key can be obtained from [`openai.com`](https://openai.com/).
```bash
export OPENAI_API_KEY="your_openai_api_key"
```

2. Run the examples using `uv`:
2. ▶️ Run the examples using `uv`:
```bash
uv run examples/agents/multi-step/main.py
```

3. Explore more examples below:

### Basics

1. [Tool Usage](examples/tool-usage)
2. [LLM Usage](examples/llm-usage)
3. [Function Calling](examples/function-calling)

### Memory

1. [Chat Buffer Memory](examples/memory/basic-chat-memory)
2. [Summary Buffer Memory](examples/memory/buffer-summary-memory)
3. [Window Buffer Memory](examples/memory/buffer-window-chat-memory)
4. [Combined Memory](examples/memory/combined-memory)

### Tools

1. [Basic Tools](examples/tool-usage/main.py)
2. [Reasoning Tools](examples/tool-usage/main.py)
3. [JIT Tools](examples/tool-usage/main.py)

### Agents

1. [Middlewares in Agents](examples/agents/middleware/)
2. [ReAct Agent](examples/agents/react/)
3. [Multi-Step Agent](examples/agents/multi-step/)
4. [Squad Agent](examples/agents/squad/)
5. [Modular Agentic Planner Agent](examples/agents/map/)

### Packages

1. [Brave Tools](packages/tiny_brave/)
2. [Tiny Chat](packages/tiny_chat)
3. [Tiny OpenAI](packages/tiny_openai)
4. [Tiny MistralAI](packages/tiny_mistralai)
5. [Tiny Gemini](packages/tiny_gemini)
6. [Tiny Anthropic](packages/tiny_anthropic)
7. [Tiny VoyageAI](packages/tiny_voyageai)
8. [Tiny Graph](packages/tiny_graph)

## Linting & Formatting
3. 🔍 Explore more examples below:

### 📚 Features & Examples

| Name | Type | Description |
|------|------|-------------|
| [Tool Usage](examples/tool-usage) | Basics | Basic tool creation and usage |
| [LLM Usage](examples/llm-usage) | Basics | Direct LLM interaction patterns |
| [Function Calling](examples/function-calling) | Basics | Function calling with LLMs |
| [Chat Buffer Memory](examples/memory/basic-chat-memory) | Memory | Store complete conversation history |
| [Summary Buffer Memory](examples/memory/buffer-summary-memory) | Memory | Summarize older messages to save tokens |
| [Window Buffer Memory](examples/memory/buffer-window-chat-memory) | Memory | Keep only recent N messages |
| [Combined Memory](examples/memory/combined-memory) | Memory | Combine multiple memory strategies |
| [Basic Tools](examples/tool-usage/main.py) | Tools | Simple tool definitions with `@tool` |
| [Reasoning Tools](examples/tool-usage/main.py) | Tools | Tools that provide reasoning traces |
| [JIT Tools](examples/tool-usage/main.py) | Tools | Just-in-time compiled tools |
| [Middlewares in Agents](examples/agents/middleware/) | Agents | Add custom processing layers to agents |
| [ReAct Agent](examples/agents/react/) | Agents | Reasoning and acting pattern |
| [Multi-Step Agent](examples/agents/multi-step/) | Agents | Break down complex tasks into steps |
| [Squad Agent](examples/agents/squad/) | Agents | Coordinate multiple specialized agents |
| [Modular Agentic Planner](examples/agents/map/) | Agents | Advanced planning with modular architecture |
| [Tiny OpenAI](packages/tiny_openai) | Package | OpenAI LLMs and embeddings |
| [Tiny Anthropic](packages/tiny_anthropic) | Package | Anthropic Claude LLMs |
| [Tiny MistralAI](packages/tiny_mistralai) | Package | Mistral AI LLMs |
| [Tiny Gemini](packages/tiny_gemini) | Package | Google Gemini LLMs |
| [Tiny VoyageAI](packages/tiny_voyageai) | Package | VoyageAI embedding models |
| [Brave Tools](packages/tiny_brave/) | Package | Brave search integration |
| [Tiny Chat](packages/tiny_chat) | Package | FastAPI-based chat interface |
| [Tiny Graph](packages/tiny_graph) | Package | Neo4j knowledge graph integration |

## ✅ Linting & Formatting

To ensure code quality, formatting consistency, and type safety, run:

Expand Down
2 changes: 1 addition & 1 deletion docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ Built with modern Python best practices, Tinygent provides:

## Why Tinygent?

### **Easy to Learn, Hard to Master**
### **Start Simple, Scale Your Way**

Tinygent follows the principle of progressive disclosure - start simple, grow complex only when needed.

Expand Down
81 changes: 51 additions & 30 deletions examples/chat-app/main.py
Original file line number Diff line number Diff line change
@@ -1,42 +1,75 @@
from pathlib import Path
from typing import Any
import uuid

from pydantic import Field

from tiny_brave import NewsSearchApiResponse
from tiny_brave import NewsSearchRequest
from tiny_brave import WebSearchApiResponse
from tiny_brave import WebSearchRequest
from tiny_brave import brave_news_search
from tiny_brave import brave_web_search
import tiny_chat as tc
from tinygent.agents import TinyReActAgent
from tinygent.agents.middleware import TinyBaseMiddleware
from tinygent.agents.middleware import TinyToolCallLimiterMiddleware
from tinygent.cli.utils import discover_and_register_components
from tinygent.core.datamodels.tool import AbstractTool
from tinygent.core.factory import build_llm
from tinygent.core.factory import build_agent
from tinygent.core.types import TinyModel
from tinygent.logging import setup_logger
from tinygent.memory import BufferChatMemory
from tinygent.prompts import ReActPromptTemplate
from tinygent.tools import register_tool
from tinygent.utils import tiny_yaml_load

logger = setup_logger('debug')

discover_and_register_components()


class BraveNewsConfig(TinyModel):
class BraveConfig(TinyModel):
query: str = Field(..., description='The search query string.')


@register_tool
async def brave_news(data: BraveNewsConfig):
result = await brave_news_search(NewsSearchRequest(q=data.query))
async def brave_news(data: BraveConfig):
"""Search recent news articles from news publishers (headlines, journalism, press, media coverage)."""
raw = await brave_news_search(NewsSearchRequest(q=data.query))

return result
return NewsSearchApiResponse.model_validate(raw)


@register_tool
async def brave_web(data: BraveConfig):
"""Search general web pages (blogs, docs, forums, websites, informational pages)."""
raw = await brave_web_search(WebSearchRequest(q=data.query))

return WebSearchApiResponse.model_validate(raw)


class ChatClientMiddleware(TinyBaseMiddleware):
@staticmethod
async def _send_sources(run_id: str, result: Any) -> bool:
if not isinstance(result, (NewsSearchApiResponse, WebSearchApiResponse)):
return False

items = (
result.results
if isinstance(result, NewsSearchApiResponse)
else result.web.results
if result.web
else []
)

for item in items:
await tc.AgentSourceMessage(
parent_id=run_id,
name=item.title,
url=item.url,
favicon=item.meta_url.favicon if item.meta_url else None,
description=item.description,
).send()

return True

async def on_answer(
self, *, run_id: str, answer: str, kwargs: dict[str, Any]
) -> None:
Expand Down Expand Up @@ -70,31 +103,19 @@ async def after_tool_call(
content=result,
).send()

try:
news_response = NewsSearchApiResponse.model_validate(result)
for article in news_response.results:
await tc.AgentSourceMessage(
parent_id=run_id,
name=article.title,
url=article.url,
favicon=article.meta_url.favicon if article.meta_url else None,
description=article.description,
).send()

except Exception:
if not await self._send_sources(run_id, result):
logger.exception('Failed to parse tool call.')


agent = TinyReActAgent(
llm=build_llm('openai:gpt-4o'),
tools=[brave_news],
agent = build_agent(
'react',
llm='openai:gpt-4o',
tools=[brave_news, brave_web],
memory=BufferChatMemory(),
prompt_template=ReActPromptTemplate(
**tiny_yaml_load(
str(Path(__file__).parent.parent / 'agents' / 'react' / 'prompts.yaml')
)
),
middleware=[ChatClientMiddleware()],
middleware=[
ChatClientMiddleware(),
TinyToolCallLimiterMiddleware(tool_name='brave_web', max_tool_calls=1),
],
)


Expand Down
Loading