← 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
81%
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 Đại lý) cho các đại lý mua/bán trên marketplace\n// ES: Módulo ACP (Protocolo de Comunicación de Agentes) para agentes compradores/vendedores del marketplace\n\n// SPEC: AI-05 - ACP agent-to-agent choreography\n// Section: AI Features | Milestone: M4\n\nimport { z } from \"zod\";\n\n// ============================================================================\n// EN: Zod Schemas for ACP Message Types\n// VI: Các Schema Zod cho các loại tin nhắn ACP\n// ES: Esquemas Zod para tipos de mensajes ACP\n// ============================================================================\n\n// EN: Base message schema for all ACP communications\n// VI: Schema tin nhắn cơ sở cho tất cả giao tiếp ACP\n// ES: Esquema de mensaje base para todas las comunicaciones ACP\nconst ACPMessageSchema = z.object({\n id: z.string().uuid(),\n timestamp: z.string().datetime(),\n sender: z.string(),\n receiver: z.string(),\n performative: z.enum([\n \"propose\",\n \"accept\",\n \"reject\",\n \"counter\",\n \"inform\",\n \"request\",\n \"confirm\",\n \"cancel\",\n ]),\n conversationId: z.string().uuid(),\n content: z.record(z.unknown()),\n protocol: z.literal(\"acp-marketplace-v1\"),\n});\n\n// EN: Product listing schema for marketplace items\n// VI: Schema danh sách sản phẩm cho các mặt hàng marketplace\n// ES: Esquema de listado de productos para artículos del marketplace\nconst ProductSchema = z.object({\n productId: z.string(),\n name: z.string(),\n description: z.string(),\n category: z.string(),\n basePrice: z.number().positive(),\n currency: z.string().default(\"USD\"),\n quantity: z.number().int().positive(),\n attributes: z.record(z.string()).optional(),\n});\n\n// EN: Buyer agent schema with preferences and budget\n// VI: Schema đại lý mua với sở thích và ngân sách\n// ES: Esquema de agente comprador con preferencias y presupuesto\nconst BuyerAgentSchema = z.object({\n agentId: z.string().uuid(),\n agentType: z.literal(\"buyer_agent\"),\n name: z.string(),\n preferences: z.object({\n categories: z.array(z.string()),\n maxPrice: z.number().positive(),\n minQuantity: z.number().int().positive().default(1),\n preferredSellers: z.array(z.string()).optional(),\n qualityThreshold: z.number().min(0).max(5).default(3),\n }),\n budget: z.number().positive(),\n status: z.enum([\"active\", \"negotiating\", \"completed\", \"suspended\"]),\n metadata: z\n .object({\n createdAt: z.string().datetime(),\n lastActive: z.string().datetime(),\n totalTransactions: z.number().int().nonnegative(),\n reputation: z.number().min(0).max(5),\n })\n .optional(),\n});\n\n// EN: Seller agent schema with inventory and pricing strategy\n// VI: Schema đại lý bán với kho hàng và chiến lược giá\n// ES: Esquema de agente vendedor con inventario y estrategia de precios\nconst SellerAgentSchema = z.object({\n agentId: z.string().uuid(),\n agentType: z.literal(\"seller_agent\"),\n name: z.string(),\n inventory: z.array(ProductSchema),\n pricingStrategy: z.object({\n minMargin: z.number().min(0).max(1),\n maxDiscount: z.number().min(0).max(1),\n bulkDiscountThreshold: z.number().int().positive(),\n bulkDiscountRate: z.number().min(0).max(1),\n }),\n status: z.enum([\"active\", \"negotiating\", \"completed\", \"suspended\"]),\n metadata: z\n .object({\n createdAt: z.string().datetime(),\n lastActive: z.string().datetime(),\n totalSales: z.number().int().nonnegative(),\n reputation: z.number().min(0).max(5),\n })\n .optional(),\n});\n\n// EN: Marketplace agent schema for orchestration\n// VI: Schema đại lý marketplace để điều phối\n// ES: Esquema de agente del marketplace para orquestación\nconst MarketplaceAgentSchema = z.object({\n agentId: z.string().uuid(),\n agentType: z.literal(\"marketplace_agent\"),\n name: z.string(),\n config: z.object({\n maxNegotiationRounds: z.number().int().positive().default(10),\n timeoutMs: z.number().int().positive().default(30000),\n feePercentage: z.number().min(0).max(0.5).default(0.05),\n escrowEnabled: z.boolean().default(true),\n }),\n activeNegotiations: z.array(z.string().uuid()),\n status: z.enum([\"online\", \"maintenance\", \"offline\"]),\n});\n\n// EN: Negotiation state schema\n// VI: Schema trạng thái đàm phán\n// ES: Esquema de estado de negociación\nconst NegotiationStateSchema = z.object({\n negotiationId: z.string().uuid(),\n buyerAgentId: z.string().uuid(),\n sellerAgentId: z.string().uuid(),\n productId: z.string(),\n currentOffer: z.number().positive(),\n counterOffer: z.number().positive().optional(),\n quantity: z.number().int().positive(),\n round: z.number().int().nonnegative(),\n status: z.enum([\"initiated\", \"in_progress\", \"accepted\", \"rejected\", \"timeout\", \"cancelled\"]),\n history: z.array(ACPMessageSchema),\n startedAt: z.string().datetime(),\n updatedAt: z.string().datetime(),\n});\n\n// EN: Transaction schema for completed deals\n// VI: Schema giao dịch cho các thỏa thuận hoàn thành\n// ES: Esquema de transacción para acuerdos completados\nconst TransactionSchema = z.object({\n transactionId: z.string().uuid(),\n negotiationId: z.string().uuid(),\n buyerAgentId: z.string().uuid(),\n sellerAgentId: z.string().uuid(),\n product: ProductSchema,\n finalPrice: z.number().positive(),\n quantity: z.number().int().positive(),\n totalAmount: z.number().positive(),\n fee: z.number().nonnegative(),\n status: z.enum([\"pending\", \"escrow\", \"completed\", \"disputed\", \"refunded\"]),\n createdAt: z.string().datetime(),\n completedAt: z.string().datetime().optional(),\n});\n\n// ============================================================================\n// EN: Type exports from Zod schemas\n// VI: Xuất kiểu từ các schema Zod\n// ES: Exportaciones de tipos desde esquemas Zod\n// ============================================================================\n\nexport type ACPMessage = z.infer<typeof ACPMessageSchema>;\nexport type Product = z.infer<typeof ProductSchema>;\nexport type BuyerAgent = z.infer<typeof BuyerAgentSchema>;\nexport type SellerAgent = z.infer<typeof SellerAgentSchema>;\nexport type MarketplaceAgent = z.infer<typeof MarketplaceAgentSchema>;\nexport type NegotiationState = z.infer<typeof NegotiationStateSchema>;\nexport type Transaction = z.infer<typeof TransactionSchema>;\n\n// ============================================================================\n// EN: ACP Protocol Implementation\n// VI: Triển khai Giao thức ACP\n// ES: Implementación del Protocolo ACP\n// ============================================================================\n\n// EN: Generate unique identifiers\n// VI: Tạo định danh duy nhất\n// ES: Generar identificadores únicos\nfunction generateUUID(): string {\n return crypto.randomUUID();\n}\n\n// EN: Get current ISO timestamp\n// VI: Lấy timestamp ISO hiện tại\n// ES: Obtener marca de tiempo ISO actual\nfunction getCurrentTimestamp(): string {\n return new Date().toISOString();\n}\n\n// EN: Create an ACP message with validation\n// VI: Tạo tin nhắn ACP với xác thực\n// ES: Crear un mensaje ACP con validación\nexport function createACPMessage(\n sender: string,\n receiver: string,\n performative: ACPMessage[\"performative\"],\n content: Record<string, unknown>,\n conversationId?: string\n): { success: true; data: ACPMessage } | { success: false; error: z.ZodError } {\n const message = {\n id: generateUUID(),\n timestamp: getCurrentTimestamp(),\n sender,\n receiver,\n performative,\n conversationId: conversationId || generateUUID(),\n content,\n protocol: \"acp-marketplace-v1\" as const,\n };\n\n const result = ACPMessageSchema.safeParse(message);\n if (result.success) {\n return { success: true, data: result.data };\n }\n return { success: false, error: result.error };\n}\n\n// ============================================================================\n// EN: Buyer Agent Implementation\n// VI: Triển khai Đại lý Mua\n// ES: Implementación del Agente Comprador\n// ============================================================================\n\nexport class BuyerAgentController {\n private agent: BuyerAgent;\n private activeNegotiations: Map<string, NegotiationState> = new Map();\n\n constructor(agent: BuyerAgent) {\n // EN: Validate agent on construction\n // VI: Xác thực đại lý khi khởi tạo\n // ES: Validar agente en construcción\n const result = BuyerAgentSchema.safeParse(agent);\n if (!result.success) {\n throw new Error(`Invalid buyer agent: ${result.error.message}`);\n }\n this.agent = result.data;\n }\n\n // EN: Initiate a purchase request\n // VI: Khởi tạo yêu cầu mua hàng\n // ES: Iniciar una solicitud de compra\n initiateRequest(\n product: Product,\n sellerAgentId: string,\n desiredQuantity: number\n ): { success: true; data: ACPMessage } | { success: false; error: string | z.ZodError } {\n // EN: Validate product\n // VI: Xác thực sản phẩm\n // ES: Validar producto\n const productResult = ProductSchema.safeParse(product);\n if (!productResult.success) {\n return { success: false, error: productResult.error };\n }\n\n // EN: Check budget constraints\n // VI: Kiểm tra ràng buộc ngân sách\n // ES: Verificar restricciones de presupuesto\n const totalCost = product.basePrice * desiredQuantity;\n if (totalCost > this.agent.budget) {\n return { success: false, error: \"Insufficient budget for this purchase\" };\n }\n\n // EN: Check price preferences\n // VI: Kiểm tra sở thích giá\n // ES: Verificar preferencias de precio\n if (product.basePrice > this.agent.preferences.maxPrice) {\n return { success: false, error: \"Product price exceeds maximum preference\" };\n }\n\n const conversationId = generateUUID();\n const messageResult = createACPMessage(\n this.agent.agentId,\n sellerAgentId,\n \"request\",\n {\n action: \"purchase_inquiry\",\n productId: product.productId,\n desiredQuantity,\n maxPricePerUnit: this.agent.preferences.maxPrice,\n buyerReputation: this.agent.metadata?.reputation || 0,\n },\n conversationId\n );\n\n if (messageResult.success) {\n // EN: Initialize negotiation state\n // VI: Khởi tạo trạng thái đàm phán\n // ES: Inicializar estado de negociación\n const negotiationState: NegotiationState = {\n negotiationId: conversationId,\n buyerAgentId: this.agent.agentId,\n sellerAgentId,\n productId: product.productId,\n currentOffer: product.basePrice,\n quantity: desiredQuantity,\n round: 0,\n status: \"initiated\",\n history: [messageResult.data],\n startedAt: getCurrentTimestamp(),\n updatedAt: getCurrentTimestamp(),\n };\n this.activeNegotiations.set(conversationId, negotiationState);\n }\n\n return messageResult;\n }\n\n // EN: Process a proposal from seller\n // VI: Xử lý đề xuất từ người bán\n // ES: Procesar una propuesta del vendedor\n processProposal(\n message: ACPMessage\n ): { success: true; data: ACPMessage } | { success: false; error: string } {\n const negotiation = this.activeNegotiations.get(message.conversationId);\n if (!negotiation) {\n return { success: false, error: \"No active negotiation found\" };\n }\n\n const proposedPrice = message.content.pricePerUnit as number;\n const proposedQuantity = message.content.availableQuantity as number;\n\n // EN: Evaluate the proposal\n // VI: Đánh giá đề xuất\n // ES: Evaluar la propuesta\n if (proposedPrice <= this.agent.preferences.maxPrice && proposedQuantity >= negotiation.quantity) {\n // EN: Accept the proposal\n // VI: Chấp nhận đề xuất\n // ES: Aceptar la propuesta\n const acceptResult = createACPMessage(\n this.agent.agentId,\n message.sender,\n \"accept\",\n {\n action: \"accept_proposal\",\n agreedPrice: proposedPrice,\n agreedQuantity: Math.min(proposedQuantity, negotiation.quantity),\n totalAmount: proposedPrice * Math.min(proposedQuantity, negotiation.quantity),\n },\n message.conversationId\n );\n\n if (acceptResult.success) {\n negotiation.status = \"accepted\";\n negotiation.currentOffer = proposedPrice;\n negotiation.history.push(acceptResult.data);\n negotiation.updatedAt = getCurrentTimestamp();\n }\n\n return acceptResult;\n }\n\n // EN: Counter-offer if price is too high\n // VI: Đề xuất ngược nếu giá quá cao\n // ES: Contraoferta si el precio es demasiado alto\n const counterPrice = Math.min(proposedPrice * 0.9, this.agent.preferences.maxPrice);\n const counterResult = createACPMessage(\n this.agent.agentId,\n message.sender,\n \"counter\",\n {\n action: \"counter_proposal\",\n counterPrice,\n desiredQuantity: negotiation.quantity,\n reason: \"Price exceeds budget constraints\",\n },\n message.conversationId\n );\n\n if (counterResult.success) {\n negotiation.round += 1;\n negotiation.counterOffer = counterPrice;\n negotiation.status = \"in_progress\";\n negotiation.history.push(counterResult.data);\n negotiation.updatedAt = getCurrentTimestamp();\n }\n\n return counterResult;\n }\n\n // EN: Get agent status\n // VI: Lấy trạng thái đại lý\n // ES: Obtener estado del agente\n getStatus(): BuyerAgent {\n return { ...this.agent };\n }\n\n // EN: Get active negotiations\n // VI: Lấy các đàm phán đang hoạ",
"spec_id": "AI-05"
}Audit Trail (2)
25d agotask_completedOpus 4.5
25d agotask_createdfoundry_swiss_race
Task ID: cda1a997-0cd1-4c6f-b805-4dd8d8f8b6f2