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
|
@@ -1,529 +0,0 @@
|
|
|
1
|
-
import path from "node:path";
|
|
2
|
-
import { z } from "zod";
|
|
3
|
-
import { type RecipeDefinition, type RecipeContext, type RecipeResult, type TableRef, tableRefConfigSchema, type MemoryScope, type MemoryEntry, isGlobalVarRef, resolveGlobalVarRef } from "aitable-workflow-core";
|
|
4
|
-
import { HANDOFF_MEMORY_KINDS, handoffScope } from "./memory-events.js";
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* 每日复盘 Step Recipe(记忆叠加版)
|
|
8
|
-
*
|
|
9
|
-
* cron_scheduler 每日凌晨触发(on_demand) → 读取昨日短期记忆 → coding.run 压缩+统计+抽取
|
|
10
|
-
* → memory.compact 写共享长期记忆 → table.upsertRecordIn 写每日统计表
|
|
11
|
-
* → table.createRecordsIn 写产品需求池。
|
|
12
|
-
*
|
|
13
|
-
* 无活动(各群昨日无短期记忆)→ 返回 tracker:false,on_demand 下不建复盘留痕行。
|
|
14
|
-
*
|
|
15
|
-
* 短期记忆按群隔离(含 conversationId),长期记忆产品级共享(不含 conversationId)。
|
|
16
|
-
* coding.run 用 workspaces/daily-review/AGENTS.md 承载全部压缩/统计/抽取规范。
|
|
17
|
-
*
|
|
18
|
-
* 群列表适配:aitable-handoff 的群是动态的,由 config-sync 发布到 globalVar(group_configs)。
|
|
19
|
-
* step.config.conversation_ids 二选一:静态数组,或引用 ${globalVar.group_configs}(无隐式回退)。
|
|
20
|
-
*/
|
|
21
|
-
|
|
22
|
-
// ─── 配置解析 ──────────────────────────────────────────
|
|
23
|
-
|
|
24
|
-
interface ReviewConfig {
|
|
25
|
-
/** 复盘群来源:静态字符串数组,或 "${globalVar.group_configs}" 引用(运行期解析) */
|
|
26
|
-
conversationIds: unknown;
|
|
27
|
-
dailyStatsTable: TableRef | null;
|
|
28
|
-
productBacklogTable: TableRef | null;
|
|
29
|
-
savedMinutesPerReply: number;
|
|
30
|
-
/** 复盘日期计算时区(IANA),应与 cron 的 timezone 一致;默认 Asia/Shanghai */
|
|
31
|
-
timezone: string;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
function isTableRefConfigured(raw: unknown): raw is { baseId: string; tableId: string } {
|
|
35
|
-
return !!raw && typeof raw === "object" && typeof (raw as Record<string, unknown>).baseId === "string" && typeof (raw as Record<string, unknown>).tableId === "string";
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
function parseConfig(raw: Record<string, unknown>): ReviewConfig {
|
|
39
|
-
const dst = raw.daily_stats_table as { baseId?: string; tableId?: string } | undefined;
|
|
40
|
-
const pbt = raw.product_backlog_table as { baseId?: string; tableId?: string } | undefined;
|
|
41
|
-
const saved = typeof raw.saved_minutes_per_reply === "number" ? raw.saved_minutes_per_reply : 15;
|
|
42
|
-
|
|
43
|
-
return {
|
|
44
|
-
conversationIds: raw.conversation_ids,
|
|
45
|
-
dailyStatsTable: isTableRefConfigured(dst) ? { baseId: dst.baseId, tableId: dst.tableId } : null,
|
|
46
|
-
productBacklogTable: isTableRefConfigured(pbt) ? { baseId: pbt.baseId, tableId: pbt.tableId } : null,
|
|
47
|
-
savedMinutesPerReply: saved,
|
|
48
|
-
timezone: normalizeTimezone(typeof raw.timezone === "string" ? raw.timezone : undefined),
|
|
49
|
-
};
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
/** 校验 IANA 时区,非法/缺省回退 Asia/Shanghai(与 cron 默认一致) */
|
|
53
|
-
function normalizeTimezone(raw: string | undefined): string {
|
|
54
|
-
const candidate = raw?.trim();
|
|
55
|
-
if (!candidate) return "Asia/Shanghai";
|
|
56
|
-
try {
|
|
57
|
-
new Intl.DateTimeFormat("en-US", { timeZone: candidate }).format(new Date());
|
|
58
|
-
return candidate;
|
|
59
|
-
} catch {
|
|
60
|
-
return "Asia/Shanghai";
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
/**
|
|
65
|
-
* 解析复盘群列表:显式二选一,无隐式回退。
|
|
66
|
-
* - 静态字符串数组 → 直接用
|
|
67
|
-
* - "${globalVar.group_configs}" 引用 → 活读并抽取 groupId(支持 [{groupId}] / ["cid"])
|
|
68
|
-
*/
|
|
69
|
-
function resolveConversationIds(raw: unknown, get: (path: string) => unknown): string[] {
|
|
70
|
-
if (isGlobalVarRef(raw)) return extractGroupIds(resolveGlobalVarRef(raw, get));
|
|
71
|
-
if (Array.isArray(raw)) return raw.map((s) => String(s).trim()).filter(Boolean);
|
|
72
|
-
return [];
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
/** 从群配置数组抽取 groupId([{groupId}] 或 ["cid"]);非数组/空 → 空数组 */
|
|
76
|
-
function extractGroupIds(list: unknown): string[] {
|
|
77
|
-
if (!Array.isArray(list)) return [];
|
|
78
|
-
return list
|
|
79
|
-
.map((g) => (typeof g === "string" ? g : g && typeof g === "object" ? String((g as Record<string, unknown>).groupId ?? "") : ""))
|
|
80
|
-
.map((s) => s.trim())
|
|
81
|
-
.filter(Boolean);
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
// ─── JSON 提取 ─────────────────────────────────────────
|
|
85
|
-
|
|
86
|
-
interface ReviewResult {
|
|
87
|
-
summary: string;
|
|
88
|
-
metrics: DailyReviewMetric[];
|
|
89
|
-
needsBugs: Array<{
|
|
90
|
-
type: string;
|
|
91
|
-
title: string;
|
|
92
|
-
description: string;
|
|
93
|
-
sourceMessage: string;
|
|
94
|
-
sender: string;
|
|
95
|
-
sourceGroup: string;
|
|
96
|
-
priority: string;
|
|
97
|
-
}>;
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
type DailyReviewMetric = {
|
|
101
|
-
conversationId: string;
|
|
102
|
-
questionCount: number;
|
|
103
|
-
agentAnsweredCount?: number;
|
|
104
|
-
knownErrorAnsweredCount?: number;
|
|
105
|
-
humanAnsweredCount?: number;
|
|
106
|
-
answeredCount: number;
|
|
107
|
-
unansweredCount: number;
|
|
108
|
-
silentCount?: number;
|
|
109
|
-
sendFailedCount?: number;
|
|
110
|
-
kbMissCount?: number;
|
|
111
|
-
demandCount?: number;
|
|
112
|
-
bugCount?: number;
|
|
113
|
-
servedUsers: number;
|
|
114
|
-
avgFirstResponseMinutes?: number;
|
|
115
|
-
};
|
|
116
|
-
|
|
117
|
-
function num(value: unknown, fallback = 0): number {
|
|
118
|
-
return typeof value === "number" && Number.isFinite(value) ? value : fallback;
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
function includesAny(text: string, patterns: string[]): boolean {
|
|
122
|
-
return patterns.some((pattern) => text.includes(pattern));
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
function computeAvgFirstResponseMinutes(entries: MemoryEntry[]): number {
|
|
126
|
-
const pendingQuestionTimes: number[] = [];
|
|
127
|
-
const responseMinutes: number[] = [];
|
|
128
|
-
const answerKinds = new Set<string>([
|
|
129
|
-
HANDOFF_MEMORY_KINDS.agentReplySent,
|
|
130
|
-
HANDOFF_MEMORY_KINDS.knownErrorReplySent,
|
|
131
|
-
HANDOFF_MEMORY_KINDS.humanReply,
|
|
132
|
-
]);
|
|
133
|
-
|
|
134
|
-
const sorted = [...entries].sort((a, b) => a.timestamp.localeCompare(b.timestamp));
|
|
135
|
-
for (const entry of sorted) {
|
|
136
|
-
const ts = Date.parse(entry.timestamp);
|
|
137
|
-
if (!Number.isFinite(ts)) continue;
|
|
138
|
-
if (entry.kind === HANDOFF_MEMORY_KINDS.userMessage) {
|
|
139
|
-
pendingQuestionTimes.push(ts);
|
|
140
|
-
continue;
|
|
141
|
-
}
|
|
142
|
-
if (answerKinds.has(entry.kind) && pendingQuestionTimes.length > 0) {
|
|
143
|
-
const questionTs = pendingQuestionTimes.shift()!;
|
|
144
|
-
if (ts >= questionTs) {
|
|
145
|
-
responseMinutes.push((ts - questionTs) / 60_000);
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
if (responseMinutes.length === 0) return 0;
|
|
151
|
-
const avg = responseMinutes.reduce((sum, value) => sum + value, 0) / responseMinutes.length;
|
|
152
|
-
return Math.round(avg * 100) / 100;
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
function computeDeterministicMetric(
|
|
156
|
-
conversationId: string,
|
|
157
|
-
entries: MemoryEntry[],
|
|
158
|
-
needsBugs: ReviewResult["needsBugs"],
|
|
159
|
-
): DailyReviewMetric {
|
|
160
|
-
const userMessages = entries.filter((entry) => entry.kind === HANDOFF_MEMORY_KINDS.userMessage);
|
|
161
|
-
const agentAnsweredCount = entries.filter((entry) => entry.kind === HANDOFF_MEMORY_KINDS.agentReplySent).length;
|
|
162
|
-
const knownErrorAnsweredCount = entries.filter((entry) => entry.kind === HANDOFF_MEMORY_KINDS.knownErrorReplySent).length;
|
|
163
|
-
const humanAnsweredCount = entries.filter((entry) => entry.kind === HANDOFF_MEMORY_KINDS.humanReply).length;
|
|
164
|
-
const answeredCount = agentAnsweredCount + knownErrorAnsweredCount + humanAnsweredCount;
|
|
165
|
-
const silentDecisions = entries.filter((entry) => {
|
|
166
|
-
if (entry.kind !== HANDOFF_MEMORY_KINDS.agentDecision) return false;
|
|
167
|
-
return entry.content.trim() === "(静默)" || entry.meta?.shouldReply !== true;
|
|
168
|
-
});
|
|
169
|
-
const sendFailedCount = entries.filter((entry) => entry.kind === HANDOFF_MEMORY_KINDS.sendFailed).length;
|
|
170
|
-
const kbMissCount = silentDecisions.filter((entry) => {
|
|
171
|
-
const reason = String(entry.meta?.reason ?? entry.content ?? "");
|
|
172
|
-
return includesAny(reason, ["知识库未覆盖", "知识库不可用", "无据", "未找到相关说明", "文档未覆盖"]);
|
|
173
|
-
}).length;
|
|
174
|
-
const servedUsers = new Set(userMessages.map((entry) => String(entry.meta?.sender ?? "")).filter(Boolean)).size;
|
|
175
|
-
const groupNeedsBugs = needsBugs.filter((item) => !item.sourceGroup || item.sourceGroup === conversationId);
|
|
176
|
-
|
|
177
|
-
return {
|
|
178
|
-
conversationId,
|
|
179
|
-
questionCount: userMessages.length,
|
|
180
|
-
agentAnsweredCount,
|
|
181
|
-
knownErrorAnsweredCount,
|
|
182
|
-
humanAnsweredCount,
|
|
183
|
-
answeredCount,
|
|
184
|
-
unansweredCount: Math.max(0, userMessages.length - answeredCount),
|
|
185
|
-
silentCount: silentDecisions.length,
|
|
186
|
-
sendFailedCount,
|
|
187
|
-
kbMissCount,
|
|
188
|
-
demandCount: groupNeedsBugs.filter((item) => item.type === "需求").length,
|
|
189
|
-
bugCount: groupNeedsBugs.filter((item) => item.type === "Bug").length,
|
|
190
|
-
servedUsers,
|
|
191
|
-
avgFirstResponseMinutes: computeAvgFirstResponseMinutes(entries),
|
|
192
|
-
};
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
function extractReviewResult(raw: string): ReviewResult | null {
|
|
196
|
-
if (!raw) return null;
|
|
197
|
-
let s = raw.trim();
|
|
198
|
-
const fence = s.match(/```(?:json)?\s*([\s\S]*?)```/i);
|
|
199
|
-
if (fence?.[1]) s = fence[1].trim();
|
|
200
|
-
const start = s.indexOf("{");
|
|
201
|
-
const end = s.lastIndexOf("}");
|
|
202
|
-
if (start === -1 || end === -1 || end <= start) return null;
|
|
203
|
-
try {
|
|
204
|
-
const parsed = JSON.parse(s.slice(start, end + 1));
|
|
205
|
-
if (typeof parsed !== "object" || parsed === null) return null;
|
|
206
|
-
return {
|
|
207
|
-
summary: String(parsed.summary ?? ""),
|
|
208
|
-
metrics: Array.isArray(parsed.metrics) ? parsed.metrics : [],
|
|
209
|
-
needsBugs: Array.isArray(parsed.needsBugs) ? parsed.needsBugs : [],
|
|
210
|
-
};
|
|
211
|
-
} catch {
|
|
212
|
-
return null;
|
|
213
|
-
}
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
// ─── 日期工具 ──────────────────────────────────────────
|
|
217
|
-
|
|
218
|
-
/** 某时区当前时刻的墙上日期(YYYY-MM-DD) */
|
|
219
|
-
function zonedDateParts(date: Date, timeZone: string): { year: number; month: number; day: number } {
|
|
220
|
-
const parts = new Intl.DateTimeFormat("en-CA", { timeZone, year: "numeric", month: "2-digit", day: "2-digit" }).formatToParts(date);
|
|
221
|
-
const pick = (t: string) => Number(parts.find((p) => p.type === t)!.value);
|
|
222
|
-
return { year: pick("year"), month: pick("month"), day: pick("day") };
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
/** 某时区在给定瞬间的 UTC 偏移(ms);用于把墙上时间换算成 UTC 瞬间 */
|
|
226
|
-
function tzOffsetMs(date: Date, timeZone: string): number {
|
|
227
|
-
const parts = new Intl.DateTimeFormat("en-US", {
|
|
228
|
-
timeZone,
|
|
229
|
-
hour12: false,
|
|
230
|
-
year: "numeric",
|
|
231
|
-
month: "2-digit",
|
|
232
|
-
day: "2-digit",
|
|
233
|
-
hour: "2-digit",
|
|
234
|
-
minute: "2-digit",
|
|
235
|
-
second: "2-digit",
|
|
236
|
-
}).formatToParts(date);
|
|
237
|
-
const map: Record<string, number> = {};
|
|
238
|
-
for (const p of parts) if (p.type !== "literal") map[p.type] = Number(p.value);
|
|
239
|
-
const hour = map.hour === 24 ? 0 : map.hour;
|
|
240
|
-
const asUTC = Date.UTC(map.year, map.month - 1, map.day, hour, map.minute, map.second);
|
|
241
|
-
return asUTC - date.getTime();
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
/** 把某时区的墙上时间转成 UTC ISO;迭代一次修正跨 DST 边界的偏移 */
|
|
245
|
-
function zonedWallClockToUtc(y: number, mon: number, d: number, h: number, min: number, s: number, ms: number, timeZone: string): string {
|
|
246
|
-
// 偏移与毫秒无关,且 formatToParts 不保留毫秒,故先置 0 算偏移再补回 ms
|
|
247
|
-
const guess = Date.UTC(y, mon, d, h, min, s, 0);
|
|
248
|
-
const offset = tzOffsetMs(new Date(guess), timeZone);
|
|
249
|
-
return new Date(guess - offset + ms).toISOString();
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
/**
|
|
253
|
-
* 计算指定时区下"昨天"的 [00:00:00, 23:59:59.999] 对应的 UTC ISO 区间。
|
|
254
|
-
* 用 Intl 取时区墙上日期,避免运行环境时区(如远端 UTC 机器)导致"昨天"错位。
|
|
255
|
-
*/
|
|
256
|
-
function yesterdayRange(timeZone: string): { since: string; until: string; dateStr: string } {
|
|
257
|
-
const today = zonedDateParts(new Date(), timeZone);
|
|
258
|
-
// 用 UTC 运算减一天,避开 DST/月末边界问题
|
|
259
|
-
const y = new Date(Date.UTC(today.year, today.month - 1, today.day) - 86_400_000);
|
|
260
|
-
const yy = y.getUTCFullYear();
|
|
261
|
-
const mm = y.getUTCMonth();
|
|
262
|
-
const dd = y.getUTCDate();
|
|
263
|
-
const dateStr = `${yy}-${String(mm + 1).padStart(2, "0")}-${String(dd).padStart(2, "0")}`;
|
|
264
|
-
const since = zonedWallClockToUtc(yy, mm, dd, 0, 0, 0, 0, timeZone);
|
|
265
|
-
const until = zonedWallClockToUtc(yy, mm, dd, 23, 59, 59, 999, timeZone);
|
|
266
|
-
return { since, until, dateStr };
|
|
267
|
-
}
|
|
268
|
-
|
|
269
|
-
// ─── 消息格式化 ────────────────────────────────────────
|
|
270
|
-
|
|
271
|
-
function formatMessages(conversationId: string, entries: MemoryEntry[]): string {
|
|
272
|
-
const lines = entries.map((e) => {
|
|
273
|
-
const ts = e.timestamp.slice(11, 16); // HH:mm
|
|
274
|
-
const sender = String(e.meta?.sender ?? "未知");
|
|
275
|
-
const role = e.meta?.role ? `/${String(e.meta.role)}` : "";
|
|
276
|
-
return `[${ts}] ${sender}${role} <${e.kind}>: ${e.content}`;
|
|
277
|
-
});
|
|
278
|
-
return `### 群: ${conversationId}\n${lines.join("\n")}`;
|
|
279
|
-
}
|
|
280
|
-
|
|
281
|
-
// ─── Recipe 定义 ───────────────────────────────────────
|
|
282
|
-
|
|
283
|
-
const recipe: RecipeDefinition = {
|
|
284
|
-
meta: {
|
|
285
|
-
id: "daily_review",
|
|
286
|
-
name: "每日复盘",
|
|
287
|
-
role: "daily-review",
|
|
288
|
-
description: "读取昨日群短期记忆 → coding.run 压缩/统计/抽取 → 写长期记忆+统计表+需求池",
|
|
289
|
-
version: "1.0.0",
|
|
290
|
-
requiresAgent: true,
|
|
291
|
-
config: z.object({
|
|
292
|
-
conversation_ids: z.union([z.array(z.string()), z.string()]).describe("复盘群来源:静态 conversationId 数组,或引用 ${globalVar.group_configs}(二选一,无隐式回退)"),
|
|
293
|
-
daily_stats_table: tableRefConfigSchema({
|
|
294
|
-
label: "每日统计表",
|
|
295
|
-
description: "每日统计表(upsertRecordIn 写入)",
|
|
296
|
-
access: "write",
|
|
297
|
-
ownership: "owned",
|
|
298
|
-
autoCreate: true,
|
|
299
|
-
defaultBase: "workflow.tracker.base_id",
|
|
300
|
-
setupSchema: {
|
|
301
|
-
fields: [
|
|
302
|
-
{ name: "统计键", type: "text" },
|
|
303
|
-
{ name: "统计日期", type: "text" },
|
|
304
|
-
{ name: "群ID", type: "text" },
|
|
305
|
-
{ name: "提问题数", type: "number" },
|
|
306
|
-
{ name: "Agent回复数", type: "number" },
|
|
307
|
-
{ name: "已知错误回复数", type: "number" },
|
|
308
|
-
{ name: "真人回复数", type: "number" },
|
|
309
|
-
{ name: "已回复数", type: "number" },
|
|
310
|
-
{ name: "未回复数", type: "number" },
|
|
311
|
-
{ name: "静默数", type: "number" },
|
|
312
|
-
{ name: "发送失败数", type: "number" },
|
|
313
|
-
{ name: "知识库未覆盖数", type: "number" },
|
|
314
|
-
{ name: "需求数", type: "number" },
|
|
315
|
-
{ name: "Bug数", type: "number" },
|
|
316
|
-
{ name: "服务用户数", type: "number" },
|
|
317
|
-
{ name: "平均首次响应分钟", type: "number" },
|
|
318
|
-
{ name: "节省工时", type: "number" },
|
|
319
|
-
{ name: "摘要内容", type: "text" },
|
|
320
|
-
],
|
|
321
|
-
},
|
|
322
|
-
}),
|
|
323
|
-
product_backlog_table: tableRefConfigSchema({
|
|
324
|
-
label: "产品需求池",
|
|
325
|
-
description: "产品需求池(createRecordsIn 写入)",
|
|
326
|
-
access: "write",
|
|
327
|
-
ownership: "owned",
|
|
328
|
-
autoCreate: true,
|
|
329
|
-
defaultBase: "workflow.tracker.base_id",
|
|
330
|
-
setupSchema: {
|
|
331
|
-
fields: [
|
|
332
|
-
{ name: "标题", type: "text" },
|
|
333
|
-
{ name: "类型", type: "text" },
|
|
334
|
-
{ name: "描述", type: "text" },
|
|
335
|
-
{ name: "来源消息", type: "text" },
|
|
336
|
-
{ name: "发送人", type: "text" },
|
|
337
|
-
{ name: "来源群", type: "text" },
|
|
338
|
-
{ name: "优先级", type: "text" },
|
|
339
|
-
{ name: "复盘日期", type: "text" },
|
|
340
|
-
{ name: "状态", type: "text" },
|
|
341
|
-
],
|
|
342
|
-
},
|
|
343
|
-
}),
|
|
344
|
-
saved_minutes_per_reply: z.number().optional().describe("每条 Agent 回复节省的人工工时(分钟),默认 15"),
|
|
345
|
-
timezone: z.string().optional().describe("复盘日期计算时区(IANA,如 Asia/Shanghai),应与 cron 的 timezone 一致;默认 Asia/Shanghai。远端 UTC 机器上必须显式设置以避免\"昨天\"错位"),
|
|
346
|
-
}),
|
|
347
|
-
},
|
|
348
|
-
|
|
349
|
-
async execute(ctx: RecipeContext): Promise<RecipeResult> {
|
|
350
|
-
const config = parseConfig(ctx.config);
|
|
351
|
-
|
|
352
|
-
async function run(): Promise<RecipeResult> {
|
|
353
|
-
const { toolkit, log, configDir } = ctx;
|
|
354
|
-
const { memory, table, coding } = toolkit;
|
|
355
|
-
|
|
356
|
-
// 0. 恢复孤儿 processing 文件
|
|
357
|
-
try {
|
|
358
|
-
await memory.recover();
|
|
359
|
-
} catch (err) {
|
|
360
|
-
log(`memory.recover 失败(不影响主流程): ${err}`);
|
|
361
|
-
}
|
|
362
|
-
|
|
363
|
-
// 1. 解析复盘群列表:显式配置静态数组,或引用 ${globalVar.group_configs}(无隐式空回退)
|
|
364
|
-
const conversationIds = resolveConversationIds(config.conversationIds, ctx.getGlobalVar);
|
|
365
|
-
if (conversationIds.length === 0) {
|
|
366
|
-
return { status: "failed", output: {}, error: "daily-review: conversation_ids 不能为空", retryable: false, logs: [] };
|
|
367
|
-
}
|
|
368
|
-
|
|
369
|
-
// 2. 计算昨日时间范围(按配置时区,避免运行环境时区错位)
|
|
370
|
-
const { since, until, dateStr } = yesterdayRange(config.timezone);
|
|
371
|
-
log(`每日复盘开始: 日期=${dateStr}, 时区=${config.timezone}, 群数=${conversationIds.length}`);
|
|
372
|
-
|
|
373
|
-
// 3. 按群读取短期记忆
|
|
374
|
-
const allGroupMessages: string[] = [];
|
|
375
|
-
const groupEntries = new Map<string, MemoryEntry[]>();
|
|
376
|
-
|
|
377
|
-
for (const convId of conversationIds) {
|
|
378
|
-
const scope = handoffScope(convId);
|
|
379
|
-
const entries = await memory.readShortTerm(scope, { since, until, limit: 500 });
|
|
380
|
-
if (entries.length > 0) {
|
|
381
|
-
groupEntries.set(convId, entries);
|
|
382
|
-
allGroupMessages.push(formatMessages(convId, entries));
|
|
383
|
-
log(`群 ${convId}: 读取 ${entries.length} 条短期记忆`);
|
|
384
|
-
} else {
|
|
385
|
-
log(`群 ${convId}: 无短期记忆,跳过`);
|
|
386
|
-
}
|
|
387
|
-
}
|
|
388
|
-
|
|
389
|
-
if (allGroupMessages.length === 0) {
|
|
390
|
-
log("所有群均无短期记忆,每日复盘结束(不留痕)");
|
|
391
|
-
return { status: "success", output: {}, tracker: false, logs: ["无活动"] };
|
|
392
|
-
}
|
|
393
|
-
|
|
394
|
-
// 4. 构建 prompt,调用 coding agent
|
|
395
|
-
const agentWorkDir = path.resolve(configDir, "workspaces/daily-review");
|
|
396
|
-
const prompt = `按【本工作目录下 AGENTS.md 的规范】阅读以下今日所有群的短期记忆消息,完成压缩摘要、统计指标抽取、需求与 Bug 识别。
|
|
397
|
-
|
|
398
|
-
## 今日消息(${dateStr})
|
|
399
|
-
|
|
400
|
-
${allGroupMessages.join("\n\n")}
|
|
401
|
-
|
|
402
|
-
## 输出契约
|
|
403
|
-
|
|
404
|
-
请按 AGENTS.md 的规范输出严格 JSON 对象,包含 summary、metrics、needsBugs 三个字段。`;
|
|
405
|
-
|
|
406
|
-
log(`调用 coding agent (workDir=${agentWorkDir})...`);
|
|
407
|
-
const result = await coding.run(prompt, { workDir: agentWorkDir });
|
|
408
|
-
|
|
409
|
-
if (!result.response) {
|
|
410
|
-
log("coding agent 未产出有效响应,每日复盘终止");
|
|
411
|
-
return { status: "failed", output: {}, error: "coding agent 未产出有效响应", retryable: false, logs: ["coding agent 无响应"] };
|
|
412
|
-
}
|
|
413
|
-
|
|
414
|
-
// 5. 解析 JSON 输出
|
|
415
|
-
const review = extractReviewResult(result.response);
|
|
416
|
-
if (!review) {
|
|
417
|
-
log(`JSON 解析失败,每日复盘终止。原始响应前120字: ${result.response.slice(0, 120)}`);
|
|
418
|
-
return { status: "failed", output: {}, error: "复盘 JSON 解析失败", retryable: false, logs: ["JSON 解析失败"] };
|
|
419
|
-
}
|
|
420
|
-
|
|
421
|
-
log(`解析成功: summary=${review.summary.length}字, metrics=${review.metrics.length}组, needsBugs=${review.needsBugs.length}条`);
|
|
422
|
-
const metrics = Array.from(groupEntries.entries()).map(([convId, entries]) =>
|
|
423
|
-
computeDeterministicMetric(convId, entries, review.needsBugs),
|
|
424
|
-
);
|
|
425
|
-
|
|
426
|
-
// 6. 写共享长期记忆(不含 conversationId,所有群共用)
|
|
427
|
-
// sourceScopes 负责从各群读取并 checkpoint 短期记忆,targetScope 只承载共享 long-term.md。
|
|
428
|
-
const sharedScope: MemoryScope = {
|
|
429
|
-
...handoffScope(),
|
|
430
|
-
};
|
|
431
|
-
const sourceScopes: MemoryScope[] = Array.from(groupEntries.keys()).map((convId) => handoffScope(convId));
|
|
432
|
-
try {
|
|
433
|
-
const compactResult = await memory.compact(sharedScope, {
|
|
434
|
-
summary: review.summary,
|
|
435
|
-
sourceScopes,
|
|
436
|
-
query: { since, until },
|
|
437
|
-
});
|
|
438
|
-
log(`长期记忆写入成功: 压缩 ${compactResult.entryCount} 条短期记忆`);
|
|
439
|
-
} catch (err) {
|
|
440
|
-
log(`memory.compact 失败(不影响后续写表): ${err}`);
|
|
441
|
-
}
|
|
442
|
-
|
|
443
|
-
// 7. 写每日统计表(按群 upsert)
|
|
444
|
-
if (!config.dailyStatsTable) {
|
|
445
|
-
log("daily_stats_table 未配置,跳过每日统计表写入");
|
|
446
|
-
}
|
|
447
|
-
for (const metric of metrics) {
|
|
448
|
-
if (!config.dailyStatsTable) continue;
|
|
449
|
-
const statsKey = `${dateStr}_${metric.conversationId}`;
|
|
450
|
-
const agentAnsweredCount = num(metric.agentAnsweredCount);
|
|
451
|
-
const knownErrorAnsweredCount = num(metric.knownErrorAnsweredCount);
|
|
452
|
-
const humanAnsweredCount = num(metric.humanAnsweredCount);
|
|
453
|
-
const answeredCount = num(metric.answeredCount, agentAnsweredCount + knownErrorAnsweredCount + humanAnsweredCount);
|
|
454
|
-
const automatedAnsweredCount = agentAnsweredCount + knownErrorAnsweredCount || answeredCount;
|
|
455
|
-
const savedHours = Math.round(
|
|
456
|
-
automatedAnsweredCount * config.savedMinutesPerReply * 100 / 60,
|
|
457
|
-
) / 100;
|
|
458
|
-
|
|
459
|
-
try {
|
|
460
|
-
await table.upsertRecordIn(config.dailyStatsTable, "统计键", {
|
|
461
|
-
"统计键": statsKey,
|
|
462
|
-
"统计日期": dateStr,
|
|
463
|
-
"群ID": metric.conversationId,
|
|
464
|
-
"提问题数": num(metric.questionCount),
|
|
465
|
-
"Agent回复数": agentAnsweredCount,
|
|
466
|
-
"已知错误回复数": knownErrorAnsweredCount,
|
|
467
|
-
"真人回复数": humanAnsweredCount,
|
|
468
|
-
"已回复数": answeredCount,
|
|
469
|
-
"未回复数": num(metric.unansweredCount),
|
|
470
|
-
"静默数": num(metric.silentCount),
|
|
471
|
-
"发送失败数": num(metric.sendFailedCount),
|
|
472
|
-
"知识库未覆盖数": num(metric.kbMissCount),
|
|
473
|
-
"需求数": num(metric.demandCount),
|
|
474
|
-
"Bug数": num(metric.bugCount),
|
|
475
|
-
"服务用户数": num(metric.servedUsers),
|
|
476
|
-
"平均首次响应分钟": num(metric.avgFirstResponseMinutes),
|
|
477
|
-
"节省工时": savedHours,
|
|
478
|
-
"摘要内容": review.summary,
|
|
479
|
-
});
|
|
480
|
-
log(`每日统计表 upsert 成功: ${statsKey} (提问题数=${metric.questionCount}, 节省工时=${savedHours})`);
|
|
481
|
-
} catch (err) {
|
|
482
|
-
log(`每日统计表 upsert 失败: ${statsKey}: ${err}`);
|
|
483
|
-
}
|
|
484
|
-
}
|
|
485
|
-
|
|
486
|
-
// 8. 写产品需求池(批量 create)
|
|
487
|
-
if (!config.productBacklogTable) {
|
|
488
|
-
log("product_backlog_table 未配置,跳过产品需求池写入");
|
|
489
|
-
} else if (review.needsBugs.length > 0) {
|
|
490
|
-
const rows = review.needsBugs.map((item) => ({
|
|
491
|
-
"标题": String(item.title ?? ""),
|
|
492
|
-
"类型": String(item.type ?? "需求"),
|
|
493
|
-
"描述": String(item.description ?? ""),
|
|
494
|
-
"来源消息": String(item.sourceMessage ?? ""),
|
|
495
|
-
"发送人": String(item.sender ?? ""),
|
|
496
|
-
"来源群": String(item.sourceGroup ?? ""),
|
|
497
|
-
"优先级": String(item.priority ?? "中"),
|
|
498
|
-
"复盘日期": dateStr,
|
|
499
|
-
"状态": "待处理",
|
|
500
|
-
}));
|
|
501
|
-
|
|
502
|
-
try {
|
|
503
|
-
const createResult = await table.createRecordsIn(config.productBacklogTable, rows);
|
|
504
|
-
log(`产品需求池写入成功: ${createResult.recordIds.length} 条`);
|
|
505
|
-
} catch (err) {
|
|
506
|
-
log(`产品需求池写入失败: ${err}`);
|
|
507
|
-
}
|
|
508
|
-
} else {
|
|
509
|
-
log("无需求/Bug 需要写入");
|
|
510
|
-
}
|
|
511
|
-
|
|
512
|
-
log("每日复盘完成");
|
|
513
|
-
return {
|
|
514
|
-
status: "success",
|
|
515
|
-
output: {
|
|
516
|
-
review_date: dateStr,
|
|
517
|
-
group_count: String(groupEntries.size),
|
|
518
|
-
needs_bug_count: String(review.needsBugs.length),
|
|
519
|
-
summary: review.summary,
|
|
520
|
-
},
|
|
521
|
-
logs: [`群 ${groupEntries.size}`, `需求Bug ${review.needsBugs.length}`],
|
|
522
|
-
};
|
|
523
|
-
}
|
|
524
|
-
|
|
525
|
-
return run();
|
|
526
|
-
},
|
|
527
|
-
};
|
|
528
|
-
|
|
529
|
-
export default recipe;
|
package/templates/aitable-handoff/workflows/daily-review/recipes/daily_review_handler.recipe.ts
DELETED
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
import type { EventHandlerRecipeDefinition, HandlerInitContext, HandlerInstance } from "aitable-workflow-core";
|
|
2
|
-
|
|
3
|
-
/** cron tick → 建一条每日复盘工单(实际复盘逻辑在 daily_review step recipe) */
|
|
4
|
-
const recipe: EventHandlerRecipeDefinition = {
|
|
5
|
-
meta: { id: "daily_review_handler", name: "每日复盘触发器", description: "cron tick → 建一条每日复盘工单" },
|
|
6
|
-
create(ctx: HandlerInitContext): HandlerInstance {
|
|
7
|
-
return {
|
|
8
|
-
onEvent(event) {
|
|
9
|
-
const firedAt = String(event.payload?.firedAt ?? new Date().toISOString());
|
|
10
|
-
// cron 事件携带调度时区与预定时刻;按时区取运行日期,避免 UTC 运行环境下标题日期错位
|
|
11
|
-
const timezone = typeof event.payload?.timezone === "string" ? (event.payload.timezone as string) : "Asia/Shanghai";
|
|
12
|
-
const scheduledFor = String(event.payload?.scheduledFor ?? firedAt);
|
|
13
|
-
let dateStr: string;
|
|
14
|
-
try {
|
|
15
|
-
dateStr = new Intl.DateTimeFormat("en-CA", { timeZone: timezone, year: "numeric", month: "2-digit", day: "2-digit" }).format(new Date(scheduledFor));
|
|
16
|
-
} catch {
|
|
17
|
-
dateStr = scheduledFor.slice(0, 10); // 时区非法时回退
|
|
18
|
-
}
|
|
19
|
-
ctx.log(`每日复盘触发 @ ${firedAt} (tz=${timezone}, 运行日=${dateStr})`);
|
|
20
|
-
ctx.pushEvent({ action: "create_record", fields: { "标题": `每日复盘 ${dateStr}` } });
|
|
21
|
-
},
|
|
22
|
-
stop() {},
|
|
23
|
-
};
|
|
24
|
-
},
|
|
25
|
-
};
|
|
26
|
-
export default recipe;
|
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
// ⚠️ 与 group-qa/recipes/memory-events.ts 保持一致:scope 常量(channel/scenario)必须相同,否则读不到同一份记忆。
|
|
2
|
-
import type { MemoryEntry, MemoryScope } from "aitable-workflow-core";
|
|
3
|
-
|
|
4
|
-
export const HANDOFF_SCENARIO = "aitable-handoff";
|
|
5
|
-
export const HANDOFF_CHANNEL = "dingtalk";
|
|
6
|
-
|
|
7
|
-
export const HANDOFF_MEMORY_KINDS = {
|
|
8
|
-
userMessage: "user_message",
|
|
9
|
-
humanReply: "human_reply",
|
|
10
|
-
agentDecision: "agent_decision",
|
|
11
|
-
agentReplySent: "agent_reply_sent",
|
|
12
|
-
knownErrorReplySent: "known_error_reply_sent",
|
|
13
|
-
sendFailed: "send_failed",
|
|
14
|
-
} as const;
|
|
15
|
-
|
|
16
|
-
export type HandoffMemoryKind = typeof HANDOFF_MEMORY_KINDS[keyof typeof HANDOFF_MEMORY_KINDS];
|
|
17
|
-
|
|
18
|
-
export const HANDOFF_MEMORY_ROLES = {
|
|
19
|
-
user: "user",
|
|
20
|
-
human: "human",
|
|
21
|
-
agent: "agent",
|
|
22
|
-
} as const;
|
|
23
|
-
|
|
24
|
-
export type HandoffMemoryRole = typeof HANDOFF_MEMORY_ROLES[keyof typeof HANDOFF_MEMORY_ROLES];
|
|
25
|
-
|
|
26
|
-
export function handoffScope(conversationId?: string): MemoryScope {
|
|
27
|
-
return {
|
|
28
|
-
channel: HANDOFF_CHANNEL,
|
|
29
|
-
scenario: HANDOFF_SCENARIO,
|
|
30
|
-
...(conversationId ? { conversationId } : {}),
|
|
31
|
-
};
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
export function handoffEntry(args: {
|
|
35
|
-
kind: HandoffMemoryKind;
|
|
36
|
-
content: string;
|
|
37
|
-
sender: string;
|
|
38
|
-
role: HandoffMemoryRole;
|
|
39
|
-
conversationId: string;
|
|
40
|
-
timestamp?: string;
|
|
41
|
-
summary?: string;
|
|
42
|
-
meta?: Record<string, unknown>;
|
|
43
|
-
}): MemoryEntry {
|
|
44
|
-
return {
|
|
45
|
-
timestamp: args.timestamp ?? new Date().toISOString(),
|
|
46
|
-
kind: args.kind,
|
|
47
|
-
content: args.content,
|
|
48
|
-
summary: args.summary ?? `${args.sender}: ${args.content.slice(0, 80)}`,
|
|
49
|
-
meta: {
|
|
50
|
-
sender: args.sender,
|
|
51
|
-
role: args.role,
|
|
52
|
-
conversationId: args.conversationId,
|
|
53
|
-
...args.meta,
|
|
54
|
-
},
|
|
55
|
-
};
|
|
56
|
-
}
|