@prestyj/agent 5.5.0 → 5.7.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/dist/index.cjs CHANGED
@@ -296,10 +296,14 @@ async function* agentLoop(messages, options) {
296
296
  const initialHardTimeoutMs = isSakana ? STREAM_THINKING_HARD_TIMEOUT_MS : STREAM_HARD_TIMEOUT_MS;
297
297
  const MAX_TOOLCALL_DELTA_CHARS = 1e6;
298
298
  const MAX_TOOLCALL_DELTA_EVENTS = 2e4;
299
+ let logicalTurnStartedAt = 0;
300
+ let firstProviderEventAt;
301
+ let providerDurationMs = 0;
299
302
  try {
300
303
  while (turn < maxTurns) {
301
304
  options.signal?.throwIfAborted();
302
305
  turn++;
306
+ if (logicalTurnStartedAt === 0) logicalTurnStartedAt = Date.now();
303
307
  toolMap = new Map((options.tools ?? []).map((t) => [t.name, t]));
304
308
  if (_diagFn) {
305
309
  let msgChars = 0;
@@ -349,6 +353,7 @@ async function* agentLoop(messages, options) {
349
353
  let idleTimer = null;
350
354
  let hardTimer = null;
351
355
  let idleTimedOut = false;
356
+ let providerAttemptStartedAt;
352
357
  let streamEventCount = 0;
353
358
  let lastEventTime = Date.now();
354
359
  let streamCallStart = Date.now();
@@ -394,12 +399,14 @@ async function* agentLoop(messages, options) {
394
399
  try {
395
400
  diag("stream_call", { nonStreaming: useNonStreamingFallback });
396
401
  streamCallStart = Date.now();
402
+ providerAttemptStartedAt = streamCallStart;
397
403
  const result = (0, import_ai.stream)({
398
404
  provider: options.provider,
399
405
  model: options.model,
400
406
  messages,
401
407
  tools: options.tools,
402
408
  serverTools: options.serverTools,
409
+ toolChoice: options.toolChoice,
403
410
  webSearch: options.webSearch,
404
411
  maxTokens: options.maxTokens,
405
412
  temperature: options.temperature,
@@ -442,6 +449,7 @@ async function* agentLoop(messages, options) {
442
449
  maxConsumerLagMs = consumerLag;
443
450
  }
444
451
  streamEventCount++;
452
+ if (firstProviderEventAt === void 0) firstProviderEventAt = pullTime;
445
453
  eventTypeCounts[event.type] = (eventTypeCounts[event.type] ?? 0) + 1;
446
454
  lastEventType = event.type;
447
455
  if ((event.type === "text_delta" || event.type === "server_toolcall" || event.type === "toolcall_delta") && !hasReceivedEvent) {
@@ -534,6 +542,7 @@ async function* agentLoop(messages, options) {
534
542
  eventTypes: eventTypeCounts
535
543
  });
536
544
  response = await abortablePromise(result.response, streamController.signal);
545
+ if (firstProviderEventAt === void 0) firstProviderEventAt = Date.now();
537
546
  } catch (err) {
538
547
  if (streamController.signal.aborted) closeIterator(streamIterator);
539
548
  const errMsg = err instanceof Error ? err.message : String(err);
@@ -758,6 +767,9 @@ async function* agentLoop(messages, options) {
758
767
  });
759
768
  throw err;
760
769
  } finally {
770
+ if (providerAttemptStartedAt !== void 0) {
771
+ providerDurationMs += Date.now() - providerAttemptStartedAt;
772
+ }
761
773
  if (idleTimer) clearTimeout(idleTimer);
762
774
  if (hardTimer) clearTimeout(hardTimer);
763
775
  options.signal?.removeEventListener("abort", forwardAbort);
@@ -801,11 +813,27 @@ async function* agentLoop(messages, options) {
801
813
  totalUsage.cacheWrite = (totalUsage.cacheWrite ?? 0) + response.usage.cacheWrite;
802
814
  }
803
815
  messages.push(response.message);
816
+ const completedAt = Date.now();
817
+ const outputTokensPerSecond = providerDurationMs > 0 && response.usage.outputTokens > 0 ? response.usage.outputTokens / (providerDurationMs / 1e3) : void 0;
818
+ const timing = {
819
+ startedAt: logicalTurnStartedAt,
820
+ ...firstProviderEventAt !== void 0 ? {
821
+ firstProviderEventAt,
822
+ ttftMs: Math.max(0, firstProviderEventAt - logicalTurnStartedAt)
823
+ } : {},
824
+ completedAt,
825
+ providerDurationMs,
826
+ ...outputTokensPerSecond !== void 0 ? { outputTokensPerSecond } : {}
827
+ };
828
+ logicalTurnStartedAt = 0;
829
+ firstProviderEventAt = void 0;
830
+ providerDurationMs = 0;
804
831
  yield {
805
832
  type: "turn_end",
806
833
  turn,
807
834
  stopReason: response.stopReason,
808
- usage: response.usage
835
+ usage: response.usage,
836
+ timing
809
837
  };
810
838
  if (response.stopReason === "pause_turn") {
811
839
  consecutivePauses++;
@@ -989,8 +1017,8 @@ async function executeSingleToolCall(toolCall, options, pushEvent) {
989
1017
  ctx.signal
990
1018
  );
991
1019
  const normalized = normalizeToolResult(raw);
992
- resultContent = normalized.content;
993
- details = normalized.details;
1020
+ resultContent = (0, import_ai.redactValue)(normalized.content);
1021
+ details = (0, import_ai.redactValue)(normalized.details);
994
1022
  for (const key of options.invalidToolArgumentCounts.keys()) {
995
1023
  if (key.startsWith(`${toolCall.name}:`)) options.invalidToolArgumentCounts.delete(key);
996
1024
  }
@@ -1018,10 +1046,12 @@ async function executeSingleToolCall(toolCall, options, pushEvent) {
1018
1046
  );
1019
1047
  }
1020
1048
  } else {
1021
- resultContent = err instanceof Error ? err.message : String(err);
1049
+ resultContent = (0, import_ai.redactValue)(err instanceof Error ? err.message : String(err));
1022
1050
  }
1023
1051
  }
1024
1052
  }
1053
+ resultContent = (0, import_ai.redactValue)(resultContent);
1054
+ details = (0, import_ai.redactValue)(details);
1025
1055
  const durationMs = Date.now() - startTime;
1026
1056
  pushEvent({
1027
1057
  type: "tool_call_end",