aitable-workflow-cli 0.1.15 → 0.1.16-beta.1786022310508
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 +3 -3
- package/templates/support-qa/lib/__tests__/declarative-matcher.test.ts +240 -0
- package/templates/support-qa/lib/__tests__/dingtalk-group-membership.test.ts +127 -0
- package/templates/support-qa/lib/__tests__/memory-events.test.ts +90 -0
- package/templates/support-qa/lib/action-dispatch.ts +1 -1
- package/templates/support-qa/lib/declarative-matcher.ts +398 -0
- package/templates/support-qa/lib/dingtalk-group-membership.ts +151 -0
- package/templates/support-qa/lib/guards.ts +18 -0
- package/templates/support-qa/lib/memory-events.ts +60 -41
- package/templates/support-qa/lib/preflight.ts +294 -0
- package/templates/support-qa/package.json +2 -4
- package/templates/support-qa/profiles/aitable/profile/fastpath/known-answers.yml +1 -1
- package/templates/support-qa/profiles/aitable/profile/troubleshoot/classifiers.yml +1 -1
- package/templates/support-qa/workflows/config-sync/recipes/config_sync.recipe.ts +10 -8
- package/templates/support-qa/workflows/daily-review/recipes/daily_review.recipe.ts +1 -1
- package/templates/support-qa/workflows/group-qa/recipes/answer.recipe.ts +2 -7
- package/templates/support-qa/workflows/group-qa/recipes/conversation_handler.recipe.ts +3 -3
- package/templates/support-qa/workflows/group-qa/recipes/fastpath.recipe.ts +5 -11
- package/templates/support-qa/workflows/group-qa/recipes/on-action.recipe.ts +4 -2
- package/templates/support-qa/workflows/group-qa/recipes/reply-to-group.recipe.ts +13 -7
- package/templates/support-qa/workflows/group-qa/recipes/troubleshoot.recipe.ts +12 -18
- package/templates/support-qa/workspaces/support/AGENTS.md +1 -1
- package/templates/aitable-handoff/.env.example +0 -17
- package/templates/aitable-handoff/aitable-workflow.config.yml +0 -64
- package/templates/aitable-handoff/coding-agents.config.json +0 -17
- package/templates/aitable-handoff/npmrc +0 -1
- package/templates/aitable-handoff/package.json +0 -16
- package/templates/aitable-handoff/roles/config-syncer.role.yml +0 -4
- package/templates/aitable-handoff/roles/daily-review.role.yml +0 -4
- package/templates/aitable-handoff/roles/faq-support.role.yml +0 -9
- package/templates/aitable-handoff/roles/faq-troubleshooter.role.yml +0 -17
- package/templates/aitable-handoff/roles/kb-editor.role.yml +0 -19
- package/templates/aitable-handoff/wiki/faq-support/01-/345/277/253/351/200/237/345/205/245/351/227/250/6/350/212/202/350/257/276/345/270/246/344/275/240/345/277/253/351/200/237/344/270/212/346/211/213AI/350/241/250/346/240/274.md +0 -43
- package/templates/aitable-handoff/wiki/faq-support/01-/345/277/253/351/200/237/345/205/245/351/227/250/AI/350/241/250/346/240/274/350/241/214/346/225/260/350/257/264/346/230/216.md +0 -85
- package/templates/aitable-handoff/wiki/faq-support/01-/345/277/253/351/200/237/345/205/245/351/227/250//344/275/277/347/224/250/345/277/253/346/215/267/351/224/256.md +0 -34
- package/templates/aitable-handoff/wiki/faq-support/01-/345/277/253/351/200/237/345/205/245/351/227/250//345/260/206Excel/346/226/207/344/273/266/345/257/274/345/205/245AI/350/241/250/346/240/274.md +0 -48
- package/templates/aitable-handoff/wiki/faq-support/01-/345/277/253/351/200/237/345/205/245/351/227/250//345/270/270/350/247/201/351/227/256/351/242/230.md +0 -88
- package/templates/aitable-handoff/wiki/faq-support/01-/345/277/253/351/200/237/345/205/245/351/227/250//346/250/241/346/235/277/344/270/255/345/277/203.md +0 -59
- package/templates/aitable-handoff/wiki/faq-support/01-/345/277/253/351/200/237/345/205/245/351/227/250//351/222/211/351/222/211AI/350/241/250/346/240/274/345/270/270/350/247/201/344/270/212/351/231/220.md +0 -181
- package/templates/aitable-handoff/wiki/faq-support/01-/345/277/253/351/200/237/345/205/245/351/227/250//351/222/211/351/222/211AI/350/241/250/346/240/274/345/277/253/351/200/237/344/270/212/346/211/213.md +0 -177
- package/templates/aitable-handoff/wiki/faq-support/02-/345/237/272/347/241/200/346/223/215/344/275/234/AI/350/241/250/346/240/274/347/232/204/345/257/274/345/207/272.md +0 -27
- package/templates/aitable-handoff/wiki/faq-support/02-/345/237/272/347/241/200/346/223/215/344/275/234//344/275/277/347/224/250/345/210/206/347/273/204.md +0 -67
- package/templates/aitable-handoff/wiki/faq-support/02-/345/237/272/347/241/200/346/223/215/344/275/234//344/275/277/347/224/250/345/241/253/350/211/262.md +0 -99
- package/templates/aitable-handoff/wiki/faq-support/02-/345/237/272/347/241/200/346/223/215/344/275/234//344/275/277/347/224/250/346/216/222/345/272/217.md +0 -66
- package/templates/aitable-handoff/wiki/faq-support/02-/345/237/272/347/241/200/346/223/215/344/275/234//344/275/277/347/224/250/347/255/233/351/200/211/345/222/214/347/255/233/351/200/211/346/235/241/344/273/266/347/273/204.md +0 -104
- package/templates/aitable-handoff/wiki/faq-support/02-/345/237/272/347/241/200/346/223/215/344/275/234//346/237/245/347/234/213/345/216/206/345/217/262/350/256/260/345/275/225.md +0 -79
- package/templates/aitable-handoff/wiki/faq-support/02-/345/237/272/347/241/200/346/223/215/344/275/234//347/224/250AI/350/241/250/346/240/274/344/270/200/350/241/250/344/270/200/345/212/251/347/220/206/345/217/221/346/266/210/346/201/257.md +0 -94
- package/templates/aitable-handoff/wiki/faq-support/02-/345/237/272/347/241/200/346/223/215/344/275/234//350/207/252/345/256/232/344/271/211/350/256/260/345/275/225/345/220/215/347/247/260.md +0 -35
- package/templates/aitable-handoff/wiki/faq-support/02-/345/237/272/347/241/200/346/223/215/344/275/234//350/207/252/345/256/232/344/271/211/350/256/260/345/275/225/350/257/246/346/203/205/351/241/265/345/222/214/345/241/253/345/206/231/351/241/265.md +0 -141
- package/templates/aitable-handoff/wiki/faq-support/02-/345/237/272/347/241/200/346/223/215/344/275/234//350/260/203/346/225/264/345/210/227/345/256/275.md +0 -42
- package/templates/aitable-handoff/wiki/faq-support/02-/345/237/272/347/241/200/346/223/215/344/275/234//350/260/203/346/225/264/350/241/214/351/253/230.md +0 -40
- package/templates/aitable-handoff/wiki/faq-support/03-/344/275/277/347/224/250/345/255/227/346/256/265//344/270/272/350/241/250/346/240/274/346/267/273/345/212/240/345/255/227/346/256/265.md +0 -188
- package/templates/aitable-handoff/wiki/faq-support/03-/344/275/277/347/224/250/345/255/227/346/256/265//345/215/225/351/200/211/345/244/232/351/200/211/345/255/227/346/256/265/345/220/214/346/255/245/345/205/266/344/273/226/350/241/250/351/200/211/351/241/271.md +0 -142
- package/templates/aitable-handoff/wiki/faq-support/03-/344/275/277/347/224/250/345/255/227/346/256/265//345/255/227/346/256/265/347/256/241/347/220/206.md +0 -44
- package/templates/aitable-handoff/wiki/faq-support/03-/344/275/277/347/224/250/345/255/227/346/256/265//345/255/227/346/256/265/347/261/273/345/236/213/345/210/227/350/241/250.md +0 -95
- package/templates/aitable-handoff/wiki/faq-support/03-/344/275/277/347/224/250/345/255/227/346/256/265//345/255/227/346/256/265/347/274/226/347/273/204.md +0 -138
- package/templates/aitable-handoff/wiki/faq-support/04-/344/275/277/347/224/250/350/241/250/345/215/225//350/241/250/345/215/225/345/221/250/346/234/237/345/210/206/350/241/250.md +0 -42
- package/templates/aitable-handoff/wiki/faq-support/04-/344/275/277/347/224/250/350/241/250/345/215/225//350/241/250/345/215/225/345/237/272/347/241/200/346/223/215/344/275/234.md +0 -344
- package/templates/aitable-handoff/wiki/faq-support/04-/344/275/277/347/224/250/350/241/250/345/215/225//350/241/250/345/215/225/346/230/216/347/273/206/350/241/250-/344/270/200/346/254/241/345/241/253/345/206/231/345/244/232/346/235/241/346/217/220/344/272/244.md +0 -174
- package/templates/aitable-handoff/wiki/faq-support/04-/344/275/277/347/224/250/350/241/250/345/215/225//350/241/250/345/215/225/351/242/204/345/241/253/351/273/230/350/256/244/345/200/274.md +0 -97
- package/templates/aitable-handoff/wiki/faq-support/05-/345/205/254/345/274/217/345/207/275/346/225/260//344/275/277/347/224/250AI/347/224/237/346/210/220/345/205/254/345/274/217.md +0 -26
- package/templates/aitable-handoff/wiki/faq-support/05-/345/205/254/345/274/217/345/207/275/346/225/260//344/275/277/347/224/250/345/205/254/345/274/217/345/207/275/346/225/260/345/270/270/350/247/201/351/227/256/351/242/230.md +0 -179
- package/templates/aitable-handoff/wiki/faq-support/05-/345/205/254/345/274/217/345/207/275/346/225/260//344/275/277/347/224/250/345/205/254/345/274/217/345/255/227/346/256/265.md +0 -81
- package/templates/aitable-handoff/wiki/faq-support/05-/345/205/254/345/274/217/345/207/275/346/225/260//344/275/277/347/224/250/345/207/275/346/225/260.md +0 -21
- package/templates/aitable-handoff/wiki/faq-support/05-/345/205/254/345/274/217/345/207/275/346/225/260//345/205/254/345/274/217/345/207/275/346/225/260/345/244/247/345/205/250.md +0 -433
- package/templates/aitable-handoff/wiki/faq-support/05-/345/205/254/345/274/217/345/207/275/346/225/260//345/205/254/345/274/217/346/224/257/346/214/201/346/230/276/347/244/272/346/240/274/345/274/217.md +0 -126
- package/templates/aitable-handoff/wiki/faq-support/05-/345/205/254/345/274/217/345/207/275/346/225/260//345/205/254/345/274/217/351/224/231/350/257/257/344/273/243/347/240/201/345/210/227/350/241/250.md +0 -30
- package/templates/aitable-handoff/wiki/faq-support/05-/345/205/254/345/274/217/345/207/275/346/225/260//345/207/275/346/225/260/345/256/236/350/267/265.md +0 -13
- package/templates/aitable-handoff/wiki/faq-support/06-/346/225/260/346/215/256/350/277/236/346/216/245/344/270/255/345/277/203//346/225/260/346/215/256/350/277/236/346/216/245/344/270/255/345/277/203.md +0 -169
- package/templates/aitable-handoff/wiki/faq-support/06-/346/225/260/346/215/256/350/277/236/346/216/245/344/270/255/345/277/203//347/273/204/347/273/207/345/206/205/345/205/261/344/272/253/346/225/260/346/215/256/346/272/220.md +0 -106
- package/templates/aitable-handoff/wiki/faq-support/06-/346/225/260/346/215/256/350/277/236/346/216/245/344/270/255/345/277/203//350/267/250AI/350/241/250/346/240/274/346/225/260/346/215/256/345/220/214/346/255/245.md +0 -176
- package/templates/aitable-handoff/wiki/faq-support/06-/346/225/260/346/215/256/350/277/236/346/216/245/344/270/255/345/277/203//351/222/211/351/222/211AI/345/220/254/350/256/260/346/225/260/346/215/256/345/220/214/346/255/245.md +0 -100
- package/templates/aitable-handoff/wiki/faq-support/06-/346/225/260/346/215/256/350/277/236/346/216/245/344/270/255/345/277/203//351/222/211/351/222/211OA/345/256/241/346/211/271/346/225/260/346/215/256/345/220/214/346/255/245.md +0 -194
- package/templates/aitable-handoff/wiki/faq-support/06-/346/225/260/346/215/256/350/277/236/346/216/245/344/270/255/345/277/203//351/222/211/351/222/211/345/276/205/345/212/236/346/225/260/346/215/256/345/220/214/346/255/245.md +0 -87
- package/templates/aitable-handoff/wiki/faq-support/06-/346/225/260/346/215/256/350/277/236/346/216/245/344/270/255/345/277/203//351/222/211/351/222/211/346/227/245/347/250/213/346/225/260/346/215/256/345/220/214/346/255/245.md +0 -92
- package/templates/aitable-handoff/wiki/faq-support/06-/346/225/260/346/215/256/350/277/236/346/216/245/344/270/255/345/277/203//351/222/211/351/222/211/350/200/203/345/213/244/346/211/223/345/215/241/346/225/260/346/215/256/345/220/214/346/255/245.md +0 -129
- package/templates/aitable-handoff/wiki/faq-support/06-/346/225/260/346/215/256/350/277/236/346/216/245/344/270/255/345/277/203//351/222/211/351/222/211/350/241/250/346/240/274/346/225/260/346/215/256/345/220/214/346/255/245.md +0 -229
- package/templates/aitable-handoff/wiki/faq-support/06-/346/225/260/346/215/256/350/277/236/346/216/245/344/270/255/345/277/203//351/222/211/351/222/211/351/200/232/350/256/257/345/275/225/346/225/260/346/215/256/345/220/214/346/255/245.md +0 -120
- package/templates/aitable-handoff/wiki/faq-support/07-/344/275/277/347/224/250/350/247/206/345/233/276//344/275/277/347/224/250AI/350/241/250/346/240/274/350/247/206/345/233/276.md +0 -219
- package/templates/aitable-handoff/wiki/faq-support/07-/344/275/277/347/224/250/350/247/206/345/233/276//345/210/206/344/272/253/350/247/206/345/233/276.md +0 -71
- package/templates/aitable-handoff/wiki/faq-support/07-/344/275/277/347/224/250/350/247/206/345/233/276//346/225/260/346/215/256/350/241/250/345/222/214/350/247/206/345/233/276/347/232/204/345/205/263/347/263/273.md +0 -48
- package/templates/aitable-handoff/wiki/faq-support/07-/344/275/277/347/224/250/350/247/206/345/233/276//346/227/245/345/216/206/350/247/206/345/233/276.md +0 -89
- package/templates/aitable-handoff/wiki/faq-support/07-/344/275/277/347/224/250/350/247/206/345/233/276//346/237/245/350/257/242/351/241/265/351/235/242.md +0 -116
- package/templates/aitable-handoff/wiki/faq-support/07-/344/275/277/347/224/250/350/247/206/345/233/276//347/224/230/347/211/271/345/233/276.md +0 -135
- package/templates/aitable-handoff/wiki/faq-support/07-/344/275/277/347/224/250/350/247/206/345/233/276//347/224/273/345/206/214/350/247/206/345/233/276.md +0 -28
- package/templates/aitable-handoff/wiki/faq-support/07-/344/275/277/347/224/250/350/247/206/345/233/276//347/234/213/346/235/277/350/247/206/345/233/276.md +0 -35
- package/templates/aitable-handoff/wiki/faq-support/07-/344/275/277/347/224/250/350/247/206/345/233/276//350/241/250/346/240/274/350/247/206/345/233/276.md +0 -116
- package/templates/aitable-handoff/wiki/faq-support/07-/344/275/277/347/224/250/350/247/206/345/233/276//351/200/217/350/247/206/350/241/250/350/247/206/345/233/276.md +0 -123
- package/templates/aitable-handoff/wiki/faq-support/08-/344/275/277/347/224/250/344/273/252/350/241/250/347/233/230/TOP_N/345/210/206/346/236/220.md +0 -78
- package/templates/aitable-handoff/wiki/faq-support/08-/344/275/277/347/224/250/344/273/252/350/241/250/347/233/230//344/273/252/350/241/250/347/233/230/344/270/255/346/267/273/345/212/240/345/244/232/344/270/252/346/225/260/346/215/256/346/272/220.md +0 -129
- package/templates/aitable-handoff/wiki/faq-support/08-/344/275/277/347/224/250/344/273/252/350/241/250/347/233/230//344/273/252/350/241/250/347/233/230/345/215/225/345/233/276/350/241/250/345/222/214AI/350/247/243/350/257/273/345/206/205/345/256/271/345/210/206/344/272/253.md +0 -104
- package/templates/aitable-handoff/wiki/faq-support/08-/344/275/277/347/224/250/344/273/252/350/241/250/347/233/230//344/273/252/350/241/250/347/233/230/345/270/270/350/247/201/351/227/256/351/242/230.md +0 -31
- package/templates/aitable-handoff/wiki/faq-support/08-/344/275/277/347/224/250/344/273/252/350/241/250/347/233/230//344/273/252/350/241/250/347/233/230/346/231/272/350/203/275/346/200/273/347/273/223/345/210/206/346/236/220.md +0 -57
- package/templates/aitable-handoff/wiki/faq-support/08-/344/275/277/347/224/250/344/273/252/350/241/250/347/233/230//344/273/252/350/241/250/347/233/230/347/273/204/344/273/266.md +0 -47
- package/templates/aitable-handoff/wiki/faq-support/08-/344/275/277/347/224/250/344/273/252/350/241/250/347/233/230//344/275/277/347/224/250AI/350/241/250/346/240/274/344/273/252/350/241/250/347/233/230.md +0 -226
- package/templates/aitable-handoff/wiki/faq-support/08-/344/275/277/347/224/250/344/273/252/350/241/250/347/233/230//344/275/277/347/224/250/350/207/252/345/212/250/345/214/226/346/265/201/347/250/213/345/217/221/351/200/201/344/273/252/350/241/250/347/233/230.md +0 -49
- package/templates/aitable-handoff/wiki/faq-support/08-/344/275/277/347/224/250/344/273/252/350/241/250/347/233/230//345/210/206/344/272/253/344/273/252/350/241/250/347/233/230.md +0 -74
- package/templates/aitable-handoff/wiki/faq-support/08-/344/275/277/347/224/250/344/273/252/350/241/250/347/233/230//345/234/250/344/273/252/350/241/250/347/233/230/344/270/255/347/255/233/351/200/211/346/225/260/346/215/256.md +0 -65
- package/templates/aitable-handoff/wiki/faq-support/08-/344/275/277/347/224/250/344/273/252/350/241/250/347/233/230//350/207/252/345/256/232/344/271/211/344/273/252/350/241/250/347/233/230/344/270/255/345/277/203.md +0 -93
- package/templates/aitable-handoff/wiki/faq-support/08-/344/275/277/347/224/250/344/273/252/350/241/250/347/233/230//350/267/237/351/232/217/350/256/277/351/227/256/350/200/205/346/235/203/351/231/220/347/273/237/350/256/241.md +0 -48
- package/templates/aitable-handoff/wiki/faq-support/09-/345/272/224/347/224/250/346/250/241/345/274/217//345/205/250/346/226/260/345/272/224/347/224/250/346/250/241/345/274/217.md +0 -155
- package/templates/aitable-handoff/wiki/faq-support/09-/345/272/224/347/224/250/346/250/241/345/274/217//345/210/227/350/241/250/347/273/204/344/273/266.md +0 -228
- package/templates/aitable-handoff/wiki/faq-support/09-/345/272/224/347/224/250/346/250/241/345/274/217//345/233/276/347/211/207.md +0 -93
- package/templates/aitable-handoff/wiki/faq-support/09-/345/272/224/347/224/250/346/250/241/345/274/217//346/214/211/351/222/256.md +0 -86
- package/templates/aitable-handoff/wiki/faq-support/09-/345/272/224/347/224/250/346/250/241/345/274/217//346/240/207/347/255/276/351/241/265.md +0 -97
- package/templates/aitable-handoff/wiki/faq-support/09-/345/272/224/347/224/250/346/250/241/345/274/217//350/247/206/345/233/276/347/273/204/344/273/266.md +0 -125
- package/templates/aitable-handoff/wiki/faq-support/09-/345/272/224/347/224/250/346/250/241/345/274/217//350/277/207/346/273/244/345/231/250.md +0 -110
- package/templates/aitable-handoff/wiki/faq-support/09-/345/272/224/347/224/250/346/250/241/345/274/217//351/200/217/350/247/206/350/241/250/347/273/204/344/273/266.md +0 -142
- package/templates/aitable-handoff/wiki/faq-support/10-/350/207/252/345/212/250/345/214/226/345/267/245/344/275/234/346/265/201/Webhook/345/217/202/346/225/260/347/232/204/350/257/246/347/273/206/350/257/264/346/230/216.md +0 -76
- package/templates/aitable-handoff/wiki/faq-support/10-/350/207/252/345/212/250/345/214/226/345/267/245/344/275/234/346/265/201//344/270/200/350/241/250/344/270/200/345/217/267Agent/346/224/257/346/214/201/347/276/244/346/224/266/351/233/206.md +0 -150
- package/templates/aitable-handoff/wiki/faq-support/10-/350/207/252/345/212/250/345/214/226/345/267/245/344/275/234/346/265/201//344/275/277/347/224/250webhook/350/247/246/345/217/221/350/207/252/345/212/250/345/214/226.md +0 -163
- package/templates/aitable-handoff/wiki/faq-support/10-/350/207/252/345/212/250/345/214/226/345/267/245/344/275/234/346/265/201//344/275/277/347/224/250/344/270/215/345/220/214/350/272/253/344/273/275/345/217/221/351/200/201/351/222/211/351/222/211/346/266/210/346/201/257.md +0 -60
- package/templates/aitable-handoff/wiki/faq-support/10-/350/207/252/345/212/250/345/214/226/345/267/245/344/275/234/346/265/201//344/275/277/347/224/250/350/207/252/345/212/250/345/214/226/345/267/245/344/275/234/346/265/201.md +0 -219
- package/templates/aitable-handoff/wiki/faq-support/10-/350/207/252/345/212/250/345/214/226/345/267/245/344/275/234/346/265/201//344/275/277/347/224/250/350/207/252/345/212/250/345/214/226/345/276/252/347/216/257/350/212/202/347/202/271.md +0 -63
- package/templates/aitable-handoff/wiki/faq-support/10-/350/207/252/345/212/250/345/214/226/345/267/245/344/275/234/346/265/201//345/234/250/346/265/201/347/250/213/344/270/255/344/275/277/347/224/250AI/351/227/256/347/255/224.md +0 -69
- package/templates/aitable-handoff/wiki/faq-support/10-/350/207/252/345/212/250/345/214/226/345/267/245/344/275/234/346/265/201//345/234/250/346/266/210/346/201/257/345/215/241/347/211/207/344/270/212/346/267/273/345/212/240/346/214/211/351/222/256.md +0 -93
- package/templates/aitable-handoff/wiki/faq-support/10-/350/207/252/345/212/250/345/214/226/345/267/245/344/275/234/346/265/201//346/265/201/347/250/213/345/217/230/351/207/217/350/247/243/351/207/212/344/270/216/345/270/270/350/247/201/346/212/245/351/224/231.md +0 -158
- package/templates/aitable-handoff/wiki/faq-support/10-/350/207/252/345/212/250/345/214/226/345/267/245/344/275/234/346/265/201//346/265/201/347/250/213/350/247/246/345/217/221/346/235/241/344/273/266/344/270/216/346/211/247/350/241/214/345/212/250/344/275/234/344/270/200/350/247/210.md +0 -310
- package/templates/aitable-handoff/wiki/faq-support/10-/350/207/252/345/212/250/345/214/226/345/267/245/344/275/234/346/265/201//347/224/250AI/350/241/250/346/240/274/344/270/200/350/241/250/344/270/200/345/212/251/347/220/206/345/217/221/346/266/210/346/201/257-/350/207/252/345/212/250/345/214/226.md +0 -129
- package/templates/aitable-handoff/wiki/faq-support/10-/350/207/252/345/212/250/345/214/226/345/267/245/344/275/234/346/265/201//347/224/250/346/237/245/346/211/276/350/256/260/345/275/225/345/217/221/351/200/201/347/273/204/345/220/210/345/255/227/346/256/265/351/200/232/347/237/245.md +0 -66
- package/templates/aitable-handoff/wiki/faq-support/10-/350/207/252/345/212/250/345/214/226/345/267/245/344/275/234/346/265/201//350/207/252/345/212/250/345/214/226/345/210/233/345/273/272/351/222/211/351/222/211/345/276/205/345/212/236/346/210/226/346/227/245/347/250/213.md +0 -84
- package/templates/aitable-handoff/wiki/faq-support/10-/350/207/252/345/212/250/345/214/226/345/267/245/344/275/234/346/265/201//350/207/252/345/212/250/345/214/226/345/217/221/350/265/267AI/347/224/265/350/257/235/345/244/226/345/221/274.md +0 -322
- package/templates/aitable-handoff/wiki/faq-support/10-/350/207/252/345/212/250/345/214/226/345/267/245/344/275/234/346/265/201//350/207/252/345/212/250/345/214/226/345/217/221/350/265/267OA/345/256/241/346/211/271.md +0 -93
- package/templates/aitable-handoff/wiki/faq-support/10-/350/207/252/345/212/250/345/214/226/345/267/245/344/275/234/346/265/201//350/207/252/345/212/250/345/214/226/345/217/221/351/200/201HTTP/350/257/267/346/261/202.md +0 -168
- package/templates/aitable-handoff/wiki/faq-support/10-/350/207/252/345/212/250/345/214/226/345/267/245/344/275/234/346/265/201//350/207/252/345/212/250/345/214/226/345/270/270/350/247/201/351/227/256/351/242/230.md +0 -83
- package/templates/aitable-handoff/wiki/faq-support/10-/350/207/252/345/212/250/345/214/226/345/267/245/344/275/234/346/265/201//350/207/252/345/212/250/345/214/226/346/211/271/351/207/217/345/217/221/351/202/256/344/273/266.md +0 -79
- package/templates/aitable-handoff/wiki/faq-support/10-/350/207/252/345/212/250/345/214/226/345/267/245/344/275/234/346/265/201//350/207/252/345/212/250/345/214/226/346/224/257/346/214/201/346/217/222/345/205/245/345/223/252/344/272/233/345/217/230/351/207/217/345/206/205/345/256/271.md +0 -80
- package/templates/aitable-handoff/wiki/faq-support/10-/350/207/252/345/212/250/345/214/226/345/267/245/344/275/234/346/265/201//350/207/252/345/212/250/345/214/226/346/233/264/345/244/232/346/211/247/350/241/214/345/212/250/344/275/234/344/275/277/347/224/250/346/214/207/345/215/227.md +0 -21
- package/templates/aitable-handoff/wiki/faq-support/10-/350/207/252/345/212/250/345/214/226/345/267/245/344/275/234/346/265/201//350/260/203/347/224/250/344/270/211/346/226/271/345/267/245/344/275/234/346/265/201/345/272/224/347/224/250.md +0 -161
- package/templates/aitable-handoff/wiki/faq-support/11-AI/350/241/250/346/240/274/345/212/251/347/220/206/AI/350/241/250/346/240/274/344/270/207/350/203/275/350/264/264/344/274/230/345/205/210/344/275/277/347/224/250/347/224/263/350/257/267.md +0 -67
- package/templates/aitable-handoff/wiki/faq-support/11-AI/350/241/250/346/240/274/345/212/251/347/220/206/AI/350/241/250/346/240/274/344/270/207/350/203/275/350/264/264/344/275/277/347/224/250/350/257/264/346/230/216.md +0 -63
- package/templates/aitable-handoff/wiki/faq-support/11-AI/350/241/250/346/240/274/345/212/251/347/220/206/AI/350/241/250/346/240/274/345/212/251/347/220/206.md +0 -107
- package/templates/aitable-handoff/wiki/faq-support/12-/351/253/230/347/272/247/346/235/203/351/231/220//344/275/277/347/224/250AI/350/241/250/346/240/274/351/253/230/347/272/247/346/235/203/351/231/220.md +0 -194
- package/templates/aitable-handoff/wiki/faq-support/12-/351/253/230/347/272/247/346/235/203/351/231/220//350/241/214/345/210/227/346/235/203/351/231/220/350/256/276/347/275/256/345/217/212/351/253/230/347/272/247/346/235/203/351/231/220/345/257/271/350/241/250/345/215/225/345/205/254/345/274/217/347/232/204/345/275/261/345/223/215.md +0 -32
- package/templates/aitable-handoff/wiki/faq-support/12-/351/253/230/347/272/247/346/235/203/351/231/220//351/242/204/350/247/210/351/253/230/347/272/247/346/235/203/351/231/220/347/273/223/346/236/234.md +0 -43
- package/templates/aitable-handoff/wiki/faq-support/12-/351/253/230/347/272/247/346/235/203/351/231/220//351/253/230/347/272/247/346/235/203/351/231/220/345/270/270/350/247/201/351/227/256/351/242/230.md +0 -47
- package/templates/aitable-handoff/wiki/faq-support/12-/351/253/230/347/272/247/346/235/203/351/231/220//351/253/230/347/272/247/346/235/203/351/231/220/347/232/204/351/273/230/350/256/244/350/247/222/350/211/262.md +0 -36
- package/templates/aitable-handoff/wiki/faq-support/13-/346/217/222/344/273/266/344/270/255/345/277/203/AI/350/241/250/346/240/274/344/270/211/346/226/271/346/217/222/344/273/266/344/275/277/347/224/250/346/216/210/346/235/203.md +0 -19
- package/templates/aitable-handoff/wiki/faq-support/13-/346/217/222/344/273/266/344/270/255/345/277/203/AI/350/241/250/346/240/274/346/217/222/344/273/266-/350/204/232/346/234/254/346/217/222/344/273/266.md +0 -42
- package/templates/aitable-handoff/wiki/faq-support/13-/346/217/222/344/273/266/344/270/255/345/277/203/AI/350/241/250/346/240/274/346/217/222/344/273/266-/350/207/252/345/256/232/344/271/211/346/217/222/344/273/266.md +0 -51
- package/templates/aitable-handoff/wiki/faq-support/13-/346/217/222/344/273/266/344/270/255/345/277/203/AI/350/241/250/346/240/274/346/217/222/344/273/266/344/270/255/345/277/203-/344/275/277/347/224/250/346/214/207/345/215/227.md +0 -97
- package/templates/aitable-handoff/wiki/faq-support/14-/347/256/241/347/220/206/345/220/216/345/217/260//344/275/277/347/224/250/346/225/260/346/215/256/350/257/264/346/230/216.md +0 -82
- package/templates/aitable-handoff/wiki/faq-support/14-/347/256/241/347/220/206/345/220/216/345/217/260//346/235/203/347/233/212/346/225/260/346/215/256/350/257/264/346/230/216.md +0 -111
- package/templates/aitable-handoff/wiki/faq-support/15-/345/234/272/346/231/257/345/256/236/350/267/265/AI/350/241/250/346/240/274/350/257/257/345/210/240/346/201/242/345/244/215/346/214/207/345/215/227.md +0 -37
- package/templates/aitable-handoff/wiki/faq-support/15-/345/234/272/346/231/257/345/256/236/350/267/265//345/234/250/350/241/250/346/240/274/344/270/255/346/240/207/350/256/260/351/207/215/345/244/215/345/206/205/345/256/271.md +0 -43
- package/templates/aitable-handoff/wiki/faq-support/15-/345/234/272/346/231/257/345/256/236/350/267/265//347/233/264/346/222/255/345/205/254/345/274/200/347/263/273/345/210/227/350/257/276.md +0 -21
- package/templates/aitable-handoff/wiki/faq-support/16-/344/273/230/350/264/271/346/235/203/347/233/212//351/222/211/351/222/211AI/350/241/250/346/240/274/344/273/230/350/264/271/346/235/203/347/233/212.md +0 -144
- package/templates/aitable-handoff/wiki/faq-support/16-/344/273/230/350/264/271/346/235/203/347/233/212//351/222/211/351/222/211AI/350/241/250/346/240/274/346/220/255/345/273/272/346/234/215/345/212/241.md +0 -95
- package/templates/aitable-handoff/wiki/faq-support/17-/345/205/254/345/221/212/AI/350/241/250/346/240/274-/346/216/222/347/211/210/346/211/223/345/215/260/345/215/207/347/272/247/350/257/264/346/230/216.md +0 -40
- package/templates/aitable-handoff/wiki/faq-support/17-/345/205/254/345/221/212/AI/350/241/250/346/240/274-/347/211/210/346/234/254/345/215/207/347/272/247/351/200/232/347/237/245.md +0 -21
- package/templates/aitable-handoff/wiki/faq-support/17-/345/205/254/345/221/212//350/267/250AI/350/241/250/346/240/274/346/225/260/346/215/256/345/220/214/346/255/245/350/260/203/346/225/264/350/257/264/346/230/216.md +0 -55
- package/templates/aitable-handoff/wiki/faq-support/18-/345/274/200/345/217/221/350/200/205/346/214/207/345/215/227/AI /350/241/250/346/240/274/346/217/222/344/273/266 - /344/274/201/344/270/232/345/206/205/346/217/222/344/273/266/345/217/221/345/270/203/346/214/207/345/215/227.md" +0 -159
- package/templates/aitable-handoff/wiki/faq-support/18-/345/274/200/345/217/221/350/200/205/346/214/207/345/215/227/AI/350/241/250/346/240/274 AI /345/255/227/346/256/265 /345/274/200/345/217/221/346/214/207/345/215/227/AI/350/241/250/346/240/274 AI /345/255/227/346/256/265/345/274/200/345/217/221/346/214/207/345/215/227/357/274/210FaaS/347/211/210/357/274/211.md" +0 -1362
- package/templates/aitable-handoff/wiki/faq-support/18-/345/274/200/345/217/221/350/200/205/346/214/207/345/215/227/AI/350/241/250/346/240/274 AI /345/255/227/346/256/265 /345/274/200/345/217/221/346/214/207/345/215/227/AI/350/241/250/346/240/274 AI /345/255/227/346/256/265/345/274/200/345/217/221/346/214/207/345/215/227/357/274/210/345/205/254/345/274/217/347/211/210/357/274/211.md" +0 -556
- package/templates/aitable-handoff/wiki/faq-support/18-/345/274/200/345/217/221/350/200/205/346/214/207/345/215/227/AI/350/241/250/346/240/274 AI /345/255/227/346/256/265 /345/274/200/345/217/221/346/214/207/345/215/227.md" +0 -15
- package/templates/aitable-handoff/wiki/faq-support/18-/345/274/200/345/217/221/350/200/205/346/214/207/345/215/227/AI/350/241/250/346/240/274/345/255/227/346/256/265/346/250/241/347/211/210 /344/275/277/347/224/250/346/214/207/345/215/227/AI /350/241/250/346/240/274 AI /345/255/227/346/256/265/345/270/270/350/247/201/346/212/245/351/224/231/350/257/264/346/230/216.md" +0 -649
- package/templates/aitable-handoff/wiki/faq-support/18-/345/274/200/345/217/221/350/200/205/346/214/207/345/215/227/AI/350/241/250/346/240/274/345/255/227/346/256/265/346/250/241/347/211/210 /344/275/277/347/224/250/346/214/207/345/215/227/Dify/346/231/272/350/203/275/344/275/223.md" +0 -55
- package/templates/aitable-handoff/wiki/faq-support/18-/345/274/200/345/217/221/350/200/205/346/214/207/345/215/227/AI/350/241/250/346/240/274/345/255/227/346/256/265/346/250/241/347/211/210 /344/275/277/347/224/250/346/214/207/345/215/227/GPTPro /345/255/227/346/256/265/346/215/267/345/276/204 /345/257/206/351/222/245/350/216/267/345/217/226/346/214/207/345/215/227.md" +0 -23
- package/templates/aitable-handoff/wiki/faq-support/18-/345/274/200/345/217/221/350/200/205/346/214/207/345/215/227/AI/350/241/250/346/240/274/345/255/227/346/256/265/346/250/241/347/211/210 /344/275/277/347/224/250/346/214/207/345/215/227/OpenClaw /345/260/217/351/276/231/350/231/276/345/212/251/346/211/213/351/205/215/347/275/256/346/225/231/347/250/213.md" +0 -27
- package/templates/aitable-handoff/wiki/faq-support/18-/345/274/200/345/217/221/350/200/205/346/214/207/345/215/227/AI/350/241/250/346/240/274/345/255/227/346/256/265/346/250/241/347/211/210 /344/275/277/347/224/250/346/214/207/345/215/227//345/233/275/345/206/205/345/244/226/345/277/253/351/200/222/347/211/251/346/265/201/344/277/241/346/201/257/346/237/245/350/257/242/344/275/277/347/224/250/346/214/207/345/215/227.md" +0 -907
- package/templates/aitable-handoff/wiki/faq-support/18-/345/274/200/345/217/221/350/200/205/346/214/207/345/215/227/AI/350/241/250/346/240/274/345/255/227/346/256/265/346/250/241/347/211/210 /344/275/277/347/224/250/346/214/207/345/215/227//345/277/253/351/200/222/347/211/251/346/265/201/346/237/245/350/257/242/345/212/251/346/211/213/344/275/277/347/224/250/346/214/207/345/215/227.md" +0 -1
- package/templates/aitable-handoff/wiki/faq-support/18-/345/274/200/345/217/221/350/200/205/346/214/207/345/215/227/AI/350/241/250/346/240/274/345/257/271/350/261/241/346/250/241/345/236/213API/345/217/202/350/200/203/346/226/207/346/241/243/AI/350/241/250/346/240/274JSAPI /347/261/273/345/236/213/346/217/217/350/277/260.xlsx +0 -0
- package/templates/aitable-handoff/wiki/faq-support/18-/345/274/200/345/217/221/350/200/205/346/214/207/345/215/227/AI/350/241/250/346/240/274/345/257/271/350/261/241/346/250/241/345/236/213API/345/217/202/350/200/203/346/226/207/346/241/243/Base /346/250/241/345/235/227.md" +0 -391
- package/templates/aitable-handoff/wiki/faq-support/18-/345/274/200/345/217/221/350/200/205/346/214/207/345/215/227/AI/350/241/250/346/240/274/345/257/271/350/261/241/346/250/241/345/236/213API/345/217/202/350/200/203/346/226/207/346/241/243/Field /346/250/241/345/235/227/AttachmentField /351/231/204/344/273/266/345/255/227/346/256/265.md" +0 -200
- package/templates/aitable-handoff/wiki/faq-support/18-/345/274/200/345/217/221/350/200/205/346/214/207/345/215/227/AI/350/241/250/346/240/274/345/257/271/350/261/241/346/250/241/345/236/213API/345/217/202/350/200/203/346/226/207/346/241/243/Field /346/250/241/345/235/227/AutoNumberField /350/207/252/345/212/250/347/274/226/345/217/267/345/255/227/346/256/265.md" +0 -75
- package/templates/aitable-handoff/wiki/faq-support/18-/345/274/200/345/217/221/350/200/205/346/214/207/345/215/227/AI/350/241/250/346/240/274/345/257/271/350/261/241/346/250/241/345/236/213API/345/217/202/350/200/203/346/226/207/346/241/243/Field /346/250/241/345/235/227/BarcodeField /346/235/241/347/240/201/345/255/227/346/256/265.md" +0 -95
- package/templates/aitable-handoff/wiki/faq-support/18-/345/274/200/345/217/221/350/200/205/346/214/207/345/215/227/AI/350/241/250/346/240/274/345/257/271/350/261/241/346/250/241/345/236/213API/345/217/202/350/200/203/346/226/207/346/241/243/Field /346/250/241/345/235/227/BidirectionalLinkField /345/217/214/345/220/221/345/205/263/350/201/224/345/255/227/346/256/265.md" +0 -294
- package/templates/aitable-handoff/wiki/faq-support/18-/345/274/200/345/217/221/350/200/205/346/214/207/345/215/227/AI/350/241/250/346/240/274/345/257/271/350/261/241/346/250/241/345/236/213API/345/217/202/350/200/203/346/226/207/346/241/243/Field /346/250/241/345/235/227/CheckboxField /345/244/215/351/200/211/346/241/206/345/255/227/346/256/265.md" +0 -95
- package/templates/aitable-handoff/wiki/faq-support/18-/345/274/200/345/217/221/350/200/205/346/214/207/345/215/227/AI/350/241/250/346/240/274/345/257/271/350/261/241/346/250/241/345/236/213API/345/217/202/350/200/203/346/226/207/346/241/243/Field /346/250/241/345/235/227/CreatedTimeField /345/210/233/345/273/272/346/227/266/351/227/264/345/255/227/346/256/265.md" +0 -134
- package/templates/aitable-handoff/wiki/faq-support/18-/345/274/200/345/217/221/350/200/205/346/214/207/345/215/227/AI/350/241/250/346/240/274/345/257/271/350/261/241/346/250/241/345/236/213API/345/217/202/350/200/203/346/226/207/346/241/243/Field /346/250/241/345/235/227/CurrencyField /350/264/247/345/270/201/345/255/227/346/256/265.md" +0 -260
- package/templates/aitable-handoff/wiki/faq-support/18-/345/274/200/345/217/221/350/200/205/346/214/207/345/215/227/AI/350/241/250/346/240/274/345/257/271/350/261/241/346/250/241/345/236/213API/345/217/202/350/200/203/346/226/207/346/241/243/Field /346/250/241/345/235/227/DateField /346/227/245/346/234/237/345/255/227/346/256/265.md" +0 -183
- package/templates/aitable-handoff/wiki/faq-support/18-/345/274/200/345/217/221/350/200/205/346/214/207/345/215/227/AI/350/241/250/346/240/274/345/257/271/350/261/241/346/250/241/345/236/213API/345/217/202/350/200/203/346/226/207/346/241/243/Field /346/250/241/345/235/227/DepartmentField /351/203/250/351/227/250/345/255/227/346/256/265.md" +0 -111
- package/templates/aitable-handoff/wiki/faq-support/18-/345/274/200/345/217/221/350/200/205/346/214/207/345/215/227/AI/350/241/250/346/240/274/345/257/271/350/261/241/346/250/241/345/236/213API/345/217/202/350/200/203/346/226/207/346/241/243/Field /346/250/241/345/235/227/EmailField /351/202/256/347/256/261/345/255/227/346/256/265.md" +0 -99
- package/templates/aitable-handoff/wiki/faq-support/18-/345/274/200/345/217/221/350/200/205/346/214/207/345/215/227/AI/350/241/250/346/240/274/345/257/271/350/261/241/346/250/241/345/236/213API/345/217/202/350/200/203/346/226/207/346/241/243/Field /346/250/241/345/235/227/FilterUpField /346/237/245/346/211/276/345/274/225/347/224/250/345/255/227/346/256/265.md" +0 -73
- package/templates/aitable-handoff/wiki/faq-support/18-/345/274/200/345/217/221/350/200/205/346/214/207/345/215/227/AI/350/241/250/346/240/274/345/257/271/350/261/241/346/250/241/345/236/213API/345/217/202/350/200/203/346/226/207/346/241/243/Field /346/250/241/345/235/227/FormulaField /345/205/254/345/274/217/345/255/227/346/256/265.md" +0 -109
- package/templates/aitable-handoff/wiki/faq-support/18-/345/274/200/345/217/221/350/200/205/346/214/207/345/215/227/AI/350/241/250/346/240/274/345/257/271/350/261/241/346/250/241/345/236/213API/345/217/202/350/200/203/346/226/207/346/241/243/Field /346/250/241/345/235/227/GeoLocationField /345/234/260/347/220/206/344/275/215/347/275/256/345/255/227/346/256/265.md" +0 -33
- package/templates/aitable-handoff/wiki/faq-support/18-/345/274/200/345/217/221/350/200/205/346/214/207/345/215/227/AI/350/241/250/346/240/274/345/257/271/350/261/241/346/250/241/345/236/213API/345/217/202/350/200/203/346/226/207/346/241/243/Field /346/250/241/345/235/227/GroupField /347/276/244/347/273/204/345/255/227/346/256/265.md" +0 -111
- package/templates/aitable-handoff/wiki/faq-support/18-/345/274/200/345/217/221/350/200/205/346/214/207/345/215/227/AI/350/241/250/346/240/274/345/257/271/350/261/241/346/250/241/345/236/213API/345/217/202/350/200/203/346/226/207/346/241/243/Field /346/250/241/345/235/227/LastModifiedTimeField /346/234/200/345/220/216/346/233/264/346/226/260/346/227/266/351/227/264/345/255/227/346/256/265.md" +0 -134
- package/templates/aitable-handoff/wiki/faq-support/18-/345/274/200/345/217/221/350/200/205/346/214/207/345/215/227/AI/350/241/250/346/240/274/345/257/271/350/261/241/346/250/241/345/236/213API/345/217/202/350/200/203/346/226/207/346/241/243/Field /346/250/241/345/235/227/LookupField /345/205/263/350/201/224/345/274/225/347/224/250/345/255/227/346/256/265.md" +0 -71
- package/templates/aitable-handoff/wiki/faq-support/18-/345/274/200/345/217/221/350/200/205/346/214/207/345/215/227/AI/350/241/250/346/240/274/345/257/271/350/261/241/346/250/241/345/236/213API/345/217/202/350/200/203/346/226/207/346/241/243/Field /346/250/241/345/235/227/MultiSelectField /345/244/232/351/200/211/345/255/227/346/256/265.md" +0 -349
- package/templates/aitable-handoff/wiki/faq-support/18-/345/274/200/345/217/221/350/200/205/346/214/207/345/215/227/AI/350/241/250/346/240/274/345/257/271/350/261/241/346/250/241/345/236/213API/345/217/202/350/200/203/346/226/207/346/241/243/Field /346/250/241/345/235/227/NumberField /346/225/260/345/255/227/345/255/227/346/256/265.md" +0 -175
- package/templates/aitable-handoff/wiki/faq-support/18-/345/274/200/345/217/221/350/200/205/346/214/207/345/215/227/AI/350/241/250/346/240/274/345/257/271/350/261/241/346/250/241/345/236/213API/345/217/202/350/200/203/346/226/207/346/241/243/Field /346/250/241/345/235/227/PrimaryField /344/270/273/351/224/256/346/226/207/346/241/243/345/255/227/346/256/265.md" +0 -91
- package/templates/aitable-handoff/wiki/faq-support/18-/345/274/200/345/217/221/350/200/205/346/214/207/345/215/227/AI/350/241/250/346/240/274/345/257/271/350/261/241/346/250/241/345/236/213API/345/217/202/350/200/203/346/226/207/346/241/243/Field /346/250/241/345/235/227/ProgressField /350/277/233/345/272/246/345/255/227/346/256/265.md" +0 -324
- package/templates/aitable-handoff/wiki/faq-support/18-/345/274/200/345/217/221/350/200/205/346/214/207/345/215/227/AI/350/241/250/346/240/274/345/257/271/350/261/241/346/250/241/345/236/213API/345/217/202/350/200/203/346/226/207/346/241/243/Field /346/250/241/345/235/227/RatingField /350/257/204/345/210/206/345/255/227/346/256/265.md" +0 -320
- package/templates/aitable-handoff/wiki/faq-support/18-/345/274/200/345/217/221/350/200/205/346/214/207/345/215/227/AI/350/241/250/346/240/274/345/257/271/350/261/241/346/250/241/345/236/213API/345/217/202/350/200/203/346/226/207/346/241/243/Field /346/250/241/345/235/227/RichTextField /345/257/214/346/226/207/346/234/254/345/255/227/346/256/265.md" +0 -45
- package/templates/aitable-handoff/wiki/faq-support/18-/345/274/200/345/217/221/350/200/205/346/214/207/345/215/227/AI/350/241/250/346/240/274/345/257/271/350/261/241/346/250/241/345/236/213API/345/217/202/350/200/203/346/226/207/346/241/243/Field /346/250/241/345/235/227/SingleSelectField /345/215/225/351/200/211/345/255/227/346/256/265.md" +0 -336
- package/templates/aitable-handoff/wiki/faq-support/18-/345/274/200/345/217/221/350/200/205/346/214/207/345/215/227/AI/350/241/250/346/240/274/345/257/271/350/261/241/346/250/241/345/236/213API/345/217/202/350/200/203/346/226/207/346/241/243/Field /346/250/241/345/235/227/TelephoneField /347/224/265/350/257/235/345/255/227/346/256/265.md" +0 -99
- package/templates/aitable-handoff/wiki/faq-support/18-/345/274/200/345/217/221/350/200/205/346/214/207/345/215/227/AI/350/241/250/346/240/274/345/257/271/350/261/241/346/250/241/345/236/213API/345/217/202/350/200/203/346/226/207/346/241/243/Field /346/250/241/345/235/227/TextField /346/226/207/346/234/254/345/255/227/346/256/265.md" +0 -93
- package/templates/aitable-handoff/wiki/faq-support/18-/345/274/200/345/217/221/350/200/205/346/214/207/345/215/227/AI/350/241/250/346/240/274/345/257/271/350/261/241/346/250/241/345/236/213API/345/217/202/350/200/203/346/226/207/346/241/243/Field /346/250/241/345/235/227/UnidirectionalLinkFields /345/215/225/345/220/221/345/205/263/350/201/224/345/255/227/346/256/265.md" +0 -295
- package/templates/aitable-handoff/wiki/faq-support/18-/345/274/200/345/217/221/350/200/205/346/214/207/345/215/227/AI/350/241/250/346/240/274/345/257/271/350/261/241/346/250/241/345/236/213API/345/217/202/350/200/203/346/226/207/346/241/243/Field /346/250/241/345/235/227/UrlField /351/223/276/346/216/245/345/255/227/346/256/265.md" +0 -163
- package/templates/aitable-handoff/wiki/faq-support/18-/345/274/200/345/217/221/350/200/205/346/214/207/345/215/227/AI/350/241/250/346/240/274/345/257/271/350/261/241/346/250/241/345/236/213API/345/217/202/350/200/203/346/226/207/346/241/243/Field /346/250/241/345/235/227/UserField /344/272/272/345/221/230/345/255/227/346/256/265.md" +0 -266
- package/templates/aitable-handoff/wiki/faq-support/18-/345/274/200/345/217/221/350/200/205/346/214/207/345/215/227/AI/350/241/250/346/240/274/345/257/271/350/261/241/346/250/241/345/236/213API/345/217/202/350/200/203/346/226/207/346/241/243/Field /346/250/241/345/235/227.md" +0 -379
- package/templates/aitable-handoff/wiki/faq-support/18-/345/274/200/345/217/221/350/200/205/346/214/207/345/215/227/AI/350/241/250/346/240/274/345/257/271/350/261/241/346/250/241/345/236/213API/345/217/202/350/200/203/346/226/207/346/241/243/Record /346/250/241/345/235/227.md" +0 -277
- package/templates/aitable-handoff/wiki/faq-support/18-/345/274/200/345/217/221/350/200/205/346/214/207/345/215/227/AI/350/241/250/346/240/274/345/257/271/350/261/241/346/250/241/345/236/213API/345/217/202/350/200/203/346/226/207/346/241/243/Sheet /346/250/241/345/235/227.md" +0 -1013
- package/templates/aitable-handoff/wiki/faq-support/18-/345/274/200/345/217/221/350/200/205/346/214/207/345/215/227/AI/350/241/250/346/240/274/345/257/271/350/261/241/346/250/241/345/236/213API/345/217/202/350/200/203/346/226/207/346/241/243/UI /346/250/241/345/235/227.md" +0 -472
- package/templates/aitable-handoff/wiki/faq-support/18-/345/274/200/345/217/221/350/200/205/346/214/207/345/215/227/AI/350/241/250/346/240/274/345/257/271/350/261/241/346/250/241/345/236/213API/345/217/202/350/200/203/346/226/207/346/241/243/View /346/250/241/345/235/227/GridView /350/241/250/346/240/274/350/247/206/345/233/276.md" +0 -835
- package/templates/aitable-handoff/wiki/faq-support/18-/345/274/200/345/217/221/350/200/205/346/214/207/345/215/227/AI/350/241/250/346/240/274/345/257/271/350/261/241/346/250/241/345/236/213API/345/217/202/350/200/203/346/226/207/346/241/243/View /346/250/241/345/235/227.md" +0 -203
- package/templates/aitable-handoff/wiki/faq-support/18-/345/274/200/345/217/221/350/200/205/346/214/207/345/215/227/AI/350/241/250/346/240/274/345/257/271/350/261/241/346/250/241/345/236/213API/345/217/202/350/200/203/346/226/207/346/241/243//345/255/227/346/256/265/346/225/260/346/215/256/347/273/223/346/236/204.md +0 -65
- package/templates/aitable-handoff/wiki/faq-support/18-/345/274/200/345/217/221/350/200/205/346/214/207/345/215/227/AI/350/241/250/346/240/274/345/257/271/350/261/241/346/250/241/345/236/213API/345/217/202/350/200/203/346/226/207/346/241/243//350/257/273/345/206/231AI /350/241/250/346/240/274/346/250/241/345/236/213.md" +0 -29
- package/templates/aitable-handoff/wiki/faq-support/18-/345/274/200/345/217/221/350/200/205/346/214/207/345/215/227/AI/350/241/250/346/240/274/346/225/260/346/215/256/346/272/220 /345/274/200/345/217/221/346/214/207/345/215/227.md" +0 -607
- package/templates/aitable-handoff/wiki/faq-support/18-/345/274/200/345/217/221/350/200/205/346/214/207/345/215/227/AI/350/241/250/346/240/274/350/204/232/346/234/254/346/217/222/344/273/266 /345/274/200/345/217/221/346/214/207/345/215/227/Base /346/250/241/345/235/227.md" +0 -391
- package/templates/aitable-handoff/wiki/faq-support/18-/345/274/200/345/217/221/350/200/205/346/214/207/345/215/227/AI/350/241/250/346/240/274/350/204/232/346/234/254/346/217/222/344/273/266 /345/274/200/345/217/221/346/214/207/345/215/227/Field /346/250/241/345/235/227.md" +0 -379
- package/templates/aitable-handoff/wiki/faq-support/18-/345/274/200/345/217/221/350/200/205/346/214/207/345/215/227/AI/350/241/250/346/240/274/350/204/232/346/234/254/346/217/222/344/273/266 /345/274/200/345/217/221/346/214/207/345/215/227/Input/346/250/241/345/235/227.md" +0 -331
- package/templates/aitable-handoff/wiki/faq-support/18-/345/274/200/345/217/221/350/200/205/346/214/207/345/215/227/AI/350/241/250/346/240/274/350/204/232/346/234/254/346/217/222/344/273/266 /345/274/200/345/217/221/346/214/207/345/215/227/Output/346/250/241/345/235/227.md" +0 -197
- package/templates/aitable-handoff/wiki/faq-support/18-/345/274/200/345/217/221/350/200/205/346/214/207/345/215/227/AI/350/241/250/346/240/274/350/204/232/346/234/254/346/217/222/344/273/266 /345/274/200/345/217/221/346/214/207/345/215/227/Record /346/250/241/345/235/227.md" +0 -277
- package/templates/aitable-handoff/wiki/faq-support/18-/345/274/200/345/217/221/350/200/205/346/214/207/345/215/227/AI/350/241/250/346/240/274/350/204/232/346/234/254/346/217/222/344/273/266 /345/274/200/345/217/221/346/214/207/345/215/227/Sheet /346/250/241/345/235/227.md" +0 -1013
- package/templates/aitable-handoff/wiki/faq-support/18-/345/274/200/345/217/221/350/200/205/346/214/207/345/215/227/AI/350/241/250/346/240/274/350/204/232/346/234/254/346/217/222/344/273/266 /345/274/200/345/217/221/346/214/207/345/215/227/UI /346/250/241/345/235/227.md" +0 -472
- package/templates/aitable-handoff/wiki/faq-support/18-/345/274/200/345/217/221/350/200/205/346/214/207/345/215/227/AI/350/241/250/346/240/274/350/204/232/346/234/254/346/217/222/344/273/266 /345/274/200/345/217/221/346/214/207/345/215/227/View /346/250/241/345/235/227.md" +0 -203
- package/templates/aitable-handoff/wiki/faq-support/18-/345/274/200/345/217/221/350/200/205/346/214/207/345/215/227/AI/350/241/250/346/240/274/350/204/232/346/234/254/346/217/222/344/273/266 /345/274/200/345/217/221/346/214/207/345/215/227//345/255/227/346/256/265/346/225/260/346/215/256/347/273/223/346/236/204.md" +0 -65
- package/templates/aitable-handoff/wiki/faq-support/18-/345/274/200/345/217/221/350/200/205/346/214/207/345/215/227/AI/350/241/250/346/240/274/350/204/232/346/234/254/346/217/222/344/273/266 /345/274/200/345/217/221/346/214/207/345/215/227.md" +0 -142
- package/templates/aitable-handoff/wiki/faq-support/18-/345/274/200/345/217/221/350/200/205/346/214/207/345/215/227/AI/350/241/250/346/240/274/350/276/271/346/240/217/346/217/222/344/273/266 /345/274/200/345/217/221/346/214/207/345/215/227/Base /346/250/241/345/235/227.md" +0 -391
- package/templates/aitable-handoff/wiki/faq-support/18-/345/274/200/345/217/221/350/200/205/346/214/207/345/215/227/AI/350/241/250/346/240/274/350/276/271/346/240/217/346/217/222/344/273/266 /345/274/200/345/217/221/346/214/207/345/215/227/Event/344/272/213/344/273/266/346/250/241/345/235/227.md" +0 -182
- package/templates/aitable-handoff/wiki/faq-support/18-/345/274/200/345/217/221/350/200/205/346/214/207/345/215/227/AI/350/241/250/346/240/274/350/276/271/346/240/217/346/217/222/344/273/266 /345/274/200/345/217/221/346/214/207/345/215/227/Field /346/250/241/345/235/227.md" +0 -379
- package/templates/aitable-handoff/wiki/faq-support/18-/345/274/200/345/217/221/350/200/205/346/214/207/345/215/227/AI/350/241/250/346/240/274/350/276/271/346/240/217/346/217/222/344/273/266 /345/274/200/345/217/221/346/214/207/345/215/227/Record /346/250/241/345/235/227.md" +0 -277
- package/templates/aitable-handoff/wiki/faq-support/18-/345/274/200/345/217/221/350/200/205/346/214/207/345/215/227/AI/350/241/250/346/240/274/350/276/271/346/240/217/346/217/222/344/273/266 /345/274/200/345/217/221/346/214/207/345/215/227/Sheet /346/250/241/345/235/227.md" +0 -1013
- package/templates/aitable-handoff/wiki/faq-support/18-/345/274/200/345/217/221/350/200/205/346/214/207/345/215/227/AI/350/241/250/346/240/274/350/276/271/346/240/217/346/217/222/344/273/266 /345/274/200/345/217/221/346/214/207/345/215/227/UI /346/250/241/345/235/227.md" +0 -472
- package/templates/aitable-handoff/wiki/faq-support/18-/345/274/200/345/217/221/350/200/205/346/214/207/345/215/227/AI/350/241/250/346/240/274/350/276/271/346/240/217/346/217/222/344/273/266 /345/274/200/345/217/221/346/214/207/345/215/227/View /346/250/241/345/235/227.md" +0 -203
- package/templates/aitable-handoff/wiki/faq-support/18-/345/274/200/345/217/221/350/200/205/346/214/207/345/215/227/AI/350/241/250/346/240/274/350/276/271/346/240/217/346/217/222/344/273/266 /345/274/200/345/217/221/346/214/207/345/215/227//345/205/266/344/273/226/346/216/245/345/217/243.md" +0 -146
- package/templates/aitable-handoff/wiki/faq-support/18-/345/274/200/345/217/221/350/200/205/346/214/207/345/215/227/AI/350/241/250/346/240/274/350/276/271/346/240/217/346/217/222/344/273/266 /345/274/200/345/217/221/346/214/207/345/215/227//345/255/227/346/256/265/346/225/260/346/215/256/347/273/223/346/236/204.md" +0 -65
- package/templates/aitable-handoff/wiki/faq-support/18-/345/274/200/345/217/221/350/200/205/346/214/207/345/215/227/AI/350/241/250/346/240/274/350/276/271/346/240/217/346/217/222/344/273/266 /345/274/200/345/217/221/346/214/207/345/215/227//346/240/270/345/277/203/347/237/245/350/257/206.md" +0 -54
- package/templates/aitable-handoff/wiki/faq-support/18-/345/274/200/345/217/221/350/200/205/346/214/207/345/215/227/AI/350/241/250/346/240/274/350/276/271/346/240/217/346/217/222/344/273/266 /345/274/200/345/217/221/346/214/207/345/215/227.md" +0 -192
- package/templates/aitable-handoff/wiki/faq-support//351/222/211/351/222/211AI/350/241/250/346/240/274FAQ.md +0 -611
- package/templates/aitable-handoff/workflows/admin-kb-update/recipes/kb-refine.recipe.ts +0 -131
- package/templates/aitable-handoff/workflows/admin-kb-update/recipes/kb_sync_handler.recipe.ts +0 -130
- package/templates/aitable-handoff/workflows/admin-kb-update/workflow.yml +0 -125
- package/templates/aitable-handoff/workflows/config-sync/recipes/config_sync.recipe.ts +0 -448
- package/templates/aitable-handoff/workflows/config-sync/recipes/config_sync_handler.recipe.ts +0 -16
- package/templates/aitable-handoff/workflows/config-sync/workflow.yml +0 -73
- package/templates/aitable-handoff/workflows/daily-review/recipes/daily_review.recipe.ts +0 -529
- package/templates/aitable-handoff/workflows/daily-review/recipes/daily_review_handler.recipe.ts +0 -26
- package/templates/aitable-handoff/workflows/daily-review/recipes/memory-events.ts +0 -56
- package/templates/aitable-handoff/workflows/daily-review/workflow.yml +0 -92
- package/templates/aitable-handoff/workflows/group-qa/error-replies.json +0 -53
- package/templates/aitable-handoff/workflows/group-qa/recipes/answer.recipe.ts +0 -197
- package/templates/aitable-handoff/workflows/group-qa/recipes/conversation_handler.recipe.ts +0 -294
- package/templates/aitable-handoff/workflows/group-qa/recipes/issue-classifier.ts +0 -120
- package/templates/aitable-handoff/workflows/group-qa/recipes/known-error-match.recipe.ts +0 -75
- package/templates/aitable-handoff/workflows/group-qa/recipes/memory-events.ts +0 -55
- package/templates/aitable-handoff/workflows/group-qa/recipes/reply-to-group.recipe.ts +0 -132
- package/templates/aitable-handoff/workflows/group-qa/recipes/troubleshoot-issue.recipe.ts +0 -195
- package/templates/aitable-handoff/workflows/group-qa/workflow.yml +0 -210
- package/templates/aitable-handoff/workspaces/daily-review/AGENTS.md +0 -189
- package/templates/aitable-handoff/workspaces/faq-support/AGENTS.md +0 -448
- package/templates/aitable-handoff/workspaces/faq-support/contacts.json +0 -14
- package/templates/aitable-handoff/workspaces/faq-support/owner-map.json +0 -18
- package/templates/aitable-handoff/workspaces/faq-support/skills/bug-triage/SKILL.md +0 -130
- package/templates/aitable-handoff/workspaces/faq-troubleshooter/AGENTS.md +0 -53
- package/templates/aitable-handoff/workspaces/faq-troubleshooter/skills/troubleshooting/SKILL.md +0 -58
- package/templates/aitable-handoff/workspaces/faq-troubleshooter/skills/troubleshooting/aitable-import-troubleshooter/SKILL.md +0 -485
- package/templates/aitable-handoff/workspaces/faq-troubleshooter/skills/troubleshooting/aitable-openapi-troubleshooter/SKILL.md +0 -183
- package/templates/aitable-handoff/workspaces/faq-troubleshooter/skills/troubleshooting/import-openapi-e2e-troubleshooter/SKILL.md +0 -459
- package/templates/aitable-handoff/workspaces/faq-troubleshooter/skills/troubleshooting/notable-datasource-troubleshooter/SKILL.md +0 -1286
- package/templates/aitable-handoff/workspaces/faq-troubleshooter/skills/troubleshooting/notable-field-troubleshooter/SKILL.md +0 -673
- package/templates/aitable-handoff/workspaces/faq-troubleshooter/skills/troubleshooting/spreadsheet-datasync-troubleshooter/SKILL.md +0 -322
- package/templates/aitable-handoff/workspaces/kb-editor/AGENTS.md +0 -32
- package/templates/support-qa/lib/assemble-cli.ts +0 -30
- package/templates/support-qa/lib/assemble.ts +0 -279
- package/templates/support-qa/lib/echo-guard.ts +0 -50
- package/templates/support-qa/lib/fastpath.ts +0 -227
- package/templates/support-qa/lib/owner-mention.ts +0 -140
- package/templates/support-qa/lib/profile-guard.ts +0 -55
- package/templates/support-qa/lib/send-failure-guard.ts +0 -59
- package/templates/support-qa/lib/troubleshoot.ts +0 -236
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "aitable-workflow-cli",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.16-beta.1786022310508",
|
|
4
4
|
"description": "aitable-workflow 命令行工具(cli):init/design/setup/run/serve 等命令;含 relay 本地反连客户端与 daemon 进程管理。bin: aitable-workflow。",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -19,8 +19,8 @@
|
|
|
19
19
|
"access": "public"
|
|
20
20
|
},
|
|
21
21
|
"dependencies": {
|
|
22
|
-
"aitable-workflow-core": "0.1.
|
|
23
|
-
"aitable-workflow-server": "0.1.
|
|
22
|
+
"aitable-workflow-core": "0.1.16-beta.1786022310508",
|
|
23
|
+
"aitable-workflow-server": "0.1.16-beta.1786022310508",
|
|
24
24
|
"@inquirer/prompts": "^8.5.2",
|
|
25
25
|
"commander": "^14.0.2",
|
|
26
26
|
"dotenv": "^17.4.2",
|
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 声明式规则匹配引擎(support-qa/lib/declarative-matcher)
|
|
3
|
+
*
|
|
4
|
+
* 断言逐条沿用迁移前的用例,锁死四条硬不变量:
|
|
5
|
+
* 单向匹配 / 只看用户本轮新话(剥离引用块)/ safety 看全文 / 优雅关闭。
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { describe, it, expect, beforeEach, afterEach } from "vitest";
|
|
9
|
+
import { mkdtemp, mkdir, writeFile, rm } from "node:fs/promises";
|
|
10
|
+
import path from "node:path";
|
|
11
|
+
import os from "node:os";
|
|
12
|
+
import {
|
|
13
|
+
loadReplyRules,
|
|
14
|
+
matchReplyRules,
|
|
15
|
+
stripQuotedBlock,
|
|
16
|
+
loadClassifierRules,
|
|
17
|
+
classifyMessage,
|
|
18
|
+
isCapabilityEnabled,
|
|
19
|
+
isGroupToggleEnabled,
|
|
20
|
+
} from "../declarative-matcher.js";
|
|
21
|
+
|
|
22
|
+
describe("loadReplyRules / matchReplyRules:声明式秒回规则 + 单向匹配 + 安全兜底", () => {
|
|
23
|
+
let dir: string;
|
|
24
|
+
beforeEach(async () => { dir = await mkdtemp(path.join(os.tmpdir(), "sq-fp-lib-")); });
|
|
25
|
+
afterEach(async () => { await rm(dir, { recursive: true, force: true }); });
|
|
26
|
+
|
|
27
|
+
async function writeRules(text: string): Promise<string> {
|
|
28
|
+
await mkdir(path.join(dir, "profile", "fastpath"), { recursive: true });
|
|
29
|
+
await writeFile(path.join(dir, "profile", "fastpath", "known-answers.yml"), text, "utf8");
|
|
30
|
+
return "fastpath/known-answers.yml";
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
it("未配置 rules → config=null(fastpath 关闭)", () => {
|
|
34
|
+
expect(loadReplyRules(dir, undefined).config).toBeNull();
|
|
35
|
+
expect(loadReplyRules(dir, "").config).toBeNull();
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
it("文件缺失 → config=null + issue(优雅关闭,不阻断)", () => {
|
|
39
|
+
const r = loadReplyRules(dir, "fastpath/missing.yml");
|
|
40
|
+
expect(r.config).toBeNull();
|
|
41
|
+
expect(r.issues.join("|")).toContain("不存在");
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
it("contains 单向匹配:消息包含规则模式命中;反向(规则含消息)绝不命中(修早期双向 includes bug)", async () => {
|
|
45
|
+
const rel = await writeRules([
|
|
46
|
+
"rules:",
|
|
47
|
+
" - { key: row_limit, contains: 多少行, reply: 单表上限 20 万行。 }",
|
|
48
|
+
].join("\n"));
|
|
49
|
+
const { config } = loadReplyRules(dir, rel);
|
|
50
|
+
// 正向:消息包含 "多少行" → 命中
|
|
51
|
+
expect(matchReplyRules(config, "请问单表支持多少行数据")).toMatchObject({ key: "row_limit", kind: "contains" });
|
|
52
|
+
// 反向:消息 "行" 是规则模式的子串,但消息不包含规则模式 → 绝不命中
|
|
53
|
+
expect(matchReplyRules(config, "行")).toBeNull();
|
|
54
|
+
expect(matchReplyRules(config, "多少")).toBeNull();
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
it("regex / template / 未命中", async () => {
|
|
58
|
+
const rel = await writeRules([
|
|
59
|
+
"rules:",
|
|
60
|
+
" - { key: rx, regex: '(最多|上限).{0,4}行', reply: R1 }",
|
|
61
|
+
" - { key: tpl, template: '完全固定的问法', reply: R2 }",
|
|
62
|
+
].join("\n"));
|
|
63
|
+
const { config } = loadReplyRules(dir, rel);
|
|
64
|
+
expect(matchReplyRules(config, "最多几行")).toMatchObject({ key: "rx", kind: "regex" });
|
|
65
|
+
expect(matchReplyRules(config, " 完全固定的问法 ")).toMatchObject({ key: "tpl", kind: "template" }); // 空白归一
|
|
66
|
+
expect(matchReplyRules(config, "完全固定的问法啊")).toBeNull(); // template 需全等
|
|
67
|
+
expect(matchReplyRules(config, "无关消息")).toBeNull();
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
it("safety 安全兜底优先级最高(先于普通规则)", async () => {
|
|
71
|
+
const rel = await writeRules([
|
|
72
|
+
"safety: { keywords: [涉及敏感内容], reply: 安全话术 }",
|
|
73
|
+
"rules:",
|
|
74
|
+
" - { key: any, contains: 内容, reply: 普通话术 }",
|
|
75
|
+
].join("\n"));
|
|
76
|
+
const { config } = loadReplyRules(dir, rel);
|
|
77
|
+
expect(matchReplyRules(config, "这条涉及敏感内容的消息")).toMatchObject({ key: "safety", kind: "safety", reply: "安全话术" });
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
it("规则形状非法 → 记 issue 并跳过(多选/缺 reply/非法正则)", async () => {
|
|
81
|
+
const rel = await writeRules([
|
|
82
|
+
"rules:",
|
|
83
|
+
" - { key: multi, contains: a, regex: b, reply: R }", // 多选
|
|
84
|
+
" - { key: noreply, contains: c }", // 缺 reply
|
|
85
|
+
" - { key: badrx, regex: '(', reply: R }", // 非法正则
|
|
86
|
+
" - { key: ok, contains: 有效, reply: OK }",
|
|
87
|
+
].join("\n"));
|
|
88
|
+
const { config, issues } = loadReplyRules(dir, rel);
|
|
89
|
+
expect(config.rules).toHaveLength(1);
|
|
90
|
+
expect(config.rules[0].key).toBe("ok");
|
|
91
|
+
expect(issues.length).toBeGreaterThanOrEqual(3);
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
it("stripQuotedBlock:剥离「引用消息:」块,只保留用户本轮新话", () => {
|
|
95
|
+
expect(stripQuotedBlock("引用字段是复制的内容\n\n引用消息: Hi u,你遇到的错误「所选字段形成循环引用」…"))
|
|
96
|
+
.toBe("引用字段是复制的内容");
|
|
97
|
+
// 全角冒号变体
|
|
98
|
+
expect(stripQuotedBlock("新话\n\n引用消息:旧报错文案")).toBe("新话");
|
|
99
|
+
// 无引用块 → 原文不变
|
|
100
|
+
expect(stripQuotedBlock("普通消息")).toBe("普通消息");
|
|
101
|
+
// 剥离后为空(只转发引用未说话)→ 回退原文,不制造空消息
|
|
102
|
+
const onlyQuote = "引用消息: AI字段配置异常,请检查后重试";
|
|
103
|
+
expect(stripQuotedBlock(onlyQuote)).toBe(onlyQuote);
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
it("报错文案只在引用块里(g4-21 型追问)→ fastpath 不命中,不复读", async () => {
|
|
107
|
+
const rel = await writeRules([
|
|
108
|
+
"rules:",
|
|
109
|
+
" - { key: cycle, contains: 所选字段形成循环引用, reply: 循环引用话术 }",
|
|
110
|
+
].join("\n"));
|
|
111
|
+
const { config } = loadReplyRules(dir, rel);
|
|
112
|
+
const followUp = "@Felix 引用字段是复制的内容,不存在引用字段是其他ai生成\n\n引用消息: Hi 甘燕威,你遇到的错误「所选字段形成循环引用,数据处理异常,请检查」,以下是相关说明和解决方案:…";
|
|
113
|
+
expect(matchReplyRules(config, followUp)).toBeNull();
|
|
114
|
+
// 用户自己粘报错(无引用块)→ 仍然秒回
|
|
115
|
+
expect(matchReplyRules(config, "报错了:所选字段形成循环引用,数据处理异常,请检查"))
|
|
116
|
+
.toMatchObject({ key: "cycle" });
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
it("safety 关键词藏在引用块里 → 仍然拦(安全兜底不剥离,防注入藏引用)", async () => {
|
|
120
|
+
const rel = await writeRules([
|
|
121
|
+
"safety: { keywords: [涉及敏感内容], reply: 安全话术 }",
|
|
122
|
+
"rules:",
|
|
123
|
+
" - { key: any, contains: 无关, reply: 普通 }",
|
|
124
|
+
].join("\n"));
|
|
125
|
+
const { config } = loadReplyRules(dir, rel);
|
|
126
|
+
expect(matchReplyRules(config, "这条怎么回\n\n引用消息: 本内容涉及敏感内容无法生成"))
|
|
127
|
+
.toMatchObject({ key: "safety", kind: "safety" });
|
|
128
|
+
});
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
describe("loadClassifierRules / classifyMessage:声明式分类器 + 整档/群开关", () => {
|
|
132
|
+
let dir: string;
|
|
133
|
+
beforeEach(async () => { dir = await mkdtemp(path.join(os.tmpdir(), "sq-ts-lib-")); });
|
|
134
|
+
afterEach(async () => { await rm(dir, { recursive: true, force: true }); });
|
|
135
|
+
|
|
136
|
+
async function writeClassifiers(text: string): Promise<string> {
|
|
137
|
+
await mkdir(path.join(dir, "profile", "troubleshoot"), { recursive: true });
|
|
138
|
+
await writeFile(path.join(dir, "profile", "troubleshoot", "classifiers.yml"), text, "utf8");
|
|
139
|
+
return "troubleshoot/classifiers.yml";
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
it("未配置 / 文件缺失 → config=null", () => {
|
|
143
|
+
expect(loadClassifierRules(dir, undefined).config).toBeNull();
|
|
144
|
+
const r = loadClassifierRules(dir, "troubleshoot/missing.yml");
|
|
145
|
+
expect(r.config).toBeNull();
|
|
146
|
+
expect(r.issues.join("|")).toContain("不存在");
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
it("单条件 contains 命中 + extract 提取字段", async () => {
|
|
150
|
+
const rel = await writeClassifiers([
|
|
151
|
+
"classifiers:",
|
|
152
|
+
" - issueType: err",
|
|
153
|
+
" reason: 命中报错",
|
|
154
|
+
" patterns: [{ contains: ERR_X }]",
|
|
155
|
+
" extract: { code: 'ERR_X[0-9]+' }",
|
|
156
|
+
].join("\n"));
|
|
157
|
+
const { config } = loadClassifierRules(dir, rel);
|
|
158
|
+
const r = classifyMessage(config, "出现了 ERR_X42 报错");
|
|
159
|
+
expect(r).toMatchObject({ issueType: "err", reason: "命中报错" });
|
|
160
|
+
expect(r.extracted.code).toBe("ERR_X42");
|
|
161
|
+
expect(classifyMessage(config, "无关消息")).toBeNull();
|
|
162
|
+
});
|
|
163
|
+
|
|
164
|
+
it("require_all:需全部 pattern 命中(双关键词共现)", async () => {
|
|
165
|
+
const rel = await writeClassifiers([
|
|
166
|
+
"classifiers:",
|
|
167
|
+
" - issueType: ds",
|
|
168
|
+
" require_all: true",
|
|
169
|
+
" patterns: [{ contains: docKey }, { contains: 时间戳 }]",
|
|
170
|
+
].join("\n"));
|
|
171
|
+
const { config } = loadClassifierRules(dir, rel);
|
|
172
|
+
expect(classifyMessage(config, "docKey=abc 时间戳=123")).toMatchObject({ issueType: "ds" });
|
|
173
|
+
expect(classifyMessage(config, "只有 docKey=abc")).toBeNull();
|
|
174
|
+
});
|
|
175
|
+
|
|
176
|
+
it("regex 命中 + 声明顺序返回第一个满足", async () => {
|
|
177
|
+
const rel = await writeClassifiers([
|
|
178
|
+
"classifiers:",
|
|
179
|
+
" - issueType: a",
|
|
180
|
+
" patterns: [{ regex: '错误码\\d{3}' }]",
|
|
181
|
+
" - issueType: b",
|
|
182
|
+
" patterns: [{ contains: 错误 }]",
|
|
183
|
+
].join("\n"));
|
|
184
|
+
const { config } = loadClassifierRules(dir, rel);
|
|
185
|
+
expect(classifyMessage(config, "错误码500")).toMatchObject({ issueType: "a" });
|
|
186
|
+
expect(classifyMessage(config, "只是错误描述")).toMatchObject({ issueType: "b" });
|
|
187
|
+
});
|
|
188
|
+
|
|
189
|
+
it("classifier 可从 profile 透传精确 Owner module(未声明则不带 module 字段)", async () => {
|
|
190
|
+
const rel = await writeClassifiers([
|
|
191
|
+
"classifiers:",
|
|
192
|
+
" - issueType: ai_field",
|
|
193
|
+
" module: AI字段",
|
|
194
|
+
" patterns: [{ contains: 'Sheet ID:' }]",
|
|
195
|
+
" - issueType: other",
|
|
196
|
+
" patterns: [{ contains: 其它 }]",
|
|
197
|
+
].join("\n"));
|
|
198
|
+
|
|
199
|
+
const { config } = loadClassifierRules(dir, rel);
|
|
200
|
+
expect(classifyMessage(config, "失败\nSheet ID: sht1")).toMatchObject({
|
|
201
|
+
issueType: "ai_field",
|
|
202
|
+
module: "AI字段",
|
|
203
|
+
});
|
|
204
|
+
const other = classifyMessage(config, "其它问题");
|
|
205
|
+
expect(other!.issueType).toBe("other");
|
|
206
|
+
expect(other!.module).toBeUndefined();
|
|
207
|
+
});
|
|
208
|
+
|
|
209
|
+
it("形状非法分类器跳过 + 记 issue", async () => {
|
|
210
|
+
const rel = await writeClassifiers([
|
|
211
|
+
"classifiers:",
|
|
212
|
+
" - reason: 缺 issueType",
|
|
213
|
+
" patterns: [{ contains: x }]",
|
|
214
|
+
" - issueType: nopat",
|
|
215
|
+
" patterns: []",
|
|
216
|
+
" - issueType: ok",
|
|
217
|
+
" patterns: [{ contains: 有效 }]",
|
|
218
|
+
].join("\n"));
|
|
219
|
+
const { config, issues } = loadClassifierRules(dir, rel);
|
|
220
|
+
expect(config.classifiers).toHaveLength(1);
|
|
221
|
+
expect(config.classifiers[0].issueType).toBe("ok");
|
|
222
|
+
expect(issues.length).toBeGreaterThanOrEqual(2);
|
|
223
|
+
});
|
|
224
|
+
|
|
225
|
+
it("isCapabilityEnabled:skills_dir 未配/不存在→false;存在→true(整档关闭)", async () => {
|
|
226
|
+
expect(isCapabilityEnabled(dir, undefined)).toBe(false);
|
|
227
|
+
expect(isCapabilityEnabled(dir, "skills/troubleshooting")).toBe(false);
|
|
228
|
+
await mkdir(path.join(dir, "skills", "troubleshooting"), { recursive: true });
|
|
229
|
+
expect(isCapabilityEnabled(dir, "skills/troubleshooting")).toBe(true);
|
|
230
|
+
});
|
|
231
|
+
|
|
232
|
+
it("isGroupTroubleshootingEnabled:仅明确开启的群为真", () => {
|
|
233
|
+
const groups = [{ groupId: "c1", troubleshootingEnabled: true }, { groupId: "c2", troubleshootingEnabled: false }, { groupId: "c3" }];
|
|
234
|
+
expect(isGroupToggleEnabled(groups, "c1", "troubleshootingEnabled")).toBe(true);
|
|
235
|
+
expect(isGroupToggleEnabled(groups, "c2", "troubleshootingEnabled")).toBe(false);
|
|
236
|
+
expect(isGroupToggleEnabled(groups, "c3", "troubleshootingEnabled")).toBe(false);
|
|
237
|
+
expect(isGroupToggleEnabled(groups, "cX", "troubleshootingEnabled")).toBe(false);
|
|
238
|
+
expect(isGroupToggleEnabled(undefined, "c1", "troubleshootingEnabled")).toBe(false);
|
|
239
|
+
});
|
|
240
|
+
});
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 群成员在群判定(support-qa/lib/dingtalk-group-membership)
|
|
3
|
+
*
|
|
4
|
+
* 核心不变量:**任何失败都降级为 { mode: "name" },绝不抛错**。
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { describe, it, expect, beforeEach, vi } from "vitest";
|
|
8
|
+
import {
|
|
9
|
+
resolveGroupMention,
|
|
10
|
+
resetGroupMembershipCache,
|
|
11
|
+
} from "../dingtalk-group-membership.js";
|
|
12
|
+
import { DwsClient } from "aitable-workflow-core";
|
|
13
|
+
import type { CommandRunner } from "aitable-workflow-core";
|
|
14
|
+
|
|
15
|
+
const CONTACT = { userId: "239198", openDingTalkId: "open-owner" };
|
|
16
|
+
|
|
17
|
+
/** 用注入的 dws stub 替代真实命令 */
|
|
18
|
+
function fakeDws(runJson: (args: string[]) => Promise<unknown>) {
|
|
19
|
+
return { runJson: vi.fn(async (args: string[]) => runJson(args)) };
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
beforeEach(() => {
|
|
23
|
+
resetGroupMembershipCache();
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
describe("resolveGroupMention — 判定与降级", () => {
|
|
27
|
+
it("list-by-ids 命中 → 真实 @", async () => {
|
|
28
|
+
const dws = fakeDws(async () => ({ result: { members: [{ openDingtalkId: "open-owner" }] } }));
|
|
29
|
+
await expect(resolveGroupMention("cid1", CONTACT, { dws, now: () => 1 }))
|
|
30
|
+
.resolves.toEqual({ mode: "at", userId: "239198" });
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
it("不在群 / 非结构化响应 / 抛错 → 一律降级 name", async () => {
|
|
34
|
+
for (const response of [
|
|
35
|
+
{ result: { members: [] } },
|
|
36
|
+
{ result: {} },
|
|
37
|
+
"not-an-object",
|
|
38
|
+
null,
|
|
39
|
+
{ unexpected: true },
|
|
40
|
+
]) {
|
|
41
|
+
resetGroupMembershipCache();
|
|
42
|
+
const dws = fakeDws(async () => response);
|
|
43
|
+
await expect(resolveGroupMention("cid1", CONTACT, { dws, now: () => 1 }))
|
|
44
|
+
.resolves.toEqual({ mode: "name" });
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
resetGroupMembershipCache();
|
|
48
|
+
const boom = fakeDws(async () => { throw new Error("timeout"); });
|
|
49
|
+
await expect(resolveGroupMention("cid1", CONTACT, { dws: boom, now: () => 1 }))
|
|
50
|
+
.resolves.toEqual({ mode: "name" });
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
it("两种 openDingTalkId 拼写都能匹配(不同 dws 版本返回不一致)", async () => {
|
|
54
|
+
for (const key of ["openDingTalkId", "openDingtalkId"]) {
|
|
55
|
+
resetGroupMembershipCache();
|
|
56
|
+
const dws = fakeDws(async () => ({ result: { members: [{ [key]: "open-owner" }] } }));
|
|
57
|
+
await expect(resolveGroupMention("cid1", CONTACT, { dws, now: () => 1 }))
|
|
58
|
+
.resolves.toEqual({ mode: "at", userId: "239198" });
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
it("缺 openDingTalkId / userId / 群ID → 直接降级 name 且不调 dws", async () => {
|
|
63
|
+
const dws = fakeDws(async () => ({ result: { members: [{ openDingTalkId: "open-owner" }] } }));
|
|
64
|
+
await expect(resolveGroupMention("cid1", { userId: "239198" }, { dws, now: () => 1 }))
|
|
65
|
+
.resolves.toEqual({ mode: "name" });
|
|
66
|
+
await expect(resolveGroupMention("cid1", { userId: "", openDingTalkId: "open-owner" }, { dws, now: () => 1 }))
|
|
67
|
+
.resolves.toEqual({ mode: "name" });
|
|
68
|
+
await expect(resolveGroupMention("", CONTACT, { dws, now: () => 1 }))
|
|
69
|
+
.resolves.toEqual({ mode: "name" });
|
|
70
|
+
expect(dws.runJson).not.toHaveBeenCalled();
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
it("不手写 --format json(由 DwsClient 统一追加)", async () => {
|
|
74
|
+
let seen: string[] = [];
|
|
75
|
+
const dws = fakeDws(async (args) => { seen = args; return { result: { members: [] } }; });
|
|
76
|
+
await resolveGroupMention("cid1", CONTACT, { dws, now: () => 1 });
|
|
77
|
+
expect(seen).toEqual([
|
|
78
|
+
"chat", "group", "members", "list-by-ids", "--id", "cid1", "--users", "open-owner",
|
|
79
|
+
]);
|
|
80
|
+
});
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
describe("resolveGroupMention — 缓存", () => {
|
|
84
|
+
it("同群同人 10min 内命中缓存,过期后重新判定", async () => {
|
|
85
|
+
const dws = fakeDws(async () => ({ result: { members: [{ openDingTalkId: "open-owner" }] } }));
|
|
86
|
+
await resolveGroupMention("cid1", CONTACT, { dws, now: () => 1 });
|
|
87
|
+
await resolveGroupMention("cid1", CONTACT, { dws, now: () => 599_999 });
|
|
88
|
+
expect(dws.runJson).toHaveBeenCalledTimes(1);
|
|
89
|
+
await resolveGroupMention("cid1", CONTACT, { dws, now: () => 600_002 });
|
|
90
|
+
expect(dws.runJson).toHaveBeenCalledTimes(2);
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
it("降级结果同样进缓存(避免故障期每条消息都重试查询)", async () => {
|
|
94
|
+
const dws = fakeDws(async () => ({ result: { members: [] } }));
|
|
95
|
+
await resolveGroupMention("cid1", CONTACT, { dws, now: () => 1 });
|
|
96
|
+
await resolveGroupMention("cid1", CONTACT, { dws, now: () => 2 });
|
|
97
|
+
expect(dws.runJson).toHaveBeenCalledTimes(1);
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
it("不同群 / 不同人各自独立缓存", async () => {
|
|
101
|
+
const dws = fakeDws(async () => ({ result: { members: [{ openDingTalkId: "open-owner" }] } }));
|
|
102
|
+
await resolveGroupMention("cid1", CONTACT, { dws, now: () => 1 });
|
|
103
|
+
await resolveGroupMention("cid2", CONTACT, { dws, now: () => 1 });
|
|
104
|
+
await resolveGroupMention("cid1", { userId: "999", openDingTalkId: "open-other" }, { dws, now: () => 1 });
|
|
105
|
+
expect(dws.runJson).toHaveBeenCalledTimes(3);
|
|
106
|
+
});
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
describe("走 DwsClient 带来的可观测性收益", () => {
|
|
110
|
+
it("dws 首次抖动后重试仍能判出 at(迁移前会直接降级为花名)", async () => {
|
|
111
|
+
let attempts = 0;
|
|
112
|
+
const runner: CommandRunner = async () => {
|
|
113
|
+
attempts += 1;
|
|
114
|
+
if (attempts === 1) throw new Error("ETIMEDOUT");
|
|
115
|
+
return {
|
|
116
|
+
stdout: JSON.stringify({ result: { members: [{ openDingTalkId: "open-owner" }] } }),
|
|
117
|
+
stderr: "",
|
|
118
|
+
exitCode: 0,
|
|
119
|
+
};
|
|
120
|
+
};
|
|
121
|
+
|
|
122
|
+
const dws = new DwsClient({ bin: "dws", runner });
|
|
123
|
+
await expect(resolveGroupMention("cid1", CONTACT, { dws, now: () => 1 }))
|
|
124
|
+
.resolves.toEqual({ mode: "at", userId: "239198" });
|
|
125
|
+
expect(attempts).toBeGreaterThan(1);
|
|
126
|
+
});
|
|
127
|
+
});
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 场景记忆事件工厂(support-qa/lib/memory-events)
|
|
3
|
+
*
|
|
4
|
+
* 锁定:scope 常量一致性,entry 形状与 questionKey 归一行为。
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { describe, it, expect } from "vitest";
|
|
8
|
+
import { supportScope, supportEntry, questionKey } from "../memory-events.js";
|
|
9
|
+
|
|
10
|
+
describe("supportScope", () => {
|
|
11
|
+
it("带 conversationId 时按会话隔离", () => {
|
|
12
|
+
expect(supportScope("cid1")).toEqual({
|
|
13
|
+
channel: "dingtalk",
|
|
14
|
+
scenario: "support-qa",
|
|
15
|
+
conversationId: "cid1",
|
|
16
|
+
});
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
it("省略 conversationId 时为场景级 scope(长期记忆读写用)", () => {
|
|
20
|
+
expect(supportScope()).toEqual({ channel: "dingtalk", scenario: "support-qa" });
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
it("空串 conversationId 不写入字段(避免脏 scope 分裂记忆)", () => {
|
|
24
|
+
expect(supportScope("")).toEqual({ channel: "dingtalk", scenario: "support-qa" });
|
|
25
|
+
});
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
describe("supportEntry", () => {
|
|
29
|
+
it("summary 省略时按 `sender: 正文前 80 字` 生成", () => {
|
|
30
|
+
const e = supportEntry({
|
|
31
|
+
kind: "user_message",
|
|
32
|
+
content: "x".repeat(200),
|
|
33
|
+
sender: "小明",
|
|
34
|
+
role: "user",
|
|
35
|
+
conversationId: "cid1",
|
|
36
|
+
});
|
|
37
|
+
expect(e.summary).toBe(`小明: ${"x".repeat(80)}`);
|
|
38
|
+
expect(e.kind).toBe("user_message");
|
|
39
|
+
expect(e.content).toHaveLength(200);
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
it("meta 固定带 sender/role/conversationId,且调用方 meta 可追加", () => {
|
|
43
|
+
const e = supportEntry({
|
|
44
|
+
kind: "agent_decision",
|
|
45
|
+
content: "(已决策回复)",
|
|
46
|
+
sender: "agent",
|
|
47
|
+
role: "agent",
|
|
48
|
+
conversationId: "cid9",
|
|
49
|
+
meta: { action: "reply", question: "上限多少" },
|
|
50
|
+
});
|
|
51
|
+
expect(e.meta).toEqual({
|
|
52
|
+
sender: "agent",
|
|
53
|
+
role: "agent",
|
|
54
|
+
conversationId: "cid9",
|
|
55
|
+
action: "reply",
|
|
56
|
+
question: "上限多少",
|
|
57
|
+
});
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
it("显式 summary / timestamp 优先", () => {
|
|
61
|
+
const e = supportEntry({
|
|
62
|
+
kind: "send_failed",
|
|
63
|
+
content: "正文",
|
|
64
|
+
sender: "agent",
|
|
65
|
+
role: "agent",
|
|
66
|
+
conversationId: "cid1",
|
|
67
|
+
summary: "发送失败(via=skipped)",
|
|
68
|
+
timestamp: "2026-08-05T00:00:00.000Z",
|
|
69
|
+
});
|
|
70
|
+
expect(e.summary).toBe("发送失败(via=skipped)");
|
|
71
|
+
expect(e.timestamp).toBe("2026-08-05T00:00:00.000Z");
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
it("timestamp 省略时为 ISO 串", () => {
|
|
75
|
+
const e = supportEntry({
|
|
76
|
+
kind: "user_message", content: "c", sender: "s", role: "user", conversationId: "cid",
|
|
77
|
+
});
|
|
78
|
+
expect(e.timestamp).toMatch(/^\d{4}-\d{2}-\d{2}T[\d:.]+Z$/);
|
|
79
|
+
});
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
describe("questionKey", () => {
|
|
83
|
+
it("折叠空白并 trim(复盘配对锚点稳定)", () => {
|
|
84
|
+
expect(questionKey(" 上限\n是\t多少 ")).toBe("上限 是 多少");
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
it("截断到 120 字", () => {
|
|
88
|
+
expect(questionKey("问".repeat(300))).toHaveLength(120);
|
|
89
|
+
});
|
|
90
|
+
});
|
|
@@ -71,7 +71,7 @@ export function renderOwnerMention(
|
|
|
71
71
|
|
|
72
72
|
// ─── 内部文案(不进 Profile 配置面) ─────────────────────
|
|
73
73
|
|
|
74
|
-
// Owner
|
|
74
|
+
// Owner 尾注(追加在主体之后)。话术用引导式口吻:
|
|
75
75
|
// 「建议在群内 @X 帮你看一下」——不谎称已通知(是否真实 @ 到人由发送层 atUserIds 决定);
|
|
76
76
|
// mention 两侧已带空格,模板不再额外加空格
|
|
77
77
|
const BUG_FOOTER = (mention: string, module: string) =>
|