blun-king-cli 9.1.550 → 9.1.562
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/LIESMICH.txt +2 -2
- package/README.md +1 -1
- package/agent-spine-plugin/scripts/check-hosts.js +196 -0
- package/bin/compaction-transaction-policy.cjs +122 -0
- package/bin/default-model-output-budget-policy.cjs +28 -0
- package/bin/file-observation-policy.cjs +133 -0
- package/bin/launcher-runtime.js +0 -1
- package/bin/micro-compaction-policy.cjs +64 -0
- package/bin/mnemo-connect-heartbeat.cjs +1 -3
- package/bin/retry-checkpoint-policy.cjs +13 -0
- package/bin/session-checkpoint-policy.cjs +25 -0
- package/bin/startup-preferences.cjs +1 -0
- package/bin/tool-file-persistence.cjs +141 -0
- package/bin/tool-result-offload-policy.cjs +12 -33
- package/bin/turn-thinking-policy.cjs +2 -26
- package/bin/update-notice.js +16 -0
- package/blun.mjs +482 -170
- package/package.json +2 -1
- package/telegram-plugin/bin/telegram-mnemo-capture.cjs +1 -3
- package/bin/empty-response-retry-policy.cjs +0 -29
package/blun.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
// BLUN_BUILD_INPUT_SHA256:
|
|
2
|
+
// BLUN_BUILD_INPUT_SHA256:058cccc03f986fac95f89d198bb56bfa928b0c5117340651158d2f731509129c
|
|
3
3
|
import { fileURLToPath as __cjsShimFileURLToPath } from 'node:url';
|
|
4
4
|
import { dirname as __cjsShimDirname } from 'node:path';
|
|
5
5
|
const __filename = __cjsShimFileURLToPath(import.meta.url);
|
|
@@ -2798,8 +2798,6 @@ var init_blun = __esmMin((() => {
|
|
|
2798
2798
|
}
|
|
2799
2799
|
const kwargs = { ...this._generationKwargs };
|
|
2800
2800
|
for (const key of Object.keys(kwargs)) if (kwargs[key] === void 0) delete kwargs[key];
|
|
2801
|
-
if (kwargs["max_completion_tokens"] === void 0 && kwargs["max_tokens"] !== void 0) kwargs["max_completion_tokens"] = kwargs["max_tokens"];
|
|
2802
|
-
delete kwargs["max_tokens"];
|
|
2803
2801
|
const { extra_body: extraBody, ...requestKwargs } = kwargs;
|
|
2804
2802
|
const extraBodyRecord = typeof extraBody === "object" && extraBody !== null ? { ...extraBody } : {};
|
|
2805
2803
|
const thinking = sanitizeThinkingConfig(extraBodyRecord.thinking);
|
|
@@ -2910,7 +2908,7 @@ var init_blun = __esmMin((() => {
|
|
|
2910
2908
|
withMaxCompletionTokens(maxCompletionTokens, options) {
|
|
2911
2909
|
let cap = maxCompletionTokens;
|
|
2912
2910
|
if (options?.usedContextTokens !== void 0 && options?.maxContextTokens !== void 0 && options.maxContextTokens > 0) cap = Math.min(cap, options.maxContextTokens - options.usedContextTokens);
|
|
2913
|
-
return this._withGenerationKwargs({
|
|
2911
|
+
return this._withGenerationKwargs({ max_tokens: Math.max(1, cap) });
|
|
2914
2912
|
}
|
|
2915
2913
|
withExtraBody(extraBody) {
|
|
2916
2914
|
const oldExtra = this._generationKwargs.extra_body ?? {};
|
|
@@ -15931,6 +15929,8 @@ function loadRuntimeConfigSafe(filePath, env = process.env) {
|
|
|
15931
15929
|
} catch (error) {
|
|
15932
15930
|
envWarnings.push(`Ignoring BLUN_MODEL_* environment overrides: ${describeUnknownError(error)}`);
|
|
15933
15931
|
}
|
|
15932
|
+
const { applyDefaultModelOutputBudget } = createRequire(import.meta.url)("./bin/default-model-output-budget-policy.cjs");
|
|
15933
|
+
config = applyDefaultModelOutputBudget(config);
|
|
15934
15934
|
return {
|
|
15935
15935
|
config,
|
|
15936
15936
|
fileWarnings,
|
|
@@ -30347,7 +30347,6 @@ function resolveCompletionBudget(args) {
|
|
|
30347
30347
|
const fromLegacy = parseEnvBudget(env["BLUN_MODEL_MAX_TOKENS"]);
|
|
30348
30348
|
if (fromLegacy !== "absent") return fromLegacy === "disabled" ? void 0 : { hardCap: fromLegacy };
|
|
30349
30349
|
if (args.maxOutputSize !== void 0 && args.maxOutputSize > 0) return { hardCap: args.maxOutputSize };
|
|
30350
|
-
if (args.reservedContextSize !== void 0 && args.reservedContextSize > 0) return { fallback: args.reservedContextSize };
|
|
30351
30350
|
return { fallback: DEFAULT_UNKNOWN_CONTEXT_FALLBACK };
|
|
30352
30351
|
}
|
|
30353
30352
|
function parseEnvBudget(raw) {
|
|
@@ -30400,13 +30399,12 @@ function applyCompletionBudgetWithDetails(args) {
|
|
|
30400
30399
|
var MIN_FLOOR, DEFAULT_UNKNOWN_CONTEXT_FALLBACK, MIN_THINKING_COMPLETION_TOKENS, COMPLETION_CONTEXT_SAFETY_MARGIN;
|
|
30401
30400
|
var init_completion_budget = __esmMin((() => {
|
|
30402
30401
|
MIN_FLOOR = 1;
|
|
30403
|
-
DEFAULT_UNKNOWN_CONTEXT_FALLBACK =
|
|
30402
|
+
DEFAULT_UNKNOWN_CONTEXT_FALLBACK = 65536;
|
|
30404
30403
|
MIN_THINKING_COMPLETION_TOKENS = 1024;
|
|
30405
30404
|
COMPLETION_CONTEXT_SAFETY_MARGIN = 1e4;
|
|
30406
30405
|
}));
|
|
30407
30406
|
//#endregion
|
|
30408
30407
|
//#region ../../packages/agent-core/src/loop/retry.ts
|
|
30409
|
-
var { nextThinkingEffortForExhaustedEmpty } = createRequire(import.meta.url)("./bin/empty-response-retry-policy.cjs");
|
|
30410
30408
|
async function chatWithRetry(input) {
|
|
30411
30409
|
const maxAttempts = input.maxAttempts ?? 3;
|
|
30412
30410
|
if (input.llm.isRetryableError === void 0 || maxAttempts <= 1) {
|
|
@@ -30420,10 +30418,9 @@ async function chatWithRetry(input) {
|
|
|
30420
30418
|
}
|
|
30421
30419
|
const delays = retryBackoffDelays(maxAttempts);
|
|
30422
30420
|
let completionBudgetRetry;
|
|
30423
|
-
let thinkingEffortRetry;
|
|
30424
30421
|
let emptyRetryKind;
|
|
30425
30422
|
for (let attempt = 1;; attempt += 1) try {
|
|
30426
|
-
return await input.llm.chat(paramsForAttempt(input, attempt, maxAttempts, completionBudgetRetry
|
|
30423
|
+
return await input.llm.chat(paramsForAttempt(input, attempt, maxAttempts, completionBudgetRetry));
|
|
30427
30424
|
} catch (error) {
|
|
30428
30425
|
if (error instanceof APIEmptyResponseError && (emptyRetryKind !== void 0 || error.emptyResponseKind === "length" || error.emptyResponseKind === "stop")) {
|
|
30429
30426
|
logEmptyResponse(input, error, attempt);
|
|
@@ -30433,24 +30430,24 @@ async function chatWithRetry(input) {
|
|
|
30433
30430
|
throw terminal;
|
|
30434
30431
|
}
|
|
30435
30432
|
completionBudgetRetry = completionBudgetRetryForEmpty(error);
|
|
30436
|
-
thinkingEffortRetry = nextThinkingEffortForExhaustedEmpty({
|
|
30437
|
-
emptyResponseKind: error.emptyResponseKind,
|
|
30438
|
-
maxCompletionTokens: error.maxCompletionTokens,
|
|
30439
|
-
completionTokens: error.completionTokens,
|
|
30440
|
-
thinkingEffort: input.llm.thinkingEffort
|
|
30441
|
-
});
|
|
30442
30433
|
emptyRetryKind = error.emptyResponseKind;
|
|
30443
30434
|
input.params.signal.throwIfAborted();
|
|
30444
|
-
|
|
30445
|
-
|
|
30446
|
-
|
|
30447
|
-
|
|
30448
|
-
|
|
30449
|
-
|
|
30450
|
-
|
|
30451
|
-
|
|
30452
|
-
|
|
30453
|
-
|
|
30435
|
+
await persistRetrySchedule({
|
|
30436
|
+
dispatchRetrying: input.dispatchEvent,
|
|
30437
|
+
flush: input.checkpointBeforeRetryWait,
|
|
30438
|
+
signal: input.params.signal,
|
|
30439
|
+
event: {
|
|
30440
|
+
type: "step.retrying",
|
|
30441
|
+
turnId: input.turnId,
|
|
30442
|
+
step: input.currentStep,
|
|
30443
|
+
stepUuid: input.stepUuid,
|
|
30444
|
+
failedAttempt: attempt,
|
|
30445
|
+
nextAttempt: attempt + 1,
|
|
30446
|
+
maxAttempts,
|
|
30447
|
+
delayMs: 0,
|
|
30448
|
+
...completionBudgetIntervention(error, completionBudgetRetry),
|
|
30449
|
+
...retryErrorFields(error)
|
|
30450
|
+
}
|
|
30454
30451
|
});
|
|
30455
30452
|
continue;
|
|
30456
30453
|
}
|
|
@@ -30460,17 +30457,22 @@ async function chatWithRetry(input) {
|
|
|
30460
30457
|
}
|
|
30461
30458
|
const delayMs = retryDelayForError(error, delays[attempt - 1] ?? 0);
|
|
30462
30459
|
input.params.signal.throwIfAborted();
|
|
30463
|
-
|
|
30464
|
-
|
|
30465
|
-
|
|
30466
|
-
|
|
30467
|
-
|
|
30468
|
-
|
|
30469
|
-
|
|
30470
|
-
|
|
30471
|
-
|
|
30472
|
-
|
|
30473
|
-
|
|
30460
|
+
await persistRetrySchedule({
|
|
30461
|
+
dispatchRetrying: input.dispatchEvent,
|
|
30462
|
+
flush: input.checkpointBeforeRetryWait,
|
|
30463
|
+
signal: input.params.signal,
|
|
30464
|
+
event: {
|
|
30465
|
+
type: "step.retrying",
|
|
30466
|
+
turnId: input.turnId,
|
|
30467
|
+
step: input.currentStep,
|
|
30468
|
+
stepUuid: input.stepUuid,
|
|
30469
|
+
failedAttempt: attempt,
|
|
30470
|
+
nextAttempt: attempt + 1,
|
|
30471
|
+
maxAttempts,
|
|
30472
|
+
delayMs,
|
|
30473
|
+
outputMayHaveStarted: input.llm.didErrorEmitPartialOutput?.(error) === true,
|
|
30474
|
+
...retryErrorFields(error)
|
|
30475
|
+
}
|
|
30474
30476
|
});
|
|
30475
30477
|
await sleepForRetry(delayMs, input.params.signal);
|
|
30476
30478
|
}
|
|
@@ -30482,6 +30484,14 @@ function completionBudgetRetryForEmpty(error) {
|
|
|
30482
30484
|
multiplier: 2
|
|
30483
30485
|
};
|
|
30484
30486
|
}
|
|
30487
|
+
function completionBudgetIntervention(error, retryBudget) {
|
|
30488
|
+
const before = Number(error.maxCompletionTokens);
|
|
30489
|
+
if (retryBudget === void 0 || !Number.isFinite(before) || before <= 0) return {};
|
|
30490
|
+
return {
|
|
30491
|
+
completionBudgetBefore: before,
|
|
30492
|
+
completionBudgetAfter: Math.max(retryBudget.minimumCompletionTokens, Math.ceil(before * retryBudget.multiplier))
|
|
30493
|
+
};
|
|
30494
|
+
}
|
|
30485
30495
|
function retryDelayForError(error, fallbackDelayMs) {
|
|
30486
30496
|
if (!(error instanceof APIProviderRateLimitError) || error.retryAfterMs === null) return fallbackDelayMs;
|
|
30487
30497
|
return Math.max(fallbackDelayMs, error.retryAfterMs);
|
|
@@ -30495,12 +30505,11 @@ function logRequestFailure(input, error, attempt, maxAttempts) {
|
|
|
30495
30505
|
...retryErrorFields(error)
|
|
30496
30506
|
});
|
|
30497
30507
|
}
|
|
30498
|
-
function paramsForAttempt(input, attempt, maxAttempts, completionBudgetRetry
|
|
30508
|
+
function paramsForAttempt(input, attempt, maxAttempts, completionBudgetRetry) {
|
|
30499
30509
|
const turnStep = `${input.turnId}.${String(input.currentStep)}`;
|
|
30500
30510
|
return {
|
|
30501
30511
|
...input.params,
|
|
30502
30512
|
completionBudgetRetry,
|
|
30503
|
-
thinkingEffortRetry,
|
|
30504
30513
|
requestLogFields: attempt === 1 ? { turnStep } : {
|
|
30505
30514
|
turnStep,
|
|
30506
30515
|
attempt: `${String(attempt)}/${String(maxAttempts)}`
|
|
@@ -30508,19 +30517,12 @@ function paramsForAttempt(input, attempt, maxAttempts, completionBudgetRetry, th
|
|
|
30508
30517
|
};
|
|
30509
30518
|
}
|
|
30510
30519
|
function logEmptyResponse(input, error, attempt) {
|
|
30511
|
-
const retryThinkingEffort = nextThinkingEffortForExhaustedEmpty({
|
|
30512
|
-
emptyResponseKind: error.emptyResponseKind,
|
|
30513
|
-
maxCompletionTokens: error.maxCompletionTokens,
|
|
30514
|
-
completionTokens: error.completionTokens,
|
|
30515
|
-
thinkingEffort: input.llm.thinkingEffort
|
|
30516
|
-
});
|
|
30517
30520
|
input.log?.warn(`[leer] fall=${error.emptyResponseKind}`, {
|
|
30518
30521
|
turnStep: `${input.turnId}.${String(input.currentStep)}`,
|
|
30519
30522
|
attempt,
|
|
30520
30523
|
budget: error.maxCompletionTokens,
|
|
30521
30524
|
completion: error.completionTokens,
|
|
30522
|
-
reasoningLength: error.reasoningLength
|
|
30523
|
-
...retryThinkingEffort === void 0 ? {} : { retryThinkingEffort }
|
|
30525
|
+
reasoningLength: error.reasoningLength
|
|
30524
30526
|
});
|
|
30525
30527
|
}
|
|
30526
30528
|
function retryBackoffDelays(maxAttempts) {
|
|
@@ -30548,7 +30550,7 @@ function maybeStatusCode(error) {
|
|
|
30548
30550
|
const statusCode = error.statusCode;
|
|
30549
30551
|
return typeof statusCode === "number" ? statusCode : void 0;
|
|
30550
30552
|
}
|
|
30551
|
-
var import_retry$1, RETRY_MIN_TIMEOUT_MS, RETRY_MAX_TIMEOUT_MS, RETRY_FACTOR;
|
|
30553
|
+
var import_retry$1, RETRY_MIN_TIMEOUT_MS, RETRY_MAX_TIMEOUT_MS, RETRY_FACTOR, persistRetrySchedule;
|
|
30552
30554
|
var init_retry = __esmMin((() => {
|
|
30553
30555
|
init_dist$4();
|
|
30554
30556
|
init_src$4();
|
|
@@ -30556,6 +30558,7 @@ var init_retry = __esmMin((() => {
|
|
|
30556
30558
|
init_abort();
|
|
30557
30559
|
init_completion_budget();
|
|
30558
30560
|
init_errors$4();
|
|
30561
|
+
({ persistRetrySchedule } = createRequire(import.meta.url)("./bin/retry-checkpoint-policy.cjs"));
|
|
30559
30562
|
RETRY_MIN_TIMEOUT_MS = 300;
|
|
30560
30563
|
RETRY_MAX_TIMEOUT_MS = 5e3;
|
|
30561
30564
|
RETRY_FACTOR = 2;
|
|
@@ -74933,6 +74936,25 @@ var init_kosong_llm = __esmMin((() => {
|
|
|
74933
74936
|
get thinkingEffort() {
|
|
74934
74937
|
return this.provider.thinkingEffort;
|
|
74935
74938
|
}
|
|
74939
|
+
describeRequest(messages, tools, retry) {
|
|
74940
|
+
const outgoingRequestTokens = estimateSystemPromptTokens(this.systemPrompt) + estimateTokensForTools(tools) + estimateTokensForMessages(messages);
|
|
74941
|
+
const reportedContextTokens = this.reportedContextTokens?.() ?? 0;
|
|
74942
|
+
const details = applyCompletionBudgetWithDetails({
|
|
74943
|
+
provider: this.provider,
|
|
74944
|
+
budget: this.completionBudgetConfig,
|
|
74945
|
+
capability: this.capability,
|
|
74946
|
+
usedContextTokens: Math.max(outgoingRequestTokens, reportedContextTokens),
|
|
74947
|
+
retry: retry ?? (thinkingEnabled(this.provider.thinkingEffort) ? {
|
|
74948
|
+
minimumCompletionTokens: 1024,
|
|
74949
|
+
multiplier: 1
|
|
74950
|
+
} : void 0)
|
|
74951
|
+
});
|
|
74952
|
+
return {
|
|
74953
|
+
thinkingEffort: this.provider.thinkingEffort,
|
|
74954
|
+
completionBudget: details.maxCompletionTokens,
|
|
74955
|
+
details
|
|
74956
|
+
};
|
|
74957
|
+
}
|
|
74936
74958
|
notifyMediaDropped(dropped) {
|
|
74937
74959
|
if (this.onMediaDropped === void 0) return;
|
|
74938
74960
|
const fresh = dropped.filter((part) => {
|
|
@@ -74975,25 +74997,12 @@ var init_kosong_llm = __esmMin((() => {
|
|
|
74975
74997
|
let result;
|
|
74976
74998
|
let completionBudget;
|
|
74977
74999
|
try {
|
|
74978
|
-
const requestProvider = params.thinkingEffortRetry === void 0 ? this.provider : this.provider.withThinking(params.thinkingEffortRetry);
|
|
74979
75000
|
const enrichedMessages = this.visionReader === void 0 ? params.messages : await enrichMessagesWithVision(params.messages, this.visionReader, params.signal, this.onVisionUsage);
|
|
74980
75001
|
const tools = [...params.tools];
|
|
74981
75002
|
const outgoingMessages = downgradeUnsupportedMedia(enrichedMessages, this.capability, (dropped) => {
|
|
74982
75003
|
this.notifyMediaDropped(dropped);
|
|
74983
75004
|
});
|
|
74984
|
-
|
|
74985
|
-
const reportedContextTokens = this.reportedContextTokens?.() ?? 0;
|
|
74986
|
-
const usedContextTokens = Math.max(outgoingRequestTokens, reportedContextTokens);
|
|
74987
|
-
completionBudget = applyCompletionBudgetWithDetails({
|
|
74988
|
-
provider: requestProvider,
|
|
74989
|
-
budget: this.completionBudgetConfig,
|
|
74990
|
-
capability: this.capability,
|
|
74991
|
-
usedContextTokens,
|
|
74992
|
-
retry: params.completionBudgetRetry ?? (thinkingEnabled(requestProvider.thinkingEffort) ? {
|
|
74993
|
-
minimumCompletionTokens: 1024,
|
|
74994
|
-
multiplier: 1
|
|
74995
|
-
} : void 0)
|
|
74996
|
-
});
|
|
75005
|
+
completionBudget = this.describeRequest(outgoingMessages, tools, params.completionBudgetRetry).details;
|
|
74997
75006
|
result = await this.generate(completionBudget.provider, this.systemPrompt, tools, outgoingMessages, callbacks, options);
|
|
74998
75007
|
} catch (error) {
|
|
74999
75008
|
if (error instanceof APIEmptyResponseError) throw error.withMetadata({ maxCompletionTokens: completionBudget === void 0 ? null : completionBudget.maxCompletionTokens ?? null });
|
|
@@ -75516,12 +75525,13 @@ function extractCompactionSummary(response) {
|
|
|
75516
75525
|
if (summary.trim().length === 0) throw new APIEmptyResponseError("The compaction response did not contain a non-empty summary.");
|
|
75517
75526
|
return summary;
|
|
75518
75527
|
}
|
|
75519
|
-
var archiveCompactionHistory, buildCompactionArchiveNotice, capCompactionCompletionTokens, capCompactionStageTarget, proactiveCompactionEligibility, waitForAbortableCompletion, COMPACTION_THINKING_EFFORT, COMPACTION_SYSTEM_PROMPT, COMPACTION_SUMMARY_RESERVE_RATIO, MAX_HIERARCHICAL_COMPACTION_PASSES, HIERARCHICAL_COMPACTION_PREFIX, CompactionTruncatedError, CompactionStallError, COMPACTION_STALL_MEASUREMENT_MULTIPLIER, REBUILT_AFTER_COMPACTION_INJECTION_VARIANTS, FullCompaction, MAX_COMPACTION_OVERFLOW_SHRINK_ATTEMPTS, COMPACTION_OVERFLOW_SHRINK_RATIOS;
|
|
75528
|
+
var archiveCompactionHistory, buildCompactionArchiveNotice, capCompactionCompletionTokens, capCompactionStageTarget, proactiveCompactionEligibility, assertBalancedToolPairs, createCompactionTransaction, endCompactionTransaction, summarizeCompactionTransaction, waitForAbortableCompletion, COMPACTION_THINKING_EFFORT, COMPACTION_SYSTEM_PROMPT, COMPACTION_SUMMARY_RESERVE_RATIO, MAX_HIERARCHICAL_COMPACTION_PASSES, HIERARCHICAL_COMPACTION_PREFIX, CompactionTruncatedError, CompactionStallError, COMPACTION_STALL_MEASUREMENT_MULTIPLIER, REBUILT_AFTER_COMPACTION_INJECTION_VARIANTS, FullCompaction, MAX_COMPACTION_OVERFLOW_SHRINK_ATTEMPTS, COMPACTION_OVERFLOW_SHRINK_RATIOS;
|
|
75520
75529
|
var init_full = __esmMin((() => {
|
|
75521
75530
|
({ archiveCompactionHistory, buildCompactionArchiveNotice } = createRequire(import.meta.url)("./bin/compaction-history-archive.cjs"));
|
|
75522
75531
|
({ waitForAbortableCompletion } = createRequire(import.meta.url)("./bin/abort-listener-policy.cjs"));
|
|
75523
75532
|
({ capCompactionCompletionTokens, capCompactionStageTarget } = createRequire(import.meta.url)("./bin/compaction-stage-policy.cjs"));
|
|
75524
75533
|
({ proactiveCompactionEligibility } = createRequire(import.meta.url)("./bin/proactive-compaction-policy.cjs"));
|
|
75534
|
+
({ assertBalancedToolPairs, createCompactionTransaction, endCompactionTransaction, summarizeCompactionTransaction } = createRequire(import.meta.url)("./bin/compaction-transaction-policy.cjs"));
|
|
75525
75535
|
init_errors$8();
|
|
75526
75536
|
init_src$4();
|
|
75527
75537
|
init_errors$4();
|
|
@@ -75672,6 +75682,15 @@ var init_full = __esmMin((() => {
|
|
|
75672
75682
|
}
|
|
75673
75683
|
if (this.agent.context.history.length === 0) throw new BlunError(ErrorCodes.COMPACTION_UNABLE, "No messages to compact in current history.");
|
|
75674
75684
|
if (data.source === "manual" && this.agent.turn.hasActiveTurn) throw new BlunError(ErrorCodes.COMPACTION_UNABLE, "Cannot compact while a turn is active. Wait for it to finish, then retry.");
|
|
75685
|
+
const history = this.agent.context.history;
|
|
75686
|
+
assertBalancedToolPairs(history, "history selected for full compaction");
|
|
75687
|
+
const { transaction, record: transactionStart } = createCompactionTransaction({
|
|
75688
|
+
source: data.source,
|
|
75689
|
+
turnId: this.agent.turn.hasActiveTurn ? this.agent.turn.currentId : null,
|
|
75690
|
+
tokensBefore: estimateTokensForMessages(history),
|
|
75691
|
+
messageCountBefore: history.length
|
|
75692
|
+
});
|
|
75693
|
+
this.agent.records.logRecord(transactionStart);
|
|
75675
75694
|
this.agent.records.logRecord({
|
|
75676
75695
|
type: "full_compaction.begin",
|
|
75677
75696
|
...data
|
|
@@ -75684,20 +75703,32 @@ var init_full = __esmMin((() => {
|
|
|
75684
75703
|
const abortController = new AbortController();
|
|
75685
75704
|
this.compacting = {
|
|
75686
75705
|
abortController,
|
|
75687
|
-
promise: this.compactionWorker(abortController.signal, data),
|
|
75706
|
+
promise: this.compactionWorker(abortController.signal, data, transaction),
|
|
75707
|
+
transaction,
|
|
75688
75708
|
blockedByTurn: false
|
|
75689
75709
|
};
|
|
75690
75710
|
}
|
|
75691
|
-
|
|
75711
|
+
closeTransaction(status, error) {
|
|
75712
|
+
const transaction = this.compacting?.transaction;
|
|
75713
|
+
if (transaction === void 0) return;
|
|
75714
|
+
const record = endCompactionTransaction(transaction, {
|
|
75715
|
+
status,
|
|
75716
|
+
...error === void 0 ? {} : { error: error instanceof Error ? `${error.name}: ${error.message}` : String(error) }
|
|
75717
|
+
});
|
|
75718
|
+
if (record !== void 0) this.agent.records.logRecord(record);
|
|
75719
|
+
}
|
|
75720
|
+
cancel(error) {
|
|
75692
75721
|
this.agent.replayBuilder.patchLast("compaction", { result: "cancelled" });
|
|
75693
75722
|
if (!this.compacting) return;
|
|
75694
75723
|
this.agent.records.logRecord({ type: "full_compaction.cancel" });
|
|
75724
|
+
this.closeTransaction(error === void 0 ? "cancelled" : "failed", error);
|
|
75695
75725
|
this.compacting.abortController.abort();
|
|
75696
75726
|
this.compacting = null;
|
|
75697
75727
|
this.agent.emitEvent({ type: "compaction.cancelled" });
|
|
75698
75728
|
}
|
|
75699
75729
|
markCompleted() {
|
|
75700
75730
|
this.agent.records.logRecord({ type: "full_compaction.complete" });
|
|
75731
|
+
this.closeTransaction("success");
|
|
75701
75732
|
this.compacting = null;
|
|
75702
75733
|
}
|
|
75703
75734
|
get tokenCountWithPending() {
|
|
@@ -75806,9 +75837,9 @@ var init_full = __esmMin((() => {
|
|
|
75806
75837
|
await waitForAbortableCompletion(signal, active.promise, onAbort);
|
|
75807
75838
|
}
|
|
75808
75839
|
}
|
|
75809
|
-
async compactionWorker(signal, data) {
|
|
75840
|
+
async compactionWorker(signal, data, transaction) {
|
|
75810
75841
|
try {
|
|
75811
|
-
const output = await this.compactionRound(signal, data);
|
|
75842
|
+
const output = await this.compactionRound(signal, data, transaction);
|
|
75812
75843
|
if (!output) return;
|
|
75813
75844
|
const { result, stageCount } = output;
|
|
75814
75845
|
try {
|
|
@@ -75833,9 +75864,12 @@ var init_full = __esmMin((() => {
|
|
|
75833
75864
|
});
|
|
75834
75865
|
this.triggerPostCompactHook(data, result);
|
|
75835
75866
|
} catch (error) {
|
|
75836
|
-
if (isAbortError$4(error))
|
|
75867
|
+
if (isAbortError$4(error)) {
|
|
75868
|
+
if (this.compacting?.transaction === transaction) this.cancel();
|
|
75869
|
+
return;
|
|
75870
|
+
}
|
|
75837
75871
|
const blockedByTurn = this.compacting?.blockedByTurn === true;
|
|
75838
|
-
this.cancel();
|
|
75872
|
+
this.cancel(error);
|
|
75839
75873
|
this.agent.log.error("compaction failed", { error });
|
|
75840
75874
|
if (blockedByTurn) throw error;
|
|
75841
75875
|
this.agent.emitEvent({
|
|
@@ -75855,7 +75889,7 @@ var init_full = __esmMin((() => {
|
|
|
75855
75889
|
const todoMarkdown = renderTodoList(todos, "## TODO List");
|
|
75856
75890
|
return `${summary.trim()}\n\n${todoMarkdown}`;
|
|
75857
75891
|
}
|
|
75858
|
-
async compactionRound(signal, data) {
|
|
75892
|
+
async compactionRound(signal, data, transaction) {
|
|
75859
75893
|
const startedAt = Date.now();
|
|
75860
75894
|
const originalHistory = [...this.agent.context.history];
|
|
75861
75895
|
const tokensBefore = estimateTokensForMessages(originalHistory);
|
|
@@ -76131,7 +76165,9 @@ var init_full = __esmMin((() => {
|
|
|
76131
76165
|
contextSummary,
|
|
76132
76166
|
compactedCount: originalHistory.length,
|
|
76133
76167
|
tokensBefore,
|
|
76134
|
-
droppedCount: droppedCount === 0 ? void 0 : droppedCount
|
|
76168
|
+
droppedCount: droppedCount === 0 ? void 0 : droppedCount,
|
|
76169
|
+
transaction,
|
|
76170
|
+
historyBefore: originalHistory
|
|
76135
76171
|
});
|
|
76136
76172
|
this.agent.telemetry.track("compaction_finished", {
|
|
76137
76173
|
source: data.source,
|
|
@@ -76242,10 +76278,18 @@ var init_full = __esmMin((() => {
|
|
|
76242
76278
|
}));
|
|
76243
76279
|
//#endregion
|
|
76244
76280
|
//#region ../../packages/agent-core/src/agent/compaction/micro.ts
|
|
76245
|
-
|
|
76281
|
+
function repeatedToolResultReference(marker, newestToolCallId) {
|
|
76282
|
+
if (newestToolCallId === void 0) return marker;
|
|
76283
|
+
return [
|
|
76284
|
+
marker,
|
|
76285
|
+
`same_as_tool_call_id: ${newestToolCallId}`,
|
|
76286
|
+
"reason: identical successful result for the same tool call arguments"
|
|
76287
|
+
].join("\n");
|
|
76288
|
+
}
|
|
76289
|
+
var selectMicroCompactionCutoff, redundantHistoricalToolResultReferences, MICRO_COMPACTION_RECENT_MESSAGES, MICRO_COMPACTION_TOOL_ARGUMENTS_ENABLED, MICRO_COMPACTION_TOOL_ARGUMENT_MIN_TOKENS, isPersistedToolResultReference, freshToolResultIds, projectHistoricalUnaddressedTelegramMessages, dedupeRepeatedUserMessages, projectRepeatedAssistantResponses, compactHistoricalSkillActivations, dedupeRecurringCronWakeups, dedupeRepeatedInjections, projectLoopEventForRecord, projectUsageModelForRecord, projectUsageForRecord, resolveCompletedStepUuid, resolveStepEventUuid, restoreUsageFromRecord, restoreUsageModelFromRecord, isWireOnlyProgrammaticEvent, DEFAULT_CONFIG, MicroCompaction;
|
|
76246
76290
|
var init_micro = __esmMin((() => {
|
|
76247
76291
|
({ isWireOnlyProgrammaticEvent } = createRequire(import.meta.url)("./bin/programmatic-context-isolation.cjs"));
|
|
76248
|
-
({ selectMicroCompactionCutoff, MICRO_COMPACTION_RECENT_MESSAGES, MICRO_COMPACTION_TOOL_ARGUMENTS_ENABLED, MICRO_COMPACTION_TOOL_ARGUMENT_MIN_TOKENS } = createRequire(import.meta.url)("./bin/micro-compaction-policy.cjs"));
|
|
76292
|
+
({ selectMicroCompactionCutoff, redundantHistoricalToolResultReferences, MICRO_COMPACTION_RECENT_MESSAGES, MICRO_COMPACTION_TOOL_ARGUMENTS_ENABLED, MICRO_COMPACTION_TOOL_ARGUMENT_MIN_TOKENS } = createRequire(import.meta.url)("./bin/micro-compaction-policy.cjs"));
|
|
76249
76293
|
({ isPersistedToolResultReference, freshToolResultIds } = createRequire(import.meta.url)("./bin/tool-result-offload-policy.cjs"));
|
|
76250
76294
|
({ projectHistoricalUnaddressedTelegramMessages } = createRequire(import.meta.url)("./bin/telegram-context-projection-policy.cjs"));
|
|
76251
76295
|
({ dedupeRepeatedUserMessages } = createRequire(import.meta.url)("./bin/repeated-user-message-projection.cjs"));
|
|
@@ -76260,7 +76304,7 @@ var init_micro = __esmMin((() => {
|
|
|
76260
76304
|
compactToolArguments: MICRO_COMPACTION_TOOL_ARGUMENTS_ENABLED,
|
|
76261
76305
|
minToolArgumentTokens: MICRO_COMPACTION_TOOL_ARGUMENT_MIN_TOKENS,
|
|
76262
76306
|
cacheMissedThresholdMs: 3600 * 1e3,
|
|
76263
|
-
truncatedMarker: "[
|
|
76307
|
+
truncatedMarker: "[Repeated tool result omitted]",
|
|
76264
76308
|
truncatedArgumentsMarker: "[Old tool call arguments cleared]",
|
|
76265
76309
|
minContextUsageRatio: .5
|
|
76266
76310
|
};
|
|
@@ -76308,10 +76352,18 @@ var init_micro = __esmMin((() => {
|
|
|
76308
76352
|
const effect = this.measureEffect(history, selection.cutoff);
|
|
76309
76353
|
const previousEffect = this.measureEffect(history, previousCutoff);
|
|
76310
76354
|
if (effect.truncatedToolResultCount <= previousEffect.truncatedToolResultCount && effect.truncatedToolArgumentCount <= previousEffect.truncatedToolArgumentCount) return;
|
|
76311
|
-
this.apply(selection.cutoff);
|
|
76312
76355
|
const rawContextTokens = estimateTokensForMessages(history);
|
|
76313
76356
|
const tokensBefore = rawContextTokens - previousEffect.truncatedToolResultTokensBefore + previousEffect.truncatedToolResultTokensAfter - previousEffect.truncatedToolArgumentTokensBefore + previousEffect.truncatedToolArgumentTokensAfter;
|
|
76314
76357
|
const tokensAfter = rawContextTokens - effect.truncatedToolResultTokensBefore + effect.truncatedToolResultTokensAfter - effect.truncatedToolArgumentTokensBefore + effect.truncatedToolArgumentTokensAfter;
|
|
76358
|
+
this.apply(selection.cutoff);
|
|
76359
|
+
this.agent.records.logRecord({
|
|
76360
|
+
type: "policy.intervention",
|
|
76361
|
+
policy: "repeated_tool_result_projection",
|
|
76362
|
+
location: "MicroCompaction.detect",
|
|
76363
|
+
size_before: tokensBefore,
|
|
76364
|
+
size_after: tokensAfter,
|
|
76365
|
+
unit: "tokens"
|
|
76366
|
+
});
|
|
76315
76367
|
this.agent.telemetry.track("micro_compaction_finished", {
|
|
76316
76368
|
trigger: selection.trigger,
|
|
76317
76369
|
keep_recent_messages: config.keepRecentMessages,
|
|
@@ -76343,15 +76395,16 @@ var init_micro = __esmMin((() => {
|
|
|
76343
76395
|
const historicalArgumentCutoff = Math.max(this.cutoff, messages.length - config.keepRecentMessages);
|
|
76344
76396
|
const completedToolCallIds = new Set(messages.filter((message) => message?.role === "tool" && message.toolCallId !== void 0).map((message) => message.toolCallId));
|
|
76345
76397
|
const protectedToolResultIds = freshToolResultIds(messages);
|
|
76398
|
+
const reducibleToolResultIds = redundantHistoricalToolResultReferences(messages, this.cutoff);
|
|
76346
76399
|
const serializedArgumentsMarker = JSON.stringify({ _blun_compacted: config.truncatedArgumentsMarker });
|
|
76347
76400
|
const result = [];
|
|
76348
76401
|
let i = 0;
|
|
76349
76402
|
for (const msg of messages) {
|
|
76350
|
-
if (i < this.cutoff && msg.role === "tool" && msg.toolCallId !== void 0 && !protectedToolResultIds.has(msg.toolCallId) && !isPersistedToolResultReference(msg.content) && estimateTokensForContentParts(msg.content) >= config.minContentTokens) result.push({
|
|
76403
|
+
if (i < this.cutoff && msg.role === "tool" && msg.toolCallId !== void 0 && reducibleToolResultIds.has(msg.toolCallId) && !protectedToolResultIds.has(msg.toolCallId) && !isPersistedToolResultReference(msg.content) && estimateTokensForContentParts(msg.content) >= config.minContentTokens) result.push({
|
|
76351
76404
|
...msg,
|
|
76352
76405
|
content: [{
|
|
76353
76406
|
type: "text",
|
|
76354
|
-
text: config.truncatedMarker
|
|
76407
|
+
text: repeatedToolResultReference(config.truncatedMarker, reducibleToolResultIds.get(msg.toolCallId))
|
|
76355
76408
|
}]
|
|
76356
76409
|
});
|
|
76357
76410
|
else if (config.compactToolArguments && i < historicalArgumentCutoff && msg.role === "assistant" && Array.isArray(msg.toolCalls)) {
|
|
@@ -76380,7 +76433,6 @@ var init_micro = __esmMin((() => {
|
|
|
76380
76433
|
return result;
|
|
76381
76434
|
}
|
|
76382
76435
|
measureEffect(messages, cutoff) {
|
|
76383
|
-
let markerTokenCount;
|
|
76384
76436
|
let argumentsMarkerTokenCount;
|
|
76385
76437
|
let truncatedToolResultCount = 0;
|
|
76386
76438
|
let truncatedToolResultTokensBefore = 0;
|
|
@@ -76390,19 +76442,20 @@ var init_micro = __esmMin((() => {
|
|
|
76390
76442
|
let truncatedToolArgumentTokensAfter = 0;
|
|
76391
76443
|
const completedToolCallIds = new Set(messages.filter((message) => message?.role === "tool" && message.toolCallId !== void 0).map((message) => message.toolCallId));
|
|
76392
76444
|
const protectedToolResultIds = freshToolResultIds(messages);
|
|
76445
|
+
const reducibleToolResultIds = redundantHistoricalToolResultReferences(messages, cutoff);
|
|
76393
76446
|
const serializedArgumentsMarker = JSON.stringify({ _blun_compacted: this.config.truncatedArgumentsMarker });
|
|
76394
76447
|
for (let i = 0; i < messages.length && i < cutoff; i++) {
|
|
76395
76448
|
const message = messages[i];
|
|
76396
|
-
if (message?.role === "tool" && message.toolCallId !== void 0 && !protectedToolResultIds.has(message.toolCallId) && !isPersistedToolResultReference(message.content)) {
|
|
76449
|
+
if (message?.role === "tool" && message.toolCallId !== void 0 && reducibleToolResultIds.has(message.toolCallId) && !protectedToolResultIds.has(message.toolCallId) && !isPersistedToolResultReference(message.content)) {
|
|
76397
76450
|
const contentTokens = estimateTokensForContentParts(message.content);
|
|
76398
76451
|
if (contentTokens >= this.config.minContentTokens) {
|
|
76399
|
-
markerTokenCount ??= estimateTokensForContentParts([{
|
|
76400
|
-
type: "text",
|
|
76401
|
-
text: this.config.truncatedMarker
|
|
76402
|
-
}]);
|
|
76403
76452
|
truncatedToolResultCount += 1;
|
|
76404
76453
|
truncatedToolResultTokensBefore += contentTokens;
|
|
76405
|
-
|
|
76454
|
+
const replacement = repeatedToolResultReference(this.config.truncatedMarker, reducibleToolResultIds.get(message.toolCallId));
|
|
76455
|
+
truncatedToolResultTokensAfter += estimateTokensForContentParts([{
|
|
76456
|
+
type: "text",
|
|
76457
|
+
text: replacement
|
|
76458
|
+
}]);
|
|
76406
76459
|
}
|
|
76407
76460
|
}
|
|
76408
76461
|
if (!this.config.compactToolArguments || message?.role !== "assistant" || !Array.isArray(message.toolCalls)) continue;
|
|
@@ -79395,6 +79448,24 @@ var init_context$2 = __esmMin((() => {
|
|
|
79395
79448
|
keptHeadUserMessageCount,
|
|
79396
79449
|
droppedCount: input.droppedCount
|
|
79397
79450
|
};
|
|
79451
|
+
const summaryMessage = {
|
|
79452
|
+
role: "user",
|
|
79453
|
+
content: [{
|
|
79454
|
+
type: "text",
|
|
79455
|
+
text: contextSummary
|
|
79456
|
+
}],
|
|
79457
|
+
toolCalls: [],
|
|
79458
|
+
origin: { kind: "compaction_summary" }
|
|
79459
|
+
};
|
|
79460
|
+
const isLegacyRestore = this.agent.records.restoring !== null && input.keptUserMessageCount === void 0 && input.compactedCount < this._history.length;
|
|
79461
|
+
const nextHistory = isLegacyRestore ? [summaryMessage, ...this._history.slice(input.compactedCount)] : [...keptMessages, summaryMessage];
|
|
79462
|
+
if (input.transaction !== void 0) this.agent.records.logRecord(summarizeCompactionTransaction(input.transaction, {
|
|
79463
|
+
summary: contextSummary,
|
|
79464
|
+
historyBefore: input.historyBefore ?? this._history,
|
|
79465
|
+
historyAfter: nextHistory,
|
|
79466
|
+
tokensAfter: result.tokensAfter,
|
|
79467
|
+
messageCountAfter: nextHistory.length
|
|
79468
|
+
}));
|
|
79398
79469
|
this.agent.records.logRecord({
|
|
79399
79470
|
type: "policy.intervention",
|
|
79400
79471
|
policy: "full_context_compaction",
|
|
@@ -79417,17 +79488,7 @@ var init_context$2 = __esmMin((() => {
|
|
|
79417
79488
|
keptHeadUserMessageCount: result.keptHeadUserMessageCount,
|
|
79418
79489
|
droppedCount: result.droppedCount
|
|
79419
79490
|
} });
|
|
79420
|
-
|
|
79421
|
-
role: "user",
|
|
79422
|
-
content: [{
|
|
79423
|
-
type: "text",
|
|
79424
|
-
text: contextSummary
|
|
79425
|
-
}],
|
|
79426
|
-
toolCalls: [],
|
|
79427
|
-
origin: { kind: "compaction_summary" }
|
|
79428
|
-
};
|
|
79429
|
-
const isLegacyRestore = this.agent.records.restoring !== null && input.keptUserMessageCount === void 0 && input.compactedCount < this._history.length;
|
|
79430
|
-
this._history = isLegacyRestore ? [summaryMessage, ...this._history.slice(input.compactedCount)] : [...keptMessages, summaryMessage];
|
|
79491
|
+
this._history = nextHistory;
|
|
79431
79492
|
this.markPendingTokenEstimateDirty();
|
|
79432
79493
|
this.openSteps.clear();
|
|
79433
79494
|
this.pendingToolResultIds.clear();
|
|
@@ -244545,6 +244606,7 @@ function createNestedToolInvoker(step, parentToolCall) {
|
|
|
244545
244606
|
...step,
|
|
244546
244607
|
signal: nestedSignal,
|
|
244547
244608
|
toolCalls: [nestedToolCall],
|
|
244609
|
+
checkpointBeforeToolExecution: void 0,
|
|
244548
244610
|
dispatchEvent: (event) => step.dispatchEvent(markProgrammaticNestedEvent(event))
|
|
244549
244611
|
};
|
|
244550
244612
|
const preflight = preflightToolCall(nestedStep, nestedToolCall);
|
|
@@ -244679,6 +244741,16 @@ async function prepareToolCall(step, call, approvalEditCount = 0) {
|
|
|
244679
244741
|
}
|
|
244680
244742
|
const executionMetadata = authorization?.executionMetadata ?? decision.metadata;
|
|
244681
244743
|
await dispatchToolCall(step, call, effectiveArgs, displayFields);
|
|
244744
|
+
if (step.checkpointBeforeToolExecution !== void 0) {
|
|
244745
|
+
const checkpoint = await checkpointBeforeExternalSideEffect({
|
|
244746
|
+
flush: step.checkpointBeforeToolExecution,
|
|
244747
|
+
signal: step.signal
|
|
244748
|
+
});
|
|
244749
|
+
if (!checkpoint.allowed) return {
|
|
244750
|
+
task: makeResolvedToolCallTask(makeErrorToolResult(call, effectiveArgs, `${checkpoint.code}: ${checkpoint.error}`)),
|
|
244751
|
+
stopBatchAfterThis: true
|
|
244752
|
+
};
|
|
244753
|
+
}
|
|
244682
244754
|
return {
|
|
244683
244755
|
task: {
|
|
244684
244756
|
accesses: execution.accesses ?? ToolAccesses.all(),
|
|
@@ -244985,9 +245057,10 @@ async function dispatchToolCall(step, call, args, displayFields) {
|
|
|
244985
245057
|
display: displayFields?.display
|
|
244986
245058
|
});
|
|
244987
245059
|
}
|
|
244988
|
-
var markProgrammaticNestedEvent, GRACE_TIMEOUT_MS, TOOL_OUTPUT_EMPTY, TOOL_OUTPUT_NON_TEXT, validators;
|
|
245060
|
+
var markProgrammaticNestedEvent, checkpointBeforeExternalSideEffect, GRACE_TIMEOUT_MS, TOOL_OUTPUT_EMPTY, TOOL_OUTPUT_NON_TEXT, validators;
|
|
244989
245061
|
var init_tool_call = __esmMin((() => {
|
|
244990
245062
|
({ markProgrammaticNestedEvent } = createRequire(import.meta.url)("./bin/programmatic-context-isolation.cjs"));
|
|
245063
|
+
({ checkpointBeforeExternalSideEffect } = createRequire(import.meta.url)("./bin/session-checkpoint-policy.cjs"));
|
|
244991
245064
|
init_args_validator();
|
|
244992
245065
|
init_path_access();
|
|
244993
245066
|
init_abort();
|
|
@@ -245011,7 +245084,7 @@ var init_tool_call = __esmMin((() => {
|
|
|
245011
245084
|
* does not lose model usage that was already spent.
|
|
245012
245085
|
*/
|
|
245013
245086
|
async function executeLoopStep(deps) {
|
|
245014
|
-
const { turnId, signal, buildMessages, buildMessagesStrict, dispatchEvent, llm, tools, hooks, log, currentStep, maxRetryAttempts, recordUsage, onStepStarted } = deps;
|
|
245087
|
+
const { turnId, signal, buildMessages, buildMessagesStrict, dispatchEvent, llm, tools, hooks, log, currentStep, maxRetryAttempts, recordUsage, onStepStarted, checkpointBeforeToolExecution, checkpointBeforeRetryWait } = deps;
|
|
245015
245088
|
const beforeStep = hooks?.beforeStep === void 0 ? void 0 : await hooks.beforeStep({
|
|
245016
245089
|
turnId,
|
|
245017
245090
|
stepNumber: currentStep,
|
|
@@ -245027,12 +245100,15 @@ async function executeLoopStep(deps) {
|
|
|
245027
245100
|
const messages = await stepBuildMessages();
|
|
245028
245101
|
signal.throwIfAborted();
|
|
245029
245102
|
const stepUuid = randomUUID();
|
|
245103
|
+
const requestMetadata = stepLLM.describeRequest?.(messages, stepTools ?? []);
|
|
245030
245104
|
const stepEvents = createStepEventGate({
|
|
245031
245105
|
dispatchEvent,
|
|
245032
245106
|
turnId,
|
|
245033
245107
|
currentStep,
|
|
245034
245108
|
stepUuid,
|
|
245035
|
-
onStepStarted
|
|
245109
|
+
onStepStarted,
|
|
245110
|
+
requestMetadata,
|
|
245111
|
+
maxAttempts: maxRetryAttempts
|
|
245036
245112
|
});
|
|
245037
245113
|
const prepareRequestBoundary = stepLLM.prepareRequestBoundary?.bind(stepLLM);
|
|
245038
245114
|
const step = {
|
|
@@ -245044,7 +245120,8 @@ async function executeLoopStep(deps) {
|
|
|
245044
245120
|
signal,
|
|
245045
245121
|
turnId,
|
|
245046
245122
|
currentStep,
|
|
245047
|
-
stepUuid
|
|
245123
|
+
stepUuid,
|
|
245124
|
+
checkpointBeforeToolExecution
|
|
245048
245125
|
};
|
|
245049
245126
|
let chatParams = {
|
|
245050
245127
|
messages,
|
|
@@ -245057,9 +245134,8 @@ async function executeLoopStep(deps) {
|
|
|
245057
245134
|
signal.throwIfAborted();
|
|
245058
245135
|
const retryInput = {
|
|
245059
245136
|
llm: stepLLM,
|
|
245060
|
-
dispatchEvent: (event) =>
|
|
245061
|
-
|
|
245062
|
-
},
|
|
245137
|
+
dispatchEvent: (event) => stepEvents.dispatchRetrying(event),
|
|
245138
|
+
checkpointBeforeRetryWait,
|
|
245063
245139
|
turnId,
|
|
245064
245140
|
currentStep,
|
|
245065
245141
|
stepUuid,
|
|
@@ -245219,29 +245295,33 @@ async function chatWithLiveResponseRepetitionRecovery(deps) {
|
|
|
245219
245295
|
occurrences: repetition.count,
|
|
245220
245296
|
wordCount: repetition.wordCount
|
|
245221
245297
|
});
|
|
245222
|
-
await
|
|
245223
|
-
|
|
245224
|
-
|
|
245225
|
-
|
|
245226
|
-
|
|
245227
|
-
|
|
245228
|
-
|
|
245229
|
-
|
|
245230
|
-
|
|
245231
|
-
|
|
245232
|
-
|
|
245233
|
-
|
|
245298
|
+
await persistRetrySchedule({
|
|
245299
|
+
dispatchRetrying: (event) => stepEvents.dispatchRetrying(event),
|
|
245300
|
+
flush: checkpointBeforeRetryWait,
|
|
245301
|
+
signal,
|
|
245302
|
+
event: {
|
|
245303
|
+
type: "step.retrying",
|
|
245304
|
+
turnId: retryInput.turnId,
|
|
245305
|
+
step: retryInput.currentStep,
|
|
245306
|
+
stepUuid: retryInput.stepUuid,
|
|
245307
|
+
failedAttempt: 1,
|
|
245308
|
+
nextAttempt: 2,
|
|
245309
|
+
maxAttempts: 2,
|
|
245310
|
+
delayMs: 0,
|
|
245311
|
+
outputMayHaveStarted: true,
|
|
245312
|
+
errorName: "LiveResponseRepetitionError",
|
|
245313
|
+
errorMessage: "Repeated assistant text detected during streaming"
|
|
245314
|
+
}
|
|
245234
245315
|
});
|
|
245235
245316
|
}
|
|
245236
245317
|
}
|
|
245237
245318
|
throw new Error("Live response repetition recovery exhausted");
|
|
245238
245319
|
}
|
|
245239
245320
|
function createStepEventGate(deps) {
|
|
245240
|
-
const { dispatchEvent, turnId, currentStep, stepUuid, onStepStarted } = deps;
|
|
245321
|
+
const { dispatchEvent, turnId, currentStep, stepUuid, onStepStarted, requestMetadata, maxAttempts } = deps;
|
|
245241
245322
|
let startPromise;
|
|
245242
245323
|
let eventQueue = Promise.resolve();
|
|
245243
245324
|
let hasOutput = false;
|
|
245244
|
-
const pendingBeforeStart = [];
|
|
245245
245325
|
let liveRepetitionGuard;
|
|
245246
245326
|
let liveRepetitionController;
|
|
245247
245327
|
let liveRepetitionResult = null;
|
|
@@ -245251,10 +245331,13 @@ function createStepEventGate(deps) {
|
|
|
245251
245331
|
type: "step.begin",
|
|
245252
245332
|
uuid: stepUuid,
|
|
245253
245333
|
turnId,
|
|
245254
|
-
step: currentStep
|
|
245334
|
+
step: currentStep,
|
|
245335
|
+
thinkingEffort: requestMetadata?.thinkingEffort,
|
|
245336
|
+
completionBudget: requestMetadata?.completionBudget,
|
|
245337
|
+
attempt: 1,
|
|
245338
|
+
maxAttempts
|
|
245255
245339
|
});
|
|
245256
245340
|
onStepStarted?.();
|
|
245257
|
-
for (const dispatch of pendingBeforeStart.splice(0)) await dispatch();
|
|
245258
245341
|
})();
|
|
245259
245342
|
return startPromise;
|
|
245260
245343
|
};
|
|
@@ -245289,14 +245372,9 @@ function createStepEventGate(deps) {
|
|
|
245289
245372
|
return AbortSignal.any([signal, liveRepetitionController.signal]);
|
|
245290
245373
|
},
|
|
245291
245374
|
dispatchRetrying: async (event) => {
|
|
245292
|
-
|
|
245293
|
-
|
|
245294
|
-
|
|
245295
|
-
});
|
|
245296
|
-
return;
|
|
245297
|
-
}
|
|
245298
|
-
const queued = eventQueue.then(() => {
|
|
245299
|
-
dispatchEvent(event);
|
|
245375
|
+
const queued = eventQueue.then(async () => {
|
|
245376
|
+
await start();
|
|
245377
|
+
await dispatchEvent(event);
|
|
245300
245378
|
});
|
|
245301
245379
|
eventQueue = queued;
|
|
245302
245380
|
await queued;
|
|
@@ -245360,7 +245438,7 @@ var init_turn_step = __esmMin((() => {
|
|
|
245360
245438
|
//#endregion
|
|
245361
245439
|
//#region ../../packages/agent-core/src/loop/run-turn.ts
|
|
245362
245440
|
async function runTurn(input) {
|
|
245363
|
-
const { turnId, signal, llm, buildMessages, buildMessagesStrict, dispatchEvent, tools, hooks, log, maxSteps, maxRetryAttempts, recordStepUsage: hostRecordStepUsage } = input;
|
|
245441
|
+
const { turnId, signal, llm, buildMessages, buildMessagesStrict, dispatchEvent, tools, hooks, log, maxSteps, maxRetryAttempts, checkpointBeforeToolExecution, checkpointBeforeRetryWait, recordStepUsage: hostRecordStepUsage } = input;
|
|
245364
245442
|
let usage = emptyUsage();
|
|
245365
245443
|
let steps = 0;
|
|
245366
245444
|
let stopReason = "end_turn";
|
|
@@ -245390,6 +245468,8 @@ async function runTurn(input) {
|
|
|
245390
245468
|
log,
|
|
245391
245469
|
currentStep: stepNumber,
|
|
245392
245470
|
maxRetryAttempts,
|
|
245471
|
+
checkpointBeforeToolExecution,
|
|
245472
|
+
checkpointBeforeRetryWait,
|
|
245393
245473
|
recordUsage: recordStepUsage,
|
|
245394
245474
|
onStepStarted: setActiveStep.bind(void 0, stepNumber)
|
|
245395
245475
|
});
|
|
@@ -246762,7 +246842,11 @@ var init_events$1 = __esmMin((() => {
|
|
|
246762
246842
|
type: literal("turn.step.started"),
|
|
246763
246843
|
turnId: number$1(),
|
|
246764
246844
|
step: number$1(),
|
|
246765
|
-
stepId: string().optional()
|
|
246845
|
+
stepId: string().optional(),
|
|
246846
|
+
thinkingEffort: string().optional(),
|
|
246847
|
+
completionBudget: number$1().int().positive().optional(),
|
|
246848
|
+
attempt: number$1().int().positive().optional(),
|
|
246849
|
+
maxAttempts: number$1().int().positive().optional()
|
|
246766
246850
|
});
|
|
246767
246851
|
turnStepCompletedEventSchema = object({
|
|
246768
246852
|
type: literal("turn.step.completed"),
|
|
@@ -246792,7 +246876,9 @@ var init_events$1 = __esmMin((() => {
|
|
|
246792
246876
|
outputMayHaveStarted: boolean$1().optional(),
|
|
246793
246877
|
errorName: string(),
|
|
246794
246878
|
errorMessage: string(),
|
|
246795
|
-
statusCode: number$1().optional()
|
|
246879
|
+
statusCode: number$1().optional(),
|
|
246880
|
+
completionBudgetBefore: number$1().int().positive().optional(),
|
|
246881
|
+
completionBudgetAfter: number$1().int().positive().optional()
|
|
246796
246882
|
});
|
|
246797
246883
|
turnStepInterruptedEventSchema = object({
|
|
246798
246884
|
type: literal("turn.step.interrupted"),
|
|
@@ -254607,7 +254693,15 @@ function replaceOnceLiteral(content, oldString, newString) {
|
|
|
254607
254693
|
if (index === -1) return content;
|
|
254608
254694
|
return content.slice(0, index) + newString + content.slice(index + oldString.length);
|
|
254609
254695
|
}
|
|
254610
|
-
|
|
254696
|
+
async function observedFileStat(kaos, path) {
|
|
254697
|
+
try {
|
|
254698
|
+
return await kaos.stat(path);
|
|
254699
|
+
} catch (error) {
|
|
254700
|
+
if (error?.code === "ENOENT" || error?.code === "ENOTDIR") return null;
|
|
254701
|
+
throw error;
|
|
254702
|
+
}
|
|
254703
|
+
}
|
|
254704
|
+
var EditInputSchema, EditTool, findDegenerateGeneratedStatementRun, writeToolTextAtomic;
|
|
254611
254705
|
var init_edit = __esmMin((() => {
|
|
254612
254706
|
init_zod$1();
|
|
254613
254707
|
init_tool_access();
|
|
@@ -254619,6 +254713,7 @@ var init_edit = __esmMin((() => {
|
|
|
254619
254713
|
init_edit$1();
|
|
254620
254714
|
init_lsp_diagnostics();
|
|
254621
254715
|
({ findDegenerateGeneratedStatementRun } = createRequire(import.meta.url)("./bin/generated-source-health.cjs"));
|
|
254716
|
+
({ writeToolTextAtomic } = createRequire(import.meta.url)("./bin/tool-file-persistence.cjs"));
|
|
254622
254717
|
EditInputSchema = object({
|
|
254623
254718
|
path: string().describe("Path to the text file to edit. Relative paths resolve against the working directory; a path outside the working directory must be absolute."),
|
|
254624
254719
|
old_string: string().min(1).describe("Exact content to replace from the Read output view, without the line-number prefix. Use LF for pure CRLF files; use actual \\r escapes where Read shows \\r."),
|
|
@@ -254632,14 +254727,16 @@ var init_edit = __esmMin((() => {
|
|
|
254632
254727
|
workspace;
|
|
254633
254728
|
history;
|
|
254634
254729
|
lsp;
|
|
254730
|
+
fileObservation;
|
|
254635
254731
|
name = "Edit";
|
|
254636
254732
|
description = edit_default;
|
|
254637
254733
|
parameters = toInputJsonSchema(EditInputSchema);
|
|
254638
|
-
constructor(kaos, workspace, history, lsp) {
|
|
254734
|
+
constructor(kaos, workspace, history, lsp, fileObservation) {
|
|
254639
254735
|
this.kaos = kaos;
|
|
254640
254736
|
this.workspace = workspace;
|
|
254641
254737
|
this.history = history;
|
|
254642
254738
|
this.lsp = lsp;
|
|
254739
|
+
this.fileObservation = fileObservation;
|
|
254643
254740
|
}
|
|
254644
254741
|
resolveExecution(args) {
|
|
254645
254742
|
const path = resolvePathAccessPath(args.path, {
|
|
@@ -254677,6 +254774,12 @@ var init_edit = __esmMin((() => {
|
|
|
254677
254774
|
output: `Refused to edit ${args.path}: generated source contains a runaway repeated statement ${String(degenerateStatementRun.count)} times from line ${String(degenerateStatementRun.line)} (starts with ${JSON.stringify(degenerateStatementRun.preview)}). Regenerate that section in a smaller focused chunk. No file was written.`
|
|
254678
254775
|
};
|
|
254679
254776
|
try {
|
|
254777
|
+
const currentStat = await observedFileStat(this.kaos, safePath);
|
|
254778
|
+
const authorization = this.fileObservation.authorizeEdit(safePath, currentStat);
|
|
254779
|
+
if (!authorization.allowed) return {
|
|
254780
|
+
isError: true,
|
|
254781
|
+
output: `[${authorization.code}] ${authorization.error}`
|
|
254782
|
+
};
|
|
254680
254783
|
const raw = await this.kaos.readText(safePath);
|
|
254681
254784
|
const modelView = toModelTextView(raw);
|
|
254682
254785
|
const content = modelView.text;
|
|
@@ -254699,7 +254802,7 @@ var init_edit = __esmMin((() => {
|
|
|
254699
254802
|
output: `old_string is not unique in ${args.path} (found ${String(count)} occurrences). To replace every occurrence, set replace_all=true. To replace only one occurrence, include more surrounding context in old_string.`
|
|
254700
254803
|
};
|
|
254701
254804
|
const newContent = replaceOnceLiteral(content, args.old_string, args.new_string);
|
|
254702
|
-
return this.writeReplacement(args, safePath, raw, newContent, modelView.lineEndingStyle, 1);
|
|
254805
|
+
return this.writeReplacement(args, safePath, raw, newContent, modelView.lineEndingStyle, 1, authorization.version);
|
|
254703
254806
|
}
|
|
254704
254807
|
const parts = content.split(args.old_string);
|
|
254705
254808
|
const replacementCount = parts.length - 1;
|
|
@@ -254709,7 +254812,7 @@ var init_edit = __esmMin((() => {
|
|
|
254709
254812
|
`
|
|
254710
254813
|
};
|
|
254711
254814
|
const newContent = parts.join(args.new_string);
|
|
254712
|
-
return this.writeReplacement(args, safePath, raw, newContent, modelView.lineEndingStyle, replacementCount);
|
|
254815
|
+
return this.writeReplacement(args, safePath, raw, newContent, modelView.lineEndingStyle, replacementCount, authorization.version);
|
|
254713
254816
|
} catch (error) {
|
|
254714
254817
|
if (error?.code === "EISDIR") return {
|
|
254715
254818
|
isError: true,
|
|
@@ -254721,7 +254824,7 @@ var init_edit = __esmMin((() => {
|
|
|
254721
254824
|
};
|
|
254722
254825
|
}
|
|
254723
254826
|
}
|
|
254724
|
-
async writeReplacement(args, safePath, currentContent, nextContent, lineEndingStyle, replacementCount) {
|
|
254827
|
+
async writeReplacement(args, safePath, currentContent, nextContent, lineEndingStyle, replacementCount, observedVersion) {
|
|
254725
254828
|
const materialized = materializeModelText(nextContent, lineEndingStyle);
|
|
254726
254829
|
const lineLimit = evaluateSourceFileLineLimit(safePath, materialized, {
|
|
254727
254830
|
currentContent,
|
|
@@ -254732,7 +254835,14 @@ var init_edit = __esmMin((() => {
|
|
|
254732
254835
|
isError: true,
|
|
254733
254836
|
output: lineLimit.error
|
|
254734
254837
|
};
|
|
254735
|
-
await this.kaos
|
|
254838
|
+
const latestStat = await observedFileStat(this.kaos, safePath);
|
|
254839
|
+
const freshness = this.fileObservation.verifyUnchanged(safePath, observedVersion, latestStat);
|
|
254840
|
+
if (!freshness.allowed) return {
|
|
254841
|
+
isError: true,
|
|
254842
|
+
output: `[${freshness.code}] ${freshness.error}`
|
|
254843
|
+
};
|
|
254844
|
+
await writeToolTextAtomic(safePath, materialized);
|
|
254845
|
+
this.fileObservation.recordPresent(safePath, await this.kaos.stat(safePath));
|
|
254736
254846
|
const occurrence = replacementCount === 1 ? "occurrence" : "occurrences";
|
|
254737
254847
|
const notice = lineLimit.notice === void 0 ? "" : ` ${lineLimit.notice}`;
|
|
254738
254848
|
return appendLspDiagnostics({ output: `Replaced ${String(replacementCount)} ${occurrence} in ${args.path}.` + notice }, safePath, this.lsp);
|
|
@@ -260327,13 +260437,15 @@ var init_read = __esmMin((() => {
|
|
|
260327
260437
|
kaos;
|
|
260328
260438
|
workspace;
|
|
260329
260439
|
contextWindowState;
|
|
260440
|
+
fileObservation;
|
|
260330
260441
|
name = "Read";
|
|
260331
260442
|
description = READ_DESCRIPTION;
|
|
260332
260443
|
parameters = toInputJsonSchema(ReadInputSchema);
|
|
260333
|
-
constructor(kaos, workspace, contextWindowState = () => ({})) {
|
|
260444
|
+
constructor(kaos, workspace, contextWindowState = () => ({}), fileObservation) {
|
|
260334
260445
|
this.kaos = kaos;
|
|
260335
260446
|
this.workspace = workspace;
|
|
260336
260447
|
this.contextWindowState = contextWindowState;
|
|
260448
|
+
this.fileObservation = fileObservation;
|
|
260337
260449
|
}
|
|
260338
260450
|
modelVisibleBytes() {
|
|
260339
260451
|
return readModelVisibleBytes(this.contextWindowState());
|
|
@@ -260370,10 +260482,13 @@ var init_read = __esmMin((() => {
|
|
|
260370
260482
|
try {
|
|
260371
260483
|
stat = await this.kaos.stat(safePath);
|
|
260372
260484
|
} catch (error) {
|
|
260373
|
-
if (isFileNotFoundError(error))
|
|
260374
|
-
|
|
260375
|
-
|
|
260376
|
-
|
|
260485
|
+
if (isFileNotFoundError(error)) {
|
|
260486
|
+
this.fileObservation.recordAbsent(safePath);
|
|
260487
|
+
return {
|
|
260488
|
+
isError: true,
|
|
260489
|
+
output: `"${args.path}" does not exist.`
|
|
260490
|
+
};
|
|
260491
|
+
}
|
|
260377
260492
|
throw error;
|
|
260378
260493
|
}
|
|
260379
260494
|
if (!isRegularFileMode(stat.stMode)) return {
|
|
@@ -260394,8 +260509,17 @@ var init_read = __esmMin((() => {
|
|
|
260394
260509
|
const requestedLines = args.n_lines ?? maxLines;
|
|
260395
260510
|
const effectiveLimit = Math.min(requestedLines, maxLines);
|
|
260396
260511
|
const maxBytes = this.modelVisibleBytes();
|
|
260397
|
-
|
|
260398
|
-
|
|
260512
|
+
const result = lineOffset < 0
|
|
260513
|
+
? await this.readTail(safePath, args.path, lineOffset, effectiveLimit, requestedLines, maxBytes, maxLines)
|
|
260514
|
+
: await this.readForward(safePath, args.path, lineOffset, effectiveLimit, requestedLines, maxBytes, maxLines);
|
|
260515
|
+
if (result.isError === true) return result;
|
|
260516
|
+
const afterStat = await observedFileStat(this.kaos, safePath);
|
|
260517
|
+
const stability = this.fileObservation.verifyStableRead(safePath, stat, afterStat);
|
|
260518
|
+
if (!stability.allowed) return {
|
|
260519
|
+
isError: true,
|
|
260520
|
+
output: `[${stability.code}] ${stability.error}`
|
|
260521
|
+
};
|
|
260522
|
+
return result;
|
|
260399
260523
|
} catch (error) {
|
|
260400
260524
|
if (isTextDecodeError(error)) return {
|
|
260401
260525
|
isError: true,
|
|
@@ -260662,10 +260786,10 @@ var init_read = __esmMin((() => {
|
|
|
260662
260786
|
name = "ReadBatch";
|
|
260663
260787
|
description = READ_BATCH_DESCRIPTION;
|
|
260664
260788
|
parameters = toInputJsonSchema(ReadBatchInputSchema);
|
|
260665
|
-
constructor(kaos, workspace, contextWindowState) {
|
|
260789
|
+
constructor(kaos, workspace, contextWindowState, fileObservation) {
|
|
260666
260790
|
this.kaos = kaos;
|
|
260667
260791
|
this.workspace = workspace;
|
|
260668
|
-
this.reader = new ReadTool(kaos, workspace, contextWindowState);
|
|
260792
|
+
this.reader = new ReadTool(kaos, workspace, contextWindowState, fileObservation);
|
|
260669
260793
|
}
|
|
260670
260794
|
resolveExecution(args) {
|
|
260671
260795
|
const items = args.requests.map((request) => ({
|
|
@@ -261090,7 +261214,7 @@ function countCompletedLines(content) {
|
|
|
261090
261214
|
for (const character of content) if (character === "\n") count += 1;
|
|
261091
261215
|
return count;
|
|
261092
261216
|
}
|
|
261093
|
-
var S_IFMT, S_IFDIR, DEFAULT_CONTINUATION_CHUNK_BYTES, MIN_CONTINUATION_CHUNK_BYTES, MAX_CONTINUATION_CHUNK_BYTES, CONTINUATION_CHUNK_BYTES_ENV, WriteContinuationSchema, WriteInputSchema, WriteTool, resolveWriteContinuationContract, resolvePlainWriteContract, splitNativeWriteBytes, writeNativeLargeContentOnDisk;
|
|
261217
|
+
var S_IFMT, S_IFDIR, DEFAULT_CONTINUATION_CHUNK_BYTES, MIN_CONTINUATION_CHUNK_BYTES, MAX_CONTINUATION_CHUNK_BYTES, CONTINUATION_CHUNK_BYTES_ENV, WriteContinuationSchema, WriteInputSchema, WriteTool, resolveWriteContinuationContract, resolvePlainWriteContract, splitNativeWriteBytes, writeNativeLargeContentOnDisk, writeToolTextAtomic;
|
|
261094
261218
|
var init_write = __esmMin((() => {
|
|
261095
261219
|
init_dist$6();
|
|
261096
261220
|
init_zod$1();
|
|
@@ -261104,6 +261228,7 @@ var init_write = __esmMin((() => {
|
|
|
261104
261228
|
init_lsp_diagnostics();
|
|
261105
261229
|
({ resolveWriteContinuationContract, resolvePlainWriteContract, splitNativeWriteBytes } = createRequire(import.meta.url)("./bin/write-continuation-policy.cjs"));
|
|
261106
261230
|
({ writeNativeLargeContentOnDisk } = createRequire(import.meta.url)("./bin/native-large-file-io.cjs"));
|
|
261231
|
+
({ writeToolTextAtomic } = createRequire(import.meta.url)("./bin/tool-file-persistence.cjs"));
|
|
261107
261232
|
S_IFMT = 61440;
|
|
261108
261233
|
S_IFDIR = 16384;
|
|
261109
261234
|
DEFAULT_CONTINUATION_CHUNK_BYTES = 2048;
|
|
@@ -261133,17 +261258,19 @@ bytesWritten: number$1().int().nonnegative() });
|
|
|
261133
261258
|
workspace;
|
|
261134
261259
|
history;
|
|
261135
261260
|
lsp;
|
|
261261
|
+
fileObservation;
|
|
261136
261262
|
maxContinuationChunkBytes;
|
|
261137
261263
|
name = "Write";
|
|
261138
261264
|
description = write_default;
|
|
261139
261265
|
parameters = toInputJsonSchema(WriteInputSchema);
|
|
261140
261266
|
pendingContinuations = /* @__PURE__ */ new Map();
|
|
261141
261267
|
continuationRequiredPaths = /* @__PURE__ */ new Set();
|
|
261142
|
-
constructor(kaos, workspace, history, lsp, maxContinuationChunkBytes = resolveWriteContinuationChunkBytes()) {
|
|
261268
|
+
constructor(kaos, workspace, history, lsp, fileObservation, maxContinuationChunkBytes = resolveWriteContinuationChunkBytes()) {
|
|
261143
261269
|
this.kaos = kaos;
|
|
261144
261270
|
this.workspace = workspace;
|
|
261145
261271
|
this.history = history;
|
|
261146
261272
|
this.lsp = lsp;
|
|
261273
|
+
this.fileObservation = fileObservation;
|
|
261147
261274
|
this.maxContinuationChunkBytes = maxContinuationChunkBytes;
|
|
261148
261275
|
}
|
|
261149
261276
|
resolveExecution(args) {
|
|
@@ -261312,6 +261439,12 @@ bytesWritten: number$1().int().nonnegative() });
|
|
|
261312
261439
|
isError: true,
|
|
261313
261440
|
output: `Refused to write ${args.path}: generated source contains a runaway repeated statement ${String(degenerateStatementRun.count)} times from line ${String(degenerateStatementRun.line)} (starts with ${JSON.stringify(degenerateStatementRun.preview)}). Regenerate that section in a smaller focused chunk. No file was written.`
|
|
261314
261441
|
};
|
|
261442
|
+
const currentStat = await observedFileStat(this.kaos, safePath);
|
|
261443
|
+
const authorization = this.fileObservation.authorizeWrite(safePath, currentStat);
|
|
261444
|
+
if (!authorization.allowed) return {
|
|
261445
|
+
isError: true,
|
|
261446
|
+
output: `[${authorization.code}] ${authorization.error}`
|
|
261447
|
+
};
|
|
261315
261448
|
let currentContent;
|
|
261316
261449
|
if (isSourceFilePath(safePath)) try {
|
|
261317
261450
|
currentContent = await this.kaos.readText(safePath);
|
|
@@ -261339,9 +261472,16 @@ bytesWritten: number$1().int().nonnegative() });
|
|
|
261339
261472
|
continuationRequired: this.continuationRequiredPaths.has(safePath)
|
|
261340
261473
|
});
|
|
261341
261474
|
if (!allowLargeContent && !plainWrite.allowed) {
|
|
261475
|
+
const latestStat = await observedFileStat(this.kaos, safePath);
|
|
261476
|
+
const freshness = this.fileObservation.verifyUnchanged(safePath, authorization.version, latestStat);
|
|
261477
|
+
if (!freshness.allowed) return {
|
|
261478
|
+
isError: true,
|
|
261479
|
+
output: `[${freshness.code}] ${freshness.error}`
|
|
261480
|
+
};
|
|
261342
261481
|
const chunks = splitNativeWriteBytes(args.content, this.maxContinuationChunkBytes);
|
|
261343
261482
|
const nativeResult = await this.writeNativeLargeContent(safePath, chunks, mode);
|
|
261344
261483
|
if (nativeResult.isError === true) return nativeResult;
|
|
261484
|
+
this.fileObservation.recordPresent(safePath, await this.kaos.stat(safePath));
|
|
261345
261485
|
this.continuationRequiredPaths.delete(safePath);
|
|
261346
261486
|
const notice = lineLimit.notice === void 0 ? "" : ` ${lineLimit.notice}`;
|
|
261347
261487
|
return appendLspDiagnostics({
|
|
@@ -261354,8 +261494,15 @@ bytesWritten: number$1().int().nonnegative() });
|
|
|
261354
261494
|
output: parentError
|
|
261355
261495
|
};
|
|
261356
261496
|
try {
|
|
261497
|
+
const latestStat = await observedFileStat(this.kaos, safePath);
|
|
261498
|
+
const freshness = this.fileObservation.verifyUnchanged(safePath, authorization.version, latestStat);
|
|
261499
|
+
if (!freshness.allowed) return {
|
|
261500
|
+
isError: true,
|
|
261501
|
+
output: `[${freshness.code}] ${freshness.error}`
|
|
261502
|
+
};
|
|
261357
261503
|
if (mode === "append") await this.kaos.writeText(safePath, args.content, { mode: "a" });
|
|
261358
|
-
else await
|
|
261504
|
+
else await writeToolTextAtomic(safePath, args.content);
|
|
261505
|
+
this.fileObservation.recordPresent(safePath, await this.kaos.stat(safePath));
|
|
261359
261506
|
const bytesWritten = Buffer.byteLength(args.content, "utf8");
|
|
261360
261507
|
const notice = lineLimit.notice === void 0 ? "" : ` ${lineLimit.notice}`;
|
|
261361
261508
|
return appendLspDiagnostics({ output: `${mode === "append" ? "Appended" : "Wrote"} ${String(bytesWritten)} bytes to ${args.path}.${notice}` }, safePath, this.lsp);
|
|
@@ -261904,7 +262051,8 @@ var init_tool_dedup = __esmMin((() => {
|
|
|
261904
262051
|
//#region ../../packages/agent-core/src/agent/turn/tool-result-budget.ts
|
|
261905
262052
|
async function budgetToolResultForModel(options) {
|
|
261906
262053
|
const text = persistableToolResultText(options.result.output);
|
|
261907
|
-
|
|
262054
|
+
const contextUsageRatio = Number.isFinite(options.maxContextTokens) && options.maxContextTokens > 0 ? Number(options.contextTokens) / options.maxContextTokens : 1;
|
|
262055
|
+
if (text === void 0 || shouldKeepFreshToolResult(options.toolName) || !shouldOffloadToolResult(text.length, { contextUsageRatio })) return options.result;
|
|
261908
262056
|
const readSourcePath = reusableReadSourcePath(options);
|
|
261909
262057
|
if (readSourcePath !== void 0) return referenceReadSourceForModel(options, text, readSourcePath);
|
|
261910
262058
|
return persistToolResultForModel(options, text);
|
|
@@ -262688,7 +262836,11 @@ function mapLoopEvent(event, turnId) {
|
|
|
262688
262836
|
type: "turn.step.started",
|
|
262689
262837
|
turnId,
|
|
262690
262838
|
step: event.step,
|
|
262691
|
-
stepId: event.uuid
|
|
262839
|
+
stepId: event.uuid,
|
|
262840
|
+
thinkingEffort: event.thinkingEffort,
|
|
262841
|
+
completionBudget: event.completionBudget,
|
|
262842
|
+
attempt: event.attempt,
|
|
262843
|
+
maxAttempts: event.maxAttempts
|
|
262692
262844
|
};
|
|
262693
262845
|
case "step.end": return {
|
|
262694
262846
|
type: "turn.step.completed",
|
|
@@ -262718,7 +262870,9 @@ function mapLoopEvent(event, turnId) {
|
|
|
262718
262870
|
outputMayHaveStarted: event.outputMayHaveStarted,
|
|
262719
262871
|
errorName: event.errorName,
|
|
262720
262872
|
errorMessage: event.errorMessage,
|
|
262721
|
-
statusCode: event.statusCode
|
|
262873
|
+
statusCode: event.statusCode,
|
|
262874
|
+
completionBudgetBefore: event.completionBudgetBefore,
|
|
262875
|
+
completionBudgetAfter: event.completionBudgetAfter
|
|
262722
262876
|
};
|
|
262723
262877
|
case "content.part": return;
|
|
262724
262878
|
case "tool.call": return {
|
|
@@ -263006,6 +263160,7 @@ var init_turn = __esmMin((() => {
|
|
|
263006
263160
|
toolScopeByTurn = /* @__PURE__ */ new Map();
|
|
263007
263161
|
interruptedTelemetryTurnIds = /* @__PURE__ */ new Set();
|
|
263008
263162
|
stepFailureByTurn = /* @__PURE__ */ new Map();
|
|
263163
|
+
stepRequestStateByTurn = /* @__PURE__ */ new Map();
|
|
263009
263164
|
currentStep = 0;
|
|
263010
263165
|
cognitiveLifecycle;
|
|
263011
263166
|
cognitiveLifecycleUnavailable = false;
|
|
@@ -263698,6 +263853,7 @@ var init_turn = __esmMin((() => {
|
|
|
263698
263853
|
this.cognitiveExternalReportsByTurn.delete(turnId);
|
|
263699
263854
|
this.cognitiveLocalClaimsByTurn.delete(turnId);
|
|
263700
263855
|
this.stepFailureByTurn.delete(turnId);
|
|
263856
|
+
this.stepRequestStateByTurn.delete(turnId);
|
|
263701
263857
|
await this.agent.records.flush();
|
|
263702
263858
|
await this.agent.records.writeResumeCheckpoint();
|
|
263703
263859
|
return {
|
|
@@ -263841,6 +263997,8 @@ var init_turn = __esmMin((() => {
|
|
|
263841
263997
|
log: this.agent.log,
|
|
263842
263998
|
maxSteps: loopControl?.maxStepsPerTurn,
|
|
263843
263999
|
maxRetryAttempts: loopControl?.maxRetriesPerStep,
|
|
264000
|
+
checkpointBeforeToolExecution: () => this.agent.records.flush(),
|
|
264001
|
+
checkpointBeforeRetryWait: () => this.agent.records.flush(),
|
|
263844
264002
|
recordStepUsage: async (usage) => {
|
|
263845
264003
|
try {
|
|
263846
264004
|
stopForGoalBudget = (await this.agent.goal.recordTokenUsage(grandTotal(usage)))?.budget.overBudget === true;
|
|
@@ -264038,14 +264196,25 @@ var init_turn = __esmMin((() => {
|
|
|
264038
264196
|
toolOutput: isError === true ? void 0 : toolOutputText(output).slice(0, 2e3)
|
|
264039
264197
|
}
|
|
264040
264198
|
});
|
|
264041
|
-
|
|
264199
|
+
const budgetedResult = await budgetToolResultForModel({
|
|
264042
264200
|
homedir: this.agent.homedir,
|
|
264043
264201
|
toolName: ctx.toolCall.name,
|
|
264044
264202
|
toolCallId: ctx.toolCall.id,
|
|
264045
264203
|
toolArgs: ctx.args,
|
|
264046
264204
|
result: finalResult,
|
|
264205
|
+
contextTokens: this.agent.context.tokenCountWithPending,
|
|
264206
|
+
maxContextTokens: this.agent.config.modelCapabilities.max_context_tokens,
|
|
264047
264207
|
telemetry: this.agent.telemetry
|
|
264048
264208
|
});
|
|
264209
|
+
if (budgetedResult !== finalResult) this.agent.records.logRecord({
|
|
264210
|
+
type: "policy.intervention",
|
|
264211
|
+
policy: "tool_result_spill",
|
|
264212
|
+
location: "budgetToolResultForModel",
|
|
264213
|
+
size_before: toolOutputText(finalResult.output).length,
|
|
264214
|
+
size_after: toolOutputText(budgetedResult.output).length,
|
|
264215
|
+
unit: "chars"
|
|
264216
|
+
});
|
|
264217
|
+
return budgetedResult;
|
|
264049
264218
|
}
|
|
264050
264219
|
}
|
|
264051
264220
|
})).stopReason;
|
|
@@ -264094,6 +264263,26 @@ var init_turn = __esmMin((() => {
|
|
|
264094
264263
|
emitLiveEvent: (event) => {
|
|
264095
264264
|
this.noteFirstRequestEvent(event);
|
|
264096
264265
|
this.trackLoopTelemetry(event, turnId);
|
|
264266
|
+
if (event.type === "thinking.delta" && event.delta.trim().length === 0) {
|
|
264267
|
+
const requestState = this.stepRequestStateByTurn.get(turnId);
|
|
264268
|
+
this.agent.records.logRecord({
|
|
264269
|
+
type: "thinking.heartbeat",
|
|
264270
|
+
turn_id: turnId,
|
|
264271
|
+
step: this.currentStepByTurn.get(turnId) ?? this.currentStep,
|
|
264272
|
+
attempt: requestState?.attempt ?? 1,
|
|
264273
|
+
max_attempts: requestState?.maxAttempts,
|
|
264274
|
+
completion_budget: requestState?.completionBudget,
|
|
264275
|
+
thinking_effort: requestState?.thinkingEffort
|
|
264276
|
+
});
|
|
264277
|
+
}
|
|
264278
|
+
if (event.type === "step.retrying" && event.completionBudgetBefore !== void 0 && event.completionBudgetAfter !== void 0) this.agent.records.logRecord({
|
|
264279
|
+
type: "policy.intervention",
|
|
264280
|
+
policy: "empty_response_completion_budget_retry",
|
|
264281
|
+
location: "chatWithRetry",
|
|
264282
|
+
size_before: event.completionBudgetBefore,
|
|
264283
|
+
size_after: event.completionBudgetAfter,
|
|
264284
|
+
unit: "tokens"
|
|
264285
|
+
});
|
|
264097
264286
|
const mapped = mapLoopEvent(event, turnId);
|
|
264098
264287
|
if (mapped !== void 0) return this.agent.emitEvent(mapped);
|
|
264099
264288
|
}
|
|
@@ -264117,9 +264306,18 @@ var init_turn = __esmMin((() => {
|
|
|
264117
264306
|
}
|
|
264118
264307
|
trackLoopTelemetry(event, turnId) {
|
|
264119
264308
|
if (event.type === "step.begin") {
|
|
264120
|
-
this.beginTrackedStep(turnId, event.step);
|
|
264309
|
+
this.beginTrackedStep(turnId, event.step, event);
|
|
264121
264310
|
return;
|
|
264122
264311
|
}
|
|
264312
|
+
if (event.type === "step.retrying") {
|
|
264313
|
+
const previous = this.stepRequestStateByTurn.get(turnId) ?? {};
|
|
264314
|
+
this.stepRequestStateByTurn.set(turnId, {
|
|
264315
|
+
...previous,
|
|
264316
|
+
attempt: event.nextAttempt,
|
|
264317
|
+
maxAttempts: event.maxAttempts,
|
|
264318
|
+
completionBudget: event.completionBudgetAfter ?? previous.completionBudget
|
|
264319
|
+
});
|
|
264320
|
+
}
|
|
264123
264321
|
if (event.type === "turn.interrupted") {
|
|
264124
264322
|
if (event.reason === "error" && event.activeStep !== void 0) this.stepFailureByTurn.set(turnId, event);
|
|
264125
264323
|
this.trackTurnInterrupted(turnId, interruptedStep(event));
|
|
@@ -264127,9 +264325,15 @@ var init_turn = __esmMin((() => {
|
|
|
264127
264325
|
}
|
|
264128
264326
|
this.trackToolLifecycle(event, turnId);
|
|
264129
264327
|
}
|
|
264130
|
-
beginTrackedStep(turnId, step) {
|
|
264328
|
+
beginTrackedStep(turnId, step, event) {
|
|
264131
264329
|
this.currentStepByTurn.set(turnId, step);
|
|
264132
264330
|
this.currentStep = step;
|
|
264331
|
+
this.stepRequestStateByTurn.set(turnId, {
|
|
264332
|
+
thinkingEffort: event?.thinkingEffort,
|
|
264333
|
+
completionBudget: event?.completionBudget,
|
|
264334
|
+
attempt: event?.attempt ?? 1,
|
|
264335
|
+
maxAttempts: event?.maxAttempts
|
|
264336
|
+
});
|
|
264133
264337
|
if (!this.stepToolCallKeys.has(step)) this.stepToolCallKeys.set(step, /* @__PURE__ */ new Set());
|
|
264134
264338
|
}
|
|
264135
264339
|
trackToolLifecycle(event, turnId) {
|
|
@@ -265838,7 +266042,7 @@ var init_builtin = __esmMin((() => {
|
|
|
265838
266042
|
var init_types$3 = __esmMin((() => {}));
|
|
265839
266043
|
//#endregion
|
|
265840
266044
|
//#region ../../packages/agent-core/src/agent/tool/index.ts
|
|
265841
|
-
var import_picomatch, profileToolExclusionPolicy, applyProfileToolExclusions, shouldRecordUserToolUnregister, SHELL_FOREGROUND_TIMEOUT_S, ToolManager;
|
|
266045
|
+
var import_picomatch, profileToolExclusionPolicy, applyProfileToolExclusions, shouldRecordUserToolUnregister, createFileObservationPolicy, SHELL_FOREGROUND_TIMEOUT_S, ToolManager;
|
|
265842
266046
|
var init_tool$1 = __esmMin((() => {
|
|
265843
266047
|
init_dist$4();
|
|
265844
266048
|
import_picomatch = /* @__PURE__ */ __toESM(require_picomatch(), 1);
|
|
@@ -265854,6 +266058,7 @@ var init_tool$1 = __esmMin((() => {
|
|
|
265854
266058
|
profileToolExclusionPolicy = createRequire(import.meta.url)("./bin/profile-tool-exclusion-policy.cjs");
|
|
265855
266059
|
applyProfileToolExclusions = profileToolExclusionPolicy.applyProfileToolExclusions;
|
|
265856
266060
|
({ shouldRecordUserToolUnregister } = createRequire(import.meta.url)("./bin/user-tool-record-policy.cjs"));
|
|
266061
|
+
({ createFileObservationPolicy } = createRequire(import.meta.url)("./bin/file-observation-policy.cjs"));
|
|
265857
266062
|
SHELL_FOREGROUND_TIMEOUT_S = 120;
|
|
265858
266063
|
ToolManager = class {
|
|
265859
266064
|
agent;
|
|
@@ -266258,11 +266463,12 @@ var init_tool$1 = __esmMin((() => {
|
|
|
266258
266463
|
contextTokens: this.agent.context.tokenCountWithPending,
|
|
266259
266464
|
maxContextTokens: this.agent.fullCompaction.getEffectiveMaxContextTokens()
|
|
266260
266465
|
});
|
|
266466
|
+
const fileObservation = createFileObservationPolicy({ pathClass: kaos.pathClass() });
|
|
266261
266467
|
this.builtinTools = new Map([
|
|
266262
|
-
new ReadTool(kaos, workspace, readBudget),
|
|
266263
|
-
new ReadBatchTool(kaos, workspace, readBudget),
|
|
266264
|
-
new WriteTool(kaos, workspace, () => this.agent.context.history, toolServices?.lsp),
|
|
266265
|
-
new EditTool(kaos, workspace, () => this.agent.context.history, toolServices?.lsp),
|
|
266468
|
+
new ReadTool(kaos, workspace, readBudget, fileObservation),
|
|
266469
|
+
new ReadBatchTool(kaos, workspace, readBudget, fileObservation),
|
|
266470
|
+
new WriteTool(kaos, workspace, () => this.agent.context.history, toolServices?.lsp, fileObservation),
|
|
266471
|
+
new EditTool(kaos, workspace, () => this.agent.context.history, toolServices?.lsp, fileObservation),
|
|
266266
266472
|
new GrepTool(kaos, workspace, this.agent.telemetry),
|
|
266267
266473
|
new GlobTool(kaos, workspace, this.agent.telemetry),
|
|
266268
266474
|
new BashTool(kaos, cwd, background, { allowBackground }),
|
|
@@ -266692,7 +266898,7 @@ var init_llm_request_logger = __esmMin((() => {
|
|
|
266692
266898
|
function normalizeRuntimeSystemPromptAppend(value) {
|
|
266693
266899
|
return value?.trim().slice(0, 16e3) ?? "";
|
|
266694
266900
|
}
|
|
266695
|
-
var PINNED_MODEL_ALIASES, createEffectiveSystemPromptResolver, resolveProviderIdleTimeoutMs, capCompletionBudgetForAdaptiveEffort,
|
|
266901
|
+
var PINNED_MODEL_ALIASES, createEffectiveSystemPromptResolver, resolveProviderIdleTimeoutMs, capCompletionBudgetForAdaptiveEffort, selectThinkingEffortForBufferedSteer, selectThinkingEffortForWorkStep, selectThinkingEffortForTurn, Agent$1;
|
|
266696
266902
|
var init_agent = __esmMin((() => {
|
|
266697
266903
|
init_dist$6();
|
|
266698
266904
|
init_config$4();
|
|
@@ -266731,7 +266937,7 @@ var init_agent = __esmMin((() => {
|
|
|
266731
266937
|
init_error_memory();
|
|
266732
266938
|
({ createEffectiveSystemPromptResolver } = createRequire(import.meta.url)("./bin/effective-system-prompt-cache-policy.cjs"));
|
|
266733
266939
|
({ resolveProviderIdleTimeoutMs } = createRequire(import.meta.url)("./bin/provider-idle-timeout-policy.cjs"));
|
|
266734
|
-
({ capCompletionBudgetForAdaptiveEffort,
|
|
266940
|
+
({ capCompletionBudgetForAdaptiveEffort, selectThinkingEffortForBufferedSteer, selectThinkingEffortForWorkStep, selectThinkingEffortForTurn } = createRequire(import.meta.url)("./bin/turn-thinking-policy.cjs"));
|
|
266735
266941
|
PINNED_MODEL_ALIASES = new Set(["blun/king"]);
|
|
266736
266942
|
Agent$1 = class {
|
|
266737
266943
|
type;
|
|
@@ -266926,7 +267132,7 @@ var init_agent = __esmMin((() => {
|
|
|
266926
267132
|
const provider = thinkingEffort === void 0 ? runtimeModel.provider : runtimeModel.provider.withThinking(thinkingEffort);
|
|
266927
267133
|
const loopControl = this.blunConfig?.loopControl;
|
|
266928
267134
|
const completionBudgetConfig = resolveCompletionBudget({
|
|
266929
|
-
maxOutputSize:
|
|
267135
|
+
maxOutputSize: runtimeModel.maxOutputSize,
|
|
266930
267136
|
reservedContextSize: loopControl?.reservedContextSize
|
|
266931
267137
|
});
|
|
266932
267138
|
return new KosongLLM({
|
|
@@ -343755,7 +343961,7 @@ const DEFAULT_NOTIFICATIONS_CONFIG = {
|
|
|
343755
343961
|
enabled: true,
|
|
343756
343962
|
condition: "unfocused"
|
|
343757
343963
|
};
|
|
343758
|
-
const DEFAULT_UPGRADE_PREFERENCES = { autoInstall:
|
|
343964
|
+
const DEFAULT_UPGRADE_PREFERENCES = { autoInstall: false };
|
|
343759
343965
|
/**
|
|
343760
343966
|
* F2 Tippen-mit-Vorschlag: Code-Sprachen standardmäßig an, md/plain aus.
|
|
343761
343967
|
* Unbekannte Sprachen fallen auf "an" zurück (Opt-out über tui.toml).
|
|
@@ -409266,6 +409472,9 @@ var TUI = class TUI extends Container {
|
|
|
409266
409472
|
setClearOnShrink(enabled) {
|
|
409267
409473
|
this.clearOnShrink = enabled;
|
|
409268
409474
|
}
|
|
409475
|
+
getRenderHeight() {
|
|
409476
|
+
return this.terminal.rows;
|
|
409477
|
+
}
|
|
409269
409478
|
setFocus(component) {
|
|
409270
409479
|
this.setFocusInternal({
|
|
409271
409480
|
component,
|
|
@@ -409874,7 +410083,7 @@ var TUI = class TUI extends Container {
|
|
|
409874
410083
|
doRender() {
|
|
409875
410084
|
if (this.stopped) return;
|
|
409876
410085
|
const width = this.terminal.columns;
|
|
409877
|
-
const height = this.
|
|
410086
|
+
const height = this.getRenderHeight();
|
|
409878
410087
|
const widthChanged = this.previousWidth !== 0 && this.previousWidth !== width;
|
|
409879
410088
|
const heightChanged = this.previousHeight !== 0 && this.previousHeight !== height;
|
|
409880
410089
|
const previousBufferLength = this.previousHeight > 0 ? this.previousViewportTop + this.previousHeight : height;
|
|
@@ -493584,12 +493793,28 @@ registerUiCatalogFragment({
|
|
|
493584
493793
|
en: {
|
|
493585
493794
|
"thinking.label": "{name} thinking",
|
|
493586
493795
|
"thinking.aborted": "aborted",
|
|
493796
|
+
"thinking.step": "step {step}",
|
|
493797
|
+
"thinking.effort": "effort {effort}",
|
|
493798
|
+
"thinking.attempt": "attempt {attempt}/{maxAttempts}",
|
|
493799
|
+
"thinking.budget": "budget {budget}",
|
|
493800
|
+
"thinking.heartbeat": "hidden-thought heartbeat {seconds}s ago",
|
|
493801
|
+
"thinking.worked": "Worked {elapsed}",
|
|
493802
|
+
"thinking.finished": "done {time}",
|
|
493803
|
+
"thinking.emptyRetry": "Empty model response; {hint} · budget {before} → {after}",
|
|
493587
493804
|
"thinking.tokens.one": "{count} Token",
|
|
493588
493805
|
"thinking.tokens.other": "{count} Tokens"
|
|
493589
493806
|
},
|
|
493590
493807
|
de: {
|
|
493591
493808
|
"thinking.label": "{name} denkt",
|
|
493592
493809
|
"thinking.aborted": "abgebrochen",
|
|
493810
|
+
"thinking.step": "Schritt {step}",
|
|
493811
|
+
"thinking.effort": "Effort {effort}",
|
|
493812
|
+
"thinking.attempt": "Versuch {attempt}/{maxAttempts}",
|
|
493813
|
+
"thinking.budget": "Budget {budget}",
|
|
493814
|
+
"thinking.heartbeat": "Verdecktes Denken läuft · letzter Takt vor {seconds}s",
|
|
493815
|
+
"thinking.worked": "Gearbeitet {elapsed}",
|
|
493816
|
+
"thinking.finished": "fertig {time}",
|
|
493817
|
+
"thinking.emptyRetry": "Leere Modellantwort; {hint} · Budget {before} → {after}",
|
|
493593
493818
|
"thinking.tokens.one": "{count} Token",
|
|
493594
493819
|
"thinking.tokens.other": "{count} Tokens"
|
|
493595
493820
|
},
|
|
@@ -493643,6 +493868,14 @@ var ThinkingComponent = class {
|
|
|
493643
493868
|
thinkElapsedMs = 0;
|
|
493644
493869
|
thinkAborted = false;
|
|
493645
493870
|
estimatedOutputTokens = 0;
|
|
493871
|
+
step;
|
|
493872
|
+
thinkingEffort;
|
|
493873
|
+
attempt = 1;
|
|
493874
|
+
maxAttempts = 1;
|
|
493875
|
+
completionBudget;
|
|
493876
|
+
lastHeartbeatAtMs;
|
|
493877
|
+
activeToolName;
|
|
493878
|
+
finishedAtMs;
|
|
493646
493879
|
textComponent;
|
|
493647
493880
|
renderCache;
|
|
493648
493881
|
constructor(text, showMarker = true, mode = "finalized", ui, metrics) {
|
|
@@ -493657,6 +493890,7 @@ var ThinkingComponent = class {
|
|
|
493657
493890
|
this.thinkStartMs = metrics?.startedAtMs ?? Date.now();
|
|
493658
493891
|
this.thinkAborted = false;
|
|
493659
493892
|
this.estimatedOutputTokens = metrics?.estimatedOutputTokens ?? 0;
|
|
493893
|
+
this.applyLiveMetrics(metrics ?? {});
|
|
493660
493894
|
}
|
|
493661
493895
|
}
|
|
493662
493896
|
markRenderDirty() {
|
|
@@ -493675,10 +493909,22 @@ var ThinkingComponent = class {
|
|
|
493675
493909
|
}
|
|
493676
493910
|
setLiveMetrics(metrics) {
|
|
493677
493911
|
if (this.mode === "live" && !this.thinkAborted && metrics.startedAtMs !== void 0) this.thinkStartMs = metrics.startedAtMs;
|
|
493678
|
-
|
|
493912
|
+
const before = JSON.stringify([this.estimatedOutputTokens, this.step, this.thinkingEffort, this.attempt, this.maxAttempts, this.completionBudget, this.lastHeartbeatAtMs, this.activeToolName]);
|
|
493679
493913
|
this.estimatedOutputTokens = metrics.estimatedOutputTokens;
|
|
493914
|
+
this.applyLiveMetrics(metrics);
|
|
493915
|
+
const after = JSON.stringify([this.estimatedOutputTokens, this.step, this.thinkingEffort, this.attempt, this.maxAttempts, this.completionBudget, this.lastHeartbeatAtMs, this.activeToolName]);
|
|
493916
|
+
if (before === after) return;
|
|
493680
493917
|
this.markRenderDirty();
|
|
493681
493918
|
}
|
|
493919
|
+
applyLiveMetrics(metrics) {
|
|
493920
|
+
this.step = metrics.step;
|
|
493921
|
+
this.thinkingEffort = metrics.thinkingEffort;
|
|
493922
|
+
this.attempt = metrics.attempt ?? 1;
|
|
493923
|
+
this.maxAttempts = metrics.maxAttempts ?? 1;
|
|
493924
|
+
this.completionBudget = metrics.completionBudget;
|
|
493925
|
+
this.lastHeartbeatAtMs = metrics.lastHeartbeatAtMs;
|
|
493926
|
+
this.activeToolName = metrics.activeToolName;
|
|
493927
|
+
}
|
|
493682
493928
|
styled(text) {
|
|
493683
493929
|
return currentTheme.italicFg("textDim", text);
|
|
493684
493930
|
}
|
|
@@ -493690,6 +493936,7 @@ var ThinkingComponent = class {
|
|
|
493690
493936
|
this.thinkElapsedMs = Date.now() - this.thinkStartMs;
|
|
493691
493937
|
this.thinkStartMs = null;
|
|
493692
493938
|
}
|
|
493939
|
+
this.finishedAtMs = Date.now();
|
|
493693
493940
|
}
|
|
493694
493941
|
dispose() {
|
|
493695
493942
|
this.stopSpinner();
|
|
@@ -493713,12 +493960,24 @@ var ThinkingComponent = class {
|
|
|
493713
493960
|
const abortMark = this.thinkAborted ? ` (${uiText("thinking.aborted")})` : "";
|
|
493714
493961
|
const tokenKey = roundedTokenCount === 1 ? "thinking.tokens.one" : "thinking.tokens.other";
|
|
493715
493962
|
const thinkingLabel = uiText("thinking.label", { name: this.persona });
|
|
493716
|
-
const
|
|
493717
|
-
|
|
493963
|
+
const details = [];
|
|
493964
|
+
if (this.step !== void 0) details.push(uiText("thinking.step", { step: this.step }));
|
|
493965
|
+
if (this.thinkingEffort !== void 0) details.push(uiText("thinking.effort", { effort: this.thinkingEffort }));
|
|
493966
|
+
if (this.attempt > 1 || this.maxAttempts > 1) details.push(uiText("thinking.attempt", { attempt: this.attempt, maxAttempts: this.maxAttempts }));
|
|
493967
|
+
if (this.completionBudget !== void 0) details.push(uiText("thinking.budget", { budget: this.completionBudget.toLocaleString(locale) }));
|
|
493968
|
+
if (this.lastHeartbeatAtMs !== void 0) details.push(uiText("thinking.heartbeat", { seconds: Math.max(0, Math.floor((Date.now() - this.lastHeartbeatAtMs) / 1e3)) }));
|
|
493969
|
+
if (this.activeToolName !== void 0) details.push(this.activeToolName);
|
|
493970
|
+
const detailText = details.length === 0 ? "" : ` · ${details.join(" · ")}`;
|
|
493971
|
+
const fullLabel = `${thinkingLabel}… (${elapsed} · ↓ ~${uiText(tokenKey, { count: tokenCount })}${detailText} · ${startedAt})${abortMark}`;
|
|
493972
|
+
const compactLabel = `${thinkingLabel}… (${elapsed} · ↓${tokenCount}${this.step === void 0 ? "" : ` · #${this.step}`} · ${startedAt})${abortMark}`;
|
|
493718
493973
|
const metricsOnly = `(${elapsed} · ${startedAt})${abortMark}`;
|
|
493719
493974
|
const availableWidth = Math.max(1, width - visibleWidth(spinner));
|
|
493720
493975
|
const label = visibleWidth(fullLabel) <= availableWidth ? fullLabel : visibleWidth(compactLabel) <= availableWidth ? compactLabel : metricsOnly;
|
|
493721
493976
|
rendered = ["", spinner + currentTheme.fg("textDim", truncateToWidth(label, availableWidth))];
|
|
493977
|
+
} else if (this.thinkElapsedMs > 0) {
|
|
493978
|
+
const finishedAt = new Date(this.finishedAtMs ?? Date.now()).toLocaleTimeString(locale, { hour: "2-digit", minute: "2-digit" });
|
|
493979
|
+
const finalLabel = `${uiText("thinking.worked", { elapsed: formatLiveElapsed(this.formatElapsedSeconds()) })} · ${uiText("thinking.finished", { time: finishedAt })}`;
|
|
493980
|
+
rendered = ["", currentTheme.fg("textDim", truncateToWidth(finalLabel, Math.max(1, width)))];
|
|
493722
493981
|
} else rendered = [""];
|
|
493723
493982
|
if (isRenderCacheEnabled()) this.renderCache = {
|
|
493724
493983
|
width,
|
|
@@ -508308,6 +508567,9 @@ var BottomPinnedTUI = class extends TUI {
|
|
|
508308
508567
|
* page-up/down jumps without re-reading the live (possibly stale) value.
|
|
508309
508568
|
*/
|
|
508310
508569
|
getTerminalRows() {
|
|
508570
|
+
return this.getRenderHeight();
|
|
508571
|
+
}
|
|
508572
|
+
getRenderHeight() {
|
|
508311
508573
|
this.ensureResizeLatch();
|
|
508312
508574
|
return this.latchedTerminalRows > 0 ? this.latchedTerminalRows : currentTerminalRows(this.terminal.rows);
|
|
508313
508575
|
}
|
|
@@ -510438,7 +510700,7 @@ var SessionEventHandler = class {
|
|
|
510438
510700
|
this.host.commitQueuedSteerAtStepStart(event.turnId);
|
|
510439
510701
|
this.host.commitChannelPromptAtStepStart(event.turnId);
|
|
510440
510702
|
this.host.streamingUI.flushNow();
|
|
510441
|
-
this.host.streamingUI.
|
|
510703
|
+
this.host.streamingUI.beginStep(event);
|
|
510442
510704
|
this.host.streamingUI.resetToolUi();
|
|
510443
510705
|
this.host.streamingUI.finalizeLiveTextBuffers("waiting");
|
|
510444
510706
|
this.host.patchLivePane({
|
|
@@ -510512,7 +510774,8 @@ var SessionEventHandler = class {
|
|
|
510512
510774
|
handleStepRetrying(event) {
|
|
510513
510775
|
this.turnWatchdog.recordProgress();
|
|
510514
510776
|
const hint = formatModelRetryProgress(event);
|
|
510515
|
-
|
|
510777
|
+
const completionBudgetRetry = event.completionBudgetBefore !== void 0 && event.completionBudgetAfter !== void 0;
|
|
510778
|
+
if (event.outputMayHaveStarted === true || completionBudgetRetry) {
|
|
510516
510779
|
const { streamingUI } = this.host;
|
|
510517
510780
|
streamingUI.flushNow();
|
|
510518
510781
|
streamingUI.discardUnfinishedToolUi();
|
|
@@ -510522,9 +510785,14 @@ var SessionEventHandler = class {
|
|
|
510522
510785
|
kind: "status",
|
|
510523
510786
|
turnId: String(event.turnId),
|
|
510524
510787
|
renderMode: "plain",
|
|
510525
|
-
content: uiText("
|
|
510788
|
+
content: completionBudgetRetry ? uiText("thinking.emptyRetry", {
|
|
510789
|
+
hint,
|
|
510790
|
+
before: event.completionBudgetBefore.toLocaleString(getCurrentUiLocale()),
|
|
510791
|
+
after: event.completionBudgetAfter.toLocaleString(getCurrentUiLocale())
|
|
510792
|
+
}) : uiText("sessionEvent.interrupted.reason", { reason: hint })
|
|
510526
510793
|
});
|
|
510527
510794
|
}
|
|
510795
|
+
this.host.streamingUI.noteStepRetry(event);
|
|
510528
510796
|
this.modelRetryHint = hint;
|
|
510529
510797
|
this.host.state.footer.setTransientHint(hint);
|
|
510530
510798
|
this.host.state.ui.requestRender();
|
|
@@ -510540,6 +510808,7 @@ var SessionEventHandler = class {
|
|
|
510540
510808
|
handleThinkingDelta(event) {
|
|
510541
510809
|
const { state, streamingUI } = this.host;
|
|
510542
510810
|
if (event.delta.length === 0 && !streamingUI.hasThinkingDraft()) return;
|
|
510811
|
+
if (event.delta.trim().length === 0) streamingUI.noteThinkingHeartbeat();
|
|
510543
510812
|
if (event.delta.length > 0) this.turnWatchdog.recordProgress();
|
|
510544
510813
|
if (event.delta.length > 0) this.clearModelRetryHint();
|
|
510545
510814
|
streamingUI.appendThinkingDelta(event.delta);
|
|
@@ -513582,6 +513851,9 @@ var StreamingUIController = class {
|
|
|
513582
513851
|
_remoteTurnActivity = { active: false };
|
|
513583
513852
|
_remoteProcessStartedAt = new Date(Date.now() - process.uptime() * 1e3).toISOString();
|
|
513584
513853
|
_liveTurnStartedAtMs = void 0;
|
|
513854
|
+
_liveStepStartedAtMs = void 0;
|
|
513855
|
+
_liveThinkingHeartbeatAtMs = void 0;
|
|
513856
|
+
_liveStepRequest = {};
|
|
513585
513857
|
_liveOutputTokens = new LiveOutputTokenCounter();
|
|
513586
513858
|
_countedToolCallIds = /* @__PURE__ */ new Set();
|
|
513587
513859
|
_assistantDraft = "";
|
|
@@ -513612,6 +513884,32 @@ var StreamingUIController = class {
|
|
|
513612
513884
|
this._currentStep = step;
|
|
513613
513885
|
this.publishTelegramConsoleStatus();
|
|
513614
513886
|
}
|
|
513887
|
+
beginStep(event) {
|
|
513888
|
+
this.setStep(event.step);
|
|
513889
|
+
this._liveStepStartedAtMs = Date.now();
|
|
513890
|
+
this._liveThinkingHeartbeatAtMs = void 0;
|
|
513891
|
+
this._liveOutputTokens.reset();
|
|
513892
|
+
this._countedToolCallIds.clear();
|
|
513893
|
+
this._liveStepRequest = {
|
|
513894
|
+
thinkingEffort: event.thinkingEffort,
|
|
513895
|
+
completionBudget: event.completionBudget,
|
|
513896
|
+
attempt: event.attempt ?? 1,
|
|
513897
|
+
maxAttempts: event.maxAttempts ?? 1
|
|
513898
|
+
};
|
|
513899
|
+
}
|
|
513900
|
+
noteStepRetry(event) {
|
|
513901
|
+
this._liveStepStartedAtMs = Date.now();
|
|
513902
|
+
this._liveThinkingHeartbeatAtMs = void 0;
|
|
513903
|
+
this._liveStepRequest = {
|
|
513904
|
+
...this._liveStepRequest,
|
|
513905
|
+
attempt: event.nextAttempt,
|
|
513906
|
+
maxAttempts: event.maxAttempts,
|
|
513907
|
+
completionBudget: event.completionBudgetAfter ?? this._liveStepRequest.completionBudget
|
|
513908
|
+
};
|
|
513909
|
+
}
|
|
513910
|
+
noteThinkingHeartbeat() {
|
|
513911
|
+
this._liveThinkingHeartbeatAtMs = Date.now();
|
|
513912
|
+
}
|
|
513615
513913
|
setRemoteTurnActivity(activity) {
|
|
513616
513914
|
const previous = this._remoteTurnActivity;
|
|
513617
513915
|
this._remoteTurnActivity = activity?.active === true ? activity : { active: false };
|
|
@@ -513640,14 +513938,25 @@ var StreamingUIController = class {
|
|
|
513640
513938
|
}
|
|
513641
513939
|
beginLiveTurn() {
|
|
513642
513940
|
this._liveTurnStartedAtMs = Date.now();
|
|
513941
|
+
this._liveStepStartedAtMs = void 0;
|
|
513942
|
+
this._liveThinkingHeartbeatAtMs = void 0;
|
|
513943
|
+
this._liveStepRequest = {};
|
|
513643
513944
|
this._liveOutputTokens.reset();
|
|
513644
513945
|
this._countedToolCallIds.clear();
|
|
513645
513946
|
this.lastFlushAt = void 0;
|
|
513646
513947
|
}
|
|
513647
513948
|
getLiveActivityMetrics() {
|
|
513949
|
+
const activeToolName = [...this._activeToolCalls.values()].at(-1)?.name ?? [...this._streamingToolCallArguments.values()].at(-1)?.name;
|
|
513648
513950
|
return {
|
|
513649
|
-
startedAtMs: this._liveTurnStartedAtMs,
|
|
513650
|
-
estimatedOutputTokens: this._liveOutputTokens.estimatedOutputTokens()
|
|
513951
|
+
startedAtMs: this._liveStepStartedAtMs ?? this._liveTurnStartedAtMs,
|
|
513952
|
+
estimatedOutputTokens: this._liveOutputTokens.estimatedOutputTokens(),
|
|
513953
|
+
step: this._currentStep,
|
|
513954
|
+
thinkingEffort: this._liveStepRequest.thinkingEffort,
|
|
513955
|
+
completionBudget: this._liveStepRequest.completionBudget,
|
|
513956
|
+
attempt: this._liveStepRequest.attempt ?? 1,
|
|
513957
|
+
maxAttempts: this._liveStepRequest.maxAttempts ?? 1,
|
|
513958
|
+
lastHeartbeatAtMs: this._liveThinkingHeartbeatAtMs,
|
|
513959
|
+
activeToolName
|
|
513651
513960
|
};
|
|
513652
513961
|
}
|
|
513653
513962
|
recordLiveOutput(fragment) {
|
|
@@ -513688,6 +513997,9 @@ var StreamingUIController = class {
|
|
|
513688
513997
|
}
|
|
513689
513998
|
resetLiveActivity() {
|
|
513690
513999
|
this._liveTurnStartedAtMs = void 0;
|
|
514000
|
+
this._liveStepStartedAtMs = void 0;
|
|
514001
|
+
this._liveThinkingHeartbeatAtMs = void 0;
|
|
514002
|
+
this._liveStepRequest = {};
|
|
513691
514003
|
this._liveOutputTokens.reset();
|
|
513692
514004
|
this._countedToolCallIds.clear();
|
|
513693
514005
|
}
|