mirror of
https://github.com/arkorty/B.Tech-Project-III.git
synced 2026-04-19 12:41:48 +00:00
98 lines
4.7 KiB
Python
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."""
|
|
)
|