@vezlo/assistant-server 2.9.0 → 2.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (56) hide show
  1. package/README.md +10 -0
  2. package/database-schema.sql +44 -0
  3. package/dist/src/bootstrap/initializeServices.d.ts +7 -0
  4. package/dist/src/bootstrap/initializeServices.d.ts.map +1 -1
  5. package/dist/src/bootstrap/initializeServices.js +25 -4
  6. package/dist/src/bootstrap/initializeServices.js.map +1 -1
  7. package/dist/src/controllers/ChatController.d.ts +6 -0
  8. package/dist/src/controllers/ChatController.d.ts.map +1 -1
  9. package/dist/src/controllers/ChatController.js +91 -17
  10. package/dist/src/controllers/ChatController.js.map +1 -1
  11. package/dist/src/controllers/DatabaseToolConfigController.d.ts +81 -0
  12. package/dist/src/controllers/DatabaseToolConfigController.d.ts.map +1 -0
  13. package/dist/src/controllers/DatabaseToolConfigController.js +524 -0
  14. package/dist/src/controllers/DatabaseToolConfigController.js.map +1 -0
  15. package/dist/src/controllers/KnowledgeController.js +4 -4
  16. package/dist/src/controllers/KnowledgeController.js.map +1 -1
  17. package/dist/src/migrations/011_create_database_tool_configs.d.ts +4 -0
  18. package/dist/src/migrations/011_create_database_tool_configs.d.ts.map +1 -0
  19. package/dist/src/migrations/011_create_database_tool_configs.js +49 -0
  20. package/dist/src/migrations/011_create_database_tool_configs.js.map +1 -0
  21. package/dist/src/server.js +399 -0
  22. package/dist/src/server.js.map +1 -1
  23. package/dist/src/services/AIService.d.ts +6 -0
  24. package/dist/src/services/AIService.d.ts.map +1 -1
  25. package/dist/src/services/AIService.js +30 -2
  26. package/dist/src/services/AIService.js.map +1 -1
  27. package/dist/src/services/DatabaseToolConfigService.d.ts +133 -0
  28. package/dist/src/services/DatabaseToolConfigService.d.ts.map +1 -0
  29. package/dist/src/services/DatabaseToolConfigService.js +442 -0
  30. package/dist/src/services/DatabaseToolConfigService.js.map +1 -0
  31. package/dist/src/services/DatabaseToolService.d.ts +75 -0
  32. package/dist/src/services/DatabaseToolService.d.ts.map +1 -0
  33. package/dist/src/services/DatabaseToolService.js +299 -0
  34. package/dist/src/services/DatabaseToolService.js.map +1 -0
  35. package/dist/src/services/IntentService.d.ts +12 -1
  36. package/dist/src/services/IntentService.d.ts.map +1 -1
  37. package/dist/src/services/IntentService.js +36 -5
  38. package/dist/src/services/IntentService.js.map +1 -1
  39. package/dist/src/services/KnowledgeBaseService.d.ts +4 -0
  40. package/dist/src/services/KnowledgeBaseService.d.ts.map +1 -1
  41. package/dist/src/services/KnowledgeBaseService.js +5 -1
  42. package/dist/src/services/KnowledgeBaseService.js.map +1 -1
  43. package/dist/src/services/ResponseGenerationService.d.ts +11 -4
  44. package/dist/src/services/ResponseGenerationService.d.ts.map +1 -1
  45. package/dist/src/services/ResponseGenerationService.js +51 -7
  46. package/dist/src/services/ResponseGenerationService.js.map +1 -1
  47. package/dist/src/services/ResponseStreamingService.d.ts +13 -1
  48. package/dist/src/services/ResponseStreamingService.d.ts.map +1 -1
  49. package/dist/src/services/ResponseStreamingService.js +50 -9
  50. package/dist/src/services/ResponseStreamingService.js.map +1 -1
  51. package/dist/src/services/ValidationService.d.ts +16 -0
  52. package/dist/src/services/ValidationService.d.ts.map +1 -0
  53. package/dist/src/services/ValidationService.js +83 -0
  54. package/dist/src/services/ValidationService.js.map +1 -0
  55. package/env.example +9 -0
  56. package/package.json +2 -1
package/README.md CHANGED
@@ -32,10 +32,12 @@ See [CHANGELOG.md](./CHANGELOG.md) for complete migration guide.
32
32
  ## 🏗️ Architecture
33
33
 
34
34
  - **Backend APIs** - RESTful API endpoints for AI chat and knowledge management
35
+ - **AI Response Validation** - LLM-as-Judge validation with developer/user modes via `@vezlo/ai-validator`
35
36
  - **Real-time Communication** - WebSocket support for live chat with Supabase Realtime broadcasting
36
37
  - **Human Agent Handoff** - Agent join/leave workflows with realtime status updates and message synchronization
37
38
  - **Advanced RAG System** - Chunk-based semantic search with adjacent retrieval using OpenAI text-embedding-3-large (3072 dims) and pgvector
38
39
  - **Conversation Management** - Persistent conversation history with agent support
40
+ - **Database Tools** - Connect external Supabase databases for natural language data queries ([see docs](./docs/DATABASE_TOOLS.md))
39
41
  - **Slack Integration** - Direct query bot with full AI responses, conversation history, and reaction-based feedback ([setup guide](./docs/SLACK_INTEGRATION.md))
40
42
  - **Feedback System** - Message rating and improvement tracking
41
43
  - **Database Migrations** - Knex.js migration system for schema management
@@ -151,6 +153,14 @@ AI_MODEL=gpt-4o
151
153
 
152
154
  # Migration Security
153
155
  MIGRATION_SECRET_KEY=your-secure-migration-key-here
156
+
157
+ # AI Response Validation (Optional)
158
+ AI_VALIDATION_ENABLED=false
159
+
160
+ # Developer Mode (Optional)
161
+ # true = Strict code grounding for technical queries
162
+ # false = User-friendly generic responses
163
+ DEVELOPER_MODE=false
154
164
  ```
155
165
 
156
166
  #### 3. Run Database Migrations (Recommended)
@@ -66,6 +66,10 @@ INSERT INTO knex_migrations (name, batch, migration_time)
66
66
  SELECT '010_add_slack_fields.ts', 1, NOW()
67
67
  WHERE NOT EXISTS (SELECT 1 FROM knex_migrations WHERE name = '010_add_slack_fields.ts');
68
68
 
69
+ INSERT INTO knex_migrations (name, batch, migration_time)
70
+ SELECT '011_create_database_tool_configs.ts', 1, NOW()
71
+ WHERE NOT EXISTS (SELECT 1 FROM knex_migrations WHERE name = '011_create_database_tool_configs.ts');
72
+
69
73
  -- Set migration lock to unlocked (0 = unlocked, 1 = locked)
70
74
  INSERT INTO knex_migrations_lock (index, is_locked)
71
75
  VALUES (1, 0)
@@ -617,3 +621,43 @@ BEGIN
617
621
  RETURN result;
618
622
  END;
619
623
  $$;
624
+
625
+ -- ============================================================================
626
+ -- DATABASE TOOLS SCHEMA (Migration 011)
627
+ -- ============================================================================
628
+
629
+ -- External database configurations
630
+ CREATE TABLE IF NOT EXISTS vezlo_database_tool_configs (
631
+ id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
632
+ company_id BIGINT NOT NULL REFERENCES vezlo_companies(id) ON DELETE CASCADE,
633
+ db_url_encrypted TEXT NOT NULL,
634
+ db_key_encrypted TEXT NOT NULL,
635
+ enabled BOOLEAN DEFAULT true,
636
+ created_at TIMESTAMPTZ DEFAULT NOW(),
637
+ updated_at TIMESTAMPTZ DEFAULT NOW()
638
+ );
639
+
640
+ CREATE INDEX IF NOT EXISTS idx_database_tool_configs_company_id ON vezlo_database_tool_configs(company_id);
641
+
642
+ -- Individual tool configurations
643
+ CREATE TABLE IF NOT EXISTS vezlo_database_tools (
644
+ id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
645
+ config_id UUID NOT NULL REFERENCES vezlo_database_tool_configs(id) ON DELETE CASCADE,
646
+ table_name TEXT NOT NULL,
647
+ tool_name TEXT NOT NULL,
648
+ tool_description TEXT,
649
+ columns JSONB NOT NULL,
650
+ id_column TEXT NOT NULL DEFAULT 'id',
651
+ id_column_type TEXT NOT NULL DEFAULT 'integer',
652
+ enabled BOOLEAN DEFAULT true,
653
+ requires_user_context BOOLEAN DEFAULT false,
654
+ user_filter_column TEXT,
655
+ user_filter_type TEXT,
656
+ user_context_key TEXT,
657
+ created_at TIMESTAMPTZ DEFAULT NOW(),
658
+ updated_at TIMESTAMPTZ DEFAULT NOW(),
659
+ UNIQUE(config_id, table_name)
660
+ );
661
+
662
+ CREATE INDEX IF NOT EXISTS idx_database_tools_config_id ON vezlo_database_tools(config_id);
663
+ CREATE INDEX IF NOT EXISTS idx_database_tools_enabled ON vezlo_database_tools(enabled);
@@ -13,6 +13,9 @@ import { CompanyService } from '../services/CompanyService';
13
13
  import { CompanyController } from '../controllers/CompanyController';
14
14
  import { SlackService } from '../services/SlackService';
15
15
  import { SlackController } from '../controllers/SlackController';
16
+ import { ValidationService } from '../services/ValidationService';
17
+ import { DatabaseToolConfigService } from '../services/DatabaseToolConfigService';
18
+ import { DatabaseToolConfigController } from '../controllers/DatabaseToolConfigController';
16
19
  export interface ServiceInitOptions {
17
20
  supabase: SupabaseClient;
18
21
  tablePrefix?: string;
@@ -30,6 +33,9 @@ export interface InitializedCoreServices {
30
33
  companyService: CompanyService;
31
34
  citationService: CitationService;
32
35
  slackService: SlackService;
36
+ validationService: ValidationService;
37
+ databaseToolService: any;
38
+ databaseToolConfigService: DatabaseToolConfigService;
33
39
  };
34
40
  controllers: {
35
41
  chatController: ChatController;
@@ -38,6 +44,7 @@ export interface InitializedCoreServices {
38
44
  apiKeyController: ApiKeyController;
39
45
  companyController: CompanyController;
40
46
  slackController: SlackController;
47
+ databaseToolConfigController: DatabaseToolConfigController;
41
48
  };
42
49
  config: {
43
50
  chatHistoryLength: number;
@@ -1 +1 @@
1
- {"version":3,"file":"initializeServices.d.ts","sourceRoot":"","sources":["../../../src/bootstrap/initializeServices.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAEvD,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAC3D,OAAO,EAAE,oBAAoB,EAAE,MAAM,kCAAkC,CAAC;AACxE,OAAO,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAC9D,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAClD,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AACtD,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAC/D,OAAO,EAAE,mBAAmB,EAAE,MAAM,oCAAoC,CAAC;AACzE,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAC/D,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAC1D,OAAO,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AACnE,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAC5D,OAAO,EAAE,iBAAiB,EAAE,MAAM,kCAAkC,CAAC;AAGrE,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AACxD,OAAO,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAC;AAEjE,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,cAAc,CAAC;IACzB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,mBAAmB,CAAC,EAAE,MAAM,CAAC;CAC9B;AAED,MAAM,WAAW,uBAAuB;IACtC,QAAQ,EAAE;QACR,OAAO,EAAE,cAAc,CAAC;QACxB,aAAa,EAAE,oBAAoB,CAAC;QACpC,SAAS,EAAE,SAAS,CAAC;QACrB,WAAW,EAAE,WAAW,CAAC;QACzB,aAAa,EAAE,aAAa,CAAC;QAC7B,cAAc,EAAE,cAAc,CAAC;QAC/B,eAAe,EAAE,eAAe,CAAC;QACjC,YAAY,EAAE,YAAY,CAAC;KAC5B,CAAC;IACF,WAAW,EAAE;QACX,cAAc,EAAE,cAAc,CAAC;QAC/B,mBAAmB,EAAE,mBAAmB,CAAC;QACzC,cAAc,EAAE,cAAc,CAAC;QAC/B,gBAAgB,EAAE,gBAAgB,CAAC;QACnC,iBAAiB,EAAE,iBAAiB,CAAC;QACrC,eAAe,EAAE,eAAe,CAAC;KAClC,CAAC;IACF,MAAM,EAAE;QACN,iBAAiB,EAAE,MAAM,CAAC;KAC3B,CAAC;CACH;AAKD,wBAAgB,oBAAoB,IAAI,MAAM,CAa7C;AAED,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,kBAAkB,GAAG,uBAAuB,CAuH3F"}
1
+ {"version":3,"file":"initializeServices.d.ts","sourceRoot":"","sources":["../../../src/bootstrap/initializeServices.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAEvD,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAC3D,OAAO,EAAE,oBAAoB,EAAE,MAAM,kCAAkC,CAAC;AACxE,OAAO,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAC9D,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAClD,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AACtD,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAC/D,OAAO,EAAE,mBAAmB,EAAE,MAAM,oCAAoC,CAAC;AACzE,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAC/D,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAC1D,OAAO,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AACnE,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAC5D,OAAO,EAAE,iBAAiB,EAAE,MAAM,kCAAkC,CAAC;AAGrE,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AACxD,OAAO,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAC;AACjE,OAAO,EAAE,iBAAiB,EAAE,MAAM,+BAA+B,CAAC;AAElE,OAAO,EAAE,yBAAyB,EAAE,MAAM,uCAAuC,CAAC;AAClF,OAAO,EAAE,4BAA4B,EAAE,MAAM,6CAA6C,CAAC;AAE3F,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,cAAc,CAAC;IACzB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,mBAAmB,CAAC,EAAE,MAAM,CAAC;CAC9B;AAED,MAAM,WAAW,uBAAuB;IACtC,QAAQ,EAAE;QACR,OAAO,EAAE,cAAc,CAAC;QACxB,aAAa,EAAE,oBAAoB,CAAC;QACpC,SAAS,EAAE,SAAS,CAAC;QACrB,WAAW,EAAE,WAAW,CAAC;QACzB,aAAa,EAAE,aAAa,CAAC;QAC7B,cAAc,EAAE,cAAc,CAAC;QAC/B,eAAe,EAAE,eAAe,CAAC;QACjC,YAAY,EAAE,YAAY,CAAC;QAC3B,iBAAiB,EAAE,iBAAiB,CAAC;QACrC,mBAAmB,EAAE,GAAG,CAAC;QACzB,yBAAyB,EAAE,yBAAyB,CAAC;KACtD,CAAC;IACF,WAAW,EAAE;QACX,cAAc,EAAE,cAAc,CAAC;QAC/B,mBAAmB,EAAE,mBAAmB,CAAC;QACzC,cAAc,EAAE,cAAc,CAAC;QAC/B,gBAAgB,EAAE,gBAAgB,CAAC;QACnC,iBAAiB,EAAE,iBAAiB,CAAC;QACrC,eAAe,EAAE,eAAe,CAAC;QACjC,4BAA4B,EAAE,4BAA4B,CAAC;KAC5D,CAAC;IACF,MAAM,EAAE;QACN,iBAAiB,EAAE,MAAM,CAAC;KAC3B,CAAC;CACH;AAKD,wBAAgB,oBAAoB,IAAI,MAAM,CAa7C;AAED,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,kBAAkB,GAAG,uBAAuB,CA8I3F"}
@@ -22,6 +22,10 @@ const IntentService_1 = require("../services/IntentService");
22
22
  const RealtimePublisher_1 = require("../services/RealtimePublisher");
23
23
  const SlackService_1 = require("../services/SlackService");
24
24
  const SlackController_1 = require("../controllers/SlackController");
25
+ const ValidationService_1 = require("../services/ValidationService");
26
+ const DatabaseToolService_1 = require("../services/DatabaseToolService");
27
+ const DatabaseToolConfigService_1 = require("../services/DatabaseToolConfigService");
28
+ const DatabaseToolConfigController_1 = require("../controllers/DatabaseToolConfigController");
25
29
  const DEFAULT_CHAT_HISTORY_LENGTH = 2;
26
30
  const DEFAULT_CONVERSATION_TIMEOUT = 3600000; // 1 hour
27
31
  function getChatHistoryLength() {
@@ -69,6 +73,12 @@ function initializeCoreServices(options) {
69
73
  maxTokens: aiMaxTokens,
70
74
  knowledgeBaseService: knowledgeBase
71
75
  });
76
+ // Initialize Database Tool Config service
77
+ const databaseToolConfigService = new DatabaseToolConfigService_1.DatabaseToolConfigService(supabase);
78
+ // Initialize external database tool service (dynamic)
79
+ const databaseToolService = new DatabaseToolService_1.DatabaseToolService(supabase, databaseToolConfigService);
80
+ aiService.setDatabaseToolService(databaseToolService);
81
+ logger_1.default.info('✅ Dynamic database tool service initialized');
72
82
  // Set V2 service for adjacent chunk retrieval
73
83
  const chatManager = new ChatManager_1.ChatManager({
74
84
  aiService,
@@ -82,7 +92,8 @@ function initializeCoreServices(options) {
82
92
  openaiApiKey: process.env.OPENAI_API_KEY,
83
93
  model: aiModel,
84
94
  assistantName: process.env.ASSISTANT_NAME,
85
- organizationName: process.env.ORGANIZATION_NAME
95
+ organizationName: process.env.ORGANIZATION_NAME,
96
+ databaseToolsEnabled: process.env.EXTERNAL_DB_ENABLED === 'true'
86
97
  });
87
98
  // Initialize realtime publisher if env vars are available
88
99
  let realtimePublisher;
@@ -93,10 +104,14 @@ function initializeCoreServices(options) {
93
104
  else {
94
105
  logger_1.default.warn('⚠️ Realtime publisher not initialized (missing SUPABASE_URL or SUPABASE_SERVICE_KEY)');
95
106
  }
107
+ // Initialize Validation service
108
+ const validationService = new ValidationService_1.ValidationService(process.env.AI_VALIDATION_ENABLED === 'true');
96
109
  const chatController = new ChatController_1.ChatController(chatManager, storage, supabase, {
97
110
  historyLength: resolvedHistoryLength,
98
111
  intentService,
99
- realtimePublisher
112
+ realtimePublisher,
113
+ validationService,
114
+ databaseToolService
100
115
  });
101
116
  const knowledgeController = new KnowledgeController_1.KnowledgeController(knowledgeBase, aiService, citationService);
102
117
  const authController = new AuthController_1.AuthController(supabase);
@@ -107,6 +122,8 @@ function initializeCoreServices(options) {
107
122
  // Initialize Slack integration
108
123
  const slackService = new SlackService_1.SlackService();
109
124
  const slackController = new SlackController_1.SlackController(slackService, chatManager, storage, resolvedHistoryLength);
125
+ // Initialize Database Tool Config controller (pass both services for cache management)
126
+ const databaseToolConfigController = new DatabaseToolConfigController_1.DatabaseToolConfigController(databaseToolConfigService, databaseToolService);
110
127
  return {
111
128
  services: {
112
129
  storage,
@@ -116,7 +133,10 @@ function initializeCoreServices(options) {
116
133
  chatManager,
117
134
  apiKeyService,
118
135
  companyService,
119
- slackService
136
+ slackService,
137
+ databaseToolService,
138
+ validationService,
139
+ databaseToolConfigService
120
140
  },
121
141
  controllers: {
122
142
  chatController,
@@ -124,7 +144,8 @@ function initializeCoreServices(options) {
124
144
  authController,
125
145
  apiKeyController,
126
146
  companyController,
127
- slackController
147
+ slackController,
148
+ databaseToolConfigController
128
149
  },
129
150
  config: {
130
151
  chatHistoryLength: resolvedHistoryLength
@@ -1 +1 @@
1
- {"version":3,"file":"initializeServices.js","sourceRoot":"","sources":["../../../src/bootstrap/initializeServices.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"initializeServices.js","sourceRoot":"","sources":["../../../src/bootstrap/initializeServices.ts"],"names":[],"mappings":"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"}
@@ -5,6 +5,8 @@ import { UnifiedStorage } from '../storage/UnifiedStorage';
5
5
  import { AuthenticatedRequest } from '../middleware/auth';
6
6
  import { IntentService } from '../services/IntentService';
7
7
  import { RealtimePublisher } from '../services/RealtimePublisher';
8
+ import { ValidationService } from '../services/ValidationService';
9
+ import { DatabaseToolService } from '../services/DatabaseToolService';
8
10
  export declare class ChatController {
9
11
  private chatManager;
10
12
  private storage;
@@ -14,10 +16,14 @@ export declare class ChatController {
14
16
  private realtimePublisher?;
15
17
  private responseGenerationService;
16
18
  private responseStreamingService;
19
+ private validationService?;
20
+ private databaseToolService?;
17
21
  constructor(chatManager: ChatManager, storage: UnifiedStorage, supabase: SupabaseClient, options?: {
18
22
  historyLength?: number;
19
23
  intentService?: IntentService;
20
24
  realtimePublisher?: RealtimePublisher;
25
+ validationService?: ValidationService;
26
+ databaseToolService?: DatabaseToolService;
21
27
  });
22
28
  createConversation(req: AuthenticatedRequest, res: Response): Promise<void>;
23
29
  createUserMessage(req: Request, res: Response): Promise<void>;
@@ -1 +1 @@
1
- {"version":3,"file":"ChatController.d.ts","sourceRoot":"","sources":["../../../src/controllers/ChatController.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAC5C,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AACtD,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAC3D,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAE1D,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAE1D,OAAO,EAAE,iBAAiB,EAAE,MAAM,+BAA+B,CAAC;AAIlE,qBAAa,cAAc;IACzB,OAAO,CAAC,WAAW,CAAc;IACjC,OAAO,CAAC,OAAO,CAAiB;IAChC,OAAO,CAAC,QAAQ,CAAiB;IACjC,OAAO,CAAC,iBAAiB,CAAS;IAClC,OAAO,CAAC,aAAa,CAAC,CAAgB;IACtC,OAAO,CAAC,iBAAiB,CAAC,CAAoB;IAC9C,OAAO,CAAC,yBAAyB,CAA4B;IAC7D,OAAO,CAAC,wBAAwB,CAA2B;gBAGzD,WAAW,EAAE,WAAW,EACxB,OAAO,EAAE,cAAc,EACvB,QAAQ,EAAE,cAAc,EACxB,OAAO,GAAE;QAAE,aAAa,CAAC,EAAE,MAAM,CAAC;QAAC,aAAa,CAAC,EAAE,aAAa,CAAC;QAAC,iBAAiB,CAAC,EAAE,iBAAiB,CAAA;KAAO;IAqB1G,kBAAkB,CAAC,GAAG,EAAE,oBAAoB,EAAE,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IA4I3E,iBAAiB,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IAyF7D,gBAAgB,CAAC,GAAG,EAAE,oBAAoB,EAAE,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IAgLzE,eAAe,CAAC,GAAG,EAAE,oBAAoB,EAAE,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IAuDxE,uBAAuB,CAAC,GAAG,EAAE,oBAAoB,EAAE,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IA4DhF,gBAAgB,CAAC,GAAG,EAAE,oBAAoB,EAAE,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IAuGzE,iBAAiB,CAAC,GAAG,EAAE,oBAAoB,EAAE,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IAoG1E,mBAAmB,CAAC,GAAG,EAAE,oBAAoB,EAAE,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IA6E5E,gBAAgB,CAAC,GAAG,EAAE,oBAAoB,EAAE,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IAmGzE,oBAAoB,CAAC,GAAG,EAAE,oBAAoB,EAAE,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IAoE7E,kBAAkB,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IAsB9D,cAAc,CAAC,GAAG,EAAE,OAAO,GAAG,oBAAoB,EAAE,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IAgEjF,cAAc,CAAC,GAAG,EAAE,OAAO,GAAG,oBAAoB,EAAE,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;YAmCzE,2BAA2B;YA4B3B,oBAAoB;CA4EnC"}
1
+ {"version":3,"file":"ChatController.d.ts","sourceRoot":"","sources":["../../../src/controllers/ChatController.ts"],"names":[],"mappings":"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"}
@@ -16,9 +16,11 @@ class ChatController {
16
16
  this.chatHistoryLength = typeof historyLength === 'number' && historyLength > 0 ? historyLength : 2;
17
17
  this.intentService = options.intentService;
18
18
  this.realtimePublisher = options.realtimePublisher;
19
+ this.validationService = options.validationService;
20
+ this.databaseToolService = options.databaseToolService;
19
21
  // Initialize services
20
22
  const aiService = chatManager.aiService;
21
- this.responseGenerationService = new ResponseGenerationService_1.ResponseGenerationService(this.intentService, aiService, this.chatHistoryLength);
23
+ this.responseGenerationService = new ResponseGenerationService_1.ResponseGenerationService(this.intentService, aiService, this.chatHistoryLength, this.databaseToolService);
22
24
  this.responseStreamingService = new ResponseStreamingService_1.ResponseStreamingService();
23
25
  }
24
26
  // Create a new conversation
@@ -151,7 +153,7 @@ class ChatController {
151
153
  // Create a user message in a conversation
152
154
  async createUserMessage(req, res) {
153
155
  try {
154
- const { uuid } = req.params;
156
+ const uuid = Array.isArray(req.params.uuid) ? req.params.uuid[0] : req.params.uuid;
155
157
  const { content } = req.body;
156
158
  if (!content) {
157
159
  res.status(400).json({ error: 'content is required' });
@@ -228,7 +230,7 @@ class ChatController {
228
230
  }
229
231
  // Generate AI response for a user message
230
232
  async generateResponse(req, res) {
231
- const { uuid } = req.params;
233
+ const uuid = Array.isArray(req.params.uuid) ? req.params.uuid[0] : req.params.uuid;
232
234
  if (!uuid) {
233
235
  res.status(400).json({ error: 'Message UUID is required' });
234
236
  return;
@@ -244,6 +246,8 @@ class ChatController {
244
246
  }
245
247
  const conversationId = userMessage.conversationId;
246
248
  const userMessageContent = userMessage.content;
249
+ // Extract user_context from request body (optional)
250
+ const userContext = req.body?.user_context || {};
247
251
  // Get conversation context (recent messages)
248
252
  // Exclude the current user message to avoid duplication (it's added separately as the query)
249
253
  const allMessages = await this.chatManager.getRecentMessages(conversationId, this.chatHistoryLength + 1);
@@ -260,15 +264,72 @@ class ChatController {
260
264
  }
261
265
  // Set up Server-Sent Events (SSE) headers for streaming
262
266
  this.responseStreamingService.setupSSEHeaders(res);
263
- // Run intent classification to decide handling strategy
264
- const intentResult = await this.responseGenerationService.classifyIntent(userMessageContent, messages);
267
+ // Run intent classification to decide handling strategy (with dynamic tools)
268
+ const companyId = conversation?.organizationId ? parseInt(String(conversation.organizationId), 10) : undefined;
269
+ const intentResult = await this.responseGenerationService.classifyIntent(userMessageContent, messages, companyId);
265
270
  const intentResponse = this.responseGenerationService.handleIntentResult(intentResult, userMessageContent);
266
271
  let accumulatedContent = '';
267
272
  let assistantMessageId;
268
273
  let sources = [];
269
274
  try {
270
- // If intent returned a response (non-knowledge intent), stream it
271
- if (intentResponse) {
275
+ // Handle database_tool intent separately
276
+ if (intentResult.intent === 'database_tool' && intentResult.toolCall) {
277
+ logger_1.default.info(`🔧 Database tool call detected: ${intentResult.toolCall.toolName}`);
278
+ if (!this.databaseToolService || !companyId) {
279
+ logger_1.default.warn('⚠️ Database tool requested but service not available or no company ID');
280
+ await this.responseStreamingService.streamTextContent('I apologize, but I cannot access your data at the moment. Please contact support.', res);
281
+ accumulatedContent = 'I apologize, but I cannot access your data at the moment. Please contact support.';
282
+ }
283
+ else {
284
+ // Execute tool with dynamic parameters and user context
285
+ logger_1.default.info(`🔧 Executing tool: ${intentResult.toolCall.toolName} for company: ${companyId}`);
286
+ const toolResult = await this.databaseToolService.executeTool(intentResult.toolCall.toolName, intentResult.toolCall.parameters, companyId, userContext // Pass user context for filtering
287
+ );
288
+ // Check if tool execution was successful
289
+ if (!toolResult.success) {
290
+ logger_1.default.error(`❌ Tool execution failed: ${toolResult.error}`);
291
+ await this.responseStreamingService.streamTextContent('I apologize, but I encountered an error accessing your data. Please try again or contact support.', res);
292
+ accumulatedContent = 'I apologize, but I encountered an error accessing your data. Please try again or contact support.';
293
+ }
294
+ else {
295
+ // Format result with LLM - use direct OpenAI call to bypass system prompt restrictions
296
+ logger_1.default.info('🔧 Formatting tool result with LLM');
297
+ const aiService = this.responseGenerationService.getAIService();
298
+ if (!aiService) {
299
+ throw new Error('AI service not available');
300
+ }
301
+ // Direct OpenAI call bypassing the restrictive system prompt
302
+ const openai = aiService.openai;
303
+ const modelToUse = process.env.AI_MODEL || 'gpt-4o-mini';
304
+ const completion = await openai.chat.completions.create({
305
+ model: modelToUse,
306
+ messages: [
307
+ {
308
+ role: 'system',
309
+ content: 'You are a helpful assistant. Format database query results naturally and conversationally for the user.'
310
+ },
311
+ {
312
+ role: 'user',
313
+ content: `User asked: "${userMessageContent}"
314
+
315
+ Database returned:
316
+ ${JSON.stringify(toolResult.data || toolResult, null, 2)}
317
+
318
+ Provide a natural, friendly response to the user's question using this data.`
319
+ }
320
+ ],
321
+ temperature: 0.7,
322
+ max_tokens: 500
323
+ });
324
+ const formattedContent = completion.choices[0]?.message?.content || 'Here is your information.';
325
+ logger_1.default.info('📤 Streaming database tool response');
326
+ await this.responseStreamingService.streamTextContent(formattedContent, res);
327
+ accumulatedContent = formattedContent;
328
+ }
329
+ }
330
+ }
331
+ // If intent returned a response (non-knowledge/non-tool intent), stream it
332
+ else if (intentResponse) {
272
333
  logger_1.default.info(`📤 Streaming intent response for: ${intentResult.intent}`);
273
334
  await this.responseStreamingService.streamTextContent(intentResponse, res);
274
335
  accumulatedContent = intentResponse;
@@ -280,7 +341,7 @@ class ChatController {
280
341
  const companyIdRaw = req.profile?.companyId || conversation?.organizationId;
281
342
  const companyId = companyIdRaw ? (typeof companyIdRaw === 'string' ? parseInt(companyIdRaw, 10) : companyIdRaw) : undefined;
282
343
  // Search knowledge base and extract sources
283
- const { knowledgeResults, sources: extractedSources } = await this.responseGenerationService.searchKnowledgeBase(userMessageContent, companyId);
344
+ const { knowledgeResults, sources: extractedSources, chunks: knowledgeChunks } = await this.responseGenerationService.searchKnowledgeBase(userMessageContent, companyId);
284
345
  sources = extractedSources;
285
346
  // Build context for AI
286
347
  const chatContext = this.responseGenerationService.buildChatContext(messages, knowledgeResults);
@@ -290,7 +351,20 @@ class ChatController {
290
351
  }
291
352
  // Stream response from OpenAI
292
353
  const stream = aiService.generateResponseStream(userMessageContent, chatContext);
293
- accumulatedContent = await this.responseStreamingService.streamAIResponse(stream, res, sources, knowledgeResults);
354
+ // Create validation callback if service is available
355
+ const validationCallback = this.validationService && knowledgeChunks.length > 0
356
+ ? async (response, query) => {
357
+ try {
358
+ // Use individual chunks for accurate validation
359
+ return await this.validationService.validateResponse(query, response, knowledgeChunks);
360
+ }
361
+ catch (error) {
362
+ logger_1.default.error('Validation error:', error);
363
+ return null;
364
+ }
365
+ }
366
+ : null;
367
+ accumulatedContent = await this.responseStreamingService.streamAIResponse(stream, res, sources, knowledgeResults, validationCallback, userMessageContent);
294
368
  }
295
369
  // Save the message after streaming completes
296
370
  try {
@@ -370,7 +444,7 @@ class ChatController {
370
444
  res.status(401).json({ error: 'Authentication required' });
371
445
  return;
372
446
  }
373
- const { uuid } = req.params;
447
+ const uuid = Array.isArray(req.params.uuid) ? req.params.uuid[0] : req.params.uuid;
374
448
  const conversation = await this.storage.getConversation(uuid);
375
449
  if (!conversation) {
376
450
  res.status(404).json({ error: 'Conversation not found' });
@@ -419,7 +493,7 @@ class ChatController {
419
493
  res.status(401).json({ error: 'Authentication required' });
420
494
  return;
421
495
  }
422
- const { uuid } = req.params;
496
+ const uuid = Array.isArray(req.params.uuid) ? req.params.uuid[0] : req.params.uuid;
423
497
  const page = Math.max(1, parseInt(req.query.page || '1', 10) || 1);
424
498
  const pageSizeRaw = parseInt(req.query.page_size || '50', 10);
425
499
  const pageSize = Math.min(200, Math.max(1, isNaN(pageSizeRaw) ? 50 : pageSizeRaw));
@@ -473,7 +547,7 @@ class ChatController {
473
547
  res.status(401).json({ error: 'Authentication required' });
474
548
  return;
475
549
  }
476
- const { uuid } = req.params;
550
+ const uuid = Array.isArray(req.params.uuid) ? req.params.uuid[0] : req.params.uuid;
477
551
  const conversation = await this.storage.getConversation(uuid);
478
552
  if (!conversation) {
479
553
  res.status(404).json({ error: 'Conversation not found' });
@@ -561,7 +635,7 @@ class ChatController {
561
635
  res.status(401).json({ error: 'Authentication required' });
562
636
  return;
563
637
  }
564
- const { uuid } = req.params;
638
+ const uuid = Array.isArray(req.params.uuid) ? req.params.uuid[0] : req.params.uuid;
565
639
  const conversation = await this.storage.getConversation(uuid);
566
640
  if (!conversation) {
567
641
  res.status(404).json({ error: 'Conversation not found' });
@@ -647,7 +721,7 @@ class ChatController {
647
721
  res.status(401).json({ error: 'Authentication required' });
648
722
  return;
649
723
  }
650
- const { uuid } = req.params;
724
+ const uuid = Array.isArray(req.params.uuid) ? req.params.uuid[0] : req.params.uuid;
651
725
  const conversation = await this.storage.getConversation(uuid);
652
726
  if (!conversation) {
653
727
  res.status(404).json({ error: 'Conversation not found' });
@@ -710,7 +784,7 @@ class ChatController {
710
784
  res.status(401).json({ error: 'Authentication required' });
711
785
  return;
712
786
  }
713
- const { uuid } = req.params;
787
+ const uuid = Array.isArray(req.params.uuid) ? req.params.uuid[0] : req.params.uuid;
714
788
  const { content } = req.body;
715
789
  if (!content) {
716
790
  res.status(400).json({ error: 'content is required' });
@@ -849,7 +923,7 @@ class ChatController {
849
923
  // Delete conversation
850
924
  async deleteConversation(req, res) {
851
925
  try {
852
- const { uuid } = req.params;
926
+ const uuid = Array.isArray(req.params.uuid) ? req.params.uuid[0] : req.params.uuid;
853
927
  const success = await this.storage.deleteConversation(uuid);
854
928
  if (!success) {
855
929
  res.status(404).json({ error: 'Conversation not found or could not be deleted' });
@@ -924,7 +998,7 @@ class ChatController {
924
998
  // Delete/undo message feedback - Public API
925
999
  async deleteFeedback(req, res) {
926
1000
  try {
927
- const { uuid } = req.params;
1001
+ const uuid = Array.isArray(req.params.uuid) ? req.params.uuid[0] : req.params.uuid;
928
1002
  if (!uuid) {
929
1003
  res.status(400).json({ error: 'Feedback UUID is required' });
930
1004
  return;