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