@anvia/core 0.11.2 → 0.12.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.
Files changed (78) hide show
  1. package/dist/agent/index.d.ts +14 -11
  2. package/dist/agent/index.js +11 -10
  3. package/dist/{agent-Bq2KtSaw.d.ts → agent-BWF8_O8k.d.ts} +17 -8
  4. package/dist/audio-generation/index.d.ts +3 -3
  5. package/dist/{chunk-N6REB3DH.js → chunk-4AJJIIAQ.js} +9 -7
  6. package/dist/chunk-4AJJIIAQ.js.map +1 -0
  7. package/dist/{chunk-WJO6NVE2.js → chunk-5LFGEMIW.js} +1 -1
  8. package/dist/{chunk-WJO6NVE2.js.map → chunk-5LFGEMIW.js.map} +1 -1
  9. package/dist/{chunk-DOS77JZC.js → chunk-JNO4AR7Q.js} +2 -2
  10. package/dist/{chunk-SISUMRUX.js → chunk-KTTIPWE7.js} +467 -111
  11. package/dist/chunk-KTTIPWE7.js.map +1 -0
  12. package/dist/{chunk-R75SGHCI.js → chunk-MIJUAWHU.js} +6 -6
  13. package/dist/{chunk-5EDHXYH5.js → chunk-PGFYN5ZX.js} +12 -7
  14. package/dist/chunk-PGFYN5ZX.js.map +1 -0
  15. package/dist/{chunk-X3SWV6W6.js → chunk-R7F2JF7J.js} +7 -7
  16. package/dist/chunk-R7F2JF7J.js.map +1 -0
  17. package/dist/{chunk-5G3VME2D.js → chunk-SRBW3LD7.js} +2 -2
  18. package/dist/chunk-SRBW3LD7.js.map +1 -0
  19. package/dist/{chunk-62RUYGMM.js → chunk-TIH4QM55.js} +12 -3
  20. package/dist/chunk-TIH4QM55.js.map +1 -0
  21. package/dist/chunk-YRERPIA5.js +451 -0
  22. package/dist/chunk-YRERPIA5.js.map +1 -0
  23. package/dist/{chunk-V3WTT7TE.js → chunk-ZGIE73BH.js} +2 -2
  24. package/dist/completion/index.d.ts +8 -6
  25. package/dist/completion/index.js +2 -2
  26. package/dist/{create-completion-BEbtU5pX.d.ts → create-completion-Y6YsYbQB.d.ts} +2 -2
  27. package/dist/evals/index.d.ts +9 -8
  28. package/dist/evals/index.js +14 -13
  29. package/dist/evals/index.js.map +1 -1
  30. package/dist/extractor/index.d.ts +9 -8
  31. package/dist/extractor/index.js +12 -11
  32. package/dist/guardrails/index.d.ts +211 -0
  33. package/dist/guardrails/index.js +35 -0
  34. package/dist/guardrails/index.js.map +1 -0
  35. package/dist/hooks/index.d.ts +3 -3
  36. package/dist/image-generation/index.d.ts +3 -3
  37. package/dist/{index-CTNzKidE.d.ts → index-DsWWqP0Q.d.ts} +9 -2
  38. package/dist/index.d.ts +13 -12
  39. package/dist/index.js +37 -19
  40. package/dist/internal/agent.d.ts +9 -8
  41. package/dist/internal/agent.js +10 -9
  42. package/dist/loaders/index.d.ts +1 -1
  43. package/dist/mcp/index.d.ts +5 -4
  44. package/dist/memory/index.d.ts +3 -3
  45. package/dist/{middleware-CG7l0rR3.d.ts → middleware-BTR0eRtx.d.ts} +3 -3
  46. package/dist/model-listing/index.d.ts +2 -1
  47. package/dist/observability/index.d.ts +4 -3
  48. package/dist/pipeline/index.d.ts +9 -8
  49. package/dist/pipeline/index.js +3 -3
  50. package/dist/request/index.d.ts +9 -8
  51. package/dist/request/index.js +9 -8
  52. package/dist/skills/index.d.ts +5 -4
  53. package/dist/skills/index.js +6 -6
  54. package/dist/{think-tool-B8Rqw2i_.d.ts → think-tool-Bn3HHu_z.d.ts} +4 -1
  55. package/dist/tool/index.d.ts +6 -5
  56. package/dist/tool/index.js +6 -6
  57. package/dist/{tool-BLypI31e.d.ts → tool-DGELXD2z.d.ts} +4 -1
  58. package/dist/transcription/index.d.ts +3 -3
  59. package/dist/{types-KKjICcrA.d.ts → types-9VPKg7ih.d.ts} +1 -1
  60. package/dist/{types-D-YTJdLj.d.ts → types-Bx_ZtjPi.d.ts} +1 -1
  61. package/dist/{types-CCxnnJjU.d.ts → types-CGML74sE.d.ts} +1 -1
  62. package/dist/{types-CNfjQ5rB.d.ts → types-CqG6d7Ce.d.ts} +1 -1
  63. package/dist/{types-CIwm9p4w.d.ts → types-Dc83Qzch.d.ts} +2 -2
  64. package/dist/{types-C8loR4il.d.ts → types-q9G7Bvwl.d.ts} +8 -8
  65. package/dist/ui/index.d.ts +1 -1
  66. package/dist/ui/index.js +2 -2
  67. package/dist/vector-store/index.d.ts +5 -4
  68. package/dist/vector-store/index.js +3 -3
  69. package/package.json +6 -2
  70. package/dist/chunk-5EDHXYH5.js.map +0 -1
  71. package/dist/chunk-5G3VME2D.js.map +0 -1
  72. package/dist/chunk-62RUYGMM.js.map +0 -1
  73. package/dist/chunk-N6REB3DH.js.map +0 -1
  74. package/dist/chunk-SISUMRUX.js.map +0 -1
  75. package/dist/chunk-X3SWV6W6.js.map +0 -1
  76. /package/dist/{chunk-DOS77JZC.js.map → chunk-JNO4AR7Q.js.map} +0 -0
  77. /package/dist/{chunk-R75SGHCI.js.map → chunk-MIJUAWHU.js.map} +0 -0
  78. /package/dist/{chunk-V3WTT7TE.js.map → chunk-ZGIE73BH.js.map} +0 -0
@@ -4,28 +4,37 @@ import {
4
4
  import {
5
5
  parseToolArgs,
6
6
  toolResultContentToText
7
- } from "./chunk-X3SWV6W6.js";
7
+ } from "./chunk-R7F2JF7J.js";
8
8
  import {
9
- mapWithConcurrency
10
- } from "./chunk-OIMLU4SF.js";
9
+ runControl,
10
+ toolCallControl
11
+ } from "./chunk-NPZDYOE6.js";
12
+ import {
13
+ compact
14
+ } from "./chunk-MMHG7WAM.js";
11
15
  import {
12
16
  CompletionRequestBuilder,
13
17
  isStreamingCompletionModel
14
- } from "./chunk-5G3VME2D.js";
18
+ } from "./chunk-SRBW3LD7.js";
15
19
  import {
20
+ AssistantContent,
16
21
  Message,
17
22
  ToolContent,
18
23
  Usage,
19
24
  assertCompletionRequestSupported,
20
25
  textFromAssistantContent
21
- } from "./chunk-WJO6NVE2.js";
26
+ } from "./chunk-5LFGEMIW.js";
22
27
  import {
23
- runControl,
24
- toolCallControl
25
- } from "./chunk-NPZDYOE6.js";
28
+ mapWithConcurrency
29
+ } from "./chunk-OIMLU4SF.js";
26
30
  import {
27
- compact
28
- } from "./chunk-MMHG7WAM.js";
31
+ appendGuardrailPolicies,
32
+ hasEnforcedOutputGuardrails,
33
+ runInputGuardrails,
34
+ runOutputGuardrails,
35
+ runToolGuardrails,
36
+ runToolResultGuardrails
37
+ } from "./chunk-YRERPIA5.js";
29
38
 
30
39
  // src/request/errors.ts
31
40
  var MaxTurnsError = class extends Error {
@@ -540,22 +549,26 @@ function isGenerationDeltaEvent(type) {
540
549
  // src/internal/prompt-runtime/tool-execution.ts
541
550
  var MCP_TOOL_METADATA_KEY = /* @__PURE__ */ Symbol.for("anvia.mcp.tool.metadata");
542
551
  var ToolCallExecutor = class {
543
- constructor(agent, activeHook, approvals, runContext, concurrency, requestMiddlewares, cancel) {
552
+ constructor(agent, activeHook, approvals, guardrails, runContext, concurrency, requestMiddlewares, cancel, onGuardrailDecision) {
544
553
  this.agent = agent;
545
554
  this.activeHook = activeHook;
546
555
  this.approvals = approvals;
556
+ this.guardrails = guardrails;
547
557
  this.runContext = runContext;
548
558
  this.concurrency = concurrency;
549
559
  this.requestMiddlewares = requestMiddlewares;
550
560
  this.cancel = cancel;
561
+ this.onGuardrailDecision = onGuardrailDecision;
551
562
  }
552
563
  agent;
553
564
  activeHook;
554
565
  approvals;
566
+ guardrails;
555
567
  runContext;
556
568
  concurrency;
557
569
  requestMiddlewares;
558
570
  cancel;
571
+ onGuardrailDecision;
559
572
  async execute(toolCalls, onResult, onStreamEvent, observation) {
560
573
  return mapWithConcurrency(toolCalls, this.concurrency, async (toolCall) => {
561
574
  const args = JSON.stringify(toolCall.function.arguments ?? {});
@@ -585,6 +598,9 @@ var ToolCallExecutor = class {
585
598
  toolMetadata
586
599
  })
587
600
  );
601
+ let output;
602
+ let skipped = false;
603
+ let effectiveArgs = args;
588
604
  const callAction = await this.activeHook?.onToolCall?.({
589
605
  ...hookArgs,
590
606
  tool: toolCallControl
@@ -595,14 +611,11 @@ var ToolCallExecutor = class {
595
611
  observation?.turn,
596
612
  toolCall,
597
613
  internalCallId,
598
- args,
614
+ effectiveArgs,
599
615
  callAction.reason
600
616
  );
601
617
  throw this.cancel(callAction.reason);
602
618
  }
603
- let output;
604
- let skipped = false;
605
- let effectiveArgs = args;
606
619
  if (callAction?.type === "skip") {
607
620
  output = callAction.reason;
608
621
  skipped = true;
@@ -614,8 +627,50 @@ var ToolCallExecutor = class {
614
627
  turn: observation?.turn ?? 0,
615
628
  originalArgs: args
616
629
  });
617
- const effectiveHookArgs = { ...hookArgs, args: effectiveArgs };
618
- approvalDecision = callAction?.type === "approval_request" ? await this.requestApproval(tool, effectiveHookArgs, callAction) : await this.evaluateToolApproval(tool, effectiveHookArgs) ?? { approved: true };
630
+ hookArgs.args = effectiveArgs;
631
+ const inputGuardrailResult = await runToolGuardrails(
632
+ this.guardrails,
633
+ tool?.inputGuardrails ?? [],
634
+ toolGuardrailContext(
635
+ tool,
636
+ hookArgs,
637
+ this.agent,
638
+ this.runContext,
639
+ observation?.turn ?? 0
640
+ )
641
+ );
642
+ await this.recordGuardrailDecisions(inputGuardrailResult.decisions);
643
+ effectiveArgs = inputGuardrailResult.rawArgs;
644
+ hookArgs.args = effectiveArgs;
645
+ if (inputGuardrailResult.blocked) {
646
+ output = inputGuardrailResult.message ?? "Tool call blocked by guardrail.";
647
+ skipped = true;
648
+ } else {
649
+ approvalDecision = inputGuardrailResult.approval !== void 0 ? await this.requestApproval(
650
+ tool,
651
+ hookArgs,
652
+ compact({
653
+ reason: inputGuardrailResult.approval.reason,
654
+ rejectMessage: inputGuardrailResult.approval.rejectMessage
655
+ })
656
+ ) : callAction?.type === "approval_request" ? await this.requestApproval(tool, hookArgs, callAction) : await this.evaluateToolApproval(tool, hookArgs) ?? { approved: true };
657
+ if (!approvalDecision.approved) {
658
+ output = approvalDecision.result;
659
+ skipped = true;
660
+ } else {
661
+ output = await this.runApprovedToolCall(
662
+ toolCall,
663
+ hookArgs,
664
+ effectiveArgs,
665
+ args,
666
+ toolObservers,
667
+ observation,
668
+ onStreamEvent,
669
+ false
670
+ );
671
+ effectiveArgs = hookArgs.args;
672
+ }
673
+ }
619
674
  } catch (error) {
620
675
  await recordToolError(
621
676
  toolObservers,
@@ -627,52 +682,6 @@ var ToolCallExecutor = class {
627
682
  );
628
683
  throw error;
629
684
  }
630
- if (!approvalDecision.approved) {
631
- output = approvalDecision.result;
632
- skipped = true;
633
- } else {
634
- try {
635
- output = await this.agent.callTool(toolCall.function.name, effectiveArgs, {
636
- emitStreamEvent: async (event) => {
637
- await toolObservers?.streamEvent(
638
- compact({
639
- turn: observation?.turn ?? 0,
640
- toolCall,
641
- toolName: toolCall.function.name,
642
- internalCallId,
643
- args: effectiveArgs,
644
- toolCallId: toolCall.callId,
645
- event
646
- })
647
- );
648
- const payload = agentToolEventPayload(toolCall, internalCallId, event);
649
- if (payload !== void 0) {
650
- onStreamEvent?.(payload);
651
- }
652
- }
653
- });
654
- } catch (error) {
655
- const errorAction = await this.activeHook?.onToolError?.({
656
- ...hookArgs,
657
- args: effectiveArgs,
658
- error,
659
- run: runControl
660
- });
661
- await toolObservers?.error({
662
- turn: observation?.turn ?? 0,
663
- toolCall,
664
- toolName: toolCall.function.name,
665
- internalCallId,
666
- args: effectiveArgs,
667
- ...toolCall.callId !== void 0 && { toolCallId: toolCall.callId },
668
- error
669
- });
670
- if (errorAction?.type === "terminate") {
671
- throw this.cancel(errorAction.reason);
672
- }
673
- output = error instanceof Error ? error.toString() : String(error);
674
- }
675
- }
676
685
  }
677
686
  let result = toolOutputToText(output);
678
687
  let structuredResult = toolOutputToStructuredResult(output);
@@ -692,6 +701,29 @@ var ToolCallExecutor = class {
692
701
  structuredResult = toolOutputToStructuredResult(middlewareReplacement);
693
702
  }
694
703
  }
704
+ const resultGuardrailResult = await runToolResultGuardrails(
705
+ this.guardrails,
706
+ tool?.outputGuardrails ?? [],
707
+ toolResultGuardrailContext(
708
+ tool,
709
+ hookArgs,
710
+ result,
711
+ structuredResult,
712
+ this.agent,
713
+ this.runContext,
714
+ observation?.turn ?? 0
715
+ )
716
+ );
717
+ await this.recordGuardrailDecisions(resultGuardrailResult.decisions);
718
+ if (resultGuardrailResult.blocked) {
719
+ output = resultGuardrailResult.message ?? "Tool result blocked by guardrail.";
720
+ result = toolOutputToText(output);
721
+ structuredResult = toolOutputToStructuredResult(output);
722
+ } else if (resultGuardrailResult.result !== result || resultGuardrailResult.structuredResult !== structuredResult) {
723
+ output = resultGuardrailResult.structuredResult ?? resultGuardrailResult.result;
724
+ result = resultGuardrailResult.result;
725
+ structuredResult = resultGuardrailResult.structuredResult;
726
+ }
695
727
  const resultAction = await this.activeHook?.onToolResult?.({
696
728
  ...hookArgs,
697
729
  args: effectiveArgs,
@@ -728,6 +760,61 @@ var ToolCallExecutor = class {
728
760
  return ToolContent.toolResult(toolCall.id, output, toolCall.callId);
729
761
  });
730
762
  }
763
+ async runApprovedToolCall(toolCall, hookArgs, effectiveArgs, originalArgs, toolObservers, observation, onStreamEvent, applyInputMiddleware = true) {
764
+ const middlewareArgs = applyInputMiddleware ? await this.runToolInputMiddlewares({
765
+ ...hookArgs,
766
+ args: effectiveArgs,
767
+ turn: observation?.turn ?? 0,
768
+ originalArgs
769
+ }) : effectiveArgs;
770
+ hookArgs.args = middlewareArgs;
771
+ try {
772
+ return await this.agent.callTool(toolCall.function.name, middlewareArgs, {
773
+ emitStreamEvent: async (event) => {
774
+ await toolObservers?.streamEvent(
775
+ compact({
776
+ turn: observation?.turn ?? 0,
777
+ toolCall,
778
+ toolName: toolCall.function.name,
779
+ internalCallId: hookArgs.internalCallId,
780
+ args: middlewareArgs,
781
+ toolCallId: toolCall.callId,
782
+ event
783
+ })
784
+ );
785
+ const payload = agentToolEventPayload(toolCall, hookArgs.internalCallId, event);
786
+ if (payload !== void 0) {
787
+ onStreamEvent?.(payload);
788
+ }
789
+ }
790
+ });
791
+ } catch (error) {
792
+ const errorAction = await this.activeHook?.onToolError?.({
793
+ ...hookArgs,
794
+ args: middlewareArgs,
795
+ error,
796
+ run: runControl
797
+ });
798
+ await toolObservers?.error({
799
+ turn: observation?.turn ?? 0,
800
+ toolCall,
801
+ toolName: toolCall.function.name,
802
+ internalCallId: hookArgs.internalCallId,
803
+ args: middlewareArgs,
804
+ ...toolCall.callId !== void 0 && { toolCallId: toolCall.callId },
805
+ error
806
+ });
807
+ if (errorAction?.type === "terminate") {
808
+ throw this.cancel(errorAction.reason);
809
+ }
810
+ return error instanceof Error ? error.toString() : String(error);
811
+ }
812
+ }
813
+ async recordGuardrailDecisions(decisions) {
814
+ for (const decision of decisions) {
815
+ await this.onGuardrailDecision?.(decision);
816
+ }
817
+ }
731
818
  async runToolResultMiddlewares(args) {
732
819
  let result = args.result;
733
820
  let structuredResult = args.structuredResult;
@@ -829,6 +916,55 @@ function approvalContext(tool, hookArgs, agent, run) {
829
916
  })
830
917
  });
831
918
  }
919
+ function toolGuardrailContext(tool, hookArgs, agent, run, turn) {
920
+ const parsedArgs = parseGuardrailContextArgs(tool, hookArgs.args);
921
+ return compact({
922
+ toolName: hookArgs.toolName,
923
+ args: parsedArgs,
924
+ rawArgs: hookArgs.args,
925
+ toolCallId: hookArgs.toolCallId,
926
+ internalCallId: hookArgs.internalCallId,
927
+ turn,
928
+ run: guardrailRunContext(agent, run)
929
+ });
930
+ }
931
+ function toolResultGuardrailContext(tool, hookArgs, result, structuredResult, agent, run, turn) {
932
+ const parsedArgs = parseGuardrailContextArgs(tool, hookArgs.args);
933
+ return compact({
934
+ toolName: hookArgs.toolName,
935
+ args: parsedArgs,
936
+ rawArgs: hookArgs.args,
937
+ result,
938
+ structuredResult,
939
+ toolCallId: hookArgs.toolCallId,
940
+ internalCallId: hookArgs.internalCallId,
941
+ turn,
942
+ run: guardrailRunContext(agent, run)
943
+ });
944
+ }
945
+ function parseGuardrailContextArgs(tool, rawArgs) {
946
+ const parsedArgs = parseGuardrailArgs(rawArgs);
947
+ try {
948
+ return tool?.parseApprovalArgs?.(parsedArgs) ?? parsedArgs;
949
+ } catch {
950
+ return parsedArgs;
951
+ }
952
+ }
953
+ function parseGuardrailArgs(args) {
954
+ try {
955
+ return parseToolArgs(args);
956
+ } catch {
957
+ return args;
958
+ }
959
+ }
960
+ function guardrailRunContext(agent, run) {
961
+ return compact({
962
+ agentId: agent.id,
963
+ runId: run.runId,
964
+ sessionId: run.sessionId,
965
+ metadata: run.metadata
966
+ });
967
+ }
832
968
  function normalizeApprovalDecision(decision) {
833
969
  if (typeof decision === "boolean") {
834
970
  return { approved: decision };
@@ -852,6 +988,8 @@ function toolTraceMetadata(tool) {
852
988
  const mcpMetadata = typeof metadata === "object" && metadata !== null ? metadata : void 0;
853
989
  return {
854
990
  approvalRequired: tool.approval !== void 0,
991
+ inputGuardrailCount: tool.inputGuardrails?.length ?? 0,
992
+ outputGuardrailCount: tool.outputGuardrails?.length ?? 0,
855
993
  ...typeof mcpMetadata?.serverName === "string" && mcpMetadata.serverName.length > 0 ? { mcpServerName: mcpMetadata.serverName } : {}
856
994
  };
857
995
  }
@@ -1100,6 +1238,7 @@ var PromptRequest = class _PromptRequest {
1100
1238
  this.maxTurnCount = agent.defaultMaxTurns ?? 0;
1101
1239
  this.activeHook = agent.hook;
1102
1240
  this.approvalOptions = agent.approvals;
1241
+ this.guardrailPolicies = [...agent.guardrails];
1103
1242
  this.memoryRecorder = new PromptRequestMemory(agent, memoryContext, initialHistory);
1104
1243
  }
1105
1244
  agent;
@@ -1109,6 +1248,8 @@ var PromptRequest = class _PromptRequest {
1109
1248
  maxTurnCount;
1110
1249
  activeHook;
1111
1250
  approvalOptions;
1251
+ guardrailPolicies;
1252
+ guardrailDecisions = [];
1112
1253
  concurrency = 1;
1113
1254
  traceOptions;
1114
1255
  requestMiddlewares = [];
@@ -1131,6 +1272,10 @@ var PromptRequest = class _PromptRequest {
1131
1272
  this.approvalOptions = options;
1132
1273
  return this;
1133
1274
  }
1275
+ guardrails(policies) {
1276
+ this.guardrailPolicies = appendGuardrailPolicies(this.guardrailPolicies, policies);
1277
+ return this;
1278
+ }
1134
1279
  /**
1135
1280
  * @deprecated Use `withHook` instead.
1136
1281
  */
@@ -1175,14 +1320,37 @@ var PromptRequest = class _PromptRequest {
1175
1320
  async send() {
1176
1321
  this.startRun();
1177
1322
  const runId = globalThis.crypto.randomUUID();
1178
- const newMessages = [this.promptMessage];
1179
- this.chatHistory = await this.memoryRecorder.prepareRun(runId, newMessages);
1180
- const pendingTurnMessages = this.memoryRecorder.pendingTurnMessages(newMessages);
1181
1323
  let usage = Usage.empty();
1182
1324
  let currentTurns = 0;
1183
1325
  let lastPrompt = this.promptMessage;
1326
+ let newMessages = [this.promptMessage];
1184
1327
  const runObservers = await this.startRunObservers();
1185
1328
  try {
1329
+ const inputResult = await runInputGuardrails(this.guardrailPolicies, {
1330
+ prompt: this.promptMessage,
1331
+ history: this.chatHistory,
1332
+ inputText: textFromMessage(this.promptMessage),
1333
+ run: this.guardrailRunContext(runId)
1334
+ });
1335
+ for (const decision of inputResult.decisions) {
1336
+ await this.recordGuardrailDecision(decision, runObservers);
1337
+ }
1338
+ this.promptMessage = inputResult.prompt;
1339
+ if (inputResult.blocked) {
1340
+ const output = inputResult.message ?? "The request was blocked by a guardrail.";
1341
+ const result = {
1342
+ output,
1343
+ usage: Usage.empty(),
1344
+ messages: [this.promptMessage, Message.assistant(output)],
1345
+ guardrails: [...this.guardrailDecisions]
1346
+ };
1347
+ await runObservers.end(result);
1348
+ this.runState = "completed";
1349
+ return result;
1350
+ }
1351
+ newMessages = [this.promptMessage];
1352
+ this.chatHistory = await this.memoryRecorder.prepareRun(runId, newMessages);
1353
+ const pendingTurnMessages = this.memoryRecorder.pendingTurnMessages(newMessages);
1186
1354
  await this.runRunStartHook(newMessages);
1187
1355
  while (currentTurns <= this.maxTurnCount + 1) {
1188
1356
  const prompt = newMessages.at(-1);
@@ -1198,7 +1366,10 @@ var PromptRequest = class _PromptRequest {
1198
1366
  const dynamicContext = await fetchDynamicContext(this.agent, ragText);
1199
1367
  const toolDefs = await fetchToolDefinitions(this.agent, ragText);
1200
1368
  let request = new CompletionRequestBuilder(this.agent.model, prompt).instructions(this.agent.instructions).messages(historyForRequest).documents([...this.agent.staticContext, ...dynamicContext]).tools(toolDefs).temperature(this.agent.temperature).maxTokens(this.agent.maxTokens).additionalParams(this.agent.additionalParams).toolChoice(this.agent.toolChoice).outputSchema(this.agent.outputSchema).build();
1201
- request = await this.runCompletionRequestMiddlewares(request, currentTurns);
1369
+ request = await this.runCompletionRequestMiddlewares(
1370
+ request,
1371
+ currentTurns
1372
+ );
1202
1373
  let response;
1203
1374
  try {
1204
1375
  response = await this.runCompletion(request, currentTurns, runObservers);
@@ -1210,27 +1381,46 @@ var PromptRequest = class _PromptRequest {
1210
1381
  usage = Usage.add(usage, response.usage);
1211
1382
  await this.runCompletionResponseHook(prompt, response, newMessages);
1212
1383
  await this.runTurnEndHook(currentTurns, response, newMessages);
1213
- const assistantMessage = Message.assistant(response.choice, response.messageId);
1214
- newMessages.push(assistantMessage);
1215
- await this.memoryRecorder.commitMessages(
1216
- runId,
1217
- currentTurns,
1218
- [assistantMessage],
1219
- pendingTurnMessages
1220
- );
1221
1384
  const toolCalls = response.choice.filter(
1222
1385
  (item) => item.type === "tool_call"
1223
1386
  );
1387
+ const assistantMessage = Message.assistant(response.choice, response.messageId);
1388
+ newMessages.push(assistantMessage);
1224
1389
  if (toolCalls.length === 0) {
1390
+ if (this.steeringMessages.length > 0) {
1391
+ await this.memoryRecorder.commitMessages(
1392
+ runId,
1393
+ currentTurns,
1394
+ [assistantMessage],
1395
+ pendingTurnMessages
1396
+ );
1397
+ }
1225
1398
  if (await this.drainSteeringMessages(runId, currentTurns, newMessages, pendingTurnMessages)) {
1226
1399
  await this.memoryRecorder.commitCompletedTurn(runId, currentTurns, pendingTurnMessages);
1227
1400
  continue;
1228
1401
  }
1402
+ const guardedOutput = await this.runOutputGuardrailsForResponse(
1403
+ runId,
1404
+ usage,
1405
+ response,
1406
+ newMessages,
1407
+ runObservers
1408
+ );
1409
+ response = guardedOutput.response;
1410
+ const finalAssistantMessage = Message.assistant(response.choice, response.messageId);
1411
+ newMessages[newMessages.length - 1] = finalAssistantMessage;
1412
+ await this.memoryRecorder.commitMessages(
1413
+ runId,
1414
+ currentTurns,
1415
+ [finalAssistantMessage],
1416
+ pendingTurnMessages
1417
+ );
1229
1418
  const result = {
1230
- output: textFromAssistantContent(response.choice),
1419
+ output: guardedOutput.output,
1231
1420
  usage,
1232
1421
  messages: [...newMessages],
1233
- trace: runObservers.trace
1422
+ trace: runObservers.trace,
1423
+ guardrails: [...this.guardrailDecisions]
1234
1424
  };
1235
1425
  await this.runRunEndHook(result, newMessages);
1236
1426
  await runObservers.end(result);
@@ -1243,6 +1433,12 @@ var PromptRequest = class _PromptRequest {
1243
1433
  this.runState = "completed";
1244
1434
  return result;
1245
1435
  }
1436
+ await this.memoryRecorder.commitMessages(
1437
+ runId,
1438
+ currentTurns,
1439
+ [assistantMessage],
1440
+ pendingTurnMessages
1441
+ );
1246
1442
  const toolResults = await this.executeToolCalls(
1247
1443
  runId,
1248
1444
  toolCalls,
@@ -1253,6 +1449,9 @@ var PromptRequest = class _PromptRequest {
1253
1449
  turn: currentTurns,
1254
1450
  runObservers,
1255
1451
  toolDefinitions: request.tools
1452
+ },
1453
+ async (decision) => {
1454
+ await this.recordGuardrailDecision(decision, runObservers);
1256
1455
  }
1257
1456
  );
1258
1457
  const toolMessage = Message.tool(toolResults);
@@ -1281,18 +1480,51 @@ var PromptRequest = class _PromptRequest {
1281
1480
  }
1282
1481
  this.startRun();
1283
1482
  const runId = globalThis.crypto.randomUUID();
1284
- const newMessages = [this.promptMessage];
1285
- this.chatHistory = await this.memoryRecorder.prepareRun(runId, newMessages);
1286
- const pendingTurnMessages = this.memoryRecorder.pendingTurnMessages(newMessages);
1287
- let usage = Usage.empty();
1288
- let currentTurns = 0;
1289
- let lastPrompt = this.promptMessage;
1290
- const runObservers = await this.startRunObservers();
1291
1483
  const emit = async (event) => {
1292
1484
  await this.recordAgentEvent(runId, event);
1293
1485
  return event;
1294
1486
  };
1487
+ let usage = Usage.empty();
1488
+ let currentTurns = 0;
1489
+ let lastPrompt = this.promptMessage;
1490
+ let newMessages = [this.promptMessage];
1491
+ const runObservers = await this.startRunObservers();
1492
+ const bufferOutputDeltas = hasEnforcedOutputGuardrails(this.guardrailPolicies);
1295
1493
  try {
1494
+ const inputResult = await runInputGuardrails(this.guardrailPolicies, {
1495
+ prompt: this.promptMessage,
1496
+ history: this.chatHistory,
1497
+ inputText: textFromMessage(this.promptMessage),
1498
+ run: this.guardrailRunContext(runId)
1499
+ });
1500
+ for (const decision of inputResult.decisions) {
1501
+ await this.recordGuardrailDecision(decision, runObservers);
1502
+ yield await emit({ type: "guardrail_decision", decision });
1503
+ }
1504
+ this.promptMessage = inputResult.prompt;
1505
+ if (inputResult.blocked) {
1506
+ const output = inputResult.message ?? "The request was blocked by a guardrail.";
1507
+ const result = {
1508
+ output,
1509
+ usage: Usage.empty(),
1510
+ messages: [this.promptMessage, Message.assistant(output)],
1511
+ guardrails: [...this.guardrailDecisions]
1512
+ };
1513
+ await runObservers.end(result);
1514
+ this.runState = "completed";
1515
+ yield await emit({
1516
+ type: "final",
1517
+ runId,
1518
+ output: result.output,
1519
+ usage: result.usage,
1520
+ messages: result.messages,
1521
+ guardrails: result.guardrails
1522
+ });
1523
+ return;
1524
+ }
1525
+ newMessages = [this.promptMessage];
1526
+ this.chatHistory = await this.memoryRecorder.prepareRun(runId, newMessages);
1527
+ const pendingTurnMessages = this.memoryRecorder.pendingTurnMessages(newMessages);
1296
1528
  await this.runRunStartHook(newMessages);
1297
1529
  while (currentTurns <= this.maxTurnCount + 1) {
1298
1530
  const prompt = newMessages.at(-1);
@@ -1314,7 +1546,10 @@ var PromptRequest = class _PromptRequest {
1314
1546
  const dynamicContext = await fetchDynamicContext(this.agent, ragText);
1315
1547
  const toolDefs = await fetchToolDefinitions(this.agent, ragText);
1316
1548
  let request = new CompletionRequestBuilder(this.agent.model, prompt).instructions(this.agent.instructions).messages(historyForRequest).documents([...this.agent.staticContext, ...dynamicContext]).tools(toolDefs).temperature(this.agent.temperature).maxTokens(this.agent.maxTokens).additionalParams(this.agent.additionalParams).toolChoice(this.agent.toolChoice).outputSchema(this.agent.outputSchema).build();
1317
- request = await this.runCompletionRequestMiddlewares(request, currentTurns);
1549
+ request = await this.runCompletionRequestMiddlewares(
1550
+ request,
1551
+ currentTurns
1552
+ );
1318
1553
  assertCompletionRequestSupported(this.agent.model, request, { streaming: true });
1319
1554
  const providerRequest = this.providerTraceRequest(request, { stream: true });
1320
1555
  const generationObservers = await runObservers.startGeneration(
@@ -1348,7 +1583,8 @@ var PromptRequest = class _PromptRequest {
1348
1583
  if (mapped.type === "tool_call") {
1349
1584
  emittedToolCallIds.add(mapped.toolCall.id);
1350
1585
  }
1351
- if (!bufferResponseEvents) {
1586
+ const shouldBuffer = bufferResponseEvents || bufferOutputDeltas && (mapped.type === "text_delta" || mapped.type === "reasoning_delta");
1587
+ if (!shouldBuffer) {
1352
1588
  yield await emit(addTurn(currentTurns, mapped));
1353
1589
  }
1354
1590
  }
@@ -1370,39 +1606,67 @@ var PromptRequest = class _PromptRequest {
1370
1606
  usage = Usage.add(usage, response.usage);
1371
1607
  await this.runCompletionResponseHook(prompt, response, newMessages);
1372
1608
  await this.runTurnEndHook(currentTurns, response, newMessages);
1373
- const assistantMessage = Message.assistant(response.choice, response.messageId);
1374
- newMessages.push(assistantMessage);
1375
- await this.memoryRecorder.commitMessages(
1376
- runId,
1377
- currentTurns,
1378
- [assistantMessage],
1379
- pendingTurnMessages
1380
- );
1381
1609
  const toolCalls = response.choice.filter(
1382
1610
  (item) => item.type === "tool_call"
1383
1611
  );
1384
- if (bufferResponseEvents) {
1385
- for (const event of responseStreamEvents(currentTurns, response)) {
1386
- yield await emit(event);
1387
- }
1388
- } else {
1389
- for (const toolCall of toolCalls) {
1390
- if (!emittedToolCallIds.has(toolCall.id)) {
1391
- yield await emit({ type: "tool_call", turn: currentTurns, toolCall });
1612
+ let assistantMessage = Message.assistant(response.choice, response.messageId);
1613
+ newMessages.push(assistantMessage);
1614
+ if (toolCalls.length === 0) {
1615
+ let emittedTurnEnd = false;
1616
+ if (!bufferOutputDeltas) {
1617
+ if (bufferResponseEvents) {
1618
+ for (const event of responseStreamEvents(currentTurns, response)) {
1619
+ yield await emit(event);
1620
+ }
1392
1621
  }
1622
+ yield await emit({ type: "turn_end", turn: currentTurns, response });
1623
+ emittedTurnEnd = true;
1624
+ }
1625
+ if (this.steeringMessages.length > 0) {
1626
+ await this.memoryRecorder.commitMessages(
1627
+ runId,
1628
+ currentTurns,
1629
+ [assistantMessage],
1630
+ pendingTurnMessages
1631
+ );
1393
1632
  }
1394
- }
1395
- yield await emit({ type: "turn_end", turn: currentTurns, response });
1396
- if (toolCalls.length === 0) {
1397
1633
  if (await this.drainSteeringMessages(runId, currentTurns, newMessages, pendingTurnMessages)) {
1398
1634
  await this.memoryRecorder.commitCompletedTurn(runId, currentTurns, pendingTurnMessages);
1399
1635
  continue;
1400
1636
  }
1637
+ const guardedOutput = await this.runOutputGuardrailsForResponse(
1638
+ runId,
1639
+ usage,
1640
+ response,
1641
+ newMessages,
1642
+ runObservers
1643
+ );
1644
+ for (const decision of guardedOutput.decisions) {
1645
+ yield await emit({ type: "guardrail_decision", decision });
1646
+ }
1647
+ response = guardedOutput.response;
1648
+ assistantMessage = Message.assistant(response.choice, response.messageId);
1649
+ newMessages[newMessages.length - 1] = assistantMessage;
1650
+ await this.memoryRecorder.commitMessages(
1651
+ runId,
1652
+ currentTurns,
1653
+ [assistantMessage],
1654
+ pendingTurnMessages
1655
+ );
1656
+ if (!emittedTurnEnd && (bufferResponseEvents || bufferOutputDeltas)) {
1657
+ for (const event of responseStreamEvents(currentTurns, response)) {
1658
+ yield await emit(event);
1659
+ }
1660
+ }
1661
+ if (!emittedTurnEnd) {
1662
+ yield await emit({ type: "turn_end", turn: currentTurns, response });
1663
+ }
1401
1664
  const result = {
1402
- output: textFromAssistantContent(response.choice),
1665
+ output: guardedOutput.output,
1403
1666
  usage,
1404
1667
  messages: [...newMessages],
1405
- trace: runObservers.trace
1668
+ trace: runObservers.trace,
1669
+ guardrails: [...this.guardrailDecisions]
1406
1670
  };
1407
1671
  await this.runRunEndHook(result, newMessages);
1408
1672
  await runObservers.end(result);
@@ -1419,10 +1683,29 @@ var PromptRequest = class _PromptRequest {
1419
1683
  output: result.output,
1420
1684
  usage: result.usage,
1421
1685
  messages: result.messages,
1422
- trace: result.trace
1686
+ trace: result.trace,
1687
+ guardrails: result.guardrails
1423
1688
  });
1424
1689
  return;
1425
1690
  }
1691
+ if (bufferResponseEvents) {
1692
+ for (const event of responseStreamEvents(currentTurns, response)) {
1693
+ yield await emit(event);
1694
+ }
1695
+ } else {
1696
+ for (const toolCall of toolCalls) {
1697
+ if (!emittedToolCallIds.has(toolCall.id)) {
1698
+ yield await emit({ type: "tool_call", turn: currentTurns, toolCall });
1699
+ }
1700
+ }
1701
+ }
1702
+ await this.memoryRecorder.commitMessages(
1703
+ runId,
1704
+ currentTurns,
1705
+ [assistantMessage],
1706
+ pendingTurnMessages
1707
+ );
1708
+ yield await emit({ type: "turn_end", turn: currentTurns, response });
1426
1709
  const toolResultEvents = createAsyncQueue();
1427
1710
  const toolResultsPromise = this.executeToolCalls(
1428
1711
  runId,
@@ -1438,6 +1721,10 @@ var PromptRequest = class _PromptRequest {
1438
1721
  turn: currentTurns,
1439
1722
  runObservers,
1440
1723
  toolDefinitions: request.tools
1724
+ },
1725
+ async (decision) => {
1726
+ await this.recordGuardrailDecision(decision, runObservers);
1727
+ toolResultEvents.enqueue({ type: "guardrail_decision", decision });
1441
1728
  }
1442
1729
  );
1443
1730
  toolResultsPromise.then(
@@ -1505,11 +1792,12 @@ var PromptRequest = class _PromptRequest {
1505
1792
  };
1506
1793
  }
1507
1794
  }
1508
- async executeToolCalls(runId, toolCalls, newMessages, onResult, onStreamEvent, observation) {
1795
+ async executeToolCalls(runId, toolCalls, newMessages, onResult, onStreamEvent, observation, onGuardrailDecision) {
1509
1796
  const executor = new ToolCallExecutor(
1510
1797
  this.agent,
1511
1798
  this.activeHook,
1512
1799
  this.approvalOptions,
1800
+ this.guardrailPolicies,
1513
1801
  {
1514
1802
  runId,
1515
1803
  sessionId: this.memoryContext?.sessionId,
@@ -1517,10 +1805,51 @@ var PromptRequest = class _PromptRequest {
1517
1805
  },
1518
1806
  this.concurrency,
1519
1807
  this.requestMiddlewares,
1520
- (reason) => this.cancelled(newMessages, reason)
1808
+ (reason) => this.cancelled(newMessages, reason),
1809
+ onGuardrailDecision
1521
1810
  );
1522
1811
  return executor.execute(toolCalls, onResult, onStreamEvent, observation);
1523
1812
  }
1813
+ async runOutputGuardrailsForResponse(runId, usage, response, messages, runObservers) {
1814
+ const originalOutput = textFromAssistantContent(response.choice);
1815
+ const result = await runOutputGuardrails(this.guardrailPolicies, {
1816
+ outputText: originalOutput,
1817
+ messages: [...this.chatHistory, ...messages],
1818
+ usage,
1819
+ run: this.guardrailRunContext(runId)
1820
+ });
1821
+ for (const decision of result.decisions) {
1822
+ await this.recordGuardrailDecision(decision, runObservers);
1823
+ }
1824
+ const output = result.blocked ? result.message ?? "The response was blocked by a guardrail." : result.outputText;
1825
+ if (output === originalOutput) {
1826
+ return { output, response, decisions: result.decisions };
1827
+ }
1828
+ return {
1829
+ output,
1830
+ response: {
1831
+ ...response,
1832
+ choice: [AssistantContent.text(output)]
1833
+ },
1834
+ decisions: result.decisions
1835
+ };
1836
+ }
1837
+ async recordGuardrailDecision(decision, runObservers) {
1838
+ this.guardrailDecisions.push(decision);
1839
+ await runObservers.event({
1840
+ name: "guardrail.decision",
1841
+ level: decision.action === "block" ? "WARNING" : "DEFAULT",
1842
+ attributes: guardrailDecisionAttributes(decision)
1843
+ });
1844
+ }
1845
+ guardrailRunContext(runId) {
1846
+ return compact({
1847
+ agentId: this.agent.id,
1848
+ runId,
1849
+ sessionId: this.memoryContext?.sessionId,
1850
+ metadata: this.memoryContext?.metadata
1851
+ });
1852
+ }
1524
1853
  async startRunObservers() {
1525
1854
  const failOnObserverError = this.traceOptions?.failOnObserverError === true || this.agent.observers.some((registration) => registration.failOnObserverError === true);
1526
1855
  return startAgentRunObservers(
@@ -1770,6 +2099,33 @@ function responseStreamEvents(turn, response) {
1770
2099
  }
1771
2100
  return events;
1772
2101
  }
2102
+ function textFromMessage(message) {
2103
+ if (message.role === "system") {
2104
+ return message.content;
2105
+ }
2106
+ return message.content.flatMap((content) => {
2107
+ if (content.type === "text") {
2108
+ return [content.text];
2109
+ }
2110
+ if (content.type === "document" && content.source.type === "text") {
2111
+ return [content.source.text];
2112
+ }
2113
+ return [];
2114
+ }).join("\n");
2115
+ }
2116
+ function guardrailDecisionAttributes(decision) {
2117
+ return compact({
2118
+ policyId: decision.policyId,
2119
+ guardrailId: decision.guardrailId,
2120
+ boundary: decision.boundary,
2121
+ mode: decision.mode,
2122
+ action: decision.action,
2123
+ applied: decision.applied,
2124
+ reason: decision.reason,
2125
+ message: decision.message,
2126
+ latencyMs: decision.latencyMs
2127
+ });
2128
+ }
1773
2129
 
1774
2130
  export {
1775
2131
  MaxTurnsError,
@@ -1778,4 +2134,4 @@ export {
1778
2134
  extractRagText,
1779
2135
  PromptRequest
1780
2136
  };
1781
- //# sourceMappingURL=chunk-SISUMRUX.js.map
2137
+ //# sourceMappingURL=chunk-KTTIPWE7.js.map