mirror of
https://github.com/arkorty/B.Tech-Project-III.git
synced 2026-04-19 20:51:49 +00:00
init
This commit is contained in:
97
negot8/backend/agents/negotiator_agent.py
Normal file
97
negot8/backend/agents/negotiator_agent.py
Normal file
@@ -0,0 +1,97 @@
|
||||
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."""
|
||||
)
|
||||
Reference in New Issue
Block a user