@futdevpro/nts-dynamo 1.15.89 → 1.15.90
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.c8rc.json +26 -26
- package/.copilot/patterns.json +7 -7
- package/.cursor/rules/__assistant_guide.mdc +30 -30
- package/.cursor/rules/_ag_backend-structure.mdc +85 -85
- package/.cursor/rules/_ag_backend.mdc +16 -16
- package/.cursor/rules/_ag_frontend-structure.mdc +86 -86
- package/.cursor/rules/_ag_frontend.mdc +39 -39
- package/.cursor/rules/_ag_import-rules.mdc +44 -44
- package/.cursor/rules/_ag_naming.mdc +115 -115
- package/.cursor/rules/_ag_should-be.mdc +6 -6
- package/.cursor/rules/ai_development_guide.md +60 -60
- package/.cursor/rules/cursor-rules.md +160 -160
- package/.cursor/rules/default-command.mdc +464 -464
- package/.cursor/rules/error_code_pattern.md +39 -39
- package/.cursor/rules/saved rule mcp server use.md +15 -15
- package/.dynamo/logs/cicd-pipeline/output.log +2816 -0
- package/.dynamo/logs/cicd-pipeline/status.json +94 -0
- package/.vscode/settings.json +10 -10
- package/HOWTO.md +15 -15
- package/LICENSE +21 -21
- package/__documentations/nts-integration-tests-2026-03-17.md +26 -26
- package/__documentations/plans/BEDROCK-HYPERPLAN.md +95 -95
- package/_specifications/BACKLOG.md +92 -92
- package/_specifications/TODO.md +15 -15
- package/_specifications/agent.md +138 -138
- package/build/_modules/scheduler/_models/scheduler-job.interface.d.ts +34 -0
- package/build/_modules/scheduler/_models/scheduler-job.interface.d.ts.map +1 -0
- package/build/_modules/scheduler/_models/scheduler-job.interface.js +3 -0
- package/build/_modules/scheduler/_models/scheduler-job.interface.js.map +1 -0
- package/build/_modules/scheduler/get-scheduler-routing-module.util.d.ts +18 -0
- package/build/_modules/scheduler/get-scheduler-routing-module.util.d.ts.map +1 -0
- package/build/_modules/scheduler/get-scheduler-routing-module.util.js +31 -0
- package/build/_modules/scheduler/get-scheduler-routing-module.util.js.map +1 -0
- package/build/_modules/scheduler/index.d.ts +5 -0
- package/build/_modules/scheduler/index.d.ts.map +1 -0
- package/build/_modules/scheduler/index.js +10 -0
- package/build/_modules/scheduler/index.js.map +1 -0
- package/build/_modules/scheduler/scheduler.controller.d.ts +25 -0
- package/build/_modules/scheduler/scheduler.controller.d.ts.map +1 -0
- package/build/_modules/scheduler/scheduler.controller.js +54 -0
- package/build/_modules/scheduler/scheduler.controller.js.map +1 -0
- package/build/_modules/scheduler/scheduler.service.d.ts +54 -0
- package/build/_modules/scheduler/scheduler.service.d.ts.map +1 -0
- package/build/_modules/scheduler/scheduler.service.js +164 -0
- package/build/_modules/scheduler/scheduler.service.js.map +1 -0
- package/eslint.config.js +3 -3
- package/nodemon.json +24 -24
- package/package.json +10 -1
- package/pnpm-workspace.yaml +5 -5
- package/scripts/run-coverage-tests.js +28 -28
- package/spec/support/helpers/spec-reporter-loader.js +359 -359
- package/spec/support/helpers/ts-node-helper.js +93 -93
- package/spec/support/jasmine.coverage.json +24 -24
- package/spec/support/jasmine.json +24 -24
- package/src/_collections/archive.util.spec.ts +57 -57
- package/src/_collections/archive.util.ts +18 -18
- package/src/_collections/atlas-default-db-options.const.ts +9 -9
- package/src/_collections/default-fallback-cache-max-age.const.spec.ts +11 -11
- package/src/_collections/default-fallback-cache-max-age.const.ts +2 -2
- package/src/_collections/default-not-found-page.const.spec.ts +19 -19
- package/src/_collections/default-not-found-page.const.ts +22 -22
- package/src/_collections/default-socket-path.const.spec.ts +12 -12
- package/src/_collections/default-socket-path.const.ts +2 -2
- package/src/_collections/get-environment-settings.util.spec.ts +210 -210
- package/src/_collections/get-environment-settings.util.ts +48 -48
- package/src/_collections/global-settings.const.ts +109 -109
- package/src/_collections/sample.env +21 -21
- package/src/_collections/star.controller.spec.ts +224 -224
- package/src/_collections/star.controller.ts +129 -129
- package/src/_enums/data-model-type.enum.ts +14 -14
- package/src/_enums/data-service-function.enum.ts +24 -24
- package/src/_enums/predefined-data-types.enum.ts +16 -16
- package/src/_enums/route-security.enum.ts +12 -12
- package/src/_models/control-models/api-call-params.control-model.spec.ts +152 -152
- package/src/_models/control-models/api-call-params.control-model.ts +142 -142
- package/src/_models/control-models/app-ext-system-controls.control-model.spec.ts +52 -52
- package/src/_models/control-models/app-ext-system-controls.control-model.ts +9 -9
- package/src/_models/control-models/app-params.control-model.spec.ts +225 -225
- package/src/_models/control-models/app-params.control-model.ts +136 -136
- package/src/_models/control-models/app-system-controls.control-model.spec.ts +31 -31
- package/src/_models/control-models/app-system-controls.control-model.ts +9 -9
- package/src/_models/control-models/endpoint-params.control-model.spec.ts +627 -627
- package/src/_models/control-models/endpoint-params.control-model.ts +627 -627
- package/src/_models/control-models/http-settings.control-model.spec.ts +77 -77
- package/src/_models/control-models/http-settings.control-model.ts +37 -37
- package/src/_models/control-models/system-control.control-model.spec.ts +27 -27
- package/src/_models/control-models/system-control.control-model.ts +12 -12
- package/src/_models/interfaces/certification-settings.interface.ts +7 -7
- package/src/_models/interfaces/environment-settings.interface.ts +59 -59
- package/src/_models/interfaces/global-log-settings.interface.ts +171 -171
- package/src/_models/interfaces/global-service-settings.interface.ts +47 -47
- package/src/_models/interfaces/global-settings.interface.ts +244 -244
- package/src/_models/interfaces/routing-module-settings.interface.ts +21 -21
- package/src/_models/interfaces/static-client-settings.interface.spec.ts +29 -29
- package/src/_models/interfaces/static-client-settings.interface.ts +28 -28
- package/src/_models/types/db-update.type.ts +100 -100
- package/src/_modules/ai/_models/ai-input-interfaces.ts +117 -117
- package/src/_modules/ai/_models/ai-test-generation-result.interface.ts +16 -16
- package/src/_modules/ai/_modules/anthropic/_services/aai-user-key.control-service.ts +138 -138
- package/src/_modules/ai/_modules/anthropic/index.ts +5 -5
- package/src/_modules/ai/_modules/document-ai/_collections/dai-chunking.util.spec.ts +242 -242
- package/src/_modules/ai/_modules/document-ai/_collections/dai-chunking.util.ts +639 -639
- package/src/_modules/ai/_modules/document-ai/_collections/dai-code-chunking.util.spec.ts +295 -295
- package/src/_modules/ai/_modules/document-ai/_collections/dai-code-chunking.util.ts +518 -518
- package/src/_modules/ai/_modules/document-ai/_collections/dai-document.util.spec.ts +209 -209
- package/src/_modules/ai/_modules/document-ai/_collections/dai-document.util.ts +85 -85
- package/src/_modules/ai/_modules/document-ai/_enums/dai-compare-result-type.enum.ts +7 -7
- package/src/_modules/ai/_modules/document-ai/_models/data-models/dai-doc-chunk.data-model.ts +146 -146
- package/src/_modules/ai/_modules/document-ai/_models/data-models/dai-doc-page.data-model.ts +162 -162
- package/src/_modules/ai/_modules/document-ai/_models/data-models/dai-document.data-model.ts +99 -99
- package/src/_modules/ai/_modules/document-ai/_models/interfaces/dai-code-chunk.interface.ts +68 -68
- package/src/_modules/ai/_modules/document-ai/_models/interfaces/dai-doc-chunk-compare-result.interface.ts +18 -18
- package/src/_modules/ai/_modules/document-ai/_models/interfaces/dai-doc-page-compare-result.interface.ts +19 -19
- package/src/_modules/ai/_modules/document-ai/_models/interfaces/dai-document-compare-result.interface.ts +25 -25
- package/src/_modules/ai/_modules/document-ai/index.ts +30 -30
- package/src/_modules/ai/_modules/fdp-ai/_services/fdpai-user-key.control-service.ts +189 -189
- package/src/_modules/ai/_modules/fdp-ai/index.ts +5 -5
- package/src/_modules/ai/_modules/open-ai/_collections/oai-global-settings.const.ts +9 -9
- package/src/_modules/ai/_modules/open-ai/_collections/oai-llm-predefined-requests-hu.conts.ts +82 -82
- package/src/_modules/ai/_modules/open-ai/_collections/oai-llm-predefined-requests.conts.ts +75 -75
- package/src/_modules/ai/_modules/open-ai/_enums/oai-gpt-message-role.enum.ts +45 -45
- package/src/_modules/ai/_modules/open-ai/_models/interfaces/oai-global-settings.interface.ts +7 -7
- package/src/_modules/ai/_modules/open-ai/_models/interfaces/oai-gpt-message.interface.ts +7 -7
- package/src/_modules/ai/_modules/open-ai/_models/interfaces/oai-llm-predefined-requests.interface.ts +57 -57
- package/src/_modules/ai/_modules/open-ai/_services/data-services/oai-doc-chunk-data.service.ts +292 -292
- package/src/_modules/ai/_modules/open-ai/_services/data-services/oai-document.data-service.spec.ts +342 -342
- package/src/_modules/ai/_modules/open-ai/_services/data-services/oai-vector-data.service.spec.ts +550 -550
- package/src/_modules/ai/_modules/open-ai/_services/data-services/oai-vector-data.service.ts +630 -630
- package/src/_modules/ai/_modules/open-ai/_services/oai-embedding.control-service.spec.ts +332 -332
- package/src/_modules/ai/_modules/open-ai/_services/oai-llm-chat.service-base.spec.ts +462 -462
- package/src/_modules/ai/_modules/open-ai/_services/oai-llm-chat.service-base.ts +634 -634
- package/src/_modules/ai/_modules/open-ai/_services/oai-llm.service-base.spec.ts +489 -489
- package/src/_modules/ai/_modules/open-ai/_services/oai-llm.service-base.tools.spec.ts +173 -173
- package/src/_modules/ai/_modules/open-ai/_services/oai-llm.service-base.ts +1033 -1033
- package/src/_modules/ai/_modules/open-ai/_services/oai-user-key.control-service.ts +157 -157
- package/src/_modules/ai/_services/ai-embedding-mock.service.spec.ts +115 -115
- package/src/_modules/ai/_services/ai-embedding-mock.service.ts +212 -212
- package/src/_modules/ai/_services/ai-embedding-provider.registry.spec.ts +110 -110
- package/src/_modules/ai/_services/ai-embedding-provider.registry.ts +110 -110
- package/src/_modules/ai/_services/ai-embedding.service-base.spec.ts +98 -98
- package/src/_modules/ai/_services/ai-embedding.service-base.ts +48 -48
- package/src/_modules/ai/_services/ai-llm-chat.service-base.spec.ts +229 -229
- package/src/_modules/ai/_services/ai-llm-chat.service-base.ts +68 -68
- package/src/_modules/ai/_services/ai-llm.service-base.spec.ts +250 -250
- package/src/_modules/ai/_services/ai-llm.service-base.ts +519 -519
- package/src/_modules/ai/_services/ai-provider.service-base.spec.ts +158 -158
- package/src/_modules/ai/_services/ai-user-key.service-base.ts +59 -59
- package/src/_modules/ai/_services/lmstudio-embedding.control-service.spec.ts +197 -197
- package/src/_modules/ai/_services/lmstudio-embedding.control-service.ts +371 -371
- package/src/_modules/ai/index.ts +23 -23
- package/src/_modules/assistant/_collections/ass-global-settings.const.ts +13 -13
- package/src/_modules/assistant/_collections/ass.util.spec.ts +176 -176
- package/src/_modules/assistant/_collections/ass.util.ts +50 -50
- package/src/_modules/assistant/_models/ass-global-settings.interface.ts +15 -15
- package/src/_modules/assistant/_services/ass-io.control-service.spec.ts +140 -140
- package/src/_modules/assistant/_services/ass-main.control-service.spec.ts +192 -192
- package/src/_modules/assistant/_services/ass-main.control-service.ts +107 -107
- package/src/_modules/bot/_collections/bot-default-commands.const.ts +12 -12
- package/src/_modules/bot/_collections/bot-global-settings.const.ts +39 -39
- package/src/_modules/bot/_models/bot-channel-wrapper.interface.ts +62 -62
- package/src/_modules/bot/_models/bot-command.interface.ts +8 -8
- package/src/_modules/bot/_models/bot-global-settings.interface.ts +96 -96
- package/src/_modules/bot/_models/bot-last-mention-date.interface.ts +6 -6
- package/src/_modules/bot/_models/bot-last-message-date.interface.ts +5 -5
- package/src/_modules/bot/_models/bot-user-wrapper.interface.ts +41 -41
- package/src/_modules/bot/_modules/discord-bot/_models/dib-platform.types.ts +9 -9
- package/src/_modules/bot/_modules/discord-bot/_services/dib-messaging-provider.control-service.spec.ts +431 -431
- package/src/_modules/bot/_modules/dynamo-bot/_collections/dyb-operations.util.spec.ts +160 -160
- package/src/_modules/bot/_modules/dynamo-bot/_collections/dyb-operations.util.ts +55 -55
- package/src/_modules/bot/_modules/dynamo-bot/_models/dyb-platform.types.ts +15 -15
- package/src/_modules/bot/_modules/dynamo-bot/_services/dyb-messaging-provider.control-service.spec.ts +374 -374
- package/src/_modules/bot/_modules/dynamo-bot/_services/dyb-messaging-provider.control-service.ts +447 -447
- package/src/_modules/bot/_modules/dynamo-bot/index.ts +15 -15
- package/src/_modules/bot/_modules/slack-bot/_models/slb-platform.types.ts +9 -9
- package/src/_modules/bot/_modules/slack-bot/_services/slb-messaging-provider.control-service.spec.ts +344 -344
- package/src/_modules/bot/_modules/slack-bot/_services/slb-messaging-provider.control-service.ts +197 -197
- package/src/_modules/bot/_modules/teams-bot/_models/teb-platform.types.ts +9 -9
- package/src/_modules/bot/_modules/teams-bot/_services/teb-messaging-provider.control-service.spec.ts +345 -345
- package/src/_modules/bot/_modules/teams-bot/_services/teb-messaging-provider.control-service.ts +197 -197
- package/src/_modules/bot/_services/bot-commands.control-service.spec.ts +116 -116
- package/src/_modules/bot/_services/bot-io.control-service.spec.ts +285 -285
- package/src/_modules/bot/_services/bot-main.control-service.spec.ts +208 -208
- package/src/_modules/bot/_services/bot-messaging-provider.service-base.spec.ts +349 -349
- package/src/_modules/bot/_services/bot-routines.control-service.spec.ts +111 -111
- package/src/_modules/custom-data/custom-data.controller.spec.ts +49 -49
- package/src/_modules/custom-data/custom-data.controller.ts +67 -67
- package/src/_modules/custom-data/custom-data.data-service.spec.ts +54 -54
- package/src/_modules/custom-data/custom-data.data-service.ts +21 -21
- package/src/_modules/custom-data/get-custom-data-routing-module.util.spec.ts +28 -28
- package/src/_modules/custom-data/get-custom-data-routing-module.util.ts +24 -24
- package/src/_modules/custom-data/index.ts +9 -9
- package/src/_modules/data-readers/_collections/dynts-sqlite-reader.util.spec.ts +161 -161
- package/src/_modules/data-readers/_collections/dynts-sqlite-reader.util.ts +203 -203
- package/src/_modules/data-readers/_models/interfaces/dynts-sqlite-reader.interface.ts +33 -33
- package/src/_modules/data-readers/index.ts +11 -11
- package/src/_modules/defaults/_collections/default-endpoints.util.ts +487 -487
- package/src/_modules/defaults/_models/default-user.data-model.ts +72 -72
- package/src/_modules/defaults/_services/default-auth.service.spec.ts +269 -269
- package/src/_modules/defaults/_services/default-auth.service.ts +177 -177
- package/src/_modules/defaults/_services/default-socket-events.service.spec.ts +42 -42
- package/src/_modules/defaults/_services/default-socket-events.service.ts +61 -61
- package/src/_modules/defaults/_services/default-user.data-service.spec.ts +187 -187
- package/src/_modules/defaults/_services/default-user.data-service.ts +98 -98
- package/src/_modules/defaults/index.ts +17 -17
- package/src/_modules/discord-assistant/_collections/dias-global-settings.const.ts +19 -19
- package/src/_modules/discord-assistant/_collections/dias.util.spec.ts +366 -366
- package/src/_modules/discord-assistant/_collections/dias.util.ts +132 -132
- package/src/_modules/discord-assistant/_models/dias-global-settings.interface.ts +19 -19
- package/src/_modules/discord-assistant/_models/dias-knowledge.data-model.ts +52 -52
- package/src/_modules/discord-assistant/_services/dias-chunk.data-service.ts +177 -177
- package/src/_modules/discord-assistant/_services/dias-io.control-service.spec.ts +108 -108
- package/src/_modules/discord-assistant/_services/dias-io.control-service.ts +69 -69
- package/src/_modules/discord-assistant/_services/dias-main.control-service.spec.ts +22 -22
- package/src/_modules/discord-assistant/_services/dias-main.control-service.ts +27 -27
- package/src/_modules/discord-assistant/_services/dias.service-base.spec.ts +195 -195
- package/src/_modules/discord-assistant/_services/dias.service-base.ts +76 -76
- package/src/_modules/discord-assistant/index.ts +38 -38
- package/src/_modules/discord-assistant-voiced/_services/dias-discord-bot.control-service.spec.ts +34 -34
- package/src/_modules/discord-assistant-voiced/_services/dias-discord-bot.control-service.ts +11 -11
- package/src/_modules/discord-assistant-voiced/index.ts +36 -36
- package/src/_modules/discord-bot/_collections/dibo-default-commands.const.ts +16 -16
- package/src/_modules/discord-bot/_collections/dibo-global-settings.conts.ts +55 -55
- package/src/_modules/discord-bot/_collections/dibo-operations.util.spec.ts +214 -214
- package/src/_modules/discord-bot/_collections/dibo-operations.util.ts +387 -387
- package/src/_modules/discord-bot/_models/dibo-command.interface.ts +12 -12
- package/src/_modules/discord-bot/_models/dibo-global-settings.interface.ts +98 -98
- package/src/_modules/discord-bot/_models/dibo-last-mention-date.inteface.ts +7 -7
- package/src/_modules/discord-bot/_models/dibo-last-message-date.interface.ts +6 -6
- package/src/_modules/discord-bot/_services/dibo-commands.control-service.spec.ts +154 -154
- package/src/_modules/discord-bot/_services/dibo-commands.control-service.ts +153 -153
- package/src/_modules/discord-bot/_services/dibo-io.control-service.spec.ts +264 -264
- package/src/_modules/discord-bot/_services/dibo-io.control-service.ts +306 -306
- package/src/_modules/discord-bot/_services/dibo-main.control-service.spec.ts +408 -408
- package/src/_modules/discord-bot/_services/dibo-main.control-service.ts +487 -487
- package/src/_modules/discord-bot/_services/dibo-routines.control-service.spec.ts +105 -105
- package/src/_modules/discord-bot/index.ts +36 -36
- package/src/_modules/local-vector-search/_enums/lvs-search-mode.enum.ts +35 -35
- package/src/_modules/local-vector-search/_models/data-models/lvs-vector-persist.data-model.ts +59 -59
- package/src/_modules/local-vector-search/_models/lvs-search-result.interface.ts +17 -17
- package/src/_modules/local-vector-search/_services/lvs-doc-chunk-data.service.spec.ts +418 -418
- package/src/_modules/local-vector-search/_services/lvs-doc-chunk-data.service.ts +276 -276
- package/src/_modules/local-vector-search/_services/lvs-local-vector-search.data-service.spec.ts +480 -480
- package/src/_modules/local-vector-search/_services/lvs-local-vector-search.data-service.ts +416 -416
- package/src/_modules/local-vector-search/_services/lvs-persistent-vector-pool.control-service.spec.ts +198 -198
- package/src/_modules/local-vector-search/_services/lvs-persistent-vector-pool.control-service.ts +146 -146
- package/src/_modules/local-vector-search/_services/lvs-vector-persist.data-service.spec.ts +167 -167
- package/src/_modules/local-vector-search/_services/lvs-vector-persist.data-service.ts +106 -106
- package/src/_modules/local-vector-search/_services/lvs-vector-pool.control-service.spec.ts +507 -507
- package/src/_modules/local-vector-search/_services/lvs-vector-pool.control-service.ts +272 -272
- package/src/_modules/local-vector-search/index.ts +16 -16
- package/src/_modules/logs/index.ts +11 -11
- package/src/_modules/mcp/_models/interfaces/dynts-mcp.interface.ts +111 -111
- package/src/_modules/mcp/_services/dynts-mcp-server.service-base.spec.ts +142 -142
- package/src/_modules/mcp/_services/dynts-mcp-server.service-base.ts +120 -120
- package/src/_modules/mcp/_services/dynts-mcp.adapter.ts +168 -168
- package/src/_modules/mcp/index.ts +13 -13
- package/src/_modules/messaging/README.md +354 -354
- package/src/_modules/messaging/_collections/get-messaging-routing-module.util.ts +26 -26
- package/src/_modules/messaging/_collections/msg-global-settings.const.ts +22 -22
- package/src/_modules/messaging/_collections/msg.util.spec.ts +226 -226
- package/src/_modules/messaging/_models/msg-global-settings.interface.ts +37 -37
- package/src/_modules/messaging/_services/msg-conversation.data-service.ts +146 -146
- package/src/_modules/messaging/_services/msg-events.service.spec.ts +219 -219
- package/src/_modules/messaging/_services/msg-events.service.ts +267 -267
- package/src/_modules/messaging/_services/msg-integration.control-service.ts +179 -179
- package/src/_modules/messaging/_services/msg-main.control-service.spec.ts +147 -147
- package/src/_modules/messaging/_services/msg-main.control-service.ts +571 -571
- package/src/_modules/messaging/_services/msg-message.data-service.ts +129 -129
- package/src/_modules/messaging/_services/msg.controller.spec.ts +201 -201
- package/src/_modules/messaging/index.ts +30 -30
- package/src/_modules/mock/app-extended-server.mock.ts +201 -201
- package/src/_modules/mock/app-integration-test.mock.ts +51 -51
- package/src/_modules/mock/app-params.mock.spec.ts +21 -21
- package/src/_modules/mock/app-params.mock.ts +9 -9
- package/src/_modules/mock/app-server.mock.ts +188 -188
- package/src/_modules/mock/auth-service.mock.spec.ts +47 -47
- package/src/_modules/mock/auth-service.mock.ts +28 -28
- package/src/_modules/mock/controller.mock.spec.ts +26 -26
- package/src/_modules/mock/controller.mock.ts +16 -16
- package/src/_modules/mock/data-model.mock.spec.ts +111 -111
- package/src/_modules/mock/data-model.mock.ts +82 -82
- package/src/_modules/mock/email-service-collection.mock.spec.ts +24 -24
- package/src/_modules/mock/email-service-collection.mock.ts +15 -15
- package/src/_modules/mock/email-service.mock.spec.ts +17 -17
- package/src/_modules/mock/email-service.mock.ts +20 -20
- package/src/_modules/mock/email-template.mock.html +14 -14
- package/src/_modules/mock/endpoint.mock.ts +91 -91
- package/src/_modules/mock/socket-client.mock.spec.ts +40 -40
- package/src/_modules/mock/socket-client.mock.ts +45 -45
- package/src/_modules/mock/socket-server.mock.spec.ts +44 -44
- package/src/_modules/mock/socket-server.mock.ts +46 -46
- package/src/_modules/oauth2/_routes/oauth2.controller.spec.ts +107 -107
- package/src/_modules/oauth2/_routes/oauth2.controller.ts +98 -98
- package/src/_modules/oauth2/_services/oauth2.auth-service.spec.ts +254 -254
- package/src/_modules/oauth2/_services/oauth2.auth-service.ts +232 -232
- package/src/_modules/oauth2/_services/oauth2.control-service.spec.ts +585 -585
- package/src/_modules/oauth2/_services/oauth2.control-service.ts +653 -653
- package/src/_modules/oauth2/index.ts +17 -17
- package/src/_modules/scheduler/_models/scheduler-job.interface.ts +35 -0
- package/src/_modules/scheduler/get-scheduler-routing-module.util.ts +33 -0
- package/src/_modules/scheduler/index.ts +8 -0
- package/src/_modules/scheduler/scheduler.controller.spec.ts +42 -0
- package/src/_modules/scheduler/scheduler.controller.ts +69 -0
- package/src/_modules/scheduler/scheduler.service.spec.ts +141 -0
- package/src/_modules/scheduler/scheduler.service.ts +176 -0
- package/src/_modules/scoped-config/_enums/dynts-scoped-config-level.enum.ts +22 -22
- package/src/_modules/scoped-config/_models/data-models/dynts-scoped-config.data-model.ts +81 -81
- package/src/_modules/scoped-config/_models/interfaces/dynts-scoped-config.interface.ts +107 -107
- package/src/_modules/scoped-config/_services/dynts-scoped-config.control-service.spec.ts +306 -306
- package/src/_modules/scoped-config/_services/dynts-scoped-config.control-service.ts +295 -295
- package/src/_modules/scoped-config/_services/dynts-scoped-config.data-service.spec.ts +118 -118
- package/src/_modules/scoped-config/_services/dynts-scoped-config.data-service.ts +105 -105
- package/src/_modules/scoped-config/index.ts +17 -17
- package/src/_modules/server/errors/errors.control-service.spec.ts +238 -238
- package/src/_modules/server/errors/errors.control-service.ts +100 -100
- package/src/_modules/server/errors/errors.controller.spec.ts +268 -268
- package/src/_modules/server/errors/errors.controller.ts +515 -515
- package/src/_modules/server/errors/errors.data-service.spec.ts +480 -480
- package/src/_modules/server/index.ts +30 -30
- package/src/_modules/server/server-status/server-status-snapshot.control-service.spec.ts +70 -70
- package/src/_modules/server/server-status/server-status-snapshot.control-service.ts +17 -17
- package/src/_modules/server/server-status/server-status-snapshot.data-service.spec.ts +77 -77
- package/src/_modules/server/server-status/server-status-snapshot.data-service.ts +37 -37
- package/src/_modules/server/server-status/server-status.control-service.spec.ts +576 -576
- package/src/_modules/server/server-status/server-status.control-service.ts +396 -396
- package/src/_modules/server/server-status/server-status.controller.spec.ts +255 -255
- package/src/_modules/server/server-status/server-status.controller.ts +272 -272
- package/src/_modules/socket/_enums/socket-security.enum.ts +11 -11
- package/src/_modules/socket/_models/socket-client-service-params.control-model.spec.ts +32 -32
- package/src/_modules/socket/_models/socket-client-service-params.control-model.ts +22 -22
- package/src/_modules/socket/_models/socket-presence.control-model.spec.ts +164 -164
- package/src/_modules/socket/_models/socket-presence.control-model.ts +210 -210
- package/src/_modules/socket/_models/socket-server-service-params.control-model.spec.ts +46 -46
- package/src/_modules/socket/_models/socket-server-service-params.control-model.ts +22 -22
- package/src/_modules/socket/_services/socket-client.service.spec.ts +15 -15
- package/src/_modules/socket/_services/socket-client.service.ts +260 -260
- package/src/_modules/socket/_services/socket-server.service.spec.ts +11 -11
- package/src/_modules/socket/app-extended.integration.spec.ts +85 -85
- package/src/_modules/socket/app-extended.server.ts +630 -630
- package/src/_modules/socket/index.ts +42 -42
- package/src/_modules/test/get-test-routing-module.util.spec.ts +28 -28
- package/src/_modules/test/get-test-routing-module.util.ts +23 -23
- package/src/_modules/test/index.ts +11 -11
- package/src/_modules/test/test.controller.spec.ts +72 -72
- package/src/_modules/test/test.controller.ts +115 -115
- package/src/_modules/usage/get-usage-routing-module.util.ts +22 -22
- package/src/_modules/usage/index.ts +15 -15
- package/src/_modules/usage/usage.controller.spec.ts +81 -81
- package/src/_modules/usage/usage.controller.ts +126 -126
- package/src/_modules/usage/usage.data-service.spec.ts +332 -332
- package/src/_modules/usage/usage.data-service.ts +185 -185
- package/src/_services/base/api.service-base.spec.ts +125 -125
- package/src/_services/base/api.service-base.ts +74 -74
- package/src/_services/base/archive-data.service.spec.ts +209 -209
- package/src/_services/base/archive-data.service.ts +224 -224
- package/src/_services/base/data.service.spec.ts +729 -729
- package/src/_services/base/data.service.ts +2740 -2740
- package/src/_services/base/db.service.spec.ts +73 -73
- package/src/_services/base/db.service.ts +1575 -1575
- package/src/_services/base/singleton.service-base.spec.ts +28 -28
- package/src/_services/base/singleton.service-base.ts +24 -24
- package/src/_services/base/singleton.service.spec.ts +114 -114
- package/src/_services/base/singleton.service.ts +38 -38
- package/src/_services/core/api.service.spec.ts +140 -140
- package/src/_services/core/auth.service.spec.ts +159 -159
- package/src/_services/core/auth.service.ts +174 -174
- package/src/_services/core/email.service.spec.ts +85 -85
- package/src/_services/core/email.service.ts +742 -742
- package/src/_services/core/global.service.spec.ts +292 -292
- package/src/_services/core/global.service.ts +487 -487
- package/src/_services/core/memory-guard.service.spec.ts +245 -245
- package/src/_services/core/memory-guard.service.ts +481 -481
- package/src/_services/core/service-collection.service.spec.ts +46 -46
- package/src/_services/core/service-collection.service.ts +6 -6
- package/src/_services/route/controller.service.spec.ts +53 -53
- package/src/_services/route/controller.service.ts +148 -148
- package/src/_services/route/routing-module.service.spec.ts +98 -98
- package/src/_services/route/routing-module.service.ts +330 -330
- package/src/_services/server/app.server.ts +1941 -1941
- package/src/_services/shared.static-service.spec.ts +99 -99
- package/src/_services/shared.static-service.ts +78 -78
- package/src/index.ts +97 -97
- package/tsconfig.app.json +12 -12
- package/tsconfig.json +42 -42
|
@@ -6,394 +6,394 @@ import { DyFM_DAI_EmbeddingInfo } from '@futdevpro/fsm-dynamo/ai/document-ai';
|
|
|
6
6
|
|
|
7
7
|
import { DyNTS_AI_CostEventCallback } from '../_models/interfaces/dynts-ai-cost-event-callback.interface';
|
|
8
8
|
import { DyNTS_global_settings } from '../../../_collections/global-settings.const';
|
|
9
|
-
import { DyNTS_AI_Embedding_ServiceBase } from './ai-embedding.service-base';
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* Az LM Studio embedding control-service config-set-je. A `baseUrl` az OpenAI-kompatibilis
|
|
13
|
-
* lokális endpoint (pl. `http://localhost:1234/v1`), az `apiKey` opcionális (LM Studio default-
|
|
14
|
-
* ban nem kér Bearer-t). Az `onCostEvent` a per-call cost-event sink (FR-002, BFR-AM-007).
|
|
15
|
-
*/
|
|
16
|
-
export interface DyNTS_LMStudio_Embedding_Settings {
|
|
17
|
-
/** OpenAI-kompatibilis lokális embedding-endpoint base URL-je (pl. `http://localhost:1234/v1`). */
|
|
18
|
-
baseUrl: string;
|
|
19
|
-
/** Opcionális Bearer token (LM Studio default-ban nem kér). */
|
|
20
|
-
apiKey?: string;
|
|
21
|
-
/** Per-call cost-event callback (FR-002 / BFR-AM-007). Non-breaking: ha undefined, nincs emit. */
|
|
22
|
-
onCostEvent?: DyNTS_AI_CostEventCallback;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
/**
|
|
26
|
-
* `DyNTS_LMStudio_Embedding_ControlService` (BFR-AM-002) — OpenAI-kompatibilis **lokális** embedding
|
|
27
|
-
* adapter `fetch`-en (Node 20 global `fetch`, így a Dynamo NEM hoz be provider-specifikus SDK-t a
|
|
28
|
-
* lokális path-hoz). A FAM `FAM_LMStudio_EmbeddingProvider` workaround-ját emeli bedrock-szintre.
|
|
29
|
-
*
|
|
30
|
-
* A `baseUrl` + `modelId` config-ot a constructor-on kapja (mint a `DyNTS_OAI_Embedding_ControlService`
|
|
31
|
-
* a `DyFM_OAI_Settings`-et). A `${baseUrl}/embeddings` POST-ra a `{ model, input }` body-t küldi, a
|
|
32
|
-
* `data[].embedding` sorrendje == a `texts` sorrendje.
|
|
33
|
-
*
|
|
34
|
-
* **Cost-event (BFR-AM-007):** minden sikeres call után `emitCostEvent`-tel jelez (callType
|
|
35
|
-
* `embedding-single` / `embedding-batch`, provider `'lm-studio'`). Lokális futás → nincs USD-költség,
|
|
36
|
-
* a token-fogyasztás a `usage`-ből (ha az endpoint adja), különben becsült (4 char ≈ 1 token).
|
|
37
|
-
*/
|
|
38
|
-
export class DyNTS_LMStudio_Embedding_ControlService extends DyNTS_AI_Embedding_ServiceBase {
|
|
39
|
-
|
|
40
|
-
/** A provider-azonosító a `LocalAI` enum-érték (LM Studio = lokális OpenAI-kompatibilis endpoint). */
|
|
41
|
-
readonly aiProvider: DyFM_AI_Provider = DyFM_AI_Provider.LocalAI;
|
|
42
|
-
|
|
43
|
-
/** A cost-event provider-string (a `DyNTS_AI_CostEvent.provider` szabad-string mezőjéhez). */
|
|
44
|
-
protected readonly costProvider: string = 'lm-studio';
|
|
45
|
-
|
|
46
|
-
/** LM Studio (OpenAI-kompatibilis lokális) capability-k: csak embedding-et igénylünk innen. */
|
|
47
|
-
readonly capabilities: DyFM_AI_ProviderCapabilities = {
|
|
48
|
-
chat: false,
|
|
49
|
-
embeddings: true,
|
|
50
|
-
imageGeneration: false,
|
|
51
|
-
vision: false,
|
|
52
|
-
audioGeneration: false,
|
|
53
|
-
audioAnalysis: false,
|
|
54
|
-
functionCalling: false,
|
|
55
|
-
streaming: false,
|
|
56
|
-
batchOperations: true,
|
|
57
|
-
supportedModelTypes: [],
|
|
58
|
-
};
|
|
59
|
-
|
|
60
|
-
/** Az OpenAI-kompatibilis endpoint base URL-je (trailing slash-mentes). */
|
|
61
|
-
protected baseUrl: string;
|
|
62
|
-
|
|
63
|
-
/** Opcionális Bearer token. */
|
|
64
|
-
protected apiKey?: string;
|
|
65
|
-
|
|
66
|
-
/**
|
|
67
|
-
* @param set baseUrl + opc. apiKey + opc. onCostEvent. A `baseUrl` kötelező — ha üres, a
|
|
68
|
-
* `DyNTS-LMS-ECS-CFG` hibát dobjuk (lokális endpoint nincs konfigurálva).
|
|
69
|
-
*/
|
|
70
|
-
constructor(set: DyNTS_LMStudio_Embedding_Settings) {
|
|
9
|
+
import { DyNTS_AI_Embedding_ServiceBase } from './ai-embedding.service-base';
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Az LM Studio embedding control-service config-set-je. A `baseUrl` az OpenAI-kompatibilis
|
|
13
|
+
* lokális endpoint (pl. `http://localhost:1234/v1`), az `apiKey` opcionális (LM Studio default-
|
|
14
|
+
* ban nem kér Bearer-t). Az `onCostEvent` a per-call cost-event sink (FR-002, BFR-AM-007).
|
|
15
|
+
*/
|
|
16
|
+
export interface DyNTS_LMStudio_Embedding_Settings {
|
|
17
|
+
/** OpenAI-kompatibilis lokális embedding-endpoint base URL-je (pl. `http://localhost:1234/v1`). */
|
|
18
|
+
baseUrl: string;
|
|
19
|
+
/** Opcionális Bearer token (LM Studio default-ban nem kér). */
|
|
20
|
+
apiKey?: string;
|
|
21
|
+
/** Per-call cost-event callback (FR-002 / BFR-AM-007). Non-breaking: ha undefined, nincs emit. */
|
|
22
|
+
onCostEvent?: DyNTS_AI_CostEventCallback;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* `DyNTS_LMStudio_Embedding_ControlService` (BFR-AM-002) — OpenAI-kompatibilis **lokális** embedding
|
|
27
|
+
* adapter `fetch`-en (Node 20 global `fetch`, így a Dynamo NEM hoz be provider-specifikus SDK-t a
|
|
28
|
+
* lokális path-hoz). A FAM `FAM_LMStudio_EmbeddingProvider` workaround-ját emeli bedrock-szintre.
|
|
29
|
+
*
|
|
30
|
+
* A `baseUrl` + `modelId` config-ot a constructor-on kapja (mint a `DyNTS_OAI_Embedding_ControlService`
|
|
31
|
+
* a `DyFM_OAI_Settings`-et). A `${baseUrl}/embeddings` POST-ra a `{ model, input }` body-t küldi, a
|
|
32
|
+
* `data[].embedding` sorrendje == a `texts` sorrendje.
|
|
33
|
+
*
|
|
34
|
+
* **Cost-event (BFR-AM-007):** minden sikeres call után `emitCostEvent`-tel jelez (callType
|
|
35
|
+
* `embedding-single` / `embedding-batch`, provider `'lm-studio'`). Lokális futás → nincs USD-költség,
|
|
36
|
+
* a token-fogyasztás a `usage`-ből (ha az endpoint adja), különben becsült (4 char ≈ 1 token).
|
|
37
|
+
*/
|
|
38
|
+
export class DyNTS_LMStudio_Embedding_ControlService extends DyNTS_AI_Embedding_ServiceBase {
|
|
39
|
+
|
|
40
|
+
/** A provider-azonosító a `LocalAI` enum-érték (LM Studio = lokális OpenAI-kompatibilis endpoint). */
|
|
41
|
+
readonly aiProvider: DyFM_AI_Provider = DyFM_AI_Provider.LocalAI;
|
|
42
|
+
|
|
43
|
+
/** A cost-event provider-string (a `DyNTS_AI_CostEvent.provider` szabad-string mezőjéhez). */
|
|
44
|
+
protected readonly costProvider: string = 'lm-studio';
|
|
45
|
+
|
|
46
|
+
/** LM Studio (OpenAI-kompatibilis lokális) capability-k: csak embedding-et igénylünk innen. */
|
|
47
|
+
readonly capabilities: DyFM_AI_ProviderCapabilities = {
|
|
48
|
+
chat: false,
|
|
49
|
+
embeddings: true,
|
|
50
|
+
imageGeneration: false,
|
|
51
|
+
vision: false,
|
|
52
|
+
audioGeneration: false,
|
|
53
|
+
audioAnalysis: false,
|
|
54
|
+
functionCalling: false,
|
|
55
|
+
streaming: false,
|
|
56
|
+
batchOperations: true,
|
|
57
|
+
supportedModelTypes: [],
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
/** Az OpenAI-kompatibilis endpoint base URL-je (trailing slash-mentes). */
|
|
61
|
+
protected baseUrl: string;
|
|
62
|
+
|
|
63
|
+
/** Opcionális Bearer token. */
|
|
64
|
+
protected apiKey?: string;
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* @param set baseUrl + opc. apiKey + opc. onCostEvent. A `baseUrl` kötelező — ha üres, a
|
|
68
|
+
* `DyNTS-LMS-ECS-CFG` hibát dobjuk (lokális endpoint nincs konfigurálva).
|
|
69
|
+
*/
|
|
70
|
+
constructor(set: DyNTS_LMStudio_Embedding_Settings) {
|
|
71
71
|
super();
|
|
72
|
-
|
|
73
|
-
if (!set?.baseUrl?.trim().length) {
|
|
74
|
-
throw new DyFM_Error({
|
|
75
|
-
...this.getDefaultErrorSettings(
|
|
76
|
-
'constructor',
|
|
77
|
-
new Error('LM Studio baseUrl is required (OpenAI-compatible local endpoint)'),
|
|
78
|
-
'DyNTS_LMStudio_Embedding_ControlService',
|
|
79
|
-
),
|
|
80
|
-
errorCode: `${DyNTS_global_settings.systemShortCodeName}|DyNTS-LMS-ECS-CFG`,
|
|
81
|
-
});
|
|
82
|
-
}
|
|
83
|
-
this.baseUrl = this.trimTrailingSlashes(set.baseUrl.trim());
|
|
72
|
+
|
|
73
|
+
if (!set?.baseUrl?.trim().length) {
|
|
74
|
+
throw new DyFM_Error({
|
|
75
|
+
...this.getDefaultErrorSettings(
|
|
76
|
+
'constructor',
|
|
77
|
+
new Error('LM Studio baseUrl is required (OpenAI-compatible local endpoint)'),
|
|
78
|
+
'DyNTS_LMStudio_Embedding_ControlService',
|
|
79
|
+
),
|
|
80
|
+
errorCode: `${DyNTS_global_settings.systemShortCodeName}|DyNTS-LMS-ECS-CFG`,
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
this.baseUrl = this.trimTrailingSlashes(set.baseUrl.trim());
|
|
84
84
|
this.apiKey = set.apiKey;
|
|
85
|
-
|
|
86
|
-
if (set.onCostEvent) {
|
|
87
|
-
this.onCostEvent = set.onCostEvent;
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
/**
|
|
92
|
-
* Az LM Studio client-et nem SDK-val, hanem `fetch`-csel hívjuk; a `setup` a `baseUrl` (és
|
|
93
|
-
* opcionálisan az `apiKey`) átkonfigurálását teszi lehetővé (a base-szerződés egységessége miatt).
|
|
94
|
-
*/
|
|
95
|
-
setup(config: DyFM_AI_Config): void {
|
|
96
|
-
if (config?.baseURL) {
|
|
97
|
-
this.baseUrl = this.trimTrailingSlashes(config.baseURL);
|
|
85
|
+
|
|
86
|
+
if (set.onCostEvent) {
|
|
87
|
+
this.onCostEvent = set.onCostEvent;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Az LM Studio client-et nem SDK-val, hanem `fetch`-csel hívjuk; a `setup` a `baseUrl` (és
|
|
93
|
+
* opcionálisan az `apiKey`) átkonfigurálását teszi lehetővé (a base-szerződés egységessége miatt).
|
|
94
|
+
*/
|
|
95
|
+
setup(config: DyFM_AI_Config): void {
|
|
96
|
+
if (config?.baseURL) {
|
|
97
|
+
this.baseUrl = this.trimTrailingSlashes(config.baseURL);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
if (config?.apiKey) {
|
|
101
|
+
this.apiKey = config.apiKey;
|
|
98
102
|
}
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
throw new DyFM_Error({
|
|
120
|
-
...this.getDefaultErrorSettings('createEmbedding', new Error('text is required'), set.issuer),
|
|
121
|
-
errorCode: `${DyNTS_global_settings.systemShortCodeName}|DyNTS-LMS-ECS-CE1`,
|
|
122
|
-
});
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
const start: number = Date.now();
|
|
126
|
-
const response: CreateEmbeddingResponse = await this.callEmbeddingsEndpoint(set.model, set.text, set.issuer);
|
|
127
|
-
const durationMs: number = Date.now() - start;
|
|
128
|
-
|
|
129
|
-
this.emitLmStudioCostEvent('embedding-single', set.model, [ set.text ], response, durationMs, set.issuer);
|
|
130
|
-
|
|
131
|
-
if (set.fullResponse) {
|
|
132
|
-
return response;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Egy-szöveg embedding (a `createEmbeddings` egyelemű alakja). `fullResponse=true` esetén a
|
|
107
|
+
* teljes (OpenAI-alakú) válasz-objektumot adja vissza, különben a tiszta `number[]`-t.
|
|
108
|
+
*/
|
|
109
|
+
async createEmbedding(
|
|
110
|
+
set: {
|
|
111
|
+
text: string;
|
|
112
|
+
model: string;
|
|
113
|
+
fullResponse?: boolean;
|
|
114
|
+
issuer: string;
|
|
115
|
+
}
|
|
116
|
+
): Promise<number[] | CreateEmbeddingResponse> {
|
|
117
|
+
try {
|
|
118
|
+
if (!set.text) {
|
|
119
|
+
throw new DyFM_Error({
|
|
120
|
+
...this.getDefaultErrorSettings('createEmbedding', new Error('text is required'), set.issuer),
|
|
121
|
+
errorCode: `${DyNTS_global_settings.systemShortCodeName}|DyNTS-LMS-ECS-CE1`,
|
|
122
|
+
});
|
|
133
123
|
}
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
124
|
+
|
|
125
|
+
const start: number = Date.now();
|
|
126
|
+
const response: CreateEmbeddingResponse = await this.callEmbeddingsEndpoint(set.model, set.text, set.issuer);
|
|
127
|
+
const durationMs: number = Date.now() - start;
|
|
128
|
+
|
|
129
|
+
this.emitLmStudioCostEvent('embedding-single', set.model, [ set.text ], response, durationMs, set.issuer);
|
|
130
|
+
|
|
131
|
+
if (set.fullResponse) {
|
|
132
|
+
return response;
|
|
139
133
|
}
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
134
|
+
|
|
135
|
+
return response.data[0].embedding;
|
|
136
|
+
} catch (error) {
|
|
137
|
+
if (error instanceof DyFM_Error) {
|
|
138
|
+
throw error;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
throw new DyFM_Error({
|
|
142
|
+
...this.getDefaultErrorSettings('createEmbedding', error, set.issuer),
|
|
143
|
+
errorCode: `${DyNTS_global_settings.systemShortCodeName}|DyNTS-LMS-ECS-CE0`,
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* Batch-embedding az OpenAI-kompatibilis `/embeddings` végpontra. A `texts` sorrendje == a
|
|
150
|
+
* visszaadott `number[][]` sorrendje. `fullResponse=true` esetén a teljes válasz-objektum.
|
|
151
|
+
*/
|
|
152
|
+
async createEmbeddings(
|
|
153
|
+
set: {
|
|
154
|
+
texts: string[];
|
|
155
|
+
model: string;
|
|
156
|
+
fullResponse?: boolean;
|
|
157
|
+
issuer: string;
|
|
158
|
+
}
|
|
159
|
+
): Promise<number[][] | CreateEmbeddingResponse> {
|
|
160
|
+
try {
|
|
161
|
+
if (!set.texts) {
|
|
162
|
+
throw new DyFM_Error({
|
|
163
|
+
...this.getDefaultErrorSettings('createEmbeddings', new Error('texts is required'), set.issuer),
|
|
164
|
+
errorCode: `${DyNTS_global_settings.systemShortCodeName}|DyNTS-LMS-ECS-CES1`,
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
const start: number = Date.now();
|
|
169
|
+
const response: CreateEmbeddingResponse = await this.callEmbeddingsEndpoint(set.model, set.texts, set.issuer);
|
|
170
|
+
const durationMs: number = Date.now() - start;
|
|
171
|
+
|
|
172
|
+
this.emitLmStudioCostEvent('embedding-batch', set.model, set.texts, response, durationMs, set.issuer);
|
|
173
|
+
|
|
174
|
+
if (set.fullResponse) {
|
|
175
|
+
return response;
|
|
176
176
|
}
|
|
177
|
-
|
|
178
|
-
return response.data.map((item) => item.embedding);
|
|
179
|
-
} catch (error) {
|
|
180
|
-
if (error instanceof DyFM_Error) {
|
|
181
|
-
throw error;
|
|
177
|
+
|
|
178
|
+
return response.data.map((item) => item.embedding);
|
|
179
|
+
} catch (error) {
|
|
180
|
+
if (error instanceof DyFM_Error) {
|
|
181
|
+
throw error;
|
|
182
182
|
}
|
|
183
|
-
|
|
184
|
-
throw new DyFM_Error({
|
|
185
|
-
...this.getDefaultErrorSettings('createEmbeddings', error, set.issuer),
|
|
186
|
-
errorCode: `${DyNTS_global_settings.systemShortCodeName}|DyNTS-LMS-ECS-CES0`,
|
|
187
|
-
});
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
/**
|
|
192
|
-
* Embedding model-info (a `DyFM_DAI_EmbeddingInfo` szerződés szerint). A provider `LocalAI`, a
|
|
193
|
-
* model a megadott azonosító (a lokális endpoint natív dimenzióját nem ismerjük előre).
|
|
194
|
-
*/
|
|
195
|
-
getEmbeddingInfo(model: string): DyFM_DAI_EmbeddingInfo {
|
|
196
|
-
return {
|
|
197
|
-
provider: DyFM_AI_Provider.LocalAI,
|
|
198
|
-
model: model,
|
|
199
|
-
};
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
/**
|
|
203
|
-
* Provider-elérhetőség: egy minimál embedding-próba (rövid token). Ha a hívás dob (endpoint down /
|
|
204
|
-
* model hiányzik), `false`. Soha nem propagál hibát (try/catch → false).
|
|
205
|
-
*/
|
|
206
|
-
async testConnection(issuer: string): Promise<boolean> {
|
|
207
|
-
try {
|
|
208
|
-
const vectors: number[][] | CreateEmbeddingResponse = await this.createEmbeddings({
|
|
209
|
-
texts: [ 'ping' ],
|
|
210
|
-
model: this.defaultProbeModel(),
|
|
211
|
-
fullResponse: false,
|
|
212
|
-
issuer: issuer,
|
|
183
|
+
|
|
184
|
+
throw new DyFM_Error({
|
|
185
|
+
...this.getDefaultErrorSettings('createEmbeddings', error, set.issuer),
|
|
186
|
+
errorCode: `${DyNTS_global_settings.systemShortCodeName}|DyNTS-LMS-ECS-CES0`,
|
|
187
|
+
});
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
/**
|
|
192
|
+
* Embedding model-info (a `DyFM_DAI_EmbeddingInfo` szerződés szerint). A provider `LocalAI`, a
|
|
193
|
+
* model a megadott azonosító (a lokális endpoint natív dimenzióját nem ismerjük előre).
|
|
194
|
+
*/
|
|
195
|
+
getEmbeddingInfo(model: string): DyFM_DAI_EmbeddingInfo {
|
|
196
|
+
return {
|
|
197
|
+
provider: DyFM_AI_Provider.LocalAI,
|
|
198
|
+
model: model,
|
|
199
|
+
};
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
/**
|
|
203
|
+
* Provider-elérhetőség: egy minimál embedding-próba (rövid token). Ha a hívás dob (endpoint down /
|
|
204
|
+
* model hiányzik), `false`. Soha nem propagál hibát (try/catch → false).
|
|
205
|
+
*/
|
|
206
|
+
async testConnection(issuer: string): Promise<boolean> {
|
|
207
|
+
try {
|
|
208
|
+
const vectors: number[][] | CreateEmbeddingResponse = await this.createEmbeddings({
|
|
209
|
+
texts: [ 'ping' ],
|
|
210
|
+
model: this.defaultProbeModel(),
|
|
211
|
+
fullResponse: false,
|
|
212
|
+
issuer: issuer,
|
|
213
213
|
});
|
|
214
|
-
|
|
215
|
-
return Array.isArray(vectors) && vectors.length === 1 && vectors[0].length > 0;
|
|
216
|
-
} catch (error) {
|
|
217
|
-
DyFM_Log.error('DyNTS_LMStudio_Embedding_ControlService', 'testConnection', 'Connection test failed', {
|
|
218
|
-
error: error,
|
|
219
|
-
issuer: issuer,
|
|
214
|
+
|
|
215
|
+
return Array.isArray(vectors) && vectors.length === 1 && vectors[0].length > 0;
|
|
216
|
+
} catch (error) {
|
|
217
|
+
DyFM_Log.error('DyNTS_LMStudio_Embedding_ControlService', 'testConnection', 'Connection test failed', {
|
|
218
|
+
error: error,
|
|
219
|
+
issuer: issuer,
|
|
220
220
|
});
|
|
221
|
-
|
|
222
|
-
return false;
|
|
223
|
-
}
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
// =========================================================================
|
|
227
|
-
// belső: fetch + parse + cost-event
|
|
228
|
-
// =========================================================================
|
|
229
|
-
|
|
230
|
-
/**
|
|
231
|
-
* Az OpenAI-kompatibilis `/embeddings` POST-hívás `fetch`-csel. A `input` lehet egyetlen string
|
|
232
|
-
* vagy string-tömb (mindkettőt az OpenAI-spec megengedi). A választ `CreateEmbeddingResponse`-alakra
|
|
233
|
-
* normalizáljuk (a `data[].embedding`-eket kivonatoljuk). HTTP-/parse-hiba deskriptív üzenettel dobódik.
|
|
234
|
-
*/
|
|
235
|
-
protected async callEmbeddingsEndpoint(
|
|
236
|
-
model: string,
|
|
237
|
-
input: string | string[],
|
|
238
|
-
issuer: string,
|
|
239
|
-
): Promise<CreateEmbeddingResponse> {
|
|
240
|
-
const url: string = `${this.baseUrl}/embeddings`;
|
|
221
|
+
|
|
222
|
+
return false;
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
// =========================================================================
|
|
227
|
+
// belső: fetch + parse + cost-event
|
|
228
|
+
// =========================================================================
|
|
229
|
+
|
|
230
|
+
/**
|
|
231
|
+
* Az OpenAI-kompatibilis `/embeddings` POST-hívás `fetch`-csel. A `input` lehet egyetlen string
|
|
232
|
+
* vagy string-tömb (mindkettőt az OpenAI-spec megengedi). A választ `CreateEmbeddingResponse`-alakra
|
|
233
|
+
* normalizáljuk (a `data[].embedding`-eket kivonatoljuk). HTTP-/parse-hiba deskriptív üzenettel dobódik.
|
|
234
|
+
*/
|
|
235
|
+
protected async callEmbeddingsEndpoint(
|
|
236
|
+
model: string,
|
|
237
|
+
input: string | string[],
|
|
238
|
+
issuer: string,
|
|
239
|
+
): Promise<CreateEmbeddingResponse> {
|
|
240
|
+
const url: string = `${this.baseUrl}/embeddings`;
|
|
241
241
|
const headers: { [key: string]: string } = { 'Content-Type': 'application/json' };
|
|
242
|
-
|
|
243
|
-
if (this.apiKey && this.apiKey.trim().length) {
|
|
244
|
-
headers.Authorization = `Bearer ${this.apiKey.trim()}`;
|
|
245
|
-
}
|
|
246
|
-
|
|
247
|
-
const response: Response = await fetch(url, {
|
|
248
|
-
method: 'POST',
|
|
249
|
-
headers: headers,
|
|
250
|
-
body: JSON.stringify({ model: model, input: input }),
|
|
251
|
-
});
|
|
252
|
-
const rawText: string = await response.text();
|
|
253
|
-
|
|
254
|
-
if (!response.ok) {
|
|
255
|
-
throw new Error(
|
|
256
|
-
`LM Studio (OpenAI-compatible) embeddings HTTP ${response.status} | url=${url} | `
|
|
257
|
-
+ `model=${model} | body=${this.snapshot(rawText)} | issuer=${issuer}`,
|
|
258
|
-
);
|
|
259
|
-
}
|
|
260
|
-
|
|
242
|
+
|
|
243
|
+
if (this.apiKey && this.apiKey.trim().length) {
|
|
244
|
+
headers.Authorization = `Bearer ${this.apiKey.trim()}`;
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
const response: Response = await fetch(url, {
|
|
248
|
+
method: 'POST',
|
|
249
|
+
headers: headers,
|
|
250
|
+
body: JSON.stringify({ model: model, input: input }),
|
|
251
|
+
});
|
|
252
|
+
const rawText: string = await response.text();
|
|
253
|
+
|
|
254
|
+
if (!response.ok) {
|
|
255
|
+
throw new Error(
|
|
256
|
+
`LM Studio (OpenAI-compatible) embeddings HTTP ${response.status} | url=${url} | `
|
|
257
|
+
+ `model=${model} | body=${this.snapshot(rawText)} | issuer=${issuer}`,
|
|
258
|
+
);
|
|
259
|
+
}
|
|
260
|
+
|
|
261
261
|
let parsed: unknown;
|
|
262
|
-
|
|
263
|
-
try {
|
|
264
|
-
parsed = JSON.parse(rawText);
|
|
265
|
-
} catch {
|
|
266
|
-
throw new Error(
|
|
267
|
-
`LM Studio embeddings: non-JSON response | url=${url} | model=${model} | body=${this.snapshot(rawText)}`,
|
|
268
|
-
);
|
|
269
|
-
}
|
|
270
|
-
|
|
262
|
+
|
|
263
|
+
try {
|
|
264
|
+
parsed = JSON.parse(rawText);
|
|
265
|
+
} catch {
|
|
266
|
+
throw new Error(
|
|
267
|
+
`LM Studio embeddings: non-JSON response | url=${url} | model=${model} | body=${this.snapshot(rawText)}`,
|
|
268
|
+
);
|
|
269
|
+
}
|
|
270
|
+
|
|
271
271
|
const expectedCount: number = Array.isArray(input) ? input.length : 1;
|
|
272
|
-
|
|
273
|
-
return this.normalizeResponse(parsed, expectedCount, url, model);
|
|
274
|
-
}
|
|
275
|
-
|
|
276
|
-
/**
|
|
277
|
-
* A nyers (OpenAI-kompatibilis) választ `CreateEmbeddingResponse`-alakra normalizálja: a `data[]`-ból
|
|
278
|
-
* a `embedding` tömböket emeli ki (csak véges number-eket), a darabszámot ellenőrzi (1:1 a `texts`-szel),
|
|
279
|
-
* és átveszi a `usage`-t ha van (a cost-event token-számához). Hibás/hiányzó mező → deskriptív hiba.
|
|
280
|
-
*/
|
|
281
|
-
protected normalizeResponse(json: unknown, expectedCount: number, url: string, modelId: string): CreateEmbeddingResponse {
|
|
282
|
-
if (json === null || typeof json !== 'object' || Array.isArray(json)) {
|
|
283
|
-
throw new Error(`LM Studio embeddings: invalid response object | url=${url} | model=${modelId}`);
|
|
284
|
-
}
|
|
272
|
+
|
|
273
|
+
return this.normalizeResponse(parsed, expectedCount, url, model);
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
/**
|
|
277
|
+
* A nyers (OpenAI-kompatibilis) választ `CreateEmbeddingResponse`-alakra normalizálja: a `data[]`-ból
|
|
278
|
+
* a `embedding` tömböket emeli ki (csak véges number-eket), a darabszámot ellenőrzi (1:1 a `texts`-szel),
|
|
279
|
+
* és átveszi a `usage`-t ha van (a cost-event token-számához). Hibás/hiányzó mező → deskriptív hiba.
|
|
280
|
+
*/
|
|
281
|
+
protected normalizeResponse(json: unknown, expectedCount: number, url: string, modelId: string): CreateEmbeddingResponse {
|
|
282
|
+
if (json === null || typeof json !== 'object' || Array.isArray(json)) {
|
|
283
|
+
throw new Error(`LM Studio embeddings: invalid response object | url=${url} | model=${modelId}`);
|
|
284
|
+
}
|
|
285
285
|
const dataRaw: unknown = Reflect.get(json, 'data');
|
|
286
|
-
|
|
287
|
-
if (!Array.isArray(dataRaw)) {
|
|
288
|
-
throw new Error(`LM Studio embeddings: missing data array | url=${url} | model=${modelId}`);
|
|
289
|
-
}
|
|
290
|
-
|
|
291
|
-
const data: CreateEmbeddingResponse['data'] = [];
|
|
286
|
+
|
|
287
|
+
if (!Array.isArray(dataRaw)) {
|
|
288
|
+
throw new Error(`LM Studio embeddings: missing data array | url=${url} | model=${modelId}`);
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
const data: CreateEmbeddingResponse['data'] = [];
|
|
292
292
|
let index: number = 0;
|
|
293
|
-
|
|
294
|
-
for (const item of dataRaw) {
|
|
295
|
-
if (item === null || typeof item !== 'object' || Array.isArray(item)) {
|
|
296
|
-
continue;
|
|
297
|
-
}
|
|
293
|
+
|
|
294
|
+
for (const item of dataRaw) {
|
|
295
|
+
if (item === null || typeof item !== 'object' || Array.isArray(item)) {
|
|
296
|
+
continue;
|
|
297
|
+
}
|
|
298
298
|
const embRaw: unknown = Reflect.get(item, 'embedding');
|
|
299
|
-
|
|
300
|
-
if (!Array.isArray(embRaw)) {
|
|
301
|
-
continue;
|
|
302
|
-
}
|
|
299
|
+
|
|
300
|
+
if (!Array.isArray(embRaw)) {
|
|
301
|
+
continue;
|
|
302
|
+
}
|
|
303
303
|
const vec: number[] = embRaw.filter((x: unknown): x is number => typeof x === 'number' && Number.isFinite(x));
|
|
304
|
-
|
|
305
|
-
if (vec.length) {
|
|
306
|
-
data.push({ object: 'embedding', embedding: vec, index: index });
|
|
307
|
-
index++;
|
|
308
|
-
}
|
|
309
|
-
}
|
|
310
|
-
|
|
311
|
-
if (data.length !== expectedCount) {
|
|
312
|
-
throw new Error(
|
|
313
|
-
`LM Studio embeddings: expected ${expectedCount} vectors, got ${data.length} | url=${url} | model=${modelId}`,
|
|
314
|
-
);
|
|
315
|
-
}
|
|
316
|
-
|
|
317
|
-
const usageRaw: unknown = Reflect.get(json, 'usage');
|
|
318
|
-
const promptTokens: number = this.readNumber(usageRaw, 'prompt_tokens');
|
|
319
|
-
const totalTokens: number = this.readNumber(usageRaw, 'total_tokens');
|
|
320
|
-
|
|
321
|
-
return {
|
|
322
|
-
object: 'list',
|
|
323
|
-
model: modelId,
|
|
324
|
-
data: data,
|
|
325
|
-
usage: {
|
|
326
|
-
prompt_tokens: promptTokens,
|
|
327
|
-
total_tokens: totalTokens || promptTokens,
|
|
328
|
-
},
|
|
329
|
-
};
|
|
330
|
-
}
|
|
331
|
-
|
|
332
|
-
/**
|
|
333
|
-
* Cost-event emit (BFR-AM-007). A token a `usage`-ből (ha az endpoint adta), különben becsült
|
|
334
|
-
* (4 char ≈ 1 token, defenzív lokális heurisztika). A provider mindig `'lm-studio'` string.
|
|
335
|
-
*/
|
|
336
|
-
protected emitLmStudioCostEvent(
|
|
337
|
-
callType: 'embedding-single' | 'embedding-batch',
|
|
338
|
-
model: string,
|
|
339
|
-
texts: string[],
|
|
340
|
-
response: CreateEmbeddingResponse,
|
|
341
|
-
durationMs: number,
|
|
342
|
-
issuer: string,
|
|
343
|
-
): void {
|
|
344
|
-
const reportedInput: number = response.usage?.prompt_tokens ?? 0;
|
|
345
|
-
const input: number = reportedInput || this.estimateTokens(texts);
|
|
346
|
-
const total: number = response.usage?.total_tokens || input;
|
|
347
|
-
|
|
348
|
-
this.emitCostEvent({
|
|
349
|
-
callType: callType,
|
|
350
|
-
provider: this.costProvider,
|
|
351
|
-
model: model,
|
|
352
|
-
tokensUsed: {
|
|
353
|
-
input: input,
|
|
354
|
-
total: total,
|
|
355
|
-
},
|
|
356
|
-
durationMs: durationMs,
|
|
357
|
-
issuer: issuer,
|
|
358
|
-
timestamp: new Date(),
|
|
359
|
-
});
|
|
360
|
-
}
|
|
361
|
-
|
|
362
|
-
/** Becsült token-szám lokális endpoint-hoz (ha nincs `usage`): 4 char ≈ 1 token. */
|
|
363
|
-
protected estimateTokens(texts: string[]): number {
|
|
304
|
+
|
|
305
|
+
if (vec.length) {
|
|
306
|
+
data.push({ object: 'embedding', embedding: vec, index: index });
|
|
307
|
+
index++;
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
if (data.length !== expectedCount) {
|
|
312
|
+
throw new Error(
|
|
313
|
+
`LM Studio embeddings: expected ${expectedCount} vectors, got ${data.length} | url=${url} | model=${modelId}`,
|
|
314
|
+
);
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
const usageRaw: unknown = Reflect.get(json, 'usage');
|
|
318
|
+
const promptTokens: number = this.readNumber(usageRaw, 'prompt_tokens');
|
|
319
|
+
const totalTokens: number = this.readNumber(usageRaw, 'total_tokens');
|
|
320
|
+
|
|
321
|
+
return {
|
|
322
|
+
object: 'list',
|
|
323
|
+
model: modelId,
|
|
324
|
+
data: data,
|
|
325
|
+
usage: {
|
|
326
|
+
prompt_tokens: promptTokens,
|
|
327
|
+
total_tokens: totalTokens || promptTokens,
|
|
328
|
+
},
|
|
329
|
+
};
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
/**
|
|
333
|
+
* Cost-event emit (BFR-AM-007). A token a `usage`-ből (ha az endpoint adta), különben becsült
|
|
334
|
+
* (4 char ≈ 1 token, defenzív lokális heurisztika). A provider mindig `'lm-studio'` string.
|
|
335
|
+
*/
|
|
336
|
+
protected emitLmStudioCostEvent(
|
|
337
|
+
callType: 'embedding-single' | 'embedding-batch',
|
|
338
|
+
model: string,
|
|
339
|
+
texts: string[],
|
|
340
|
+
response: CreateEmbeddingResponse,
|
|
341
|
+
durationMs: number,
|
|
342
|
+
issuer: string,
|
|
343
|
+
): void {
|
|
344
|
+
const reportedInput: number = response.usage?.prompt_tokens ?? 0;
|
|
345
|
+
const input: number = reportedInput || this.estimateTokens(texts);
|
|
346
|
+
const total: number = response.usage?.total_tokens || input;
|
|
347
|
+
|
|
348
|
+
this.emitCostEvent({
|
|
349
|
+
callType: callType,
|
|
350
|
+
provider: this.costProvider,
|
|
351
|
+
model: model,
|
|
352
|
+
tokensUsed: {
|
|
353
|
+
input: input,
|
|
354
|
+
total: total,
|
|
355
|
+
},
|
|
356
|
+
durationMs: durationMs,
|
|
357
|
+
issuer: issuer,
|
|
358
|
+
timestamp: new Date(),
|
|
359
|
+
});
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
/** Becsült token-szám lokális endpoint-hoz (ha nincs `usage`): 4 char ≈ 1 token. */
|
|
363
|
+
protected estimateTokens(texts: string[]): number {
|
|
364
364
|
let chars: number = 0;
|
|
365
|
-
|
|
366
|
-
for (const text of texts) {
|
|
367
|
-
chars += (text ?? '').length;
|
|
365
|
+
|
|
366
|
+
for (const text of texts) {
|
|
367
|
+
chars += (text ?? '').length;
|
|
368
368
|
}
|
|
369
|
-
|
|
370
|
-
return Math.max(1, Math.ceil(chars / 4));
|
|
371
|
-
}
|
|
372
|
-
|
|
373
|
-
/** A `testConnection` próba-modellje (env-override-olható, default a FAM-mintára). */
|
|
374
|
-
protected defaultProbeModel(): string {
|
|
375
|
-
return process.env.LMSTUDIO_EMBEDDING_MODEL || 'nomic-embed-text-v1.5';
|
|
376
|
-
}
|
|
377
|
-
|
|
378
|
-
/** Trailing `/`-ek levágása (kettős slash elkerülése a `/embeddings` join-nál). */
|
|
379
|
-
protected trimTrailingSlashes(value: string): string {
|
|
380
|
-
return value.replace(/\/+$/, '');
|
|
381
|
-
}
|
|
382
|
-
|
|
383
|
-
/** Rövid, biztonságos válasz-snapshot a hiba-üzenethez (max 300 char). */
|
|
384
|
-
protected snapshot(value: string): string {
|
|
369
|
+
|
|
370
|
+
return Math.max(1, Math.ceil(chars / 4));
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
/** A `testConnection` próba-modellje (env-override-olható, default a FAM-mintára). */
|
|
374
|
+
protected defaultProbeModel(): string {
|
|
375
|
+
return process.env.LMSTUDIO_EMBEDDING_MODEL || 'nomic-embed-text-v1.5';
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
/** Trailing `/`-ek levágása (kettős slash elkerülése a `/embeddings` join-nál). */
|
|
379
|
+
protected trimTrailingSlashes(value: string): string {
|
|
380
|
+
return value.replace(/\/+$/, '');
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
/** Rövid, biztonságos válasz-snapshot a hiba-üzenethez (max 300 char). */
|
|
384
|
+
protected snapshot(value: string): string {
|
|
385
385
|
const trimmed: string = (value ?? '').slice(0, 300);
|
|
386
|
-
|
|
387
|
-
return trimmed.length === 300 ? `${trimmed}…` : trimmed;
|
|
388
|
-
}
|
|
389
|
-
|
|
390
|
-
/** Egy number mező típusbiztos kiolvasása egy ismeretlen objektumból (hiány → 0). */
|
|
391
|
-
protected readNumber(obj: unknown, key: string): number {
|
|
392
|
-
if (obj === null || typeof obj !== 'object') {
|
|
393
|
-
return 0;
|
|
394
|
-
}
|
|
386
|
+
|
|
387
|
+
return trimmed.length === 300 ? `${trimmed}…` : trimmed;
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
/** Egy number mező típusbiztos kiolvasása egy ismeretlen objektumból (hiány → 0). */
|
|
391
|
+
protected readNumber(obj: unknown, key: string): number {
|
|
392
|
+
if (obj === null || typeof obj !== 'object') {
|
|
393
|
+
return 0;
|
|
394
|
+
}
|
|
395
395
|
const value: unknown = Reflect.get(obj, key);
|
|
396
|
-
|
|
397
|
-
return typeof value === 'number' && Number.isFinite(value) ? value : 0;
|
|
398
|
-
}
|
|
399
|
-
}
|
|
396
|
+
|
|
397
|
+
return typeof value === 'number' && Number.isFinite(value) ? value : 0;
|
|
398
|
+
}
|
|
399
|
+
}
|