@kenkaiiii/gg-agent 5.16.0 → 5.17.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.d.cts CHANGED
@@ -49,11 +49,26 @@ interface AgentToolCallEndEvent {
49
49
  isError: boolean;
50
50
  durationMs: number;
51
51
  }
52
+ interface AgentTurnTiming {
53
+ /** Logical turn start, before context transforms or provider retries. Unix epoch milliseconds. */
54
+ startedAt: number;
55
+ /** First provider event, or full-response arrival for non-streaming fallback. */
56
+ firstProviderEventAt?: number;
57
+ /** Successful provider response completion. Unix epoch milliseconds. */
58
+ completedAt: number;
59
+ /** Time spent awaiting provider attempts, including failed attempts but excluding retry backoff. */
60
+ providerDurationMs: number;
61
+ /** Time from logical turn start to the first provider event. */
62
+ ttftMs?: number;
63
+ /** Output tokens divided by total provider duration. Omitted when no rate is measurable. */
64
+ outputTokensPerSecond?: number;
65
+ }
52
66
  interface AgentTurnEndEvent {
53
67
  type: "turn_end";
54
68
  turn: number;
55
69
  stopReason: StopReason;
56
70
  usage: Usage;
71
+ timing: AgentTurnTiming;
57
72
  }
58
73
  interface AgentDoneEvent {
59
74
  type: "agent_done";
@@ -129,6 +144,8 @@ interface AgentOptions {
129
144
  priorMessages?: Message[];
130
145
  tools?: AgentTool[];
131
146
  serverTools?: ServerToolDefinition[];
147
+ /** Control whether tools may/must be called, or select a named tool when supported. */
148
+ toolChoice?: StreamOptions["toolChoice"];
132
149
  maxTurns?: number;
133
150
  maxTokens?: number;
134
151
  temperature?: number;
@@ -282,4 +299,4 @@ declare function isBillingError(err: unknown): boolean;
282
299
  declare function isUsageLimitError(err: unknown): boolean;
283
300
  declare function agentLoop(messages: Message[], options: AgentOptions): AsyncGenerator<AgentEvent, AgentResult>;
284
301
 
285
- export { Agent, type AgentDoneEvent, type AgentErrorEvent, type AgentEvent, type AgentFollowUpMessageEvent, type AgentOptions, type AgentResult, type AgentRetryEvent, type AgentServerToolCallEvent, type AgentServerToolResultEvent, type AgentSteeringMessageEvent, AgentStream, type AgentTextDeltaEvent, type AgentThinkingDeltaEvent, type AgentTool, type AgentToolCallDeltaEvent, type AgentToolCallEndEvent, type AgentToolCallStartEvent, type AgentToolCallUpdateEvent, type AgentTurnEndEvent, type StreamDiagnosticFn, type StructuredToolResult, type ToolContext, type ToolExecuteResult, type ToolExecutionMode, agentLoop, isAbortError, isBillingError, isContextOverflow, isUsageLimitError, setStreamDiagnostic };
302
+ export { Agent, type AgentDoneEvent, type AgentErrorEvent, type AgentEvent, type AgentFollowUpMessageEvent, type AgentOptions, type AgentResult, type AgentRetryEvent, type AgentServerToolCallEvent, type AgentServerToolResultEvent, type AgentSteeringMessageEvent, AgentStream, type AgentTextDeltaEvent, type AgentThinkingDeltaEvent, type AgentTool, type AgentToolCallDeltaEvent, type AgentToolCallEndEvent, type AgentToolCallStartEvent, type AgentToolCallUpdateEvent, type AgentTurnEndEvent, type AgentTurnTiming, type StreamDiagnosticFn, type StructuredToolResult, type ToolContext, type ToolExecuteResult, type ToolExecutionMode, agentLoop, isAbortError, isBillingError, isContextOverflow, isUsageLimitError, setStreamDiagnostic };
package/dist/index.d.ts CHANGED
@@ -49,11 +49,26 @@ interface AgentToolCallEndEvent {
49
49
  isError: boolean;
50
50
  durationMs: number;
51
51
  }
52
+ interface AgentTurnTiming {
53
+ /** Logical turn start, before context transforms or provider retries. Unix epoch milliseconds. */
54
+ startedAt: number;
55
+ /** First provider event, or full-response arrival for non-streaming fallback. */
56
+ firstProviderEventAt?: number;
57
+ /** Successful provider response completion. Unix epoch milliseconds. */
58
+ completedAt: number;
59
+ /** Time spent awaiting provider attempts, including failed attempts but excluding retry backoff. */
60
+ providerDurationMs: number;
61
+ /** Time from logical turn start to the first provider event. */
62
+ ttftMs?: number;
63
+ /** Output tokens divided by total provider duration. Omitted when no rate is measurable. */
64
+ outputTokensPerSecond?: number;
65
+ }
52
66
  interface AgentTurnEndEvent {
53
67
  type: "turn_end";
54
68
  turn: number;
55
69
  stopReason: StopReason;
56
70
  usage: Usage;
71
+ timing: AgentTurnTiming;
57
72
  }
58
73
  interface AgentDoneEvent {
59
74
  type: "agent_done";
@@ -129,6 +144,8 @@ interface AgentOptions {
129
144
  priorMessages?: Message[];
130
145
  tools?: AgentTool[];
131
146
  serverTools?: ServerToolDefinition[];
147
+ /** Control whether tools may/must be called, or select a named tool when supported. */
148
+ toolChoice?: StreamOptions["toolChoice"];
132
149
  maxTurns?: number;
133
150
  maxTokens?: number;
134
151
  temperature?: number;
@@ -282,4 +299,4 @@ declare function isBillingError(err: unknown): boolean;
282
299
  declare function isUsageLimitError(err: unknown): boolean;
283
300
  declare function agentLoop(messages: Message[], options: AgentOptions): AsyncGenerator<AgentEvent, AgentResult>;
284
301
 
285
- export { Agent, type AgentDoneEvent, type AgentErrorEvent, type AgentEvent, type AgentFollowUpMessageEvent, type AgentOptions, type AgentResult, type AgentRetryEvent, type AgentServerToolCallEvent, type AgentServerToolResultEvent, type AgentSteeringMessageEvent, AgentStream, type AgentTextDeltaEvent, type AgentThinkingDeltaEvent, type AgentTool, type AgentToolCallDeltaEvent, type AgentToolCallEndEvent, type AgentToolCallStartEvent, type AgentToolCallUpdateEvent, type AgentTurnEndEvent, type StreamDiagnosticFn, type StructuredToolResult, type ToolContext, type ToolExecuteResult, type ToolExecutionMode, agentLoop, isAbortError, isBillingError, isContextOverflow, isUsageLimitError, setStreamDiagnostic };
302
+ export { Agent, type AgentDoneEvent, type AgentErrorEvent, type AgentEvent, type AgentFollowUpMessageEvent, type AgentOptions, type AgentResult, type AgentRetryEvent, type AgentServerToolCallEvent, type AgentServerToolResultEvent, type AgentSteeringMessageEvent, AgentStream, type AgentTextDeltaEvent, type AgentThinkingDeltaEvent, type AgentTool, type AgentToolCallDeltaEvent, type AgentToolCallEndEvent, type AgentToolCallStartEvent, type AgentToolCallUpdateEvent, type AgentTurnEndEvent, type AgentTurnTiming, type StreamDiagnosticFn, type StructuredToolResult, type ToolContext, type ToolExecuteResult, type ToolExecutionMode, agentLoop, isAbortError, isBillingError, isContextOverflow, isUsageLimitError, setStreamDiagnostic };
package/dist/index.js CHANGED
@@ -7,7 +7,8 @@ import {
7
7
  stream,
8
8
  EventStream,
9
9
  GGAIError,
10
- isHardBillingMessage
10
+ isHardBillingMessage,
11
+ redactValue
11
12
  } from "@kenkaiiii/gg-ai";
12
13
  var DEFAULT_MAX_TURNS = 300;
13
14
  var _diagFn = null;
@@ -224,10 +225,14 @@ async function* agentLoop(messages, options) {
224
225
  const initialHardTimeoutMs = isSakana ? STREAM_THINKING_HARD_TIMEOUT_MS : STREAM_HARD_TIMEOUT_MS;
225
226
  const MAX_TOOLCALL_DELTA_CHARS = 1e6;
226
227
  const MAX_TOOLCALL_DELTA_EVENTS = 2e4;
228
+ let logicalTurnStartedAt = 0;
229
+ let firstProviderEventAt;
230
+ let providerDurationMs = 0;
227
231
  try {
228
232
  while (turn < maxTurns) {
229
233
  options.signal?.throwIfAborted();
230
234
  turn++;
235
+ if (logicalTurnStartedAt === 0) logicalTurnStartedAt = Date.now();
231
236
  toolMap = new Map((options.tools ?? []).map((t) => [t.name, t]));
232
237
  if (_diagFn) {
233
238
  let msgChars = 0;
@@ -277,6 +282,7 @@ async function* agentLoop(messages, options) {
277
282
  let idleTimer = null;
278
283
  let hardTimer = null;
279
284
  let idleTimedOut = false;
285
+ let providerAttemptStartedAt;
280
286
  let streamEventCount = 0;
281
287
  let lastEventTime = Date.now();
282
288
  let streamCallStart = Date.now();
@@ -321,12 +327,14 @@ async function* agentLoop(messages, options) {
321
327
  try {
322
328
  diag("stream_call", { nonStreaming: useNonStreamingFallback });
323
329
  streamCallStart = Date.now();
330
+ providerAttemptStartedAt = streamCallStart;
324
331
  const result = stream({
325
332
  provider: options.provider,
326
333
  model: options.model,
327
334
  messages,
328
335
  tools: options.tools,
329
336
  serverTools: options.serverTools,
337
+ toolChoice: options.toolChoice,
330
338
  webSearch: options.webSearch,
331
339
  maxTokens: options.maxTokens,
332
340
  temperature: options.temperature,
@@ -365,6 +373,7 @@ async function* agentLoop(messages, options) {
365
373
  maxConsumerLagMs = consumerLag;
366
374
  }
367
375
  streamEventCount++;
376
+ if (firstProviderEventAt === void 0) firstProviderEventAt = pullTime;
368
377
  eventTypeCounts[event.type] = (eventTypeCounts[event.type] ?? 0) + 1;
369
378
  lastEventType = event.type;
370
379
  if ((event.type === "text_delta" || event.type === "server_toolcall" || event.type === "toolcall_delta") && !hasReceivedEvent) {
@@ -457,6 +466,7 @@ async function* agentLoop(messages, options) {
457
466
  eventTypes: eventTypeCounts
458
467
  });
459
468
  response = await result.response;
469
+ if (firstProviderEventAt === void 0) firstProviderEventAt = Date.now();
460
470
  } catch (err) {
461
471
  const errMsg = err instanceof Error ? err.message : String(err);
462
472
  diag("stream_error", {
@@ -680,6 +690,9 @@ async function* agentLoop(messages, options) {
680
690
  });
681
691
  throw err;
682
692
  } finally {
693
+ if (providerAttemptStartedAt !== void 0) {
694
+ providerDurationMs += Date.now() - providerAttemptStartedAt;
695
+ }
683
696
  if (idleTimer) clearTimeout(idleTimer);
684
697
  if (hardTimer) clearTimeout(hardTimer);
685
698
  options.signal?.removeEventListener("abort", forwardAbort);
@@ -723,11 +736,27 @@ async function* agentLoop(messages, options) {
723
736
  totalUsage.cacheWrite = (totalUsage.cacheWrite ?? 0) + response.usage.cacheWrite;
724
737
  }
725
738
  messages.push(response.message);
739
+ const completedAt = Date.now();
740
+ const outputTokensPerSecond = providerDurationMs > 0 && response.usage.outputTokens > 0 ? response.usage.outputTokens / (providerDurationMs / 1e3) : void 0;
741
+ const timing = {
742
+ startedAt: logicalTurnStartedAt,
743
+ ...firstProviderEventAt !== void 0 ? {
744
+ firstProviderEventAt,
745
+ ttftMs: Math.max(0, firstProviderEventAt - logicalTurnStartedAt)
746
+ } : {},
747
+ completedAt,
748
+ providerDurationMs,
749
+ ...outputTokensPerSecond !== void 0 ? { outputTokensPerSecond } : {}
750
+ };
751
+ logicalTurnStartedAt = 0;
752
+ firstProviderEventAt = void 0;
753
+ providerDurationMs = 0;
726
754
  yield {
727
755
  type: "turn_end",
728
756
  turn,
729
757
  stopReason: response.stopReason,
730
- usage: response.usage
758
+ usage: response.usage,
759
+ timing
731
760
  };
732
761
  if (response.stopReason === "pause_turn") {
733
762
  consecutivePauses++;
@@ -908,8 +937,8 @@ async function executeSingleToolCall(toolCall, options, pushEvent) {
908
937
  };
909
938
  const raw = await tool.execute(parsed, ctx);
910
939
  const normalized = normalizeToolResult(raw);
911
- resultContent = normalized.content;
912
- details = normalized.details;
940
+ resultContent = redactValue(normalized.content);
941
+ details = redactValue(normalized.details);
913
942
  for (const key of options.invalidToolArgumentCounts.keys()) {
914
943
  if (key.startsWith(`${toolCall.name}:`)) options.invalidToolArgumentCounts.delete(key);
915
944
  }
@@ -937,10 +966,12 @@ async function executeSingleToolCall(toolCall, options, pushEvent) {
937
966
  );
938
967
  }
939
968
  } else {
940
- resultContent = err instanceof Error ? err.message : String(err);
969
+ resultContent = redactValue(err instanceof Error ? err.message : String(err));
941
970
  }
942
971
  }
943
972
  }
973
+ resultContent = redactValue(resultContent);
974
+ details = redactValue(details);
944
975
  const durationMs = Date.now() - startTime;
945
976
  pushEvent({
946
977
  type: "tool_call_end",