@flutchai/flutch-sdk 0.6.5 → 0.6.7
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 +106 -7
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +79 -55
- package/dist/index.d.ts +79 -55
- package/dist/index.js +102 -8
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -5113,6 +5113,16 @@ function _ts_decorate21(decorators, target, key, desc) {
|
|
|
5113
5113
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
5114
5114
|
}
|
|
5115
5115
|
__name(_ts_decorate21, "_ts_decorate");
|
|
5116
|
+
function joinTextSteps(parts) {
|
|
5117
|
+
let out = "";
|
|
5118
|
+
for (const part of parts) {
|
|
5119
|
+
if (!part) continue;
|
|
5120
|
+
if (!out || /\s$/.test(out) || /^\s/.test(part)) out += part;
|
|
5121
|
+
else out += "\n\n" + part;
|
|
5122
|
+
}
|
|
5123
|
+
return out;
|
|
5124
|
+
}
|
|
5125
|
+
__name(joinTextSteps, "joinTextSteps");
|
|
5116
5126
|
exports.EventProcessor = class _EventProcessor {
|
|
5117
5127
|
static {
|
|
5118
5128
|
__name(this, "EventProcessor");
|
|
@@ -5548,7 +5558,7 @@ exports.EventProcessor = class _EventProcessor {
|
|
|
5548
5558
|
totalEvents: acc.traceEvents.length
|
|
5549
5559
|
} : null;
|
|
5550
5560
|
const textChain = allChains.find((c) => c.channel === "text");
|
|
5551
|
-
const text = textChain ? textChain.steps.filter((step) => step.type === "text").map((step) => step.text || "")
|
|
5561
|
+
const text = textChain ? joinTextSteps(textChain.steps.filter((step) => step.type === "text").map((step) => step.text || "")) : "";
|
|
5552
5562
|
this.logger.log("\u{1F4CA} [EventProcessor] Final result assembled", {
|
|
5553
5563
|
totalChains: allChains.length,
|
|
5554
5564
|
textChains: allChains.filter((c) => c.channel === "text").length,
|
|
@@ -7113,6 +7123,48 @@ function modelAcceptsSamplingParams(modelIdentifier) {
|
|
|
7113
7123
|
return !atOrAboveThreshold;
|
|
7114
7124
|
}
|
|
7115
7125
|
__name(modelAcceptsSamplingParams, "modelAcceptsSamplingParams");
|
|
7126
|
+
var PROMPT_CACHE_MIN_VERSIONS = {
|
|
7127
|
+
opus: {
|
|
7128
|
+
major: 4,
|
|
7129
|
+
minor: 0
|
|
7130
|
+
},
|
|
7131
|
+
sonnet: {
|
|
7132
|
+
major: 4,
|
|
7133
|
+
minor: 0
|
|
7134
|
+
},
|
|
7135
|
+
haiku: {
|
|
7136
|
+
major: 4,
|
|
7137
|
+
minor: 5
|
|
7138
|
+
}
|
|
7139
|
+
};
|
|
7140
|
+
function modelSupportsPromptCache(modelIdentifier) {
|
|
7141
|
+
if (!modelIdentifier) return false;
|
|
7142
|
+
const match = CLAUDE_FAMILY_VERSION.exec(modelIdentifier.toLowerCase());
|
|
7143
|
+
if (!match) return false;
|
|
7144
|
+
const [, family, majorRaw, minorRaw] = match;
|
|
7145
|
+
const threshold = PROMPT_CACHE_MIN_VERSIONS[family];
|
|
7146
|
+
if (!threshold) return false;
|
|
7147
|
+
const major = Number(majorRaw);
|
|
7148
|
+
const minor = minorRaw === void 0 ? 0 : Number(minorRaw);
|
|
7149
|
+
return major > threshold.major || major === threshold.major && minor >= threshold.minor;
|
|
7150
|
+
}
|
|
7151
|
+
__name(modelSupportsPromptCache, "modelSupportsPromptCache");
|
|
7152
|
+
function resolvePromptCacheControl(modelIdentifiers, promptCache, ttl) {
|
|
7153
|
+
const enabled = promptCache ?? modelIdentifiers.some((id) => modelSupportsPromptCache(id));
|
|
7154
|
+
return enabled ? {
|
|
7155
|
+
type: "ephemeral",
|
|
7156
|
+
ttl: ttl ?? "5m"
|
|
7157
|
+
} : void 0;
|
|
7158
|
+
}
|
|
7159
|
+
__name(resolvePromptCacheControl, "resolvePromptCacheControl");
|
|
7160
|
+
function buildEffortRequestFields(effort) {
|
|
7161
|
+
return effort ? {
|
|
7162
|
+
output_config: {
|
|
7163
|
+
effort
|
|
7164
|
+
}
|
|
7165
|
+
} : void 0;
|
|
7166
|
+
}
|
|
7167
|
+
__name(buildEffortRequestFields, "buildEffortRequestFields");
|
|
7116
7168
|
function resolveSamplingParams(modelIdentifiers, requested, supportsSamplingParams) {
|
|
7117
7169
|
const accepted = supportsSamplingParams ?? modelIdentifiers.every((id) => modelAcceptsSamplingParams(id));
|
|
7118
7170
|
if (accepted) {
|
|
@@ -7443,7 +7495,9 @@ var ModelInitializer = class _ModelInitializer {
|
|
|
7443
7495
|
generateModelCacheKey(config) {
|
|
7444
7496
|
const base = generateModelCacheKey(config.modelId, config.temperature, config.maxTokens, config.toolsConfig, config.baseURL);
|
|
7445
7497
|
const withMcp = config.mcpServers && config.mcpServers.length > 0 ? `${base}:mcp:${JSON.stringify(config.mcpServers)}` : base;
|
|
7446
|
-
|
|
7498
|
+
const withSampling = config.supportsSamplingParams === void 0 ? withMcp : `${withMcp}:sp:${config.supportsSamplingParams}`;
|
|
7499
|
+
const withCache = config.promptCache === void 0 && config.promptCacheTtl === void 0 ? withSampling : `${withSampling}:pc:${config.promptCache ?? "auto"}:${config.promptCacheTtl ?? "default"}`;
|
|
7500
|
+
return config.effort === void 0 ? withCache : `${withCache}:eff:${config.effort}`;
|
|
7447
7501
|
}
|
|
7448
7502
|
// Chat model creators
|
|
7449
7503
|
chatModelCreators = {
|
|
@@ -7458,7 +7512,7 @@ var ModelInitializer = class _ModelInitializer {
|
|
|
7458
7512
|
}
|
|
7459
7513
|
return new openai.ChatOpenAI(config);
|
|
7460
7514
|
},
|
|
7461
|
-
[ModelProvider.ANTHROPIC]: ({ modelName, defaultTemperature, defaultMaxTokens, apiToken, baseURL }) => {
|
|
7515
|
+
[ModelProvider.ANTHROPIC]: ({ modelName, defaultTemperature, defaultMaxTokens, apiToken, baseURL }, promptCacheControl) => {
|
|
7462
7516
|
const routerURL = resolveRouterURL(baseURL);
|
|
7463
7517
|
return new anthropic.ChatAnthropic({
|
|
7464
7518
|
modelName,
|
|
@@ -7468,6 +7522,13 @@ var ModelInitializer = class _ModelInitializer {
|
|
|
7468
7522
|
temperature: defaultTemperature
|
|
7469
7523
|
},
|
|
7470
7524
|
maxTokens: defaultMaxTokens,
|
|
7525
|
+
// Top-level prompt caching: one breakpoint on the last cacheable block,
|
|
7526
|
+
// advanced automatically as the conversation grows. Survives the router
|
|
7527
|
+
// (which forwards the Anthropic body untouched) and is accepted by
|
|
7528
|
+
// Bedrock's InvokeModel schema behind it.
|
|
7529
|
+
...promptCacheControl && {
|
|
7530
|
+
cache_control: promptCacheControl
|
|
7531
|
+
},
|
|
7471
7532
|
anthropicApiKey: apiToken || this.resolveApiKey(ModelProvider.ANTHROPIC),
|
|
7472
7533
|
...routerURL && {
|
|
7473
7534
|
anthropicApiUrl: routerURL,
|
|
@@ -7672,9 +7733,17 @@ var ModelInitializer = class _ModelInitializer {
|
|
|
7672
7733
|
defaultMaxTokens: toOptionalNumber(config.maxTokens) ?? toOptionalNumber(modelConfig.defaultMaxTokens),
|
|
7673
7734
|
baseURL: config.baseURL ?? modelConfig.baseURL
|
|
7674
7735
|
};
|
|
7736
|
+
const promptCacheControl = resolvePromptCacheControl([
|
|
7737
|
+
finalConfig.bedrockModelId,
|
|
7738
|
+
finalConfig.modelName
|
|
7739
|
+
], config.promptCache ?? modelConfig.promptCache, config.promptCacheTtl ?? modelConfig.promptCacheTtl);
|
|
7740
|
+
if (promptCacheControl) {
|
|
7741
|
+
this.logger.debug(`Prompt caching enabled for ${finalConfig.bedrockModelId ?? finalConfig.modelName} (ttl=${promptCacheControl.ttl})`);
|
|
7742
|
+
}
|
|
7675
7743
|
this.logger.debug(`Creating new chat model instance: ${cacheKey}`);
|
|
7676
7744
|
let model;
|
|
7677
7745
|
if (finalConfig.useBedrock && finalConfig.bedrockModelId) {
|
|
7746
|
+
const effortFields = buildEffortRequestFields(config.effort ?? modelConfig.defaultEffort);
|
|
7678
7747
|
model = new FlutchChatBedrockConverse({
|
|
7679
7748
|
model: finalConfig.bedrockModelId,
|
|
7680
7749
|
region: this.resolveBedrockRegion(),
|
|
@@ -7682,6 +7751,9 @@ var ModelInitializer = class _ModelInitializer {
|
|
|
7682
7751
|
...finalConfig.defaultTemperature !== void 0 && {
|
|
7683
7752
|
temperature: finalConfig.defaultTemperature
|
|
7684
7753
|
},
|
|
7754
|
+
...effortFields && {
|
|
7755
|
+
additionalModelRequestFields: effortFields
|
|
7756
|
+
},
|
|
7685
7757
|
maxTokens: finalConfig.defaultMaxTokens,
|
|
7686
7758
|
streaming: true
|
|
7687
7759
|
});
|
|
@@ -7690,14 +7762,24 @@ var ModelInitializer = class _ModelInitializer {
|
|
|
7690
7762
|
if (!creator) {
|
|
7691
7763
|
throw new Error(`Chat models not supported for provider: ${modelConfig.provider}`);
|
|
7692
7764
|
}
|
|
7693
|
-
model = creator(finalConfig);
|
|
7765
|
+
model = creator(finalConfig, promptCacheControl);
|
|
7694
7766
|
}
|
|
7695
7767
|
model.metadata = {
|
|
7696
7768
|
...model.metadata,
|
|
7697
7769
|
modelId: config.modelId
|
|
7698
7770
|
};
|
|
7699
7771
|
if (config.toolsConfig || config.customTools || config.mcpServers && config.mcpServers.length > 0) {
|
|
7700
|
-
const boundModel = await this.bindToolsToModel(
|
|
7772
|
+
const boundModel = await this.bindToolsToModel(
|
|
7773
|
+
model,
|
|
7774
|
+
config.toolsConfig,
|
|
7775
|
+
config.customTools,
|
|
7776
|
+
config.mcpServers,
|
|
7777
|
+
config.mcpContext,
|
|
7778
|
+
// Converse takes cache control as a per-call option; the Anthropic
|
|
7779
|
+
// client already got it as a constructor field, and handing it the
|
|
7780
|
+
// same value twice would put an unknown key in its call options.
|
|
7781
|
+
finalConfig.useBedrock ? promptCacheControl : void 0
|
|
7782
|
+
);
|
|
7701
7783
|
this.modelInstanceCache.set(cacheKey, boundModel);
|
|
7702
7784
|
return boundModel;
|
|
7703
7785
|
}
|
|
@@ -7709,11 +7791,20 @@ var ModelInitializer = class _ModelInitializer {
|
|
|
7709
7791
|
* For toolsConfig: fetch tool executors from MCP Runtime
|
|
7710
7792
|
* For customTools: use as-is (already prepared DynamicStructuredTool)
|
|
7711
7793
|
*
|
|
7794
|
+
* `promptCacheControl` is the **Bedrock-only** half of prompt caching: it is
|
|
7795
|
+
* bound alongside the tools as a default call option, and `ChatBedrockConverse`
|
|
7796
|
+
* turns it into `cachePoint` blocks after the tool schemas, the system prompt
|
|
7797
|
+
* and the last message. Tool schemas dominate the request, so this is the one
|
|
7798
|
+
* place worth caching — a model with no tools keeps its plain `BaseChatModel`
|
|
7799
|
+
* type and no cache points (callers there rely on `withStructuredOutput` and
|
|
7800
|
+
* friends). The Anthropic client takes its cache settings in the constructor
|
|
7801
|
+
* instead and must not be handed them again here.
|
|
7802
|
+
*
|
|
7712
7803
|
* Returns:
|
|
7713
7804
|
* - Runnable when tools are bound (model.bindTools returns Runnable)
|
|
7714
7805
|
* - BaseChatModel when no tools
|
|
7715
7806
|
*/
|
|
7716
|
-
async bindToolsToModel(model, toolsConfig, customTools, mcpServers, mcpContext) {
|
|
7807
|
+
async bindToolsToModel(model, toolsConfig, customTools, mcpServers, mcpContext, promptCacheControl) {
|
|
7717
7808
|
const allTools = [];
|
|
7718
7809
|
const enabledToolsConfig = (toolsConfig || []).filter((tc) => tc.enabled !== false);
|
|
7719
7810
|
const hasInlineServers = !!(mcpServers && mcpServers.length > 0);
|
|
@@ -7734,7 +7825,10 @@ var ModelInitializer = class _ModelInitializer {
|
|
|
7734
7825
|
}
|
|
7735
7826
|
if (allTools.length > 0) {
|
|
7736
7827
|
this.logger.debug(`Binding ${allTools.length} tools to model`);
|
|
7737
|
-
const
|
|
7828
|
+
const boundOptions = {
|
|
7829
|
+
cache_control: promptCacheControl
|
|
7830
|
+
};
|
|
7831
|
+
const modelWithTools = promptCacheControl ? model.bindTools(allTools, boundOptions) : model.bindTools(allTools);
|
|
7738
7832
|
return modelWithTools;
|
|
7739
7833
|
}
|
|
7740
7834
|
return model;
|
|
@@ -8553,6 +8647,7 @@ exports.ModelProvider = ModelProvider;
|
|
|
8553
8647
|
exports.ModelType = ModelType;
|
|
8554
8648
|
exports.MongoTokenStore = MongoTokenStore;
|
|
8555
8649
|
exports.OAuthTokenManager = OAuthTokenManager;
|
|
8650
|
+
exports.PROMPT_CACHE_MIN_VERSIONS = PROMPT_CACHE_MIN_VERSIONS;
|
|
8556
8651
|
exports.RetrieverSearchType = RetrieverSearchType;
|
|
8557
8652
|
exports.SAMPLING_PARAM_FREE_THRESHOLDS = SAMPLING_PARAM_FREE_THRESHOLDS;
|
|
8558
8653
|
exports.StreamChannel = StreamChannel;
|
|
@@ -8564,6 +8659,7 @@ exports.WithEndpoints = WithEndpoints;
|
|
|
8564
8659
|
exports.WithUIEndpoints = WithUIEndpoints;
|
|
8565
8660
|
exports._internals = _internals;
|
|
8566
8661
|
exports.bootstrap = bootstrap;
|
|
8662
|
+
exports.buildEffortRequestFields = buildEffortRequestFields;
|
|
8567
8663
|
exports.buildOAuthAuthorizationUrl = buildOAuthAuthorizationUrl;
|
|
8568
8664
|
exports.buildOpenAIModelConfig = buildOpenAIModelConfig;
|
|
8569
8665
|
exports.clearAttachmentDataStore = clearAttachmentDataStore;
|
|
@@ -8597,12 +8693,15 @@ exports.isInternalMode = isInternalMode;
|
|
|
8597
8693
|
exports.isReasoningBlock = isReasoningBlock;
|
|
8598
8694
|
exports.isReasoningModel = isReasoningModel;
|
|
8599
8695
|
exports.isSendableReasoningBlock = isSendableReasoningBlock;
|
|
8696
|
+
exports.joinTextSteps = joinTextSteps;
|
|
8600
8697
|
exports.loadOAuthProviders = loadOAuthProviders;
|
|
8601
8698
|
exports.modelAcceptsSamplingParams = modelAcceptsSamplingParams;
|
|
8699
|
+
exports.modelSupportsPromptCache = modelSupportsPromptCache;
|
|
8602
8700
|
exports.normalizeToolConfigs = normalizeToolConfigs;
|
|
8603
8701
|
exports.registerFinanceExampleCallback = registerFinanceExampleCallback;
|
|
8604
8702
|
exports.registerUIEndpointsFromClass = registerUIEndpointsFromClass;
|
|
8605
8703
|
exports.resolveOAuthProviderConfig = resolveOAuthProviderConfig;
|
|
8704
|
+
exports.resolvePromptCacheControl = resolvePromptCacheControl;
|
|
8606
8705
|
exports.resolveRouterURL = resolveRouterURL;
|
|
8607
8706
|
exports.resolveSamplingParams = resolveSamplingParams;
|
|
8608
8707
|
exports.sanitizeMessageReasoning = sanitizeMessageReasoning;
|