@rubytech/create-maxy-code 0.1.601 → 0.1.602
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 +1 -1
- package/payload/platform/plugins/admin/hooks/video-frames-inject.sh +141 -0
- package/payload/platform/plugins/admin/skills/platform-architecture/SKILL.md +5 -1
- package/payload/platform/plugins/admin/skills/whats-new/SKILL.md +6 -0
- package/payload/platform/plugins/docs/references/admin-ui.md +2 -0
- package/payload/platform/plugins/docs/references/telegram-guide.md +2 -0
- package/payload/platform/plugins/scheduling/PLUGIN.md +2 -0
- package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/gate-audits.test.js +67 -1
- package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/gate-audits.test.js.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/gate.test.js +89 -1
- package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/gate.test.js.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/outage-marker.test.d.ts +2 -0
- package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/outage-marker.test.d.ts.map +1 -0
- package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/outage-marker.test.js +160 -0
- package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/outage-marker.test.js.map +1 -0
- package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/routine-run.test.js +16 -0
- package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/routine-run.test.js.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/lib/gate.d.ts +31 -1
- package/payload/platform/plugins/scheduling/mcp/dist/lib/gate.d.ts.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/lib/gate.js +42 -4
- package/payload/platform/plugins/scheduling/mcp/dist/lib/gate.js.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/lib/outage-marker.d.ts +101 -0
- package/payload/platform/plugins/scheduling/mcp/dist/lib/outage-marker.d.ts.map +1 -0
- package/payload/platform/plugins/scheduling/mcp/dist/lib/outage-marker.js +130 -0
- package/payload/platform/plugins/scheduling/mcp/dist/lib/outage-marker.js.map +1 -0
- package/payload/platform/plugins/scheduling/mcp/dist/lib/routine-run.d.ts +10 -1
- package/payload/platform/plugins/scheduling/mcp/dist/lib/routine-run.d.ts.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/lib/routine-run.js.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/lib/schedule-audit.d.ts +24 -0
- package/payload/platform/plugins/scheduling/mcp/dist/lib/schedule-audit.d.ts.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/lib/schedule-audit.js +89 -0
- package/payload/platform/plugins/scheduling/mcp/dist/lib/schedule-audit.js.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/scripts/__tests__/agent-turn-dispatch.test.js +67 -1
- package/payload/platform/plugins/scheduling/mcp/dist/scripts/__tests__/agent-turn-dispatch.test.js.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/scripts/__tests__/gate-dispatch-wiring.test.js +31 -0
- package/payload/platform/plugins/scheduling/mcp/dist/scripts/__tests__/gate-dispatch-wiring.test.js.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/scripts/agent-turn-dispatch.d.ts +10 -1
- package/payload/platform/plugins/scheduling/mcp/dist/scripts/agent-turn-dispatch.d.ts.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/scripts/agent-turn-dispatch.js +46 -1
- package/payload/platform/plugins/scheduling/mcp/dist/scripts/agent-turn-dispatch.js.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/scripts/check-due-events.js +72 -4
- package/payload/platform/plugins/scheduling/mcp/dist/scripts/check-due-events.js.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/tools/__tests__/scheduling-gate.test.js +81 -4
- package/payload/platform/plugins/scheduling/mcp/dist/tools/__tests__/scheduling-gate.test.js.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/tools/scheduling-gate.d.ts +50 -0
- package/payload/platform/plugins/scheduling/mcp/dist/tools/scheduling-gate.d.ts.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/tools/scheduling-gate.js +48 -7
- package/payload/platform/plugins/scheduling/mcp/dist/tools/scheduling-gate.js.map +1 -1
- package/payload/platform/plugins/telegram/PLUGIN.md +4 -0
- package/payload/platform/plugins/telegram/mcp/dist/__tests__/public-pin-registry.test.js +33 -1
- package/payload/platform/plugins/telegram/mcp/dist/__tests__/public-pin-registry.test.js.map +1 -1
- package/payload/platform/plugins/telegram/mcp/dist/__tests__/public-pin.test.js +166 -1
- package/payload/platform/plugins/telegram/mcp/dist/__tests__/public-pin.test.js.map +1 -1
- package/payload/platform/plugins/telegram/mcp/dist/index.js +39 -14
- package/payload/platform/plugins/telegram/mcp/dist/index.js.map +1 -1
- package/payload/platform/plugins/telegram/mcp/dist/lib/public-pin.d.ts +95 -0
- package/payload/platform/plugins/telegram/mcp/dist/lib/public-pin.d.ts.map +1 -1
- package/payload/platform/plugins/telegram/mcp/dist/lib/public-pin.js +125 -0
- package/payload/platform/plugins/telegram/mcp/dist/lib/public-pin.js.map +1 -1
- package/payload/platform/services/telegram-channel/dist/notification.d.ts +6 -0
- package/payload/platform/services/telegram-channel/dist/notification.d.ts.map +1 -1
- package/payload/platform/services/telegram-channel/dist/notification.js +12 -5
- package/payload/platform/services/telegram-channel/dist/notification.js.map +1 -1
- package/payload/platform/services/whatsapp-channel/dist/notification.d.ts +5 -0
- package/payload/platform/services/whatsapp-channel/dist/notification.d.ts.map +1 -1
- package/payload/platform/services/whatsapp-channel/dist/notification.js +9 -3
- package/payload/platform/services/whatsapp-channel/dist/notification.js.map +1 -1
- package/payload/platform/templates/account-settings.json +6 -0
- package/payload/server/chunk-CYU75QAV.js +377 -0
- package/payload/server/{chunk-34FPJYHN.js → chunk-GI5AVCRG.js} +87 -146
- package/payload/server/chunk-KUVNCAE4.js +77 -0
- package/payload/server/{manager-7BXVB76I.js → manager-VDHT3YYI.js} +2 -1
- package/payload/server/maxy-edge.js +33 -1
- package/payload/server/public/activity.html +6 -6
- package/payload/server/public/agents.html +5 -5
- package/payload/server/public/assets/{AdminLoginScreens-B3W6J6Bl.js → AdminLoginScreens-CaQqLuxZ.js} +1 -1
- package/payload/server/public/assets/AdminLoginScreens-CaQqLuxZ.js.br +0 -0
- package/payload/server/public/assets/AdminLoginScreens-CaQqLuxZ.js.gz +0 -0
- package/payload/server/public/assets/{AdminShell-C3R-vMZ5.js → AdminShell-D8WTrqem.js} +1 -1
- package/payload/server/public/assets/AdminShell-D8WTrqem.js.br +0 -0
- package/payload/server/public/assets/AdminShell-D8WTrqem.js.gz +0 -0
- package/payload/server/public/assets/{activity-tzv68iBs.js → activity-B3fiJrC2.js} +1 -1
- package/payload/server/public/assets/activity-B3fiJrC2.js.br +0 -0
- package/payload/server/public/assets/activity-B3fiJrC2.js.gz +0 -0
- package/payload/server/public/assets/admin-ouF-DflP.js +1 -0
- package/payload/server/public/assets/admin-ouF-DflP.js.br +0 -0
- package/payload/server/public/assets/admin-ouF-DflP.js.gz +0 -0
- package/payload/server/public/assets/{agents-DUZfeY3X.js → agents-C8RSXHdh.js} +1 -1
- package/payload/server/public/assets/agents-C8RSXHdh.js.br +0 -0
- package/payload/server/public/assets/agents-C8RSXHdh.js.gz +0 -0
- package/payload/server/public/assets/{browser-DwLaXqjO.js → browser-Dbv6-Rag.js} +1 -1
- package/payload/server/public/assets/browser-Dbv6-Rag.js.br +0 -0
- package/payload/server/public/assets/browser-Dbv6-Rag.js.gz +0 -0
- package/payload/server/public/assets/{calendar-Cli8Qjl9.js → calendar-vJjtsH9n.js} +1 -1
- package/payload/server/public/assets/calendar-vJjtsH9n.js.br +0 -0
- package/payload/server/public/assets/calendar-vJjtsH9n.js.gz +0 -0
- package/payload/server/public/assets/chat-cqL4qPUy.js +1 -0
- package/payload/server/public/assets/chat-cqL4qPUy.js.br +1 -0
- package/payload/server/public/assets/chat-cqL4qPUy.js.gz +0 -0
- package/payload/server/public/assets/chevron-left-DB98DSG3.js +1 -0
- package/payload/server/public/assets/chevron-left-DB98DSG3.js.br +0 -0
- package/payload/server/public/assets/clock-4YwsYe4L.js +1 -0
- package/payload/server/public/assets/clock-4YwsYe4L.js.br +0 -0
- package/payload/server/public/assets/clock-4YwsYe4L.js.gz +0 -0
- package/payload/server/public/assets/{copy-yhhwfEbQ.js → copy-DyG7sC5o.js} +1 -1
- package/payload/server/public/assets/copy-DyG7sC5o.js.br +0 -0
- package/payload/server/public/assets/copy-DyG7sC5o.js.gz +0 -0
- package/payload/server/public/assets/data-BAzLtx9C.js +1 -0
- package/payload/server/public/assets/data-BAzLtx9C.js.br +0 -0
- package/payload/server/public/assets/data-BAzLtx9C.js.gz +0 -0
- package/payload/server/public/assets/{field-jg0YQNDy.js → field-Bx6pM-vq.js} +1 -1
- package/payload/server/public/assets/field-Bx6pM-vq.js.br +0 -0
- package/payload/server/public/assets/field-Bx6pM-vq.js.gz +0 -0
- package/payload/server/public/assets/{file-text-D0EdW7h4.js → file-text-CpHWsMGe.js} +1 -1
- package/payload/server/public/assets/file-text-CpHWsMGe.js.br +0 -0
- package/payload/server/public/assets/file-text-CpHWsMGe.js.gz +0 -0
- package/payload/server/public/assets/{graph--AUr4uBc.js → graph-DjOywuv_.js} +1 -1
- package/payload/server/public/assets/graph-DjOywuv_.js.br +0 -0
- package/payload/server/public/assets/graph-DjOywuv_.js.gz +0 -0
- package/payload/server/public/assets/{graph-labels-DM0CiAX1.js → graph-labels-CGWtqa-m.js} +1 -1
- package/payload/server/public/assets/graph-labels-CGWtqa-m.js.br +0 -0
- package/payload/server/public/assets/graph-labels-CGWtqa-m.js.gz +0 -0
- package/payload/server/public/assets/{jsx-runtime-lfcjzaWi.css → jsx-runtime-D75_aR1J.css} +1 -1
- package/payload/server/public/assets/jsx-runtime-D75_aR1J.css.br +0 -0
- package/payload/server/public/assets/{jsx-runtime-lfcjzaWi.css.gz → jsx-runtime-D75_aR1J.css.gz} +0 -0
- package/payload/server/public/assets/{operator-CNYKStFX.js → operator-_DN0RF1R.js} +1 -1
- package/payload/server/public/assets/operator-_DN0RF1R.js.br +0 -0
- package/payload/server/public/assets/operator-_DN0RF1R.js.gz +0 -0
- package/payload/server/public/assets/page-DI4qQIK0.js +1 -0
- package/payload/server/public/assets/page-DI4qQIK0.js.br +0 -0
- package/payload/server/public/assets/page-DI4qQIK0.js.gz +0 -0
- package/payload/server/public/assets/page-zCwgrs8m.js +32 -0
- package/payload/server/public/assets/page-zCwgrs8m.js.br +0 -0
- package/payload/server/public/assets/page-zCwgrs8m.js.gz +0 -0
- package/payload/server/public/assets/play-CHQ5a9yh.js +1 -0
- package/payload/server/public/assets/play-CHQ5a9yh.js.br +0 -0
- package/payload/server/public/assets/play-CHQ5a9yh.js.gz +0 -0
- package/payload/server/public/assets/{public-7gXDqCog.js → public-DDVWBNSH.js} +1 -1
- package/payload/server/public/assets/public-DDVWBNSH.js.br +0 -0
- package/payload/server/public/assets/public-DDVWBNSH.js.gz +0 -0
- package/payload/server/public/assets/{rotate-ccw-DhqNTPpo.js → rotate-ccw-xTwkf-m7.js} +1 -1
- package/payload/server/public/assets/rotate-ccw-xTwkf-m7.js.br +0 -0
- package/payload/server/public/assets/rotate-ccw-xTwkf-m7.js.gz +0 -0
- package/payload/server/public/assets/{routines-DN_yDtEj.js → routines-Bu5MdNmG.js} +1 -1
- package/payload/server/public/assets/routines-Bu5MdNmG.js.br +0 -0
- package/payload/server/public/assets/routines-Bu5MdNmG.js.gz +0 -0
- package/payload/server/public/assets/{skills-pb_3BdOl.js → skills-DRunh5vy.js} +1 -1
- package/payload/server/public/assets/skills-DRunh5vy.js.br +0 -0
- package/payload/server/public/assets/skills-DRunh5vy.js.gz +0 -0
- package/payload/server/public/assets/{tasks-BQm4boat.js → tasks-DI2fznvd.js} +1 -1
- package/payload/server/public/assets/tasks-DI2fznvd.js.br +0 -0
- package/payload/server/public/assets/tasks-DI2fznvd.js.gz +0 -0
- package/payload/server/public/assets/{triangle-alert-d7yjaIqv.js → triangle-alert-B6CHZeUf.js} +1 -1
- package/payload/server/public/assets/triangle-alert-B6CHZeUf.js.br +0 -0
- package/payload/server/public/assets/triangle-alert-B6CHZeUf.js.gz +0 -0
- package/payload/server/public/assets/{useCopyFeedback-CZ6Qhfkj.js → useCopyFeedback-6rU2IEPk.js} +1 -1
- package/payload/server/public/assets/useCopyFeedback-6rU2IEPk.js.br +2 -0
- package/payload/server/public/assets/useCopyFeedback-6rU2IEPk.js.gz +0 -0
- package/payload/server/public/assets/{useMediaQuery-R1smYLx4.js → useMediaQuery-D7A5Bzs3.js} +1 -1
- package/payload/server/public/assets/useMediaQuery-D7A5Bzs3.js.br +0 -0
- package/payload/server/public/assets/useMediaQuery-D7A5Bzs3.js.gz +0 -0
- package/payload/server/public/assets/useVoiceRecorder-CptrerVA.js +2 -0
- package/payload/server/public/assets/useVoiceRecorder-CptrerVA.js.br +0 -0
- package/payload/server/public/assets/useVoiceRecorder-CptrerVA.js.gz +0 -0
- package/payload/server/public/assets/{wrench-DL1pbaCs.js → wrench-DyX4C8aY.js} +1 -1
- package/payload/server/public/assets/wrench-DyX4C8aY.js.br +0 -0
- package/payload/server/public/assets/wrench-DyX4C8aY.js.gz +0 -0
- package/payload/server/public/browser.html +5 -5
- package/payload/server/public/calendar.html +8 -8
- package/payload/server/public/chat.html +14 -14
- package/payload/server/public/data.html +12 -12
- package/payload/server/public/field.html +3 -3
- package/payload/server/public/graph.html +10 -10
- package/payload/server/public/index.html +14 -14
- package/payload/server/public/operator.html +15 -15
- package/payload/server/public/public.html +14 -14
- package/payload/server/public/routines.html +8 -8
- package/payload/server/public/skills.html +6 -6
- package/payload/server/public/tasks.html +7 -7
- package/payload/server/server.js +634 -461
- package/payload/server/video-extract.js +36 -0
- package/payload/server/public/assets/AdminLoginScreens-B3W6J6Bl.js.br +0 -0
- package/payload/server/public/assets/AdminLoginScreens-B3W6J6Bl.js.gz +0 -0
- package/payload/server/public/assets/AdminShell-C3R-vMZ5.js.br +0 -0
- package/payload/server/public/assets/AdminShell-C3R-vMZ5.js.gz +0 -0
- package/payload/server/public/assets/activity-tzv68iBs.js.br +0 -0
- package/payload/server/public/assets/activity-tzv68iBs.js.gz +0 -0
- package/payload/server/public/assets/admin-CzW_9jm3.js +0 -1
- package/payload/server/public/assets/admin-CzW_9jm3.js.br +0 -0
- package/payload/server/public/assets/admin-CzW_9jm3.js.gz +0 -0
- package/payload/server/public/assets/agents-DUZfeY3X.js.br +0 -0
- package/payload/server/public/assets/agents-DUZfeY3X.js.gz +0 -0
- package/payload/server/public/assets/browser-DwLaXqjO.js.br +0 -0
- package/payload/server/public/assets/browser-DwLaXqjO.js.gz +0 -0
- package/payload/server/public/assets/calendar-Cli8Qjl9.js.br +0 -0
- package/payload/server/public/assets/calendar-Cli8Qjl9.js.gz +0 -0
- package/payload/server/public/assets/chat-ByAgBgm1.js +0 -1
- package/payload/server/public/assets/chat-ByAgBgm1.js.br +0 -1
- package/payload/server/public/assets/chat-ByAgBgm1.js.gz +0 -0
- package/payload/server/public/assets/chevron-left-BIYVnwvk.js +0 -1
- package/payload/server/public/assets/chevron-left-BIYVnwvk.js.br +0 -0
- package/payload/server/public/assets/clock-Dzy79hq3.js +0 -1
- package/payload/server/public/assets/clock-Dzy79hq3.js.br +0 -0
- package/payload/server/public/assets/clock-Dzy79hq3.js.gz +0 -0
- package/payload/server/public/assets/copy-yhhwfEbQ.js.br +0 -0
- package/payload/server/public/assets/copy-yhhwfEbQ.js.gz +0 -0
- package/payload/server/public/assets/data-CsMMki2A.js +0 -1
- package/payload/server/public/assets/data-CsMMki2A.js.br +0 -0
- package/payload/server/public/assets/data-CsMMki2A.js.gz +0 -0
- package/payload/server/public/assets/field-jg0YQNDy.js.br +0 -0
- package/payload/server/public/assets/field-jg0YQNDy.js.gz +0 -0
- package/payload/server/public/assets/file-text-D0EdW7h4.js.br +0 -0
- package/payload/server/public/assets/file-text-D0EdW7h4.js.gz +0 -0
- package/payload/server/public/assets/graph--AUr4uBc.js.br +0 -0
- package/payload/server/public/assets/graph--AUr4uBc.js.gz +0 -0
- package/payload/server/public/assets/graph-labels-DM0CiAX1.js.br +0 -0
- package/payload/server/public/assets/graph-labels-DM0CiAX1.js.gz +0 -0
- package/payload/server/public/assets/jsx-runtime-lfcjzaWi.css.br +0 -0
- package/payload/server/public/assets/operator-CNYKStFX.js.br +0 -0
- package/payload/server/public/assets/operator-CNYKStFX.js.gz +0 -0
- package/payload/server/public/assets/page-DSsEpl8J.js +0 -32
- package/payload/server/public/assets/page-DSsEpl8J.js.br +0 -0
- package/payload/server/public/assets/page-DSsEpl8J.js.gz +0 -0
- package/payload/server/public/assets/page-DjhmwxnY.js +0 -1
- package/payload/server/public/assets/page-DjhmwxnY.js.br +0 -0
- package/payload/server/public/assets/page-DjhmwxnY.js.gz +0 -0
- package/payload/server/public/assets/play-DhZlml5b.js +0 -1
- package/payload/server/public/assets/play-DhZlml5b.js.br +0 -0
- package/payload/server/public/assets/play-DhZlml5b.js.gz +0 -0
- package/payload/server/public/assets/public-7gXDqCog.js.br +0 -0
- package/payload/server/public/assets/public-7gXDqCog.js.gz +0 -0
- package/payload/server/public/assets/rotate-ccw-DhqNTPpo.js.br +0 -0
- package/payload/server/public/assets/rotate-ccw-DhqNTPpo.js.gz +0 -0
- package/payload/server/public/assets/routines-DN_yDtEj.js.br +0 -0
- package/payload/server/public/assets/routines-DN_yDtEj.js.gz +0 -0
- package/payload/server/public/assets/skills-pb_3BdOl.js.br +0 -0
- package/payload/server/public/assets/skills-pb_3BdOl.js.gz +0 -0
- package/payload/server/public/assets/tasks-BQm4boat.js.br +0 -0
- package/payload/server/public/assets/tasks-BQm4boat.js.gz +0 -0
- package/payload/server/public/assets/triangle-alert-d7yjaIqv.js.br +0 -0
- package/payload/server/public/assets/triangle-alert-d7yjaIqv.js.gz +0 -0
- package/payload/server/public/assets/useCopyFeedback-CZ6Qhfkj.js.br +0 -0
- package/payload/server/public/assets/useCopyFeedback-CZ6Qhfkj.js.gz +0 -0
- package/payload/server/public/assets/useMediaQuery-R1smYLx4.js.br +0 -0
- package/payload/server/public/assets/useMediaQuery-R1smYLx4.js.gz +0 -0
- package/payload/server/public/assets/useVoiceRecorder-DM1v6sRa.js +0 -2
- package/payload/server/public/assets/useVoiceRecorder-DM1v6sRa.js.br +0 -0
- package/payload/server/public/assets/useVoiceRecorder-DM1v6sRa.js.gz +0 -0
- package/payload/server/public/assets/wrench-DL1pbaCs.js.br +0 -0
- package/payload/server/public/assets/wrench-DL1pbaCs.js.gz +0 -0
- /package/payload/server/public/assets/{jsx-runtime-BtDK2X5t.js → jsx-runtime-B2Q1UOSJ.js} +0 -0
- /package/payload/server/public/assets/{jsx-runtime-BtDK2X5t.js.br → jsx-runtime-B2Q1UOSJ.js.br} +0 -0
- /package/payload/server/public/assets/{jsx-runtime-BtDK2X5t.js.gz → jsx-runtime-B2Q1UOSJ.js.gz} +0 -0
|
@@ -9,6 +9,10 @@ import {
|
|
|
9
9
|
isValidAccountId,
|
|
10
10
|
registerLoop
|
|
11
11
|
} from "./chunk-6AQYMT6C.js";
|
|
12
|
+
import {
|
|
13
|
+
extractVideo,
|
|
14
|
+
transcribe
|
|
15
|
+
} from "./chunk-CYU75QAV.js";
|
|
12
16
|
import {
|
|
13
17
|
__commonJS,
|
|
14
18
|
__require,
|
|
@@ -4125,90 +4129,6 @@ function isTimeInRange(time, opens, closes) {
|
|
|
4125
4129
|
return time >= opens || time < closes;
|
|
4126
4130
|
}
|
|
4127
4131
|
|
|
4128
|
-
// app/lib/stt/index.ts
|
|
4129
|
-
import { execFile } from "child_process";
|
|
4130
|
-
import { unlink, stat } from "fs/promises";
|
|
4131
|
-
import { promisify } from "util";
|
|
4132
|
-
var execFileAsync = promisify(execFile);
|
|
4133
|
-
var TAG16 = "[stt]";
|
|
4134
|
-
var WHISPER_BINARY = process.env.WHISPER_BINARY ?? "/opt/whisper.cpp/build/bin/whisper-cli";
|
|
4135
|
-
var WHISPER_MODEL = process.env.WHISPER_MODEL ?? "/opt/whisper.cpp/models/ggml-base.bin";
|
|
4136
|
-
var WHISPER_TIMEOUT_MS = 20 * 60 * 1e3;
|
|
4137
|
-
var SPECIAL_TOKEN_RE = /\[_[A-Z]+(?:_\d+)?_?\]/g;
|
|
4138
|
-
function stripSpecialTokens(input) {
|
|
4139
|
-
const matches = input.match(SPECIAL_TOKEN_RE);
|
|
4140
|
-
const count = matches ? matches.length : 0;
|
|
4141
|
-
if (!count) return { text: input, count: 0 };
|
|
4142
|
-
const text = input.replace(SPECIAL_TOKEN_RE, "").replace(/[ \t]{2,}/g, " ").trim();
|
|
4143
|
-
return { text, count };
|
|
4144
|
-
}
|
|
4145
|
-
async function transcribe(audioPath, mimetype) {
|
|
4146
|
-
const startMs = Date.now();
|
|
4147
|
-
let audioBytes = 0;
|
|
4148
|
-
try {
|
|
4149
|
-
const s = await stat(audioPath);
|
|
4150
|
-
audioBytes = s.size;
|
|
4151
|
-
} catch {
|
|
4152
|
-
console.error(`${TAG16} failed: file not readable path=${audioPath}`);
|
|
4153
|
-
return void 0;
|
|
4154
|
-
}
|
|
4155
|
-
console.error(
|
|
4156
|
-
`${TAG16} start provider=whisper-local audio_bytes=${audioBytes} mimetype=${mimetype} path=${audioPath}`
|
|
4157
|
-
);
|
|
4158
|
-
const wavPath = audioPath.replace(/\.[^.]+$/, "") + ".wav";
|
|
4159
|
-
try {
|
|
4160
|
-
await execFileAsync("ffmpeg", [
|
|
4161
|
-
"-i",
|
|
4162
|
-
audioPath,
|
|
4163
|
-
"-ar",
|
|
4164
|
-
"16000",
|
|
4165
|
-
"-ac",
|
|
4166
|
-
"1",
|
|
4167
|
-
"-c:a",
|
|
4168
|
-
"pcm_s16le",
|
|
4169
|
-
"-y",
|
|
4170
|
-
// overwrite without prompting
|
|
4171
|
-
wavPath
|
|
4172
|
-
], { timeout: 3e4 });
|
|
4173
|
-
} catch (err) {
|
|
4174
|
-
const reason = err instanceof Error ? err.message : String(err);
|
|
4175
|
-
console.error(`${TAG16} failed: ffmpeg conversion error=${reason}`);
|
|
4176
|
-
return void 0;
|
|
4177
|
-
}
|
|
4178
|
-
try {
|
|
4179
|
-
const { stdout, stderr } = await execFileAsync(WHISPER_BINARY, [
|
|
4180
|
-
"-m",
|
|
4181
|
-
WHISPER_MODEL,
|
|
4182
|
-
"-f",
|
|
4183
|
-
wavPath,
|
|
4184
|
-
"--no-timestamps",
|
|
4185
|
-
"-l",
|
|
4186
|
-
"auto"
|
|
4187
|
-
], { timeout: WHISPER_TIMEOUT_MS, maxBuffer: 10 * 1024 * 1024 });
|
|
4188
|
-
const durationMs = Date.now() - startMs;
|
|
4189
|
-
const { text, count: stripped } = stripSpecialTokens(stdout.trim());
|
|
4190
|
-
if (!text) {
|
|
4191
|
-
console.error(`${TAG16} failed: whisper returned empty output duration_ms=${durationMs}`);
|
|
4192
|
-
return void 0;
|
|
4193
|
-
}
|
|
4194
|
-
const langMatch = stderr.match(/auto-detected language:\s*(\w+)/);
|
|
4195
|
-
const language = langMatch?.[1] ?? "unknown";
|
|
4196
|
-
const words = text.split(/\s+/).filter(Boolean).length;
|
|
4197
|
-
console.error(
|
|
4198
|
-
`${TAG16} done provider=whisper-local duration_ms=${durationMs} words=${words} stripped=${stripped} lang=${language}`
|
|
4199
|
-
);
|
|
4200
|
-
return { text, language, durationMs };
|
|
4201
|
-
} catch (err) {
|
|
4202
|
-
const durationMs = Date.now() - startMs;
|
|
4203
|
-
const reason = err instanceof Error ? err.message : String(err);
|
|
4204
|
-
console.error(`${TAG16} failed provider=whisper-local duration_ms=${durationMs} error=${reason}`);
|
|
4205
|
-
return void 0;
|
|
4206
|
-
} finally {
|
|
4207
|
-
unlink(wavPath).catch(() => {
|
|
4208
|
-
});
|
|
4209
|
-
}
|
|
4210
|
-
}
|
|
4211
|
-
|
|
4212
4132
|
// app/lib/whatsapp/reply-error.ts
|
|
4213
4133
|
var WaReplyError = class extends Error {
|
|
4214
4134
|
terminal;
|
|
@@ -4220,7 +4140,7 @@ var WaReplyError = class extends Error {
|
|
|
4220
4140
|
};
|
|
4221
4141
|
|
|
4222
4142
|
// app/lib/whatsapp/manager.ts
|
|
4223
|
-
var
|
|
4143
|
+
var TAG16 = "[whatsapp:manager]";
|
|
4224
4144
|
var MAX_RECONNECT_ATTEMPTS = 10;
|
|
4225
4145
|
var REARM_INTERVAL_MS = 15 * 6e4;
|
|
4226
4146
|
var MESSAGE_STORE_MAX = 500;
|
|
@@ -4276,7 +4196,7 @@ function storeMessage(storeKey, entry2) {
|
|
|
4276
4196
|
if (entries.length > MESSAGE_STORE_MAX) {
|
|
4277
4197
|
const trimmed = entries.length - MESSAGE_STORE_MAX;
|
|
4278
4198
|
entries.splice(0, trimmed);
|
|
4279
|
-
console.error(`${
|
|
4199
|
+
console.error(`${TAG16} message store trimmed for ${storeKey}: ${trimmed} oldest messages removed`);
|
|
4280
4200
|
}
|
|
4281
4201
|
}
|
|
4282
4202
|
function deriveCacheKey(input) {
|
|
@@ -4320,7 +4240,7 @@ function buildSelfChatDispatch(input) {
|
|
|
4320
4240
|
}
|
|
4321
4241
|
async function init(opts) {
|
|
4322
4242
|
if (initialized) {
|
|
4323
|
-
console.error(`${
|
|
4243
|
+
console.error(`${TAG16} already initialized`);
|
|
4324
4244
|
return;
|
|
4325
4245
|
}
|
|
4326
4246
|
configDir = opts.configDir;
|
|
@@ -4330,20 +4250,20 @@ async function init(opts) {
|
|
|
4330
4250
|
loadConfig(opts.accountConfig);
|
|
4331
4251
|
const accountIds = listCredentialAccountIds(configDir);
|
|
4332
4252
|
if (accountIds.length === 0) {
|
|
4333
|
-
console.error(`${
|
|
4253
|
+
console.error(`${TAG16} init: no stored WhatsApp credentials found`);
|
|
4334
4254
|
initialized = true;
|
|
4335
4255
|
return;
|
|
4336
4256
|
}
|
|
4337
|
-
console.error(`${
|
|
4257
|
+
console.error(`${TAG16} init: found ${accountIds.length} credentialed account(s): ${accountIds.join(", ")}`);
|
|
4338
4258
|
initialized = true;
|
|
4339
4259
|
for (const accountId of accountIds) {
|
|
4340
4260
|
const accountCfg = whatsAppConfig.accounts?.[accountId];
|
|
4341
4261
|
if (accountCfg?.enabled === false) {
|
|
4342
|
-
console.error(`${
|
|
4262
|
+
console.error(`${TAG16} skipping disabled account=${accountId}`);
|
|
4343
4263
|
continue;
|
|
4344
4264
|
}
|
|
4345
4265
|
startConnection(accountId).catch((err) => {
|
|
4346
|
-
console.error(`${
|
|
4266
|
+
console.error(`${TAG16} failed to auto-start account=${accountId}: ${formatError(err)}`);
|
|
4347
4267
|
});
|
|
4348
4268
|
}
|
|
4349
4269
|
}
|
|
@@ -4368,7 +4288,7 @@ async function startConnection(accountId) {
|
|
|
4368
4288
|
const authDir = resolveAuthDir(configDir, accountId);
|
|
4369
4289
|
const hasAuth = await authExists(authDir);
|
|
4370
4290
|
if (!hasAuth) {
|
|
4371
|
-
console.error(`${
|
|
4291
|
+
console.error(`${TAG16} no credentials for account=${accountId}`);
|
|
4372
4292
|
throw new Error(`no credentials for account=${accountId}`);
|
|
4373
4293
|
}
|
|
4374
4294
|
const { platformAccountId, houseAccountId } = resolveConnectionAccountIds(accountId);
|
|
@@ -4392,7 +4312,7 @@ async function startConnection(accountId) {
|
|
|
4392
4312
|
};
|
|
4393
4313
|
connections.set(accountId, conn);
|
|
4394
4314
|
void connectWithReconnect(conn).catch((err) => {
|
|
4395
|
-
console.error(`${
|
|
4315
|
+
console.error(`${TAG16} connection loop ended in error account=${accountId}: ${formatError(err)}`);
|
|
4396
4316
|
});
|
|
4397
4317
|
}
|
|
4398
4318
|
async function stopConnection(accountId) {
|
|
@@ -4411,11 +4331,11 @@ async function stopConnection(accountId) {
|
|
|
4411
4331
|
conn.sock.ev.removeAllListeners("creds.update");
|
|
4412
4332
|
conn.sock.ws?.close?.();
|
|
4413
4333
|
} catch (err) {
|
|
4414
|
-
console.warn(`${
|
|
4334
|
+
console.warn(`${TAG16} socket cleanup error during stop account=${accountId}: ${String(err)}`);
|
|
4415
4335
|
}
|
|
4416
4336
|
}
|
|
4417
4337
|
connections.delete(accountId);
|
|
4418
|
-
console.error(`${
|
|
4338
|
+
console.error(`${TAG16} stopped account=${accountId}`);
|
|
4419
4339
|
}
|
|
4420
4340
|
function getStatus() {
|
|
4421
4341
|
return Array.from(connections.values()).map((conn) => ({
|
|
@@ -4535,9 +4455,9 @@ async function registerLoginSocket(accountId, sock, authDir) {
|
|
|
4535
4455
|
monitorChatMetadata(conn);
|
|
4536
4456
|
try {
|
|
4537
4457
|
await sock.sendPresenceUpdate("available");
|
|
4538
|
-
console.error(`${
|
|
4458
|
+
console.error(`${TAG16} presence set to available account=${accountId}`);
|
|
4539
4459
|
} catch (err) {
|
|
4540
|
-
console.error(`${
|
|
4460
|
+
console.error(`${TAG16} presence update failed account=${accountId}: ${String(err)}`);
|
|
4541
4461
|
}
|
|
4542
4462
|
await runInitQueries(sock, {
|
|
4543
4463
|
accountId,
|
|
@@ -4548,7 +4468,7 @@ async function registerLoginSocket(accountId, sock, authDir) {
|
|
|
4548
4468
|
});
|
|
4549
4469
|
watchForDisconnect(conn);
|
|
4550
4470
|
attachSelfIdRefreshOnCredsUpdate(conn);
|
|
4551
|
-
console.error(`${
|
|
4471
|
+
console.error(`${TAG16} registered login socket for account=${accountId} phone=${conn.selfPhone ?? "unknown"}`);
|
|
4552
4472
|
}
|
|
4553
4473
|
function attachSelfIdRefreshOnCredsUpdate(conn) {
|
|
4554
4474
|
if (!conn.sock) return;
|
|
@@ -4607,7 +4527,7 @@ async function shutdown() {
|
|
|
4607
4527
|
const ids = Array.from(connections.keys());
|
|
4608
4528
|
await Promise.all(ids.map((id) => stopConnection(id)));
|
|
4609
4529
|
initialized = false;
|
|
4610
|
-
console.error(`${
|
|
4530
|
+
console.error(`${TAG16} shutdown complete`);
|
|
4611
4531
|
}
|
|
4612
4532
|
function loadConfig(accountConfig) {
|
|
4613
4533
|
try {
|
|
@@ -4618,19 +4538,19 @@ function loadConfig(accountConfig) {
|
|
|
4618
4538
|
if (result.ok) {
|
|
4619
4539
|
whatsAppConfig = result.data;
|
|
4620
4540
|
if (result.droppedKeys.length > 0) {
|
|
4621
|
-
console.error(`${
|
|
4541
|
+
console.error(`${TAG16} config: dropped unknown keys=[${result.droppedKeys.join(",")}] preserved known config`);
|
|
4622
4542
|
}
|
|
4623
4543
|
} else {
|
|
4624
|
-
console.error(`${
|
|
4544
|
+
console.error(`${TAG16} config validation failed: ${result.error.message}`);
|
|
4625
4545
|
whatsAppConfig = {};
|
|
4626
4546
|
}
|
|
4627
4547
|
const diskAdmin = Array.isArray(wa.adminPhones) ? wa.adminPhones : [];
|
|
4628
4548
|
if (diskAdmin.length > 0 && (whatsAppConfig.adminPhones?.length ?? 0) === 0) {
|
|
4629
|
-
console.error(`${
|
|
4549
|
+
console.error(`${TAG16} WARN adminPhones present on disk but empty after load`);
|
|
4630
4550
|
}
|
|
4631
4551
|
}
|
|
4632
4552
|
} catch (err) {
|
|
4633
|
-
console.error(`${
|
|
4553
|
+
console.error(`${TAG16} config load error: ${String(err)}`);
|
|
4634
4554
|
whatsAppConfig = {};
|
|
4635
4555
|
}
|
|
4636
4556
|
}
|
|
@@ -4654,7 +4574,7 @@ async function connectWithReconnect(conn) {
|
|
|
4654
4574
|
let connectedAt;
|
|
4655
4575
|
let heldTimer;
|
|
4656
4576
|
try {
|
|
4657
|
-
console.error(`${
|
|
4577
|
+
console.error(`${TAG16} connecting account=${conn.accountId} attempt=${conn.reconnectAttempts}`);
|
|
4658
4578
|
if (conn.debouncer) {
|
|
4659
4579
|
await conn.debouncer.destroy();
|
|
4660
4580
|
conn.debouncer = null;
|
|
@@ -4668,7 +4588,7 @@ async function connectWithReconnect(conn) {
|
|
|
4668
4588
|
applySelfIdentity(conn, sock, "pre-listener");
|
|
4669
4589
|
monitorInbound(conn);
|
|
4670
4590
|
monitorChatMetadata(conn);
|
|
4671
|
-
console.error(`${
|
|
4591
|
+
console.error(`${TAG16} socket created account=${conn.accountId} \u2014 waiting for connection`);
|
|
4672
4592
|
await waitForConnection(sock);
|
|
4673
4593
|
connectedAt = Date.now();
|
|
4674
4594
|
conn.connected = true;
|
|
@@ -4676,7 +4596,7 @@ async function connectWithReconnect(conn) {
|
|
|
4676
4596
|
conn.lastError = void 0;
|
|
4677
4597
|
conn.terminalReason = void 0;
|
|
4678
4598
|
applySelfIdentity(conn, sock, "post-connect");
|
|
4679
|
-
console.error(`${
|
|
4599
|
+
console.error(`${TAG16} connected account=${conn.accountId} phone=${conn.selfPhone ?? "unknown"}`);
|
|
4680
4600
|
if (conn.sessionStuckReason) {
|
|
4681
4601
|
heldTimer = setTimeout(() => {
|
|
4682
4602
|
if (!conn.connected || connections.get(conn.accountId) !== conn) return;
|
|
@@ -4686,9 +4606,9 @@ async function connectWithReconnect(conn) {
|
|
|
4686
4606
|
}
|
|
4687
4607
|
try {
|
|
4688
4608
|
await sock.sendPresenceUpdate("available");
|
|
4689
|
-
console.error(`${
|
|
4609
|
+
console.error(`${TAG16} presence set to available account=${conn.accountId}`);
|
|
4690
4610
|
} catch (err) {
|
|
4691
|
-
console.error(`${
|
|
4611
|
+
console.error(`${TAG16} presence update failed account=${conn.accountId}: ${String(err)}`);
|
|
4692
4612
|
}
|
|
4693
4613
|
await runInitQueries(sock, {
|
|
4694
4614
|
accountId: conn.accountId,
|
|
@@ -4711,7 +4631,7 @@ async function connectWithReconnect(conn) {
|
|
|
4711
4631
|
}
|
|
4712
4632
|
const classification = classifyDisconnect(err);
|
|
4713
4633
|
conn.lastError = classification.message;
|
|
4714
|
-
console.error(`${
|
|
4634
|
+
console.error(`${TAG16} disconnect account=${conn.accountId}: ${classification.kind} \u2014 ${classification.message}`);
|
|
4715
4635
|
if (!classification.shouldRetry) {
|
|
4716
4636
|
conn.terminalReason = classification.message;
|
|
4717
4637
|
if (conn.sessionStuckReason) {
|
|
@@ -4719,7 +4639,7 @@ async function connectWithReconnect(conn) {
|
|
|
4719
4639
|
`${HEALTH_TAG} op=rearm account=${conn.accountId} attempt=${conn.rearmAttempts} sinceStuckMs=${sinceStuckMs(conn)} outcome=skipped-terminal`
|
|
4720
4640
|
);
|
|
4721
4641
|
}
|
|
4722
|
-
console.error(`${
|
|
4642
|
+
console.error(`${TAG16} terminal disconnect for account=${conn.accountId}, stopping reconnection`);
|
|
4723
4643
|
if (heldTimer !== void 0) clearTimeout(heldTimer);
|
|
4724
4644
|
return;
|
|
4725
4645
|
}
|
|
@@ -4739,7 +4659,7 @@ async function connectWithReconnect(conn) {
|
|
|
4739
4659
|
);
|
|
4740
4660
|
}
|
|
4741
4661
|
console.error(
|
|
4742
|
-
`${
|
|
4662
|
+
`${TAG16} ${stuckReason} \u2014 re-arming in ${REARM_INTERVAL_MS}ms and every ${REARM_INTERVAL_MS}ms after; a re-pair via QR ends the wait sooner`
|
|
4743
4663
|
);
|
|
4744
4664
|
conn.sessionStuckReason = stuckReason;
|
|
4745
4665
|
conn.lastError = stuckReason;
|
|
@@ -4758,18 +4678,18 @@ async function connectWithReconnect(conn) {
|
|
|
4758
4678
|
conn.reconnectAttempts = decision.nextAttempts;
|
|
4759
4679
|
if (decision.reason === "short-lived") {
|
|
4760
4680
|
console.error(
|
|
4761
|
-
`${
|
|
4681
|
+
`${TAG16} short-lived session account=${conn.accountId} uptimeMs=${uptimeMs} attempt=${decision.nextAttempts}/${maxAttempts} lastError=${conn.lastError ?? "(clean disconnect)"}`
|
|
4762
4682
|
);
|
|
4763
4683
|
} else {
|
|
4764
4684
|
clearStuck(conn);
|
|
4765
4685
|
console.error(
|
|
4766
|
-
`${
|
|
4686
|
+
`${TAG16} session stable account=${conn.accountId} uptimeMs=${uptimeMs} \u2014 reconnect counter reset`
|
|
4767
4687
|
);
|
|
4768
4688
|
}
|
|
4769
4689
|
if (decision.reason === "short-lived" || cycleError) {
|
|
4770
4690
|
const delay = computeBackoff(Math.max(1, decision.nextAttempts));
|
|
4771
4691
|
console.error(
|
|
4772
|
-
`${
|
|
4692
|
+
`${TAG16} reconnecting account=${conn.accountId} in ${delay}ms (attempt ${decision.nextAttempts}/${maxAttempts})`
|
|
4773
4693
|
);
|
|
4774
4694
|
await new Promise((resolve6) => {
|
|
4775
4695
|
const timer = setTimeout(resolve6, delay);
|
|
@@ -4803,11 +4723,11 @@ function watchForDisconnect(conn) {
|
|
|
4803
4723
|
conn.sock.ev.on("connection.update", (update) => {
|
|
4804
4724
|
if (update.connection === "close") {
|
|
4805
4725
|
if (connections.get(conn.accountId) !== conn) return;
|
|
4806
|
-
console.error(`${
|
|
4726
|
+
console.error(`${TAG16} socket disconnected for account=${conn.accountId}`);
|
|
4807
4727
|
conn.connected = false;
|
|
4808
4728
|
conn.sock = null;
|
|
4809
4729
|
connectWithReconnect(conn).catch((err) => {
|
|
4810
|
-
console.error(`${
|
|
4730
|
+
console.error(`${TAG16} reconnection failed for account=${conn.accountId}: ${formatError(err)}`);
|
|
4811
4731
|
});
|
|
4812
4732
|
}
|
|
4813
4733
|
});
|
|
@@ -4842,7 +4762,7 @@ function monitorChatMetadata(conn) {
|
|
|
4842
4762
|
}
|
|
4843
4763
|
const { canonical, resolved } = await resolveCanonicalConversationJid(e.jid, conn.lidMapping);
|
|
4844
4764
|
if (resolved === "lid2pn") {
|
|
4845
|
-
console.error(`${
|
|
4765
|
+
console.error(`${TAG16} [wa-chatmeta] op=canonical raw=${e.jid} canonical=${canonical}`);
|
|
4846
4766
|
out.push({ ...e, jid: canonical });
|
|
4847
4767
|
} else {
|
|
4848
4768
|
out.push(e);
|
|
@@ -4855,13 +4775,13 @@ function monitorChatMetadata(conn) {
|
|
|
4855
4775
|
if (perJid) {
|
|
4856
4776
|
for (const e of entries) {
|
|
4857
4777
|
console.error(
|
|
4858
|
-
`${
|
|
4778
|
+
`${TAG16} [wa-chatmeta] op=event kind=${kind} jid=${e.jid} name=${e.name.length} source=${e.source}`
|
|
4859
4779
|
);
|
|
4860
4780
|
}
|
|
4861
4781
|
}
|
|
4862
4782
|
const total = writeChatMetadataMerged(account, entries);
|
|
4863
4783
|
console.error(
|
|
4864
|
-
`${
|
|
4784
|
+
`${TAG16} [wa-chatmeta] op=persist kind=${kind} account=${account.slice(0, 8)} updates=${entries.length} outcome=${total < 0 ? "fail" : "ok"} entries=${total}`
|
|
4865
4785
|
);
|
|
4866
4786
|
};
|
|
4867
4787
|
sock.ev.on("messaging-history.set", ({ chats, contacts }) => {
|
|
@@ -4869,7 +4789,7 @@ function monitorChatMetadata(conn) {
|
|
|
4869
4789
|
const chatEntries = chatEntriesFromChats(chats ?? [], nowIso);
|
|
4870
4790
|
const contactEntries = chatEntriesFromContacts(contacts ?? [], nowIso);
|
|
4871
4791
|
console.error(
|
|
4872
|
-
`${
|
|
4792
|
+
`${TAG16} [wa-chatmeta] op=history-set account=${account.slice(0, 8)} chats=${chats?.length ?? 0} contacts=${contacts?.length ?? 0} groups=${chatEntries.filter((e) => e.isGroup).length} named=${chatEntries.length + contactEntries.length}`
|
|
4873
4793
|
);
|
|
4874
4794
|
void canonicalise([...chatEntries, ...contactEntries]).then((e) => persist("history-set", e, false));
|
|
4875
4795
|
});
|
|
@@ -4900,7 +4820,7 @@ function monitorChatMetadata(conn) {
|
|
|
4900
4820
|
try {
|
|
4901
4821
|
const meta = await sock.groupMetadata(jid);
|
|
4902
4822
|
console.error(
|
|
4903
|
-
`${
|
|
4823
|
+
`${TAG16} [wa-chatmeta] op=group-fetch jid=${jid} ms=${Date.now() - startedAt} outcome=ok`
|
|
4904
4824
|
);
|
|
4905
4825
|
persist(
|
|
4906
4826
|
"group-fetch",
|
|
@@ -4909,7 +4829,7 @@ function monitorChatMetadata(conn) {
|
|
|
4909
4829
|
);
|
|
4910
4830
|
} catch (err) {
|
|
4911
4831
|
console.error(
|
|
4912
|
-
`${
|
|
4832
|
+
`${TAG16} [wa-chatmeta] op=group-fetch jid=${jid} ms=${Date.now() - startedAt} outcome=fail reason=${(err instanceof Error ? err.message : String(err)).slice(0, 100)}`
|
|
4913
4833
|
);
|
|
4914
4834
|
}
|
|
4915
4835
|
}
|
|
@@ -4922,7 +4842,7 @@ function monitorInbound(conn) {
|
|
|
4922
4842
|
if (!conn.sock || !onInboundMessage) return;
|
|
4923
4843
|
const sock = conn.sock;
|
|
4924
4844
|
const debounceMs = whatsAppConfig.accounts?.[conn.accountId]?.debounceMs ?? whatsAppConfig.debounceMs ?? 0;
|
|
4925
|
-
console.error(`${
|
|
4845
|
+
console.error(`${TAG16} monitorInbound started account=${conn.accountId} debounceMs=${debounceMs}`);
|
|
4926
4846
|
conn.debouncer = createInboundDebouncer({
|
|
4927
4847
|
debounceMs,
|
|
4928
4848
|
buildKey: (payload) => {
|
|
@@ -4932,12 +4852,12 @@ function monitorInbound(conn) {
|
|
|
4932
4852
|
onFlush: (entries) => {
|
|
4933
4853
|
if (!onInboundMessage) return;
|
|
4934
4854
|
if (entries.length > 1) {
|
|
4935
|
-
console.error(`${
|
|
4855
|
+
console.error(`${TAG16} debounce: combining ${entries.length} messages account=${conn.accountId} from=${entries[0].senderPhone}`);
|
|
4936
4856
|
}
|
|
4937
4857
|
dispatchInboundPayload(conn, combineInboundBatch(entries));
|
|
4938
4858
|
},
|
|
4939
4859
|
onError: (err) => {
|
|
4940
|
-
console.error(`${
|
|
4860
|
+
console.error(`${TAG16} debounce flush error account=${conn.accountId}: ${String(err)}`);
|
|
4941
4861
|
}
|
|
4942
4862
|
});
|
|
4943
4863
|
sock.ev.on("messages.upsert", async (upsert) => {
|
|
@@ -5055,7 +4975,7 @@ function monitorInbound(conn) {
|
|
|
5055
4975
|
}
|
|
5056
4976
|
const entries = messageStore.get(storeKey);
|
|
5057
4977
|
console.error(
|
|
5058
|
-
`${
|
|
4978
|
+
`${TAG16} stored message ${msg.key.id ?? "?"} for ${remoteJid} (type: ${upsert.type}, store size: ${entries?.length ?? 0}/${MESSAGE_STORE_MAX}) storeAccount=${persistAccountId} socketOwner=${conn.platformAccountId}`
|
|
5059
4979
|
);
|
|
5060
4980
|
recordActivity({
|
|
5061
4981
|
accountId: conn.accountId,
|
|
@@ -5109,7 +5029,7 @@ function monitorInbound(conn) {
|
|
|
5109
5029
|
const wantsServableMedia = mediaServable && !!conn.sock && (!fromMe || !alreadyRecorded);
|
|
5110
5030
|
if (fromMe && mediaServable && !!conn.sock) {
|
|
5111
5031
|
console.error(
|
|
5112
|
-
`${
|
|
5032
|
+
`${TAG16} fromMe-media-echo msgKey=${msg.key.id} decision=${alreadyRecorded ? "skip" : "store"} reason=${alreadyRecorded ? "already-recorded" : "no-prior-record"}`
|
|
5113
5033
|
);
|
|
5114
5034
|
}
|
|
5115
5035
|
const mediaSeed = `whatsapp-live:${conn.accountId}:${canonicalRemoteJid}:${msg.key.id}`;
|
|
@@ -5192,7 +5112,7 @@ function monitorInbound(conn) {
|
|
|
5192
5112
|
receiptDeferredToWorker = true;
|
|
5193
5113
|
if (!accepted) {
|
|
5194
5114
|
console.error(
|
|
5195
|
-
`${
|
|
5115
|
+
`${TAG16} append-media overflow account=${conn.platformAccountId} msgKey=${msgKeyId ?? "?"} \u2014 pending cap ${APPEND_MEDIA_MAX_PENDING} reached, text-fallback persist, inline media shed`
|
|
5196
5116
|
);
|
|
5197
5117
|
const persisted = await persistWhatsAppMessage({
|
|
5198
5118
|
...basePersist,
|
|
@@ -5269,13 +5189,13 @@ function monitorInbound(conn) {
|
|
|
5269
5189
|
const skippedSenderJid = isGroupJid(remoteJid) ? msg.key.participant ?? remoteJid : remoteJid;
|
|
5270
5190
|
const skippedSenderPhone = await resolveJidToE164(skippedSenderJid, conn.lidMapping) ?? skippedSenderJid;
|
|
5271
5191
|
console.error(
|
|
5272
|
-
`${
|
|
5192
|
+
`${TAG16} append-type message ${msg.key.id ?? "?"} dispatch skipped from=${skippedSenderPhone}${msg.pushName ? ` name=${msg.pushName}` : ""} account=${conn.accountId} (persistence not confirmed here)`
|
|
5273
5193
|
);
|
|
5274
5194
|
continue;
|
|
5275
5195
|
}
|
|
5276
5196
|
await handleInboundMessage(conn, msg);
|
|
5277
5197
|
} catch (err) {
|
|
5278
|
-
console.error(`${
|
|
5198
|
+
console.error(`${TAG16} inbound handler error account=${conn.accountId}: ${String(err)}`);
|
|
5279
5199
|
}
|
|
5280
5200
|
}
|
|
5281
5201
|
});
|
|
@@ -5334,31 +5254,31 @@ async function handleInboundMessage(conn, msg) {
|
|
|
5334
5254
|
const remoteJid = msg.key.remoteJid;
|
|
5335
5255
|
if (!remoteJid) return;
|
|
5336
5256
|
if (remoteJid === "status@broadcast") {
|
|
5337
|
-
console.error(`${
|
|
5257
|
+
console.error(`${TAG16} drop: status broadcast account=${conn.accountId}`);
|
|
5338
5258
|
return;
|
|
5339
5259
|
}
|
|
5340
5260
|
if (!msg.message) {
|
|
5341
|
-
console.error(`${
|
|
5261
|
+
console.error(`${TAG16} drop: empty message account=${conn.accountId} from=${remoteJid}`);
|
|
5342
5262
|
return;
|
|
5343
5263
|
}
|
|
5344
5264
|
const dedupKey = `${conn.accountId}:${remoteJid}:${msg.key.id}`;
|
|
5345
5265
|
if (isDuplicateInbound(dedupKey)) {
|
|
5346
|
-
console.error(`${
|
|
5266
|
+
console.error(`${TAG16} drop: duplicate account=${conn.accountId} key=${dedupKey}`);
|
|
5347
5267
|
return;
|
|
5348
5268
|
}
|
|
5349
5269
|
if (msg.key.fromMe) {
|
|
5350
5270
|
if (msg.key.id && isAgentSentMessage(msg.key.id)) {
|
|
5351
|
-
console.error(`${
|
|
5271
|
+
console.error(`${TAG16} drop: echo suppression account=${conn.accountId} msgId=${msg.key.id}`);
|
|
5352
5272
|
return;
|
|
5353
5273
|
}
|
|
5354
5274
|
const extracted2 = extractMessage(msg);
|
|
5355
5275
|
if (!extracted2.text) {
|
|
5356
|
-
console.error(`${
|
|
5276
|
+
console.error(`${TAG16} owner reply skipped \u2014 no text content account=${conn.accountId}`);
|
|
5357
5277
|
return;
|
|
5358
5278
|
}
|
|
5359
5279
|
const isGroup2 = isGroupJid(remoteJid);
|
|
5360
5280
|
const senderPhone2 = conn.selfPhone ?? "owner";
|
|
5361
|
-
console.error(`${
|
|
5281
|
+
console.error(`${TAG16} owner reply mirrored to session from=${senderPhone2} account=${conn.accountId}`);
|
|
5362
5282
|
const reply2 = async (text) => {
|
|
5363
5283
|
const currentSock = conn.sock;
|
|
5364
5284
|
if (!currentSock) throw new Error("WhatsApp disconnected \u2014 cannot reply");
|
|
@@ -5392,7 +5312,7 @@ async function handleInboundMessage(conn, msg) {
|
|
|
5392
5312
|
}
|
|
5393
5313
|
const extracted = extractMessage(msg);
|
|
5394
5314
|
if (!extracted.text && !extracted.mediaType) {
|
|
5395
|
-
console.error(`${
|
|
5315
|
+
console.error(`${TAG16} drop: no text or media account=${conn.accountId} from=${remoteJid}`);
|
|
5396
5316
|
return;
|
|
5397
5317
|
}
|
|
5398
5318
|
const isGroup = isGroupJid(remoteJid);
|
|
@@ -5425,7 +5345,7 @@ async function handleInboundMessage(conn, msg) {
|
|
|
5425
5345
|
});
|
|
5426
5346
|
}
|
|
5427
5347
|
console.error(
|
|
5428
|
-
`${
|
|
5348
|
+
`${TAG16} inbound account=${conn.accountId} from=${senderPhone} group=${isGroup} access=${accessResult.allowed ? "allowed" : "blocked"}(${accessResult.reason}) agent=${accessResult.agentType} effectiveAccount=${accessResult.effectiveAccountId ?? ""} destAccount=${conn.platformAccountId}` + // Task 2234 — the sender class is not derivable from `agent=public` alone:
|
|
5429
5349
|
// a registered party and an open-policy stranger both read `public`. The
|
|
5430
5350
|
// label is the only thing on this line that separates them.
|
|
5431
5351
|
(accessResult.party ? ` party=${accessResult.party}` : "") + // Task 2235 — an inherited policy behaves exactly like a set one until the
|
|
@@ -5438,7 +5358,7 @@ async function handleInboundMessage(conn, msg) {
|
|
|
5438
5358
|
const shadowedParty = registeredPartyFor(whatsAppConfig.registeredParties ?? {}, senderPhone);
|
|
5439
5359
|
if (shadowedParty && shadowedParty.account === conn.platformAccountId) {
|
|
5440
5360
|
console.error(
|
|
5441
|
-
`${
|
|
5361
|
+
`${TAG16} op=registered-party-shadowed phone=${senderPhone} account=${shadowedParty.account} party=${shadowedParty.party} shadowedBy=${accessResult.reason}`
|
|
5442
5362
|
);
|
|
5443
5363
|
}
|
|
5444
5364
|
}
|
|
@@ -5477,7 +5397,7 @@ async function handleInboundMessage(conn, msg) {
|
|
|
5477
5397
|
maxBytes: maxMb * 1024 * 1024
|
|
5478
5398
|
});
|
|
5479
5399
|
if (!mediaResult) {
|
|
5480
|
-
console.error(`${
|
|
5400
|
+
console.error(`${TAG16} media download returned undefined account=${conn.accountId} type=${extracted.mediaType} from=${remoteJid}`);
|
|
5481
5401
|
}
|
|
5482
5402
|
}
|
|
5483
5403
|
if (extracted.mediaType === "audio" && mediaResult?.path) {
|
|
@@ -5497,9 +5417,24 @@ async function handleInboundMessage(conn, msg) {
|
|
|
5497
5417
|
resolvePending();
|
|
5498
5418
|
}
|
|
5499
5419
|
}
|
|
5420
|
+
let videoTimeline;
|
|
5421
|
+
if (extracted.mediaType === "video" && mediaResult?.path) {
|
|
5422
|
+
const conversationKey2 = isGroup ? remoteJid : senderPhone;
|
|
5423
|
+
const debounceKey = `${conn.accountId}:${conversationKey2}:${senderPhone}`;
|
|
5424
|
+
let resolveVideoPending;
|
|
5425
|
+
const videoPending = new Promise((resolve6) => {
|
|
5426
|
+
resolveVideoPending = resolve6;
|
|
5427
|
+
});
|
|
5428
|
+
if (conn.debouncer) conn.debouncer.registerPending(debounceKey, videoPending);
|
|
5429
|
+
try {
|
|
5430
|
+
videoTimeline = await extractVideo(mediaResult.path, mediaResult.mimetype);
|
|
5431
|
+
} finally {
|
|
5432
|
+
resolveVideoPending();
|
|
5433
|
+
}
|
|
5434
|
+
}
|
|
5500
5435
|
const reply = async (text) => {
|
|
5501
5436
|
if (isGroupJid(remoteJid)) {
|
|
5502
|
-
console.error(`${
|
|
5437
|
+
console.error(`${TAG16} op=group-reply-blocked jid=${remoteJid}`);
|
|
5503
5438
|
throw new WaReplyError("group reply blocked \u2014 observe-only", false);
|
|
5504
5439
|
}
|
|
5505
5440
|
const currentSock = conn.sock;
|
|
@@ -5539,7 +5474,14 @@ async function handleInboundMessage(conn, msg) {
|
|
|
5539
5474
|
reply,
|
|
5540
5475
|
composing,
|
|
5541
5476
|
cacheKey,
|
|
5542
|
-
media: mediaResult?.path ? [{
|
|
5477
|
+
media: mediaResult?.path ? [{
|
|
5478
|
+
path: mediaResult.path,
|
|
5479
|
+
type: extracted.mediaType,
|
|
5480
|
+
mimetype: mediaResult.mimetype,
|
|
5481
|
+
// Task 2696 — undefined for every non-video item and for a video whose
|
|
5482
|
+
// extraction degraded; the weaver then keeps the file-path note.
|
|
5483
|
+
timeline: videoTimeline
|
|
5484
|
+
}] : [],
|
|
5543
5485
|
replyContext: extracted.quotedMessage,
|
|
5544
5486
|
// Task 1383 — the gate's single resolution feeds the spawn (house or the
|
|
5545
5487
|
// bound sub-account); the router never re-resolves.
|
|
@@ -5556,15 +5498,15 @@ async function handleInboundMessage(conn, msg) {
|
|
|
5556
5498
|
if (accessResult.agentType === "public") {
|
|
5557
5499
|
const hoursResult = await isBusinessOpen(conn.accountId);
|
|
5558
5500
|
if (!hoursResult.open) {
|
|
5559
|
-
console.error(`${
|
|
5501
|
+
console.error(`${TAG16} [${conn.accountId}] dispatch skipped: business closed`);
|
|
5560
5502
|
const afterHoursMessage = whatsAppConfig.accounts?.[conn.accountId]?.afterHoursMessage ?? whatsAppConfig.afterHoursMessage;
|
|
5561
5503
|
if (afterHoursMessage) {
|
|
5562
5504
|
try {
|
|
5563
5505
|
await reply(afterHoursMessage);
|
|
5564
|
-
console.error(`${
|
|
5506
|
+
console.error(`${TAG16} [${conn.accountId}] after-hours auto-reply sent to ${remoteJid}`);
|
|
5565
5507
|
} catch (err) {
|
|
5566
5508
|
console.error(
|
|
5567
|
-
`${
|
|
5509
|
+
`${TAG16} [${conn.accountId}] after-hours auto-reply failed: ${err instanceof Error ? err.message : String(err)}`
|
|
5568
5510
|
);
|
|
5569
5511
|
}
|
|
5570
5512
|
}
|
|
@@ -5704,7 +5646,6 @@ export {
|
|
|
5704
5646
|
validateFilePathInAccount,
|
|
5705
5647
|
storeComponentArtefact,
|
|
5706
5648
|
WHATSAPP_DOCUMENT_MAX_BYTES,
|
|
5707
|
-
transcribe,
|
|
5708
5649
|
WaReplyError,
|
|
5709
5650
|
buildNotifyPending,
|
|
5710
5651
|
isObserveAccount,
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { createRequire as __createRequire } from 'node:module'; const require = __createRequire(import.meta.url);
|
|
2
|
+
|
|
3
|
+
// app/lib/stt/audio-mime.ts
|
|
4
|
+
var AUDIO_MIME_TYPES = /* @__PURE__ */ new Set([
|
|
5
|
+
"audio/ogg",
|
|
6
|
+
"audio/opus",
|
|
7
|
+
"audio/webm",
|
|
8
|
+
"audio/mp4",
|
|
9
|
+
"audio/x-m4a",
|
|
10
|
+
"audio/mpeg",
|
|
11
|
+
"audio/wav",
|
|
12
|
+
"video/mp4"
|
|
13
|
+
]);
|
|
14
|
+
function normalizeMime(mimeType) {
|
|
15
|
+
return mimeType.split(";")[0].trim().toLowerCase();
|
|
16
|
+
}
|
|
17
|
+
function isAudioMime(mimeType) {
|
|
18
|
+
return AUDIO_MIME_TYPES.has(normalizeMime(mimeType));
|
|
19
|
+
}
|
|
20
|
+
function audioExtension(mimeType) {
|
|
21
|
+
switch (normalizeMime(mimeType)) {
|
|
22
|
+
case "audio/ogg":
|
|
23
|
+
return ".ogg";
|
|
24
|
+
case "audio/opus":
|
|
25
|
+
return ".opus";
|
|
26
|
+
case "audio/webm":
|
|
27
|
+
return ".webm";
|
|
28
|
+
case "audio/mp4":
|
|
29
|
+
return ".m4a";
|
|
30
|
+
case "audio/x-m4a":
|
|
31
|
+
return ".m4a";
|
|
32
|
+
case "audio/mpeg":
|
|
33
|
+
return ".mp3";
|
|
34
|
+
case "audio/wav":
|
|
35
|
+
return ".wav";
|
|
36
|
+
case "video/mp4":
|
|
37
|
+
return ".mp4";
|
|
38
|
+
default:
|
|
39
|
+
return ".audio";
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// app/lib/video/video-mime.ts
|
|
44
|
+
var VIDEO_MIME_TYPES = /* @__PURE__ */ new Set([
|
|
45
|
+
"video/mp4",
|
|
46
|
+
"video/quicktime",
|
|
47
|
+
"video/webm",
|
|
48
|
+
"video/x-matroska",
|
|
49
|
+
"video/3gpp"
|
|
50
|
+
]);
|
|
51
|
+
function isVideoMime(mimeType) {
|
|
52
|
+
return VIDEO_MIME_TYPES.has(normalizeMime(mimeType));
|
|
53
|
+
}
|
|
54
|
+
function videoExtension(mimeType) {
|
|
55
|
+
switch (normalizeMime(mimeType)) {
|
|
56
|
+
case "video/mp4":
|
|
57
|
+
return ".mp4";
|
|
58
|
+
case "video/quicktime":
|
|
59
|
+
return ".mov";
|
|
60
|
+
case "video/webm":
|
|
61
|
+
return ".webm";
|
|
62
|
+
case "video/x-matroska":
|
|
63
|
+
return ".mkv";
|
|
64
|
+
case "video/3gpp":
|
|
65
|
+
return ".3gp";
|
|
66
|
+
default:
|
|
67
|
+
return ".video";
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export {
|
|
72
|
+
isAudioMime,
|
|
73
|
+
audioExtension,
|
|
74
|
+
VIDEO_MIME_TYPES,
|
|
75
|
+
isVideoMime,
|
|
76
|
+
videoExtension
|
|
77
|
+
};
|