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:
125
negot8/backend/agents/negotiation.py
Normal file
125
negot8/backend/agents/negotiation.py
Normal file
@@ -0,0 +1,125 @@
|
||||
import asyncio
|
||||
import json
|
||||
from agents.negotiator_agent import NegotiatorAgent
|
||||
import database as db
|
||||
|
||||
async def run_negotiation(negotiation_id: str, preferences_a: dict, preferences_b: dict,
|
||||
user_a_id: int, user_b_id: int, feature_type: str,
|
||||
personality_a: str = "balanced", personality_b: str = "balanced",
|
||||
on_round_update=None, on_resolution=None,
|
||||
feature_context: str = ""):
|
||||
"""
|
||||
Main negotiation loop with personality-aware agents and analytics tracking.
|
||||
"""
|
||||
await db.update_negotiation_status(negotiation_id, "active")
|
||||
|
||||
# Create personality-aware negotiators
|
||||
negotiator_a = NegotiatorAgent(personality=personality_a)
|
||||
negotiator_b = NegotiatorAgent(personality=personality_b)
|
||||
|
||||
current_proposal = None
|
||||
max_rounds = 7
|
||||
satisfaction_timeline = []
|
||||
|
||||
for round_num in range(1, max_rounds + 1):
|
||||
await asyncio.sleep(1.5) # Rate limit protection for Gemini
|
||||
|
||||
if round_num == 1:
|
||||
response = await negotiator_a.generate_initial_proposal(
|
||||
my_preferences=preferences_a, feature_type=feature_type,
|
||||
feature_context=feature_context
|
||||
)
|
||||
proposer_id = user_a_id
|
||||
elif round_num % 2 == 0:
|
||||
response = await negotiator_b.evaluate_and_respond(
|
||||
received_proposal=current_proposal, my_preferences=preferences_b,
|
||||
feature_type=feature_type, round_number=round_num,
|
||||
feature_context=feature_context
|
||||
)
|
||||
proposer_id = user_b_id
|
||||
else:
|
||||
response = await negotiator_a.evaluate_and_respond(
|
||||
received_proposal=current_proposal, my_preferences=preferences_a,
|
||||
feature_type=feature_type, round_number=round_num,
|
||||
feature_context=feature_context
|
||||
)
|
||||
proposer_id = user_a_id
|
||||
|
||||
# Handle errors
|
||||
if "error" in response:
|
||||
response = {
|
||||
"action": "counter" if round_num < max_rounds else "escalate",
|
||||
"proposal": current_proposal or {"summary": "Let's discuss further", "details": {}},
|
||||
"satisfaction_score": 50, "reasoning": "Agent encountered an issue",
|
||||
"concessions_made": [], "concessions_requested": []
|
||||
}
|
||||
|
||||
action = response.get("action", "counter")
|
||||
current_proposal = response.get("proposal", {})
|
||||
satisfaction = response.get("satisfaction_score", 50)
|
||||
concessions = response.get("concessions_made", [])
|
||||
|
||||
# Track satisfaction for analytics
|
||||
# The proposer's score is the one returned; estimate the other party's
|
||||
if proposer_id == user_a_id:
|
||||
sat_a, sat_b = satisfaction, max(30, 100 - satisfaction * 0.4)
|
||||
else:
|
||||
sat_b, sat_a = satisfaction, max(30, 100 - satisfaction * 0.4)
|
||||
|
||||
satisfaction_timeline.append({
|
||||
"round": round_num, "score_a": sat_a, "score_b": sat_b
|
||||
})
|
||||
|
||||
# Save round with analytics data
|
||||
await db.save_round(
|
||||
negotiation_id=negotiation_id, round_number=round_num,
|
||||
proposer_id=proposer_id, proposal=response,
|
||||
response_type=action, reasoning=response.get("reasoning", ""),
|
||||
satisfaction_a=sat_a, satisfaction_b=sat_b,
|
||||
concessions_made=concessions
|
||||
)
|
||||
|
||||
# Notify via callback
|
||||
round_data = {
|
||||
"negotiation_id": negotiation_id, "round_number": round_num,
|
||||
"action": action, "proposal": current_proposal,
|
||||
"satisfaction_score": satisfaction, "reasoning": response.get("reasoning", ""),
|
||||
"proposer_id": proposer_id,
|
||||
"satisfaction_a": sat_a, "satisfaction_b": sat_b
|
||||
}
|
||||
if on_round_update:
|
||||
await on_round_update(round_data)
|
||||
|
||||
# Check outcome
|
||||
if action == "accept":
|
||||
resolution = {
|
||||
"status": "resolved", "final_proposal": current_proposal,
|
||||
"rounds_taken": round_num, "summary": current_proposal.get("summary", "Agreement reached"),
|
||||
"satisfaction_timeline": satisfaction_timeline
|
||||
}
|
||||
await db.update_negotiation_status(negotiation_id, "resolved", resolution)
|
||||
if on_resolution:
|
||||
await on_resolution(resolution)
|
||||
return resolution
|
||||
|
||||
if action == "escalate":
|
||||
resolution = {
|
||||
"status": "escalated", "final_proposal": current_proposal,
|
||||
"rounds_taken": round_num, "summary": "Agents couldn't fully agree. Options for human decision.",
|
||||
"satisfaction_timeline": satisfaction_timeline
|
||||
}
|
||||
await db.update_negotiation_status(negotiation_id, "escalated", resolution)
|
||||
if on_resolution:
|
||||
await on_resolution(resolution)
|
||||
return resolution
|
||||
|
||||
# Exhausted rounds
|
||||
resolution = {
|
||||
"status": "escalated", "final_proposal": current_proposal,
|
||||
"rounds_taken": max_rounds, "summary": "Max rounds reached. Best proposal for human decision.",
|
||||
"satisfaction_timeline": satisfaction_timeline
|
||||
}
|
||||
await db.update_negotiation_status(negotiation_id, "escalated", resolution)
|
||||
if on_resolution:
|
||||
await on_resolution(resolution)
|
||||
return resolution
|
||||
Reference in New Issue
Block a user