@silmaril-security/sdk 0.7.9 → 0.8.0
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 +20 -0
- package/README.md +59 -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 +382 -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 +380 -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 +406 -71
- 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 +406 -71
- package/dist/index.js.map +1 -1
- package/package.json +6 -6
package/dist/index.cjs
CHANGED
|
@@ -278,10 +278,90 @@ var init_extract = __esm({
|
|
|
278
278
|
}
|
|
279
279
|
});
|
|
280
280
|
|
|
281
|
+
// src/adapters/thread-identity.ts
|
|
282
|
+
function record(value) {
|
|
283
|
+
return value !== null && typeof value === "object" && !Array.isArray(value) ? value : void 0;
|
|
284
|
+
}
|
|
285
|
+
function validThreadId(value) {
|
|
286
|
+
return typeof value === "string" && value.trim().length > 0 ? value : void 0;
|
|
287
|
+
}
|
|
288
|
+
function nativeThreadId(runtime, metadata, inherited, currentConfig) {
|
|
289
|
+
const explicit = record(record(runtime)?.configurable);
|
|
290
|
+
const current = record(record(currentConfig)?.configurable);
|
|
291
|
+
for (const candidate of [explicit, current, record(metadata)]) {
|
|
292
|
+
if (candidate && Object.prototype.hasOwnProperty.call(candidate, "thread_id")) {
|
|
293
|
+
return validThreadId(candidate.thread_id);
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
return inherited;
|
|
297
|
+
}
|
|
298
|
+
function rejectConversationOptions(options) {
|
|
299
|
+
if ("conversationId" in options || "conversation_id" in options) {
|
|
300
|
+
throw new TypeError("conversationId/conversation_id was removed. Pass the native configurable.thread_id when invoking the agent or runnable instead.");
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
var RunThreadIdentity;
|
|
304
|
+
var init_thread_identity = __esm({
|
|
305
|
+
"src/adapters/thread-identity.ts"() {
|
|
306
|
+
"use strict";
|
|
307
|
+
RunThreadIdentity = class {
|
|
308
|
+
constructor(boundIdentity, currentConfig = () => void 0) {
|
|
309
|
+
this.boundIdentity = boundIdentity;
|
|
310
|
+
this.currentConfig = currentConfig;
|
|
311
|
+
}
|
|
312
|
+
boundIdentity;
|
|
313
|
+
currentConfig;
|
|
314
|
+
runs = /* @__PURE__ */ new Map();
|
|
315
|
+
children = /* @__PURE__ */ new Map();
|
|
316
|
+
start(runId, parentRunId, metadata) {
|
|
317
|
+
const discarded = this.finish(runId);
|
|
318
|
+
if (this.runs.size >= 4096) {
|
|
319
|
+
const oldestRoot = [...this.runs].find(([, run]) => run.parentRunId === void 0 || !this.runs.has(run.parentRunId))?.[0] ?? this.runs.keys().next().value;
|
|
320
|
+
if (oldestRoot !== void 0) discarded.push(...this.finish(oldestRoot));
|
|
321
|
+
}
|
|
322
|
+
const inherited = parentRunId === void 0 ? void 0 : this.runs.get(parentRunId)?.threadId;
|
|
323
|
+
const exposed = record(metadata);
|
|
324
|
+
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;
|
|
325
|
+
this.runs.set(runId, { threadId, parentRunId });
|
|
326
|
+
if (parentRunId !== void 0 && parentRunId !== runId) {
|
|
327
|
+
const children = this.children.get(parentRunId) ?? /* @__PURE__ */ new Set();
|
|
328
|
+
children.add(runId);
|
|
329
|
+
this.children.set(parentRunId, children);
|
|
330
|
+
}
|
|
331
|
+
return discarded;
|
|
332
|
+
}
|
|
333
|
+
get(runId) {
|
|
334
|
+
const run = this.runs.get(runId);
|
|
335
|
+
return run ? run.threadId : this.boundIdentity?.threadId;
|
|
336
|
+
}
|
|
337
|
+
finish(runId) {
|
|
338
|
+
const pending = [runId];
|
|
339
|
+
const seen = /* @__PURE__ */ new Set();
|
|
340
|
+
while (pending.length) {
|
|
341
|
+
const id = pending.pop();
|
|
342
|
+
if (seen.has(id)) continue;
|
|
343
|
+
seen.add(id);
|
|
344
|
+
pending.push(...this.children.get(id) ?? []);
|
|
345
|
+
this.children.delete(id);
|
|
346
|
+
const parent = this.runs.get(id)?.parentRunId;
|
|
347
|
+
this.runs.delete(id);
|
|
348
|
+
if (parent !== void 0) {
|
|
349
|
+
const siblings = this.children.get(parent);
|
|
350
|
+
siblings?.delete(id);
|
|
351
|
+
if (siblings?.size === 0) this.children.delete(parent);
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
return [...seen];
|
|
355
|
+
}
|
|
356
|
+
};
|
|
357
|
+
}
|
|
358
|
+
});
|
|
359
|
+
|
|
281
360
|
// src/adapters/langchain.ts
|
|
282
361
|
var langchain_exports = {};
|
|
283
362
|
__export(langchain_exports, {
|
|
284
|
-
createLangChainHandler: () => createLangChainHandler
|
|
363
|
+
createLangChainHandler: () => createLangChainHandler,
|
|
364
|
+
protectLangChainRunnable: () => protectLangChainRunnable
|
|
285
365
|
});
|
|
286
366
|
function getMessageRole(message) {
|
|
287
367
|
if (typeof message.role === "string") {
|
|
@@ -290,7 +370,8 @@ function getMessageRole(message) {
|
|
|
290
370
|
if (typeof message.type === "string") {
|
|
291
371
|
return message.type.toLowerCase();
|
|
292
372
|
}
|
|
293
|
-
|
|
373
|
+
const legacyType = message.getType?.() ?? message._getType?.();
|
|
374
|
+
return typeof legacyType === "string" ? legacyType.toLowerCase() : "";
|
|
294
375
|
}
|
|
295
376
|
function extractMessageText(content) {
|
|
296
377
|
if (content === void 0) {
|
|
@@ -319,7 +400,16 @@ function findLastUserMessage2(messages) {
|
|
|
319
400
|
return void 0;
|
|
320
401
|
}
|
|
321
402
|
async function createLangChainHandler(firewall, options = {}) {
|
|
322
|
-
|
|
403
|
+
return buildLangChainHandler(firewall, options);
|
|
404
|
+
}
|
|
405
|
+
async function buildLangChainHandler(firewall, options, boundIdentity) {
|
|
406
|
+
rejectConversationOptions(options);
|
|
407
|
+
const { ensureConfig } = await import("@langchain/core/runnables");
|
|
408
|
+
const threads = new RunThreadIdentity(boundIdentity, () => ensureConfig());
|
|
409
|
+
const { BaseTracer } = await import("@langchain/core/tracers/base");
|
|
410
|
+
let finishRun = (runId) => {
|
|
411
|
+
threads.finish(runId);
|
|
412
|
+
};
|
|
323
413
|
const enabledHooks = resolveHooks(options.hooks);
|
|
324
414
|
const includeTool = options.includeTool ?? true;
|
|
325
415
|
const failOpen = options.failOpen ?? true;
|
|
@@ -338,14 +428,14 @@ async function createLangChainHandler(firewall, options = {}) {
|
|
|
338
428
|
logger("onClassify callback threw", err);
|
|
339
429
|
}
|
|
340
430
|
};
|
|
341
|
-
const
|
|
431
|
+
const classifyEvent = async (text, hookLabel, runId, toolName) => {
|
|
342
432
|
let result;
|
|
343
433
|
try {
|
|
344
434
|
result = await firewall.classify(text, {
|
|
345
435
|
hook: hookLabel,
|
|
346
436
|
metadata: {
|
|
347
437
|
langgraph: { run_id: runId },
|
|
348
|
-
...
|
|
438
|
+
...threads.get(runId) === void 0 ? {} : { conversationId: threads.get(runId) }
|
|
349
439
|
},
|
|
350
440
|
...requestedMode !== void 0 ? { mode: requestedMode } : {},
|
|
351
441
|
...toolName !== void 0 ? { toolName } : {}
|
|
@@ -389,97 +479,325 @@ async function createLangChainHandler(firewall, options = {}) {
|
|
|
389
479
|
result
|
|
390
480
|
});
|
|
391
481
|
};
|
|
392
|
-
|
|
482
|
+
const classify = async (text, hook, runId, toolName) => {
|
|
483
|
+
try {
|
|
484
|
+
await classifyEvent(text, hook, runId, toolName);
|
|
485
|
+
} catch (error) {
|
|
486
|
+
finishRun(runId);
|
|
487
|
+
throw error;
|
|
488
|
+
}
|
|
489
|
+
};
|
|
490
|
+
function serialized(value, name) {
|
|
491
|
+
if (value && typeof value === "object" && "id" in value && Array.isArray(value.id)) return value;
|
|
492
|
+
return { lc: 1, type: "not_implemented", id: [name] };
|
|
493
|
+
}
|
|
494
|
+
class SilmarilFirewallHandler extends BaseTracer {
|
|
393
495
|
name = "silmaril_firewall_handler";
|
|
394
496
|
raiseError = true;
|
|
395
497
|
awaitHandlers = true;
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
498
|
+
// LangChain clears runnable context inside ordinary callbacks. Its synchronous
|
|
499
|
+
// tracer pre-start hooks capture native config before that boundary. Runs are
|
|
500
|
+
// memory-only and every terminal path discards both native tracer maps.
|
|
501
|
+
async persistRun() {
|
|
502
|
+
}
|
|
503
|
+
getRunById(runId) {
|
|
504
|
+
return runId === void 0 ? void 0 : this.runMap.get(runId);
|
|
505
|
+
}
|
|
506
|
+
// Only lifecycle identity is needed. Do not retain prompts, outputs, token
|
|
507
|
+
// events, or completed children when upstream omits a cancellation callback.
|
|
508
|
+
_addRunToRunMap(run) {
|
|
509
|
+
return super._addRunToRunMap({
|
|
510
|
+
...run,
|
|
511
|
+
inputs: {},
|
|
512
|
+
extra: {},
|
|
513
|
+
serialized: {},
|
|
514
|
+
tags: [],
|
|
515
|
+
child_runs: [],
|
|
516
|
+
events: []
|
|
517
|
+
});
|
|
518
|
+
}
|
|
519
|
+
_addChildRun() {
|
|
520
|
+
}
|
|
521
|
+
async _endTrace(run) {
|
|
522
|
+
try {
|
|
523
|
+
await super._endTrace(run);
|
|
524
|
+
} finally {
|
|
525
|
+
run.inputs = {};
|
|
526
|
+
delete run.outputs;
|
|
527
|
+
delete run.error;
|
|
528
|
+
run.extra = {};
|
|
529
|
+
run.events = [];
|
|
530
|
+
run.child_runs = [];
|
|
406
531
|
}
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
532
|
+
}
|
|
533
|
+
async handleText() {
|
|
534
|
+
}
|
|
535
|
+
async handleAgentAction() {
|
|
536
|
+
}
|
|
537
|
+
async handleAgentEnd() {
|
|
538
|
+
}
|
|
539
|
+
async handleLLMNewToken(_token, _idx, runId) {
|
|
540
|
+
return this.getRunById(runId) ?? this._createRunForLLMStart(serialized(void 0, "llm"), [], runId);
|
|
541
|
+
}
|
|
542
|
+
capture(runId, parentRunId, metadata) {
|
|
543
|
+
for (const id of threads.start(runId, parentRunId, metadata)) {
|
|
544
|
+
this.runMap.delete(id);
|
|
545
|
+
this.runTreeMap?.delete(id);
|
|
410
546
|
}
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
547
|
+
}
|
|
548
|
+
finishAll() {
|
|
549
|
+
for (const id of [...this.runMap.keys()]) this.finishRun(id);
|
|
550
|
+
this.runTreeMap?.clear();
|
|
551
|
+
}
|
|
552
|
+
finishRun(runId) {
|
|
553
|
+
for (const id of threads.finish(runId)) {
|
|
554
|
+
this.runMap.delete(id);
|
|
555
|
+
this.runTreeMap?.delete(id);
|
|
414
556
|
}
|
|
415
|
-
await classify(text, FIREWALL_HOOK_TO_LABEL[FirewallHook.CHAT_MODEL_START], runId);
|
|
416
557
|
}
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
558
|
+
_createRunForLLMStart(...args) {
|
|
559
|
+
this.capture(args[2], args[3], args[6]);
|
|
560
|
+
return super._createRunForLLMStart(...args);
|
|
561
|
+
}
|
|
562
|
+
_createRunForChatModelStart(...args) {
|
|
563
|
+
this.capture(args[2], args[3], args[6]);
|
|
564
|
+
return super._createRunForChatModelStart(...args);
|
|
565
|
+
}
|
|
566
|
+
_createRunForChainStart(...args) {
|
|
567
|
+
this.capture(args[2], args[3], args[5]);
|
|
568
|
+
return super._createRunForChainStart(...args);
|
|
569
|
+
}
|
|
570
|
+
_createRunForToolStart(...args) {
|
|
571
|
+
this.capture(args[2], args[3], args[5]);
|
|
572
|
+
return super._createRunForToolStart(...args);
|
|
573
|
+
}
|
|
574
|
+
_createRunForRetrieverStart(...args) {
|
|
575
|
+
this.capture(args[2], args[3], args[5]);
|
|
576
|
+
return super._createRunForRetrieverStart(...args);
|
|
577
|
+
}
|
|
578
|
+
async handleChatModelStart(llm, messages, runId, parentRunId, extraParams, tags, metadata) {
|
|
579
|
+
const batches = messages;
|
|
580
|
+
const run = this.getRunById(runId) ?? this._createRunForChatModelStart(
|
|
581
|
+
serialized(llm, "chat_model"),
|
|
582
|
+
messages,
|
|
583
|
+
runId,
|
|
584
|
+
parentRunId,
|
|
585
|
+
extraParams,
|
|
586
|
+
tags,
|
|
587
|
+
metadata
|
|
588
|
+
);
|
|
589
|
+
if (enabledHooks.has(FirewallHook.CHAT_MODEL_START)) {
|
|
590
|
+
const lastUser = findLastUserMessage2(batches.flat());
|
|
591
|
+
const text = lastUser ? extractMessageText(lastUser.content).trim() : "";
|
|
592
|
+
if (text) await classify(text, FIREWALL_HOOK_TO_LABEL[FirewallHook.CHAT_MODEL_START], runId);
|
|
593
|
+
}
|
|
594
|
+
return run;
|
|
595
|
+
}
|
|
596
|
+
async handleLLMStart(llm, prompts, runId, parentRunId, extraParams, tags, metadata) {
|
|
597
|
+
const run = this.getRunById(runId) ?? this._createRunForLLMStart(
|
|
598
|
+
serialized(llm, "llm"),
|
|
599
|
+
prompts,
|
|
600
|
+
runId,
|
|
601
|
+
parentRunId,
|
|
602
|
+
extraParams,
|
|
603
|
+
tags,
|
|
604
|
+
metadata
|
|
605
|
+
);
|
|
606
|
+
if (enabledHooks.has(FirewallHook.LLM_START)) {
|
|
607
|
+
const text = extractTextFromPrompts(prompts);
|
|
608
|
+
if (text) await classify(text, FIREWALL_HOOK_TO_LABEL[FirewallHook.LLM_START], runId);
|
|
609
|
+
}
|
|
610
|
+
return run;
|
|
611
|
+
}
|
|
612
|
+
async handleToolStart(tool, inputStr, runId, parentRunId, tags, metadata) {
|
|
613
|
+
const run = this.getRunById(runId) ?? this._createRunForToolStart(
|
|
614
|
+
serialized(tool, tool?.name ?? "tool"),
|
|
615
|
+
inputStr,
|
|
616
|
+
runId,
|
|
617
|
+
parentRunId,
|
|
618
|
+
tags,
|
|
619
|
+
metadata
|
|
620
|
+
);
|
|
621
|
+
if (includeTool && enabledHooks.has(FirewallHook.TOOL_START)) {
|
|
622
|
+
const text = extractTextFromToolInput(inputStr);
|
|
623
|
+
if (text) await classify(text, FIREWALL_HOOK_TO_LABEL[FirewallHook.TOOL_START], runId, tool?.name);
|
|
420
624
|
}
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
625
|
+
return run;
|
|
626
|
+
}
|
|
627
|
+
async handleRetrieverStart(retriever, query, runId, parentRunId, tags, metadata) {
|
|
628
|
+
const run = this.getRunById(runId) ?? this._createRunForRetrieverStart(
|
|
629
|
+
serialized(retriever, "retriever"),
|
|
630
|
+
query,
|
|
631
|
+
runId,
|
|
632
|
+
parentRunId,
|
|
633
|
+
tags,
|
|
634
|
+
metadata
|
|
635
|
+
);
|
|
636
|
+
if (enabledHooks.has(FirewallHook.RETRIEVER_START) && query.trim()) {
|
|
637
|
+
await classify(query.trim(), FIREWALL_HOOK_TO_LABEL[FirewallHook.RETRIEVER_START], runId);
|
|
424
638
|
}
|
|
425
|
-
|
|
639
|
+
return run;
|
|
426
640
|
}
|
|
427
|
-
async
|
|
428
|
-
|
|
429
|
-
|
|
641
|
+
async handleLLMEnd(output, runId) {
|
|
642
|
+
try {
|
|
643
|
+
if (!this.getRunById(runId)) this._createRunForLLMStart(serialized(void 0, "llm"), [], runId);
|
|
644
|
+
if (enabledHooks.has(FirewallHook.LLM_END)) {
|
|
645
|
+
const text = extractTextFromLLMResult(output);
|
|
646
|
+
if (text) await classify(text, FIREWALL_HOOK_TO_LABEL[FirewallHook.LLM_END], runId);
|
|
647
|
+
}
|
|
648
|
+
return await super.handleLLMEnd(output, runId);
|
|
649
|
+
} finally {
|
|
650
|
+
finishRun(runId);
|
|
430
651
|
}
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
652
|
+
}
|
|
653
|
+
async handleToolEnd(output, runId, _parentRunId, _tags, kwargs) {
|
|
654
|
+
try {
|
|
655
|
+
if (!this.getRunById(runId)) this._createRunForToolStart(serialized(void 0, "tool"), "", runId);
|
|
656
|
+
if (includeTool && enabledHooks.has(FirewallHook.TOOL_END)) {
|
|
657
|
+
const text = String(output).trim();
|
|
658
|
+
if (text) await classify(text, FIREWALL_HOOK_TO_LABEL[FirewallHook.TOOL_END], runId, kwargs?.name);
|
|
659
|
+
}
|
|
660
|
+
return await super.handleToolEnd(output, runId);
|
|
661
|
+
} finally {
|
|
662
|
+
finishRun(runId);
|
|
434
663
|
}
|
|
435
|
-
const toolName = tool?.name;
|
|
436
|
-
await classify(text, FIREWALL_HOOK_TO_LABEL[FirewallHook.TOOL_START], runId, toolName);
|
|
437
664
|
}
|
|
438
|
-
async
|
|
439
|
-
|
|
440
|
-
|
|
665
|
+
async handleRetrieverEnd(documents, runId) {
|
|
666
|
+
try {
|
|
667
|
+
if (!this.getRunById(runId)) this._createRunForRetrieverStart(serialized(void 0, "retriever"), "", runId);
|
|
668
|
+
if (enabledHooks.has(FirewallHook.RETRIEVER_END)) {
|
|
669
|
+
const text = extractTextFromDocuments(documents);
|
|
670
|
+
if (text) await classify(text, FIREWALL_HOOK_TO_LABEL[FirewallHook.RETRIEVER_END], runId);
|
|
671
|
+
}
|
|
672
|
+
return await super.handleRetrieverEnd(documents, runId);
|
|
673
|
+
} finally {
|
|
674
|
+
finishRun(runId);
|
|
441
675
|
}
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
676
|
+
}
|
|
677
|
+
async handleChainStart(chain, inputs, runId, parentRunId, tags, metadata, runType, name) {
|
|
678
|
+
return super.handleChainStart(serialized(chain, "chain"), inputs, runId, parentRunId, tags, metadata, runType, name);
|
|
679
|
+
}
|
|
680
|
+
async handleChainEnd(...args) {
|
|
681
|
+
if (!this.getRunById(args[1])) this._createRunForChainStart(serialized(void 0, "chain"), {}, args[1]);
|
|
682
|
+
try {
|
|
683
|
+
return await super.handleChainEnd(...args);
|
|
684
|
+
} finally {
|
|
685
|
+
finishRun(args[1]);
|
|
445
686
|
}
|
|
446
|
-
await classify(text, FIREWALL_HOOK_TO_LABEL[FirewallHook.RETRIEVER_START], runId);
|
|
447
687
|
}
|
|
448
|
-
async
|
|
449
|
-
if (!
|
|
450
|
-
|
|
688
|
+
async handleChainError(...args) {
|
|
689
|
+
if (!this.getRunById(args[1])) this._createRunForChainStart(serialized(void 0, "chain"), {}, args[1]);
|
|
690
|
+
try {
|
|
691
|
+
return await super.handleChainError(...args);
|
|
692
|
+
} finally {
|
|
693
|
+
finishRun(args[1]);
|
|
451
694
|
}
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
695
|
+
}
|
|
696
|
+
async handleLLMError(...args) {
|
|
697
|
+
if (!this.getRunById(args[1])) this._createRunForLLMStart(serialized(void 0, "llm"), [], args[1]);
|
|
698
|
+
try {
|
|
699
|
+
return await super.handleLLMError(...args);
|
|
700
|
+
} finally {
|
|
701
|
+
finishRun(args[1]);
|
|
455
702
|
}
|
|
456
|
-
await classify(text, FIREWALL_HOOK_TO_LABEL[FirewallHook.LLM_END], runId);
|
|
457
703
|
}
|
|
458
|
-
async
|
|
459
|
-
if (!
|
|
460
|
-
|
|
704
|
+
async handleToolError(...args) {
|
|
705
|
+
if (!this.getRunById(args[1])) this._createRunForToolStart(serialized(void 0, "tool"), "", args[1]);
|
|
706
|
+
try {
|
|
707
|
+
return await super.handleToolError(...args);
|
|
708
|
+
} finally {
|
|
709
|
+
finishRun(args[1]);
|
|
461
710
|
}
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
711
|
+
}
|
|
712
|
+
async handleRetrieverError(...args) {
|
|
713
|
+
if (!this.getRunById(args[1])) this._createRunForRetrieverStart(serialized(void 0, "retriever"), "", args[1]);
|
|
714
|
+
try {
|
|
715
|
+
return await super.handleRetrieverError(...args);
|
|
716
|
+
} finally {
|
|
717
|
+
finishRun(args[1]);
|
|
465
718
|
}
|
|
466
|
-
const toolName = _kwargs?.name;
|
|
467
|
-
await classify(text, FIREWALL_HOOK_TO_LABEL[FirewallHook.TOOL_END], runId, toolName);
|
|
468
719
|
}
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
720
|
+
}
|
|
721
|
+
const handler = new SilmarilFirewallHandler();
|
|
722
|
+
finishRun = (runId) => {
|
|
723
|
+
handler.finishRun(runId);
|
|
724
|
+
};
|
|
725
|
+
handlerCleanups.set(handler, () => handler.finishAll());
|
|
726
|
+
return handler;
|
|
727
|
+
}
|
|
728
|
+
async function protectLangChainRunnable(firewall, runnable, options = {}) {
|
|
729
|
+
rejectConversationOptions(options);
|
|
730
|
+
const { RunnableBinding, RunnableRetry, ensureConfig, mergeConfigs } = await import("@langchain/core/runnables");
|
|
731
|
+
const { IterableReadableStream } = await import("@langchain/core/utils/stream");
|
|
732
|
+
const configFactories = [async (config) => {
|
|
733
|
+
const effective = ensureConfig(config);
|
|
734
|
+
const handler = await buildLangChainHandler(firewall, options, {
|
|
735
|
+
threadId: validThreadId(effective.configurable?.thread_id)
|
|
736
|
+
});
|
|
737
|
+
return { callbacks: [handler] };
|
|
738
|
+
}];
|
|
739
|
+
class ProtectedBinding extends RunnableBinding {
|
|
740
|
+
async scopedConfig(...configs) {
|
|
741
|
+
const created = [];
|
|
742
|
+
const scopedFactories = configFactories.map((factory) => async (config2) => {
|
|
743
|
+
const update = await factory(config2);
|
|
744
|
+
if (Array.isArray(update.callbacks)) created.push(...update.callbacks);
|
|
745
|
+
return update;
|
|
746
|
+
});
|
|
747
|
+
const scoped = new RunnableBinding({ bound: this.bound, config: this.config, configFactories: scopedFactories });
|
|
748
|
+
const config = await scoped._mergeConfig(...configs);
|
|
749
|
+
return { config, dispose: () => {
|
|
750
|
+
for (const handler of created) handlerCleanups.get(handler)?.();
|
|
751
|
+
} };
|
|
752
|
+
}
|
|
753
|
+
async invoke(input, options2) {
|
|
754
|
+
const scoped = await this.scopedConfig(options2, this.kwargs);
|
|
755
|
+
try {
|
|
756
|
+
return await this.bound.invoke(input, scoped.config);
|
|
757
|
+
} finally {
|
|
758
|
+
scoped.dispose();
|
|
472
759
|
}
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
760
|
+
}
|
|
761
|
+
async stream(input, options2) {
|
|
762
|
+
const scoped = await this.scopedConfig(ensureConfig(options2), this.kwargs);
|
|
763
|
+
let upstream;
|
|
764
|
+
try {
|
|
765
|
+
upstream = await this.bound.stream(input, scoped.config);
|
|
766
|
+
} catch (error) {
|
|
767
|
+
scoped.dispose();
|
|
768
|
+
throw error;
|
|
476
769
|
}
|
|
477
|
-
|
|
770
|
+
const managed = async function* () {
|
|
771
|
+
try {
|
|
772
|
+
yield* upstream;
|
|
773
|
+
} finally {
|
|
774
|
+
scoped.dispose();
|
|
775
|
+
}
|
|
776
|
+
};
|
|
777
|
+
return IterableReadableStream.fromAsyncGenerator(managed());
|
|
778
|
+
}
|
|
779
|
+
async *_streamIterator(input, options2) {
|
|
780
|
+
const stream = await this.stream(input, options2);
|
|
781
|
+
yield* stream;
|
|
782
|
+
}
|
|
783
|
+
withConfig(config) {
|
|
784
|
+
return new ProtectedBinding({ bound: this.bound, config: mergeConfigs(this.config, config), configFactories });
|
|
785
|
+
}
|
|
786
|
+
withListeners(fields) {
|
|
787
|
+
return new RunnableBinding({ bound: this, config: {} }).withListeners(fields);
|
|
788
|
+
}
|
|
789
|
+
withRetry(fields) {
|
|
790
|
+
return new RunnableRetry({
|
|
791
|
+
bound: this,
|
|
792
|
+
config: {},
|
|
793
|
+
...fields?.stopAfterAttempt === void 0 ? {} : { maxAttemptNumber: fields.stopAfterAttempt },
|
|
794
|
+
...fields?.onFailedAttempt === void 0 ? {} : { onFailedAttempt: fields.onFailedAttempt }
|
|
795
|
+
});
|
|
478
796
|
}
|
|
479
797
|
}
|
|
480
|
-
return new
|
|
798
|
+
return new ProtectedBinding({ bound: runnable, config: {}, configFactories });
|
|
481
799
|
}
|
|
482
|
-
var USER_ROLES;
|
|
800
|
+
var handlerCleanups, USER_ROLES;
|
|
483
801
|
var init_langchain = __esm({
|
|
484
802
|
"src/adapters/langchain.ts"() {
|
|
485
803
|
"use strict";
|
|
@@ -487,6 +805,8 @@ var init_langchain = __esm({
|
|
|
487
805
|
init_hooks();
|
|
488
806
|
init_modes();
|
|
489
807
|
init_extract();
|
|
808
|
+
init_thread_identity();
|
|
809
|
+
handlerCleanups = /* @__PURE__ */ new WeakMap();
|
|
490
810
|
USER_ROLES = /* @__PURE__ */ new Set(["human", "user"]);
|
|
491
811
|
}
|
|
492
812
|
});
|
|
@@ -844,6 +1164,18 @@ function normalizeHarmfulOutcomeMap(values, fieldName) {
|
|
|
844
1164
|
}
|
|
845
1165
|
return Object.freeze(out);
|
|
846
1166
|
}
|
|
1167
|
+
function normalizeHarmfulOutcomeCountMap(values, fieldName) {
|
|
1168
|
+
const out = normalizeHarmfulOutcomeMap(values, fieldName);
|
|
1169
|
+
if (out === void 0) {
|
|
1170
|
+
return void 0;
|
|
1171
|
+
}
|
|
1172
|
+
for (const [key, value] of Object.entries(out)) {
|
|
1173
|
+
if (typeof value !== "number" || !Number.isFinite(value) || !Number.isInteger(value) || value < 0) {
|
|
1174
|
+
throw new Error(`Firewall: invalid ${fieldName} value for ${JSON.stringify(key)}`);
|
|
1175
|
+
}
|
|
1176
|
+
}
|
|
1177
|
+
return out;
|
|
1178
|
+
}
|
|
847
1179
|
|
|
848
1180
|
// src/sanitization.ts
|
|
849
1181
|
function isHighSurrogate(code) {
|
|
@@ -872,7 +1204,7 @@ function sanitizeText(text) {
|
|
|
872
1204
|
}
|
|
873
1205
|
|
|
874
1206
|
// src/firewall.ts
|
|
875
|
-
var SDK_VERSION = "0.
|
|
1207
|
+
var SDK_VERSION = "0.8.0";
|
|
876
1208
|
var DEFAULT_TIMEOUT_MS = 1e4;
|
|
877
1209
|
var DEFAULT_MAX_RETRIES = 5;
|
|
878
1210
|
var MAX_BACKOFF_SECONDS = 30;
|
|
@@ -942,7 +1274,10 @@ function blockResultFromResponse(data, requestedMode, requestedReview) {
|
|
|
942
1274
|
}
|
|
943
1275
|
}
|
|
944
1276
|
if (data.detector_counts !== void 0) {
|
|
945
|
-
const detectorCounts =
|
|
1277
|
+
const detectorCounts = normalizeHarmfulOutcomeCountMap(
|
|
1278
|
+
data.detector_counts,
|
|
1279
|
+
"detector_counts"
|
|
1280
|
+
);
|
|
946
1281
|
if (detectorCounts !== void 0) {
|
|
947
1282
|
result.detectorCounts = detectorCounts;
|
|
948
1283
|
}
|