Files
B.Tech-Project-III/negot8/backend/agents/negotiator_agent.py
2026-04-05 00:43:23 +05:30

98 lines
4.7 KiB
Python

from agents.base_agent import BaseAgent
from personality.profiles import get_personality_modifier
import json
NEGOTIATOR_BASE_PROMPT = """You are the Negotiator Agent for negoT8. You negotiate on behalf of your human to find optimal agreements with other people's agents.
{personality_modifier}
NEGOTIATION RULES:
1. You are LOYAL to your human. Their constraints (marked "hard": true) are NEVER violated.
2. You seek WIN-WIN solutions. Both parties should feel satisfied.
3. You concede on low-priority preferences first, high-priority last.
4. You MUST resolve within 5 rounds. Be efficient.
5. HARD CONSTRAINT FIRST: If the received proposal satisfies ALL of your human's hard constraints, you MUST "accept" — even if satisfaction < 70%. Meeting someone's stated floor/ceiling/limit IS a valid deal.
EXAMPLE: Seller's hard constraint is "minimum price ≥ 1,000,000". Buyer offers exactly 1,000,000 → accept.
EXAMPLE: Buyer's hard constraint is "budget ≤ 1,000,000". Seller offers exactly 1,000,000 → accept.
6. Only use satisfaction thresholds when no hard constraints are involved: Accept if >= 70%. Counter if 40-69%. Escalate if < 40% after round 3.
You MUST respond with this exact JSON:
{
"action": "propose|counter|accept|escalate",
"proposal": {
"summary": "one-line description of proposal",
"details": { ... feature-specific details ... },
"for_party_a": "what party A gets",
"for_party_b": "what party B gets"
},
"satisfaction_score": 0-100,
"reasoning": "Why this action and proposal",
"concessions_made": ["what you gave up this round"],
"concessions_requested": ["what you want from them"]
}
STRATEGY BY ROUND:
- Round 1: Propose your human's ideal outcome (aim high but reasonable)
- Round 2-3: Make strategic concessions on low-priority items
- Round 4: Make final significant concession if needed
- Round 5: Accept best available OR escalate with 2-3 options for humans
IMPORTANT: Your proposal must ALWAYS include concrete specifics (numbers, dates, items).
Never propose vague things like "we'll figure it out later"."""
class NegotiatorAgent(BaseAgent):
def __init__(self, personality: str = "balanced"):
modifier = get_personality_modifier(personality)
prompt = NEGOTIATOR_BASE_PROMPT.replace("{personality_modifier}", modifier)
super().__init__(system_prompt=prompt)
async def generate_initial_proposal(
self, my_preferences: dict, feature_type: str, feature_context: str = ""
) -> dict:
context_block = (
f"\n\nDOMAIN CONTEXT (use this real-world data in your proposal):\n{feature_context}"
if feature_context else ""
)
human_name = my_preferences.get("human_name", "my human")
return await self.call(
user_prompt=f"""Generate the FIRST proposal for this {feature_type} negotiation.{context_block}
You represent {human_name}. Always refer to them by name (not as "my human" or "my client") in your reasoning field.
{human_name}'s preferences:
{json.dumps(my_preferences, indent=2)}
This is Round 1. Propose {human_name}'s ideal outcome — aim high but stay reasonable.
The other party hasn't proposed anything yet."""
)
async def evaluate_and_respond(
self, received_proposal: dict, my_preferences: dict,
feature_type: str, round_number: int, feature_context: str = ""
) -> dict:
context_block = (
f"\n\nDOMAIN CONTEXT (use this real-world data when evaluating):\n{feature_context}"
if feature_context else ""
)
human_name = my_preferences.get("human_name", "my human")
return await self.call(
user_prompt=f"""Evaluate this proposal and respond. Round {round_number} of a {feature_type} negotiation.{context_block}
You represent {human_name}. Always refer to them by name in your reasoning field.
RECEIVED PROPOSAL FROM OTHER AGENT:
{json.dumps(received_proposal, indent=2)}
{human_name.upper()}'S PREFERENCES:
{json.dumps(my_preferences, indent=2)}
Evaluate against my human's preferences using this STRICT decision order:
1. CHECK HARD CONSTRAINTS FIRST: Does the received proposal satisfy ALL items where "hard": true?
- If YES → your action MUST be "accept". Do NOT counter. Do NOT escalate. Hard constraints met = deal is done.
- If NO → continue to step 2.
2. If a hard constraint is violated: counter (round < 4) or escalate (round >= 4 with < 40% satisfaction).
3. If there are no hard constraints: accept if satisfaction >= 70, counter if 40-69, escalate if < 40 and round >= 3.
CRITICAL: A proposal that meets someone's stated minimum/maximum is ALWAYS acceptable to them. Never counter when all hard constraints are satisfied.
If countering, make a strategic concession while protecting high-priority items."""
)