joao
A dual-purpose tool providing both a Python library for building chat agents and a ready-to-use CLI chat interface. Built with function calling capabilities and compatible with OpenAI-style APIs.
Features
-
As a Library:
- Simple and clean API for chat interactions
- Support for function calling (tools)
- Both synchronous and asynchronous APIs
- Streaming support for real-time responses
- Compatible with any OpenAI-style API (tested with Gemini 2.0 Flash)
-
As a CLI:
- Interactive chat interface
- Single prompt mode
- Rich markdown formatting for output
- Temperature control for response randomness
- Configurable system prompts
- Multiple API provider support
-
Minimal dependencies
Requirements
- Python 3.7 or higher
- An API key from one of these providers:
- Gemini (Recommended): Get your API key from Google AI Studio
- OpenAI: Get your API key from OpenAI Platform
Installation
-
Install the package:
pip install joao
-
Set up environment variables:
For Gemini (default):
export OPENAI_API_KEY="your_gemini_api_key"
For OpenAI:
export OPENAI_API_KEY="your_openai_api_key" export OPENAI_BASE_URL="https://api.openai.com/v1" export OPENAI_MODEL="gpt-3.5-turbo" # or your preferred model
Usage
Command Line Options
# Start interactive chat mode (with system prompt)
joao -s "You are a helpful assistant"
# Start chat mode without system prompt
joao
# Single prompt mode with system prompt
joao -s "You are a helpful assistant" "What is the capital of France?"
# Single prompt mode without system prompt
joao "What is the capital of France?"
# Enable streaming output
joao -s "You are a storyteller" --stream "Tell me a story"
# Set temperature (0.0-2.0, default: 0)
joao -s "You are a creative writer" -t 0.7 "Tell me a creative story"
# Show raw output without markdown formatting
joao -s "You are a helpful assistant" --raw "Hello"
# Use different API provider
joao -s "You are a helpful assistant" -e OPENAI "Using OpenAI API"
# Show debug info
joao -s "You are a helpful assistant" --debug "Test message"
Interactive Chat Commands
When in chat mode, you have access to these commands:
/reset- Clear conversation history/reset <prompt>- Clear history and set new system promptCtrl+C- Exit chat session
Configuration Examples
from joao import Agent, AsyncAgent
# Basic configuration with API key
agent = Agent(
system_prompt="You are a helpful assistant",
api_key="your-api-key-here"
)
# Full configuration
agent = Agent(
system_prompt="You are a helpful assistant",
api_key="your-api-key-here",
temperature=0.7, # Control response randomness (0.0-2.0)
tenant_prefix="AZURE", # Use AZURE_OPENAI_BASE_URL, AZURE_OPENAI_MODEL etc.
debug=True # Enable debug output
)
# Async agent configuration
async_agent = AsyncAgent(
system_prompt="You are a helpful assistant",
api_key="your-api-key-here",
temperature=0.7,
tenant_prefix="OPENAI" # Use OPENAI_BASE_URL, OPENAI_MODEL etc.
)
The API key can be provided in three ways (in order of precedence):
- Directly in the constructor via
api_keyparameter - Through environment variable
OPENAI_API_KEY - Through prefixed environment variable (e.g.,
AZURE_OPENAI_API_KEYif tenant_prefix="AZURE")
Simple Chat API
from joao import Agent
# Create an agent with a personality
agent = Agent(
"You are Snoopy, the beloved Peanuts character",
api_key="your-api-key-here" # Optional - can also use environment variable
)
# Get a response
response = agent.request("Who are your friends?")
print(response)
# Get a streamed response
for token in agent.request("Tell me a story", stream=True):
print(token, end="", flush=True)
print() # Final newline
Using Function Calling (Tools)
from joao import Agent
def drive_to(location: str):
"""Drive to the specified location"""
print(f"Driving to {location}!")
# Create an agent with tools
agent = Agent(
"You are a helpful driver",
api_key="your-api-key-here" # Optional - can also use environment variable
)
response = agent.request(
"Can you drive me to San Francisco?",
tools=[drive_to],
auto_use_tools=True # Auto-execute any tool calls
)
Async Support
from joao import AsyncAgent
import asyncio
async def main():
agent = AsyncAgent(
"You are a helpful assistant",
api_key="your-api-key-here" # Optional - can also use environment variable
)
response = await agent.request("Hello!")
print(response)
# With streaming
async for token in agent.request("Tell me a story", stream=True):
print(token, end="", flush=True)
print()
asyncio.run(main())
Environment Variables
OPENAI_API_KEY- Your API keyOPENAI_BASE_URL- API endpoint (default: Gemini endpoint)OPENAI_MODEL- Model to use (default: gemini-2.0-flash)
You can prefix these with any string by using the -e flag, e.g., -e AZURE will look for AZURE_OPENAI_API_KEY
Metadata
Release files for joao 0.1.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| joao-0.1.1.tar.gz | 16.7 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| joao-0.1.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 31.4 kB
Release files / joao-0.1.1.tar.gz
| Download URL | joao-0.1.1.tar.gz |
|---|---|
| Size | 16.7 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
af0c7011d810ed46a8c069c8aac4fd18369d3831f6c17efb5cdfde4b3520e726
|
|
BLAKE2b-256 checksum How to use checksums |
1b862a1e6042ad022f05a10c83c137cb89420e7fddcd9c843489d0f2355d5949
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.0.1 CPython/3.12.0
|
Release files / joao-0.1.1-py3-none-any.whl
| Download URL | joao-0.1.1-py3-none-any.whl |
|---|---|
| Size | 14.7 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
be2a9c09a45f00c335d9d45a37ed18bfcff2b06caf1f663e3414d6817fdf55f1
|
|
BLAKE2b-256 checksum How to use checksums |
f5b6e1932418e4b23c2c94eb99d6ffc8e6afbdd3eb4b42b1798ba41f70323308
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.0.1 CPython/3.12.0
|