@flutchai/flutch-sdk 0.1.24 → 0.1.26
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.cjs +284 -94
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +38 -10
- package/dist/index.d.ts +38 -10
- package/dist/index.js +284 -97
- package/dist/index.js.map +1 -1
- package/package.json +4 -2
package/dist/index.cjs
CHANGED
|
@@ -11,7 +11,11 @@ var promClient = require('prom-client');
|
|
|
11
11
|
var core = require('@nestjs/core');
|
|
12
12
|
var net = require('net');
|
|
13
13
|
var config = require('@nestjs/config');
|
|
14
|
+
var mongoose = require('mongoose');
|
|
15
|
+
var langgraphCheckpointMongodb = require('@langchain/langgraph-checkpoint-mongodb');
|
|
14
16
|
var LangGraph = require('@langchain/langgraph');
|
|
17
|
+
var messages = require('@langchain/core/messages');
|
|
18
|
+
var dispatch = require('@langchain/core/callbacks/dispatch');
|
|
15
19
|
var tools = require('@langchain/core/tools');
|
|
16
20
|
var zod = require('zod');
|
|
17
21
|
var axios2 = require('axios');
|
|
@@ -48,6 +52,7 @@ var fs__namespace = /*#__PURE__*/_interopNamespace(fs);
|
|
|
48
52
|
var path2__namespace = /*#__PURE__*/_interopNamespace(path2);
|
|
49
53
|
var os__namespace = /*#__PURE__*/_interopNamespace(os);
|
|
50
54
|
var net__namespace = /*#__PURE__*/_interopNamespace(net);
|
|
55
|
+
var mongoose__default = /*#__PURE__*/_interopDefault(mongoose);
|
|
51
56
|
var LangGraph__namespace = /*#__PURE__*/_interopNamespace(LangGraph);
|
|
52
57
|
var axios2__default = /*#__PURE__*/_interopDefault(axios2);
|
|
53
58
|
|
|
@@ -1245,28 +1250,54 @@ var init_versioned_graph_service = __esm({
|
|
|
1245
1250
|
], exports.VersionedGraphService);
|
|
1246
1251
|
}
|
|
1247
1252
|
});
|
|
1253
|
+
function generateCallbackToken(graphType) {
|
|
1254
|
+
return `cb::${graphType}::${crypto.randomBytes(8).toString("base64url")}`;
|
|
1255
|
+
}
|
|
1256
|
+
function createCallbackRecord(entry, token, now) {
|
|
1257
|
+
return {
|
|
1258
|
+
...entry,
|
|
1259
|
+
token,
|
|
1260
|
+
status: "pending",
|
|
1261
|
+
createdAt: now,
|
|
1262
|
+
retries: 0
|
|
1263
|
+
};
|
|
1264
|
+
}
|
|
1265
|
+
function resolveCallbackTTL(entry) {
|
|
1266
|
+
return entry.metadata?.ttlSec ?? 600;
|
|
1267
|
+
}
|
|
1268
|
+
function parseCallbackRecord(data) {
|
|
1269
|
+
try {
|
|
1270
|
+
return JSON.parse(data);
|
|
1271
|
+
} catch {
|
|
1272
|
+
return null;
|
|
1273
|
+
}
|
|
1274
|
+
}
|
|
1275
|
+
function markAsFailed(record, error) {
|
|
1276
|
+
return {
|
|
1277
|
+
...record,
|
|
1278
|
+
status: "failed",
|
|
1279
|
+
retries: (record.retries || 0) + 1,
|
|
1280
|
+
lastError: error
|
|
1281
|
+
};
|
|
1282
|
+
}
|
|
1283
|
+
function markAsPending(record) {
|
|
1284
|
+
return { ...record, status: "pending" };
|
|
1285
|
+
}
|
|
1286
|
+
|
|
1287
|
+
// src/callbacks/callback-store.ts
|
|
1248
1288
|
var CallbackStore = class {
|
|
1249
1289
|
constructor(redis) {
|
|
1250
1290
|
this.redis = redis;
|
|
1251
1291
|
this.isProduction = process.env.NODE_ENV === "production";
|
|
1252
1292
|
}
|
|
1253
1293
|
isProduction;
|
|
1254
|
-
generateToken(graphType) {
|
|
1255
|
-
return `cb::${graphType}::${crypto.randomBytes(8).toString("base64url")}`;
|
|
1256
|
-
}
|
|
1257
1294
|
/**
|
|
1258
1295
|
* Issues a new callback token and persists its payload.
|
|
1259
1296
|
*/
|
|
1260
1297
|
async issue(entry) {
|
|
1261
|
-
const token =
|
|
1262
|
-
const record =
|
|
1263
|
-
|
|
1264
|
-
token,
|
|
1265
|
-
status: "pending",
|
|
1266
|
-
createdAt: Date.now(),
|
|
1267
|
-
retries: 0
|
|
1268
|
-
};
|
|
1269
|
-
const ttl = entry.metadata?.ttlSec ?? 600;
|
|
1298
|
+
const token = generateCallbackToken(entry.graphType);
|
|
1299
|
+
const record = createCallbackRecord(entry, token, Date.now());
|
|
1300
|
+
const ttl = resolveCallbackTTL(entry);
|
|
1270
1301
|
await this.redis.setex(`callback:${token}`, ttl, JSON.stringify(record));
|
|
1271
1302
|
return token;
|
|
1272
1303
|
}
|
|
@@ -1281,7 +1312,9 @@ var CallbackStore = class {
|
|
|
1281
1312
|
}
|
|
1282
1313
|
}
|
|
1283
1314
|
/**
|
|
1284
|
-
* Production version
|
|
1315
|
+
* Production version: uses Redis Lua scripting for atomic get-and-lock.
|
|
1316
|
+
* NOTE: redis.eval() here executes a Lua script on the Redis server,
|
|
1317
|
+
* NOT JavaScript eval(). This is the standard ioredis API for Lua scripting.
|
|
1285
1318
|
*/
|
|
1286
1319
|
async getAndLockAtomic(token) {
|
|
1287
1320
|
const script = `
|
|
@@ -1305,18 +1338,17 @@ var CallbackStore = class {
|
|
|
1305
1338
|
if (!data) {
|
|
1306
1339
|
return null;
|
|
1307
1340
|
}
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
await this.redis.set(key, JSON.stringify(record));
|
|
1315
|
-
return record;
|
|
1316
|
-
} catch (error) {
|
|
1317
|
-
console.error("Failed to parse callback record:", error);
|
|
1341
|
+
const record = parseCallbackRecord(data);
|
|
1342
|
+
if (!record) {
|
|
1343
|
+
console.error("Failed to parse callback record");
|
|
1344
|
+
return null;
|
|
1345
|
+
}
|
|
1346
|
+
if (record.status !== "pending") {
|
|
1318
1347
|
return null;
|
|
1319
1348
|
}
|
|
1349
|
+
record.status = "processing";
|
|
1350
|
+
await this.redis.set(key, JSON.stringify(record));
|
|
1351
|
+
return record;
|
|
1320
1352
|
}
|
|
1321
1353
|
/**
|
|
1322
1354
|
* Finalizes callback processing by removing token.
|
|
@@ -1335,7 +1367,8 @@ var CallbackStore = class {
|
|
|
1335
1367
|
}
|
|
1336
1368
|
}
|
|
1337
1369
|
/**
|
|
1338
|
-
* Production version
|
|
1370
|
+
* Production version: uses Redis Lua scripting for atomic fail.
|
|
1371
|
+
* NOTE: redis.eval() here executes a Lua script on the Redis server.
|
|
1339
1372
|
*/
|
|
1340
1373
|
async failAtomic(token, error) {
|
|
1341
1374
|
const script = `
|
|
@@ -1360,17 +1393,14 @@ var CallbackStore = class {
|
|
|
1360
1393
|
if (!data) {
|
|
1361
1394
|
return null;
|
|
1362
1395
|
}
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
record.retries = (record.retries || 0) + 1;
|
|
1367
|
-
record.lastError = error;
|
|
1368
|
-
await this.redis.set(key, JSON.stringify(record));
|
|
1369
|
-
return record;
|
|
1370
|
-
} catch (parseError) {
|
|
1371
|
-
console.error("Failed to parse callback record:", parseError);
|
|
1396
|
+
const record = parseCallbackRecord(data);
|
|
1397
|
+
if (!record) {
|
|
1398
|
+
console.error("Failed to parse callback record");
|
|
1372
1399
|
return null;
|
|
1373
1400
|
}
|
|
1401
|
+
const updated = markAsFailed(record, error);
|
|
1402
|
+
await this.redis.set(key, JSON.stringify(updated));
|
|
1403
|
+
return updated;
|
|
1374
1404
|
}
|
|
1375
1405
|
/**
|
|
1376
1406
|
* Reset callback status to pending for retry.
|
|
@@ -1383,7 +1413,8 @@ var CallbackStore = class {
|
|
|
1383
1413
|
}
|
|
1384
1414
|
}
|
|
1385
1415
|
/**
|
|
1386
|
-
* Production version
|
|
1416
|
+
* Production version: uses Redis Lua scripting for atomic retry.
|
|
1417
|
+
* NOTE: redis.eval() here executes a Lua script on the Redis server.
|
|
1387
1418
|
*/
|
|
1388
1419
|
async retryAtomic(token) {
|
|
1389
1420
|
const script = `
|
|
@@ -1406,15 +1437,14 @@ var CallbackStore = class {
|
|
|
1406
1437
|
if (!data) {
|
|
1407
1438
|
return null;
|
|
1408
1439
|
}
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
await this.redis.set(key, JSON.stringify(record));
|
|
1413
|
-
return record;
|
|
1414
|
-
} catch (parseError) {
|
|
1415
|
-
console.error("Failed to parse callback record:", parseError);
|
|
1440
|
+
const record = parseCallbackRecord(data);
|
|
1441
|
+
if (!record) {
|
|
1442
|
+
console.error("Failed to parse callback record");
|
|
1416
1443
|
return null;
|
|
1417
1444
|
}
|
|
1445
|
+
const updated = markAsPending(record);
|
|
1446
|
+
await this.redis.set(key, JSON.stringify(updated));
|
|
1447
|
+
return updated;
|
|
1418
1448
|
}
|
|
1419
1449
|
};
|
|
1420
1450
|
|
|
@@ -3066,6 +3096,38 @@ exports.CallbackController = __decorateClass([
|
|
|
3066
3096
|
|
|
3067
3097
|
// src/graph/abstract-graph.builder.ts
|
|
3068
3098
|
init_agent_ui();
|
|
3099
|
+
|
|
3100
|
+
// src/graph/graph.logic.ts
|
|
3101
|
+
function isValidSemver(version) {
|
|
3102
|
+
return /^\d+\.\d+\.\d+$/.test(version);
|
|
3103
|
+
}
|
|
3104
|
+
function parseCallbackToken(token) {
|
|
3105
|
+
const parts = token.split("_");
|
|
3106
|
+
if (parts.length < 4 || parts[0] !== "cb") {
|
|
3107
|
+
return null;
|
|
3108
|
+
}
|
|
3109
|
+
const graphName = parts[1];
|
|
3110
|
+
const handler = parts[2];
|
|
3111
|
+
const graphType = `${graphName}::1.0.0`;
|
|
3112
|
+
return { graphType, handler };
|
|
3113
|
+
}
|
|
3114
|
+
function decodeCallbackParams(token) {
|
|
3115
|
+
const parts = token.split("_");
|
|
3116
|
+
if (parts.length < 4) {
|
|
3117
|
+
return {};
|
|
3118
|
+
}
|
|
3119
|
+
try {
|
|
3120
|
+
const encodedParams = parts.slice(3).join("_");
|
|
3121
|
+
const decodedParams = Buffer.from(encodedParams, "base64url").toString(
|
|
3122
|
+
"utf8"
|
|
3123
|
+
);
|
|
3124
|
+
return JSON.parse(decodedParams);
|
|
3125
|
+
} catch {
|
|
3126
|
+
return {};
|
|
3127
|
+
}
|
|
3128
|
+
}
|
|
3129
|
+
|
|
3130
|
+
// src/graph/abstract-graph.builder.ts
|
|
3069
3131
|
var _AbstractGraphBuilder = class _AbstractGraphBuilder {
|
|
3070
3132
|
logger = new common.Logger(_AbstractGraphBuilder.name);
|
|
3071
3133
|
callbackRegistry;
|
|
@@ -3136,13 +3198,37 @@ var _AbstractGraphBuilder = class _AbstractGraphBuilder {
|
|
|
3136
3198
|
/**
|
|
3137
3199
|
* Basic configuration preparation for graph execution
|
|
3138
3200
|
* Automatically creates context with tracer and usageRecorder
|
|
3139
|
-
*
|
|
3201
|
+
* Handles message deserialization and LangGraph-compatible structure
|
|
3202
|
+
* FINAL method - cannot be overridden. Use customizeConfig() hook instead.
|
|
3140
3203
|
*/
|
|
3141
3204
|
async prepareConfig(payload) {
|
|
3142
3205
|
const context = this.createGraphContext(payload);
|
|
3143
|
-
|
|
3206
|
+
let message = payload.message;
|
|
3207
|
+
if (payload.message && typeof payload.message === "object" && "lc" in payload.message) {
|
|
3208
|
+
try {
|
|
3209
|
+
const { load } = await import('@langchain/core/load');
|
|
3210
|
+
message = await load(JSON.stringify(payload.message));
|
|
3211
|
+
this.logger.debug({
|
|
3212
|
+
message: "Deserialized BaseMessage using load()",
|
|
3213
|
+
type: message.constructor?.name
|
|
3214
|
+
});
|
|
3215
|
+
} catch (error) {
|
|
3216
|
+
this.logger.warn({
|
|
3217
|
+
message: "Failed to deserialize message",
|
|
3218
|
+
error: error.message
|
|
3219
|
+
});
|
|
3220
|
+
}
|
|
3221
|
+
}
|
|
3222
|
+
const baseConfig = {
|
|
3223
|
+
// Input for LangGraph (messages array)
|
|
3224
|
+
input: message ? {
|
|
3225
|
+
messages: [message]
|
|
3226
|
+
} : void 0,
|
|
3227
|
+
// Configurable settings for LangGraph checkpointing and context
|
|
3144
3228
|
configurable: {
|
|
3145
3229
|
thread_id: payload.threadId,
|
|
3230
|
+
checkpoint_ns: this.graphType,
|
|
3231
|
+
checkpoint_id: `${payload.threadId}-${Date.now()}`,
|
|
3146
3232
|
context,
|
|
3147
3233
|
// Add metadata for compatibility
|
|
3148
3234
|
metadata: {
|
|
@@ -3150,10 +3236,39 @@ var _AbstractGraphBuilder = class _AbstractGraphBuilder {
|
|
|
3150
3236
|
agentId: payload.agentId,
|
|
3151
3237
|
requestId: payload.requestId,
|
|
3152
3238
|
graphType: this.graphType,
|
|
3153
|
-
version: this.version
|
|
3154
|
-
|
|
3239
|
+
version: this.version,
|
|
3240
|
+
workflowType: this.graphType
|
|
3241
|
+
},
|
|
3242
|
+
// Graph-specific settings from payload
|
|
3243
|
+
graphSettings: payload.graphSettings || {}
|
|
3155
3244
|
}
|
|
3156
3245
|
};
|
|
3246
|
+
const finalConfig = await this.customizeConfig(baseConfig, payload);
|
|
3247
|
+
return finalConfig;
|
|
3248
|
+
}
|
|
3249
|
+
/**
|
|
3250
|
+
* Hook for customizing config after base preparation
|
|
3251
|
+
* Override this method in child classes to add/modify config fields
|
|
3252
|
+
*
|
|
3253
|
+
* @param config - Base config prepared by SDK
|
|
3254
|
+
* @param payload - Original request payload
|
|
3255
|
+
* @returns Modified config
|
|
3256
|
+
*
|
|
3257
|
+
* @example
|
|
3258
|
+
* ```typescript
|
|
3259
|
+
* protected async customizeConfig(config: any, payload: IGraphRequestPayload): Promise<any> {
|
|
3260
|
+
* // Add custom fields
|
|
3261
|
+
* config.configurable.myCustomField = "value";
|
|
3262
|
+
*
|
|
3263
|
+
* // Modify existing fields
|
|
3264
|
+
* config.configurable.context.customData = await this.loadCustomData(payload);
|
|
3265
|
+
*
|
|
3266
|
+
* return config;
|
|
3267
|
+
* }
|
|
3268
|
+
* ```
|
|
3269
|
+
*/
|
|
3270
|
+
async customizeConfig(config, payload) {
|
|
3271
|
+
return config;
|
|
3157
3272
|
}
|
|
3158
3273
|
/**
|
|
3159
3274
|
* Load graph manifest (if using manifest-based approach)
|
|
@@ -3274,8 +3389,7 @@ var _AbstractGraphBuilder = class _AbstractGraphBuilder {
|
|
|
3274
3389
|
* Version validation
|
|
3275
3390
|
*/
|
|
3276
3391
|
validateVersion() {
|
|
3277
|
-
|
|
3278
|
-
if (!versionRegex.test(this.version)) {
|
|
3392
|
+
if (!isValidSemver(this.version)) {
|
|
3279
3393
|
throw new Error(
|
|
3280
3394
|
`Invalid version format: ${this.version}. Expected format: X.Y.Z`
|
|
3281
3395
|
);
|
|
@@ -3625,36 +3739,21 @@ exports.UniversalGraphService = class UniversalGraphService {
|
|
|
3625
3739
|
* Expected format: cb_{graphName}_{handler}_{encodedParams}
|
|
3626
3740
|
*/
|
|
3627
3741
|
parseCallbackToken(token) {
|
|
3628
|
-
const
|
|
3629
|
-
if (
|
|
3742
|
+
const result = parseCallbackToken(token);
|
|
3743
|
+
if (!result) {
|
|
3630
3744
|
throw new Error(`Invalid callback token format: ${token}`);
|
|
3631
3745
|
}
|
|
3632
|
-
|
|
3633
|
-
const handler = parts[2];
|
|
3634
|
-
const graphType = `${graphName}::1.0.0`;
|
|
3635
|
-
return { graphType, handler };
|
|
3746
|
+
return result;
|
|
3636
3747
|
}
|
|
3637
3748
|
/**
|
|
3638
3749
|
* Extract parameters from callback token
|
|
3639
3750
|
*/
|
|
3640
3751
|
parseCallbackParams(token) {
|
|
3641
|
-
const
|
|
3642
|
-
if (
|
|
3643
|
-
|
|
3644
|
-
}
|
|
3645
|
-
try {
|
|
3646
|
-
const encodedParams = parts.slice(3).join("_");
|
|
3647
|
-
const decodedParams = Buffer.from(encodedParams, "base64url").toString(
|
|
3648
|
-
"utf8"
|
|
3649
|
-
);
|
|
3650
|
-
return JSON.parse(decodedParams);
|
|
3651
|
-
} catch (error) {
|
|
3652
|
-
this.logger.warn(
|
|
3653
|
-
`Failed to parse callback params from token: ${token}`,
|
|
3654
|
-
error
|
|
3655
|
-
);
|
|
3656
|
-
return {};
|
|
3752
|
+
const result = decodeCallbackParams(token);
|
|
3753
|
+
if (Object.keys(result).length === 0 && token.split("_").length >= 4) {
|
|
3754
|
+
this.logger.warn(`Failed to parse callback params from token: ${token}`);
|
|
3657
3755
|
}
|
|
3756
|
+
return result;
|
|
3658
3757
|
}
|
|
3659
3758
|
/**
|
|
3660
3759
|
* Call a graph endpoint
|
|
@@ -3882,6 +3981,24 @@ async function bootstrap(AppModule, options = {}) {
|
|
|
3882
3981
|
// src/core/index.ts
|
|
3883
3982
|
init_builder_registry_service();
|
|
3884
3983
|
|
|
3984
|
+
// src/core/mongodb/mongodb-client.adapter.ts
|
|
3985
|
+
function createMongoClientAdapter(mongooseClient) {
|
|
3986
|
+
if (!mongooseClient || typeof mongooseClient.db !== "function") {
|
|
3987
|
+
throw new Error(
|
|
3988
|
+
"Invalid MongoDB client: missing required methods. Expected MongoClient from mongoose.Connection.getClient()"
|
|
3989
|
+
);
|
|
3990
|
+
}
|
|
3991
|
+
const requiredMethods = ["db", "close", "connect"];
|
|
3992
|
+
for (const method of requiredMethods) {
|
|
3993
|
+
if (typeof mongooseClient[method] !== "function") {
|
|
3994
|
+
throw new Error(
|
|
3995
|
+
`Invalid MongoDB client: missing required method '${method}'`
|
|
3996
|
+
);
|
|
3997
|
+
}
|
|
3998
|
+
}
|
|
3999
|
+
return mongooseClient;
|
|
4000
|
+
}
|
|
4001
|
+
|
|
3885
4002
|
// src/messages/attachments.ts
|
|
3886
4003
|
var AttachmentType = /* @__PURE__ */ ((AttachmentType2) => {
|
|
3887
4004
|
AttachmentType2["IMAGE"] = "image";
|
|
@@ -4322,8 +4439,8 @@ function getLangGraphDispatch() {
|
|
|
4322
4439
|
if (cachedDispatch !== void 0) {
|
|
4323
4440
|
return cachedDispatch;
|
|
4324
4441
|
}
|
|
4325
|
-
const { dispatchCustomEvent } = LangGraph__namespace;
|
|
4326
|
-
cachedDispatch = typeof
|
|
4442
|
+
const { dispatchCustomEvent: dispatchCustomEvent2 } = LangGraph__namespace;
|
|
4443
|
+
cachedDispatch = typeof dispatchCustomEvent2 === "function" ? dispatchCustomEvent2 : null;
|
|
4327
4444
|
return cachedDispatch;
|
|
4328
4445
|
}
|
|
4329
4446
|
function sanitizeTraceData(value, depth = 0, seen = /* @__PURE__ */ new WeakSet(), options) {
|
|
@@ -4630,6 +4747,14 @@ exports.EventProcessor = class EventProcessor {
|
|
|
4630
4747
|
*/
|
|
4631
4748
|
processEvent(acc, event, onPartial) {
|
|
4632
4749
|
this.captureTraceEvent(acc, event);
|
|
4750
|
+
if (event.event === "on_custom_event" && event.data) {
|
|
4751
|
+
const channel = event.metadata?.stream_channel ?? "text" /* TEXT */;
|
|
4752
|
+
if (event.name === "send_static_message" && event.data.content) {
|
|
4753
|
+
const blocks = this.normalizeContentBlocks(event.data.content);
|
|
4754
|
+
this.processContentStream(acc, channel, blocks, onPartial);
|
|
4755
|
+
}
|
|
4756
|
+
return;
|
|
4757
|
+
}
|
|
4633
4758
|
if (event.event === "on_chat_model_stream" && event.data?.chunk?.content) {
|
|
4634
4759
|
const channel = event.metadata?.stream_channel ?? "text" /* TEXT */;
|
|
4635
4760
|
const blocks = this.normalizeContentBlocks(event.data.chunk.content);
|
|
@@ -4754,6 +4879,7 @@ exports.EventProcessor = class EventProcessor {
|
|
|
4754
4879
|
}
|
|
4755
4880
|
if (state.currentBlock) {
|
|
4756
4881
|
state.contentChain.push(state.currentBlock);
|
|
4882
|
+
state.currentBlock = null;
|
|
4757
4883
|
}
|
|
4758
4884
|
if (state.contentChain.length > 0) {
|
|
4759
4885
|
allChains.push({
|
|
@@ -5116,6 +5242,13 @@ exports.LangGraphEngine = __decorateClass([
|
|
|
5116
5242
|
common.Injectable(),
|
|
5117
5243
|
__decorateParam(1, common.Optional())
|
|
5118
5244
|
], exports.LangGraphEngine);
|
|
5245
|
+
async function createStaticMessage(content, config) {
|
|
5246
|
+
const message = new messages.AIMessage({
|
|
5247
|
+
content
|
|
5248
|
+
});
|
|
5249
|
+
await dispatch.dispatchCustomEvent("send_static_message", { content }, config);
|
|
5250
|
+
return message;
|
|
5251
|
+
}
|
|
5119
5252
|
|
|
5120
5253
|
// src/core/universal-graph.module.ts
|
|
5121
5254
|
init_builder_registry_service();
|
|
@@ -5303,6 +5436,58 @@ exports.UniversalGraphModule = class UniversalGraphModule {
|
|
|
5303
5436
|
},
|
|
5304
5437
|
inject: [CallbackRegistry]
|
|
5305
5438
|
},
|
|
5439
|
+
// MongoDB connection (optional - only if mongodb config provided)
|
|
5440
|
+
...options.mongodb ? [
|
|
5441
|
+
{
|
|
5442
|
+
provide: "MONGO_CONNECTION",
|
|
5443
|
+
useFactory: async (configService) => {
|
|
5444
|
+
const logger2 = new common.Logger("UniversalGraphModule");
|
|
5445
|
+
const mongoUri = options.mongodb?.uri || configService.get("MONGODB_URI") || process.env.MONGODB_URI;
|
|
5446
|
+
const dbName = options.mongodb?.dbName || configService.get("MONGO_DB_NAME") || process.env.MONGO_DB_NAME;
|
|
5447
|
+
if (!mongoUri) {
|
|
5448
|
+
throw new Error(
|
|
5449
|
+
"MONGODB_URI is not defined in options, config, or environment"
|
|
5450
|
+
);
|
|
5451
|
+
}
|
|
5452
|
+
logger2.log(
|
|
5453
|
+
`Connecting to MongoDB: ${mongoUri?.substring(0, 50) + "..."}`
|
|
5454
|
+
);
|
|
5455
|
+
try {
|
|
5456
|
+
await mongoose__default.default.connect(mongoUri, { dbName });
|
|
5457
|
+
logger2.log(
|
|
5458
|
+
`Successfully connected to MongoDB (db: ${dbName})`
|
|
5459
|
+
);
|
|
5460
|
+
return mongoose__default.default.connection;
|
|
5461
|
+
} catch (error) {
|
|
5462
|
+
logger2.error("Failed to connect to MongoDB", error);
|
|
5463
|
+
throw error;
|
|
5464
|
+
}
|
|
5465
|
+
},
|
|
5466
|
+
inject: [config.ConfigService]
|
|
5467
|
+
},
|
|
5468
|
+
// MongoDB checkpointer
|
|
5469
|
+
{
|
|
5470
|
+
provide: "CHECKPOINTER",
|
|
5471
|
+
useFactory: async (connection, configService) => {
|
|
5472
|
+
const logger2 = new common.Logger("UniversalGraphModule");
|
|
5473
|
+
const dbName = options.mongodb?.dbName || configService.get("MONGO_DB_NAME") || process.env.MONGO_DB_NAME;
|
|
5474
|
+
const checkpointCollectionName = options.mongodb?.checkpointCollectionName || "checkpoints";
|
|
5475
|
+
const checkpointWritesCollectionName = options.mongodb?.checkpointWritesCollectionName || "checkpoint_writes";
|
|
5476
|
+
logger2.log(
|
|
5477
|
+
`Creating CHECKPOINTER with collections: ${checkpointCollectionName}, ${checkpointWritesCollectionName}`
|
|
5478
|
+
);
|
|
5479
|
+
const mongooseClient = connection.getClient();
|
|
5480
|
+
const mongoClient = createMongoClientAdapter(mongooseClient);
|
|
5481
|
+
return new langgraphCheckpointMongodb.MongoDBSaver({
|
|
5482
|
+
client: mongoClient,
|
|
5483
|
+
dbName,
|
|
5484
|
+
checkpointCollectionName,
|
|
5485
|
+
checkpointWritesCollectionName
|
|
5486
|
+
});
|
|
5487
|
+
},
|
|
5488
|
+
inject: ["MONGO_CONNECTION", config.ConfigService]
|
|
5489
|
+
}
|
|
5490
|
+
] : [],
|
|
5306
5491
|
{
|
|
5307
5492
|
provide: "GRAPH_ENGINE",
|
|
5308
5493
|
useFactory: (langGraphEngine) => langGraphEngine,
|
|
@@ -5984,6 +6169,24 @@ var ChatFeature = /* @__PURE__ */ ((ChatFeature2) => {
|
|
|
5984
6169
|
ChatFeature2["JSON_MODE"] = "json_mode";
|
|
5985
6170
|
return ChatFeature2;
|
|
5986
6171
|
})(ChatFeature || {});
|
|
6172
|
+
function isReasoningModel(modelName) {
|
|
6173
|
+
return modelName.includes("gpt-5") || modelName.includes("gpt-o1") || modelName.includes("gpt-o2") || modelName.includes("gpt-o3") || modelName.includes("gpt-o4") || /^gpt-(5|6|7|8|9)/.test(modelName) || /^gpt-o[1-4]/.test(modelName);
|
|
6174
|
+
}
|
|
6175
|
+
function hashToolsConfig(toolsConfig) {
|
|
6176
|
+
const sorted = toolsConfig.map((t) => `${t.toolName}:${t.enabled}:${JSON.stringify(t.config || {})}`).sort().join("|");
|
|
6177
|
+
return crypto.createHash("md5").update(sorted).digest("hex").slice(0, 16);
|
|
6178
|
+
}
|
|
6179
|
+
function generateModelCacheKey(modelId, temperature, maxTokens, toolsConfig) {
|
|
6180
|
+
const parts = [
|
|
6181
|
+
modelId,
|
|
6182
|
+
temperature ?? "default",
|
|
6183
|
+
maxTokens ?? "default"
|
|
6184
|
+
];
|
|
6185
|
+
if (toolsConfig && toolsConfig.length > 0) {
|
|
6186
|
+
parts.push(hashToolsConfig(toolsConfig));
|
|
6187
|
+
}
|
|
6188
|
+
return parts.join(":");
|
|
6189
|
+
}
|
|
5987
6190
|
var VoyageAIRerank = class extends document_compressors.BaseDocumentCompressor {
|
|
5988
6191
|
apiKey;
|
|
5989
6192
|
model;
|
|
@@ -6279,8 +6482,7 @@ var ModelInitializer = class _ModelInitializer {
|
|
|
6279
6482
|
* Uses MD5 hash to create short, unique identifier
|
|
6280
6483
|
*/
|
|
6281
6484
|
hashToolsConfig(toolsConfig) {
|
|
6282
|
-
|
|
6283
|
-
return crypto.createHash("md5").update(sorted).digest("hex").slice(0, 16);
|
|
6485
|
+
return hashToolsConfig(toolsConfig);
|
|
6284
6486
|
}
|
|
6285
6487
|
/**
|
|
6286
6488
|
* Generate cache key from ModelByIdConfig
|
|
@@ -6288,16 +6490,12 @@ var ModelInitializer = class _ModelInitializer {
|
|
|
6288
6490
|
* Example: "model123:0.7:4096" or "model123:0.7:4096:a1b2c3d4e5f6g7h8"
|
|
6289
6491
|
*/
|
|
6290
6492
|
generateModelCacheKey(config) {
|
|
6291
|
-
|
|
6493
|
+
return generateModelCacheKey(
|
|
6292
6494
|
config.modelId,
|
|
6293
|
-
config.temperature
|
|
6294
|
-
config.maxTokens
|
|
6295
|
-
|
|
6296
|
-
|
|
6297
|
-
const toolsHash = this.hashToolsConfig(config.toolsConfig);
|
|
6298
|
-
parts.push(toolsHash);
|
|
6299
|
-
}
|
|
6300
|
-
return parts.join(":");
|
|
6495
|
+
config.temperature,
|
|
6496
|
+
config.maxTokens,
|
|
6497
|
+
config.toolsConfig
|
|
6498
|
+
);
|
|
6301
6499
|
}
|
|
6302
6500
|
/**
|
|
6303
6501
|
* TEMPORARY SOLUTION for compatibility with new OpenAI models
|
|
@@ -6314,20 +6512,10 @@ var ModelInitializer = class _ModelInitializer {
|
|
|
6314
6512
|
* @returns true if model requires maxCompletionTokens and temperature = 1
|
|
6315
6513
|
*/
|
|
6316
6514
|
requiresMaxCompletionTokens(modelName) {
|
|
6317
|
-
const requiresNew =
|
|
6318
|
-
/^gpt-(5|6|7|8|9)/.test(modelName) || /^gpt-o[1-4]/.test(modelName);
|
|
6515
|
+
const requiresNew = isReasoningModel(modelName);
|
|
6319
6516
|
this.logger.debug(`Checking token parameter for model "${modelName}"`, {
|
|
6320
6517
|
modelName,
|
|
6321
|
-
requiresMaxCompletionTokens: requiresNew
|
|
6322
|
-
checks: {
|
|
6323
|
-
includesGpt5: modelName.includes("gpt-5"),
|
|
6324
|
-
includesO1: modelName.includes("gpt-o1"),
|
|
6325
|
-
includesO2: modelName.includes("gpt-o2"),
|
|
6326
|
-
includesO3: modelName.includes("gpt-o3"),
|
|
6327
|
-
includesO4: modelName.includes("gpt-o4"),
|
|
6328
|
-
regexGpt5Plus: /^gpt-(5|6|7|8|9)/.test(modelName),
|
|
6329
|
-
regexO1to4: /^gpt-o[1-4]/.test(modelName)
|
|
6330
|
-
}
|
|
6518
|
+
requiresMaxCompletionTokens: requiresNew
|
|
6331
6519
|
});
|
|
6332
6520
|
return requiresNew;
|
|
6333
6521
|
}
|
|
@@ -7202,6 +7390,8 @@ exports.WithEndpoints = WithEndpoints;
|
|
|
7202
7390
|
exports.WithUIEndpoints = WithUIEndpoints;
|
|
7203
7391
|
exports.bootstrap = bootstrap;
|
|
7204
7392
|
exports.createEndpointDescriptors = createEndpointDescriptors;
|
|
7393
|
+
exports.createMongoClientAdapter = createMongoClientAdapter;
|
|
7394
|
+
exports.createStaticMessage = createStaticMessage;
|
|
7205
7395
|
exports.findCallbackMethod = findCallbackMethod;
|
|
7206
7396
|
exports.findEndpointMethod = findEndpointMethod;
|
|
7207
7397
|
exports.getCallbackMetadata = getCallbackMetadata;
|