/** * 统一报价 A3 · 渠道寻源 —— 活动包代码入口(ADR-004)。 * * **loop 活动**:下一步由 Agent 在案例模型的结构上临场决断,引擎只推进到 Enabled 为止。 * 本文件只做视图流控 —— 把阶段、里程碑与比价进展摆给人看。 */ import { defineActivity } from '@sdk'; import type { ActivityBase, ActivityOutcome } from '@sdk'; const QUOTES = 'quote_sourcing.supplier_quote'; const COMPARE = 'quote_sourcing.compare_table'; export default defineActivity({ name: 'quote-sourcing', paradigm: 'loop', async run(base: ActivityBase): Promise { const quotes = await base.ledger.read(QUOTES); const compare = await base.ledger.read(COMPARE); const suppliers = new Set(quotes.map((q) => String(q['supplier'] ?? ''))); await base.interaction.pushView([ { t: 'kv', title: '寻源进展', items: [ { k: '场景', v: String(base.contract.data['scenario'] ?? '') }, { k: '已圈渠道', v: `${suppliers.size} 家` }, { k: '已收回价', v: `${quotes.length} 单` }, { k: '比价表', v: compare.length > 0 ? '已填' : '未填' }, ], }, { t: 'table', title: '供应商回价', cols: ['供应商', '回价', 'MOQ', '交期', '渠道等级'], rows: quotes.map((q) => [ String(q['supplier'] ?? ''), String(q['price'] ?? '—'), String(q['moq'] ?? '—'), String(q['lead_time'] ?? '—'), String(q['grade'] ?? '—'), ]), }, ]); if (compare.length === 0) { // 交集为空即断点 —— 由引擎判定、Agent 定夺调人还是立监听,这里不代它决定 await base.interaction.say( suppliers.size === 0 ? '尚未圈定渠道,先按场景定策。' : `已收 ${quotes.length} 单回价,待填寻源比价表。`, 'conclusion', ); return { kind: 'await', reason: '寻源比价表未交付' }; } await base.interaction.say('寻源比价表已填齐,可交回 PM。', 'criterion'); return { kind: 'submit', deliverable: 'compare-table', rationale: '每料有有效报价或明确无货' }; }, });