@hope666/melu 1.0.0

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.
Files changed (87) hide show
  1. package/LICENSE +15 -0
  2. package/README.md +57 -0
  3. package/dist/cli.d.ts +8 -0
  4. package/dist/cli.d.ts.map +1 -0
  5. package/dist/cli.js +630 -0
  6. package/dist/cli.js.map +1 -0
  7. package/dist/config.d.ts +45 -0
  8. package/dist/config.d.ts.map +1 -0
  9. package/dist/config.js +135 -0
  10. package/dist/config.js.map +1 -0
  11. package/dist/embedder-client.d.ts +24 -0
  12. package/dist/embedder-client.d.ts.map +1 -0
  13. package/dist/embedder-client.js +164 -0
  14. package/dist/embedder-client.js.map +1 -0
  15. package/dist/embedder-daemon-client.d.ts +10 -0
  16. package/dist/embedder-daemon-client.d.ts.map +1 -0
  17. package/dist/embedder-daemon-client.js +185 -0
  18. package/dist/embedder-daemon-client.js.map +1 -0
  19. package/dist/embedder-daemon.d.ts +11 -0
  20. package/dist/embedder-daemon.d.ts.map +1 -0
  21. package/dist/embedder-daemon.js +284 -0
  22. package/dist/embedder-daemon.js.map +1 -0
  23. package/dist/embedder-ipc.d.ts +27 -0
  24. package/dist/embedder-ipc.d.ts.map +1 -0
  25. package/dist/embedder-ipc.js +60 -0
  26. package/dist/embedder-ipc.js.map +1 -0
  27. package/dist/embedder-main.d.ts +2 -0
  28. package/dist/embedder-main.d.ts.map +1 -0
  29. package/dist/embedder-main.js +6 -0
  30. package/dist/embedder-main.js.map +1 -0
  31. package/dist/embedder.d.ts +41 -0
  32. package/dist/embedder.d.ts.map +1 -0
  33. package/dist/embedder.js +231 -0
  34. package/dist/embedder.js.map +1 -0
  35. package/dist/extraction-queue.d.ts +53 -0
  36. package/dist/extraction-queue.d.ts.map +1 -0
  37. package/dist/extraction-queue.js +418 -0
  38. package/dist/extraction-queue.js.map +1 -0
  39. package/dist/extraction-stats.d.ts +15 -0
  40. package/dist/extraction-stats.d.ts.map +1 -0
  41. package/dist/extraction-stats.js +89 -0
  42. package/dist/extraction-stats.js.map +1 -0
  43. package/dist/extractor-worker-main.d.ts +2 -0
  44. package/dist/extractor-worker-main.d.ts.map +1 -0
  45. package/dist/extractor-worker-main.js +70 -0
  46. package/dist/extractor-worker-main.js.map +1 -0
  47. package/dist/extractor-worker.d.ts +17 -0
  48. package/dist/extractor-worker.d.ts.map +1 -0
  49. package/dist/extractor-worker.js +164 -0
  50. package/dist/extractor-worker.js.map +1 -0
  51. package/dist/extractor.d.ts +36 -0
  52. package/dist/extractor.d.ts.map +1 -0
  53. package/dist/extractor.js +244 -0
  54. package/dist/extractor.js.map +1 -0
  55. package/dist/i18n.d.ts +995 -0
  56. package/dist/i18n.d.ts.map +1 -0
  57. package/dist/i18n.js +1024 -0
  58. package/dist/i18n.js.map +1 -0
  59. package/dist/memory.d.ts +62 -0
  60. package/dist/memory.d.ts.map +1 -0
  61. package/dist/memory.js +293 -0
  62. package/dist/memory.js.map +1 -0
  63. package/dist/model-bootstrap.d.ts +29 -0
  64. package/dist/model-bootstrap.d.ts.map +1 -0
  65. package/dist/model-bootstrap.js +235 -0
  66. package/dist/model-bootstrap.js.map +1 -0
  67. package/dist/proxy-main.d.ts +5 -0
  68. package/dist/proxy-main.d.ts.map +1 -0
  69. package/dist/proxy-main.js +10 -0
  70. package/dist/proxy-main.js.map +1 -0
  71. package/dist/proxy.d.ts +9 -0
  72. package/dist/proxy.d.ts.map +1 -0
  73. package/dist/proxy.js +309 -0
  74. package/dist/proxy.js.map +1 -0
  75. package/dist/run-runtime.d.ts +34 -0
  76. package/dist/run-runtime.d.ts.map +1 -0
  77. package/dist/run-runtime.js +170 -0
  78. package/dist/run-runtime.js.map +1 -0
  79. package/dist/runtime-context.d.ts +12 -0
  80. package/dist/runtime-context.d.ts.map +1 -0
  81. package/dist/runtime-context.js +39 -0
  82. package/dist/runtime-context.js.map +1 -0
  83. package/dist/text-chunking.d.ts +7 -0
  84. package/dist/text-chunking.d.ts.map +1 -0
  85. package/dist/text-chunking.js +50 -0
  86. package/dist/text-chunking.js.map +1 -0
  87. package/package.json +46 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run-runtime.d.ts","sourceRoot":"","sources":["../src/run-runtime.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,qBAAqB,EAAE,MAAM,CAAC;CAC/B;AAED,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,cAAc,EAAE,MAAM,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,UAAU,kBAAkB;IAC1B,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,wBAAgB,WAAW,IAAI,MAAM,CAEpC;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,YAAY,CAOvD;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE,YAAY,GAAG,IAAI,CAMxD;AAED,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,MAAM,EAAE,cAAc,SAAI,GAAG,YAAY,CASrF;AAED,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,IAAI,CAYtE;AAED,wBAAgB,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,YAAY,GAAG,IAAI,CAyBnE;AAED,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAOvD;AAED,wBAAgB,WAAW,CACzB,KAAK,EAAE,YAAY,EACnB,QAAQ,EAAE,MAAM,EAChB,SAAS,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAM,GACjD,MAAM,CAAC,UAAU,CAUnB;AAED,wBAAgB,kBAAkB,CAAC,SAAS,SAAS,kBAAkB,GAAG,kBAAkB,EAC1F,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAChC,SAAS,SAAQ,GAChB,OAAO,CAAC,SAAS,CAAC,CAmDpB;AAED,wBAAsB,sBAAsB,CAC1C,UAAU,EAAE,MAAM,EAClB,SAAS,SAAQ,GAChB,OAAO,CAAC,IAAI,CAAC,CAsBf;AAED,wBAAgB,KAAK,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAI/C"}
@@ -0,0 +1,170 @@
1
+ import { randomUUID } from "node:crypto";
2
+ import { existsSync, mkdirSync, readdirSync, readFileSync, renameSync, writeFileSync } from "node:fs";
3
+ import { dirname, join } from "node:path";
4
+ import { createConnection } from "node:net";
5
+ import { MELU_HOME, SOCKETS_DIR, STATS_DIR } from "./config.js";
6
+ export function createRunId() {
7
+ return `${Date.now()}-${randomUUID().slice(0, 8)}`;
8
+ }
9
+ export function getRunPaths(runId) {
10
+ return {
11
+ runId,
12
+ socketPath: join(SOCKETS_DIR, runId, "embedder.sock"),
13
+ statsPath: join(STATS_DIR, runId, "stats.json"),
14
+ pendingExtractionsDir: join(MELU_HOME, "pending-extractions", runId),
15
+ };
16
+ }
17
+ export function ensureRunPaths(paths) {
18
+ for (const dir of [dirname(paths.socketPath), dirname(paths.statsPath), paths.pendingExtractionsDir]) {
19
+ if (!existsSync(dir)) {
20
+ mkdirSync(dir, { recursive: true });
21
+ }
22
+ }
23
+ }
24
+ export function createInitialRunStats(runId, remainingQueue = 0) {
25
+ return {
26
+ runId,
27
+ processed: 0,
28
+ newMemories: 0,
29
+ failed: 0,
30
+ remainingQueue,
31
+ updatedAt: new Date().toISOString(),
32
+ };
33
+ }
34
+ export function writeAtomicJson(filePath, value) {
35
+ const dir = dirname(filePath);
36
+ if (!existsSync(dir)) {
37
+ mkdirSync(dir, { recursive: true });
38
+ }
39
+ const tmpPath = join(dir, `.${process.pid}-${Date.now()}-${randomUUID().slice(0, 8)}.tmp`);
40
+ writeFileSync(tmpPath, JSON.stringify(value, null, 2), "utf-8");
41
+ renameSync(tmpPath, filePath);
42
+ }
43
+ export function readRunStats(statsPath) {
44
+ if (!existsSync(statsPath))
45
+ return null;
46
+ try {
47
+ const raw = readFileSync(statsPath, "utf-8");
48
+ const parsed = JSON.parse(raw);
49
+ if (typeof parsed.runId !== "string" ||
50
+ typeof parsed.processed !== "number" ||
51
+ typeof parsed.newMemories !== "number" ||
52
+ typeof parsed.failed !== "number" ||
53
+ typeof parsed.remainingQueue !== "number") {
54
+ return null;
55
+ }
56
+ return {
57
+ runId: parsed.runId,
58
+ processed: parsed.processed,
59
+ newMemories: parsed.newMemories,
60
+ failed: parsed.failed,
61
+ remainingQueue: parsed.remainingQueue,
62
+ updatedAt: typeof parsed.updatedAt === "string" ? parsed.updatedAt : new Date().toISOString(),
63
+ };
64
+ }
65
+ catch {
66
+ return null;
67
+ }
68
+ }
69
+ export function countQueueJobs(queueDir) {
70
+ if (!existsSync(queueDir))
71
+ return 0;
72
+ try {
73
+ return readdirSync(queueDir).filter((name) => name.endsWith(".pending.json") || name.endsWith(".working.json")).length;
74
+ }
75
+ catch {
76
+ return 0;
77
+ }
78
+ }
79
+ export function buildRunEnv(paths, ownerPid, overrides = {}) {
80
+ return {
81
+ ...process.env,
82
+ MELU_RUN_ID: paths.runId,
83
+ MELU_OWNER_PID: String(ownerPid),
84
+ MELU_EMBEDDER_SOCKET: paths.socketPath,
85
+ MELU_PENDING_EXTRACTIONS_DIR: paths.pendingExtractionsDir,
86
+ MELU_RUN_STATS_FILE: paths.statsPath,
87
+ ...overrides,
88
+ };
89
+ }
90
+ export function sendUnixSocketJson(socketPath, payload, timeoutMs = 10000) {
91
+ return new Promise((resolve, reject) => {
92
+ const socket = createConnection(socketPath);
93
+ let buffer = "";
94
+ let settled = false;
95
+ const finish = (error, response) => {
96
+ if (settled)
97
+ return;
98
+ settled = true;
99
+ clearTimeout(timer);
100
+ socket.destroy();
101
+ if (error) {
102
+ reject(error);
103
+ }
104
+ else {
105
+ resolve(response);
106
+ }
107
+ };
108
+ const timer = setTimeout(() => {
109
+ finish(new Error(`timeout waiting for unix socket response: ${socketPath}`));
110
+ }, timeoutMs);
111
+ socket.setEncoding("utf-8");
112
+ socket.on("connect", () => {
113
+ socket.write(`${JSON.stringify(payload)}\n`);
114
+ });
115
+ socket.on("data", (chunk) => {
116
+ buffer += chunk;
117
+ const newlineIndex = buffer.indexOf("\n");
118
+ if (newlineIndex === -1)
119
+ return;
120
+ const line = buffer.slice(0, newlineIndex).trim();
121
+ if (!line) {
122
+ finish(new Error("empty unix socket response"));
123
+ return;
124
+ }
125
+ try {
126
+ const parsed = JSON.parse(line);
127
+ finish(undefined, parsed);
128
+ }
129
+ catch (error) {
130
+ finish(error instanceof Error ? error : new Error(String(error)));
131
+ }
132
+ });
133
+ socket.on("error", (error) => {
134
+ finish(error);
135
+ });
136
+ socket.on("close", () => {
137
+ if (!settled) {
138
+ finish(new Error(`unix socket closed before response: ${socketPath}`));
139
+ }
140
+ });
141
+ });
142
+ }
143
+ export async function waitForUnixSocketReady(socketPath, timeoutMs = 10000) {
144
+ const start = Date.now();
145
+ while (true) {
146
+ try {
147
+ const response = await sendUnixSocketJson(socketPath, {
148
+ id: `ready-${Date.now()}`,
149
+ type: "ping",
150
+ texts: [],
151
+ }, Math.min(2000, timeoutMs));
152
+ if (!response.error) {
153
+ return;
154
+ }
155
+ }
156
+ catch {
157
+ // Retry until timeout.
158
+ }
159
+ if (Date.now() - start >= timeoutMs) {
160
+ throw new Error(`embedder daemon did not become ready within ${timeoutMs}ms`);
161
+ }
162
+ await sleep(250);
163
+ }
164
+ }
165
+ export function sleep(ms) {
166
+ return new Promise((resolve) => {
167
+ setTimeout(resolve, ms);
168
+ });
169
+ }
170
+ //# sourceMappingURL=run-runtime.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run-runtime.js","sourceRoot":"","sources":["../src/run-runtime.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ export declare const MELU_RUN_ID_ENV = "MELU_RUN_ID";
2
+ export declare const MELU_EMBEDDER_SOCKET_ENV = "MELU_EMBEDDER_SOCKET";
3
+ export interface MeluRuntimeContext {
4
+ runId: string;
5
+ embedderSocketPath: string;
6
+ }
7
+ export declare function normalizeMeluRunId(value: string | null | undefined): string;
8
+ export declare function buildEmbedderSocketPath(runId: string): string;
9
+ export declare function createMeluRuntimeContext(runId?: string | null): MeluRuntimeContext;
10
+ export declare function getMeluRuntimeContext(): MeluRuntimeContext;
11
+ export declare function applyMeluRuntimeContextEnv(context: MeluRuntimeContext): void;
12
+ //# sourceMappingURL=runtime-context.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runtime-context.d.ts","sourceRoot":"","sources":["../src/runtime-context.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,eAAe,gBAAgB,CAAC;AAC7C,eAAO,MAAM,wBAAwB,yBAAyB,CAAC;AAG/D,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,MAAM,CAAC;IACd,kBAAkB,EAAE,MAAM,CAAC;CAC5B;AASD,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,CAI3E;AAED,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAE7D;AAED,wBAAgB,wBAAwB,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,kBAAkB,CAMlF;AAED,wBAAgB,qBAAqB,IAAI,kBAAkB,CAI1D;AAED,wBAAgB,0BAA0B,CAAC,OAAO,EAAE,kBAAkB,GAAG,IAAI,CAG5E"}
@@ -0,0 +1,39 @@
1
+ import { randomUUID } from "node:crypto";
2
+ import { join } from "node:path";
3
+ import { SOCKETS_DIR } from "./config.js";
4
+ export const MELU_RUN_ID_ENV = "MELU_RUN_ID";
5
+ export const MELU_EMBEDDER_SOCKET_ENV = "MELU_EMBEDDER_SOCKET";
6
+ const LEGACY_RUN_ID = "legacy";
7
+ function sanitizeRunId(value) {
8
+ const trimmed = value.trim();
9
+ if (!trimmed)
10
+ return LEGACY_RUN_ID;
11
+ const sanitized = trimmed.replace(/[^a-zA-Z0-9._-]+/g, "_");
12
+ return sanitized || LEGACY_RUN_ID;
13
+ }
14
+ export function normalizeMeluRunId(value) {
15
+ const trimmed = value?.trim();
16
+ if (!trimmed)
17
+ return randomUUID();
18
+ return sanitizeRunId(trimmed);
19
+ }
20
+ export function buildEmbedderSocketPath(runId) {
21
+ return join(SOCKETS_DIR, `embedder-${sanitizeRunId(runId)}.sock`);
22
+ }
23
+ export function createMeluRuntimeContext(runId) {
24
+ const normalizedRunId = normalizeMeluRunId(runId);
25
+ return {
26
+ runId: normalizedRunId,
27
+ embedderSocketPath: buildEmbedderSocketPath(normalizedRunId),
28
+ };
29
+ }
30
+ export function getMeluRuntimeContext() {
31
+ const runId = normalizeMeluRunId(process.env[MELU_RUN_ID_ENV]);
32
+ const embedderSocketPath = process.env[MELU_EMBEDDER_SOCKET_ENV]?.trim() || buildEmbedderSocketPath(runId);
33
+ return { runId, embedderSocketPath };
34
+ }
35
+ export function applyMeluRuntimeContextEnv(context) {
36
+ process.env[MELU_RUN_ID_ENV] = context.runId;
37
+ process.env[MELU_EMBEDDER_SOCKET_ENV] = context.embedderSocketPath;
38
+ }
39
+ //# sourceMappingURL=runtime-context.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runtime-context.js","sourceRoot":"","sources":["../src/runtime-context.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE1C,MAAM,CAAC,MAAM,eAAe,GAAG,aAAa,CAAC;AAC7C,MAAM,CAAC,MAAM,wBAAwB,GAAG,sBAAsB,CAAC;AAC/D,MAAM,aAAa,GAAG,QAAQ,CAAC;AAO/B,SAAS,aAAa,CAAC,KAAa;IAClC,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC;IAC7B,IAAI,CAAC,OAAO;QAAE,OAAO,aAAa,CAAC;IACnC,MAAM,SAAS,GAAG,OAAO,CAAC,OAAO,CAAC,mBAAmB,EAAE,GAAG,CAAC,CAAC;IAC5D,OAAO,SAAS,IAAI,aAAa,CAAC;AACpC,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,KAAgC;IACjE,MAAM,OAAO,GAAG,KAAK,EAAE,IAAI,EAAE,CAAC;IAC9B,IAAI,CAAC,OAAO;QAAE,OAAO,UAAU,EAAE,CAAC;IAClC,OAAO,aAAa,CAAC,OAAO,CAAC,CAAC;AAChC,CAAC;AAED,MAAM,UAAU,uBAAuB,CAAC,KAAa;IACnD,OAAO,IAAI,CAAC,WAAW,EAAE,YAAY,aAAa,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;AACpE,CAAC;AAED,MAAM,UAAU,wBAAwB,CAAC,KAAqB;IAC5D,MAAM,eAAe,GAAG,kBAAkB,CAAC,KAAK,CAAC,CAAC;IAClD,OAAO;QACL,KAAK,EAAE,eAAe;QACtB,kBAAkB,EAAE,uBAAuB,CAAC,eAAe,CAAC;KAC7D,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,qBAAqB;IACnC,MAAM,KAAK,GAAG,kBAAkB,CAAC,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC,CAAC;IAC/D,MAAM,kBAAkB,GAAG,OAAO,CAAC,GAAG,CAAC,wBAAwB,CAAC,EAAE,IAAI,EAAE,IAAI,uBAAuB,CAAC,KAAK,CAAC,CAAC;IAC3G,OAAO,EAAE,KAAK,EAAE,kBAAkB,EAAE,CAAC;AACvC,CAAC;AAED,MAAM,UAAU,0BAA0B,CAAC,OAA2B;IACpE,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,GAAG,OAAO,CAAC,KAAK,CAAC;IAC7C,OAAO,CAAC,GAAG,CAAC,wBAAwB,CAAC,GAAG,OAAO,CAAC,kBAAkB,CAAC;AACrE,CAAC"}
@@ -0,0 +1,7 @@
1
+ export declare const DEFAULT_TEXT_WINDOW_CHARS = 2000;
2
+ export declare const DEFAULT_TEXT_WINDOW_OVERLAP_CHARS = 50;
3
+ export declare function splitTextIntoOverlappingWindows(text: string, maxChars?: number, overlapChars?: number): string[];
4
+ export declare function countCharacters(text: string): number;
5
+ export declare function truncateCharacters(text: string, maxChars: number, suffix?: string): string;
6
+ export declare function normalizeWhitespace(text: string): string;
7
+ //# sourceMappingURL=text-chunking.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"text-chunking.d.ts","sourceRoot":"","sources":["../src/text-chunking.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,yBAAyB,OAAO,CAAC;AAC9C,eAAO,MAAM,iCAAiC,KAAK,CAAC;AAEpD,wBAAgB,+BAA+B,CAC7C,IAAI,EAAE,MAAM,EACZ,QAAQ,SAA4B,EACpC,YAAY,SAAoC,GAC/C,MAAM,EAAE,CA6BV;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEpD;AAED,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,SAAM,GAAG,MAAM,CAYvF;AAED,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAExD"}
@@ -0,0 +1,50 @@
1
+ export const DEFAULT_TEXT_WINDOW_CHARS = 2000;
2
+ export const DEFAULT_TEXT_WINDOW_OVERLAP_CHARS = 50;
3
+ export function splitTextIntoOverlappingWindows(text, maxChars = DEFAULT_TEXT_WINDOW_CHARS, overlapChars = DEFAULT_TEXT_WINDOW_OVERLAP_CHARS) {
4
+ const normalized = text.trim();
5
+ if (normalized === "")
6
+ return [];
7
+ if (maxChars <= 0)
8
+ throw new Error("maxChars must be > 0");
9
+ if (overlapChars < 0)
10
+ throw new Error("overlapChars must be >= 0");
11
+ if (overlapChars >= maxChars) {
12
+ throw new Error("overlapChars must be smaller than maxChars");
13
+ }
14
+ const chars = Array.from(normalized);
15
+ if (chars.length <= maxChars) {
16
+ return [normalized];
17
+ }
18
+ const stride = maxChars - overlapChars;
19
+ const chunks = [];
20
+ for (let start = 0; start < chars.length; start += stride) {
21
+ const end = Math.min(start + maxChars, chars.length);
22
+ const chunk = chars.slice(start, end).join("").trim();
23
+ if (chunk !== "") {
24
+ chunks.push(chunk);
25
+ }
26
+ if (end >= chars.length) {
27
+ break;
28
+ }
29
+ }
30
+ return chunks;
31
+ }
32
+ export function countCharacters(text) {
33
+ return Array.from(text).length;
34
+ }
35
+ export function truncateCharacters(text, maxChars, suffix = "…") {
36
+ const chars = Array.from(text.trim());
37
+ if (chars.length <= maxChars) {
38
+ return chars.join("");
39
+ }
40
+ if (maxChars <= 0)
41
+ return "";
42
+ if (maxChars <= suffix.length) {
43
+ return chars.slice(0, maxChars).join("");
44
+ }
45
+ return chars.slice(0, maxChars - suffix.length).join("") + suffix;
46
+ }
47
+ export function normalizeWhitespace(text) {
48
+ return text.replace(/\s+/g, " ").trim();
49
+ }
50
+ //# sourceMappingURL=text-chunking.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"text-chunking.js","sourceRoot":"","sources":["../src/text-chunking.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,yBAAyB,GAAG,IAAI,CAAC;AAC9C,MAAM,CAAC,MAAM,iCAAiC,GAAG,EAAE,CAAC;AAEpD,MAAM,UAAU,+BAA+B,CAC7C,IAAY,EACZ,QAAQ,GAAG,yBAAyB,EACpC,YAAY,GAAG,iCAAiC;IAEhD,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;IAC/B,IAAI,UAAU,KAAK,EAAE;QAAE,OAAO,EAAE,CAAC;IACjC,IAAI,QAAQ,IAAI,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,sBAAsB,CAAC,CAAC;IAC3D,IAAI,YAAY,GAAG,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,2BAA2B,CAAC,CAAC;IACnE,IAAI,YAAY,IAAI,QAAQ,EAAE,CAAC;QAC7B,MAAM,IAAI,KAAK,CAAC,4CAA4C,CAAC,CAAC;IAChE,CAAC;IAED,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IACrC,IAAI,KAAK,CAAC,MAAM,IAAI,QAAQ,EAAE,CAAC;QAC7B,OAAO,CAAC,UAAU,CAAC,CAAC;IACtB,CAAC;IAED,MAAM,MAAM,GAAG,QAAQ,GAAG,YAAY,CAAC;IACvC,MAAM,MAAM,GAAa,EAAE,CAAC;IAE5B,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,KAAK,CAAC,MAAM,EAAE,KAAK,IAAI,MAAM,EAAE,CAAC;QAC1D,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,GAAG,QAAQ,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;QACrD,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;QACtD,IAAI,KAAK,KAAK,EAAE,EAAE,CAAC;YACjB,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACrB,CAAC;QACD,IAAI,GAAG,IAAI,KAAK,CAAC,MAAM,EAAE,CAAC;YACxB,MAAM;QACR,CAAC;IACH,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,IAAY;IAC1C,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC;AACjC,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,IAAY,EAAE,QAAgB,EAAE,MAAM,GAAG,GAAG;IAC7E,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;IACtC,IAAI,KAAK,CAAC,MAAM,IAAI,QAAQ,EAAE,CAAC;QAC7B,OAAO,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACxB,CAAC;IAED,IAAI,QAAQ,IAAI,CAAC;QAAE,OAAO,EAAE,CAAC;IAC7B,IAAI,QAAQ,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;QAC9B,OAAO,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAC3C,CAAC;IAED,OAAO,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,QAAQ,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC;AACpE,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,IAAY;IAC9C,OAAO,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;AAC1C,CAAC"}
package/package.json ADDED
@@ -0,0 +1,46 @@
1
+ {
2
+ "name": "@hope666/melu",
3
+ "version": "1.0.0",
4
+ "description": "Transparent AI memory agent — intercepts LLM API calls, injects persistent memory, extracts new memories automatically.",
5
+ "type": "module",
6
+ "bin": {
7
+ "melu": "dist/cli.js"
8
+ },
9
+ "files": [
10
+ "dist",
11
+ "LICENSE",
12
+ "README.md"
13
+ ],
14
+ "scripts": {
15
+ "build": "tsc",
16
+ "dev": "tsc --watch",
17
+ "start": "node dist/cli.js"
18
+ },
19
+ "keywords": [
20
+ "ai",
21
+ "memory",
22
+ "agent",
23
+ "claude",
24
+ "proxy",
25
+ "llm"
26
+ ],
27
+ "license": "Apache-2.0",
28
+ "author": "Hong Yupeng",
29
+ "engines": {
30
+ "node": ">=20.0.0"
31
+ },
32
+ "dependencies": {
33
+ "@anthropic-ai/sdk": "^0.30.0",
34
+ "@inquirer/prompts": "^7.10.1",
35
+ "better-sqlite3": "^11.0.0",
36
+ "commander": "^12.0.0",
37
+ "node-llama-cpp": "^3.18.1",
38
+ "uuid": "^10.0.0"
39
+ },
40
+ "devDependencies": {
41
+ "@types/better-sqlite3": "^7.6.0",
42
+ "@types/node": "^22.0.0",
43
+ "@types/uuid": "^10.0.0",
44
+ "typescript": "^5.5.0"
45
+ }
46
+ }