This repository has been archived on 2026-09-13. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
BPOS-MVP/activities/quote-pricing/src/manifest.ts
T
ChaiHaoandClaude Opus 5 374206b408 六个活动的汇报界面与技能补齐;skill-engine 接上装配面
汇报界面(AM 07):
  · 视图外壳与卡片件提到 `@sdk`(viewShell / kvCard / tableCard / stagesCard / noteCard)——
    六个活动共用一套面貌,不各自发明;样式内联自带(沙箱页面不继承工作台 CSS)。
  · flow 四活动按**步序位置**挂模版:
    A1 事态全景 / 打标判据 / 成果预览;A4 取价基准 / 定价与门禁 / 草案待放行;
    A6 正式报价单 / 放行即发出;A7 结果登记 / 闭环待放行。
  · loop 两活动按**阶段与里程碑**组织:案例全景一屏,画阶段生命周期态、当下可为、目标缺口 ——
    素材全部来自语义引擎,零 LLM 即可成屏;模型只决定下一步做什么,不负责画面。
    为此给 loop-engine 补了视图端口,与 flow 共用同一个网关。
  · 每张模版都把「这一屏在说什么 / 放行意味着什么」写在数据旁边 ——
    人要在数据上作判断,判据就得摆在手边。

技能(AM 08):
  · 六个活动各写了 1–2 条真技能:适用描述 + 方法正文 + 结晶片段脚本。
    正文写的是**方法经验**而非流程复述(如「原文没写的不要补」「该等还是该问」
    「无基准不是异常,是一种基准」)。
  · 资源声明放**技能 ID**(权力面),资产放**定义本体**(方法面),两处分清。
  · **skill-engine 从来没有被构造过** —— 模块实现完整却无人调用,这是它一直没被用上的原因。
    容器里补上:目录与白名单都取自活动清单,装配前查扩权。
  · loop 的叙事面接入**技能目录**(渐进披露:常驻上下文只给「有哪些方法、何时适用」,
    正文等 AI 说要才加载),装配随即**盖戳入任务记忆** —— 回放与归因依赖之。

gates: tsc / eslint / depcruise(334 模块)/ 423 测试 全绿

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KeDBx2PHLavbURXB8LJJ7m
2026-07-27 10:59:13 +08:00

263 lines
10 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* 活动包清单 —— 统一报价 A4 · 成本定价。
*
* 业务素材:docs/MVP示例工作流.html §1.2(S1 取价基准 → S2 逐条定价 → S3 底价自检)。
* README《已裁定的落地决策》③:**A4 = flow** —— 取价、查表定价、自检的判断
* **全部装进 DMN 决策表确定性求值**;一旦出现「由 AI 决定怎么办」,按 AM 2.1 上升。
*/
import type { ActivityManifest, DmnModel } from '@contracts';
import { PRICING_SKILLS } from './skills.ts';
import { activityIdSchema } from '@contracts';
import { PRICING_BASIS, PRICING_PRICED, PRICING_RELEASE } from './views/report.ts';
const DOMAIN = 'quote_pricing';
const ACTIVITY_ID = activityIdSchema.parse('quote-pricing');
/**
* 利润模型 P-01 —— 品牌 × 类型 × 客户等级 × 数量档 → 目标毛利。
* 「经验」段落不入决策表(那是技能 / 活动记忆种子:载方法不载权力)。
*/
export const P01_DMN: DmnModel = {
drd: [
{ decision: 'p01-margin', requires: [], inputs: ['customerGrade', 'materialType', 'volumeTier'] },
{ decision: 'p02-floor', requires: ['p01-margin'], inputs: ['quotedPrice', 'floorPrice'] },
],
tables: [
{
id: 'p01-margin',
label: '利润模型 P-01',
hitPolicy: 'FIRST',
inputs: [
{ name: 'customerGrade', expression: 'customerGrade' },
{ name: 'materialType', expression: 'materialType' },
{ name: 'volumeTier', expression: 'volumeTier' },
],
outputs: [{ name: 'marginLow' }, { name: 'marginHigh' }],
rules: [
{ id: 'p01-1', when: ['"战略客户"', '"A"', '"大批量"'], then: [0.08, 0.1], annotation: '战略客户 A 类标准件大批量 8%–10%' },
{ id: 'p01-2', when: ['"普通客户"', '"A"', '-'], then: [0.12, 0.15], annotation: '普通客户 A 类标准件 12%–15%' },
{ id: 'p01-3', when: ['-', '"B"', '-'], then: [0.15, 0.2], annotation: 'B 类波动件 15%–20%' },
{ id: 'p01-4', when: ['-', '"C"', '-'], then: [0.2, 0.5], annotation: 'C 类替代/EOL ≥20% 或一事一议' },
{ id: 'p01-default', when: ['-', '-', '-'], then: [0.12, 0.15], annotation: '兜底按普通客户标准件' },
],
},
{
/** 底价门禁 P-02 —— 偏离底价 ±20% 即止 */
id: 'p02-floor',
label: '底价门禁 P-02',
hitPolicy: 'FIRST',
inputs: [{ name: 'deviation', expression: 'deviation' }],
outputs: [{ name: 'disposition' }, { name: 'passable' }],
rules: [
{ id: 'p02-1', when: ['>= 0'], then: ['直接放行', true], annotation: '≥底价 → 直接放行' },
{ id: 'p02-2', when: ['[-0.20..0)'], then: ['PM 附理由放行', true], annotation: '低于底价 ≤20% → PM 附理由' },
{ id: 'p02-3', when: ['< -0.20'], then: ['拦截 · BOSS 拍板', false], annotation: '低于底价 >20% → 拦截' },
],
},
],
};
export const manifest: ActivityManifest = {
identity: {
activityId: ACTIVITY_ID,
name: 'A4 · 成本定价',
packageVersion: '0.1.5',
category: '统一报价',
paradigm: 'flow',
sdkVersion: '0.1.0-m5',
checksum: 'dev-checksum-quote-pricing',
},
contract: {
activityId: ACTIVITY_ID,
version: '0.1.0',
input: {
data: {
type: 'object',
required: ['customerCode', 'records'],
properties: {
customerCode: { type: 'string' },
records: { type: 'array' },
// B/C 类由 A3/A2 交回的底价与替代方案;A 类直通时为空
floorPrices: { type: 'array' },
},
},
messageAllowed: true,
},
output: {
mandatory: [
{
name: 'draft',
payload: {
type: 'object',
required: ['items'],
properties: { items: { type: 'array' } },
},
description: '报价草案(逐条带偏离度)',
},
],
selective: [],
},
requiredDeliverables: [{ key: 'quote-draft', label: '报价草案(全条目带偏离度)' }],
acceptanceCriteria: [
{ key: 'all-priced', label: '每条都有拟报单价与毛利率', level: 'L1', predicate: 'unpriced = 0' },
// 底价门禁沉为 L2 机检 —— 「约束力收缩」的终点
{ key: 'floor-gate', label: '偏离底价 ≤±20%,超限者已回调或注明理由', level: 'L2', modelRef: 'p02-floor' },
{ key: 'pm-release', label: 'BD 放行', level: 'L5' },
],
prohibitions: [
{ key: 'no-silent-override', statement: '不得静默绕开 P-02 的结论;要破线只能走「人 · 决策」' },
{ key: 'no-stale-floor', statement: '底价超一周未更新的,先刷底价再判' },
],
authorization: {
discretion: [{ key: 'margin-band', statement: '在 P-01 给出的毛利区间内自决;出区间必须调人决策' }],
preauthorizedActions: [],
humanCallBudget: 3,
},
resources: {
tools: [{ name: 'quote-pricing.basis' }, { name: 'crm.history-price-read' }],
skills: PRICING_SKILLS.map((s) => s.id),
models: ['quote-extractor'],
roles: ['BD'],
budget: { steps: 60, tokens: 150_000, activeMinutes: 120, humanCalls: 3 },
},
},
declarations: {
models: ['quote-extractor'],
tools: [{ name: 'crm.history-price-read' }, { name: 'quote-pricing.basis' }],
ledger: [
{
domain: DOMAIN,
object: 'draft',
label: '报价草案',
fields: [
{ name: 'pn', type: 'text', primaryKey: true, masked: false, label: 'PN' },
{ name: 'quoted_price', type: 'number', primaryKey: false, masked: false, label: '拟报单价' },
{ name: 'margin', type: 'number', primaryKey: false, masked: false, label: '毛利率' },
{ name: 'last_price', type: 'number', primaryKey: false, masked: false, label: '基准价' },
{ name: 'deviation', type: 'number', primaryKey: false, masked: false, label: '偏离度' },
{ name: 'disposition', type: 'text', primaryKey: false, masked: false, label: '门禁处置' },
],
},
],
listeners: [
{
origin: 'static',
eventType: 'human',
keyFilter: { kind: 'decision' },
semantic: 'complete-step',
deadline: 'PT4H',
escalation: ['nudge', 'escalate'],
},
],
// SLA <2h(MVP示例 §1.2 留痕 · SLA)
harness: {
memoryWindow: 20,
stallAfter: 'PT2H',
nudge: [{ after: 'PT1H', action: 'nudge' }],
retry: { times: 2, backoff: 'PT30S' },
},
},
assets: {
businessModel: {
paradigm: 'flow',
steps: [
{
kind: 'tool',
name: 'S1_basis',
label: 'S1 取价基准',
// Type A 取历史价近期价;B/C 取供应商底价表(C 类参考替代对标表)
input: { pn: 'pn' },
// 取回来的是**基准价**;偏离率要等 S2 定出拟报价才算得出来(见 S2B)
output: { domain: DOMAIN, object: 'draft', key: { pn: 'pn' }, fields: { last_price: 'lastPrice' } },
tool: 'crm.history-price-read',
view: 'pricing-basis',
failure: { retry: { times: 2, backoff: 'PT1M' }, fallback: { kind: 'human', workOrder: 'execution' } },
},
{
kind: 'pure-tool',
name: 'S2_price',
label: 'S2 逐条定价(DMN · 利润模型 P-01)',
input: { customerGrade: 'customerGrade', materialType: 'materialType', volumeTier: 'volumeTier' },
output: {
domain: DOMAIN,
object: 'draft',
key: { pn: 'pn' },
fields: { margin: 'marginLow', quoted_price: 'quotedPrice' },
},
tool: 'quote-pricing.margin',
failure: { retry: { times: 1, backoff: 'PT10S' }, fallback: { kind: 'blocked' } },
},
{
kind: 'pure-tool',
name: 'S2B_deviation',
label: 'S2B 算偏离率(基准价 ↔ 拟报价)',
input: { lastPrice: 'last_price', quotedPrice: 'quoted_price' },
output: { domain: DOMAIN, object: 'draft', key: { pn: 'pn' }, fields: { deviation: 'deviation' } },
tool: 'quote-pricing.basis',
failure: { retry: { times: 1, backoff: 'PT10S' }, fallback: { kind: 'blocked' } },
},
{
kind: 'pure-tool',
name: 'S3_floor_gate',
label: 'S3 底价自检(DMN · 底价门禁 P-02)',
input: { deviation: 'deviation' },
output: { domain: DOMAIN, object: 'draft', key: { pn: 'pn' }, fields: { disposition: 'disposition' } },
tool: 'quote-pricing.floor-gate',
view: 'pricing-priced',
failure: { retry: { times: 1, backoff: 'PT10S' }, fallback: { kind: 'blocked' } },
},
{
kind: 'human',
name: 'S4_decide_breach',
label: '超限条目:调人决策(回调还是注明理由)',
// 只有门禁不过才调人 —— 条件必谓词,零 LLM
when: 'breached > 0',
input: {},
workOrder: 'execution',
card: { title: '有条目低于底价 20% 以上,请裁决', fields: ['disposition', 'reason'] },
deadline: 'PT4H',
failure: { retry: { times: 0, backoff: 'PT30S' }, fallback: { kind: 'blocked' } },
},
{
kind: 'human',
name: 'S5_release',
label: 'S5 报价草案验收放行',
input: {},
workOrder: 'acceptance',
card: { title: '报价草案(全条目带偏离度)请验收', deliverable: 'quote-draft' },
deadline: 'P1D',
view: 'pricing-release',
failure: { retry: { times: 0, backoff: 'PT30S' }, fallback: { kind: 'blocked' } },
},
],
parallelGroups: [],
},
skills: PRICING_SKILLS,
viewTemplates: [
{ name: 'pricing-basis', html: PRICING_BASIS },
{ name: 'pricing-priced', html: PRICING_PRICED },
{ name: 'pricing-release', html: PRICING_RELEASE },
],
cardSchemas: {},
distillHooks: [
{
on: 'terminal',
prompt: '归纳本单定价的经验:哪些组合的毛利档被人回调过、底价门禁拦下的形态、破线的理由。',
},
],
},
samples: [
{
name: '战略客户 A 类大批量',
input: { customerCode: 'C001', records: [{ pn: 'LM358DR', type: 'A' }] },
expect: { ports: ['draft'] },
},
],
entry: { file: 'index.js', checksum: 'dev-entry-quote-pricing' },
};