@flutchai/flutch-sdk 0.6.3 → 0.6.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.cjs +396 -78
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +108 -37
- package/dist/index.d.ts +108 -37
- package/dist/index.js +384 -79
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1878,13 +1878,13 @@ async function findAvailablePort(startPort) {
|
|
|
1878
1878
|
throw new Error(`No available ports found in range ${startPort}-${startPort + 99}`);
|
|
1879
1879
|
}
|
|
1880
1880
|
__name(findAvailablePort, "findAvailablePort");
|
|
1881
|
-
async function registerWithServiceDiscovery(AppModule, port,
|
|
1881
|
+
async function registerWithServiceDiscovery(AppModule, port, logger3, app) {
|
|
1882
1882
|
try {
|
|
1883
|
-
|
|
1883
|
+
logger3.debug("[SERVICE_DISCOVERY] Starting service discovery registration...");
|
|
1884
1884
|
const { FileBasedDiscovery: FileBasedDiscovery2 } = await Promise.resolve().then(() => (init_file_based_discovery(), file_based_discovery_exports));
|
|
1885
|
-
|
|
1885
|
+
logger3.debug("[SERVICE_DISCOVERY] FileBasedDiscovery imported successfully");
|
|
1886
1886
|
const discovery = new FileBasedDiscovery2();
|
|
1887
|
-
|
|
1887
|
+
logger3.debug("[SERVICE_DISCOVERY] FileBasedDiscovery instance created");
|
|
1888
1888
|
const serviceName = AppModule.name.replace("Module", "").toLowerCase();
|
|
1889
1889
|
let graphTypes = [];
|
|
1890
1890
|
try {
|
|
@@ -1893,26 +1893,26 @@ async function registerWithServiceDiscovery(AppModule, port, logger2, app) {
|
|
|
1893
1893
|
const builderRegistry = app.get(BuilderRegistryService2, {
|
|
1894
1894
|
strict: false
|
|
1895
1895
|
});
|
|
1896
|
-
|
|
1896
|
+
logger3.debug(`BuilderRegistryService found in DI: ${!!builderRegistry}`);
|
|
1897
1897
|
if (builderRegistry) {
|
|
1898
1898
|
const builders = builderRegistry.getBuilders();
|
|
1899
|
-
|
|
1899
|
+
logger3.debug(`Found ${builders.length} builders in registry`);
|
|
1900
1900
|
const baseGraphTypes = builders.map((builder) => builder.graphType);
|
|
1901
|
-
|
|
1901
|
+
logger3.debug(`Base graph types: [${baseGraphTypes.join(", ")}]`);
|
|
1902
1902
|
try {
|
|
1903
|
-
|
|
1903
|
+
logger3.debug("Attempting to import VersionedGraphService...");
|
|
1904
1904
|
const { VersionedGraphService: VersionedGraphService2 } = await Promise.resolve().then(() => (init_versioned_graph_service(), versioned_graph_service_exports));
|
|
1905
|
-
|
|
1905
|
+
logger3.debug("VersionedGraphService imported successfully");
|
|
1906
1906
|
const versionedService = app.get(VersionedGraphService2, {
|
|
1907
1907
|
strict: false
|
|
1908
1908
|
});
|
|
1909
|
-
|
|
1909
|
+
logger3.debug(`VersionedGraphService found in DI: ${!!versionedService}`);
|
|
1910
1910
|
if (versionedService) {
|
|
1911
1911
|
const allVersionedTypes = [];
|
|
1912
1912
|
for (const baseType of baseGraphTypes) {
|
|
1913
|
-
|
|
1913
|
+
logger3.debug(`Getting versions for base type: ${baseType}`);
|
|
1914
1914
|
const versions = versionedService.getAvailableVersions(baseType);
|
|
1915
|
-
|
|
1915
|
+
logger3.debug(`Found ${versions.length} versions for ${baseType}: [${versions.join(", ")}]`);
|
|
1916
1916
|
if (versions.length > 0) {
|
|
1917
1917
|
allVersionedTypes.push(baseType);
|
|
1918
1918
|
versions.forEach((version) => {
|
|
@@ -1923,23 +1923,23 @@ async function registerWithServiceDiscovery(AppModule, port, logger2, app) {
|
|
|
1923
1923
|
}
|
|
1924
1924
|
}
|
|
1925
1925
|
graphTypes = allVersionedTypes;
|
|
1926
|
-
|
|
1926
|
+
logger3.debug(`Found ${baseGraphTypes.length} base types with ${graphTypes.length} total versioned types: ${graphTypes.join(", ")}`);
|
|
1927
1927
|
} else {
|
|
1928
1928
|
graphTypes = baseGraphTypes;
|
|
1929
|
-
|
|
1929
|
+
logger3.debug(`VersionedGraphService not found in DI container, using base types: ${graphTypes.join(", ")}`);
|
|
1930
1930
|
}
|
|
1931
1931
|
} catch (error) {
|
|
1932
1932
|
graphTypes = baseGraphTypes;
|
|
1933
|
-
|
|
1934
|
-
|
|
1933
|
+
logger3.debug(`Failed to get versioned types, using base types: ${error.message}`);
|
|
1934
|
+
logger3.debug(`Stack trace: ${error.stack}`);
|
|
1935
1935
|
}
|
|
1936
1936
|
}
|
|
1937
1937
|
}
|
|
1938
1938
|
} catch (error) {
|
|
1939
|
-
|
|
1939
|
+
logger3.debug(`Failed to get graph types from builders: ${error.message}`);
|
|
1940
1940
|
}
|
|
1941
1941
|
if (graphTypes.length === 0) {
|
|
1942
|
-
|
|
1942
|
+
logger3.debug("No builders found, using service name as graph type");
|
|
1943
1943
|
graphTypes = [
|
|
1944
1944
|
serviceName
|
|
1945
1945
|
];
|
|
@@ -1950,21 +1950,21 @@ async function registerWithServiceDiscovery(AppModule, port, logger2, app) {
|
|
|
1950
1950
|
startTime: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1951
1951
|
version: process.env.npm_package_version || "1.0.0"
|
|
1952
1952
|
}, graphTypes);
|
|
1953
|
-
|
|
1953
|
+
logger3.log(`\u{1F4E1} Service registered with discovery: ${serviceName} (types: ${graphTypes.join(", ")})`);
|
|
1954
1954
|
} catch (error) {
|
|
1955
|
-
|
|
1955
|
+
logger3.warn(`Failed to register with service discovery: ${error.message}`);
|
|
1956
1956
|
}
|
|
1957
1957
|
}
|
|
1958
1958
|
__name(registerWithServiceDiscovery, "registerWithServiceDiscovery");
|
|
1959
1959
|
async function bootstrap(AppModule, options = {}) {
|
|
1960
1960
|
setupRedisMock();
|
|
1961
1961
|
const app = await NestFactory.create(AppModule);
|
|
1962
|
-
const
|
|
1962
|
+
const logger3 = new Logger("Bootstrap");
|
|
1963
1963
|
const requestedPort = options.port || parseInt(process.env.PORT || "3100", 10);
|
|
1964
1964
|
const port = await findAvailablePort(requestedPort);
|
|
1965
1965
|
const globalPrefix = options.globalPrefix;
|
|
1966
1966
|
if (port !== requestedPort) {
|
|
1967
|
-
|
|
1967
|
+
logger3.warn(`Port ${requestedPort} is busy, using port ${port} instead`);
|
|
1968
1968
|
}
|
|
1969
1969
|
if (globalPrefix) {
|
|
1970
1970
|
app.setGlobalPrefix(globalPrefix);
|
|
@@ -1983,13 +1983,13 @@ async function bootstrap(AppModule, options = {}) {
|
|
|
1983
1983
|
SwaggerModule.setup("api/docs", app, document);
|
|
1984
1984
|
await app.listen(port);
|
|
1985
1985
|
const baseUrl = globalPrefix ? `http://localhost:${port}/${globalPrefix}` : `http://localhost:${port}`;
|
|
1986
|
-
|
|
1987
|
-
|
|
1986
|
+
logger3.log(`\u{1F680} Graph service is running on: ${baseUrl}`);
|
|
1987
|
+
logger3.log(`\u{1F4DA} API Documentation: http://localhost:${port}/api/docs`);
|
|
1988
1988
|
if (process.env.NODE_ENV !== "production") {
|
|
1989
|
-
|
|
1990
|
-
await registerWithServiceDiscovery(AppModule, port,
|
|
1989
|
+
logger3.debug(`Attempting service discovery registration (NODE_ENV: ${process.env.NODE_ENV || "undefined"})`);
|
|
1990
|
+
await registerWithServiceDiscovery(AppModule, port, logger3, app);
|
|
1991
1991
|
} else {
|
|
1992
|
-
|
|
1992
|
+
logger3.debug(`Skipping service discovery registration (NODE_ENV: ${process.env.NODE_ENV})`);
|
|
1993
1993
|
}
|
|
1994
1994
|
return app;
|
|
1995
1995
|
}
|
|
@@ -4842,7 +4842,7 @@ function clearAttachmentDataStore(threadId) {
|
|
|
4842
4842
|
}
|
|
4843
4843
|
__name(clearAttachmentDataStore, "clearAttachmentDataStore");
|
|
4844
4844
|
async function executeToolWithAttachments(params) {
|
|
4845
|
-
const { toolCall, mcpClient, enrichedArgs, executionContext, config, attachments, logger:
|
|
4845
|
+
const { toolCall, mcpClient, enrichedArgs, executionContext, config, attachments, logger: logger3, threshold = DEFAULT_ATTACHMENT_THRESHOLD, injectIntoArg = "data", sourceAttachmentId, threadId, toolSchema, mcpServers } = params;
|
|
4846
4846
|
const argsWithInjection = {
|
|
4847
4847
|
...enrichedArgs
|
|
4848
4848
|
};
|
|
@@ -4855,12 +4855,12 @@ async function executeToolWithAttachments(params) {
|
|
|
4855
4855
|
const data = storedData !== void 0 ? storedData : attachment.data;
|
|
4856
4856
|
if (data != null) {
|
|
4857
4857
|
argsWithInjection[injectIntoArg] = typeof data === "string" ? data : JSON.stringify(data);
|
|
4858
|
-
|
|
4858
|
+
logger3?.debug(`[Attachment] Auto-injected data from attachment "${attachment.toolCallId}" into ${toolCall.name}.${injectIntoArg} (source: ${storedData !== void 0 ? "memory" : "state"})`);
|
|
4859
4859
|
}
|
|
4860
4860
|
}
|
|
4861
4861
|
}
|
|
4862
4862
|
} catch (e) {
|
|
4863
|
-
|
|
4863
|
+
logger3?.warn(`[Attachment] Auto-injection failed: ${e}`);
|
|
4864
4864
|
}
|
|
4865
4865
|
const { content, success, rawResult } = await mcpClient.executeToolWithEvents(toolCall.id, toolCall.name, argsWithInjection, executionContext, config, mcpServers);
|
|
4866
4866
|
try {
|
|
@@ -4871,7 +4871,7 @@ async function executeToolWithAttachments(params) {
|
|
|
4871
4871
|
...attachment,
|
|
4872
4872
|
data: null
|
|
4873
4873
|
};
|
|
4874
|
-
|
|
4874
|
+
logger3?.debug(`[Attachment] Stored large result (${content.length} chars) as attachment "${toolCall.id}" (data in memory, metadata in state)`);
|
|
4875
4875
|
const toolMessage2 = new ToolMessage({
|
|
4876
4876
|
content: attachment.summary,
|
|
4877
4877
|
tool_call_id: toolCall.id,
|
|
@@ -4886,7 +4886,7 @@ async function executeToolWithAttachments(params) {
|
|
|
4886
4886
|
};
|
|
4887
4887
|
}
|
|
4888
4888
|
} catch (e) {
|
|
4889
|
-
|
|
4889
|
+
logger3?.warn(`[Attachment] Failed to create attachment, using full content: ${e}`);
|
|
4890
4890
|
}
|
|
4891
4891
|
const toolMessage = new ToolMessage({
|
|
4892
4892
|
content,
|
|
@@ -6200,7 +6200,7 @@ function createMetaBuilder(config, versionedGraphService, moduleRef) {
|
|
|
6200
6200
|
}
|
|
6201
6201
|
__name(createMetaBuilder, "createMetaBuilder");
|
|
6202
6202
|
function buildCheckpointerProviders(options) {
|
|
6203
|
-
const
|
|
6203
|
+
const logger3 = new Logger("UniversalGraphModule");
|
|
6204
6204
|
if (options.postgres !== void 0) {
|
|
6205
6205
|
return [
|
|
6206
6206
|
{
|
|
@@ -6214,7 +6214,7 @@ function buildCheckpointerProviders(options) {
|
|
|
6214
6214
|
if (!connString) {
|
|
6215
6215
|
throw new Error("[UniversalGraphModule] Postgres checkpointer: provide postgres.connectionString or set the DATABASE_URL environment variable.");
|
|
6216
6216
|
}
|
|
6217
|
-
|
|
6217
|
+
logger3.log(`Checkpointer: PostgreSQL (${connString.replace(/:[^:@]+@/, ":***@")})`);
|
|
6218
6218
|
const saver = PostgresSaver.fromConnString(connString, {
|
|
6219
6219
|
...options.postgres.schema ? {
|
|
6220
6220
|
schema: options.postgres.schema
|
|
@@ -6236,7 +6236,7 @@ function buildCheckpointerProviders(options) {
|
|
|
6236
6236
|
if (!mongoUri) {
|
|
6237
6237
|
throw new Error("[UniversalGraphModule] MongoDB checkpointer: provide mongodb.uri or set the MONGODB_URI environment variable.");
|
|
6238
6238
|
}
|
|
6239
|
-
|
|
6239
|
+
logger3.log(`Checkpointer: MongoDB (${mongoUri.substring(0, 50)}...)`);
|
|
6240
6240
|
await mongoose.connect(mongoUri, {
|
|
6241
6241
|
dbName
|
|
6242
6242
|
});
|
|
@@ -6270,7 +6270,7 @@ function buildCheckpointerProviders(options) {
|
|
|
6270
6270
|
provide: "CHECKPOINTER",
|
|
6271
6271
|
useFactory: /* @__PURE__ */ __name(async () => {
|
|
6272
6272
|
const { MemorySaver } = await import('@langchain/langgraph');
|
|
6273
|
-
|
|
6273
|
+
logger3.warn("Checkpointer: MemorySaver (in-process, no persistence). Configure postgres or mongodb in UniversalGraphModule.forRoot() for production.");
|
|
6274
6274
|
return new MemorySaver();
|
|
6275
6275
|
}, "useFactory")
|
|
6276
6276
|
}
|
|
@@ -6309,8 +6309,8 @@ var UniversalGraphModule = class _UniversalGraphModule {
|
|
|
6309
6309
|
const redisUrl = options.redis?.url ?? process.env.REDIS_URL;
|
|
6310
6310
|
if (redisUrl) {
|
|
6311
6311
|
const Redis2 = __require("ioredis");
|
|
6312
|
-
const
|
|
6313
|
-
|
|
6312
|
+
const logger3 = new Logger("UniversalGraphModule");
|
|
6313
|
+
logger3.log(`Callbacks: Redis (${redisUrl.replace(/:[^:@]+@/, ":***@")})`);
|
|
6314
6314
|
return new Redis2(redisUrl);
|
|
6315
6315
|
}
|
|
6316
6316
|
const IORedisMock = __require("ioredis-mock");
|
|
@@ -6594,7 +6594,7 @@ var McpConverter = class _McpConverter {
|
|
|
6594
6594
|
* Convert a single MCP tool to LangChain DynamicStructuredTool
|
|
6595
6595
|
*/
|
|
6596
6596
|
convertTool(mcpTool) {
|
|
6597
|
-
const
|
|
6597
|
+
const logger3 = this.logger;
|
|
6598
6598
|
const mcpRuntimeUrl = this.mcpRuntimeUrl;
|
|
6599
6599
|
let enhancedDescription = mcpTool.description;
|
|
6600
6600
|
if (mcpTool.inputSchema?.properties) {
|
|
@@ -6614,12 +6614,12 @@ ${paramDescriptions.join("\n")}`;
|
|
|
6614
6614
|
}
|
|
6615
6615
|
}
|
|
6616
6616
|
const schema = this.jsonSchemaToZod(mcpTool.inputSchema);
|
|
6617
|
-
|
|
6618
|
-
|
|
6617
|
+
logger3.debug(`\u{1F527} [${mcpTool.name}] Original schema:`, JSON.stringify(mcpTool.inputSchema, null, 2));
|
|
6618
|
+
logger3.debug(`\u{1F527} [${mcpTool.name}] Using schema type: ${schema?._def?.typeName ?? "unknown"}`);
|
|
6619
6619
|
if (schema?._def?.shape && typeof schema._def.shape === "function") {
|
|
6620
6620
|
try {
|
|
6621
6621
|
const shape = schema._def.shape();
|
|
6622
|
-
|
|
6622
|
+
logger3.debug(`\u{1F527} [${mcpTool.name}] Converted Zod schema shape:`, JSON.stringify(Object.entries(shape).reduce((acc, [key, val]) => {
|
|
6623
6623
|
acc[key] = {
|
|
6624
6624
|
type: val?._def?.typeName,
|
|
6625
6625
|
description: val?._def?.description,
|
|
@@ -6628,50 +6628,50 @@ ${paramDescriptions.join("\n")}`;
|
|
|
6628
6628
|
return acc;
|
|
6629
6629
|
}, {}), null, 2));
|
|
6630
6630
|
} catch (error) {
|
|
6631
|
-
|
|
6631
|
+
logger3.debug(`\u{1F527} [${mcpTool.name}] Could not extract Zod schema shape: ${error}`);
|
|
6632
6632
|
}
|
|
6633
6633
|
}
|
|
6634
6634
|
try {
|
|
6635
6635
|
const convertedJsonSchema = zodToJsonSchema(schema);
|
|
6636
|
-
|
|
6636
|
+
logger3.warn(`\u{1F527} [${mcpTool.name}] JSON Schema that LangChain will use:`, JSON.stringify(convertedJsonSchema, null, 2));
|
|
6637
6637
|
} catch (error) {
|
|
6638
|
-
|
|
6638
|
+
logger3.warn(`\u{1F527} [${mcpTool.name}] Could not convert Zod to JSON Schema: ${error}`);
|
|
6639
6639
|
}
|
|
6640
6640
|
return new DynamicStructuredTool({
|
|
6641
6641
|
name: mcpTool.name,
|
|
6642
6642
|
description: enhancedDescription,
|
|
6643
6643
|
schema,
|
|
6644
6644
|
func: /* @__PURE__ */ __name(async (input, _runManager, config) => {
|
|
6645
|
-
|
|
6645
|
+
logger3.log(`\u{1F527} [${mcpTool.name}] LLM INPUT: ${JSON.stringify(input)}`);
|
|
6646
6646
|
const configurable = config?.configurable;
|
|
6647
6647
|
const context = {
|
|
6648
6648
|
agentId: configurable?.agentId,
|
|
6649
6649
|
userId: configurable?.userId,
|
|
6650
6650
|
threadId: configurable?.thread_id
|
|
6651
6651
|
};
|
|
6652
|
-
|
|
6652
|
+
logger3.debug(`\u{1F527} [${mcpTool.name}] Execution context: ${JSON.stringify(context)}`);
|
|
6653
6653
|
try {
|
|
6654
6654
|
const request = {
|
|
6655
6655
|
name: mcpTool.name,
|
|
6656
6656
|
arguments: input ?? {},
|
|
6657
6657
|
context
|
|
6658
6658
|
};
|
|
6659
|
-
|
|
6659
|
+
logger3.log(`\u{1F527} [${mcpTool.name}] Calling MCP Runtime...`);
|
|
6660
6660
|
const response = await axios2.post(`${mcpRuntimeUrl}/tools/execute`, request, {
|
|
6661
6661
|
timeout: 3e4
|
|
6662
6662
|
});
|
|
6663
6663
|
const result = response.data;
|
|
6664
|
-
|
|
6664
|
+
logger3.log(`\u{1F527} [${mcpTool.name}] MCP Runtime response: success=${result.success}`);
|
|
6665
6665
|
if (!result.success) {
|
|
6666
6666
|
const errorMessage = result.error || "Tool execution failed";
|
|
6667
|
-
|
|
6667
|
+
logger3.error(`\u{1F527} [${mcpTool.name}] MCP Runtime error: ${errorMessage}`);
|
|
6668
6668
|
throw new Error(errorMessage);
|
|
6669
6669
|
}
|
|
6670
6670
|
const output = typeof result.result === "string" ? result.result : JSON.stringify(result.result, null, 2);
|
|
6671
|
-
|
|
6671
|
+
logger3.log(`\u{1F527} [${mcpTool.name}] TOOL OUTPUT: ${output.length > 200 ? output.substring(0, 200) + "..." : output}`);
|
|
6672
6672
|
return output;
|
|
6673
6673
|
} catch (error) {
|
|
6674
|
-
|
|
6674
|
+
logger3.error(`\u{1F527} [${mcpTool.name}] Exception during execution`, error);
|
|
6675
6675
|
if (axios2.isAxiosError(error)) {
|
|
6676
6676
|
throw new Error(`MCP Runtime error: ${error.message}`);
|
|
6677
6677
|
}
|
|
@@ -7046,6 +7046,110 @@ function isReasoningModel(modelName) {
|
|
|
7046
7046
|
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);
|
|
7047
7047
|
}
|
|
7048
7048
|
__name(isReasoningModel, "isReasoningModel");
|
|
7049
|
+
function toOptionalNumber(value) {
|
|
7050
|
+
if (value === void 0 || value === null || value === "") return void 0;
|
|
7051
|
+
const n = Number(value);
|
|
7052
|
+
return Number.isFinite(n) ? n : void 0;
|
|
7053
|
+
}
|
|
7054
|
+
__name(toOptionalNumber, "toOptionalNumber");
|
|
7055
|
+
var SAMPLING_PARAM_FREE_THRESHOLDS = {
|
|
7056
|
+
opus: {
|
|
7057
|
+
major: 4,
|
|
7058
|
+
minor: 7
|
|
7059
|
+
},
|
|
7060
|
+
sonnet: {
|
|
7061
|
+
major: 5,
|
|
7062
|
+
minor: 0
|
|
7063
|
+
},
|
|
7064
|
+
haiku: {
|
|
7065
|
+
major: 5,
|
|
7066
|
+
minor: 0
|
|
7067
|
+
}
|
|
7068
|
+
};
|
|
7069
|
+
var SAMPLING_PARAM_FREE_FAMILIES = /claude-(fable|mythos)\b/;
|
|
7070
|
+
var CLAUDE_FAMILY_VERSION = /claude-(opus|sonnet|haiku)-(\d{1,2})(?:-(\d{1,2}))?(?![\d.])/;
|
|
7071
|
+
function modelAcceptsSamplingParams(modelIdentifier) {
|
|
7072
|
+
if (!modelIdentifier) return true;
|
|
7073
|
+
const id = modelIdentifier.toLowerCase();
|
|
7074
|
+
if (SAMPLING_PARAM_FREE_FAMILIES.test(id)) return false;
|
|
7075
|
+
const match = CLAUDE_FAMILY_VERSION.exec(id);
|
|
7076
|
+
if (!match) return true;
|
|
7077
|
+
const [, family, majorRaw, minorRaw] = match;
|
|
7078
|
+
const threshold = SAMPLING_PARAM_FREE_THRESHOLDS[family];
|
|
7079
|
+
if (!threshold) return true;
|
|
7080
|
+
const major = Number(majorRaw);
|
|
7081
|
+
const minor = minorRaw === void 0 ? 0 : Number(minorRaw);
|
|
7082
|
+
const atOrAboveThreshold = major > threshold.major || major === threshold.major && minor >= threshold.minor;
|
|
7083
|
+
return !atOrAboveThreshold;
|
|
7084
|
+
}
|
|
7085
|
+
__name(modelAcceptsSamplingParams, "modelAcceptsSamplingParams");
|
|
7086
|
+
var PROMPT_CACHE_MIN_VERSIONS = {
|
|
7087
|
+
opus: {
|
|
7088
|
+
major: 4,
|
|
7089
|
+
minor: 0
|
|
7090
|
+
},
|
|
7091
|
+
sonnet: {
|
|
7092
|
+
major: 4,
|
|
7093
|
+
minor: 0
|
|
7094
|
+
},
|
|
7095
|
+
haiku: {
|
|
7096
|
+
major: 4,
|
|
7097
|
+
minor: 5
|
|
7098
|
+
}
|
|
7099
|
+
};
|
|
7100
|
+
function modelSupportsPromptCache(modelIdentifier) {
|
|
7101
|
+
if (!modelIdentifier) return false;
|
|
7102
|
+
const match = CLAUDE_FAMILY_VERSION.exec(modelIdentifier.toLowerCase());
|
|
7103
|
+
if (!match) return false;
|
|
7104
|
+
const [, family, majorRaw, minorRaw] = match;
|
|
7105
|
+
const threshold = PROMPT_CACHE_MIN_VERSIONS[family];
|
|
7106
|
+
if (!threshold) return false;
|
|
7107
|
+
const major = Number(majorRaw);
|
|
7108
|
+
const minor = minorRaw === void 0 ? 0 : Number(minorRaw);
|
|
7109
|
+
return major > threshold.major || major === threshold.major && minor >= threshold.minor;
|
|
7110
|
+
}
|
|
7111
|
+
__name(modelSupportsPromptCache, "modelSupportsPromptCache");
|
|
7112
|
+
function resolvePromptCacheControl(modelIdentifiers, promptCache, ttl) {
|
|
7113
|
+
const enabled = promptCache ?? modelIdentifiers.some((id) => modelSupportsPromptCache(id));
|
|
7114
|
+
return enabled ? {
|
|
7115
|
+
type: "ephemeral",
|
|
7116
|
+
ttl: ttl ?? "5m"
|
|
7117
|
+
} : void 0;
|
|
7118
|
+
}
|
|
7119
|
+
__name(resolvePromptCacheControl, "resolvePromptCacheControl");
|
|
7120
|
+
function buildEffortRequestFields(effort) {
|
|
7121
|
+
return effort ? {
|
|
7122
|
+
output_config: {
|
|
7123
|
+
effort
|
|
7124
|
+
}
|
|
7125
|
+
} : void 0;
|
|
7126
|
+
}
|
|
7127
|
+
__name(buildEffortRequestFields, "buildEffortRequestFields");
|
|
7128
|
+
function resolveSamplingParams(modelIdentifiers, requested, supportsSamplingParams) {
|
|
7129
|
+
const accepted = supportsSamplingParams ?? modelIdentifiers.every((id) => modelAcceptsSamplingParams(id));
|
|
7130
|
+
if (accepted) {
|
|
7131
|
+
const params = {};
|
|
7132
|
+
if (requested.temperature !== void 0) params.temperature = requested.temperature;
|
|
7133
|
+
if (requested.topP !== void 0) params.topP = requested.topP;
|
|
7134
|
+
if (requested.topK !== void 0) params.topK = requested.topK;
|
|
7135
|
+
return {
|
|
7136
|
+
params,
|
|
7137
|
+
dropped: [],
|
|
7138
|
+
accepted: true
|
|
7139
|
+
};
|
|
7140
|
+
}
|
|
7141
|
+
const dropped = [
|
|
7142
|
+
"temperature",
|
|
7143
|
+
"topP",
|
|
7144
|
+
"topK"
|
|
7145
|
+
].filter((key) => requested[key] !== void 0);
|
|
7146
|
+
return {
|
|
7147
|
+
params: {},
|
|
7148
|
+
dropped,
|
|
7149
|
+
accepted: false
|
|
7150
|
+
};
|
|
7151
|
+
}
|
|
7152
|
+
__name(resolveSamplingParams, "resolveSamplingParams");
|
|
7049
7153
|
function hashToolsConfig(toolsConfig) {
|
|
7050
7154
|
const sorted = toolsConfig.map((t) => `${t.toolName}:${t.enabled}:${JSON.stringify(t.config || {})}`).sort().join("|");
|
|
7051
7155
|
return createHash("md5").update(sorted).digest("hex").slice(0, 16);
|
|
@@ -7098,13 +7202,122 @@ function buildOpenAIModelConfig(modelName, temperature, maxTokens, apiToken) {
|
|
|
7098
7202
|
}
|
|
7099
7203
|
return {
|
|
7100
7204
|
modelName,
|
|
7101
|
-
|
|
7205
|
+
// Omit the key entirely when absent — an explicit `undefined` would still
|
|
7206
|
+
// be enumerable and can be forwarded as a null-ish value downstream.
|
|
7207
|
+
...temperature !== void 0 && {
|
|
7208
|
+
temperature
|
|
7209
|
+
},
|
|
7102
7210
|
maxTokens,
|
|
7103
7211
|
streaming: true,
|
|
7104
7212
|
openAIApiKey: apiToken
|
|
7105
7213
|
};
|
|
7106
7214
|
}
|
|
7107
7215
|
__name(buildOpenAIModelConfig, "buildOpenAIModelConfig");
|
|
7216
|
+
|
|
7217
|
+
// src/models/reasoning-content.logic.ts
|
|
7218
|
+
function isReasoningBlock(block) {
|
|
7219
|
+
return typeof block === "object" && block !== null && block.type === "reasoning_content";
|
|
7220
|
+
}
|
|
7221
|
+
__name(isReasoningBlock, "isReasoningBlock");
|
|
7222
|
+
function isSendableReasoningBlock(block) {
|
|
7223
|
+
if (typeof block.redactedContent === "string" && block.redactedContent !== "") return true;
|
|
7224
|
+
const text = block.reasoningText?.text;
|
|
7225
|
+
return typeof text === "string" && text !== "";
|
|
7226
|
+
}
|
|
7227
|
+
__name(isSendableReasoningBlock, "isSendableReasoningBlock");
|
|
7228
|
+
function normalizeUnsendableBlock(block) {
|
|
7229
|
+
const signature = block.reasoningText?.signature;
|
|
7230
|
+
if (typeof signature !== "string" || signature === "") return null;
|
|
7231
|
+
return {
|
|
7232
|
+
type: "reasoning_content",
|
|
7233
|
+
reasoningText: {
|
|
7234
|
+
text: "",
|
|
7235
|
+
signature
|
|
7236
|
+
}
|
|
7237
|
+
};
|
|
7238
|
+
}
|
|
7239
|
+
__name(normalizeUnsendableBlock, "normalizeUnsendableBlock");
|
|
7240
|
+
function hasToolCalls(message) {
|
|
7241
|
+
const toolCalls = message.tool_calls;
|
|
7242
|
+
return Array.isArray(toolCalls) && toolCalls.length > 0;
|
|
7243
|
+
}
|
|
7244
|
+
__name(hasToolCalls, "hasToolCalls");
|
|
7245
|
+
function withContent(message, content) {
|
|
7246
|
+
const clone = Object.assign(Object.create(Object.getPrototypeOf(message)), message, {
|
|
7247
|
+
content
|
|
7248
|
+
});
|
|
7249
|
+
if (clone.lc_kwargs) clone.lc_kwargs = {
|
|
7250
|
+
...clone.lc_kwargs,
|
|
7251
|
+
content
|
|
7252
|
+
};
|
|
7253
|
+
return clone;
|
|
7254
|
+
}
|
|
7255
|
+
__name(withContent, "withContent");
|
|
7256
|
+
function sanitizeMessageReasoning(message) {
|
|
7257
|
+
if (message.getType() !== "ai") return message;
|
|
7258
|
+
const content = message.content;
|
|
7259
|
+
if (!Array.isArray(content)) return message;
|
|
7260
|
+
const unsendable = content.filter((block) => isReasoningBlock(block) && !isSendableReasoningBlock(block));
|
|
7261
|
+
if (unsendable.length === 0) return message;
|
|
7262
|
+
const kept = content.filter((block) => !unsendable.includes(block));
|
|
7263
|
+
if (kept.length === 0 && !hasToolCalls(message)) {
|
|
7264
|
+
for (let i = unsendable.length - 1; i >= 0; i--) {
|
|
7265
|
+
const normalized = normalizeUnsendableBlock(unsendable[i]);
|
|
7266
|
+
if (normalized) return withContent(message, [
|
|
7267
|
+
normalized
|
|
7268
|
+
]);
|
|
7269
|
+
}
|
|
7270
|
+
}
|
|
7271
|
+
return withContent(message, kept);
|
|
7272
|
+
}
|
|
7273
|
+
__name(sanitizeMessageReasoning, "sanitizeMessageReasoning");
|
|
7274
|
+
function sanitizeReasoningForBedrock(messages) {
|
|
7275
|
+
let sanitized = 0;
|
|
7276
|
+
let next;
|
|
7277
|
+
for (let i = 0; i < messages.length; i++) {
|
|
7278
|
+
const cleaned = sanitizeMessageReasoning(messages[i]);
|
|
7279
|
+
if (cleaned === messages[i]) continue;
|
|
7280
|
+
if (!next) next = [
|
|
7281
|
+
...messages
|
|
7282
|
+
];
|
|
7283
|
+
next[i] = cleaned;
|
|
7284
|
+
const before = messages[i].content.length;
|
|
7285
|
+
const after = cleaned.content.length;
|
|
7286
|
+
sanitized += Math.max(1, before - after);
|
|
7287
|
+
}
|
|
7288
|
+
return {
|
|
7289
|
+
messages: next ?? messages,
|
|
7290
|
+
sanitized
|
|
7291
|
+
};
|
|
7292
|
+
}
|
|
7293
|
+
__name(sanitizeReasoningForBedrock, "sanitizeReasoningForBedrock");
|
|
7294
|
+
|
|
7295
|
+
// src/models/bedrock-chat-model.ts
|
|
7296
|
+
var logger2 = new Logger("FlutchChatBedrockConverse");
|
|
7297
|
+
var FlutchChatBedrockConverse = class extends ChatBedrockConverse {
|
|
7298
|
+
static {
|
|
7299
|
+
__name(this, "FlutchChatBedrockConverse");
|
|
7300
|
+
}
|
|
7301
|
+
static lc_name() {
|
|
7302
|
+
return "FlutchChatBedrockConverse";
|
|
7303
|
+
}
|
|
7304
|
+
sanitize(messages) {
|
|
7305
|
+
const { messages: cleaned, sanitized } = sanitizeReasoningForBedrock(messages);
|
|
7306
|
+
if (sanitized > 0) {
|
|
7307
|
+
logger2.debug(`Dropped ${sanitized} unsendable reasoning block(s) from outgoing history (model=${this.model})`);
|
|
7308
|
+
}
|
|
7309
|
+
return cleaned;
|
|
7310
|
+
}
|
|
7311
|
+
/** `.invoke()` / `.generate()` path. */
|
|
7312
|
+
async _generate(messages, options, runManager) {
|
|
7313
|
+
return super._generate(this.sanitize(messages), options, runManager);
|
|
7314
|
+
}
|
|
7315
|
+
/** `.stream()` / `streamEvents()` path (also used by `_generate` when the
|
|
7316
|
+
* model is constructed with `streaming: true` — sanitizing is idempotent). */
|
|
7317
|
+
async *_streamResponseChunks(messages, options, runManager) {
|
|
7318
|
+
yield* super._streamResponseChunks(this.sanitize(messages), options, runManager);
|
|
7319
|
+
}
|
|
7320
|
+
};
|
|
7108
7321
|
var VoyageAIRerank = class extends BaseDocumentCompressor {
|
|
7109
7322
|
static {
|
|
7110
7323
|
__name(this, "VoyageAIRerank");
|
|
@@ -7176,10 +7389,10 @@ var ModelInitializer = class _ModelInitializer {
|
|
|
7176
7389
|
[ModelProvider.COHERE]: "COHERE_API_KEY",
|
|
7177
7390
|
[ModelProvider.VOYAGEAI]: "VOYAGEAI_API_KEY"
|
|
7178
7391
|
};
|
|
7179
|
-
constructor(configFetcher,
|
|
7392
|
+
constructor(configFetcher, logger3, apiKeyResolver) {
|
|
7180
7393
|
this.configFetcher = configFetcher;
|
|
7181
7394
|
this.apiKeyResolver = apiKeyResolver;
|
|
7182
|
-
this.logger =
|
|
7395
|
+
this.logger = logger3 || new Logger(_ModelInitializer.name);
|
|
7183
7396
|
}
|
|
7184
7397
|
/**
|
|
7185
7398
|
* Resolve API key for a provider.
|
|
@@ -7202,6 +7415,32 @@ var ModelInitializer = class _ModelInitializer {
|
|
|
7202
7415
|
return process.env.BEDROCK_AWS_REGION || process.env.AWS_REGION || process.env.AWS_DEFAULT_REGION || "us-east-1";
|
|
7203
7416
|
}
|
|
7204
7417
|
/**
|
|
7418
|
+
* Resolve sampling parameters for a model, dropping them when the model
|
|
7419
|
+
* does not accept them (Claude Opus 4.7+, Claude 5 and newer).
|
|
7420
|
+
*
|
|
7421
|
+
* An explicitly requested value on such a model is **ignored with a warning**
|
|
7422
|
+
* rather than raising: the request must keep working, and the model runs at
|
|
7423
|
+
* its own default sampling behaviour. Pass `supportsSamplingParams: true` in
|
|
7424
|
+
* the config to force the params through anyway.
|
|
7425
|
+
*
|
|
7426
|
+
* @param modelIdentifiers every name the model is known by (catalog model
|
|
7427
|
+
* name, Bedrock model id, …) — a match on any of them drops the params
|
|
7428
|
+
* @param wasExplicit whether the caller explicitly asked for these values
|
|
7429
|
+
* (as opposed to inheriting a catalog/SDK default) — controls log level
|
|
7430
|
+
*/
|
|
7431
|
+
resolveSampling(modelIdentifiers, requested, supportsSamplingParams, wasExplicit = false) {
|
|
7432
|
+
const resolved = resolveSamplingParams(modelIdentifiers, requested, supportsSamplingParams);
|
|
7433
|
+
if (!resolved.accepted && resolved.dropped.length > 0) {
|
|
7434
|
+
const message = `Model ${modelIdentifiers.filter(Boolean).join(" / ")} does not accept sampling parameters \u2014 ignoring ${resolved.dropped.join(", ")}. Set supportsSamplingParams: true to override.`;
|
|
7435
|
+
if (wasExplicit) {
|
|
7436
|
+
this.logger.warn(message);
|
|
7437
|
+
} else {
|
|
7438
|
+
this.logger.debug(message);
|
|
7439
|
+
}
|
|
7440
|
+
}
|
|
7441
|
+
return resolved.params;
|
|
7442
|
+
}
|
|
7443
|
+
/**
|
|
7205
7444
|
* Generate hash from toolsConfig for cache key
|
|
7206
7445
|
* Uses MD5 hash to create short, unique identifier
|
|
7207
7446
|
*/
|
|
@@ -7215,10 +7454,10 @@ var ModelInitializer = class _ModelInitializer {
|
|
|
7215
7454
|
*/
|
|
7216
7455
|
generateModelCacheKey(config) {
|
|
7217
7456
|
const base = generateModelCacheKey(config.modelId, config.temperature, config.maxTokens, config.toolsConfig, config.baseURL);
|
|
7218
|
-
|
|
7219
|
-
|
|
7220
|
-
}
|
|
7221
|
-
return
|
|
7457
|
+
const withMcp = config.mcpServers && config.mcpServers.length > 0 ? `${base}:mcp:${JSON.stringify(config.mcpServers)}` : base;
|
|
7458
|
+
const withSampling = config.supportsSamplingParams === void 0 ? withMcp : `${withMcp}:sp:${config.supportsSamplingParams}`;
|
|
7459
|
+
const withCache = config.promptCache === void 0 && config.promptCacheTtl === void 0 ? withSampling : `${withSampling}:pc:${config.promptCache ?? "auto"}:${config.promptCacheTtl ?? "default"}`;
|
|
7460
|
+
return config.effort === void 0 ? withCache : `${withCache}:eff:${config.effort}`;
|
|
7222
7461
|
}
|
|
7223
7462
|
// Chat model creators
|
|
7224
7463
|
chatModelCreators = {
|
|
@@ -7233,12 +7472,23 @@ var ModelInitializer = class _ModelInitializer {
|
|
|
7233
7472
|
}
|
|
7234
7473
|
return new ChatOpenAI(config);
|
|
7235
7474
|
},
|
|
7236
|
-
[ModelProvider.ANTHROPIC]: ({ modelName, defaultTemperature, defaultMaxTokens, apiToken, baseURL }) => {
|
|
7475
|
+
[ModelProvider.ANTHROPIC]: ({ modelName, defaultTemperature, defaultMaxTokens, apiToken, baseURL }, promptCacheControl) => {
|
|
7237
7476
|
const routerURL = resolveRouterURL(baseURL);
|
|
7238
7477
|
return new ChatAnthropic({
|
|
7239
7478
|
modelName,
|
|
7240
|
-
temperature
|
|
7479
|
+
// Claude Opus 4.7+ / Claude 5 reject `temperature` outright — the key
|
|
7480
|
+
// must be absent, not `undefined`.
|
|
7481
|
+
...defaultTemperature !== void 0 && {
|
|
7482
|
+
temperature: defaultTemperature
|
|
7483
|
+
},
|
|
7241
7484
|
maxTokens: defaultMaxTokens,
|
|
7485
|
+
// Top-level prompt caching: one breakpoint on the last cacheable block,
|
|
7486
|
+
// advanced automatically as the conversation grows. Survives the router
|
|
7487
|
+
// (which forwards the Anthropic body untouched) and is accepted by
|
|
7488
|
+
// Bedrock's InvokeModel schema behind it.
|
|
7489
|
+
...promptCacheControl && {
|
|
7490
|
+
cache_control: promptCacheControl
|
|
7491
|
+
},
|
|
7242
7492
|
anthropicApiKey: apiToken || this.resolveApiKey(ModelProvider.ANTHROPIC),
|
|
7243
7493
|
...routerURL && {
|
|
7244
7494
|
anthropicApiUrl: routerURL,
|
|
@@ -7253,7 +7503,9 @@ var ModelInitializer = class _ModelInitializer {
|
|
|
7253
7503
|
const token = apiToken || this.resolveApiKey(ModelProvider.COHERE);
|
|
7254
7504
|
return routerURL ? new ChatCohere({
|
|
7255
7505
|
model: modelName,
|
|
7256
|
-
|
|
7506
|
+
...defaultTemperature !== void 0 && {
|
|
7507
|
+
temperature: defaultTemperature
|
|
7508
|
+
},
|
|
7257
7509
|
client: new CohereClient({
|
|
7258
7510
|
token,
|
|
7259
7511
|
baseUrl: routerURL,
|
|
@@ -7263,7 +7515,9 @@ var ModelInitializer = class _ModelInitializer {
|
|
|
7263
7515
|
})
|
|
7264
7516
|
}) : new ChatCohere({
|
|
7265
7517
|
model: modelName,
|
|
7266
|
-
|
|
7518
|
+
...defaultTemperature !== void 0 && {
|
|
7519
|
+
temperature: defaultTemperature
|
|
7520
|
+
},
|
|
7267
7521
|
apiKey: token
|
|
7268
7522
|
});
|
|
7269
7523
|
},
|
|
@@ -7271,7 +7525,9 @@ var ModelInitializer = class _ModelInitializer {
|
|
|
7271
7525
|
const routerURL = resolveRouterURL(baseURL);
|
|
7272
7526
|
return new ChatMistralAI({
|
|
7273
7527
|
model: modelName,
|
|
7274
|
-
|
|
7528
|
+
...defaultTemperature !== void 0 && {
|
|
7529
|
+
temperature: defaultTemperature
|
|
7530
|
+
},
|
|
7275
7531
|
maxTokens: defaultMaxTokens,
|
|
7276
7532
|
apiKey: apiToken || this.resolveApiKey(ModelProvider.MISTRAL),
|
|
7277
7533
|
...routerURL && {
|
|
@@ -7361,7 +7617,8 @@ var ModelInitializer = class _ModelInitializer {
|
|
|
7361
7617
|
async initializeChatModelDirect(config, customTools) {
|
|
7362
7618
|
const toolsConfig = normalizeToolConfigs(config.tools);
|
|
7363
7619
|
const modelIdentifier = `${config.provider}:${config.modelName}`;
|
|
7364
|
-
const
|
|
7620
|
+
const baseCacheKey = generateModelCacheKey(modelIdentifier, config.temperature, config.maxTokens, toolsConfig, config.baseURL);
|
|
7621
|
+
const cacheKey = config.supportsSamplingParams === void 0 ? baseCacheKey : `${baseCacheKey}:sp:${config.supportsSamplingParams}`;
|
|
7365
7622
|
const cached = this.modelInstanceCache.get(cacheKey);
|
|
7366
7623
|
if (cached) {
|
|
7367
7624
|
this.logger.debug(`Using cached chat model instance: ${cacheKey}`);
|
|
@@ -7372,18 +7629,23 @@ var ModelInitializer = class _ModelInitializer {
|
|
|
7372
7629
|
throw new Error(`Unknown provider "${provider}". Valid: ${Object.values(ModelProvider).join(", ")}`);
|
|
7373
7630
|
}
|
|
7374
7631
|
const apiToken = this.resolveApiKey(provider);
|
|
7375
|
-
const
|
|
7376
|
-
const
|
|
7632
|
+
const maxTokens = toOptionalNumber(config.maxTokens) ?? 4096;
|
|
7633
|
+
const sampling = this.resolveSampling([
|
|
7634
|
+
config.modelName
|
|
7635
|
+
], {
|
|
7636
|
+
temperature: toOptionalNumber(config.temperature) ?? 0.7
|
|
7637
|
+
}, config.supportsSamplingParams, config.temperature !== void 0);
|
|
7377
7638
|
const modelConfig = {
|
|
7378
7639
|
modelId: modelIdentifier,
|
|
7379
7640
|
modelName: config.modelName,
|
|
7380
7641
|
provider,
|
|
7381
7642
|
modelType: ModelType.CHAT,
|
|
7382
|
-
defaultTemperature:
|
|
7383
|
-
defaultMaxTokens:
|
|
7643
|
+
defaultTemperature: sampling.temperature,
|
|
7644
|
+
defaultMaxTokens: maxTokens,
|
|
7384
7645
|
apiToken,
|
|
7385
7646
|
requiresApiKey: true,
|
|
7386
|
-
baseURL: config.baseURL
|
|
7647
|
+
baseURL: config.baseURL,
|
|
7648
|
+
supportsSamplingParams: config.supportsSamplingParams
|
|
7387
7649
|
};
|
|
7388
7650
|
this.logger.debug(`Creating chat model: ${modelIdentifier} (apiKeyResolved=${!!apiToken})`);
|
|
7389
7651
|
const creator = this.chatModelCreators[provider];
|
|
@@ -7418,19 +7680,40 @@ var ModelInitializer = class _ModelInitializer {
|
|
|
7418
7680
|
if (modelConfig.modelType !== ModelType.CHAT) {
|
|
7419
7681
|
throw new Error(`Model ${config.modelId} is not a chat model (type: ${modelConfig.modelType})`);
|
|
7420
7682
|
}
|
|
7683
|
+
const requestedTemperature = toOptionalNumber(config.temperature) ?? toOptionalNumber(modelConfig.defaultTemperature);
|
|
7684
|
+
const sampling = this.resolveSampling([
|
|
7685
|
+
modelConfig.modelName,
|
|
7686
|
+
modelConfig.bedrockModelId
|
|
7687
|
+
], {
|
|
7688
|
+
temperature: requestedTemperature
|
|
7689
|
+
}, config.supportsSamplingParams ?? modelConfig.supportsSamplingParams, config.temperature !== void 0);
|
|
7421
7690
|
const finalConfig = {
|
|
7422
7691
|
...modelConfig,
|
|
7423
|
-
defaultTemperature:
|
|
7424
|
-
defaultMaxTokens:
|
|
7692
|
+
defaultTemperature: sampling.temperature,
|
|
7693
|
+
defaultMaxTokens: toOptionalNumber(config.maxTokens) ?? toOptionalNumber(modelConfig.defaultMaxTokens),
|
|
7425
7694
|
baseURL: config.baseURL ?? modelConfig.baseURL
|
|
7426
7695
|
};
|
|
7696
|
+
const promptCacheControl = resolvePromptCacheControl([
|
|
7697
|
+
finalConfig.bedrockModelId,
|
|
7698
|
+
finalConfig.modelName
|
|
7699
|
+
], config.promptCache ?? modelConfig.promptCache, config.promptCacheTtl ?? modelConfig.promptCacheTtl);
|
|
7700
|
+
if (promptCacheControl) {
|
|
7701
|
+
this.logger.debug(`Prompt caching enabled for ${finalConfig.bedrockModelId ?? finalConfig.modelName} (ttl=${promptCacheControl.ttl})`);
|
|
7702
|
+
}
|
|
7427
7703
|
this.logger.debug(`Creating new chat model instance: ${cacheKey}`);
|
|
7428
7704
|
let model;
|
|
7429
7705
|
if (finalConfig.useBedrock && finalConfig.bedrockModelId) {
|
|
7430
|
-
|
|
7706
|
+
const effortFields = buildEffortRequestFields(config.effort ?? modelConfig.defaultEffort);
|
|
7707
|
+
model = new FlutchChatBedrockConverse({
|
|
7431
7708
|
model: finalConfig.bedrockModelId,
|
|
7432
7709
|
region: this.resolveBedrockRegion(),
|
|
7433
|
-
|
|
7710
|
+
// Key omitted (not `undefined`) for models that reject sampling params.
|
|
7711
|
+
...finalConfig.defaultTemperature !== void 0 && {
|
|
7712
|
+
temperature: finalConfig.defaultTemperature
|
|
7713
|
+
},
|
|
7714
|
+
...effortFields && {
|
|
7715
|
+
additionalModelRequestFields: effortFields
|
|
7716
|
+
},
|
|
7434
7717
|
maxTokens: finalConfig.defaultMaxTokens,
|
|
7435
7718
|
streaming: true
|
|
7436
7719
|
});
|
|
@@ -7439,14 +7722,24 @@ var ModelInitializer = class _ModelInitializer {
|
|
|
7439
7722
|
if (!creator) {
|
|
7440
7723
|
throw new Error(`Chat models not supported for provider: ${modelConfig.provider}`);
|
|
7441
7724
|
}
|
|
7442
|
-
model = creator(finalConfig);
|
|
7725
|
+
model = creator(finalConfig, promptCacheControl);
|
|
7443
7726
|
}
|
|
7444
7727
|
model.metadata = {
|
|
7445
7728
|
...model.metadata,
|
|
7446
7729
|
modelId: config.modelId
|
|
7447
7730
|
};
|
|
7448
7731
|
if (config.toolsConfig || config.customTools || config.mcpServers && config.mcpServers.length > 0) {
|
|
7449
|
-
const boundModel = await this.bindToolsToModel(
|
|
7732
|
+
const boundModel = await this.bindToolsToModel(
|
|
7733
|
+
model,
|
|
7734
|
+
config.toolsConfig,
|
|
7735
|
+
config.customTools,
|
|
7736
|
+
config.mcpServers,
|
|
7737
|
+
config.mcpContext,
|
|
7738
|
+
// Converse takes cache control as a per-call option; the Anthropic
|
|
7739
|
+
// client already got it as a constructor field, and handing it the
|
|
7740
|
+
// same value twice would put an unknown key in its call options.
|
|
7741
|
+
finalConfig.useBedrock ? promptCacheControl : void 0
|
|
7742
|
+
);
|
|
7450
7743
|
this.modelInstanceCache.set(cacheKey, boundModel);
|
|
7451
7744
|
return boundModel;
|
|
7452
7745
|
}
|
|
@@ -7458,11 +7751,20 @@ var ModelInitializer = class _ModelInitializer {
|
|
|
7458
7751
|
* For toolsConfig: fetch tool executors from MCP Runtime
|
|
7459
7752
|
* For customTools: use as-is (already prepared DynamicStructuredTool)
|
|
7460
7753
|
*
|
|
7754
|
+
* `promptCacheControl` is the **Bedrock-only** half of prompt caching: it is
|
|
7755
|
+
* bound alongside the tools as a default call option, and `ChatBedrockConverse`
|
|
7756
|
+
* turns it into `cachePoint` blocks after the tool schemas, the system prompt
|
|
7757
|
+
* and the last message. Tool schemas dominate the request, so this is the one
|
|
7758
|
+
* place worth caching — a model with no tools keeps its plain `BaseChatModel`
|
|
7759
|
+
* type and no cache points (callers there rely on `withStructuredOutput` and
|
|
7760
|
+
* friends). The Anthropic client takes its cache settings in the constructor
|
|
7761
|
+
* instead and must not be handed them again here.
|
|
7762
|
+
*
|
|
7461
7763
|
* Returns:
|
|
7462
7764
|
* - Runnable when tools are bound (model.bindTools returns Runnable)
|
|
7463
7765
|
* - BaseChatModel when no tools
|
|
7464
7766
|
*/
|
|
7465
|
-
async bindToolsToModel(model, toolsConfig, customTools, mcpServers, mcpContext) {
|
|
7767
|
+
async bindToolsToModel(model, toolsConfig, customTools, mcpServers, mcpContext, promptCacheControl) {
|
|
7466
7768
|
const allTools = [];
|
|
7467
7769
|
const enabledToolsConfig = (toolsConfig || []).filter((tc) => tc.enabled !== false);
|
|
7468
7770
|
const hasInlineServers = !!(mcpServers && mcpServers.length > 0);
|
|
@@ -7483,7 +7785,10 @@ var ModelInitializer = class _ModelInitializer {
|
|
|
7483
7785
|
}
|
|
7484
7786
|
if (allTools.length > 0) {
|
|
7485
7787
|
this.logger.debug(`Binding ${allTools.length} tools to model`);
|
|
7486
|
-
const
|
|
7788
|
+
const boundOptions = {
|
|
7789
|
+
cache_control: promptCacheControl
|
|
7790
|
+
};
|
|
7791
|
+
const modelWithTools = promptCacheControl ? model.bindTools(allTools, boundOptions) : model.bindTools(allTools);
|
|
7487
7792
|
return modelWithTools;
|
|
7488
7793
|
}
|
|
7489
7794
|
return model;
|
|
@@ -8276,6 +8581,6 @@ var MongoTokenStore = class {
|
|
|
8276
8581
|
}
|
|
8277
8582
|
};
|
|
8278
8583
|
|
|
8279
|
-
export { AbstractGraphBuilder, AttachmentType, GraphController as BaseGraphServiceController, UniversalGraphModule as BaseGraphServiceModule, BuilderRegistryService, Callback, CallbackACL, CallbackAuditAction, CallbackAuditor, CallbackController, CallbackMetrics, CallbackPatchService, CallbackRateLimiter, CallbackRegistry, CallbackStore, CallbackTokenGuard, ChatFeature, DEFAULT_ATTACHMENT_THRESHOLD, DEFAULT_ROUTER_URL, DEFAULT_TRACER_OPTIONS, ENDPOINT_METADATA_KEY, Endpoint, EndpointRegistry, EventProcessor, ExternalGraphBuilder, FileBasedDiscovery, FileTokenStore, GraphController, GraphEngineFactory, GraphEngineType, GraphManifestSchema, GraphManifestValidator, GraphServiceTokens, GraphTypeUtils, IdempotencyManager, IdempotencyStatus, LangGraphEngine, McpConverter, McpRuntimeHttpClient, McpToolFilter, ModelInitializer, ModelProvider, ModelType, MongoTokenStore, OAuthTokenManager, RetrieverSearchType, RetrieverService, SmartCallbackRouter, StaticDiscovery, StreamChannel, TelegramPatchHandler, UIDispatchController, UIEndpoint, UIEndpointsDiscoveryService, UniversalCallbackService, UniversalGraphModule, UniversalGraphService, VersionedGraphService, VoyageAIRerank, WebPatchHandler, WithCallbacks, WithEndpoints, WithUIEndpoints, _internals, bootstrap, buildOAuthAuthorizationUrl, buildOpenAIModelConfig, clearAttachmentDataStore, createEndpointDescriptors, createGraphAttachment, createMongoClientAdapter, createStaticMessage, decryptTokens, dispatchAttachments, encryptTokens, executeToolWithAttachments, findCallbackMethod, findEndpointMethod, flutchFetch, flutchHeaders, flutchMistralHook, generateAttachmentSummary, generateModelCacheKey, getAttachmentData, getCallbackMetadata, getEndpointMetadata, getFlutchContext, getOAuthProvider, getOAuthProviderNames, getUIEndpointClassMetadata, getUIEndpointMethodsMetadata, hasCallbacks, hasUIEndpoints, hashToolsConfig, isInternalMode, isReasoningModel, loadOAuthProviders, normalizeToolConfigs, registerFinanceExampleCallback, registerUIEndpointsFromClass, resolveOAuthProviderConfig, resolveRouterURL, sanitizeTraceData, storeAttachmentData, traceApiCall, withFlutchContext, wrapCohereFetcher };
|
|
8584
|
+
export { AbstractGraphBuilder, AttachmentType, GraphController as BaseGraphServiceController, UniversalGraphModule as BaseGraphServiceModule, BuilderRegistryService, Callback, CallbackACL, CallbackAuditAction, CallbackAuditor, CallbackController, CallbackMetrics, CallbackPatchService, CallbackRateLimiter, CallbackRegistry, CallbackStore, CallbackTokenGuard, ChatFeature, DEFAULT_ATTACHMENT_THRESHOLD, DEFAULT_ROUTER_URL, DEFAULT_TRACER_OPTIONS, ENDPOINT_METADATA_KEY, Endpoint, EndpointRegistry, EventProcessor, ExternalGraphBuilder, FileBasedDiscovery, FileTokenStore, FlutchChatBedrockConverse, GraphController, GraphEngineFactory, GraphEngineType, GraphManifestSchema, GraphManifestValidator, GraphServiceTokens, GraphTypeUtils, IdempotencyManager, IdempotencyStatus, LangGraphEngine, McpConverter, McpRuntimeHttpClient, McpToolFilter, ModelInitializer, ModelProvider, ModelType, MongoTokenStore, OAuthTokenManager, PROMPT_CACHE_MIN_VERSIONS, RetrieverSearchType, RetrieverService, SAMPLING_PARAM_FREE_THRESHOLDS, SmartCallbackRouter, StaticDiscovery, StreamChannel, TelegramPatchHandler, UIDispatchController, UIEndpoint, UIEndpointsDiscoveryService, UniversalCallbackService, UniversalGraphModule, UniversalGraphService, VersionedGraphService, VoyageAIRerank, WebPatchHandler, WithCallbacks, WithEndpoints, WithUIEndpoints, _internals, bootstrap, buildEffortRequestFields, buildOAuthAuthorizationUrl, buildOpenAIModelConfig, clearAttachmentDataStore, createEndpointDescriptors, createGraphAttachment, createMongoClientAdapter, createStaticMessage, decryptTokens, dispatchAttachments, encryptTokens, executeToolWithAttachments, findCallbackMethod, findEndpointMethod, flutchFetch, flutchHeaders, flutchMistralHook, generateAttachmentSummary, generateModelCacheKey, getAttachmentData, getCallbackMetadata, getEndpointMetadata, getFlutchContext, getOAuthProvider, getOAuthProviderNames, getUIEndpointClassMetadata, getUIEndpointMethodsMetadata, hasCallbacks, hasUIEndpoints, hashToolsConfig, isInternalMode, isReasoningBlock, isReasoningModel, isSendableReasoningBlock, loadOAuthProviders, modelAcceptsSamplingParams, modelSupportsPromptCache, normalizeToolConfigs, registerFinanceExampleCallback, registerUIEndpointsFromClass, resolveOAuthProviderConfig, resolvePromptCacheControl, resolveRouterURL, resolveSamplingParams, sanitizeMessageReasoning, sanitizeReasoningForBedrock, sanitizeTraceData, storeAttachmentData, toOptionalNumber, traceApiCall, withFlutchContext, wrapCohereFetcher };
|
|
8280
8585
|
//# sourceMappingURL=index.js.map
|
|
8281
8586
|
//# sourceMappingURL=index.js.map
|