@kenkaiiii/gg-agent 4.11.3 → 4.12.1

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.js CHANGED
@@ -220,23 +220,25 @@ async function* agentLoop(messages, options) {
220
220
  while (turn < maxTurns) {
221
221
  options.signal?.throwIfAborted();
222
222
  turn++;
223
- let msgChars = 0;
224
- for (const m of messages) {
225
- if (typeof m.content === "string") msgChars += m.content.length;
226
- else if (Array.isArray(m.content)) {
227
- for (const p of m.content) {
228
- if ("text" in p && typeof p.text === "string") msgChars += p.text.length;
229
- if ("content" in p && typeof p.content === "string") msgChars += p.content.length;
223
+ if (_diagFn) {
224
+ let msgChars = 0;
225
+ for (const m of messages) {
226
+ if (typeof m.content === "string") msgChars += m.content.length;
227
+ else if (Array.isArray(m.content)) {
228
+ for (const p of m.content) {
229
+ if ("text" in p && typeof p.text === "string") msgChars += p.text.length;
230
+ if ("content" in p && typeof p.content === "string") msgChars += p.content.length;
231
+ }
230
232
  }
231
233
  }
234
+ diag("turn_start", {
235
+ turn,
236
+ messages: messages.length,
237
+ chars: msgChars,
238
+ provider: options.provider,
239
+ model: options.model
240
+ });
232
241
  }
233
- diag("turn_start", {
234
- turn,
235
- messages: messages.length,
236
- chars: msgChars,
237
- provider: options.provider,
238
- model: options.model
239
- });
240
242
  if (firstTurn && options.getSteeringMessages) {
241
243
  const steering = await options.getSteeringMessages();
242
244
  if (steering && steering.length > 0) {
@@ -772,7 +774,7 @@ async function* agentLoop(messages, options) {
772
774
  const hasSequentialToolCall = toolCalls.some(
773
775
  (toolCall) => toolMap.get(toolCall.name)?.executionMode === "sequential"
774
776
  );
775
- const executionResult = hasSequentialToolCall ? yield* executeToolCallsSequential(toolCalls, toolResults, executionOptions) : yield* executeToolCallsParallel(toolCalls, toolResults, executionOptions);
777
+ const executionResult = hasSequentialToolCall ? yield* executeToolCallsMixed(toolCalls, toolResults, executionOptions) : yield* executeToolCallsParallel(toolCalls, toolResults, executionOptions);
776
778
  messages.push({ role: "tool", content: executionResult.toolResults });
777
779
  const toolsAborted = executionResult.aborted;
778
780
  if (fatalToolArgumentError) {
@@ -832,8 +834,10 @@ async function executeSingleToolCall(toolCall, options, pushEvent) {
832
834
  } else {
833
835
  try {
834
836
  const parsed = tool.parameters.parse(toolCall.args);
837
+ const callerSignal = options.signal;
838
+ const toolTimeout = AbortSignal.timeout(3e5);
835
839
  const ctx = {
836
- signal: options.signal ?? AbortSignal.timeout(3e5),
840
+ signal: callerSignal ? AbortSignal.any([callerSignal, toolTimeout]) : toolTimeout,
837
841
  toolCallId: toolCall.id,
838
842
  onUpdate: (update) => {
839
843
  pushEvent({
@@ -882,22 +886,59 @@ async function executeSingleToolCall(toolCall, options, pushEvent) {
882
886
  });
883
887
  return { toolCallId: toolCall.id, content: resultContent, isError };
884
888
  }
885
- async function* executeToolCallsSequential(toolCalls, initialToolResults, options) {
889
+ async function* executeToolCallsMixed(toolCalls, initialToolResults, options) {
886
890
  const eventStream = new EventStream();
887
891
  const state = { finalized: false };
888
892
  const resultsById = /* @__PURE__ */ new Map();
889
893
  const abortHandler = () => eventStream.abort(new Error("aborted"));
890
894
  options.signal?.addEventListener("abort", abortHandler, { once: true });
895
+ const phases = [];
896
+ let currentParallel = [];
897
+ for (const toolCall of toolCalls) {
898
+ const isSequential = options.toolMap.get(toolCall.name)?.executionMode === "sequential";
899
+ if (isSequential) {
900
+ if (currentParallel.length > 0) {
901
+ phases.push({ parallel: currentParallel, sequential: null });
902
+ currentParallel = [];
903
+ }
904
+ phases.push({ parallel: [], sequential: toolCall });
905
+ } else {
906
+ currentParallel.push(toolCall);
907
+ }
908
+ }
909
+ if (currentParallel.length > 0) {
910
+ phases.push({ parallel: currentParallel, sequential: null });
911
+ }
891
912
  void (async () => {
892
913
  try {
893
- for (const toolCall of toolCalls) {
914
+ for (const phase of phases) {
894
915
  if (options.signal?.aborted) break;
895
- const record = await executeSingleToolCall(
896
- toolCall,
897
- options,
898
- (event) => pushToolEvent(eventStream, state, event)
899
- );
900
- resultsById.set(record.toolCallId, record);
916
+ if (phase.sequential) {
917
+ const record = await executeSingleToolCall(
918
+ phase.sequential,
919
+ options,
920
+ (event) => pushToolEvent(eventStream, state, event)
921
+ );
922
+ resultsById.set(record.toolCallId, record);
923
+ } else if (phase.parallel.length === 1) {
924
+ const record = await executeSingleToolCall(
925
+ phase.parallel[0],
926
+ options,
927
+ (event) => pushToolEvent(eventStream, state, event)
928
+ );
929
+ resultsById.set(record.toolCallId, record);
930
+ } else {
931
+ await Promise.all(
932
+ phase.parallel.map(async (toolCall) => {
933
+ const record = await executeSingleToolCall(
934
+ toolCall,
935
+ options,
936
+ (event) => pushToolEvent(eventStream, state, event)
937
+ );
938
+ resultsById.set(record.toolCallId, record);
939
+ })
940
+ );
941
+ }
901
942
  }
902
943
  if (!state.finalized) eventStream.close();
903
944
  } catch (err) {