@silmaril-security/sdk 0.7.10 → 0.8.1
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/CHANGELOG.md +23 -0
- package/README.md +60 -11
- package/dist/adapters/deepagents.cjs +37 -8
- package/dist/adapters/deepagents.cjs.map +1 -1
- package/dist/adapters/deepagents.d.cts +1 -3
- package/dist/adapters/deepagents.d.ts +1 -3
- package/dist/adapters/deepagents.js +37 -8
- package/dist/adapters/deepagents.js.map +1 -1
- package/dist/adapters/langchain.cjs +409 -68
- package/dist/adapters/langchain.cjs.map +1 -1
- package/dist/adapters/langchain.d.cts +5 -2
- package/dist/adapters/langchain.d.ts +5 -2
- package/dist/adapters/langchain.js +407 -67
- package/dist/adapters/langchain.js.map +1 -1
- package/dist/adapters/vercel.d.cts +1 -1
- package/dist/adapters/vercel.d.ts +1 -1
- package/dist/{firewall-DqjD6aXD.d.cts → firewall-Bv5y03P0.d.cts} +0 -2
- package/dist/{firewall-DqjD6aXD.d.ts → firewall-Bv5y03P0.d.ts} +0 -2
- package/dist/index.cjs +417 -70
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +417 -70
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
|
@@ -148,7 +148,81 @@ function extractTextFromDocuments(documents) {
|
|
|
148
148
|
return parts.join("\n");
|
|
149
149
|
}
|
|
150
150
|
|
|
151
|
+
// src/adapters/thread-identity.ts
|
|
152
|
+
function record(value) {
|
|
153
|
+
return value !== null && typeof value === "object" && !Array.isArray(value) ? value : void 0;
|
|
154
|
+
}
|
|
155
|
+
function validThreadId(value) {
|
|
156
|
+
return typeof value === "string" && value.trim().length > 0 ? value : void 0;
|
|
157
|
+
}
|
|
158
|
+
function nativeThreadId(runtime, metadata, inherited, currentConfig) {
|
|
159
|
+
const explicit = record(record(runtime)?.configurable);
|
|
160
|
+
const current = record(record(currentConfig)?.configurable);
|
|
161
|
+
for (const candidate of [explicit, current, record(metadata)]) {
|
|
162
|
+
if (candidate && Object.prototype.hasOwnProperty.call(candidate, "thread_id")) {
|
|
163
|
+
return validThreadId(candidate.thread_id);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
return inherited;
|
|
167
|
+
}
|
|
168
|
+
function rejectConversationOptions(options) {
|
|
169
|
+
if ("conversationId" in options || "conversation_id" in options) {
|
|
170
|
+
throw new TypeError("conversationId/conversation_id was removed. Pass the native configurable.thread_id when invoking the agent or runnable instead.");
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
var RunThreadIdentity = class {
|
|
174
|
+
constructor(boundIdentity, currentConfig = () => void 0) {
|
|
175
|
+
this.boundIdentity = boundIdentity;
|
|
176
|
+
this.currentConfig = currentConfig;
|
|
177
|
+
}
|
|
178
|
+
boundIdentity;
|
|
179
|
+
currentConfig;
|
|
180
|
+
runs = /* @__PURE__ */ new Map();
|
|
181
|
+
children = /* @__PURE__ */ new Map();
|
|
182
|
+
start(runId, parentRunId, metadata) {
|
|
183
|
+
const discarded = this.finish(runId);
|
|
184
|
+
if (this.runs.size >= 4096) {
|
|
185
|
+
const oldestRoot = [...this.runs].find(([, run]) => run.parentRunId === void 0 || !this.runs.has(run.parentRunId))?.[0] ?? this.runs.keys().next().value;
|
|
186
|
+
if (oldestRoot !== void 0) discarded.push(...this.finish(oldestRoot));
|
|
187
|
+
}
|
|
188
|
+
const inherited = parentRunId === void 0 ? void 0 : this.runs.get(parentRunId)?.threadId;
|
|
189
|
+
const exposed = record(metadata);
|
|
190
|
+
const threadId = this.boundIdentity && (parentRunId === void 0 || !this.runs.has(parentRunId)) ? this.boundIdentity.threadId : exposed && Object.prototype.hasOwnProperty.call(exposed, "thread_id") ? typeof exposed.langgraph_node === "string" ? nativeThreadId(void 0, exposed, inherited, this.currentConfig()) : validThreadId(exposed.thread_id) : inherited;
|
|
191
|
+
this.runs.set(runId, { threadId, parentRunId });
|
|
192
|
+
if (parentRunId !== void 0 && parentRunId !== runId) {
|
|
193
|
+
const children = this.children.get(parentRunId) ?? /* @__PURE__ */ new Set();
|
|
194
|
+
children.add(runId);
|
|
195
|
+
this.children.set(parentRunId, children);
|
|
196
|
+
}
|
|
197
|
+
return discarded;
|
|
198
|
+
}
|
|
199
|
+
get(runId) {
|
|
200
|
+
const run = this.runs.get(runId);
|
|
201
|
+
return run ? run.threadId : this.boundIdentity?.threadId;
|
|
202
|
+
}
|
|
203
|
+
finish(runId) {
|
|
204
|
+
const pending = [runId];
|
|
205
|
+
const seen = /* @__PURE__ */ new Set();
|
|
206
|
+
while (pending.length) {
|
|
207
|
+
const id = pending.pop();
|
|
208
|
+
if (seen.has(id)) continue;
|
|
209
|
+
seen.add(id);
|
|
210
|
+
pending.push(...this.children.get(id) ?? []);
|
|
211
|
+
this.children.delete(id);
|
|
212
|
+
const parent = this.runs.get(id)?.parentRunId;
|
|
213
|
+
this.runs.delete(id);
|
|
214
|
+
if (parent !== void 0) {
|
|
215
|
+
const siblings = this.children.get(parent);
|
|
216
|
+
siblings?.delete(id);
|
|
217
|
+
if (siblings?.size === 0) this.children.delete(parent);
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
return [...seen];
|
|
221
|
+
}
|
|
222
|
+
};
|
|
223
|
+
|
|
151
224
|
// src/adapters/langchain.ts
|
|
225
|
+
var handlerCleanups = /* @__PURE__ */ new WeakMap();
|
|
152
226
|
var USER_ROLES = /* @__PURE__ */ new Set(["human", "user"]);
|
|
153
227
|
function getMessageRole(message) {
|
|
154
228
|
if (typeof message.role === "string") {
|
|
@@ -157,7 +231,8 @@ function getMessageRole(message) {
|
|
|
157
231
|
if (typeof message.type === "string") {
|
|
158
232
|
return message.type.toLowerCase();
|
|
159
233
|
}
|
|
160
|
-
|
|
234
|
+
const legacyType = message.getType?.() ?? message._getType?.();
|
|
235
|
+
return typeof legacyType === "string" ? legacyType.toLowerCase() : "";
|
|
161
236
|
}
|
|
162
237
|
function extractMessageText(content) {
|
|
163
238
|
if (content === void 0) {
|
|
@@ -186,7 +261,16 @@ function findLastUserMessage(messages) {
|
|
|
186
261
|
return void 0;
|
|
187
262
|
}
|
|
188
263
|
async function createLangChainHandler(firewall, options = {}) {
|
|
189
|
-
|
|
264
|
+
return buildLangChainHandler(firewall, options);
|
|
265
|
+
}
|
|
266
|
+
async function buildLangChainHandler(firewall, options, boundIdentity) {
|
|
267
|
+
rejectConversationOptions(options);
|
|
268
|
+
const { ensureConfig } = await import("@langchain/core/runnables");
|
|
269
|
+
const threads = new RunThreadIdentity(boundIdentity, () => ensureConfig());
|
|
270
|
+
const { BaseTracer } = await import("@langchain/core/tracers/base");
|
|
271
|
+
let finishRun = (runId) => {
|
|
272
|
+
threads.finish(runId);
|
|
273
|
+
};
|
|
190
274
|
const enabledHooks = resolveHooks(options.hooks);
|
|
191
275
|
const includeTool = options.includeTool ?? true;
|
|
192
276
|
const failOpen = options.failOpen ?? true;
|
|
@@ -205,14 +289,14 @@ async function createLangChainHandler(firewall, options = {}) {
|
|
|
205
289
|
logger("onClassify callback threw", err);
|
|
206
290
|
}
|
|
207
291
|
};
|
|
208
|
-
const
|
|
292
|
+
const classifyEvent = async (text, hookLabel, runId, toolName) => {
|
|
209
293
|
let result;
|
|
210
294
|
try {
|
|
211
295
|
result = await firewall.classify(text, {
|
|
212
296
|
hook: hookLabel,
|
|
213
297
|
metadata: {
|
|
214
298
|
langgraph: { run_id: runId },
|
|
215
|
-
...
|
|
299
|
+
...threads.get(runId) === void 0 ? {} : { conversationId: threads.get(runId) }
|
|
216
300
|
},
|
|
217
301
|
...requestedMode !== void 0 ? { mode: requestedMode } : {},
|
|
218
302
|
...toolName !== void 0 ? { toolName } : {}
|
|
@@ -256,97 +340,353 @@ async function createLangChainHandler(firewall, options = {}) {
|
|
|
256
340
|
result
|
|
257
341
|
});
|
|
258
342
|
};
|
|
259
|
-
|
|
343
|
+
const classify = async (text, hook, runId, toolName) => {
|
|
344
|
+
try {
|
|
345
|
+
await classifyEvent(text, hook, runId, toolName);
|
|
346
|
+
} catch (error) {
|
|
347
|
+
finishRun(runId);
|
|
348
|
+
throw error;
|
|
349
|
+
}
|
|
350
|
+
};
|
|
351
|
+
function serialized(value, name) {
|
|
352
|
+
if (value && typeof value === "object" && "id" in value && Array.isArray(value.id)) return value;
|
|
353
|
+
return { lc: 1, type: "not_implemented", id: [name] };
|
|
354
|
+
}
|
|
355
|
+
class SilmarilFirewallHandler extends BaseTracer {
|
|
260
356
|
name = "silmaril_firewall_handler";
|
|
261
357
|
raiseError = true;
|
|
262
358
|
awaitHandlers = true;
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
359
|
+
// LangChain clears runnable context inside ordinary callbacks. Its synchronous
|
|
360
|
+
// tracer pre-start hooks capture native config before that boundary. Runs are
|
|
361
|
+
// memory-only and every terminal path discards both native tracer maps.
|
|
362
|
+
async persistRun() {
|
|
363
|
+
}
|
|
364
|
+
getRunById(runId) {
|
|
365
|
+
return runId === void 0 ? void 0 : this.runMap.get(runId);
|
|
366
|
+
}
|
|
367
|
+
// Only lifecycle identity is needed. Do not retain prompts, outputs, token
|
|
368
|
+
// events, or completed children when upstream omits a cancellation callback.
|
|
369
|
+
_addRunToRunMap(run) {
|
|
370
|
+
return super._addRunToRunMap({
|
|
371
|
+
...run,
|
|
372
|
+
inputs: {},
|
|
373
|
+
extra: {},
|
|
374
|
+
serialized: {},
|
|
375
|
+
tags: [],
|
|
376
|
+
child_runs: [],
|
|
377
|
+
events: []
|
|
378
|
+
});
|
|
379
|
+
}
|
|
380
|
+
_addChildRun() {
|
|
381
|
+
}
|
|
382
|
+
async _endTrace(run) {
|
|
383
|
+
try {
|
|
384
|
+
await super._endTrace(run);
|
|
385
|
+
} finally {
|
|
386
|
+
run.inputs = {};
|
|
387
|
+
delete run.outputs;
|
|
388
|
+
delete run.error;
|
|
389
|
+
run.extra = {};
|
|
390
|
+
run.events = [];
|
|
391
|
+
run.child_runs = [];
|
|
266
392
|
}
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
393
|
+
}
|
|
394
|
+
async handleText() {
|
|
395
|
+
}
|
|
396
|
+
async handleAgentAction() {
|
|
397
|
+
}
|
|
398
|
+
async handleAgentEnd() {
|
|
399
|
+
}
|
|
400
|
+
async handleLLMNewToken(_token, _idx, runId) {
|
|
401
|
+
return this.getRunById(runId) ?? this._createRunForLLMStart(serialized(void 0, "llm"), [], runId);
|
|
402
|
+
}
|
|
403
|
+
capture(runId, parentRunId, metadata) {
|
|
404
|
+
for (const id of threads.start(runId, parentRunId, metadata)) {
|
|
405
|
+
this.runMap.delete(id);
|
|
406
|
+
this.runTreeMap?.delete(id);
|
|
273
407
|
}
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
408
|
+
}
|
|
409
|
+
finishAll() {
|
|
410
|
+
for (const id of [...this.runMap.keys()]) this.finishRun(id);
|
|
411
|
+
this.runTreeMap?.clear();
|
|
412
|
+
}
|
|
413
|
+
finishRun(runId) {
|
|
414
|
+
for (const id of threads.finish(runId)) {
|
|
415
|
+
this.runMap.delete(id);
|
|
416
|
+
this.runTreeMap?.delete(id);
|
|
277
417
|
}
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
418
|
+
}
|
|
419
|
+
_createRunForLLMStart(...args) {
|
|
420
|
+
this.capture(args[2], args[3], args[6]);
|
|
421
|
+
return super._createRunForLLMStart(...args);
|
|
422
|
+
}
|
|
423
|
+
_createRunForChatModelStart(...args) {
|
|
424
|
+
this.capture(args[2], args[3], args[6]);
|
|
425
|
+
return super._createRunForChatModelStart(...args);
|
|
426
|
+
}
|
|
427
|
+
_createRunForChainStart(...args) {
|
|
428
|
+
this.capture(args[2], args[3], args[5]);
|
|
429
|
+
return super._createRunForChainStart(...args);
|
|
430
|
+
}
|
|
431
|
+
_createRunForToolStart(...args) {
|
|
432
|
+
this.capture(args[2], args[3], args[5]);
|
|
433
|
+
return super._createRunForToolStart(...args);
|
|
434
|
+
}
|
|
435
|
+
_createRunForRetrieverStart(...args) {
|
|
436
|
+
this.capture(args[2], args[3], args[5]);
|
|
437
|
+
return super._createRunForRetrieverStart(...args);
|
|
438
|
+
}
|
|
439
|
+
async handleChatModelStart(llm, messages, runId, parentRunId, extraParams, tags, metadata) {
|
|
440
|
+
const batches = messages;
|
|
441
|
+
const run = this.getRunById(runId) ?? this._createRunForChatModelStart(
|
|
442
|
+
serialized(llm, "chat_model"),
|
|
443
|
+
messages,
|
|
444
|
+
runId,
|
|
445
|
+
parentRunId,
|
|
446
|
+
extraParams,
|
|
447
|
+
tags,
|
|
448
|
+
metadata
|
|
449
|
+
);
|
|
450
|
+
if (enabledHooks.has(FirewallHook.CHAT_MODEL_START)) {
|
|
451
|
+
const lastUser = findLastUserMessage(batches.flat());
|
|
452
|
+
const text = lastUser ? extractMessageText(lastUser.content).trim() : "";
|
|
453
|
+
if (text) await classify(text, FIREWALL_HOOK_TO_LABEL[FirewallHook.CHAT_MODEL_START], runId);
|
|
281
454
|
}
|
|
282
|
-
|
|
455
|
+
return run;
|
|
283
456
|
}
|
|
284
|
-
async handleLLMStart(
|
|
285
|
-
|
|
286
|
-
|
|
457
|
+
async handleLLMStart(llm, prompts, runId, parentRunId, extraParams, tags, metadata) {
|
|
458
|
+
const run = this.getRunById(runId) ?? this._createRunForLLMStart(
|
|
459
|
+
serialized(llm, "llm"),
|
|
460
|
+
prompts,
|
|
461
|
+
runId,
|
|
462
|
+
parentRunId,
|
|
463
|
+
extraParams,
|
|
464
|
+
tags,
|
|
465
|
+
metadata
|
|
466
|
+
);
|
|
467
|
+
if (enabledHooks.has(FirewallHook.LLM_START)) {
|
|
468
|
+
const text = extractTextFromPrompts(prompts);
|
|
469
|
+
if (text) await classify(text, FIREWALL_HOOK_TO_LABEL[FirewallHook.LLM_START], runId);
|
|
287
470
|
}
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
471
|
+
return run;
|
|
472
|
+
}
|
|
473
|
+
async handleToolStart(tool, inputStr, runId, parentRunId, tags, metadata) {
|
|
474
|
+
const run = this.getRunById(runId) ?? this._createRunForToolStart(
|
|
475
|
+
serialized(tool, tool?.name ?? "tool"),
|
|
476
|
+
inputStr,
|
|
477
|
+
runId,
|
|
478
|
+
parentRunId,
|
|
479
|
+
tags,
|
|
480
|
+
metadata
|
|
481
|
+
);
|
|
482
|
+
if (includeTool && enabledHooks.has(FirewallHook.TOOL_START)) {
|
|
483
|
+
const text = extractTextFromToolInput(inputStr);
|
|
484
|
+
if (text) await classify(text, FIREWALL_HOOK_TO_LABEL[FirewallHook.TOOL_START], runId, tool?.name);
|
|
291
485
|
}
|
|
292
|
-
|
|
486
|
+
return run;
|
|
293
487
|
}
|
|
294
|
-
async
|
|
295
|
-
|
|
296
|
-
|
|
488
|
+
async handleRetrieverStart(retriever, query, runId, parentRunId, tags, metadata) {
|
|
489
|
+
const run = this.getRunById(runId) ?? this._createRunForRetrieverStart(
|
|
490
|
+
serialized(retriever, "retriever"),
|
|
491
|
+
query,
|
|
492
|
+
runId,
|
|
493
|
+
parentRunId,
|
|
494
|
+
tags,
|
|
495
|
+
metadata
|
|
496
|
+
);
|
|
497
|
+
if (enabledHooks.has(FirewallHook.RETRIEVER_START) && query.trim()) {
|
|
498
|
+
await classify(query.trim(), FIREWALL_HOOK_TO_LABEL[FirewallHook.RETRIEVER_START], runId);
|
|
297
499
|
}
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
500
|
+
return run;
|
|
501
|
+
}
|
|
502
|
+
async handleLLMEnd(output, runId) {
|
|
503
|
+
try {
|
|
504
|
+
if (!this.getRunById(runId)) this._createRunForLLMStart(serialized(void 0, "llm"), [], runId);
|
|
505
|
+
if (enabledHooks.has(FirewallHook.LLM_END)) {
|
|
506
|
+
const text = extractTextFromLLMResult(output);
|
|
507
|
+
if (text) await classify(text, FIREWALL_HOOK_TO_LABEL[FirewallHook.LLM_END], runId);
|
|
508
|
+
}
|
|
509
|
+
return await super.handleLLMEnd(output, runId);
|
|
510
|
+
} finally {
|
|
511
|
+
finishRun(runId);
|
|
301
512
|
}
|
|
302
|
-
const toolName = tool?.name;
|
|
303
|
-
await classify(text, FIREWALL_HOOK_TO_LABEL[FirewallHook.TOOL_START], runId, toolName);
|
|
304
513
|
}
|
|
305
|
-
async
|
|
306
|
-
|
|
307
|
-
|
|
514
|
+
async handleToolEnd(output, runId, _parentRunId, _tags, kwargs) {
|
|
515
|
+
try {
|
|
516
|
+
if (!this.getRunById(runId)) this._createRunForToolStart(serialized(void 0, "tool"), "", runId);
|
|
517
|
+
if (includeTool && enabledHooks.has(FirewallHook.TOOL_END)) {
|
|
518
|
+
const text = String(output).trim();
|
|
519
|
+
if (text) await classify(text, FIREWALL_HOOK_TO_LABEL[FirewallHook.TOOL_END], runId, kwargs?.name);
|
|
520
|
+
}
|
|
521
|
+
return await super.handleToolEnd(output, runId);
|
|
522
|
+
} finally {
|
|
523
|
+
finishRun(runId);
|
|
308
524
|
}
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
525
|
+
}
|
|
526
|
+
async handleRetrieverEnd(documents, runId) {
|
|
527
|
+
try {
|
|
528
|
+
if (!this.getRunById(runId)) this._createRunForRetrieverStart(serialized(void 0, "retriever"), "", runId);
|
|
529
|
+
if (enabledHooks.has(FirewallHook.RETRIEVER_END)) {
|
|
530
|
+
const text = extractTextFromDocuments(documents);
|
|
531
|
+
if (text) await classify(text, FIREWALL_HOOK_TO_LABEL[FirewallHook.RETRIEVER_END], runId);
|
|
532
|
+
}
|
|
533
|
+
return await super.handleRetrieverEnd(documents, runId);
|
|
534
|
+
} finally {
|
|
535
|
+
finishRun(runId);
|
|
312
536
|
}
|
|
313
|
-
await classify(text, FIREWALL_HOOK_TO_LABEL[FirewallHook.RETRIEVER_START], runId);
|
|
314
537
|
}
|
|
315
|
-
async
|
|
316
|
-
|
|
317
|
-
|
|
538
|
+
async handleChainStart(chain, inputs, runId, parentRunId, tags, metadata, runType, name) {
|
|
539
|
+
return super.handleChainStart(serialized(chain, "chain"), inputs, runId, parentRunId, tags, metadata, runType, name);
|
|
540
|
+
}
|
|
541
|
+
async handleChainEnd(...args) {
|
|
542
|
+
if (!this.getRunById(args[1])) this._createRunForChainStart(serialized(void 0, "chain"), {}, args[1]);
|
|
543
|
+
try {
|
|
544
|
+
return await super.handleChainEnd(...args);
|
|
545
|
+
} finally {
|
|
546
|
+
finishRun(args[1]);
|
|
318
547
|
}
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
548
|
+
}
|
|
549
|
+
async handleChainError(...args) {
|
|
550
|
+
if (!this.getRunById(args[1])) this._createRunForChainStart(serialized(void 0, "chain"), {}, args[1]);
|
|
551
|
+
try {
|
|
552
|
+
return await super.handleChainError(...args);
|
|
553
|
+
} finally {
|
|
554
|
+
finishRun(args[1]);
|
|
322
555
|
}
|
|
323
|
-
await classify(text, FIREWALL_HOOK_TO_LABEL[FirewallHook.LLM_END], runId);
|
|
324
556
|
}
|
|
325
|
-
async
|
|
326
|
-
if (!
|
|
327
|
-
|
|
557
|
+
async handleLLMError(...args) {
|
|
558
|
+
if (!this.getRunById(args[1])) this._createRunForLLMStart(serialized(void 0, "llm"), [], args[1]);
|
|
559
|
+
try {
|
|
560
|
+
return await super.handleLLMError(...args);
|
|
561
|
+
} finally {
|
|
562
|
+
finishRun(args[1]);
|
|
328
563
|
}
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
564
|
+
}
|
|
565
|
+
async handleToolError(...args) {
|
|
566
|
+
if (!this.getRunById(args[1])) this._createRunForToolStart(serialized(void 0, "tool"), "", args[1]);
|
|
567
|
+
try {
|
|
568
|
+
return await super.handleToolError(...args);
|
|
569
|
+
} finally {
|
|
570
|
+
finishRun(args[1]);
|
|
332
571
|
}
|
|
333
|
-
const toolName = _kwargs?.name;
|
|
334
|
-
await classify(text, FIREWALL_HOOK_TO_LABEL[FirewallHook.TOOL_END], runId, toolName);
|
|
335
572
|
}
|
|
336
|
-
async
|
|
337
|
-
if (!
|
|
338
|
-
|
|
573
|
+
async handleRetrieverError(...args) {
|
|
574
|
+
if (!this.getRunById(args[1])) this._createRunForRetrieverStart(serialized(void 0, "retriever"), "", args[1]);
|
|
575
|
+
try {
|
|
576
|
+
return await super.handleRetrieverError(...args);
|
|
577
|
+
} finally {
|
|
578
|
+
finishRun(args[1]);
|
|
339
579
|
}
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
580
|
+
}
|
|
581
|
+
}
|
|
582
|
+
const handler = new SilmarilFirewallHandler();
|
|
583
|
+
finishRun = (runId) => {
|
|
584
|
+
handler.finishRun(runId);
|
|
585
|
+
};
|
|
586
|
+
handlerCleanups.set(handler, () => handler.finishAll());
|
|
587
|
+
return handler;
|
|
588
|
+
}
|
|
589
|
+
async function protectLangChainRunnable(firewall, runnable, options = {}) {
|
|
590
|
+
rejectConversationOptions(options);
|
|
591
|
+
const { RunnableBinding, RunnableRetry, ensureConfig, mergeConfigs } = await import("@langchain/core/runnables");
|
|
592
|
+
const { IterableReadableStream } = await import("@langchain/core/utils/stream");
|
|
593
|
+
const configFactories = [async (config) => {
|
|
594
|
+
const effective = ensureConfig(config);
|
|
595
|
+
const handler = await buildLangChainHandler(firewall, options, {
|
|
596
|
+
threadId: validThreadId(effective.configurable?.thread_id)
|
|
597
|
+
});
|
|
598
|
+
return { callbacks: [handler] };
|
|
599
|
+
}];
|
|
600
|
+
class ProtectedBinding extends RunnableBinding {
|
|
601
|
+
async scopedConfig(...configs) {
|
|
602
|
+
const created = [];
|
|
603
|
+
const scopedFactories = configFactories.map((factory) => async (config2) => {
|
|
604
|
+
const update = await factory(config2);
|
|
605
|
+
if (Array.isArray(update.callbacks)) created.push(...update.callbacks);
|
|
606
|
+
return update;
|
|
607
|
+
});
|
|
608
|
+
const scoped = new RunnableBinding({ bound: this.bound, config: this.config, configFactories: scopedFactories });
|
|
609
|
+
const config = await scoped._mergeConfig(...configs);
|
|
610
|
+
return { config, dispose: () => {
|
|
611
|
+
for (const handler of created) handlerCleanups.get(handler)?.();
|
|
612
|
+
} };
|
|
613
|
+
}
|
|
614
|
+
async invoke(input, options2) {
|
|
615
|
+
const scoped = await this.scopedConfig(options2, this.kwargs);
|
|
616
|
+
try {
|
|
617
|
+
return await this.bound.invoke(input, scoped.config);
|
|
618
|
+
} finally {
|
|
619
|
+
scoped.dispose();
|
|
620
|
+
}
|
|
621
|
+
}
|
|
622
|
+
async stream(input, options2) {
|
|
623
|
+
const scoped = await this.scopedConfig(ensureConfig(options2), this.kwargs);
|
|
624
|
+
let upstream;
|
|
625
|
+
try {
|
|
626
|
+
upstream = await this.bound.stream(input, scoped.config);
|
|
627
|
+
} catch (error) {
|
|
628
|
+
scoped.dispose();
|
|
629
|
+
throw error;
|
|
343
630
|
}
|
|
344
|
-
|
|
631
|
+
const managed = async function* () {
|
|
632
|
+
try {
|
|
633
|
+
yield* upstream;
|
|
634
|
+
} finally {
|
|
635
|
+
scoped.dispose();
|
|
636
|
+
}
|
|
637
|
+
};
|
|
638
|
+
return IterableReadableStream.fromAsyncGenerator(managed());
|
|
639
|
+
}
|
|
640
|
+
async *_streamIterator(input, options2) {
|
|
641
|
+
const stream = await this.stream(input, options2);
|
|
642
|
+
yield* stream;
|
|
643
|
+
}
|
|
644
|
+
withConfig(config) {
|
|
645
|
+
return new ProtectedBinding({ bound: this.bound, config: mergeConfigs(this.config, config), configFactories });
|
|
646
|
+
}
|
|
647
|
+
withListeners(fields) {
|
|
648
|
+
return new RunnableBinding({ bound: this, config: {} }).withListeners(fields);
|
|
649
|
+
}
|
|
650
|
+
withRetry(fields) {
|
|
651
|
+
return new RunnableRetry({
|
|
652
|
+
bound: this,
|
|
653
|
+
config: {},
|
|
654
|
+
...fields?.stopAfterAttempt === void 0 ? {} : { maxAttemptNumber: fields.stopAfterAttempt },
|
|
655
|
+
...fields?.onFailedAttempt === void 0 ? {} : { onFailedAttempt: fields.onFailedAttempt }
|
|
656
|
+
});
|
|
657
|
+
}
|
|
658
|
+
}
|
|
659
|
+
const bindings = /* @__PURE__ */ new Set();
|
|
660
|
+
const installBoundary = (candidate) => {
|
|
661
|
+
if (!RunnableBinding.isRunnableBinding(candidate)) {
|
|
662
|
+
return new ProtectedBinding({ bound: candidate, config: {}, configFactories });
|
|
663
|
+
}
|
|
664
|
+
if (bindings.has(candidate)) throw new TypeError("Cannot protect cyclic runnable bindings");
|
|
665
|
+
bindings.add(candidate);
|
|
666
|
+
const binding = candidate;
|
|
667
|
+
const Binding = binding.constructor;
|
|
668
|
+
return new Binding({ ...binding, bound: installBoundary(binding.bound) });
|
|
669
|
+
};
|
|
670
|
+
class ComposableBinding extends RunnableBinding {
|
|
671
|
+
withConfig(config) {
|
|
672
|
+
return new ComposableBinding({ bound: this.bound, config: mergeConfigs(this.config, config) });
|
|
673
|
+
}
|
|
674
|
+
withListeners(fields) {
|
|
675
|
+
return new RunnableBinding({ bound: this, config: {} }).withListeners(fields);
|
|
676
|
+
}
|
|
677
|
+
withRetry(fields) {
|
|
678
|
+
return new RunnableRetry({
|
|
679
|
+
bound: this,
|
|
680
|
+
config: {},
|
|
681
|
+
...fields?.stopAfterAttempt === void 0 ? {} : { maxAttemptNumber: fields.stopAfterAttempt },
|
|
682
|
+
...fields?.onFailedAttempt === void 0 ? {} : { onFailedAttempt: fields.onFailedAttempt }
|
|
683
|
+
});
|
|
345
684
|
}
|
|
346
685
|
}
|
|
347
|
-
return new
|
|
686
|
+
return new ComposableBinding({ bound: installBoundary(runnable), config: {} });
|
|
348
687
|
}
|
|
349
688
|
export {
|
|
350
|
-
createLangChainHandler
|
|
689
|
+
createLangChainHandler,
|
|
690
|
+
protectLangChainRunnable
|
|
351
691
|
};
|
|
352
692
|
//# sourceMappingURL=langchain.js.map
|