@alipay/alipay-aipay 1.6.8-beta4 → 1.6.8-beta5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@alipay/alipay-aipay",
3
- "version": "1.6.8-beta4",
3
+ "version": "1.6.8-beta5",
4
4
  "description": "支付宝 AI 付接入 Skill 安装包 - 优先安装 Agent Skill,并在 macOS/Linux 后台准备用户级 CLI 工具",
5
5
  "type": "module",
6
6
  "bin": {
package/skill/VERSION CHANGED
@@ -1 +1 @@
1
- 1.6.8-beta4
1
+ 1.6.8-beta5
@@ -315,6 +315,7 @@ function dynamicMccRecordsFromCatalog(rawCatalog) {
315
315
  throw new Error('mcc-catalog-json 必须是非空数组');
316
316
  }
317
317
  const records = new Map();
318
+ const refs = new Set();
318
319
  for (const item of catalog) {
319
320
  if (!item || typeof item !== 'object' || Array.isArray(item)) throw new Error('mcc-catalog-json 项必须是对象');
320
321
  const code = String(item.mccCode || item.code || '').toUpperCase();
@@ -325,6 +326,10 @@ function dynamicMccRecordsFromCatalog(rawCatalog) {
325
326
  if (typeof item.needSpecialQual !== 'boolean') throw new Error(`动态 MCC ${code} 缺少布尔型 needSpecialQual`);
326
327
  if (!Array.isArray(item.qualificationGroups)) throw new Error(`动态 MCC ${code} 的 qualificationGroups 必须是数组`);
327
328
  if (records.has(code)) throw new Error(`动态 MCC 重复:${code}`);
329
+ const ref = item.mccRef == null ? '' : String(item.mccRef);
330
+ if (ref && !/^mcc-\d+$/u.test(ref)) throw new Error(`动态 MCC ${code} 的 mccRef 非法`);
331
+ if (ref && refs.has(ref)) throw new Error(`动态 MCC 目录引用重复:${ref}`);
332
+ if (ref) refs.add(ref);
328
333
  const needSpecialQual = item.needSpecialQual;
329
334
  const qualificationGroups = item.qualificationGroups;
330
335
  records.set(code, {
@@ -334,6 +339,7 @@ function dynamicMccRecordsFromCatalog(rawCatalog) {
334
339
  needSpecialQual,
335
340
  qualificationGroups,
336
341
  qualification: mccQualificationSummary({ needSpecialQual, qualificationGroups }),
342
+ ref: ref || undefined,
337
343
  dynamic: true
338
344
  });
339
345
  }
@@ -352,9 +358,20 @@ function sortedMccRecords(records) {
352
358
  return [...records.values()].sort((left, right) => left.code.localeCompare(right.code));
353
359
  }
354
360
 
361
+ function mccAgentRefEntries(records) {
362
+ const refs = new Map();
363
+ sortedMccRecords(records).forEach((record, index) => {
364
+ const ref = record.ref || `mcc-${index + 1}`;
365
+ if (refs.has(ref)) throw new Error(`动态 MCC 目录引用重复:${ref}`);
366
+ refs.set(ref, record.code);
367
+ });
368
+ return refs;
369
+ }
370
+
355
371
  function mccCatalogForAgent(records) {
356
- return sortedMccRecords(records).map((record, index) => ({
357
- ref: `mcc-${index + 1}`,
372
+ const refsByCode = new Map([...mccAgentRefEntries(records)].map(([ref, code]) => [code, ref]));
373
+ return sortedMccRecords(records).map((record) => ({
374
+ ref: refsByCode.get(record.code),
358
375
  mccName: record.name,
359
376
  mccDescription: record.applicableBusinesses
360
377
  }));
@@ -372,7 +389,7 @@ function parseAgentCandidateRefs(args, records) {
372
389
  if (!Array.isArray(parsed) || parsed.length > 8 || parsed.some((ref) => typeof ref !== 'string')) {
373
390
  throw new Error('agent-candidate-refs-json 必须是最多 8 项的 JSON 字符串数组');
374
391
  }
375
- const refs = new Map(sortedMccRecords(records).map((record, index) => [`mcc-${index + 1}`, record.code]));
392
+ const refs = mccAgentRefEntries(records);
376
393
  const codes = [];
377
394
  for (const ref of parsed) {
378
395
  if (!refs.has(ref) || codes.includes(refs.get(ref))) {
@@ -13,7 +13,7 @@
13
13
 
14
14
  `queryMcc`、签约查询和签约提交使用 `{"request":{...},"ctx":{}}`;`batchQueryMcc` 使用 `{"request":{"mccCodes":[...]}}`。完整 payload 只在脚本中维护;Agent 不从本模块自行构造 MCP 调用。
15
15
 
16
- `queryMcc` 成功树按同一 run、产品短时缓存,并逐项提供二级 MCC 编码、名称、描述和布尔型 `needSpecialQual`;任一必需字段缺失、为空或类型异常均失败关闭,不从其他字段回退。非精确编码时,Agent 应先理解用户原话,并在行业俗称或场景表达与目录用词可能不同时于首次调用一并提供有原话依据的行业概念或同义表达;本地词面结果为 `NONE`、候选冲突或低置信时,runner 可发出一次目录复核 marker,携带同一次 `queryMcc` 返回的当前产品 MCC 名称、描述和稳定引用;Agent 只返回该 marker 中的目录引用,runner 映射并校验为当前动态目录中的候选,不接受自由提交 MCC code。目录复核不新增 MCP/网络调用,语义扩充仍按 flow 最多完成两次。候选确定后,仅把其中 `needSpecialQual=true` 的编码集中交给一次 `batchQueryMcc` 获取特殊资质项;没有此类候选时不调用。多候选的完整树事实和资格详情按 run、产品、原查询、规范化语义词和选择回执缓存,用户选择时携带同一语义词且有效命中则两种 MCC 方法都不重调。缓存默认 1800 秒、无有效 run 不落盘;过期、损坏、符号链接、跨 run、语义词变化或事实哈希不一致时忽略并从完整当前产品目录重查,不修补缓存事实,不做产品级全量预取。
16
+ `queryMcc` 成功树按同一 run、产品短时缓存,并逐项提供二级 MCC 编码、名称、描述和布尔型 `needSpecialQual`;任一必需字段缺失、为空或类型异常均失败关闭,不从其他字段回退。非精确编码时,Agent 应先理解用户原话,并在行业俗称或场景表达与目录用词可能不同时于首次调用一并提供有原话依据的行业概念或同义表达;本地词面结果为 `NONE`、候选冲突或低置信时,runner 可发出一次目录复核 marker,携带同一次 `queryMcc` 返回的当前产品 MCC 名称、描述和稳定引用;Agent 只返回该 marker 中的目录引用,runner 映射并校验为当前动态目录中的候选,不接受自由提交 MCC code。稳定引用由完整动态目录生成,并随候选裁剪和资格详情合并原样携带;最终方案 runner 不得按缩减后的候选数组重新编号。目录复核不新增 MCP/网络调用,语义扩充仍按 flow 最多完成两次。候选确定后,仅把其中 `needSpecialQual=true` 的编码集中交给一次 `batchQueryMcc` 获取特殊资质项;没有此类候选时不调用。多候选的完整树事实和资格详情按 run、产品、原查询、规范化语义词和选择回执缓存,用户选择时携带同一语义词且有效命中则两种 MCC 方法都不重调。缓存默认 1800 秒、无有效 run 不落盘;过期、损坏、符号链接、跨 run、语义词变化或事实哈希不一致时忽略并从完整当前产品目录重查,不修补缓存事实,不做产品级全量预取。
17
17
 
18
18
  ## 签约状态
19
19
 
@@ -674,7 +674,10 @@ mcc_rows_from_tree() {
674
674
  elif (($rows | map(.fullCode) | unique | length) != ($rows | length)) then
675
675
  error("queryMcc returned duplicate selectable mcc")
676
676
  else
677
- $rows
677
+ ($rows
678
+ | sort_by(.fullCode)
679
+ | to_entries
680
+ | map(.value + {mccRef: ("mcc-" + ((.key + 1) | tostring))}))
678
681
  end
679
682
  ' 2>/dev/null
680
683
  }
@@ -682,16 +685,17 @@ mcc_rows_from_tree() {
682
685
  normalize_mcc_tree_catalog() {
683
686
  local rows_json="$1"
684
687
  jq -cn --argjson rows "$rows_json" '
685
- [
686
- $rows[] |
687
- {
688
+ ($rows |
689
+ map({
688
690
  mccCode: .fullCode,
689
691
  mccName: .treeName,
690
692
  mccDescription: .treeDescription,
691
693
  needSpecialQual: .treeNeedSpecialQual,
692
694
  qualificationGroups: []
693
- }
694
- ]
695
+ }) |
696
+ sort_by(.mccCode) |
697
+ to_entries |
698
+ map(.value + {mccRef: ("mcc-" + ((.key + 1) | tostring))}))
695
699
  ' 2>/dev/null
696
700
  }
697
701
 
@@ -778,6 +782,7 @@ normalize_mcc_catalog() {
778
782
  mccName: $row.treeName,
779
783
  mccDescription: $row.treeDescription,
780
784
  needSpecialQual: $row.treeNeedSpecialQual,
785
+ mccRef: $row.mccRef,
781
786
  qualificationGroups: (if $row.treeNeedSpecialQual then
782
787
  (($detail.qualificationGroups // []) | map({
783
788
  qualifications: ((.qualifications // []) | map({
@@ -994,7 +999,7 @@ run_resolve_plan() {
994
999
  else
995
1000
  full_codes=$(printf '%s' "$resolution" | jq -c '.mergedCandidateCodes // []' 2>/dev/null) || mcc_query_failed
996
1001
  fi
997
- if [ -z "${catalog:-}" ]; then
1002
+ if [ -z "${catalog:-}" ]; then
998
1003
  if ! printf '%s' "$full_codes" | jq -e 'type == "array" and length > 0' >/dev/null 2>&1; then
999
1004
  catalog="$tree_catalog"
1000
1005
  else
@@ -1014,6 +1019,15 @@ run_resolve_plan() {
1014
1019
  fi
1015
1020
  fi
1016
1021
  fi
1022
+ if [ -n "$agent_candidate_refs_json" ] && ! printf '%s' "$catalog" | jq -e \
1023
+ --argjson refs "$agent_candidate_refs_json" '
1024
+ ([.[] | .mccRef?] | map(select(type == "string"))) as $available |
1025
+ ($refs | type == "array" and all(.[]; . as $ref | $available | index($ref) != null))
1026
+ ' >/dev/null 2>&1; then
1027
+ # An invalid Agent review may have already fallen back to local matches.
1028
+ # Do not pass that invalid reference into the reduced final catalog.
1029
+ agent_candidate_refs_json=""
1030
+ fi
1017
1031
  node_args=(
1018
1032
  "$ONBOARDING_RUNNER" mcc-resolve-plan
1019
1033
  --query "$query"
@@ -1065,7 +1079,7 @@ case "${1:-}" in
1065
1079
  run_resolve_plan "$@"
1066
1080
  ;;
1067
1081
  *)
1068
- echo "用法: bash mcc.sh resolve-plan --query <经营描述|MCC编码> --product-type <aipay|webpay|apppay> --root-intent <onboarding_only|full_process> [--semantic-terms-json <JSON数组>] [--select <MCC编码> --selection-receipt <receipt>] [--input-id <USER_INPUT_ID>]"
1082
+ echo "用法: bash mcc.sh resolve-plan --query <经营描述|MCC编码> --product-type <aipay|webpay|apppay> --root-intent <onboarding_only|full_process> [--semantic-terms-json <JSON数组>] [--agent-candidate-refs-json <JSON数组>] [--select <MCC编码> --selection-receipt <receipt>] [--input-id <USER_INPUT_ID>]"
1069
1083
  exit 1
1070
1084
  ;;
1071
1085
  esac