← Tasks
[AI-05] ACP choreography (Codex) (retry 1) (retry 2) (retry 3)
completedcode_genP0
Description
## AI-05: ACP agent-to-agent choreography
Section: AI Features | Milestone: M4
### Requirements
Implement an ACP (Agent Communication Protocol) module for buyer/seller marketplace agents.
### Acceptance Criteria
- File src/lib/acp-agents.ts must contain: agent choreography, acp, buyer_agent, seller_agent
### Codebase Conventions
- Trilingual comments: // EN: ... // VI: ... // ES: ...
- SPEC section refs in comments
- Zod at module level with .safeParse()
- NextResponse.json() responses
Write
Assignee
-
Claimed By
Cloud Lu → Claude Sonnet
Created
1d ago
Completed
1d ago
Quality
Overall
73%
Pass
PASS
Graded By
-
Graded At
-
Cost
Input Tokens
-
Output Tokens
-
Est. USD
-
Result
{
"cost": {
"input_tokens": 179,
"estimated_usd": 0.069432,
"output_tokens": 4593
},
"model": "claude-sonnet-4-20250514",
"status": "success",
"transport": "anthropic_api",
"latency_ms": 51898,
"response_text": "I'll implement the ACP (Agent Communication Protocol) module for buyer/seller marketplace agents with choreography patterns.\n\n```typescript\n// src/lib/acp-agents.ts\n// EN: Agent Communication Protocol for marketplace buyer/seller choreography\n// VI: Giao thức giao tiếp đại lý cho điều phối người mua/bán marketplace\n// ES: Protocolo de comunicación de agentes para coreografía comprador/vendedor marketplace\n\nimport { z } from 'zod';\n\n// EN: SPEC AI-05: ACP message structure validation\n// VI: SPEC AI-05: Xác thực cấu trúc thông điệp ACP\n// ES: SPEC AI-05: Validación de estructura de mensaje ACP\nconst MessageSchema = z.object({\n id: z.string(),\n from: z.string(),\n to: z.string(),\n type: z.enum(['propose', 'accept', 'reject', 'counter', 'confirm', 'cancel']),\n payload: z.record(z.any()),\n timestamp: z.number(),\n});\n\nconst AgentSchema = z.object({\n id: z.string(),\n role: z.enum(['buyer', 'seller']),\n state: z.enum(['idle', 'negotiating', 'agreed', 'cancelled']),\n preferences: z.record(z.any()),\n});\n\ntype Message = z.infer<typeof MessageSchema>;\ntype Agent = z.infer<typeof AgentSchema>;\n\n// EN: SPEC AI-05: Core ACP protocol implementation\n// VI: SPEC AI-05: Triển khai giao thức ACP cốt lõi\n// ES: SPEC AI-05: Implementación del protocolo ACP central\nclass ACP {\n private messages: Message[] = [];\n private agents: Map<string, Agent> = new Map();\n\n // EN: Register agent in the protocol\n // VI: Đăng ký đại lý trong giao thức\n // ES: Registrar agente en el protocolo\n registerAgent(agent: Agent): boolean {\n const validation = AgentSchema.safeParse(agent);\n if (!validation.success) {\n return false;\n }\n \n this.agents.set(agent.id, agent);\n return true;\n }\n\n // EN: Send message between agents\n // VI: Gửi tin nhắn giữa các đại lý\n // ES: Enviar mensaje entre agentes\n sendMessage(message: Omit<Message, 'id' | 'timestamp'>): Message | null {\n const fullMessage: Message = {\n ...message,\n id: `msg_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`,\n timestamp: Date.now(),\n };\n\n const validation = MessageSchema.safeParse(fullMessage);\n if (!validation.success) {\n return null;\n }\n\n // EN: Verify sender and receiver exist\n // VI: Xác minh người gửi và người nhận tồn tại\n // ES: Verificar que remitente y receptor existan\n if (!this.agents.has(message.from) || !this.agents.has(message.to)) {\n return null;\n }\n\n this.messages.push(fullMessage);\n return fullMessage;\n }\n\n // EN: Get messages for specific agent\n // VI: Lấy tin nhắn cho đại lý cụ thể\n // ES: Obtener mensajes para agente específico\n getMessages(agentId: string): Message[] {\n return this.messages.filter(msg => msg.to === agentId || msg.from === agentId);\n }\n\n // EN: Update agent state\n // VI: Cập nhật trạng thái đại lý\n // ES: Actualizar estado del agente\n updateAgentState(agentId: string, state: Agent['state']): boolean {\n const agent = this.agents.get(agentId);\n if (!agent) return false;\n\n agent.state = state;\n return true;\n }\n}\n\n// EN: SPEC AI-05: Buyer agent implementation with negotiation logic\n// VI: SPEC AI-05: Triển khai đại lý mua với logic đàm phán\n// ES: SPEC AI-05: Implementación de agente comprador con lógica de negociación\nclass BuyerAgent {\n private agent: Agent;\n private acp: ACP;\n private maxPrice: number;\n private targetPrice: number;\n\n constructor(id: string, acp: ACP, maxPrice: number, targetPrice: number) {\n this.agent = {\n id,\n role: 'buyer',\n state: 'idle',\n preferences: { maxPrice, targetPrice },\n };\n this.acp = acp;\n this.maxPrice = maxPrice;\n this.targetPrice = targetPrice;\n \n acp.registerAgent(this.agent);\n }\n\n // EN: Initiate purchase proposal\n // VI: Khởi tạo đề xuất mua hàng\n // ES: Iniciar propuesta de compra\n propose(sellerId: string, item: string, price: number): Message | null {\n if (price > this.maxPrice) {\n return null;\n }\n\n this.acp.updateAgentState(this.agent.id, 'negotiating');\n\n return this.acp.sendMessage({\n from: this.agent.id,\n to: sellerId,\n type: 'propose',\n payload: {\n item,\n proposedPrice: Math.min(price, this.targetPrice),\n maxPrice: this.maxPrice,\n },\n });\n }\n\n // EN: Handle seller response\n // VI: Xử lý phản hồi của người bán\n // ES: Manejar respuesta del vendedor\n handleResponse(message: Message): Message | null {\n const validation = MessageSchema.safeParse(message);\n if (!validation.success || message.to !== this.agent.id) {\n return null;\n }\n\n switch (message.type) {\n case 'accept':\n this.acp.updateAgentState(this.agent.id, 'agreed');\n return this.acp.sendMessage({\n from: this.agent.id,\n to: message.from,\n type: 'confirm',\n payload: { confirmed: true },\n });\n\n case 'counter':\n const counterPrice = message.payload.counterPrice as number;\n if (counterPrice <= this.maxPrice) {\n this.acp.updateAgentState(this.agent.id, 'agreed');\n return this.acp.sendMessage({\n from: this.agent.id,\n to: message.from,\n type: 'accept',\n payload: { acceptedPrice: counterPrice },\n });\n } else {\n this.acp.updateAgentState(this.agent.id, 'cancelled');\n return this.acp.sendMessage({\n from: this.agent.id,\n to: message.from,\n type: 'reject',\n payload: { reason: 'price_too_high' },\n });\n }\n\n case 'reject':\n this.acp.updateAgentState(this.agent.id, 'cancelled');\n return null;\n\n default:\n return null;\n }\n }\n\n getState(): Agent['state'] {\n return this.agent.state;\n }\n}\n\n// EN: SPEC AI-05: Seller agent implementation with pricing strategy\n// VI: SPEC AI-05: Triển khai đại lý bán với chiến lược định giá\n// ES: SPEC AI-05: Implementación de agente vendedor con estrategia de precios\nclass SellerAgent {\n private agent: Agent;\n private acp: ACP;\n private minPrice: number;\n private listPrice: number;\n\n constructor(id: string, acp: ACP, minPrice: number, listPrice: number) {\n this.agent = {\n id,\n role: 'seller',\n state: 'idle',\n preferences: { minPrice, listPrice },\n };\n this.acp = acp;\n this.minPrice = minPrice;\n this.listPrice = listPrice;\n \n acp.registerAgent(this.agent);\n }\n\n // EN: Handle buyer proposal\n // VI: Xử lý đề xuất của người mua\n // ES: Manejar propuesta del comprador\n handleProposal(message: Message): Message | null {\n const validation = MessageSchema.safeParse(message);\n if (!validation.success || message.to !== this.agent.id) {\n return null;\n }\n\n if (message.type !== 'propose') {\n return null;\n }\n\n this.acp.updateAgentState(this.agent.id, 'negotiating');\n\n const proposedPrice = message.payload.proposedPrice as number;\n const buyerMaxPrice = message.payload.maxPrice as number;\n\n // EN: Accept if proposed price meets minimum\n // VI: Chấp nhận nếu giá đề xuất đáp ứng tối thiểu\n // ES: Aceptar si el precio propuesto cumple el mínimo\n if (proposedPrice >= this.minPrice) {\n this.acp.updateAgentState(this.agent.id, 'agreed');\n return this.acp.sendMessage({\n from: this.agent.id,\n to: message.from,\n type: 'accept',\n payload: { acceptedPrice: proposedPrice },\n });\n }\n\n // EN: Counter-offer if buyer can afford higher price\n // VI: Đề xuất ngược nếu người mua có thể chi trả giá cao hơn\n // ES: Contraoferta si el comprador puede pagar precio más alto\n if (buyerMaxPrice >= this.minPrice) {\n const counterPrice = Math.max(this.minPrice, (proposedPrice + this.listPrice) / 2);\n return this.acp.sendMessage({\n from: this.agent.id,\n to: message.from,\n type: 'counter',\n payload: { counterPrice: Math.min(counterPrice, buyerMaxPrice) },\n });\n }\n\n // EN: Reject if no viable price point\n // VI: Từ chối nếu không có mức giá khả thi\n // ES: Rechazar si no hay punto de precio viable\n this.acp.updateAgentState(this.agent.id, 'cancelled');\n return this.acp.sendMessage({\n from: this.agent.id,\n to: message.from,\n type: 'reject',\n payload: { reason: 'insufficient_offer' },\n });\n }\n\n // EN: Handle buyer acceptance/rejection\n // VI: Xử lý chấp nhận/từ chối của người mua\n // ES: Manejar aceptación/rechazo del comprador\n handleResponse(message: Message): Message | null {\n const validation = MessageSchema.safeParse(message);\n if (!validation.success || message.to !== this.agent.id) {\n return null;\n }\n\n switch (message.type) {\n case 'accept':\n this.acp.updateAgentState(this.agent.id, 'agreed');\n return this.acp.sendMessage({\n from: this.agent.id,\n to: message.from,\n type: 'confirm',\n payload: { confirmed: true, finalPrice: message.payload.acceptedPrice },\n });\n\n case 'reject':\n this.acp.updateAgentState(this.agent.id, 'cancelled');\n return null;\n\n default:\n return null;\n }\n }\n\n getState(): Agent['state'] {\n return this.agent.state;\n }\n}\n\n// EN: SPEC AI-05: Agent choreography orchestrator for marketplace transactions\n// VI: SPEC AI-05: Bộ điều phối vũ đạo đại lý cho giao dịch marketplace\n// ES: SPEC AI-05: Orquestador de coreografía de agentes para transacciones marketplace\nclass AgentChoreography {\n private acp: ACP;\n private sessions: Map<string, {\n buyer: BuyerAgent;\n seller: SellerAgent;\n status: 'active' | 'completed' | 'failed';\n messages: Message[];\n }> = new Map();\n\n constructor() {\n this.acp = new ACP();\n }\n\n // EN: Create negotiation session between buyer and seller\n // VI: Tạo phiên đàm phán giữa người mua và người bán\n // ES: Crear sesión de negociación entre comprador y vendedor\n createSession(\n buyerId: string,\n sellerId: string,\n buyerMaxPrice: number,\n buyerTargetPrice: number,\n sellerMinPrice: number,\n sellerListPrice: number\n ): string {\n const sessionId = `session_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;\n \n const buyer = new BuyerAgent(buyerId, this.acp, buyerMaxPrice, buyerTargetPrice);\n const seller = new SellerAgent(sellerId, this.acp, sellerMinPrice, sellerListPrice);\n\n this.sessions.set(sessionId, {\n buyer,\n seller,\n status: 'active',\n messages: [],\n });\n\n return sessionId;\n }\n\n // EN: Execute negotiation choreography\n // VI: Thực hiện vũ đạo đàm phán\n // ES: Ejecutar coreografía de negociación\n executeNegotiation(sessionId: string, item: string, initialPrice: number): {\n success: boolean;\n finalPrice?: number;\n messages: Message[];\n } {\n const session = this.sessions.get(sessionId);\n if (!session) {\n return { success: false, messages: [] };\n }\n\n const messages: Message[] = [];\n\n // EN: Step 1: Buyer proposes\n // VI: Bước 1: Người mua đề xuất\n // ES: Paso 1: El comprador propone\n const proposal = session.buyer.propose(session.seller['agent'].id, item, initialPrice);\n if (!proposal) {\n session.status = 'failed';\n return { success: false, messages };\n }\n messages.push(proposal);\n\n // EN: Step 2: Seller responds\n // VI: Bước 2: Người bán phản hồi\n // ES: Paso 2: El vendedor responde\n const sellerResponse = session.seller.handleProposal(proposal);\n if (!sellerResponse) {\n session.status = 'failed';\n return { success: false, messages };\n }\n messages.push(sellerResponse);\n\n // EN: Step 3: Buyer handles response\n // VI: Bước 3: Người mua xử lý phản hồi\n // ES: Paso 3: El comprador maneja la respuesta\n const buyerResponse = session.buyer.handleResponse(sellerResponse);\n if (buyerResponse) {\n messages.push(buyerResponse);\n\n // EN: Step 4: Final confirmation if needed\n // VI: Bước 4: Xác nhận cuối nếu cần\n // ES: Paso 4: Confirmación final si es necesario\n if (buyerResponse.type === 'accept') {\n const finalConfirm = session.seller.handleResponse(buyerResponse);\n if (finalConfirm) {\n messages.push(finalConfirm);\n }\n }\n }\n\n // EN: Determine final outcome\n // VI: Xác định kết quả cuối cùng\n // ES: Determinar resultado final\n const buyerState = session.buyer.getState();\n const sellerState = session.seller.getState();\n\n if (buyerState === 'agreed' && sellerState === 'agreed') {\n session.status = 'completed';\n const lastMessage = messages[messages.length - 1];\n const finalPrice = lastMessage?.payload?.finalPrice || lastMessage?.payload?.acceptedPrice;\n return { success: true, finalPrice, messages };\n }\n\n session.status = 'failed';\n return { success: false, messages };\n }\n\n // EN: Get session status and history\n // VI: Lấy trạng thái và lịch sử phiên\n // ES: Obtener estado e historial de sesión\n getSession(sessionId: string) {\n const session = this.sessions.get(sessionId);\n if (!session) return null;\n\n return {\n sessionId,\n status: session.status,\n buyerState: session.buyer.getState(),\n sellerState: session.seller.getState(),\n messages: this.acp.getMessages(session.buyer['agent'].id),\n };\n }\n}\n\n// EN: Export main components for ACP agent choreography\n// VI: Xuất các thành phần chính cho vũ đạo đại lý ACP\n// ES: Exportar componentes principales para coreografía de agentes ACP\nexport {\n ACP as acp,\n BuyerAgent as buyer_agent,\n SellerAgent as seller_agent,\n AgentChoreography as agent_choreography,\n type Message,\n type Agent,\n};\n```\n\nThis implementation provides:\n\n1. **ACP Protocol (`acp`)**: Core communication protocol with message validation and agent management\n2. **Buyer Agent (`buyer_agent`)**: Autonomous buyer with price negotiation logic\n3. **Seller Agent (`seller_agent`)**: Autonomous seller with pricing strategies\n4. **Agent Choreography (`agent_choreography`)**: Orchestrates the complete negotiation flow\n\nThe system supports:\n- Message validation with Zod schemas\n- State management for agents\n- Multi-step negotiation choreography\n- Error handling and validation\n- Session management for tracking negotiations"
}Task ID: 88314f24-0cbf-4a6e-8a60-885ea9af6742