@rubytech/create-maxy-code 0.1.538 → 0.1.539
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/skills/platform-architecture/SKILL.md +28 -2
- package/payload/platform/plugins/admin/skills/whats-new/SKILL.md +7 -0
- package/payload/platform/plugins/docs/references/admin-ui.md +26 -0
- package/payload/platform/plugins/docs/references/channel-wake-and-prompt.md +1 -1
- package/payload/platform/plugins/scheduling/PLUGIN.md +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/tools/__tests__/schedule-get-description.test.d.ts +2 -0
- package/payload/platform/plugins/scheduling/mcp/dist/tools/__tests__/schedule-get-description.test.d.ts.map +1 -0
- package/payload/platform/plugins/scheduling/mcp/dist/tools/__tests__/schedule-get-description.test.js +59 -0
- package/payload/platform/plugins/scheduling/mcp/dist/tools/__tests__/schedule-get-description.test.js.map +1 -0
- package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-get.d.ts.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-get.js +6 -0
- package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-get.js.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-update.d.ts.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-update.js +10 -6
- package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-update.js.map +1 -1
- package/payload/platform/plugins/whatsapp/skills/manage-whatsapp-config/SKILL.md +11 -7
- package/payload/platform/services/webchat-channel/dist/notification.d.ts +31 -0
- package/payload/platform/services/webchat-channel/dist/notification.d.ts.map +1 -1
- package/payload/platform/services/webchat-channel/dist/notification.js +31 -1
- package/payload/platform/services/webchat-channel/dist/notification.js.map +1 -1
- package/payload/platform/services/webchat-channel/dist/server.d.ts.map +1 -1
- package/payload/platform/services/webchat-channel/dist/server.js +15 -1
- package/payload/platform/services/webchat-channel/dist/server.js.map +1 -1
- package/payload/server/{chunk-FQO5RDWZ.js → chunk-S4FIEM3L.js} +60 -10
- package/payload/server/{manager-EBZQRV5V.js → manager-5QV2EAZ2.js} +1 -1
- package/payload/server/public/activity.html +5 -5
- package/payload/server/public/agents.html +4 -4
- package/payload/server/public/assets/{AdminLoginScreens-CfXQwKIY.js → AdminLoginScreens-BpHnjHp_.js} +1 -1
- package/payload/server/public/assets/AdminLoginScreens-BpHnjHp_.js.br +0 -0
- package/payload/server/public/assets/AdminLoginScreens-BpHnjHp_.js.gz +0 -0
- package/payload/server/public/assets/AdminShell-D24evn4t.js +2 -0
- package/payload/server/public/assets/AdminShell-D24evn4t.js.br +0 -0
- package/payload/server/public/assets/AdminShell-D24evn4t.js.gz +0 -0
- package/payload/server/public/assets/{activity-h8-sjHz9.js → activity-ZVUTB5uZ.js} +1 -1
- package/payload/server/public/assets/activity-ZVUTB5uZ.js.br +0 -0
- package/payload/server/public/assets/activity-ZVUTB5uZ.js.gz +0 -0
- package/payload/server/public/assets/{admin-BzhhLC7C.js → admin-XJqQz3QJ.js} +1 -1
- package/payload/server/public/assets/admin-XJqQz3QJ.js.br +0 -0
- package/payload/server/public/assets/admin-XJqQz3QJ.js.gz +0 -0
- package/payload/server/public/assets/{agents-DLuhIIgn.js → agents-Dc9SNC9N.js} +1 -1
- package/payload/server/public/assets/agents-Dc9SNC9N.js.br +0 -0
- package/payload/server/public/assets/agents-Dc9SNC9N.js.gz +0 -0
- package/payload/server/public/assets/{browser-FAnTY27n.js → browser-CCedMIga.js} +1 -1
- package/payload/server/public/assets/browser-CCedMIga.js.br +0 -0
- package/payload/server/public/assets/browser-CCedMIga.js.gz +0 -0
- package/payload/server/public/assets/calendar-BDoMLP2j.js +1 -0
- package/payload/server/public/assets/calendar-BDoMLP2j.js.br +0 -0
- package/payload/server/public/assets/calendar-BDoMLP2j.js.gz +0 -0
- package/payload/server/public/assets/chat-BAhoqTY9.js +1 -0
- package/payload/server/public/assets/chat-BAhoqTY9.js.br +0 -0
- package/payload/server/public/assets/chat-BAhoqTY9.js.gz +0 -0
- package/payload/server/public/assets/chevron-left-NGLHgPjF.js +1 -0
- package/payload/server/public/assets/chevron-right-B4B7OkG8.js +1 -0
- package/payload/server/public/assets/chevron-right-B4B7OkG8.js.br +0 -0
- package/payload/server/public/assets/clock-7IMwxJdH.js +1 -0
- package/payload/server/public/assets/clock-7IMwxJdH.js.br +0 -0
- package/payload/server/public/assets/clock-7IMwxJdH.js.gz +0 -0
- package/payload/server/public/assets/{copy-Rde_TL9Q.js → copy-PkR4EFD6.js} +1 -1
- package/payload/server/public/assets/copy-PkR4EFD6.js.br +0 -0
- package/payload/server/public/assets/copy-PkR4EFD6.js.gz +0 -0
- package/payload/server/public/assets/data-yQYhw2IR.js +1 -0
- package/payload/server/public/assets/data-yQYhw2IR.js.br +1 -0
- package/payload/server/public/assets/data-yQYhw2IR.js.gz +0 -0
- package/payload/server/public/assets/{file-text-DMCUVg80.js → file-text-BA9p7TLU.js} +1 -1
- package/payload/server/public/assets/file-text-BA9p7TLU.js.br +0 -0
- package/payload/server/public/assets/file-text-BA9p7TLU.js.gz +0 -0
- package/payload/server/public/assets/{graph-Bo-WcsKS.js → graph-C8cQ6Nqf.js} +1 -1
- package/payload/server/public/assets/graph-C8cQ6Nqf.js.br +0 -0
- package/payload/server/public/assets/graph-C8cQ6Nqf.js.gz +0 -0
- package/payload/server/public/assets/{graph-labels-g-JodMWQ.js → graph-labels-CiK412vE.js} +1 -1
- package/payload/server/public/assets/graph-labels-CiK412vE.js.br +0 -0
- package/payload/server/public/assets/graph-labels-CiK412vE.js.gz +0 -0
- package/payload/server/public/assets/{operator-X_LcOnAI.js → operator-CaQAEUBu.js} +1 -1
- package/payload/server/public/assets/operator-CaQAEUBu.js.br +0 -0
- package/payload/server/public/assets/operator-CaQAEUBu.js.gz +0 -0
- package/payload/server/public/assets/page-CpJpyoPS.js +32 -0
- package/payload/server/public/assets/page-CpJpyoPS.js.br +0 -0
- package/payload/server/public/assets/page-CpJpyoPS.js.gz +0 -0
- package/payload/server/public/assets/page-D0ShNyGE.js +1 -0
- package/payload/server/public/assets/page-D0ShNyGE.js.br +0 -0
- package/payload/server/public/assets/page-D0ShNyGE.js.gz +0 -0
- package/payload/server/public/assets/{play-CraN5kUU.js → play-huZpq9ra.js} +1 -1
- package/payload/server/public/assets/play-huZpq9ra.js.br +0 -0
- package/payload/server/public/assets/play-huZpq9ra.js.gz +0 -0
- package/payload/server/public/assets/{public--NUjaJ-q.js → public--8RWWGjF.js} +1 -1
- package/payload/server/public/assets/public--8RWWGjF.js.br +0 -0
- package/payload/server/public/assets/public--8RWWGjF.js.gz +0 -0
- package/payload/server/public/assets/{rotate-ccw-DshFgg2T.js → rotate-ccw-g7l4ZSR3.js} +1 -1
- package/payload/server/public/assets/rotate-ccw-g7l4ZSR3.js.br +0 -0
- package/payload/server/public/assets/rotate-ccw-g7l4ZSR3.js.gz +0 -0
- package/payload/server/public/assets/{routines-CfAS4gri.js → routines-DzFcPNMb.js} +1 -1
- package/payload/server/public/assets/routines-DzFcPNMb.js.br +0 -0
- package/payload/server/public/assets/routines-DzFcPNMb.js.gz +0 -0
- package/payload/server/public/assets/{skills-CM6ryWpx.js → skills-5vl_Bt9U.js} +1 -1
- package/payload/server/public/assets/skills-5vl_Bt9U.js.br +0 -0
- package/payload/server/public/assets/skills-5vl_Bt9U.js.gz +0 -0
- package/payload/server/public/assets/{tasks-B07m9LIA.js → tasks-DQHtJ8Pq.js} +1 -1
- package/payload/server/public/assets/tasks-DQHtJ8Pq.js.br +0 -0
- package/payload/server/public/assets/tasks-DQHtJ8Pq.js.gz +0 -0
- package/payload/server/public/assets/{triangle-alert-CKHyS_gC.js → triangle-alert-Cy4Z0uFv.js} +1 -1
- package/payload/server/public/assets/triangle-alert-Cy4Z0uFv.js.br +0 -0
- package/payload/server/public/assets/triangle-alert-Cy4Z0uFv.js.gz +0 -0
- package/payload/server/public/assets/{useCopyFeedback-CmawEsVi.js → useCopyFeedback-BwK1RhmF.js} +1 -1
- package/payload/server/public/assets/useCopyFeedback-BwK1RhmF.js.br +0 -0
- package/payload/server/public/assets/useCopyFeedback-BwK1RhmF.js.gz +0 -0
- package/payload/server/public/assets/{useSubAccountSwitcher-yN4lhH2x.css → useSubAccountSwitcher-DCkivCBS.css} +1 -1
- package/payload/server/public/assets/useSubAccountSwitcher-DCkivCBS.css.br +0 -0
- package/payload/server/public/assets/{useSubAccountSwitcher-yN4lhH2x.css.gz → useSubAccountSwitcher-DCkivCBS.css.gz} +0 -0
- package/payload/server/public/assets/{useVoiceRecorder-DpQTvvqD.js → useVoiceRecorder-DgyAGgmF.js} +1 -1
- package/payload/server/public/assets/useVoiceRecorder-DgyAGgmF.js.br +0 -0
- package/payload/server/public/assets/useVoiceRecorder-DgyAGgmF.js.gz +0 -0
- package/payload/server/public/assets/{wrench-BPOEUNJB.js → wrench-CICORrSc.js} +1 -1
- package/payload/server/public/assets/wrench-CICORrSc.js.br +0 -0
- package/payload/server/public/assets/wrench-CICORrSc.js.gz +0 -0
- package/payload/server/public/browser.html +4 -4
- package/payload/server/public/calendar.html +8 -7
- package/payload/server/public/chat.html +13 -13
- package/payload/server/public/data.html +11 -11
- package/payload/server/public/graph.html +9 -9
- package/payload/server/public/index.html +14 -14
- package/payload/server/public/operator.html +14 -14
- package/payload/server/public/public.html +13 -13
- package/payload/server/public/routines.html +6 -6
- package/payload/server/public/skills.html +5 -5
- package/payload/server/public/tasks.html +6 -6
- package/payload/server/server.js +149 -46
- package/payload/server/public/assets/AdminLoginScreens-CfXQwKIY.js.br +0 -0
- package/payload/server/public/assets/AdminLoginScreens-CfXQwKIY.js.gz +0 -0
- package/payload/server/public/assets/AdminShell-y0_mzlDF.js +0 -2
- package/payload/server/public/assets/AdminShell-y0_mzlDF.js.br +0 -0
- package/payload/server/public/assets/AdminShell-y0_mzlDF.js.gz +0 -0
- package/payload/server/public/assets/activity-h8-sjHz9.js.br +0 -0
- package/payload/server/public/assets/activity-h8-sjHz9.js.gz +0 -0
- package/payload/server/public/assets/admin-BzhhLC7C.js.br +0 -0
- package/payload/server/public/assets/admin-BzhhLC7C.js.gz +0 -0
- package/payload/server/public/assets/agents-DLuhIIgn.js.br +0 -0
- package/payload/server/public/assets/agents-DLuhIIgn.js.gz +0 -0
- package/payload/server/public/assets/browser-FAnTY27n.js.br +0 -0
- package/payload/server/public/assets/browser-FAnTY27n.js.gz +0 -0
- package/payload/server/public/assets/calendar-C_PkqlkQ.js +0 -1
- package/payload/server/public/assets/calendar-C_PkqlkQ.js.br +0 -0
- package/payload/server/public/assets/calendar-C_PkqlkQ.js.gz +0 -0
- package/payload/server/public/assets/chat-DW81Ra89.js +0 -1
- package/payload/server/public/assets/chat-DW81Ra89.js.br +0 -0
- package/payload/server/public/assets/chat-DW81Ra89.js.gz +0 -0
- package/payload/server/public/assets/chevron-left-zV-WRzHb.js +0 -1
- package/payload/server/public/assets/chevron-left-zV-WRzHb.js.br +0 -0
- package/payload/server/public/assets/chevron-right-fnINU4bx.js +0 -1
- package/payload/server/public/assets/chevron-right-fnINU4bx.js.br +0 -0
- package/payload/server/public/assets/clock-2fSxBl6d.js +0 -1
- package/payload/server/public/assets/clock-2fSxBl6d.js.br +0 -0
- package/payload/server/public/assets/copy-Rde_TL9Q.js.br +0 -0
- package/payload/server/public/assets/copy-Rde_TL9Q.js.gz +0 -0
- package/payload/server/public/assets/data-S5g4wIDe.js +0 -1
- package/payload/server/public/assets/data-S5g4wIDe.js.br +0 -0
- package/payload/server/public/assets/data-S5g4wIDe.js.gz +0 -0
- package/payload/server/public/assets/file-text-DMCUVg80.js.br +0 -0
- package/payload/server/public/assets/file-text-DMCUVg80.js.gz +0 -0
- package/payload/server/public/assets/graph-Bo-WcsKS.js.br +0 -0
- package/payload/server/public/assets/graph-Bo-WcsKS.js.gz +0 -0
- package/payload/server/public/assets/graph-labels-g-JodMWQ.js.br +0 -0
- package/payload/server/public/assets/graph-labels-g-JodMWQ.js.gz +0 -0
- package/payload/server/public/assets/operator-X_LcOnAI.js.br +0 -0
- package/payload/server/public/assets/operator-X_LcOnAI.js.gz +0 -0
- package/payload/server/public/assets/page-Cz0p1mBf.js +0 -1
- package/payload/server/public/assets/page-Cz0p1mBf.js.br +0 -0
- package/payload/server/public/assets/page-Cz0p1mBf.js.gz +0 -0
- package/payload/server/public/assets/page-Dzs3MsFL.js +0 -32
- package/payload/server/public/assets/page-Dzs3MsFL.js.br +0 -0
- package/payload/server/public/assets/page-Dzs3MsFL.js.gz +0 -0
- package/payload/server/public/assets/play-CraN5kUU.js.br +0 -0
- package/payload/server/public/assets/play-CraN5kUU.js.gz +0 -0
- package/payload/server/public/assets/public--NUjaJ-q.js.br +0 -0
- package/payload/server/public/assets/public--NUjaJ-q.js.gz +0 -0
- package/payload/server/public/assets/rotate-ccw-DshFgg2T.js.br +0 -0
- package/payload/server/public/assets/rotate-ccw-DshFgg2T.js.gz +0 -0
- package/payload/server/public/assets/routines-CfAS4gri.js.br +0 -0
- package/payload/server/public/assets/routines-CfAS4gri.js.gz +0 -0
- package/payload/server/public/assets/skills-CM6ryWpx.js.br +0 -0
- package/payload/server/public/assets/skills-CM6ryWpx.js.gz +0 -0
- package/payload/server/public/assets/tasks-B07m9LIA.js.br +0 -0
- package/payload/server/public/assets/tasks-B07m9LIA.js.gz +0 -0
- package/payload/server/public/assets/triangle-alert-CKHyS_gC.js.br +0 -0
- package/payload/server/public/assets/triangle-alert-CKHyS_gC.js.gz +0 -0
- package/payload/server/public/assets/useCopyFeedback-CmawEsVi.js.br +0 -0
- package/payload/server/public/assets/useCopyFeedback-CmawEsVi.js.gz +0 -0
- package/payload/server/public/assets/useSubAccountSwitcher-yN4lhH2x.css.br +0 -0
- package/payload/server/public/assets/useVoiceRecorder-DpQTvvqD.js.br +0 -0
- package/payload/server/public/assets/useVoiceRecorder-DpQTvvqD.js.gz +0 -0
- package/payload/server/public/assets/wrench-BPOEUNJB.js.br +0 -0
- package/payload/server/public/assets/wrench-BPOEUNJB.js.gz +0 -0
- /package/payload/server/public/assets/{useSubAccountSwitcher-CVHqKsqK.js → useSubAccountSwitcher-C7TtIbR3.js} +0 -0
- /package/payload/server/public/assets/{useSubAccountSwitcher-CVHqKsqK.js.br → useSubAccountSwitcher-C7TtIbR3.js.br} +0 -0
- /package/payload/server/public/assets/{useSubAccountSwitcher-CVHqKsqK.js.gz → useSubAccountSwitcher-C7TtIbR3.js.gz} +0 -0
package/payload/server/server.js
CHANGED
|
@@ -195,7 +195,7 @@ import {
|
|
|
195
195
|
waitForConnection,
|
|
196
196
|
warnNonUuidAccount,
|
|
197
197
|
writeChatMetadataMerged
|
|
198
|
-
} from "./chunk-
|
|
198
|
+
} from "./chunk-S4FIEM3L.js";
|
|
199
199
|
import {
|
|
200
200
|
ACCOUNTS_DIR,
|
|
201
201
|
BIN_DIR,
|
|
@@ -231,6 +231,7 @@ import {
|
|
|
231
231
|
getDefaultAccountId,
|
|
232
232
|
getRecentMessages,
|
|
233
233
|
getSession,
|
|
234
|
+
getUserTimezone,
|
|
234
235
|
isActiveAgentSlug,
|
|
235
236
|
isValidAccountId,
|
|
236
237
|
linkConversationTranscript,
|
|
@@ -5024,7 +5025,7 @@ async function defaultHttpGet(url) {
|
|
|
5024
5025
|
}
|
|
5025
5026
|
}
|
|
5026
5027
|
async function defaultResolve(accountId) {
|
|
5027
|
-
const { resolveSocket: resolveSocket2 } = await import("./manager-
|
|
5028
|
+
const { resolveSocket: resolveSocket2 } = await import("./manager-5QV2EAZ2.js");
|
|
5028
5029
|
return resolveSocket2(accountId);
|
|
5029
5030
|
}
|
|
5030
5031
|
async function fetchAvatar(accountId, jid, deps = {}) {
|
|
@@ -10651,6 +10652,12 @@ function unwrapChannel(text) {
|
|
|
10651
10652
|
var COMPOSED_ADMIN_FRAME = /^(?:## Scheduled automation \(platform-verified\)\n[\s\S]*?\n\n)?(?:## Standing rules\n[\s\S]*?\n\n)?## Context\n([\s\S]*)\n\n## Instruction\n[\s\S]*$/;
|
|
10652
10653
|
var SCHEDULED_MARKER_PREFIX = "## Scheduled automation (platform-verified)\n";
|
|
10653
10654
|
var UPLOAD_ANNOTATION = /(?:\n\n)?\[The operator uploaded \d+ file\(s\): [\s\S]*\]$/;
|
|
10655
|
+
var REPLY_NOTE = /^\[In reply to an earlier message in this conversation(?:\.|: "([\s\S]*?)")\]\n\n/;
|
|
10656
|
+
function splitReplyNote(payload) {
|
|
10657
|
+
const m = payload.match(REPLY_NOTE);
|
|
10658
|
+
if (!m) return { body: payload };
|
|
10659
|
+
return { body: payload.slice(m[0].length), quoted: { body: m[1] ?? "" } };
|
|
10660
|
+
}
|
|
10654
10661
|
function rawFromComposedAdminFrame(text) {
|
|
10655
10662
|
const context = text.match(COMPOSED_ADMIN_FRAME)?.[1];
|
|
10656
10663
|
if (context === void 0) return void 0;
|
|
@@ -10662,8 +10669,10 @@ function uploadCountOf(text) {
|
|
|
10662
10669
|
const n = Number(text.match(UPLOAD_COUNT)?.[1]);
|
|
10663
10670
|
return Number.isInteger(n) && n > 0 ? n : void 0;
|
|
10664
10671
|
}
|
|
10665
|
-
function operatorInboundTurn(u, ts) {
|
|
10666
|
-
const
|
|
10672
|
+
function operatorInboundTurn(u, ts, uuid) {
|
|
10673
|
+
const framed = rawFromComposedAdminFrame(u.text);
|
|
10674
|
+
const split = framed === void 0 ? void 0 : splitReplyNote(framed);
|
|
10675
|
+
const rawBody = split?.body;
|
|
10667
10676
|
const uploadCount = uploadCountOf(u.text);
|
|
10668
10677
|
const scheduled = rawBody !== void 0 && u.text.startsWith(SCHEDULED_MARKER_PREFIX);
|
|
10669
10678
|
const text = rawBody === void 0 ? u.text.replace(PUBLIC_UPLOAD_ANNOTATION, "") : u.text;
|
|
@@ -10674,7 +10683,9 @@ function operatorInboundTurn(u, ts) {
|
|
|
10674
10683
|
...u.source ? { source: u.source } : {},
|
|
10675
10684
|
...rawBody !== void 0 ? { rawBody } : {},
|
|
10676
10685
|
...uploadCount !== void 0 ? { uploadCount } : {},
|
|
10677
|
-
...scheduled ? { scheduled: true } : {}
|
|
10686
|
+
...scheduled ? { scheduled: true } : {},
|
|
10687
|
+
...uuid !== void 0 ? { uuid } : {},
|
|
10688
|
+
...split?.quoted !== void 0 ? { quoted: split.quoted } : {}
|
|
10678
10689
|
};
|
|
10679
10690
|
}
|
|
10680
10691
|
function asString(content) {
|
|
@@ -10718,17 +10729,17 @@ function erroredToolUseIds(lines) {
|
|
|
10718
10729
|
}
|
|
10719
10730
|
return ids;
|
|
10720
10731
|
}
|
|
10721
|
-
function assistantTurns(content, ts, promoteFinal = false, erroredIds = /* @__PURE__ */ new Set()) {
|
|
10732
|
+
function assistantTurns(content, ts, promoteFinal = false, erroredIds = /* @__PURE__ */ new Set(), uuid) {
|
|
10722
10733
|
if (!Array.isArray(content)) return [];
|
|
10723
10734
|
const out = [];
|
|
10724
10735
|
for (const block of content) {
|
|
10725
10736
|
if (!block || typeof block !== "object") continue;
|
|
10726
10737
|
const b = block;
|
|
10727
10738
|
if (b.type === "text" && typeof b.text === "string") {
|
|
10728
|
-
out.push(promoteFinal && b.text.trim().length > 0 ? { kind: "agent-webchat-final", text: b.text, ts } : { kind: "agent-text", text: b.text, ts });
|
|
10739
|
+
out.push(promoteFinal && b.text.trim().length > 0 ? { kind: "agent-webchat-final", text: b.text, ts, ...uuid !== void 0 ? { uuid } : {} } : { kind: "agent-text", text: b.text, ts });
|
|
10729
10740
|
} else if (b.type === "tool_use" && (b.name === WA_REPLY_TOOL || b.name === WEBCHAT_REPLY_TOOL || b.name === CHANNEL_REPLY_TOOL)) {
|
|
10730
10741
|
const text = b.input?.text;
|
|
10731
|
-
out.push({ kind: "agent-reply", text: typeof text === "string" ? text : "", ts });
|
|
10742
|
+
out.push({ kind: "agent-reply", text: typeof text === "string" ? text : "", ts, ...uuid !== void 0 ? { uuid } : {} });
|
|
10732
10743
|
} else if (b.type === "tool_use" && (b.name === WA_REPLY_DOCUMENT_TOOL || b.name === CHANNEL_REPLY_DOCUMENT_TOOL)) {
|
|
10733
10744
|
const input = b.input ?? {};
|
|
10734
10745
|
const files = Array.isArray(input.files) ? input.files.filter((f) => typeof f === "string") : [];
|
|
@@ -10764,6 +10775,10 @@ function toolResultTurns(content, ts) {
|
|
|
10764
10775
|
}
|
|
10765
10776
|
return out;
|
|
10766
10777
|
}
|
|
10778
|
+
function parseTranscriptLine(line) {
|
|
10779
|
+
const turns = parseTranscript([line]);
|
|
10780
|
+
return turns.length > 0 ? turns[0] : null;
|
|
10781
|
+
}
|
|
10767
10782
|
function lastTurnTs(turns) {
|
|
10768
10783
|
for (let i = turns.length - 1; i >= 0; i--) {
|
|
10769
10784
|
if (turns[i].ts) return turns[i].ts;
|
|
@@ -10773,12 +10788,12 @@ function lastTurnTs(turns) {
|
|
|
10773
10788
|
function isModelGated(turns) {
|
|
10774
10789
|
return turns.some((t) => t.kind === "agent-error" && t.code === "model_unavailable");
|
|
10775
10790
|
}
|
|
10776
|
-
function renderOrSuppressChannelInbound(u, ts, out, queuedPendingSuppress) {
|
|
10791
|
+
function renderOrSuppressChannelInbound(u, ts, out, queuedPendingSuppress, uuid) {
|
|
10777
10792
|
const armed2 = queuedPendingSuppress.get(u.text) ?? 0;
|
|
10778
10793
|
if (armed2 > 0) {
|
|
10779
10794
|
queuedPendingSuppress.set(u.text, armed2 - 1);
|
|
10780
10795
|
} else {
|
|
10781
|
-
out.push(operatorInboundTurn(u, ts));
|
|
10796
|
+
out.push(operatorInboundTurn(u, ts, uuid));
|
|
10782
10797
|
}
|
|
10783
10798
|
}
|
|
10784
10799
|
function parseTranscript(lines, queuedPendingSuppress = /* @__PURE__ */ new Map(), turnCtx = {}) {
|
|
@@ -10807,7 +10822,7 @@ function parseTranscript(lines, queuedPendingSuppress = /* @__PURE__ */ new Map(
|
|
|
10807
10822
|
}
|
|
10808
10823
|
const isEnd = msg?.stop_reason === "end_turn";
|
|
10809
10824
|
const promoteFinal = isEnd && turnCtx.lastChannelSource === "webchat";
|
|
10810
|
-
out.push(...assistantTurns(msg?.content, ts, promoteFinal, erroredIds));
|
|
10825
|
+
out.push(...assistantTurns(msg?.content, ts, promoteFinal, erroredIds, asString(row.uuid) ?? void 0));
|
|
10811
10826
|
continue;
|
|
10812
10827
|
}
|
|
10813
10828
|
if (row.type === "queue-operation" && row.operation === "enqueue") {
|
|
@@ -10829,7 +10844,7 @@ function parseTranscript(lines, queuedPendingSuppress = /* @__PURE__ */ new Map(
|
|
|
10829
10844
|
const u = unwrapChannel(att.prompt);
|
|
10830
10845
|
turnCtx.lastChannelSource = u.source;
|
|
10831
10846
|
if (!isScheduleSource(att.prompt)) {
|
|
10832
|
-
renderOrSuppressChannelInbound(u, ts, out, queuedPendingSuppress);
|
|
10847
|
+
renderOrSuppressChannelInbound(u, ts, out, queuedPendingSuppress, asString(row.uuid) ?? void 0);
|
|
10833
10848
|
}
|
|
10834
10849
|
}
|
|
10835
10850
|
continue;
|
|
@@ -10858,7 +10873,7 @@ function parseTranscript(lines, queuedPendingSuppress = /* @__PURE__ */ new Map(
|
|
|
10858
10873
|
const u = unwrapChannel(text);
|
|
10859
10874
|
turnCtx.lastChannelSource = u.source;
|
|
10860
10875
|
if (!isScheduleSource(text)) {
|
|
10861
|
-
renderOrSuppressChannelInbound(u, ts, out, queuedPendingSuppress);
|
|
10876
|
+
renderOrSuppressChannelInbound(u, ts, out, queuedPendingSuppress, asString(row.uuid) ?? void 0);
|
|
10862
10877
|
}
|
|
10863
10878
|
} else if (row.isMeta === true) {
|
|
10864
10879
|
out.push({ kind: "harness-internal", text, ts });
|
|
@@ -11158,15 +11173,27 @@ data: ${JSON.stringify(obj)}
|
|
|
11158
11173
|
const { buf, end } = readFrom(jsonlPath, 0);
|
|
11159
11174
|
offset = end;
|
|
11160
11175
|
let n = 0;
|
|
11176
|
+
let delivered = 0;
|
|
11177
|
+
let identified = 0;
|
|
11178
|
+
let quotedTurns = 0;
|
|
11161
11179
|
for (const turn of parseTranscript(buf.toString("utf8").split("\n"), queuedPendingSuppress, turnCtx)) {
|
|
11162
11180
|
send(controller, enrichAdminAttachments(enrichDownloads(turn, scratchpadRoot), sessionId), offset);
|
|
11163
11181
|
actx.lastParentTurns.push(turn);
|
|
11164
11182
|
if (turn.kind === "agent-error") {
|
|
11165
11183
|
console.log(`[wa-stream] op=agent-error conn=${connId} sessionId=${sessionId} code=${turn.code} source=jsonl`);
|
|
11166
11184
|
}
|
|
11185
|
+
if (turn.kind === "operator-inbound" || turn.kind === "agent-reply" || turn.kind === "agent-webchat-final") {
|
|
11186
|
+
delivered++;
|
|
11187
|
+
if (turn.uuid !== void 0) identified++;
|
|
11188
|
+
if (turn.kind === "operator-inbound" && turn.quoted !== void 0) quotedTurns++;
|
|
11189
|
+
}
|
|
11167
11190
|
n++;
|
|
11168
11191
|
}
|
|
11169
11192
|
console.log(`[wa-stream] op=backlog conn=${connId} turns=${n} bytes=${end}`);
|
|
11193
|
+
console.log(`[session-reader] op=turn-id-census sessionId=${sessionId} delivered=${delivered} identified=${identified}`);
|
|
11194
|
+
if (quotedTurns > 0) {
|
|
11195
|
+
console.log(`[session-reader] op=chat-quote sessionId=${sessionId} quoted=${quotedTurns}`);
|
|
11196
|
+
}
|
|
11170
11197
|
} catch {
|
|
11171
11198
|
controller.enqueue(encoder.encode('event: error\ndata: "read-failed"\n\n'));
|
|
11172
11199
|
}
|
|
@@ -12249,6 +12276,35 @@ function locateSession(sessionId) {
|
|
|
12249
12276
|
const meta = readSidecarMeta(join27(dir, `${sessionId}.meta.json`));
|
|
12250
12277
|
return { projectDir: dir, channel: meta.channel, accountId: meta.accountId };
|
|
12251
12278
|
}
|
|
12279
|
+
function resolveQuoted(sessionId, quotedUuid, sendId) {
|
|
12280
|
+
if (!quotedUuid) return void 0;
|
|
12281
|
+
const log2 = (present, chars) => console.log(`[webchat:inbound] op=reply-quote sendId=${sendId} target=${quotedUuid} present=${present} chars=${chars}`);
|
|
12282
|
+
if (!sessionId || !UUID_PATTERN.test(quotedUuid)) {
|
|
12283
|
+
log2(false, 0);
|
|
12284
|
+
return void 0;
|
|
12285
|
+
}
|
|
12286
|
+
const { projectDir } = locateSession(sessionId);
|
|
12287
|
+
if (!projectDir) {
|
|
12288
|
+
log2(false, 0);
|
|
12289
|
+
return void 0;
|
|
12290
|
+
}
|
|
12291
|
+
let line;
|
|
12292
|
+
try {
|
|
12293
|
+
const needle = `"uuid":"${quotedUuid}"`;
|
|
12294
|
+
line = readFileSync21(join27(projectDir, `${sessionId}.jsonl`), "utf8").split("\n").find((l) => l.includes(needle));
|
|
12295
|
+
} catch {
|
|
12296
|
+
log2(false, 0);
|
|
12297
|
+
return void 0;
|
|
12298
|
+
}
|
|
12299
|
+
if (line === void 0) {
|
|
12300
|
+
log2(false, 0);
|
|
12301
|
+
return void 0;
|
|
12302
|
+
}
|
|
12303
|
+
const turn = parseTranscriptLine(line);
|
|
12304
|
+
const text = turn === null ? void 0 : turn.kind === "operator-inbound" ? turn.rawBody ?? turn.text : "text" in turn ? turn.text : void 0;
|
|
12305
|
+
log2(true, text ? [...text].length : 0);
|
|
12306
|
+
return text ? { id: quotedUuid, text } : { id: quotedUuid };
|
|
12307
|
+
}
|
|
12252
12308
|
function locateSidecar(sessionId) {
|
|
12253
12309
|
const cfg = claudeConfigDir();
|
|
12254
12310
|
if (!cfg) return null;
|
|
@@ -12501,6 +12557,7 @@ function createWebchatRoutes(deps) {
|
|
|
12501
12557
|
let target;
|
|
12502
12558
|
let files = [];
|
|
12503
12559
|
let clearSignal = false;
|
|
12560
|
+
let quotedUuid;
|
|
12504
12561
|
const contentType = c.req.header("content-type") ?? "";
|
|
12505
12562
|
const isMultipart = contentType.startsWith("multipart/form-data");
|
|
12506
12563
|
if (isMultipart) {
|
|
@@ -12522,6 +12579,8 @@ function createWebchatRoutes(deps) {
|
|
|
12522
12579
|
target = rawTarget;
|
|
12523
12580
|
}
|
|
12524
12581
|
clearSignal = formData.get("clearSignal") === "true";
|
|
12582
|
+
const rawQuoted = formData.get("quotedUuid");
|
|
12583
|
+
quotedUuid = typeof rawQuoted === "string" && rawQuoted ? rawQuoted : void 0;
|
|
12525
12584
|
} else {
|
|
12526
12585
|
const body = await c.req.json().catch(() => null);
|
|
12527
12586
|
const typed = body?.text;
|
|
@@ -12537,6 +12596,7 @@ function createWebchatRoutes(deps) {
|
|
|
12537
12596
|
target = rawTarget;
|
|
12538
12597
|
}
|
|
12539
12598
|
clearSignal = body?.clearSignal === true;
|
|
12599
|
+
quotedUuid = typeof body?.quotedUuid === "string" && body.quotedUuid ? body.quotedUuid : void 0;
|
|
12540
12600
|
}
|
|
12541
12601
|
let deliveryKey = WEBCHAT_ADMIN_KEY;
|
|
12542
12602
|
let deliverySessionId;
|
|
@@ -12656,8 +12716,9 @@ ${note}` : note;
|
|
|
12656
12716
|
}
|
|
12657
12717
|
const adminUserId = requesterUserId ?? void 0;
|
|
12658
12718
|
const inboundStartedAt = Date.now();
|
|
12659
|
-
const inbound = deliverySessionId !== void 0 ? await deps.handleInbound({ role: "admin", accountId: deliveryAccountId, key: deliveryKey, text, sessionId: deliverySessionId, adminUserId }) : await deps.handleInbound({ role: "admin", accountId: bootstrapAccountId, key: deliveryKey, text, adminUserId });
|
|
12660
12719
|
const sendId = sendIdFromResolve ?? ++sendSeq;
|
|
12720
|
+
const replyContext = resolveQuoted(deliverySessionId, quotedUuid, sendId);
|
|
12721
|
+
const inbound = deliverySessionId !== void 0 ? await deps.handleInbound({ role: "admin", accountId: deliveryAccountId, key: deliveryKey, text, sessionId: deliverySessionId, adminUserId, ...replyContext ? { replyContext } : {} }) : await deps.handleInbound({ role: "admin", accountId: bootstrapAccountId, key: deliveryKey, text, adminUserId });
|
|
12661
12722
|
let turnSessionId = deliverySessionId;
|
|
12662
12723
|
if (turnSessionId === void 0) {
|
|
12663
12724
|
const canonAccount = scopeAccountId ? validateAccountId2(scopeAccountId) : null;
|
|
@@ -14135,6 +14196,22 @@ var client_error_default = app13;
|
|
|
14135
14196
|
|
|
14136
14197
|
// server/routes/admin/session.ts
|
|
14137
14198
|
import { randomUUID as randomUUID5 } from "crypto";
|
|
14199
|
+
|
|
14200
|
+
// server/lib/session-timezone.ts
|
|
14201
|
+
async function resolveSessionTimezone(accountId) {
|
|
14202
|
+
try {
|
|
14203
|
+
const tz = await getUserTimezone(accountId);
|
|
14204
|
+
if (tz) return { timezone: tz, timezoneSource: "account" };
|
|
14205
|
+
} catch (err) {
|
|
14206
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
14207
|
+
console.error(
|
|
14208
|
+
`[admin-session] op=timezone-resolve outcome=failed accountId=${accountId.slice(0, 8)} err="${message}"`
|
|
14209
|
+
);
|
|
14210
|
+
}
|
|
14211
|
+
return { timezone: null, timezoneSource: "browser" };
|
|
14212
|
+
}
|
|
14213
|
+
|
|
14214
|
+
// server/routes/admin/session.ts
|
|
14138
14215
|
async function resolveUserIdentity(accountId, userId) {
|
|
14139
14216
|
const result = await loadAdminUserName(userId);
|
|
14140
14217
|
if (result.source === "neo4j") {
|
|
@@ -14172,6 +14249,7 @@ async function createAdminSession(accountId, thinkingView, userId, userName, rol
|
|
|
14172
14249
|
}
|
|
14173
14250
|
console.log(`[session] admin session created: userId=${userId ?? "\u2013"} userName=${userName ?? "\u2013"} accountId=${accountId} sessionId=${initialSessionId ?? "unbound"} cacheKey=${cacheKey.slice(0, 8)}`);
|
|
14174
14251
|
console.log(`[admin-session] role=${role ?? "null"} cacheKey=${cacheKey.slice(0, 8)} phase=create eager-ensured=${initialSessionId ? "true" : "false"}`);
|
|
14252
|
+
const { timezone, timezoneSource } = await resolveSessionTimezone(accountId);
|
|
14175
14253
|
return {
|
|
14176
14254
|
session_key: signedSessionToken,
|
|
14177
14255
|
agent_id: "admin",
|
|
@@ -14181,6 +14259,8 @@ async function createAdminSession(accountId, thinkingView, userId, userName, rol
|
|
|
14181
14259
|
role: role ?? null,
|
|
14182
14260
|
thinkingView: effectiveThinkingView,
|
|
14183
14261
|
businessName,
|
|
14262
|
+
timezone,
|
|
14263
|
+
timezoneSource,
|
|
14184
14264
|
sessionId: initialSessionId
|
|
14185
14265
|
};
|
|
14186
14266
|
}
|
|
@@ -14225,6 +14305,7 @@ app14.get("/", async (c) => {
|
|
|
14225
14305
|
const account = validateAccountId2(accountId);
|
|
14226
14306
|
const thinkingView = account?.config.thinkingView ?? "default";
|
|
14227
14307
|
const businessName = await fetchAccountName(accountId) || void 0;
|
|
14308
|
+
const { timezone, timezoneSource } = await resolveSessionTimezone(accountId);
|
|
14228
14309
|
const role = getRoleForSession(cacheKey);
|
|
14229
14310
|
console.log(`[admin-session] role=${role ?? "null"} accountId=${accountId.slice(0, 8)} cacheKey=${cacheKey.slice(0, 8)} phase=restore`);
|
|
14230
14311
|
const restoredUserId = getUserIdForSession(cacheKey);
|
|
@@ -14247,6 +14328,8 @@ app14.get("/", async (c) => {
|
|
|
14247
14328
|
role: role ?? null,
|
|
14248
14329
|
thinkingView,
|
|
14249
14330
|
businessName,
|
|
14331
|
+
timezone,
|
|
14332
|
+
timezoneSource,
|
|
14250
14333
|
sessionId: getSessionIdForSession(cacheKey) ?? null
|
|
14251
14334
|
});
|
|
14252
14335
|
});
|
|
@@ -23238,6 +23321,7 @@ function serializeMeetingICS(m, opts) {
|
|
|
23238
23321
|
}
|
|
23239
23322
|
lines.push(`SUMMARY:${escapeText(m.title ?? "")}`);
|
|
23240
23323
|
if (m.location) lines.push(`LOCATION:${escapeText(m.location)}`);
|
|
23324
|
+
if (m.description) lines.push(`DESCRIPTION:${escapeText(m.description)}`);
|
|
23241
23325
|
if (opts.includeAttendees) {
|
|
23242
23326
|
for (const a of m.attendees) {
|
|
23243
23327
|
const line = attendeeLine(a);
|
|
@@ -23408,7 +23492,7 @@ function normalizeAttendees(raw) {
|
|
|
23408
23492
|
};
|
|
23409
23493
|
});
|
|
23410
23494
|
}
|
|
23411
|
-
var EDITABLE_FIELDS = ["title", "startsAt", "endsAt", "location", "privateNote"];
|
|
23495
|
+
var EDITABLE_FIELDS = ["title", "startsAt", "endsAt", "location", "description", "privateNote"];
|
|
23412
23496
|
var CREATE_FIELDS = EDITABLE_FIELDS;
|
|
23413
23497
|
function buildCreateParams(accountId, body) {
|
|
23414
23498
|
const params = {
|
|
@@ -23426,6 +23510,7 @@ var MEETING_COLS = `elementId(m) AS id, m.title AS title,
|
|
|
23426
23510
|
toString(m.startsAt) AS startsAt, toString(m.endsAt) AS endsAt,
|
|
23427
23511
|
m.location AS location, coalesce(m.isAllDay, false) AS isAllDay,
|
|
23428
23512
|
'meeting' AS kind, m.uid AS uid, m.privateNote AS privateNote,
|
|
23513
|
+
m.description AS description, m.timezone AS timezone,
|
|
23429
23514
|
[(att:Person)-[:ATTENDED]->(m) | {name: coalesce(att.displayName, att.email), email: att.email}] AS attendees`;
|
|
23430
23515
|
var MEETING_RETURN = `RETURN ${MEETING_COLS}`;
|
|
23431
23516
|
function mapMeeting(r) {
|
|
@@ -23438,29 +23523,21 @@ function mapMeeting(r) {
|
|
|
23438
23523
|
isAllDay: r.get("isAllDay"),
|
|
23439
23524
|
kind: r.get("kind"),
|
|
23440
23525
|
attendees: normalizeAttendees(r.get("attendees")),
|
|
23441
|
-
privateNote: r.get("privateNote")
|
|
23526
|
+
privateNote: r.get("privateNote"),
|
|
23527
|
+
// Task 2280 — the meeting's own body, and the zone it was created in. Both
|
|
23528
|
+
// were stored and projected by nothing.
|
|
23529
|
+
description: r.get("description"),
|
|
23530
|
+
timezone: r.get("timezone")
|
|
23442
23531
|
};
|
|
23443
23532
|
}
|
|
23444
|
-
|
|
23445
|
-
const cacheKey = c.var.cacheKey;
|
|
23446
|
-
const accountId = getAccountIdForSession(cacheKey);
|
|
23447
|
-
if (!accountId) {
|
|
23448
|
-
console.error('[calendar] op=admin-read auth-rejected reason="no account for session"');
|
|
23449
|
-
return c.json({ error: "Account not found for session" }, 401);
|
|
23450
|
-
}
|
|
23451
|
-
const from = c.req.query("from");
|
|
23452
|
-
const to = c.req.query("to");
|
|
23453
|
-
if (!from || !to) return c.json({ error: "from and to (ISO) required" }, 400);
|
|
23454
|
-
const session = getSession();
|
|
23455
|
-
try {
|
|
23456
|
-
const res = await session.run(
|
|
23457
|
-
`MATCH (m:Meeting {accountId: $accountId})
|
|
23533
|
+
var GET_UNION = `MATCH (m:Meeting {accountId: $accountId})
|
|
23458
23534
|
WHERE NOT (m.endsAt IS NOT NULL AND m.endsAt <= datetime($from))
|
|
23459
23535
|
AND m.startsAt < datetime($to)
|
|
23460
23536
|
RETURN elementId(m) AS id, m.title AS title,
|
|
23461
23537
|
toString(m.startsAt) AS startsAt, toString(m.endsAt) AS endsAt,
|
|
23462
23538
|
m.location AS location, coalesce(m.isAllDay, false) AS isAllDay,
|
|
23463
23539
|
'meeting' AS kind, m.privateNote AS privateNote,
|
|
23540
|
+
m.description AS description, m.timezone AS timezone,
|
|
23464
23541
|
[(p:Person)-[:ATTENDED]->(m) | {name: coalesce(p.displayName, p.email), email: p.email}] AS attendees
|
|
23465
23542
|
UNION
|
|
23466
23543
|
MATCH (e:Event {accountId: $accountId})
|
|
@@ -23472,6 +23549,7 @@ app49.get("/meetings", requireAdminSession, async (c) => {
|
|
|
23472
23549
|
CASE WHEN e.endDate IS NULL THEN null ELSE toString(datetime(e.endDate)) END AS endsAt,
|
|
23473
23550
|
e.location AS location, false AS isAllDay,
|
|
23474
23551
|
'event' AS kind, null AS privateNote,
|
|
23552
|
+
e.description AS description, e.timezone AS timezone,
|
|
23475
23553
|
[] AS attendees
|
|
23476
23554
|
UNION
|
|
23477
23555
|
MATCH (t:Task {accountId: $accountId})
|
|
@@ -23482,9 +23560,21 @@ app49.get("/meetings", requireAdminSession, async (c) => {
|
|
|
23482
23560
|
toString(datetime(t.dueDate)) AS startsAt, null AS endsAt,
|
|
23483
23561
|
null AS location, true AS isAllDay,
|
|
23484
23562
|
'task' AS kind, null AS privateNote,
|
|
23485
|
-
|
|
23486
|
-
|
|
23487
|
-
|
|
23563
|
+
t.description AS description, null AS timezone,
|
|
23564
|
+
[] AS attendees`;
|
|
23565
|
+
app49.get("/meetings", requireAdminSession, async (c) => {
|
|
23566
|
+
const cacheKey = c.var.cacheKey;
|
|
23567
|
+
const accountId = getAccountIdForSession(cacheKey);
|
|
23568
|
+
if (!accountId) {
|
|
23569
|
+
console.error('[calendar] op=admin-read auth-rejected reason="no account for session"');
|
|
23570
|
+
return c.json({ error: "Account not found for session" }, 401);
|
|
23571
|
+
}
|
|
23572
|
+
const from = c.req.query("from");
|
|
23573
|
+
const to = c.req.query("to");
|
|
23574
|
+
if (!from || !to) return c.json({ error: "from and to (ISO) required" }, 400);
|
|
23575
|
+
const session = getSession();
|
|
23576
|
+
try {
|
|
23577
|
+
const res = await session.run(GET_UNION, { accountId, from, to });
|
|
23488
23578
|
const meetings = res.records.map(mapMeeting).sort((a, b) => new Date(a.startsAt).getTime() - new Date(b.startsAt).getTime());
|
|
23489
23579
|
const counts = { meeting: 0, event: 0, task: 0 };
|
|
23490
23580
|
for (const m of meetings) counts[m.kind]++;
|
|
@@ -23632,6 +23722,7 @@ app49.get("/meetings/:id/ics", requireAdminSession, async (c) => {
|
|
|
23632
23722
|
startsAt: mapped.startsAt,
|
|
23633
23723
|
endsAt: mapped.endsAt,
|
|
23634
23724
|
location: mapped.location,
|
|
23725
|
+
description: mapped.description,
|
|
23635
23726
|
isAllDay: mapped.isAllDay,
|
|
23636
23727
|
attendees: mapped.attendees
|
|
23637
23728
|
};
|
|
@@ -23668,7 +23759,7 @@ app49.patch("/meetings/:id", requireAdminSession, async (c) => {
|
|
|
23668
23759
|
const body = await safeJson(c) ?? {};
|
|
23669
23760
|
const fields = EDITABLE_FIELDS.filter((f) => f in body);
|
|
23670
23761
|
if (fields.length === 0) {
|
|
23671
|
-
return c.json({ error: "No editable field supplied (title, startsAt, endsAt, location, privateNote)" }, 400);
|
|
23762
|
+
return c.json({ error: "No editable field supplied (title, startsAt, endsAt, location, description, privateNote)" }, 400);
|
|
23672
23763
|
}
|
|
23673
23764
|
const setClauses = fields.map(
|
|
23674
23765
|
(f) => f === "startsAt" || f === "endsAt" ? `m.${f} = datetime($${f})` : `m.${f} = $${f}`
|
|
@@ -29155,7 +29246,7 @@ async function dispatchAdminRelay(deps, event) {
|
|
|
29155
29246
|
var routed = 0;
|
|
29156
29247
|
var notified = 0;
|
|
29157
29248
|
var relayed = 0;
|
|
29158
|
-
var
|
|
29249
|
+
var answered = 0;
|
|
29159
29250
|
function noteRouted() {
|
|
29160
29251
|
routed += 1;
|
|
29161
29252
|
}
|
|
@@ -29165,24 +29256,24 @@ function noteNotified() {
|
|
|
29165
29256
|
function noteRelayed() {
|
|
29166
29257
|
relayed += 1;
|
|
29167
29258
|
}
|
|
29168
|
-
function
|
|
29169
|
-
|
|
29259
|
+
function noteAnswered() {
|
|
29260
|
+
answered += 1;
|
|
29170
29261
|
}
|
|
29171
29262
|
function readPublicInboundCensus() {
|
|
29172
29263
|
return {
|
|
29173
29264
|
routed,
|
|
29174
29265
|
notified,
|
|
29175
29266
|
relayed,
|
|
29176
|
-
|
|
29267
|
+
answered,
|
|
29177
29268
|
gap: Math.max(0, routed - notified),
|
|
29178
29269
|
relayGap: Math.max(0, routed - relayed),
|
|
29179
|
-
|
|
29270
|
+
answerGap: Math.max(0, relayed - answered)
|
|
29180
29271
|
};
|
|
29181
29272
|
}
|
|
29182
29273
|
function runPublicNotifyReconcile() {
|
|
29183
29274
|
const c = readPublicInboundCensus();
|
|
29184
29275
|
console.error(
|
|
29185
|
-
`[whatsapp:notify] op=public-notify-reconcile routed=${c.routed} notified=${c.notified} relayed=${c.relayed}
|
|
29276
|
+
`[whatsapp:notify] op=public-notify-reconcile routed=${c.routed} notified=${c.notified} relayed=${c.relayed} answered=${c.answered} gap=${c.gap} relayGap=${c.relayGap} answerGap=${c.answerGap}`
|
|
29186
29277
|
);
|
|
29187
29278
|
}
|
|
29188
29279
|
|
|
@@ -29924,13 +30015,25 @@ var WebchatGateway = class _WebchatGateway {
|
|
|
29924
30015
|
`[preference-inject] op=inject channel=web accountId=${input.accountId} injected=${injected} owner=${owner8} source=${res.source}`
|
|
29925
30016
|
);
|
|
29926
30017
|
}
|
|
30018
|
+
const messageId = `wc-${++this.seq}`;
|
|
29927
30019
|
this.hub.deliver(
|
|
29928
|
-
{
|
|
30020
|
+
{
|
|
30021
|
+
key: input.key,
|
|
30022
|
+
text: input.text,
|
|
30023
|
+
messageId,
|
|
30024
|
+
standingRules,
|
|
30025
|
+
...input.replyContext ? { replyContext: input.replyContext } : {}
|
|
30026
|
+
},
|
|
29929
30027
|
Date.now()
|
|
29930
30028
|
);
|
|
30029
|
+
if (input.replyContext) {
|
|
30030
|
+
console.error(
|
|
30031
|
+
`[webchat:inbound] op=reply-quote-forward key=${keyDisplay(input.key)} messageId=${messageId} target=${input.replyContext.id}`
|
|
30032
|
+
);
|
|
30033
|
+
}
|
|
29931
30034
|
if (willDeliverNow) this.lastDeliveredAt.set(input.key, Date.now());
|
|
29932
30035
|
console.error(
|
|
29933
|
-
`[webchat:inbound] op=received key=${keyDisplay(input.key)} role=${input.role} bytes=${bytes} delivery=${willDeliverNow ? "immediate" : "queued"}`
|
|
30036
|
+
`[webchat:inbound] op=received key=${keyDisplay(input.key)} messageId=${messageId} role=${input.role} bytes=${bytes} delivery=${willDeliverNow ? "immediate" : "queued"}`
|
|
29934
30037
|
);
|
|
29935
30038
|
if (input.role === "admin") {
|
|
29936
30039
|
this.recoverable.set(input.key, {
|
|
@@ -33595,7 +33698,7 @@ init({
|
|
|
33595
33698
|
}
|
|
33596
33699
|
try {
|
|
33597
33700
|
const houseForRelay = resolveAccount();
|
|
33598
|
-
let
|
|
33701
|
+
let answerCounted = false;
|
|
33599
33702
|
const relayAccountId = msg.effectiveAccountId;
|
|
33600
33703
|
await dispatchAdminRelay(
|
|
33601
33704
|
{
|
|
@@ -33603,9 +33706,9 @@ init({
|
|
|
33603
33706
|
handleInbound: (input) => waGateway.handleInbound(input),
|
|
33604
33707
|
sendText: async (accountId, destination, text) => {
|
|
33605
33708
|
await sendWhatsAppTextForRelay(accountId, destination, text);
|
|
33606
|
-
if (!
|
|
33607
|
-
|
|
33608
|
-
|
|
33709
|
+
if (!answerCounted) {
|
|
33710
|
+
answerCounted = true;
|
|
33711
|
+
noteAnswered();
|
|
33609
33712
|
}
|
|
33610
33713
|
},
|
|
33611
33714
|
houseAccountId: msg.accountId
|
|
Binary file
|
|
Binary file
|