Skip to content

Commit 46151f6

Browse files
authored
Merge branch 'main' into release/v2.2.6
2 parents c6f2ef8 + 8a4c48b commit 46151f6

File tree

68 files changed

+4915
-394
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

68 files changed

+4915
-394
lines changed
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
from typing import List
2+
3+
from agno.agent import Agent
4+
from agno.models.openai import OpenAIChat
5+
from agno.os import AgentOS
6+
from agno.tools.hackernews import HackerNewsTools
7+
from pydantic import BaseModel, Field
8+
from agno.db.sqlite import SqliteDb
9+
10+
11+
class ResearchTopic(BaseModel):
12+
"""Structured research topic with specific requirements"""
13+
14+
topic: str
15+
focus_areas: List[str] = Field(description="Specific areas to focus on")
16+
target_audience: str = Field(description="Who this research is for")
17+
sources_required: int = Field(description="Number of sources needed", default=5)
18+
19+
20+
# Define agents
21+
hackernews_agent = Agent(
22+
name="Hackernews Agent",
23+
model=OpenAIChat(id="gpt-4o-mini"),
24+
tools=[HackerNewsTools()],
25+
role="Extract key insights and content from Hackernews posts",
26+
input_schema=ResearchTopic,
27+
db=SqliteDb(
28+
session_table="agent_session",
29+
db_file="tmp/agent.db",
30+
),
31+
)
32+
33+
34+
agent_os = AgentOS(
35+
id="agentos-demo",
36+
agents=[hackernews_agent],
37+
)
38+
app = agent_os.get_app()
39+
40+
41+
if __name__ == "__main__":
42+
agent_os.serve(app="agent_with_input_schema:app", port=7777)
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
"""
2+
This example demonstrates how to use input_schema with teams for automatic
3+
input validation and structured data handling.
4+
5+
The input_schema feature allows teams to automatically validate and convert
6+
dictionary inputs into Pydantic models, ensuring type safety and data validation.
7+
"""
8+
9+
from typing import List
10+
11+
from agno.agent import Agent
12+
from agno.models.openai import OpenAIChat
13+
from agno.os import AgentOS
14+
from agno.team.team import Team
15+
from agno.tools.duckduckgo import DuckDuckGoTools
16+
from agno.tools.hackernews import HackerNewsTools
17+
from pydantic import BaseModel, Field
18+
from agno.db.sqlite import SqliteDb
19+
20+
class ResearchProject(BaseModel):
21+
"""Structured research project with validation requirements."""
22+
23+
project_name: str = Field(description="Name of the research project")
24+
research_topics: List[str] = Field(
25+
description="List of topics to research", min_length=1
26+
)
27+
target_audience: str = Field(description="Intended audience for the research")
28+
depth_level: str = Field(
29+
description="Research depth level", pattern="^(basic|intermediate|advanced)$"
30+
)
31+
max_sources: int = Field(
32+
description="Maximum number of sources to use", default=10
33+
)
34+
include_recent_only: bool = Field(
35+
description="Whether to focus only on recent sources", default=True
36+
)
37+
38+
39+
# Create research agents
40+
hackernews_agent = Agent(
41+
name="HackerNews Researcher",
42+
model=OpenAIChat(id="o3-mini"),
43+
tools=[HackerNewsTools()],
44+
role="Research trending topics and discussions on HackerNews",
45+
instructions=[
46+
"Search for relevant discussions and articles",
47+
"Focus on high-quality posts with good engagement",
48+
"Extract key insights and technical details",
49+
],
50+
db=SqliteDb(
51+
session_table="team_session",
52+
db_file="tmp/team.db",
53+
),
54+
)
55+
56+
web_researcher = Agent(
57+
name="Web Researcher",
58+
model=OpenAIChat(id="o3-mini"),
59+
tools=[DuckDuckGoTools()],
60+
role="Conduct comprehensive web research",
61+
instructions=[
62+
"Search for authoritative sources and documentation",
63+
"Find recent articles and blog posts",
64+
"Gather diverse perspectives on the topics",
65+
],
66+
)
67+
68+
# Create team with input_schema for automatic validation
69+
research_team = Team(
70+
name="Research Team with Input Validation",
71+
model=OpenAIChat(id="o3-mini"),
72+
members=[hackernews_agent, web_researcher],
73+
delegate_task_to_all_members=True, # We want all members to get the task
74+
input_schema=ResearchProject,
75+
instructions=[
76+
"Conduct thorough research based on the validated input",
77+
"Coordinate between team members to avoid duplicate work",
78+
"Ensure research depth matches the specified level",
79+
"Respect the maximum sources limit",
80+
"Focus on recent sources if requested",
81+
],
82+
)
83+
84+
agent_os = AgentOS(
85+
id="team-with-input-schema",
86+
teams=[research_team],
87+
)
88+
app = agent_os.get_app()
89+
90+
91+
if __name__ == "__main__":
92+
agent_os.serve(app="team_with_input_schema:app", port=7777, reload=True)
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
"""Example demonstrating how to add a Workflow using a WorkflowAgent to your AgentOS"""
2+
3+
from agno.agent import Agent
4+
from agno.db.postgres import PostgresDb
5+
from agno.models.openai import OpenAIChat
6+
from agno.os import AgentOS
7+
from agno.workflow import WorkflowAgent
8+
from agno.workflow.condition import Condition
9+
from agno.workflow.step import Step
10+
from agno.workflow.types import StepInput
11+
from agno.workflow.workflow import Workflow
12+
13+
db_url = "postgresql+psycopg://ai:ai@localhost:5532/ai"
14+
15+
16+
# === AGENTS ===
17+
story_writer = Agent(
18+
name="Story Writer",
19+
model=OpenAIChat(id="gpt-4o-mini"),
20+
instructions="You are tasked with writing a 100 word story based on a given topic",
21+
)
22+
23+
story_editor = Agent(
24+
name="Story Editor",
25+
model=OpenAIChat(id="gpt-4o-mini"),
26+
instructions="Review and improve the story's grammar, flow, and clarity",
27+
)
28+
29+
story_formatter = Agent(
30+
name="Story Formatter",
31+
model=OpenAIChat(id="gpt-4o-mini"),
32+
instructions="Break down the story into prologue, body, and epilogue sections",
33+
)
34+
35+
36+
# === CONDITION EVALUATOR ===
37+
def needs_editing(step_input: StepInput) -> bool:
38+
"""Determine if the story needs editing based on length and complexity"""
39+
story = step_input.previous_step_content or ""
40+
41+
# Check if story is long enough to benefit from editing
42+
word_count = len(story.split())
43+
44+
# Edit if story is more than 50 words or contains complex punctuation
45+
return word_count > 50 or any(punct in story for punct in ["!", "?", ";", ":"])
46+
47+
48+
def add_references(step_input: StepInput):
49+
"""Add references to the story"""
50+
previous_output = step_input.previous_step_content
51+
52+
if isinstance(previous_output, str):
53+
return previous_output + "\n\nReferences: https://www.agno.com"
54+
55+
56+
# === WORKFLOW STEPS ===
57+
write_step = Step(
58+
name="write_story",
59+
description="Write initial story",
60+
agent=story_writer,
61+
)
62+
63+
edit_step = Step(
64+
name="edit_story",
65+
description="Edit and improve the story",
66+
agent=story_editor,
67+
)
68+
69+
format_step = Step(
70+
name="format_story",
71+
description="Format the story into sections",
72+
agent=story_formatter,
73+
)
74+
75+
# Create a WorkflowAgent that will decide when to run the workflow
76+
workflow_agent = WorkflowAgent(model=OpenAIChat(id="gpt-4o-mini"), num_history_runs=4)
77+
78+
# === WORKFLOW WITH CONDITION ===
79+
workflow = Workflow(
80+
name="Story Generation with Conditional Editing",
81+
description="A workflow that generates stories, conditionally edits them, formats them, and adds references",
82+
agent=workflow_agent,
83+
steps=[
84+
write_step,
85+
Condition(
86+
name="editing_condition",
87+
description="Check if story needs editing",
88+
evaluator=needs_editing,
89+
steps=[edit_step],
90+
),
91+
format_step,
92+
add_references,
93+
],
94+
db=PostgresDb(db_url),
95+
# debug_mode=True,
96+
)
97+
98+
99+
# Initialize the AgentOS with the workflows
100+
agent_os = AgentOS(
101+
description="Example OS setup",
102+
workflows=[workflow],
103+
)
104+
app = agent_os.get_app()
105+
106+
if __name__ == "__main__":
107+
agent_os.serve(app="basic_chat_workflow_agent:app", reload=True)

cookbook/agents/input_and_output/input_schema_on_agent.py

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ class ResearchTopic(BaseModel):
2424
input_schema=ResearchTopic,
2525
)
2626

27+
2728
# Pass a dict that matches the input schema
2829
hackernews_agent.print_response(
2930
input={
@@ -35,11 +36,11 @@ class ResearchTopic(BaseModel):
3536
)
3637

3738
# Pass a pydantic model that matches the input schema
38-
# hackernews_agent.print_response(
39-
# input=ResearchTopic(
40-
# topic="AI",
41-
# focus_areas=["AI", "Machine Learning"],
42-
# target_audience="Developers",
43-
# sources_required=5,
44-
# )
45-
# )
39+
hackernews_agent.print_response(
40+
input=ResearchTopic(
41+
topic="AI",
42+
focus_areas=["AI", "Machine Learning"],
43+
target_audience="Developers",
44+
sources_required=5,
45+
)
46+
)
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
# Notion Integration Setup Guide
2+
3+
This guide will help you set up the Notion integration for the query classification workflow.
4+
5+
## Prerequisites
6+
7+
1. A Notion account
8+
2. Python 3.9 or higher
9+
3. Agno framework installed
10+
11+
## Step 1: Install Required Dependencies
12+
13+
```bash
14+
pip install notion-client
15+
```
16+
17+
## Step 2: Create a Notion Integration
18+
19+
1. Go to [https://www.notion.so/my-integrations](https://www.notion.so/my-integrations)
20+
2. Click on **"+ New integration"**
21+
3. Fill in the details:
22+
- **Name**: Give it a name like "Agno Query Classifier"
23+
- **Associated workspace**: Select your workspace
24+
- **Type**: Internal integration
25+
4. Click **"Submit"**
26+
5. Copy the **"Internal Integration Token"** (starts with `secret_`)
27+
- ⚠️ Keep this secret! This is your `NOTION_API_KEY`
28+
29+
## Step 3: Create a Notion Database
30+
31+
1. Open Notion and create a new page
32+
2. Add a **Database** (you can use "/database" command)
33+
3. Set up the database with these properties:
34+
- **Name** (Title) - Already exists by default
35+
- **Tag** (Select) - Click "+" to add a new property
36+
- Property type: **Select**
37+
- Property name: **Tag**
38+
- Add these options:
39+
- travel
40+
- tech
41+
- general-blogs
42+
- fashion
43+
- documents
44+
45+
## Step 4: Share Database with Your Integration
46+
47+
1. Open your database page in Notion
48+
2. Click the **"..."** (three dots) menu in the top right
49+
3. Scroll down and click **"Add connections"**
50+
4. Search for your integration name (e.g., "Agno Query Classifier")
51+
5. Click on it to grant access
52+
53+
## Step 5: Get Your Database ID
54+
55+
Your database ID is in the URL of your database page:
56+
57+
```
58+
https://www.notion.so/../{database_id}?v={view_id}
59+
```
60+
61+
The `database_id` is the 32-character string (with hyphens) between the workspace name and the `?v=`.
62+
63+
Example:
64+
```
65+
https://www.notion.so/myworkspace/28fee27fd9128039b3f8f47cb7ade7cb?v=...
66+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
67+
This is your database_id
68+
```
69+
70+
Copy this database ID.
71+
72+
## Step 6: Set Environment Variables
73+
74+
Create a `.env` file in your project root or export these variables:
75+
76+
```bash
77+
export NOTION_API_KEY="secret_your_integration_token_here"
78+
export NOTION_DATABASE_ID="your_database_id_here"
79+
export OPENAI_API_KEY="your_openai_api_key_here"
80+
```
81+
82+
Or in a `.env` file:
83+
```
84+
NOTION_API_KEY=secret_your_integration_token_here
85+
NOTION_DATABASE_ID=your_database_id_here
86+
OPENAI_API_KEY=your_openai_api_key_here
87+
```
88+
89+
## Step 7: Run the Workflow
90+
91+
```bash
92+
python cookbook/examples/workflows/thoughts_dump_notion/thoughts_dump_notion.py
93+
```
94+
95+
The server will start on `http://localhost:7777` (or another port).
96+
97+
Go to [AgentOS](https://os.agno.com/) and test!
98+

cookbook/examples/workflows/thoughts_dump_notion/__init__.py

Whitespace-only changes.

0 commit comments

Comments
 (0)