@prestyj/agent 4.12.1 → 4.13.3

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/dist/index.cjs CHANGED
@@ -293,23 +293,25 @@ async function* agentLoop(messages, options) {
293
293
  while (turn < maxTurns) {
294
294
  options.signal?.throwIfAborted();
295
295
  turn++;
296
- let msgChars = 0;
297
- for (const m of messages) {
298
- if (typeof m.content === "string") msgChars += m.content.length;
299
- else if (Array.isArray(m.content)) {
300
- for (const p of m.content) {
301
- if ("text" in p && typeof p.text === "string") msgChars += p.text.length;
302
- if ("content" in p && typeof p.content === "string") msgChars += p.content.length;
296
+ if (_diagFn) {
297
+ let msgChars = 0;
298
+ for (const m of messages) {
299
+ if (typeof m.content === "string") msgChars += m.content.length;
300
+ else if (Array.isArray(m.content)) {
301
+ for (const p of m.content) {
302
+ if ("text" in p && typeof p.text === "string") msgChars += p.text.length;
303
+ if ("content" in p && typeof p.content === "string") msgChars += p.content.length;
304
+ }
303
305
  }
304
306
  }
307
+ diag("turn_start", {
308
+ turn,
309
+ messages: messages.length,
310
+ chars: msgChars,
311
+ provider: options.provider,
312
+ model: options.model
313
+ });
305
314
  }
306
- diag("turn_start", {
307
- turn,
308
- messages: messages.length,
309
- chars: msgChars,
310
- provider: options.provider,
311
- model: options.model
312
- });
313
315
  if (firstTurn && options.getSteeringMessages) {
314
316
  const steering = await options.getSteeringMessages();
315
317
  if (steering && steering.length > 0) {
@@ -851,7 +853,7 @@ async function* agentLoop(messages, options) {
851
853
  const hasSequentialToolCall = toolCalls.some(
852
854
  (toolCall) => toolMap.get(toolCall.name)?.executionMode === "sequential"
853
855
  );
854
- const executionResult = hasSequentialToolCall ? yield* executeToolCallsSequential(toolCalls, toolResults, executionOptions) : yield* executeToolCallsParallel(toolCalls, toolResults, executionOptions);
856
+ const executionResult = hasSequentialToolCall ? yield* executeToolCallsMixed(toolCalls, toolResults, executionOptions) : yield* executeToolCallsParallel(toolCalls, toolResults, executionOptions);
855
857
  messages.push({ role: "tool", content: executionResult.toolResults });
856
858
  const toolsAborted = executionResult.aborted;
857
859
  if (fatalToolArgumentError) {
@@ -911,8 +913,10 @@ async function executeSingleToolCall(toolCall, options, pushEvent) {
911
913
  } else {
912
914
  try {
913
915
  const parsed = tool.parameters.parse(toolCall.args);
916
+ const callerSignal = options.signal;
917
+ const toolTimeout = AbortSignal.timeout(3e5);
914
918
  const ctx = {
915
- signal: options.signal ?? AbortSignal.timeout(3e5),
919
+ signal: callerSignal ? AbortSignal.any([callerSignal, toolTimeout]) : toolTimeout,
916
920
  toolCallId: toolCall.id,
917
921
  onUpdate: (update) => {
918
922
  pushEvent({
@@ -964,22 +968,59 @@ async function executeSingleToolCall(toolCall, options, pushEvent) {
964
968
  });
965
969
  return { toolCallId: toolCall.id, content: resultContent, isError };
966
970
  }
967
- async function* executeToolCallsSequential(toolCalls, initialToolResults, options) {
971
+ async function* executeToolCallsMixed(toolCalls, initialToolResults, options) {
968
972
  const eventStream = new import_ai.EventStream();
969
973
  const state = { finalized: false };
970
974
  const resultsById = /* @__PURE__ */ new Map();
971
975
  const abortHandler = () => eventStream.abort(new Error("aborted"));
972
976
  options.signal?.addEventListener("abort", abortHandler, { once: true });
977
+ const phases = [];
978
+ let currentParallel = [];
979
+ for (const toolCall of toolCalls) {
980
+ const isSequential = options.toolMap.get(toolCall.name)?.executionMode === "sequential";
981
+ if (isSequential) {
982
+ if (currentParallel.length > 0) {
983
+ phases.push({ parallel: currentParallel, sequential: null });
984
+ currentParallel = [];
985
+ }
986
+ phases.push({ parallel: [], sequential: toolCall });
987
+ } else {
988
+ currentParallel.push(toolCall);
989
+ }
990
+ }
991
+ if (currentParallel.length > 0) {
992
+ phases.push({ parallel: currentParallel, sequential: null });
993
+ }
973
994
  void (async () => {
974
995
  try {
975
- for (const toolCall of toolCalls) {
996
+ for (const phase of phases) {
976
997
  if (options.signal?.aborted) break;
977
- const record = await executeSingleToolCall(
978
- toolCall,
979
- options,
980
- (event) => pushToolEvent(eventStream, state, event)
981
- );
982
- resultsById.set(record.toolCallId, record);
998
+ if (phase.sequential) {
999
+ const record = await executeSingleToolCall(
1000
+ phase.sequential,
1001
+ options,
1002
+ (event) => pushToolEvent(eventStream, state, event)
1003
+ );
1004
+ resultsById.set(record.toolCallId, record);
1005
+ } else if (phase.parallel.length === 1) {
1006
+ const record = await executeSingleToolCall(
1007
+ phase.parallel[0],
1008
+ options,
1009
+ (event) => pushToolEvent(eventStream, state, event)
1010
+ );
1011
+ resultsById.set(record.toolCallId, record);
1012
+ } else {
1013
+ await Promise.all(
1014
+ phase.parallel.map(async (toolCall) => {
1015
+ const record = await executeSingleToolCall(
1016
+ toolCall,
1017
+ options,
1018
+ (event) => pushToolEvent(eventStream, state, event)
1019
+ );
1020
+ resultsById.set(record.toolCallId, record);
1021
+ })
1022
+ );
1023
+ }
983
1024
  }
984
1025
  if (!state.finalized) eventStream.close();
985
1026
  } catch (err) {