← Tasks
[AI-05] Goldilocks Odd Couple (structured)
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
Team Odd Couple (structured)
Created
25d ago
Completed
25d ago
Quality
Overall
81%
Pass
PASS
Graded By
-
Graded At
-
Cost
Input Tokens
-
Output Tokens
-
Est. USD
$0.3261
Result
{
"code": "```typescript\nimport { z } from 'zod';\n\n// EN: Define ACPMessage type and schema // VI: Định nghĩa loại và sơ đồ ACPMessage // ES: Definir tipo y esquema ACPMessage\nexport type ACPMessageType = 'request' | 'response' | 'notification';\n\nexport interface ACPMessage {\n id: string;\n type: ACPMessageType;\n senderId: string;\n receiverId: string;\n payload: Record<string, unknown>;\n timestamp: Date;\n conversationId: string;\n replyTo?: string;\n}\n\nexport const ACPMessageSchema = z.object({\n id: z.string().uuid(),\n type: z.enum(['request', 'response', 'notification']),\n senderId: z.string(),\n receiverId: z.string(),\n payload: z.record(z.unknown()),\n timestamp: z.date(),\n conversationId: z.string(),\n replyTo: z.string().optional(),\n});\n\n// EN: Define BuyerAgent type and schema // VI: Định nghĩa loại và sơ đồ BuyerAgent // ES: Definir tipo y esquema BuyerAgent\nexport type AgentStatus = 'active' | 'inactive';\n\nexport interface BuyerPreferences {\n categories: string[];\n keywords?: string[];\n maxDistance?: number;\n preferredConditions?: string[];\n}\n\nexport const BuyerPreferencesSchema = z.object({\n categories: z.array(z.string()),\n keywords: z.array(z.string()).optional(),\n maxDistance: z.number().optional(),\n preferredConditions: z.array(z.string()).optional(),\n});\n\nexport interface BudgetConstraints {\n minPrice?: number;\n maxPrice: number;\n flexibilityPercent?: number;\n}\n\nexport const BudgetConstraintsSchema = z.object({\n minPrice: z.number().optional(),\n maxPrice: z.number(),\n flexibilityPercent: z.number().optional(),\n});\n\nexport interface BuyerAgent {\n id: string;\n type: 'buyer';\n userId: string;\n preferences: BuyerPreferences;\n budget: BudgetConstraints;\n status: AgentStatus;\n activeConversations: string[];\n}\n\nexport const BuyerAgentSchema = z.object({\n id: z.string(),\n type: z.literal('buyer'),\n userId: z.string(),\n preferences: BuyerPreferencesSchema,\n budget: BudgetConstraintsSchema,\n status: z.enum(['active', 'inactive']),\n activeConversations: z.array(z.string()),\n});\n\n// EN: Define SellerAgent type and schema // VI: Định nghĩa loại và sơ đồ SellerAgent // ES: Definir tipo y esquema SellerAgent\nexport interface InventoryItem {\n itemId: string;\n title: string;\n askingPrice: number;\n minAcceptablePrice: number;\n condition: string;\n}\n\nexport const InventoryItemSchema = z.object({\n itemId: z.string(),\n title: z.string(),\n askingPrice: z.number(),\n minAcceptablePrice: z.number(),\n condition: z.string(),\n});\n\nexport type PricingStrategyType = 'fixed' | 'negotiable' | 'auction';\n\nexport interface PricingStrategy {\n type: PricingStrategyType;\n discountThreshold?: number;\n bulkDiscountPercent?: number;\n}\n\nexport const PricingStrategySchema = z.object({\n type: z.enum(['fixed', 'negotiable', 'auction']),\n discountThreshold: z.number().optional(),\n bulkDiscountPercent: z.number().optional(),\n});\n\nexport interface SellerAgent {\n id: string;\n type: 'seller';\n userId: string;\n inventory: InventoryItem[];\n pricingStrategy: PricingStrategy;\n status: AgentStatus;\n activeConversations: string[];\n}\n\nexport const SellerAgentSchema = z.object({\n id: z.string(),\n type: z.literal('seller'),\n userId: z.string(),\n inventory: z.array(InventoryItemSchema),\n pricingStrategy: PricingStrategySchema,\n status: z.enum(['active', 'inactive']),\n activeConversations: z.array(z.string()),\n});\n\n// EN: Define MarketplaceAgent type and schema // VI: Định nghĩa loại và sơ đồ MarketplaceAgent // ES: Definir tipo y esquema MarketplaceAgent\nexport interface AgentInfo {\n id: string;\n type: 'buyer' | 'seller';\n registeredAt: Date;\n reputation: number;\n}\n\nexport interface Transaction {\n id: string;\n buyerAgentId: string;\n sellerAgentId: string;\n itemId: string;\n agreedPrice?: number;\n status: TransactionStatus;\n createdAt: Date;\n updatedAt: Date;\n}\n\nexport type TransactionStatus = 'pending' | 'completed' | 'failed';\n\nexport const TransactionSchema = z.object({\n id: z.string(),\n buyerAgentId: z.string(),\n sellerAgentId: z.string(),\n itemId: z.string(),\n agreedPrice: z.number().optional(),\n status: z.enum(['pending', 'completed', 'failed']),\n createdAt: z.date(),\n updatedAt: z.date(),\n});\n\nexport interface MarketplaceAgent {\n id: string;\n type: 'marketplace';\n registeredAgents: Map<string, AgentInfo>;\n activeTransactions: Transaction[];\n messageQueue: ACPMessage[];\n}\n\nexport const MarketplaceAgentSchema = z.object({\n id: z.string(),\n type: z.literal('marketplace'),\n registeredAgents: z.map(z.string(), z.object({\n id: z.string(),\n type: z.enum(['buyer', 'seller']),\n registeredAt: z.date(),\n reputation: z.number(),\n })),\n activeTransactions: z.array(TransactionSchema),\n messageQueue: z.array(ACPMessageSchema),\n});\n\n// EN: Define NegotiationResult type and schema // VI: Định nghĩa loại và sơ đồ NegotiationResult // ES: Definir tipo y esquema NegotiationResult\nexport interface NegotiationResult {\n success: boolean;\n finalPrice?: number;\n counterOffer?: number;\n message: string;\n}\n\nexport const NegotiationResultSchema = z.object({\n success: z.boolean(),\n finalPrice: z.number().optional(),\n counterOffer: z.number().optional(),\n message: z.string(),\n});\n\n// EN: Function to create a BuyerAgent // VI: Hàm để tạo BuyerAgent // ES: Función para crear BuyerAgent\nexport function createBuyerAgent(userId: string, preferences: BuyerPreferences, budget: BudgetConstraints): BuyerAgent {\n return {\n id: generateUUID(),\n type: 'buyer',\n userId,\n preferences,\n budget,\n status: 'active',\n activeConversations: []\n };\n}\n\n// EN: Function to create a SellerAgent // VI: Hàm để tạo SellerAgent // ES: Función para crear SellerAgent\nexport function createSellerAgent(userId: string, inventory: InventoryItem[], pricingStrategy: PricingStrategy): SellerAgent {\n return {\n id: generateUUID(),\n type: 'seller',\n userId,\n inventory,\n pricingStrategy,\n status: 'active',\n activeConversations: []\n };\n}\n\n// EN: Function to create a MarketplaceAgent // VI: Hàm để tạo MarketplaceAgent // ES: Función para crear MarketplaceAgent\nexport function createMarketplaceAgent(): MarketplaceAgent {\n return {\n id: generateUUID(),\n type: 'marketplace',\n registeredAgents: new Map<string, AgentInfo>(),\n activeTransactions: [],\n messageQueue: []\n };\n}\n\n// EN: Function to send an ACPMessage // VI: Hàm để gửi ACPMessage // ES: Función para enviar ACPMessage\nexport function sendACPMessage(sender: BuyerAgent | SellerAgent, receiverId: string, type: ACPMessageType, payload: Record<string, unknown>, conversationId: string): ACPMessage {\n const message: ACPMessage = {\n id: generateUUID(),\n type,\n senderId: sender.id,\n receiverId,\n payload,\n timestamp: new Date(),\n conversationId\n };\n // EN: Add message to sender's active conversations // VI: Thêm tin nhắn vào các cuộc hội thoại đang hoạt động của người gửi // ES: Añadir mensaje a las conversaciones activas del remitente\n sender.activeConversations.push(conversationId);\n return message;\n}\n\n// EN: Function to process an ACPMessage in MarketplaceAgent // VI: Hàm để xử lý một ACPMessage trong MarketplaceAgent // ES: Función para procesar un ACPMessage en MarketplaceAgent\nexport async function processACPMessage(marketplace: MarketplaceAgent, message: ACPMessage): Promise<ACPMessage | null> {\n const parsedMessage = ACPMessageSchema.safeParse(message);\n if (!parsedMessage.success) {\n console.error('Invalid message schema:', parsedMessage.error);\n return null;\n }\n\n const validMessage = parsedMessage.data;\n marketplace.messageQueue.push(validMessage);\n // EN: Simulate processing and return a response message // VI: Mô phỏng xử lý và trả về một tin nhắn phản hồi // ES: Simular procesamiento y devolver un mensaje de respuesta\n return {\n ...validMessage,\n id: generateUUID(),\n type: 'response',\n senderId: validMessage.receiverId,\n receiverId: validMessage.senderId,\n payload: { status: 'processed' },\n timestamp: new Date(),\n conversationId: validMessage.conversationId\n };\n}\n\n// EN: Utility function to generate a UUID // VI: Hàm tiện ích để tạo UUID // ES: Función utilitaria para generar un UUID\nfunction generateUUID(): string {\n // EN: Simple UUID generator // VI: Trình tạo UUID đơn giản // ES: Generador de UUID simple\n return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {\n const r = Math.random() * 16 | 0, v = c === 'x' ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n}\n\n// EN: Function to negotiate price between buyer and seller agents // VI: Hàm để thương lượng giá giữa các đại lý người mua và người bán // ES: Función para negociar el precio entre los agentes comprador y vendedor\nexport async function negotiatePrice(buyer: BuyerAgent, seller: SellerAgent, itemId: string): Promise<NegotiationResult> {\n const item = seller.inventory.find(i => i.itemId === itemId);\n if (!item) {\n console.error('Item not found:', itemId);\n return { success: false, message: 'Item not found' };\n }\n\n // EN: Simulate negotiation process // VI: Mô phỏng quá trình thương lượng // ES: Simular proceso de negociación\n let finalPrice = item.askingPrice;\n if (seller.pricingStrategy.type === 'negotiable') {\n finalPrice = Math.max(item.minAcceptablePrice, item.askingPrice * (1 - (buyer.budget.flexibilityPercent || 0) / 100));\n }\n\n if (finalPrice < item.minAcceptablePrice) {\n console.error('Negotiated price below acceptable threshold');\n return { success: false, message: 'Negotiated price below acceptable threshold' };\n }\n\n return { success: true, finalPrice, message: 'Negotiation successful' };\n}\n\n// EN: Function to execute a transaction // VI: Hàm để thực hiện giao dịch // ES: Función para ejecutar una transacción\nexport async function executeTransaction(marketplace: MarketplaceAgent, transaction: Transaction): Promise<Transaction> {\n const parsedTransaction = TransactionSchema.safeParse(transaction);\n if (!parsedTransaction.success) {\n console.error('Invalid transaction schema:', parsedTransaction.error);\n return { ...transaction, status: 'failed', updatedAt: new Date() };\n }\n\n const validTransaction = parsedTransaction.data;\n marketplace.activeTransactions.push(validTransaction);\n // EN: Simulate transaction execution // VI: Mô phỏng thực hiện giao dịch // ES: Simular ejecución de la transacción\n validTransaction.status = 'completed';\n validTransaction.updatedAt = new Date();\n return validTransaction;\n}\n\n// EN: Function to handle edge cases like inactive agents or marketplace unavailability // VI: Hàm để xử lý các trường hợp ngoại lệ như đại lý không hoạt động hoặc thị trường không khả dụng // ES: Función para manejar casos extremos como agentes inactivos o indisponibilidad del mercado\nexport function handleEdgeCases(agentStatus: AgentStatus, marketplaceAvailable: boolean): string {\n if (agentStatus === 'inactive') {\n return 'Agent is inactive';\n }\n if (!marketplaceAvailable) {\n return 'Marketplace is unavailable';\n }\n return 'All systems operational';\n}\n```",
"spec_id": "AI-05"
}Audit Trail (2)
25d agotask_completedTeam Odd Couple (structured)
25d agotask_createdfoundry_goldilocks
Task ID: 39200351-92a4-4c98-8a36-719fdabef28e