@kenkaiiii/gg-agent 5.61.0 → 5.61.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.cjs +73 -12
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +73 -12
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -326,6 +326,35 @@ function abortableSleep(ms, signal) {
|
|
|
326
326
|
signal?.addEventListener("abort", onAbort, { once: true });
|
|
327
327
|
});
|
|
328
328
|
}
|
|
329
|
+
var PREFILL_TIMEOUT_MS_PER_1K_TOKENS = 640;
|
|
330
|
+
var STREAM_FIRST_EVENT_TIMEOUT_MS = 45e3;
|
|
331
|
+
var STREAM_FIRST_EVENT_TIMEOUT_MAX_MS = 18e4;
|
|
332
|
+
var STREAM_FIRST_EVENT_TIMEOUT_SCALE_MIN_TOKENS = 2e4;
|
|
333
|
+
function scaledFirstEventTimeoutMs(promptTokens) {
|
|
334
|
+
if (promptTokens < STREAM_FIRST_EVENT_TIMEOUT_SCALE_MIN_TOKENS) return null;
|
|
335
|
+
return Math.min(
|
|
336
|
+
STREAM_FIRST_EVENT_TIMEOUT_MAX_MS,
|
|
337
|
+
STREAM_FIRST_EVENT_TIMEOUT_MS + promptTokens / 1e3 * PREFILL_TIMEOUT_MS_PER_1K_TOKENS
|
|
338
|
+
);
|
|
339
|
+
}
|
|
340
|
+
var CACHE_HEALTH_MIN_PROMPT_TOKENS = 4e4;
|
|
341
|
+
var CACHE_HEALTH_LOW_RATIO = 0.5;
|
|
342
|
+
function assessCacheHealth(usage) {
|
|
343
|
+
const input = usage.inputTokens ?? 0;
|
|
344
|
+
const cacheRead = usage.cacheRead ?? 0;
|
|
345
|
+
const cacheWrite = usage.cacheWrite ?? 0;
|
|
346
|
+
const promptTokens = input + cacheRead + cacheWrite;
|
|
347
|
+
if (promptTokens < CACHE_HEALTH_MIN_PROMPT_TOKENS) {
|
|
348
|
+
return { ratio: null, promptTokens, cacheRead, low: false };
|
|
349
|
+
}
|
|
350
|
+
const ratio = cacheRead / promptTokens;
|
|
351
|
+
return {
|
|
352
|
+
ratio,
|
|
353
|
+
promptTokens,
|
|
354
|
+
cacheRead,
|
|
355
|
+
low: ratio < CACHE_HEALTH_LOW_RATIO
|
|
356
|
+
};
|
|
357
|
+
}
|
|
329
358
|
async function* agentLoop(messages, options) {
|
|
330
359
|
const maxTurns = options.maxTurns ?? DEFAULT_MAX_TURNS;
|
|
331
360
|
let effectiveMaxTurns = maxTurns;
|
|
@@ -367,6 +396,7 @@ async function* agentLoop(messages, options) {
|
|
|
367
396
|
let providerCalls = 0;
|
|
368
397
|
let nonStreamingCalls = 0;
|
|
369
398
|
let warnedNonStreaming = false;
|
|
399
|
+
let warnedPromptCacheMiss = false;
|
|
370
400
|
const MAX_OUTPUT_CEILING_RETRIES = 1;
|
|
371
401
|
let outputCeilingRetries = 0;
|
|
372
402
|
const ceilingKey = outputRouteKey({
|
|
@@ -376,7 +406,6 @@ async function* agentLoop(messages, options) {
|
|
|
376
406
|
});
|
|
377
407
|
const OVERLOAD_BASE_DELAY_MS = 2e3;
|
|
378
408
|
const OVERLOAD_MAX_DELAY_MS = 3e4;
|
|
379
|
-
const STREAM_FIRST_EVENT_TIMEOUT_MS = 45e3;
|
|
380
409
|
const STREAM_IDLE_TIMEOUT_MS = 9e4;
|
|
381
410
|
const STREAM_HARD_TIMEOUT_MS = 9e4;
|
|
382
411
|
const STREAM_OUTPUT_HARD_TIMEOUT_MS = 3e5;
|
|
@@ -385,8 +414,8 @@ async function* agentLoop(messages, options) {
|
|
|
385
414
|
const NON_STREAMING_HARD_TIMEOUT_MS = 3e5;
|
|
386
415
|
const usesSilentReasoningBudget = options.provider === "sakana" || options.provider === "openai" && options.thinking != null;
|
|
387
416
|
const localBackend = isLocalBackendUrl(options.baseUrl);
|
|
388
|
-
const
|
|
389
|
-
const
|
|
417
|
+
const baseFirstEventTimeoutMs = localBackend ? Number.POSITIVE_INFINITY : usesSilentReasoningBudget ? STREAM_THINKING_IDLE_TIMEOUT_MS : STREAM_FIRST_EVENT_TIMEOUT_MS;
|
|
418
|
+
const baseHardTimeoutMs = localBackend || usesSilentReasoningBudget ? STREAM_THINKING_HARD_TIMEOUT_MS : STREAM_HARD_TIMEOUT_MS;
|
|
390
419
|
const MAX_TOOLCALL_DELTA_CHARS = 1e6;
|
|
391
420
|
const MAX_TOOLCALL_DELTA_EVENTS = 2e4;
|
|
392
421
|
let logicalTurnStartedAt = 0;
|
|
@@ -398,17 +427,28 @@ async function* agentLoop(messages, options) {
|
|
|
398
427
|
turn++;
|
|
399
428
|
if (logicalTurnStartedAt === 0) logicalTurnStartedAt = Date.now();
|
|
400
429
|
toolMap = new Map((options.tools ?? []).map((t) => [t.name, t]));
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
if ("content" in p && typeof p.content === "string") msgChars += p.content.length;
|
|
409
|
-
}
|
|
430
|
+
let msgChars = 0;
|
|
431
|
+
for (const m of messages) {
|
|
432
|
+
if (typeof m.content === "string") msgChars += m.content.length;
|
|
433
|
+
else if (Array.isArray(m.content)) {
|
|
434
|
+
for (const p of m.content) {
|
|
435
|
+
if ("text" in p && typeof p.text === "string") msgChars += p.text.length;
|
|
436
|
+
if ("content" in p && typeof p.content === "string") msgChars += p.content.length;
|
|
410
437
|
}
|
|
411
438
|
}
|
|
439
|
+
}
|
|
440
|
+
let firstEventTimeoutMs;
|
|
441
|
+
let initialHardTimeoutMs;
|
|
442
|
+
if (baseFirstEventTimeoutMs === STREAM_FIRST_EVENT_TIMEOUT_MS) {
|
|
443
|
+
const promptTokens = Math.ceil(msgChars / 3);
|
|
444
|
+
const scaled = scaledFirstEventTimeoutMs(promptTokens);
|
|
445
|
+
firstEventTimeoutMs = scaled ?? baseFirstEventTimeoutMs;
|
|
446
|
+
initialHardTimeoutMs = Math.max(baseHardTimeoutMs, firstEventTimeoutMs + 3e4);
|
|
447
|
+
} else {
|
|
448
|
+
firstEventTimeoutMs = baseFirstEventTimeoutMs;
|
|
449
|
+
initialHardTimeoutMs = baseHardTimeoutMs;
|
|
450
|
+
}
|
|
451
|
+
if (_diagFn) {
|
|
412
452
|
diag("turn_start", {
|
|
413
453
|
turn,
|
|
414
454
|
messages: messages.length,
|
|
@@ -1018,6 +1058,27 @@ async function* agentLoop(messages, options) {
|
|
|
1018
1058
|
if (response.usage.cacheWrite) {
|
|
1019
1059
|
totalUsage.cacheWrite = (totalUsage.cacheWrite ?? 0) + response.usage.cacheWrite;
|
|
1020
1060
|
}
|
|
1061
|
+
const cacheHealth = assessCacheHealth(response.usage);
|
|
1062
|
+
if (cacheHealth.ratio !== null) {
|
|
1063
|
+
diag("cache_health", {
|
|
1064
|
+
promptTokens: cacheHealth.promptTokens,
|
|
1065
|
+
cacheRead: cacheHealth.cacheRead,
|
|
1066
|
+
ratio: Math.round(cacheHealth.ratio * 100) / 100,
|
|
1067
|
+
provider: options.provider,
|
|
1068
|
+
model: options.model
|
|
1069
|
+
});
|
|
1070
|
+
if (cacheHealth.low && !warnedPromptCacheMiss) {
|
|
1071
|
+
warnedPromptCacheMiss = true;
|
|
1072
|
+
diag("prompt_cache_miss", {
|
|
1073
|
+
promptTokens: cacheHealth.promptTokens,
|
|
1074
|
+
cacheRead: cacheHealth.cacheRead,
|
|
1075
|
+
ratio: Math.round(cacheHealth.ratio * 100) / 100,
|
|
1076
|
+
provider: options.provider,
|
|
1077
|
+
model: options.model,
|
|
1078
|
+
impact: "large prompts are consistently served mostly uncached \u2014 every turn re-prefills the whole context; if this persists, lower the provider's compaction latency cap (resolveCompactionPolicy)"
|
|
1079
|
+
});
|
|
1080
|
+
}
|
|
1081
|
+
}
|
|
1021
1082
|
if (!emptyExhausted) {
|
|
1022
1083
|
messages.push(response.message);
|
|
1023
1084
|
latestProviderUsage = response.usage;
|