A powerful framework for orchestrating multi-agent teams using Large Language Models. Create intelligent AI agent swarms that collaborate through streaming delegation and dynamic tool discovery.
Project description
Gnosari Engine
Core Agent Orchestration Library
The Gnosari Engine is the core orchestration layer for AI agent teams. It provides configuration-driven agent management, tool integration, knowledge retrieval (RAG), and multi-agent coordination.
Table of Contents
- Quick Start
- Architecture Overview
- Providers
- Agent Execution Flow
- YAML Configuration Reference
- CLI Commands
- Tools System
- Knowledge System (RAG)
- Sessions
- Structured Output
- Events System
- Non-Active Fields Reference
Quick Start
Prerequisites
- Python 3.12+
- Poetry for dependency management
- API Keys for LLM providers
Installation
# Clone and install
git clone https://github.com/neomanex/gnosari-engine.git
cd gnosari-engine
poetry install
# Set up environment
cp .env.example .env
# Edit .env with your API keys
Your First Team
Create my-team.yaml:
id: "my-team"
name: "My First Team"
agents:
- id: "coordinator"
is_orchestrator: true
model: "gpt-4o"
instructions: |
You coordinate tasks and delegate to specialists.
delegations:
- target_agent_id: "writer"
instructions: "Delegate writing tasks"
- id: "writer"
model: "gpt-4o"
instructions: |
You create clear, engaging content.
Run Your Team
# Run entire team
poetry run gnosari run my-team.yaml -m "Write a blog post about AI"
# Run specific agent
poetry run gnosari run my-team.yaml -m "Hello" -a coordinator
# With streaming
poetry run gnosari run my-team.yaml -m "Hello" --stream
Architecture Overview
┌─────────────────────────────────────────────────────────────────┐
│ CLI / Library │
│ gnosari run | gnosari push | gnosari knowledge | gnosari view │
└─────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────┐
│ Configuration Service │
│ Parse → Validate → Build → Resolve → Index │
└─────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────┐
│ Domain Objects │
│ Team, Agent, Tool, Knowledge, Trait │
└─────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────┐
│ GnosariRunner │
│ Provider autodiscovery + execution │
└─────────────────────────────────────────────────────────────────┘
│
┌───────────────┴───────────────┐
▼ ▼
┌─────────────────────────┐ ┌─────────────────────────┐
│ OpenAI Provider │ │ Claude Provider │
│ (OpenAI Agents SDK) │ │ (Claude Agent SDK) │
│ Default provider │ │ Best for dev/complex │
└─────────────────────────┘ └─────────────────────────┘
Directory Structure
src/gnosari_engine/
├── cli/ # CLI commands and services
│ └── commands/ # run, view, push, task, start, learn, status, version
├── config/ # Configuration loading pipeline
├── factories/ # Domain object factories
├── knowledge/ # Knowledge loading service (uses gnosisllm-knowledge library)
│ └── services/ # KnowledgeLoaderService
├── learning/ # Agent learning system (parking)
├── prompts/ # Prompt building utilities
├── queue/ # Celery async task queue (ready, not active)
├── runners/ # Provider strategies
│ ├── provider/ # OpenAI, Claude implementations
│ └── factories/ # Stream processor factory
├── schemas/ # Pydantic domain models
│ └── domain/ # Team, Agent, Tool, Knowledge, Event, etc.
├── services/ # Business logic services
├── sessions/ # Session persistence
│ ├── providers/ # openai, claude session providers
│ └── events/ # Redis event publishing
└── tools/ # Tool implementations
├── builtin/ # KnowledgeQueryTool, MemoryTool, EmitEventTool, etc.
├── factories/ # Tool factory
├── providers/ # Provider-specific tool wrappers
└── streaming/ # Tool streaming support
Providers
OpenAI Provider (Default)
- Uses OpenAI Agents SDK (
agentspackage) - General-purpose orchestration
- Native support for handoffs, delegations (as tools), MCP servers
- Session persistence via database
Claude Provider
- Uses Claude Agent SDK
- Best suited for development and complex tasks
- Session integration not yet implemented
Agent Execution Flow
The AgentRun → ctx.context Flow
This is the key pattern for understanding how context flows through the engine:
┌──────────────────────────────────────────────────────────────────┐
│ 1. AgentRun Created │
│ - agent: Agent configuration │
│ - team: Team configuration │
│ - message: User input │
│ - context: ExecutionContext (stream, debug, etc.) │
│ - metadata: AgentRunMetadata (session_id, account_id, etc.) │
└──────────────────────────────────────────────────────────────────┘
│
▼
┌──────────────────────────────────────────────────────────────────┐
│ 2. Prompt Building │
│ AgentPromptBuilder.build_agent_prompt() │
│ - Base instructions │
│ - Team context │
│ - Traits (name, description, instructions) │
│ - Knowledge sources (with query instructions) │
│ - Available tools │
│ - Handoffs/delegations info │
│ - Memory (if not empty) │
└──────────────────────────────────────────────────────────────────┘
│
▼
┌──────────────────────────────────────────────────────────────────┐
│ 3. OpenAI Agent Creation (OpenAIAgentFactory) │
│ Agent( │
│ name=agent.name, │
│ instructions=processed_instructions, │
│ model=agent.model, │
│ tools=[...regular_tools, ...delegation_tools], │
│ handoffs=[...handoff_agents], │
│ ) │
└──────────────────────────────────────────────────────────────────┘
│
▼
┌──────────────────────────────────────────────────────────────────┐
│ 4. Execution │
│ Runner.run( │
│ agent, │
│ input=message, │
│ session=openai_session, │
│ context=agent_run ◄── AgentRun passed as context │
│ ) │
└──────────────────────────────────────────────────────────────────┘
│
▼
┌──────────────────────────────────────────────────────────────────┐
│ 5. Tool Execution │
│ async def _execute_openai_tool(ctx, args): │
│ session_context = ctx.context ◄── ctx.context IS AgentRun │
│ result = await base_tool.execute_core_logic( │
│ agent_run=session_context, │
│ **parsed_args │
│ ) │
└──────────────────────────────────────────────────────────────────┘
Delegation vs Handoffs
| Aspect | Delegations | Handoffs |
|---|---|---|
| Implementation | .as_tool() - Agent becomes a tool |
Native Agent.handoffs array |
| Context | Stateless - doesn't pass conversation context | Stateful - transfers full control with context |
| Use Case | Sub-tasks, specialized operations | Complete workflow transfer |
| Return | Returns to calling agent | Does not return automatically |
MCP Server Lifecycle
MCP servers require manual lifecycle management within a single async task to avoid cancel scope issues:
# Task-isolated streaming pattern
async def _isolated_producer():
connected_servers = []
try:
# Connect in THIS task
for server in mcp_servers:
await server.connect()
connected_servers.append(server)
# Run agent
async for event in result.stream_events():
await event_queue.put(event)
finally:
# Cleanup in THIS task (same task as connect)
for server in connected_servers:
await server.cleanup()
YAML Configuration Reference
Team Configuration
# Required
id: "my-team" # Team identifier (unique)
# Optional
name: "My Team" # Display name (auto-generated from id if not set)
description: "Team description" # Optional description
version: "1.0.0" # Configuration version
tags: ["production", "sales"] # Team tags for organization
# Team-level configuration
config:
max_turns: 25 # Maximum conversation turns
timeout: 600 # Execution timeout in seconds
debug: false # Enable debug mode
# Components
agents: [...] # Required - at least one agent
tools: [...] # Team-level tools
knowledge: [...] # Team-level knowledge bases
traits: [...] # Team-level traits
Agent Configuration
# Required
id: "ceo" # Agent identifier (unique within team)
instructions: | # Agent base instructions (min 10 chars)
You are the CEO agent responsible for...
# Optional - Identity
name: "CEO Agent" # Display name (auto-generated from id)
description: "Chief agent" # Agent description
# Optional - Model Configuration
model: "gpt-4o" # LLM model (default: gpt-4o or env OPENAI_MODEL)
# Optional - Behavior
is_orchestrator: true # Exactly ONE agent must be orchestrator
max_turns: 10 # Override team max_turns
debug: false # Enable debug mode for this agent
# Optional - Components (reference IDs or inline definitions)
tools: # Tools available to this agent
- "api_tool"
- "mcp_server"
knowledge: # Knowledge bases available
- "company_docs"
traits: # Personality traits
- "helpful"
- "professional"
# Optional - Agent Relations
handoffs: # Agents to transfer control to
- target_agent_id: "specialist"
condition: "When technical expertise needed"
message: "Transferring to specialist"
delegations: # Agents to delegate tasks to
- target_agent_id: "researcher"
instructions: "Research the topic thoroughly"
# Optional - Memory
memory:
content: "Previous context..." # Persisted memory content
# Optional - Structured Output (forces typed JSON responses)
structured_output:
example: # Schema inferred from example types
task_name: "Implement feature"
priority: "high"
estimated_hours: 8
strict: true # Enable strict mode (default: true)
Tool Configuration
Built-in Tool
id: "knowledge_query" # Tool identifier
name: "Knowledge Query" # Display name
description: "Query knowledge" # Tool description
# Built-in tool definition
module: "gnosari_engine.tools.builtin.knowledge_query"
class_name: "KnowledgeQueryTool"
# Tool arguments
args:
some_config: "value"
MCP Tool (HTTP/SSE)
id: "my_mcp_server"
name: "My MCP Server"
description: "External MCP server"
# MCP configuration
url: "http://localhost:8000/mcp"
connection_type: "sse" # "sse" | "streamable_http" | "stdio"
headers:
Authorization: "Bearer ${API_KEY}"
timeout: 30 # Connection timeout in seconds
MCP Tool (Stdio)
id: "local_mcp"
name: "Local MCP"
command: "python"
connection_type: "stdio"
args:
- "-m"
- "my_mcp_server"
Knowledge Configuration
id: "company_docs" # Knowledge identifier
name: "Company Documentation" # Display name
description: "Internal docs" # Description (shown in agent prompt)
# Knowledge type and sources
type: "website" # website | sitemap | youtube | pdf | text | csv | json | directory
data: # Data sources (URLs or file paths)
- "https://docs.company.com"
- "https://wiki.company.com"
# Optional - Provider configuration
config:
provider: "opensearch"
opensearch:
host: "localhost"
port: 9200
loader_config:
chunk_size: 6000
chunk_overlap: 200
Trait Configuration
id: "helpful" # Trait identifier
name: "Helpful" # Display name
description: "Always helpful" # Description (shown in agent prompt)
instructions: | # Behavior instructions (injected into system prompt)
Always be helpful and supportive.
Provide clear explanations.
Environment Variable Substitution
Use ${VAR_NAME} or ${VAR_NAME:default_value} in YAML:
tools:
- id: "api_tool"
url: "${API_URL:http://localhost:8000}"
headers:
Authorization: "Bearer ${API_KEY}"
Complete Example
id: "sales-team"
name: "Sales Team"
version: "1.0.0"
config:
max_turns: 25
timeout: 600
traits:
- id: "professional"
name: "Professional"
instructions: "Maintain professional communication at all times."
- id: "empathetic"
name: "Empathetic"
instructions: "Show empathy and understanding to customers."
knowledge:
- id: "product_catalog"
name: "Product Catalog"
description: "All product information and pricing"
type: "website"
data:
- "https://products.company.com"
tools:
- id: "crm_api"
name: "CRM API"
url: "http://localhost:8001/mcp"
connection_type: "streamable_http"
timeout: 30
agents:
- id: "sales_manager"
name: "Sales Manager"
is_orchestrator: true
instructions: |
You are the Sales Manager responsible for:
- Handling customer inquiries
- Delegating to specialists when needed
- Closing deals
model: "gpt-4o"
tools:
- "crm_api"
knowledge:
- "product_catalog"
traits:
- "professional"
- "empathetic"
delegations:
- target_agent_id: "product_specialist"
instructions: "Get detailed product information"
- id: "product_specialist"
name: "Product Specialist"
is_orchestrator: false
instructions: |
You are a Product Specialist with deep knowledge of:
- Product features and specifications
- Technical details
- Pricing and availability
knowledge:
- "product_catalog"
traits:
- "professional"
CLI Commands
gnosari run
Run a team or specific agent.
# Run entire team (orchestrator handles routing)
gnosari run teams/my_team.yaml -m "Hello team!"
# Run specific agent
gnosari run teams/my_team.yaml -m "Hello agent!" -a ceo
# With session persistence
gnosari run teams/my_team.yaml -m "Continue discussion" -s session-001
# Options
--stream/--no-stream # Streaming output (default: enabled)
--debug/--no-debug # Debug mode
--provider [openai|claude] # LLM provider (default: openai)
--database-url URL # Database for sessions
--tool-streaming/--no-tool-streaming # Tool streaming (default: enabled)
gnosari view
View team configuration details.
# Tree format (default)
gnosari view teams/my_team.yaml
# JSON format
gnosari view teams/my_team.yaml --format json
# Table format
gnosari view teams/my_team.yaml --format table
# Flow chart
gnosari view teams/my_team.yaml --format chart
gnosari push
Push team configuration to Gnosari API.
gnosari push teams/my_team.yaml --api-url https://api.gnosari.com
gnosari knowledge (via gnosisllm-knowledge library)
The knowledge CLI is provided by the gnosisllm-knowledge library.
# Show all available commands
gnosari knowledge --help
# Setup OpenSearch with ML model for neural search
gnosari knowledge setup
# Load and index content from URLs or sitemaps
gnosari knowledge load <url>
# Search indexed content
gnosari knowledge search "query" --mode hybrid
# Show configuration and environment info
gnosari knowledge info
# Agentic search commands
gnosari knowledge agentic setup # Setup agentic search agents
gnosari knowledge agentic chat # Interactive agentic chat
gnosari knowledge agentic status # Show agent status
gnosari task run
Execute a task by ID from the database.
gnosari task run teams/my_team.yaml --task-id 123
gnosari task run teams/my_team.yaml -t 123 --async # Async via queue
gnosari start
Start the queue worker (for async task execution).
gnosari start
gnosari start --concurrency 8
gnosari start --queue priority_queue
gnosari learn
Learning system commands (currently in development).
gnosari status
Check system status.
gnosari version
Display version information.
Tools System
Built-in Tools
| Tool | Description | Auto-Injected |
|---|---|---|
KnowledgeQueryTool |
Query knowledge bases (multi-KB, search modes) | Yes, when agent has knowledge |
MemoryTool |
Store and recall agent memories | No |
EmitEventTool |
Emit events to UI via tool streaming | No |
GnosariTasksTool |
Task management operations | No |
CodingAgentTool |
Code execution | No |
Tool Factory
The AutoDiscoveryToolFactory automatically discovers tools:
- Looks up tool by
module+class_name - Creates provider-specific wrapper (OpenAI, Claude)
- Initializes with
argsfrom configuration - Passes
agent_runfor context access
MCP Integration
MCP (Model Context Protocol) is the preferred way to add custom tools:
tools:
- id: "external_api"
url: "http://localhost:8000/mcp"
connection_type: "streamable_http" # Recommended
headers:
Authorization: "Bearer ${TOKEN}"
timeout: 30
Connection Types:
sse: Server-Sent Events (legacy)streamable_http: HTTP with streaming (recommended)stdio: Local subprocess
Knowledge System (RAG)
Architecture
The knowledge system uses the gnosisllm-knowledge library as a facade for all knowledge operations:
- Unified API: Single
Knowledgeclass handles all search and indexing operations - Multi-Knowledge Query: Query multiple knowledge bases in a single call
- Multiple Search Modes: hybrid, semantic, keyword, and agentic search
- Multi-Tenancy: Per-account index isolation via
index_namefield
OpenSearch Integration
Knowledge bases use OpenSearch with hybrid search:
- Keyword search: BM25 algorithm
- Semantic search: OpenAI embeddings (1536 dimensions)
- Hybrid scoring: Combination of both (default mode)
- Agentic search: AI-powered reasoning with citations
Data Loaders
| Type | Description | Data Format |
|---|---|---|
website |
Scrape web pages | URLs |
sitemap |
Parse sitemap and scrape | Sitemap URL |
discovery |
Crawl and discover URLs | Starting URL |
youtube |
Extract transcripts | YouTube URLs |
pdf |
Parse PDF documents | File paths or URLs |
text |
Plain text files | File paths |
csv |
CSV data | File paths |
json |
JSON data | File paths |
directory |
All files in directory | Directory path |
Auto-Injection
When an agent has knowledge configured, the engine automatically:
- Adds
knowledge_querytool to the agent - Includes knowledge sources in the system prompt
- Provides query instructions to the agent
Multi-Knowledge Query
The KnowledgeQueryTool supports querying multiple knowledge bases in a single call:
# Query multiple KBs
knowledge_names=["docs", "faq", "support"]
search_mode="hybrid" # or "semantic", "keyword", "agentic"
limit=10
Results include collection_id to identify the source knowledge base for each result.
Sessions
GnosariSession
Sessions persist conversation history:
- Provider:
openai_database(SQL-based) - Storage: PostgreSQL, MySQL, or SQLite
- Tracking: session_id, account_id, team_id, agent_id
Session Configuration
# Environment variables
SESSION_PROVIDER=file|database|gnosari_api
SESSION_DATABASE_URL=postgresql+asyncpg://user:pass@host:port/db
# Usage
gnosari run team.yaml -m "Hello" -s session-001
gnosari run team.yaml -m "What did I say?" -s session-001 # Remembers context
Session Events (Redis)
Sessions can publish events to Redis for real-time updates:
- Located in
sessions/events/ RedisPublisherfor event publishing- Event models for structured event data
Structured Output
Structured output enables agents to return responses in a defined schema format rather than free-form text.
Configuration Modes
| Mode | Fields | Description |
|---|---|---|
| Example Only | example |
Schema auto-inferred from example types |
| Schema Only | schema |
Explicit JSON Schema definition |
| Both | schema + example |
Full control with LLM guidance (recommended) |
Type Inference (Example-Only Mode)
| YAML Value | Inferred Type |
|---|---|
"string" |
string |
123 |
integer |
12.5 |
number |
true/false |
boolean |
["a", "b"] |
array |
{key: val} |
object (recursive) |
Example Configuration
agents:
- id: "task_analyzer"
instructions: "Analyze tasks and return structured data"
is_orchestrator: true
structured_output:
example:
task_name: "Implement feature X"
priority: "high"
estimated_hours: 8
tags: ["backend", "api"]
subtasks:
- name: "Design"
hours: 2
strict: true
Implementation Details
- OpenAI Provider: Uses
output_typeparameter with dynamically generated Pydantic models - Result Handling: Structured outputs are automatically converted to Python dicts
- Strict Mode: When
strict: true(default), OpenAI enforces exact schema compliance
Events System
The engine supports emitting events to the UI via the EmitEventTool.
EmitEventTool
A passthrough tool that emits events to the UI via existing tool streaming:
# Tool receives event data and returns it unchanged
# UI detects emit_event tool calls and handles them as events
event_id: str # Event identifier (e.g., "conversation.completed")
metadata_json: str # JSON string containing event payload
Usage in Agent Instructions
agents:
- id: "event_emitter"
instructions: |
When you complete a task, emit an event using the emit_event tool:
- event_id: "task.completed"
- metadata_json: '{"task_name": "...", "result": "success"}'
tools:
- id: "emit_event"
module: "gnosari_engine.tools.builtin.emit_event"
class_name: "EmitEventTool"
How It Works
- Agent calls
emit_eventtool with event_id and metadata - Tool returns event data unchanged
- UI receives tool_call/tool_result via streaming
- UI detects
emit_eventcalls and processes as events
Non-Active Fields Reference
The following fields are defined in the schema but not actively used in execution:
Agent Fields
| Field | Status | Notes |
|---|---|---|
temperature |
Loaded but NOT passed to OpenAI | Bug/oversight - should be passed |
reasoning_effort |
Not used | Defined but not implemented |
role |
Display + learning only | Not used in execution |
listen |
Not implemented | Event system planned |
trigger |
Not implemented | Event system planned |
learning_objectives |
Learning system only | System is being rethought |
Delegation Fields
| Field | Status | Notes |
|---|---|---|
mode |
Display only | Always uses sync via .as_tool() |
timeout |
Not used | Delegation timeout not implemented |
retry_attempts |
Not used | Retry logic not implemented |
Trait Fields
| Field | Status | Notes |
|---|---|---|
weight |
Display only | Not used for actual weighting in prompts |
category |
Display only | For organization, not execution |
tags |
Display only | For organization, not execution |
Tool Fields
| Field | Status | Notes |
|---|---|---|
rate_limit |
Not implemented | Rate limiting not implemented |
enable_caching |
Not implemented | Response caching not implemented |
cache_timeout |
Not implemented | Cache timeout not implemented |
retry_attempts |
Not implemented | Retry logic for builtin tools not implemented |
retry_delay |
Not implemented | Retry delay not implemented |
Team Fields
| Field | Status | Notes |
|---|---|---|
config.log_level |
Not used | Logging configured via CLI |
config.enable_memory |
Not used | Memory always available |
overrides |
Loaded, not applied | Override system not implemented |
components |
Not used | Component filtering not implemented |
account_id |
Display/push only | Not used in execution |
Development
Environment Setup
Required environment variables (see .env.example):
OPENAI_API_KEY=your-key
ANTHROPIC_API_KEY=your-key # If using Claude
GNOSARI_API_KEY=your-key # For pushing teams
OPENSEARCH_HOST=localhost # For knowledge system
OPENSEARCH_PORT=9200
Key Files
| File | Purpose |
|---|---|
runners/gnosari_runner.py |
Main entry point, provider autodiscovery |
runners/provider/openai.py |
OpenAI provider implementation |
runners/provider/claude.py |
Claude provider implementation |
config/services.py |
YAML → Domain Objects pipeline |
prompts/agent_prompt_builder.py |
System prompt construction |
schemas/domain/*.py |
Team, Agent, Tool, Knowledge models |
tools/builtin/*.py |
Built-in tool implementations |
tools/factories/ |
Tool factory |
License
Creative Commons Attribution 4.0 International License
Maintenance: Update this file when architecture, CLI, configuration options, or significant patterns change.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file gnosari_engine-0.5.0.tar.gz.
File metadata
- Download URL: gnosari_engine-0.5.0.tar.gz
- Upload date:
- Size: 213.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: poetry/2.2.1 CPython/3.13.9 Darwin/23.4.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
73b1cc71ea64dfcabe008e785cce9f4bd342a9fa372a3c69600229b11d297dc2
|
|
| MD5 |
e584c0328d08f7b88276a34799e6923a
|
|
| BLAKE2b-256 |
70c8757ca234a56f5c22c3cce53ec986ae6c220c5824e923780c2d903f79e557
|
File details
Details for the file gnosari_engine-0.5.0-py3-none-any.whl.
File metadata
- Download URL: gnosari_engine-0.5.0-py3-none-any.whl
- Upload date:
- Size: 295.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: poetry/2.2.1 CPython/3.13.9 Darwin/23.4.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
46613b32c1fc71ace9bbf5d82b4762e1226ad85ab28deb249c030ae5fa53e830
|
|
| MD5 |
8d6b802c36a65cecbce80c42fc0b22b7
|
|
| BLAKE2b-256 |
9f650c18016076ddab06cbb4d21629b345e821c0365a4ca95e33705d574aa5b0
|