← Tasks
[AI-05] ACP choreography (G3 Flash)
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
G3 Flash
Created
25d ago
Completed
25d ago
Quality
Overall
76%
Pass
PASS
Graded By
-
Graded At
-
Cost
Input Tokens
168
Output Tokens
2,077
Est. USD
$0.0008
Result
{
"code": "```typescript\n// EN: ACP agent-to-agent choreography module // VI: Mô-đun biên đạo tác nhân ACP // ES: Módulo de coreografía de agentes ACP\n// File: src/lib/acp-agents.ts\n// SPEC: AI-05\n\nimport { z } from \"zod\";\nimport { NextResponse } from \"next/server\";\n\n// EN: Define Zod schemas for agent types // VI: Xác định lược đồ Zod cho các loại tác nhân // ES: Define esquemas Zod para tipos de agentes\n\nconst BuyerAgentSchema = z.object({\n id: z.string(),\n type: z.literal(\"buyer\"),\n preferences: z.object({\n productCategory: z.string(),\n maxPrice: z.number().optional(),\n }),\n});\ntype BuyerAgent = z.infer<typeof BuyerAgentSchema>;\n\nconst SellerAgentSchema = z.object({\n id: z.string(),\n type: z.literal(\"seller\"),\n inventory: z.array(\n z.object({\n productName: z.string(),\n productCategory: z.string(),\n price: z.number(),\n quantity: z.number(),\n })\n ),\n});\ntype SellerAgent = z.infer<typeof SellerAgentSchema>;\n\nconst MarketplaceAgentSchema = z.object({\n id: z.string(),\n type: z.literal(\"marketplace\"),\n agents: z.array(z.union([BuyerAgentSchema, SellerAgentSchema])),\n});\ntype MarketplaceAgent = z.infer<typeof MarketplaceAgentSchema>;\n\nconst OfferSchema = z.object({\n productName: z.string(),\n price: z.number(),\n quantity: z.number(),\n sellerId: z.string(),\n});\ntype Offer = z.infer<typeof OfferSchema>;\n\nconst PurchaseOrderSchema = z.object({\n productName: z.string(),\n price: z.number(),\n quantity: z.number(),\n buyerId: z.string(),\n sellerId: z.string(),\n});\ntype PurchaseOrder = z.infer<typeof PurchaseOrderSchema>;\n\n// EN: Define ACP messages // VI: Định nghĩa tin nhắn ACP // ES: Define mensajes ACP\ntype ACPMessage =\n | { type: \"request_offer\"; buyerId: string; productCategory: string }\n | { type: \"offer\"; offer: Offer }\n | { type: \"accept_offer\"; offer: Offer; buyerId: string }\n | { type: \"reject_offer\"; offer: Offer; buyerId: string }\n | { type: \"purchase_order\"; purchaseOrder: PurchaseOrder }\n | { type: \"confirmation\"; purchaseOrderId: string };\n\n// EN: Implement agent choreography // VI: Thực hiện biên đạo tác nhân // ES: Implementar coreografía de agentes\nasync function acp(\n message: ACPMessage,\n buyerAgent: BuyerAgent,\n sellerAgent: SellerAgent\n): Promise<NextResponse> {\n // EN: Handle different message types // VI: Xử lý các loại tin nhắn khác nhau // ES: Manejar diferentes tipos de mensajes\n switch (message.type) {\n case \"request_offer\":\n // EN: Buyer requests an offer // VI: Người mua yêu cầu một ưu đãi // ES: El comprador solicita una oferta\n if (message.buyerId !== buyerAgent.id) {\n return NextResponse.json(\n { error: \"Unauthorized\" },\n { status: 403 }\n );\n }\n\n const relevantProducts = sellerAgent.inventory.filter(\n (item) => item.productCategory === message.productCategory && item.quantity > 0\n );\n\n if (relevantProducts.length === 0) {\n return NextResponse.json({ message: \"No products found\" });\n }\n\n const bestProduct = relevantProducts.sort((a, b) => a.price - b.price)[0];\n\n const offer: Offer = {\n productName: bestProduct.productName,\n price: bestProduct.price,\n quantity: Math.min(bestProduct.quantity, 10), // Limit quantity\n sellerId: sellerAgent.id,\n };\n\n return NextResponse.json({ type: \"offer\", offer });\n\n case \"accept_offer\":\n // EN: Buyer accepts the offer // VI: Người mua chấp nhận ưu đãi // ES: El comprador acepta la oferta\n if (message.buyerId !== buyerAgent.id) {\n return NextResponse.json(\n { error: \"Unauthorized\" },\n { status: 403 }\n );\n }\n if (message.offer.sellerId !== sellerAgent.id) {\n return NextResponse.json(\n { error: \"Unauthorized seller\" },\n { status: 403 }\n );\n }\n // EN: Check if the seller has enough quantity // VI: Kiểm tra xem người bán có đủ số lượng không // ES: Verificar si el vendedor tiene suficiente cantidad\n const productIndex = sellerAgent.inventory.findIndex(\n (item) =>\n item.productName === message.offer.productName &&\n item.price === message.offer.price\n );\n\n if (productIndex === -1) {\n return NextResponse.json({ error: \"Product not found in inventory\" }, { status: 404 });\n }\n\n if (sellerAgent.inventory[productIndex].quantity < message.offer.quantity) {\n return NextResponse.json({ error: \"Insufficient quantity\" }, { status: 400 });\n }\n\n // EN: Create a purchase order // VI: Tạo đơn đặt hàng // ES: Crear una orden de compra\n const purchaseOrder: PurchaseOrder = {\n productName: message.offer.productName,\n price: message.offer.price,\n quantity: message.offer.quantity,\n buyerId: buyerAgent.id,\n sellerId: sellerAgent.id,\n };\n\n sellerAgent.inventory[productIndex].quantity -= message.offer.quantity; // Update inventory\n\n return NextResponse.json({ type: \"purchase_order\", purchaseOrder });\n\n case \"reject_offer\":\n // EN: Buyer rejects the offer // VI: Người mua từ chối ưu đãi // ES: El comprador rechaza la oferta\n if (message.buyerId !== buyerAgent.id) {\n return NextResponse.json(\n { error: \"Unauthorized\" },\n { status: 403 }\n );\n }\n return NextResponse.json({ message: \"Offer rejected\" });\n\n default:\n return NextResponse.json({ error: \"Invalid message type\" }, { status: 400 });\n }\n}\n\n// EN: Example Usage (for testing - remove in production) // VI: Ví dụ sử dụng (để kiểm tra - loại bỏ trong sản xuất) // ES: Ejemplo de uso (para pruebas - eliminar en producción)\nasync function exampleUsage() {\n const buyer: BuyerAgent = {\n id: \"buyer123\",\n type: \"buyer\",\n preferences: {\n productCategory: \"electronics\",\n maxPrice: 100,\n },\n };\n\n const seller: SellerAgent = {\n id: \"seller456\",\n type: \"seller\",\n inventory: [\n { productName: \"Laptop\", productCategory: \"electronics\", price: 90, quantity: 5 },\n { productName: \"Mouse\", productCategory: \"electronics\", price: 15, quantity: 10 },\n ],\n };\n\n // EN: Buyer requests an offer for electronics // VI: Người mua yêu cầu một ưu đãi cho đồ điện tử // ES: El comprador solicita una oferta de productos electrónicos\n const requestOfferMessage: ACPMessage = {\n type: \"request_offer\",\n buyerId: \"buyer123\",\n productCategory: \"electronics\",\n };\n\n const offerResponse = await acp(requestOfferMessage, buyer, seller);\n const offerData = await offerResponse.json();\n\n if (offerData.type === \"offer\") {\n console.log(\"Offer received:\", offerData.offer);\n\n // EN: Buyer accepts the offer // VI: Người mua chấp nhận ưu đãi // ES: El comprador acepta la oferta\n const acceptOfferMessage: ACPMessage = {\n type: \"accept_offer\",\n offer: offerData.offer,\n buyerId: \"buyer123\",\n };\n\n const purchaseOrderResponse = await acp(acceptOfferMessage, buyer, seller);\n const purchaseOrderData = await purchaseOrderResponse.json();\n\n if (purchaseOrderData.type === \"purchase_order\") {\n console.log(\"Purchase order:\", purchaseOrderData.purchaseOrder);\n } else {\n console.error(\"Error:\", purchaseOrderData);\n }\n } else {\n console.error(\"Error:\", offerData);\n }\n}\n\n// exampleUsage(); // UNCOMMENT FOR TESTING\n\nexport { acp, BuyerAgentSchema, SellerAgentSchema, MarketplaceAgentSchema, type BuyerAgent, type SellerAgent, type MarketplaceAgent, type ACPMessage, type Offer, type PurchaseOrder };\n```",
"spec_id": "AI-05"
}Audit Trail (2)
25d agotask_completedG3 Flash
25d agotask_createdfoundry_swiss_race
Task ID: 77be9434-1fc4-4b46-8811-e0d723cd26e0