@solidstarters/solid-core 1.2.173 → 1.2.175

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 (88) hide show
  1. package/dev-grooming-docs/ozzy-prompts.txt +13 -0
  2. package/dist/config/iam.config.js +2 -2
  3. package/dist/config/iam.config.js.map +1 -1
  4. package/dist/constants/chatter-message.constants.d.ts +11 -0
  5. package/dist/constants/chatter-message.constants.d.ts.map +1 -0
  6. package/dist/constants/chatter-message.constants.js +14 -0
  7. package/dist/constants/chatter-message.constants.js.map +1 -0
  8. package/dist/controllers/ai-interaction.controller.js +1 -1
  9. package/dist/controllers/ai-interaction.controller.js.map +1 -1
  10. package/dist/controllers/authentication.controller.d.ts +1 -2
  11. package/dist/controllers/authentication.controller.d.ts.map +1 -1
  12. package/dist/controllers/chatter-message-details.controller.d.ts +0 -16
  13. package/dist/controllers/chatter-message-details.controller.d.ts.map +1 -1
  14. package/dist/controllers/chatter-message-details.controller.js +0 -109
  15. package/dist/controllers/chatter-message-details.controller.js.map +1 -1
  16. package/dist/controllers/chatter-message.controller.d.ts +10 -13
  17. package/dist/controllers/chatter-message.controller.d.ts.map +1 -1
  18. package/dist/controllers/chatter-message.controller.js +19 -88
  19. package/dist/controllers/chatter-message.controller.js.map +1 -1
  20. package/dist/controllers/service.controller.js +2 -1
  21. package/dist/controllers/service.controller.js.map +1 -1
  22. package/dist/dtos/invoke-ai-prompt.dto.d.ts +1 -0
  23. package/dist/dtos/invoke-ai-prompt.dto.d.ts.map +1 -1
  24. package/dist/dtos/invoke-ai-prompt.dto.js +6 -1
  25. package/dist/dtos/invoke-ai-prompt.dto.js.map +1 -1
  26. package/dist/entities/chatter-message-details.entity.d.ts +1 -0
  27. package/dist/entities/chatter-message-details.entity.d.ts.map +1 -1
  28. package/dist/entities/chatter-message-details.entity.js +5 -1
  29. package/dist/entities/chatter-message-details.entity.js.map +1 -1
  30. package/dist/entities/chatter-message.entity.d.ts +4 -0
  31. package/dist/entities/chatter-message.entity.d.ts.map +1 -1
  32. package/dist/entities/chatter-message.entity.js +14 -1
  33. package/dist/entities/chatter-message.entity.js.map +1 -1
  34. package/dist/entities/user.entity.d.ts +1 -0
  35. package/dist/entities/user.entity.d.ts.map +1 -1
  36. package/dist/entities/user.entity.js +5 -1
  37. package/dist/entities/user.entity.js.map +1 -1
  38. package/dist/interfaces.d.ts +2 -1
  39. package/dist/interfaces.d.ts.map +1 -1
  40. package/dist/interfaces.js.map +1 -1
  41. package/dist/jobs/database/trigger-mcp-client-subscriber-database.service.d.ts +3 -2
  42. package/dist/jobs/database/trigger-mcp-client-subscriber-database.service.d.ts.map +1 -1
  43. package/dist/jobs/database/trigger-mcp-client-subscriber-database.service.js +61 -22
  44. package/dist/jobs/database/trigger-mcp-client-subscriber-database.service.js.map +1 -1
  45. package/dist/repository/chatter-message-details.repository.d.ts.map +1 -1
  46. package/dist/repository/chatter-message-details.repository.js +7 -3
  47. package/dist/repository/chatter-message-details.repository.js.map +1 -1
  48. package/dist/repository/chatter-message.repository.d.ts.map +1 -1
  49. package/dist/repository/chatter-message.repository.js +4 -0
  50. package/dist/repository/chatter-message.repository.js.map +1 -1
  51. package/dist/seeders/seed-data/solid-core-metadata.json +78 -5
  52. package/dist/services/ai-interaction.service.d.ts +2 -1
  53. package/dist/services/ai-interaction.service.d.ts.map +1 -1
  54. package/dist/services/ai-interaction.service.js +15 -3
  55. package/dist/services/ai-interaction.service.js.map +1 -1
  56. package/dist/services/authentication.service.d.ts +2 -3
  57. package/dist/services/authentication.service.d.ts.map +1 -1
  58. package/dist/services/authentication.service.js +4 -4
  59. package/dist/services/authentication.service.js.map +1 -1
  60. package/dist/services/chatter-message.service.d.ts +16 -3
  61. package/dist/services/chatter-message.service.d.ts.map +1 -1
  62. package/dist/services/chatter-message.service.js +120 -25
  63. package/dist/services/chatter-message.service.js.map +1 -1
  64. package/dist/services/refresh-token-ids-storage.service.d.ts +2 -1
  65. package/dist/services/refresh-token-ids-storage.service.d.ts.map +1 -1
  66. package/dist/services/refresh-token-ids-storage.service.js +6 -7
  67. package/dist/services/refresh-token-ids-storage.service.js.map +1 -1
  68. package/dist/tsconfig.tsbuildinfo +1 -1
  69. package/package.json +1 -1
  70. package/src/config/iam.config.ts +2 -2
  71. package/src/constants/chatter-message.constants.ts +11 -0
  72. package/src/controllers/ai-interaction.controller.ts +1 -1
  73. package/src/controllers/chatter-message-details.controller.ts +44 -44
  74. package/src/controllers/chatter-message.controller.ts +58 -38
  75. package/src/controllers/service.controller.ts +2 -2
  76. package/src/dtos/invoke-ai-prompt.dto.ts +5 -1
  77. package/src/entities/chatter-message-details.entity.ts +3 -0
  78. package/src/entities/chatter-message.entity.ts +9 -2
  79. package/src/entities/user.entity.ts +2 -0
  80. package/src/interfaces.ts +2 -1
  81. package/src/jobs/database/trigger-mcp-client-subscriber-database.service.ts +108 -25
  82. package/src/repository/chatter-message-details.repository.ts +6 -5
  83. package/src/repository/chatter-message.repository.ts +2 -0
  84. package/src/seeders/seed-data/solid-core-metadata.json +78 -5
  85. package/src/services/ai-interaction.service.ts +24 -3
  86. package/src/services/authentication.service.ts +9 -4
  87. package/src/services/chatter-message.service.ts +143 -24
  88. package/src/services/refresh-token-ids-storage.service.ts +11 -7
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@solidstarters/solid-core",
3
- "version": "1.2.173",
3
+ "version": "1.2.175",
4
4
  "description": "This module is a NestJS module containing all the required core providers required by a Solid application",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -32,7 +32,7 @@ export const jwtConfig = registerAs('jwt', () => {
32
32
  secret: process.env.IAM_JWT_SECRET,
33
33
  audience: process.env.IAM_JWT_TOKEN_AUDIENCE,
34
34
  issuer: process.env.IAM_JWT_TOKEN_ISSUER,
35
- accessTokenTtl: parseInt(process.env.IAM_JWT_ACCESS_TOKEN_TTL ?? '3600', 10),
36
- refreshTokenTtl: parseInt(process.env.IAM_JWT_REFRESH_TOKEN_TTL ?? '86400', 10),
35
+ accessTokenTtl: parseInt(process.env.IAM_JWT_ACCESS_TOKEN_TTL ?? '1200', 10), // 20 minutes
36
+ refreshTokenTtl: parseInt(process.env.IAM_JWT_REFRESH_TOKEN_TTL ?? '604800', 10), // 7 days
37
37
  };
38
38
  });
@@ -0,0 +1,11 @@
1
+ export const CHATTER_MESSAGE_TYPE = {
2
+ AUDIT: 'audit',
3
+ CUSTOM: 'custom',
4
+ } as const;
5
+
6
+ export const CHATTER_MESSAGE_SUBTYPE = {
7
+ AUDIT_INSERT: 'audit_insert',
8
+ AUDIT_UPDATE: 'audit_update',
9
+ AUDIT_DELETE: 'audit_delete',
10
+ CUSTOM: 'custom',
11
+ } as const;
@@ -95,7 +95,7 @@ export class AiInteractionController {
95
95
  @ApiBearerAuth("jwt")
96
96
  @Post('/trigger-mcp-client-job')
97
97
  async triggerMcpClientJob(@Body() dto: InvokeAiPromptDto, @ActiveUser() activeUser: ActiveUserData) {
98
- return this.service.triggerMcpClientJob(dto.prompt, activeUser.sub);
98
+ return this.service.triggerMcpClientJob(dto,activeUser.sub);
99
99
  }
100
100
 
101
101
  @ApiBearerAuth("jwt")
@@ -15,46 +15,46 @@ enum ShowSoftDeleted {
15
15
  export class ChatterMessageDetailsController {
16
16
  constructor(private readonly service: ChatterMessageDetailsService) {}
17
17
 
18
- @ApiBearerAuth("jwt")
19
- @Post()
20
- @UseInterceptors(AnyFilesInterceptor())
21
- create(@Body() createDto: CreateChatterMessageDetailsDto, @UploadedFiles() files: Array<Express.Multer.File>) {
22
- return this.service.create(createDto, files);
23
- }
18
+ // @ApiBearerAuth("jwt")
19
+ // @Post()
20
+ // @UseInterceptors(AnyFilesInterceptor())
21
+ // create(@Body() createDto: CreateChatterMessageDetailsDto, @UploadedFiles() files: Array<Express.Multer.File>) {
22
+ // return this.service.create(createDto, files);
23
+ // }
24
24
 
25
- @ApiBearerAuth("jwt")
26
- @Post('/bulk')
27
- @UseInterceptors(AnyFilesInterceptor())
28
- insertMany(@Body() createDtos: CreateChatterMessageDetailsDto[], @UploadedFiles() filesArray: Express.Multer.File[][] = []) {
29
- return this.service.insertMany(createDtos, filesArray);
30
- }
25
+ // @ApiBearerAuth("jwt")
26
+ // @Post('/bulk')
27
+ // @UseInterceptors(AnyFilesInterceptor())
28
+ // insertMany(@Body() createDtos: CreateChatterMessageDetailsDto[], @UploadedFiles() filesArray: Express.Multer.File[][] = []) {
29
+ // return this.service.insertMany(createDtos, filesArray);
30
+ // }
31
31
 
32
32
 
33
- @ApiBearerAuth("jwt")
34
- @Put(':id')
35
- @UseInterceptors(AnyFilesInterceptor())
36
- update(@Param('id') id: number, @Body() updateDto: UpdateChatterMessageDetailsDto, @UploadedFiles() files: Array<Express.Multer.File>) {
37
- return this.service.update(id, updateDto, files);
38
- }
33
+ // @ApiBearerAuth("jwt")
34
+ // @Put(':id')
35
+ // @UseInterceptors(AnyFilesInterceptor())
36
+ // update(@Param('id') id: number, @Body() updateDto: UpdateChatterMessageDetailsDto, @UploadedFiles() files: Array<Express.Multer.File>) {
37
+ // return this.service.update(id, updateDto, files);
38
+ // }
39
39
 
40
- @ApiBearerAuth("jwt")
41
- @Patch(':id')
42
- @UseInterceptors(AnyFilesInterceptor())
43
- partialUpdate(@Param('id') id: number, @Body() updateDto: UpdateChatterMessageDetailsDto, @UploadedFiles() files: Array<Express.Multer.File>) {
44
- return this.service.update(id, updateDto, files, true);
45
- }
40
+ // @ApiBearerAuth("jwt")
41
+ // @Patch(':id')
42
+ // @UseInterceptors(AnyFilesInterceptor())
43
+ // partialUpdate(@Param('id') id: number, @Body() updateDto: UpdateChatterMessageDetailsDto, @UploadedFiles() files: Array<Express.Multer.File>) {
44
+ // return this.service.update(id, updateDto, files, true);
45
+ // }
46
46
 
47
- @ApiBearerAuth("jwt")
48
- @Post('/bulk-recover')
49
- async recoverMany(@Body() ids: number[]) {
50
- return this.service.recoverMany(ids);
51
- }
47
+ // @ApiBearerAuth("jwt")
48
+ // @Post('/bulk-recover')
49
+ // async recoverMany(@Body() ids: number[]) {
50
+ // return this.service.recoverMany(ids);
51
+ // }
52
52
 
53
- @ApiBearerAuth("jwt")
54
- @Get('/recover/:id')
55
- async recover(@Param('id') id: number) {
56
- return this.service.recover(id);
57
- }
53
+ // @ApiBearerAuth("jwt")
54
+ // @Get('/recover/:id')
55
+ // async recover(@Param('id') id: number) {
56
+ // return this.service.recover(id);
57
+ // }
58
58
 
59
59
  @ApiBearerAuth("jwt")
60
60
  @ApiQuery({ name: 'showSoftDeleted', required: false, enum: ShowSoftDeleted })
@@ -77,16 +77,16 @@ export class ChatterMessageDetailsController {
77
77
  return this.service.findOne(+id, query);
78
78
  }
79
79
 
80
- @ApiBearerAuth("jwt")
81
- @Delete('/bulk')
82
- async deleteMany(@Body() ids: number[]) {
83
- return this.service.deleteMany(ids);
84
- }
80
+ // @ApiBearerAuth("jwt")
81
+ // @Delete('/bulk')
82
+ // async deleteMany(@Body() ids: number[]) {
83
+ // return this.service.deleteMany(ids);
84
+ // }
85
85
 
86
- @ApiBearerAuth("jwt")
87
- @Delete(':id')
88
- async delete(@Param('id') id: number) {
89
- return this.service.delete(id);
90
- }
86
+ // @ApiBearerAuth("jwt")
87
+ // @Delete(':id')
88
+ // async delete(@Param('id') id: number) {
89
+ // return this.service.delete(id);
90
+ // }
91
91
 
92
92
  }
@@ -7,6 +7,7 @@ import { UpdateChatterMessageDto } from '../dtos/update-chatter-message.dto';
7
7
  import { PostChatterMessageDto } from '../dtos/post-chatter-message.dto';
8
8
  import { SolidRequestContextDecorator } from 'src/decorators/solid-request-context.decorator';
9
9
  import { SolidRequestContextDto } from 'src/dtos/solid-request-context.dto';
10
+ import { Public } from 'src/decorators/public.decorator';
10
11
 
11
12
  enum ShowSoftDeleted {
12
13
  INCLUSIVE = "inclusive",
@@ -25,40 +26,59 @@ export class ChatterMessageController {
25
26
  return this.service.create(createDto, files);
26
27
  }
27
28
 
28
- @ApiBearerAuth("jwt")
29
- @Post('/bulk')
30
- @UseInterceptors(AnyFilesInterceptor())
31
- insertMany(@Body() createDtos: CreateChatterMessageDto[], @UploadedFiles() filesArray: Express.Multer.File[][] = []) {
32
- return this.service.insertMany(createDtos, filesArray);
33
- }
29
+ // @ApiBearerAuth("jwt")
30
+ // @Post('/bulk')
31
+ // @UseInterceptors(AnyFilesInterceptor())
32
+ // insertMany(@Body() createDtos: CreateChatterMessageDto[], @UploadedFiles() filesArray: Express.Multer.File[][] = []) {
33
+ // return this.service.insertMany(createDtos, filesArray);
34
+ // }
34
35
 
35
36
 
36
- @ApiBearerAuth("jwt")
37
- @Put(':id')
38
- @UseInterceptors(AnyFilesInterceptor())
39
- update(@Param('id') id: number, @Body() updateDto: UpdateChatterMessageDto, @UploadedFiles() files: Array<Express.Multer.File>) {
40
- return this.service.update(id, updateDto, files);
41
- }
37
+ // @ApiBearerAuth("jwt")
38
+ // @Put(':id')
39
+ // @UseInterceptors(AnyFilesInterceptor())
40
+ // update(@Param('id') id: number, @Body() updateDto: UpdateChatterMessageDto, @UploadedFiles() files: Array<Express.Multer.File>) {
41
+ // return this.service.update(id, updateDto, files);
42
+ // }
42
43
 
43
- @ApiBearerAuth("jwt")
44
- @Patch(':id')
45
- @UseInterceptors(AnyFilesInterceptor())
46
- partialUpdate(@Param('id') id: number, @Body() updateDto: UpdateChatterMessageDto, @UploadedFiles() files: Array<Express.Multer.File>) {
47
- return this.service.update(id, updateDto, files, true);
48
- }
44
+ // @ApiBearerAuth("jwt")
45
+ // @Patch(':id')
46
+ // @UseInterceptors(AnyFilesInterceptor())
47
+ // partialUpdate(@Param('id') id: number, @Body() updateDto: UpdateChatterMessageDto, @UploadedFiles() files: Array<Express.Multer.File>) {
48
+ // return this.service.update(id, updateDto, files, true);
49
+ // }
49
50
 
50
- @ApiBearerAuth("jwt")
51
- @Post('/bulk-recover')
52
- async recoverMany(@Body() ids: number[]) {
53
- return this.service.recoverMany(ids);
54
- }
51
+ // @ApiBearerAuth("jwt")
52
+ // @Post('/bulk-recover')
53
+ // async recoverMany(@Body() ids: number[]) {
54
+ // return this.service.recoverMany(ids);
55
+ // }
55
56
 
56
- @ApiBearerAuth("jwt")
57
- @Get('/recover/:id')
58
- async recover(@Param('id') id: number) {
59
- return this.service.recover(id);
57
+ // @ApiBearerAuth("jwt")
58
+ // @Get('/recover/:id')
59
+ // async recover(@Param('id') id: number) {
60
+ // return this.service.recover(id);
61
+ // }
62
+
63
+ @Public()
64
+ @Get('/getChatterMessages/:entityId/:entityName')
65
+ @ApiQuery({ name: 'showSoftDeleted', required: false, enum: ShowSoftDeleted })
66
+ @ApiQuery({ name: 'limit', required: false, type: Number })
67
+ @ApiQuery({ name: 'offset', required: false, type: Number })
68
+ @ApiQuery({ name: 'fields', required: false, type: Array })
69
+ @ApiQuery({ name: 'sort', required: false, type: Array })
70
+ @ApiQuery({ name: 'groupBy', required: false, type: Array })
71
+ @ApiQuery({ name: 'populate', required: false, type: Array })
72
+ @ApiQuery({ name: 'populateMedia', required: false, type: Array })
73
+ @ApiQuery({ name: 'filters', required: false, type: Array })
74
+ async getChatterMessages(
75
+ @Param('entityId') entityId: number,
76
+ @Param('entityName') entityName: string,
77
+ @Query() query: any
78
+ ) {
79
+ return this.service.getChatterMessages(entityId, entityName, query);
60
80
  }
61
-
81
+
62
82
  @ApiBearerAuth("jwt")
63
83
  @ApiQuery({ name: 'showSoftDeleted', required: false, enum: ShowSoftDeleted })
64
84
  @ApiQuery({ name: 'limit', required: false, type: Number })
@@ -80,17 +100,17 @@ export class ChatterMessageController {
80
100
  return this.service.findOne(+id, query);
81
101
  }
82
102
 
83
- @ApiBearerAuth("jwt")
84
- @Delete('/bulk')
85
- async deleteMany(@Body() ids: number[]) {
86
- return this.service.deleteMany(ids);
87
- }
103
+ // @ApiBearerAuth("jwt")
104
+ // @Delete('/bulk')
105
+ // async deleteMany(@Body() ids: number[]) {
106
+ // return this.service.deleteMany(ids);
107
+ // }
88
108
 
89
- @ApiBearerAuth("jwt")
90
- @Delete(':id')
91
- async delete(@Param('id') id: number) {
92
- return this.service.delete(id);
93
- }
109
+ // @ApiBearerAuth("jwt")
110
+ // @Delete(':id')
111
+ // async delete(@Param('id') id: number) {
112
+ // return this.service.delete(id);
113
+ // }
94
114
 
95
115
  @ApiBearerAuth("jwt")
96
116
  @Post('post')
@@ -36,9 +36,9 @@ export class ServiceController {
36
36
  // If failure then decide shape to return.
37
37
 
38
38
  const threadId = `pingPongTxn-${activeUser.sub}`;
39
-
39
+ const dto ={prompt:"Can you do 1 + 1", moduleName:"solidCoreModule"}
40
40
  const { queueMessageId, aiInteractionId } = await this.aiInteractionService.triggerMcpClientJob(
41
- `Can you do 1 + 1`,
41
+ dto,
42
42
  activeUser.sub,
43
43
  true,
44
44
  threadId
@@ -1,6 +1,10 @@
1
- import { IsString } from 'class-validator';
1
+ import { IsOptional, IsString } from 'class-validator';
2
2
 
3
3
  export class InvokeAiPromptDto {
4
4
  @IsString()
5
5
  prompt: string;
6
+
7
+ @IsOptional()
8
+ @IsString()
9
+ moduleName: string;
6
10
  }
@@ -22,4 +22,7 @@ newValueDisplay: string;
22
22
 
23
23
  @Column({ type: "varchar" })
24
24
  fieldName: string;
25
+
26
+ @Column({ type: "text", nullable: true })
27
+ fieldDisplayName: string;
25
28
  }
@@ -1,6 +1,7 @@
1
1
  import { CommonEntity } from 'src/entities/common.entity'
2
- import { Entity, Column, Index, JoinColumn, ManyToOne } from 'typeorm';
2
+ import {Entity, Column, Index, JoinColumn, ManyToOne, OneToMany} from 'typeorm';
3
3
  import { User } from 'src/entities/user.entity'
4
+ import { ChatterMessageDetails } from './chatter-message-details.entity';
4
5
 
5
6
  @Entity("ss_chatter_message")
6
7
  export class ChatterMessage extends CommonEntity {
@@ -8,7 +9,7 @@ export class ChatterMessage extends CommonEntity {
8
9
  @Column({ type: "varchar" })
9
10
  messageType: string; // audit | custom
10
11
  @Column({ type: "varchar" })
11
- messageSubType: string; // update | insert | delete | post_message
12
+ messageSubType: string; // audit_update | audit_insert | audit_delete | custom
12
13
  @Column({ type: "text" })
13
14
  messageBody: string;
14
15
  @Index()
@@ -19,4 +20,10 @@ export class ChatterMessage extends CommonEntity {
19
20
  @ManyToOne(() => User, { onDelete: "CASCADE", nullable: true })
20
21
  @JoinColumn()
21
22
  user: User;
23
+ @OneToMany(() => ChatterMessageDetails, (chatterMessageDetails) => chatterMessageDetails.chatterMessage, { cascade: true })
24
+ chatterMessageDetails: ChatterMessageDetails[];
25
+ @Column({ type: "text", nullable: true })
26
+ modelDisplayName: string;
27
+ @Column({ type: "text", nullable: true })
28
+ modelUserKey: string;
22
29
  }
@@ -111,4 +111,6 @@ export class User extends CommonEntity {
111
111
  // dont send to client
112
112
  @Column({ type: "timestamp", nullable: true })
113
113
  rehashedAt: Date;
114
+ @Expose()
115
+ _media: any;
114
116
  }
package/src/interfaces.ts CHANGED
@@ -66,6 +66,7 @@ export interface CodeGenerationOptions {
66
66
 
67
67
  export interface TriggerMcpClientOptions {
68
68
  aiInteractionId: number;
69
+ moduleName:string;
69
70
  }
70
71
 
71
72
  export interface McpResponse {
@@ -77,7 +78,7 @@ export interface McpResponse {
77
78
  tool_calls?: any[];
78
79
  duration_ms?: number;
79
80
  errors?: string[];
80
- trace?: string[];
81
+ error_trace?: string[];
81
82
  content_type?: string;
82
83
  }
83
84
 
@@ -3,7 +3,7 @@ import { Injectable, Logger } from '@nestjs/common';
3
3
  import { QueueMessage } from 'src/interfaces/mq';
4
4
  import { MqMessageService } from '../../services/mq-message.service';
5
5
  import { MqMessageQueueService } from '../../services/mq-message-queue.service';
6
- import { QueuesModuleOptions, TriggerMcpClientOptions } from "../../interfaces";
6
+ import { McpResponse, QueuesModuleOptions, TriggerMcpClientOptions } from "../../interfaces";
7
7
  import { DatabaseSubscriber } from 'src/services/queues/database-subscriber.service';
8
8
  import triggerMcpClientQueueOptions from "./trigger-mcp-client-queue-options";
9
9
  import { AiInteractionService } from 'src/services/ai-interaction.service';
@@ -28,6 +28,36 @@ export class TriggerMcpClientSubscriberDatabase extends DatabaseSubscriber<Trigg
28
28
  }
29
29
  }
30
30
 
31
+ cleanNestedResponse(aiResponse: McpResponse) {
32
+ let nestedResponse: any;
33
+
34
+ try {
35
+ let raw = aiResponse.response;
36
+
37
+ if (typeof raw === "string") {
38
+ raw = raw.trim();
39
+ try {
40
+ // Try to parse as JSON
41
+ nestedResponse = JSON.parse(raw);
42
+ } catch {
43
+ // Not JSON, just keep as string
44
+ nestedResponse = raw;
45
+ }
46
+ } else if (typeof raw === "object" && raw !== null) {
47
+ // Already JSON
48
+ nestedResponse = raw;
49
+ } else {
50
+ // Fallback
51
+ nestedResponse = String(raw);
52
+ }
53
+ } catch (err) {
54
+ this.triggerMcpClientSubscriberLogger.error("Error processing AI response:", err);
55
+ nestedResponse = `Error handling response: ${err?.message || String(err)}`;
56
+ }
57
+
58
+ return nestedResponse;
59
+ }
60
+
31
61
  async subscribe(message: QueueMessage<TriggerMcpClientOptions>) {
32
62
  this.triggerMcpClientSubscriberLogger.debug(`Received message: ${JSON.stringify(message)}`);
33
63
 
@@ -48,50 +78,103 @@ export class TriggerMcpClientSubscriberDatabase extends DatabaseSubscriber<Trigg
48
78
  // Use this to invoke our mcp client
49
79
  // TODO: try / catch ...
50
80
  // Handle the rejection gracefully...
51
- const aiResponse = await this.aiInteractionService.runMcpPrompt(prompt);
81
+
82
+ // We create the aiInteraction entry first
83
+ const genAiInteraction = await this.aiInteractionService.create({
84
+ userId: aiInteraction.user.id,
85
+ threadId: aiInteraction.threadId,
86
+ parentInteractionId: aiInteraction.id,
87
+ role: 'gen-ai',
88
+ message: '...', // Updated in the tool
89
+ contentType: '', // Updated in the tool
90
+ errorMessage: '', // Updated after we receive the response
91
+ modelUsed: '', // Updated after we receive the response
92
+ responseTimeMs: 0, // Updated after we receive the response
93
+ metadata: '', // Updated in the tool
94
+ isApplied: false, // Updated after we receive the response
95
+ status: '' // Updated after we receive the response
96
+ });
97
+
98
+ const finalPrompt = `
99
+ # User Prompt:
100
+ ${prompt}
101
+
102
+ # System Instructions:
103
+ - aiInteractionId: ${genAiInteraction.id}
104
+ - moduleName:${message.payload.moduleName}
105
+ - You will be invoking tools if needed.
106
+ - If a tool is invoked, you must return **exactly** the raw output from the tool, without any additional formatting, commentary, or text.
107
+ - Do not wrap the result in quotes, JSON, or markdown fences.
108
+ - Do not explain what the result means.
109
+ - Your final response must be identical to the tool output.
110
+ `
111
+
112
+ const aiResponse = await this.aiInteractionService.runMcpPrompt(finalPrompt);
52
113
  this.triggerMcpClientSubscriberLogger.log(`aiResponse: `);
53
114
  this.triggerMcpClientSubscriberLogger.log(JSON.stringify(aiResponse));
54
115
 
55
116
  if (!aiResponse.success) {
56
117
  this.triggerMcpClientSubscriberLogger.log(`Gen ai has returned with a false status code`);
57
118
 
58
- const errorsStr = aiResponse.errors.join('; ');
59
-
60
- await this.aiInteractionService.create({
61
- userId: aiInteraction.user.id,
62
- threadId: aiInteraction.threadId,
63
- parentInteractionId: aiInteraction.id,
64
- role: 'gen-ai',
65
- message: '-',
66
- contentType: aiResponse.content_type,
67
- errorMessage: errorsStr,
119
+ const errorsStr = aiResponse.errors.join('\n ');
120
+ const errorTrace = aiResponse.error_trace.join('\n');
121
+
122
+ // await this.aiInteractionService.create({
123
+ // userId: aiInteraction.user.id,
124
+ // threadId: aiInteraction.threadId,
125
+ // parentInteractionId: aiInteraction.id,
126
+ // role: 'gen-ai',
127
+ // message: '-',
128
+ // contentType: aiResponse.content_type,
129
+ // errorMessage: errorsStr,
130
+ // modelUsed: aiResponse.model,
131
+ // responseTimeMs: aiResponse.duration_ms,
132
+ // metadata: JSON.stringify(aiResponse, null, 2),
133
+ // isApplied: aiInteraction.isApplied,
134
+ // status: aiResponse.success ? 'succeeded' : 'failed'
135
+ // });
136
+
137
+ // TODO: Update the previously created genAiInteraction record with the respective error fields and save to DB
138
+ await this.aiInteractionService.update(genAiInteraction.id, {
139
+ // contentType: aiResponse.content_type,
140
+ errorMessage: `${errorsStr}\n\n${errorTrace}`,
68
141
  modelUsed: aiResponse.model,
69
142
  responseTimeMs: aiResponse.duration_ms,
70
- metadata: JSON.stringify(aiResponse, null, 2),
71
143
  isApplied: aiInteraction.isApplied,
72
144
  status: aiResponse.success ? 'succeeded' : 'failed'
73
- });
145
+ }, [], true);
74
146
 
75
147
  // update the job entry with failure... raising an error will lead the job to be marked as failed...
76
148
  throw new Error(errorsStr);
77
149
  }
78
150
  else {
79
- let nestedResponse = aiResponse.response.trim();
80
-
81
- const genAiInteraction = await this.aiInteractionService.create({
82
- userId: aiInteraction.user.id,
83
- threadId: aiInteraction.threadId,
84
- parentInteractionId: aiInteraction.id,
85
- role: 'gen-ai',
86
- message: nestedResponse,
87
- contentType: aiResponse.content_type,
151
+ // let nestedResponse = this.cleanNestedResponse(aiResponse);
152
+
153
+ // const genAiInteraction = await this.aiInteractionService.create({
154
+ // userId: aiInteraction.user.id,
155
+ // threadId: aiInteraction.threadId,
156
+ // parentInteractionId: aiInteraction.id,
157
+ // role: 'gen-ai',
158
+ // message: nestedResponse,
159
+ // contentType: aiResponse.content_type,
160
+ // errorMessage: '',
161
+ // modelUsed: aiResponse.model,
162
+ // responseTimeMs: aiResponse.duration_ms,
163
+ // metadata: JSON.stringify(aiResponse, null, 2),
164
+ // isApplied: aiInteraction.isApplied,
165
+ // status: aiResponse.success ? 'succeeded' : 'failed'
166
+ // });
167
+
168
+ // TODO: Update the previously created genAiInteraction record with the respective success fields and save to DB
169
+ await this.aiInteractionService.update(genAiInteraction.id, {
170
+ // contentType: aiResponse.content_type,
88
171
  errorMessage: '',
172
+ // message: nestedResponse,
89
173
  modelUsed: aiResponse.model,
90
174
  responseTimeMs: aiResponse.duration_ms,
91
- metadata: JSON.stringify(aiResponse, null, 2),
92
175
  isApplied: aiInteraction.isApplied,
93
176
  status: aiResponse.success ? 'succeeded' : 'failed'
94
- });
177
+ }, [], true);
95
178
 
96
179
  // If the human interaction was with isAutoApply=true, then we can go ahead and autoApply.
97
180
  if (aiInteraction.isAutoApply) {
@@ -37,17 +37,16 @@ export class ChatterMessageDetailsRepository extends SolidBaseRepository<Chatter
37
37
  ): SelectQueryBuilder<ChatterMessageDetails> {
38
38
  const activeUser = this.requestContextService.getActiveUser();
39
39
  let qb = super.createQueryBuilder(alias, queryRunner);
40
-
41
- // Join the real relation so we can access co_model_* fields
42
- qb = qb.leftJoin(`${alias}.chatterMessage`, 'chatterMessage');
40
+ if (!activeUser) return qb;
43
41
 
44
42
  // Example: join the "client" co-model (pass whatever co-model name you need)
45
43
  const [coModelName, coModelAlias] = this.getCoModelNameAndAlias();
44
+ if (!coModelName) return qb;
46
45
 
46
+ // Join the real relation so we can access co_model_* fields
47
+ qb = qb.leftJoin(`${alias}.chatterMessage`, 'chatterMessage');
47
48
  qb = this.leftJoinCoModel(qb, coModelName, 'chatterMessage');
48
49
 
49
- if (!activeUser) return qb;
50
-
51
50
  // If your security rules should apply to the co-model rows, pass the co-model alias.
52
51
  // Here we use the co-model name "client" both as model key and alias base for consistency.
53
52
  return this.securityRuleRepository.applySecurityRules(
@@ -102,6 +101,8 @@ export class ChatterMessageDetailsRepository extends SolidBaseRepository<Chatter
102
101
  if (!requestFilter) return [undefined, undefined];
103
102
 
104
103
  const coModelName = get(requestFilter, this.CO_MODEL_NAME_PATH);
104
+ if (!coModelName) return [undefined, undefined];
105
+
105
106
  const alias = camelize(coModelName);
106
107
  return [coModelName, alias];
107
108
  }
@@ -26,6 +26,7 @@ export class ChatterMessageRepository extends SolidBaseRepository<ChatterMessage
26
26
 
27
27
  //Left join on the associated chatter model entity
28
28
  const [coModelName, coModelAlias] = this.getCoModelNameAndAlias();
29
+ if (!coModelName) return qb;
29
30
  qb = this.leftJoinCoModel(qb, coModelName);
30
31
 
31
32
  return this.securityRuleRepository.applySecurityRules(
@@ -61,6 +62,7 @@ export class ChatterMessageRepository extends SolidBaseRepository<ChatterMessage
61
62
  if (!requestFilter) return [undefined, undefined];
62
63
 
63
64
  const coModelName = get(requestFilter, this.CO_MODEL_NAME_PATH);
65
+ if (!coModelName) return [undefined, undefined];
64
66
  const alias = camelize(coModelName);
65
67
  return [coModelName, alias];
66
68
  }