@agentforge/core 0.11.6 → 0.11.8

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 CHANGED
@@ -91,6 +91,9 @@ __export(index_exports, {
91
91
  createProgressTracker: () => createProgressTracker,
92
92
  createSSEFormatter: () => createSSEFormatter,
93
93
  createSequentialWorkflow: () => createSequentialWorkflow,
94
+ createSharedCache: () => createSharedCache,
95
+ createSharedConcurrencyController: () => createSharedConcurrencyController,
96
+ createSharedRateLimiter: () => createSharedRateLimiter,
94
97
  createSqliteCheckpointer: () => createSqliteCheckpointer,
95
98
  createStateAnnotation: () => createStateAnnotation,
96
99
  createSubgraph: () => createSubgraph,
@@ -121,6 +124,7 @@ __export(index_exports, {
121
124
  isHumanRequestInterrupt: () => isHumanRequestInterrupt,
122
125
  isMemoryCheckpointer: () => isMemoryCheckpointer,
123
126
  isTracingEnabled: () => isTracingEnabled,
127
+ loadPrompt: () => loadPrompt,
124
128
  map: () => map,
125
129
  merge: () => merge,
126
130
  mergeState: () => mergeState,
@@ -129,8 +133,10 @@ __export(index_exports, {
129
133
  presets: () => presets,
130
134
  production: () => production,
131
135
  reduce: () => reduce,
136
+ renderTemplate: () => renderTemplate,
132
137
  retry: () => retry,
133
138
  safeValidateSchemaDescriptions: () => safeValidateSchemaDescriptions,
139
+ sanitizeValue: () => sanitizeValue,
134
140
  sendMessage: () => sendMessage,
135
141
  sequential: () => sequential,
136
142
  sequentialBuilder: () => sequentialBuilder,
@@ -146,11 +152,16 @@ __export(index_exports, {
146
152
  validateTool: () => validateTool,
147
153
  validateToolMetadata: () => validateToolMetadata,
148
154
  validateToolName: () => validateToolName,
155
+ withCache: () => withCache,
156
+ withConcurrency: () => withConcurrency,
149
157
  withErrorHandler: () => withErrorHandler,
158
+ withLogging: () => withLogging,
150
159
  withMetrics: () => withMetrics,
160
+ withRateLimit: () => withRateLimit,
151
161
  withRetry: () => withRetry,
152
162
  withTimeout: () => withTimeout,
153
- withTracing: () => withTracing
163
+ withTracing: () => withTracing,
164
+ withValidation: () => withValidation
154
165
  });
155
166
  module.exports = __toCommonJS(index_exports);
156
167
 
@@ -2854,6 +2865,578 @@ var presets = {
2854
2865
  testing
2855
2866
  };
2856
2867
 
2868
+ // src/langgraph/middleware/caching.ts
2869
+ var LRUCache = class {
2870
+ cache = /* @__PURE__ */ new Map();
2871
+ maxSize;
2872
+ evictionStrategy;
2873
+ constructor(maxSize, evictionStrategy = "lru") {
2874
+ this.maxSize = maxSize;
2875
+ this.evictionStrategy = evictionStrategy;
2876
+ }
2877
+ get(key) {
2878
+ const entry = this.cache.get(key);
2879
+ if (!entry) return void 0;
2880
+ entry.hits++;
2881
+ entry.lastAccessed = Date.now();
2882
+ return entry.value;
2883
+ }
2884
+ set(key, value) {
2885
+ if (this.cache.size >= this.maxSize && !this.cache.has(key)) {
2886
+ this.evict();
2887
+ }
2888
+ this.cache.set(key, {
2889
+ value,
2890
+ timestamp: Date.now(),
2891
+ hits: 0,
2892
+ lastAccessed: Date.now()
2893
+ });
2894
+ }
2895
+ has(key) {
2896
+ return this.cache.has(key);
2897
+ }
2898
+ delete(key) {
2899
+ return this.cache.delete(key);
2900
+ }
2901
+ clear() {
2902
+ this.cache.clear();
2903
+ }
2904
+ size() {
2905
+ return this.cache.size;
2906
+ }
2907
+ evict() {
2908
+ if (this.cache.size === 0) return;
2909
+ let keyToEvict;
2910
+ if (this.evictionStrategy === "lru") {
2911
+ let oldestAccess = Infinity;
2912
+ for (const [key, entry] of this.cache.entries()) {
2913
+ if (entry.lastAccessed < oldestAccess) {
2914
+ oldestAccess = entry.lastAccessed;
2915
+ keyToEvict = key;
2916
+ }
2917
+ }
2918
+ } else if (this.evictionStrategy === "lfu") {
2919
+ let lowestHits = Infinity;
2920
+ for (const [key, entry] of this.cache.entries()) {
2921
+ if (entry.hits < lowestHits) {
2922
+ lowestHits = entry.hits;
2923
+ keyToEvict = key;
2924
+ }
2925
+ }
2926
+ } else {
2927
+ keyToEvict = this.cache.keys().next().value;
2928
+ }
2929
+ if (keyToEvict) {
2930
+ this.cache.delete(keyToEvict);
2931
+ }
2932
+ }
2933
+ };
2934
+ function defaultKeyGenerator(state) {
2935
+ try {
2936
+ return JSON.stringify(state);
2937
+ } catch {
2938
+ return String(state);
2939
+ }
2940
+ }
2941
+ function withCache(node, options = {}) {
2942
+ const {
2943
+ ttl = 36e5,
2944
+ // 1 hour default
2945
+ maxSize = 100,
2946
+ evictionStrategy = "lru",
2947
+ keyGenerator = defaultKeyGenerator,
2948
+ cacheErrors = false,
2949
+ onCacheHit,
2950
+ onCacheMiss,
2951
+ onEviction
2952
+ } = options;
2953
+ const cache2 = new LRUCache(maxSize, evictionStrategy);
2954
+ return async (state) => {
2955
+ const cacheKey = keyGenerator(state);
2956
+ const cachedValue = cache2.get(cacheKey);
2957
+ if (cachedValue !== void 0) {
2958
+ const entry = cache2.cache.get(cacheKey);
2959
+ const age = Date.now() - entry.timestamp;
2960
+ if (age < ttl) {
2961
+ if (onCacheHit) {
2962
+ onCacheHit(cacheKey, cachedValue);
2963
+ }
2964
+ return cachedValue;
2965
+ } else {
2966
+ cache2.delete(cacheKey);
2967
+ if (onEviction) {
2968
+ onEviction(cacheKey, cachedValue);
2969
+ }
2970
+ }
2971
+ }
2972
+ if (onCacheMiss) {
2973
+ onCacheMiss(cacheKey);
2974
+ }
2975
+ try {
2976
+ const result = await Promise.resolve(node(state));
2977
+ cache2.set(cacheKey, result);
2978
+ return result;
2979
+ } catch (error) {
2980
+ if (cacheErrors && error instanceof Error) {
2981
+ const errorResult = { error: error.message };
2982
+ cache2.set(cacheKey, errorResult);
2983
+ }
2984
+ throw error;
2985
+ }
2986
+ };
2987
+ }
2988
+ function createSharedCache(options = {}) {
2989
+ const {
2990
+ ttl = 36e5,
2991
+ maxSize = 100,
2992
+ evictionStrategy = "lru",
2993
+ cacheErrors = false,
2994
+ onCacheHit,
2995
+ onCacheMiss,
2996
+ onEviction
2997
+ } = options;
2998
+ const cache2 = new LRUCache(maxSize, evictionStrategy);
2999
+ return {
3000
+ withCache: (node, keyGenerator = defaultKeyGenerator) => {
3001
+ return async (state) => {
3002
+ const cacheKey = keyGenerator(state);
3003
+ const cachedValue = cache2.get(cacheKey);
3004
+ if (cachedValue !== void 0) {
3005
+ const entry = cache2.cache.get(cacheKey);
3006
+ const age = Date.now() - entry.timestamp;
3007
+ if (age < ttl) {
3008
+ if (onCacheHit) {
3009
+ onCacheHit(cacheKey, cachedValue);
3010
+ }
3011
+ return cachedValue;
3012
+ } else {
3013
+ cache2.delete(cacheKey);
3014
+ if (onEviction) {
3015
+ onEviction(cacheKey, cachedValue);
3016
+ }
3017
+ }
3018
+ }
3019
+ if (onCacheMiss) {
3020
+ onCacheMiss(cacheKey);
3021
+ }
3022
+ try {
3023
+ const result = await Promise.resolve(node(state));
3024
+ cache2.set(cacheKey, result);
3025
+ return result;
3026
+ } catch (error) {
3027
+ if (cacheErrors && error instanceof Error) {
3028
+ const errorResult = { error: error.message };
3029
+ cache2.set(cacheKey, errorResult);
3030
+ }
3031
+ throw error;
3032
+ }
3033
+ };
3034
+ },
3035
+ clear: () => cache2.clear(),
3036
+ size: () => cache2.size()
3037
+ };
3038
+ }
3039
+
3040
+ // src/langgraph/middleware/rate-limiting.ts
3041
+ var TokenBucket = class {
3042
+ constructor(maxTokens, refillRate) {
3043
+ this.maxTokens = maxTokens;
3044
+ this.refillRate = refillRate;
3045
+ this.tokens = maxTokens;
3046
+ this.lastRefill = Date.now();
3047
+ }
3048
+ tokens;
3049
+ lastRefill;
3050
+ tryConsume() {
3051
+ this.refill();
3052
+ if (this.tokens >= 1) {
3053
+ this.tokens -= 1;
3054
+ return true;
3055
+ }
3056
+ return false;
3057
+ }
3058
+ refill() {
3059
+ const now = Date.now();
3060
+ const timePassed = now - this.lastRefill;
3061
+ const tokensToAdd = timePassed * this.refillRate;
3062
+ this.tokens = Math.min(this.maxTokens, this.tokens + tokensToAdd);
3063
+ this.lastRefill = now;
3064
+ }
3065
+ reset() {
3066
+ this.tokens = this.maxTokens;
3067
+ this.lastRefill = Date.now();
3068
+ }
3069
+ };
3070
+ var SlidingWindow = class {
3071
+ constructor(maxRequests, windowMs) {
3072
+ this.maxRequests = maxRequests;
3073
+ this.windowMs = windowMs;
3074
+ }
3075
+ requests = [];
3076
+ tryConsume() {
3077
+ const now = Date.now();
3078
+ this.requests = this.requests.filter((timestamp) => now - timestamp < this.windowMs);
3079
+ if (this.requests.length < this.maxRequests) {
3080
+ this.requests.push(now);
3081
+ return true;
3082
+ }
3083
+ return false;
3084
+ }
3085
+ reset() {
3086
+ this.requests = [];
3087
+ }
3088
+ };
3089
+ var FixedWindow = class {
3090
+ constructor(maxRequests, windowMs) {
3091
+ this.maxRequests = maxRequests;
3092
+ this.windowMs = windowMs;
3093
+ this.windowStart = Date.now();
3094
+ }
3095
+ count = 0;
3096
+ windowStart;
3097
+ tryConsume() {
3098
+ const now = Date.now();
3099
+ if (now - this.windowStart >= this.windowMs) {
3100
+ this.count = 0;
3101
+ this.windowStart = now;
3102
+ }
3103
+ if (this.count < this.maxRequests) {
3104
+ this.count++;
3105
+ return true;
3106
+ }
3107
+ return false;
3108
+ }
3109
+ reset() {
3110
+ this.count = 0;
3111
+ this.windowStart = Date.now();
3112
+ }
3113
+ };
3114
+ function withRateLimit(node, options) {
3115
+ const {
3116
+ maxRequests,
3117
+ windowMs,
3118
+ strategy = "token-bucket",
3119
+ onRateLimitExceeded,
3120
+ onRateLimitReset,
3121
+ keyGenerator = () => "global"
3122
+ } = options;
3123
+ const limiters = /* @__PURE__ */ new Map();
3124
+ return async (state) => {
3125
+ const key = keyGenerator(state);
3126
+ if (!limiters.has(key)) {
3127
+ let limiter2;
3128
+ switch (strategy) {
3129
+ case "token-bucket":
3130
+ limiter2 = new TokenBucket(maxRequests, maxRequests / windowMs);
3131
+ break;
3132
+ case "sliding-window":
3133
+ limiter2 = new SlidingWindow(maxRequests, windowMs);
3134
+ break;
3135
+ case "fixed-window":
3136
+ limiter2 = new FixedWindow(maxRequests, windowMs);
3137
+ break;
3138
+ default:
3139
+ throw new Error(`Unknown rate limit strategy: ${strategy}`);
3140
+ }
3141
+ limiters.set(key, limiter2);
3142
+ }
3143
+ const limiter = limiters.get(key);
3144
+ if (!limiter.tryConsume()) {
3145
+ if (onRateLimitExceeded) {
3146
+ onRateLimitExceeded(key);
3147
+ }
3148
+ throw new Error(`Rate limit exceeded for key: ${key}`);
3149
+ }
3150
+ return await Promise.resolve(node(state));
3151
+ };
3152
+ }
3153
+ function createSharedRateLimiter(options) {
3154
+ const {
3155
+ maxRequests,
3156
+ windowMs,
3157
+ strategy = "token-bucket",
3158
+ onRateLimitExceeded,
3159
+ onRateLimitReset
3160
+ } = options;
3161
+ const limiters = /* @__PURE__ */ new Map();
3162
+ return {
3163
+ withRateLimit: (node, keyGenerator = (state) => "global") => {
3164
+ return async (state) => {
3165
+ const key = keyGenerator(state);
3166
+ if (!limiters.has(key)) {
3167
+ let limiter2;
3168
+ switch (strategy) {
3169
+ case "token-bucket":
3170
+ limiter2 = new TokenBucket(maxRequests, maxRequests / windowMs);
3171
+ break;
3172
+ case "sliding-window":
3173
+ limiter2 = new SlidingWindow(maxRequests, windowMs);
3174
+ break;
3175
+ case "fixed-window":
3176
+ limiter2 = new FixedWindow(maxRequests, windowMs);
3177
+ break;
3178
+ default:
3179
+ throw new Error(`Unknown rate limit strategy: ${strategy}`);
3180
+ }
3181
+ limiters.set(key, limiter2);
3182
+ }
3183
+ const limiter = limiters.get(key);
3184
+ if (!limiter.tryConsume()) {
3185
+ if (onRateLimitExceeded) {
3186
+ onRateLimitExceeded(key);
3187
+ }
3188
+ throw new Error(`Rate limit exceeded for key: ${key}`);
3189
+ }
3190
+ return await Promise.resolve(node(state));
3191
+ };
3192
+ },
3193
+ reset: (key) => {
3194
+ if (key) {
3195
+ const limiter = limiters.get(key);
3196
+ if (limiter) {
3197
+ limiter.reset();
3198
+ if (onRateLimitReset) {
3199
+ onRateLimitReset(key);
3200
+ }
3201
+ }
3202
+ } else {
3203
+ limiters.forEach((limiter, k) => {
3204
+ limiter.reset();
3205
+ if (onRateLimitReset) {
3206
+ onRateLimitReset(k);
3207
+ }
3208
+ });
3209
+ }
3210
+ }
3211
+ };
3212
+ }
3213
+
3214
+ // src/langgraph/middleware/validation.ts
3215
+ function withValidation(node, options) {
3216
+ const {
3217
+ inputSchema,
3218
+ outputSchema,
3219
+ inputValidator,
3220
+ outputValidator,
3221
+ mode = "both",
3222
+ throwOnError = true,
3223
+ onValidationError,
3224
+ onValidationSuccess,
3225
+ stripUnknown = false
3226
+ } = options;
3227
+ return async (state) => {
3228
+ if (mode === "input" || mode === "both") {
3229
+ try {
3230
+ if (inputSchema) {
3231
+ const validated = inputSchema.parse(state);
3232
+ state = validated;
3233
+ }
3234
+ if (inputValidator) {
3235
+ const isValid = await Promise.resolve(inputValidator(state));
3236
+ if (!isValid) {
3237
+ throw new Error("Input validation failed: custom validator returned false");
3238
+ }
3239
+ }
3240
+ if (onValidationSuccess) {
3241
+ onValidationSuccess(state, "input");
3242
+ }
3243
+ } catch (error) {
3244
+ if (onValidationError) {
3245
+ return onValidationError(error, state, "input");
3246
+ }
3247
+ if (throwOnError) {
3248
+ throw error;
3249
+ }
3250
+ return state;
3251
+ }
3252
+ }
3253
+ const result = await Promise.resolve(node(state));
3254
+ if (mode === "output" || mode === "both") {
3255
+ try {
3256
+ if (outputSchema) {
3257
+ const validated = outputSchema.parse(result);
3258
+ if (onValidationSuccess) {
3259
+ onValidationSuccess(validated, "output");
3260
+ }
3261
+ return validated;
3262
+ }
3263
+ if (outputValidator) {
3264
+ const isValid = await Promise.resolve(outputValidator(result));
3265
+ if (!isValid) {
3266
+ throw new Error("Output validation failed: custom validator returned false");
3267
+ }
3268
+ }
3269
+ if (onValidationSuccess) {
3270
+ onValidationSuccess(result, "output");
3271
+ }
3272
+ } catch (error) {
3273
+ if (onValidationError) {
3274
+ return onValidationError(error, state, "output");
3275
+ }
3276
+ if (throwOnError) {
3277
+ throw error;
3278
+ }
3279
+ }
3280
+ }
3281
+ return result;
3282
+ };
3283
+ }
3284
+
3285
+ // src/langgraph/middleware/concurrency.ts
3286
+ var ConcurrencyController = class {
3287
+ constructor(maxConcurrent, maxQueueSize, onQueued, onExecutionStart, onExecutionComplete, onQueueFull, queueTimeout) {
3288
+ this.maxConcurrent = maxConcurrent;
3289
+ this.maxQueueSize = maxQueueSize;
3290
+ this.onQueued = onQueued;
3291
+ this.onExecutionStart = onExecutionStart;
3292
+ this.onExecutionComplete = onExecutionComplete;
3293
+ this.onQueueFull = onQueueFull;
3294
+ this.queueTimeout = queueTimeout;
3295
+ }
3296
+ activeCount = 0;
3297
+ queue = [];
3298
+ async execute(state, priority, executor) {
3299
+ if (this.activeCount < this.maxConcurrent) {
3300
+ return this.executeTask(state, executor);
3301
+ }
3302
+ if (this.maxQueueSize > 0 && this.queue.length >= this.maxQueueSize) {
3303
+ if (this.onQueueFull) {
3304
+ this.onQueueFull(state);
3305
+ }
3306
+ throw new Error(`Queue is full (max size: ${this.maxQueueSize})`);
3307
+ }
3308
+ return new Promise((resolve, reject) => {
3309
+ const task = {
3310
+ state,
3311
+ priority,
3312
+ executor,
3313
+ resolve,
3314
+ reject,
3315
+ timestamp: Date.now()
3316
+ };
3317
+ this.insertByPriority(task);
3318
+ if (this.onQueued) {
3319
+ this.onQueued(this.queue.length, state);
3320
+ }
3321
+ if (this.queueTimeout && this.queueTimeout > 0) {
3322
+ setTimeout(() => {
3323
+ const index = this.queue.indexOf(task);
3324
+ if (index !== -1) {
3325
+ this.queue.splice(index, 1);
3326
+ reject(new Error(`Task timed out after ${this.queueTimeout}ms in queue`));
3327
+ }
3328
+ }, this.queueTimeout);
3329
+ }
3330
+ });
3331
+ }
3332
+ insertByPriority(task) {
3333
+ const priorityOrder = { high: 0, normal: 1, low: 2 };
3334
+ const taskPriorityValue = priorityOrder[task.priority];
3335
+ let insertIndex = this.queue.length;
3336
+ for (let i = 0; i < this.queue.length; i++) {
3337
+ const queuedPriorityValue = priorityOrder[this.queue[i].priority];
3338
+ if (taskPriorityValue < queuedPriorityValue) {
3339
+ insertIndex = i;
3340
+ break;
3341
+ }
3342
+ }
3343
+ this.queue.splice(insertIndex, 0, task);
3344
+ }
3345
+ async executeTask(state, executor) {
3346
+ this.activeCount++;
3347
+ if (this.onExecutionStart) {
3348
+ this.onExecutionStart(this.activeCount, state);
3349
+ }
3350
+ try {
3351
+ const result = await executor(state);
3352
+ if (this.onExecutionComplete) {
3353
+ this.onExecutionComplete(this.activeCount - 1, state);
3354
+ }
3355
+ return result;
3356
+ } finally {
3357
+ this.activeCount--;
3358
+ this.processQueue();
3359
+ }
3360
+ }
3361
+ processQueue() {
3362
+ if (this.queue.length === 0 || this.activeCount >= this.maxConcurrent) {
3363
+ return;
3364
+ }
3365
+ const task = this.queue.shift();
3366
+ if (task) {
3367
+ this.executeTask(task.state, task.executor).then(task.resolve).catch(task.reject);
3368
+ }
3369
+ }
3370
+ getStats() {
3371
+ return {
3372
+ activeCount: this.activeCount,
3373
+ queueSize: this.queue.length
3374
+ };
3375
+ }
3376
+ clear() {
3377
+ this.queue.forEach((task) => {
3378
+ task.reject(new Error("Queue cleared"));
3379
+ });
3380
+ this.queue = [];
3381
+ }
3382
+ };
3383
+ function withConcurrency(node, options = {}) {
3384
+ const {
3385
+ maxConcurrent = 1,
3386
+ maxQueueSize = 0,
3387
+ priorityFn = () => "normal",
3388
+ onQueued,
3389
+ onExecutionStart,
3390
+ onExecutionComplete,
3391
+ onQueueFull,
3392
+ queueTimeout = 0
3393
+ } = options;
3394
+ const controller = new ConcurrencyController(
3395
+ maxConcurrent,
3396
+ maxQueueSize,
3397
+ onQueued,
3398
+ onExecutionStart,
3399
+ onExecutionComplete,
3400
+ onQueueFull,
3401
+ queueTimeout
3402
+ );
3403
+ return async (state) => {
3404
+ const priority = priorityFn(state);
3405
+ return controller.execute(state, priority, async (s) => await node(s));
3406
+ };
3407
+ }
3408
+ function createSharedConcurrencyController(options = {}) {
3409
+ const {
3410
+ maxConcurrent = 1,
3411
+ maxQueueSize = 0,
3412
+ priorityFn = () => "normal",
3413
+ onQueued,
3414
+ onExecutionStart,
3415
+ onExecutionComplete,
3416
+ onQueueFull,
3417
+ queueTimeout = 0
3418
+ } = options;
3419
+ const controller = new ConcurrencyController(
3420
+ maxConcurrent,
3421
+ maxQueueSize,
3422
+ onQueued,
3423
+ onExecutionStart,
3424
+ onExecutionComplete,
3425
+ onQueueFull,
3426
+ queueTimeout
3427
+ );
3428
+ return {
3429
+ withConcurrency: (node) => {
3430
+ return async (state) => {
3431
+ const priority = priorityFn(state);
3432
+ return controller.execute(state, priority, async (s) => await node(s));
3433
+ };
3434
+ },
3435
+ getStats: () => controller.getStats(),
3436
+ clear: () => controller.clear()
3437
+ };
3438
+ }
3439
+
2857
3440
  // src/langgraph/persistence/checkpointer.ts
2858
3441
  var import_langgraph5 = require("@langchain/langgraph");
2859
3442
  function createMemoryCheckpointer(options) {
@@ -4350,6 +4933,68 @@ var CircuitBreaker = class {
4350
4933
  function createCircuitBreaker(options) {
4351
4934
  return new CircuitBreaker(options);
4352
4935
  }
4936
+
4937
+ // src/prompt-loader/index.ts
4938
+ var import_fs = require("fs");
4939
+ var import_path = require("path");
4940
+ var MAX_VARIABLE_LENGTH = 500;
4941
+ function sanitizeValue(value) {
4942
+ if (value === void 0 || value === null) return "";
4943
+ let sanitized = String(value);
4944
+ sanitized = sanitized.replace(/^#+\s*/gm, "");
4945
+ sanitized = sanitized.replace(/[\r\n]+/g, " ");
4946
+ sanitized = sanitized.trim().replace(/\s+/g, " ");
4947
+ if (sanitized.length > MAX_VARIABLE_LENGTH) {
4948
+ sanitized = sanitized.substring(0, MAX_VARIABLE_LENGTH) + "...";
4949
+ }
4950
+ return sanitized;
4951
+ }
4952
+ function renderTemplate(template, options) {
4953
+ let rawVariables;
4954
+ let sanitizedVariables;
4955
+ if ("trustedVariables" in options || "untrustedVariables" in options) {
4956
+ const opts = options;
4957
+ rawVariables = {
4958
+ ...opts.trustedVariables,
4959
+ ...opts.untrustedVariables
4960
+ };
4961
+ const sanitizedUntrusted = {};
4962
+ if (opts.untrustedVariables) {
4963
+ for (const [key, value] of Object.entries(opts.untrustedVariables)) {
4964
+ sanitizedUntrusted[key] = sanitizeValue(value);
4965
+ }
4966
+ }
4967
+ sanitizedVariables = {
4968
+ ...opts.trustedVariables,
4969
+ ...sanitizedUntrusted
4970
+ };
4971
+ } else {
4972
+ rawVariables = options;
4973
+ sanitizedVariables = options;
4974
+ }
4975
+ let result = template;
4976
+ result = result.replace(/\{\{#if\s+(\w+)\}\}([\s\S]*?)\{\{\/if\}\}/g, (_, varName, content) => {
4977
+ return rawVariables[varName] ? content : "";
4978
+ });
4979
+ result = result.replace(/\{\{(\w+)\}\}/g, (_, varName) => {
4980
+ const value = sanitizedVariables[varName];
4981
+ if (value === void 0 || value === null) return "";
4982
+ return String(value);
4983
+ });
4984
+ return result;
4985
+ }
4986
+ function loadPrompt(promptName, options = {}, promptsDir) {
4987
+ const baseDir = promptsDir || (0, import_path.join)(process.cwd(), "prompts");
4988
+ const promptPath = (0, import_path.join)(baseDir, `${promptName}.md`);
4989
+ try {
4990
+ const template = (0, import_fs.readFileSync)(promptPath, "utf-8");
4991
+ return renderTemplate(template, options);
4992
+ } catch (error) {
4993
+ throw new Error(
4994
+ `Failed to load prompt "${promptName}" from ${promptPath}: ${error instanceof Error ? error.message : String(error)}`
4995
+ );
4996
+ }
4997
+ }
4353
4998
  // Annotate the CommonJS export names for ESM import in node:
4354
4999
  0 && (module.exports = {
4355
5000
  AgentError,
@@ -4413,6 +5058,9 @@ function createCircuitBreaker(options) {
4413
5058
  createProgressTracker,
4414
5059
  createSSEFormatter,
4415
5060
  createSequentialWorkflow,
5061
+ createSharedCache,
5062
+ createSharedConcurrencyController,
5063
+ createSharedRateLimiter,
4416
5064
  createSqliteCheckpointer,
4417
5065
  createStateAnnotation,
4418
5066
  createSubgraph,
@@ -4443,6 +5091,7 @@ function createCircuitBreaker(options) {
4443
5091
  isHumanRequestInterrupt,
4444
5092
  isMemoryCheckpointer,
4445
5093
  isTracingEnabled,
5094
+ loadPrompt,
4446
5095
  map,
4447
5096
  merge,
4448
5097
  mergeState,
@@ -4451,8 +5100,10 @@ function createCircuitBreaker(options) {
4451
5100
  presets,
4452
5101
  production,
4453
5102
  reduce,
5103
+ renderTemplate,
4454
5104
  retry,
4455
5105
  safeValidateSchemaDescriptions,
5106
+ sanitizeValue,
4456
5107
  sendMessage,
4457
5108
  sequential,
4458
5109
  sequentialBuilder,
@@ -4468,9 +5119,14 @@ function createCircuitBreaker(options) {
4468
5119
  validateTool,
4469
5120
  validateToolMetadata,
4470
5121
  validateToolName,
5122
+ withCache,
5123
+ withConcurrency,
4471
5124
  withErrorHandler,
5125
+ withLogging,
4472
5126
  withMetrics,
5127
+ withRateLimit,
4473
5128
  withRetry,
4474
5129
  withTimeout,
4475
- withTracing
5130
+ withTracing,
5131
+ withValidation
4476
5132
  });