@usewhisper/sdk 2.1.0 → 2.2.1
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.d.mts +124 -7
- package/index.d.ts +124 -7
- package/index.js +287 -42
- package/index.mjs +285 -41
- package/package.json +1 -1
package/index.mjs
CHANGED
|
@@ -117,7 +117,7 @@ ${context}` : "",
|
|
|
117
117
|
if (extractedMemories.length > 0) {
|
|
118
118
|
const bulk = await this.client.addMemoriesBulk({
|
|
119
119
|
project: options?.project ?? this.options.project,
|
|
120
|
-
|
|
120
|
+
write_mode: "async",
|
|
121
121
|
memories: extractedMemories.map((m) => ({
|
|
122
122
|
content: m.content,
|
|
123
123
|
memory_type: m.memoryType,
|
|
@@ -185,6 +185,10 @@ ${context}` : "",
|
|
|
185
185
|
extracted: result?.memories_created ?? 0
|
|
186
186
|
};
|
|
187
187
|
} catch (error) {
|
|
188
|
+
const fallback = await this.fallbackCaptureViaAddMemory(messages, options);
|
|
189
|
+
if (fallback.success) {
|
|
190
|
+
return fallback;
|
|
191
|
+
}
|
|
188
192
|
console.error("[Whisper] Session capture failed:", error);
|
|
189
193
|
return { success: false, extracted: 0 };
|
|
190
194
|
}
|
|
@@ -242,6 +246,28 @@ User: ${params.userMessage}` : params.userMessage;
|
|
|
242
246
|
}
|
|
243
247
|
return Array.from(new Set(ids));
|
|
244
248
|
}
|
|
249
|
+
async fallbackCaptureViaAddMemory(messages, options) {
|
|
250
|
+
const userMessages = messages.filter((m) => m.role === "user").map((m) => (m.content || "").trim()).filter((content) => content.length >= 5).slice(-2);
|
|
251
|
+
if (userMessages.length === 0) {
|
|
252
|
+
return { success: false, extracted: 0 };
|
|
253
|
+
}
|
|
254
|
+
let extracted = 0;
|
|
255
|
+
for (const content of userMessages) {
|
|
256
|
+
try {
|
|
257
|
+
await this.client.addMemory({
|
|
258
|
+
project: options?.project ?? this.options.project,
|
|
259
|
+
content,
|
|
260
|
+
memory_type: "factual",
|
|
261
|
+
user_id: options?.userId ?? this.userId,
|
|
262
|
+
session_id: options?.sessionId ?? this.sessionId,
|
|
263
|
+
allow_legacy_fallback: true
|
|
264
|
+
});
|
|
265
|
+
extracted += 1;
|
|
266
|
+
} catch {
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
return { success: extracted > 0, extracted };
|
|
270
|
+
}
|
|
245
271
|
};
|
|
246
272
|
var whisper_agent_default = Whisper;
|
|
247
273
|
|
|
@@ -314,6 +340,31 @@ function createAgentMiddleware(config) {
|
|
|
314
340
|
return new WhisperAgentMiddleware(config);
|
|
315
341
|
}
|
|
316
342
|
|
|
343
|
+
// ../src/sdk/graph-utils.ts
|
|
344
|
+
function sanitizeId(id) {
|
|
345
|
+
return `n_${id.replace(/[^a-zA-Z0-9_]/g, "_")}`;
|
|
346
|
+
}
|
|
347
|
+
function shortLabel(input, max = 48) {
|
|
348
|
+
const text = (input || "").replace(/\s+/g, " ").trim();
|
|
349
|
+
if (text.length <= max) return text;
|
|
350
|
+
return `${text.slice(0, max - 3)}...`;
|
|
351
|
+
}
|
|
352
|
+
function memoryGraphToMermaid(graph) {
|
|
353
|
+
const lines = ["flowchart LR"];
|
|
354
|
+
for (const node of graph.nodes || []) {
|
|
355
|
+
const sid = sanitizeId(node.id);
|
|
356
|
+
const label = shortLabel(node.label || node.id);
|
|
357
|
+
lines.push(` ${sid}["${label.replace(/"/g, '\\"')}"]`);
|
|
358
|
+
}
|
|
359
|
+
for (const edge of graph.edges || []) {
|
|
360
|
+
const s = sanitizeId(edge.source);
|
|
361
|
+
const t = sanitizeId(edge.target);
|
|
362
|
+
const rel = shortLabel(edge.type || "rel", 18).replace(/"/g, '\\"');
|
|
363
|
+
lines.push(` ${s} -->|${rel}| ${t}`);
|
|
364
|
+
}
|
|
365
|
+
return lines.join("\n");
|
|
366
|
+
}
|
|
367
|
+
|
|
317
368
|
// ../src/sdk/index.ts
|
|
318
369
|
var WhisperError = class extends Error {
|
|
319
370
|
code;
|
|
@@ -358,6 +409,10 @@ function normalizeEndpoint(endpoint) {
|
|
|
358
409
|
}
|
|
359
410
|
return withLeadingSlash;
|
|
360
411
|
}
|
|
412
|
+
function isProjectNotFoundMessage(message) {
|
|
413
|
+
const normalized = message.toLowerCase();
|
|
414
|
+
return normalized.includes("project not found") || normalized.includes("no project found") || normalized.includes("project does not exist");
|
|
415
|
+
}
|
|
361
416
|
var WhisperContext = class _WhisperContext {
|
|
362
417
|
apiKey;
|
|
363
418
|
baseUrl;
|
|
@@ -464,9 +519,17 @@ var WhisperContext = class _WhisperContext {
|
|
|
464
519
|
return Array.from(candidates).filter(Boolean);
|
|
465
520
|
}
|
|
466
521
|
async withProjectRefFallback(projectRef, execute) {
|
|
522
|
+
try {
|
|
523
|
+
return await execute(projectRef);
|
|
524
|
+
} catch (error) {
|
|
525
|
+
if (!(error instanceof WhisperError) || error.code !== "PROJECT_NOT_FOUND") {
|
|
526
|
+
throw error;
|
|
527
|
+
}
|
|
528
|
+
}
|
|
467
529
|
const refs = await this.getProjectRefCandidates(projectRef);
|
|
468
530
|
let lastError;
|
|
469
531
|
for (const ref of refs) {
|
|
532
|
+
if (ref === projectRef) continue;
|
|
470
533
|
try {
|
|
471
534
|
return await execute(ref);
|
|
472
535
|
} catch (error) {
|
|
@@ -489,7 +552,7 @@ var WhisperContext = class _WhisperContext {
|
|
|
489
552
|
if (status === 401 || /api key|unauthorized|forbidden/i.test(message)) {
|
|
490
553
|
return { code: "INVALID_API_KEY", retryable: false };
|
|
491
554
|
}
|
|
492
|
-
if (status === 404
|
|
555
|
+
if (status === 404 && isProjectNotFoundMessage(message)) {
|
|
493
556
|
return { code: "PROJECT_NOT_FOUND", retryable: false };
|
|
494
557
|
}
|
|
495
558
|
if (status === 408) {
|
|
@@ -503,6 +566,16 @@ var WhisperContext = class _WhisperContext {
|
|
|
503
566
|
}
|
|
504
567
|
return { code: "REQUEST_FAILED", retryable: false };
|
|
505
568
|
}
|
|
569
|
+
isEndpointNotFoundError(error) {
|
|
570
|
+
if (!(error instanceof WhisperError)) {
|
|
571
|
+
return false;
|
|
572
|
+
}
|
|
573
|
+
if (error.status !== 404) {
|
|
574
|
+
return false;
|
|
575
|
+
}
|
|
576
|
+
const message = (error.message || "").toLowerCase();
|
|
577
|
+
return !isProjectNotFoundMessage(message);
|
|
578
|
+
}
|
|
506
579
|
async request(endpoint, options = {}) {
|
|
507
580
|
const maxAttempts = Math.max(1, this.retryConfig.maxAttempts);
|
|
508
581
|
const normalizedEndpoint = normalizeEndpoint(endpoint);
|
|
@@ -536,7 +609,11 @@ var WhisperContext = class _WhisperContext {
|
|
|
536
609
|
} catch {
|
|
537
610
|
payload = await response.text().catch(() => "");
|
|
538
611
|
}
|
|
539
|
-
|
|
612
|
+
let message = typeof payload === "string" ? payload : payload?.error || payload?.message || `HTTP ${response.status}: ${response.statusText}`;
|
|
613
|
+
if (response.status === 404 && !isProjectNotFoundMessage(message)) {
|
|
614
|
+
const endpointHint = `${this.baseUrl}${normalizedEndpoint}`;
|
|
615
|
+
message = `Endpoint not found at ${endpointHint}. This deployment may not support this API route.`;
|
|
616
|
+
}
|
|
540
617
|
const { code, retryable } = this.classifyError(response.status, message);
|
|
541
618
|
const err = new WhisperError({
|
|
542
619
|
code,
|
|
@@ -679,13 +756,18 @@ var WhisperContext = class _WhisperContext {
|
|
|
679
756
|
session_id: params.session_id,
|
|
680
757
|
agent_id: params.agent_id,
|
|
681
758
|
importance: params.importance,
|
|
682
|
-
metadata: params.metadata
|
|
759
|
+
metadata: params.metadata,
|
|
760
|
+
async: params.async,
|
|
761
|
+
write_mode: params.write_mode
|
|
683
762
|
})
|
|
684
763
|
});
|
|
685
|
-
const id2 = direct?.memory?.id || direct?.id || direct?.memory_id;
|
|
764
|
+
const id2 = direct?.memory?.id || direct?.id || direct?.memory_id || direct?.job_id;
|
|
686
765
|
if (id2) {
|
|
687
766
|
return { id: id2, success: true, path: "sota", fallback_used: false };
|
|
688
767
|
}
|
|
768
|
+
if (direct?.success === true) {
|
|
769
|
+
return { id: "", success: true, path: "sota", fallback_used: false };
|
|
770
|
+
}
|
|
689
771
|
} catch (error) {
|
|
690
772
|
if (params.allow_legacy_fallback === false) {
|
|
691
773
|
throw error;
|
|
@@ -717,10 +799,40 @@ var WhisperContext = class _WhisperContext {
|
|
|
717
799
|
}
|
|
718
800
|
async addMemoriesBulk(params) {
|
|
719
801
|
const projectRef = this.getRequiredProject(params.project);
|
|
720
|
-
return this.withProjectRefFallback(projectRef, (project) =>
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
802
|
+
return this.withProjectRefFallback(projectRef, async (project) => {
|
|
803
|
+
try {
|
|
804
|
+
return await this.request("/v1/memory/bulk", {
|
|
805
|
+
method: "POST",
|
|
806
|
+
body: JSON.stringify({ ...params, project })
|
|
807
|
+
});
|
|
808
|
+
} catch (error) {
|
|
809
|
+
if (!this.isEndpointNotFoundError(error)) {
|
|
810
|
+
throw error;
|
|
811
|
+
}
|
|
812
|
+
const created = await Promise.all(
|
|
813
|
+
params.memories.map(
|
|
814
|
+
(memory) => this.addMemory({
|
|
815
|
+
project,
|
|
816
|
+
content: memory.content,
|
|
817
|
+
memory_type: memory.memory_type,
|
|
818
|
+
user_id: memory.user_id,
|
|
819
|
+
session_id: memory.session_id,
|
|
820
|
+
agent_id: memory.agent_id,
|
|
821
|
+
importance: memory.importance,
|
|
822
|
+
metadata: memory.metadata,
|
|
823
|
+
allow_legacy_fallback: true
|
|
824
|
+
})
|
|
825
|
+
)
|
|
826
|
+
);
|
|
827
|
+
return {
|
|
828
|
+
success: true,
|
|
829
|
+
created: created.length,
|
|
830
|
+
memories: created,
|
|
831
|
+
path: "legacy",
|
|
832
|
+
fallback_used: true
|
|
833
|
+
};
|
|
834
|
+
}
|
|
835
|
+
});
|
|
724
836
|
}
|
|
725
837
|
async extractMemories(params) {
|
|
726
838
|
const projectRef = this.getRequiredProject(params.project);
|
|
@@ -745,17 +857,48 @@ var WhisperContext = class _WhisperContext {
|
|
|
745
857
|
}
|
|
746
858
|
async searchMemories(params) {
|
|
747
859
|
const projectRef = this.getRequiredProject(params.project);
|
|
748
|
-
return this.withProjectRefFallback(projectRef, (project) =>
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
860
|
+
return this.withProjectRefFallback(projectRef, async (project) => {
|
|
861
|
+
try {
|
|
862
|
+
return await this.request("/v1/memory/search", {
|
|
863
|
+
method: "POST",
|
|
864
|
+
body: JSON.stringify({
|
|
865
|
+
query: params.query,
|
|
866
|
+
project,
|
|
867
|
+
user_id: params.user_id,
|
|
868
|
+
session_id: params.session_id,
|
|
869
|
+
memory_types: params.memory_type ? [params.memory_type] : void 0,
|
|
870
|
+
top_k: params.top_k || 10,
|
|
871
|
+
profile: params.profile,
|
|
872
|
+
include_pending: params.include_pending
|
|
873
|
+
})
|
|
874
|
+
});
|
|
875
|
+
} catch (error) {
|
|
876
|
+
if (!this.isEndpointNotFoundError(error)) {
|
|
877
|
+
throw error;
|
|
878
|
+
}
|
|
879
|
+
const legacyTypeMap = {
|
|
880
|
+
factual: "factual",
|
|
881
|
+
preference: "semantic",
|
|
882
|
+
event: "episodic",
|
|
883
|
+
relationship: "semantic",
|
|
884
|
+
opinion: "semantic",
|
|
885
|
+
goal: "semantic",
|
|
886
|
+
instruction: "procedural"
|
|
887
|
+
};
|
|
888
|
+
return this.request("/v1/memories/search", {
|
|
889
|
+
method: "POST",
|
|
890
|
+
body: JSON.stringify({
|
|
891
|
+
query: params.query,
|
|
892
|
+
project,
|
|
893
|
+
user_id: params.user_id,
|
|
894
|
+
session_id: params.session_id,
|
|
895
|
+
agent_id: params.agent_id,
|
|
896
|
+
memory_type: params.memory_type ? legacyTypeMap[params.memory_type] : void 0,
|
|
897
|
+
top_k: params.top_k || 10
|
|
898
|
+
})
|
|
899
|
+
});
|
|
900
|
+
}
|
|
901
|
+
});
|
|
759
902
|
}
|
|
760
903
|
async createApiKey(params) {
|
|
761
904
|
return this.request("/v1/keys", {
|
|
@@ -771,10 +914,29 @@ var WhisperContext = class _WhisperContext {
|
|
|
771
914
|
}
|
|
772
915
|
async searchMemoriesSOTA(params) {
|
|
773
916
|
const projectRef = this.getRequiredProject(params.project);
|
|
774
|
-
return this.withProjectRefFallback(projectRef, (project) =>
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
917
|
+
return this.withProjectRefFallback(projectRef, async (project) => {
|
|
918
|
+
try {
|
|
919
|
+
return await this.request("/v1/memory/search", {
|
|
920
|
+
method: "POST",
|
|
921
|
+
body: JSON.stringify({ ...params, project })
|
|
922
|
+
});
|
|
923
|
+
} catch (error) {
|
|
924
|
+
if (!this.isEndpointNotFoundError(error)) {
|
|
925
|
+
throw error;
|
|
926
|
+
}
|
|
927
|
+
const firstType = params.memory_types?.[0];
|
|
928
|
+
return this.searchMemories({
|
|
929
|
+
project,
|
|
930
|
+
query: params.query,
|
|
931
|
+
user_id: params.user_id,
|
|
932
|
+
session_id: params.session_id,
|
|
933
|
+
memory_type: firstType,
|
|
934
|
+
top_k: params.top_k,
|
|
935
|
+
profile: params.profile,
|
|
936
|
+
include_pending: params.include_pending
|
|
937
|
+
});
|
|
938
|
+
}
|
|
939
|
+
});
|
|
778
940
|
}
|
|
779
941
|
async ingestSession(params) {
|
|
780
942
|
const projectRef = this.getRequiredProject(params.project);
|
|
@@ -784,37 +946,116 @@ var WhisperContext = class _WhisperContext {
|
|
|
784
946
|
}));
|
|
785
947
|
}
|
|
786
948
|
async getSessionMemories(params) {
|
|
787
|
-
const
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
949
|
+
const projectRef = this.getRequiredProject(params.project);
|
|
950
|
+
return this.withProjectRefFallback(projectRef, async (project) => {
|
|
951
|
+
const query = new URLSearchParams({
|
|
952
|
+
project,
|
|
953
|
+
...params.limit && { limit: params.limit.toString() },
|
|
954
|
+
...params.since_date && { since_date: params.since_date },
|
|
955
|
+
...params.include_pending !== void 0 && { include_pending: String(params.include_pending) }
|
|
956
|
+
});
|
|
957
|
+
try {
|
|
958
|
+
return await this.request(`/v1/memory/session/${params.session_id}?${query}`);
|
|
959
|
+
} catch (error) {
|
|
960
|
+
if (!this.isEndpointNotFoundError(error)) {
|
|
961
|
+
throw error;
|
|
962
|
+
}
|
|
963
|
+
return { memories: [], count: 0 };
|
|
964
|
+
}
|
|
792
965
|
});
|
|
793
|
-
return this.request(`/v1/memory/session/${params.session_id}?${query}`);
|
|
794
966
|
}
|
|
795
967
|
async getUserProfile(params) {
|
|
796
|
-
const
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
968
|
+
const projectRef = this.getRequiredProject(params.project);
|
|
969
|
+
return this.withProjectRefFallback(projectRef, async (project) => {
|
|
970
|
+
const query = new URLSearchParams({
|
|
971
|
+
project,
|
|
972
|
+
...params.memory_types && { memory_types: params.memory_types },
|
|
973
|
+
...params.include_pending !== void 0 && { include_pending: String(params.include_pending) }
|
|
974
|
+
});
|
|
975
|
+
try {
|
|
976
|
+
return await this.request(`/v1/memory/profile/${params.user_id}?${query}`);
|
|
977
|
+
} catch (error) {
|
|
978
|
+
if (!this.isEndpointNotFoundError(error)) {
|
|
979
|
+
throw error;
|
|
980
|
+
}
|
|
981
|
+
const legacyQuery = new URLSearchParams({
|
|
982
|
+
project,
|
|
983
|
+
user_id: params.user_id,
|
|
984
|
+
limit: "200"
|
|
985
|
+
});
|
|
986
|
+
const legacy = await this.request(`/v1/memories?${legacyQuery}`);
|
|
987
|
+
const memories = Array.isArray(legacy?.memories) ? legacy.memories : [];
|
|
988
|
+
return {
|
|
989
|
+
user_id: params.user_id,
|
|
990
|
+
memories,
|
|
991
|
+
count: memories.length
|
|
992
|
+
};
|
|
993
|
+
}
|
|
800
994
|
});
|
|
801
|
-
return this.request(`/v1/memory/profile/${params.user_id}?${query}`);
|
|
802
995
|
}
|
|
803
996
|
async getMemoryVersions(memoryId) {
|
|
804
997
|
return this.request(`/v1/memory/${memoryId}/versions`);
|
|
805
998
|
}
|
|
806
999
|
async updateMemory(memoryId, params) {
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
1000
|
+
try {
|
|
1001
|
+
return await this.request(`/v1/memory/${memoryId}`, {
|
|
1002
|
+
method: "PUT",
|
|
1003
|
+
body: JSON.stringify(params)
|
|
1004
|
+
});
|
|
1005
|
+
} catch (error) {
|
|
1006
|
+
if (!this.isEndpointNotFoundError(error)) {
|
|
1007
|
+
throw error;
|
|
1008
|
+
}
|
|
1009
|
+
const legacy = await this.request(`/v1/memories/${memoryId}`, {
|
|
1010
|
+
method: "PUT",
|
|
1011
|
+
body: JSON.stringify({
|
|
1012
|
+
content: params.content
|
|
1013
|
+
})
|
|
1014
|
+
});
|
|
1015
|
+
return {
|
|
1016
|
+
success: true,
|
|
1017
|
+
new_memory_id: legacy?.id || memoryId,
|
|
1018
|
+
old_memory_id: memoryId
|
|
1019
|
+
};
|
|
1020
|
+
}
|
|
811
1021
|
}
|
|
812
1022
|
async deleteMemory(memoryId) {
|
|
813
|
-
|
|
1023
|
+
try {
|
|
1024
|
+
return await this.request(`/v1/memory/${memoryId}`, { method: "DELETE" });
|
|
1025
|
+
} catch (error) {
|
|
1026
|
+
if (!this.isEndpointNotFoundError(error)) {
|
|
1027
|
+
throw error;
|
|
1028
|
+
}
|
|
1029
|
+
await this.request(`/v1/memories/${memoryId}`, { method: "DELETE" });
|
|
1030
|
+
return {
|
|
1031
|
+
success: true,
|
|
1032
|
+
deleted: memoryId
|
|
1033
|
+
};
|
|
1034
|
+
}
|
|
814
1035
|
}
|
|
815
1036
|
async getMemoryRelations(memoryId) {
|
|
816
1037
|
return this.request(`/v1/memory/${memoryId}/relations`);
|
|
817
1038
|
}
|
|
1039
|
+
async getMemoryGraph(params) {
|
|
1040
|
+
const project = await this.resolveProjectId(this.getRequiredProject(params.project));
|
|
1041
|
+
const query = new URLSearchParams({
|
|
1042
|
+
project,
|
|
1043
|
+
...params.user_id && { user_id: params.user_id },
|
|
1044
|
+
...params.session_id && { session_id: params.session_id },
|
|
1045
|
+
...params.include_inactive !== void 0 && { include_inactive: String(params.include_inactive) },
|
|
1046
|
+
...params.limit !== void 0 && { limit: String(params.limit) }
|
|
1047
|
+
});
|
|
1048
|
+
return this.request(`/v1/memory/graph?${query}`);
|
|
1049
|
+
}
|
|
1050
|
+
async getConversationGraph(params) {
|
|
1051
|
+
const project = await this.resolveProjectId(this.getRequiredProject(params.project));
|
|
1052
|
+
const query = new URLSearchParams({
|
|
1053
|
+
project,
|
|
1054
|
+
...params.include_inactive !== void 0 && { include_inactive: String(params.include_inactive) },
|
|
1055
|
+
...params.limit !== void 0 && { limit: String(params.limit) }
|
|
1056
|
+
});
|
|
1057
|
+
return this.request(`/v1/memory/graph/conversation/${params.session_id}?${query}`);
|
|
1058
|
+
}
|
|
818
1059
|
async oracleSearch(params) {
|
|
819
1060
|
const project = await this.resolveProjectId(this.getRequiredProject(params.project));
|
|
820
1061
|
return this.request("/v1/oracle/search", {
|
|
@@ -951,6 +1192,8 @@ var WhisperContext = class _WhisperContext {
|
|
|
951
1192
|
update: (memoryId, params) => this.updateMemory(memoryId, params),
|
|
952
1193
|
delete: (memoryId) => this.deleteMemory(memoryId),
|
|
953
1194
|
getRelations: (memoryId) => this.getMemoryRelations(memoryId),
|
|
1195
|
+
getGraph: (params) => this.getMemoryGraph(params),
|
|
1196
|
+
getConversationGraph: (params) => this.getConversationGraph(params),
|
|
954
1197
|
consolidate: (params) => this.consolidateMemories(params),
|
|
955
1198
|
updateDecay: (params) => this.updateImportanceDecay(params),
|
|
956
1199
|
getImportanceStats: (project) => this.getImportanceStats(project)
|
|
@@ -985,5 +1228,6 @@ export {
|
|
|
985
1228
|
whisper_agent_default as WhisperDefault,
|
|
986
1229
|
WhisperError,
|
|
987
1230
|
createAgentMiddleware,
|
|
988
|
-
index_default as default
|
|
1231
|
+
index_default as default,
|
|
1232
|
+
memoryGraphToMermaid
|
|
989
1233
|
};
|