@futdevpro/nts-dynamo 1.11.25 → 1.11.27

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (78) hide show
  1. package/.github/workflows/main.yml +1 -0
  2. package/build/_models/control-models/app-params.control-model.d.ts.map +1 -1
  3. package/build/_models/control-models/app-params.control-model.js +4 -0
  4. package/build/_models/control-models/app-params.control-model.js.map +1 -1
  5. package/build/_models/control-models/endpoint-params.control-model.d.ts.map +1 -1
  6. package/build/_models/control-models/endpoint-params.control-model.js +2 -0
  7. package/build/_models/control-models/endpoint-params.control-model.js.map +1 -1
  8. package/build/_modules/discord-assistant/_collections/dias-global-settings.const.js +1 -1
  9. package/build/_modules/discord-assistant/_collections/dias-global-settings.const.js.map +1 -1
  10. package/build/_modules/discord-assistant/_collections/dias.util.d.ts +1 -0
  11. package/build/_modules/discord-assistant/_collections/dias.util.d.ts.map +1 -1
  12. package/build/_modules/discord-assistant/_collections/dias.util.js +1 -0
  13. package/build/_modules/discord-assistant/_collections/dias.util.js.map +1 -1
  14. package/build/_modules/discord-assistant/_models/dias-global-settings.interface.d.ts +1 -1
  15. package/build/_modules/discord-assistant/_services/dias-io.control-service.d.ts.map +1 -1
  16. package/build/_modules/discord-assistant/_services/dias-io.control-service.js +4 -2
  17. package/build/_modules/discord-assistant/_services/dias-io.control-service.js.map +1 -1
  18. package/build/_modules/discord-assistant/_services/dias-main.control-service.d.ts +0 -3
  19. package/build/_modules/discord-assistant/_services/dias-main.control-service.d.ts.map +1 -1
  20. package/build/_modules/discord-assistant/_services/dias.service-base.d.ts +6 -2
  21. package/build/_modules/discord-assistant/_services/dias.service-base.d.ts.map +1 -1
  22. package/build/_modules/discord-assistant/_services/dias.service-base.js +6 -4
  23. package/build/_modules/discord-assistant/_services/dias.service-base.js.map +1 -1
  24. package/build/_modules/discord-bot/_collections/dibo-global-settings.conts.js +1 -1
  25. package/build/_modules/discord-bot/_collections/dibo-global-settings.conts.js.map +1 -1
  26. package/build/_modules/discord-bot/_collections/dibo-operations.util.d.ts.map +1 -1
  27. package/build/_modules/discord-bot/_collections/dibo-operations.util.js +13 -11
  28. package/build/_modules/discord-bot/_collections/dibo-operations.util.js.map +1 -1
  29. package/build/_modules/discord-bot/_services/dibo-commands.control-service.d.ts +1 -1
  30. package/build/_modules/discord-bot/_services/dibo-commands.control-service.d.ts.map +1 -1
  31. package/build/_modules/discord-bot/_services/dibo-commands.control-service.js +3 -3
  32. package/build/_modules/discord-bot/_services/dibo-commands.control-service.js.map +1 -1
  33. package/build/_modules/discord-bot/_services/dibo-io.control-service.d.ts +1 -0
  34. package/build/_modules/discord-bot/_services/dibo-io.control-service.d.ts.map +1 -1
  35. package/build/_modules/discord-bot/_services/dibo-io.control-service.js +3 -2
  36. package/build/_modules/discord-bot/_services/dibo-io.control-service.js.map +1 -1
  37. package/build/_modules/discord-bot/_services/dibo-main.control-service.d.ts.map +1 -1
  38. package/build/_modules/discord-bot/_services/dibo-main.control-service.js +25 -0
  39. package/build/_modules/discord-bot/_services/dibo-main.control-service.js.map +1 -1
  40. package/build/_modules/mock/socket-server.mock.d.ts +4 -0
  41. package/build/_modules/mock/socket-server.mock.d.ts.map +1 -1
  42. package/build/_modules/mock/socket-server.mock.js +11 -1
  43. package/build/_modules/mock/socket-server.mock.js.map +1 -1
  44. package/build/_modules/mock/socket-server.mock.spec.js +1 -1
  45. package/build/_modules/mock/socket-server.mock.spec.js.map +1 -1
  46. package/build/_modules/open-ai/_services/oai-llm-chat.service-base.d.ts +16 -141
  47. package/build/_modules/open-ai/_services/oai-llm-chat.service-base.d.ts.map +1 -1
  48. package/build/_modules/open-ai/_services/oai-llm-chat.service-base.js +9 -6
  49. package/build/_modules/open-ai/_services/oai-llm-chat.service-base.js.map +1 -1
  50. package/build/_modules/open-ai/_services/oai-llm.service-base.d.ts +1 -22
  51. package/build/_modules/open-ai/_services/oai-llm.service-base.d.ts.map +1 -1
  52. package/build/_modules/open-ai/_services/oai-llm.service-base.js +28 -75
  53. package/build/_modules/open-ai/_services/oai-llm.service-base.js.map +1 -1
  54. package/build/_modules/socket/_services/socket-server.service.d.ts.map +1 -1
  55. package/build/_modules/socket/_services/socket-server.service.js +12 -3
  56. package/build/_modules/socket/_services/socket-server.service.js.map +1 -1
  57. package/build/_modules/socket/app-extended.server.spec.js +44 -7
  58. package/build/_modules/socket/app-extended.server.spec.js.map +1 -1
  59. package/package.json +3 -4
  60. package/src/_models/control-models/app-params.control-model.ts +7 -0
  61. package/src/_models/control-models/endpoint-params.control-model.ts +2 -0
  62. package/src/_modules/discord-assistant/_collections/dias-global-settings.const.ts +1 -1
  63. package/src/_modules/discord-assistant/_collections/dias.util.ts +3 -1
  64. package/src/_modules/discord-assistant/_models/dias-global-settings.interface.ts +1 -1
  65. package/src/_modules/discord-assistant/_services/dias-io.control-service.ts +4 -2
  66. package/src/_modules/discord-assistant/_services/dias-main.control-service.ts +2 -2
  67. package/src/_modules/discord-assistant/_services/dias.service-base.ts +13 -6
  68. package/src/_modules/discord-bot/_collections/dibo-global-settings.conts.ts +1 -1
  69. package/src/_modules/discord-bot/_collections/dibo-operations.util.ts +13 -11
  70. package/src/_modules/discord-bot/_services/dibo-commands.control-service.ts +3 -3
  71. package/src/_modules/discord-bot/_services/dibo-io.control-service.ts +4 -2
  72. package/src/_modules/discord-bot/_services/dibo-main.control-service.ts +21 -0
  73. package/src/_modules/mock/socket-server.mock.spec.ts +1 -1
  74. package/src/_modules/mock/socket-server.mock.ts +13 -3
  75. package/src/_modules/open-ai/_services/oai-llm-chat.service-base.ts +28 -23
  76. package/src/_modules/open-ai/_services/oai-llm.service-base.ts +31 -96
  77. package/src/_modules/socket/_services/socket-server.service.ts +15 -6
  78. package/src/_modules/socket/app-extended.server.spec.ts +50 -18
@@ -1,7 +1,7 @@
1
1
  import { OpenAI } from 'openai';
2
2
 
3
3
  import { DyFM_OpenAI_Settings, DyFM_OpenAIModel, DyFM_GPTCall_Settings } from '@futdevpro/fsm-dynamo/open-ai';
4
- import { DyFM_AnyError, DyFM_Error, DyFM_Error_Settings, DyFM_Log, DyFM_notNull } from '@futdevpro/fsm-dynamo';
4
+ import { DyFM_AnyError, DyFM_Error, DyFM_Error_Settings, DyFM_Log, DyFM_notNull, DyFM_Shared } from '@futdevpro/fsm-dynamo';
5
5
 
6
6
  import { DyNTS_global_settings } from '../../../_collections/global-settings.const';
7
7
  import { DyNTS_OAI_GPT_Message } from '../_models/interfaces/oai-gpt-message.interface';
@@ -193,7 +193,7 @@ export class DyNTS_OAI_LLM_ServiceBase {
193
193
 
194
194
  const answer = await this.askQuestion(set);
195
195
 
196
- return DyFM_safeParseJSON<T>(answer);
196
+ return DyFM_Shared.safeParseJSON<T>(answer);
197
197
  }
198
198
  /** the exact same as {@link requestSelect} */
199
199
  selectRequest = this.requestSelect;
@@ -263,7 +263,7 @@ export class DyNTS_OAI_LLM_ServiceBase {
263
263
 
264
264
  const answer = await this.askQuestion(set);
265
265
 
266
- return DyFM_safeParseList<T[]>(answer);
266
+ return DyFM_Shared.safeParseList<T[]>(answer);
267
267
  }
268
268
  /** the exact same as {@link requestMultipleSelect} */
269
269
  multipleSelectRequest = this.requestMultipleSelect;
@@ -291,7 +291,7 @@ export class DyNTS_OAI_LLM_ServiceBase {
291
291
 
292
292
  const answer = await this.askQuestion(set);
293
293
 
294
- return DyFM_safeParseJSON<T>(answer);
294
+ return DyFM_Shared.safeParseJSON<T>(answer);
295
295
  }
296
296
  /** the exact same as {@link askJSONQuestion} */
297
297
  jsonQuestion = this.askJSONQuestion;
@@ -324,7 +324,7 @@ export class DyNTS_OAI_LLM_ServiceBase {
324
324
 
325
325
  const answer = await this.askQuestion(set);
326
326
 
327
- return DyFM_safeParseJSON<T>(answer);
327
+ return DyFM_Shared.safeParseJSON<T>(answer);
328
328
  }
329
329
  /** the exact same as {@link askJSONQuestionWithKeysDescription} */
330
330
  jsonQuestionWithKeysDescription = this.askJSONQuestionWithKeysDescription;
@@ -357,7 +357,7 @@ export class DyNTS_OAI_LLM_ServiceBase {
357
357
 
358
358
  const answer = await this.askQuestion(set);
359
359
 
360
- return DyFM_safeParseJSON<T>(answer);
360
+ return DyFM_Shared.safeParseJSON<T>(answer);
361
361
  }
362
362
  /** the exact same as {@link askJSONQuestionWithExactKeys} */
363
363
  jsonQuestionWithExactKeys = this.askJSONQuestionWithExactKeys;
@@ -385,7 +385,7 @@ export class DyNTS_OAI_LLM_ServiceBase {
385
385
 
386
386
  const answer = await this.askQuestion(set);
387
387
 
388
- return DyFM_safeParseList(answer);
388
+ return DyFM_Shared.safeParseList<string[]>(answer);
389
389
  }
390
390
  /** the exact same as {@link askListQuestion} */
391
391
  listQuestion = this.askListQuestion;
@@ -597,6 +597,30 @@ export class DyNTS_OAI_LLM_ServiceBase {
597
597
  content: settings?.systemPrompt || this.defaultSystemPrompt,
598
598
  };
599
599
  }
600
+
601
+ protected validateConversation(conversation: DyNTS_OAI_GPT_Message[]): void {
602
+ conversation.forEach((message: DyNTS_OAI_GPT_Message, index: number) => {
603
+ if (!message.role) {
604
+ throw new DyFM_Error({
605
+ message: `Message has no role at index ${index}`,
606
+ additionalContent: {
607
+ invalidMessage: message,
608
+ conversation: conversation,
609
+ }
610
+ });
611
+ }
612
+
613
+ if (!message.content) {
614
+ throw new DyFM_Error({
615
+ message: `Message has no content at index ${index}`,
616
+ additionalContent: {
617
+ invalidMessage: message,
618
+ conversation: conversation,
619
+ }
620
+ });
621
+ }
622
+ });
623
+ }
600
624
 
601
625
  protected getDefaultErrorSettings(
602
626
  fnName: string,
@@ -618,92 +642,3 @@ export class DyNTS_OAI_LLM_ServiceBase {
618
642
 
619
643
  //#endregion
620
644
  }
621
-
622
- /**
623
- * parses the JSON list, if it fails, it returns the answer as a single item in an array
624
- *
625
- * (uses {@link DyFM_safeParseJSON})
626
- * @deprecated use {@link DyFM_Shared.safeParseList} instead
627
- */
628
- export function DyFM_safeParseList<T extends Array<any>>(
629
- textedJSON: string,
630
- disableErrorLog?: boolean
631
- ): T {
632
- const parsed = DyFM_safeParseJSON<T>(textedJSON, true);
633
-
634
- if (Array.isArray(parsed)) {
635
- return parsed;
636
- } else if (typeof parsed === 'object') {
637
- if (!disableErrorLog) {
638
- DyFM_Log.warn(
639
- 'DyFM_safeParseList result is an object, returning its values',
640
- {
641
- parsed: parsed,
642
- }
643
- );
644
- }
645
-
646
- return Object.values(parsed) as T;
647
- } else {
648
-
649
- if (!disableErrorLog) {
650
- DyFM_Log.warn(
651
- 'DyFM_safeParseList result is not an array or object, returning it as a single item',
652
- {
653
- parsed: parsed,
654
- }
655
- );
656
- }
657
-
658
- return [ parsed ] as string[] as T;
659
- }
660
- }
661
-
662
- /**
663
- * parses the JSON, if it fails, it returns { unparsableResult: textedJSON }
664
- *
665
- * (uses {@link DyFM_failableSafeParseJSON})
666
- * @deprecated use {@link DyFM_Shared.safeParseJSON} instead
667
- */
668
- export function DyFM_safeParseJSON<T = any>(
669
- textedJSON: string,
670
- disableErrorLog?: boolean
671
- ): T | { unparsableResult: string } {
672
- try {
673
- return DyFM_failableSafeParseJSON(textedJSON);
674
- } catch (error) {
675
- if (!disableErrorLog) {
676
- DyFM_Log.error(
677
- 'Unable to parse JSON answer:',
678
- {
679
- unparsedJSON: textedJSON,
680
- error: error,
681
- }
682
- );
683
- }
684
-
685
- return { unparsableResult: textedJSON };
686
- }
687
- }
688
-
689
- /**
690
- * parses the JSON, if it fails, it throws an error
691
- * (also will extract the JSON from "```json ... ```" wrapper)
692
- * @deprecated use {@link DyFM_Shared.failableSafeParseJSON} instead
693
- */
694
- export function DyFM_failableSafeParseJSON<T = any>(textedJSON: string): T {
695
- if (!textedJSON) {
696
- throw new Error(`No content provided to JSON parse ("${textedJSON}")`);
697
- }
698
-
699
- const match = textedJSON.match(/```json(.*)```/s);
700
- textedJSON = textedJSON.replaceAll('\n', '');
701
-
702
- if (match) {
703
- return JSON.parse(match[1].replaceAll('\n', ''));
704
- } else {
705
- return JSON.parse(
706
- textedJSON.replaceAll('```json', '').replaceAll('```', '')
707
- );
708
- }
709
- }
@@ -498,12 +498,21 @@ export abstract class DyNTS_SocketServerService<
498
498
  }
499
499
  });
500
500
 
501
- newSocketServer.listen(this.params.port);
502
-
503
- DyFM_Log.success(
504
- `\nsocket server setup finished: "${this.params.name}"` +
505
- `\nsocket server listening on port: "${this.params.port}"`
506
- );
501
+ try {
502
+ newSocketServer.listen(this.params.port);
503
+
504
+ DyFM_Log.success(
505
+ `\nsocket server setup finished: "${this.params.name}"` +
506
+ `\nsocket server listening on port: "${this.params.port}"`
507
+ );
508
+ } catch (listenError) {
509
+ const errorMessage = `Failed to bind socket server "${this.params.name}" to port ${this.params.port}. ` +
510
+ `This could be due to port already in use or insufficient permissions. ` +
511
+ `Please ensure the port is available and try again.`;
512
+
513
+ DyFM_Log.error(errorMessage, listenError);
514
+ throw new Error(errorMessage);
515
+ }
507
516
 
508
517
  successCallback();
509
518
 
@@ -9,17 +9,42 @@ describe('| DyNTS_AppExtended;', (): void => {
9
9
  process.setMaxListeners(20);
10
10
  let app: DyNTS_AppExtended;
11
11
 
12
+ // Helper function to safely stop and cleanup app
13
+ const safeStopApp = async (): Promise<void> => {
14
+ if (app) {
15
+ try {
16
+ await app.stop();
17
+ } catch (error) {
18
+ DyFM_Log.testWarn('Error stopping app:', error);
19
+ }
20
+ app = null;
21
+ }
22
+ };
23
+
24
+ // Helper function to wait for app to be ready with timeout
25
+ const waitForAppReady = async (appInstance: DyNTS_AppExtended, timeoutMs: number = 10000): Promise<void> => {
26
+ const startTime = Date.now();
27
+ while (!appInstance.started && (Date.now() - startTime) < timeoutMs) {
28
+ await DyFM_delay(100);
29
+ }
30
+
31
+ if (!appInstance.started) {
32
+ throw new Error(`App failed to start within ${timeoutMs}ms`);
33
+ }
34
+ };
35
+
12
36
  describe('| a extended-base instance;', (): void => {
13
37
  beforeEach(async (): Promise<void> => {
14
38
  try {
15
39
  await DyFM_waitUntil((): boolean => !app, second);
40
+ await DyFM_delay(100); // Ensure previous instance is fully cleaned up
16
41
 
17
42
  app = new DyNTS_AppExtendedBase_Mock();
18
-
19
43
  await DyFM_delay(100);
20
44
 
21
45
  await app.ready();
22
-
46
+ await waitForAppReady(app);
47
+
23
48
  await DyFM_delay(100);
24
49
  } catch (error) {
25
50
  DyFM_Log.testError(
@@ -35,16 +60,15 @@ describe('| DyNTS_AppExtended;', (): void => {
35
60
  (new Error()).stack,
36
61
  (error as DyFM_Error)?.additionalContent?.errors?.reverse()?.unshift()?.stack
37
62
  );
63
+ throw error; // Re-throw to fail the test
38
64
  }
39
65
  });
40
66
 
41
67
  afterEach(async (): Promise<void> => {
42
68
  try {
43
69
  await DyFM_delay(100);
44
-
45
- await app.stop();
46
-
47
- app = null;
70
+ await safeStopApp();
71
+ await DyFM_delay(100);
48
72
  } catch (error) {
49
73
  DyFM_Log.testError(
50
74
  '| DyNTS_AppExtended; | a extended-base instance; test afterEach error:\n',
@@ -64,10 +88,12 @@ describe('| DyNTS_AppExtended;', (): void => {
64
88
 
65
89
  it('| should be created', (): void => {
66
90
  expect(app).toBeDefined();
91
+ expect(app).toBeInstanceOf(DyNTS_AppExtendedBase_Mock);
67
92
  });
68
93
 
69
- it('| should be started', (): void => {
94
+ it('| should be started', async (): Promise<void> => {
70
95
  expect(app.started).toBeTrue();
96
+ expect(app).toBeDefined();
71
97
  });
72
98
  });
73
99
 
@@ -75,13 +101,14 @@ describe('| DyNTS_AppExtended;', (): void => {
75
101
  beforeEach(async (): Promise<void> => {
76
102
  try {
77
103
  await DyFM_waitUntil((): boolean => !app, second);
104
+ await DyFM_delay(100); // Ensure previous instance is fully cleaned up
78
105
 
79
106
  app = new DyNTS_AppExtendedFull_Mock();
80
-
81
107
  await DyFM_delay(100);
82
108
 
83
109
  await app.ready();
84
-
110
+ await waitForAppReady(app);
111
+
85
112
  await DyFM_delay(100);
86
113
  } catch (error) {
87
114
  DyFM_Log.testError(
@@ -97,16 +124,15 @@ describe('| DyNTS_AppExtended;', (): void => {
97
124
  (new Error()).stack,
98
125
  (error as DyFM_Error)?.additionalContent?.errors?.reverse()?.unshift()?.stack
99
126
  );
127
+ throw error; // Re-throw to fail the test
100
128
  }
101
129
  });
102
130
 
103
131
  afterEach(async (): Promise<void> => {
104
132
  try {
105
133
  await DyFM_delay(100);
106
-
107
- await app.stop();
108
-
109
- app = null;
134
+ await safeStopApp();
135
+ await DyFM_delay(100);
110
136
  } catch (error) {
111
137
  DyFM_Log.testError(
112
138
  '| DyNTS_AppExtended; | a extended-full instance; test afterEach error:\n',
@@ -126,10 +152,12 @@ describe('| DyNTS_AppExtended;', (): void => {
126
152
 
127
153
  it('| should be created', async (): Promise<void> => {
128
154
  expect(app).toBeDefined();
155
+ expect(app).toBeInstanceOf(DyNTS_AppExtendedFull_Mock);
129
156
  });
130
157
 
131
158
  it('| should be started', async (): Promise<void> => {
132
159
  expect(app.started).toBeTrue();
160
+ expect(app).toBeDefined();
133
161
  });
134
162
  });
135
163
 
@@ -137,12 +165,14 @@ describe('| DyNTS_AppExtended;', (): void => {
137
165
  beforeEach(async (): Promise<void> => {
138
166
  try {
139
167
  await DyFM_waitUntil((): boolean => !app, second);
168
+ await DyFM_delay(100); // Ensure previous instance is fully cleaned up
140
169
 
141
170
  app = new DyNTS_AppWbMock_Mock();
142
171
  await DyFM_delay(100);
143
172
 
144
173
  await app.ready();
145
-
174
+ await waitForAppReady(app);
175
+
146
176
  await DyFM_delay(100);
147
177
  } catch (error) {
148
178
  DyFM_Log.testError(
@@ -158,15 +188,15 @@ describe('| DyNTS_AppExtended;', (): void => {
158
188
  (new Error()).stack,
159
189
  (error as DyFM_Error)?.additionalContent?.errors?.reverse()?.unshift()?.stack
160
190
  );
191
+ throw error; // Re-throw to fail the test
161
192
  }
162
193
  });
194
+
163
195
  afterEach(async (): Promise<void> => {
164
196
  try {
165
197
  await DyFM_delay(100);
166
-
167
- await app.stop();
168
-
169
- app = null;
198
+ await safeStopApp();
199
+ await DyFM_delay(100);
170
200
  } catch (error) {
171
201
  DyFM_Log.testError(
172
202
  '| DyNTS_AppExtended; | a wb-mock instance; test afterEach error:\n',
@@ -186,10 +216,12 @@ describe('| DyNTS_AppExtended;', (): void => {
186
216
 
187
217
  it('| should be created', async (): Promise<void> => {
188
218
  expect(app).toBeDefined();
219
+ expect(app).toBeInstanceOf(DyNTS_AppWbMock_Mock);
189
220
  });
190
221
 
191
222
  it('| should be started', async (): Promise<void> => {
192
223
  expect(app.started).toBeTrue();
224
+ expect(app).toBeDefined();
193
225
  });
194
226
  });
195
227
  });