miladyai 2.0.0-alpha.27

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 (241) hide show
  1. package/dist/_virtual/_rolldown/runtime.js +7 -0
  2. package/dist/actions/emote.js +64 -0
  3. package/dist/actions/restart.js +81 -0
  4. package/dist/actions/send-message.js +152 -0
  5. package/dist/agent-admin-routes.js +82 -0
  6. package/dist/agent-lifecycle-routes.js +79 -0
  7. package/dist/agent-transfer-routes.js +102 -0
  8. package/dist/api/agent-admin-routes.js +82 -0
  9. package/dist/api/agent-lifecycle-routes.js +79 -0
  10. package/dist/api/agent-transfer-routes.js +102 -0
  11. package/dist/api/apps-hyperscape-routes.js +58 -0
  12. package/dist/api/apps-routes.js +114 -0
  13. package/dist/api/auth-routes.js +56 -0
  14. package/dist/api/autonomy-routes.js +44 -0
  15. package/dist/api/bug-report-routes.js +111 -0
  16. package/dist/api/character-routes.js +195 -0
  17. package/dist/api/cloud-routes.js +330 -0
  18. package/dist/api/cloud-status-routes.js +155 -0
  19. package/dist/api/compat-utils.js +111 -0
  20. package/dist/api/database.js +735 -0
  21. package/dist/api/diagnostics-routes.js +205 -0
  22. package/dist/api/drop-service.js +134 -0
  23. package/dist/api/early-logs.js +86 -0
  24. package/dist/api/http-helpers.js +131 -0
  25. package/dist/api/knowledge-routes.js +534 -0
  26. package/dist/api/memory-bounds.js +71 -0
  27. package/dist/api/models-routes.js +28 -0
  28. package/dist/api/og-tracker.js +36 -0
  29. package/dist/api/permissions-routes.js +109 -0
  30. package/dist/api/plugin-validation.js +198 -0
  31. package/dist/api/provider-switch-config.js +41 -0
  32. package/dist/api/registry-routes.js +86 -0
  33. package/dist/api/registry-service.js +164 -0
  34. package/dist/api/sandbox-routes.js +1112 -0
  35. package/dist/api/server.js +7949 -0
  36. package/dist/api/subscription-routes.js +172 -0
  37. package/dist/api/terminal-run-limits.js +24 -0
  38. package/dist/api/training-routes.js +158 -0
  39. package/dist/api/trajectory-routes.js +300 -0
  40. package/dist/api/trigger-routes.js +246 -0
  41. package/dist/api/twitter-verify.js +134 -0
  42. package/dist/api/tx-service.js +108 -0
  43. package/dist/api/wallet-routes.js +266 -0
  44. package/dist/api/wallet.js +568 -0
  45. package/dist/api/whatsapp-routes.js +182 -0
  46. package/dist/api/zip-utils.js +109 -0
  47. package/dist/apps-hyperscape-routes.js +58 -0
  48. package/dist/apps-routes.js +114 -0
  49. package/dist/ascii.js +20 -0
  50. package/dist/auth/anthropic.js +44 -0
  51. package/dist/auth/apply-stealth.js +41 -0
  52. package/dist/auth/claude-code-stealth.js +78 -0
  53. package/dist/auth/credentials.js +156 -0
  54. package/dist/auth/index.js +5 -0
  55. package/dist/auth/openai-codex.js +66 -0
  56. package/dist/auth/types.js +9 -0
  57. package/dist/auth-routes.js +56 -0
  58. package/dist/autonomy-routes.js +44 -0
  59. package/dist/bug-report-routes.js +111 -0
  60. package/dist/build-info.json +6 -0
  61. package/dist/character-routes.js +195 -0
  62. package/dist/cli/argv.js +63 -0
  63. package/dist/cli/banner.js +34 -0
  64. package/dist/cli/cli-name.js +21 -0
  65. package/dist/cli/cli-utils.js +16 -0
  66. package/dist/cli/git-commit.js +78 -0
  67. package/dist/cli/parse-duration.js +15 -0
  68. package/dist/cli/plugins-cli.js +590 -0
  69. package/dist/cli/profile-utils.js +9 -0
  70. package/dist/cli/profile.js +95 -0
  71. package/dist/cli/program/build-program.js +17 -0
  72. package/dist/cli/program/command-registry.js +23 -0
  73. package/dist/cli/program/help.js +47 -0
  74. package/dist/cli/program/preaction.js +33 -0
  75. package/dist/cli/program/register.config.js +106 -0
  76. package/dist/cli/program/register.configure.js +20 -0
  77. package/dist/cli/program/register.dashboard.js +124 -0
  78. package/dist/cli/program/register.models.js +23 -0
  79. package/dist/cli/program/register.setup.js +36 -0
  80. package/dist/cli/program/register.start.js +22 -0
  81. package/dist/cli/program/register.subclis.js +70 -0
  82. package/dist/cli/program/register.tui.js +163 -0
  83. package/dist/cli/program/register.update.js +154 -0
  84. package/dist/cli/program.js +3 -0
  85. package/dist/cli/run-main.js +37 -0
  86. package/dist/cli/version.js +7 -0
  87. package/dist/cloud/validate-url.js +93 -0
  88. package/dist/cloud-routes.js +330 -0
  89. package/dist/cloud-status-routes.js +155 -0
  90. package/dist/compat-utils.js +111 -0
  91. package/dist/config/config.js +69 -0
  92. package/dist/config/env-vars.js +19 -0
  93. package/dist/config/includes.js +121 -0
  94. package/dist/config/object-utils.js +7 -0
  95. package/dist/config/paths.js +38 -0
  96. package/dist/config/plugin-auto-enable.js +231 -0
  97. package/dist/config/schema.js +864 -0
  98. package/dist/config/telegram-custom-commands.js +76 -0
  99. package/dist/config/zod-schema.agent-runtime.js +519 -0
  100. package/dist/config/zod-schema.core.js +538 -0
  101. package/dist/config/zod-schema.hooks.js +103 -0
  102. package/dist/config/zod-schema.js +488 -0
  103. package/dist/config/zod-schema.providers-core.js +785 -0
  104. package/dist/config/zod-schema.session.js +73 -0
  105. package/dist/core-plugins.js +37 -0
  106. package/dist/custom-actions.js +250 -0
  107. package/dist/database.js +735 -0
  108. package/dist/diagnostics/integration-observability.js +57 -0
  109. package/dist/diagnostics-routes.js +205 -0
  110. package/dist/drop-service.js +134 -0
  111. package/dist/early-logs.js +24 -0
  112. package/dist/eliza.js +2061 -0
  113. package/dist/emotes/catalog.js +271 -0
  114. package/dist/entry.js +40 -0
  115. package/dist/hooks/discovery.js +167 -0
  116. package/dist/hooks/eligibility.js +64 -0
  117. package/dist/hooks/index.js +4 -0
  118. package/dist/hooks/loader.js +147 -0
  119. package/dist/hooks/registry.js +55 -0
  120. package/dist/http-helpers.js +131 -0
  121. package/dist/index.js +49 -0
  122. package/dist/knowledge-routes.js +534 -0
  123. package/dist/memory-bounds.js +71 -0
  124. package/dist/milady-plugin.js +90 -0
  125. package/dist/models-routes.js +28 -0
  126. package/dist/onboarding-names.js +78 -0
  127. package/dist/onboarding-presets.js +922 -0
  128. package/dist/package.json +1 -0
  129. package/dist/permissions-routes.js +109 -0
  130. package/dist/plugin-validation.js +107 -0
  131. package/dist/plugins/whatsapp/actions.js +91 -0
  132. package/dist/plugins/whatsapp/index.js +16 -0
  133. package/dist/plugins/whatsapp/service.js +270 -0
  134. package/dist/provider-switch-config.js +41 -0
  135. package/dist/providers/admin-trust.js +46 -0
  136. package/dist/providers/autonomous-state.js +101 -0
  137. package/dist/providers/session-bridge.js +86 -0
  138. package/dist/providers/session-utils.js +36 -0
  139. package/dist/providers/simple-mode.js +50 -0
  140. package/dist/providers/ui-catalog.js +15 -0
  141. package/dist/providers/workspace-provider.js +93 -0
  142. package/dist/providers/workspace.js +348 -0
  143. package/dist/registry-routes.js +86 -0
  144. package/dist/registry-service.js +164 -0
  145. package/dist/restart.js +40 -0
  146. package/dist/runtime/core-plugins.js +37 -0
  147. package/dist/runtime/custom-actions.js +250 -0
  148. package/dist/runtime/eliza.js +2061 -0
  149. package/dist/runtime/embedding-manager-support.js +185 -0
  150. package/dist/runtime/embedding-manager.js +193 -0
  151. package/dist/runtime/embedding-presets.js +54 -0
  152. package/dist/runtime/embedding-state.js +8 -0
  153. package/dist/runtime/milady-plugin.js +90 -0
  154. package/dist/runtime/onboarding-names.js +78 -0
  155. package/dist/runtime/restart.js +40 -0
  156. package/dist/runtime/version.js +7 -0
  157. package/dist/sandbox-routes.js +1112 -0
  158. package/dist/security/audit-log.js +149 -0
  159. package/dist/security/network-policy.js +70 -0
  160. package/dist/server.js +7949 -0
  161. package/dist/services/agent-export.js +559 -0
  162. package/dist/services/app-manager.js +389 -0
  163. package/dist/services/browser-capture.js +86 -0
  164. package/dist/services/fallback-training-service.js +128 -0
  165. package/dist/services/mcp-marketplace.js +134 -0
  166. package/dist/services/plugin-installer.js +396 -0
  167. package/dist/services/plugin-manager-types.js +15 -0
  168. package/dist/services/registry-client-app-meta.js +144 -0
  169. package/dist/services/registry-client-endpoints.js +166 -0
  170. package/dist/services/registry-client-local.js +271 -0
  171. package/dist/services/registry-client-network.js +93 -0
  172. package/dist/services/registry-client-queries.js +70 -0
  173. package/dist/services/registry-client.js +157 -0
  174. package/dist/services/sandbox-engine.js +511 -0
  175. package/dist/services/sandbox-manager.js +297 -0
  176. package/dist/services/self-updater.js +175 -0
  177. package/dist/services/skill-catalog-client.js +119 -0
  178. package/dist/services/skill-marketplace.js +521 -0
  179. package/dist/services/stream-manager.js +236 -0
  180. package/dist/services/update-checker.js +121 -0
  181. package/dist/services/update-notifier.js +29 -0
  182. package/dist/services/version-compat.js +78 -0
  183. package/dist/services/whatsapp-pairing.js +196 -0
  184. package/dist/shared/ui-catalog-prompt.js +728 -0
  185. package/dist/subscription-routes.js +172 -0
  186. package/dist/terminal/links.js +19 -0
  187. package/dist/terminal/palette.js +14 -0
  188. package/dist/terminal/theme.js +25 -0
  189. package/dist/terminal-run-limits.js +24 -0
  190. package/dist/training-routes.js +158 -0
  191. package/dist/trajectory-routes.js +300 -0
  192. package/dist/trigger-routes.js +246 -0
  193. package/dist/triggers/action.js +218 -0
  194. package/dist/triggers/runtime.js +281 -0
  195. package/dist/triggers/scheduling.js +295 -0
  196. package/dist/triggers/types.js +5 -0
  197. package/dist/tui/components/assistant-message.js +76 -0
  198. package/dist/tui/components/chat-editor.js +34 -0
  199. package/dist/tui/components/embeddings-overlay.js +46 -0
  200. package/dist/tui/components/footer.js +60 -0
  201. package/dist/tui/components/index.js +15 -0
  202. package/dist/tui/components/modal-frame.js +45 -0
  203. package/dist/tui/components/modal-style.js +15 -0
  204. package/dist/tui/components/model-selector.js +70 -0
  205. package/dist/tui/components/pinned-chat-layout.js +46 -0
  206. package/dist/tui/components/plugins-endpoints-tab.js +196 -0
  207. package/dist/tui/components/plugins-installed-tab-view.js +69 -0
  208. package/dist/tui/components/plugins-installed-tab.js +319 -0
  209. package/dist/tui/components/plugins-overlay-catalog.js +81 -0
  210. package/dist/tui/components/plugins-overlay-data-api.js +21 -0
  211. package/dist/tui/components/plugins-overlay-data-shared.js +20 -0
  212. package/dist/tui/components/plugins-overlay-data.js +323 -0
  213. package/dist/tui/components/plugins-overlay.js +117 -0
  214. package/dist/tui/components/plugins-store-tab.js +148 -0
  215. package/dist/tui/components/settings-overlay.js +61 -0
  216. package/dist/tui/components/status-bar.js +64 -0
  217. package/dist/tui/components/tool-execution.js +68 -0
  218. package/dist/tui/components/user-message.js +22 -0
  219. package/dist/tui/eliza-tui-bridge.js +606 -0
  220. package/dist/tui/index.js +370 -0
  221. package/dist/tui/modal-presets.js +33 -0
  222. package/dist/tui/model-spec.js +46 -0
  223. package/dist/tui/sse-parser.js +78 -0
  224. package/dist/tui/theme.js +110 -0
  225. package/dist/tui/titlebar-spinner.js +62 -0
  226. package/dist/tui/tui-app.js +311 -0
  227. package/dist/tui/ws-client.js +215 -0
  228. package/dist/twitter-verify.js +134 -0
  229. package/dist/tx-service.js +108 -0
  230. package/dist/utils/exec-safety.js +17 -0
  231. package/dist/utils/globals.js +20 -0
  232. package/dist/utils/milady-root.js +61 -0
  233. package/dist/utils/number-parsing.js +37 -0
  234. package/dist/version-resolver.js +37 -0
  235. package/dist/version.js +7 -0
  236. package/dist/wallet-routes.js +266 -0
  237. package/dist/wallet.js +568 -0
  238. package/dist/whatsapp-routes.js +182 -0
  239. package/dist/zip-utils.js +109 -0
  240. package/milady.mjs +14 -0
  241. package/package.json +111 -0
@@ -0,0 +1,185 @@
1
+ import { __require } from "../_virtual/_rolldown/runtime.js";
2
+ import os from "node:os";
3
+ import path from "node:path";
4
+ import fs from "node:fs";
5
+ import https from "node:https";
6
+
7
+ //#region src/runtime/embedding-manager-support.ts
8
+ const DEFAULT_IDLE_TIMEOUT_MS = 1800 * 1e3;
9
+ const DEFAULT_MODELS_DIR = path.join(os.homedir(), ".eliza", "models");
10
+ const EMBEDDING_META_DIR = process.env.MILAIDY_EMBEDDING_META_DIR ?? path.join(os.homedir(), ".milaidy", "state");
11
+ const EMBEDDING_META_PATH = process.env.MILAIDY_EMBEDDING_META_PATH ?? path.join(EMBEDDING_META_DIR, "embedding-meta.json");
12
+ let _logger;
13
+ function getLogger() {
14
+ if (_logger) return _logger;
15
+ try {
16
+ const core = __require("@elizaos/core");
17
+ if (core?.logger) {
18
+ _logger = core.logger;
19
+ return _logger;
20
+ }
21
+ } catch {}
22
+ _logger = console;
23
+ return _logger;
24
+ }
25
+ function readEmbeddingMeta() {
26
+ try {
27
+ if (!fs.existsSync(EMBEDDING_META_PATH)) return null;
28
+ return JSON.parse(fs.readFileSync(EMBEDDING_META_PATH, "utf-8"));
29
+ } catch {
30
+ return null;
31
+ }
32
+ }
33
+ function writeEmbeddingMeta(meta) {
34
+ try {
35
+ fs.mkdirSync(EMBEDDING_META_DIR, { recursive: true });
36
+ fs.writeFileSync(EMBEDDING_META_PATH, JSON.stringify(meta, null, 2));
37
+ } catch (err) {
38
+ getLogger().warn(`[milaidy] Failed to write embedding metadata: ${err}`);
39
+ }
40
+ }
41
+ function checkDimensionMigration(model, dimensions) {
42
+ const log = getLogger();
43
+ const stored = readEmbeddingMeta();
44
+ if (stored && stored.dimensions !== dimensions) log.warn(`[milaidy] Embedding dimensions changed (${stored.dimensions} → ${dimensions}). Existing memory embeddings will be re-indexed on next access.`);
45
+ writeEmbeddingMeta({
46
+ model,
47
+ dimensions,
48
+ lastChanged: (/* @__PURE__ */ new Date()).toISOString()
49
+ });
50
+ }
51
+ function safeUnlink(filepath) {
52
+ try {
53
+ if (fs.existsSync(filepath)) fs.unlinkSync(filepath);
54
+ } catch {}
55
+ }
56
+ function getErrorMessage(error) {
57
+ if (error instanceof Error) return error.message;
58
+ if (typeof error === "string") return error;
59
+ if (error != null && typeof error === "object" && "message" in error && typeof error.message === "string") return error.message;
60
+ return String(error);
61
+ }
62
+ function isCorruptedModelLoadError(error) {
63
+ const message = getErrorMessage(error).toLowerCase();
64
+ return message.includes("failed to load model") || message.includes("data is not within the file bounds") || message.includes("tensor") && message.includes("is corrupted") || message.includes("model is corrupted");
65
+ }
66
+ function parseContentLength(contentLength) {
67
+ if (!contentLength || Array.isArray(contentLength)) return null;
68
+ const parsed = Number.parseInt(contentLength, 10);
69
+ return Number.isFinite(parsed) && parsed >= 0 ? parsed : null;
70
+ }
71
+ function isAllowedDownloadHost(hostname) {
72
+ return hostname === "huggingface.co" || hostname.endsWith(".huggingface.co");
73
+ }
74
+ function validateDownloadUrl(rawUrl) {
75
+ let parsed;
76
+ try {
77
+ parsed = new URL(rawUrl);
78
+ } catch {
79
+ throw new Error(`Download failed: invalid URL "${rawUrl}"`);
80
+ }
81
+ if (parsed.protocol !== "https:") throw new Error("Download failed: only https:// URLs are allowed");
82
+ if (!isAllowedDownloadHost(parsed.hostname.toLowerCase())) throw new Error(`Download failed: host "${parsed.hostname}" is not allowed`);
83
+ return parsed;
84
+ }
85
+ function sanitizeModelRepo(repo) {
86
+ const trimmed = repo.trim();
87
+ if (!/^[A-Za-z0-9._-]+\/[A-Za-z0-9._-]+$/.test(trimmed)) throw new Error(`Invalid embedding model repo: ${repo}`);
88
+ return trimmed;
89
+ }
90
+ function sanitizeModelFilename(filename) {
91
+ const trimmed = filename.trim();
92
+ if (!/^[A-Za-z0-9._-]+\.gguf$/i.test(trimmed)) throw new Error(`Invalid embedding model filename: ${filename}`);
93
+ return trimmed;
94
+ }
95
+ function resolveModelPath(modelsDir, filename) {
96
+ const resolvedDir = path.resolve(modelsDir);
97
+ const resolvedPath = path.resolve(resolvedDir, filename);
98
+ if (resolvedPath !== resolvedDir && !resolvedPath.startsWith(`${resolvedDir}${path.sep}`)) throw new Error("Invalid embedding model path");
99
+ return resolvedPath;
100
+ }
101
+ function downloadFile(url, dest, maxRedirects = 5) {
102
+ return new Promise((resolve, reject) => {
103
+ let settled = false;
104
+ let redirectCount = 0;
105
+ const request = (reqUrl) => {
106
+ let validatedUrl;
107
+ try {
108
+ validatedUrl = validateDownloadUrl(reqUrl);
109
+ } catch (error) {
110
+ reject(error instanceof Error ? error : /* @__PURE__ */ new Error("Invalid download URL"));
111
+ return;
112
+ }
113
+ const file = fs.createWriteStream(dest);
114
+ let bytesReceived = 0;
115
+ let expectedBytes = null;
116
+ const settleError = (err) => {
117
+ if (settled) return;
118
+ settled = true;
119
+ file.close();
120
+ safeUnlink(dest);
121
+ reject(err);
122
+ };
123
+ const settleSuccess = () => {
124
+ if (settled) return;
125
+ if (expectedBytes != null && bytesReceived !== expectedBytes) {
126
+ settleError(/* @__PURE__ */ new Error(`[milaidy] Download failed: bytes received (${bytesReceived}) does not match Content-Length (${expectedBytes})`));
127
+ return;
128
+ }
129
+ settled = true;
130
+ file.close();
131
+ resolve();
132
+ };
133
+ https.get(validatedUrl.toString(), { headers: { "User-Agent": "milaidy" } }, (res) => {
134
+ expectedBytes = parseContentLength(res.headers["content-length"]);
135
+ if (res.statusCode && res.statusCode >= 300 && res.statusCode < 400 && res.headers.location) {
136
+ res.resume();
137
+ file.close();
138
+ safeUnlink(dest);
139
+ redirectCount += 1;
140
+ if (redirectCount > maxRedirects) {
141
+ settleError(/* @__PURE__ */ new Error(`Download failed: too many redirects (>${maxRedirects})`));
142
+ return;
143
+ }
144
+ let next;
145
+ try {
146
+ next = new URL(res.headers.location, validatedUrl.toString()).toString();
147
+ } catch {
148
+ settleError(/* @__PURE__ */ new Error(`Download failed: malformed redirect URL "${res.headers.location}"`));
149
+ return;
150
+ }
151
+ request(next);
152
+ return;
153
+ }
154
+ if (res.statusCode !== 200) {
155
+ settleError(/* @__PURE__ */ new Error(`Download failed: HTTP ${res.statusCode} for ${validatedUrl.toString()}`));
156
+ return;
157
+ }
158
+ res.on("data", (chunk) => {
159
+ bytesReceived += chunk.length;
160
+ });
161
+ res.pipe(file);
162
+ file.on("finish", settleSuccess);
163
+ file.on("error", settleError);
164
+ }).on("error", settleError);
165
+ };
166
+ request(url);
167
+ });
168
+ }
169
+ async function ensureModel(modelsDir, repo, filename, force = false) {
170
+ const safeRepo = sanitizeModelRepo(repo);
171
+ const safeFilename = sanitizeModelFilename(filename);
172
+ const modelPath = resolveModelPath(modelsDir, safeFilename);
173
+ if (force) safeUnlink(modelPath);
174
+ if (fs.existsSync(modelPath)) return modelPath;
175
+ const log = getLogger();
176
+ fs.mkdirSync(path.resolve(modelsDir), { recursive: true });
177
+ const url = `https://huggingface.co/${safeRepo}/resolve/main/${safeFilename}`;
178
+ log.info(`[milaidy] Downloading embedding model: ${safeFilename} from ${safeRepo}...`);
179
+ await downloadFile(url, modelPath);
180
+ log.info(`[milaidy] Embedding model downloaded: ${modelPath}`);
181
+ return modelPath;
182
+ }
183
+
184
+ //#endregion
185
+ export { DEFAULT_IDLE_TIMEOUT_MS, DEFAULT_MODELS_DIR, EMBEDDING_META_PATH, checkDimensionMigration, ensureModel, getErrorMessage, getLogger, isCorruptedModelLoadError, readEmbeddingMeta, safeUnlink };
@@ -0,0 +1,193 @@
1
+ import { DEFAULT_IDLE_TIMEOUT_MS, DEFAULT_MODELS_DIR, EMBEDDING_META_PATH, checkDimensionMigration, ensureModel, getErrorMessage, getLogger, isCorruptedModelLoadError, readEmbeddingMeta, safeUnlink } from "./embedding-manager-support.js";
2
+ import { detectEmbeddingPreset } from "./embedding-presets.js";
3
+
4
+ //#region src/runtime/embedding-manager.ts
5
+ /**
6
+ * MiladyEmbeddingManager — wraps node-llama-cpp to provide:
7
+ * • Metal GPU acceleration on Apple Silicon (gpuLayers: "auto")
8
+ * • Configurable embedding model with hardware-adaptive defaults
9
+ * • Idle timeout unloading (default: 30 min) with transparent lazy re-init
10
+ * • Dimension migration detection with warning logging
11
+ */
12
+ var MiladyEmbeddingManager = class {
13
+ constructor(config = {}) {
14
+ this.llama = null;
15
+ this.embeddingModel = null;
16
+ this.embeddingContext = null;
17
+ this.initialized = false;
18
+ this.initializing = null;
19
+ this.lastUsedAt = null;
20
+ this.idleTimer = null;
21
+ this.disposed = false;
22
+ this.inFlightCount = 0;
23
+ this.unloading = null;
24
+ this.dimensionCheckDone = false;
25
+ const detected = detectEmbeddingPreset();
26
+ this.model = config.model ?? detected.model;
27
+ this.modelRepo = config.modelRepo ?? detected.modelRepo;
28
+ this.dimensions = config.dimensions ?? detected.dimensions;
29
+ this.gpuLayers = config.gpuLayers ?? detected.gpuLayers;
30
+ this.idleTimeoutMs = config.idleTimeoutMs ?? DEFAULT_IDLE_TIMEOUT_MS;
31
+ this.modelsDir = config.modelsDir ?? DEFAULT_MODELS_DIR;
32
+ }
33
+ async generateEmbedding(text) {
34
+ if (this.disposed) throw new Error("[milaidy] EmbeddingManager has been disposed");
35
+ if (this.unloading) await this.unloading;
36
+ await this.ensureInitialized();
37
+ this.inFlightCount += 1;
38
+ this.lastUsedAt = Date.now();
39
+ try {
40
+ if (!this.embeddingContext) throw new Error("[milaidy] Embedding context not available after init");
41
+ const result = await this.embeddingContext.getEmbeddingFor(text);
42
+ return Array.from(result.vector);
43
+ } catch (err) {
44
+ getLogger().error(`[milaidy] Embedding generation failed: ${err}`);
45
+ return new Array(this.dimensions).fill(0);
46
+ } finally {
47
+ this.inFlightCount -= 1;
48
+ }
49
+ }
50
+ async dispose() {
51
+ if (this.disposed) return;
52
+ this.disposed = true;
53
+ await this.releaseResources();
54
+ }
55
+ isLoaded() {
56
+ return this.initialized && this.embeddingModel !== null;
57
+ }
58
+ getStats() {
59
+ return {
60
+ lastUsedAt: this.lastUsedAt,
61
+ isLoaded: this.isLoaded(),
62
+ model: this.model,
63
+ gpuLayers: this.gpuLayers,
64
+ dimensions: this.dimensions
65
+ };
66
+ }
67
+ async ensureInitialized() {
68
+ if (this.initialized && this.embeddingModel && this.embeddingContext) return;
69
+ if (this.initializing) {
70
+ await this.initializing;
71
+ return;
72
+ }
73
+ this.initializing = this.doInit();
74
+ try {
75
+ await this.initializing;
76
+ } finally {
77
+ this.initializing = null;
78
+ }
79
+ }
80
+ async doInit() {
81
+ const log = getLogger();
82
+ if (!this.dimensionCheckDone) {
83
+ checkDimensionMigration(this.model, this.dimensions);
84
+ this.dimensionCheckDone = true;
85
+ }
86
+ const modelPath = await ensureModel(this.modelsDir, this.modelRepo, this.model);
87
+ const { getLlama, LlamaLogLevel } = await import("node-llama-cpp");
88
+ log.info(`[milaidy] Initializing embedding model: ${this.model} (dims=${this.dimensions}, gpuLayers=${this.gpuLayers})`);
89
+ if (!this.llama) this.llama = await getLlama({
90
+ logLevel: LlamaLogLevel.error,
91
+ logger: (level, message) => {
92
+ if (level === "error" || level === "fatal") {
93
+ const text = message.trim();
94
+ if (text) log.error(`[node-llama-cpp] ${text}`);
95
+ }
96
+ }
97
+ });
98
+ const loadOpts = {
99
+ modelPath,
100
+ gpuLayers: this.gpuLayers
101
+ };
102
+ let model;
103
+ try {
104
+ model = await this.llama.loadModel(loadOpts);
105
+ } catch (err) {
106
+ if (!isCorruptedModelLoadError(err)) throw err;
107
+ const failureMessage = getErrorMessage(err);
108
+ safeUnlink(modelPath);
109
+ log.warn(`[milaidy] Embedding model load failed due to a likely corrupted/incomplete file (${failureMessage}) at ${modelPath}. Deleting file and re-downloading, then retrying once.`);
110
+ try {
111
+ const recoveredPath = await ensureModel(this.modelsDir, this.modelRepo, this.model, true);
112
+ model = await this.llama.loadModel({
113
+ ...loadOpts,
114
+ modelPath: recoveredPath
115
+ });
116
+ } catch (retryErr) {
117
+ safeUnlink(modelPath);
118
+ throw retryErr;
119
+ }
120
+ }
121
+ let context;
122
+ try {
123
+ context = await model.createEmbeddingContext();
124
+ } catch (err) {
125
+ if (isCorruptedModelLoadError(err)) safeUnlink(modelPath);
126
+ try {
127
+ await model.dispose();
128
+ } catch {}
129
+ throw err;
130
+ }
131
+ this.embeddingModel = model;
132
+ this.embeddingContext = context;
133
+ this.initialized = true;
134
+ log.info(`[milaidy] Embedding model loaded: ${this.model}`);
135
+ this.startIdleTimer();
136
+ }
137
+ startIdleTimer() {
138
+ this.stopIdleTimer();
139
+ if (this.idleTimeoutMs <= 0) return;
140
+ const checkIntervalMs = Math.min(this.idleTimeoutMs, 6e4);
141
+ this.idleTimer = setInterval(() => {
142
+ if (this.inFlightCount > 0) return;
143
+ if (this.lastUsedAt && Date.now() - this.lastUsedAt > this.idleTimeoutMs) {
144
+ getLogger().info(`[milaidy] Embedding model idle for >${Math.round(this.idleTimeoutMs / 6e4)} min — unloading to free memory`);
145
+ this.idleUnload();
146
+ }
147
+ }, checkIntervalMs);
148
+ if (this.idleTimer && typeof this.idleTimer === "object" && "unref" in this.idleTimer) this.idleTimer.unref();
149
+ }
150
+ stopIdleTimer() {
151
+ if (this.idleTimer !== null) {
152
+ clearInterval(this.idleTimer);
153
+ this.idleTimer = null;
154
+ }
155
+ }
156
+ async idleUnload() {
157
+ this.stopIdleTimer();
158
+ const unloadWork = this.releaseModelResources().then(() => {
159
+ this.initialized = false;
160
+ this.unloading = null;
161
+ });
162
+ this.unloading = unloadWork;
163
+ await unloadWork;
164
+ }
165
+ async releaseModelResources() {
166
+ const log = getLogger();
167
+ if (this.embeddingContext) {
168
+ try {
169
+ await this.embeddingContext.dispose();
170
+ } catch (err) {
171
+ log.warn(`[milaidy] Error disposing embedding context: ${err}`);
172
+ }
173
+ this.embeddingContext = null;
174
+ }
175
+ if (this.embeddingModel) {
176
+ try {
177
+ await this.embeddingModel.dispose();
178
+ } catch (err) {
179
+ log.warn(`[milaidy] Error disposing embedding model: ${err}`);
180
+ }
181
+ this.embeddingModel = null;
182
+ }
183
+ }
184
+ async releaseResources() {
185
+ this.stopIdleTimer();
186
+ await this.releaseModelResources();
187
+ this.llama = null;
188
+ this.initialized = false;
189
+ }
190
+ };
191
+
192
+ //#endregion
193
+ export { MiladyEmbeddingManager };
@@ -0,0 +1,54 @@
1
+ import os from "node:os";
2
+
3
+ //#region src/runtime/embedding-presets.ts
4
+ /** All available presets, indexed by tier. */
5
+ const EMBEDDING_PRESETS = {
6
+ fallback: {
7
+ tier: "fallback",
8
+ label: "Efficient (CPU)",
9
+ description: "768-dim, 74MB download — best for Intel Macs and low-RAM machines",
10
+ model: "nomic-embed-text-v1.5.Q4_K_S.gguf",
11
+ modelRepo: "nomic-ai/nomic-embed-text-v1.5-GGUF",
12
+ dimensions: 768,
13
+ gpuLayers: 0,
14
+ contextSize: 8192,
15
+ downloadSizeMB: 74
16
+ },
17
+ standard: {
18
+ tier: "standard",
19
+ label: "Balanced (Metal GPU)",
20
+ description: "768-dim, 95MB download — great quality with Metal acceleration",
21
+ model: "nomic-embed-text-v1.5.Q5_K_M.gguf",
22
+ modelRepo: "nomic-ai/nomic-embed-text-v1.5-GGUF",
23
+ dimensions: 768,
24
+ gpuLayers: "auto",
25
+ contextSize: 8192,
26
+ downloadSizeMB: 95
27
+ },
28
+ performance: {
29
+ tier: "performance",
30
+ label: "Maximum (7B model)",
31
+ description: "4096-dim, 4.2GB download — SOTA retrieval quality, 32K context",
32
+ model: "ggml-e5-mistral-7b-instruct-q4_k_m.gguf",
33
+ modelRepo: "dranger003/e5-mistral-7b-instruct-GGUF",
34
+ dimensions: 4096,
35
+ gpuLayers: "auto",
36
+ contextSize: 32768,
37
+ downloadSizeMB: 4200
38
+ }
39
+ };
40
+ const BYTES_PER_GB = 1024 ** 3;
41
+ /** Detect the best embedding tier for the current hardware. */
42
+ function detectEmbeddingTier() {
43
+ const totalRamGB = Math.round(os.totalmem() / BYTES_PER_GB);
44
+ if (!(process.platform === "darwin" && process.arch === "arm64") || totalRamGB <= 8) return "fallback";
45
+ if (totalRamGB >= 128) return "performance";
46
+ return "standard";
47
+ }
48
+ /** Get the preset for the current hardware. */
49
+ function detectEmbeddingPreset() {
50
+ return EMBEDDING_PRESETS[detectEmbeddingTier()];
51
+ }
52
+
53
+ //#endregion
54
+ export { EMBEDDING_PRESETS, detectEmbeddingPreset };
@@ -0,0 +1,8 @@
1
+ //#region src/runtime/embedding-state.ts
2
+ let _state = null;
3
+ function getEmbeddingState() {
4
+ return _state;
5
+ }
6
+
7
+ //#endregion
8
+ export { getEmbeddingState };
@@ -0,0 +1,90 @@
1
+ import { EMOTE_CATALOG } from "../emotes/catalog.js";
2
+ import { DEFAULT_AGENT_WORKSPACE_DIR } from "../providers/workspace.js";
3
+ import { loadCustomActions, setCustomActionsRuntime } from "./custom-actions.js";
4
+ import { registerTriggerTaskWorker } from "../triggers/runtime.js";
5
+ import { emoteAction } from "../actions/emote.js";
6
+ import { restartAction } from "../actions/restart.js";
7
+ import { sendMessageAction } from "../actions/send-message.js";
8
+ import { adminTrustProvider } from "../providers/admin-trust.js";
9
+ import { createAutonomousStateProvider, ensureAutonomousStateTracking } from "../providers/autonomous-state.js";
10
+ import { createSessionKeyProvider } from "../providers/session-bridge.js";
11
+ import { getSessionProviders, resolveDefaultSessionStorePath } from "../providers/session-utils.js";
12
+ import { createChannelProfileProvider } from "../providers/simple-mode.js";
13
+ import { uiCatalogProvider } from "../providers/ui-catalog.js";
14
+ import { createWorkspaceProvider } from "../providers/workspace-provider.js";
15
+ import { createTriggerTaskAction } from "../triggers/action.js";
16
+
17
+ //#region src/runtime/milady-plugin.ts
18
+ function createMiladyPlugin(config) {
19
+ const workspaceDir = config?.workspaceDir ?? DEFAULT_AGENT_WORKSPACE_DIR;
20
+ const agentId = config?.agentId ?? "main";
21
+ const sessionStorePath = config?.sessionStorePath ?? resolveDefaultSessionStorePath(agentId);
22
+ const baseProviders = [
23
+ createChannelProfileProvider(),
24
+ createWorkspaceProvider({
25
+ workspaceDir,
26
+ maxCharsPerFile: config?.bootstrapMaxChars
27
+ }),
28
+ adminTrustProvider,
29
+ createAutonomousStateProvider(),
30
+ createSessionKeyProvider({ defaultAgentId: agentId }),
31
+ ...getSessionProviders({ storePath: sessionStorePath })
32
+ ];
33
+ const emoteProvider = {
34
+ name: "emotes",
35
+ description: "Available avatar emote animations",
36
+ async get(_runtime, _message, _state) {
37
+ if ((_runtime.character?.settings)?.DISABLE_EMOTES) return { text: "" };
38
+ return { text: [
39
+ "## Available Emotes",
40
+ "",
41
+ "You can play emote animations on your 3D avatar using the PLAY_EMOTE action.",
42
+ "Use emotes sparingly and naturally during conversation to express yourself.",
43
+ "",
44
+ `Available emote IDs: ${EMOTE_CATALOG.map((e) => e.id).join(", ")}`
45
+ ].join("\n") };
46
+ }
47
+ };
48
+ const customActionsProvider = {
49
+ name: "customActions",
50
+ description: "User-defined custom actions",
51
+ async get() {
52
+ const customActions = loadCustomActions();
53
+ if (customActions.length === 0) return { text: "" };
54
+ return { text: [
55
+ "## Custom Actions",
56
+ "",
57
+ "The following custom actions are available:",
58
+ ...customActions.map((a) => {
59
+ const params = a.parameters?.map((p) => `${p.name}${p.required ? " (required)" : ""}`).join(", ") || "none";
60
+ return `- **${a.name}**: ${a.description} [params: ${params}]`;
61
+ })
62
+ ].join("\n") };
63
+ }
64
+ };
65
+ return {
66
+ name: "milady",
67
+ description: "Milady workspace context, session keys, and lifecycle actions",
68
+ init: async (_pluginConfig, runtime) => {
69
+ registerTriggerTaskWorker(runtime);
70
+ ensureAutonomousStateTracking(runtime);
71
+ setCustomActionsRuntime(runtime);
72
+ },
73
+ providers: [
74
+ ...baseProviders,
75
+ uiCatalogProvider,
76
+ emoteProvider,
77
+ customActionsProvider
78
+ ],
79
+ actions: [
80
+ restartAction,
81
+ sendMessageAction,
82
+ createTriggerTaskAction,
83
+ emoteAction,
84
+ ...loadCustomActions()
85
+ ]
86
+ };
87
+ }
88
+
89
+ //#endregion
90
+ export { createMiladyPlugin };
@@ -0,0 +1,78 @@
1
+ //#region src/runtime/onboarding-names.ts
2
+ /**
3
+ * Shared pool of Japanese agent names for onboarding.
4
+ *
5
+ * Used by both the CLI first-run flow (eliza.ts) and the
6
+ * web UI API server (api/server.ts).
7
+ */
8
+ /** Pool of Japanese names to randomly sample from during onboarding. */
9
+ const AGENT_NAME_POOL = [
10
+ "Reimu",
11
+ "Sakuya",
12
+ "Yukari",
13
+ "Marisa",
14
+ "Youmu",
15
+ "Koakuma",
16
+ "Reisen",
17
+ "Yuyuko",
18
+ "Aya",
19
+ "Ran",
20
+ "Sanae",
21
+ "Suika",
22
+ "Koishi",
23
+ "Nue",
24
+ "Chen",
25
+ "Mokou",
26
+ "Satori",
27
+ "Remilia",
28
+ "Suwako",
29
+ "Momiji",
30
+ "Tenshi",
31
+ "Kaguya",
32
+ "Komachi",
33
+ "Nitori",
34
+ "Charlotte",
35
+ "Kasen",
36
+ "Mima",
37
+ "Yuuka",
38
+ "Kogasa",
39
+ "Rin",
40
+ "Tewi",
41
+ "Eirin",
42
+ "Hina",
43
+ "Kagerou",
44
+ "Sumireko",
45
+ "Kokoro",
46
+ "Mamizou",
47
+ "Rinnosuke",
48
+ "Yumemi",
49
+ "Akyuu",
50
+ "Kanako",
51
+ "Hatsune",
52
+ "Shinki",
53
+ "Shion",
54
+ "Daiyousei",
55
+ "Iku",
56
+ "Miya",
57
+ "Mai",
58
+ "Meira",
59
+ "Murasa",
60
+ "Usagi",
61
+ "Rei",
62
+ "Yumi",
63
+ "Miku",
64
+ "Kira"
65
+ ];
66
+ /** Pick `count` unique random names from the pool using Fisher-Yates shuffle. */
67
+ function pickRandomNames(count) {
68
+ const clamped = Math.max(0, Math.min(count, AGENT_NAME_POOL.length));
69
+ const pool = [...AGENT_NAME_POOL];
70
+ for (let i = pool.length - 1; i > 0; i--) {
71
+ const j = Math.floor(Math.random() * (i + 1));
72
+ [pool[i], pool[j]] = [pool[j], pool[i]];
73
+ }
74
+ return pool.slice(0, clamped);
75
+ }
76
+
77
+ //#endregion
78
+ export { pickRandomNames };
@@ -0,0 +1,40 @@
1
+ import process from "node:process";
2
+
3
+ //#region src/runtime/restart.ts
4
+ /**
5
+ * Restart infrastructure for Milady.
6
+ *
7
+ * Provides a pluggable restart handler so the restart action (and the
8
+ * `/api/agent/restart` endpoint) work in every host environment:
9
+ *
10
+ * - **CLI** (default): exits with {@link RESTART_EXIT_CODE} (75). The runner
11
+ * script (`scripts/run-node.mjs`) catches this, rebuilds if source files
12
+ * changed, and relaunches.
13
+ * - **Dev-server / API**: the host registers a handler via
14
+ * {@link setRestartHandler} that stops the current runtime, creates a new
15
+ * one, and hot-swaps references.
16
+ * - **Electron app**: the host registers a handler that calls
17
+ * `AgentManager.restart()`.
18
+ *
19
+ * @module restart
20
+ */
21
+ /**
22
+ * Special exit code that tells the CLI runner to restart the process.
23
+ * Must stay in sync with `RESTART_EXIT_CODE` in `scripts/run-node.mjs`.
24
+ */
25
+ const RESTART_EXIT_CODE = 75;
26
+ let _handler = () => {
27
+ process.exit(RESTART_EXIT_CODE);
28
+ };
29
+ /**
30
+ * Trigger a restart. Delegates to whatever handler is currently registered.
31
+ *
32
+ * Safe to call from the restart action, the API endpoint, or any other code
33
+ * that needs to bounce the agent.
34
+ */
35
+ function requestRestart(reason) {
36
+ return _handler(reason);
37
+ }
38
+
39
+ //#endregion
40
+ export { requestRestart };
@@ -0,0 +1,7 @@
1
+ import { resolveMiladyVersion } from "../version-resolver.js";
2
+
3
+ //#region src/runtime/version.ts
4
+ const VERSION = resolveMiladyVersion(import.meta.url);
5
+
6
+ //#endregion
7
+ export { VERSION };