@flutchai/flutch-sdk 0.1.25 → 0.1.27
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +219 -7
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +49 -9
- package/dist/index.d.ts +49 -9
- package/dist/index.js +216 -9
- 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
|
|
|
@@ -3193,13 +3198,37 @@ var _AbstractGraphBuilder = class _AbstractGraphBuilder {
|
|
|
3193
3198
|
/**
|
|
3194
3199
|
* Basic configuration preparation for graph execution
|
|
3195
3200
|
* Automatically creates context with tracer and usageRecorder
|
|
3196
|
-
*
|
|
3201
|
+
* Handles message deserialization and LangGraph-compatible structure
|
|
3202
|
+
* FINAL method - cannot be overridden. Use customizeConfig() hook instead.
|
|
3197
3203
|
*/
|
|
3198
3204
|
async prepareConfig(payload) {
|
|
3199
3205
|
const context = this.createGraphContext(payload);
|
|
3200
|
-
|
|
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
|
|
3201
3228
|
configurable: {
|
|
3202
3229
|
thread_id: payload.threadId,
|
|
3230
|
+
checkpoint_ns: this.graphType,
|
|
3231
|
+
checkpoint_id: `${payload.threadId}-${Date.now()}`,
|
|
3203
3232
|
context,
|
|
3204
3233
|
// Add metadata for compatibility
|
|
3205
3234
|
metadata: {
|
|
@@ -3207,10 +3236,39 @@ var _AbstractGraphBuilder = class _AbstractGraphBuilder {
|
|
|
3207
3236
|
agentId: payload.agentId,
|
|
3208
3237
|
requestId: payload.requestId,
|
|
3209
3238
|
graphType: this.graphType,
|
|
3210
|
-
version: this.version
|
|
3211
|
-
|
|
3239
|
+
version: this.version,
|
|
3240
|
+
workflowType: this.graphType
|
|
3241
|
+
},
|
|
3242
|
+
// Graph-specific settings from payload
|
|
3243
|
+
graphSettings: payload.graphSettings || {}
|
|
3212
3244
|
}
|
|
3213
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;
|
|
3214
3272
|
}
|
|
3215
3273
|
/**
|
|
3216
3274
|
* Load graph manifest (if using manifest-based approach)
|
|
@@ -3923,6 +3981,24 @@ async function bootstrap(AppModule, options = {}) {
|
|
|
3923
3981
|
// src/core/index.ts
|
|
3924
3982
|
init_builder_registry_service();
|
|
3925
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
|
+
|
|
3926
4002
|
// src/messages/attachments.ts
|
|
3927
4003
|
var AttachmentType = /* @__PURE__ */ ((AttachmentType2) => {
|
|
3928
4004
|
AttachmentType2["IMAGE"] = "image";
|
|
@@ -4363,8 +4439,8 @@ function getLangGraphDispatch() {
|
|
|
4363
4439
|
if (cachedDispatch !== void 0) {
|
|
4364
4440
|
return cachedDispatch;
|
|
4365
4441
|
}
|
|
4366
|
-
const { dispatchCustomEvent } = LangGraph__namespace;
|
|
4367
|
-
cachedDispatch = typeof
|
|
4442
|
+
const { dispatchCustomEvent: dispatchCustomEvent2 } = LangGraph__namespace;
|
|
4443
|
+
cachedDispatch = typeof dispatchCustomEvent2 === "function" ? dispatchCustomEvent2 : null;
|
|
4368
4444
|
return cachedDispatch;
|
|
4369
4445
|
}
|
|
4370
4446
|
function sanitizeTraceData(value, depth = 0, seen = /* @__PURE__ */ new WeakSet(), options) {
|
|
@@ -4671,6 +4747,14 @@ exports.EventProcessor = class EventProcessor {
|
|
|
4671
4747
|
*/
|
|
4672
4748
|
processEvent(acc, event, onPartial) {
|
|
4673
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
|
+
}
|
|
4674
4758
|
if (event.event === "on_chat_model_stream" && event.data?.chunk?.content) {
|
|
4675
4759
|
const channel = event.metadata?.stream_channel ?? "text" /* TEXT */;
|
|
4676
4760
|
const blocks = this.normalizeContentBlocks(event.data.chunk.content);
|
|
@@ -4795,6 +4879,7 @@ exports.EventProcessor = class EventProcessor {
|
|
|
4795
4879
|
}
|
|
4796
4880
|
if (state.currentBlock) {
|
|
4797
4881
|
state.contentChain.push(state.currentBlock);
|
|
4882
|
+
state.currentBlock = null;
|
|
4798
4883
|
}
|
|
4799
4884
|
if (state.contentChain.length > 0) {
|
|
4800
4885
|
allChains.push({
|
|
@@ -5157,6 +5242,13 @@ exports.LangGraphEngine = __decorateClass([
|
|
|
5157
5242
|
common.Injectable(),
|
|
5158
5243
|
__decorateParam(1, common.Optional())
|
|
5159
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
|
+
}
|
|
5160
5252
|
|
|
5161
5253
|
// src/core/universal-graph.module.ts
|
|
5162
5254
|
init_builder_registry_service();
|
|
@@ -5344,6 +5436,58 @@ exports.UniversalGraphModule = class UniversalGraphModule {
|
|
|
5344
5436
|
},
|
|
5345
5437
|
inject: [CallbackRegistry]
|
|
5346
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
|
+
] : [],
|
|
5347
5491
|
{
|
|
5348
5492
|
provide: "GRAPH_ENGINE",
|
|
5349
5493
|
useFactory: (langGraphEngine) => langGraphEngine,
|
|
@@ -5975,7 +6119,8 @@ exports.McpRuntimeHttpClient = class McpRuntimeHttpClient {
|
|
|
5975
6119
|
await runManager?.handleToolEnd(content);
|
|
5976
6120
|
return {
|
|
5977
6121
|
content,
|
|
5978
|
-
success: result.success
|
|
6122
|
+
success: result.success,
|
|
6123
|
+
rawResult: result.success ? result.result : void 0
|
|
5979
6124
|
};
|
|
5980
6125
|
} catch (error) {
|
|
5981
6126
|
this.logger.error(`Error executing tool ${toolName}:`, error);
|
|
@@ -5995,6 +6140,69 @@ exports.McpRuntimeHttpClient = __decorateClass([
|
|
|
5995
6140
|
common.Injectable()
|
|
5996
6141
|
], exports.McpRuntimeHttpClient);
|
|
5997
6142
|
|
|
6143
|
+
// src/tools/attachment-summary.ts
|
|
6144
|
+
var MAX_SAMPLE_ROWS = 5;
|
|
6145
|
+
var MAX_TEXT_PREVIEW_LENGTH = 500;
|
|
6146
|
+
function generateAttachmentSummary(data, toolCallId) {
|
|
6147
|
+
try {
|
|
6148
|
+
if (Array.isArray(data) && data.length > 0 && isTabular(data)) {
|
|
6149
|
+
return generateTabularSummary(data, toolCallId);
|
|
6150
|
+
}
|
|
6151
|
+
return generateTextSummary(data, toolCallId);
|
|
6152
|
+
} catch {
|
|
6153
|
+
return `[Data stored as attachment: ${toolCallId}]`;
|
|
6154
|
+
}
|
|
6155
|
+
}
|
|
6156
|
+
function createGraphAttachment(data, toolName, toolCallId) {
|
|
6157
|
+
return {
|
|
6158
|
+
data,
|
|
6159
|
+
summary: generateAttachmentSummary(data, toolCallId),
|
|
6160
|
+
toolName,
|
|
6161
|
+
toolCallId,
|
|
6162
|
+
createdAt: Date.now()
|
|
6163
|
+
};
|
|
6164
|
+
}
|
|
6165
|
+
function isTabular(data) {
|
|
6166
|
+
const first = data[0];
|
|
6167
|
+
return first !== null && typeof first === "object" && !Array.isArray(first);
|
|
6168
|
+
}
|
|
6169
|
+
function generateTabularSummary(data, toolCallId) {
|
|
6170
|
+
const rowCount = data.length;
|
|
6171
|
+
const columns = Object.keys(data[0]);
|
|
6172
|
+
const sampleRows = data.slice(0, MAX_SAMPLE_ROWS);
|
|
6173
|
+
const rowLabel = rowCount === 1 ? "row" : "rows";
|
|
6174
|
+
const colLabel = columns.length === 1 ? "column" : "columns";
|
|
6175
|
+
let summary = `${rowCount} ${rowLabel}, ${columns.length} ${colLabel} (${columns.join(", ")})
|
|
6176
|
+
`;
|
|
6177
|
+
summary += `Sample data:
|
|
6178
|
+
`;
|
|
6179
|
+
for (const row of sampleRows) {
|
|
6180
|
+
try {
|
|
6181
|
+
summary += JSON.stringify(row) + "\n";
|
|
6182
|
+
} catch {
|
|
6183
|
+
summary += "[unserializable row]\n";
|
|
6184
|
+
}
|
|
6185
|
+
}
|
|
6186
|
+
summary += `[Data stored as attachment: ${toolCallId}]`;
|
|
6187
|
+
return summary;
|
|
6188
|
+
}
|
|
6189
|
+
function generateTextSummary(data, toolCallId) {
|
|
6190
|
+
let text;
|
|
6191
|
+
try {
|
|
6192
|
+
text = typeof data === "string" ? data : JSON.stringify(data);
|
|
6193
|
+
} catch {
|
|
6194
|
+
text = String(data);
|
|
6195
|
+
}
|
|
6196
|
+
const preview = text.slice(0, MAX_TEXT_PREVIEW_LENGTH);
|
|
6197
|
+
const suffix = text.length > MAX_TEXT_PREVIEW_LENGTH ? "..." : "";
|
|
6198
|
+
let summary = `${text.length} characters
|
|
6199
|
+
`;
|
|
6200
|
+
summary += `Preview: ${preview}${suffix}
|
|
6201
|
+
`;
|
|
6202
|
+
summary += `[Data stored as attachment: ${toolCallId}]`;
|
|
6203
|
+
return summary;
|
|
6204
|
+
}
|
|
6205
|
+
|
|
5998
6206
|
// src/models/enums.ts
|
|
5999
6207
|
var ModelProvider = /* @__PURE__ */ ((ModelProvider2) => {
|
|
6000
6208
|
ModelProvider2["FLUTCH"] = "flutch";
|
|
@@ -7246,8 +7454,12 @@ exports.WithEndpoints = WithEndpoints;
|
|
|
7246
7454
|
exports.WithUIEndpoints = WithUIEndpoints;
|
|
7247
7455
|
exports.bootstrap = bootstrap;
|
|
7248
7456
|
exports.createEndpointDescriptors = createEndpointDescriptors;
|
|
7457
|
+
exports.createGraphAttachment = createGraphAttachment;
|
|
7458
|
+
exports.createMongoClientAdapter = createMongoClientAdapter;
|
|
7459
|
+
exports.createStaticMessage = createStaticMessage;
|
|
7249
7460
|
exports.findCallbackMethod = findCallbackMethod;
|
|
7250
7461
|
exports.findEndpointMethod = findEndpointMethod;
|
|
7462
|
+
exports.generateAttachmentSummary = generateAttachmentSummary;
|
|
7251
7463
|
exports.getCallbackMetadata = getCallbackMetadata;
|
|
7252
7464
|
exports.getEndpointMetadata = getEndpointMetadata;
|
|
7253
7465
|
exports.getUIEndpointClassMetadata = getUIEndpointClassMetadata;
|