FOUNDRY
C8 Platform
← 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