← Tasks
[AI-05] ACP choreography (Opus 4.5)
completedcode_genP3
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
Opus 4.5
Created
25d ago
Completed
25d ago
Quality
Overall
86%
Pass
PASS
Graded By
-
Graded At
-
Cost
Input Tokens
196
Output Tokens
4,096
Est. USD
$0.3101
Result
{
"code": "```typescript\n// src/lib/acp-agents.ts\n// EN: ACP (Agent Communication Protocol) module for buyer/seller marketplace agents\n// VI: Module ACP (Giao thức Giao tiếp Agent) cho các agent mua/bán trong marketplace\n// ES: Módulo ACP (Protocolo de Comunicación de Agentes) para agentes comprador/vendedor del marketplace\n// SPEC: AI-05 - ACP agent-to-agent choreography\n\nimport { z } from \"zod\";\nimport { NextResponse } from \"next/server\";\n\n// EN: Agent role enumeration for the marketplace\n// VI: Enum vai trò agent cho marketplace\n// ES: Enumeración de roles de agente para el marketplace\nexport const AgentRoleSchema = z.enum([\n \"buyer_agent\",\n \"seller_agent\",\n \"marketplace_agent\",\n]);\nexport type AgentRole = z.infer<typeof AgentRoleSchema>;\n\n// EN: Message types for ACP protocol\n// VI: Các loại tin nhắn cho giao thức ACP\n// ES: Tipos de mensajes para el protocolo ACP\nexport const ACPMessageTypeSchema = z.enum([\n \"REQUEST\",\n \"PROPOSE\",\n \"ACCEPT\",\n \"REJECT\",\n \"INFORM\",\n \"CONFIRM\",\n \"CANCEL\",\n \"QUERY\",\n \"NEGOTIATE\",\n]);\nexport type ACPMessageType = z.infer<typeof ACPMessageTypeSchema>;\n\n// EN: Agent status enumeration\n// VI: Enum trạng thái agent\n// ES: Enumeración de estado del agente\nexport const AgentStatusSchema = z.enum([\n \"IDLE\",\n \"NEGOTIATING\",\n \"AWAITING_RESPONSE\",\n \"PROCESSING\",\n \"COMPLETED\",\n \"ERROR\",\n]);\nexport type AgentStatus = z.infer<typeof AgentStatusSchema>;\n\n// EN: Product schema for marketplace items\n// VI: Schema sản phẩm cho các mặt hàng marketplace\n// ES: Schema de producto para artículos del marketplace\nexport const ProductSchema = z.object({\n id: z.string().uuid(),\n name: z.string().min(1).max(200),\n description: z.string().optional(),\n price: z.number().positive(),\n quantity: z.number().int().nonnegative(),\n sellerId: z.string().uuid(),\n category: z.string().optional(),\n metadata: z.record(z.unknown()).optional(),\n});\nexport type Product = z.infer<typeof ProductSchema>;\n\n// EN: ACP Message schema - core communication unit between agents\n// VI: Schema tin nhắn ACP - đơn vị giao tiếp cốt lõi giữa các agent\n// ES: Schema de mensaje ACP - unidad de comunicación central entre agentes\nexport const ACPMessageSchema = z.object({\n id: z.string().uuid(),\n timestamp: z.string().datetime(),\n senderId: z.string().uuid(),\n senderRole: AgentRoleSchema,\n receiverId: z.string().uuid(),\n receiverRole: AgentRoleSchema,\n messageType: ACPMessageTypeSchema,\n conversationId: z.string().uuid(),\n replyTo: z.string().uuid().optional(),\n payload: z.object({\n action: z.string(),\n data: z.record(z.unknown()),\n constraints: z.record(z.unknown()).optional(),\n }),\n priority: z.number().int().min(1).max(10).default(5),\n ttl: z.number().int().positive().optional(), // Time to live in seconds\n});\nexport type ACPMessage = z.infer<typeof ACPMessageSchema>;\n\n// EN: Base agent schema with common properties\n// VI: Schema agent cơ bản với các thuộc tính chung\n// ES: Schema de agente base con propiedades comunes\nconst BaseAgentSchema = z.object({\n id: z.string().uuid(),\n name: z.string().min(1).max(100),\n status: AgentStatusSchema,\n createdAt: z.string().datetime(),\n lastActiveAt: z.string().datetime(),\n capabilities: z.array(z.string()),\n metadata: z.record(z.unknown()).optional(),\n});\n\n// EN: Buyer agent schema - represents purchasing entities\n// VI: Schema agent mua - đại diện cho các thực thể mua hàng\n// ES: Schema de agente comprador - representa entidades de compra\nexport const BuyerAgentSchema = BaseAgentSchema.extend({\n role: z.literal(\"buyer_agent\"),\n preferences: z.object({\n maxBudget: z.number().positive(),\n preferredCategories: z.array(z.string()),\n qualityThreshold: z.number().min(0).max(100).optional(),\n urgency: z.enum([\"LOW\", \"MEDIUM\", \"HIGH\"]).default(\"MEDIUM\"),\n }),\n purchaseHistory: z.array(z.string().uuid()).default([]),\n activeNegotiations: z.array(z.string().uuid()).default([]),\n trustScore: z.number().min(0).max(100).default(50),\n});\nexport type BuyerAgent = z.infer<typeof BuyerAgentSchema>;\n\n// EN: Seller agent schema - represents selling entities\n// VI: Schema agent bán - đại diện cho các thực thể bán hàng\n// ES: Schema de agente vendedor - representa entidades de venta\nexport const SellerAgentSchema = BaseAgentSchema.extend({\n role: z.literal(\"seller_agent\"),\n inventory: z.array(ProductSchema).default([]),\n pricingStrategy: z.object({\n minMargin: z.number().min(0).max(100),\n negotiationFlexibility: z.number().min(0).max(100),\n bulkDiscountThreshold: z.number().int().positive().optional(),\n bulkDiscountPercent: z.number().min(0).max(50).optional(),\n }),\n salesHistory: z.array(z.string().uuid()).default([]),\n activeListings: z.array(z.string().uuid()).default([]),\n reputationScore: z.number().min(0).max(100).default(50),\n});\nexport type SellerAgent = z.infer<typeof SellerAgentSchema>;\n\n// EN: Marketplace agent schema - orchestrates transactions\n// VI: Schema agent marketplace - điều phối các giao dịch\n// ES: Schema de agente marketplace - orquesta transacciones\nexport const MarketplaceAgentSchema = BaseAgentSchema.extend({\n role: z.literal(\"marketplace_agent\"),\n registeredBuyers: z.array(z.string().uuid()).default([]),\n registeredSellers: z.array(z.string().uuid()).default([]),\n activeTransactions: z.array(z.string().uuid()).default([]),\n commissionRate: z.number().min(0).max(30).default(5),\n disputeResolutionPolicy: z.object({\n autoResolveThreshold: z.number().positive(),\n escalationTimeoutHours: z.number().int().positive().default(48),\n }),\n analytics: z.object({\n totalTransactions: z.number().int().nonnegative().default(0),\n totalVolume: z.number().nonnegative().default(0),\n averageTransactionValue: z.number().nonnegative().default(0),\n }),\n});\nexport type MarketplaceAgent = z.infer<typeof MarketplaceAgentSchema>;\n\n// EN: Transaction schema for marketplace operations\n// VI: Schema giao dịch cho các hoạt động marketplace\n// ES: Schema de transacción para operaciones del marketplace\nexport const TransactionSchema = z.object({\n id: z.string().uuid(),\n buyerId: z.string().uuid(),\n sellerId: z.string().uuid(),\n productId: z.string().uuid(),\n quantity: z.number().int().positive(),\n agreedPrice: z.number().positive(),\n status: z.enum([\n \"INITIATED\",\n \"NEGOTIATING\",\n \"AGREED\",\n \"PAYMENT_PENDING\",\n \"COMPLETED\",\n \"CANCELLED\",\n \"DISPUTED\",\n ]),\n messages: z.array(z.string().uuid()).default([]),\n createdAt: z.string().datetime(),\n updatedAt: z.string().datetime(),\n completedAt: z.string().datetime().optional(),\n});\nexport type Transaction = z.infer<typeof TransactionSchema>;\n\n// EN: Negotiation state schema for tracking bargaining progress\n// VI: Schema trạng thái đàm phán để theo dõi tiến trình thương lượng\n// ES: Schema de estado de negociación para seguir el progreso de la negociación\nexport const NegotiationStateSchema = z.object({\n transactionId: z.string().uuid(),\n currentOffer: z.number().positive(),\n counterOffers: z.array(\n z.object({\n agentId: z.string().uuid(),\n amount: z.number().positive(),\n timestamp: z.string().datetime(),\n })\n ),\n round: z.number().int().nonnegative(),\n maxRounds: z.number().int().positive().default(10),\n deadline: z.string().datetime().optional(),\n});\nexport type NegotiationState = z.infer<typeof NegotiationStateSchema>;\n\n// EN: ACP Choreography class - manages agent communication flow\n// VI: Class ACP Choreography - quản lý luồng giao tiếp agent\n// ES: Clase ACP Choreography - gestiona el flujo de comunicación de agentes\n// SPEC: AI-05 - Core choreography implementation\nexport class ACPChoreography {\n private agents: Map<string, BuyerAgent | SellerAgent | MarketplaceAgent> =\n new Map();\n private messages: Map<string, ACPMessage> = new Map();\n private transactions: Map<string, Transaction> = new Map();\n private negotiations: Map<string, NegotiationState> = new Map();\n\n // EN: Register a new agent in the choreography\n // VI: Đăng ký một agent mới trong choreography\n // ES: Registrar un nuevo agente en la coreografía\n registerAgent(\n agent: BuyerAgent | SellerAgent | MarketplaceAgent\n ): { success: boolean; error?: string } {\n const schemaMap = {\n buyer_agent: BuyerAgentSchema,\n seller_agent: SellerAgentSchema,\n marketplace_agent: MarketplaceAgentSchema,\n };\n\n const schema = schemaMap[agent.role];\n const result = schema.safeParse(agent);\n\n if (!result.success) {\n return {\n success: false,\n error: `Validation failed: ${result.error.message}`,\n };\n }\n\n this.agents.set(agent.id, agent);\n return { success: true };\n }\n\n // EN: Create and send an ACP message between agents\n // VI: Tạo và gửi tin nhắn ACP giữa các agent\n // ES: Crear y enviar un mensaje ACP entre agentes\n sendMessage(\n messageData: Omit<ACPMessage, \"id\" | \"timestamp\">\n ): { success: boolean; messageId?: string; error?: string } {\n const message: ACPMessage = {\n ...messageData,\n id: crypto.randomUUID(),\n timestamp: new Date().toISOString(),\n };\n\n const result = ACPMessageSchema.safeParse(message);\n if (!result.success) {\n return {\n success: false,\n error: `Message validation failed: ${result.error.message}`,\n };\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 el remitente y receptor existan\n if (!this.agents.has(message.senderId)) {\n return { success: false, error: \"Sender agent not found\" };\n }\n if (!this.agents.has(message.receiverId)) {\n return { success: false, error: \"Receiver agent not found\" };\n }\n\n this.messages.set(message.id, message);\n this.processMessage(message);\n\n return { success: true, messageId: message.id };\n }\n\n // EN: Process incoming message based on type and agent roles\n // VI: Xử lý tin nhắn đến dựa trên loại và vai trò agent\n // ES: Procesar mensaje entrante según tipo y roles de agente\n private processMessage(message: ACPMessage): void {\n const receiver = this.agents.get(message.receiverId);\n if (!receiver) return;\n\n // EN: Update agent status based on message type\n // VI: Cập nhật trạng thái agent dựa trên loại tin nhắn\n // ES: Actualizar estado del agente según tipo de mensaje\n switch (message.messageType) {\n case \"REQUEST\":\n this.handleRequest(message, receiver);\n break;\n case \"PROPOSE\":\n this.handleProposal(message, receiver);\n break;\n case \"ACCEPT\":\n this.handleAcceptance(message, receiver);\n break;\n case \"REJECT\":\n this.handleRejection(message, receiver);\n break;\n case \"NEGOTIATE\":\n this.handleNegotiation(message, receiver);\n break;\n case \"CONFIRM\":\n this.handleConfirmation(message, receiver);\n break;\n default:\n // EN: Log unhandled message types\n // VI: Ghi log các loại tin nhắn không được xử lý\n // ES: Registrar tipos de mensajes no manejados\n console.log(`Unhandled message type: ${message.messageType}`);\n }\n }\n\n // EN: Handle purchase/listing request messages\n // VI: Xử lý tin nhắn yêu cầu mua/đăng bán\n // ES: Manejar mensajes de solicitud de compra/listado\n private handleRequest(\n message: ACPMessage,\n receiver: BuyerAgent | SellerAgent | MarketplaceAgent\n ): void {\n const updatedReceiver = { ...receiver, status: \"PROCESSING\" as const };\n this.agents.set(receiver.id, updatedReceiver);\n }\n\n // EN: Handle price/terms proposal messages\n // VI: Xử lý tin nhắn đề xuất giá/điều khoản\n // ES: Manejar mensajes de propuesta de precio/términos\n private handleProposal(\n message: ACPMessage,\n receiver: BuyerAgent | SellerAgent | MarketplaceAgent\n ): void {\n const updatedReceiver = { ...receiver, status: \"NEGOTIATING\" as const };\n this.agents.set(receiver.id, updatedReceiver);\n }\n\n // EN: Handle acceptance messages\n // VI: Xử lý tin nhắn chấp nhận\n // ES: Manejar mensajes de aceptación\n private handleAcceptance(\n message: ACPMessage,\n receiver: BuyerAgent | SellerAgent | MarketplaceAgent\n ): void {\n const transactionId = message.payload.data.transactionId as string;\n const transaction = this.transactions.get(transactionId);\n\n if (transaction) {\n const updatedTransaction = {\n ...transaction,\n status: \"AGREED\" as const,\n updatedAt: new Date().toISOString(),\n };\n this.transactions.set(transactionId, updatedTransaction);\n }\n }\n\n // EN: Handle rejection messages\n // VI: Xử lý tin nhắn từ chối\n // ES: Manejar mensajes de rechazo\n private handleRejection(\n message: ACPMessage,\n receiver: BuyerAgent | SellerAgent | MarketplaceAgent\n ): void {\n const updatedReceiver = { ...receiver, status: \"IDLE\" as const };\n this.agents.set(receiver.id, update",
"spec_id": "AI-05"
}Audit Trail (2)
25d agotask_completedOpus 4.5
25d agotask_createdfoundry_race
Task ID: 0ef872c0-a12f-47e5-9cdb-760e4281e01e