levix-bot 3.3.0-rc.2 → 4.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 (118) hide show
  1. package/README.md +13 -9
  2. package/app.cjs +49 -46
  3. package/package.json +9 -1
  4. package/public/dashboard/assets/index-BBBXWzM0.js +391 -0
  5. package/public/dashboard/assets/index-pYaivHON.css +1 -0
  6. package/public/dashboard/index.html +19 -0
  7. package/public/dashboard.css +391 -66
  8. package/public/dashboard.js +593 -42
  9. package/scheduler.cjs +9 -14
  10. package/src/auth/use-database-auth-state.js +2 -4
  11. package/src/bootstrap/core.js +2 -5
  12. package/src/bootstrap/panel.js +10 -5
  13. package/src/cli.js +3 -5
  14. package/src/commands/autoschedule.cjs +1 -4
  15. package/src/commands/blacklist.cjs +22 -20
  16. package/src/commands/block.cjs +2 -4
  17. package/src/commands/calc.cjs +9 -16
  18. package/src/commands/digit.cjs +97 -0
  19. package/src/commands/gemini.cjs +147 -161
  20. package/src/commands/group/add.cjs +7 -16
  21. package/src/commands/group/antiSpam.cjs +5 -11
  22. package/src/commands/group/antilink.cjs +34 -28
  23. package/src/commands/group/approveall.cjs +3 -11
  24. package/src/commands/group/clearwarns.cjs +2 -5
  25. package/src/commands/group/demote.cjs +3 -8
  26. package/src/commands/group/kick.cjs +12 -15
  27. package/src/commands/group/media.cjs +17 -24
  28. package/src/commands/group/members.cjs +1 -2
  29. package/src/commands/group/promote.cjs +4 -12
  30. package/src/commands/group/removeall.cjs +2 -5
  31. package/src/commands/group/setpp.cjs +1 -1
  32. package/src/commands/group/setrules.cjs +2 -8
  33. package/src/commands/group/setwarn.cjs +4 -2
  34. package/src/commands/group/tagadmins.cjs +2 -5
  35. package/src/commands/group/warn.cjs +26 -24
  36. package/src/commands/group/warns.cjs +1 -2
  37. package/src/commands/group/welcome.cjs +13 -17
  38. package/src/commands/group.cjs +7 -10
  39. package/src/commands/help.cjs +6 -12
  40. package/src/commands/lang.cjs +104 -0
  41. package/src/commands/listschedules.cjs +2 -6
  42. package/src/commands/loop.cjs +6 -13
  43. package/src/commands/memory.cjs +19 -32
  44. package/src/commands/mod.cjs +97 -35
  45. package/src/commands/perm.cjs +18 -56
  46. package/src/commands/ping.cjs +1 -5
  47. package/src/commands/poll.cjs +1 -1
  48. package/src/commands/rand.cjs +2 -5
  49. package/src/commands/schedule.cjs +4 -8
  50. package/src/commands/score.cjs +8 -2
  51. package/src/commands/setprefix.cjs +2 -2
  52. package/src/commands/shortlink.cjs +7 -15
  53. package/src/commands/shutdown.cjs +1 -1
  54. package/src/commands/sticker.cjs +222 -0
  55. package/src/commands/stt.cjs +136 -68
  56. package/src/commands/todo.cjs +9 -15
  57. package/src/commands/tts.cjs +10 -16
  58. package/src/commands/unblock.cjs +2 -6
  59. package/src/commands/weather.cjs +5 -12
  60. package/src/config/ai-persona.md +5 -3
  61. package/src/config/available-models.json +1156 -0
  62. package/src/config/baileys.config.js +2 -1
  63. package/src/config/brand.esm.js +1 -10
  64. package/src/config/constants.js +1 -1
  65. package/src/config/defaults.cjs +66 -66
  66. package/src/config/lock.cjs +2 -2
  67. package/src/config/modelCapabilities.cjs +172 -0
  68. package/src/config/runtime-config.cjs +8 -13
  69. package/src/config/secrets.cjs +18 -10
  70. package/src/config/settings.cjs +94 -10
  71. package/src/config/vault.cjs +107 -0
  72. package/src/core/connection.js +13 -12
  73. package/src/core/events.js +41 -23
  74. package/src/core/proxy.js +7 -7
  75. package/src/core/session.js +91 -48
  76. package/src/core/socket.js +12 -15
  77. package/src/db/db.cjs +14 -6
  78. package/src/db/store.cjs +221 -87
  79. package/src/domain/caddy.js +1 -1
  80. package/src/domain/command.js +40 -19
  81. package/src/domain/detect.js +1 -1
  82. package/src/domain/system.js +2 -5
  83. package/src/handlers/command.handler.js +22 -43
  84. package/src/handlers/group.handler.js +13 -13
  85. package/src/handlers/message.handler.js +11 -21
  86. package/src/index.js +8 -4
  87. package/src/middleware/antispam.middleware.js +46 -23
  88. package/src/middleware/blacklist.middleware.js +14 -9
  89. package/src/middleware/forward-tracking.middleware.js +3 -2
  90. package/src/middleware/permissions.middleware.js +7 -10
  91. package/src/panel/login-throttle.cjs +43 -0
  92. package/src/panel/session-auth.cjs +17 -0
  93. package/src/routes/dashboard.api.esm.js +394 -72
  94. package/src/services/aiAgent.cjs +136 -49
  95. package/src/services/aiProviders.cjs +193 -47
  96. package/src/services/aiRouter.cjs +137 -0
  97. package/src/services/aiTools.cjs +305 -128
  98. package/src/services/llmDiscovery.cjs +481 -0
  99. package/src/services/modelRegistry.cjs +412 -0
  100. package/src/utils/datetime.cjs +2 -2
  101. package/src/utils/lid-helper.esm.js +7 -7
  102. package/src/utils/logger.cjs +1 -1
  103. package/src/utils/markdownParser.cjs +159 -0
  104. package/src/utils/memory.cjs +43 -13
  105. package/src/utils/messageContent.cjs +40 -0
  106. package/src/utils/normalizeJid.esm.js +7 -7
  107. package/src/utils/numerals.cjs +75 -0
  108. package/src/utils/permissions.esm.js +10 -15
  109. package/src/utils/providerUrl.cjs +281 -0
  110. package/src/utils/recurrence.cjs +7 -11
  111. package/src/utils/sendBotMessage.esm.js +4 -14
  112. package/src/utils/statusMessage.cjs +5 -13
  113. package/src/utils/storage.cjs +10 -0
  114. package/src/utils/storage.esm.js +11 -0
  115. package/src/utils/textDecode.cjs +4 -9
  116. package/src/utils/thumbnail.cjs +8 -14
  117. package/src/utils/typing.esm.js +12 -12
  118. package/views/dashboard.ejs +134 -106
@@ -0,0 +1,137 @@
1
+ // file: src/services/aiRouter.cjs
2
+ // Modular AI Provider Registry and Router.
3
+ //
4
+ // Instead of hardcoding conditionals for each provider across command handlers
5
+ // and service loops, providers register an adapter implementing the BaseAIProvider
6
+ // interface. The router dispatches based on the active `ai_provider` setting.
7
+
8
+ const settings = require("../config/settings.cjs");
9
+ const { resolveCapabilities } = require("./modelRegistry.cjs");
10
+
11
+ class BaseAIProvider {
12
+ constructor({
13
+ id,
14
+ label,
15
+ keySetting,
16
+ modelSetting,
17
+ baseUrlSetting,
18
+ defaultBaseUrl = "",
19
+ supportsFiles = false,
20
+ }) {
21
+ this.id = id;
22
+ this.label = label;
23
+ this.keySetting = keySetting;
24
+ this.modelSetting = modelSetting;
25
+ this.baseUrlSetting = baseUrlSetting;
26
+ this.defaultBaseUrl = defaultBaseUrl;
27
+ this.supportsFiles = supportsFiles;
28
+ }
29
+
30
+ isConfigured() {
31
+ return Boolean(this.getKey());
32
+ }
33
+
34
+ getKey() {
35
+ return settings.get(this.keySetting) || "";
36
+ }
37
+
38
+ getModel() {
39
+ return settings.get(this.modelSetting) || "";
40
+ }
41
+
42
+ getBaseUrl() {
43
+ if (!this.baseUrlSetting) return this.defaultBaseUrl;
44
+ return settings.get(this.baseUrlSetting) || this.defaultBaseUrl;
45
+ }
46
+
47
+ supportsMedia(mime = "") {
48
+ const caps = detectModelCapabilities(this.id);
49
+ if (typeof mime === "string" && mime.startsWith("image/")) {
50
+ return Boolean(settings.get("ai_vision_enabled") && caps.supportsVision);
51
+ }
52
+ if (typeof mime === "string" && mime.startsWith("audio/")) {
53
+ return Boolean(settings.get("ai_stt_enabled") && caps.supportsAudioStt);
54
+ }
55
+ if (this.supportsFiles) return true;
56
+ return false;
57
+ }
58
+
59
+ async prepareMedia(parts, mediaMessage, mimeOverride, _context = {}) {
60
+ const mime = mimeOverride || mediaMessage?.mimetype || "ملف";
61
+ parts.push({
62
+ text: `[تم إرفاق وسائط (${mime}) — المزود الحالي لا يدعم هذا النوع من الوسائط]`,
63
+ });
64
+ return null;
65
+ }
66
+
67
+ async runTurn(_options) {
68
+ throw new Error(`runTurn() not implemented for provider: ${this.id}`);
69
+ }
70
+ }
71
+
72
+ const REGISTRY = new Map();
73
+
74
+ function registerProvider(id, providerInstance) {
75
+ if (!id || typeof id !== "string") {
76
+ throw new Error("Provider id must be a non-empty string");
77
+ }
78
+ REGISTRY.set(id.toLowerCase(), providerInstance);
79
+ }
80
+
81
+ function getProvider(id = settings.get("ai_provider")) {
82
+ const key = String(id || "gemini").toLowerCase();
83
+ const provider = REGISTRY.get(key);
84
+ if (!provider) {
85
+ throw new Error(`مزود غير معروف: ${id}`);
86
+ }
87
+ return provider;
88
+ }
89
+
90
+ function hasProvider(id) {
91
+ return REGISTRY.has(String(id || "").toLowerCase());
92
+ }
93
+
94
+ function listProviders() {
95
+ return Array.from(REGISTRY.values());
96
+ }
97
+
98
+ function activeProviderKeySetting(provider = settings.get("ai_provider")) {
99
+ const p = getProvider(provider);
100
+ return p.keySetting;
101
+ }
102
+
103
+ function detectModelCapabilities(provider = settings.get("ai_provider"), model = null) {
104
+ const p = provider || "gemini";
105
+ const m = String(
106
+ model ||
107
+ (p === "gemini"
108
+ ? settings.get("gemini_model")
109
+ : p === "openai"
110
+ ? settings.get("openai_model")
111
+ : settings.get("anthropic_model")) ||
112
+ "",
113
+ );
114
+
115
+ const resolved = resolveCapabilities(p, m);
116
+ const caps = resolved.capabilities;
117
+
118
+ return {
119
+ provider: p,
120
+ model: m,
121
+ capabilities: caps,
122
+ capabilitySource: resolved.capabilitySource,
123
+ supportsVision: Boolean(caps.vision),
124
+ supportsAudioStt: Boolean(caps.stt),
125
+ visionRecommended: Boolean(caps.vision) && !settings.get("ai_vision_enabled"),
126
+ };
127
+ }
128
+
129
+ module.exports = {
130
+ BaseAIProvider,
131
+ registerProvider,
132
+ getProvider,
133
+ hasProvider,
134
+ listProviders,
135
+ activeProviderKeySetting,
136
+ detectModelCapabilities,
137
+ };