@alipay/alipay-aipay 1.6.8-beta → 1.6.8-beta1
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
package/skill/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
1.6.8-
|
|
1
|
+
1.6.8-beta1
|
|
@@ -105,13 +105,15 @@ node "<SKILL_DIR>/references/normal/scripts/runtime.mjs" onboarding-message prod
|
|
|
105
105
|
|
|
106
106
|
已有经营描述、二级类目名称或编码时,以原话作为 `MCC_SEARCH_QUERY` 进入唯一 MCC 解析/方案入口。非精确编码时,Agent 应先理解原话;遇到行业俗称、场景表达或目录不一定直接出现的用词时,在首次调用中一并传入 0 到 12 个有原话依据的行业概念、经营对象或同义表达,形成 `MCC_SEMANTIC_TERMS_JSON`;只传概念、不传 MCC 编码,不补原话无依据的行业。没有可靠扩展时省略,不追加用户确认。runner 在完整动态类目内做 NFKC、泛词剥离、标点边界内二/三元词组召回和动态稀有度排序;原始精确编码/完整名称决定性优先,其余原话与 Agent 辅助概念联合评分,语义项按 `0.7` 权重参与,名称证据高于描述,其他候选最多 8 项。评分只用于真实目录召回排序;禁止业务词到 MCC 的硬编码点映射、Agent 全表判断、远程语义或额外网络调用。
|
|
107
107
|
|
|
108
|
+
同一 `run + 用户输入 + 原始 MCC_SEARCH_QUERY + 产品` 的语义扩充最多重试 2 次。首次未提供语义词且结果为 `NONE`,或已提供语义词但结果仍为 `NONE` 且仍有预算时,`mcc.sh` 只输出唯一内部 `MCC_SEMANTIC_RETRY_REQUIRED`,stdout 为空;Agent 必须保留原始 query、复用同一 `USER_INPUT_ID`,根据原话补充此前未使用且有依据的概念后原样重跑本命令,不向用户展示中间无匹配。后续重试提交的语义词必须保留此前语义词并至少新增一个此前未使用的词;未新增或替换原语义词时不消耗额度,直接进入既有无匹配分支。`MCC_SEMANTIC_RETRY_REQUIRED` 的 `attempt` 从 1 到 2,达到 2 后不再产生该 marker;仍为 `NONE` 时输出下方既有无匹配文案并停止。精确 MCC 编码不存在不进入语义重试;网络/CLI 失败仍只走各自既有恢复分支。语义重试计数只保存在当前 run 的私有缓存中,不随 MCC 树缓存 TTL 过期,读写异常按已耗尽处理,禁止通过更换 query、重置参数或重复调用绕过上限。
|
|
109
|
+
|
|
108
110
|
`queryMcc` 树和多候选快照使用默认 1800 秒、本轮 run 私有缓存;无有效 run 不缓存。快照绑定产品、salesCode、原查询、规范化语义词、选择回执、候选树事实及按需取得的资格详情;有效命中原样复用,失效才重查。runner 只接受最多 12 项、单项 2 到 40 字符、总计不超过 240 字符的 JSON 字符串数组并拒绝 MCC 编码;Agent 参数错误时基于原话更正或省略,不要求用户重述。两种 MCP 请求体不变;`batchQueryMcc` 最多一次,只传树内命中且 `needSpecialQual=true` 的候选编码。
|
|
109
111
|
|
|
110
112
|
```bash
|
|
111
113
|
node "<SKILL_DIR>/references/normal/scripts/runtime.mjs" mcc resolve-plan --query "$MCC_SEARCH_QUERY" --product-type "$PRODUCT_TYPE" --root-intent "$ROOT_INTENT" [--semantic-terms-json "$MCC_SEMANTIC_TERMS_JSON"] --input-id "$USER_INPUT_ID" [--telemetry-run-id "$RUN_ID" --telemetry-history-count "$HISTORY_COUNT"]
|
|
112
114
|
```
|
|
113
115
|
|
|
114
|
-
只收唯一 `ALIPAY_AIPAY_INTERNAL:MCC_QUERY_RESULT=SUCCESS` 与 `ALIPAY_AIPAY_INTERNAL:MCC_RESOLUTION=<json
|
|
116
|
+
只收唯一 `ALIPAY_AIPAY_INTERNAL:MCC_QUERY_RESULT=SUCCESS` 与 `ALIPAY_AIPAY_INTERNAL:MCC_RESOLUTION=<json>`。若同时收到唯一 `ALIPAY_AIPAY_INTERNAL:MCC_SEMANTIC_RETRY_REQUIRED=<json>` 且 stdout 为空,不产生对客消息,按上面的规则在同一工作回合自动重跑;不得把该 marker 或中间状态展示给用户。`UNIQUE` 恰一项,并有唯一 `CUSTOMER_MESSAGE_DELIVERY_REQUIRED=onboarding.plan.confirm`、`MCC_CONTEXT_RECEIPT`;先把 stdout 作为可见进行中消息原文送达,随后同一回合进入 `execute`,不等待回复。`MULTIPLE` 送候选后等待;预算耗尽的 `NONE` 送既有无匹配文案后等待用户重新描述。禁止旧 `mcc-search`/`mcc-candidates`、手写候选或近似追问。
|
|
115
117
|
|
|
116
118
|
`MCC_FLOW:RETRY_WITH_NETWORK`:联网后原样重试同一 `mcc resolve-plan`。`CLI_FLOW:RETRY_WITH_LOCAL_FS_PERMISSION` 且 stdout 空:给同命令 CLI 私有状态目录权限后原样重试。失败停 MCC;禁无匹配兜底或进方案/授权/签约。
|
|
117
119
|
|
|
@@ -123,7 +125,7 @@ node "<SKILL_DIR>/references/normal/scripts/runtime.mjs" mcc resolve-plan --quer
|
|
|
123
125
|
|
|
124
126
|
`salesCode`、`scope` 和基础材料只取“产品映射”。方案只由 `mcc resolve-plan` 或已有唯一 MCC 事实时的 `onboarding-message plan-confirm --root-intent "$ROOT_INTENT" --mcc-context-receipt ... [--telemetry-run-id "$RUN_ID" --telemetry-history-count "$HISTORY_COUNT"]` 生成,展示产品/scope、MCC、特殊资质、企业账号边界及商家平台链接。已有 active run 时必须传 telemetry 参数;如果该命令首次创建 run,则尚无 marker,省略参数并由同一进程把本次 plan stage 的 history 固定为 0,命令返回后取得后续使用的 `RUN_ID`。`ROOT_INTENT` 取当前路线根意图,只能是 `onboarding_only` 或 `full_process`。特殊资质只来自 `qualificationGroups`:多个 group 是 OR 关系;同一 group 内多个 qualifications 是 AND 关系;`attaType` 为空或 null 的 qualification 只展示 `qualName`,不生成上传项。禁止补充模板外资格或审核规则。
|
|
125
127
|
|
|
126
|
-
不得保留“先运行旧字符串搜索,无匹配后再临时让 Agent
|
|
128
|
+
不得保留“先运行旧字符串搜索,无匹配后再临时让 Agent 猜”的两阶段流程,或重复询问已知信息;这里的语义重试只允许按上一段登记的两次预算执行,且不增加用户确认。语义概念与原话必须在同一次 `resolve-plan` 中提交并统一校验。唯一事实校验通过、方案 marker 唯一且 stdout 已送达后,执行 `onboarding-execute-ready --product-type "$PRODUCT_TYPE"`;缺值/冲突/非唯一继续澄清,产品/MCC 变更重渲染。`execute` loader 只继承 `clarify_intent` 已记录的正式 run 事实,不再单独记录 stage,不代表新增用户回复,禁手工上报;Agent 在收到每条聊天框用户消息时,必须先按 `runtime-entry.md` 的统一前置命令计数,不按是否与 Skill 相关筛选,`summary` 收口后不再计入当前 run,`full_process` 不重置。
|
|
127
129
|
|
|
128
130
|
<!-- ALIPAY_AIPAY_FLOW:ONBOARDING_ENTRY:END -->
|
|
129
131
|
|
|
@@ -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 应先理解用户原话,并在行业俗称或场景表达与目录用词可能不同时于首次调用一并提供有原话依据的行业概念或同义表达;runner 拒绝由 Agent 提供 MCC code
|
|
16
|
+
`queryMcc` 成功树按同一 run、产品短时缓存,并逐项提供二级 MCC 编码、名称、描述和布尔型 `needSpecialQual`;任一必需字段缺失、为空或类型异常均失败关闭,不从其他字段回退。非精确编码时,Agent 应先理解用户原话,并在行业俗称或场景表达与目录用词可能不同时于首次调用一并提供有原话依据的行业概念或同义表达;runner 拒绝由 Agent 提供 MCC code,并只在当前产品动态树内召回和校验。首次未提供语义词且结果为 `NONE`,或已提供语义词但结果仍为 `NONE` 时,由脚本发出 flow 登记的重试 marker,Agent 按 flow 最多完成两次语义扩充重试;后续重试必须保留此前语义词并至少新增一个此前未使用的词,未新增或替换原语义词时不消耗额度,直接回到既有无匹配分支;耗尽后回到 flow 登记的无匹配文案,要求重新描述经营信息。候选确定后,仅把其中 `needSpecialQual=true` 的编码集中交给一次 `batchQueryMcc` 获取特殊资质项;没有此类候选时不调用。多候选的完整树事实和资格详情按 run、产品、原查询、规范化语义词和选择回执缓存,用户选择时携带同一语义词且有效命中则两种 MCC 方法都不重调。缓存默认 1800 秒、无有效 run 不落盘;过期、损坏、符号链接、跨 run、语义词变化或事实哈希不一致时忽略并从完整当前产品目录重查,不修补缓存事实,不做产品级全量预取。
|
|
17
17
|
|
|
18
18
|
## 签约状态
|
|
19
19
|
|
|
@@ -20,6 +20,7 @@ fi
|
|
|
20
20
|
source "${SCRIPT_DIR}/network_retry.sh"
|
|
21
21
|
|
|
22
22
|
ONBOARDING_RUNNER="${SCRIPT_DIR}/../../../normal/scripts/onboarding_message_runner.mjs"
|
|
23
|
+
MCC_SEMANTIC_RETRY_LIMIT=2
|
|
23
24
|
|
|
24
25
|
require_command jq || exit 1
|
|
25
26
|
require_command node || exit 1
|
|
@@ -306,6 +307,203 @@ write_mcc_selection_cache() {
|
|
|
306
307
|
}
|
|
307
308
|
}
|
|
308
309
|
|
|
310
|
+
mcc_semantic_retry_file() {
|
|
311
|
+
local product_type="$1" sales_code="$2" root scope
|
|
312
|
+
root="$(mcc_cache_root)" || return 1
|
|
313
|
+
scope="$(mcc_cache_scope_id)" || return 1
|
|
314
|
+
if [ -e "$root" ] && { [ ! -d "$root" ] || [ -L "$root" ]; }; then
|
|
315
|
+
return 1
|
|
316
|
+
fi
|
|
317
|
+
mkdir -p "$root" 2>/dev/null || return 1
|
|
318
|
+
chmod 700 "$root" 2>/dev/null || true
|
|
319
|
+
printf '%s/%s.%s.%s.semantic-retries.json' \
|
|
320
|
+
"$root" \
|
|
321
|
+
"$(mcc_cache_component "$scope")" \
|
|
322
|
+
"$(mcc_cache_component "$product_type")" \
|
|
323
|
+
"$(mcc_cache_component "$sales_code")"
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
claim_mcc_semantic_retry() {
|
|
327
|
+
local product_type="$1" sales_code="$2" query="$3" input_id="$4" semantic_terms_json="$5"
|
|
328
|
+
local file dir lock entry original_query retry_count next_retry_count now tmp lock_acquired=false
|
|
329
|
+
local current_terms previous_terms missing_previous_terms new_terms
|
|
330
|
+
file="$(mcc_semantic_retry_file "$product_type" "$sales_code")" || return 2
|
|
331
|
+
dir="${file%/*}"
|
|
332
|
+
lock="${file}.lock"
|
|
333
|
+
current_terms="$(printf '%s' "$semantic_terms_json" | jq -ce '
|
|
334
|
+
select(type == "array" and all(.[]; type == "string")) | unique | sort
|
|
335
|
+
' 2>/dev/null)" || return 2
|
|
336
|
+
|
|
337
|
+
# Claim and persist one retry under a bounded private lock. Lock contention
|
|
338
|
+
# is treated as exhausted so a broken local state cannot cause a retry loop.
|
|
339
|
+
for _ in 1 2 3 4 5 6 7 8 9 10; do
|
|
340
|
+
if mkdir "$lock" 2>/dev/null; then
|
|
341
|
+
lock_acquired=true
|
|
342
|
+
break
|
|
343
|
+
fi
|
|
344
|
+
sleep 0.05
|
|
345
|
+
done
|
|
346
|
+
[ "$lock_acquired" = true ] || return 2
|
|
347
|
+
|
|
348
|
+
if [ -e "$file" ]; then
|
|
349
|
+
if [ ! -f "$file" ] || [ -L "$file" ]; then
|
|
350
|
+
rmdir "$lock" 2>/dev/null || true
|
|
351
|
+
return 2
|
|
352
|
+
fi
|
|
353
|
+
now="$(date +%s 2>/dev/null)" || {
|
|
354
|
+
rmdir "$lock" 2>/dev/null || true
|
|
355
|
+
return 2
|
|
356
|
+
}
|
|
357
|
+
entry="$(jq -cr \
|
|
358
|
+
--arg inputId "$input_id" \
|
|
359
|
+
'
|
|
360
|
+
if .schemaVersion == 1
|
|
361
|
+
and ((.entries // null) | type == "array")
|
|
362
|
+
and all(.entries[];
|
|
363
|
+
type == "object"
|
|
364
|
+
and ((.inputId // null) | type == "string")
|
|
365
|
+
and ((.query // null) | type == "string")
|
|
366
|
+
and ((.count // null) | type == "number")
|
|
367
|
+
and (.count >= 0)
|
|
368
|
+
and ((.count | floor) == .count)
|
|
369
|
+
and ((.updatedAtEpoch // null) | type == "number")
|
|
370
|
+
and ((.semanticTerms // []) | type == "array")
|
|
371
|
+
and all((.semanticTerms // [])[]; type == "string")
|
|
372
|
+
)
|
|
373
|
+
then
|
|
374
|
+
([.entries[] |
|
|
375
|
+
select(
|
|
376
|
+
.inputId == $inputId
|
|
377
|
+
) |
|
|
378
|
+
{query, count, updatedAtEpoch, semanticTerms: (.semanticTerms // [])}
|
|
379
|
+
] | sort_by(.updatedAtEpoch) | last) // null
|
|
380
|
+
else
|
|
381
|
+
error("invalid MCC semantic retry state")
|
|
382
|
+
end
|
|
383
|
+
' "$file" 2>/dev/null)" || {
|
|
384
|
+
rmdir "$lock" 2>/dev/null || true
|
|
385
|
+
return 2
|
|
386
|
+
}
|
|
387
|
+
else
|
|
388
|
+
entry='null'
|
|
389
|
+
fi
|
|
390
|
+
|
|
391
|
+
if [ "$entry" = "null" ]; then
|
|
392
|
+
original_query="$query"
|
|
393
|
+
retry_count=0
|
|
394
|
+
previous_terms='[]'
|
|
395
|
+
else
|
|
396
|
+
original_query="$(printf '%s' "$entry" | jq -r '.query // empty' 2>/dev/null)" || original_query=""
|
|
397
|
+
retry_count="$(printf '%s' "$entry" | jq -r '.count // -1' 2>/dev/null)" || retry_count=-1
|
|
398
|
+
previous_terms="$(printf '%s' "$entry" | jq -c '.semanticTerms // []' 2>/dev/null)" || previous_terms=""
|
|
399
|
+
if [ "$original_query" != "$query" ]; then
|
|
400
|
+
rmdir "$lock" 2>/dev/null || true
|
|
401
|
+
return 2
|
|
402
|
+
fi
|
|
403
|
+
[ -n "$previous_terms" ] || {
|
|
404
|
+
rmdir "$lock" 2>/dev/null || true
|
|
405
|
+
return 2
|
|
406
|
+
}
|
|
407
|
+
missing_previous_terms="$(jq -nr \
|
|
408
|
+
--argjson previous "$previous_terms" \
|
|
409
|
+
--argjson current "$current_terms" \
|
|
410
|
+
'($previous - $current) | length' 2>/dev/null)" || {
|
|
411
|
+
rmdir "$lock" 2>/dev/null || true
|
|
412
|
+
return 2
|
|
413
|
+
}
|
|
414
|
+
new_terms="$(jq -nr \
|
|
415
|
+
--argjson previous "$previous_terms" \
|
|
416
|
+
--argjson current "$current_terms" \
|
|
417
|
+
'($current - $previous) | length' 2>/dev/null)" || {
|
|
418
|
+
rmdir "$lock" 2>/dev/null || true
|
|
419
|
+
return 2
|
|
420
|
+
}
|
|
421
|
+
if [ "$missing_previous_terms" -ne 0 ] || [ "$new_terms" -eq 0 ]; then
|
|
422
|
+
# A semantic retry must be cumulative and add at least one new term.
|
|
423
|
+
# Do not consume a retry budget for an unchanged or replaced term set.
|
|
424
|
+
rmdir "$lock" 2>/dev/null || true
|
|
425
|
+
return 3
|
|
426
|
+
fi
|
|
427
|
+
fi
|
|
428
|
+
case "$retry_count" in
|
|
429
|
+
''|*[!0-9]*) retry_count="$MCC_SEMANTIC_RETRY_LIMIT" ;;
|
|
430
|
+
esac
|
|
431
|
+
if [ "$retry_count" -ge "$MCC_SEMANTIC_RETRY_LIMIT" ]; then
|
|
432
|
+
rmdir "$lock" 2>/dev/null || true
|
|
433
|
+
return 2
|
|
434
|
+
fi
|
|
435
|
+
next_retry_count=$((retry_count + 1))
|
|
436
|
+
now="$(date +%s 2>/dev/null)" || {
|
|
437
|
+
rmdir "$lock" 2>/dev/null || true
|
|
438
|
+
return 2
|
|
439
|
+
}
|
|
440
|
+
tmp="$(mktemp "$dir/.mcc-semantic-retries.XXXXXX" 2>/dev/null)" || {
|
|
441
|
+
rmdir "$lock" 2>/dev/null || true
|
|
442
|
+
return 2
|
|
443
|
+
}
|
|
444
|
+
chmod 600 "$tmp" 2>/dev/null || true
|
|
445
|
+
if [ -f "$file" ] && [ ! -L "$file" ]; then
|
|
446
|
+
if ! jq -ce \
|
|
447
|
+
--arg query "$original_query" \
|
|
448
|
+
--arg inputId "$input_id" \
|
|
449
|
+
--argjson count "$next_retry_count" \
|
|
450
|
+
--argjson now "$now" \
|
|
451
|
+
--argjson semanticTerms "$current_terms" '
|
|
452
|
+
if .schemaVersion != 1 or ((.entries // null) | type != "array") then
|
|
453
|
+
error("invalid MCC semantic retry state")
|
|
454
|
+
else
|
|
455
|
+
.entries = (
|
|
456
|
+
[.entries[] | select(.inputId != $inputId)]
|
|
457
|
+
+ [{
|
|
458
|
+
query: $query,
|
|
459
|
+
inputId: $inputId,
|
|
460
|
+
count: $count,
|
|
461
|
+
updatedAtEpoch: $now,
|
|
462
|
+
semanticTerms: $semanticTerms
|
|
463
|
+
}]
|
|
464
|
+
)
|
|
465
|
+
| .entries |= sort_by(.updatedAtEpoch)
|
|
466
|
+
end
|
|
467
|
+
' "$file" >"$tmp" 2>/dev/null; then
|
|
468
|
+
rm -f "$tmp" 2>/dev/null || true
|
|
469
|
+
rmdir "$lock" 2>/dev/null || true
|
|
470
|
+
return 2
|
|
471
|
+
fi
|
|
472
|
+
elif [ -e "$file" ]; then
|
|
473
|
+
rm -f "$tmp" 2>/dev/null || true
|
|
474
|
+
rmdir "$lock" 2>/dev/null || true
|
|
475
|
+
return 2
|
|
476
|
+
else
|
|
477
|
+
if ! jq -cn \
|
|
478
|
+
--arg query "$original_query" \
|
|
479
|
+
--arg inputId "$input_id" \
|
|
480
|
+
--argjson count "$next_retry_count" \
|
|
481
|
+
--argjson now "$now" \
|
|
482
|
+
--argjson semanticTerms "$current_terms" \
|
|
483
|
+
'{
|
|
484
|
+
schemaVersion: 1,
|
|
485
|
+
entries: [{
|
|
486
|
+
query: $query,
|
|
487
|
+
inputId: $inputId,
|
|
488
|
+
count: $count,
|
|
489
|
+
updatedAtEpoch: $now,
|
|
490
|
+
semanticTerms: $semanticTerms
|
|
491
|
+
}]
|
|
492
|
+
}' >"$tmp" 2>/dev/null; then
|
|
493
|
+
rm -f "$tmp" 2>/dev/null || true
|
|
494
|
+
rmdir "$lock" 2>/dev/null || true
|
|
495
|
+
return 2
|
|
496
|
+
fi
|
|
497
|
+
fi
|
|
498
|
+
if ! mv "$tmp" "$file" 2>/dev/null; then
|
|
499
|
+
rm -f "$tmp" 2>/dev/null || true
|
|
500
|
+
rmdir "$lock" 2>/dev/null || true
|
|
501
|
+
return 2
|
|
502
|
+
fi
|
|
503
|
+
rmdir "$lock" 2>/dev/null || true
|
|
504
|
+
printf '%s' "$next_retry_count"
|
|
505
|
+
}
|
|
506
|
+
|
|
309
507
|
get_mcc_tree() {
|
|
310
508
|
local product_type="$1" sales_code="$2" cached tree cached_rows
|
|
311
509
|
cached="$(read_mcc_tree_cache "$product_type" "$sales_code" 2>/dev/null || true)"
|
|
@@ -550,7 +748,7 @@ validate_mcc_selection_cache() {
|
|
|
550
748
|
}
|
|
551
749
|
|
|
552
750
|
run_resolve_plan() {
|
|
553
|
-
local query="" product_type="" root_intent="" semantic_terms_json='[]' select_value="" selection_receipt="" input_id="" sales_code tree rows tree_catalog resolution match_type full_codes candidate_rows qualification_rows details catalog selection_cache="" used_selection_cache=false stale_selection=false resolved_semantic_terms='[]'
|
|
751
|
+
local query="" product_type="" root_intent="" semantic_terms_json='[]' select_value="" selection_receipt="" input_id="" sales_code tree rows tree_catalog resolution match_type semantic_status full_codes candidate_rows qualification_rows details catalog selection_cache="" used_selection_cache=false stale_selection=false resolved_semantic_terms='[]' retry_input_id="" retry_rc=0 next_retry_count=0 retry_reason="" retry_payload=""
|
|
554
752
|
shift
|
|
555
753
|
while [[ $# -gt 0 ]]; do
|
|
556
754
|
case "$1" in
|
|
@@ -630,7 +828,34 @@ run_resolve_plan() {
|
|
|
630
828
|
}
|
|
631
829
|
capture_or_exit resolution run_mcc_match_codes "$query" "$product_type" "$root_intent" "$tree_catalog" "$semantic_terms_json"
|
|
632
830
|
match_type=$(printf '%s' "$resolution" | jq -r '.matchType // ""' 2>/dev/null) || mcc_query_failed
|
|
831
|
+
semantic_status=$(printf '%s' "$resolution" | jq -r '.semanticStatus // ""' 2>/dev/null) || mcc_query_failed
|
|
633
832
|
resolved_semantic_terms=$(printf '%s' "$resolution" | jq -c '.semanticTerms // []' 2>/dev/null) || mcc_query_failed
|
|
833
|
+
if [ "$match_type" = "NONE" ] \
|
|
834
|
+
&& [ "$semantic_status" != "DYNAMIC_CATALOG_CODE_NOT_FOUND" ] \
|
|
835
|
+
&& [ "$semantic_status" != "DYNAMIC_CATALOG_CODE_AMBIGUOUS" ]; then
|
|
836
|
+
retry_input_id="${input_id:-__NO_INPUT_ID__}"
|
|
837
|
+
next_retry_count="$(claim_mcc_semantic_retry \
|
|
838
|
+
"$product_type" "$sales_code" "$query" "$retry_input_id" "$resolved_semantic_terms" 2>/dev/null)"
|
|
839
|
+
retry_rc=$?
|
|
840
|
+
if [ "$retry_rc" -eq 0 ]; then
|
|
841
|
+
if [ "$semantic_terms_json" = "[]" ]; then
|
|
842
|
+
retry_reason="MISSING_SEMANTIC_TERMS"
|
|
843
|
+
else
|
|
844
|
+
retry_reason="NO_MATCH"
|
|
845
|
+
fi
|
|
846
|
+
retry_payload=$(jq -cn \
|
|
847
|
+
--argjson attempt "$next_retry_count" \
|
|
848
|
+
--argjson maxAttempts "$MCC_SEMANTIC_RETRY_LIMIT" \
|
|
849
|
+
--argjson remainingAttempts "$((MCC_SEMANTIC_RETRY_LIMIT - next_retry_count))" \
|
|
850
|
+
--arg reason "$retry_reason" \
|
|
851
|
+
'{attempt: $attempt, maxAttempts: $maxAttempts, remainingAttempts: $remainingAttempts, reason: $reason}') \
|
|
852
|
+
|| mcc_query_failed
|
|
853
|
+
emit_control "MCC_QUERY_RESULT=SUCCESS"
|
|
854
|
+
emit_control "MCC_RESOLUTION=$resolution"
|
|
855
|
+
emit_control "MCC_SEMANTIC_RETRY_REQUIRED=$retry_payload"
|
|
856
|
+
return 0
|
|
857
|
+
fi
|
|
858
|
+
fi
|
|
634
859
|
if [ "$match_type" = "NONE" ]; then
|
|
635
860
|
catalog="$tree_catalog"
|
|
636
861
|
else
|
|
@@ -60,7 +60,7 @@ node "<SKILL_DIR>/references/normal/scripts/runtime.mjs" render <messageId> --va
|
|
|
60
60
|
|
|
61
61
|
每个登记 stage 动作前,Agent 回顾当前可见历史并得到 `HISTORY_COUNT`;只统计本 run `clarify_intent` 后的用户角色消息,无法可靠回顾时使用 `null`。调用能生成 stage 的业务命令时追加 `--telemetry-run-id "$RUN_ID" --telemetry-history-count "$HISTORY_COUNT"`,由统一 gateway 在业务 parser 前剥离并传给唯一 stage 责任方,Agent 不再额外调用 `telemetry stage`。首次在产品/MCC 确认命令内部新建 run 时尚无 marker,该进程使用刚创建的 active run 且本次 history 固定为 0。`c4` 只承载 `user_input_after_clarify_intent`、`history_count`、`root_intent` 和按唯一非 summary event 数计算的 `progress_pct`;正式计数始终取 runtime counter,history 只诊断、不纠偏。
|
|
62
62
|
|
|
63
|
-
三种入口均只在无法确定产品时执行 `product-clarify` runner;产品明确但缺 MCC 用 `mcc-clarify`,且必须携带当前 `ROOT_INTENT`,由 runner 先创建或复用正式 telemetry run。已有经营描述、名称或编码时只执行 `node "<SKILL_DIR>/references/normal/scripts/runtime.mjs" mcc resolve-plan --query "$MCC_SEARCH_QUERY" --product-type "$PRODUCT_TYPE" --root-intent "$ROOT_INTENT" [--semantic-terms-json "$MCC_SEMANTIC_TERMS_JSON"] --input-id "$USER_INPUT_ID"`。`ROOT_INTENT` 缺失或非法时 runner 必须停止,禁止依赖跨进程环境变量静默推断或在没有正式 run 的情况下继续 MCC 查询。非精确编码时,Agent 在首次调用中最多补充 12
|
|
63
|
+
三种入口均只在无法确定产品时执行 `product-clarify` runner;产品明确但缺 MCC 用 `mcc-clarify`,且必须携带当前 `ROOT_INTENT`,由 runner 先创建或复用正式 telemetry run。已有经营描述、名称或编码时只执行 `node "<SKILL_DIR>/references/normal/scripts/runtime.mjs" mcc resolve-plan --query "$MCC_SEARCH_QUERY" --product-type "$PRODUCT_TYPE" --root-intent "$ROOT_INTENT" [--semantic-terms-json "$MCC_SEMANTIC_TERMS_JSON"] --input-id "$USER_INPUT_ID"`。`ROOT_INTENT` 缺失或非法时 runner 必须停止,禁止依赖跨进程环境变量静默推断或在没有正式 run 的情况下继续 MCC 查询。非精确编码时,Agent 在首次调用中最多补充 12 个有原话依据的行业概念、经营对象或同义表达;首次未提供语义词且结果为 `NONE`,或已提供语义词但结果仍为 `NONE` 时,同一 `run + 用户输入 + 原始 query + 产品` 最多再扩充并重试 2 次,复用同一 `USER_INPUT_ID`,每次只增加有原话依据且此前未使用的概念;后续重试提交的语义词必须保留此前语义词并至少新增一个此前未使用的词,未新增或替换原语义词时不消耗额度;达到上限仍为 `NONE` 时必须按既有 no-match 对客消息要求用户重新描述经营信息。只传概念、不传 MCC 编码且不新增确认;禁止通过更换 query、重置参数或重复调用绕过上限,也禁止硬编码映射、全表判断、远程语义或手拼候选。runner 按 Onboarding entry 严格校验当前产品 `queryMcc` 目录、联合排序原话与语义证据,只为命中且 `needSpecialQual=true` 的候选调用一次 `batchQueryMcc`,并复用有效的同 run/产品候选快照。
|
|
64
64
|
|
|
65
65
|
代码开发或完整接入缺项目位置/服务端语言时,使用 `integration.context.required` 或 `integration.project_path.required` 标准消息;框架缺失不触发补问。先区分新建/复用,`PROJECT_INPUT` 保留原话。Agent 确定两类项目的真实 `PROJECT_PATH`,以 `resolve-project --project-path "$PROJECT_PATH" --intent <existing|new>` 交 runner 校验;`PROJECT_INPUT` 不得代替路径。默认新建也先选安全路径并显式传入。现有项目位置未知时先定位候选;路径经 `resolve-project` 后再用 `framework-resolve`。补齐前不初始化、装依赖或改文件。
|
|
66
66
|
|