Skip to main content

negmas-negolog

PyPI - Python Version PyPI - Version PyPI - Status PyPI - Downloads License: AGPL-3.0 Tests Docs Ruff

A bridge between NegMAS and NegoLog negotiation frameworks, allowing NegoLog agents to be used as NegMAS SAONegotiator instances.

Documentation | API Reference | Available Agents


NegoLog Attribution

This package vendors NegoLog — an integrated Python-based automated negotiation framework.

NegoLog was presented at IJCAI 2024. If you use this package, please cite the original NegoLog paper as well as NegMAS (see Citation):

@inproceedings{ijcai2024p998,
  title     = {NegoLog: An Integrated Python-based Automated Negotiation Framework with Enhanced Assessment Components},
  author    = {Doğru, Anıl and Keskin, Mehmet Onur and Jonker, Catholijn M. and Baarslag, Tim and Aydoğan, Reyhan},
  booktitle = {Proceedings of the Thirty-Third International Joint Conference on
               Artificial Intelligence, {IJCAI-24}},
  publisher = {International Joint Conferences on Artificial Intelligence Organization},
  editor    = {Kate Larson},
  pages     = {8640--8643},
  year      = {2024},
  month     = {8},
  note      = {Demo Track},
  doi       = {10.24963/ijcai.2024/998},
  url       = {https://doi.org/10.24963/ijcai.2024/998},
}

Features

  • 26 NegoLog agents available as NegMAS negotiators
  • Seamless integration with NegMAS mechanisms and tournaments
  • Full compatibility with NegMAS utility functions and outcome spaces
  • Zero configuration - agents work out of the box

Installation

pip install negmas-negolog

Or with uv:

uv add negmas-negolog

Development Installation

git clone https://github.com/yasserfarouk/negmas-negolog.git
cd negmas-negolog
uv sync --dev

Quick Start

from negmas.outcomes import make_issue
from negmas.preferences import LinearAdditiveUtilityFunction
from negmas.sao import SAOMechanism

from negmas_negolog import BoulwareAgent, ConcederAgent

# Define negotiation issues
issues = [
    make_issue(values=["low", "medium", "high"], name="price"),
    make_issue(values=["1", "2", "3"], name="quantity"),
]

# Create utility functions
buyer_ufun = LinearAdditiveUtilityFunction(
    values={
        "price": {"low": 1.0, "medium": 0.5, "high": 0.0},
        "quantity": {"1": 0.0, "2": 0.5, "3": 1.0},
    },
    weights={"price": 0.6, "quantity": 0.4},
)

seller_ufun = LinearAdditiveUtilityFunction(
    values={
        "price": {"low": 0.0, "medium": 0.5, "high": 1.0},
        "quantity": {"1": 1.0, "2": 0.5, "3": 0.0},
    },
    weights={"price": 0.6, "quantity": 0.4},
)

# Create mechanism and add agents
mechanism = SAOMechanism(issues=issues, n_steps=100)
mechanism.add(BoulwareAgent(name="buyer"), preferences=buyer_ufun)
mechanism.add(ConcederAgent(name="seller"), preferences=seller_ufun)

# Run negotiation
state = mechanism.run()

if state.agreement:
    print(f"Agreement reached: {state.agreement}")
    print(f"Buyer utility: {buyer_ufun(state.agreement):.3f}")
    print(f"Seller utility: {seller_ufun(state.agreement):.3f}")
else:
    print("No agreement reached")

Available Agents

The following table lists all 26 available agents with their ANAC competition results and references.

Note: Agent descriptions were AI-generated based on the referenced papers and source code analysis.

Agent Competition Algorithm Summary Reference
Atlas3Agent ANAC 2015 Winner Utility-based bid search with frequency-based opponent modeling and evolutionary stable strategy concession Mori & Ito 2017
HardHeaded ANAC 2011 Winner Hardheaded concession with frequency-based opponent preference learning van Krimpen et al. 2013
CUHKAgent ANAC 2012 Winner Adaptive negotiation strategy for bilateral multi-item negotiations Hao & Leung 2014
Caduceus ANAC 2016 Winner Portfolio/mixture of experts combining multiple negotiation agents Güneş et al. 2017
PonPokoAgent ANAC 2017 Winner Multiple random bidding strategies to prevent opponent prediction Aydoğan et al. 2021
AgentGG ANAC 2019 Winner Frequentist opponent model with importance-based bid selection Aydoğan et al. 2020
AhBuNeAgent ANAC 2020 Winner Heuristic bidding with Importance Map opponent model Yıldırım et al. 2023
AgentBuyog ANAC 2015 Runner-up Opponent concession function estimation Fujita et al. 2017
Kawaii ANAC 2015 Runner-up Time-based concession strategy Baarslag et al. 2015
ParsCatAgent ANAC 2016 Runner-up Time-dependent bidding with adaptive thresholds Aydoğan et al. 2021
YXAgent ANAC 2016 Runner-up Frequency-based opponent modeling Aydoğan et al. 2021
LuckyAgent2022 ANAC 2022 Runner-up BOA components with stop-learning multi-armed bandit mechanism Ebrahimnezhad & Nassiri-Mofakham 2022
MICROAgent ANAC 2022 Runner-up Concedes only when opponent concedes de Jonge 2022
IAMhaggler ANAC 2012 Nash Winner Gaussian Process prediction for opponent concession Williams et al. 2012
AgentKN ANAC 2017 Nash Finalist Simulated Annealing bid search with frequency-based scoring Aydoğan et al. 2021
ParsAgent ANAC 2015 Finalist Hybrid time-dependent, random and frequency-based strategy Khosravimehr & Nassiri-Mofakham 2017
RandomDance ANAC 2015 Finalist Weighted function opponent modeling with random selection Kakimoto & Fujita 2017
Rubick ANAC 2017 Finalist Time-based conceder with frequency-based opponent model Aydoğan et al. 2021
SAGAAgent ANAC 2019 Finalist Genetic Algorithm for self-preference estimation Aydoğan et al. 2020
NiceTitForTat — Tit-for-tat with Bayesian opponent model aiming for Nash point Baarslag et al. 2013
BoulwareAgent — Time-based concession (slow, sub-linear) using Bezier curves Faratin et al. 1998
ConcederAgent — Time-based concession (fast, super-linear) Faratin et al. 1998
LinearAgent — Time-based concession (linear) Faratin et al. 1998
HybridAgent — Combines Time-Based and Behavior-Based strategies Keskin et al. 2021
HybridAgentWithOppModel — Hybrid Agent extended with opponent modeling Yesevi et al. 2023
Caduceus2015 — Sub-agent for Caduceus portfolio Güneş et al. 2017

Using the NegMAS Registry

All NegoLog agents are automatically registered in the NegMAS negotiator registry when you import the package. This allows you to discover and instantiate agents dynamically:

import negmas_negolog  # Triggers auto-registration
from negmas import negotiator_registry

# Query all negolog agents
negolog_agents = negotiator_registry.query_by_tag("negolog")
print(f"Found {len(negolog_agents)} NegoLog agents")

# Query by ANAC competition year
anac2015_agents = negotiator_registry.query_by_tag("anac-2015")

# Query learning agents
learning_agents = negotiator_registry.query_by_tag("learning")

# Get a specific agent class by name
AgentClass = negotiator_registry.get("Atlas3Agent").type
agent = AgentClass(name="my_atlas3")

# Combined queries
from negmas.registry import query
results = query(negotiator_registry, tags=["negolog", "frequency"], bilateral_only=True)

Registry Tags

Each agent is tagged with relevant metadata:

  • negolog - All agents from this package
  • sao, propose, respond - Negotiation capabilities
  • anac, anac-YYYY - ANAC competition participation
  • time-based, learning, frequency, bayesian, tit-for-tat - Strategy types

Naming Convention

To avoid conflicts with Genius agents that share the same name, some agents are registered with an "NL" prefix:

  • Genius has AgentGG, negmas-negolog registers NLAgentGG
  • Genius has HardHeaded, negmas-negolog registers NLHardHeaded

Agents unique to NegoLog keep their original names (e.g., Atlas3Agent, BoulwareAgent).

Mixing with NegMAS Agents

NegoLog agents can negotiate with native NegMAS agents:

from negmas.sao import AspirationNegotiator
from negmas_negolog import BoulwareAgent

mechanism = SAOMechanism(issues=issues, n_steps=100)
mechanism.add(BoulwareAgent(name="negolog_agent"), preferences=ufun1)
mechanism.add(AspirationNegotiator(name="negmas_agent"), preferences=ufun2)

state = mechanism.run()

Running Tournaments

from negmas.sao import SAOMechanism
from negmas_negolog import (
    BoulwareAgent, ConcederAgent, LinearAgent,
    Atlas3Agent, HardHeaded, NiceTitForTat
)

agents = [
    BoulwareAgent, ConcederAgent, LinearAgent,
    Atlas3Agent, HardHeaded, NiceTitForTat
]

# Run round-robin tournament
results = []
for i, AgentA in enumerate(agents):
    for AgentB in agents[i+1:]:
        mechanism = SAOMechanism(issues=issues, n_steps=100)
        mechanism.add(AgentA(name="A"), preferences=ufun1)
        mechanism.add(AgentB(name="B"), preferences=ufun2)
        state = mechanism.run()
        results.append({
            "agent_a": AgentA.__name__,
            "agent_b": AgentB.__name__,
            "agreement": state.agreement is not None,
        })

API Reference

Base Classes

NegologNegotiatorWrapper

Base class for all NegoLog agent wrappers. Inherits from negmas.sao.SAONegotiator.

class NegologNegotiatorWrapper(SAONegotiator):
    def __init__(
        self,
        preferences: BaseUtilityFunction | None = None,
        ufun: BaseUtilityFunction | None = None,
        name: str | None = None,
        session_time: int = 180,  # Session time in seconds for NegoLog agent
        **kwargs,
    ): ...

NegologPreferenceAdapter

Adapts NegMAS utility functions to NegoLog's Preference interface. Used internally by the wrappers.

Creating Custom Wrappers

To wrap additional NegoLog agents:

from negmas_negolog import NegologNegotiatorWrapper
from agents.MyAgent.MyAgent import MyAgent as NLMyAgent

class MyAgent(NegologNegotiatorWrapper):
    """NegMAS wrapper for NegoLog's MyAgent."""
    negolog_agent_class = NLMyAgent

Development

Running Tests

uv run pytest tests/ -v

Running Specific Test Files

uv run pytest tests/test_wrapper.py -v      # Wrapper functionality tests
uv run pytest tests/test_equivalence.py -v  # Native vs wrapped comparison tests

Behavior Comparison

The project includes a comprehensive behavior comparison script that tests all 25 agents in both native NegoLog and wrapped NegMAS environments. This helps verify that wrapped agents behave equivalently to their native counterparts.

# Run the behavior comparison
uv run python scripts/compare_behavior.py

The script generates reports in the reports/ directory:

  • behavior_comparison_report.md - Human-readable Markdown report
  • behavior_comparison_report.json - Machine-readable JSON data

The comparison tests each agent against a Boulware opponent and measures:

  • Agreement consistency - Whether both environments reach the same agreement outcome
  • Round count similarity - How close the negotiation lengths are
  • Utility equivalence - Whether final utilities match when both agree
  • First offer similarity - Whether agents start with the same initial offer

See the latest comparison report for current results.

Architecture

negmas-negolog/
├── src/negmas_negolog/
│   ├── __init__.py      # Package exports
│   ├── common.py        # Base classes (NegologNegotiatorWrapper, NegologPreferenceAdapter)
│   ├── agents/          # Individual agent wrapper modules
│   │   ├── atlas3.py
│   │   ├── boulware.py
│   │   ├── conceder.py
│   │   └── ...          # 25 agent wrappers total
│   └── _vendor/NegoLog/ # Vendored NegoLog library (bundled so it ships in the wheel)
│       ├── agents/      # NegoLog agent implementations
│       └── nenv/        # NegoLog environment
├── docs/                # Documentation source
├── scripts/
│   └── compare_behavior.py  # Behavior comparison script
├── reports/             # Generated comparison reports
│   ├── behavior_comparison_report.md
│   └── behavior_comparison_report.json
└── tests/
    ├── test_wrapper.py      # Wrapper tests
    └── test_equivalence.py  # Equivalence tests

How It Works

  1. Preference Adaptation: NegologPreferenceAdapter wraps NegMAS utility functions to provide NegoLog's Preference interface, allowing NegoLog agents to evaluate bids using NegMAS utility functions.

  2. Bid/Outcome Conversion: The wrapper handles conversion between NegMAS Outcome tuples and NegoLog Bid objects.

  3. Time Mapping: NegMAS relative time (0 to 1) is passed directly to NegoLog agents, which use it for their concession strategies.

  4. Action Translation: NegoLog Offer and Accept actions are translated to NegMAS propose() returns and ResponseType values.

License

This project is licensed under AGPL-3.0 — see LICENSE for details.

It bundles and redistributes NegoLog, which is licensed under GPL-3.0 (see NegoLog Attribution). Combining a GPL-3.0 work with an AGPL-3.0 work is expressly permitted by section 13 of both licenses: the NegoLog portion remains under GPL-3.0 while the distribution as a whole is governed by AGPL-3.0. NegoLog's license text ships with the package at src/negmas_negolog/_vendor/NegoLog/LICENSE.

Acknowledgments

Citation

If you use this library in your research, please cite this wrapper, NegMAS, and the original NegoLog paper:

@software{negmas_negolog,
  title = {negmas-negolog: Bridge between NegMAS and NegoLog},
  author = {Mohammad, Yasser},
  year = {2024},
  url = {https://github.com/yasserfarouk/negmas-negolog}
}

@inproceedings{mohammad2018negmas,
  title     = {NegMAS: A Platform for Situated Negotiations},
  author    = {Mohammad, Yasser and Greenwald, Amy and Nakadai, Shinji},
  booktitle = {ACAN Workshop at IJCAI},
  year      = {2018},
  url       = {https://github.com/yasserfarouk/negmas}
}

@inproceedings{ijcai2024p998,
  title     = {NegoLog: An Integrated Python-based Automated Negotiation Framework with Enhanced Assessment Components},
  author    = {Doğru, Anıl and Keskin, Mehmet Onur and Jonker, Catholijn M. and Baarslag, Tim and Aydoğan, Reyhan},
  booktitle = {Proceedings of the Thirty-Third International Joint Conference on
               Artificial Intelligence, {IJCAI-24}},
  publisher = {International Joint Conferences on Artificial Intelligence Organization},
  editor    = {Kate Larson},
  pages     = {8640--8643},
  year      = {2024},
  month     = {8},
  note      = {Demo Track},
  doi       = {10.24963/ijcai.2024/998},
  url       = {https://doi.org/10.24963/ijcai.2024/998},
}

Metadata

Release files for negmas-negolog 0.3.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for negmas-negolog 0.3.0
File Size Uploaded Provenance Actions
negmas_negolog-0.3.0.tar.gz 182.4 kB With provenance Details for negmas_negolog-0.3.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for negmas-negolog 0.3.0
File Interpreter ABI Platform Actions
negmas_negolog-0.3.0-py3-none-any.whl Python 3 none any Details for negmas_negolog-0.3.0-py3-none-any.whl

Total release size: 455.5 kB

Release files / negmas_negolog-0.3.0.tar.gz

Download URL negmas_negolog-0.3.0.tar.gz
Size 182.4 kB
Tags Source
SHA-256 checksum
How to use checksums
134449271524c0c4a9f245f95b4f5bc7abeb0155359eceddff5896c8a40178c8
BLAKE2b-256 checksum
How to use checksums
a2b9dcf148f906e50350e89507f46c4ae314c7974a78ff189150e058bcf0c151
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 2, 2026.

Transparency log

Release files / negmas_negolog-0.3.0-py3-none-any.whl

Download URL negmas_negolog-0.3.0-py3-none-any.whl
Size 273.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
64fbe036dd84a0a3beed7875483247903face7c0bfd9091f4f60980ca8b0136b
BLAKE2b-256 checksum
How to use checksums
62513da5192eee5f1159d91cebc9037452eda9aba032c7c4837e59100a84728a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 2, 2026.

Transparency log

Security for negmas-negolog 0.3.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for negmas_negolog-0.3.0.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 2, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page