Skip to main content

NegMAS wrappers for NegoLog negotiating agents

Project description

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
│   ├── 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

AGPL-3.0 License - see LICENSE for details.

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},
}

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

negmas_negolog-0.2.2.tar.gz (28.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

negmas_negolog-0.2.2-py3-none-any.whl (47.4 kB view details)

Uploaded Python 3

File details

Details for the file negmas_negolog-0.2.2.tar.gz.

File metadata

  • Download URL: negmas_negolog-0.2.2.tar.gz
  • Upload date:
  • Size: 28.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for negmas_negolog-0.2.2.tar.gz
Algorithm Hash digest
SHA256 1704d427dcbe5f0912b949e2798da908153fc24c114f9f87f6afc91512391d17
MD5 87db50a7a614a029ca2bc99c97618ea3
BLAKE2b-256 826cfedd56c02ddfe2e98831c14383094f25f1a181da574d8a8b3e5134d6808f

See more details on using hashes here.

Provenance

The following attestation bundles were made for negmas_negolog-0.2.2.tar.gz:

Publisher: publish.yml on autoneg/negmas-negolog

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file negmas_negolog-0.2.2-py3-none-any.whl.

File metadata

  • Download URL: negmas_negolog-0.2.2-py3-none-any.whl
  • Upload date:
  • Size: 47.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for negmas_negolog-0.2.2-py3-none-any.whl
Algorithm Hash digest
SHA256 3b9d20e86abe96dad779ae37189c133b9c95854919b998fe23f3e128031009bd
MD5 107e2920d0d06df9b6ddcdddbdfc5e0e
BLAKE2b-256 f0e22c30519959eeb63d6d76d30fed67857592916983717cfeb2f480842c8df8

See more details on using hashes here.

Provenance

The following attestation bundles were made for negmas_negolog-0.2.2-py3-none-any.whl:

Publisher: publish.yml on autoneg/negmas-negolog

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page