odant-work 1.0.15 → 1.0.17

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 (84) hide show
  1. package/#system/package-manifest.json +57 -49
  2. package/$server/$folder/handlers/methods/create/$handler/class.js +83 -2
  3. package/$server/$folder/handlers/pages/form/$handler/form.js +2 -1
  4. package/$server/$folder/lib/icon/icon.js +14 -0
  5. package/$server/$folder/lib/node/node.js +51 -1
  6. package/$server/$folder/lib/tree/tree.js +5 -1
  7. package/.secretsignore +4 -0
  8. package/MODELS/$ai/$folder/$class/$ai/class.js +58 -3
  9. package/MODELS/$ai/$folder/$class/$ai/handlers/pages/form/trainer/$handler/class.js +6 -4
  10. package/MODELS/$ai/$folder/$class/$ai/handlers/pages/form/trainer/$handler/trainer.js +344 -3
  11. package/MODELS/$ai/$folder/$class/$provider/class.js +1 -1
  12. package/MODELS/$ai/$folder/$class/$provider/handlers/pages/form/provider/$handler/class.js +13 -0
  13. package/MODELS/$ai/$folder/$class/$provider/handlers/pages/form/provider/$handler/provider.js +479 -0
  14. package/MODELS/$ai/$folder/$class/$provider/handlers/pages/form/trainer/$handler/class.js +3 -3
  15. package/MODELS/$ai/$folder/$class/$provider/handlers/pages/form/trainer/$handler/trainer.js +530 -920
  16. package/MODELS/GigaChat/$provider/$folder/$class/$ai/class.js +10 -20
  17. package/MODELS/GigaChat/$provider/class.js +10 -7
  18. package/MODELS/GigaChat/GigaChat 2 Lite/$ai/class.js +15 -0
  19. package/MODELS/GigaChat/GigaChat 2 Max/$ai/class.js +16 -0
  20. package/MODELS/GigaChat/GigaChat 2 Pro/$ai/class.js +15 -0
  21. package/MODELS/GigaChat/GigaChat Embeddings/$ai/class.js +13 -0
  22. package/MODELS/Local/$provider/$folder/$class/$ai/class.js +3 -3
  23. package/MODELS/Local/$provider/class.js +7 -3
  24. package/MODELS/MTS-AI/$provider/$folder/$class/$ai/class.js +8 -0
  25. package/MODELS/MTS-AI/$provider/class.js +8 -0
  26. package/MODELS/MTS-AI/Cotype Lite/$ai/class.js +15 -0
  27. package/MODELS/MTS-AI/Cotype Pro 2/$ai/class.js +15 -0
  28. package/MODELS/MTS-AI/Cotype Vision/$ai/class.js +14 -0
  29. package/MODELS/T-Bank/$provider/$folder/$class/$ai/class.js +8 -0
  30. package/MODELS/T-Bank/$provider/class.js +8 -0
  31. package/MODELS/T-Bank/T-Lite 2.0/$ai/class.js +15 -0
  32. package/MODELS/T-Bank/T-Pro 2.0/$ai/class.js +16 -0
  33. package/MODELS/T-Bank/T-VoiceKit ASR/$ai/class.js +13 -0
  34. package/MODELS/T-Bank/T-VoiceKit TTS/$ai/class.js +13 -0
  35. package/MODELS/Yandex/$provider/$folder/$class/$ai/class.js +9 -0
  36. package/MODELS/Yandex/$provider/class.js +9 -0
  37. package/MODELS/Yandex/Alice AI (YandexGPT 5 Pro)/$ai/class.js +15 -0
  38. package/MODELS/Yandex/Yandex Embeddings/$ai/class.js +13 -0
  39. package/MODELS/Yandex/Yandex SpeechKit ASR/$ai/class.js +13 -0
  40. package/MODELS/Yandex/Yandex SpeechKit TTS/$ai/class.js +13 -0
  41. package/MODELS/Yandex/YandexART/$ai/class.js +13 -0
  42. package/MODELS/Yandex/YandexGPT 5 Lite/$ai/class.js +15 -0
  43. package/MODELS/Yandex/YandexGPT Reasoning/$ai/class.js +22 -0
  44. package/oda/tools/icons/lib/svg/ai.svg +20 -0
  45. package/package.json +1 -1
  46. package/scripts/check-ignored-code.mjs +3 -0
  47. package/scripts/check-secrets.mjs +1 -1
  48. package/sources/data/progress.md +24 -0
  49. package/sources/host/watch.js +13 -2
  50. package/sources/modules/agent/index.js +23 -2
  51. package/sources/modules/trainer/halogen.js +128 -29
  52. package/sources/modules/trainer/huggingface.js +11 -5
  53. package/sources/modules/trainer/index.js +176 -3
  54. package/sources/modules/trainer/local-engine.js +67 -1
  55. package/sources/modules/trainer/providers.js +1213 -0
  56. package/sources/modules/trainer/runner.js +47 -1
  57. package/sources/server/class.js +55 -3
  58. package/MODELS/GigaChat/GigaChat Light/$ai/class.js +0 -15
  59. package/MODELS/GigaChat/GigaChat Pro/$ai/class.js +0 -15
  60. package/MODELS/Halogen/$provider/$folder/$class/$ai/class.js +0 -11
  61. package/MODELS/Halogen/$provider/class.js +0 -16
  62. package/MODELS/Halogen/$provider/readme.md +0 -28
  63. package/MODELS/Halogen/Decider-NPU/$ai/class.js +0 -22
  64. package/MODELS/Halogen/Flux2-Klein-NPU/$ai/class.js +0 -21
  65. package/MODELS/Halogen/Qwen3-ASR-NPU/$ai/class.js +0 -21
  66. package/MODELS/Halogen/Qwen3-Embedding-NPU/$ai/class.js +0 -22
  67. package/MODELS/Halogen/Qwen3-Reranker-NPU/$ai/class.js +0 -21
  68. package/MODELS/Halogen/Qwen3-TTS-NPU/$ai/class.js +0 -26
  69. package/MODELS/Halogen/Qwen3.5-2B-NPU/$ai/class.js +0 -23
  70. package/MODELS/Halogen/Qwen3.8-Flash-Next/$ai/class.js +0 -31
  71. package/MODELS/Local/Flux-Image/$ai/class.js +0 -20
  72. package/MODELS/Local/Qwen3-0.6B/$ai/class.js +0 -26
  73. package/MODELS/Local/Qwen3-14B/$ai/class.js +0 -27
  74. package/MODELS/Local/Qwen3-30B-A3B/$ai/class.js +0 -30
  75. package/MODELS/Local/Qwen3-Embedding/$ai/class.js +0 -21
  76. package/MODELS/Local/Qwen3-Voice/$ai/class.js +0 -26
  77. package/MODELS/odant/$provider/$folder/$class/$ai/class.js +0 -11
  78. package/MODELS/odant/$provider/class.js +0 -75
  79. package/MODELS/odant/$provider/readme.md +0 -21
  80. package/MODELS/odant/Qwen3-ASR/$ai/class.js +0 -15
  81. package/MODELS/odant/Qwen3-TTS/$ai/class.js +0 -22
  82. package/MODELS/odant/Qwen3.8 27b/$ai/class.js +0 -11
  83. package/MODELS/odant/Z-Image-Turbo/$ai/class.js +0 -8
  84. package/MODELS/odant/Z-Image-Turbo/$ai/readme.md +0 -24
@@ -1,20 +1,10 @@
1
- /**
2
- * GigaChat — прототип для моделей провайдера GigaChat.
3
- *
4
- * Наследуется всеми моделями внутри models/GigaChat/.
5
- * Содержит общие настройки подключения и метаданные GigaChat.
6
- */
7
- export default {
8
- icon: 'ai:gigachat',
9
- description: 'Провайдер GigaChat',
10
-
11
- protocol: 'gigachat',
12
- baseUrl: 'https://gigachat.devices.sberbank.ru/api/v1/chat/completions',
13
- authUrl: 'https://ngw.devices.sberbank.ru:9443/api/v2/oauth',
14
- /** Authorization key: файл /MODELS/GigaChat/$provider/#secret/gigachat.json ({"token": "..."}); запасной вариант — env GIGACHAT_KEY. */
15
- token: 'secret:gigachat.json',
16
- scope: 'GIGACHAT_API_PERS',
17
-
18
- /** Native tools / ask_user через streamChat (OpenAI-compatible functions) */
19
- functionCalling: true,
20
- }
1
+ export default {
2
+ "icon": "ai:gigachat",
3
+ "description": "Модель провайдера GigaChat (Сбер)",
4
+ "protocol": "gigachat",
5
+ "baseUrl": "https://gigachat.devices.sberbank.ru/api/v1/chat/completions",
6
+ "functionCalling": true,
7
+ "authUrl": "https://ngw.devices.sberbank.ru:9443/api/v2/oauth",
8
+ "token": "secret:gigachat.json",
9
+ "scope": "GIGACHAT_API_PERS"
10
+ };
@@ -1,7 +1,10 @@
1
- /**
2
- * GigaChat — провайдер ($provider) моделей GigaChat.
3
- */
4
- export default {
5
- icon: 'ai:gigachat',
6
- label: 'GigaChat',
7
- }
1
+ export default {
2
+ "icon": "ai:gigachat",
3
+ "label": "GigaChat (Сбер)",
4
+ "form": "provider",
5
+ "protocol": "gigachat",
6
+ "baseUrl": "https://gigachat.devices.sberbank.ru/api/v1/chat/completions",
7
+ "authUrl": "https://ngw.devices.sberbank.ru:9443/api/v2/oauth",
8
+ "token": "secret:gigachat.json",
9
+ "scope": "GIGACHAT_API_PERS"
10
+ };
@@ -0,0 +1,15 @@
1
+ export default {
2
+ "label": "GigaChat 2 Lite",
3
+ "model": "GigaChat-2",
4
+ "icon": "ai:gigachat",
5
+ "modality": "llm",
6
+ "maxTokens": 131072,
7
+ "maxOutput": 8192,
8
+ "functionCalling": true,
9
+ "capabilities": [
10
+ "chat",
11
+ "stream",
12
+ "tools",
13
+ "functions"
14
+ ]
15
+ };
@@ -0,0 +1,16 @@
1
+ export default {
2
+ "label": "GigaChat 2 Max",
3
+ "model": "GigaChat-2-Max",
4
+ "icon": "ai:gigachat",
5
+ "modality": "vlm",
6
+ "maxTokens": 131072,
7
+ "maxOutput": 8192,
8
+ "functionCalling": true,
9
+ "capabilities": [
10
+ "chat",
11
+ "stream",
12
+ "tools",
13
+ "functions",
14
+ "vision"
15
+ ]
16
+ };
@@ -0,0 +1,15 @@
1
+ export default {
2
+ "label": "GigaChat 2 Pro",
3
+ "model": "GigaChat-2-Pro",
4
+ "icon": "ai:gigachat",
5
+ "modality": "llm",
6
+ "maxTokens": 131072,
7
+ "maxOutput": 8192,
8
+ "functionCalling": true,
9
+ "capabilities": [
10
+ "chat",
11
+ "stream",
12
+ "tools",
13
+ "functions"
14
+ ]
15
+ };
@@ -0,0 +1,13 @@
1
+ export default {
2
+ "label": "GigaChat Embeddings",
3
+ "model": "EmbeddingsGigaR",
4
+ "icon": "carbon:search-locate",
5
+ "modality": "embed",
6
+ "maxTokens": 4096,
7
+ "maxOutput": 1024,
8
+ "functionCalling": false,
9
+ "capabilities": [
10
+ "embeddings",
11
+ "rag"
12
+ ]
13
+ };
@@ -1,11 +1,11 @@
1
1
  /**
2
- * Local — прототип моделей ($ai) локального провайдера /MODELS/Local.
2
+ * Local — прототип моделей ($ai) единого локального провайдера /MODELS/Local.
3
3
  * Наследуется всеми локальными моделями через tilde (cross-type $provider → $ai).
4
4
  */
5
5
  export default {
6
6
  icon: 'ai:ollama',
7
7
  description: 'Локальная модель ИИ',
8
- protocol: 'openai',
9
- baseUrl: 'http://127.0.0.1:8080/v1/chat/completions',
8
+ protocol: 'local',
9
+ baseUrl: 'http://127.0.0.1:8731/v1/chat/completions',
10
10
  functionCalling: true,
11
11
  }
@@ -1,10 +1,14 @@
1
1
  /**
2
- * Local — провайдер ($provider) локальных моделей и встроенного дообучения ИИ.
2
+ * Local — единый провайдер ($provider) локальных моделей ИИ, дообучения (LoRA / SFT / GRPO)
3
+ * и аппаратного контура Halo (AMD Ryzen™ AI Max+ PRO 395/495 · 128–192 ГБ Unified Memory: GPU + NPU).
4
+ *
5
+ * В чистой поставке папка /MODELS/Local пуста — дочерние узлы моделей ($ai) создаются автоматически
6
+ * только после реального скачивания весов модели в /MODELS/Local/<Модель>/#weights.
3
7
  */
4
8
  export default {
5
- icon: 'carbon:location-company',
9
+ icon: 'carbon:chip',
6
10
  label: 'Local',
7
11
  protocol: 'local',
8
12
  form: 'trainer',
9
- baseUrl: 'http://127.0.0.1:8080/v1/chat/completions',
13
+ baseUrl: 'http://127.0.0.1:8731/v1/chat/completions',
10
14
  }
@@ -0,0 +1,8 @@
1
+ export default {
2
+ "icon": "ai:mts",
3
+ "description": "Модель провайдера MTS AI (Cotype)",
4
+ "protocol": "openai",
5
+ "baseUrl": "https://api.mts.ai/v1/chat/completions",
6
+ "functionCalling": true,
7
+ "apiKey": "secret:mts.json"
8
+ };
@@ -0,0 +1,8 @@
1
+ export default {
2
+ "icon": "ai:mts",
3
+ "label": "MTS AI (Cotype)",
4
+ "form": "provider",
5
+ "protocol": "openai",
6
+ "baseUrl": "https://api.mts.ai/v1/chat/completions",
7
+ "apiKey": "secret:mts.json"
8
+ };
@@ -0,0 +1,15 @@
1
+ export default {
2
+ "label": "Cotype Lite",
3
+ "model": "cotype-lite",
4
+ "icon": "ai:mts",
5
+ "modality": "llm",
6
+ "maxTokens": 32768,
7
+ "maxOutput": 8192,
8
+ "functionCalling": true,
9
+ "capabilities": [
10
+ "chat",
11
+ "stream",
12
+ "tools",
13
+ "functions"
14
+ ]
15
+ };
@@ -0,0 +1,15 @@
1
+ export default {
2
+ "label": "Cotype Pro 2",
3
+ "model": "cotype-pro-2",
4
+ "icon": "ai:mts",
5
+ "modality": "llm",
6
+ "maxTokens": 131072,
7
+ "maxOutput": 8192,
8
+ "functionCalling": true,
9
+ "capabilities": [
10
+ "chat",
11
+ "stream",
12
+ "tools",
13
+ "functions"
14
+ ]
15
+ };
@@ -0,0 +1,14 @@
1
+ export default {
2
+ "label": "Cotype Vision",
3
+ "model": "cotype-vl",
4
+ "icon": "ai:mts",
5
+ "modality": "vlm",
6
+ "maxTokens": 32768,
7
+ "maxOutput": 8192,
8
+ "functionCalling": true,
9
+ "capabilities": [
10
+ "chat",
11
+ "stream",
12
+ "vision"
13
+ ]
14
+ };
@@ -0,0 +1,8 @@
1
+ export default {
2
+ "icon": "ai:tbank",
3
+ "description": "Модель провайдера T-Bank AI (T-Pro)",
4
+ "protocol": "openai",
5
+ "baseUrl": "https://api.tbank.ru/v1/chat/completions",
6
+ "functionCalling": true,
7
+ "apiKey": "secret:tbank.json"
8
+ };
@@ -0,0 +1,8 @@
1
+ export default {
2
+ "icon": "ai:tbank",
3
+ "label": "T-Bank AI (T-Pro)",
4
+ "form": "provider",
5
+ "protocol": "openai",
6
+ "baseUrl": "https://api.tbank.ru/v1/chat/completions",
7
+ "apiKey": "secret:tbank.json"
8
+ };
@@ -0,0 +1,15 @@
1
+ export default {
2
+ "label": "T-Lite 2.0",
3
+ "model": "t-tech/T-lite-it-2.0",
4
+ "icon": "ai:tbank",
5
+ "modality": "llm",
6
+ "maxTokens": 131072,
7
+ "maxOutput": 8192,
8
+ "functionCalling": true,
9
+ "capabilities": [
10
+ "chat",
11
+ "stream",
12
+ "tools",
13
+ "functions"
14
+ ]
15
+ };
@@ -0,0 +1,16 @@
1
+ export default {
2
+ "label": "T-Pro 2.0",
3
+ "model": "t-tech/T-pro-it-2.0",
4
+ "icon": "ai:tbank",
5
+ "modality": "llm",
6
+ "maxTokens": 131072,
7
+ "maxOutput": 8192,
8
+ "functionCalling": true,
9
+ "capabilities": [
10
+ "chat",
11
+ "stream",
12
+ "tools",
13
+ "functions",
14
+ "thinking"
15
+ ]
16
+ };
@@ -0,0 +1,13 @@
1
+ export default {
2
+ "label": "T-VoiceKit ASR",
3
+ "model": "t-voicekit-asr",
4
+ "icon": "carbon:microphone",
5
+ "modality": "audio",
6
+ "maxTokens": 4096,
7
+ "maxOutput": 2048,
8
+ "functionCalling": false,
9
+ "capabilities": [
10
+ "stt",
11
+ "asr"
12
+ ]
13
+ };
@@ -0,0 +1,13 @@
1
+ export default {
2
+ "label": "T-VoiceKit TTS",
3
+ "model": "t-voicekit-tts",
4
+ "icon": "carbon:volume-up",
5
+ "modality": "audio",
6
+ "maxTokens": 4096,
7
+ "maxOutput": 2048,
8
+ "functionCalling": false,
9
+ "capabilities": [
10
+ "tts",
11
+ "voice"
12
+ ]
13
+ };
@@ -0,0 +1,9 @@
1
+ export default {
2
+ "icon": "ai:yandex",
3
+ "description": "Модель провайдера Yandex AI (Алиса)",
4
+ "protocol": "yandex",
5
+ "baseUrl": "https://llm.api.cloud.yandex.net/v1/chat/completions",
6
+ "functionCalling": true,
7
+ "apiKey": "secret:yandex.json",
8
+ "folderId": "secret:yandex.json"
9
+ };
@@ -0,0 +1,9 @@
1
+ export default {
2
+ "icon": "ai:yandex",
3
+ "label": "Yandex AI (Алиса)",
4
+ "form": "provider",
5
+ "protocol": "yandex",
6
+ "baseUrl": "https://llm.api.cloud.yandex.net/v1/chat/completions",
7
+ "apiKey": "secret:yandex.json",
8
+ "folderId": "secret:yandex.json"
9
+ };
@@ -0,0 +1,15 @@
1
+ export default {
2
+ "label": "Alice AI (YandexGPT 5 Pro)",
3
+ "model": "yandexgpt/latest",
4
+ "icon": "ai:yandex",
5
+ "modality": "llm",
6
+ "maxTokens": 32768,
7
+ "maxOutput": 8192,
8
+ "functionCalling": true,
9
+ "capabilities": [
10
+ "chat",
11
+ "stream",
12
+ "tools",
13
+ "functions"
14
+ ]
15
+ };
@@ -0,0 +1,13 @@
1
+ export default {
2
+ "label": "Yandex Embeddings",
3
+ "model": "text-search-doc/latest",
4
+ "icon": "carbon:search-locate",
5
+ "modality": "embed",
6
+ "maxTokens": 4096,
7
+ "maxOutput": 1024,
8
+ "functionCalling": false,
9
+ "capabilities": [
10
+ "embeddings",
11
+ "rag"
12
+ ]
13
+ };
@@ -0,0 +1,13 @@
1
+ export default {
2
+ "label": "Yandex SpeechKit ASR",
3
+ "model": "general:rc",
4
+ "icon": "carbon:microphone",
5
+ "modality": "audio",
6
+ "maxTokens": 4096,
7
+ "maxOutput": 2048,
8
+ "functionCalling": false,
9
+ "capabilities": [
10
+ "stt",
11
+ "asr"
12
+ ]
13
+ };
@@ -0,0 +1,13 @@
1
+ export default {
2
+ "label": "Yandex SpeechKit TTS",
3
+ "model": "alena",
4
+ "icon": "carbon:volume-up",
5
+ "modality": "audio",
6
+ "maxTokens": 4096,
7
+ "maxOutput": 2048,
8
+ "functionCalling": false,
9
+ "capabilities": [
10
+ "tts",
11
+ "voice"
12
+ ]
13
+ };
@@ -0,0 +1,13 @@
1
+ export default {
2
+ "label": "YandexART",
3
+ "model": "yandex-art/latest",
4
+ "icon": "ai:stablediffusion",
5
+ "modality": "image",
6
+ "maxTokens": 4096,
7
+ "maxOutput": 1024,
8
+ "functionCalling": false,
9
+ "capabilities": [
10
+ "image",
11
+ "text-to-image"
12
+ ]
13
+ };
@@ -0,0 +1,15 @@
1
+ export default {
2
+ "label": "YandexGPT 5 Lite",
3
+ "model": "yandexgpt-lite/latest",
4
+ "icon": "ai:yandex",
5
+ "modality": "llm",
6
+ "maxTokens": 32768,
7
+ "maxOutput": 8192,
8
+ "functionCalling": true,
9
+ "capabilities": [
10
+ "chat",
11
+ "stream",
12
+ "tools",
13
+ "functions"
14
+ ]
15
+ };
@@ -0,0 +1,22 @@
1
+ export default {
2
+ "label": "YandexGPT Reasoning",
3
+ "model": "yandexgpt/rc",
4
+ "icon": "ai:yandex",
5
+ "modality": "llm",
6
+ "maxTokens": 32768,
7
+ "maxOutput": 8192,
8
+ "functionCalling": true,
9
+ "capabilities": [
10
+ "chat",
11
+ "stream",
12
+ "tools",
13
+ "functions",
14
+ "effort",
15
+ "thinking"
16
+ ],
17
+ "efforts": [
18
+ "low",
19
+ "medium",
20
+ "high"
21
+ ]
22
+ };
@@ -209,4 +209,24 @@
209
209
  <symbol id="characterai">
210
210
  <path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 3c1.66 0 3 1.34 3 3s-1.34 3-3 3-3-1.34-3-3 1.34-3 3-3zm0 14.2c-2.5 0-4.71-1.28-6-3.22.03-1.99 4-3.08 6-3.08 1.99 0 5.97 1.09 6 3.08-1.29 1.94-3.5 3.22-6 3.22z"/>
211
211
  </symbol>
212
+
213
+ <!-- Yandex AI / Алиса (Яндекс) -->
214
+ <symbol id="yandex">
215
+ <path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm3.2 15.5h-2.1v-4.3h-1.1c-1.5 0-2.3.8-2.9 2.3l-.8 2H6.1l1.1-2.5c.6-1.3 1.3-2 2.3-2.3-1.5-.4-2.5-1.6-2.5-3.4 0-2.3 1.6-3.8 4.3-3.8h3.9v12zm-2.1-6.1V7.3h-1.6c-1.5 0-2.3.7-2.3 2s.8 2.1 2.3 2.1h1.6z"/>
216
+ </symbol>
217
+
218
+ <!-- T-Bank AI (T-Pro) -->
219
+ <symbol id="tbank">
220
+ <path d="M4 3h16a1 1 0 0 1 1 1v9c0 4.5-3.8 7.8-9 9-5.2-1.2-9-4.5-9-9V4a1 1 0 0 1 1-1zm3 4v2.5h3.7V17h2.6V9.5H17V7H7z"/>
221
+ </symbol>
222
+
223
+ <!-- MTS AI (Cotype) -->
224
+ <symbol id="mts">
225
+ <path d="M12 2C7.5 2 4 7.2 4 13c0 5 3.5 9 8 9s8-4 8-9c0-5.8-3.5-11-8-11zm0 3.2c2.9 0 5.2 4 5.2 7.8 0 3.4-2.3 6-5.2 6s-5.2-2.6-5.2-6c0-3.8 2.3-7.8 5.2-7.8z"/>
226
+ </symbol>
227
+
228
+ <!-- OpenRouter -->
229
+ <symbol id="openrouter">
230
+ <path d="M12 2L3 7v10l9 5 9-5V7l-9-5zm0 2.3l6.8 3.8L12 11.9 5.2 8.1 12 4.3zM5 9.8l6 3.4v6.5l-6-3.3V9.8zm8 9.9v-6.5l6-3.4v6.6l-6 3.3z"/>
231
+ </symbol>
212
232
  </svg>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "odant-work",
3
- "version": "1.0.15",
3
+ "version": "1.0.17",
4
4
  "description": "ODANT-WORK — платформа цифровой организации (встроенная система учёта, документооборот, управление процессами и приватный мультимодальный ИИ)",
5
5
  "type": "module",
6
6
  "main": "sources/work.js",
@@ -69,7 +69,10 @@ if (ignored.length) {
69
69
 
70
70
  // Проверяем также .npmignore через npm pack --dry-run --json (кроме tests и license-server)
71
71
  const NPM_CODE_ROOTS = new Set(['$server', 'sources', 'oda', 'scripts', 'rules', 'MODELS', 'NODES', 'SERVICES']);
72
+ const NPM_INTENTIONAL_EXCLUDE = /^MODELS\/(?:odant|Halogen)\/|^MODELS\/Local\/(?!\$provider\/)/;
72
73
  const npmCandidates = candidates.filter(f => {
74
+ if (NPM_INTENTIONAL_EXCLUDE.test(f))
75
+ return false;
73
76
  const top = f.split('/')[0];
74
77
  return NPM_CODE_ROOTS.has(top) || !f.includes('/');
75
78
  });
@@ -84,7 +84,7 @@ export function scanText(content, ignores = []) {
84
84
  continue;
85
85
  const value = m[0];
86
86
  if (rule === 'keyword-value' || rule === 'bearer-basic-b64') {
87
- const v = (value.match(/['"]([^'"]+)['"]/) || value.match(/[A-Za-z0-9+/]{20,}/) || [])[1] || value;
87
+ const v = (value.match(/['"]([^'"]+)['"]\s*$/) || value.match(/['"]([^'"]+)['"]/) || value.match(/[A-Za-z0-9+/]{20,}/) || [])[1] || value;
88
88
  if (SAFE_VALUE.test(v) || SAFE_MARK.test(v) || SAFE_MARK.test(line))
89
89
  continue;
90
90
  }
@@ -1,6 +1,30 @@
1
1
  # Прогресс: sources/data
2
2
 
3
3
  ## Последние изменения
4
+ - [21:20, 13.11] Переработка представления **«Модели ИИ»** (`form/trainer` / `form/provider`), интеграция локального ИИ-сервера внутрь WORK с адаптивным управлением памятью и чистый минималистичный интерфейс (`MODELS/$ai/**`, `sources/modules/trainer/{local-engine,runner,index}.js`, `tests/trainer-unsloth.test.js`, `odant-work@1.0.17`):
5
+ - **Единое название представления — «Модели ИИ» (`carbon:chip`):**
6
+ - Представление на `/MODELS/Local`, на облачных провайдерах (`/MODELS/GigaChat`, `/MODELS/Yandex`, `/MODELS/T-Bank`, `/MODELS/MTS-AI`, `/MODELS/OpenAI` и др.) и на конкретных узлах моделей (`$ai`) единообразно называется **«Модели ИИ»**.
7
+ - При клике на конкретную модель `$ai` в дереве вместо сырого JSON-кода открывается чистая карточка модели (статус активности, тумблер Вкл/Выкл, удаление с диска для локальных моделей, параметры контекста/возможностей и быстрая проверка ответа).
8
+ - **Встроенный сервер локального ИИ с адаптивным управлением памятью (`local-engine.js`, `runner.js`):**
9
+ - Локальный ИИ-движок полностью управляется самим сервером WORK без ручного запуска в консоли: на обычных ПК (< 120 ГБ ОЗУ) запускается автоматически по запросу и выгружается из памяти через 30 минут простоя (+ кнопка **«Освободить память»** в шапке), а на серверных машинках Halo (≥ 128 ГБ ОЗУ) удерживается в памяти постоянно.
10
+ - **Разгруженный интерфейс «Модели ИИ» на `/MODELS/Local` в системной палитре ODA:**
11
+ - Убраны двухколоночные сплит-панели, разноцветный спам бейджей и консольные простыни команд; оставлены **2 спокойные вкладки**:
12
+ 1. **«Модели»**: список установленных локальных моделей (статус, объём на диске, тумблер «Вкл» и кнопка **«Удалить»** для полной очистки модели и `#weights` с диска) + каталог моделей для установки в 1 клик с автоподбором формата под память ПК и встроенным прогресс-баром прямо внутри карточки. При выборе фильтра **«Комплект Halo (128–192 ГБ)»** отображается краткая памятка по настройке BIOS (выделение UMA Frame Buffer 128 ГБ / 96 ГБ и включение NPU) и кнопка установки комплекта GPU+NPU в 1 клик.
13
+ 2. **«Дообучение»**: двухшаговый мастер (*Шаг 1. Собрать обучающий набор из организации → Шаг 2. Дообучить модель LoRA*).
14
+ - [20:55, 13.11] Архитектура провайдеров и моделей ИИ в `/MODELS`: чистота дистрибутива (исключён `odant`, пустой единый `/MODELS/Local` вместе с контуром машинок Halo), предустановленные российские провайдеры (`GigaChat`, `Yandex`, `T-Bank`, `MTS-AI`), быстрое добавление любых внешних провайдеров и цветовая индикация активности моделей в дереве (`sources/modules/trainer/{providers,halogen,huggingface,index}.js`, `MODELS/$ai/**`, `MODELS/{GigaChat,Yandex,T-Bank,MTS-AI,Local}/**`, `$server/$folder/handlers/methods/create/$handler/class.js`, `$server/$folder/lib/{node/node,icon/icon,tree/tree}.js`, `sources/server/class.js`, `.npmignore`, `odant-work@1.0.16`):
15
+ - **Чистота `/MODELS` в поставке и объединение `Local` + `Halogen`:**
16
+ - Внутренний провайдер разработчика `/MODELS/odant` исключён из npm-дистрибутива (`.npmignore`: `/MODELS/odant/`), а `defaultModel()` в `sources/modules/agent/index.js` автоматически переключается на первую доступную активную модель в `/MODELS`.
17
+ - Ветки `Local` и `Halogen` объединены в единый провайдер **`/MODELS/Local`**, который в чистой поставке полностью пуст — дочерние узлы моделей (`$ai`) создаются в `/MODELS/Local/<Модель>` только при реальной установке/загрузке весов (включая матрицу из 8 GPU+NPU моделей для машинок Halo на базе AMD Ryzen™ AI Max+ PRO 495 192 ГБ).
18
+ - **Предустановленные российские провайдеры ИИ без зашитых ключей:**
19
+ - **`/MODELS/GigaChat` (Сбер):** `GigaChat 2 Lite`, `GigaChat 2 Pro`, `GigaChat 2 Max`, `GigaChat Embeddings`.
20
+ - **`/MODELS/Yandex` (Яндекс AI / Алиса, протокол `yandex`):** `Alice AI (YandexGPT 5 Pro)`, `YandexGPT 5 Lite`, `YandexGPT Reasoning`, `YandexART`, `Yandex SpeechKit ASR`, `Yandex SpeechKit TTS`, `Yandex Embeddings`.
21
+ - **`/MODELS/T-Bank` (Т-Банк AI / T-Pro):** `T-Pro 2.0`, `T-Lite 2.0`, `T-VoiceKit ASR`, `T-VoiceKit TTS`.
22
+ - **`/MODELS/MTS-AI` (МТС AI / Cotype):** `Cotype Pro 2`, `Cotype Lite`, `Cotype Vision`.
23
+ - **Мастер быстрого добавления провайдеров и экран `form/provider`:**
24
+ - При нажатии `+` на `/MODELS` открывается витрина шаблонов мировых и российских провайдеров (`OpenAI`, `Anthropic`, `DeepSeek`, `Gemini`, `OpenRouter`, `Grok`, `Mistral`, `Ollama`, `GigaChat`, `Yandex`, `T-Bank`, `MTS-AI`, `Custom`) с вводом API-ключа и автосозданием набора моделей в 1 клик.
25
+ - Добавлено представление **`form/provider` («Подключение и модели»)** на узлах `$provider` для сохранения ключей в `#secret`, проверки связи с API (`GET /v1/models`), включения/выключения и добавления моделей в 1 клик.
26
+ - **Визуальная индикация активных и неактивных моделей в дереве (`aiActive`):**
27
+ - Активные провайдеры и модели (у которых настроен API-ключ в `#secret` или скачаны локальные веса в `#weights`) помечаются в дереве зелёным индикатором `.ai-dot.active` и полной яркостью, а неактивные — приглушённым серым цветом (`.ai-inactive`, `opacity: 0.48`) с подсказкой причины и скрываются из выпадающего селектора моделей чата.
4
28
  - [20:05, 12.11] Прямая 1-клик регистрация первого администратора (`BOSS`) без настроенного почтового сервера и горячее перечитывание SMTP-настроек из `WORK → Почта` (`$server/#secret/email.json`) и `#system/mail.json` (`sources/host/mail.js`, `sources/host/auth-methods.js`, `sources/modules/user-profile/user-profile.js`, `tests/license-and-deploy.test.js`, `odant-work@1.0.15`):
5
29
  - **Регистрация первого пользователя (`BOSS`) без SMTP:** если на новом компьютере почтовый сервер ещё не настроен (`getMailer() === null`), а в `/USERS` ещё нет зарегистрированного `BOSS`, `user_register_start` возвращает `{ autoCode }`, и `user-profile.js` сразу в 1 клик генерирует криптоключ, регистрирует пользователя как `BOSS` всего `WORK` и выполняет вход без требования почтового кода.
6
30
  - **Настройка почтовика из интерфейса WORK и горячий подхват (`sources/host/mail.js`):** `getMailer()` динамически (по `mtime` без перезапуска сервера) читает настройки SMTP как из `#system/mail.json`, так и из штатного диалога **«Почтовые ящики» (`⚙️` на форме `WORK → Почта`, файл `$server/#secret/email.json`)**, а при отсутствии файлов не засоряет консоль ошибкой `ENOENT`.
@@ -50,14 +50,25 @@ function flush($server) {
50
50
  Promise.resolve(globalThis.WORK_AGENT_CORE?.()).then(c => c?.voice?.resetVoiceProbes?.()).catch(() => {});
51
51
  }
52
52
  for (const f of files) {
53
- const p = '/' + f.replace(/\\/g, '/');
53
+ const norm = f.replace(/\\/g, '/');
54
+ const p = '/' + norm;
55
+ if (!fs.existsSync(f)) {
56
+ const parentDir = path.posix.dirname(norm);
57
+ if (parentDir && parentDir !== '.' && fs.existsSync(parentDir)) {
58
+ Promise.resolve(globalThis.WORK?.get_item('/' + parentDir)).then(item => {
59
+ if (item && !Array.isArray(item))
60
+ item.reset?.();
61
+ }).catch(() => {});
62
+ }
63
+ continue;
64
+ }
54
65
  Promise.resolve(globalThis.WORK?.get_item(p)).then(item => {
55
66
  if (item && !Array.isArray(item))
56
67
  item.reset?.();
57
68
  }).catch(() => {});
58
69
  // Если изменился /X/$type/class.js — сбрасываем также сам узел класса /X
59
70
  const clsMatch = p.match(/^(\/.*?)\/\$[^/]+\/class\.js$/i);
60
- if (clsMatch?.[1]) {
71
+ if (clsMatch?.[1] && fs.existsSync(clsMatch[1].slice(1))) {
61
72
  Promise.resolve(globalThis.WORK?.get_item(clsMatch[1])).then(clsItem => {
62
73
  if (clsItem && !Array.isArray(clsItem))
63
74
  clsItem.reset?.();
@@ -259,7 +259,24 @@ export async function llmWithFallback(primaryPath, fallbackPaths = []) {
259
259
  };
260
260
  return adapter;
261
261
  }
262
- /** Первая модель с capability image (или ai/config.js imageModel). */
262
+ /** Первая доступная чат-модель в /MODELS (активная приоритетно), когда дефолтная модель отсутствует. */
263
+ async function findFirstAvailableChatModel() {
264
+ const root = await WORK.get_item('/MODELS').catch(() => null);
265
+ let firstAny = '';
266
+ for (const provider of (await root?.items) || []) {
267
+ for (const m of (await provider.items) || []) {
268
+ await m.init;
269
+ const caps = Array.isArray(m.capabilities) ? m.capabilities : String(m.capabilities || '').split(/[\s,]+/);
270
+ if (!caps.includes('chat') || typeof m.streamChat !== 'function')
271
+ continue;
272
+ if (!firstAny)
273
+ firstAny = m.path;
274
+ if ((m.aiActive ?? m.DATA?.aiActive) !== false)
275
+ return m.path;
276
+ }
277
+ }
278
+ return firstAny;
279
+ }
263
280
  async function findImageModel(config) {
264
281
  if (config.imageModel) {
265
282
  const m = await WORK.get_item(config.imageModel).catch(() => null);
@@ -530,7 +547,11 @@ export async function createEnv({ place, contextPath, session, host, tz, locatio
530
547
  return [stable, volatile].filter(Boolean).join('\n\n');
531
548
  },
532
549
  async defaultModel() {
533
- return config.model || DEFAULT_MODEL;
550
+ const candidate = config.model || DEFAULT_MODEL;
551
+ const item = await WORK.get_item(candidate).catch(() => null);
552
+ if (item)
553
+ return candidate;
554
+ return (await findFirstAvailableChatModel()) || candidate;
534
555
  },
535
556
  /** Память изменена инструментом memory — пересобрать блок на следующем ходе. */
536
557
  resetMemory() {