@anvia/core 0.4.2 → 0.5.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.
@@ -7,7 +7,7 @@ import {
7
7
  import {
8
8
  ToolSet,
9
9
  toolResultContentToText
10
- } from "./chunk-35GF7P43.js";
10
+ } from "./chunk-S7EOE6EC.js";
11
11
  import {
12
12
  createTool
13
13
  } from "./chunk-P425B6GR.js";
@@ -745,17 +745,17 @@ function isEmptyToolArguments(value) {
745
745
  // src/agent/tool-execution.ts
746
746
  var MCP_TOOL_METADATA_KEY = /* @__PURE__ */ Symbol.for("anvia.mcp.tool.metadata");
747
747
  var ToolCallExecutor = class {
748
- constructor(agent, activeHook, concurrency, requestToolMiddlewares, cancel) {
748
+ constructor(agent, activeHook, concurrency, requestMiddlewares, cancel) {
749
749
  this.agent = agent;
750
750
  this.activeHook = activeHook;
751
751
  this.concurrency = concurrency;
752
- this.requestToolMiddlewares = requestToolMiddlewares;
752
+ this.requestMiddlewares = requestMiddlewares;
753
753
  this.cancel = cancel;
754
754
  }
755
755
  agent;
756
756
  activeHook;
757
757
  concurrency;
758
- requestToolMiddlewares;
758
+ requestMiddlewares;
759
759
  cancel;
760
760
  async execute(toolCalls, onResult, onStreamEvent, observation) {
761
761
  return mapWithConcurrency(toolCalls, this.concurrency, async (toolCall) => {
@@ -813,19 +813,25 @@ var ToolCallExecutor = class {
813
813
  }
814
814
  let output;
815
815
  let skipped = false;
816
+ let effectiveArgs = args;
816
817
  if (callAction?.type === "skip") {
817
818
  output = callAction.reason;
818
819
  skipped = true;
819
820
  } else {
821
+ effectiveArgs = await this.runToolInputMiddlewares({
822
+ ...hookArgs,
823
+ turn: observation?.turn ?? 0,
824
+ originalArgs: args
825
+ });
820
826
  try {
821
- output = await this.agent.callTool(toolCall.function.name, args, {
827
+ output = await this.agent.callTool(toolCall.function.name, effectiveArgs, {
822
828
  emitStreamEvent: async (event) => {
823
829
  await toolObservers?.streamEvent({
824
830
  turn: observation?.turn ?? 0,
825
831
  toolCall,
826
832
  toolName: toolCall.function.name,
827
833
  internalCallId,
828
- args,
834
+ args: effectiveArgs,
829
835
  ...toolCall.callId === void 0 ? {} : { toolCallId: toolCall.callId },
830
836
  event
831
837
  });
@@ -836,6 +842,24 @@ var ToolCallExecutor = class {
836
842
  }
837
843
  });
838
844
  } catch (error) {
845
+ const errorAction = await this.activeHook?.onToolError?.({
846
+ ...hookArgs,
847
+ args: effectiveArgs,
848
+ error,
849
+ run: runControl
850
+ });
851
+ await toolObservers?.error({
852
+ turn: observation?.turn ?? 0,
853
+ toolCall,
854
+ toolName: toolCall.function.name,
855
+ internalCallId,
856
+ args: effectiveArgs,
857
+ ...toolCall.callId === void 0 ? {} : { toolCallId: toolCall.callId },
858
+ error
859
+ });
860
+ if (errorAction?.type === "terminate") {
861
+ throw this.cancel(errorAction.reason);
862
+ }
839
863
  output = error instanceof Error ? error.toString() : String(error);
840
864
  }
841
865
  }
@@ -844,6 +868,7 @@ var ToolCallExecutor = class {
844
868
  if (this.agent.shouldApplyToolMiddleware(toolCall.function.name)) {
845
869
  const middlewareReplacement = await this.runToolResultMiddlewares({
846
870
  ...hookArgs,
871
+ args: effectiveArgs,
847
872
  result,
848
873
  originalResult: result,
849
874
  structuredResult,
@@ -852,12 +877,13 @@ var ToolCallExecutor = class {
852
877
  });
853
878
  if (middlewareReplacement !== void 0) {
854
879
  output = middlewareReplacement;
855
- result = middlewareReplacement;
856
- structuredResult = void 0;
880
+ result = toolOutputToText(middlewareReplacement);
881
+ structuredResult = toolOutputToStructuredResult(middlewareReplacement);
857
882
  }
858
883
  }
859
884
  const resultAction = await this.activeHook?.onToolResult?.({
860
885
  ...hookArgs,
886
+ args: effectiveArgs,
861
887
  result,
862
888
  structuredResult,
863
889
  run: runControl
@@ -867,7 +893,7 @@ var ToolCallExecutor = class {
867
893
  toolCall,
868
894
  toolName: toolCall.function.name,
869
895
  internalCallId,
870
- args,
896
+ args: effectiveArgs,
871
897
  result,
872
898
  structuredResult,
873
899
  skipped,
@@ -880,7 +906,7 @@ var ToolCallExecutor = class {
880
906
  type: "tool_result",
881
907
  toolName: toolCall.function.name,
882
908
  internalCallId,
883
- args,
909
+ args: effectiveArgs,
884
910
  result,
885
911
  structuredResult
886
912
  };
@@ -893,20 +919,62 @@ var ToolCallExecutor = class {
893
919
  }
894
920
  async runToolResultMiddlewares(args) {
895
921
  let result = args.result;
922
+ let structuredResult = args.structuredResult;
896
923
  let replaced = false;
897
- for (const middleware of [...this.agent.toolMiddlewares, ...this.requestToolMiddlewares]) {
898
- const replacement = await middleware.onResult?.({
924
+ for (const middleware of this.activeMiddlewares()) {
925
+ const outputReplacement = await middleware.onToolOutput?.({
926
+ ...args,
927
+ result,
928
+ structuredResult
929
+ });
930
+ if (outputReplacement !== void 0) {
931
+ const normalized = normalizeToolOutputMiddlewareResult(outputReplacement);
932
+ if (normalized.result !== void 0) {
933
+ result = normalized.result;
934
+ structuredResult = void 0;
935
+ }
936
+ if (normalized.structuredResult !== void 0) {
937
+ structuredResult = normalized.structuredResult;
938
+ result = toolResultContentToText(normalized.structuredResult);
939
+ }
940
+ replaced = true;
941
+ }
942
+ const legacyReplacement = await middleware.onResult?.({
899
943
  ...args,
900
- result
944
+ result,
945
+ structuredResult
901
946
  });
902
- if (replacement !== void 0) {
903
- result = replacement;
947
+ if (legacyReplacement !== void 0) {
948
+ result = legacyReplacement;
949
+ structuredResult = void 0;
904
950
  replaced = true;
905
951
  }
906
952
  }
907
- return replaced ? result : void 0;
953
+ return replaced ? structuredResult ?? result : void 0;
954
+ }
955
+ async runToolInputMiddlewares(args) {
956
+ let current = args.args;
957
+ for (const middleware of this.activeMiddlewares()) {
958
+ const replacement = await middleware.onToolInput?.({
959
+ ...args,
960
+ args: current
961
+ });
962
+ if (replacement?.args !== void 0) {
963
+ current = typeof replacement.args === "string" ? replacement.args : JSON.stringify(replacement.args);
964
+ }
965
+ }
966
+ return current;
967
+ }
968
+ activeMiddlewares() {
969
+ return [...this.agent.middlewares, ...this.requestMiddlewares];
908
970
  }
909
971
  };
972
+ function normalizeToolOutputMiddlewareResult(result) {
973
+ if (typeof result === "string") {
974
+ return { result };
975
+ }
976
+ return result ?? {};
977
+ }
910
978
  function toolTraceMetadata(tool) {
911
979
  if (tool === void 0) {
912
980
  return void 0;
@@ -967,7 +1035,7 @@ var PromptRequest = class _PromptRequest {
967
1035
  activeHook;
968
1036
  concurrency = 1;
969
1037
  traceOptions;
970
- requestToolMiddlewares = [];
1038
+ requestMiddlewares = [];
971
1039
  memoryRecorder;
972
1040
  static fromAgent(agent, prompt, options = {}) {
973
1041
  const normalized = normalizePromptInput(prompt);
@@ -977,22 +1045,40 @@ var PromptRequest = class _PromptRequest {
977
1045
  this.maxTurnCount = maxTurns;
978
1046
  return this;
979
1047
  }
980
- requestHook(hook) {
1048
+ withHook(hook) {
981
1049
  this.activeHook = hook;
982
1050
  return this;
983
1051
  }
1052
+ /**
1053
+ * @deprecated Use `withHook` instead.
1054
+ */
1055
+ requestHook(hook) {
1056
+ return this.withHook(hook);
1057
+ }
984
1058
  withToolConcurrency(concurrency) {
985
1059
  this.concurrency = Math.max(1, concurrency);
986
1060
  return this;
987
1061
  }
988
- withToolMiddleware(middleware) {
989
- this.requestToolMiddlewares.push(middleware);
1062
+ withMiddleware(middleware) {
1063
+ this.requestMiddlewares.push(middleware);
990
1064
  return this;
991
1065
  }
992
- withToolMiddlewares(middlewares) {
993
- this.requestToolMiddlewares.push(...middlewares);
1066
+ withMiddlewares(middlewares) {
1067
+ this.requestMiddlewares.push(...middlewares);
994
1068
  return this;
995
1069
  }
1070
+ /**
1071
+ * @deprecated Use `withMiddleware` instead.
1072
+ */
1073
+ withToolMiddleware(middleware) {
1074
+ return this.withMiddleware(middleware);
1075
+ }
1076
+ /**
1077
+ * @deprecated Use `withMiddlewares` instead.
1078
+ */
1079
+ withToolMiddlewares(middlewares) {
1080
+ return this.withMiddlewares(middlewares);
1081
+ }
996
1082
  withTrace(trace) {
997
1083
  this.traceOptions = trace;
998
1084
  return this;
@@ -1007,6 +1093,7 @@ var PromptRequest = class _PromptRequest {
1007
1093
  let lastPrompt = this.promptMessage;
1008
1094
  const runObservers = await this.startRunObservers();
1009
1095
  try {
1096
+ await this.runRunStartHook(newMessages);
1010
1097
  while (currentTurns <= this.maxTurnCount + 1) {
1011
1098
  const prompt = newMessages.at(-1);
1012
1099
  if (prompt === void 0) {
@@ -1015,14 +1102,24 @@ var PromptRequest = class _PromptRequest {
1015
1102
  lastPrompt = prompt;
1016
1103
  currentTurns += 1;
1017
1104
  const historyForRequest = [...this.chatHistory, ...newMessages.slice(0, -1)];
1105
+ await this.runTurnStartHook(currentTurns, prompt, historyForRequest, newMessages);
1018
1106
  await this.runCompletionCallHook(prompt, historyForRequest, newMessages);
1019
1107
  const ragText = extractRagText(prompt);
1020
1108
  const dynamicContext = await fetchDynamicContext(this.agent, ragText);
1021
1109
  const toolDefs = await fetchToolDefinitions(this.agent, ragText);
1022
- const 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();
1023
- const response = await this.runCompletion(request, currentTurns, runObservers);
1110
+ 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();
1111
+ request = await this.runCompletionRequestMiddlewares(request, currentTurns);
1112
+ let response;
1113
+ try {
1114
+ response = await this.runCompletion(request, currentTurns, runObservers);
1115
+ } catch (error) {
1116
+ await this.runCompletionErrorHook(prompt, error, newMessages);
1117
+ throw error;
1118
+ }
1119
+ response = await this.runCompletionResponseMiddlewares(request, response, currentTurns);
1024
1120
  usage = Usage.add(usage, response.usage);
1025
1121
  await this.runCompletionResponseHook(prompt, response, newMessages);
1122
+ await this.runTurnEndHook(currentTurns, response, newMessages);
1026
1123
  const assistantMessage = Message.assistant(response.choice, response.messageId);
1027
1124
  newMessages.push(assistantMessage);
1028
1125
  await this.memoryRecorder.commitMessages(
@@ -1047,6 +1144,7 @@ var PromptRequest = class _PromptRequest {
1047
1144
  messages: [...newMessages],
1048
1145
  trace: runObservers.trace
1049
1146
  };
1147
+ await this.runRunEndHook(result, newMessages);
1050
1148
  await runObservers.end(result);
1051
1149
  return result;
1052
1150
  }
@@ -1073,9 +1171,10 @@ var PromptRequest = class _PromptRequest {
1073
1171
  }
1074
1172
  throw new MaxTurnsError(this.maxTurnCount, [...this.chatHistory, ...newMessages], lastPrompt);
1075
1173
  } catch (error) {
1076
- await runObservers.error({ error, usage, messages: [...newMessages] });
1077
- await this.memoryRecorder.recordError(runId, error, newMessages);
1078
- throw error;
1174
+ const finalError = await this.runRunErrorHook(error, usage, newMessages);
1175
+ await runObservers.error({ error: finalError, usage, messages: [...newMessages] });
1176
+ await this.memoryRecorder.recordError(runId, finalError, newMessages);
1177
+ throw finalError;
1079
1178
  }
1080
1179
  }
1081
1180
  async *stream() {
@@ -1095,6 +1194,7 @@ var PromptRequest = class _PromptRequest {
1095
1194
  return event;
1096
1195
  };
1097
1196
  try {
1197
+ await this.runRunStartHook(newMessages);
1098
1198
  while (currentTurns <= this.maxTurnCount + 1) {
1099
1199
  const prompt = newMessages.at(-1);
1100
1200
  if (prompt === void 0) {
@@ -1109,11 +1209,13 @@ var PromptRequest = class _PromptRequest {
1109
1209
  prompt,
1110
1210
  history: historyForRequest
1111
1211
  });
1212
+ await this.runTurnStartHook(currentTurns, prompt, historyForRequest, newMessages);
1112
1213
  await this.runCompletionCallHook(prompt, historyForRequest, newMessages);
1113
1214
  const ragText = extractRagText(prompt);
1114
1215
  const dynamicContext = await fetchDynamicContext(this.agent, ragText);
1115
1216
  const toolDefs = await fetchToolDefinitions(this.agent, ragText);
1116
- const 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();
1217
+ 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();
1218
+ request = await this.runCompletionRequestMiddlewares(request, currentTurns);
1117
1219
  assertCompletionRequestSupported(this.agent.model, request, { streaming: true });
1118
1220
  const providerRequest = this.providerTraceRequest(request, { stream: true });
1119
1221
  const generationObservers = await runObservers.startGeneration({
@@ -1144,16 +1246,19 @@ var PromptRequest = class _PromptRequest {
1144
1246
  }
1145
1247
  } catch (error) {
1146
1248
  await generationObservers.error({ turn: currentTurns, error });
1249
+ await this.runCompletionErrorHook(prompt, error, newMessages);
1147
1250
  throw error;
1148
1251
  }
1149
- const response = accumulator.response();
1252
+ let response = accumulator.response();
1150
1253
  await generationObservers.end({
1151
1254
  turn: currentTurns,
1152
1255
  response,
1153
1256
  ...firstDeltaMs === void 0 ? {} : { firstDeltaMs }
1154
1257
  });
1258
+ response = await this.runCompletionResponseMiddlewares(request, response, currentTurns);
1155
1259
  usage = Usage.add(usage, response.usage);
1156
1260
  await this.runCompletionResponseHook(prompt, response, newMessages);
1261
+ await this.runTurnEndHook(currentTurns, response, newMessages);
1157
1262
  const assistantMessage = Message.assistant(response.choice, response.messageId);
1158
1263
  newMessages.push(assistantMessage);
1159
1264
  await this.memoryRecorder.commitMessages(
@@ -1185,6 +1290,7 @@ var PromptRequest = class _PromptRequest {
1185
1290
  messages: [...newMessages],
1186
1291
  trace: runObservers.trace
1187
1292
  });
1293
+ await this.runRunEndHook({ output, usage, messages: [...newMessages] }, newMessages);
1188
1294
  await runObservers.end({ output, usage, messages: [...newMessages] });
1189
1295
  return;
1190
1296
  }
@@ -1224,10 +1330,11 @@ var PromptRequest = class _PromptRequest {
1224
1330
  }
1225
1331
  throw new MaxTurnsError(this.maxTurnCount, [...this.chatHistory, ...newMessages], lastPrompt);
1226
1332
  } catch (error) {
1227
- await runObservers.error({ error, usage, messages: [...newMessages] });
1228
- await this.memoryRecorder.recordError(runId, error, newMessages);
1229
- yield await emit({ type: "error", error });
1230
- throw error;
1333
+ const finalError = await this.runRunErrorHook(error, usage, newMessages);
1334
+ await runObservers.error({ error: finalError, usage, messages: [...newMessages] });
1335
+ await this.memoryRecorder.recordError(runId, finalError, newMessages);
1336
+ yield await emit({ type: "error", error: finalError });
1337
+ throw finalError;
1231
1338
  }
1232
1339
  }
1233
1340
  readableStream() {
@@ -1269,7 +1376,7 @@ var PromptRequest = class _PromptRequest {
1269
1376
  this.agent,
1270
1377
  this.activeHook,
1271
1378
  this.concurrency,
1272
- this.requestToolMiddlewares,
1379
+ this.requestMiddlewares,
1273
1380
  (reason) => this.cancelled(newMessages, reason)
1274
1381
  );
1275
1382
  return executor.execute(toolCalls, onResult, onStreamEvent, observation);
@@ -1324,6 +1431,90 @@ var PromptRequest = class _PromptRequest {
1324
1431
  throw this.cancelled(newMessages, action.reason);
1325
1432
  }
1326
1433
  }
1434
+ async runRunStartHook(newMessages) {
1435
+ const action = await this.activeHook?.onRunStart?.({
1436
+ prompt: this.promptMessage,
1437
+ history: this.chatHistory,
1438
+ maxTurns: this.maxTurnCount,
1439
+ run: runControl
1440
+ });
1441
+ if (action?.type === "terminate") {
1442
+ throw this.cancelled(newMessages, action.reason);
1443
+ }
1444
+ }
1445
+ async runRunEndHook(result, newMessages) {
1446
+ const action = await this.activeHook?.onRunEnd?.({
1447
+ output: result.output,
1448
+ usage: result.usage,
1449
+ messages: result.messages,
1450
+ run: runControl
1451
+ });
1452
+ if (action?.type === "terminate") {
1453
+ throw this.cancelled(newMessages, action.reason);
1454
+ }
1455
+ }
1456
+ async runRunErrorHook(error, usage, newMessages) {
1457
+ const action = await this.activeHook?.onRunError?.({
1458
+ error,
1459
+ usage,
1460
+ messages: [...this.chatHistory, ...newMessages],
1461
+ run: runControl
1462
+ });
1463
+ if (action?.type === "terminate") {
1464
+ return this.cancelled(newMessages, action.reason);
1465
+ }
1466
+ return error;
1467
+ }
1468
+ async runTurnStartHook(turn, prompt, history, newMessages) {
1469
+ const action = await this.activeHook?.onTurnStart?.({
1470
+ turn,
1471
+ prompt,
1472
+ history,
1473
+ run: runControl
1474
+ });
1475
+ if (action?.type === "terminate") {
1476
+ throw this.cancelled(newMessages, action.reason);
1477
+ }
1478
+ }
1479
+ async runTurnEndHook(turn, response, newMessages) {
1480
+ const action = await this.activeHook?.onTurnEnd?.({
1481
+ turn,
1482
+ response,
1483
+ run: runControl
1484
+ });
1485
+ if (action?.type === "terminate") {
1486
+ throw this.cancelled(newMessages, action.reason);
1487
+ }
1488
+ }
1489
+ async runCompletionRequestMiddlewares(request, turn) {
1490
+ let current = request;
1491
+ for (const middleware of this.activeMiddlewares()) {
1492
+ const replacement = await middleware.onCompletionRequest?.({
1493
+ turn,
1494
+ request: current,
1495
+ originalRequest: request
1496
+ });
1497
+ if (replacement?.request !== void 0) {
1498
+ current = replacement.request;
1499
+ }
1500
+ }
1501
+ return current;
1502
+ }
1503
+ async runCompletionResponseMiddlewares(request, response, turn) {
1504
+ let current = response;
1505
+ for (const middleware of this.activeMiddlewares()) {
1506
+ const replacement = await middleware.onCompletionResponse?.({
1507
+ turn,
1508
+ request,
1509
+ response: current,
1510
+ originalResponse: response
1511
+ });
1512
+ if (replacement?.response !== void 0) {
1513
+ current = replacement.response;
1514
+ }
1515
+ }
1516
+ return current;
1517
+ }
1327
1518
  async runCompletionResponseHook(prompt, response, newMessages) {
1328
1519
  const action = await this.activeHook?.onCompletionResponse?.({
1329
1520
  prompt,
@@ -1334,6 +1525,19 @@ var PromptRequest = class _PromptRequest {
1334
1525
  throw this.cancelled(newMessages, action.reason);
1335
1526
  }
1336
1527
  }
1528
+ async runCompletionErrorHook(prompt, error, newMessages) {
1529
+ const action = await this.activeHook?.onCompletionError?.({
1530
+ prompt,
1531
+ error,
1532
+ run: runControl
1533
+ });
1534
+ if (action?.type === "terminate") {
1535
+ throw this.cancelled(newMessages, action.reason);
1536
+ }
1537
+ }
1538
+ activeMiddlewares() {
1539
+ return [...this.agent.middlewares, ...this.requestMiddlewares];
1540
+ }
1337
1541
  cancelled(newMessages, reason) {
1338
1542
  return new PromptCancelledError([...this.chatHistory, ...newMessages], reason);
1339
1543
  }
@@ -1394,6 +1598,10 @@ var Agent = class {
1394
1598
  observers;
1395
1599
  dynamicContexts;
1396
1600
  dynamicTools;
1601
+ middlewares;
1602
+ /**
1603
+ * @deprecated Use `middlewares` instead.
1604
+ */
1397
1605
  toolMiddlewares;
1398
1606
  memory;
1399
1607
  eventStore;
@@ -1415,7 +1623,8 @@ var Agent = class {
1415
1623
  this.observers = options.observers ?? [];
1416
1624
  this.dynamicContexts = options.dynamicContexts ?? [];
1417
1625
  this.dynamicTools = options.dynamicTools ?? [];
1418
- this.toolMiddlewares = options.toolMiddlewares ?? [];
1626
+ this.middlewares = options.middlewares ?? options.toolMiddlewares ?? [];
1627
+ this.toolMiddlewares = this.middlewares;
1419
1628
  this.memory = options.memory;
1420
1629
  this.eventStore = options.eventStore;
1421
1630
  }
@@ -1543,4 +1752,4 @@ export {
1543
1752
  Agent,
1544
1753
  AgentSession
1545
1754
  };
1546
- //# sourceMappingURL=chunk-N7NMSGZI.js.map
1755
+ //# sourceMappingURL=chunk-ORLEOXD7.js.map