dsh-phone-bridge 0.2.5 → 0.2.7
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/index.js +85 -15
- package/package.json +1 -1
package/index.js
CHANGED
|
@@ -943,36 +943,106 @@ export function apply(ctx, config = {}) {
|
|
|
943
943
|
}
|
|
944
944
|
const sessionController = ctx.get("sessionController");
|
|
945
945
|
if (!sessionController) throw new Error("sessionController is unavailable");
|
|
946
|
-
if (typeof sessionController.page !== "function") {
|
|
947
|
-
throw new Error("this DSH build does not expose sessionController.page");
|
|
948
|
-
}
|
|
949
946
|
|
|
950
947
|
const signal = new AbortController().signal;
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
948
|
+
const traces = {};
|
|
949
|
+
|
|
950
|
+
// Two ways in, tried in order.
|
|
951
|
+
//
|
|
952
|
+
// inspect() hands back the event list outright (SessionInspection.events),
|
|
953
|
+
// so it needs no cursor. page() does need one: throughSeq is an absolute
|
|
954
|
+
// sequence, and -1 is not "newest" but "nothing", since paginate starts at
|
|
955
|
+
// end = throughSeq + 1 = 0 and walks backwards from -1. That misreading is
|
|
956
|
+
// what made the first version answer ok with zero messages.
|
|
957
|
+
let events = [];
|
|
958
|
+
let used = null;
|
|
959
|
+
|
|
960
|
+
if (typeof sessionController.inspect === "function") {
|
|
961
|
+
try {
|
|
962
|
+
const inspection = await sessionController.inspect(sessionId, signal);
|
|
963
|
+
const list = Array.isArray(inspection?.events) ? inspection.events : [];
|
|
964
|
+
traces.inspect = {
|
|
965
|
+
eventCount: list.length,
|
|
966
|
+
firstSeq: list[0]?.seq ?? null,
|
|
967
|
+
lastSeq: list[list.length - 1]?.seq ?? null,
|
|
968
|
+
};
|
|
969
|
+
if (list.length) {
|
|
970
|
+
events = list;
|
|
971
|
+
used = "inspect";
|
|
972
|
+
}
|
|
973
|
+
} catch (error) {
|
|
974
|
+
traces.inspect = { error: String(error?.message ?? error) };
|
|
975
|
+
}
|
|
976
|
+
}
|
|
977
|
+
|
|
978
|
+
if (!events.length && typeof sessionController.page === "function") {
|
|
979
|
+
try {
|
|
980
|
+
// Page from whatever cursor inspect gave us, else from the very start.
|
|
981
|
+
const cursor = Number(traces.inspect?.lastSeq ?? 0);
|
|
982
|
+
const page = await sessionController.page({
|
|
983
|
+
address: { kind: "session", sessionId },
|
|
984
|
+
throughSeq: Number.isSafeInteger(cursor) && cursor >= 0 ? cursor : 0,
|
|
985
|
+
maxMessages: 400,
|
|
986
|
+
}, signal);
|
|
987
|
+
const list = (page?.records ?? []).map((record) => record?.event).filter(Boolean);
|
|
988
|
+
traces.page = {
|
|
989
|
+
cursor,
|
|
990
|
+
recordCount: list.length,
|
|
991
|
+
hasMore: page?.hasMore ?? null,
|
|
992
|
+
firstSeq: list[0]?.seq ?? null,
|
|
993
|
+
lastSeq: list[list.length - 1]?.seq ?? null,
|
|
994
|
+
};
|
|
995
|
+
if (list.length) {
|
|
996
|
+
events = list;
|
|
997
|
+
used = "page";
|
|
998
|
+
}
|
|
999
|
+
} catch (error) {
|
|
1000
|
+
traces.page = { error: String(error?.message ?? error) };
|
|
1001
|
+
}
|
|
1002
|
+
}
|
|
958
1003
|
|
|
959
1004
|
const texts = [];
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
1005
|
+
const typeTally = {};
|
|
1006
|
+
let firstUserEvent = null;
|
|
1007
|
+
let userEventCount = 0;
|
|
1008
|
+
for (const event of events) {
|
|
1009
|
+
if (!event) continue;
|
|
1010
|
+
const key = event.type ?? "(none)";
|
|
1011
|
+
typeTally[key] = (typeTally[key] ?? 0) + 1;
|
|
1012
|
+
if (event.type !== "user/message") continue;
|
|
1013
|
+
userEventCount += 1;
|
|
1014
|
+
if (!firstUserEvent) firstUserEvent = event;
|
|
963
1015
|
if (event?.data?.source?.kind !== "user") continue;
|
|
964
1016
|
const text = textFromContentBlocks(event.data.content);
|
|
965
1017
|
if (!text) continue;
|
|
966
1018
|
texts.push({ at: event.time ?? null, text });
|
|
967
1019
|
}
|
|
968
1020
|
|
|
969
|
-
|
|
1021
|
+
const payload = {
|
|
970
1022
|
ok: true,
|
|
971
1023
|
sessionId,
|
|
1024
|
+
source: used,
|
|
972
1025
|
total: texts.length,
|
|
973
1026
|
// Newest last, so the caller can slice from the end.
|
|
974
1027
|
messages: texts.slice(-limit),
|
|
975
|
-
}
|
|
1028
|
+
};
|
|
1029
|
+
|
|
1030
|
+
// Opt-in shape report. The history event format is not a documented
|
|
1031
|
+
// surface, so when a read comes back empty the only quick way to find out
|
|
1032
|
+
// why is to look at what actually arrived. Loopback-only, and truncated.
|
|
1033
|
+
if ((url.searchParams.get("debug") ?? "") === "1") {
|
|
1034
|
+
payload.diagnostics = {
|
|
1035
|
+
used,
|
|
1036
|
+
eventCount: events.length,
|
|
1037
|
+
userEventCount,
|
|
1038
|
+
eventTypes: typeTally,
|
|
1039
|
+
traces,
|
|
1040
|
+
firstEventKeys: events[0] ? Object.keys(events[0]) : [],
|
|
1041
|
+
firstUserEventSample: firstUserEvent ? JSON.stringify(firstUserEvent).slice(0, 1500) : null,
|
|
1042
|
+
};
|
|
1043
|
+
}
|
|
1044
|
+
|
|
1045
|
+
sendJson(res, 200, payload);
|
|
976
1046
|
} catch (error) {
|
|
977
1047
|
sendJson(res, 500, { ok: false, error: String(error?.message ?? error) });
|
|
978
1048
|
}
|