HANI is a web-based interface for conducting negotiations between humans and AI agents. It provides a rich set of tools for analyzing negotiation dynamics, making offers, and understanding your negotiation partner's behavior.
📖 Full documentation: autoneg.github.io/hani — installation, quick start, authentication, scenarios, Prolific integration, and more.
🎮 Try it now: anac.cs.brown.edu/hanplay/app — public playground, no signup required.
pip install haniRun the setup command to initialize your configuration:
hani setupThis creates the settings directory at ~/negmas/hani/settings/ with:
env.json- Main configuration fileusers.json- User credentialsscenarios/- Default negotiation scenarios- Other configuration files
haniThis starts both the main app (port 5006) and guest/playground (port 5008).
Then open your browser to http://localhost:5006 and log in:
- Username:
adminoruser - Password:
adminpassoruserpass(defaults, change in env.json)
| Command | Description |
|---|---|
hani |
Start all services (main app + guest playground) |
hani setup |
Initialize settings directory with default configuration |
hani main |
Start only the main app (default port 5006) |
hani guest |
Start only the guest/playground app (default port 5008) |
hani auth |
Show OAuth setup instructions |
hani --help |
Show all available commands and options |
Each command accepts a --port flag (e.g. hani guest --port 12000,
hani-app --port 6006, hani-reg --port 5107). The top-level hani
command takes --main-port / --guest-port to override both services
at once. Equivalent env vars: HANI_PORT, HANI_GUEST_PORT,
HANI_REG_PORT.
For paid Prolific studies, see docs/prolific.md.
# Start with specific agent types
hani --agents "AspirationNegotiator,helpers.AgentK"
# Start without opening browser
hani main --no-browser
# Run setup and overwrite existing files
hani setup --force
# Set custom admin password during setup
hani setup --admin-password "my-secure-password"HANI uses a JSON configuration file located at ~/negmas/hani/settings/env.json.
{
"urls": {
"app": "http://localhost:5006",
"playground": "http://localhost:5008"
},
"admin": {
"password": "adminpass",
"emails": []
},
"auth": {
"mode": "password",
"cookie_secret": "change-this-in-production"
}
}| Setting | Description | Default |
|---|---|---|
urls.app |
Main app URL | http://localhost:5006 |
urls.playground |
Guest playground URL | http://localhost:5008 |
admin.password |
Admin user password | adminpass |
admin.emails |
Admin emails for OAuth mode | [] |
auth.mode |
Auth mode: password, dual, oauth, auto |
password |
auth.cookie_secret |
Session cookie secret | (default value) |
auth.enforce_consent |
Require consent form before negotiation | false |
- Action Panel: Make offers by setting values for each negotiation issue
- History View: See the full negotiation history with offers from both parties
- Utility Display: Real-time feedback on how good each offer is for you
When configured with an LLM API key, HANI provides:
- Text-to-Outcome Extraction: Extract structured offers from natural language messages
- Outcome-to-Text Generation: Generate natural language descriptions of your offers
- Response Generator: Describe what you want to say and let AI generate both the message and offer
- Utility Plot: Visualize utility over time
- Outcome Plot: See where offers fall in the outcome space
- Preferences View: Understand your preferences for the negotiation
- Negotiation Trace: Detailed log of all negotiation events
HANI supports multiple authentication modes configured via auth.mode in env.json.
Best for local development and small deployments.
{
"auth": {
"mode": "password"
}
}- Users stored in
~/negmas/hani/settings/users.json - Default users:
admin/adminpassanduser/userpass - New users can register via
/registerendpoint
Allows users to log in with either password or OAuth providers.
{
"auth": {
"mode": "dual"
},
"oauth": {
"redirect_uri": "http://localhost:5006",
"providers": {
"github": {
"enabled": true,
"key": "your-github-client-id",
"secret": "your-github-client-secret"
},
"google": {
"enabled": true,
"key": "your-google-client-id",
"secret": "your-google-client-secret"
}
}
}
}Run hani auth to see detailed setup instructions. Here's a summary:
- Go to https://github.com/settings/developers
- Create a new OAuth App
- Set Homepage URL:
http://localhost:5006 - Set Authorization callback URL:
http://localhost:5006/oauth/callback - Copy Client ID and Client Secret to
env.json
- Go to https://console.cloud.google.com/apis/credentials
- Create OAuth 2.0 Client ID (Web application)
- Add authorized redirect URI:
http://localhost:5006/oauth/callback - Copy Client ID and Client Secret to
env.json
In OAuth/dual mode, admin access is granted to users whose email is in the admin.emails list:
{
"admin": {
"emails": ["admin@example.com", "another-admin@example.com"]
}
}When auth.mode is auto:
- Uses OAuth if OAuth credentials are configured
- Falls back to password authentication otherwise
HANI allows you to specify which negotiator types the AI opponent can use.
# Use specific NegMAS negotiators
hani --agents "AspirationNegotiator,BoulwareTBNegotiator,ConcederTBNegotiator"
# Mix of different negotiator types
hani --agents "AspirationNegotiator,helpers.AgentK,helpers.Atlas3,LLMHybridNegotiator"
# Use only HANI custom negotiators
hani --agents "helpers.AgentK,helpers.HardHeaded,helpers.AverageTitForTat"Use group syntax to select categories of agents:
# All LLM-based negotiators
hani --agents ":llm"
# All template-based negotiators
hani --agents ":template"
# All NegMAS negotiators
hani --agents ":negmas"
# Combine groups
hani --agents ":llm,:template"hani --agents "AspirationNegotiator,BoulwareTBNegotiator,NaiveTitForTatNegotiator"hani --agents "helpers.AgentK,helpers.Atlas3,helpers.CUHKAgent,helpers.HardHeaded"hani --agents "genius.Atlas3,genius.AgentK,genius.HardHeaded"hani --agents "LLMHybridNegotiator,LLMBoulwareTBNegotiator,LLMConcederTBNegotiator"# Load from a Python file
hani --agents "file:mynegotiator.MyNegotiator"
# With path
hani --agents "file:agents/custom/myneg.MyNegotiator"Create ~/negmas/hani/settings/announcements.md to display custom announcements on the welcome screen.
Custom scenarios can be placed in ~/negmas/hani/settings/scenarios/. Run hani setup to copy the default scenarios as examples.
Edit ~/negmas/hani/settings/consent.md to customize the consent form. Enable it with:
{
"auth": {
"enforce_consent": true
}
}-
Scenario Loading: A negotiation scenario is loaded with defined issues (e.g., price, quantity) and preferences for each party.
-
Turn-Based Negotiation: You and the AI agent take turns making offers. Each offer specifies values for all issues.
-
Decision Making: On each turn, you can:
- Send an offer: Propose specific values for each issue
- Accept: Accept the current offer from your partner
- End Negotiation: Terminate without agreement
-
Text Messages: Optionally include natural language messages with your offers to communicate intent.
-
Analysis: Use the built-in tools to understand the negotiation dynamics and make informed decisions.
Administrators can configure LLM settings in the sidebar under "LLM Settings":
- Provider: OpenAI or Anthropic
- Model: The model to use (e.g.,
gpt-4o-mini,claude-3-haiku) - Temperature: Controls response randomness (0.0-2.0)
- Prompts: Customize extraction and generation prompts
LLM API keys can be set in ~/negmas/hani/settings/llm_settings.json or via environment variables (OPENAI_API_KEY, ANTHROPIC_API_KEY).
To contribute, clone this repo and install development dependencies:
git clone https://github.com/autoneg/hani.git
cd hani
pip install -e ".[dev]"hani devThis enables auto-reload when files change.
src/hani/
├── app.py # Main application
├── auth.py # Authentication utilities
├── common.py # Shared configuration
├── dual_auth.py # OAuth and dual auth handlers
├── llm_service.py # LLM integration
├── run.py # CLI entry point
├── tools/ # Analysis tools
│ ├── generator.py # Response generator tool
│ ├── preferences.py # Preferences viewer
│ └── ...
├── scenarios/ # Built-in negotiation scenarios
├── sample_scenarios/ # Default scenarios copied on setup
└── default_settings/ # Default configuration files
This project is licensed under the GNU Affero General Public License v3.0 (AGPL-3.0).
See the LICENSE file for details.
Yasser Mohammad (yasserfarouk@gmail.com)
