@flutchai/flutch-sdk 0.1.5 → 0.1.6

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/dist/index.js CHANGED
@@ -1,10 +1,12 @@
1
1
  import 'reflect-metadata';
2
- import { Injectable, Post, UseGuards, Req, Controller, Inject, Get, Body, Res, Param, Logger, Module, UnauthorizedException, Headers, NotFoundException, InternalServerErrorException, ForbiddenException, ValidationPipe, HttpException, HttpStatus } from '@nestjs/common';
2
+ import { Injectable, Post, UseGuards, Req, Controller, Inject, Get, Body, Res, Param, Logger, Module, UnauthorizedException, Optional, Headers, NotFoundException, InternalServerErrorException, ForbiddenException, ValidationPipe, HttpException, HttpStatus } from '@nestjs/common';
3
3
  import { ApiOperation, ApiResponse, ApiTags, ApiParam, DocumentBuilder, SwaggerModule } from '@nestjs/swagger';
4
- import * as path from 'path';
4
+ import * as fs from 'fs';
5
+ import * as path2 from 'path';
6
+ import * as os from 'os';
5
7
  import { randomBytes, createHash, randomUUID } from 'crypto';
6
8
  import { Registry, collectDefaultMetrics, Counter, Histogram, Gauge } from 'prom-client';
7
- import { NestFactory, ModuleRef, DiscoveryModule } from '@nestjs/core';
9
+ import { NestFactory, MetadataScanner, ModuleRef, DiscoveryModule } from '@nestjs/core';
8
10
  import * as net from 'net';
9
11
  import { ConfigModule } from '@nestjs/config';
10
12
  import * as LangGraph from '@langchain/langgraph';
@@ -432,12 +434,21 @@ var init_ui_endpoints_discovery = __esm({
432
434
  this.endpointRegistry = endpointRegistry;
433
435
  }
434
436
  logger = new Logger(UIEndpointsDiscoveryService.name);
437
+ async onModuleInit() {
438
+ await this.discoverUIEndpoints();
439
+ }
435
440
  /**
436
441
  * Discover and register all UI endpoint classes
437
442
  * Called automatically during module initialization
438
443
  */
439
444
  async discoverUIEndpoints() {
440
445
  this.logger.log("Starting UI endpoints discovery...");
446
+ if (!this.discoveryService) {
447
+ this.logger.warn(
448
+ "DiscoveryService not available, skipping UI endpoints discovery"
449
+ );
450
+ return;
451
+ }
441
452
  const providers = this.discoveryService.getProviders();
442
453
  let registeredCount = 0;
443
454
  let totalEndpoints = 0;
@@ -489,7 +500,9 @@ var init_ui_endpoints_discovery = __esm({
489
500
  }
490
501
  };
491
502
  UIEndpointsDiscoveryService = __decorateClass([
492
- Injectable()
503
+ Injectable(),
504
+ __decorateParam(0, Optional()),
505
+ __decorateParam(1, Optional())
493
506
  ], UIEndpointsDiscoveryService);
494
507
  }
495
508
  });
@@ -684,6 +697,523 @@ var init_agent_ui = __esm({
684
697
  init_ui_dispatch_controller();
685
698
  }
686
699
  });
700
+
701
+ // src/service-discovery/file-based.discovery.ts
702
+ var file_based_discovery_exports = {};
703
+ __export(file_based_discovery_exports, {
704
+ FileBasedDiscovery: () => FileBasedDiscovery
705
+ });
706
+ var FileBasedDiscovery;
707
+ var init_file_based_discovery = __esm({
708
+ "src/service-discovery/file-based.discovery.ts"() {
709
+ FileBasedDiscovery = class {
710
+ logger = new Logger(FileBasedDiscovery.name);
711
+ servicesDir;
712
+ constructor() {
713
+ this.servicesDir = path2.join(os.homedir(), ".flutch", "services");
714
+ this.ensureServicesDirectory();
715
+ this.cleanupStaleServices();
716
+ }
717
+ /**
718
+ * Register service
719
+ */
720
+ async registerService(name, address, port, metadata, graphTypes = []) {
721
+ const registration = {
722
+ name,
723
+ address,
724
+ port,
725
+ metadata,
726
+ pid: process.pid,
727
+ timestamp: Date.now(),
728
+ graphTypes
729
+ };
730
+ const serviceFile = path2.join(
731
+ this.servicesDir,
732
+ `${name}-${process.pid}.json`
733
+ );
734
+ try {
735
+ await fs.promises.writeFile(
736
+ serviceFile,
737
+ JSON.stringify(registration, null, 2)
738
+ );
739
+ this.logger.log(`Registered service: ${name} at ${address}:${port}`);
740
+ process.on("exit", () => this.unregisterService(name));
741
+ process.on("SIGINT", () => {
742
+ this.unregisterService(name);
743
+ process.exit(0);
744
+ });
745
+ process.on("SIGTERM", () => {
746
+ this.unregisterService(name);
747
+ process.exit(0);
748
+ });
749
+ } catch (error) {
750
+ this.logger.error(`Failed to register service ${name}: ${error.message}`);
751
+ }
752
+ }
753
+ /**
754
+ * Unregister service
755
+ */
756
+ async unregisterService(name) {
757
+ const serviceFile = path2.join(
758
+ this.servicesDir,
759
+ `${name}-${process.pid}.json`
760
+ );
761
+ try {
762
+ if (fs.existsSync(serviceFile)) {
763
+ await fs.promises.unlink(serviceFile);
764
+ this.logger.log(`Unregistered service: ${name}`);
765
+ }
766
+ } catch (error) {
767
+ this.logger.error(
768
+ `Failed to unregister service ${name}: ${error.message}`
769
+ );
770
+ }
771
+ }
772
+ /**
773
+ * Get list of services by graph type
774
+ */
775
+ async getServices(graphType) {
776
+ try {
777
+ const files = await fs.promises.readdir(this.servicesDir);
778
+ const services = [];
779
+ for (const file of files) {
780
+ if (!file.endsWith(".json")) continue;
781
+ try {
782
+ const serviceFile = path2.join(this.servicesDir, file);
783
+ const content = await fs.promises.readFile(serviceFile, "utf-8");
784
+ const registration = JSON.parse(content);
785
+ if (!this.isProcessAlive(registration.pid)) {
786
+ await fs.promises.unlink(serviceFile);
787
+ continue;
788
+ }
789
+ if (registration.graphTypes.includes(graphType) || registration.metadata.graphTypes?.includes(graphType)) {
790
+ services.push({
791
+ name: registration.name,
792
+ address: registration.address,
793
+ port: registration.port,
794
+ metadata: registration.metadata
795
+ });
796
+ }
797
+ } catch (error) {
798
+ this.logger.warn(
799
+ `Failed to parse service file ${file}: ${error.message}`
800
+ );
801
+ }
802
+ }
803
+ return services;
804
+ } catch (error) {
805
+ this.logger.error(`Failed to get services: ${error.message}`);
806
+ return [];
807
+ }
808
+ }
809
+ /**
810
+ * Find service by name
811
+ */
812
+ async findServiceByName(serviceName) {
813
+ try {
814
+ const files = await fs.promises.readdir(this.servicesDir);
815
+ for (const file of files) {
816
+ if (!file.endsWith(".json")) continue;
817
+ try {
818
+ const serviceFile = path2.join(this.servicesDir, file);
819
+ const content = await fs.promises.readFile(serviceFile, "utf-8");
820
+ const registration = JSON.parse(content);
821
+ if (registration.name === serviceName && this.isProcessAlive(registration.pid)) {
822
+ return {
823
+ name: registration.name,
824
+ address: registration.address,
825
+ port: registration.port,
826
+ metadata: registration.metadata
827
+ };
828
+ }
829
+ } catch (error) {
830
+ this.logger.warn(
831
+ `Failed to parse service file ${file}: ${error.message}`
832
+ );
833
+ }
834
+ }
835
+ return null;
836
+ } catch (error) {
837
+ this.logger.error(
838
+ `Failed to find service ${serviceName}: ${error.message}`
839
+ );
840
+ return null;
841
+ }
842
+ }
843
+ /**
844
+ * Ensure services directory exists
845
+ */
846
+ ensureServicesDirectory() {
847
+ try {
848
+ const amelieDir = path2.join(os.homedir(), ".flutch");
849
+ if (!fs.existsSync(amelieDir)) {
850
+ fs.mkdirSync(amelieDir, { recursive: true });
851
+ }
852
+ if (!fs.existsSync(this.servicesDir)) {
853
+ fs.mkdirSync(this.servicesDir, { recursive: true });
854
+ }
855
+ } catch (error) {
856
+ this.logger.error(
857
+ `Failed to create services directory: ${error.message}`
858
+ );
859
+ }
860
+ }
861
+ /**
862
+ * Cleanup stale services
863
+ */
864
+ async cleanupStaleServices() {
865
+ try {
866
+ const files = await fs.promises.readdir(this.servicesDir);
867
+ for (const file of files) {
868
+ if (!file.endsWith(".json")) continue;
869
+ try {
870
+ const serviceFile = path2.join(this.servicesDir, file);
871
+ const content = await fs.promises.readFile(serviceFile, "utf-8");
872
+ const registration = JSON.parse(content);
873
+ if (!this.isProcessAlive(registration.pid)) {
874
+ await fs.promises.unlink(serviceFile);
875
+ this.logger.debug(`Cleaned up stale service: ${registration.name}`);
876
+ }
877
+ } catch (error) {
878
+ try {
879
+ await fs.promises.unlink(path2.join(this.servicesDir, file));
880
+ } catch {
881
+ }
882
+ }
883
+ }
884
+ } catch (error) {
885
+ this.logger.error(`Failed to cleanup stale services: ${error.message}`);
886
+ }
887
+ }
888
+ /**
889
+ * Check if process is still alive
890
+ */
891
+ isProcessAlive(pid) {
892
+ try {
893
+ process.kill(pid, 0);
894
+ return true;
895
+ } catch (error) {
896
+ return false;
897
+ }
898
+ }
899
+ };
900
+ FileBasedDiscovery = __decorateClass([
901
+ Injectable()
902
+ ], FileBasedDiscovery);
903
+ }
904
+ });
905
+
906
+ // src/core/builder-registry.service.ts
907
+ var builder_registry_service_exports = {};
908
+ __export(builder_registry_service_exports, {
909
+ BuilderRegistryService: () => BuilderRegistryService
910
+ });
911
+ var BuilderRegistryService;
912
+ var init_builder_registry_service = __esm({
913
+ "src/core/builder-registry.service.ts"() {
914
+ BuilderRegistryService = class {
915
+ builders = [];
916
+ registerBuilder(builder) {
917
+ const existingBuilder = this.builders.find(
918
+ (b) => b.graphType === builder.graphType
919
+ );
920
+ if (!existingBuilder) {
921
+ this.builders.push(builder);
922
+ }
923
+ }
924
+ getBuilders() {
925
+ return this.builders;
926
+ }
927
+ };
928
+ BuilderRegistryService = __decorateClass([
929
+ Injectable()
930
+ ], BuilderRegistryService);
931
+ }
932
+ });
933
+
934
+ // src/utils/graph-type.utils.ts
935
+ var GraphTypeUtils;
936
+ var init_graph_type_utils = __esm({
937
+ "src/utils/graph-type.utils.ts"() {
938
+ GraphTypeUtils = class {
939
+ /**
940
+ * Parse full graph type
941
+ * @param fullType - full graph type
942
+ * @returns object with type components
943
+ */
944
+ static parse(fullType) {
945
+ if (fullType.includes("::")) {
946
+ const [baseType, version] = fullType.split("::");
947
+ const [companyId, name] = baseType.split(".");
948
+ return { companyId, name, version };
949
+ }
950
+ const parts = fullType.split(".");
951
+ if (parts.length === 1) {
952
+ return { companyId: "global", name: parts[0] };
953
+ }
954
+ return { companyId: parts[0], name: parts[1] };
955
+ }
956
+ /**
957
+ * Build full type from components
958
+ * @param companyId - company ID
959
+ * @param name - graph name
960
+ * @param version - version (optional)
961
+ * @returns full graph type
962
+ */
963
+ static build(companyId, name, version) {
964
+ const base = `${companyId}.${name}`;
965
+ return version ? `${base}::${version}` : base;
966
+ }
967
+ /**
968
+ * Normalize graph type for backward compatibility
969
+ * @param graphType - graph type in any format
970
+ * @returns normalized type
971
+ */
972
+ static normalize(graphType) {
973
+ const { companyId, name, version } = this.parse(graphType);
974
+ return this.build(companyId, name, version);
975
+ }
976
+ /**
977
+ * Get base type without version
978
+ * @param graphType - full graph type
979
+ * @returns base type
980
+ */
981
+ static getBaseType(graphType) {
982
+ if (graphType.includes("::")) {
983
+ return graphType.split("::")[0];
984
+ }
985
+ const { companyId, name } = this.parse(graphType);
986
+ return `${companyId}.${name}`;
987
+ }
988
+ /**
989
+ * Extract version from graph type
990
+ * @param graphType - full graph type
991
+ * @returns version or undefined
992
+ */
993
+ static getVersion(graphType) {
994
+ return graphType.includes("::") ? graphType.split("::")[1] : void 0;
995
+ }
996
+ /**
997
+ * Validate version (basic semver check)
998
+ * @param version - version to check
999
+ * @returns true if version is valid
1000
+ */
1001
+ static isValidVersion(version) {
1002
+ const semverRegex = /^\d+\.\d+\.\d+(-[a-zA-Z0-9.-]+)?$/;
1003
+ return semverRegex.test(version);
1004
+ }
1005
+ /**
1006
+ * Check if type is system (global)
1007
+ * @param graphType - graph type
1008
+ * @returns true if graph is system
1009
+ */
1010
+ static isSystemGraph(graphType) {
1011
+ const { companyId } = this.parse(graphType);
1012
+ return companyId === "global";
1013
+ }
1014
+ /**
1015
+ * Compare versions (simple comparison for sorting)
1016
+ * @param a - first version
1017
+ * @param b - second version
1018
+ * @returns -1, 0, 1 for sorting
1019
+ */
1020
+ static compareVersions(a, b) {
1021
+ const parseVersion = (v) => {
1022
+ const [main, prerelease] = v.split("-");
1023
+ const [major, minor, patch] = main.split(".").map(Number);
1024
+ return { major, minor, patch, prerelease };
1025
+ };
1026
+ const versionA = parseVersion(a);
1027
+ const versionB = parseVersion(b);
1028
+ if (versionA.major !== versionB.major) {
1029
+ return versionA.major - versionB.major;
1030
+ }
1031
+ if (versionA.minor !== versionB.minor) {
1032
+ return versionA.minor - versionB.minor;
1033
+ }
1034
+ if (versionA.patch !== versionB.patch) {
1035
+ return versionA.patch - versionB.patch;
1036
+ }
1037
+ if (versionA.prerelease && !versionB.prerelease) return -1;
1038
+ if (!versionA.prerelease && versionB.prerelease) return 1;
1039
+ if (versionA.prerelease && versionB.prerelease) {
1040
+ return versionA.prerelease.localeCompare(versionB.prerelease);
1041
+ }
1042
+ return 0;
1043
+ }
1044
+ };
1045
+ }
1046
+ });
1047
+
1048
+ // src/graph/versioning/versioned-graph.service.ts
1049
+ var versioned_graph_service_exports = {};
1050
+ __export(versioned_graph_service_exports, {
1051
+ VersionedGraphService: () => VersionedGraphService
1052
+ });
1053
+ var VersionedGraphService;
1054
+ var init_versioned_graph_service = __esm({
1055
+ "src/graph/versioning/versioned-graph.service.ts"() {
1056
+ init_graph_type_utils();
1057
+ VersionedGraphService = class {
1058
+ logger = new Logger(VersionedGraphService.name);
1059
+ versionConfigs = /* @__PURE__ */ new Map();
1060
+ constructor() {
1061
+ }
1062
+ /**
1063
+ * Register versioning configuration
1064
+ */
1065
+ registerVersioning(config) {
1066
+ this.versionConfigs.set(config.baseGraphType, config);
1067
+ this.logger.log(
1068
+ `Registered versioning for ${config.baseGraphType} with ${config.versions.length} versions`
1069
+ );
1070
+ }
1071
+ /**
1072
+ * Resolve graph version
1073
+ */
1074
+ async resolveVersion(graphType, options = {}) {
1075
+ const parsed = GraphTypeUtils.parse(graphType);
1076
+ const baseType = GraphTypeUtils.getBaseType(graphType);
1077
+ const requestedVersion = GraphTypeUtils.getVersion(graphType) || options.requestedVersion;
1078
+ const config = this.versionConfigs.get(baseType);
1079
+ if (!config) {
1080
+ throw new Error(`No versioning configuration found for ${baseType}`);
1081
+ }
1082
+ const route = this.findBestVersionRoute(config, requestedVersion, options);
1083
+ if (!route) {
1084
+ throw new Error(
1085
+ `No compatible version found for ${graphType} with options: ${JSON.stringify(options)}`
1086
+ );
1087
+ }
1088
+ const fullGraphType = GraphTypeUtils.build(
1089
+ parsed.companyId,
1090
+ parsed.name,
1091
+ route.version
1092
+ );
1093
+ return {
1094
+ version: route.version,
1095
+ builderClass: route.builderClass,
1096
+ fullGraphType
1097
+ };
1098
+ }
1099
+ /**
1100
+ * Create builder for specified version
1101
+ */
1102
+ async createVersionedBuilder(graphType, moduleRef, options = {}) {
1103
+ const resolution = await this.resolveVersion(graphType, options);
1104
+ try {
1105
+ if (!moduleRef) {
1106
+ throw new Error(
1107
+ "ModuleRef is not available - falling back to direct instantiation"
1108
+ );
1109
+ }
1110
+ const builder = await moduleRef.create(resolution.builderClass);
1111
+ this.logger.debug(
1112
+ `Created versioned builder for ${resolution.fullGraphType}`
1113
+ );
1114
+ return builder;
1115
+ } catch (error) {
1116
+ this.logger.error(
1117
+ `Failed to create builder for ${resolution.fullGraphType}: ${error.message}`
1118
+ );
1119
+ throw new Error(`Failed to create versioned builder: ${error.message}`);
1120
+ }
1121
+ }
1122
+ /**
1123
+ * Get all available versions for a graph
1124
+ */
1125
+ getAvailableVersions(baseGraphType) {
1126
+ const config = this.versionConfigs.get(baseGraphType);
1127
+ if (!config) {
1128
+ return [];
1129
+ }
1130
+ return config.versions.map((route) => route.version).sort((a, b) => GraphTypeUtils.compareVersions(b, a));
1131
+ }
1132
+ /**
1133
+ * Check version support
1134
+ */
1135
+ isVersionSupported(graphType, options = {}) {
1136
+ try {
1137
+ const baseType = GraphTypeUtils.getBaseType(graphType);
1138
+ const requestedVersion = GraphTypeUtils.getVersion(graphType);
1139
+ const config = this.versionConfigs.get(baseType);
1140
+ if (!config) {
1141
+ return false;
1142
+ }
1143
+ const route = this.findBestVersionRoute(
1144
+ config,
1145
+ requestedVersion,
1146
+ options
1147
+ );
1148
+ return route !== null;
1149
+ } catch {
1150
+ return false;
1151
+ }
1152
+ }
1153
+ /**
1154
+ * Find best version
1155
+ */
1156
+ findBestVersionRoute(config, requestedVersion, options = {}) {
1157
+ const { strict = false } = options;
1158
+ let candidates = [...config.versions];
1159
+ if (requestedVersion) {
1160
+ const exactMatch = candidates.find(
1161
+ (route) => route.version === requestedVersion
1162
+ );
1163
+ if (exactMatch) {
1164
+ return exactMatch;
1165
+ }
1166
+ if (strict) {
1167
+ return null;
1168
+ }
1169
+ const compatibleVersions = candidates.filter(
1170
+ (route) => this.isVersionCompatible(requestedVersion, route.version)
1171
+ );
1172
+ if (compatibleVersions.length > 0) {
1173
+ return compatibleVersions.sort(
1174
+ (a, b) => GraphTypeUtils.compareVersions(b.version, a.version)
1175
+ )[0];
1176
+ }
1177
+ }
1178
+ const defaultRoute = candidates.find((route) => route.isDefault);
1179
+ if (defaultRoute) {
1180
+ return defaultRoute;
1181
+ }
1182
+ if (config.defaultVersionStrategy === "latest" || !config.defaultVersionStrategy) {
1183
+ const sortedVersions = candidates.sort(
1184
+ (a, b) => GraphTypeUtils.compareVersions(b.version, a.version)
1185
+ );
1186
+ return sortedVersions[0] || null;
1187
+ }
1188
+ return null;
1189
+ }
1190
+ /**
1191
+ * Check version compatibility (simplified semantics)
1192
+ */
1193
+ isVersionCompatible(requested, available) {
1194
+ try {
1195
+ const requestedParts = requested.split(".").map(Number);
1196
+ const availableParts = available.split(".").map(Number);
1197
+ if (requestedParts[0] !== availableParts[0]) {
1198
+ return false;
1199
+ }
1200
+ return GraphTypeUtils.compareVersions(available, requested) >= 0;
1201
+ } catch {
1202
+ return false;
1203
+ }
1204
+ }
1205
+ /**
1206
+ * Get versioning configuration information
1207
+ */
1208
+ getVersioningInfo(baseGraphType) {
1209
+ return this.versionConfigs.get(baseGraphType) || null;
1210
+ }
1211
+ };
1212
+ VersionedGraphService = __decorateClass([
1213
+ Injectable()
1214
+ ], VersionedGraphService);
1215
+ }
1216
+ });
687
1217
  var CallbackStore = class {
688
1218
  constructor(redis) {
689
1219
  this.redis = redis;
@@ -2525,7 +3055,7 @@ var _AbstractGraphBuilder = class _AbstractGraphBuilder {
2525
3055
  /**
2526
3056
  * Path to root graph manifest (defaults to graph.manifest.json in root)
2527
3057
  */
2528
- manifestPath = path.join(
3058
+ manifestPath = path2.join(
2529
3059
  process.cwd(),
2530
3060
  "graph.manifest.json"
2531
3061
  );
@@ -2605,10 +3135,10 @@ var _AbstractGraphBuilder = class _AbstractGraphBuilder {
2605
3135
  return null;
2606
3136
  }
2607
3137
  try {
2608
- const fs = await import('fs/promises');
2609
- const path2 = await import('path');
2610
- const manifestFullPath = path2.resolve(this.manifestPath);
2611
- const manifestContent = await fs.readFile(manifestFullPath, "utf-8");
3138
+ const fs2 = await import('fs/promises');
3139
+ const path3 = await import('path');
3140
+ const manifestFullPath = path3.resolve(this.manifestPath);
3141
+ const manifestContent = await fs2.readFile(manifestFullPath, "utf-8");
2612
3142
  const manifest = JSON.parse(manifestContent);
2613
3143
  this.manifest = manifest;
2614
3144
  return manifest;
@@ -2627,10 +3157,10 @@ var _AbstractGraphBuilder = class _AbstractGraphBuilder {
2627
3157
  return null;
2628
3158
  }
2629
3159
  try {
2630
- const fs = __require("fs");
2631
- const path2 = __require("path");
2632
- const manifestFullPath = path2.resolve(this.manifestPath);
2633
- const manifestContent = fs.readFileSync(manifestFullPath, "utf-8");
3160
+ const fs2 = __require("fs");
3161
+ const path3 = __require("path");
3162
+ const manifestFullPath = path3.resolve(this.manifestPath);
3163
+ const manifestContent = fs2.readFileSync(manifestFullPath, "utf-8");
2634
3164
  const manifest = JSON.parse(manifestContent);
2635
3165
  this.manifest = manifest;
2636
3166
  return manifest;
@@ -2670,12 +3200,12 @@ var _AbstractGraphBuilder = class _AbstractGraphBuilder {
2670
3200
  let configSchema = null;
2671
3201
  if (versionConfig.configSchemaPath) {
2672
3202
  try {
2673
- const fs = await import('fs/promises');
2674
- const schemaPath = path.resolve(
3203
+ const fs2 = await import('fs/promises');
3204
+ const schemaPath = path2.resolve(
2675
3205
  process.cwd(),
2676
3206
  versionConfig.configSchemaPath
2677
3207
  );
2678
- const schemaContent = await fs.readFile(schemaPath, "utf-8");
3208
+ const schemaContent = await fs2.readFile(schemaPath, "utf-8");
2679
3209
  const schemaData = JSON.parse(schemaContent);
2680
3210
  configSchema = schemaData.schema;
2681
3211
  } catch (error) {
@@ -3140,6 +3670,20 @@ UniversalGraphService = __decorateClass([
3140
3670
  __decorateParam(2, Inject("GRAPH_ENGINE")),
3141
3671
  __decorateParam(3, Inject(EndpointRegistry))
3142
3672
  ], UniversalGraphService);
3673
+ function setupRedisMock() {
3674
+ if (process.env.NODE_ENV === "development" && !process.env.KUBERNETES_SERVICE_HOST) {
3675
+ console.log("[REDIS_MOCK] Intercepting ioredis requires for development");
3676
+ const Module2 = __require("module");
3677
+ const originalRequire = Module2.prototype.require;
3678
+ Module2.prototype.require = function(...args) {
3679
+ if (args[0] === "ioredis") {
3680
+ console.log("[REDIS_MOCK] Redirecting ioredis to ioredis-mock");
3681
+ return originalRequire.apply(this, ["ioredis-mock"]);
3682
+ }
3683
+ return originalRequire.apply(this, args);
3684
+ };
3685
+ }
3686
+ }
3143
3687
  async function isPortAvailable(port) {
3144
3688
  return new Promise((resolve2) => {
3145
3689
  const server = net.createServer();
@@ -3161,10 +3705,110 @@ async function findAvailablePort(startPort) {
3161
3705
  `No available ports found in range ${startPort}-${startPort + 99}`
3162
3706
  );
3163
3707
  }
3708
+ async function registerWithServiceDiscovery(AppModule, port, logger2, app) {
3709
+ try {
3710
+ logger2.debug(
3711
+ "[SERVICE_DISCOVERY] Starting service discovery registration..."
3712
+ );
3713
+ const { FileBasedDiscovery: FileBasedDiscovery2 } = await Promise.resolve().then(() => (init_file_based_discovery(), file_based_discovery_exports));
3714
+ logger2.debug(
3715
+ "[SERVICE_DISCOVERY] FileBasedDiscovery imported successfully"
3716
+ );
3717
+ const discovery = new FileBasedDiscovery2();
3718
+ logger2.debug("[SERVICE_DISCOVERY] FileBasedDiscovery instance created");
3719
+ const serviceName = AppModule.name.replace("Module", "").toLowerCase();
3720
+ let graphTypes = [];
3721
+ try {
3722
+ if (app) {
3723
+ const { BuilderRegistryService: BuilderRegistryService2 } = await Promise.resolve().then(() => (init_builder_registry_service(), builder_registry_service_exports));
3724
+ const builderRegistry = app.get(BuilderRegistryService2, {
3725
+ strict: false
3726
+ });
3727
+ logger2.debug(
3728
+ `BuilderRegistryService found in DI: ${!!builderRegistry}`
3729
+ );
3730
+ if (builderRegistry) {
3731
+ const builders = builderRegistry.getBuilders();
3732
+ logger2.debug(`Found ${builders.length} builders in registry`);
3733
+ const baseGraphTypes = builders.map((builder) => builder.graphType);
3734
+ logger2.debug(`Base graph types: [${baseGraphTypes.join(", ")}]`);
3735
+ try {
3736
+ logger2.debug("Attempting to import VersionedGraphService...");
3737
+ const { VersionedGraphService: VersionedGraphService2 } = await Promise.resolve().then(() => (init_versioned_graph_service(), versioned_graph_service_exports));
3738
+ logger2.debug("VersionedGraphService imported successfully");
3739
+ const versionedService = app.get(VersionedGraphService2, {
3740
+ strict: false
3741
+ });
3742
+ logger2.debug(
3743
+ `VersionedGraphService found in DI: ${!!versionedService}`
3744
+ );
3745
+ if (versionedService) {
3746
+ const allVersionedTypes = [];
3747
+ for (const baseType of baseGraphTypes) {
3748
+ logger2.debug(`Getting versions for base type: ${baseType}`);
3749
+ const versions = versionedService.getAvailableVersions(baseType);
3750
+ logger2.debug(
3751
+ `Found ${versions.length} versions for ${baseType}: [${versions.join(", ")}]`
3752
+ );
3753
+ if (versions.length > 0) {
3754
+ allVersionedTypes.push(baseType);
3755
+ versions.forEach((version) => {
3756
+ allVersionedTypes.push(`${baseType}::${version}`);
3757
+ });
3758
+ } else {
3759
+ allVersionedTypes.push(baseType);
3760
+ }
3761
+ }
3762
+ graphTypes = allVersionedTypes;
3763
+ logger2.debug(
3764
+ `Found ${baseGraphTypes.length} base types with ${graphTypes.length} total versioned types: ${graphTypes.join(", ")}`
3765
+ );
3766
+ } else {
3767
+ graphTypes = baseGraphTypes;
3768
+ logger2.debug(
3769
+ `VersionedGraphService not found in DI container, using base types: ${graphTypes.join(", ")}`
3770
+ );
3771
+ }
3772
+ } catch (error) {
3773
+ graphTypes = baseGraphTypes;
3774
+ logger2.debug(
3775
+ `Failed to get versioned types, using base types: ${error.message}`
3776
+ );
3777
+ logger2.debug(`Stack trace: ${error.stack}`);
3778
+ }
3779
+ }
3780
+ }
3781
+ } catch (error) {
3782
+ logger2.debug(`Failed to get graph types from builders: ${error.message}`);
3783
+ }
3784
+ if (graphTypes.length === 0) {
3785
+ logger2.debug("No builders found, using service name as graph type");
3786
+ graphTypes = [serviceName];
3787
+ }
3788
+ await discovery.registerService(
3789
+ serviceName,
3790
+ "localhost",
3791
+ port,
3792
+ {
3793
+ graphTypes,
3794
+ environment: "development",
3795
+ startTime: (/* @__PURE__ */ new Date()).toISOString(),
3796
+ version: process.env.npm_package_version || "1.0.0"
3797
+ },
3798
+ graphTypes
3799
+ );
3800
+ logger2.log(
3801
+ `\u{1F4E1} Service registered with discovery: ${serviceName} (types: ${graphTypes.join(", ")})`
3802
+ );
3803
+ } catch (error) {
3804
+ logger2.warn(`Failed to register with service discovery: ${error.message}`);
3805
+ }
3806
+ }
3164
3807
  async function bootstrap(AppModule, options = {}) {
3808
+ setupRedisMock();
3165
3809
  const app = await NestFactory.create(AppModule);
3166
3810
  const logger2 = new Logger("Bootstrap");
3167
- const requestedPort = options.port || parseInt(process.env.PORT || "3000", 10);
3811
+ const requestedPort = options.port || parseInt(process.env.PORT || "3100", 10);
3168
3812
  const port = await findAvailablePort(requestedPort);
3169
3813
  const globalPrefix = options.globalPrefix;
3170
3814
  if (port !== requestedPort) {
@@ -3191,57 +3835,21 @@ async function bootstrap(AppModule, options = {}) {
3191
3835
  const baseUrl = globalPrefix ? `http://localhost:${port}/${globalPrefix}` : `http://localhost:${port}`;
3192
3836
  logger2.log(`\u{1F680} Graph service is running on: ${baseUrl}`);
3193
3837
  logger2.log(`\u{1F4DA} API Documentation: http://localhost:${port}/api/docs`);
3194
- if (process.env.NODE_ENV !== "production") ;
3195
- return app;
3196
- }
3197
- var BuilderRegistryService = class {
3198
- builders = [];
3199
- registerBuilder(builder) {
3200
- const existingBuilder = this.builders.find(
3201
- (b) => b.graphType === builder.graphType
3838
+ if (process.env.NODE_ENV !== "production") {
3839
+ logger2.debug(
3840
+ `Attempting service discovery registration (NODE_ENV: ${process.env.NODE_ENV || "undefined"})`
3841
+ );
3842
+ await registerWithServiceDiscovery(AppModule, port, logger2, app);
3843
+ } else {
3844
+ logger2.debug(
3845
+ `Skipping service discovery registration (NODE_ENV: ${process.env.NODE_ENV})`
3202
3846
  );
3203
- if (!existingBuilder) {
3204
- this.builders.push(builder);
3205
- }
3206
- }
3207
- getBuilders() {
3208
- return this.builders;
3209
- }
3210
- };
3211
- BuilderRegistryService = __decorateClass([
3212
- Injectable()
3213
- ], BuilderRegistryService);
3214
- var GraphEngineType = /* @__PURE__ */ ((GraphEngineType2) => {
3215
- GraphEngineType2["LANGGRAPH"] = "langgraph";
3216
- GraphEngineType2["LANGFLOW"] = "langflow";
3217
- GraphEngineType2["FLOWISE"] = "flowise";
3218
- return GraphEngineType2;
3219
- })(GraphEngineType || {});
3220
- var GraphEngineFactory = class {
3221
- constructor(langgraph) {
3222
- this.langgraph = langgraph;
3223
- }
3224
- /**
3225
- * Get engine for the specified type
3226
- */
3227
- getEngine(engineType) {
3228
- switch (engineType) {
3229
- case "langgraph" /* LANGGRAPH */:
3230
- return this.langgraph;
3231
- // Will add other types in the future
3232
- // case GraphEngineType.LANGFLOW:
3233
- // return new LangFlowEngine();
3234
- // case GraphEngineType.FLOWISE:
3235
- // return new FlowiseEngine();
3236
- default:
3237
- throw new Error(`Unsupported graph engine type: ${engineType}`);
3238
- }
3239
3847
  }
3240
- };
3241
- GraphEngineFactory = __decorateClass([
3242
- Injectable(),
3243
- __decorateParam(0, Inject())
3244
- ], GraphEngineFactory);
3848
+ return app;
3849
+ }
3850
+
3851
+ // src/core/index.ts
3852
+ init_builder_registry_service();
3245
3853
 
3246
3854
  // src/messages/attachments.ts
3247
3855
  var AttachmentType = /* @__PURE__ */ ((AttachmentType2) => {
@@ -3623,274 +4231,8 @@ ${result.errors.join("\n")}`
3623
4231
  }
3624
4232
  };
3625
4233
 
3626
- // src/utils/graph-type.utils.ts
3627
- var GraphTypeUtils = class {
3628
- /**
3629
- * Parse full graph type
3630
- * @param fullType - full graph type
3631
- * @returns object with type components
3632
- */
3633
- static parse(fullType) {
3634
- if (fullType.includes("::")) {
3635
- const [baseType, version] = fullType.split("::");
3636
- const [companyId, name] = baseType.split(".");
3637
- return { companyId, name, version };
3638
- }
3639
- const parts = fullType.split(".");
3640
- if (parts.length === 1) {
3641
- return { companyId: "global", name: parts[0] };
3642
- }
3643
- return { companyId: parts[0], name: parts[1] };
3644
- }
3645
- /**
3646
- * Build full type from components
3647
- * @param companyId - company ID
3648
- * @param name - graph name
3649
- * @param version - version (optional)
3650
- * @returns full graph type
3651
- */
3652
- static build(companyId, name, version) {
3653
- const base = `${companyId}.${name}`;
3654
- return version ? `${base}::${version}` : base;
3655
- }
3656
- /**
3657
- * Normalize graph type for backward compatibility
3658
- * @param graphType - graph type in any format
3659
- * @returns normalized type
3660
- */
3661
- static normalize(graphType) {
3662
- const { companyId, name, version } = this.parse(graphType);
3663
- return this.build(companyId, name, version);
3664
- }
3665
- /**
3666
- * Get base type without version
3667
- * @param graphType - full graph type
3668
- * @returns base type
3669
- */
3670
- static getBaseType(graphType) {
3671
- if (graphType.includes("::")) {
3672
- return graphType.split("::")[0];
3673
- }
3674
- const { companyId, name } = this.parse(graphType);
3675
- return `${companyId}.${name}`;
3676
- }
3677
- /**
3678
- * Extract version from graph type
3679
- * @param graphType - full graph type
3680
- * @returns version or undefined
3681
- */
3682
- static getVersion(graphType) {
3683
- return graphType.includes("::") ? graphType.split("::")[1] : void 0;
3684
- }
3685
- /**
3686
- * Validate version (basic semver check)
3687
- * @param version - version to check
3688
- * @returns true if version is valid
3689
- */
3690
- static isValidVersion(version) {
3691
- const semverRegex = /^\d+\.\d+\.\d+(-[a-zA-Z0-9.-]+)?$/;
3692
- return semverRegex.test(version);
3693
- }
3694
- /**
3695
- * Check if type is system (global)
3696
- * @param graphType - graph type
3697
- * @returns true if graph is system
3698
- */
3699
- static isSystemGraph(graphType) {
3700
- const { companyId } = this.parse(graphType);
3701
- return companyId === "global";
3702
- }
3703
- /**
3704
- * Compare versions (simple comparison for sorting)
3705
- * @param a - first version
3706
- * @param b - second version
3707
- * @returns -1, 0, 1 for sorting
3708
- */
3709
- static compareVersions(a, b) {
3710
- const parseVersion = (v) => {
3711
- const [main, prerelease] = v.split("-");
3712
- const [major, minor, patch] = main.split(".").map(Number);
3713
- return { major, minor, patch, prerelease };
3714
- };
3715
- const versionA = parseVersion(a);
3716
- const versionB = parseVersion(b);
3717
- if (versionA.major !== versionB.major) {
3718
- return versionA.major - versionB.major;
3719
- }
3720
- if (versionA.minor !== versionB.minor) {
3721
- return versionA.minor - versionB.minor;
3722
- }
3723
- if (versionA.patch !== versionB.patch) {
3724
- return versionA.patch - versionB.patch;
3725
- }
3726
- if (versionA.prerelease && !versionB.prerelease) return -1;
3727
- if (!versionA.prerelease && versionB.prerelease) return 1;
3728
- if (versionA.prerelease && versionB.prerelease) {
3729
- return versionA.prerelease.localeCompare(versionB.prerelease);
3730
- }
3731
- return 0;
3732
- }
3733
- };
3734
-
3735
- // src/graph/versioning/versioned-graph.service.ts
3736
- var VersionedGraphService = class {
3737
- logger = new Logger(VersionedGraphService.name);
3738
- versionConfigs = /* @__PURE__ */ new Map();
3739
- constructor() {
3740
- }
3741
- /**
3742
- * Register versioning configuration
3743
- */
3744
- registerVersioning(config) {
3745
- this.versionConfigs.set(config.baseGraphType, config);
3746
- this.logger.log(
3747
- `Registered versioning for ${config.baseGraphType} with ${config.versions.length} versions`
3748
- );
3749
- }
3750
- /**
3751
- * Resolve graph version
3752
- */
3753
- async resolveVersion(graphType, options = {}) {
3754
- const parsed = GraphTypeUtils.parse(graphType);
3755
- const baseType = GraphTypeUtils.getBaseType(graphType);
3756
- const requestedVersion = GraphTypeUtils.getVersion(graphType) || options.requestedVersion;
3757
- const config = this.versionConfigs.get(baseType);
3758
- if (!config) {
3759
- throw new Error(`No versioning configuration found for ${baseType}`);
3760
- }
3761
- const route = this.findBestVersionRoute(config, requestedVersion, options);
3762
- if (!route) {
3763
- throw new Error(
3764
- `No compatible version found for ${graphType} with options: ${JSON.stringify(options)}`
3765
- );
3766
- }
3767
- const fullGraphType = GraphTypeUtils.build(
3768
- parsed.companyId,
3769
- parsed.name,
3770
- route.version
3771
- );
3772
- return {
3773
- version: route.version,
3774
- builderClass: route.builderClass,
3775
- fullGraphType
3776
- };
3777
- }
3778
- /**
3779
- * Create builder for specified version
3780
- */
3781
- async createVersionedBuilder(graphType, moduleRef, options = {}) {
3782
- const resolution = await this.resolveVersion(graphType, options);
3783
- try {
3784
- if (!moduleRef) {
3785
- throw new Error(
3786
- "ModuleRef is not available - falling back to direct instantiation"
3787
- );
3788
- }
3789
- const builder = await moduleRef.create(resolution.builderClass);
3790
- this.logger.debug(
3791
- `Created versioned builder for ${resolution.fullGraphType}`
3792
- );
3793
- return builder;
3794
- } catch (error) {
3795
- this.logger.error(
3796
- `Failed to create builder for ${resolution.fullGraphType}: ${error.message}`
3797
- );
3798
- throw new Error(`Failed to create versioned builder: ${error.message}`);
3799
- }
3800
- }
3801
- /**
3802
- * Get all available versions for a graph
3803
- */
3804
- getAvailableVersions(baseGraphType) {
3805
- const config = this.versionConfigs.get(baseGraphType);
3806
- if (!config) {
3807
- return [];
3808
- }
3809
- return config.versions.map((route) => route.version).sort((a, b) => GraphTypeUtils.compareVersions(b, a));
3810
- }
3811
- /**
3812
- * Check version support
3813
- */
3814
- isVersionSupported(graphType, options = {}) {
3815
- try {
3816
- const baseType = GraphTypeUtils.getBaseType(graphType);
3817
- const requestedVersion = GraphTypeUtils.getVersion(graphType);
3818
- const config = this.versionConfigs.get(baseType);
3819
- if (!config) {
3820
- return false;
3821
- }
3822
- const route = this.findBestVersionRoute(
3823
- config,
3824
- requestedVersion,
3825
- options
3826
- );
3827
- return route !== null;
3828
- } catch {
3829
- return false;
3830
- }
3831
- }
3832
- /**
3833
- * Find best version
3834
- */
3835
- findBestVersionRoute(config, requestedVersion, options = {}) {
3836
- const { strict = false } = options;
3837
- let candidates = [...config.versions];
3838
- if (requestedVersion) {
3839
- const exactMatch = candidates.find(
3840
- (route) => route.version === requestedVersion
3841
- );
3842
- if (exactMatch) {
3843
- return exactMatch;
3844
- }
3845
- if (strict) {
3846
- return null;
3847
- }
3848
- const compatibleVersions = candidates.filter(
3849
- (route) => this.isVersionCompatible(requestedVersion, route.version)
3850
- );
3851
- if (compatibleVersions.length > 0) {
3852
- return compatibleVersions.sort(
3853
- (a, b) => GraphTypeUtils.compareVersions(b.version, a.version)
3854
- )[0];
3855
- }
3856
- }
3857
- const defaultRoute = candidates.find((route) => route.isDefault);
3858
- if (defaultRoute) {
3859
- return defaultRoute;
3860
- }
3861
- if (config.defaultVersionStrategy === "latest" || !config.defaultVersionStrategy) {
3862
- const sortedVersions = candidates.sort(
3863
- (a, b) => GraphTypeUtils.compareVersions(b.version, a.version)
3864
- );
3865
- return sortedVersions[0] || null;
3866
- }
3867
- return null;
3868
- }
3869
- /**
3870
- * Check version compatibility (simplified semantics)
3871
- */
3872
- isVersionCompatible(requested, available) {
3873
- try {
3874
- const requestedParts = requested.split(".").map(Number);
3875
- const availableParts = available.split(".").map(Number);
3876
- if (requestedParts[0] !== availableParts[0]) {
3877
- return false;
3878
- }
3879
- return GraphTypeUtils.compareVersions(available, requested) >= 0;
3880
- } catch {
3881
- return false;
3882
- }
3883
- }
3884
- /**
3885
- * Get versioning configuration information
3886
- */
3887
- getVersioningInfo(baseGraphType) {
3888
- return this.versionConfigs.get(baseGraphType) || null;
3889
- }
3890
- };
3891
- VersionedGraphService = __decorateClass([
3892
- Injectable()
3893
- ], VersionedGraphService);
4234
+ // src/graph/versioning/index.ts
4235
+ init_versioned_graph_service();
3894
4236
  var logger = new Logger("ApiCallTracer");
3895
4237
  var DEFAULT_TRACER_OPTIONS = {
3896
4238
  maxStringLength: 5e3,
@@ -4034,8 +4376,36 @@ function sanitizeTraceError(error, options) {
4034
4376
  raw: sanitizeTraceData(error, 0, /* @__PURE__ */ new WeakSet(), options)
4035
4377
  };
4036
4378
  }
4037
-
4038
- // src/engines/langgraph/event-processor.utils.ts
4379
+ var GraphEngineType = /* @__PURE__ */ ((GraphEngineType2) => {
4380
+ GraphEngineType2["LANGGRAPH"] = "langgraph";
4381
+ GraphEngineType2["LANGFLOW"] = "langflow";
4382
+ GraphEngineType2["FLOWISE"] = "flowise";
4383
+ return GraphEngineType2;
4384
+ })(GraphEngineType || {});
4385
+ var GraphEngineFactory = class {
4386
+ constructor(langgraph) {
4387
+ this.langgraph = langgraph;
4388
+ }
4389
+ /**
4390
+ * Get engine for the specified type
4391
+ */
4392
+ getEngine(engineType) {
4393
+ switch (engineType) {
4394
+ case "langgraph" /* LANGGRAPH */:
4395
+ return this.langgraph;
4396
+ // Will add other types in the future
4397
+ // case GraphEngineType.LANGFLOW:
4398
+ // return new LangFlowEngine();
4399
+ // case GraphEngineType.FLOWISE:
4400
+ // return new FlowiseEngine();
4401
+ default:
4402
+ throw new Error(`Unsupported graph engine type: ${engineType}`);
4403
+ }
4404
+ }
4405
+ };
4406
+ GraphEngineFactory = __decorateClass([
4407
+ Injectable()
4408
+ ], GraphEngineFactory);
4039
4409
  var EventProcessor = class {
4040
4410
  logger = new Logger(EventProcessor.name);
4041
4411
  /**
@@ -4568,12 +4938,11 @@ var LangGraphEngine = class {
4568
4938
  }
4569
4939
  };
4570
4940
  LangGraphEngine = __decorateClass([
4571
- Injectable(),
4572
- __decorateParam(0, Inject())
4941
+ Injectable()
4573
4942
  ], LangGraphEngine);
4574
4943
 
4575
4944
  // src/core/universal-graph.module.ts
4576
- init_ui_dispatch_controller();
4945
+ init_builder_registry_service();
4577
4946
  init_agent_ui();
4578
4947
  function createMetaBuilder(config, versionedGraphService, moduleRef, callbackRegistry, endpointRegistry) {
4579
4948
  const className = `${config.baseGraphType.replace(/\./g, "")}VersionRouter`;
@@ -4642,6 +5011,8 @@ function createMetaBuilder(config, versionedGraphService, moduleRef, callbackReg
4642
5011
  var UniversalGraphModule = class {
4643
5012
  static forRoot(options) {
4644
5013
  const providers = [
5014
+ // Discovery services from @nestjs/core
5015
+ MetadataScanner,
4645
5016
  // Event processor for stream handling
4646
5017
  EventProcessor,
4647
5018
  // Graph engines
@@ -4671,14 +5042,8 @@ var UniversalGraphModule = class {
4671
5042
  provide: CallbackRegistry,
4672
5043
  useClass: CallbackRegistry
4673
5044
  },
4674
- {
4675
- provide: EndpointRegistry,
4676
- useClass: EndpointRegistry
4677
- },
4678
- {
4679
- provide: UIEndpointsDiscoveryService,
4680
- useClass: UIEndpointsDiscoveryService
4681
- },
5045
+ EndpointRegistry,
5046
+ UIEndpointsDiscoveryService,
4682
5047
  {
4683
5048
  provide: CallbackACL,
4684
5049
  useClass: CallbackACL
@@ -4755,14 +5120,6 @@ var UniversalGraphModule = class {
4755
5120
  },
4756
5121
  inject: [CallbackRegistry]
4757
5122
  },
4758
- {
4759
- provide: "UI_ENDPOINTS_DISCOVERY",
4760
- useFactory: async (discoveryService) => {
4761
- await discoveryService.discoverUIEndpoints();
4762
- return true;
4763
- },
4764
- inject: [UIEndpointsDiscoveryService]
4765
- },
4766
5123
  {
4767
5124
  provide: "GRAPH_ENGINE",
4768
5125
  useFactory: (factory) => {
@@ -5182,6 +5539,94 @@ var McpToolFilter = class _McpToolFilter {
5182
5539
  }
5183
5540
  }
5184
5541
  };
5542
+ var McpRuntimeHttpClient = class {
5543
+ logger = new Logger(McpRuntimeHttpClient.name);
5544
+ httpClient;
5545
+ baseUrl;
5546
+ constructor(mcpRuntimeUrl) {
5547
+ this.baseUrl = mcpRuntimeUrl || process.env.MCP_RUNTIME_URL || "http://localhost:3004";
5548
+ this.httpClient = axios2.create({
5549
+ baseURL: this.baseUrl,
5550
+ timeout: 3e4
5551
+ // 30 seconds
5552
+ });
5553
+ this.logger.log(
5554
+ `MCP Runtime HTTP Client initialized with URL: ${this.baseUrl}`
5555
+ );
5556
+ }
5557
+ /**
5558
+ * Get all available tools from MCP Runtime
5559
+ */
5560
+ async getTools() {
5561
+ try {
5562
+ this.logger.debug("Fetching available tools from MCP runtime");
5563
+ const response = await this.httpClient.get("/tools/list");
5564
+ const tools = Array.isArray(response.data) ? response.data : [];
5565
+ this.logger.log(`Retrieved ${tools.length} tools from MCP runtime`);
5566
+ return tools;
5567
+ } catch (error) {
5568
+ this.logger.error("Failed to fetch tools from MCP runtime:", error);
5569
+ throw new Error(`Failed to fetch tools: ${error.message}`);
5570
+ }
5571
+ }
5572
+ /**
5573
+ * Execute a tool by name with given arguments
5574
+ */
5575
+ async executeTool(name, args, context) {
5576
+ try {
5577
+ this.logger.debug(`Executing tool: ${name} with args:`, args);
5578
+ const payload = {
5579
+ name,
5580
+ arguments: args || {}
5581
+ };
5582
+ if (context) {
5583
+ payload.context = context;
5584
+ }
5585
+ const response = await this.httpClient.post("/tools/execute", payload);
5586
+ this.logger.log(`Tool ${name} executed successfully`);
5587
+ return response.data;
5588
+ } catch (error) {
5589
+ this.logger.error(`Failed to execute tool ${name}:`, error);
5590
+ if (error.response) {
5591
+ return {
5592
+ success: false,
5593
+ error: error.response.data.message || error.response.data.error || "Tool execution failed"
5594
+ };
5595
+ }
5596
+ return {
5597
+ success: false,
5598
+ error: error.message || "Unknown error occurred"
5599
+ };
5600
+ }
5601
+ }
5602
+ /**
5603
+ * Get tool execution statistics from MCP Runtime
5604
+ */
5605
+ async getToolStats() {
5606
+ try {
5607
+ const response = await this.httpClient.get("/tools/stats");
5608
+ return response.data;
5609
+ } catch (error) {
5610
+ this.logger.error("Failed to fetch tool stats:", error);
5611
+ return null;
5612
+ }
5613
+ }
5614
+ /**
5615
+ * Health check for MCP Runtime service
5616
+ */
5617
+ async isHealthy() {
5618
+ try {
5619
+ const response = await this.httpClient.get("/", { timeout: 5e3 });
5620
+ return response.status === 200;
5621
+ } catch (error) {
5622
+ this.logger.warn("MCP Runtime health check failed:", error.message);
5623
+ return false;
5624
+ }
5625
+ }
5626
+ };
5627
+ McpRuntimeHttpClient = __decorateClass([
5628
+ Injectable()
5629
+ ], McpRuntimeHttpClient);
5185
5630
 
5186
5631
  // src/models/enums.ts
5187
5632
  var ModelProvider = /* @__PURE__ */ ((ModelProvider2) => {
@@ -6343,6 +6788,28 @@ RetrieverService = __decorateClass([
6343
6788
  Injectable()
6344
6789
  ], RetrieverService);
6345
6790
 
6346
- export { AbstractGraphBuilder, AttachmentType, GraphController as BaseGraphServiceController, UniversalGraphModule as BaseGraphServiceModule, BuilderRegistryService, Callback, CallbackACL, CallbackAuditAction, CallbackAuditor, CallbackController, CallbackMetrics, CallbackPatchService, CallbackRateLimiter, CallbackRegistry, CallbackStore, CallbackTokenGuard, ChatFeature, DEFAULT_TRACER_OPTIONS, ENDPOINT_METADATA_KEY, Endpoint, EndpointRegistry, EventProcessor, GraphController, GraphEngineFactory, GraphEngineType, GraphManifestSchema, GraphManifestValidator, GraphServiceTokens, GraphTypeUtils, IdempotencyManager, IdempotencyStatus, LangGraphEngine, McpConverter, McpToolFilter, ModelInitializer, ModelProvider, ModelType, RetrieverSearchType, RetrieverService, SmartCallbackRouter, StreamChannel, TelegramPatchHandler, UIDispatchController, UIEndpoint, UIEndpointsDiscoveryService, UniversalCallbackService, UniversalGraphModule, UniversalGraphService, VersionedGraphService, VoyageAIRerank, WebPatchHandler, WithCallbacks, WithEndpoints, WithUIEndpoints, bootstrap, createEndpointDescriptors, findCallbackMethod, findEndpointMethod, getCallbackMetadata, getEndpointMetadata, getUIEndpointClassMetadata, getUIEndpointMethodsMetadata, hasCallbacks, hasUIEndpoints, prepareModelWithTools, registerFinanceExampleCallback, registerUIEndpointsFromClass, sanitizeTraceData, traceApiCall };
6791
+ // src/utils/index.ts
6792
+ init_graph_type_utils();
6793
+
6794
+ // src/service-discovery/index.ts
6795
+ init_file_based_discovery();
6796
+ var StaticDiscovery = class {
6797
+ constructor(services) {
6798
+ this.services = services;
6799
+ }
6800
+ /**
6801
+ * Get list of services by category
6802
+ */
6803
+ async getServices(category) {
6804
+ return this.services.filter(
6805
+ (service) => service.category === category || service.metadata?.category === category
6806
+ );
6807
+ }
6808
+ };
6809
+ StaticDiscovery = __decorateClass([
6810
+ Injectable()
6811
+ ], StaticDiscovery);
6812
+
6813
+ export { AbstractGraphBuilder, AttachmentType, GraphController as BaseGraphServiceController, UniversalGraphModule as BaseGraphServiceModule, BuilderRegistryService, Callback, CallbackACL, CallbackAuditAction, CallbackAuditor, CallbackController, CallbackMetrics, CallbackPatchService, CallbackRateLimiter, CallbackRegistry, CallbackStore, CallbackTokenGuard, ChatFeature, DEFAULT_TRACER_OPTIONS, ENDPOINT_METADATA_KEY, Endpoint, EndpointRegistry, EventProcessor, FileBasedDiscovery, GraphController, GraphEngineFactory, GraphEngineType, GraphManifestSchema, GraphManifestValidator, GraphServiceTokens, GraphTypeUtils, IdempotencyManager, IdempotencyStatus, LangGraphEngine, McpConverter, McpRuntimeHttpClient, McpToolFilter, ModelInitializer, ModelProvider, ModelType, RetrieverSearchType, RetrieverService, SmartCallbackRouter, StaticDiscovery, StreamChannel, TelegramPatchHandler, UIDispatchController, UIEndpoint, UIEndpointsDiscoveryService, UniversalCallbackService, UniversalGraphModule, UniversalGraphService, VersionedGraphService, VoyageAIRerank, WebPatchHandler, WithCallbacks, WithEndpoints, WithUIEndpoints, bootstrap, createEndpointDescriptors, findCallbackMethod, findEndpointMethod, getCallbackMetadata, getEndpointMetadata, getUIEndpointClassMetadata, getUIEndpointMethodsMetadata, hasCallbacks, hasUIEndpoints, prepareModelWithTools, registerFinanceExampleCallback, registerUIEndpointsFromClass, sanitizeTraceData, traceApiCall };
6347
6814
  //# sourceMappingURL=index.js.map
6348
6815
  //# sourceMappingURL=index.js.map