blun-king-cli 9.1.536 → 9.1.561
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 +13 -869
- package/README.md +41 -833
- package/bin/assistant-message-offload-policy.cjs +3 -1
- package/bin/compaction-transaction-policy.cjs +122 -0
- package/bin/context-performance-policy.cjs +2 -5
- package/bin/context-pressure-policy.cjs +20 -0
- package/bin/cron-run-output.cjs +45 -0
- package/bin/cron-run-store.cjs +145 -0
- package/bin/default-model-output-budget-policy.cjs +28 -0
- package/bin/durable-task-resume-policy.cjs +130 -0
- package/bin/durable-task-resume-runtime.cjs +117 -0
- package/bin/durable-task-resume-store.cjs +88 -0
- package/bin/editable-tool-approval-policy.cjs +540 -0
- package/bin/editable-tool-approval-runtime.cjs +99 -0
- package/bin/file-observation-policy.cjs +133 -0
- package/bin/html-to-research-markdown.cjs +146 -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/programmatic-tool-runtime.mjs +330 -4
- package/bin/read-continuation-policy.cjs +36 -5
- package/bin/retry-checkpoint-policy.cjs +13 -0
- package/bin/scoped-cron-run-policy.cjs +358 -0
- package/bin/session-checkpoint-policy.cjs +25 -0
- package/bin/startup-preferences.cjs +4 -3
- package/bin/structured-agent-swarm-output.cjs +325 -0
- package/bin/subagent-context-fork-policy.cjs +155 -0
- package/bin/subagent-skill-policy.cjs +204 -0
- package/bin/telegram-approval-relay.cjs +2 -1
- package/bin/tool-file-persistence.cjs +141 -0
- package/bin/tool-result-offload-policy.cjs +25 -33
- package/bin/turn-thinking-policy.cjs +2 -26
- package/bin/update-notice.js +30 -18
- package/bin/user-message-offload-policy.cjs +3 -1
- package/blun.mjs +1564 -640
- package/codebase-index/README.md +12 -0
- package/codebase-index/codebase_index.py +129 -18
- package/package.json +23 -58
- package/telegram-plugin/bin/telegram-mnemo-capture.cjs +1 -3
- package/telegram-plugin/bin/telegram-typing-keepalive.cjs +89 -0
- package/telegram-plugin/dist/bridge.mjs +8 -1
- package/CHANGELOG.md +0 -321
- package/agent-spine-plugin/CHANGELOG.md +0 -406
- package/agent-spine-plugin/CONTRIBUTING.md +0 -52
- package/agent-spine-plugin/README.md +0 -344
- package/agent-spine-plugin/SECURITY.md +0 -47
- package/agent-spine-plugin/docs/acceptance.md +0 -61
- package/agent-spine-plugin/docs/architecture.md +0 -183
- package/agent-spine-plugin/docs/attention.md +0 -121
- package/agent-spine-plugin/docs/automatic-continuity.md +0 -79
- package/agent-spine-plugin/docs/channel-runtime.md +0 -92
- package/agent-spine-plugin/docs/coordination.md +0 -138
- package/agent-spine-plugin/docs/feed-transport.md +0 -99
- package/agent-spine-plugin/docs/gateway-runtime.md +0 -116
- package/agent-spine-plugin/docs/harness-reference.md +0 -45
- package/agent-spine-plugin/docs/host-integration.md +0 -129
- package/agent-spine-plugin/docs/https-transport.md +0 -116
- package/agent-spine-plugin/docs/learning.md +0 -133
- package/agent-spine-plugin/docs/object-transport.md +0 -93
- package/agent-spine-plugin/docs/peer-transport.md +0 -88
- package/agent-spine-plugin/docs/preflight-recall.md +0 -69
- package/agent-spine-plugin/docs/preservation-contract.md +0 -53
- package/agent-spine-plugin/docs/quality-gates.md +0 -50
- package/agent-spine-plugin/docs/relationships.md +0 -73
- package/agent-spine-plugin/docs/releasing.md +0 -83
- package/agent-spine-plugin/docs/roadmap.md +0 -307
- package/agent-spine-plugin/docs/selfstarter.md +0 -88
- package/agent-spine-plugin/docs/session-briefing.md +0 -74
- package/agent-spine-plugin/docs/shared-memory.md +0 -259
- package/agent-spine-plugin/docs/source-roots.md +0 -86
- package/agent-spine-plugin/docs/sqlite-transport.md +0 -76
- package/agent-spine-plugin/scripts/check-hosts.js +0 -195
- package/agent-spine-plugin/scripts/check-install.js +0 -569
- package/agent-spine-plugin/scripts/check-syntax.js +0 -29
- package/agent-spine-plugin/scripts/github-actions.js +0 -11
- package/agent-spine-plugin/scripts/release-check.js +0 -128
- package/agent-spine-plugin/scripts/run-acceptance.js +0 -19
- package/agent-spine-plugin/scripts/run-checks.js +0 -46
- package/agent-spine-plugin/scripts/run-tests-hermetic.js +0 -73
- package/agent-spine-plugin/spine-example/1-identity.md +0 -12
- package/agent-spine-plugin/spine-example/2-voice.md +0 -6
- package/agent-spine-plugin/spine-example/3-conduct.md +0 -8
- package/agent-spine-plugin/spine-example/4-history.md +0 -4
- package/bin/empty-response-retry-policy.cjs +0 -29
- package/bin/fredrik-glm-provider.cjs +0 -256
- package/bin/package-regression-policy.cjs +0 -77
- package/fredrik-glm-profile.toml.example +0 -26
- package/release-planned-removals.json +0 -15
- package/scripts/check-active-profile-plugin-startup.js +0 -36
- package/scripts/check-active-work-steer-regression.js +0 -46
- package/scripts/check-approval-observability-regression.js +0 -111
- package/scripts/check-approval-queue-shortcuts-regression.js +0 -65
- package/scripts/check-bundled-agent-spine-regression.js +0 -48
- package/scripts/check-codebase-search-packaging-regression.js +0 -92
- package/scripts/check-copy-command-regression.js +0 -74
- package/scripts/check-current-turn-read-pin-mutation-regression.js +0 -72
- package/scripts/check-current-turn-read-pin-regression.js +0 -94
- package/scripts/check-deepseek-native-max-regression.js +0 -49
- package/scripts/check-empty-response-effort-downgrade-regression.js +0 -48
- package/scripts/check-fredrik-glm-mutation-regression.js +0 -18
- package/scripts/check-fredrik-glm-regression.js +0 -169
- package/scripts/check-historical-tool-result-preview-regression.js +0 -77
- package/scripts/check-history-pressure-offload-regression.js +0 -77
- package/scripts/check-mcp-startup-wait-budget.js +0 -48
- package/scripts/check-package-regression.js +0 -38
- package/scripts/check-plugin-startup-regression.js +0 -53
- package/scripts/check-programmatic-context-isolation-regression.js +0 -193
- package/scripts/check-programmatic-tool-regression.js +0 -294
- package/scripts/check-queue-controls-regression.js +0 -189
- package/scripts/check-release-metadata.js +0 -103
- package/scripts/check-reload-agent-spine-regression.js +0 -76
- package/scripts/check-resume-replay-regression.js +0 -102
- package/scripts/check-session-cancel-regression.js +0 -43
- package/scripts/check-session-picker-resume-metrics-regression.js +0 -97
- package/scripts/check-session-start-hook-context-regression.js +0 -228
- package/scripts/check-shell-terminal-isolation-regression.js +0 -81
- package/scripts/check-slash-escape-regression.js +0 -89
- package/scripts/check-startup-swarm-command-regression.js +0 -24
- package/scripts/check-structured-subagent-output-regression.js +0 -331
- package/scripts/check-telegram-bridge-watchdog.js +0 -60
- package/scripts/check-telegram-direct-work-resume-regression.js +0 -53
- package/scripts/check-telegram-loop-exactly-once-regression.js +0 -71
- package/scripts/check-todo-loop-regression.js +0 -78
- package/scripts/check-todo-progress-regression.js +0 -416
- package/scripts/check-todo-recovery-catalog-regression.js +0 -50
- package/scripts/check-tool-schema-capacity-regression.js +0 -40
- package/scripts/programmatic-tool-runtime.test.mjs +0 -365
- package/scripts/structured-subagent-output.test.cjs +0 -170
- /package/{scripts → bin}/fix-node-pty-perms.js +0 -0
package/blun.mjs
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
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);
|
|
6
6
|
const __dirname = __cjsShimDirname(__filename);
|
|
7
7
|
import { createRequire } from "node:module";
|
|
8
|
+
const { htmlToResearchMarkdown } = createRequire(import.meta.url)("./bin/html-to-research-markdown.cjs");
|
|
8
9
|
import telegramConsoleStatusPolicy from "./bin/telegram-console-status-policy.cjs";
|
|
9
10
|
import cognitiveGoalAutostartPolicy from "./bin/cognitive-goal-autostart-policy.cjs";
|
|
10
11
|
import cognitiveGoalTimeTriggerController from "./bin/cognitive-goal-time-trigger-controller.cjs";
|
|
@@ -16,7 +17,8 @@ import sessionScrollbackArchive from "./bin/session-scrollback-archive.cjs";
|
|
|
16
17
|
import sessionReplayWindowPolicy from "./bin/session-replay-window-policy.cjs";
|
|
17
18
|
import globPatternPolicy from "./bin/glob-pattern-policy.cjs";
|
|
18
19
|
import userHomePathPolicy from "./bin/user-home-path-policy.cjs";
|
|
19
|
-
import
|
|
20
|
+
import editableToolApprovalPolicy from "./bin/editable-tool-approval-policy.cjs";
|
|
21
|
+
import editableToolApprovalRuntime from "./bin/editable-tool-approval-runtime.cjs";
|
|
20
22
|
import crypto$1, { createHash, randomBytes, randomInt, randomUUID, timingSafeEqual } from "node:crypto";
|
|
21
23
|
import * as fs$16 from "node:fs";
|
|
22
24
|
import Kt, { accessSync, appendFileSync, chmodSync, closeSync, constants, copyFileSync, createReadStream, createWriteStream, existsSync, fsyncSync, linkSync, lstatSync, mkdirSync, openSync, promises, readFileSync, readSync, readdirSync, realpathSync, renameSync, rmSync, statSync, unlinkSync, writeFileSync, writeSync } from "node:fs";
|
|
@@ -58,17 +60,13 @@ const { replayWindowStartIndex, resolveReplayActiveTurnCount } = sessionReplayWi
|
|
|
58
60
|
const { globPatternError } = globPatternPolicy;
|
|
59
61
|
const { unsupportedUserHomePathError } = userHomePathPolicy;
|
|
60
62
|
const {
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
normalizeEffort: normalizeFredrikGlmEffort,
|
|
69
|
-
requestControls: fredrikGlmRequestControls,
|
|
70
|
-
readApiKeyFile: readFredrikGlmApiKeyFile
|
|
71
|
-
} = fredrikGlmProviderPolicy;
|
|
63
|
+
buildApprovalEditedEvent,
|
|
64
|
+
canonicalEditedToolInputJson,
|
|
65
|
+
isEditableToolApprovalEligible,
|
|
66
|
+
parseEditedToolInputJson,
|
|
67
|
+
validateEditedApprovalDecision
|
|
68
|
+
} = editableToolApprovalPolicy;
|
|
69
|
+
const { buildEditedToolCallPlan } = editableToolApprovalRuntime;
|
|
72
70
|
import { EventEmitter as EventEmitter$1 } from "node:events";
|
|
73
71
|
import { StringDecoder } from "node:string_decoder";
|
|
74
72
|
import co from "node:assert";
|
|
@@ -2733,7 +2731,6 @@ var init_blun = __esmMin((() => {
|
|
|
2733
2731
|
_defaultHeaders;
|
|
2734
2732
|
_generationKwargs;
|
|
2735
2733
|
_supportEfforts;
|
|
2736
|
-
_openAICompatible;
|
|
2737
2734
|
_client;
|
|
2738
2735
|
_clientFactory;
|
|
2739
2736
|
_files;
|
|
@@ -2747,7 +2744,6 @@ var init_blun = __esmMin((() => {
|
|
|
2747
2744
|
this._stream = options.stream ?? true;
|
|
2748
2745
|
this._generationKwargs = { ...options.generationKwargs };
|
|
2749
2746
|
this._supportEfforts = options.supportEfforts ?? [];
|
|
2750
|
-
this._openAICompatible = options.openAICompatible === true;
|
|
2751
2747
|
this._client = this._apiKey === void 0 ? void 0 : createFetchHttpClient({
|
|
2752
2748
|
apiKey: this._apiKey,
|
|
2753
2749
|
baseUrl: this._baseUrl,
|
|
@@ -2802,8 +2798,6 @@ var init_blun = __esmMin((() => {
|
|
|
2802
2798
|
}
|
|
2803
2799
|
const kwargs = { ...this._generationKwargs };
|
|
2804
2800
|
for (const key of Object.keys(kwargs)) if (kwargs[key] === void 0) delete kwargs[key];
|
|
2805
|
-
if (kwargs["max_completion_tokens"] === void 0 && kwargs["max_tokens"] !== void 0) kwargs["max_completion_tokens"] = kwargs["max_tokens"];
|
|
2806
|
-
delete kwargs["max_tokens"];
|
|
2807
2801
|
const { extra_body: extraBody, ...requestKwargs } = kwargs;
|
|
2808
2802
|
const extraBodyRecord = typeof extraBody === "object" && extraBody !== null ? { ...extraBody } : {};
|
|
2809
2803
|
const thinking = sanitizeThinkingConfig(extraBodyRecord.thinking);
|
|
@@ -2859,17 +2853,8 @@ var init_blun = __esmMin((() => {
|
|
|
2859
2853
|
delete requestExtraBody["model"];
|
|
2860
2854
|
delete requestExtraBody["messages"];
|
|
2861
2855
|
if (!thinkingDisabled && thinking?.keep !== void 0) requestExtraBody["thinking"] = { keep: thinking.keep };
|
|
2862
|
-
|
|
2863
|
-
|
|
2864
|
-
delete requestKwargs["chat_template_kwargs"];
|
|
2865
|
-
const controls = fredrikGlmRequestControls(effectiveThinkingEffort ?? "max");
|
|
2866
|
-
requestExtraBody["thinking"] = controls.thinking;
|
|
2867
|
-
requestExtraBody["reasoning_effort"] = controls.reasoning_effort;
|
|
2868
|
-
reasoningRequested = true;
|
|
2869
|
-
} else {
|
|
2870
|
-
const effectiveTemplateKwargs = requestKwargs["chat_template_kwargs"];
|
|
2871
|
-
reasoningRequested = typeof effectiveTemplateKwargs === "object" && effectiveTemplateKwargs !== null && effectiveTemplateKwargs.thinking === true;
|
|
2872
|
-
}
|
|
2856
|
+
const effectiveTemplateKwargs = requestKwargs["chat_template_kwargs"];
|
|
2857
|
+
const reasoningRequested = typeof effectiveTemplateKwargs === "object" && effectiveTemplateKwargs !== null && effectiveTemplateKwargs.thinking === true;
|
|
2873
2858
|
const createParams = {
|
|
2874
2859
|
model: this._model,
|
|
2875
2860
|
messages,
|
|
@@ -2923,7 +2908,7 @@ var init_blun = __esmMin((() => {
|
|
|
2923
2908
|
withMaxCompletionTokens(maxCompletionTokens, options) {
|
|
2924
2909
|
let cap = maxCompletionTokens;
|
|
2925
2910
|
if (options?.usedContextTokens !== void 0 && options?.maxContextTokens !== void 0 && options.maxContextTokens > 0) cap = Math.min(cap, options.maxContextTokens - options.usedContextTokens);
|
|
2926
|
-
return this._withGenerationKwargs({
|
|
2911
|
+
return this._withGenerationKwargs({ max_tokens: Math.max(1, cap) });
|
|
2927
2912
|
}
|
|
2928
2913
|
withExtraBody(extraBody) {
|
|
2929
2914
|
const oldExtra = this._generationKwargs.extra_body ?? {};
|
|
@@ -10013,7 +9998,7 @@ var init_schema = __esmMin((() => {
|
|
|
10013
9998
|
init_matches_rule();
|
|
10014
9999
|
init_errors$8();
|
|
10015
10000
|
init_zod$1();
|
|
10016
|
-
ProviderTypeSchema =
|
|
10001
|
+
ProviderTypeSchema = literal("blun");
|
|
10017
10002
|
OAuthRefSchema = object({
|
|
10018
10003
|
storage: _enum(["file", "keyring"]),
|
|
10019
10004
|
key: string().min(1),
|
|
@@ -10023,7 +10008,6 @@ var init_schema = __esmMin((() => {
|
|
|
10023
10008
|
ProviderConfigSchema = object({
|
|
10024
10009
|
type: ProviderTypeSchema,
|
|
10025
10010
|
apiKey: string().optional(),
|
|
10026
|
-
apiKeyFile: string().optional(),
|
|
10027
10011
|
baseUrl: string().optional(),
|
|
10028
10012
|
defaultModel: string().optional(),
|
|
10029
10013
|
oauth: OAuthRefSchema.optional(),
|
|
@@ -14687,7 +14671,7 @@ async function refreshProviderModels(host, options = {}) {
|
|
|
14687
14671
|
var BLUN_LOCAL_PROVIDER_NAME;
|
|
14688
14672
|
var init_refreshProviderModels = __esmMin((() => {
|
|
14689
14673
|
init_managed_blun();
|
|
14690
|
-
BLUN_LOCAL_PROVIDER_NAME = "
|
|
14674
|
+
BLUN_LOCAL_PROVIDER_NAME = "blun";
|
|
14691
14675
|
}));
|
|
14692
14676
|
//#endregion
|
|
14693
14677
|
//#region ../../packages/oauth/src/index.ts
|
|
@@ -15945,6 +15929,8 @@ function loadRuntimeConfigSafe(filePath, env = process.env) {
|
|
|
15945
15929
|
} catch (error) {
|
|
15946
15930
|
envWarnings.push(`Ignoring BLUN_MODEL_* environment overrides: ${describeUnknownError(error)}`);
|
|
15947
15931
|
}
|
|
15932
|
+
const { applyDefaultModelOutputBudget } = createRequire(import.meta.url)("./bin/default-model-output-budget-policy.cjs");
|
|
15933
|
+
config = applyDefaultModelOutputBudget(config);
|
|
15948
15934
|
return {
|
|
15949
15935
|
config,
|
|
15950
15936
|
fileWarnings,
|
|
@@ -21405,7 +21391,10 @@ var init_flags = __esmMin((() => {
|
|
|
21405
21391
|
var RawSubagentProfileSchema, RawAgentProfileSchema;
|
|
21406
21392
|
var init_types$13 = __esmMin((() => {
|
|
21407
21393
|
init_zod$1();
|
|
21408
|
-
RawSubagentProfileSchema = object({
|
|
21394
|
+
RawSubagentProfileSchema = object({
|
|
21395
|
+
description: string().optional(),
|
|
21396
|
+
skills: array(string()).optional()
|
|
21397
|
+
});
|
|
21409
21398
|
RawAgentProfileSchema = object({
|
|
21410
21399
|
extends: string().optional(),
|
|
21411
21400
|
name: string().min(1),
|
|
@@ -28499,10 +28488,13 @@ function linkResolvedSubagents(mergedProfiles, resolvedProfiles) {
|
|
|
28499
28488
|
for (const [ownerName, owner] of mergedProfiles) {
|
|
28500
28489
|
if (owner.subagents === void 0) continue;
|
|
28501
28490
|
const subagents = {};
|
|
28502
|
-
for (const subagentName of Object.
|
|
28491
|
+
for (const [subagentName, subagentBinding] of Object.entries(owner.subagents)) {
|
|
28503
28492
|
const target = resolvedProfiles.get(subagentName);
|
|
28504
28493
|
if (target === void 0) throwMissingSubagent(ownerName, subagentName);
|
|
28505
|
-
subagents[subagentName] = target
|
|
28494
|
+
subagents[subagentName] = subagentBinding.skills === void 0 ? target : {
|
|
28495
|
+
...target,
|
|
28496
|
+
subagentSkills: [...subagentBinding.skills]
|
|
28497
|
+
};
|
|
28506
28498
|
}
|
|
28507
28499
|
const resolved = resolvedProfiles.get(ownerName);
|
|
28508
28500
|
if (resolved !== void 0) resolved.subagents = subagents;
|
|
@@ -28568,10 +28560,12 @@ var init_load = __esmMin((() => {
|
|
|
28568
28560
|
//#region ../../packages/agent-core/src/profile/default/agent.yaml?raw
|
|
28569
28561
|
var agent_default$1;
|
|
28570
28562
|
var init_agent$3 = __esmMin((() => {
|
|
28571
|
-
agent_default$1 = "name: agent\ndescription: Default BLUN King agent\n\nsystemPromptPath: ./system.md\npromptVars:\n roleAdditional: ''\n\ntools:\n - Read\n - Write\n - Edit\n - Grep\n - Glob\n - Bash\n - TaskList\n - TaskOutput\n - TaskUpdate\n - TaskStop\n - CronCreate\n - CronList\n - CronDelete\n - ReadMediaFile\n - TodoList\n - Skill\n - WebSearch\n - Agent\n - AgentSwarm\n - FetchURL\n - GenerateImage\n - GenerateVideo\n - GenerateSpeech\n - UnderstandImage\n - UnderstandVideo\n - DubVideo\n - LipSyncMedia\n - GetMedia\n - AskUserQuestion\n - MistakeRecord\n - CodebaseSearch\n - EnterPlanMode\n - ExitPlanMode\n - CreateGoal\n - GetGoal\n - SetGoalBudget\n - UpdateGoal\n - mcp__*\n\nsubagents:\n coder:\n description: General software engineering agent — the only subagent type with file-editing tools; use it for any delegated task that must modify code.\n explore:\n description: Fast codebase exploration with prompt-enforced read-only behavior.\n plan:\n description: Read-only implementation planning and architecture design.\n";
|
|
28563
|
+
agent_default$1 = "name: agent\ndescription: Default BLUN King agent\n\nsystemPromptPath: ./system.md\npromptVars:\n roleAdditional: ''\n\ntools:\n - Read\n - Write\n - Edit\n - Grep\n - Glob\n - Bash\n - TaskList\n - TaskOutput\n - TaskUpdate\n - TaskResume\n - TaskStop\n - CronCreate\n - CronList\n - CronDelete\n - ReadMediaFile\n - TodoList\n - Skill\n - WebSearch\n - Agent\n - AgentSwarm\n - FetchURL\n - GenerateImage\n - GenerateVideo\n - GenerateSpeech\n - UnderstandImage\n - UnderstandVideo\n - DubVideo\n - LipSyncMedia\n - GetMedia\n - AskUserQuestion\n - MistakeRecord\n - CodebaseSearch\n - EnterPlanMode\n - ExitPlanMode\n - CreateGoal\n - GetGoal\n - SetGoalBudget\n - UpdateGoal\n - mcp__*\n\nsubagents:\n coder:\n description: General software engineering agent — the only subagent type with file-editing tools; use it for any delegated task that must modify code.\n explore:\n description: Fast codebase exploration with prompt-enforced read-only behavior.\n plan:\n description: Read-only implementation planning and architecture design.\n";
|
|
28564
|
+
agent_default$1 = agent_default$1.replace(" plan:\n", " research:\n description: Read-only web and source research with an explicit two-skill allowlist.\n skills:\n - web-lesen\n - premortem\n plan:\n");
|
|
28572
28565
|
agent_default$1 = agent_default$1.replace(" - Read\n", " - Read\n - ReadBatch\n");
|
|
28573
28566
|
agent_default$1 = agent_default$1.replace(" - TodoList\n", " - TodoList\n - CompactConversation\n");
|
|
28574
28567
|
agent_default$1 = agent_default$1.replace(" - CodebaseSearch\n", " - CodebaseSearch\n - ProgrammaticTool\n");
|
|
28568
|
+
agent_default$1 = agent_default$1.replace(" - CronList\n", " - CronList\n - CronRunList\n - CronRunOutput\n");
|
|
28575
28569
|
}));
|
|
28576
28570
|
//#endregion
|
|
28577
28571
|
//#region ../../packages/agent-core/src/profile/default/coder.yaml?raw
|
|
@@ -28590,6 +28584,13 @@ var init_explore = __esmMin((() => {
|
|
|
28590
28584
|
explore_default = explore_default.replace(" - ReadBatch\n", " - ReadBatch\n - ProgrammaticTool\n");
|
|
28591
28585
|
}));
|
|
28592
28586
|
//#endregion
|
|
28587
|
+
//#region ../../packages/agent-core/src/profile/default/research.yaml?raw
|
|
28588
|
+
var research_default;
|
|
28589
|
+
var init_research = __esmMin((() => {
|
|
28590
|
+
init_explore();
|
|
28591
|
+
research_default = explore_default.replace("name: explore\n", "name: research\n").replace("Fast agent specialized for exploring codebases.", "Read-only agent specialized for source and web research with profile-scoped skills.");
|
|
28592
|
+
}));
|
|
28593
|
+
//#endregion
|
|
28593
28594
|
//#region ../../packages/agent-core/src/profile/default/init.md?raw
|
|
28594
28595
|
var init_default$2;
|
|
28595
28596
|
var init_init = __esmMin((() => {
|
|
@@ -28620,6 +28621,7 @@ var init_default$1 = __esmMin((() => {
|
|
|
28620
28621
|
coder_default = coder_default.replace("\nwhenToUse:", "\nexcludedTools:\n - mcp__plugin-telegram_telegram__reply\n - mcp__plugin-telegram_telegram__react\n - mcp__plugin-telegram_telegram__edit_message\n - mcp__plugin-telegram_telegram__download_attachment\n\nwhenToUse:");
|
|
28621
28622
|
init_explore();
|
|
28622
28623
|
explore_default = explore_default.replace("\nwhenToUse:", "\nexcludedTools:\n - mcp__plugin-telegram_telegram__reply\n - mcp__plugin-telegram_telegram__react\n - mcp__plugin-telegram_telegram__edit_message\n - mcp__plugin-telegram_telegram__download_attachment\n\nwhenToUse:");
|
|
28624
|
+
init_research();
|
|
28623
28625
|
init_init();
|
|
28624
28626
|
init_plan$1();
|
|
28625
28627
|
plan_default = plan_default.replace("\nwhenToUse:", "\nexcludedTools:\n - mcp__plugin-telegram_telegram__reply\n - mcp__plugin-telegram_telegram__react\n - mcp__plugin-telegram_telegram__edit_message\n - mcp__plugin-telegram_telegram__download_attachment\n\nwhenToUse:");
|
|
@@ -28630,6 +28632,7 @@ var init_default$1 = __esmMin((() => {
|
|
|
28630
28632
|
"profile/default/agent.yaml": agent_default$1,
|
|
28631
28633
|
"profile/default/coder.yaml": coder_default,
|
|
28632
28634
|
"profile/default/explore.yaml": explore_default,
|
|
28635
|
+
"profile/default/research.yaml": research_default,
|
|
28633
28636
|
"profile/default/plan.yaml": plan_default,
|
|
28634
28637
|
"profile/default/system.md": system_default
|
|
28635
28638
|
};
|
|
@@ -28638,6 +28641,7 @@ var init_default$1 = __esmMin((() => {
|
|
|
28638
28641
|
"agent.yaml",
|
|
28639
28642
|
"coder.yaml",
|
|
28640
28643
|
"explore.yaml",
|
|
28644
|
+
"research.yaml",
|
|
28641
28645
|
"plan.yaml"
|
|
28642
28646
|
].map((file) => `profile/default/${file}`), PROFILE_SOURCES);
|
|
28643
28647
|
}));
|
|
@@ -29132,6 +29136,9 @@ var init_agent_task = __esmMin((() => {
|
|
|
29132
29136
|
runInBackground;
|
|
29133
29137
|
parentToolCallId;
|
|
29134
29138
|
responseFormat;
|
|
29139
|
+
resumed;
|
|
29140
|
+
replacesTaskId;
|
|
29141
|
+
resumeRootTaskId;
|
|
29135
29142
|
kind = "agent";
|
|
29136
29143
|
idPrefix = "agent";
|
|
29137
29144
|
agentId;
|
|
@@ -29145,6 +29152,9 @@ var init_agent_task = __esmMin((() => {
|
|
|
29145
29152
|
this.runInBackground = options.runInBackground;
|
|
29146
29153
|
this.parentToolCallId = options.parentToolCallId;
|
|
29147
29154
|
this.responseFormat = options.responseFormat;
|
|
29155
|
+
this.resumed = options.resumed;
|
|
29156
|
+
this.replacesTaskId = options.replacesTaskId;
|
|
29157
|
+
this.resumeRootTaskId = options.resumeRootTaskId;
|
|
29148
29158
|
this.agentId = handle.agentId;
|
|
29149
29159
|
this.subagentType = handle.profileName;
|
|
29150
29160
|
}
|
|
@@ -29197,7 +29207,10 @@ var init_agent_task = __esmMin((() => {
|
|
|
29197
29207
|
timeoutMs: this.continuationTimeoutMs,
|
|
29198
29208
|
kind: "agent",
|
|
29199
29209
|
agentId: this.agentId,
|
|
29200
|
-
subagentType: this.subagentType
|
|
29210
|
+
subagentType: this.subagentType,
|
|
29211
|
+
resumed: this.resumed,
|
|
29212
|
+
replacesTaskId: this.replacesTaskId,
|
|
29213
|
+
resumeRootTaskId: this.resumeRootTaskId
|
|
29201
29214
|
};
|
|
29202
29215
|
}
|
|
29203
29216
|
};
|
|
@@ -29470,6 +29483,11 @@ function buildBackgroundTaskNotificationBody(info) {
|
|
|
29470
29483
|
if (info.status === "completed") return baseLine;
|
|
29471
29484
|
const agentId = info.agentId;
|
|
29472
29485
|
if (agentId === void 0 || agentId === info.taskId) return baseLine;
|
|
29486
|
+
if (info.status === "lost") return `${baseLine}${[
|
|
29487
|
+
"",
|
|
29488
|
+
`To recover this interrupted background run explicitly, call TaskResume(task_id="${info.taskId}", prompt="Inspect the preserved state and continue without repeating completed side effects.", description="Resume ${info.description}").`,
|
|
29489
|
+
`TaskResume keeps agent_id "${agentId}" and its context, creates a new linked task_id, and never runs automatically at startup.`
|
|
29490
|
+
].join("\n")}`;
|
|
29473
29491
|
return `${baseLine}${[
|
|
29474
29492
|
"",
|
|
29475
29493
|
`To recover or continue this subagent, call Agent(resume="${agentId}", prompt="Pick up where you left off; redo the last tool call if its result was never observed.").`,
|
|
@@ -29478,7 +29496,7 @@ function buildBackgroundTaskNotificationBody(info) {
|
|
|
29478
29496
|
"The subagent retains its full prior context across the restart, but any in-flight tool call lost its result and may need to be redone."
|
|
29479
29497
|
].join("\n")}`;
|
|
29480
29498
|
}
|
|
29481
|
-
var MAX_OUTPUT_BYTES$2, NOTIFICATION_FALLBACK_PREVIEW_BYTES, MAX_FOREGROUND_CAPTURE_BYTES, captureForegroundOutputChunk, createAbortOutcome, SIGTERM_GRACE_MS$1, USER_INTERRUPT_REASON$1, _ALPHABET, BackgroundManager;
|
|
29499
|
+
var MAX_OUTPUT_BYTES$2, NOTIFICATION_FALLBACK_PREVIEW_BYTES, MAX_FOREGROUND_CAPTURE_BYTES, captureForegroundOutputChunk, createAbortOutcome, DurableTaskResumeStore$1, decorateTaskInfo$1, SIGTERM_GRACE_MS$1, USER_INTERRUPT_REASON$1, _ALPHABET, BackgroundManager;
|
|
29482
29500
|
var init_background = __esmMin((() => {
|
|
29483
29501
|
init_dist$4();
|
|
29484
29502
|
init_errors$4();
|
|
@@ -29494,13 +29512,17 @@ var init_background = __esmMin((() => {
|
|
|
29494
29512
|
NOTIFICATION_FALLBACK_PREVIEW_BYTES = 3e3;
|
|
29495
29513
|
({ MAX_FOREGROUND_CAPTURE_BYTES, captureForegroundOutputChunk } = createRequire(import.meta.url)("./bin/foreground-output-capture-policy.cjs"));
|
|
29496
29514
|
({ createAbortOutcome } = createRequire(import.meta.url)("./bin/abort-listener-policy.cjs"));
|
|
29515
|
+
({ DurableTaskResumeStore: DurableTaskResumeStore$1 } = createRequire(import.meta.url)("./bin/durable-task-resume-store.cjs"));
|
|
29516
|
+
({ decorateTaskInfo: decorateTaskInfo$1 } = createRequire(import.meta.url)("./bin/durable-task-resume-policy.cjs"));
|
|
29497
29517
|
SIGTERM_GRACE_MS$1 = 5e3;
|
|
29498
29518
|
USER_INTERRUPT_REASON$1 = "Interrupted by user";
|
|
29499
29519
|
_ALPHABET = "0123456789abcdefghijklmnopqrstuvwxyz";
|
|
29500
29520
|
BackgroundManager = class {
|
|
29501
29521
|
agent;
|
|
29502
29522
|
persistence;
|
|
29523
|
+
resumeStore;
|
|
29503
29524
|
tasks = /* @__PURE__ */ new Map();
|
|
29525
|
+
reservedTaskIds = /* @__PURE__ */ new Set();
|
|
29504
29526
|
/**
|
|
29505
29527
|
* Ghosts: tasks loaded from disk during reconcile that have no live
|
|
29506
29528
|
* KaosProcess. They appear in `list()` / `getTask()` with status
|
|
@@ -29512,6 +29534,7 @@ var init_background = __esmMin((() => {
|
|
|
29512
29534
|
constructor(agent, persistence) {
|
|
29513
29535
|
this.agent = agent;
|
|
29514
29536
|
this.persistence = persistence;
|
|
29537
|
+
this.resumeStore = persistence?.sessionDir ? new DurableTaskResumeStore$1(persistence.sessionDir) : void 0;
|
|
29515
29538
|
}
|
|
29516
29539
|
fireTerminalEffects(entry) {
|
|
29517
29540
|
if (!this.isDetached(entry)) return;
|
|
@@ -29555,6 +29578,13 @@ var init_background = __esmMin((() => {
|
|
|
29555
29578
|
isDetached(entry) {
|
|
29556
29579
|
return entry.foregroundRelease === void 0;
|
|
29557
29580
|
}
|
|
29581
|
+
reserveTaskId(prefix) {
|
|
29582
|
+
let taskId;
|
|
29583
|
+
do taskId = generateTaskId(prefix);
|
|
29584
|
+
while (this.tasks.has(taskId) || this.ghosts.has(taskId) || this.reservedTaskIds.has(taskId) || this.resumeStore?.list().some((intent) => intent.replacementTaskId === taskId));
|
|
29585
|
+
this.reservedTaskIds.add(taskId);
|
|
29586
|
+
return taskId;
|
|
29587
|
+
}
|
|
29558
29588
|
registerTask(task, options = {}) {
|
|
29559
29589
|
const detached = options.detached ?? true;
|
|
29560
29590
|
const entryOptions = {
|
|
@@ -29564,7 +29594,10 @@ var init_background = __esmMin((() => {
|
|
|
29564
29594
|
signal: detached ? void 0 : options.signal
|
|
29565
29595
|
};
|
|
29566
29596
|
this.assertCanRegister(detached);
|
|
29567
|
-
const taskId =
|
|
29597
|
+
const taskId = options.taskId ?? this.reserveTaskId(task.idPrefix);
|
|
29598
|
+
if (!VALID_TASK_ID$1.test(taskId)) throw new Error(`Invalid task id: "${taskId}"`);
|
|
29599
|
+
if (this.tasks.has(taskId) || this.ghosts.has(taskId)) throw new Error(`Task id already exists: ${taskId}`);
|
|
29600
|
+
this.reservedTaskIds.delete(taskId);
|
|
29568
29601
|
const entry = {
|
|
29569
29602
|
taskId,
|
|
29570
29603
|
task,
|
|
@@ -29598,8 +29631,8 @@ var init_background = __esmMin((() => {
|
|
|
29598
29631
|
/** Get info about a specific task. Falls back to reconcile ghosts. */
|
|
29599
29632
|
getTask(taskId) {
|
|
29600
29633
|
const entry = this.tasks.get(taskId);
|
|
29601
|
-
|
|
29602
|
-
return this.
|
|
29634
|
+
const info = entry !== void 0 ? this.toInfo(entry) : this.ghosts.get(taskId);
|
|
29635
|
+
return decorateTaskInfo$1(info, this.resumeStore?.getBySourceTaskId(taskId));
|
|
29603
29636
|
}
|
|
29604
29637
|
updateAgentTask(taskId, message) {
|
|
29605
29638
|
const entry = this.tasks.get(taskId);
|
|
@@ -29622,12 +29655,13 @@ var init_background = __esmMin((() => {
|
|
|
29622
29655
|
list(activeOnly = true, limit) {
|
|
29623
29656
|
const result = [];
|
|
29624
29657
|
for (const entry of this.tasks.values()) {
|
|
29625
|
-
const info = this.toInfo(entry);
|
|
29658
|
+
const info = decorateTaskInfo$1(this.toInfo(entry), this.resumeStore?.getBySourceTaskId(entry.taskId));
|
|
29626
29659
|
if (!this.shouldListTask(info, activeOnly)) continue;
|
|
29627
29660
|
result.push(info);
|
|
29628
29661
|
if (limit !== void 0 && result.length >= limit) return result;
|
|
29629
29662
|
}
|
|
29630
|
-
if (!activeOnly) for (const
|
|
29663
|
+
if (!activeOnly) for (const storedGhost of this.ghosts.values()) {
|
|
29664
|
+
const ghost = decorateTaskInfo$1(storedGhost, this.resumeStore?.getBySourceTaskId(storedGhost.taskId));
|
|
29631
29665
|
if (!this.shouldListTask(ghost, activeOnly)) continue;
|
|
29632
29666
|
result.push(ghost);
|
|
29633
29667
|
if (limit !== void 0 && result.length >= limit) return result;
|
|
@@ -29775,6 +29809,7 @@ var init_background = __esmMin((() => {
|
|
|
29775
29809
|
async loadFromDisk() {
|
|
29776
29810
|
const persistence = this.persistence;
|
|
29777
29811
|
if (persistence === void 0) return;
|
|
29812
|
+
await this.resumeStore?.load();
|
|
29778
29813
|
this.ghosts.clear();
|
|
29779
29814
|
const persisted = await persistence.listTasks();
|
|
29780
29815
|
for (const t of persisted) {
|
|
@@ -29820,6 +29855,11 @@ var init_background = __esmMin((() => {
|
|
|
29820
29855
|
entry.persistWriteQueue = entry.persistWriteQueue.then(() => persistence.writeTask(info)).catch(() => {});
|
|
29821
29856
|
return entry.persistWriteQueue;
|
|
29822
29857
|
}
|
|
29858
|
+
async awaitTaskPersisted(taskId) {
|
|
29859
|
+
const entry = this.tasks.get(taskId);
|
|
29860
|
+
if (entry === void 0) throw new Error(`Task not found: ${taskId}`);
|
|
29861
|
+
await entry.persistWriteQueue;
|
|
29862
|
+
}
|
|
29823
29863
|
appendOutput(entry, chunk) {
|
|
29824
29864
|
const capture = this.isDetached(entry) ? {
|
|
29825
29865
|
capturedText: chunk,
|
|
@@ -30307,7 +30347,6 @@ function resolveCompletionBudget(args) {
|
|
|
30307
30347
|
const fromLegacy = parseEnvBudget(env["BLUN_MODEL_MAX_TOKENS"]);
|
|
30308
30348
|
if (fromLegacy !== "absent") return fromLegacy === "disabled" ? void 0 : { hardCap: fromLegacy };
|
|
30309
30349
|
if (args.maxOutputSize !== void 0 && args.maxOutputSize > 0) return { hardCap: args.maxOutputSize };
|
|
30310
|
-
if (args.reservedContextSize !== void 0 && args.reservedContextSize > 0) return { fallback: args.reservedContextSize };
|
|
30311
30350
|
return { fallback: DEFAULT_UNKNOWN_CONTEXT_FALLBACK };
|
|
30312
30351
|
}
|
|
30313
30352
|
function parseEnvBudget(raw) {
|
|
@@ -30360,13 +30399,12 @@ function applyCompletionBudgetWithDetails(args) {
|
|
|
30360
30399
|
var MIN_FLOOR, DEFAULT_UNKNOWN_CONTEXT_FALLBACK, MIN_THINKING_COMPLETION_TOKENS, COMPLETION_CONTEXT_SAFETY_MARGIN;
|
|
30361
30400
|
var init_completion_budget = __esmMin((() => {
|
|
30362
30401
|
MIN_FLOOR = 1;
|
|
30363
|
-
DEFAULT_UNKNOWN_CONTEXT_FALLBACK =
|
|
30402
|
+
DEFAULT_UNKNOWN_CONTEXT_FALLBACK = 65536;
|
|
30364
30403
|
MIN_THINKING_COMPLETION_TOKENS = 1024;
|
|
30365
30404
|
COMPLETION_CONTEXT_SAFETY_MARGIN = 1e4;
|
|
30366
30405
|
}));
|
|
30367
30406
|
//#endregion
|
|
30368
30407
|
//#region ../../packages/agent-core/src/loop/retry.ts
|
|
30369
|
-
var { nextThinkingEffortForExhaustedEmpty } = createRequire(import.meta.url)("./bin/empty-response-retry-policy.cjs");
|
|
30370
30408
|
async function chatWithRetry(input) {
|
|
30371
30409
|
const maxAttempts = input.maxAttempts ?? 3;
|
|
30372
30410
|
if (input.llm.isRetryableError === void 0 || maxAttempts <= 1) {
|
|
@@ -30380,10 +30418,9 @@ async function chatWithRetry(input) {
|
|
|
30380
30418
|
}
|
|
30381
30419
|
const delays = retryBackoffDelays(maxAttempts);
|
|
30382
30420
|
let completionBudgetRetry;
|
|
30383
|
-
let thinkingEffortRetry;
|
|
30384
30421
|
let emptyRetryKind;
|
|
30385
30422
|
for (let attempt = 1;; attempt += 1) try {
|
|
30386
|
-
return await input.llm.chat(paramsForAttempt(input, attempt, maxAttempts, completionBudgetRetry
|
|
30423
|
+
return await input.llm.chat(paramsForAttempt(input, attempt, maxAttempts, completionBudgetRetry));
|
|
30387
30424
|
} catch (error) {
|
|
30388
30425
|
if (error instanceof APIEmptyResponseError && (emptyRetryKind !== void 0 || error.emptyResponseKind === "length" || error.emptyResponseKind === "stop")) {
|
|
30389
30426
|
logEmptyResponse(input, error, attempt);
|
|
@@ -30393,24 +30430,24 @@ async function chatWithRetry(input) {
|
|
|
30393
30430
|
throw terminal;
|
|
30394
30431
|
}
|
|
30395
30432
|
completionBudgetRetry = completionBudgetRetryForEmpty(error);
|
|
30396
|
-
thinkingEffortRetry = nextThinkingEffortForExhaustedEmpty({
|
|
30397
|
-
emptyResponseKind: error.emptyResponseKind,
|
|
30398
|
-
maxCompletionTokens: error.maxCompletionTokens,
|
|
30399
|
-
completionTokens: error.completionTokens,
|
|
30400
|
-
thinkingEffort: input.llm.thinkingEffort
|
|
30401
|
-
});
|
|
30402
30433
|
emptyRetryKind = error.emptyResponseKind;
|
|
30403
30434
|
input.params.signal.throwIfAborted();
|
|
30404
|
-
|
|
30405
|
-
|
|
30406
|
-
|
|
30407
|
-
|
|
30408
|
-
|
|
30409
|
-
|
|
30410
|
-
|
|
30411
|
-
|
|
30412
|
-
|
|
30413
|
-
|
|
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
|
+
}
|
|
30414
30451
|
});
|
|
30415
30452
|
continue;
|
|
30416
30453
|
}
|
|
@@ -30420,17 +30457,22 @@ async function chatWithRetry(input) {
|
|
|
30420
30457
|
}
|
|
30421
30458
|
const delayMs = retryDelayForError(error, delays[attempt - 1] ?? 0);
|
|
30422
30459
|
input.params.signal.throwIfAborted();
|
|
30423
|
-
|
|
30424
|
-
|
|
30425
|
-
|
|
30426
|
-
|
|
30427
|
-
|
|
30428
|
-
|
|
30429
|
-
|
|
30430
|
-
|
|
30431
|
-
|
|
30432
|
-
|
|
30433
|
-
|
|
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
|
+
}
|
|
30434
30476
|
});
|
|
30435
30477
|
await sleepForRetry(delayMs, input.params.signal);
|
|
30436
30478
|
}
|
|
@@ -30442,6 +30484,14 @@ function completionBudgetRetryForEmpty(error) {
|
|
|
30442
30484
|
multiplier: 2
|
|
30443
30485
|
};
|
|
30444
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
|
+
}
|
|
30445
30495
|
function retryDelayForError(error, fallbackDelayMs) {
|
|
30446
30496
|
if (!(error instanceof APIProviderRateLimitError) || error.retryAfterMs === null) return fallbackDelayMs;
|
|
30447
30497
|
return Math.max(fallbackDelayMs, error.retryAfterMs);
|
|
@@ -30455,12 +30505,11 @@ function logRequestFailure(input, error, attempt, maxAttempts) {
|
|
|
30455
30505
|
...retryErrorFields(error)
|
|
30456
30506
|
});
|
|
30457
30507
|
}
|
|
30458
|
-
function paramsForAttempt(input, attempt, maxAttempts, completionBudgetRetry
|
|
30508
|
+
function paramsForAttempt(input, attempt, maxAttempts, completionBudgetRetry) {
|
|
30459
30509
|
const turnStep = `${input.turnId}.${String(input.currentStep)}`;
|
|
30460
30510
|
return {
|
|
30461
30511
|
...input.params,
|
|
30462
30512
|
completionBudgetRetry,
|
|
30463
|
-
thinkingEffortRetry,
|
|
30464
30513
|
requestLogFields: attempt === 1 ? { turnStep } : {
|
|
30465
30514
|
turnStep,
|
|
30466
30515
|
attempt: `${String(attempt)}/${String(maxAttempts)}`
|
|
@@ -30468,19 +30517,12 @@ function paramsForAttempt(input, attempt, maxAttempts, completionBudgetRetry, th
|
|
|
30468
30517
|
};
|
|
30469
30518
|
}
|
|
30470
30519
|
function logEmptyResponse(input, error, attempt) {
|
|
30471
|
-
const retryThinkingEffort = nextThinkingEffortForExhaustedEmpty({
|
|
30472
|
-
emptyResponseKind: error.emptyResponseKind,
|
|
30473
|
-
maxCompletionTokens: error.maxCompletionTokens,
|
|
30474
|
-
completionTokens: error.completionTokens,
|
|
30475
|
-
thinkingEffort: input.llm.thinkingEffort
|
|
30476
|
-
});
|
|
30477
30520
|
input.log?.warn(`[leer] fall=${error.emptyResponseKind}`, {
|
|
30478
30521
|
turnStep: `${input.turnId}.${String(input.currentStep)}`,
|
|
30479
30522
|
attempt,
|
|
30480
30523
|
budget: error.maxCompletionTokens,
|
|
30481
30524
|
completion: error.completionTokens,
|
|
30482
|
-
reasoningLength: error.reasoningLength
|
|
30483
|
-
...retryThinkingEffort === void 0 ? {} : { retryThinkingEffort }
|
|
30525
|
+
reasoningLength: error.reasoningLength
|
|
30484
30526
|
});
|
|
30485
30527
|
}
|
|
30486
30528
|
function retryBackoffDelays(maxAttempts) {
|
|
@@ -30508,7 +30550,7 @@ function maybeStatusCode(error) {
|
|
|
30508
30550
|
const statusCode = error.statusCode;
|
|
30509
30551
|
return typeof statusCode === "number" ? statusCode : void 0;
|
|
30510
30552
|
}
|
|
30511
|
-
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;
|
|
30512
30554
|
var init_retry = __esmMin((() => {
|
|
30513
30555
|
init_dist$4();
|
|
30514
30556
|
init_src$4();
|
|
@@ -30516,6 +30558,7 @@ var init_retry = __esmMin((() => {
|
|
|
30516
30558
|
init_abort();
|
|
30517
30559
|
init_completion_budget();
|
|
30518
30560
|
init_errors$4();
|
|
30561
|
+
({ persistRetrySchedule } = createRequire(import.meta.url)("./bin/retry-checkpoint-policy.cjs"));
|
|
30519
30562
|
RETRY_MIN_TIMEOUT_MS = 300;
|
|
30520
30563
|
RETRY_MAX_TIMEOUT_MS = 5e3;
|
|
30521
30564
|
RETRY_FACTOR = 2;
|
|
@@ -30653,7 +30696,7 @@ var init_programmatic_tool = __esmMin((() => {
|
|
|
30653
30696
|
PROGRAMMATIC_TOOL_NAME = "ProgrammaticTool";
|
|
30654
30697
|
ProgrammaticTool = class {
|
|
30655
30698
|
name = PROGRAMMATIC_TOOL_NAME;
|
|
30656
|
-
description = "Run bounded JavaScript in an isolated QuickJS interpreter to coordinate several sequential BLUN tool calls without returning every intermediate value to the model context. Declare every callable tool explicitly with its current BLUN name and a JavaScript alias. Calls still pass through the normal schema, hook, permission, scheduler, event, and result pipeline; denied or unavailable tools fail inside the program. The interpreter has no host filesystem, network, process, package loader, clock, or dynamic eval. Return a JSON-serializable result and use the JSON state object only for explicit continuation.";
|
|
30699
|
+
description = "Run bounded JavaScript in an isolated QuickJS interpreter to coordinate several sequential BLUN tool calls without returning every intermediate value to the model context. Declare every callable tool explicitly with its current BLUN name and a JavaScript alias. Calls still pass through the normal schema, hook, permission, scheduler, event, and result pipeline; denied or unavailable tools fail inside the program. The interpreter has no host filesystem, network, process, package loader, clock, or dynamic eval. Use bounded console.log, console.warn, or console.error diagnostics when needed. Return a JSON-serializable result and use the JSON state object only for explicit continuation.";
|
|
30657
30700
|
parameters = {
|
|
30658
30701
|
type: "object",
|
|
30659
30702
|
properties: {
|
|
@@ -30724,8 +30767,13 @@ var init_programmatic_tool = __esmMin((() => {
|
|
|
30724
30767
|
if (context.invokeTool.stopTurn === true) result.stopTurn = true;
|
|
30725
30768
|
return result;
|
|
30726
30769
|
} catch (error) {
|
|
30770
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
30771
|
+
const programmaticConsole = error && typeof error === "object" ? error.programmaticConsole : void 0;
|
|
30727
30772
|
const result = {
|
|
30728
|
-
output:
|
|
30773
|
+
output: programmaticConsole ? JSON.stringify({
|
|
30774
|
+
error: message,
|
|
30775
|
+
console: programmaticConsole
|
|
30776
|
+
}) : message,
|
|
30729
30777
|
isError: true
|
|
30730
30778
|
};
|
|
30731
30779
|
if (context.invokeTool.stopTurn === true) result.stopTurn = true;
|
|
@@ -74888,6 +74936,25 @@ var init_kosong_llm = __esmMin((() => {
|
|
|
74888
74936
|
get thinkingEffort() {
|
|
74889
74937
|
return this.provider.thinkingEffort;
|
|
74890
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
|
+
}
|
|
74891
74958
|
notifyMediaDropped(dropped) {
|
|
74892
74959
|
if (this.onMediaDropped === void 0) return;
|
|
74893
74960
|
const fresh = dropped.filter((part) => {
|
|
@@ -74930,25 +74997,12 @@ var init_kosong_llm = __esmMin((() => {
|
|
|
74930
74997
|
let result;
|
|
74931
74998
|
let completionBudget;
|
|
74932
74999
|
try {
|
|
74933
|
-
const requestProvider = params.thinkingEffortRetry === void 0 ? this.provider : this.provider.withThinking(params.thinkingEffortRetry);
|
|
74934
75000
|
const enrichedMessages = this.visionReader === void 0 ? params.messages : await enrichMessagesWithVision(params.messages, this.visionReader, params.signal, this.onVisionUsage);
|
|
74935
75001
|
const tools = [...params.tools];
|
|
74936
75002
|
const outgoingMessages = downgradeUnsupportedMedia(enrichedMessages, this.capability, (dropped) => {
|
|
74937
75003
|
this.notifyMediaDropped(dropped);
|
|
74938
75004
|
});
|
|
74939
|
-
|
|
74940
|
-
const reportedContextTokens = this.reportedContextTokens?.() ?? 0;
|
|
74941
|
-
const usedContextTokens = Math.max(outgoingRequestTokens, reportedContextTokens);
|
|
74942
|
-
completionBudget = applyCompletionBudgetWithDetails({
|
|
74943
|
-
provider: requestProvider,
|
|
74944
|
-
budget: this.completionBudgetConfig,
|
|
74945
|
-
capability: this.capability,
|
|
74946
|
-
usedContextTokens,
|
|
74947
|
-
retry: params.completionBudgetRetry ?? (thinkingEnabled(requestProvider.thinkingEffort) ? {
|
|
74948
|
-
minimumCompletionTokens: 1024,
|
|
74949
|
-
multiplier: 1
|
|
74950
|
-
} : void 0)
|
|
74951
|
-
});
|
|
75005
|
+
completionBudget = this.describeRequest(outgoingMessages, tools, params.completionBudgetRetry).details;
|
|
74952
75006
|
result = await this.generate(completionBudget.provider, this.systemPrompt, tools, outgoingMessages, callbacks, options);
|
|
74953
75007
|
} catch (error) {
|
|
74954
75008
|
if (error instanceof APIEmptyResponseError) throw error.withMetadata({ maxCompletionTokens: completionBudget === void 0 ? null : completionBudget.maxCompletionTokens ?? null });
|
|
@@ -75471,12 +75525,13 @@ function extractCompactionSummary(response) {
|
|
|
75471
75525
|
if (summary.trim().length === 0) throw new APIEmptyResponseError("The compaction response did not contain a non-empty summary.");
|
|
75472
75526
|
return summary;
|
|
75473
75527
|
}
|
|
75474
|
-
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;
|
|
75475
75529
|
var init_full = __esmMin((() => {
|
|
75476
75530
|
({ archiveCompactionHistory, buildCompactionArchiveNotice } = createRequire(import.meta.url)("./bin/compaction-history-archive.cjs"));
|
|
75477
75531
|
({ waitForAbortableCompletion } = createRequire(import.meta.url)("./bin/abort-listener-policy.cjs"));
|
|
75478
75532
|
({ capCompactionCompletionTokens, capCompactionStageTarget } = createRequire(import.meta.url)("./bin/compaction-stage-policy.cjs"));
|
|
75479
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"));
|
|
75480
75535
|
init_errors$8();
|
|
75481
75536
|
init_src$4();
|
|
75482
75537
|
init_errors$4();
|
|
@@ -75563,23 +75618,27 @@ var init_full = __esmMin((() => {
|
|
|
75563
75618
|
const budget = this.strategy.compactionBudgetTokens;
|
|
75564
75619
|
return budget !== void 0 && Number.isFinite(budget) && budget > 0 ? Math.floor(budget) : void 0;
|
|
75565
75620
|
}
|
|
75566
|
-
proactiveCompactionStatus() {
|
|
75567
|
-
|
|
75568
|
-
|
|
75569
|
-
|
|
75570
|
-
|
|
75571
|
-
|
|
75572
|
-
|
|
75621
|
+
proactiveCompactionStatus(context = {}) {
|
|
75622
|
+
const usedTokens = this.estimateCurrentRequestTokens(context);
|
|
75623
|
+
return {
|
|
75624
|
+
...proactiveCompactionEligibility({
|
|
75625
|
+
usedTokens,
|
|
75626
|
+
budgetTokens: this.getCompactionBudgetTokens(),
|
|
75627
|
+
hasShrinkableHistory: this.hasShrinkableHistory(this.agent.context.history),
|
|
75628
|
+
isCompacting: this.isCompacting
|
|
75629
|
+
}),
|
|
75630
|
+
usedTokens
|
|
75631
|
+
};
|
|
75573
75632
|
}
|
|
75574
75633
|
isProactiveCompactionEligible() {
|
|
75575
75634
|
return this.proactiveCompactionStatus().eligible;
|
|
75576
75635
|
}
|
|
75577
|
-
requestProactiveCompaction() {
|
|
75578
|
-
const status = this.proactiveCompactionStatus();
|
|
75636
|
+
requestProactiveCompaction(context = {}) {
|
|
75637
|
+
const status = this.proactiveCompactionStatus(context);
|
|
75579
75638
|
if (!status.eligible) return status;
|
|
75580
75639
|
this.proactiveCompactionRequested = true;
|
|
75581
75640
|
this.agent.telemetry.track("proactive_compaction_requested", {
|
|
75582
|
-
used_tokens:
|
|
75641
|
+
used_tokens: status.usedTokens,
|
|
75583
75642
|
threshold_tokens: status.thresholdTokens
|
|
75584
75643
|
});
|
|
75585
75644
|
return status;
|
|
@@ -75623,6 +75682,15 @@ var init_full = __esmMin((() => {
|
|
|
75623
75682
|
}
|
|
75624
75683
|
if (this.agent.context.history.length === 0) throw new BlunError(ErrorCodes.COMPACTION_UNABLE, "No messages to compact in current history.");
|
|
75625
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);
|
|
75626
75694
|
this.agent.records.logRecord({
|
|
75627
75695
|
type: "full_compaction.begin",
|
|
75628
75696
|
...data
|
|
@@ -75635,20 +75703,32 @@ var init_full = __esmMin((() => {
|
|
|
75635
75703
|
const abortController = new AbortController();
|
|
75636
75704
|
this.compacting = {
|
|
75637
75705
|
abortController,
|
|
75638
|
-
promise: this.compactionWorker(abortController.signal, data),
|
|
75706
|
+
promise: this.compactionWorker(abortController.signal, data, transaction),
|
|
75707
|
+
transaction,
|
|
75639
75708
|
blockedByTurn: false
|
|
75640
75709
|
};
|
|
75641
75710
|
}
|
|
75642
|
-
|
|
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) {
|
|
75643
75721
|
this.agent.replayBuilder.patchLast("compaction", { result: "cancelled" });
|
|
75644
75722
|
if (!this.compacting) return;
|
|
75645
75723
|
this.agent.records.logRecord({ type: "full_compaction.cancel" });
|
|
75724
|
+
this.closeTransaction(error === void 0 ? "cancelled" : "failed", error);
|
|
75646
75725
|
this.compacting.abortController.abort();
|
|
75647
75726
|
this.compacting = null;
|
|
75648
75727
|
this.agent.emitEvent({ type: "compaction.cancelled" });
|
|
75649
75728
|
}
|
|
75650
75729
|
markCompleted() {
|
|
75651
75730
|
this.agent.records.logRecord({ type: "full_compaction.complete" });
|
|
75731
|
+
this.closeTransaction("success");
|
|
75652
75732
|
this.compacting = null;
|
|
75653
75733
|
}
|
|
75654
75734
|
get tokenCountWithPending() {
|
|
@@ -75675,9 +75755,19 @@ var init_full = __esmMin((() => {
|
|
|
75675
75755
|
const requestMessages = requestContext.messages ?? this.agent.context.messages;
|
|
75676
75756
|
const projectedMessages = requestContext.additionalMessages === void 0 ? requestMessages : [...requestMessages, ...requestContext.additionalMessages];
|
|
75677
75757
|
const requestTokens = this.estimateCurrentRequestTokens(requestContext);
|
|
75678
|
-
const proactiveStatus = this.requestProactiveCompaction();
|
|
75758
|
+
const proactiveStatus = this.requestProactiveCompaction(requestContext);
|
|
75679
75759
|
if (proactiveStatus.eligible) {
|
|
75680
75760
|
this.proactiveCompactionRequested = false;
|
|
75761
|
+
this.agent.records.logRecord({
|
|
75762
|
+
type: "policy.intervention",
|
|
75763
|
+
policy: "proactive_compaction_trigger",
|
|
75764
|
+
location: "FullCompaction.beforeStep",
|
|
75765
|
+
size_before: this.estimateCurrentRequestTokens(),
|
|
75766
|
+
size_after: proactiveStatus.usedTokens,
|
|
75767
|
+
unit: "tokens",
|
|
75768
|
+
threshold_tokens: proactiveStatus.thresholdTokens,
|
|
75769
|
+
selected_tool_count: requestContext.tools?.length ?? 0
|
|
75770
|
+
});
|
|
75681
75771
|
if (!this.compacting) this.beginAutoCompaction();
|
|
75682
75772
|
await this.block(signal);
|
|
75683
75773
|
}
|
|
@@ -75747,9 +75837,9 @@ var init_full = __esmMin((() => {
|
|
|
75747
75837
|
await waitForAbortableCompletion(signal, active.promise, onAbort);
|
|
75748
75838
|
}
|
|
75749
75839
|
}
|
|
75750
|
-
async compactionWorker(signal, data) {
|
|
75840
|
+
async compactionWorker(signal, data, transaction) {
|
|
75751
75841
|
try {
|
|
75752
|
-
const output = await this.compactionRound(signal, data);
|
|
75842
|
+
const output = await this.compactionRound(signal, data, transaction);
|
|
75753
75843
|
if (!output) return;
|
|
75754
75844
|
const { result, stageCount } = output;
|
|
75755
75845
|
try {
|
|
@@ -75774,9 +75864,12 @@ var init_full = __esmMin((() => {
|
|
|
75774
75864
|
});
|
|
75775
75865
|
this.triggerPostCompactHook(data, result);
|
|
75776
75866
|
} catch (error) {
|
|
75777
|
-
if (isAbortError$4(error))
|
|
75867
|
+
if (isAbortError$4(error)) {
|
|
75868
|
+
if (this.compacting?.transaction === transaction) this.cancel();
|
|
75869
|
+
return;
|
|
75870
|
+
}
|
|
75778
75871
|
const blockedByTurn = this.compacting?.blockedByTurn === true;
|
|
75779
|
-
this.cancel();
|
|
75872
|
+
this.cancel(error);
|
|
75780
75873
|
this.agent.log.error("compaction failed", { error });
|
|
75781
75874
|
if (blockedByTurn) throw error;
|
|
75782
75875
|
this.agent.emitEvent({
|
|
@@ -75796,7 +75889,7 @@ var init_full = __esmMin((() => {
|
|
|
75796
75889
|
const todoMarkdown = renderTodoList(todos, "## TODO List");
|
|
75797
75890
|
return `${summary.trim()}\n\n${todoMarkdown}`;
|
|
75798
75891
|
}
|
|
75799
|
-
async compactionRound(signal, data) {
|
|
75892
|
+
async compactionRound(signal, data, transaction) {
|
|
75800
75893
|
const startedAt = Date.now();
|
|
75801
75894
|
const originalHistory = [...this.agent.context.history];
|
|
75802
75895
|
const tokensBefore = estimateTokensForMessages(originalHistory);
|
|
@@ -76072,7 +76165,9 @@ var init_full = __esmMin((() => {
|
|
|
76072
76165
|
contextSummary,
|
|
76073
76166
|
compactedCount: originalHistory.length,
|
|
76074
76167
|
tokensBefore,
|
|
76075
|
-
droppedCount: droppedCount === 0 ? void 0 : droppedCount
|
|
76168
|
+
droppedCount: droppedCount === 0 ? void 0 : droppedCount,
|
|
76169
|
+
transaction,
|
|
76170
|
+
historyBefore: originalHistory
|
|
76076
76171
|
});
|
|
76077
76172
|
this.agent.telemetry.track("compaction_finished", {
|
|
76078
76173
|
source: data.source,
|
|
@@ -76183,10 +76278,18 @@ var init_full = __esmMin((() => {
|
|
|
76183
76278
|
}));
|
|
76184
76279
|
//#endregion
|
|
76185
76280
|
//#region ../../packages/agent-core/src/agent/compaction/micro.ts
|
|
76186
|
-
|
|
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;
|
|
76187
76290
|
var init_micro = __esmMin((() => {
|
|
76188
76291
|
({ isWireOnlyProgrammaticEvent } = createRequire(import.meta.url)("./bin/programmatic-context-isolation.cjs"));
|
|
76189
|
-
({ 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"));
|
|
76190
76293
|
({ isPersistedToolResultReference, freshToolResultIds } = createRequire(import.meta.url)("./bin/tool-result-offload-policy.cjs"));
|
|
76191
76294
|
({ projectHistoricalUnaddressedTelegramMessages } = createRequire(import.meta.url)("./bin/telegram-context-projection-policy.cjs"));
|
|
76192
76295
|
({ dedupeRepeatedUserMessages } = createRequire(import.meta.url)("./bin/repeated-user-message-projection.cjs"));
|
|
@@ -76201,7 +76304,7 @@ var init_micro = __esmMin((() => {
|
|
|
76201
76304
|
compactToolArguments: MICRO_COMPACTION_TOOL_ARGUMENTS_ENABLED,
|
|
76202
76305
|
minToolArgumentTokens: MICRO_COMPACTION_TOOL_ARGUMENT_MIN_TOKENS,
|
|
76203
76306
|
cacheMissedThresholdMs: 3600 * 1e3,
|
|
76204
|
-
truncatedMarker: "[
|
|
76307
|
+
truncatedMarker: "[Repeated tool result omitted]",
|
|
76205
76308
|
truncatedArgumentsMarker: "[Old tool call arguments cleared]",
|
|
76206
76309
|
minContextUsageRatio: .5
|
|
76207
76310
|
};
|
|
@@ -76249,10 +76352,18 @@ var init_micro = __esmMin((() => {
|
|
|
76249
76352
|
const effect = this.measureEffect(history, selection.cutoff);
|
|
76250
76353
|
const previousEffect = this.measureEffect(history, previousCutoff);
|
|
76251
76354
|
if (effect.truncatedToolResultCount <= previousEffect.truncatedToolResultCount && effect.truncatedToolArgumentCount <= previousEffect.truncatedToolArgumentCount) return;
|
|
76252
|
-
this.apply(selection.cutoff);
|
|
76253
76355
|
const rawContextTokens = estimateTokensForMessages(history);
|
|
76254
76356
|
const tokensBefore = rawContextTokens - previousEffect.truncatedToolResultTokensBefore + previousEffect.truncatedToolResultTokensAfter - previousEffect.truncatedToolArgumentTokensBefore + previousEffect.truncatedToolArgumentTokensAfter;
|
|
76255
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
|
+
});
|
|
76256
76367
|
this.agent.telemetry.track("micro_compaction_finished", {
|
|
76257
76368
|
trigger: selection.trigger,
|
|
76258
76369
|
keep_recent_messages: config.keepRecentMessages,
|
|
@@ -76284,15 +76395,16 @@ var init_micro = __esmMin((() => {
|
|
|
76284
76395
|
const historicalArgumentCutoff = Math.max(this.cutoff, messages.length - config.keepRecentMessages);
|
|
76285
76396
|
const completedToolCallIds = new Set(messages.filter((message) => message?.role === "tool" && message.toolCallId !== void 0).map((message) => message.toolCallId));
|
|
76286
76397
|
const protectedToolResultIds = freshToolResultIds(messages);
|
|
76398
|
+
const reducibleToolResultIds = redundantHistoricalToolResultReferences(messages, this.cutoff);
|
|
76287
76399
|
const serializedArgumentsMarker = JSON.stringify({ _blun_compacted: config.truncatedArgumentsMarker });
|
|
76288
76400
|
const result = [];
|
|
76289
76401
|
let i = 0;
|
|
76290
76402
|
for (const msg of messages) {
|
|
76291
|
-
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({
|
|
76292
76404
|
...msg,
|
|
76293
76405
|
content: [{
|
|
76294
76406
|
type: "text",
|
|
76295
|
-
text: config.truncatedMarker
|
|
76407
|
+
text: repeatedToolResultReference(config.truncatedMarker, reducibleToolResultIds.get(msg.toolCallId))
|
|
76296
76408
|
}]
|
|
76297
76409
|
});
|
|
76298
76410
|
else if (config.compactToolArguments && i < historicalArgumentCutoff && msg.role === "assistant" && Array.isArray(msg.toolCalls)) {
|
|
@@ -76321,7 +76433,6 @@ var init_micro = __esmMin((() => {
|
|
|
76321
76433
|
return result;
|
|
76322
76434
|
}
|
|
76323
76435
|
measureEffect(messages, cutoff) {
|
|
76324
|
-
let markerTokenCount;
|
|
76325
76436
|
let argumentsMarkerTokenCount;
|
|
76326
76437
|
let truncatedToolResultCount = 0;
|
|
76327
76438
|
let truncatedToolResultTokensBefore = 0;
|
|
@@ -76331,19 +76442,20 @@ var init_micro = __esmMin((() => {
|
|
|
76331
76442
|
let truncatedToolArgumentTokensAfter = 0;
|
|
76332
76443
|
const completedToolCallIds = new Set(messages.filter((message) => message?.role === "tool" && message.toolCallId !== void 0).map((message) => message.toolCallId));
|
|
76333
76444
|
const protectedToolResultIds = freshToolResultIds(messages);
|
|
76445
|
+
const reducibleToolResultIds = redundantHistoricalToolResultReferences(messages, cutoff);
|
|
76334
76446
|
const serializedArgumentsMarker = JSON.stringify({ _blun_compacted: this.config.truncatedArgumentsMarker });
|
|
76335
76447
|
for (let i = 0; i < messages.length && i < cutoff; i++) {
|
|
76336
76448
|
const message = messages[i];
|
|
76337
|
-
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)) {
|
|
76338
76450
|
const contentTokens = estimateTokensForContentParts(message.content);
|
|
76339
76451
|
if (contentTokens >= this.config.minContentTokens) {
|
|
76340
|
-
markerTokenCount ??= estimateTokensForContentParts([{
|
|
76341
|
-
type: "text",
|
|
76342
|
-
text: this.config.truncatedMarker
|
|
76343
|
-
}]);
|
|
76344
76452
|
truncatedToolResultCount += 1;
|
|
76345
76453
|
truncatedToolResultTokensBefore += contentTokens;
|
|
76346
|
-
|
|
76454
|
+
const replacement = repeatedToolResultReference(this.config.truncatedMarker, reducibleToolResultIds.get(message.toolCallId));
|
|
76455
|
+
truncatedToolResultTokensAfter += estimateTokensForContentParts([{
|
|
76456
|
+
type: "text",
|
|
76457
|
+
text: replacement
|
|
76458
|
+
}]);
|
|
76347
76459
|
}
|
|
76348
76460
|
}
|
|
76349
76461
|
if (!this.config.compactToolArguments || message?.role !== "assistant" || !Array.isArray(message.toolCalls)) continue;
|
|
@@ -76556,6 +76668,9 @@ function isValidCronTask(obj) {
|
|
|
76556
76668
|
if (o["paused"] !== void 0 && typeof o["paused"] !== "boolean") return false;
|
|
76557
76669
|
if (o["autoExpire"] !== void 0 && typeof o["autoExpire"] !== "boolean") return false;
|
|
76558
76670
|
if (o["scheduleFromAt"] !== void 0 && (typeof o["scheduleFromAt"] !== "number" || !Number.isFinite(o["scheduleFromAt"]))) return false;
|
|
76671
|
+
if (o["allowedTools"] !== void 0 && (!Array.isArray(o["allowedTools"]) || !o["allowedTools"].every((name) => typeof name === "string"))) return false;
|
|
76672
|
+
if (o["allowedTools"] !== void 0 && typeof o["toolScopeDigest"] !== "string") return false;
|
|
76673
|
+
if (o["allowedTools"] === void 0 && o["toolScopeDigest"] !== void 0) return false;
|
|
76559
76674
|
if (o["owner"] === "session-loop" && (typeof o["loopInterval"] !== "string" || o["loopInterval"].length === 0 || o["recurring"] === false || o["autoExpire"] !== false)) return false;
|
|
76560
76675
|
return true;
|
|
76561
76676
|
}
|
|
@@ -77333,7 +77448,7 @@ function hasUnfinishedTodoWork(agent) {
|
|
|
77333
77448
|
const todos = agent.tools.storeData()["todo"];
|
|
77334
77449
|
return Array.isArray(todos) && todos.some((todo) => todo?.status === "in_progress" || todo?.status === "pending");
|
|
77335
77450
|
}
|
|
77336
|
-
var STALE_THRESHOLD_MS, CronManager;
|
|
77451
|
+
var STALE_THRESHOLD_MS, normalizeCronAllowedTools, cronToolScopeForTask, filterToolsForCronScope, inheritedCronToolScope, createCronRunReceipt, buildCronFileCandidate, publicCronRunList, createCronRunStore, createMemoryCronRunStore, readCronFinalMessage, CronManager;
|
|
77337
77452
|
var init_manager$3 = __esmMin((() => {
|
|
77338
77453
|
init_clock();
|
|
77339
77454
|
init_cron_fire_xml();
|
|
@@ -77341,6 +77456,17 @@ var init_manager$3 = __esmMin((() => {
|
|
|
77341
77456
|
init_session_store$2();
|
|
77342
77457
|
init_scheduler();
|
|
77343
77458
|
init_telemetry_events();
|
|
77459
|
+
({
|
|
77460
|
+
normalizeCronAllowedTools,
|
|
77461
|
+
cronToolScopeForTask,
|
|
77462
|
+
filterToolsForCronScope,
|
|
77463
|
+
inheritedCronToolScope,
|
|
77464
|
+
createCronRunReceipt,
|
|
77465
|
+
buildCronFileCandidate,
|
|
77466
|
+
publicCronRunList
|
|
77467
|
+
} = createRequire(import.meta.url)("./bin/scoped-cron-run-policy.cjs"));
|
|
77468
|
+
({ createCronRunStore, createMemoryCronRunStore } = createRequire(import.meta.url)("./bin/cron-run-store.cjs"));
|
|
77469
|
+
({ readCronFinalMessage } = createRequire(import.meta.url)("./bin/cron-run-output.cjs"));
|
|
77344
77470
|
STALE_THRESHOLD_MS = 10080 * 60 * 1e3;
|
|
77345
77471
|
CronManager = class {
|
|
77346
77472
|
/** In-memory task store. Empty at construction; populated by
|
|
@@ -77376,6 +77502,11 @@ var init_manager$3 = __esmMin((() => {
|
|
|
77376
77502
|
* later `blun resume` can reload via {@link loadFromDisk}.
|
|
77377
77503
|
*/
|
|
77378
77504
|
persistStore;
|
|
77505
|
+
runStore;
|
|
77506
|
+
bufferedRuns = [];
|
|
77507
|
+
runByTurnId = /* @__PURE__ */ new Map();
|
|
77508
|
+
runAccumulators = /* @__PURE__ */ new Map();
|
|
77509
|
+
drainTimer = null;
|
|
77379
77510
|
/**
|
|
77380
77511
|
* Per-id serializer for persistence writes. Prevents a fast
|
|
77381
77512
|
* `add` → `remove` sequence on the same id from racing each other on
|
|
@@ -77389,6 +77520,7 @@ var init_manager$3 = __esmMin((() => {
|
|
|
77389
77520
|
this.store = new SessionCronStore();
|
|
77390
77521
|
this.clocks = opts.clocks ?? resolveClockSources(process.env["BLUN_CRON_CLOCK"]) ?? SYSTEM_CLOCKS;
|
|
77391
77522
|
this.persistStore = agent.homedir === void 0 ? void 0 : createCronPersistStore(agent.homedir);
|
|
77523
|
+
this.runStore = agent.homedir === void 0 ? createMemoryCronRunStore() : createCronRunStore(agent.homedir, { now: () => this.clocks.wallNow() });
|
|
77392
77524
|
this.scheduler = createCronScheduler({
|
|
77393
77525
|
clocks: this.clocks,
|
|
77394
77526
|
source: () => this.store.list(),
|
|
@@ -77440,7 +77572,10 @@ var init_manager$3 = __esmMin((() => {
|
|
|
77440
77572
|
*/
|
|
77441
77573
|
removeTasks(ids) {
|
|
77442
77574
|
const removed = this.store.remove(ids);
|
|
77443
|
-
for (const id of removed)
|
|
77575
|
+
for (const id of removed) {
|
|
77576
|
+
this.persistEnqueue(id, () => this.persistStore.remove(id));
|
|
77577
|
+
this.runStore.markJobDeletedById(id);
|
|
77578
|
+
}
|
|
77444
77579
|
return removed;
|
|
77445
77580
|
}
|
|
77446
77581
|
updateTask(id, patch) {
|
|
@@ -77480,6 +77615,11 @@ var init_manager$3 = __esmMin((() => {
|
|
|
77480
77615
|
* input, so a regenerated value would corrupt both.
|
|
77481
77616
|
*/
|
|
77482
77617
|
async loadFromDisk() {
|
|
77618
|
+
const loadedRuns = this.runStore.load();
|
|
77619
|
+
for (const runId of loadedRuns.lostRunIds ?? []) {
|
|
77620
|
+
const receipt = this.runStore.get(runId);
|
|
77621
|
+
if (receipt !== void 0) this.emitRunTerminal(receipt);
|
|
77622
|
+
}
|
|
77483
77623
|
if (this.persistStore === void 0) return;
|
|
77484
77624
|
const tasks = await this.persistStore.list();
|
|
77485
77625
|
this.store.clear();
|
|
@@ -77547,6 +77687,8 @@ var init_manager$3 = __esmMin((() => {
|
|
|
77547
77687
|
* would be missing from the resume's `loadFromDisk()`.
|
|
77548
77688
|
*/
|
|
77549
77689
|
async stop() {
|
|
77690
|
+
if (this.drainTimer !== null) clearTimeout(this.drainTimer);
|
|
77691
|
+
this.drainTimer = null;
|
|
77550
77692
|
this.unbindSigusr1();
|
|
77551
77693
|
await this.scheduler.stop();
|
|
77552
77694
|
await this.flushPersist();
|
|
@@ -77612,24 +77754,49 @@ var init_manager$3 = __esmMin((() => {
|
|
|
77612
77754
|
*/
|
|
77613
77755
|
handleFire(task, ctx) {
|
|
77614
77756
|
const stale = this.isStale(task);
|
|
77757
|
+
const toolScope = cronToolScopeForTask(task);
|
|
77758
|
+
const runId = randomBytes(8).toString("hex");
|
|
77615
77759
|
const origin = {
|
|
77616
77760
|
kind: "cron_job",
|
|
77617
77761
|
jobId: task.id,
|
|
77762
|
+
runId,
|
|
77618
77763
|
cron: task.cron,
|
|
77619
77764
|
recurring: task.recurring !== false,
|
|
77620
77765
|
coalescedCount: ctx.coalescedCount,
|
|
77621
|
-
stale
|
|
77766
|
+
stale,
|
|
77767
|
+
...(toolScope.mode === "scoped" ? { toolScope } : {})
|
|
77622
77768
|
};
|
|
77623
77769
|
const content = [{
|
|
77624
77770
|
type: "text",
|
|
77625
77771
|
text: task.owner === "session-loop" ? renderSessionLoopWakeupXml(origin, task.prompt, task.loopInterval ?? "auto") : renderCronFireXml(origin, task.prompt)
|
|
77626
77772
|
}];
|
|
77773
|
+
const receipt = createCronRunReceipt({
|
|
77774
|
+
runId,
|
|
77775
|
+
jobId: task.id,
|
|
77776
|
+
cron: task.cron,
|
|
77777
|
+
recurring: task.recurring !== false,
|
|
77778
|
+
stale,
|
|
77779
|
+
coalescedCount: ctx.coalescedCount,
|
|
77780
|
+
toolScopeDigest: toolScope.digest,
|
|
77781
|
+
firedAt: new Date(this.clocks.wallNow()).toISOString()
|
|
77782
|
+
});
|
|
77783
|
+
this.runStore.create(receipt);
|
|
77784
|
+
this.bufferedRuns.push({ runId, content, origin });
|
|
77785
|
+
this.runAccumulators.set(runId, {
|
|
77786
|
+
toolCalls: /* @__PURE__ */ new Map(),
|
|
77787
|
+
fileCandidates: /* @__PURE__ */ new Map(),
|
|
77788
|
+
outputs: [],
|
|
77789
|
+
finalStepId: null
|
|
77790
|
+
});
|
|
77791
|
+
this.agent.emitEvent({ type: "cron.fired", origin });
|
|
77627
77792
|
this.agent.emitEvent({
|
|
77628
|
-
type: "cron.
|
|
77629
|
-
|
|
77630
|
-
|
|
77793
|
+
type: "cron.run.created",
|
|
77794
|
+
runId,
|
|
77795
|
+
jobId: task.id,
|
|
77796
|
+
coalescedCount: ctx.coalescedCount,
|
|
77797
|
+
toolScopeDigest: toolScope.digest
|
|
77631
77798
|
});
|
|
77632
|
-
const turnId = this.
|
|
77799
|
+
const turnId = this.launchBufferedRuns();
|
|
77633
77800
|
this.agent.telemetry.track(CRON_FIRED, {
|
|
77634
77801
|
recurring: task.recurring !== false,
|
|
77635
77802
|
coalesced_count: ctx.coalescedCount,
|
|
@@ -77641,6 +77808,137 @@ var init_manager$3 = __esmMin((() => {
|
|
|
77641
77808
|
this.emitDeleted(task.id);
|
|
77642
77809
|
}
|
|
77643
77810
|
}
|
|
77811
|
+
launchBufferedRuns() {
|
|
77812
|
+
if (this.bufferedRuns.length === 0) return null;
|
|
77813
|
+
if (this.agent.turn.hasActiveTurn || this.agent.fullCompaction.isCompacting) {
|
|
77814
|
+
this.scheduleBufferedRunDrain();
|
|
77815
|
+
return null;
|
|
77816
|
+
}
|
|
77817
|
+
const next = this.bufferedRuns.shift();
|
|
77818
|
+
const acceptance = this.agent.turn.promptWithAcceptance(next.content, next.origin);
|
|
77819
|
+
if (acceptance.accepted !== true || acceptance.turnId === null) {
|
|
77820
|
+
this.bufferedRuns.unshift(next);
|
|
77821
|
+
this.scheduleBufferedRunDrain();
|
|
77822
|
+
return null;
|
|
77823
|
+
}
|
|
77824
|
+
return acceptance.turnId;
|
|
77825
|
+
}
|
|
77826
|
+
scheduleBufferedRunDrain() {
|
|
77827
|
+
if (this.drainTimer !== null || this.bufferedRuns.length === 0) return;
|
|
77828
|
+
this.drainTimer = setTimeout(() => {
|
|
77829
|
+
this.drainTimer = null;
|
|
77830
|
+
this.launchBufferedRuns();
|
|
77831
|
+
}, 250);
|
|
77832
|
+
this.drainTimer.unref?.();
|
|
77833
|
+
}
|
|
77834
|
+
observeLoopEvent(turnId, event) {
|
|
77835
|
+
const runId = this.runByTurnId.get(turnId);
|
|
77836
|
+
if (runId === void 0) return;
|
|
77837
|
+
const accumulator = this.runAccumulators.get(runId);
|
|
77838
|
+
if (accumulator === void 0) return;
|
|
77839
|
+
if (event.type === "step.begin" && typeof event.uuid === "string") accumulator.finalStepId = event.uuid;
|
|
77840
|
+
if (event.type === "tool.call") {
|
|
77841
|
+
accumulator.toolCalls.set(event.toolCallId, { name: event.name, isError: false });
|
|
77842
|
+
const candidate = buildCronFileCandidate({
|
|
77843
|
+
toolName: event.name,
|
|
77844
|
+
toolCallId: event.toolCallId,
|
|
77845
|
+
display: event.display,
|
|
77846
|
+
workspaceRoot: this.agent.config.cwd,
|
|
77847
|
+
additionalRoots: this.agent.getAdditionalDirs(),
|
|
77848
|
+
pathExists: typeof event.display?.path === "string" && existsSync(event.display.path)
|
|
77849
|
+
});
|
|
77850
|
+
if (candidate !== null) accumulator.fileCandidates.set(event.toolCallId, candidate);
|
|
77851
|
+
}
|
|
77852
|
+
if (event.type === "tool.result") {
|
|
77853
|
+
const call = accumulator.toolCalls.get(event.toolCallId);
|
|
77854
|
+
if (call !== void 0) call.isError = event.result.isError === true;
|
|
77855
|
+
const candidate = accumulator.fileCandidates.get(event.toolCallId);
|
|
77856
|
+
if (candidate !== void 0 && event.result.isError !== true) accumulator.outputs.push(candidate);
|
|
77857
|
+
accumulator.fileCandidates.delete(event.toolCallId);
|
|
77858
|
+
}
|
|
77859
|
+
}
|
|
77860
|
+
observeAgentEvent(event) {
|
|
77861
|
+
if (event.type === "turn.started") {
|
|
77862
|
+
const runId = event.origin?.kind === "cron_job" && typeof event.origin.runId === "string" ? event.origin.runId : event.origin?.kind === "system_trigger" && typeof event.origin.cronRunId === "string" ? event.origin.cronRunId : void 0;
|
|
77863
|
+
if (runId === void 0) return;
|
|
77864
|
+
const receipt = this.runStore.get(runId);
|
|
77865
|
+
if (receipt?.status !== "buffered" && receipt?.status !== "running") return;
|
|
77866
|
+
this.runByTurnId.set(event.turnId, runId);
|
|
77867
|
+
if (receipt.status === "buffered") {
|
|
77868
|
+
const running = this.runStore.transition(runId, "running", {
|
|
77869
|
+
turnId: event.turnId,
|
|
77870
|
+
startedAt: new Date(this.clocks.wallNow()).toISOString()
|
|
77871
|
+
});
|
|
77872
|
+
this.agent.emitEvent({
|
|
77873
|
+
type: "cron.run.started",
|
|
77874
|
+
runId: running.runId,
|
|
77875
|
+
jobId: running.jobId,
|
|
77876
|
+
turnId: event.turnId
|
|
77877
|
+
});
|
|
77878
|
+
}
|
|
77879
|
+
return;
|
|
77880
|
+
}
|
|
77881
|
+
if (event.type !== "turn.ended") return;
|
|
77882
|
+
const runId = this.runByTurnId.get(event.turnId);
|
|
77883
|
+
if (runId === void 0) return;
|
|
77884
|
+
const accumulator = this.runAccumulators.get(runId);
|
|
77885
|
+
if (accumulator !== void 0) accumulator.lastTurnEnd = event;
|
|
77886
|
+
this.runByTurnId.delete(event.turnId);
|
|
77887
|
+
}
|
|
77888
|
+
observeRunWorkerEnded(runId, event) {
|
|
77889
|
+
const current = this.runStore.get(runId);
|
|
77890
|
+
if (current?.status !== "running" && current?.status !== "buffered") return;
|
|
77891
|
+
const accumulator = this.runAccumulators.get(runId) ?? {
|
|
77892
|
+
toolCalls: /* @__PURE__ */ new Map(),
|
|
77893
|
+
outputs: [],
|
|
77894
|
+
finalStepId: null
|
|
77895
|
+
};
|
|
77896
|
+
const status = event.reason === "cancelled" ? "cancelled" : event.reason === "failed" || event.reason === "filtered" ? "failed" : "completed";
|
|
77897
|
+
const terminal = this.runStore.transition(runId, status, {
|
|
77898
|
+
endedAt: new Date(this.clocks.wallNow()).toISOString(),
|
|
77899
|
+
toolCalls: [...accumulator.toolCalls.values()],
|
|
77900
|
+
outputs: accumulator.outputs,
|
|
77901
|
+
finalStepId: accumulator.finalStepId,
|
|
77902
|
+
error: status === "failed" ? {
|
|
77903
|
+
category: event.reason === "filtered" ? "policy" : "executor",
|
|
77904
|
+
code: event.error?.code ?? (event.reason === "filtered" ? "PROVIDER_FILTERED" : "TURN_FAILED")
|
|
77905
|
+
} : void 0
|
|
77906
|
+
});
|
|
77907
|
+
this.emitRunTerminal(terminal);
|
|
77908
|
+
this.runAccumulators.delete(runId);
|
|
77909
|
+
this.scheduleBufferedRunDrain();
|
|
77910
|
+
}
|
|
77911
|
+
observeRunWorkerFailed(runId) {
|
|
77912
|
+
this.observeRunWorkerEnded(runId, {
|
|
77913
|
+
reason: "failed",
|
|
77914
|
+
error: { code: "TURN_WORKER_FAILED" }
|
|
77915
|
+
});
|
|
77916
|
+
}
|
|
77917
|
+
emitRunTerminal(receipt) {
|
|
77918
|
+
const durationMs = receipt.startedAt === null || receipt.endedAt === null ? void 0 : Math.max(0, Date.parse(receipt.endedAt) - Date.parse(receipt.startedAt));
|
|
77919
|
+
this.agent.emitEvent({
|
|
77920
|
+
type: `cron.run.${receipt.status}`,
|
|
77921
|
+
runId: receipt.runId,
|
|
77922
|
+
jobId: receipt.jobId,
|
|
77923
|
+
durationMs,
|
|
77924
|
+
toolCalls: receipt.toolSummary.calls,
|
|
77925
|
+
toolErrors: receipt.toolSummary.errors,
|
|
77926
|
+
outputCount: receipt.outputs.length,
|
|
77927
|
+
errorCategory: receipt.error?.category
|
|
77928
|
+
});
|
|
77929
|
+
}
|
|
77930
|
+
listRuns(filters) {
|
|
77931
|
+
return publicCronRunList(this.runStore.list(), filters);
|
|
77932
|
+
}
|
|
77933
|
+
readRunOutput(runId) {
|
|
77934
|
+
const receipt = this.runStore.get(runId);
|
|
77935
|
+
if (receipt === void 0) return null;
|
|
77936
|
+
let finalMessage = null;
|
|
77937
|
+
if (receipt.finalMessageRef !== null && this.agent.homedir !== void 0) try {
|
|
77938
|
+
finalMessage = readCronFinalMessage(join$4(this.agent.homedir, "wire.jsonl"), receipt.finalMessageRef.stepId);
|
|
77939
|
+
} catch {}
|
|
77940
|
+
return { receipt, finalMessage };
|
|
77941
|
+
}
|
|
77644
77942
|
/**
|
|
77645
77943
|
* Reserved hook for an explicit "you missed N fires while offline"
|
|
77646
77944
|
* banner. Today the scheduler's `coalescedCount` semantics already
|
|
@@ -78105,7 +78403,8 @@ var init_cron_create = __esmMin((() => {
|
|
|
78105
78403
|
CronCreateInputSchema = object({
|
|
78106
78404
|
cron: string().describe("5-field cron expression in local time: \"M H DoM Mon DoW\" (e.g. \"*/5 * * * *\" = every 5 minutes; \"30 14 28 2 *\" = Feb 28 at 2:30pm local — a pinned date like this repeats yearly unless you also pass recurring: false)."),
|
|
78107
78405
|
prompt: string().min(1).max(MAX_PROMPT_BYTES).describe("The prompt to enqueue at each fire time. Limited to 8 KiB (UTF-8)."),
|
|
78108
|
-
recurring: boolean$1().optional().default(true).describe("true (default) = fire on every cron match until deleted or auto-expired after 7 days. false = fire once at the next match, then auto-delete. Use false for \"remind me at X\" one-shot requests with pinned minute/hour/dom/month.")
|
|
78406
|
+
recurring: boolean$1().optional().default(true).describe("true (default) = fire on every cron match until deleted or auto-expired after 7 days. false = fire once at the next match, then auto-delete. Use false for \"remind me at X\" one-shot requests with pinned minute/hour/dom/month."),
|
|
78407
|
+
allowed_tools: array(string()).max(64).optional().describe("Optional exact tool names allowed in each isolated run. Omit for legacy behavior; an empty array allows no tools. Wildcards and unknown tools are rejected.")
|
|
78109
78408
|
});
|
|
78110
78409
|
CronCreateTool = class {
|
|
78111
78410
|
manager;
|
|
@@ -78145,6 +78444,15 @@ var init_cron_create = __esmMin((() => {
|
|
|
78145
78444
|
output: `Prompt exceeds ${String(MAX_PROMPT_BYTES)} bytes (got ${String(byteLen)}).`
|
|
78146
78445
|
};
|
|
78147
78446
|
const recurring = args.recurring !== false;
|
|
78447
|
+
let toolScope;
|
|
78448
|
+
try {
|
|
78449
|
+
toolScope = normalizeCronAllowedTools(args.allowed_tools, this.manager.agent.tools.loopTools);
|
|
78450
|
+
} catch (error) {
|
|
78451
|
+
return {
|
|
78452
|
+
isError: true,
|
|
78453
|
+
output: error instanceof Error ? error.message : String(error)
|
|
78454
|
+
};
|
|
78455
|
+
}
|
|
78148
78456
|
if (!recurring) {
|
|
78149
78457
|
const firstFire = computeNextCronRun(parsed, nowAtPrepare);
|
|
78150
78458
|
if (firstFire !== null && firstFire - nowAtPrepare > ONE_SHOT_MAX_FUTURE_MS) return {
|
|
@@ -78157,7 +78465,8 @@ var init_cron_create = __esmMin((() => {
|
|
|
78157
78465
|
approvalRule: literalRulePattern(this.name, JSON.stringify({
|
|
78158
78466
|
cron: normalizedCron,
|
|
78159
78467
|
prompt: args.prompt,
|
|
78160
|
-
recurring
|
|
78468
|
+
recurring,
|
|
78469
|
+
...(args.allowed_tools === void 0 ? {} : { allowed_tools: toolScope.names })
|
|
78161
78470
|
})),
|
|
78162
78471
|
execute: async () => {
|
|
78163
78472
|
const nowMs = this.manager.clocks.wallNow();
|
|
@@ -78168,7 +78477,11 @@ var init_cron_create = __esmMin((() => {
|
|
|
78168
78477
|
const task = this.manager.addTask({
|
|
78169
78478
|
cron: normalizedCron,
|
|
78170
78479
|
prompt: args.prompt,
|
|
78171
|
-
recurring
|
|
78480
|
+
recurring,
|
|
78481
|
+
...(toolScope.mode === "scoped" ? {
|
|
78482
|
+
allowedTools: toolScope.names,
|
|
78483
|
+
toolScopeDigest: toolScope.digest
|
|
78484
|
+
} : {})
|
|
78172
78485
|
});
|
|
78173
78486
|
const ideal = computeNextCronRun(parsed, nowMs);
|
|
78174
78487
|
const nextFireAt = ideal === null ? null : recurring ? jitteredNextCronRunMs(task, parsed, ideal) : oneShotJitteredNextCronRunMs(task, ideal);
|
|
@@ -79135,6 +79448,32 @@ var init_context$2 = __esmMin((() => {
|
|
|
79135
79448
|
keptHeadUserMessageCount,
|
|
79136
79449
|
droppedCount: input.droppedCount
|
|
79137
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
|
+
}));
|
|
79469
|
+
this.agent.records.logRecord({
|
|
79470
|
+
type: "policy.intervention",
|
|
79471
|
+
policy: "full_context_compaction",
|
|
79472
|
+
location: "AgentContext.applyCompaction",
|
|
79473
|
+
size_before: result.tokensBefore,
|
|
79474
|
+
size_after: result.tokensAfter,
|
|
79475
|
+
unit: "tokens"
|
|
79476
|
+
});
|
|
79138
79477
|
this.agent.records.logRecord({
|
|
79139
79478
|
type: "context.apply_compaction",
|
|
79140
79479
|
...result
|
|
@@ -79149,17 +79488,7 @@ var init_context$2 = __esmMin((() => {
|
|
|
79149
79488
|
keptHeadUserMessageCount: result.keptHeadUserMessageCount,
|
|
79150
79489
|
droppedCount: result.droppedCount
|
|
79151
79490
|
} });
|
|
79152
|
-
|
|
79153
|
-
role: "user",
|
|
79154
|
-
content: [{
|
|
79155
|
-
type: "text",
|
|
79156
|
-
text: contextSummary
|
|
79157
|
-
}],
|
|
79158
|
-
toolCalls: [],
|
|
79159
|
-
origin: { kind: "compaction_summary" }
|
|
79160
|
-
};
|
|
79161
|
-
const isLegacyRestore = this.agent.records.restoring !== null && input.keptUserMessageCount === void 0 && input.compactedCount < this._history.length;
|
|
79162
|
-
this._history = isLegacyRestore ? [summaryMessage, ...this._history.slice(input.compactedCount)] : [...keptMessages, summaryMessage];
|
|
79491
|
+
this._history = nextHistory;
|
|
79163
79492
|
this.markPendingTokenEstimateDirty();
|
|
79164
79493
|
this.openSteps.clear();
|
|
79165
79494
|
this.pendingToolResultIds.clear();
|
|
@@ -79195,6 +79524,7 @@ var init_context$2 = __esmMin((() => {
|
|
|
79195
79524
|
}
|
|
79196
79525
|
project(messages, options) {
|
|
79197
79526
|
const anomalies = [];
|
|
79527
|
+
const underPressure = toolResultOffloadPressureForAgent(this.agent);
|
|
79198
79528
|
const userOffloaded = this.agent.userMessageOffload.compact(messages);
|
|
79199
79529
|
const historicalMediaProjected = projectHistoricalMediaParts(userOffloaded);
|
|
79200
79530
|
const historicalUserReferencesProjected = compactHistoricalPersistedUserMessageReferences(historicalMediaProjected);
|
|
@@ -79202,7 +79532,9 @@ var init_context$2 = __esmMin((() => {
|
|
|
79202
79532
|
const historicalTelegramProjected = projectHistoricalUnaddressedTelegramMessages(duplicateUserMessagesProjected);
|
|
79203
79533
|
const assistantOffloaded = this.agent.assistantMessageOffload.compact(historicalTelegramProjected);
|
|
79204
79534
|
const repeatedAssistantProjected = projectRepeatedAssistantResponses(assistantOffloaded);
|
|
79205
|
-
const
|
|
79535
|
+
const batchProjected = this.agent.toolResultBatchOffload.compact(dedupeRecurringCronWakeups(dedupeRepeatedInjections(compactHistoricalSkillActivations(compactBaselineSkillInjections(repeatedAssistantProjected)))));
|
|
79536
|
+
const toolResultsProjected = compactHistoricalSuccessfulToolResults(dedupeRepeatedSuccessfulToolResults(repeatedAssistantProjected, batchProjected), { underPressure });
|
|
79537
|
+
const result = project(this.agent.microCompaction.compact(toolResultsProjected), {
|
|
79206
79538
|
...options,
|
|
79207
79539
|
onAnomaly: (anomaly) => {
|
|
79208
79540
|
anomalies.push(anomaly);
|
|
@@ -233897,9 +234229,9 @@ var init_plan_mode_guard_deny = __esmMin((() => {
|
|
|
233897
234229
|
message: planModeWriteDeniedMessage(planFilePath)
|
|
233898
234230
|
};
|
|
233899
234231
|
}
|
|
233900
|
-
if (toolName === "TaskStop") return {
|
|
234232
|
+
if (toolName === "TaskStop" || toolName === "TaskResume") return {
|
|
233901
234233
|
kind: "deny",
|
|
233902
|
-
message:
|
|
234234
|
+
message: `${toolName} is not available in plan mode. Call ExitPlanMode before changing background task execution.`
|
|
233903
234235
|
};
|
|
233904
234236
|
if (toolName === "CronCreate" || toolName === "CronDelete") return {
|
|
233905
234237
|
kind: "deny",
|
|
@@ -234265,6 +234597,16 @@ var init_permission = __esmMin((() => {
|
|
|
234265
234597
|
if (pattern === void 0) return;
|
|
234266
234598
|
this.localSessionApprovalRulePatterns.add(pattern);
|
|
234267
234599
|
}
|
|
234600
|
+
recordApprovalEdited(context, editedArgs) {
|
|
234601
|
+
const event = buildApprovalEditedEvent({
|
|
234602
|
+
turnId: Number(context.turnId),
|
|
234603
|
+
toolCallId: context.toolCall.id,
|
|
234604
|
+
toolName: context.toolCall.name,
|
|
234605
|
+
originalArgs: context.args,
|
|
234606
|
+
editedArgs
|
|
234607
|
+
});
|
|
234608
|
+
this.agent.records.logRecord(event);
|
|
234609
|
+
}
|
|
234268
234610
|
get sessionApprovalRulePatterns() {
|
|
234269
234611
|
return [...this.localSessionApprovalRulePatterns, ...this.parent?.sessionApprovalRulePatterns ?? []];
|
|
234270
234612
|
}
|
|
@@ -234284,6 +234626,8 @@ var init_permission = __esmMin((() => {
|
|
|
234284
234626
|
const { signal } = context;
|
|
234285
234627
|
const id = context.toolCall.id;
|
|
234286
234628
|
const name = context.toolCall.name;
|
|
234629
|
+
const approvalEditCount = Number.isSafeInteger(context.approvalEditCount) ? context.approvalEditCount : 0;
|
|
234630
|
+
const allowEdit = approvalEditCount === 0 && isEditableToolApprovalEligible(name);
|
|
234287
234631
|
const display = context.execution.display ?? {
|
|
234288
234632
|
kind: "generic",
|
|
234289
234633
|
summary: context.execution.description ?? `Approve ${name}`,
|
|
@@ -234321,7 +234665,10 @@ var init_permission = __esmMin((() => {
|
|
|
234321
234665
|
toolCallId: id,
|
|
234322
234666
|
toolName: name,
|
|
234323
234667
|
action,
|
|
234324
|
-
display
|
|
234668
|
+
display,
|
|
234669
|
+
allowEdit,
|
|
234670
|
+
approvalEditCount,
|
|
234671
|
+
editableToolInput: allowEdit ? context.args : void 0
|
|
234325
234672
|
}, { signal });
|
|
234326
234673
|
} catch (error) {
|
|
234327
234674
|
this.agent.telemetry.track("permission_approval_result", {
|
|
@@ -234349,6 +234696,19 @@ var init_permission = __esmMin((() => {
|
|
|
234349
234696
|
return resolved === void 0 ? Promise.reject(error) : this.permissionPolicyResolutionToPrepare(resolved, context, policyName);
|
|
234350
234697
|
}
|
|
234351
234698
|
} else response = { decision: "approved" };
|
|
234699
|
+
let editedDecision;
|
|
234700
|
+
if (response.decision === "edited") try {
|
|
234701
|
+
editedDecision = validateEditedApprovalDecision({
|
|
234702
|
+
response,
|
|
234703
|
+
toolName: name,
|
|
234704
|
+
editCount: approvalEditCount
|
|
234705
|
+
});
|
|
234706
|
+
} catch (error) {
|
|
234707
|
+
response = {
|
|
234708
|
+
decision: "rejected",
|
|
234709
|
+
feedback: `Edited approval was rejected before tool preparation: ${error instanceof Error ? error.message : String(error)}`
|
|
234710
|
+
};
|
|
234711
|
+
}
|
|
234352
234712
|
const sessionApprovalRule = response.decision === "approved" && response.scope === "session" ? context.execution.approvalRule : void 0;
|
|
234353
234713
|
if (requestedApproval) this.agent.hooks?.fireAndForgetTrigger?.("PermissionResult", {
|
|
234354
234714
|
matcherValue: name,
|
|
@@ -234363,13 +234723,14 @@ var init_permission = __esmMin((() => {
|
|
|
234363
234723
|
selectedLabel: response.selectedLabel
|
|
234364
234724
|
}
|
|
234365
234725
|
});
|
|
234726
|
+
const approvalRecordResponse = response.decision === "edited" ? { decision: "edited" } : response;
|
|
234366
234727
|
this.recordApprovalResult({
|
|
234367
234728
|
turnId: Number(context.turnId),
|
|
234368
234729
|
toolCallId: id,
|
|
234369
234730
|
toolName: name,
|
|
234370
234731
|
action,
|
|
234371
234732
|
sessionApprovalRule,
|
|
234372
|
-
result:
|
|
234733
|
+
result: approvalRecordResponse
|
|
234373
234734
|
});
|
|
234374
234735
|
this.agent.telemetry.track("permission_approval_result", {
|
|
234375
234736
|
policy_name: policyName ?? null,
|
|
@@ -234381,6 +234742,17 @@ var init_permission = __esmMin((() => {
|
|
|
234381
234742
|
session_cache_written: sessionApprovalRule !== void 0,
|
|
234382
234743
|
has_feedback: response.feedback !== void 0 && response.feedback.length > 0
|
|
234383
234744
|
});
|
|
234745
|
+
if (response.decision === "edited" && editedDecision !== void 0) {
|
|
234746
|
+
let recorded = false;
|
|
234747
|
+
return { approvalEdit: {
|
|
234748
|
+
args: editedDecision.editedToolInput,
|
|
234749
|
+
record: (validatedArgs) => {
|
|
234750
|
+
if (recorded) throw new Error("Edited approval Wire event was already recorded");
|
|
234751
|
+
recorded = true;
|
|
234752
|
+
this.recordApprovalEdited(context, validatedArgs);
|
|
234753
|
+
}
|
|
234754
|
+
} };
|
|
234755
|
+
}
|
|
234384
234756
|
const resolved = result.resolveApproval?.(response);
|
|
234385
234757
|
if (resolved !== void 0) return this.permissionPolicyResolutionToPrepare(resolved, context, policyName);
|
|
234386
234758
|
if (response.decision === "approved") return;
|
|
@@ -244234,6 +244606,7 @@ function createNestedToolInvoker(step, parentToolCall) {
|
|
|
244234
244606
|
...step,
|
|
244235
244607
|
signal: nestedSignal,
|
|
244236
244608
|
toolCalls: [nestedToolCall],
|
|
244609
|
+
checkpointBeforeToolExecution: void 0,
|
|
244237
244610
|
dispatchEvent: (event) => step.dispatchEvent(markProgrammaticNestedEvent(event))
|
|
244238
244611
|
};
|
|
244239
244612
|
const preflight = preflightToolCall(nestedStep, nestedToolCall);
|
|
@@ -244306,7 +244679,7 @@ function validateExecutableToolArgs(tool, args) {
|
|
|
244306
244679
|
}
|
|
244307
244680
|
return validateToolArgs(validator, args);
|
|
244308
244681
|
}
|
|
244309
|
-
async function prepareToolCall(step, call) {
|
|
244682
|
+
async function prepareToolCall(step, call, approvalEditCount = 0) {
|
|
244310
244683
|
const settleError = async (args, output, displayFields) => {
|
|
244311
244684
|
await dispatchToolCall(step, call, args, displayFields);
|
|
244312
244685
|
return { task: makeResolvedToolCallTask(makeErrorToolResult(call, args, output)) };
|
|
@@ -244341,12 +244714,43 @@ async function prepareToolCall(step, call) {
|
|
|
244341
244714
|
const settleAborted = () => settleError(effectiveArgs, abortedToolOutput(call.toolName, step.signal), displayFields);
|
|
244342
244715
|
if (step.signal.aborted) return settleAborted();
|
|
244343
244716
|
if (execution.isError === true) return settleSynthetic(effectiveArgs, execution, displayFields);
|
|
244344
|
-
const authorization = await runAuthorizeToolExecutionHook(step, call, effectiveArgs, execution);
|
|
244717
|
+
const authorization = await runAuthorizeToolExecutionHook(step, call, effectiveArgs, execution, approvalEditCount);
|
|
244345
244718
|
if (step.signal.aborted) return settleAborted();
|
|
244346
244719
|
if (authorization?.block === true) return settleError(effectiveArgs, authorization.reason ?? `Tool call "${call.toolName}" was blocked`, displayFields);
|
|
244347
244720
|
if (authorization?.syntheticResult !== void 0) return settleSynthetic(effectiveArgs, authorization.syntheticResult, displayFields);
|
|
244721
|
+
if (authorization?.approvalEdit !== void 0) {
|
|
244722
|
+
let plan;
|
|
244723
|
+
try {
|
|
244724
|
+
plan = buildEditedToolCallPlan({
|
|
244725
|
+
step,
|
|
244726
|
+
call,
|
|
244727
|
+
editedArgs: authorization.approvalEdit.args,
|
|
244728
|
+
editCount: approvalEditCount,
|
|
244729
|
+
preflightToolCall
|
|
244730
|
+
});
|
|
244731
|
+
} catch (error) {
|
|
244732
|
+
return settleError(authorization.approvalEdit.args, `Edited approval could not be re-prepared: ${errorMessage$12(error)}`, displayFields);
|
|
244733
|
+
}
|
|
244734
|
+
if (plan.kind === "rejected") return settleError(plan.call.args, plan.output ?? `Edited args for tool "${call.toolName}" were rejected`, displayFields);
|
|
244735
|
+
try {
|
|
244736
|
+
authorization.approvalEdit.record(plan.call.args);
|
|
244737
|
+
} catch (error) {
|
|
244738
|
+
return settleError(plan.call.args, `Edited approval evidence could not be recorded: ${errorMessage$12(error)}`, displayFields);
|
|
244739
|
+
}
|
|
244740
|
+
return prepareToolCall(plan.step, plan.call, plan.editCount);
|
|
244741
|
+
}
|
|
244348
244742
|
const executionMetadata = authorization?.executionMetadata ?? decision.metadata;
|
|
244349
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
|
+
}
|
|
244350
244754
|
return {
|
|
244351
244755
|
task: {
|
|
244352
244756
|
accesses: execution.accesses ?? ToolAccesses.all(),
|
|
@@ -244418,7 +244822,7 @@ async function runPrepareToolExecutionHook(step, call) {
|
|
|
244418
244822
|
metadata: hookResult?.executionMetadata
|
|
244419
244823
|
};
|
|
244420
244824
|
}
|
|
244421
|
-
async function runAuthorizeToolExecutionHook(step, call, args, execution) {
|
|
244825
|
+
async function runAuthorizeToolExecutionHook(step, call, args, execution, approvalEditCount = 0) {
|
|
244422
244826
|
const { hooks, signal, turnId, currentStep, llm } = step;
|
|
244423
244827
|
if (hooks?.authorizeToolExecution === void 0) return void 0;
|
|
244424
244828
|
try {
|
|
@@ -244428,6 +244832,7 @@ async function runAuthorizeToolExecutionHook(step, call, args, execution) {
|
|
|
244428
244832
|
tool: call.tool,
|
|
244429
244833
|
args,
|
|
244430
244834
|
execution,
|
|
244835
|
+
approvalEditCount,
|
|
244431
244836
|
turnId,
|
|
244432
244837
|
stepNumber: currentStep,
|
|
244433
244838
|
signal,
|
|
@@ -244652,9 +245057,10 @@ async function dispatchToolCall(step, call, args, displayFields) {
|
|
|
244652
245057
|
display: displayFields?.display
|
|
244653
245058
|
});
|
|
244654
245059
|
}
|
|
244655
|
-
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;
|
|
244656
245061
|
var init_tool_call = __esmMin((() => {
|
|
244657
245062
|
({ markProgrammaticNestedEvent } = createRequire(import.meta.url)("./bin/programmatic-context-isolation.cjs"));
|
|
245063
|
+
({ checkpointBeforeExternalSideEffect } = createRequire(import.meta.url)("./bin/session-checkpoint-policy.cjs"));
|
|
244658
245064
|
init_args_validator();
|
|
244659
245065
|
init_path_access();
|
|
244660
245066
|
init_abort();
|
|
@@ -244678,7 +245084,7 @@ var init_tool_call = __esmMin((() => {
|
|
|
244678
245084
|
* does not lose model usage that was already spent.
|
|
244679
245085
|
*/
|
|
244680
245086
|
async function executeLoopStep(deps) {
|
|
244681
|
-
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;
|
|
244682
245088
|
const beforeStep = hooks?.beforeStep === void 0 ? void 0 : await hooks.beforeStep({
|
|
244683
245089
|
turnId,
|
|
244684
245090
|
stepNumber: currentStep,
|
|
@@ -244694,12 +245100,15 @@ async function executeLoopStep(deps) {
|
|
|
244694
245100
|
const messages = await stepBuildMessages();
|
|
244695
245101
|
signal.throwIfAborted();
|
|
244696
245102
|
const stepUuid = randomUUID();
|
|
245103
|
+
const requestMetadata = stepLLM.describeRequest?.(messages, stepTools ?? []);
|
|
244697
245104
|
const stepEvents = createStepEventGate({
|
|
244698
245105
|
dispatchEvent,
|
|
244699
245106
|
turnId,
|
|
244700
245107
|
currentStep,
|
|
244701
245108
|
stepUuid,
|
|
244702
|
-
onStepStarted
|
|
245109
|
+
onStepStarted,
|
|
245110
|
+
requestMetadata,
|
|
245111
|
+
maxAttempts: maxRetryAttempts
|
|
244703
245112
|
});
|
|
244704
245113
|
const prepareRequestBoundary = stepLLM.prepareRequestBoundary?.bind(stepLLM);
|
|
244705
245114
|
const step = {
|
|
@@ -244711,7 +245120,8 @@ async function executeLoopStep(deps) {
|
|
|
244711
245120
|
signal,
|
|
244712
245121
|
turnId,
|
|
244713
245122
|
currentStep,
|
|
244714
|
-
stepUuid
|
|
245123
|
+
stepUuid,
|
|
245124
|
+
checkpointBeforeToolExecution
|
|
244715
245125
|
};
|
|
244716
245126
|
let chatParams = {
|
|
244717
245127
|
messages,
|
|
@@ -244724,9 +245134,8 @@ async function executeLoopStep(deps) {
|
|
|
244724
245134
|
signal.throwIfAborted();
|
|
244725
245135
|
const retryInput = {
|
|
244726
245136
|
llm: stepLLM,
|
|
244727
|
-
dispatchEvent: (event) =>
|
|
244728
|
-
|
|
244729
|
-
},
|
|
245137
|
+
dispatchEvent: (event) => stepEvents.dispatchRetrying(event),
|
|
245138
|
+
checkpointBeforeRetryWait,
|
|
244730
245139
|
turnId,
|
|
244731
245140
|
currentStep,
|
|
244732
245141
|
stepUuid,
|
|
@@ -244886,29 +245295,33 @@ async function chatWithLiveResponseRepetitionRecovery(deps) {
|
|
|
244886
245295
|
occurrences: repetition.count,
|
|
244887
245296
|
wordCount: repetition.wordCount
|
|
244888
245297
|
});
|
|
244889
|
-
await
|
|
244890
|
-
|
|
244891
|
-
|
|
244892
|
-
|
|
244893
|
-
|
|
244894
|
-
|
|
244895
|
-
|
|
244896
|
-
|
|
244897
|
-
|
|
244898
|
-
|
|
244899
|
-
|
|
244900
|
-
|
|
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
|
+
}
|
|
244901
245315
|
});
|
|
244902
245316
|
}
|
|
244903
245317
|
}
|
|
244904
245318
|
throw new Error("Live response repetition recovery exhausted");
|
|
244905
245319
|
}
|
|
244906
245320
|
function createStepEventGate(deps) {
|
|
244907
|
-
const { dispatchEvent, turnId, currentStep, stepUuid, onStepStarted } = deps;
|
|
245321
|
+
const { dispatchEvent, turnId, currentStep, stepUuid, onStepStarted, requestMetadata, maxAttempts } = deps;
|
|
244908
245322
|
let startPromise;
|
|
244909
245323
|
let eventQueue = Promise.resolve();
|
|
244910
245324
|
let hasOutput = false;
|
|
244911
|
-
const pendingBeforeStart = [];
|
|
244912
245325
|
let liveRepetitionGuard;
|
|
244913
245326
|
let liveRepetitionController;
|
|
244914
245327
|
let liveRepetitionResult = null;
|
|
@@ -244918,10 +245331,13 @@ function createStepEventGate(deps) {
|
|
|
244918
245331
|
type: "step.begin",
|
|
244919
245332
|
uuid: stepUuid,
|
|
244920
245333
|
turnId,
|
|
244921
|
-
step: currentStep
|
|
245334
|
+
step: currentStep,
|
|
245335
|
+
thinkingEffort: requestMetadata?.thinkingEffort,
|
|
245336
|
+
completionBudget: requestMetadata?.completionBudget,
|
|
245337
|
+
attempt: 1,
|
|
245338
|
+
maxAttempts
|
|
244922
245339
|
});
|
|
244923
245340
|
onStepStarted?.();
|
|
244924
|
-
for (const dispatch of pendingBeforeStart.splice(0)) await dispatch();
|
|
244925
245341
|
})();
|
|
244926
245342
|
return startPromise;
|
|
244927
245343
|
};
|
|
@@ -244956,14 +245372,9 @@ function createStepEventGate(deps) {
|
|
|
244956
245372
|
return AbortSignal.any([signal, liveRepetitionController.signal]);
|
|
244957
245373
|
},
|
|
244958
245374
|
dispatchRetrying: async (event) => {
|
|
244959
|
-
|
|
244960
|
-
|
|
244961
|
-
|
|
244962
|
-
});
|
|
244963
|
-
return;
|
|
244964
|
-
}
|
|
244965
|
-
const queued = eventQueue.then(() => {
|
|
244966
|
-
dispatchEvent(event);
|
|
245375
|
+
const queued = eventQueue.then(async () => {
|
|
245376
|
+
await start();
|
|
245377
|
+
await dispatchEvent(event);
|
|
244967
245378
|
});
|
|
244968
245379
|
eventQueue = queued;
|
|
244969
245380
|
await queued;
|
|
@@ -245027,7 +245438,7 @@ var init_turn_step = __esmMin((() => {
|
|
|
245027
245438
|
//#endregion
|
|
245028
245439
|
//#region ../../packages/agent-core/src/loop/run-turn.ts
|
|
245029
245440
|
async function runTurn(input) {
|
|
245030
|
-
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;
|
|
245031
245442
|
let usage = emptyUsage();
|
|
245032
245443
|
let steps = 0;
|
|
245033
245444
|
let stopReason = "end_turn";
|
|
@@ -245057,6 +245468,8 @@ async function runTurn(input) {
|
|
|
245057
245468
|
log,
|
|
245058
245469
|
currentStep: stepNumber,
|
|
245059
245470
|
maxRetryAttempts,
|
|
245471
|
+
checkpointBeforeToolExecution,
|
|
245472
|
+
checkpointBeforeRetryWait,
|
|
245060
245473
|
recordUsage: recordStepUsage,
|
|
245061
245474
|
onStepStarted: setActiveStep.bind(void 0, stepNumber)
|
|
245062
245475
|
});
|
|
@@ -245955,7 +246368,7 @@ var init_modelCatalog$2 = __esmMin((() => {
|
|
|
245955
246368
|
function isVolatileEventType(type) {
|
|
245956
246369
|
return volatileEventTypeSet.has(type);
|
|
245957
246370
|
}
|
|
245958
|
-
var MCP_OAUTH_AUTHORIZATION_URL_TOOL_UPDATE, tokenUsageSchema, finishReasonSchema, usageStatusSchema, permissionModeSchema, skillSourceSchema, userPromptOriginSchema, skillActivationOriginSchema, pluginCommandOriginSchema, injectionOriginSchema, shellCommandOriginSchema, compactionSummaryOriginSchema, systemTriggerOriginSchema, agentCoreBackgroundTaskStatusSchema, backgroundTaskOriginSchema, cronJobOriginSchema, cronMissedOriginSchema, hookResultOriginSchema, retryOriginSchema, promptOriginSchema, goalStatusSchema, goalActorSchema, goalBudgetReportSchema, goalSnapshotSchema, goalChangeStatsSchema, goalChangeKindSchema, goalChangeSchema, blunErrorCodeSchema, blunErrorPayloadSchema, backgroundTaskInfoBaseSchema, processBackgroundTaskInfoSchema, agentBackgroundTaskInfoSchema, questionBackgroundTaskInfoSchema, backgroundTaskInfoSchema, compactionResultSchema, toolUpdateSchema, turnEndReasonSchema, agentStatusUpdatedEventSchema, sessionMetaUpdatedEventSchema, sessionCreatedEventSchema, workspaceCreatedEventSchema, workspaceUpdatedEventSchema, workspaceDeletedEventSchema, sessionStatusChangedEventSchema, modelCatalogChangedEventSchema, goalUpdatedEventSchema, skillActivatedEventSchema, pluginCommandActivatedEventSchema, errorEventSchema, warningEventSchema, turnStartedEventSchema, turnEndedEventSchema, turnStepStartedEventSchema, turnStepCompletedEventSchema, turnStepRetryingEventSchema, turnStepInterruptedEventSchema, assistantDeltaEventSchema, hookResultEventSchema, thinkingDeltaEventSchema, toolCallDeltaEventSchema, toolCallStartedEventSchema, toolProgressEventSchema, shellOutputEventSchema, shellStartedEventSchema, toolResultEventSchema, subagentSpawnedEventSchema, subagentStartedEventSchema, subagentSuspendedEventSchema, subagentCompletedEventSchema, subagentFailedEventSchema, compactionStartedEventSchema, compactionBlockedEventSchema, compactionCancelledEventSchema, compactionProgressEventSchema, compactionCompletedEventSchema, backgroundTaskStartedEventSchema, backgroundTaskTerminatedEventSchema, cronFiredEventSchema, attentionIntentSchema, attentionAuthorizedEventSchema, promptSubmittedEventSchema, toolListUpdatedReasonSchema, toolListUpdatedEventSchema, mcpServerStatusPayloadSchema, mcpServerStatusEventSchema, mediaDroppedEventSchema, agentEventSchema, eventSchema, VOLATILE_EVENT_TYPES, volatileEventTypeSet;
|
|
246371
|
+
var MCP_OAUTH_AUTHORIZATION_URL_TOOL_UPDATE, tokenUsageSchema, finishReasonSchema, usageStatusSchema, permissionModeSchema, skillSourceSchema, userPromptOriginSchema, skillActivationOriginSchema, pluginCommandOriginSchema, injectionOriginSchema, shellCommandOriginSchema, compactionSummaryOriginSchema, cronToolScopeSchema, systemTriggerOriginSchema, agentCoreBackgroundTaskStatusSchema, backgroundTaskOriginSchema, cronJobOriginSchema, cronMissedOriginSchema, hookResultOriginSchema, retryOriginSchema, promptOriginSchema, goalStatusSchema, goalActorSchema, goalBudgetReportSchema, goalSnapshotSchema, goalChangeStatsSchema, goalChangeKindSchema, goalChangeSchema, blunErrorCodeSchema, blunErrorPayloadSchema, backgroundTaskInfoBaseSchema, processBackgroundTaskInfoSchema, agentBackgroundTaskInfoSchema, questionBackgroundTaskInfoSchema, backgroundTaskInfoSchema, compactionResultSchema, toolUpdateSchema, turnEndReasonSchema, agentStatusUpdatedEventSchema, sessionMetaUpdatedEventSchema, sessionCreatedEventSchema, workspaceCreatedEventSchema, workspaceUpdatedEventSchema, workspaceDeletedEventSchema, sessionStatusChangedEventSchema, modelCatalogChangedEventSchema, goalUpdatedEventSchema, skillActivatedEventSchema, pluginCommandActivatedEventSchema, errorEventSchema, warningEventSchema, turnStartedEventSchema, turnEndedEventSchema, turnStepStartedEventSchema, turnStepCompletedEventSchema, turnStepRetryingEventSchema, turnStepInterruptedEventSchema, assistantDeltaEventSchema, hookResultEventSchema, thinkingDeltaEventSchema, toolCallDeltaEventSchema, toolCallStartedEventSchema, toolProgressEventSchema, shellOutputEventSchema, shellStartedEventSchema, toolResultEventSchema, subagentSpawnedEventSchema, subagentStartedEventSchema, subagentSuspendedEventSchema, subagentCompletedEventSchema, subagentFailedEventSchema, compactionStartedEventSchema, compactionBlockedEventSchema, compactionCancelledEventSchema, compactionProgressEventSchema, compactionCompletedEventSchema, backgroundTaskStartedEventSchema, backgroundTaskTerminatedEventSchema, cronFiredEventSchema, cronRunCreatedEventSchema, cronRunStartedEventSchema, cronRunTerminalEventSchema, attentionIntentSchema, attentionAuthorizedEventSchema, promptSubmittedEventSchema, toolListUpdatedReasonSchema, toolListUpdatedEventSchema, mcpServerStatusPayloadSchema, mcpServerStatusEventSchema, mediaDroppedEventSchema, agentEventSchema, eventSchema, VOLATILE_EVENT_TYPES, volatileEventTypeSet;
|
|
245959
246372
|
var init_events$1 = __esmMin((() => {
|
|
245960
246373
|
init_zod$1();
|
|
245961
246374
|
init_display();
|
|
@@ -246029,9 +246442,16 @@ var init_events$1 = __esmMin((() => {
|
|
|
246029
246442
|
isError: boolean$1().optional()
|
|
246030
246443
|
});
|
|
246031
246444
|
compactionSummaryOriginSchema = object({ kind: literal("compaction_summary") });
|
|
246445
|
+
cronToolScopeSchema = object({
|
|
246446
|
+
mode: literal("scoped"),
|
|
246447
|
+
names: array(string()).max(64),
|
|
246448
|
+
digest: string()
|
|
246449
|
+
});
|
|
246032
246450
|
systemTriggerOriginSchema = object({
|
|
246033
246451
|
kind: literal("system_trigger"),
|
|
246034
|
-
name: string()
|
|
246452
|
+
name: string(),
|
|
246453
|
+
cronRunId: string().optional(),
|
|
246454
|
+
toolScope: cronToolScopeSchema.optional()
|
|
246035
246455
|
});
|
|
246036
246456
|
agentCoreBackgroundTaskStatusSchema = _enum([
|
|
246037
246457
|
"running",
|
|
@@ -246050,10 +246470,12 @@ var init_events$1 = __esmMin((() => {
|
|
|
246050
246470
|
cronJobOriginSchema = object({
|
|
246051
246471
|
kind: literal("cron_job"),
|
|
246052
246472
|
jobId: string(),
|
|
246473
|
+
runId: string().optional(),
|
|
246053
246474
|
cron: string(),
|
|
246054
246475
|
recurring: boolean$1(),
|
|
246055
246476
|
coalescedCount: number$1(),
|
|
246056
|
-
stale: boolean$1()
|
|
246477
|
+
stale: boolean$1(),
|
|
246478
|
+
toolScope: cronToolScopeSchema.optional()
|
|
246057
246479
|
});
|
|
246058
246480
|
cronMissedOriginSchema = object({
|
|
246059
246481
|
kind: literal("cron_missed"),
|
|
@@ -246066,7 +246488,8 @@ var init_events$1 = __esmMin((() => {
|
|
|
246066
246488
|
});
|
|
246067
246489
|
retryOriginSchema = object({
|
|
246068
246490
|
kind: literal("retry"),
|
|
246069
|
-
trigger: string().optional()
|
|
246491
|
+
trigger: string().optional(),
|
|
246492
|
+
toolScope: cronToolScopeSchema.optional()
|
|
246070
246493
|
});
|
|
246071
246494
|
promptOriginSchema = discriminatedUnion("kind", [
|
|
246072
246495
|
userPromptOriginSchema,
|
|
@@ -246419,7 +246842,11 @@ var init_events$1 = __esmMin((() => {
|
|
|
246419
246842
|
type: literal("turn.step.started"),
|
|
246420
246843
|
turnId: number$1(),
|
|
246421
246844
|
step: number$1(),
|
|
246422
|
-
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()
|
|
246423
246850
|
});
|
|
246424
246851
|
turnStepCompletedEventSchema = object({
|
|
246425
246852
|
type: literal("turn.step.completed"),
|
|
@@ -246449,7 +246876,9 @@ var init_events$1 = __esmMin((() => {
|
|
|
246449
246876
|
outputMayHaveStarted: boolean$1().optional(),
|
|
246450
246877
|
errorName: string(),
|
|
246451
246878
|
errorMessage: string(),
|
|
246452
|
-
statusCode: number$1().optional()
|
|
246879
|
+
statusCode: number$1().optional(),
|
|
246880
|
+
completionBudgetBefore: number$1().int().positive().optional(),
|
|
246881
|
+
completionBudgetAfter: number$1().int().positive().optional()
|
|
246453
246882
|
});
|
|
246454
246883
|
turnStepInterruptedEventSchema = object({
|
|
246455
246884
|
type: literal("turn.step.interrupted"),
|
|
@@ -246586,8 +247015,30 @@ var init_events$1 = __esmMin((() => {
|
|
|
246586
247015
|
});
|
|
246587
247016
|
cronFiredEventSchema = object({
|
|
246588
247017
|
type: literal("cron.fired"),
|
|
246589
|
-
origin: cronJobOriginSchema
|
|
246590
|
-
|
|
247018
|
+
origin: cronJobOriginSchema
|
|
247019
|
+
});
|
|
247020
|
+
cronRunCreatedEventSchema = object({
|
|
247021
|
+
type: literal("cron.run.created"),
|
|
247022
|
+
runId: string(),
|
|
247023
|
+
jobId: string(),
|
|
247024
|
+
coalescedCount: number$1(),
|
|
247025
|
+
toolScopeDigest: string().nullable()
|
|
247026
|
+
});
|
|
247027
|
+
cronRunStartedEventSchema = object({
|
|
247028
|
+
type: literal("cron.run.started"),
|
|
247029
|
+
runId: string(),
|
|
247030
|
+
jobId: string(),
|
|
247031
|
+
turnId: number$1()
|
|
247032
|
+
});
|
|
247033
|
+
cronRunTerminalEventSchema = object({
|
|
247034
|
+
type: _enum(["cron.run.completed", "cron.run.failed", "cron.run.cancelled", "cron.run.lost"]),
|
|
247035
|
+
runId: string(),
|
|
247036
|
+
jobId: string(),
|
|
247037
|
+
durationMs: number$1().optional(),
|
|
247038
|
+
toolCalls: number$1(),
|
|
247039
|
+
toolErrors: number$1(),
|
|
247040
|
+
outputCount: number$1(),
|
|
247041
|
+
errorCategory: string().optional()
|
|
246591
247042
|
});
|
|
246592
247043
|
attentionIntentSchema = object({
|
|
246593
247044
|
accepted: literal(true),
|
|
@@ -246701,6 +247152,9 @@ var init_events$1 = __esmMin((() => {
|
|
|
246701
247152
|
backgroundTaskStartedEventSchema,
|
|
246702
247153
|
backgroundTaskTerminatedEventSchema,
|
|
246703
247154
|
cronFiredEventSchema,
|
|
247155
|
+
cronRunCreatedEventSchema,
|
|
247156
|
+
cronRunStartedEventSchema,
|
|
247157
|
+
cronRunTerminalEventSchema,
|
|
246704
247158
|
attentionAuthorizedEventSchema,
|
|
246705
247159
|
promptSubmittedEventSchema
|
|
246706
247160
|
]);
|
|
@@ -247246,7 +247700,8 @@ var init_approval$2 = __esmMin((() => {
|
|
|
247246
247700
|
approvalDecisionSchema = _enum([
|
|
247247
247701
|
"approved",
|
|
247248
247702
|
"rejected",
|
|
247249
|
-
"cancelled"
|
|
247703
|
+
"cancelled",
|
|
247704
|
+
"edited"
|
|
247250
247705
|
]);
|
|
247251
247706
|
approvalScopeSchema = _enum(["session"]);
|
|
247252
247707
|
approvalRequestSchema = object({
|
|
@@ -247257,6 +247712,7 @@ var init_approval$2 = __esmMin((() => {
|
|
|
247257
247712
|
tool_name: string().min(1),
|
|
247258
247713
|
action: string(),
|
|
247259
247714
|
tool_input_display: unknown(),
|
|
247715
|
+
allow_edit: boolean$1().optional(),
|
|
247260
247716
|
created_at: isoDateTimeSchema,
|
|
247261
247717
|
expires_at: isoDateTimeSchema
|
|
247262
247718
|
});
|
|
@@ -247264,7 +247720,8 @@ var init_approval$2 = __esmMin((() => {
|
|
|
247264
247720
|
decision: approvalDecisionSchema,
|
|
247265
247721
|
scope: approvalScopeSchema.optional(),
|
|
247266
247722
|
feedback: string().optional(),
|
|
247267
|
-
selected_label: string().optional()
|
|
247723
|
+
selected_label: string().optional(),
|
|
247724
|
+
edited_tool_input: unknown().optional()
|
|
247268
247725
|
});
|
|
247269
247726
|
}));
|
|
247270
247727
|
//#endregion
|
|
@@ -251720,6 +252177,89 @@ var init_task_update = __esmMin((() => {
|
|
|
251720
252177
|
};
|
|
251721
252178
|
}));
|
|
251722
252179
|
//#endregion
|
|
252180
|
+
//#region ../../packages/agent-core/src/tools/background/task-resume.ts
|
|
252181
|
+
var DurableTaskResumeRuntime$1, TaskResumeInputSchema, TaskResumeTool;
|
|
252182
|
+
var init_task_resume = __esmMin((() => {
|
|
252183
|
+
init_zod$1();
|
|
252184
|
+
init_input_schema();
|
|
252185
|
+
init_rule_match();
|
|
252186
|
+
init_agent_task();
|
|
252187
|
+
({ DurableTaskResumeRuntime: DurableTaskResumeRuntime$1 } = createRequire(import.meta.url)("./bin/durable-task-resume-runtime.cjs"));
|
|
252188
|
+
TaskResumeInputSchema = object({
|
|
252189
|
+
task_id: string().trim().min(1).describe("The lost agent task ID, or completed TaskResume successor, to continue."),
|
|
252190
|
+
prompt: string().trim().min(1).max(32768).describe("New instructions for the preserved agent context."),
|
|
252191
|
+
description: string().trim().min(1).max(1024).describe("Short description for the replacement background task."),
|
|
252192
|
+
timeout_minutes: number$1().int().min(0).max(10080).optional().describe("Wall-clock continuation interval for the replacement run. Defaults to 240 minutes; 0 disables it for this run.")
|
|
252193
|
+
});
|
|
252194
|
+
TaskResumeTool = class {
|
|
252195
|
+
manager;
|
|
252196
|
+
subagentHost;
|
|
252197
|
+
runtime;
|
|
252198
|
+
name = "TaskResume";
|
|
252199
|
+
description = "Explicitly continue a recoverable background agent task after a process loss. This resumes the same agent and preserved context, but creates a new background task ID linked to the terminal source task. Only lost agent tasks and completed TaskResume successors are accepted. It never resumes automatically at startup.";
|
|
252200
|
+
parameters = toInputJsonSchema(TaskResumeInputSchema);
|
|
252201
|
+
constructor(manager, subagentHost) {
|
|
252202
|
+
this.manager = manager;
|
|
252203
|
+
this.subagentHost = subagentHost;
|
|
252204
|
+
this.runtime = new DurableTaskResumeRuntime$1({
|
|
252205
|
+
getTask: (taskId) => manager.getTask(taskId),
|
|
252206
|
+
getIntent: (taskId) => manager.resumeStore?.getBySourceTaskId(taskId),
|
|
252207
|
+
writeIntent: (intent) => manager.resumeStore.write(intent),
|
|
252208
|
+
markIntentStarted: (taskId, startedAt) => manager.resumeStore.markStarted(taskId, startedAt),
|
|
252209
|
+
reserveTaskId: (prefix) => manager.reserveTaskId(prefix),
|
|
252210
|
+
resumeAgent: (agentId, options) => subagentHost.resume(agentId, options),
|
|
252211
|
+
createTask: (handle, description, metadata) => new AgentBackgroundTask(handle, description, subagentHost, metadata.controller ?? new AbortController(), {
|
|
252212
|
+
timeoutMs: resolveSubagentTimeoutMs({ perRunMinutes: metadata.timeoutMinutes }),
|
|
252213
|
+
runInBackground: true,
|
|
252214
|
+
parentToolCallId: metadata.parentToolCallId,
|
|
252215
|
+
responseFormat: void 0,
|
|
252216
|
+
resumed: true,
|
|
252217
|
+
replacesTaskId: metadata.replacesTaskId,
|
|
252218
|
+
resumeRootTaskId: metadata.resumeRootTaskId
|
|
252219
|
+
}),
|
|
252220
|
+
registerTask: (task, options) => manager.registerTask(task, options),
|
|
252221
|
+
awaitTaskPersisted: (taskId) => manager.awaitTaskPersisted(taskId),
|
|
252222
|
+
emitEvent: (event) => manager.agent.emitEvent(event),
|
|
252223
|
+
now: () => Date.now()
|
|
252224
|
+
});
|
|
252225
|
+
}
|
|
252226
|
+
resolveExecution(args) {
|
|
252227
|
+
return {
|
|
252228
|
+
description: `Resuming agent task ${args.task_id}`,
|
|
252229
|
+
approvalRule: this.name,
|
|
252230
|
+
matchesRule: (ruleArgs) => matchesGlobRuleSubject(ruleArgs, args.task_id),
|
|
252231
|
+
execute: (ctx) => this.execute(args, ctx)
|
|
252232
|
+
};
|
|
252233
|
+
}
|
|
252234
|
+
async execute(args, { toolCallId, signal, turnId }) {
|
|
252235
|
+
const controller = new AbortController();
|
|
252236
|
+
try {
|
|
252237
|
+
signal.throwIfAborted();
|
|
252238
|
+
const result = await this.runtime.resume({
|
|
252239
|
+
taskId: args.task_id,
|
|
252240
|
+
prompt: args.prompt,
|
|
252241
|
+
description: args.description,
|
|
252242
|
+
timeoutMinutes: args.timeout_minutes,
|
|
252243
|
+
parentToolCallId: toolCallId,
|
|
252244
|
+
toolScope: this.subagentHost.toolScopeForTurn(Number(turnId)),
|
|
252245
|
+
controller,
|
|
252246
|
+
signal
|
|
252247
|
+
});
|
|
252248
|
+
return {
|
|
252249
|
+
output: `task_id: ${result.taskId}\nstatus: ${result.status}\nagent_id: ${result.agentId}\nreplaces_task_id: ${result.replacesTaskId}\nresume_root_task_id: ${result.resumeRootTaskId}\nresumed: true`,
|
|
252250
|
+
isError: false
|
|
252251
|
+
};
|
|
252252
|
+
} catch (error) {
|
|
252253
|
+
controller.abort();
|
|
252254
|
+
return {
|
|
252255
|
+
output: error instanceof Error ? error.message : String(error),
|
|
252256
|
+
isError: true
|
|
252257
|
+
};
|
|
252258
|
+
}
|
|
252259
|
+
}
|
|
252260
|
+
};
|
|
252261
|
+
}));
|
|
252262
|
+
//#endregion
|
|
251723
252263
|
//#region ../../packages/agent-core/src/tools/background/task-stop.md?raw
|
|
251724
252264
|
var task_stop_default;
|
|
251725
252265
|
var init_task_stop$1 = __esmMin((() => {
|
|
@@ -251907,6 +252447,67 @@ var init_cron_list = __esmMin((() => {
|
|
|
251907
252447
|
};
|
|
251908
252448
|
}));
|
|
251909
252449
|
//#endregion
|
|
252450
|
+
//#region ../../packages/agent-core/src/tools/cron/cron-runs.ts
|
|
252451
|
+
var CronRunListInputSchema, CronRunOutputInputSchema, CronRunListTool, CronRunOutputTool;
|
|
252452
|
+
var init_cron_runs = __esmMin((() => {
|
|
252453
|
+
init_zod$1();
|
|
252454
|
+
init_input_schema();
|
|
252455
|
+
CronRunListInputSchema = object({
|
|
252456
|
+
job_id: string().regex(/^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$/u).optional().describe("Optional cron job id filter."),
|
|
252457
|
+
status: string().regex(/^(buffered|running|completed|failed|cancelled|lost)$/u).optional().describe("Optional run status filter."),
|
|
252458
|
+
limit: number$1().int().min(1).max(100).optional().default(20).describe("Maximum number of newest run receipts.")
|
|
252459
|
+
}).strict();
|
|
252460
|
+
CronRunOutputInputSchema = object({
|
|
252461
|
+
run_id: string().regex(/^[0-9a-f]{16}$/u).describe("The 16-hex run id returned by CronRunList.")
|
|
252462
|
+
}).strict();
|
|
252463
|
+
CronRunListTool = class {
|
|
252464
|
+
manager;
|
|
252465
|
+
name = "CronRunList";
|
|
252466
|
+
description = "List bounded private receipts for cron runs in this session. Receipts contain lifecycle, tool counts, and output references, never prompts, thoughts, raw tool arguments, results, headers, or approval feedback.";
|
|
252467
|
+
parameters = toInputJsonSchema(CronRunListInputSchema);
|
|
252468
|
+
constructor(manager) {
|
|
252469
|
+
this.manager = manager;
|
|
252470
|
+
}
|
|
252471
|
+
resolveExecution(args) {
|
|
252472
|
+
return {
|
|
252473
|
+
description: "Listing private cron run receipts",
|
|
252474
|
+
approvalRule: this.name,
|
|
252475
|
+
execute: async () => {
|
|
252476
|
+
const runs = this.manager.listRuns({
|
|
252477
|
+
jobId: args.job_id,
|
|
252478
|
+
status: args.status,
|
|
252479
|
+
limit: args.limit
|
|
252480
|
+
});
|
|
252481
|
+
return { output: JSON.stringify({ runs }, null, 2), isError: false };
|
|
252482
|
+
}
|
|
252483
|
+
};
|
|
252484
|
+
}
|
|
252485
|
+
};
|
|
252486
|
+
CronRunOutputTool = class {
|
|
252487
|
+
manager;
|
|
252488
|
+
name = "CronRunOutput";
|
|
252489
|
+
description = "Read one private cron run receipt and its bounded final assistant message. Raw prompts, thoughts, tool arguments, tool results, headers, approvals, and Bash-inferred files are never returned.";
|
|
252490
|
+
parameters = toInputJsonSchema(CronRunOutputInputSchema);
|
|
252491
|
+
constructor(manager) {
|
|
252492
|
+
this.manager = manager;
|
|
252493
|
+
}
|
|
252494
|
+
resolveExecution(args) {
|
|
252495
|
+
return {
|
|
252496
|
+
description: `Reading private cron run ${args.run_id}`,
|
|
252497
|
+
approvalRule: this.name,
|
|
252498
|
+
execute: async () => {
|
|
252499
|
+
const run = this.manager.readRunOutput(args.run_id);
|
|
252500
|
+
if (run === null) return {
|
|
252501
|
+
output: `No cron run with id ${args.run_id} exists in this session.`,
|
|
252502
|
+
isError: true
|
|
252503
|
+
};
|
|
252504
|
+
return { output: JSON.stringify(run, null, 2), isError: false };
|
|
252505
|
+
}
|
|
252506
|
+
};
|
|
252507
|
+
}
|
|
252508
|
+
};
|
|
252509
|
+
}));
|
|
252510
|
+
//#endregion
|
|
251910
252511
|
//#region ../../packages/agent-core/src/agent/permission/policies/deny-all.ts
|
|
251911
252512
|
var DenyAllPermissionPolicy;
|
|
251912
252513
|
var init_deny_all = __esmMin((() => {
|
|
@@ -252318,6 +252919,7 @@ var init_subagent_batch = __esmMin((() => {
|
|
|
252318
252919
|
description: task.description,
|
|
252319
252920
|
swarmIndex: task.swarmIndex,
|
|
252320
252921
|
runInBackground: task.runInBackground,
|
|
252922
|
+
responseFormat: task.responseFormat,
|
|
252321
252923
|
compactBeforeRetry: attempt.state.retryCount > 0,
|
|
252322
252924
|
signal: attempt.controller.signal,
|
|
252323
252925
|
onReady: () => {
|
|
@@ -252342,11 +252944,13 @@ var init_subagent_batch = __esmMin((() => {
|
|
|
252342
252944
|
return this.failedAttemptOutcome(attempt, error);
|
|
252343
252945
|
}
|
|
252344
252946
|
attempt.state.agentId = handle.agentId;
|
|
252947
|
+
attempt.state.profileName = handle.profileName;
|
|
252345
252948
|
try {
|
|
252346
252949
|
const completion = await handle.completion;
|
|
252347
252950
|
return {
|
|
252348
252951
|
task,
|
|
252349
252952
|
agentId: handle.agentId,
|
|
252953
|
+
profileName: handle.profileName,
|
|
252350
252954
|
status: "completed",
|
|
252351
252955
|
result: completion.result,
|
|
252352
252956
|
usage: completion.usage
|
|
@@ -252370,6 +252974,7 @@ var init_subagent_batch = __esmMin((() => {
|
|
|
252370
252974
|
return {
|
|
252371
252975
|
task: attempt.state.task,
|
|
252372
252976
|
agentId: attempt.state.agentId,
|
|
252977
|
+
profileName: attempt.state.profileName,
|
|
252373
252978
|
status,
|
|
252374
252979
|
state: attempt.state.agentId === void 0 ? "not_started" : "started",
|
|
252375
252980
|
error: this.attemptErrorMessage(attempt, error, status)
|
|
@@ -252633,7 +253238,7 @@ async function runChildTurnToCompletion(child, signal) {
|
|
|
252633
253238
|
}
|
|
252634
253239
|
return completion.stopReason;
|
|
252635
253240
|
}
|
|
252636
|
-
async function completeChildTurnWithMaxTokensHandoff(child, signal) {
|
|
253241
|
+
async function completeChildTurnWithMaxTokensHandoff(child, signal, promptOrigin = SUBAGENT_PROMPT_ORIGIN) {
|
|
252637
253242
|
let stopReason = await runChildTurnToCompletion(child, signal);
|
|
252638
253243
|
let handoffAttempts = 0;
|
|
252639
253244
|
while (shouldRequestSubagentHandoff(stopReason, handoffAttempts)) {
|
|
@@ -252642,7 +253247,7 @@ async function completeChildTurnWithMaxTokensHandoff(child, signal) {
|
|
|
252642
253247
|
if (child.turn.prompt([{
|
|
252643
253248
|
type: "text",
|
|
252644
253249
|
text: SUBAGENT_MAX_TOKENS_HANDOFF_PROMPT
|
|
252645
|
-
}],
|
|
253250
|
+
}], promptOrigin) === null) throw new Error("Subagent could not start its max_tokens recovery handoff.");
|
|
252646
253251
|
stopReason = await runChildTurnToCompletion(child, signal);
|
|
252647
253252
|
}
|
|
252648
253253
|
if (stopReason === "max_tokens") throw new Error(buildSubagentMaxTokensFailure(lastAssistantText(child)));
|
|
@@ -252659,7 +253264,7 @@ function lastAssistantText(agent) {
|
|
|
252659
253264
|
}
|
|
252660
253265
|
return "";
|
|
252661
253266
|
}
|
|
252662
|
-
async function completeStructuredSubagentResult(child, childId, profileName, responseFormat, signal) {
|
|
253267
|
+
async function completeStructuredSubagentResult(child, childId, profileName, responseFormat, signal, promptOrigin = SUBAGENT_PROMPT_ORIGIN) {
|
|
252663
253268
|
let validation = validateStructuredSubagentOutput(lastAssistantText(child), responseFormat);
|
|
252664
253269
|
if (validation.validatorException === true) throw new Error(validation.error);
|
|
252665
253270
|
if (!validation.ok) {
|
|
@@ -252667,8 +253272,8 @@ async function completeStructuredSubagentResult(child, childId, profileName, res
|
|
|
252667
253272
|
if (child.turn.prompt([{
|
|
252668
253273
|
type: "text",
|
|
252669
253274
|
text: buildStructuredResponseRepairPrompt(responseFormat, validation.error)
|
|
252670
|
-
}],
|
|
252671
|
-
await completeChildTurnWithMaxTokensHandoff(child, signal);
|
|
253275
|
+
}], promptOrigin) === null) throw new Error("Subagent could not start its structured-output repair turn.");
|
|
253276
|
+
await completeChildTurnWithMaxTokensHandoff(child, signal, promptOrigin);
|
|
252672
253277
|
signal.throwIfAborted();
|
|
252673
253278
|
validation = validateStructuredSubagentOutput(lastAssistantText(child), responseFormat);
|
|
252674
253279
|
if (validation.validatorException === true) throw new Error(validation.error);
|
|
@@ -252681,7 +253286,7 @@ function shouldSuppressQueuedAttemptFailureEvent(options, error) {
|
|
|
252681
253286
|
if (isProviderRateLimitError(error)) return true;
|
|
252682
253287
|
return isAbortError$4(error) || options.signal.aborted;
|
|
252683
253288
|
}
|
|
252684
|
-
var DEFAULT_SUBAGENT_TIMEOUT_MS, resolveSubagentTimeoutMs, runAgentWithTimeoutContinuation, buildSubagentUsageDelta, inheritSubagentAllowedTools, inheritSubagentLifecycleTools, STRUCTURED_SUBAGENT_OUTPUT_ERROR, prepareStructuredResponseFormat, validateStructuredSubagentOutput, buildStructuredResponseFormatReminder, buildStructuredResponseRepairPrompt, buildStructuredSubagentEnvelope, SUBAGENT_MAX_TOKENS_ERROR, SUBAGENT_MAX_TOKENS_HANDOFF_PROMPT, buildSubagentMaxTokensFailure, isSubagentMaxTokensTurnError, shouldRequestSubagentHandoff, SUMMARY_MIN_LENGTH, SUMMARY_CONTINUATION_ATTEMPTS, HOOK_TEXT_PREVIEW_LENGTH, TOOL_CALL_DISABLED_MESSAGE, SUBAGENT_PROMPT_ORIGIN, SIDE_QUESTION_SYSTEM_REMINDER, SessionSubagentHost;
|
|
253289
|
+
var DEFAULT_SUBAGENT_TIMEOUT_MS, resolveSubagentTimeoutMs, runAgentWithTimeoutContinuation, buildSubagentUsageDelta, inheritSubagentAllowedTools, inheritSubagentLifecycleTools, prepareSubagentSkillPolicy, profileWithSubagentSkillTools, restoreSubagentSkillPolicy, STRUCTURED_SUBAGENT_OUTPUT_ERROR, prepareStructuredResponseFormat, validateStructuredSubagentOutput, buildStructuredResponseFormatReminder, buildStructuredResponseRepairPrompt, buildStructuredSubagentEnvelope, SUBAGENT_MAX_TOKENS_ERROR, SUBAGENT_MAX_TOKENS_HANDOFF_PROMPT, buildSubagentMaxTokensFailure, isSubagentMaxTokensTurnError, shouldRequestSubagentHandoff, SUBAGENT_FORK_REMINDER, projectSubagentForkContext, resolveSubagentContextMode, SUMMARY_MIN_LENGTH, SUMMARY_CONTINUATION_ATTEMPTS, HOOK_TEXT_PREVIEW_LENGTH, TOOL_CALL_DISABLED_MESSAGE, SUBAGENT_PROMPT_ORIGIN, SIDE_QUESTION_SYSTEM_REMINDER, SessionSubagentHost;
|
|
252685
253290
|
var init_subagent_host = __esmMin((() => {
|
|
252686
253291
|
init_src$4();
|
|
252687
253292
|
init_errors$8();
|
|
@@ -252696,6 +253301,8 @@ var init_subagent_host = __esmMin((() => {
|
|
|
252696
253301
|
({ DEFAULT_SUBAGENT_TIMEOUT_MS, resolveSubagentTimeoutMs, runAgentWithTimeoutContinuation } = createRequire(import.meta.url)("./bin/subagent-timeout-policy.cjs"));
|
|
252697
253302
|
({ buildSubagentUsageDelta } = createRequire(import.meta.url)("./bin/subagent-usage-rollup-policy.cjs"));
|
|
252698
253303
|
({ inheritSubagentAllowedTools, inheritSubagentLifecycleTools } = createRequire(import.meta.url)("./bin/subagent-tool-policy.cjs"));
|
|
253304
|
+
({ prepareSubagentSkillPolicy, profileWithSubagentSkillTools, restoreSubagentSkillPolicy } = createRequire(import.meta.url)("./bin/subagent-skill-policy.cjs"));
|
|
253305
|
+
({ SUBAGENT_FORK_REMINDER, projectSubagentForkContext, resolveSubagentContextMode } = createRequire(import.meta.url)("./bin/subagent-context-fork-policy.cjs"));
|
|
252699
253306
|
({
|
|
252700
253307
|
STRUCTURED_SUBAGENT_OUTPUT_ERROR,
|
|
252701
253308
|
prepareStructuredResponseFormat,
|
|
@@ -252719,6 +253326,12 @@ var init_subagent_host = __esmMin((() => {
|
|
|
252719
253326
|
kind: "system_trigger",
|
|
252720
253327
|
name: "subagent"
|
|
252721
253328
|
};
|
|
253329
|
+
function subagentPromptOrigin(toolScope) {
|
|
253330
|
+
return toolScope === void 0 ? SUBAGENT_PROMPT_ORIGIN : {
|
|
253331
|
+
...SUBAGENT_PROMPT_ORIGIN,
|
|
253332
|
+
toolScope
|
|
253333
|
+
};
|
|
253334
|
+
}
|
|
252722
253335
|
SIDE_QUESTION_SYSTEM_REMINDER = `
|
|
252723
253336
|
This is a side-channel conversation with the user. You should answer user questions directly based on what you already know.
|
|
252724
253337
|
|
|
@@ -252757,21 +253370,37 @@ IMPORTANT:
|
|
|
252757
253370
|
}
|
|
252758
253371
|
return this.session.getReadyAgent(currentId);
|
|
252759
253372
|
}
|
|
253373
|
+
toolScopeForTurn(turnId) {
|
|
253374
|
+
return inheritedCronToolScope(this.session.getReadyAgent(this.ownerAgentId)?.turn.toolScopeForTurn(turnId));
|
|
253375
|
+
}
|
|
253376
|
+
isRootAgent() {
|
|
253377
|
+
return this.session.metadata.agents[this.ownerAgentId]?.parentAgentId == null;
|
|
253378
|
+
}
|
|
252760
253379
|
async spawn(options) {
|
|
252761
253380
|
options.signal.throwIfAborted();
|
|
252762
253381
|
const parent = await this.session.ensureAgentResumed(this.ownerAgentId);
|
|
253382
|
+
const contextMode = resolveSubagentContextMode({
|
|
253383
|
+
requested: options.contextMode,
|
|
253384
|
+
isRoot: this.isRootAgent()
|
|
253385
|
+
});
|
|
252763
253386
|
const profile = this.resolveProfile(parent, options.profileName);
|
|
253387
|
+
const skillPolicy = prepareSubagentSkillPolicy(profile.subagentSkills, this.session.skills);
|
|
253388
|
+
const effectiveProfile = profileWithSubagentSkillTools(profile, skillPolicy);
|
|
252764
253389
|
const { id, agent } = await this.session.createAgent({
|
|
252765
253390
|
type: "sub",
|
|
252766
|
-
generate: parent.rawGenerate
|
|
253391
|
+
generate: parent.rawGenerate,
|
|
253392
|
+
skillRegistry: skillPolicy.registry
|
|
252767
253393
|
}, {
|
|
252768
253394
|
parentAgentId: this.ownerAgentId,
|
|
252769
|
-
swarmItem: options.swarmItem
|
|
253395
|
+
swarmItem: options.swarmItem,
|
|
253396
|
+
profileName: profile.name,
|
|
253397
|
+
skillPolicy: skillPolicy.metadata
|
|
252770
253398
|
});
|
|
252771
253399
|
const completion = this.runWithTrackedChildUsage(parent, agent, id, options, async (runOptions) => {
|
|
252772
253400
|
this.emitSubagentSpawned(parent, id, profile.name, runOptions);
|
|
252773
253401
|
try {
|
|
252774
|
-
await this.configureChild(parent, agent,
|
|
253402
|
+
await this.configureChild(parent, agent, effectiveProfile);
|
|
253403
|
+
if (contextMode === "fork") this.seedForkedContext(parent, agent);
|
|
252775
253404
|
return await this.runPromptTurn(parent, id, agent, profile.name, runOptions);
|
|
252776
253405
|
} catch (error) {
|
|
252777
253406
|
this.emitSubagentFailed(parent, id, runOptions, error);
|
|
@@ -252845,7 +253474,7 @@ IMPORTANT:
|
|
|
252845
253474
|
await child.fullCompaction.block(runOptions.signal);
|
|
252846
253475
|
}
|
|
252847
253476
|
this.emitSubagentStarted(parent, agentId);
|
|
252848
|
-
if (child.turn.retry("agent-host") === null) throw new Error(`Agent instance "${agentId}" could not start a retry turn`);
|
|
253477
|
+
if (child.turn.retry("agent-host", runOptions.toolScope) === null) throw new Error(`Agent instance "${agentId}" could not start a retry turn`);
|
|
252849
253478
|
this.observeFirstRequest(child, runOptions);
|
|
252850
253479
|
return await this.waitForChildCompletion(parent, agentId, child, profileName, runOptions);
|
|
252851
253480
|
} catch (error) {
|
|
@@ -252968,23 +253597,29 @@ IMPORTANT:
|
|
|
252968
253597
|
const gitContext = await collectGitContext(child.kaos, child.config.cwd);
|
|
252969
253598
|
if (gitContext) childPrompt = `${gitContext}\n\n${childPrompt}`;
|
|
252970
253599
|
}
|
|
253600
|
+
if (options.systemReminder !== void 0) child.context.appendSystemReminder(options.systemReminder, {
|
|
253601
|
+
kind: "system_trigger",
|
|
253602
|
+
name: "durable_task_resume"
|
|
253603
|
+
});
|
|
252971
253604
|
if (options.responseFormat !== void 0) child.context.appendSystemReminder(buildStructuredResponseFormatReminder(options.responseFormat), {
|
|
252972
253605
|
kind: "system_trigger",
|
|
252973
253606
|
name: "subagent_response_format"
|
|
252974
253607
|
});
|
|
252975
253608
|
this.emitSubagentStarted(parent, childId);
|
|
253609
|
+
const childOrigin = subagentPromptOrigin(options.toolScope);
|
|
252976
253610
|
if (child.turn.prompt([{
|
|
252977
253611
|
type: "text",
|
|
252978
253612
|
text: childPrompt
|
|
252979
|
-
}],
|
|
253613
|
+
}], childOrigin) === null) throw new Error(`Agent instance "${childId}" could not start a turn`);
|
|
252980
253614
|
this.observeFirstRequest(child, options);
|
|
252981
253615
|
return this.waitForChildCompletion(parent, childId, child, profileName, options);
|
|
252982
253616
|
}
|
|
252983
253617
|
async waitForChildCompletion(parent, childId, child, profileName, options) {
|
|
252984
|
-
|
|
253618
|
+
const childOrigin = subagentPromptOrigin(options.toolScope);
|
|
253619
|
+
await completeChildTurnWithMaxTokensHandoff(child, options.signal, childOrigin);
|
|
252985
253620
|
let result;
|
|
252986
253621
|
if (options.responseFormat !== void 0) {
|
|
252987
|
-
const structuredResult = await completeStructuredSubagentResult(child, childId, profileName, options.responseFormat, options.signal);
|
|
253622
|
+
const structuredResult = await completeStructuredSubagentResult(child, childId, profileName, options.responseFormat, options.signal, childOrigin);
|
|
252988
253623
|
result = buildStructuredSubagentEnvelope({
|
|
252989
253624
|
agentId: childId,
|
|
252990
253625
|
profileName,
|
|
@@ -253001,8 +253636,8 @@ IMPORTANT:
|
|
|
253001
253636
|
child.turn.prompt([{
|
|
253002
253637
|
type: "text",
|
|
253003
253638
|
text: summary_continuation_default
|
|
253004
|
-
}],
|
|
253005
|
-
await completeChildTurnWithMaxTokensHandoff(child, options.signal);
|
|
253639
|
+
}], childOrigin);
|
|
253640
|
+
await completeChildTurnWithMaxTokensHandoff(child, options.signal, childOrigin);
|
|
253006
253641
|
result = lastAssistantText(child);
|
|
253007
253642
|
}
|
|
253008
253643
|
}
|
|
@@ -253029,10 +253664,22 @@ IMPORTANT:
|
|
|
253029
253664
|
});
|
|
253030
253665
|
const context = await prepareSystemPromptContext(this.session.systemContextKaos(child.kaos.getcwd()), this.session.options.blunHomeDir, { additionalDirs: child.getAdditionalDirs() });
|
|
253031
253666
|
child.useProfile(profile, context, this.session.options.blunHomeDir);
|
|
253032
|
-
child.tools.inheritUserTools(parent.tools);
|
|
253667
|
+
child.tools.inheritUserTools(parent.tools, /* @__PURE__ */ new Set(["Skill"]));
|
|
253033
253668
|
inheritSubagentLifecycleTools(parent.tools, child.tools);
|
|
253034
253669
|
inheritSubagentAllowedTools(parent.tools, child.tools);
|
|
253035
253670
|
}
|
|
253671
|
+
seedForkedContext(parent, child) {
|
|
253672
|
+
const projection = projectSubagentForkContext(parent.context.history);
|
|
253673
|
+
child.context.useProjectedHistoryFrom({
|
|
253674
|
+
history: projection.messages,
|
|
253675
|
+
project: (history) => history
|
|
253676
|
+
});
|
|
253677
|
+
child.context.appendSystemReminder(SUBAGENT_FORK_REMINDER, {
|
|
253678
|
+
kind: "system_trigger",
|
|
253679
|
+
name: "subagent_context_fork"
|
|
253680
|
+
});
|
|
253681
|
+
return projection;
|
|
253682
|
+
}
|
|
253036
253683
|
async triggerSubagentStart(parent, profileName, prompt, signal) {
|
|
253037
253684
|
await parent.hooks?.trigger("SubagentStart", {
|
|
253038
253685
|
matcherValue: profileName,
|
|
@@ -253064,10 +253711,11 @@ IMPORTANT:
|
|
|
253064
253711
|
subagentId: childId,
|
|
253065
253712
|
subagentName: profileName,
|
|
253066
253713
|
parentToolCallId: options.parentToolCallId,
|
|
253067
|
-
|
|
253068
|
-
|
|
253069
|
-
|
|
253070
|
-
|
|
253714
|
+
parentToolCallUuid: options.parentToolCallUuid,
|
|
253715
|
+
parentAgentId: this.ownerAgentId,
|
|
253716
|
+
description: options.description,
|
|
253717
|
+
contextMode: options.contextMode === "fork" ? "fork" : "isolated",
|
|
253718
|
+
swarmIndex: options.swarmIndex,
|
|
253071
253719
|
runInBackground: options.runInBackground
|
|
253072
253720
|
});
|
|
253073
253721
|
parent.telemetry.track("subagent_created", {
|
|
@@ -253160,7 +253808,7 @@ function buildSubagentDescriptions(subagents) {
|
|
|
253160
253808
|
return `${header}\n Tools: ${subagent.tools.join(", ")}`;
|
|
253161
253809
|
}).join("\n");
|
|
253162
253810
|
}
|
|
253163
|
-
var AgentToolInputSchema, BACKGROUND_AGENT_UNAVAILABLE, AgentTool, USER_INTERRUPTED_SUBAGENT_MESSAGE, resolveSubagentRunMode;
|
|
253811
|
+
var AgentToolInputSchema, BACKGROUND_AGENT_UNAVAILABLE, SUBAGENT_CONTEXT_FORK_TOOL_DESCRIPTION, AgentTool, USER_INTERRUPTED_SUBAGENT_MESSAGE, resolveSubagentRunMode;
|
|
253164
253812
|
var init_agent$1 = __esmMin((() => {
|
|
253165
253813
|
init_zod$1();
|
|
253166
253814
|
init_tool_access();
|
|
@@ -253174,6 +253822,7 @@ var init_agent$1 = __esmMin((() => {
|
|
|
253174
253822
|
init_agent_background_enabled();
|
|
253175
253823
|
init_agent$2();
|
|
253176
253824
|
({ resolveSubagentRunMode } = createRequire(import.meta.url)("./bin/subagent-parent-responsiveness.cjs"));
|
|
253825
|
+
SUBAGENT_CONTEXT_FORK_TOOL_DESCRIPTION = "The default context_mode=isolated starts with zero conversation context. For a new root-level subagent whose work genuinely depends on this exact conversation, context_mode=fork passes only a bounded, redacted projection of direct local user text and completed text-only assistant replies. It never passes private channel messages, system injections, attachments, tool calls, arguments, or results. The delegated prompt remains required and authoritative. Fork is unavailable when resuming and unavailable to nested subagents.";
|
|
253177
253826
|
AgentToolInputSchema = preprocess((input) => {
|
|
253178
253827
|
if (typeof input !== "object" || input === null || Array.isArray(input)) return input;
|
|
253179
253828
|
const normalized = { ...input };
|
|
@@ -253186,6 +253835,7 @@ var init_agent$1 = __esmMin((() => {
|
|
|
253186
253835
|
prompt: string().describe("Full task prompt for the subagent"),
|
|
253187
253836
|
description: string().describe("Short task description (3-5 words) for UI display"),
|
|
253188
253837
|
subagent_type: string().optional().describe("One of the available agent types (see \"Available agent types\" in this tool description). Defaults to \"coder\" when omitted."),
|
|
253838
|
+
context_mode: _enum(["isolated", "fork"]).optional().describe("Context boundary for a new subagent. Defaults to isolated. fork is root-only and passes a bounded redacted user/assistant projection without tools, private channels, system injections, attachments, or tool results."),
|
|
253189
253839
|
resume: string().optional().describe("Optional agent ID to resume instead of creating a new instance. When set, do not also pass subagent_type — the resumed agent keeps its own type, and supplying both is rejected."),
|
|
253190
253840
|
run_in_background: boolean$1().optional().describe("Compatibility option. Normal subagents run detached when task management is available. A response_format call requires this to be false or omitted and runs in the foreground for validation."),
|
|
253191
253841
|
timeout_minutes: number$1().int().min(0).max(10080).optional().describe("Wall-clock interval before the same agent is continued automatically. Defaults to 240 minutes. Set 0 to disable the interval for this run."),
|
|
@@ -253217,7 +253867,7 @@ var init_agent$1 = __esmMin((() => {
|
|
|
253217
253867
|
const log = options?.log;
|
|
253218
253868
|
this.allowBackground = options?.allowBackground ?? true;
|
|
253219
253869
|
const typeLines = buildSubagentDescriptions(subagents);
|
|
253220
|
-
const baseDescription = `${agent_default}\n\n${this.allowBackground ? agent_background_enabled_default : agent_background_disabled_default}`;
|
|
253870
|
+
const baseDescription = `${agent_default}\n\n${SUBAGENT_CONTEXT_FORK_TOOL_DESCRIPTION}\n\n${this.allowBackground ? agent_background_enabled_default : agent_background_disabled_default}`;
|
|
253221
253871
|
this.description = typeLines ? `${baseDescription}\n\nAvailable agent types (pass via subagent_type):\n${typeLines}` : baseDescription;
|
|
253222
253872
|
this.log = log;
|
|
253223
253873
|
}
|
|
@@ -253246,7 +253896,7 @@ var init_agent$1 = __esmMin((() => {
|
|
|
253246
253896
|
execute: (ctx) => this.execution(args, ctx)
|
|
253247
253897
|
};
|
|
253248
253898
|
}
|
|
253249
|
-
async execution(args, { toolCallId, signal }) {
|
|
253899
|
+
async execution(args, { toolCallId, signal, turnId }) {
|
|
253250
253900
|
try {
|
|
253251
253901
|
signal.throwIfAborted();
|
|
253252
253902
|
if (args.response_format !== void 0 && args.run_in_background === true) return {
|
|
@@ -253269,6 +253919,19 @@ var init_agent$1 = __esmMin((() => {
|
|
|
253269
253919
|
const runInBackground = responseFormat === void 0 ? resolvedRunMode.runInBackground : false;
|
|
253270
253920
|
const requestedProfileName = args.subagent_type?.length ? args.subagent_type : void 0;
|
|
253271
253921
|
const resumeAgentId = args.resume?.trim();
|
|
253922
|
+
let contextMode;
|
|
253923
|
+
try {
|
|
253924
|
+
contextMode = resolveSubagentContextMode({
|
|
253925
|
+
requested: args.context_mode,
|
|
253926
|
+
resume: resumeAgentId !== void 0 && resumeAgentId.length > 0,
|
|
253927
|
+
isRoot: this.subagentHost.isRootAgent()
|
|
253928
|
+
});
|
|
253929
|
+
} catch (error) {
|
|
253930
|
+
return {
|
|
253931
|
+
output: error instanceof Error ? error.message : String(error),
|
|
253932
|
+
isError: true
|
|
253933
|
+
};
|
|
253934
|
+
}
|
|
253272
253935
|
if (resumeAgentId !== void 0 && resumeAgentId.length > 0 && requestedProfileName !== void 0) return {
|
|
253273
253936
|
output: "Cannot set subagent_type when resuming an existing agent. Resume by agent id only.",
|
|
253274
253937
|
isError: true
|
|
@@ -253289,6 +253952,8 @@ var init_agent$1 = __esmMin((() => {
|
|
|
253289
253952
|
description: args.description,
|
|
253290
253953
|
runInBackground,
|
|
253291
253954
|
responseFormat,
|
|
253955
|
+
contextMode,
|
|
253956
|
+
toolScope: this.subagentHost.toolScopeForTurn(Number(turnId)),
|
|
253292
253957
|
signal: controller.signal
|
|
253293
253958
|
};
|
|
253294
253959
|
let handle;
|
|
@@ -253365,7 +254030,7 @@ var init_agent$1 = __esmMin((() => {
|
|
|
253365
254030
|
//#region ../../packages/agent-core/src/tools/builtin/collaboration/agent-swarm.md?raw
|
|
253366
254031
|
var agent_swarm_default;
|
|
253367
254032
|
var init_agent_swarm$1 = __esmMin((() => {
|
|
253368
|
-
agent_swarm_default = "Launch multiple subagents from one prompt template, existing agent resumes, or both.\n\nUse AgentSwarm when many subagents should run the same kind of task over different inputs. The placeholder is exactly `{{item}}`. For example, with `prompt_template` set to `Review {{item}} for likely regressions.` and `items` set to `[\"src/a.ts\", \"src/b.ts\"]`, AgentSwarm launches two new subagents with those two concrete prompts. For a few differently-shaped tasks, make separate `Agent` calls in one message instead.\n\nUse `resume_agent_ids` to continue subagents that already exist from earlier work, such as ones that failed or timed out: map each agent id to the prompt for that resumed subagent (usually `continue` if no extra information is needed). You may combine `resume_agent_ids` with `items` in the same call to resume existing subagents and launch new ones. Do not duplicate resumed work in `items`.\n\nEach of these is enforced — a violation is rejected before any subagent starts: provide at least 2 `items` unless you pass `resume_agent_ids`; whenever `items` are present, `prompt_template` is required and must contain `{{item}}`; and the filled-in prompts must be distinct (two items that expand to the same prompt are rejected).\n\nUse enough subagents to keep the work focused and parallel. AgentSwarm supports up to 128 subagents, and launches are queued automatically, so it is safe to split large tasks into many clear, independent items.\n\nIf `AgentSwarm` is called, that call must be the only tool call in the response.\n";
|
|
254033
|
+
agent_swarm_default = "Launch multiple subagents from one prompt template, existing agent resumes, or both.\n\nUse AgentSwarm when many subagents should run the same kind of task over different inputs. The placeholder is exactly `{{item}}`. For example, with `prompt_template` set to `Review {{item}} for likely regressions.` and `items` set to `[\"src/a.ts\", \"src/b.ts\"]`, AgentSwarm launches two new subagents with those two concrete prompts. For a few differently-shaped tasks, make separate `Agent` calls in one message instead.\n\nUse `resume_agent_ids` to continue subagents that already exist from earlier work, such as ones that failed or timed out: map each agent id to the prompt for that resumed subagent (usually `continue` if no extra information is needed). You may combine `resume_agent_ids` with `items` in the same call to resume existing subagents and launch new ones. Do not duplicate resumed work in `items`.\n\nEach of these is enforced — a violation is rejected before any subagent starts: provide at least 2 `items` unless you pass `resume_agent_ids`; whenever `items` are present, `prompt_template` is required and must contain `{{item}}`; and the filled-in prompts must be distinct (two items that expand to the same prompt are rejected).\n\nUse enough subagents to keep the work focused and parallel. AgentSwarm supports up to 128 subagents, and launches are queued automatically, so it is safe to split large tasks into many clear, independent items.\n\nUse `response_format` when all children must return one shared bounded JSON shape. Each child is validated and repaired independently, and the final result is canonical task-order JSON. Omit it to retain the existing XML result format unchanged.\n\nIf `AgentSwarm` is called, that call must be the only tool call in the response.\n";
|
|
253369
254034
|
}));
|
|
253370
254035
|
//#endregion
|
|
253371
254036
|
//#region ../../packages/agent-core/src/tools/builtin/collaboration/agent-swarm.ts
|
|
@@ -253448,13 +254113,14 @@ function renderSwarmSummary(completed, failed, aborted = 0) {
|
|
|
253448
254113
|
function escapeXmlAttribute(value) {
|
|
253449
254114
|
return value.replaceAll("&", "&").replaceAll("\"", """).replaceAll("<", "<").replaceAll(">", ">");
|
|
253450
254115
|
}
|
|
253451
|
-
var DEFAULT_SUBAGENT_TYPE, PROMPT_TEMPLATE_PLACEHOLDER, MAX_AGENT_SWARM_SUBAGENTS, AgentSwarmToolInputSchema, AgentSwarmTool;
|
|
254116
|
+
var DEFAULT_SUBAGENT_TYPE, PROMPT_TEMPLATE_PLACEHOLDER, MAX_AGENT_SWARM_SUBAGENTS, renderStructuredSwarmResults, parseStructuredSwarmDisplay, structuredSwarmToolResult, AgentSwarmToolInputSchema, AgentSwarmTool;
|
|
253452
254117
|
var init_agent_swarm = __esmMin((() => {
|
|
253453
254118
|
init_zod$1();
|
|
253454
254119
|
init_subagent_host();
|
|
253455
254120
|
init_tool_access();
|
|
253456
254121
|
init_input_schema();
|
|
253457
254122
|
init_agent_swarm$1();
|
|
254123
|
+
({ renderStructuredSwarmResults, parseStructuredSwarmDisplay, structuredSwarmToolResult } = createRequire(import.meta.url)("./bin/structured-agent-swarm-output.cjs"));
|
|
253458
254124
|
DEFAULT_SUBAGENT_TYPE = "coder";
|
|
253459
254125
|
PROMPT_TEMPLATE_PLACEHOLDER = "{{item}}";
|
|
253460
254126
|
MAX_AGENT_SWARM_SUBAGENTS = 128;
|
|
@@ -253464,7 +254130,11 @@ var init_agent_swarm = __esmMin((() => {
|
|
|
253464
254130
|
prompt_template: string().trim().min(1).optional().describe(`Prompt template for each subagent. The ${PROMPT_TEMPLATE_PLACEHOLDER} placeholder is replaced with each item value.`),
|
|
253465
254131
|
items: array(string().trim().min(1)).max(MAX_AGENT_SWARM_SUBAGENTS).optional().describe(`Values used to fill ${PROMPT_TEMPLATE_PLACEHOLDER}. Each item launches one new subagent.`),
|
|
253466
254132
|
resume_agent_ids: record(string().trim().min(1), string().trim().min(1)).optional().describe("Map of existing subagent agent_id to the prompt used to resume that subagent. These resumed subagents are launched before new item-based subagents."),
|
|
253467
|
-
timeout_minutes: number$1().int().min(0).max(10080).optional().describe("Wall-clock interval before each same swarm agent is continued automatically. Defaults to 240 minutes. Set 0 to disable the interval for this run.")
|
|
254133
|
+
timeout_minutes: number$1().int().min(0).max(10080).optional().describe("Wall-clock interval before each same swarm agent is continued automatically. Defaults to 240 minutes. Set 0 to disable the interval for this run."),
|
|
254134
|
+
response_format: object({
|
|
254135
|
+
name: string().min(1).max(64).describe("Stable name for the shared structured result"),
|
|
254136
|
+
schema: record(string(), unknown()).describe("Restricted JSON Schema applied to every child result")
|
|
254137
|
+
}).optional().describe("Require one shared validated JSON object shape from every spawned or resumed swarm child.")
|
|
253468
254138
|
}).strict();
|
|
253469
254139
|
AgentSwarmTool = class {
|
|
253470
254140
|
subagentHost;
|
|
@@ -253492,8 +254162,17 @@ var init_agent_swarm = __esmMin((() => {
|
|
|
253492
254162
|
}
|
|
253493
254163
|
async execution(args, context) {
|
|
253494
254164
|
try {
|
|
254165
|
+
let responseFormat;
|
|
254166
|
+
if (args.response_format !== void 0) try {
|
|
254167
|
+
responseFormat = prepareStructuredResponseFormat(args.response_format, compileToolArgsValidator);
|
|
254168
|
+
} catch (error) {
|
|
254169
|
+
return {
|
|
254170
|
+
output: `Invalid response_format: ${error instanceof Error ? error.message : String(error)}`,
|
|
254171
|
+
isError: true
|
|
254172
|
+
};
|
|
254173
|
+
}
|
|
253495
254174
|
this.swarmMode.enter("tool");
|
|
253496
|
-
return
|
|
254175
|
+
return structuredSwarmToolResult(await this.runSwarm(args, context.signal, context.toolCallId, responseFormat, context.turnId));
|
|
253497
254176
|
} catch (error) {
|
|
253498
254177
|
return {
|
|
253499
254178
|
output: error instanceof Error ? error.message : String(error),
|
|
@@ -253501,7 +254180,7 @@ var init_agent_swarm = __esmMin((() => {
|
|
|
253501
254180
|
};
|
|
253502
254181
|
}
|
|
253503
254182
|
}
|
|
253504
|
-
async runSwarm(args, signal, toolCallId) {
|
|
254183
|
+
async runSwarm(args, signal, toolCallId, responseFormat, turnId) {
|
|
253505
254184
|
const profileName = normalizeOptionalString$2(args.subagent_type) ?? DEFAULT_SUBAGENT_TYPE;
|
|
253506
254185
|
const tasks = createAgentSwarmSpecs(args, (agentId) => this.subagentHost.getSwarmItem(agentId)).map((spec) => {
|
|
253507
254186
|
const descriptionName = spec.kind === "resume" ? "resume" : profileName;
|
|
@@ -253513,6 +254192,8 @@ var init_agent_swarm = __esmMin((() => {
|
|
|
253513
254192
|
description: childDescription(args.description, spec.index, descriptionName),
|
|
253514
254193
|
swarmIndex: spec.index,
|
|
253515
254194
|
runInBackground: false,
|
|
254195
|
+
responseFormat,
|
|
254196
|
+
toolScope: this.subagentHost.toolScopeForTurn(Number(turnId)),
|
|
253516
254197
|
swarmItem: spec.item,
|
|
253517
254198
|
signal,
|
|
253518
254199
|
timeout: resolveSubagentTimeoutMs({ perRunMinutes: args.timeout_minutes })
|
|
@@ -253527,10 +254208,11 @@ var init_agent_swarm = __esmMin((() => {
|
|
|
253527
254208
|
kind: "spawn"
|
|
253528
254209
|
};
|
|
253529
254210
|
});
|
|
253530
|
-
|
|
254211
|
+
const results = (await this.subagentHost.runQueued(tasks)).map(({ task, ...result }) => ({
|
|
253531
254212
|
spec: task.data,
|
|
253532
254213
|
...result
|
|
253533
|
-
}))
|
|
254214
|
+
}));
|
|
254215
|
+
return responseFormat === void 0 ? renderSwarmResults(results) : renderStructuredSwarmResults(results, responseFormat);
|
|
253534
254216
|
}
|
|
253535
254217
|
};
|
|
253536
254218
|
}));
|
|
@@ -254011,7 +254693,15 @@ function replaceOnceLiteral(content, oldString, newString) {
|
|
|
254011
254693
|
if (index === -1) return content;
|
|
254012
254694
|
return content.slice(0, index) + newString + content.slice(index + oldString.length);
|
|
254013
254695
|
}
|
|
254014
|
-
|
|
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;
|
|
254015
254705
|
var init_edit = __esmMin((() => {
|
|
254016
254706
|
init_zod$1();
|
|
254017
254707
|
init_tool_access();
|
|
@@ -254023,6 +254713,7 @@ var init_edit = __esmMin((() => {
|
|
|
254023
254713
|
init_edit$1();
|
|
254024
254714
|
init_lsp_diagnostics();
|
|
254025
254715
|
({ findDegenerateGeneratedStatementRun } = createRequire(import.meta.url)("./bin/generated-source-health.cjs"));
|
|
254716
|
+
({ writeToolTextAtomic } = createRequire(import.meta.url)("./bin/tool-file-persistence.cjs"));
|
|
254026
254717
|
EditInputSchema = object({
|
|
254027
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."),
|
|
254028
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."),
|
|
@@ -254036,14 +254727,16 @@ var init_edit = __esmMin((() => {
|
|
|
254036
254727
|
workspace;
|
|
254037
254728
|
history;
|
|
254038
254729
|
lsp;
|
|
254730
|
+
fileObservation;
|
|
254039
254731
|
name = "Edit";
|
|
254040
254732
|
description = edit_default;
|
|
254041
254733
|
parameters = toInputJsonSchema(EditInputSchema);
|
|
254042
|
-
constructor(kaos, workspace, history, lsp) {
|
|
254734
|
+
constructor(kaos, workspace, history, lsp, fileObservation) {
|
|
254043
254735
|
this.kaos = kaos;
|
|
254044
254736
|
this.workspace = workspace;
|
|
254045
254737
|
this.history = history;
|
|
254046
254738
|
this.lsp = lsp;
|
|
254739
|
+
this.fileObservation = fileObservation;
|
|
254047
254740
|
}
|
|
254048
254741
|
resolveExecution(args) {
|
|
254049
254742
|
const path = resolvePathAccessPath(args.path, {
|
|
@@ -254081,6 +254774,12 @@ var init_edit = __esmMin((() => {
|
|
|
254081
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.`
|
|
254082
254775
|
};
|
|
254083
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
|
+
};
|
|
254084
254783
|
const raw = await this.kaos.readText(safePath);
|
|
254085
254784
|
const modelView = toModelTextView(raw);
|
|
254086
254785
|
const content = modelView.text;
|
|
@@ -254103,7 +254802,7 @@ var init_edit = __esmMin((() => {
|
|
|
254103
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.`
|
|
254104
254803
|
};
|
|
254105
254804
|
const newContent = replaceOnceLiteral(content, args.old_string, args.new_string);
|
|
254106
|
-
return this.writeReplacement(args, safePath, raw, newContent, modelView.lineEndingStyle, 1);
|
|
254805
|
+
return this.writeReplacement(args, safePath, raw, newContent, modelView.lineEndingStyle, 1, authorization.version);
|
|
254107
254806
|
}
|
|
254108
254807
|
const parts = content.split(args.old_string);
|
|
254109
254808
|
const replacementCount = parts.length - 1;
|
|
@@ -254113,7 +254812,7 @@ var init_edit = __esmMin((() => {
|
|
|
254113
254812
|
`
|
|
254114
254813
|
};
|
|
254115
254814
|
const newContent = parts.join(args.new_string);
|
|
254116
|
-
return this.writeReplacement(args, safePath, raw, newContent, modelView.lineEndingStyle, replacementCount);
|
|
254815
|
+
return this.writeReplacement(args, safePath, raw, newContent, modelView.lineEndingStyle, replacementCount, authorization.version);
|
|
254117
254816
|
} catch (error) {
|
|
254118
254817
|
if (error?.code === "EISDIR") return {
|
|
254119
254818
|
isError: true,
|
|
@@ -254125,7 +254824,7 @@ var init_edit = __esmMin((() => {
|
|
|
254125
254824
|
};
|
|
254126
254825
|
}
|
|
254127
254826
|
}
|
|
254128
|
-
async writeReplacement(args, safePath, currentContent, nextContent, lineEndingStyle, replacementCount) {
|
|
254827
|
+
async writeReplacement(args, safePath, currentContent, nextContent, lineEndingStyle, replacementCount, observedVersion) {
|
|
254129
254828
|
const materialized = materializeModelText(nextContent, lineEndingStyle);
|
|
254130
254829
|
const lineLimit = evaluateSourceFileLineLimit(safePath, materialized, {
|
|
254131
254830
|
currentContent,
|
|
@@ -254136,7 +254835,14 @@ var init_edit = __esmMin((() => {
|
|
|
254136
254835
|
isError: true,
|
|
254137
254836
|
output: lineLimit.error
|
|
254138
254837
|
};
|
|
254139
|
-
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));
|
|
254140
254846
|
const occurrence = replacementCount === 1 ? "occurrence" : "occurrences";
|
|
254141
254847
|
const notice = lineLimit.notice === void 0 ? "" : ` ${lineLimit.notice}`;
|
|
254142
254848
|
return appendLspDiagnostics({ output: `Replaced ${String(replacementCount)} ${occurrence} in ${args.path}.` + notice }, safePath, this.lsp);
|
|
@@ -259646,7 +260352,7 @@ function renderLine(entry, lineEndingStyle) {
|
|
|
259646
260352
|
function renderedLineBytes(renderedLine, isFirst) {
|
|
259647
260353
|
return (isFirst ? 0 : 1) + Buffer.byteLength(renderedLine, "utf8");
|
|
259648
260354
|
}
|
|
259649
|
-
function renderEntries(entries, lineEndingStyle) {
|
|
260355
|
+
function renderEntries(entries, lineEndingStyle, maxBytes) {
|
|
259650
260356
|
const renderedLines = [];
|
|
259651
260357
|
const truncatedLineNumbers = [];
|
|
259652
260358
|
let bytes = 0;
|
|
@@ -259654,14 +260360,14 @@ function renderEntries(entries, lineEndingStyle) {
|
|
|
259654
260360
|
for (const entry of entries) {
|
|
259655
260361
|
const rendered = renderLine(entry, lineEndingStyle);
|
|
259656
260362
|
const lineBytes = renderedLineBytes(rendered.line, renderedLines.length === 0);
|
|
259657
|
-
if (renderedLines.length > 0 && bytes + lineBytes >
|
|
260363
|
+
if (renderedLines.length > 0 && bytes + lineBytes > maxBytes) {
|
|
259658
260364
|
maxBytesReached = true;
|
|
259659
260365
|
break;
|
|
259660
260366
|
}
|
|
259661
260367
|
if (rendered.wasTruncated) truncatedLineNumbers.push(entry.lineNo);
|
|
259662
260368
|
renderedLines.push(rendered.line);
|
|
259663
260369
|
bytes += lineBytes;
|
|
259664
|
-
if (bytes >=
|
|
260370
|
+
if (bytes >= maxBytes) {
|
|
259665
260371
|
maxBytesReached = true;
|
|
259666
260372
|
break;
|
|
259667
260373
|
}
|
|
@@ -259692,7 +260398,7 @@ function containsNulByte(text) {
|
|
|
259692
260398
|
function notReadableFileOutput(path) {
|
|
259693
260399
|
return `"${path}" is not readable as UTF-8 text. If it is an image or video, use ReadMediaFile. For other binary formats, use Bash or an MCP tool if available.`;
|
|
259694
260400
|
}
|
|
259695
|
-
var MAX_LINES$1, MAX_LINE_LENGTH,
|
|
260401
|
+
var MAX_LINES$1, MAX_LINE_LENGTH, S_IFMT$1, S_IFREG, PositiveLineOffsetSchema, TailLineOffsetSchema, ReadInputSchema, ReadBatchInputSchema, READ_DESCRIPTION, READ_BATCH_DESCRIPTION, ReadTool, ReadBatchTool, readContinuationNotice, readModelVisibleBytes, readModelVisibleLines, MAX_READ_BATCH_REQUESTS, readBatchAllFailed, renderReadBatchOutput;
|
|
259696
260402
|
var init_read = __esmMin((() => {
|
|
259697
260403
|
init_zod$1();
|
|
259698
260404
|
init_tool_access();
|
|
@@ -259703,46 +260409,49 @@ var init_read = __esmMin((() => {
|
|
|
259703
260409
|
init_rule_match();
|
|
259704
260410
|
init_line_endings();
|
|
259705
260411
|
init_read$1();
|
|
259706
|
-
({ readContinuationNotice,
|
|
260412
|
+
({ readContinuationNotice, readModelVisibleBytes, readModelVisibleLines } = createRequire(import.meta.url)("./bin/read-continuation-policy.cjs"));
|
|
259707
260413
|
({ MAX_READ_BATCH_REQUESTS, readBatchAllFailed, renderReadBatchOutput } = createRequire(import.meta.url)("./bin/read-batch-policy.cjs"));
|
|
259708
260414
|
MAX_LINES$1 = 1e3;
|
|
259709
260415
|
MAX_LINE_LENGTH = 2e3;
|
|
259710
|
-
MAX_BYTES = READ_MODEL_VISIBLE_BYTES;
|
|
259711
260416
|
S_IFMT$1 = 61440;
|
|
259712
260417
|
S_IFREG = 32768;
|
|
259713
260418
|
PositiveLineOffsetSchema = number$1().int().min(1);
|
|
259714
|
-
TailLineOffsetSchema = number$1().int().
|
|
260419
|
+
TailLineOffsetSchema = number$1().int().max(-1);
|
|
259715
260420
|
ReadInputSchema = object({
|
|
259716
260421
|
path: string().describe("Path to a text file. Relative paths resolve against the working directory; a path outside the working directory must be absolute. Directories are not supported; use `ls` via Bash for a known directory, or Glob for pattern search."),
|
|
259717
|
-
line_offset: union([PositiveLineOffsetSchema, TailLineOffsetSchema]).optional().describe(
|
|
259718
|
-
n_lines: number$1().int().positive().optional().describe(
|
|
260422
|
+
line_offset: union([PositiveLineOffsetSchema, TailLineOffsetSchema]).optional().describe("The line number to start reading from. Omit to start at line 1. Negative values read backward from the end within the active context budget."),
|
|
260423
|
+
n_lines: number$1().int().positive().optional().describe("The number of lines for an explicit targeted range. Omit to read the complete file whenever the active context has room.")
|
|
259719
260424
|
});
|
|
259720
260425
|
ReadBatchInputSchema = object({ requests: array(ReadInputSchema).min(2).max(MAX_READ_BATCH_REQUESTS).describe(`Two to ${String(MAX_READ_BATCH_REQUESTS)} independent known text-file reads. Do not batch a read whose path or range depends on an earlier result.`) });
|
|
259721
260426
|
object({
|
|
259722
260427
|
content: string(),
|
|
259723
260428
|
lineCount: number$1().int().nonnegative()
|
|
259724
260429
|
});
|
|
260430
|
+
read_default = "Read a known UTF-8 text file. Invalid paths error; directories are unsupported. Relative paths use the working directory; outside paths must be absolute. Use Glob for unknown names, Grep for content, and ReadMediaFile for media.\n\nOmit `line_offset` and `n_lines` to read the complete file whenever the active context has room. Explicit ranges remain available for targeted inspection. Under real context pressure, a result is capped and names the exact next `line_offset`; continue from that line without gaps. Individual lines beyond {{ MAX_LINE_LENGTH }} characters are truncated. Negative `line_offset` reads from the end, up to {{ MAX_LINES }} lines. Issue independent Read calls together in one response when several files or ranges may be useful. Prefer ReadBatch when two or more independent paths or ranges are already known.\n\nSensitive files such as `.env` and credential stores are refused; templates and public keys remain readable. Only UTF-8 text without NUL bytes is accepted; use Bash or an MCP tool for other binaries.\n\nOutput is `<line-number>\\t<content>` per line. The trailing `<system>...</system>` block is status, not file content. Pure CRLF appears as LF and is preserved by Edit. Mixed or lone carriage returns appear as `\\r` and require exact `Edit.old_string` escapes.";
|
|
259725
260431
|
READ_DESCRIPTION = renderPrompt(read_default, {
|
|
259726
260432
|
MAX_LINES: MAX_LINES$1,
|
|
259727
|
-
MAX_BYTES_KB: MAX_BYTES / 1024,
|
|
259728
|
-
MAX_LINE_LENGTH
|
|
259729
|
-
});
|
|
259730
|
-
read_default = "Read a known UTF-8 text file. Invalid paths error; directories are unsupported. Relative paths use the working directory; outside paths must be absolute. Use Glob for unknown names, Grep for content, and ReadMediaFile for media.\n\nEach call returns at most {{ MAX_LINES }} lines or {{ MAX_BYTES_KB }} KB and truncates lines beyond {{ MAX_LINE_LENGTH }} characters. Page large files with 1-based `line_offset` and `n_lines`; omit `n_lines` for the cap. Negative `line_offset` reads from the end, up to {{ MAX_LINES }} lines. A capped result names the exact next `line_offset`. Issue independent Read calls together in one response when several files or ranges may be useful. Prefer ReadBatch when two or more independent paths or ranges are already known.\n\nSensitive files such as `.env` and credential stores are refused; templates and public keys remain readable. Only UTF-8 text without NUL bytes is accepted; use Bash or an MCP tool for other binaries.\n\nOutput is `<line-number>\\t<content>` per line. The trailing `<system>...</system>` block is status, not file content. Pure CRLF appears as LF and is preserved by Edit. Mixed or lone carriage returns appear as `\\r` and require exact `Edit.old_string` escapes.";
|
|
259731
|
-
READ_DESCRIPTION = renderPrompt(read_default, {
|
|
259732
|
-
MAX_LINES: MAX_LINES$1,
|
|
259733
|
-
MAX_BYTES_KB: MAX_BYTES / 1024,
|
|
259734
260433
|
MAX_LINE_LENGTH
|
|
259735
260434
|
});
|
|
259736
260435
|
READ_BATCH_DESCRIPTION = `Read ${String(MAX_READ_BATCH_REQUESTS)} or fewer independent known UTF-8 text files or ranges concurrently in one tool call. Use this instead of serial Read calls only when every path and range is already known and no later request depends on an earlier result. Each request uses the same path, sensitive-file, UTF-8, line, and byte rules as Read. Results remain in request order and identify partial failures individually.`;
|
|
259737
260436
|
ReadTool = class {
|
|
259738
260437
|
kaos;
|
|
259739
260438
|
workspace;
|
|
260439
|
+
contextWindowState;
|
|
260440
|
+
fileObservation;
|
|
259740
260441
|
name = "Read";
|
|
259741
260442
|
description = READ_DESCRIPTION;
|
|
259742
260443
|
parameters = toInputJsonSchema(ReadInputSchema);
|
|
259743
|
-
constructor(kaos, workspace) {
|
|
260444
|
+
constructor(kaos, workspace, contextWindowState = () => ({}), fileObservation) {
|
|
259744
260445
|
this.kaos = kaos;
|
|
259745
260446
|
this.workspace = workspace;
|
|
260447
|
+
this.contextWindowState = contextWindowState;
|
|
260448
|
+
this.fileObservation = fileObservation;
|
|
260449
|
+
}
|
|
260450
|
+
modelVisibleBytes() {
|
|
260451
|
+
return readModelVisibleBytes(this.contextWindowState());
|
|
260452
|
+
}
|
|
260453
|
+
modelVisibleLines() {
|
|
260454
|
+
return readModelVisibleLines(this.contextWindowState());
|
|
259746
260455
|
}
|
|
259747
260456
|
resolveExecution(args) {
|
|
259748
260457
|
const path = resolvePathAccessPath(args.path, {
|
|
@@ -259773,10 +260482,13 @@ var init_read = __esmMin((() => {
|
|
|
259773
260482
|
try {
|
|
259774
260483
|
stat = await this.kaos.stat(safePath);
|
|
259775
260484
|
} catch (error) {
|
|
259776
|
-
if (isFileNotFoundError(error))
|
|
259777
|
-
|
|
259778
|
-
|
|
259779
|
-
|
|
260485
|
+
if (isFileNotFoundError(error)) {
|
|
260486
|
+
this.fileObservation.recordAbsent(safePath);
|
|
260487
|
+
return {
|
|
260488
|
+
isError: true,
|
|
260489
|
+
output: `"${args.path}" does not exist.`
|
|
260490
|
+
};
|
|
260491
|
+
}
|
|
259780
260492
|
throw error;
|
|
259781
260493
|
}
|
|
259782
260494
|
if (!isRegularFileMode(stat.stMode)) return {
|
|
@@ -259793,10 +260505,21 @@ var init_read = __esmMin((() => {
|
|
|
259793
260505
|
output: notReadableFileOutput(args.path)
|
|
259794
260506
|
};
|
|
259795
260507
|
const lineOffset = args.line_offset ?? 1;
|
|
259796
|
-
const
|
|
259797
|
-
const
|
|
259798
|
-
|
|
259799
|
-
|
|
260508
|
+
const maxLines = this.modelVisibleLines();
|
|
260509
|
+
const requestedLines = args.n_lines ?? maxLines;
|
|
260510
|
+
const effectiveLimit = Math.min(requestedLines, maxLines);
|
|
260511
|
+
const maxBytes = this.modelVisibleBytes();
|
|
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;
|
|
259800
260523
|
} catch (error) {
|
|
259801
260524
|
if (isTextDecodeError(error)) return {
|
|
259802
260525
|
isError: true,
|
|
@@ -259808,7 +260531,7 @@ var init_read = __esmMin((() => {
|
|
|
259808
260531
|
};
|
|
259809
260532
|
}
|
|
259810
260533
|
}
|
|
259811
|
-
async readForward(safePath, displayPath, lineOffset, effectiveLimit, requestedLines) {
|
|
260534
|
+
async readForward(safePath, displayPath, lineOffset, effectiveLimit, requestedLines, maxBytes, maxLines) {
|
|
259812
260535
|
const rangeKaos = this.kaos;
|
|
259813
260536
|
if (rangeKaos.scanTextFile !== void 0 && rangeKaos.readLineRange !== void 0) {
|
|
259814
260537
|
const scan = await rangeKaos.scanTextFile(safePath);
|
|
@@ -259817,31 +260540,47 @@ var init_read = __esmMin((() => {
|
|
|
259817
260540
|
output: notReadableFileOutput(displayPath)
|
|
259818
260541
|
};
|
|
259819
260542
|
const selectedEntries = [];
|
|
260543
|
+
const lineEndingStyle = lineEndingStyleFromFlags(scan.lineEndingFlags);
|
|
260544
|
+
let selectedBytes = 0;
|
|
260545
|
+
let maxBytesReached = false;
|
|
259820
260546
|
let lineNo = lineOffset;
|
|
259821
260547
|
for await (const rawLine of rangeKaos.readLineRange(safePath, {
|
|
259822
260548
|
startLine: lineOffset,
|
|
259823
260549
|
maxLines: effectiveLimit,
|
|
259824
260550
|
errors: "strict"
|
|
259825
260551
|
})) {
|
|
259826
|
-
|
|
260552
|
+
const entry = {
|
|
259827
260553
|
lineNo,
|
|
259828
260554
|
rawContent: stripTrailingLf(rawLine)
|
|
259829
|
-
}
|
|
260555
|
+
};
|
|
260556
|
+
const rendered = renderLine(entry, lineEndingStyle);
|
|
260557
|
+
const lineBytes = renderedLineBytes(rendered.line, selectedEntries.length === 0);
|
|
260558
|
+
if (selectedEntries.length > 0 && selectedBytes + lineBytes > maxBytes) {
|
|
260559
|
+
maxBytesReached = true;
|
|
260560
|
+
break;
|
|
260561
|
+
}
|
|
260562
|
+
selectedEntries.push(entry);
|
|
260563
|
+
selectedBytes += lineBytes;
|
|
259830
260564
|
lineNo += 1;
|
|
260565
|
+
if (selectedBytes >= maxBytes) {
|
|
260566
|
+
maxBytesReached = true;
|
|
260567
|
+
break;
|
|
260568
|
+
}
|
|
259831
260569
|
}
|
|
259832
|
-
const
|
|
259833
|
-
const rendered = renderEntries(selectedEntries, lineEndingStyle);
|
|
260570
|
+
const rendered = renderEntries(selectedEntries, lineEndingStyle, maxBytes);
|
|
259834
260571
|
return this.finishReadResult({
|
|
259835
260572
|
renderedLines: rendered.renderedLines,
|
|
259836
260573
|
truncatedLineNumbers: rendered.truncatedLineNumbers,
|
|
259837
|
-
maxLinesReached: effectiveLimit >=
|
|
259838
|
-
maxBytesReached: rendered.maxBytesReached,
|
|
260574
|
+
maxLinesReached: effectiveLimit >= maxLines && lineOffset + maxLines <= scan.totalLines,
|
|
260575
|
+
maxBytesReached: maxBytesReached || rendered.maxBytesReached,
|
|
259839
260576
|
lineEndingStyle,
|
|
259840
260577
|
startLine: selectedEntries.length > 0 ? lineOffset : 0,
|
|
259841
260578
|
totalLines: scan.totalLines,
|
|
259842
260579
|
requestedLines,
|
|
259843
260580
|
lineOffset,
|
|
259844
|
-
effectiveLimit
|
|
260581
|
+
effectiveLimit,
|
|
260582
|
+
maxBytes,
|
|
260583
|
+
maxLines
|
|
259845
260584
|
});
|
|
259846
260585
|
}
|
|
259847
260586
|
const selectedEntries = [];
|
|
@@ -259852,7 +260591,10 @@ var init_read = __esmMin((() => {
|
|
|
259852
260591
|
};
|
|
259853
260592
|
let currentLineNo = 0;
|
|
259854
260593
|
let maxLinesReached = false;
|
|
260594
|
+
let maxBytesReached = false;
|
|
260595
|
+
let selectedBytes = 0;
|
|
259855
260596
|
let collectionClosed = false;
|
|
260597
|
+
let closedByLines = false;
|
|
259856
260598
|
for await (const rawLine of this.kaos.readLines(safePath, { errors: "strict" })) {
|
|
259857
260599
|
if (containsNulByte(rawLine)) return {
|
|
259858
260600
|
isError: true,
|
|
@@ -259861,38 +260603,56 @@ var init_read = __esmMin((() => {
|
|
|
259861
260603
|
currentLineNo += 1;
|
|
259862
260604
|
updateLineEndingFlags(flags, rawLine);
|
|
259863
260605
|
if (collectionClosed) {
|
|
259864
|
-
if (effectiveLimit >=
|
|
260606
|
+
if (closedByLines && effectiveLimit >= maxLines && currentLineNo >= lineOffset) maxLinesReached = true;
|
|
259865
260607
|
continue;
|
|
259866
260608
|
}
|
|
259867
260609
|
if (currentLineNo < lineOffset) continue;
|
|
259868
260610
|
if (selectedEntries.length >= effectiveLimit) {
|
|
259869
|
-
if (effectiveLimit >=
|
|
260611
|
+
if (effectiveLimit >= maxLines) maxLinesReached = true;
|
|
259870
260612
|
collectionClosed = true;
|
|
260613
|
+
closedByLines = true;
|
|
259871
260614
|
continue;
|
|
259872
260615
|
}
|
|
259873
|
-
|
|
260616
|
+
const entry = {
|
|
259874
260617
|
lineNo: currentLineNo,
|
|
259875
260618
|
rawContent: stripTrailingLf(rawLine)
|
|
259876
|
-
}
|
|
259877
|
-
|
|
260619
|
+
};
|
|
260620
|
+
const conservative = renderLine(entry, "mixed");
|
|
260621
|
+
const lineBytes = renderedLineBytes(conservative.line, selectedEntries.length === 0);
|
|
260622
|
+
if (selectedEntries.length > 0 && selectedBytes + lineBytes > maxBytes) {
|
|
260623
|
+
maxBytesReached = true;
|
|
260624
|
+
collectionClosed = true;
|
|
260625
|
+
continue;
|
|
260626
|
+
}
|
|
260627
|
+
selectedEntries.push(entry);
|
|
260628
|
+
selectedBytes += lineBytes;
|
|
260629
|
+
if (selectedEntries.length >= effectiveLimit) {
|
|
260630
|
+
collectionClosed = true;
|
|
260631
|
+
closedByLines = true;
|
|
260632
|
+
} else if (selectedBytes >= maxBytes) {
|
|
260633
|
+
maxBytesReached = true;
|
|
260634
|
+
collectionClosed = true;
|
|
260635
|
+
}
|
|
259878
260636
|
}
|
|
259879
260637
|
const lineEndingStyle = lineEndingStyleFromFlags(flags);
|
|
259880
|
-
const rendered = renderEntries(selectedEntries, lineEndingStyle);
|
|
260638
|
+
const rendered = renderEntries(selectedEntries, lineEndingStyle, maxBytes);
|
|
259881
260639
|
return this.finishReadResult({
|
|
259882
260640
|
renderedLines: rendered.renderedLines,
|
|
259883
260641
|
truncatedLineNumbers: rendered.truncatedLineNumbers,
|
|
259884
260642
|
maxLinesReached,
|
|
259885
|
-
maxBytesReached: rendered.maxBytesReached,
|
|
260643
|
+
maxBytesReached: maxBytesReached || rendered.maxBytesReached,
|
|
259886
260644
|
lineEndingStyle,
|
|
259887
260645
|
startLine: selectedEntries.length > 0 ? lineOffset : 0,
|
|
259888
260646
|
totalLines: currentLineNo,
|
|
259889
260647
|
requestedLines,
|
|
259890
260648
|
lineOffset,
|
|
259891
|
-
effectiveLimit
|
|
260649
|
+
effectiveLimit,
|
|
260650
|
+
maxBytes,
|
|
260651
|
+
maxLines
|
|
259892
260652
|
});
|
|
259893
260653
|
}
|
|
259894
|
-
async readTail(safePath, displayPath, lineOffset, effectiveLimit, requestedLines) {
|
|
259895
|
-
const tailCount = Math.abs(lineOffset);
|
|
260654
|
+
async readTail(safePath, displayPath, lineOffset, effectiveLimit, requestedLines, maxBytes, maxLines) {
|
|
260655
|
+
const tailCount = Math.min(Math.abs(lineOffset), maxLines);
|
|
259896
260656
|
const rangeKaos = this.kaos;
|
|
259897
260657
|
if (rangeKaos.scanTextFile !== void 0 && rangeKaos.readTailLines !== void 0) {
|
|
259898
260658
|
const scan = await rangeKaos.scanTextFile(safePath);
|
|
@@ -259915,7 +260675,9 @@ var init_read = __esmMin((() => {
|
|
|
259915
260675
|
lineEndingFlags: scan.lineEndingFlags,
|
|
259916
260676
|
effectiveLimit,
|
|
259917
260677
|
totalLines: scan.totalLines,
|
|
259918
|
-
requestedLines
|
|
260678
|
+
requestedLines,
|
|
260679
|
+
maxBytes,
|
|
260680
|
+
maxLines
|
|
259919
260681
|
});
|
|
259920
260682
|
}
|
|
259921
260683
|
const entries = [];
|
|
@@ -259943,7 +260705,9 @@ var init_read = __esmMin((() => {
|
|
|
259943
260705
|
lineEndingFlags: flags,
|
|
259944
260706
|
effectiveLimit,
|
|
259945
260707
|
totalLines: currentLineNo,
|
|
259946
|
-
requestedLines
|
|
260708
|
+
requestedLines,
|
|
260709
|
+
maxBytes,
|
|
260710
|
+
maxLines
|
|
259947
260711
|
});
|
|
259948
260712
|
}
|
|
259949
260713
|
finishTailEntries(input) {
|
|
@@ -259957,7 +260721,7 @@ var init_read = __esmMin((() => {
|
|
|
259957
260721
|
let totalBytes = 0;
|
|
259958
260722
|
for (const [index, candidate] of renderedCandidates.entries()) totalBytes += renderedLineBytes(candidate.rendered.line, index === 0);
|
|
259959
260723
|
let maxBytesReached = false;
|
|
259960
|
-
if (totalBytes >
|
|
260724
|
+
if (totalBytes > input.maxBytes) {
|
|
259961
260725
|
maxBytesReached = true;
|
|
259962
260726
|
const kept = [];
|
|
259963
260727
|
let bytes = 0;
|
|
@@ -259965,7 +260729,7 @@ var init_read = __esmMin((() => {
|
|
|
259965
260729
|
const candidate = renderedCandidates[i];
|
|
259966
260730
|
if (candidate === void 0) continue;
|
|
259967
260731
|
const lineBytes = renderedLineBytes(candidate.rendered.line, kept.length === 0);
|
|
259968
|
-
if (bytes + lineBytes >
|
|
260732
|
+
if (bytes + lineBytes > input.maxBytes) break;
|
|
259969
260733
|
kept.unshift(candidate);
|
|
259970
260734
|
bytes += lineBytes;
|
|
259971
260735
|
}
|
|
@@ -259985,7 +260749,9 @@ var init_read = __esmMin((() => {
|
|
|
259985
260749
|
lineEndingStyle,
|
|
259986
260750
|
startLine: renderedCandidates[0]?.entry.lineNo ?? 0,
|
|
259987
260751
|
totalLines: input.totalLines,
|
|
259988
|
-
requestedLines: input.requestedLines
|
|
260752
|
+
requestedLines: input.requestedLines,
|
|
260753
|
+
maxBytes: input.maxBytes,
|
|
260754
|
+
maxLines: input.maxLines
|
|
259989
260755
|
});
|
|
259990
260756
|
}
|
|
259991
260757
|
finishReadResult(input) {
|
|
@@ -260000,8 +260766,8 @@ var init_read = __esmMin((() => {
|
|
|
260000
260766
|
const lineCount = input.renderedLines.length;
|
|
260001
260767
|
const parts = lineCount > 0 ? [`${String(lineCount)} ${lineCount === 1 ? "line" : "lines"} read from file starting from line ${String(input.startLine)}.`] : ["No lines read from file."];
|
|
260002
260768
|
parts.push(`Total lines in file: ${String(input.totalLines)}.`);
|
|
260003
|
-
if (input.maxLinesReached) parts.push(`Max ${String(
|
|
260004
|
-
else if (input.maxBytesReached) parts.push(`Max ${String(
|
|
260769
|
+
if (input.maxLinesReached) parts.push(`Max ${String(input.maxLines)} lines reached.`);
|
|
260770
|
+
else if (input.maxBytesReached) parts.push(`Max ${String(input.maxBytes)} bytes reached.`);
|
|
260005
260771
|
else if (lineCount < input.requestedLines) parts.push("End of file reached.");
|
|
260006
260772
|
const continuationNotice = readContinuationNotice({
|
|
260007
260773
|
...input,
|
|
@@ -260020,10 +260786,10 @@ var init_read = __esmMin((() => {
|
|
|
260020
260786
|
name = "ReadBatch";
|
|
260021
260787
|
description = READ_BATCH_DESCRIPTION;
|
|
260022
260788
|
parameters = toInputJsonSchema(ReadBatchInputSchema);
|
|
260023
|
-
constructor(kaos, workspace) {
|
|
260789
|
+
constructor(kaos, workspace, contextWindowState, fileObservation) {
|
|
260024
260790
|
this.kaos = kaos;
|
|
260025
260791
|
this.workspace = workspace;
|
|
260026
|
-
this.reader = new ReadTool(kaos, workspace);
|
|
260792
|
+
this.reader = new ReadTool(kaos, workspace, contextWindowState, fileObservation);
|
|
260027
260793
|
}
|
|
260028
260794
|
resolveExecution(args) {
|
|
260029
260795
|
const items = args.requests.map((request) => ({
|
|
@@ -260448,7 +261214,7 @@ function countCompletedLines(content) {
|
|
|
260448
261214
|
for (const character of content) if (character === "\n") count += 1;
|
|
260449
261215
|
return count;
|
|
260450
261216
|
}
|
|
260451
|
-
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;
|
|
260452
261218
|
var init_write = __esmMin((() => {
|
|
260453
261219
|
init_dist$6();
|
|
260454
261220
|
init_zod$1();
|
|
@@ -260462,6 +261228,7 @@ var init_write = __esmMin((() => {
|
|
|
260462
261228
|
init_lsp_diagnostics();
|
|
260463
261229
|
({ resolveWriteContinuationContract, resolvePlainWriteContract, splitNativeWriteBytes } = createRequire(import.meta.url)("./bin/write-continuation-policy.cjs"));
|
|
260464
261230
|
({ writeNativeLargeContentOnDisk } = createRequire(import.meta.url)("./bin/native-large-file-io.cjs"));
|
|
261231
|
+
({ writeToolTextAtomic } = createRequire(import.meta.url)("./bin/tool-file-persistence.cjs"));
|
|
260465
261232
|
S_IFMT = 61440;
|
|
260466
261233
|
S_IFDIR = 16384;
|
|
260467
261234
|
DEFAULT_CONTINUATION_CHUNK_BYTES = 2048;
|
|
@@ -260491,17 +261258,19 @@ bytesWritten: number$1().int().nonnegative() });
|
|
|
260491
261258
|
workspace;
|
|
260492
261259
|
history;
|
|
260493
261260
|
lsp;
|
|
261261
|
+
fileObservation;
|
|
260494
261262
|
maxContinuationChunkBytes;
|
|
260495
261263
|
name = "Write";
|
|
260496
261264
|
description = write_default;
|
|
260497
261265
|
parameters = toInputJsonSchema(WriteInputSchema);
|
|
260498
261266
|
pendingContinuations = /* @__PURE__ */ new Map();
|
|
260499
261267
|
continuationRequiredPaths = /* @__PURE__ */ new Set();
|
|
260500
|
-
constructor(kaos, workspace, history, lsp, maxContinuationChunkBytes = resolveWriteContinuationChunkBytes()) {
|
|
261268
|
+
constructor(kaos, workspace, history, lsp, fileObservation, maxContinuationChunkBytes = resolveWriteContinuationChunkBytes()) {
|
|
260501
261269
|
this.kaos = kaos;
|
|
260502
261270
|
this.workspace = workspace;
|
|
260503
261271
|
this.history = history;
|
|
260504
261272
|
this.lsp = lsp;
|
|
261273
|
+
this.fileObservation = fileObservation;
|
|
260505
261274
|
this.maxContinuationChunkBytes = maxContinuationChunkBytes;
|
|
260506
261275
|
}
|
|
260507
261276
|
resolveExecution(args) {
|
|
@@ -260670,6 +261439,12 @@ bytesWritten: number$1().int().nonnegative() });
|
|
|
260670
261439
|
isError: true,
|
|
260671
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.`
|
|
260672
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
|
+
};
|
|
260673
261448
|
let currentContent;
|
|
260674
261449
|
if (isSourceFilePath(safePath)) try {
|
|
260675
261450
|
currentContent = await this.kaos.readText(safePath);
|
|
@@ -260697,9 +261472,16 @@ bytesWritten: number$1().int().nonnegative() });
|
|
|
260697
261472
|
continuationRequired: this.continuationRequiredPaths.has(safePath)
|
|
260698
261473
|
});
|
|
260699
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
|
+
};
|
|
260700
261481
|
const chunks = splitNativeWriteBytes(args.content, this.maxContinuationChunkBytes);
|
|
260701
261482
|
const nativeResult = await this.writeNativeLargeContent(safePath, chunks, mode);
|
|
260702
261483
|
if (nativeResult.isError === true) return nativeResult;
|
|
261484
|
+
this.fileObservation.recordPresent(safePath, await this.kaos.stat(safePath));
|
|
260703
261485
|
this.continuationRequiredPaths.delete(safePath);
|
|
260704
261486
|
const notice = lineLimit.notice === void 0 ? "" : ` ${lineLimit.notice}`;
|
|
260705
261487
|
return appendLspDiagnostics({
|
|
@@ -260712,8 +261494,15 @@ bytesWritten: number$1().int().nonnegative() });
|
|
|
260712
261494
|
output: parentError
|
|
260713
261495
|
};
|
|
260714
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
|
+
};
|
|
260715
261503
|
if (mode === "append") await this.kaos.writeText(safePath, args.content, { mode: "a" });
|
|
260716
|
-
else await
|
|
261504
|
+
else await writeToolTextAtomic(safePath, args.content);
|
|
261505
|
+
this.fileObservation.recordPresent(safePath, await this.kaos.stat(safePath));
|
|
260717
261506
|
const bytesWritten = Buffer.byteLength(args.content, "utf8");
|
|
260718
261507
|
const notice = lineLimit.notice === void 0 ? "" : ` ${lineLimit.notice}`;
|
|
260719
261508
|
return appendLspDiagnostics({ output: `${mode === "append" ? "Appended" : "Wrote"} ${String(bytesWritten)} bytes to ${args.path}.${notice}` }, safePath, this.lsp);
|
|
@@ -261262,7 +262051,8 @@ var init_tool_dedup = __esmMin((() => {
|
|
|
261262
262051
|
//#region ../../packages/agent-core/src/agent/turn/tool-result-budget.ts
|
|
261263
262052
|
async function budgetToolResultForModel(options) {
|
|
261264
262053
|
const text = persistableToolResultText(options.result.output);
|
|
261265
|
-
|
|
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;
|
|
261266
262056
|
const readSourcePath = reusableReadSourcePath(options);
|
|
261267
262057
|
if (readSourcePath !== void 0) return referenceReadSourceForModel(options, text, readSourcePath);
|
|
261268
262058
|
return persistToolResultForModel(options, text);
|
|
@@ -261418,7 +262208,7 @@ function renderHistoricalToolResultReference(toolName, toolCallId, text, outputP
|
|
|
261418
262208
|
function safeToolResultFileStem(toolName, toolCallId) {
|
|
261419
262209
|
return `${toolName}-${toolCallId}`.replace(/[^a-zA-Z0-9._-]+/g, "_").replace(/^_+|_+$/g, "").slice(0, 80) || "tool-result";
|
|
261420
262210
|
}
|
|
261421
|
-
var TOOL_RESULT_MAX_CHARS, TOOL_RESULT_PREVIEW_CHARS, TOOL_RESULT_HISTORICAL_PREVIEW_CHARS, TOOL_RESULT_RECOVERY_PAGE_LINES, TOOL_RESULT_OFFLOAD_MARKER, TOOL_RESULT_HISTORICAL_KEEP_RECENT_MESSAGES, shouldKeepFreshToolResult, shouldOffloadToolResult, createToolResultPreview, compactPersistedToolResultReference, compactHistoricalSuccessfulToolResults, currentTurnReadToolResultIds, currentUserTurnStartIndex, dedupeRepeatedSuccessfulToolResults, readContinuationLineOffset, selectToolResultBatchOffloads, selectHistoricalToolResultOffloads, buildToolResultOffloadTelemetry;
|
|
262211
|
+
var TOOL_RESULT_MAX_CHARS, TOOL_RESULT_PREVIEW_CHARS, TOOL_RESULT_HISTORICAL_PREVIEW_CHARS, TOOL_RESULT_RECOVERY_PAGE_LINES, TOOL_RESULT_OFFLOAD_MARKER, TOOL_RESULT_HISTORICAL_KEEP_RECENT_MESSAGES, shouldKeepFreshToolResult, shouldOffloadToolResult, createToolResultPreview, compactPersistedToolResultReference, compactHistoricalSuccessfulToolResults, currentTurnReadToolResultIds, currentUserTurnStartIndex, dedupeRepeatedSuccessfulToolResults, hasToolResultOffloadPressure, readContinuationLineOffset, selectToolResultBatchOffloads, selectHistoricalToolResultOffloads, buildToolResultOffloadTelemetry;
|
|
261422
262212
|
var init_tool_result_budget = __esmMin((() => {
|
|
261423
262213
|
init_dist$6();
|
|
261424
262214
|
const toolResultOffloadPolicy = createRequire(import.meta.url)("./bin/tool-result-offload-policy.cjs");
|
|
@@ -261438,6 +262228,7 @@ var init_tool_result_budget = __esmMin((() => {
|
|
|
261438
262228
|
currentUserTurnStartIndex = toolResultOffloadPolicy.currentUserTurnStartIndex;
|
|
261439
262229
|
dedupeRepeatedSuccessfulToolResults = toolResultOffloadPolicy.dedupeRepeatedSuccessfulToolResults;
|
|
261440
262230
|
freshToolResultIds = toolResultOffloadPolicy.freshToolResultIds;
|
|
262231
|
+
hasToolResultOffloadPressure = toolResultOffloadPolicy.hasToolResultOffloadPressure;
|
|
261441
262232
|
readContinuationLineOffset = toolResultOffloadPolicy.readContinuationLineOffset;
|
|
261442
262233
|
selectToolResultBatchOffloads = toolResultOffloadPolicy.selectToolResultBatchOffloads;
|
|
261443
262234
|
selectHistoricalToolResultOffloads = toolResultOffloadPolicy.selectHistoricalToolResultOffloads;
|
|
@@ -261452,6 +262243,7 @@ var ToolResultBatchOffload = class {
|
|
|
261452
262243
|
}
|
|
261453
262244
|
async detect() {
|
|
261454
262245
|
const history = this.agent.context.history;
|
|
262246
|
+
if (!toolResultOffloadPressureForAgent(this.agent)) return 0;
|
|
261455
262247
|
const tailIds = freshToolResultIds(history);
|
|
261456
262248
|
const pinnedReadIds = currentTurnReadToolResultIds(history);
|
|
261457
262249
|
const recentStart = Math.max(0, history.length - TOOL_RESULT_HISTORICAL_KEEP_RECENT_MESSAGES);
|
|
@@ -261534,6 +262326,7 @@ var ToolResultBatchOffload = class {
|
|
|
261534
262326
|
});
|
|
261535
262327
|
}
|
|
261536
262328
|
compact(messages) {
|
|
262329
|
+
if (!toolResultOffloadPressureForAgent(this.agent)) return messages;
|
|
261537
262330
|
const recentStart = Math.max(0, messages.length - TOOL_RESULT_HISTORICAL_KEEP_RECENT_MESSAGES);
|
|
261538
262331
|
let changed = false;
|
|
261539
262332
|
const projected = messages.map((message, index) => {
|
|
@@ -261584,6 +262377,13 @@ var ToolResultBatchOffload = class {
|
|
|
261584
262377
|
}
|
|
261585
262378
|
}
|
|
261586
262379
|
};
|
|
262380
|
+
function toolResultOffloadPressureForAgent(agent) {
|
|
262381
|
+
return hasToolResultOffloadPressure({ contextUsageRatio: contextUsageRatioForAgent(agent) });
|
|
262382
|
+
}
|
|
262383
|
+
function contextUsageRatioForAgent(agent) {
|
|
262384
|
+
const maxContextTokens = agent.fullCompaction.getEffectiveMaxContextTokens();
|
|
262385
|
+
return maxContextTokens > 0 ? agent.context.tokenCountWithPending / maxContextTokens : 1;
|
|
262386
|
+
}
|
|
261587
262387
|
//#endregion
|
|
261588
262388
|
//#region ../../packages/agent-core/src/agent/turn/user-message-offload.ts
|
|
261589
262389
|
function persistableUserMessageText(message) {
|
|
@@ -261652,6 +262452,7 @@ var UserMessageOffload = class {
|
|
|
261652
262452
|
if (this.agent.homedir === void 0) return 0;
|
|
261653
262453
|
const currentTurnStart = currentUserTurnStartIndex(history);
|
|
261654
262454
|
const totalHistoryChars = historyTextChars(history);
|
|
262455
|
+
const contextUsageRatio = contextUsageRatioForAgent(this.agent);
|
|
261655
262456
|
let offloaded = 0;
|
|
261656
262457
|
for (let historyIndex = 0; historyIndex < history.length; historyIndex++) {
|
|
261657
262458
|
if (historyIndex === currentTurnStart) continue;
|
|
@@ -261663,7 +262464,8 @@ var UserMessageOffload = class {
|
|
|
261663
262464
|
historyIndex,
|
|
261664
262465
|
historyLength: history.length,
|
|
261665
262466
|
historyChars: totalHistoryChars,
|
|
261666
|
-
textChars: text.length
|
|
262467
|
+
textChars: text.length,
|
|
262468
|
+
contextUsageRatio
|
|
261667
262469
|
});
|
|
261668
262470
|
if (!immediateOversize && !historicalOversize) continue;
|
|
261669
262471
|
const messageHash = userMessageOffloadHash(message, text);
|
|
@@ -261675,6 +262477,14 @@ var UserMessageOffload = class {
|
|
|
261675
262477
|
type: "text",
|
|
261676
262478
|
text: replacementText
|
|
261677
262479
|
}, ...message.content.filter((part) => part.type !== "text")];
|
|
262480
|
+
this.agent.records.logRecord({
|
|
262481
|
+
type: "policy.intervention",
|
|
262482
|
+
policy: "user_message_offload",
|
|
262483
|
+
location: "UserMessageOffload.detect",
|
|
262484
|
+
size_before: text.length,
|
|
262485
|
+
size_after: replacementText.length,
|
|
262486
|
+
unit: "chars"
|
|
262487
|
+
});
|
|
261678
262488
|
this.apply({
|
|
261679
262489
|
messageHash,
|
|
261680
262490
|
content,
|
|
@@ -261699,7 +262509,7 @@ var UserMessageOffload = class {
|
|
|
261699
262509
|
});
|
|
261700
262510
|
}
|
|
261701
262511
|
compact(messages) {
|
|
261702
|
-
if (this.replacements.size === 0) return messages;
|
|
262512
|
+
if (this.replacements.size === 0 || !toolResultOffloadPressureForAgent(this.agent)) return messages;
|
|
261703
262513
|
return messages.map((message) => {
|
|
261704
262514
|
const text = persistableUserMessageText(message);
|
|
261705
262515
|
if (text === void 0) return message;
|
|
@@ -261786,6 +262596,7 @@ var AssistantMessageOffload = class {
|
|
|
261786
262596
|
const history = this.agent.context.history;
|
|
261787
262597
|
if (this.agent.homedir === void 0) return 0;
|
|
261788
262598
|
const totalHistoryChars = historyTextChars(history);
|
|
262599
|
+
const contextUsageRatio = contextUsageRatioForAgent(this.agent);
|
|
261789
262600
|
let offloaded = 0;
|
|
261790
262601
|
for (let historyIndex = 0; historyIndex < history.length; historyIndex++) {
|
|
261791
262602
|
const message = history[historyIndex];
|
|
@@ -261794,7 +262605,8 @@ var AssistantMessageOffload = class {
|
|
|
261794
262605
|
historyIndex,
|
|
261795
262606
|
historyLength: history.length,
|
|
261796
262607
|
historyChars: totalHistoryChars,
|
|
261797
|
-
textChars: text.length
|
|
262608
|
+
textChars: text.length,
|
|
262609
|
+
contextUsageRatio
|
|
261798
262610
|
})) continue;
|
|
261799
262611
|
const messageHash = assistantMessageOffloadHash(message, text);
|
|
261800
262612
|
if (this.replacements.has(messageHash)) continue;
|
|
@@ -261805,6 +262617,14 @@ var AssistantMessageOffload = class {
|
|
|
261805
262617
|
type: "text",
|
|
261806
262618
|
text: replacementText
|
|
261807
262619
|
}, ...message.content.filter((part) => part.type !== "text")];
|
|
262620
|
+
this.agent.records.logRecord({
|
|
262621
|
+
type: "policy.intervention",
|
|
262622
|
+
policy: "assistant_message_offload",
|
|
262623
|
+
location: "AssistantMessageOffload.detect",
|
|
262624
|
+
size_before: text.length,
|
|
262625
|
+
size_after: replacementText.length,
|
|
262626
|
+
unit: "chars"
|
|
262627
|
+
});
|
|
261808
262628
|
this.apply({
|
|
261809
262629
|
messageHash,
|
|
261810
262630
|
content,
|
|
@@ -261829,6 +262649,7 @@ var AssistantMessageOffload = class {
|
|
|
261829
262649
|
});
|
|
261830
262650
|
}
|
|
261831
262651
|
compact(messages) {
|
|
262652
|
+
const underPressure = toolResultOffloadPressureForAgent(this.agent);
|
|
261832
262653
|
const completedToolCallIds = new Set(messages.filter((message) => message?.role === "tool" && message.toolCallId !== void 0).map((message) => message.toolCallId));
|
|
261833
262654
|
const totalHistoryChars = historyTextChars(messages);
|
|
261834
262655
|
let changed = false;
|
|
@@ -261858,7 +262679,7 @@ var AssistantMessageOffload = class {
|
|
|
261858
262679
|
}
|
|
261859
262680
|
const text = persistableAssistantMessageText(message);
|
|
261860
262681
|
if (text === void 0) return message;
|
|
261861
|
-
const replacement = this.replacements.get(assistantMessageOffloadHash(message, text));
|
|
262682
|
+
const replacement = underPressure ? this.replacements.get(assistantMessageOffloadHash(message, text)) : void 0;
|
|
261862
262683
|
if (replacement === void 0) return message;
|
|
261863
262684
|
changed = true;
|
|
261864
262685
|
return { ...message, content: replacement.content };
|
|
@@ -261885,6 +262706,17 @@ function blunExtractText(content) {
|
|
|
261885
262706
|
if (Array.isArray(content)) return content.map((c) => typeof c === "string" ? c : c && typeof c === "object" && "text" in c && typeof c.text === "string" ? c.text : "").join(" ");
|
|
261886
262707
|
return "";
|
|
261887
262708
|
}
|
|
262709
|
+
function blunRepeatActiveTurnPrompt(history, input, stepNumber) {
|
|
262710
|
+
if (stepNumber <= 1) return history;
|
|
262711
|
+
const prompt = blunExtractText(input);
|
|
262712
|
+
if (prompt.length === 0) return history;
|
|
262713
|
+
return [...history, {
|
|
262714
|
+
role: "user",
|
|
262715
|
+
content: [{ type: "text", text: `<active-task-reminder>\nThe active user task is repeated verbatim below. Continue from the current work state; do not restart completed work.\n\n${prompt}\n</active-task-reminder>` }],
|
|
262716
|
+
toolCalls: [],
|
|
262717
|
+
origin: { kind: "injection", variant: "active_turn_prompt" }
|
|
262718
|
+
}];
|
|
262719
|
+
}
|
|
261888
262720
|
/**
|
|
261889
262721
|
* BLUN: decide whether a turn should carry the full tool set. Small-context models
|
|
261890
262722
|
* (e.g. King on an 8k window) lose their identity/language when all tool schemas
|
|
@@ -262004,7 +262836,11 @@ function mapLoopEvent(event, turnId) {
|
|
|
262004
262836
|
type: "turn.step.started",
|
|
262005
262837
|
turnId,
|
|
262006
262838
|
step: event.step,
|
|
262007
|
-
stepId: event.uuid
|
|
262839
|
+
stepId: event.uuid,
|
|
262840
|
+
thinkingEffort: event.thinkingEffort,
|
|
262841
|
+
completionBudget: event.completionBudget,
|
|
262842
|
+
attempt: event.attempt,
|
|
262843
|
+
maxAttempts: event.maxAttempts
|
|
262008
262844
|
};
|
|
262009
262845
|
case "step.end": return {
|
|
262010
262846
|
type: "turn.step.completed",
|
|
@@ -262034,7 +262870,9 @@ function mapLoopEvent(event, turnId) {
|
|
|
262034
262870
|
outputMayHaveStarted: event.outputMayHaveStarted,
|
|
262035
262871
|
errorName: event.errorName,
|
|
262036
262872
|
errorMessage: event.errorMessage,
|
|
262037
|
-
statusCode: event.statusCode
|
|
262873
|
+
statusCode: event.statusCode,
|
|
262874
|
+
completionBudgetBefore: event.completionBudgetBefore,
|
|
262875
|
+
completionBudgetAfter: event.completionBudgetAfter
|
|
262038
262876
|
};
|
|
262039
262877
|
case "content.part": return;
|
|
262040
262878
|
case "tool.call": return {
|
|
@@ -262263,6 +263101,15 @@ var init_turn = __esmMin((() => {
|
|
|
262263
263101
|
kind: "system_trigger",
|
|
262264
263102
|
name: "goal_continuation"
|
|
262265
263103
|
};
|
|
263104
|
+
function goalContinuationOrigin(origin) {
|
|
263105
|
+
const cronRunId = origin?.kind === "cron_job" ? origin.runId : origin?.cronRunId;
|
|
263106
|
+
if (cronRunId === void 0 && origin?.toolScope === void 0) return GOAL_CONTINUATION_ORIGIN;
|
|
263107
|
+
return {
|
|
263108
|
+
...GOAL_CONTINUATION_ORIGIN,
|
|
263109
|
+
...(cronRunId === void 0 ? {} : { cronRunId }),
|
|
263110
|
+
...(origin?.toolScope === void 0 ? {} : { toolScope: origin.toolScope })
|
|
263111
|
+
};
|
|
263112
|
+
}
|
|
262266
263113
|
GOAL_COMPLETION_REMINDER_NAME = "goal_completion";
|
|
262267
263114
|
GOAL_BLOCKED_REMINDER_NAME = "goal_blocked";
|
|
262268
263115
|
GOAL_RATE_LIMIT_PAUSE_REASON = "Paused after provider rate limit";
|
|
@@ -262310,8 +263157,10 @@ var init_turn = __esmMin((() => {
|
|
|
262310
263157
|
stepToolCallKeys = /* @__PURE__ */ new Map();
|
|
262311
263158
|
telemetryModeByTurn = /* @__PURE__ */ new Map();
|
|
262312
263159
|
currentStepByTurn = /* @__PURE__ */ new Map();
|
|
263160
|
+
toolScopeByTurn = /* @__PURE__ */ new Map();
|
|
262313
263161
|
interruptedTelemetryTurnIds = /* @__PURE__ */ new Set();
|
|
262314
263162
|
stepFailureByTurn = /* @__PURE__ */ new Map();
|
|
263163
|
+
stepRequestStateByTurn = /* @__PURE__ */ new Map();
|
|
262315
263164
|
currentStep = 0;
|
|
262316
263165
|
cognitiveLifecycle;
|
|
262317
263166
|
cognitiveLifecycleUnavailable = false;
|
|
@@ -262576,10 +263425,11 @@ var init_turn = __esmMin((() => {
|
|
|
262576
263425
|
duplicate: false
|
|
262577
263426
|
};
|
|
262578
263427
|
}
|
|
262579
|
-
retry(trigger) {
|
|
263428
|
+
retry(trigger, toolScope) {
|
|
262580
263429
|
return this.prompt([], {
|
|
262581
263430
|
kind: "retry",
|
|
262582
|
-
trigger
|
|
263431
|
+
trigger,
|
|
263432
|
+
...(toolScope === void 0 ? {} : { toolScope })
|
|
262583
263433
|
});
|
|
262584
263434
|
}
|
|
262585
263435
|
launch(input, origin) {
|
|
@@ -262657,6 +263507,9 @@ var init_turn = __esmMin((() => {
|
|
|
262657
263507
|
get hasActiveTurn() {
|
|
262658
263508
|
return this.activeTurn !== null && this.activeTurn !== "resuming";
|
|
262659
263509
|
}
|
|
263510
|
+
toolScopeForTurn(turnId) {
|
|
263511
|
+
return this.toolScopeByTurn.get(turnId);
|
|
263512
|
+
}
|
|
262660
263513
|
ensureActiveTurn() {
|
|
262661
263514
|
if (this.activeTurn === null || this.activeTurn === "resuming") throw new Error("No active turn");
|
|
262662
263515
|
return this.activeTurn;
|
|
@@ -262768,15 +263621,23 @@ var init_turn = __esmMin((() => {
|
|
|
262768
263621
|
*/
|
|
262769
263622
|
async turnWorker(firstTurnId, input, origin, signal) {
|
|
262770
263623
|
const ownsActiveTurn = () => this.activeTurn !== null && this.activeTurn !== "resuming" && this.activeTurn.controller.signal === signal;
|
|
263624
|
+
let result;
|
|
262771
263625
|
try {
|
|
262772
|
-
if (this.agent.goal.getGoal().goal?.status === "active")
|
|
262773
|
-
|
|
262774
|
-
|
|
262775
|
-
|
|
262776
|
-
|
|
262777
|
-
|
|
262778
|
-
|
|
263626
|
+
if (this.agent.goal.getGoal().goal?.status === "active") result = await this.driveGoal(firstTurnId, input, origin, signal);
|
|
263627
|
+
else {
|
|
263628
|
+
const end = await this.runOneTurn(firstTurnId, input, origin, signal, true);
|
|
263629
|
+
if (this.agent.goal.getGoal().goal?.status === "active" && end.event.reason !== "cancelled" && end.event.reason !== "failed" && end.event.reason !== "filtered") result = await this.driveGoal(this.allocateTurnId(), [{
|
|
263630
|
+
type: "text",
|
|
263631
|
+
text: GOAL_CONTINUATION_PROMPT
|
|
263632
|
+
}], goalContinuationOrigin(origin), signal);
|
|
263633
|
+
else result = end;
|
|
263634
|
+
}
|
|
263635
|
+
return result;
|
|
263636
|
+
} catch (error) {
|
|
263637
|
+
if (origin.kind === "cron_job" && typeof origin.runId === "string") this.agent.cron?.observeRunWorkerFailed(origin.runId);
|
|
263638
|
+
throw error;
|
|
262779
263639
|
} finally {
|
|
263640
|
+
if (result !== void 0 && origin.kind === "cron_job" && typeof origin.runId === "string") this.agent.cron?.observeRunWorkerEnded(origin.runId, result.event);
|
|
262780
263641
|
if (ownsActiveTurn()) this.activeTurn = null;
|
|
262781
263642
|
}
|
|
262782
263643
|
}
|
|
@@ -262830,7 +263691,7 @@ var init_turn = __esmMin((() => {
|
|
|
262830
263691
|
type: "text",
|
|
262831
263692
|
text: GOAL_CONTINUATION_PROMPT
|
|
262832
263693
|
}];
|
|
262833
|
-
turnOrigin =
|
|
263694
|
+
turnOrigin = goalContinuationOrigin(origin);
|
|
262834
263695
|
}
|
|
262835
263696
|
}
|
|
262836
263697
|
async endGoalTurnWithoutModel(turnId, input, origin) {
|
|
@@ -262878,6 +263739,7 @@ var init_turn = __esmMin((() => {
|
|
|
262878
263739
|
this.currentStepByTurn.set(turnId, 0);
|
|
262879
263740
|
this.recordExternalReportSources(turnId, origin);
|
|
262880
263741
|
const persistedOrigin = durablePromptOrigin(origin);
|
|
263742
|
+
if (persistedOrigin.toolScope !== void 0) this.toolScopeByTurn.set(turnId, persistedOrigin.toolScope);
|
|
262881
263743
|
this.agent.telemetry.track("turn_started", {
|
|
262882
263744
|
mode: telemetryMode,
|
|
262883
263745
|
...this.requestProviderProps()
|
|
@@ -262985,11 +263847,13 @@ var init_turn = __esmMin((() => {
|
|
|
262985
263847
|
if (ended.reason !== "completed") this.trackTurnInterrupted(turnId, this.currentStepByTurn.get(turnId) ?? this.currentStep);
|
|
262986
263848
|
this.telemetryModeByTurn.delete(turnId);
|
|
262987
263849
|
this.currentStepByTurn.delete(turnId);
|
|
263850
|
+
this.toolScopeByTurn.delete(turnId);
|
|
262988
263851
|
this.interruptedTelemetryTurnIds.delete(turnId);
|
|
262989
263852
|
this.cognitiveActionEvidenceByTurn.delete(turnId);
|
|
262990
263853
|
this.cognitiveExternalReportsByTurn.delete(turnId);
|
|
262991
263854
|
this.cognitiveLocalClaimsByTurn.delete(turnId);
|
|
262992
263855
|
this.stepFailureByTurn.delete(turnId);
|
|
263856
|
+
this.stepRequestStateByTurn.delete(turnId);
|
|
262993
263857
|
await this.agent.records.flush();
|
|
262994
263858
|
await this.agent.records.writeResumeCheckpoint();
|
|
262995
263859
|
return {
|
|
@@ -263082,13 +263946,14 @@ var init_turn = __esmMin((() => {
|
|
|
263082
263946
|
let previousStepToolOutcome = "initial";
|
|
263083
263947
|
let currentStepHadTool = false;
|
|
263084
263948
|
let currentStepHadFailure = false;
|
|
263949
|
+
let currentLoopStep = 0;
|
|
263085
263950
|
while (true) {
|
|
263086
263951
|
signal.throwIfAborted();
|
|
263087
263952
|
const model = this.agent.config.model;
|
|
263088
263953
|
const loopControl = this.agent.blunConfig?.loopControl;
|
|
263089
263954
|
let stopForGoalBudget = false;
|
|
263090
263955
|
try {
|
|
263091
|
-
const originTools = blunToolsForOrigin(this.agent.injection.filterPersonalMemoryToolsForTurn(turnId, input, origin, this.agent.tools.loopTools), origin);
|
|
263956
|
+
const originTools = filterToolsForCronScope(blunToolsForOrigin(this.agent.injection.filterPersonalMemoryToolsForTurn(turnId, input, origin, this.agent.tools.loopTools), origin), origin.toolScope);
|
|
263092
263957
|
const compactConversationTool = originTools.find((tool) => tool.name === "CompactConversation");
|
|
263093
263958
|
const eligibleTools = originTools.filter((tool) => tool.name !== "CompactConversation" || this.agent.fullCompaction.isProactiveCompactionEligible());
|
|
263094
263959
|
const turnRequiredToolNames = new Set(requiredToolNames);
|
|
@@ -263114,12 +263979,13 @@ var init_turn = __esmMin((() => {
|
|
|
263114
263979
|
eligibleToolSchemaTokens: estimateTokensForTools(eligibleTools),
|
|
263115
263980
|
selectedToolSchemaTokens: estimateTokensForTools(selectedTools)
|
|
263116
263981
|
});
|
|
263982
|
+
const turnHistory = () => fastConversation ? turnThinkingEffort === "off" ? blunStandaloneConversationHistory(this.agent.context.history) : blunFastConversationHistory(this.agent.context.history) : origin.kind === "cron_job" && origin.recurring === true ? projectRecurringCronHistory(this.agent.context.history, origin.jobId) : personalMemoryRecall === void 0 ? this.agent.context.history : [...this.agent.context.history, personalMemoryRecall];
|
|
263117
263983
|
return (await runTurn({
|
|
263118
263984
|
turnId: String(turnId),
|
|
263119
263985
|
signal,
|
|
263120
263986
|
llm: turnLLM,
|
|
263121
|
-
buildMessages: () => this.agent.context.project(
|
|
263122
|
-
buildMessagesStrict: () => this.agent.context.project(
|
|
263987
|
+
buildMessages: () => this.agent.context.project(blunRepeatActiveTurnPrompt(turnHistory(), input, currentLoopStep), { dropOrphanResults: true }),
|
|
263988
|
+
buildMessagesStrict: () => this.agent.context.project(blunRepeatActiveTurnPrompt(turnHistory(), input, currentLoopStep), {
|
|
263123
263989
|
synthesizeMissing: true,
|
|
263124
263990
|
dropOrphanResults: true,
|
|
263125
263991
|
dedupeDuplicateToolCalls: true,
|
|
@@ -263131,6 +263997,8 @@ var init_turn = __esmMin((() => {
|
|
|
263131
263997
|
log: this.agent.log,
|
|
263132
263998
|
maxSteps: loopControl?.maxStepsPerTurn,
|
|
263133
263999
|
maxRetryAttempts: loopControl?.maxRetriesPerStep,
|
|
264000
|
+
checkpointBeforeToolExecution: () => this.agent.records.flush(),
|
|
264001
|
+
checkpointBeforeRetryWait: () => this.agent.records.flush(),
|
|
263134
264002
|
recordStepUsage: async (usage) => {
|
|
263135
264003
|
try {
|
|
263136
264004
|
stopForGoalBudget = (await this.agent.goal.recordTokenUsage(grandTotal(usage)))?.budget.overBudget === true;
|
|
@@ -263140,6 +264008,7 @@ var init_turn = __esmMin((() => {
|
|
|
263140
264008
|
},
|
|
263141
264009
|
hooks: {
|
|
263142
264010
|
beforeStep: async ({ signal: stepSignal, stepNumber }) => {
|
|
264011
|
+
currentLoopStep = stepNumber;
|
|
263143
264012
|
await this.agent.records.flush();
|
|
263144
264013
|
await this.agent.toolResultBatchOffload.detect();
|
|
263145
264014
|
this.agent.microCompaction.detect();
|
|
@@ -263327,14 +264196,25 @@ var init_turn = __esmMin((() => {
|
|
|
263327
264196
|
toolOutput: isError === true ? void 0 : toolOutputText(output).slice(0, 2e3)
|
|
263328
264197
|
}
|
|
263329
264198
|
});
|
|
263330
|
-
|
|
264199
|
+
const budgetedResult = await budgetToolResultForModel({
|
|
263331
264200
|
homedir: this.agent.homedir,
|
|
263332
264201
|
toolName: ctx.toolCall.name,
|
|
263333
264202
|
toolCallId: ctx.toolCall.id,
|
|
263334
264203
|
toolArgs: ctx.args,
|
|
263335
264204
|
result: finalResult,
|
|
264205
|
+
contextTokens: this.agent.context.tokenCountWithPending,
|
|
264206
|
+
maxContextTokens: this.agent.config.modelCapabilities.max_context_tokens,
|
|
263336
264207
|
telemetry: this.agent.telemetry
|
|
263337
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;
|
|
263338
264218
|
}
|
|
263339
264219
|
}
|
|
263340
264220
|
})).stopReason;
|
|
@@ -263377,11 +264257,32 @@ var init_turn = __esmMin((() => {
|
|
|
263377
264257
|
buildDispatchEvent(turnId) {
|
|
263378
264258
|
return createLoopEventDispatcher({
|
|
263379
264259
|
appendTranscriptRecord: async (event) => {
|
|
264260
|
+
this.agent.cron?.observeLoopEvent(turnId, event);
|
|
263380
264261
|
this.agent.context.appendLoopEvent(event);
|
|
263381
264262
|
},
|
|
263382
264263
|
emitLiveEvent: (event) => {
|
|
263383
264264
|
this.noteFirstRequestEvent(event);
|
|
263384
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
|
+
});
|
|
263385
264286
|
const mapped = mapLoopEvent(event, turnId);
|
|
263386
264287
|
if (mapped !== void 0) return this.agent.emitEvent(mapped);
|
|
263387
264288
|
}
|
|
@@ -263405,9 +264306,18 @@ var init_turn = __esmMin((() => {
|
|
|
263405
264306
|
}
|
|
263406
264307
|
trackLoopTelemetry(event, turnId) {
|
|
263407
264308
|
if (event.type === "step.begin") {
|
|
263408
|
-
this.beginTrackedStep(turnId, event.step);
|
|
264309
|
+
this.beginTrackedStep(turnId, event.step, event);
|
|
263409
264310
|
return;
|
|
263410
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
|
+
}
|
|
263411
264321
|
if (event.type === "turn.interrupted") {
|
|
263412
264322
|
if (event.reason === "error" && event.activeStep !== void 0) this.stepFailureByTurn.set(turnId, event);
|
|
263413
264323
|
this.trackTurnInterrupted(turnId, interruptedStep(event));
|
|
@@ -263415,9 +264325,15 @@ var init_turn = __esmMin((() => {
|
|
|
263415
264325
|
}
|
|
263416
264326
|
this.trackToolLifecycle(event, turnId);
|
|
263417
264327
|
}
|
|
263418
|
-
beginTrackedStep(turnId, step) {
|
|
264328
|
+
beginTrackedStep(turnId, step, event) {
|
|
263419
264329
|
this.currentStepByTurn.set(turnId, step);
|
|
263420
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
|
+
});
|
|
263421
264337
|
if (!this.stepToolCallKeys.has(step)) this.stepToolCallKeys.set(step, /* @__PURE__ */ new Set());
|
|
263422
264338
|
}
|
|
263423
264339
|
trackToolLifecycle(event, turnId) {
|
|
@@ -264434,7 +265350,7 @@ var init_codebase_search = __esmMin((() => {
|
|
|
264434
265350
|
description: `Semantic search: ${args.query.length > 50 ? `${args.query.slice(0, 50)}…` : args.query}`,
|
|
264435
265351
|
display: {
|
|
264436
265352
|
kind: "command",
|
|
264437
|
-
command: `python codebase_index.py query . "${args.query}" --top ${String(args.top)}`,
|
|
265353
|
+
command: `python codebase_index.py query . "${args.query}" --top ${String(args.top)} --model auto`,
|
|
264438
265354
|
cwd: this.cwd,
|
|
264439
265355
|
description: `Codebase semantic search`,
|
|
264440
265356
|
language: "bash"
|
|
@@ -264454,7 +265370,9 @@ var init_codebase_search = __esmMin((() => {
|
|
|
264454
265370
|
this.cwd,
|
|
264455
265371
|
args.query,
|
|
264456
265372
|
"--top",
|
|
264457
|
-
String(args.top)
|
|
265373
|
+
String(args.top),
|
|
265374
|
+
"--model",
|
|
265375
|
+
"auto"
|
|
264458
265376
|
], {
|
|
264459
265377
|
cwd: this.cwd,
|
|
264460
265378
|
timeout: SCRIPT_TIMEOUT_MS,
|
|
@@ -265087,10 +266005,12 @@ var init_builtin = __esmMin((() => {
|
|
|
265087
266005
|
init_task_list();
|
|
265088
266006
|
init_task_output();
|
|
265089
266007
|
init_task_update();
|
|
266008
|
+
init_task_resume();
|
|
265090
266009
|
init_task_stop();
|
|
265091
266010
|
init_cron_create();
|
|
265092
266011
|
init_cron_delete();
|
|
265093
266012
|
init_cron_list();
|
|
266013
|
+
init_cron_runs();
|
|
265094
266014
|
init_agent$1();
|
|
265095
266015
|
init_agent_swarm();
|
|
265096
266016
|
init_ask_user();
|
|
@@ -265122,7 +266042,7 @@ var init_builtin = __esmMin((() => {
|
|
|
265122
266042
|
var init_types$3 = __esmMin((() => {}));
|
|
265123
266043
|
//#endregion
|
|
265124
266044
|
//#region ../../packages/agent-core/src/agent/tool/index.ts
|
|
265125
|
-
var import_picomatch, profileToolExclusionPolicy, applyProfileToolExclusions, shouldRecordUserToolUnregister, SHELL_FOREGROUND_TIMEOUT_S, ToolManager;
|
|
266045
|
+
var import_picomatch, profileToolExclusionPolicy, applyProfileToolExclusions, shouldRecordUserToolUnregister, createFileObservationPolicy, SHELL_FOREGROUND_TIMEOUT_S, ToolManager;
|
|
265126
266046
|
var init_tool$1 = __esmMin((() => {
|
|
265127
266047
|
init_dist$4();
|
|
265128
266048
|
import_picomatch = /* @__PURE__ */ __toESM(require_picomatch(), 1);
|
|
@@ -265138,6 +266058,7 @@ var init_tool$1 = __esmMin((() => {
|
|
|
265138
266058
|
profileToolExclusionPolicy = createRequire(import.meta.url)("./bin/profile-tool-exclusion-policy.cjs");
|
|
265139
266059
|
applyProfileToolExclusions = profileToolExclusionPolicy.applyProfileToolExclusions;
|
|
265140
266060
|
({ shouldRecordUserToolUnregister } = createRequire(import.meta.url)("./bin/user-tool-record-policy.cjs"));
|
|
266061
|
+
({ createFileObservationPolicy } = createRequire(import.meta.url)("./bin/file-observation-policy.cjs"));
|
|
265141
266062
|
SHELL_FOREGROUND_TIMEOUT_S = 120;
|
|
265142
266063
|
ToolManager = class {
|
|
265143
266064
|
agent;
|
|
@@ -265320,9 +266241,10 @@ var init_tool$1 = __esmMin((() => {
|
|
|
265320
266241
|
hasUserTool(name) {
|
|
265321
266242
|
return this.userTools.has(name);
|
|
265322
266243
|
}
|
|
265323
|
-
inheritUserTools(parent) {
|
|
266244
|
+
inheritUserTools(parent, excludedNames = /* @__PURE__ */ new Set()) {
|
|
265324
266245
|
for (const tool of parent.userTools.values()) {
|
|
265325
266246
|
if (!parent.enabledTools.has(tool.name)) continue;
|
|
266247
|
+
if (excludedNames.has(tool.name)) continue;
|
|
265326
266248
|
this.registerUserTool({
|
|
265327
266249
|
name: tool.name,
|
|
265328
266250
|
description: tool.description,
|
|
@@ -265537,11 +266459,16 @@ var init_tool$1 = __esmMin((() => {
|
|
|
265537
266459
|
}, this.agent.skills?.registry.getSkillRoots() ?? []);
|
|
265538
266460
|
const allowBackground = this.enabledTools.has("TaskList") && this.enabledTools.has("TaskOutput") && this.enabledTools.has("TaskStop");
|
|
265539
266461
|
const goalToolsEnabled = this.agent.type === "main";
|
|
266462
|
+
const readBudget = () => ({
|
|
266463
|
+
contextTokens: this.agent.context.tokenCountWithPending,
|
|
266464
|
+
maxContextTokens: this.agent.fullCompaction.getEffectiveMaxContextTokens()
|
|
266465
|
+
});
|
|
266466
|
+
const fileObservation = createFileObservationPolicy({ pathClass: kaos.pathClass() });
|
|
265540
266467
|
this.builtinTools = new Map([
|
|
265541
|
-
new ReadTool(kaos, workspace),
|
|
265542
|
-
new ReadBatchTool(kaos, workspace),
|
|
265543
|
-
new WriteTool(kaos, workspace, () => this.agent.context.history, toolServices?.lsp),
|
|
265544
|
-
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),
|
|
265545
266472
|
new GrepTool(kaos, workspace, this.agent.telemetry),
|
|
265546
266473
|
new GlobTool(kaos, workspace, this.agent.telemetry),
|
|
265547
266474
|
new BashTool(kaos, cwd, background, { allowBackground }),
|
|
@@ -265559,9 +266486,12 @@ var init_tool$1 = __esmMin((() => {
|
|
|
265559
266486
|
new TaskListTool(background),
|
|
265560
266487
|
new TaskOutputTool(background),
|
|
265561
266488
|
new TaskUpdateTool(background),
|
|
266489
|
+
this.agent.subagentHost && allowBackground && background.resumeStore && new TaskResumeTool(background, this.agent.subagentHost),
|
|
265562
266490
|
new TaskStopTool(background),
|
|
265563
266491
|
this.agent.cron && new CronCreateTool(this.agent.cron),
|
|
265564
266492
|
this.agent.cron && new CronListTool(this.agent.cron),
|
|
266493
|
+
this.agent.cron && new CronRunListTool(this.agent.cron),
|
|
266494
|
+
this.agent.cron && new CronRunOutputTool(this.agent.cron),
|
|
265565
266495
|
this.agent.cron && new CronDeleteTool(this.agent.cron),
|
|
265566
266496
|
this.agent.skills?.registry.listInvocableSkills().length && new SkillTool(this.agent),
|
|
265567
266497
|
this.agent.subagentHost && new AgentTool(this.agent.subagentHost, background, DEFAULT_AGENT_PROFILES["agent"]?.subagents, {
|
|
@@ -265968,7 +266898,7 @@ var init_llm_request_logger = __esmMin((() => {
|
|
|
265968
266898
|
function normalizeRuntimeSystemPromptAppend(value) {
|
|
265969
266899
|
return value?.trim().slice(0, 16e3) ?? "";
|
|
265970
266900
|
}
|
|
265971
|
-
var PINNED_MODEL_ALIASES, createEffectiveSystemPromptResolver, resolveProviderIdleTimeoutMs, capCompletionBudgetForAdaptiveEffort,
|
|
266901
|
+
var PINNED_MODEL_ALIASES, createEffectiveSystemPromptResolver, resolveProviderIdleTimeoutMs, capCompletionBudgetForAdaptiveEffort, selectThinkingEffortForBufferedSteer, selectThinkingEffortForWorkStep, selectThinkingEffortForTurn, Agent$1;
|
|
265972
266902
|
var init_agent = __esmMin((() => {
|
|
265973
266903
|
init_dist$6();
|
|
265974
266904
|
init_config$4();
|
|
@@ -266007,8 +266937,8 @@ var init_agent = __esmMin((() => {
|
|
|
266007
266937
|
init_error_memory();
|
|
266008
266938
|
({ createEffectiveSystemPromptResolver } = createRequire(import.meta.url)("./bin/effective-system-prompt-cache-policy.cjs"));
|
|
266009
266939
|
({ resolveProviderIdleTimeoutMs } = createRequire(import.meta.url)("./bin/provider-idle-timeout-policy.cjs"));
|
|
266010
|
-
({ capCompletionBudgetForAdaptiveEffort,
|
|
266011
|
-
PINNED_MODEL_ALIASES = new Set(["king
|
|
266940
|
+
({ capCompletionBudgetForAdaptiveEffort, selectThinkingEffortForBufferedSteer, selectThinkingEffortForWorkStep, selectThinkingEffortForTurn } = createRequire(import.meta.url)("./bin/turn-thinking-policy.cjs"));
|
|
266941
|
+
PINNED_MODEL_ALIASES = new Set(["blun/king"]);
|
|
266012
266942
|
Agent$1 = class {
|
|
266013
266943
|
type;
|
|
266014
266944
|
_kaos;
|
|
@@ -266202,7 +267132,7 @@ var init_agent = __esmMin((() => {
|
|
|
266202
267132
|
const provider = thinkingEffort === void 0 ? runtimeModel.provider : runtimeModel.provider.withThinking(thinkingEffort);
|
|
266203
267133
|
const loopControl = this.blunConfig?.loopControl;
|
|
266204
267134
|
const completionBudgetConfig = resolveCompletionBudget({
|
|
266205
|
-
maxOutputSize:
|
|
267135
|
+
maxOutputSize: runtimeModel.maxOutputSize,
|
|
266206
267136
|
reservedContextSize: loopControl?.reservedContextSize
|
|
266207
267137
|
});
|
|
266208
267138
|
return new KosongLLM({
|
|
@@ -266550,6 +267480,7 @@ var init_agent = __esmMin((() => {
|
|
|
266550
267480
|
}
|
|
266551
267481
|
emitEvent(event) {
|
|
266552
267482
|
if (this.records.restoring) return;
|
|
267483
|
+
this.cron?.observeAgentEvent(event);
|
|
266553
267484
|
return this.rpc?.emitEvent?.(event);
|
|
266554
267485
|
}
|
|
266555
267486
|
emitStatusUpdated() {
|
|
@@ -298410,7 +299341,9 @@ var init_session$1 = __esmMin((() => {
|
|
|
298410
299341
|
homedir,
|
|
298411
299342
|
type,
|
|
298412
299343
|
parentAgentId,
|
|
298413
|
-
swarmItem: options.swarmItem
|
|
299344
|
+
swarmItem: options.swarmItem,
|
|
299345
|
+
profileName: options.profileName,
|
|
299346
|
+
skillPolicy: options.skillPolicy
|
|
298414
299347
|
};
|
|
298415
299348
|
this.writeMetadata();
|
|
298416
299349
|
}
|
|
@@ -298686,7 +299619,7 @@ var init_session$1 = __esmMin((() => {
|
|
|
298686
299619
|
missingCapability: part.missingCapability
|
|
298687
299620
|
});
|
|
298688
299621
|
},
|
|
298689
|
-
skills: this.skills,
|
|
299622
|
+
skills: config.skillRegistry === void 0 ? this.skills : config.skillRegistry,
|
|
298690
299623
|
rpc: proxyWithExtraPayload(this.rpc, { agentId: id }),
|
|
298691
299624
|
modelProvider: this.options.providerManager,
|
|
298692
299625
|
hookEngine: config.hookEngine ?? this.hookEngine,
|
|
@@ -298751,9 +299684,16 @@ var init_session$1 = __esmMin((() => {
|
|
|
298751
299684
|
const parentAgentId = meta.parentAgentId ?? null;
|
|
298752
299685
|
const parent = parentAgentId === null ? void 0 : await this.resumeAgent(parentAgentId, [...stack, id]);
|
|
298753
299686
|
try {
|
|
298754
|
-
|
|
299687
|
+
let restoredSkillPolicy;
|
|
299688
|
+
if (meta.type === "sub" && meta.skillPolicy !== void 0) {
|
|
299689
|
+
if (meta.profileName === void 0) throw new Error("SUBAGENT_SKILL_POLICY_CHANGED: persisted subagent profile is unavailable; spawn a new subagent");
|
|
299690
|
+
const persistedProfile = DEFAULT_AGENT_PROFILES[parent?.agent.config.profileName ?? "agent"]?.subagents?.[meta.profileName] ?? DEFAULT_AGENT_PROFILES["agent"]?.subagents?.[meta.profileName];
|
|
299691
|
+
if (persistedProfile === void 0) throw new Error("SUBAGENT_SKILL_POLICY_CHANGED: persisted subagent profile was not found; spawn a new subagent");
|
|
299692
|
+
restoredSkillPolicy = restoreSubagentSkillPolicy(persistedProfile.subagentSkills, meta.skillPolicy, this.skills);
|
|
299693
|
+
}
|
|
299694
|
+
const agent = this.instantiateAgent(id, meta.homedir, meta.type, restoredSkillPolicy === void 0 ? {} : { skillRegistry: restoredSkillPolicy.registry }, parentAgentId);
|
|
298755
299695
|
const result = await agent.resume();
|
|
298756
|
-
await this.restoreAgentProfileHandle(agent, meta, parent?.agent);
|
|
299696
|
+
await this.restoreAgentProfileHandle(agent, meta, parent?.agent, restoredSkillPolicy);
|
|
298757
299697
|
this.ensureBaselineSkill(agent);
|
|
298758
299698
|
agent.setRuntimeSystemPromptAppend(this.accountMemoryContext);
|
|
298759
299699
|
this.agents.set(id, agent);
|
|
@@ -298766,18 +299706,33 @@ var init_session$1 = __esmMin((() => {
|
|
|
298766
299706
|
throw error;
|
|
298767
299707
|
}
|
|
298768
299708
|
}
|
|
298769
|
-
async restoreAgentProfileHandle(agent, meta, parentAgent) {
|
|
299709
|
+
async restoreAgentProfileHandle(agent, meta, parentAgent, restoredSkillPolicy) {
|
|
298770
299710
|
if (agent.config.systemPrompt === "") return;
|
|
298771
|
-
|
|
299711
|
+
let profile = this.resolvePersistedProfile(agent, meta, parentAgent);
|
|
298772
299712
|
if (profile === void 0) return;
|
|
299713
|
+
if (restoredSkillPolicy !== void 0) profile = profileWithSubagentSkillTools(profile, restoredSkillPolicy);
|
|
298773
299714
|
agent.setActiveProfile(profile, this.options.blunHomeDir);
|
|
298774
299715
|
await agent.refreshSystemPrompt();
|
|
298775
299716
|
}
|
|
298776
299717
|
ensureBaselineSkill(agent) {
|
|
298777
|
-
|
|
299718
|
+
const skill = this.skills.getSkill(BASELINE_SKILL_NAME);
|
|
299719
|
+
if (skill === void 0) {
|
|
299720
|
+
this.log.warn("baseline skill is unavailable", { skill: BASELINE_SKILL_NAME });
|
|
299721
|
+
return;
|
|
299722
|
+
}
|
|
299723
|
+
const variant = `${BASELINE_SKILL_ORIGIN_PREFIX}${skill.name}`;
|
|
299724
|
+
if (agent.context.history.some((message) => message.origin?.kind === "injection" && message.origin.variant === variant)) return;
|
|
299725
|
+
agent.context.appendSystemReminder(renderBaselineSkillPrompt({
|
|
299726
|
+
skillName: skill.name,
|
|
299727
|
+
skillSource: skill.source,
|
|
299728
|
+
skillDir: skill.dir
|
|
299729
|
+
}), {
|
|
299730
|
+
kind: "injection",
|
|
299731
|
+
variant
|
|
299732
|
+
});
|
|
298778
299733
|
}
|
|
298779
299734
|
resolvePersistedProfile(agent, meta, parentAgent) {
|
|
298780
|
-
const profileName = agent.config.profileName;
|
|
299735
|
+
const profileName = meta.profileName ?? agent.config.profileName;
|
|
298781
299736
|
if (profileName === void 0) return void 0;
|
|
298782
299737
|
if (meta.type === "sub") return DEFAULT_AGENT_PROFILES[parentAgent?.config.profileName ?? "agent"]?.subagents?.[profileName] ?? DEFAULT_AGENT_PROFILES["agent"]?.subagents?.[profileName];
|
|
298783
299738
|
return DEFAULT_AGENT_PROFILES[profileName];
|
|
@@ -313566,27 +314521,14 @@ var init_local_fetch_url = __esmMin((() => {
|
|
|
313566
314521
|
kind: "passthrough"
|
|
313567
314522
|
};
|
|
313568
314523
|
return {
|
|
313569
|
-
content: this.extractMainContent(body),
|
|
314524
|
+
content: this.extractMainContent(body, url),
|
|
313570
314525
|
kind: "extracted"
|
|
313571
314526
|
};
|
|
313572
314527
|
}
|
|
313573
|
-
extractMainContent(html) {
|
|
313574
|
-
const
|
|
313575
|
-
|
|
313576
|
-
|
|
313577
|
-
if (article !== null) {
|
|
313578
|
-
const text = (article.textContent ?? "").trim();
|
|
313579
|
-
if (text.length > 0) {
|
|
313580
|
-
const title = (article.title ?? "").trim();
|
|
313581
|
-
return title.length > 0 ? `# ${title}\n\n${text}` : text;
|
|
313582
|
-
}
|
|
313583
|
-
}
|
|
313584
|
-
} catch {}
|
|
313585
|
-
const { document } = parseHTML(html);
|
|
313586
|
-
const titleText = (document.querySelector("title")?.textContent ?? "").trim();
|
|
313587
|
-
const fallbackText = ((document.querySelector("article") ?? document.querySelector("main") ?? document.querySelector("body"))?.textContent ?? "").trim();
|
|
313588
|
-
if (fallbackText.length === 0) throw new Error("Failed to extract meaningful content from the page. The page may require JavaScript to render.");
|
|
313589
|
-
return titleText.length > 0 ? `# ${titleText}\n\n${fallbackText}` : fallbackText;
|
|
314528
|
+
extractMainContent(html, baseUrl) {
|
|
314529
|
+
const content = htmlToResearchMarkdown(html, baseUrl);
|
|
314530
|
+
if (content.length === 0) throw new Error("Failed to extract meaningful content from the page. The page may require JavaScript to render.");
|
|
314531
|
+
return content;
|
|
313590
314532
|
}
|
|
313591
314533
|
};
|
|
313592
314534
|
}));
|
|
@@ -315079,17 +316021,7 @@ function resolveModelCapabilities(alias, provider) {
|
|
|
315079
316021
|
};
|
|
315080
316022
|
}
|
|
315081
316023
|
function toKosongProviderConfig(provider, model, blunRequestHeaders, promptCacheKey, supportEfforts) {
|
|
315082
|
-
|
|
315083
|
-
if (provider.type === FREDRIK_GLM_PROVIDER_TYPE) return {
|
|
315084
|
-
type: "blun",
|
|
315085
|
-
model,
|
|
315086
|
-
baseUrl: provider.baseUrl,
|
|
315087
|
-
apiKey: readFredrikGlmApiKeyFile(provider),
|
|
315088
|
-
generationKwargs: { prompt_cache_key: promptCacheKey },
|
|
315089
|
-
supportEfforts: [...FREDRIK_GLM_EFFORTS],
|
|
315090
|
-
openAICompatible: true,
|
|
315091
|
-
defaultHeaders: { "User-Agent": "BLUN-King/Fredrik-GLM" }
|
|
315092
|
-
};
|
|
316024
|
+
assertBlunProviderType(provider);
|
|
315093
316025
|
const envCustomHeaders = parseBlunCodeCustomHeaders();
|
|
315094
316026
|
return {
|
|
315095
316027
|
type: "blun",
|
|
@@ -315110,12 +316042,11 @@ function defaultHeadersField(headers) {
|
|
|
315110
316042
|
return { defaultHeaders: { ...headers } };
|
|
315111
316043
|
}
|
|
315112
316044
|
function providerApiKey(provider) {
|
|
315113
|
-
|
|
315114
|
-
if (provider.type === FREDRIK_GLM_PROVIDER_TYPE) return readFredrikGlmApiKeyFile(provider);
|
|
316045
|
+
assertBlunProviderType(provider);
|
|
315115
316046
|
return providerValue(provider.apiKey, provider.env, "BLUN_API_KEY");
|
|
315116
316047
|
}
|
|
315117
|
-
function
|
|
315118
|
-
if (provider.type !== "blun"
|
|
316048
|
+
function assertBlunProviderType(provider) {
|
|
316049
|
+
if (provider.type !== "blun") throw new BlunError(ErrorCodes.MODEL_CONFIG_INVALID, "Only the BLUN provider type is supported.");
|
|
315119
316050
|
}
|
|
315120
316051
|
function providerValue(configured, env, envKey) {
|
|
315121
316052
|
return nonEmptyString$2(configured) ?? envValue(env, envKey);
|
|
@@ -315134,7 +316065,7 @@ var init_provider_manager = __esmMin((() => {
|
|
|
315134
316065
|
init_config$4();
|
|
315135
316066
|
init_errors$8();
|
|
315136
316067
|
MANAGED_PROVIDER_NAME$2 = "managed:blun";
|
|
315137
|
-
MANAGED_BLUN_MODEL_ALIASES$1 = new Set(["blun/king"
|
|
316068
|
+
MANAGED_BLUN_MODEL_ALIASES$1 = new Set(["blun/king"]);
|
|
315138
316069
|
ProviderManager = class {
|
|
315139
316070
|
options;
|
|
315140
316071
|
runtimeModelContexts = /* @__PURE__ */ new Map();
|
|
@@ -315153,9 +316084,7 @@ var init_provider_manager = __esmMin((() => {
|
|
|
315153
316084
|
if (providerName === void 0) throw new BlunError(ErrorCodes.CONFIG_INVALID, `Model "${model}" must define a provider in config.toml.`);
|
|
315154
316085
|
const providerConfig = this.config.providers[providerName];
|
|
315155
316086
|
if (providerConfig === void 0) throw new BlunError(ErrorCodes.CONFIG_INVALID, `Provider "${providerName}" for model "${model}" is not configured.`);
|
|
315156
|
-
|
|
315157
|
-
if (providerConfig.type === FREDRIK_GLM_PROVIDER_TYPE && (providerName !== FREDRIK_GLM_PROVIDER_ID || !isConfiguredFredrikGlmAlias(model, alias))) throw new BlunError(ErrorCodes.CONFIG_INVALID, "Fredrik GLM provider aliases must match the approved profile-local model catalog.");
|
|
315158
|
-
if (providerConfig.type !== FREDRIK_GLM_PROVIDER_TYPE && isConfiguredFredrikGlmAlias(model, alias)) throw new BlunError(ErrorCodes.CONFIG_INVALID, "Fredrik GLM aliases require the approved profile-local provider.");
|
|
316087
|
+
assertBlunProviderType(providerConfig);
|
|
315159
316088
|
const runtimeContext = this.runtimeModelContexts.get(model);
|
|
315160
316089
|
const maxContextSize = runtimeContext?.providerName === providerName && runtimeContext.model === alias.model ? runtimeContext.maxContextTokens : effectiveAlias.maxContextSize;
|
|
315161
316090
|
if (!Number.isInteger(maxContextSize) || maxContextSize <= 0) throw new BlunError(ErrorCodes.CONFIG_INVALID, `Model "${model}" must define a positive max_context_size in config.toml.`);
|
|
@@ -315169,7 +316098,7 @@ var init_provider_manager = __esmMin((() => {
|
|
|
315169
316098
|
}, provider),
|
|
315170
316099
|
alwaysThinking: (effectiveAlias.capabilities ?? []).some((c) => c.trim().toLowerCase() === "always_thinking"),
|
|
315171
316100
|
maxOutputSize: effectiveAlias.maxOutputSize,
|
|
315172
|
-
type:
|
|
316101
|
+
type: "blun"
|
|
315173
316102
|
};
|
|
315174
316103
|
}
|
|
315175
316104
|
setRuntimeModelContext(input) {
|
|
@@ -315177,7 +316106,7 @@ var init_provider_manager = __esmMin((() => {
|
|
|
315177
316106
|
if (!Number.isSafeInteger(input.maxContextTokens) || input.maxContextTokens <= 0) throw new BlunError(ErrorCodes.CONFIG_INVALID, "Runtime model context must be a positive integer.");
|
|
315178
316107
|
const alias = this.config.models?.[input.modelAlias];
|
|
315179
316108
|
const providerName = alias?.provider ?? this.config.defaultProvider;
|
|
315180
|
-
if (alias === void 0 || providerName !== input.providerName || alias.model !== input.model || providerName !== "managed:blun"
|
|
316109
|
+
if (alias === void 0 || providerName !== input.providerName || alias.model !== input.model || providerName !== "managed:blun") throw new BlunError(ErrorCodes.CONFIG_INVALID, "Runtime model context does not match the configured BLUN model.");
|
|
315181
316110
|
const previous = this.runtimeModelContexts.get(input.modelAlias);
|
|
315182
316111
|
this.runtimeModelContexts.set(input.modelAlias, {
|
|
315183
316112
|
providerName: input.providerName,
|
|
@@ -315189,7 +316118,7 @@ var init_provider_manager = __esmMin((() => {
|
|
|
315189
316118
|
resolveAuth(model, options) {
|
|
315190
316119
|
const { providerName } = this.resolveProviderConfig(model);
|
|
315191
316120
|
const providerConfig = this.config.providers[providerName];
|
|
315192
|
-
const apiKey = providerConfig
|
|
316121
|
+
const apiKey = providerConfig === void 0 ? void 0 : providerApiKey(providerConfig);
|
|
315193
316122
|
const revocationStore = this.options.managedApiKeyRevocationStore;
|
|
315194
316123
|
if (providerName === MANAGED_PROVIDER_NAME$2 && providerConfig?.oauth === void 0 && apiKey !== void 0 && revocationStore !== void 0) return this.resolveManagedApiKeyAuth(providerName, apiKey, revocationStore, options?.log);
|
|
315195
316124
|
if (providerConfig?.oauth === void 0) return void 0;
|
|
@@ -319412,6 +320341,7 @@ function toBrokerRequest$1(req, params) {
|
|
|
319412
320341
|
tool_name: req.toolName,
|
|
319413
320342
|
action: req.action,
|
|
319414
320343
|
tool_input_display: req.display,
|
|
320344
|
+
allow_edit: req.allowEdit === true ? true : void 0,
|
|
319415
320345
|
created_at: params.createdAt,
|
|
319416
320346
|
expires_at: params.expiresAt
|
|
319417
320347
|
};
|
|
@@ -319426,7 +320356,8 @@ function toAgentCoreResponse$1(resp) {
|
|
|
319426
320356
|
decision: resp.decision,
|
|
319427
320357
|
scope: resp.scope,
|
|
319428
320358
|
feedback: resp.feedback,
|
|
319429
|
-
selectedLabel: resp.selected_label
|
|
320359
|
+
selectedLabel: resp.selected_label,
|
|
320360
|
+
edited_tool_input: resp.edited_tool_input
|
|
319430
320361
|
};
|
|
319431
320362
|
}
|
|
319432
320363
|
var IApprovalService;
|
|
@@ -343030,7 +343961,7 @@ const DEFAULT_NOTIFICATIONS_CONFIG = {
|
|
|
343030
343961
|
enabled: true,
|
|
343031
343962
|
condition: "unfocused"
|
|
343032
343963
|
};
|
|
343033
|
-
const DEFAULT_UPGRADE_PREFERENCES = { autoInstall:
|
|
343964
|
+
const DEFAULT_UPGRADE_PREFERENCES = { autoInstall: false };
|
|
343034
343965
|
/**
|
|
343035
343966
|
* F2 Tippen-mit-Vorschlag: Code-Sprachen standardmäßig an, md/plain aus.
|
|
343036
343967
|
* Unbekannte Sprachen fallen auf "an" zurück (Opt-out über tui.toml).
|
|
@@ -373133,16 +374064,18 @@ var PendingApproval = class {
|
|
|
373133
374064
|
createdAt;
|
|
373134
374065
|
expiresAt;
|
|
373135
374066
|
protocolRequest;
|
|
374067
|
+
editContext;
|
|
373136
374068
|
_resolveFn;
|
|
373137
374069
|
_rejectFn;
|
|
373138
374070
|
_settled = false;
|
|
373139
|
-
constructor(approvalId, sessionId, toolCallId, createdAt, expiresAt, protocolRequest, _resolveFn, _rejectFn) {
|
|
374071
|
+
constructor(approvalId, sessionId, toolCallId, createdAt, expiresAt, protocolRequest, editContext, _resolveFn, _rejectFn) {
|
|
373140
374072
|
this.approvalId = approvalId;
|
|
373141
374073
|
this.sessionId = sessionId;
|
|
373142
374074
|
this.toolCallId = toolCallId;
|
|
373143
374075
|
this.createdAt = createdAt;
|
|
373144
374076
|
this.expiresAt = expiresAt;
|
|
373145
374077
|
this.protocolRequest = protocolRequest;
|
|
374078
|
+
this.editContext = editContext;
|
|
373146
374079
|
this._resolveFn = _resolveFn;
|
|
373147
374080
|
this._rejectFn = _rejectFn;
|
|
373148
374081
|
}
|
|
@@ -373216,7 +374149,10 @@ let ApprovalService = class ApprovalService extends Disposable {
|
|
|
373216
374149
|
toolCallId: req.toolCallId
|
|
373217
374150
|
}, "approval requested");
|
|
373218
374151
|
return new Promise((resolve, reject) => {
|
|
373219
|
-
this._pending.set(approvalId, new PendingApproval(approvalId, req.sessionId, req.toolCallId, createdAt, expiresAt, protocolRequest,
|
|
374152
|
+
this._pending.set(approvalId, new PendingApproval(approvalId, req.sessionId, req.toolCallId, createdAt, expiresAt, protocolRequest, {
|
|
374153
|
+
toolName: req.toolName,
|
|
374154
|
+
editCount: Number.isSafeInteger(req.approvalEditCount) ? req.approvalEditCount : 0
|
|
374155
|
+
}, resolve, reject));
|
|
373220
374156
|
this._byToolCallId.set(req.toolCallId, approvalId);
|
|
373221
374157
|
});
|
|
373222
374158
|
}
|
|
@@ -373245,6 +374181,14 @@ let ApprovalService = class ApprovalService extends Disposable {
|
|
|
373245
374181
|
isPending(approvalId) {
|
|
373246
374182
|
return this._pending.has(approvalId);
|
|
373247
374183
|
}
|
|
374184
|
+
getEditContext(approvalId) {
|
|
374185
|
+
const pending = this._pending.get(approvalId);
|
|
374186
|
+
if (!pending) return void 0;
|
|
374187
|
+
return {
|
|
374188
|
+
toolName: pending.editContext.toolName,
|
|
374189
|
+
editCount: pending.editContext.editCount
|
|
374190
|
+
};
|
|
374191
|
+
}
|
|
373248
374192
|
listPending(sessionId) {
|
|
373249
374193
|
return Array.from(this._pending.values()).filter((p) => p.sessionId === sessionId).map((p) => p.protocolRequest);
|
|
373250
374194
|
}
|
|
@@ -373287,6 +374231,24 @@ const approvalParamsSchema = object({
|
|
|
373287
374231
|
session_id: string().min(1),
|
|
373288
374232
|
approval_id: string().min(1)
|
|
373289
374233
|
});
|
|
374234
|
+
const EDITABLE_APPROVAL_RAW_BODY_LIMIT = 65536;
|
|
374235
|
+
async function captureEditableApprovalRawBody(req, reply, payload) {
|
|
374236
|
+
const chunks = [];
|
|
374237
|
+
let totalBytes = 0;
|
|
374238
|
+
for await (const chunk of payload) {
|
|
374239
|
+
const bytes = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk);
|
|
374240
|
+
totalBytes += bytes.length;
|
|
374241
|
+
if (totalBytes > EDITABLE_APPROVAL_RAW_BODY_LIMIT) {
|
|
374242
|
+
const error = new Error("Approval response body exceeds the editable-input limit");
|
|
374243
|
+
error.statusCode = 413;
|
|
374244
|
+
throw error;
|
|
374245
|
+
}
|
|
374246
|
+
chunks.push(bytes);
|
|
374247
|
+
}
|
|
374248
|
+
const rawBody = Buffer.concat(chunks, totalBytes);
|
|
374249
|
+
req.editableApprovalRawBody = rawBody.toString("utf8");
|
|
374250
|
+
return Readable.from([rawBody]);
|
|
374251
|
+
}
|
|
373290
374252
|
function registerApprovalsRoutes(app, ix) {
|
|
373291
374253
|
const listRoute = defineRoute({
|
|
373292
374254
|
method: "GET",
|
|
@@ -373331,7 +374293,27 @@ function registerApprovalsRoutes(app, ix) {
|
|
|
373331
374293
|
reply.send(errEnvelope(ErrorCode$1.APPROVAL_NOT_FOUND, `approval ${approval_id} not found`, req.id));
|
|
373332
374294
|
return;
|
|
373333
374295
|
}
|
|
373334
|
-
const
|
|
374296
|
+
const editContext = broker.getEditContext(approval_id);
|
|
374297
|
+
if (editContext === void 0 || typeof req.editableApprovalRawBody !== "string") {
|
|
374298
|
+
reply.send(errEnvelope(ErrorCode$1.VALIDATION_FAILED, "approval response could not be validated from its raw JSON body", req.id));
|
|
374299
|
+
return;
|
|
374300
|
+
}
|
|
374301
|
+
let inProc;
|
|
374302
|
+
try {
|
|
374303
|
+
const rawResponse = parseEditedToolInputJson(req.editableApprovalRawBody);
|
|
374304
|
+
const normalized = validateEditedApprovalDecision({
|
|
374305
|
+
response: rawResponse,
|
|
374306
|
+
toolName: editContext.toolName,
|
|
374307
|
+
editCount: editContext.editCount
|
|
374308
|
+
});
|
|
374309
|
+
inProc = normalized.decision === "edited" ? {
|
|
374310
|
+
decision: "edited",
|
|
374311
|
+
edited_tool_input: normalized.editedToolInput
|
|
374312
|
+
} : normalized;
|
|
374313
|
+
} catch (error) {
|
|
374314
|
+
reply.send(errEnvelope(ErrorCode$1.VALIDATION_FAILED, error instanceof Error ? error.message : String(error), req.id));
|
|
374315
|
+
return;
|
|
374316
|
+
}
|
|
373335
374317
|
broker.resolve(approval_id, inProc);
|
|
373336
374318
|
broker.markResolved(approval_id);
|
|
373337
374319
|
const result = {
|
|
@@ -373340,6 +374322,7 @@ function registerApprovalsRoutes(app, ix) {
|
|
|
373340
374322
|
};
|
|
373341
374323
|
reply.send(okEnvelope(result, req.id));
|
|
373342
374324
|
});
|
|
374325
|
+
route.options.preParsing = captureEditableApprovalRawBody;
|
|
373343
374326
|
app.post(route.path, route.options, route.handler);
|
|
373344
374327
|
}
|
|
373345
374328
|
//#endregion
|
|
@@ -404208,13 +405191,6 @@ const BUILTIN_SLASH_COMMAND_DEFINITIONS = [
|
|
|
404208
405191
|
completeArgs: swarmArgumentCompletions,
|
|
404209
405192
|
availability: "idle-only"
|
|
404210
405193
|
},
|
|
404211
|
-
{
|
|
404212
|
-
name: "model",
|
|
404213
|
-
aliases: [],
|
|
404214
|
-
descriptionKey: "command.model.description",
|
|
404215
|
-
priority: 96,
|
|
404216
|
-
availability: "always"
|
|
404217
|
-
},
|
|
404218
405194
|
{
|
|
404219
405195
|
name: "effort",
|
|
404220
405196
|
aliases: ["thinking"],
|
|
@@ -404666,6 +405642,7 @@ registerUiCatalogFragment({
|
|
|
404666
405642
|
//#endregion
|
|
404667
405643
|
//#region src/tui/commands/resolve.ts
|
|
404668
405644
|
const LEGACY_EFFORT_COMMANDS = new Set([
|
|
405645
|
+
"model",
|
|
404669
405646
|
"automodel",
|
|
404670
405647
|
"router"
|
|
404671
405648
|
]);
|
|
@@ -408495,6 +409472,9 @@ var TUI = class TUI extends Container {
|
|
|
408495
409472
|
setClearOnShrink(enabled) {
|
|
408496
409473
|
this.clearOnShrink = enabled;
|
|
408497
409474
|
}
|
|
409475
|
+
getRenderHeight() {
|
|
409476
|
+
return this.terminal.rows;
|
|
409477
|
+
}
|
|
408498
409478
|
setFocus(component) {
|
|
408499
409479
|
this.setFocusInternal({
|
|
408500
409480
|
component,
|
|
@@ -409103,7 +410083,7 @@ var TUI = class TUI extends Container {
|
|
|
409103
410083
|
doRender() {
|
|
409104
410084
|
if (this.stopped) return;
|
|
409105
410085
|
const width = this.terminal.columns;
|
|
409106
|
-
const height = this.
|
|
410086
|
+
const height = this.getRenderHeight();
|
|
409107
410087
|
const widthChanged = this.previousWidth !== 0 && this.previousWidth !== width;
|
|
409108
410088
|
const heightChanged = this.previousHeight !== 0 && this.previousHeight !== height;
|
|
409109
410089
|
const previousBufferLength = this.previousHeight > 0 ? this.previousViewportTop + this.previousHeight : height;
|
|
@@ -417702,168 +418682,6 @@ function segmentsFor(model) {
|
|
|
417702
418682
|
if (availability === "unsupported") return ["off"];
|
|
417703
418683
|
return ["off", "on"];
|
|
417704
418684
|
}
|
|
417705
|
-
function fredrikSelectableModels(models) {
|
|
417706
|
-
return Object.fromEntries(Object.entries(models).filter(([alias]) => isAllowedFredrikRuntimeAlias(alias, models)));
|
|
417707
|
-
}
|
|
417708
|
-
function fredrikProviderDisplayName(provider) {
|
|
417709
|
-
if (provider === "managed:blun") return PRODUCT_NAME;
|
|
417710
|
-
if (provider.startsWith("managed:")) return provider.slice(8);
|
|
417711
|
-
return provider;
|
|
417712
|
-
}
|
|
417713
|
-
function fredrikCreateModelChoices(models) {
|
|
417714
|
-
return Object.entries(fredrikSelectableModels(models)).map(([alias, configured]) => {
|
|
417715
|
-
const model = effectiveModelAlias(configured);
|
|
417716
|
-
const name = modelDisplayName$1(alias, model);
|
|
417717
|
-
const provider = fredrikProviderDisplayName(model.provider);
|
|
417718
|
-
return {
|
|
417719
|
-
alias,
|
|
417720
|
-
model,
|
|
417721
|
-
name,
|
|
417722
|
-
provider,
|
|
417723
|
-
label: `${name} (${provider})`
|
|
417724
|
-
};
|
|
417725
|
-
});
|
|
417726
|
-
}
|
|
417727
|
-
function fredrikEffortLabel(effort) {
|
|
417728
|
-
const label = effortDisplayLabel(effort);
|
|
417729
|
-
if (label !== effort || effort.length === 0) return label;
|
|
417730
|
-
return effort.charAt(0).toUpperCase() + effort.slice(1);
|
|
417731
|
-
}
|
|
417732
|
-
function fredrikDefaultThinkingEffort(model) {
|
|
417733
|
-
if (thinkingAvailability(model) === "unsupported") return "off";
|
|
417734
|
-
const efforts = effortsOf(model);
|
|
417735
|
-
if (efforts.length > 0) return model.defaultEffort ?? efforts[Math.floor(efforts.length / 2)];
|
|
417736
|
-
return "on";
|
|
417737
|
-
}
|
|
417738
|
-
function fredrikCommitEffort(choice, draft) {
|
|
417739
|
-
if (draft === "on") return fredrikDefaultThinkingEffort(choice.model);
|
|
417740
|
-
return draft;
|
|
417741
|
-
}
|
|
417742
|
-
var FredrikModelSelectorComponent = class extends Container {
|
|
417743
|
-
focused = false;
|
|
417744
|
-
opts;
|
|
417745
|
-
list;
|
|
417746
|
-
thinkingOverrides = /* @__PURE__ */ new Map();
|
|
417747
|
-
ignoreSubmitTailUntil = Date.now() + 250;
|
|
417748
|
-
constructor(opts) {
|
|
417749
|
-
super();
|
|
417750
|
-
this.opts = opts;
|
|
417751
|
-
const choices = fredrikCreateModelChoices(opts.models);
|
|
417752
|
-
const selectedIndex = choices.findIndex((choice) => choice.alias === (opts.selectedValue ?? opts.currentValue));
|
|
417753
|
-
this.list = new SearchableList({
|
|
417754
|
-
items: choices,
|
|
417755
|
-
toSearchText: (choice) => choice.label,
|
|
417756
|
-
initialIndex: Math.max(selectedIndex, 0),
|
|
417757
|
-
searchable: opts.searchable === true
|
|
417758
|
-
});
|
|
417759
|
-
}
|
|
417760
|
-
draftFor(choice) {
|
|
417761
|
-
const override = this.thinkingOverrides.get(choice.alias);
|
|
417762
|
-
if (override !== void 0) return override;
|
|
417763
|
-
if (choice.alias === this.opts.currentValue) return this.opts.currentThinkingEffort;
|
|
417764
|
-
const efforts = effortsOf(choice.model);
|
|
417765
|
-
if (efforts.length > 0) {
|
|
417766
|
-
const fallback = choice.model.defaultEffort ?? efforts[Math.floor(efforts.length / 2)];
|
|
417767
|
-
if (fallback !== void 0 && efforts.includes(fallback)) return fallback;
|
|
417768
|
-
return efforts[0];
|
|
417769
|
-
}
|
|
417770
|
-
return thinkingAvailability(choice.model) !== "unsupported" ? "on" : "off";
|
|
417771
|
-
}
|
|
417772
|
-
effectiveEffort(choice) {
|
|
417773
|
-
const draft = this.draftFor(choice);
|
|
417774
|
-
const segments = segmentsFor(choice.model);
|
|
417775
|
-
return segments.includes(draft) ? draft : segments[0];
|
|
417776
|
-
}
|
|
417777
|
-
handleInput(data) {
|
|
417778
|
-
if (isKeyRelease(data)) return;
|
|
417779
|
-
if (Date.now() <= this.ignoreSubmitTailUntil && /^[\r\n]+$/.test(data)) return;
|
|
417780
|
-
this.ignoreSubmitTailUntil = 0;
|
|
417781
|
-
if (matchesKey(data, Key.escape)) {
|
|
417782
|
-
if (this.list.clearQuery()) return;
|
|
417783
|
-
this.opts.onCancel();
|
|
417784
|
-
return;
|
|
417785
|
-
}
|
|
417786
|
-
if (this.list.handleKey(data)) return;
|
|
417787
|
-
if (matchesKey(data, Key.left) || matchesKey(data, Key.right)) {
|
|
417788
|
-
const selected = this.selectedChoice();
|
|
417789
|
-
if (selected !== void 0) {
|
|
417790
|
-
const segments = segmentsFor(selected.model);
|
|
417791
|
-
if (segments.length > 1) {
|
|
417792
|
-
const current = this.effectiveEffort(selected);
|
|
417793
|
-
const index = segments.indexOf(current);
|
|
417794
|
-
const delta = matchesKey(data, Key.left) ? -1 : 1;
|
|
417795
|
-
const next = Math.max(0, Math.min(segments.length - 1, index + delta));
|
|
417796
|
-
if (next !== index) this.thinkingOverrides.set(selected.alias, segments[next]);
|
|
417797
|
-
}
|
|
417798
|
-
}
|
|
417799
|
-
return;
|
|
417800
|
-
}
|
|
417801
|
-
if (matchesKey(data, Key.enter)) {
|
|
417802
|
-
const selected = this.selectedChoice();
|
|
417803
|
-
if (selected === void 0) return;
|
|
417804
|
-
this.opts.onSelect({
|
|
417805
|
-
alias: selected.alias,
|
|
417806
|
-
thinking: fredrikCommitEffort(selected, this.effectiveEffort(selected))
|
|
417807
|
-
});
|
|
417808
|
-
return;
|
|
417809
|
-
}
|
|
417810
|
-
if (matchesKey(data, Key.alt("s")) && this.opts.onSessionOnlySelect !== void 0) {
|
|
417811
|
-
const selected = this.selectedChoice();
|
|
417812
|
-
if (selected === void 0) return;
|
|
417813
|
-
this.opts.onSessionOnlySelect({
|
|
417814
|
-
alias: selected.alias,
|
|
417815
|
-
thinking: fredrikCommitEffort(selected, this.effectiveEffort(selected))
|
|
417816
|
-
});
|
|
417817
|
-
}
|
|
417818
|
-
}
|
|
417819
|
-
render(width) {
|
|
417820
|
-
const view = this.list.view();
|
|
417821
|
-
const totalCount = Object.keys(fredrikSelectableModels(this.opts.models)).length;
|
|
417822
|
-
const titleSuffix = this.opts.searchable === true && view.query.length === 0 ? currentTheme.fg("textMuted", ` (${uiText("model.typeToSearch")})`) : "";
|
|
417823
|
-
const lines = [
|
|
417824
|
-
currentTheme.fg("primary", "-".repeat(width)),
|
|
417825
|
-
currentTheme.boldFg("primary", ` ${uiText("model.title")}`) + titleSuffix,
|
|
417826
|
-
currentTheme.fg("textMuted", ` ${uiText("model.navigate")} | ${uiText("model.thinking")} (Left/Right) | Enter ${uiText("model.select")} | Esc ${uiText("model.cancel")}`),
|
|
417827
|
-
""
|
|
417828
|
-
];
|
|
417829
|
-
if (view.query.length > 0) lines.push(currentTheme.fg("primary", ` ${uiText("model.search")}: `) + currentTheme.fg("text", view.query));
|
|
417830
|
-
if (view.items.length === 0) lines.push(currentTheme.fg("textMuted", ` ${uiText("model.noMatches")}`));
|
|
417831
|
-
for (let index = view.page.start; index < view.page.end; index++) {
|
|
417832
|
-
const choice = view.items[index];
|
|
417833
|
-
if (choice === void 0) continue;
|
|
417834
|
-
const selected = index === view.selectedIndex;
|
|
417835
|
-
const current = choice.alias === this.opts.currentValue;
|
|
417836
|
-
const pointer = selected ? ">" : " ";
|
|
417837
|
-
let line = currentTheme.fg(selected ? "primary" : "textDim", ` ${pointer} `);
|
|
417838
|
-
line += selected ? currentTheme.boldFg("primary", choice.name) : currentTheme.fg("text", choice.name);
|
|
417839
|
-
line += " " + currentTheme.fg("textMuted", choice.provider);
|
|
417840
|
-
if (current) line += " " + currentTheme.fg("success", currentMark());
|
|
417841
|
-
lines.push(line);
|
|
417842
|
-
}
|
|
417843
|
-
if (view.query.length > 0) lines.push("", currentTheme.fg("textMuted", ` ${String(view.items.length)} / ${String(totalCount)}`));
|
|
417844
|
-
lines.push("");
|
|
417845
|
-
const selected = this.selectedChoice();
|
|
417846
|
-
if (selected !== void 0) {
|
|
417847
|
-
lines.push(currentTheme.fg("textMuted", ` ${uiText("model.thinking")} (Left/Right ${uiText("model.toSwitch")})`));
|
|
417848
|
-
lines.push(this.renderThinkingControl(selected));
|
|
417849
|
-
}
|
|
417850
|
-
lines.push("", currentTheme.fg("primary", "-".repeat(width)));
|
|
417851
|
-
return lines.map((line) => truncateToWidth(line, width));
|
|
417852
|
-
}
|
|
417853
|
-
selectedChoice() {
|
|
417854
|
-
return this.list.selected();
|
|
417855
|
-
}
|
|
417856
|
-
renderThinkingControl(choice) {
|
|
417857
|
-
const segment = (label, active) => active ? currentTheme.boldFg("primary", `[ ${label} ]`) : currentTheme.fg("text", ` ${label} `);
|
|
417858
|
-
const unavailable = (label) => currentTheme.fg("textMuted", ` ${label} (${uiText("model.unsupported")}) `);
|
|
417859
|
-
const efforts = effortsOf(choice.model);
|
|
417860
|
-
const availability = thinkingAvailability(choice.model);
|
|
417861
|
-
if (efforts.length === 0 && availability === "always-on") return ` ${segment(uiText("model.on"), true)} ${unavailable(uiText("model.off"))}`;
|
|
417862
|
-
if (efforts.length === 0 && availability === "unsupported") return ` ${unavailable(uiText("model.on"))} ${segment(uiText("model.off"), true)}`;
|
|
417863
|
-
const active = this.effectiveEffort(choice);
|
|
417864
|
-
return ` ${segmentsFor(choice.model).map((effort) => segment(fredrikEffortLabel(effort), effort === active)).join(" ")}`;
|
|
417865
|
-
}
|
|
417866
|
-
};
|
|
417867
418685
|
//#endregion
|
|
417868
418686
|
//#region src/tui/components/dialogs/permission-selector.ts
|
|
417869
418687
|
function permissionOptions() {
|
|
@@ -421669,47 +422487,6 @@ async function handleThemeCommand(host, args) {
|
|
|
421669
422487
|
}
|
|
421670
422488
|
await applyThemeChoice(host, theme);
|
|
421671
422489
|
}
|
|
421672
|
-
function resolveFredrikModelArgument(models, raw) {
|
|
421673
|
-
const query = raw.trim().toLowerCase();
|
|
421674
|
-
if (query.length === 0) return void 0;
|
|
421675
|
-
return Object.entries(models).filter(([alias]) => isAllowedFredrikRuntimeAlias(alias, models)).find(([alias, model]) => [alias, model.model, model.displayName].filter((value) => typeof value === "string").some((value) => value.toLowerCase() === query))?.[0];
|
|
421676
|
-
}
|
|
421677
|
-
function showFredrikModelPicker(host, selectedValue = host.state.appState.model) {
|
|
421678
|
-
const models = fredrikSelectableModels(host.state.appState.availableModels);
|
|
421679
|
-
host.mountEditorReplacement(new FredrikModelSelectorComponent({
|
|
421680
|
-
models,
|
|
421681
|
-
currentValue: host.state.appState.model,
|
|
421682
|
-
selectedValue,
|
|
421683
|
-
currentThinkingEffort: host.state.appState.thinkingEffort,
|
|
421684
|
-
searchable: true,
|
|
421685
|
-
onSelect: (selection) => {
|
|
421686
|
-
host.restoreEditorAfter(() => performModelSwitch(host, selection.alias, selection.thinking, false));
|
|
421687
|
-
},
|
|
421688
|
-
onSessionOnlySelect: (selection) => {
|
|
421689
|
-
host.restoreEditorAfter(() => performModelSwitch(host, selection.alias, selection.thinking, false));
|
|
421690
|
-
},
|
|
421691
|
-
onCancel: () => {
|
|
421692
|
-
host.restoreEditor();
|
|
421693
|
-
}
|
|
421694
|
-
}));
|
|
421695
|
-
}
|
|
421696
|
-
async function handleModelCommand(host, args) {
|
|
421697
|
-
if (host.session === void 0) {
|
|
421698
|
-
host.showError(noActiveSessionMessage());
|
|
421699
|
-
return;
|
|
421700
|
-
}
|
|
421701
|
-
const raw = args.trim();
|
|
421702
|
-
if (raw.length === 0) {
|
|
421703
|
-
showFredrikModelPicker(host);
|
|
421704
|
-
return;
|
|
421705
|
-
}
|
|
421706
|
-
const alias = resolveFredrikModelArgument(host.state.appState.availableModels, raw);
|
|
421707
|
-
if (alias === void 0) {
|
|
421708
|
-
host.showError(uiText("config.model.unknownAlias", { alias: raw }));
|
|
421709
|
-
return;
|
|
421710
|
-
}
|
|
421711
|
-
showFredrikModelPicker(host, alias);
|
|
421712
|
-
}
|
|
421713
422490
|
async function handleEffortCommand(host, args) {
|
|
421714
422491
|
const alias = host.state.appState.model;
|
|
421715
422492
|
const model = host.state.appState.availableModels[alias];
|
|
@@ -421741,7 +422518,7 @@ async function handleEffortCommand(host, args) {
|
|
|
421741
422518
|
}));
|
|
421742
422519
|
return;
|
|
421743
422520
|
}
|
|
421744
|
-
await performEffortSelection(host, alias, arg,
|
|
422521
|
+
await performEffortSelection(host, alias, arg, true);
|
|
421745
422522
|
}
|
|
421746
422523
|
function showEffortPicker(host, model, segments) {
|
|
421747
422524
|
const liveEffort = host.state.appState.thinkingEffort;
|
|
@@ -421752,7 +422529,7 @@ function showEffortPicker(host, model, segments) {
|
|
|
421752
422529
|
currentValue,
|
|
421753
422530
|
currentBlunSwarm: host.state.appState.swarmMode && host.state.appState.swarmModeEntry === "effort",
|
|
421754
422531
|
onSelect: (effort) => {
|
|
421755
|
-
host.restoreEditorAfter(() => performEffortSelection(host, alias, effort,
|
|
422532
|
+
host.restoreEditorAfter(() => performEffortSelection(host, alias, effort, true));
|
|
421756
422533
|
},
|
|
421757
422534
|
onSessionOnlySelect: (effort) => {
|
|
421758
422535
|
host.restoreEditorAfter(() => performEffortSelection(host, alias, effort, false));
|
|
@@ -432550,6 +433327,11 @@ function agentSwarmResultSummaryFromOutput(output) {
|
|
|
432550
433327
|
};
|
|
432551
433328
|
}
|
|
432552
433329
|
function parseAgentSwarmResultStatuses(output) {
|
|
433330
|
+
const structured = parseStructuredSwarmDisplay(output);
|
|
433331
|
+
if (structured.recognized) return structured.statuses.map((entry) => ({
|
|
433332
|
+
...entry,
|
|
433333
|
+
status: entry.status === "aborted" ? "cancelled" : entry.status
|
|
433334
|
+
}));
|
|
432553
433335
|
const xmlStatuses = parseAgentSwarmXmlResultStatuses(output);
|
|
432554
433336
|
if (xmlStatuses.length > 0) return xmlStatuses;
|
|
432555
433337
|
return parseAgentSwarmLegacyResultStatuses(output);
|
|
@@ -493011,12 +493793,28 @@ registerUiCatalogFragment({
|
|
|
493011
493793
|
en: {
|
|
493012
493794
|
"thinking.label": "{name} thinking",
|
|
493013
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}",
|
|
493014
493804
|
"thinking.tokens.one": "{count} Token",
|
|
493015
493805
|
"thinking.tokens.other": "{count} Tokens"
|
|
493016
493806
|
},
|
|
493017
493807
|
de: {
|
|
493018
493808
|
"thinking.label": "{name} denkt",
|
|
493019
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}",
|
|
493020
493818
|
"thinking.tokens.one": "{count} Token",
|
|
493021
493819
|
"thinking.tokens.other": "{count} Tokens"
|
|
493022
493820
|
},
|
|
@@ -493070,6 +493868,14 @@ var ThinkingComponent = class {
|
|
|
493070
493868
|
thinkElapsedMs = 0;
|
|
493071
493869
|
thinkAborted = false;
|
|
493072
493870
|
estimatedOutputTokens = 0;
|
|
493871
|
+
step;
|
|
493872
|
+
thinkingEffort;
|
|
493873
|
+
attempt = 1;
|
|
493874
|
+
maxAttempts = 1;
|
|
493875
|
+
completionBudget;
|
|
493876
|
+
lastHeartbeatAtMs;
|
|
493877
|
+
activeToolName;
|
|
493878
|
+
finishedAtMs;
|
|
493073
493879
|
textComponent;
|
|
493074
493880
|
renderCache;
|
|
493075
493881
|
constructor(text, showMarker = true, mode = "finalized", ui, metrics) {
|
|
@@ -493084,6 +493890,7 @@ var ThinkingComponent = class {
|
|
|
493084
493890
|
this.thinkStartMs = metrics?.startedAtMs ?? Date.now();
|
|
493085
493891
|
this.thinkAborted = false;
|
|
493086
493892
|
this.estimatedOutputTokens = metrics?.estimatedOutputTokens ?? 0;
|
|
493893
|
+
this.applyLiveMetrics(metrics ?? {});
|
|
493087
493894
|
}
|
|
493088
493895
|
}
|
|
493089
493896
|
markRenderDirty() {
|
|
@@ -493102,10 +493909,22 @@ var ThinkingComponent = class {
|
|
|
493102
493909
|
}
|
|
493103
493910
|
setLiveMetrics(metrics) {
|
|
493104
493911
|
if (this.mode === "live" && !this.thinkAborted && metrics.startedAtMs !== void 0) this.thinkStartMs = metrics.startedAtMs;
|
|
493105
|
-
|
|
493912
|
+
const before = JSON.stringify([this.estimatedOutputTokens, this.step, this.thinkingEffort, this.attempt, this.maxAttempts, this.completionBudget, this.lastHeartbeatAtMs, this.activeToolName]);
|
|
493106
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;
|
|
493107
493917
|
this.markRenderDirty();
|
|
493108
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
|
+
}
|
|
493109
493928
|
styled(text) {
|
|
493110
493929
|
return currentTheme.italicFg("textDim", text);
|
|
493111
493930
|
}
|
|
@@ -493117,6 +493936,7 @@ var ThinkingComponent = class {
|
|
|
493117
493936
|
this.thinkElapsedMs = Date.now() - this.thinkStartMs;
|
|
493118
493937
|
this.thinkStartMs = null;
|
|
493119
493938
|
}
|
|
493939
|
+
this.finishedAtMs = Date.now();
|
|
493120
493940
|
}
|
|
493121
493941
|
dispose() {
|
|
493122
493942
|
this.stopSpinner();
|
|
@@ -493140,12 +493960,24 @@ var ThinkingComponent = class {
|
|
|
493140
493960
|
const abortMark = this.thinkAborted ? ` (${uiText("thinking.aborted")})` : "";
|
|
493141
493961
|
const tokenKey = roundedTokenCount === 1 ? "thinking.tokens.one" : "thinking.tokens.other";
|
|
493142
493962
|
const thinkingLabel = uiText("thinking.label", { name: this.persona });
|
|
493143
|
-
const
|
|
493144
|
-
|
|
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}`;
|
|
493145
493973
|
const metricsOnly = `(${elapsed} · ${startedAt})${abortMark}`;
|
|
493146
493974
|
const availableWidth = Math.max(1, width - visibleWidth(spinner));
|
|
493147
493975
|
const label = visibleWidth(fullLabel) <= availableWidth ? fullLabel : visibleWidth(compactLabel) <= availableWidth ? compactLabel : metricsOnly;
|
|
493148
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)))];
|
|
493149
493981
|
} else rendered = [""];
|
|
493150
493982
|
if (isRenderCacheEnabled()) this.renderCache = {
|
|
493151
493983
|
width,
|
|
@@ -497454,9 +498286,6 @@ async function handleBuiltInSlashCommand(host, name, args) {
|
|
|
497454
498286
|
case "theme":
|
|
497455
498287
|
await handleThemeCommand(host, args);
|
|
497456
498288
|
return;
|
|
497457
|
-
case "model":
|
|
497458
|
-
await handleModelCommand(host, args);
|
|
497459
|
-
return;
|
|
497460
498289
|
case "effort":
|
|
497461
498290
|
await handleEffortCommand(host, args);
|
|
497462
498291
|
return;
|
|
@@ -499539,9 +500368,11 @@ registerUiCatalogFragment({
|
|
|
499539
500368
|
"approval.search.scope": "scope: {scope}",
|
|
499540
500369
|
"approval.backgroundTask": "{status} {kind} task {taskId}: {description}",
|
|
499541
500370
|
"approval.hint.feedback": "Type feedback · ↵ submit.",
|
|
500371
|
+
"approval.hint.editArguments": "Enter the complete replacement JSON object · ↵ submit.",
|
|
499542
500372
|
"approval.hint.main": "↑/↓ select · {numbers} choose · ↵ confirm{preview}",
|
|
499543
500373
|
"approval.hint.preview": " · ctrl+e preview",
|
|
499544
500374
|
"approval.choice.approveOnce": "Approve once",
|
|
500375
|
+
"approval.choice.editArguments": "Edit arguments (JSON)",
|
|
499545
500376
|
"approval.choice.approveSession": "Approve for this session",
|
|
499546
500377
|
"approval.choice.reject": "Reject",
|
|
499547
500378
|
"approval.choice.rejectFeedback": "Reject with feedback",
|
|
@@ -499551,6 +500382,7 @@ registerUiCatalogFragment({
|
|
|
499551
500382
|
"approval.transcript.approvedSession": "Approved for session",
|
|
499552
500383
|
"approval.transcript.rejected": "Rejected",
|
|
499553
500384
|
"approval.transcript.cancelled": "Cancelled",
|
|
500385
|
+
"approval.transcript.edited": "Arguments edited",
|
|
499554
500386
|
"approval.transcript.action": "{decision}: {action}",
|
|
499555
500387
|
"approval.transcript.actionWithFeedback": "{decision}: {action} — \"{feedback}\""
|
|
499556
500388
|
},
|
|
@@ -499570,9 +500402,11 @@ registerUiCatalogFragment({
|
|
|
499570
500402
|
"approval.search.scope": "Bereich: {scope}",
|
|
499571
500403
|
"approval.backgroundTask": "Aufgabe {taskId} ({status}, {kind}): {description}",
|
|
499572
500404
|
"approval.hint.feedback": "Feedback eingeben · ↵ absenden.",
|
|
500405
|
+
"approval.hint.editArguments": "Vollständiges Ersatz-JSON-Objekt eingeben · ↵ absenden.",
|
|
499573
500406
|
"approval.hint.main": "↑/↓ auswählen · {numbers} wählen · ↵ bestätigen{preview}",
|
|
499574
500407
|
"approval.hint.preview": " · ctrl+e Vorschau",
|
|
499575
500408
|
"approval.choice.approveOnce": "Einmal genehmigen",
|
|
500409
|
+
"approval.choice.editArguments": "Argumente bearbeiten (JSON)",
|
|
499576
500410
|
"approval.choice.approveSession": "Für diese Sitzung genehmigen",
|
|
499577
500411
|
"approval.choice.reject": "Ablehnen",
|
|
499578
500412
|
"approval.choice.rejectFeedback": "Ablehnen und Feedback geben",
|
|
@@ -499582,6 +500416,7 @@ registerUiCatalogFragment({
|
|
|
499582
500416
|
"approval.transcript.approvedSession": "Für diese Sitzung genehmigt",
|
|
499583
500417
|
"approval.transcript.rejected": "Abgelehnt",
|
|
499584
500418
|
"approval.transcript.cancelled": "Abgebrochen",
|
|
500419
|
+
"approval.transcript.edited": "Argumente bearbeitet",
|
|
499585
500420
|
"approval.transcript.action": "{decision}: {action}",
|
|
499586
500421
|
"approval.transcript.actionWithFeedback": "{decision}: {action} – „{feedback}“"
|
|
499587
500422
|
},
|
|
@@ -499601,9 +500436,11 @@ registerUiCatalogFragment({
|
|
|
499601
500436
|
"approval.search.scope": "Ámbito: {scope}",
|
|
499602
500437
|
"approval.backgroundTask": "Tarea {taskId} ({status}, {kind}): {description}",
|
|
499603
500438
|
"approval.hint.feedback": "Escribe tus comentarios · ↵ enviar.",
|
|
500439
|
+
"approval.hint.editArguments": "Introduce el objeto JSON completo de sustitución · ↵ enviar.",
|
|
499604
500440
|
"approval.hint.main": "↑/↓ seleccionar · {numbers} elegir · ↵ confirmar{preview}",
|
|
499605
500441
|
"approval.hint.preview": " · ctrl+e vista previa",
|
|
499606
500442
|
"approval.choice.approveOnce": "Aprobar una vez",
|
|
500443
|
+
"approval.choice.editArguments": "Editar argumentos (JSON)",
|
|
499607
500444
|
"approval.choice.approveSession": "Aprobar durante esta sesión",
|
|
499608
500445
|
"approval.choice.reject": "Rechazar",
|
|
499609
500446
|
"approval.choice.rejectFeedback": "Rechazar y enviar comentarios",
|
|
@@ -499613,6 +500450,7 @@ registerUiCatalogFragment({
|
|
|
499613
500450
|
"approval.transcript.approvedSession": "Aprobado durante esta sesión",
|
|
499614
500451
|
"approval.transcript.rejected": "Rechazado",
|
|
499615
500452
|
"approval.transcript.cancelled": "Cancelado",
|
|
500453
|
+
"approval.transcript.edited": "Argumentos modificados",
|
|
499616
500454
|
"approval.transcript.action": "{decision}: {action}",
|
|
499617
500455
|
"approval.transcript.actionWithFeedback": "{decision}: {action} — «{feedback}»"
|
|
499618
500456
|
},
|
|
@@ -499632,9 +500470,11 @@ registerUiCatalogFragment({
|
|
|
499632
500470
|
"approval.search.scope": "Portée : {scope}",
|
|
499633
500471
|
"approval.backgroundTask": "Tâche {taskId} ({status}, {kind}) : {description}",
|
|
499634
500472
|
"approval.hint.feedback": "Saisissez un commentaire · ↵ envoyer.",
|
|
500473
|
+
"approval.hint.editArguments": "Saisissez l’objet JSON de remplacement complet · ↵ envoyer.",
|
|
499635
500474
|
"approval.hint.main": "↑/↓ sélectionner · {numbers} choisir · ↵ confirmer{preview}",
|
|
499636
500475
|
"approval.hint.preview": " · ctrl+e aperçu",
|
|
499637
500476
|
"approval.choice.approveOnce": "Approuver une fois",
|
|
500477
|
+
"approval.choice.editArguments": "Modifier les arguments (JSON)",
|
|
499638
500478
|
"approval.choice.approveSession": "Approuver pour cette session",
|
|
499639
500479
|
"approval.choice.reject": "Refuser",
|
|
499640
500480
|
"approval.choice.rejectFeedback": "Refuser et ajouter un commentaire",
|
|
@@ -499644,6 +500484,7 @@ registerUiCatalogFragment({
|
|
|
499644
500484
|
"approval.transcript.approvedSession": "Approuvé pour cette session",
|
|
499645
500485
|
"approval.transcript.rejected": "Refusé",
|
|
499646
500486
|
"approval.transcript.cancelled": "Annulé",
|
|
500487
|
+
"approval.transcript.edited": "Arguments modifiés",
|
|
499647
500488
|
"approval.transcript.action": "{decision} : {action}",
|
|
499648
500489
|
"approval.transcript.actionWithFeedback": "{decision} : {action} — « {feedback} »"
|
|
499649
500490
|
},
|
|
@@ -499663,9 +500504,11 @@ registerUiCatalogFragment({
|
|
|
499663
500504
|
"approval.search.scope": "Omfattning: {scope}",
|
|
499664
500505
|
"approval.backgroundTask": "Uppgift {taskId} ({status}, {kind}): {description}",
|
|
499665
500506
|
"approval.hint.feedback": "Skriv återkoppling · ↵ skicka.",
|
|
500507
|
+
"approval.hint.editArguments": "Ange hela JSON-objektet som ska ersätta det befintliga · ↵ skicka.",
|
|
499666
500508
|
"approval.hint.main": "↑/↓ markera · {numbers} välj · ↵ bekräfta{preview}",
|
|
499667
500509
|
"approval.hint.preview": " · ctrl+e förhandsgranska",
|
|
499668
500510
|
"approval.choice.approveOnce": "Godkänn en gång",
|
|
500511
|
+
"approval.choice.editArguments": "Redigera argument (JSON)",
|
|
499669
500512
|
"approval.choice.approveSession": "Godkänn för den här sessionen",
|
|
499670
500513
|
"approval.choice.reject": "Avvisa",
|
|
499671
500514
|
"approval.choice.rejectFeedback": "Avvisa och lämna återkoppling",
|
|
@@ -499675,6 +500518,7 @@ registerUiCatalogFragment({
|
|
|
499675
500518
|
"approval.transcript.approvedSession": "Godkänt för den här sessionen",
|
|
499676
500519
|
"approval.transcript.rejected": "Avvisat",
|
|
499677
500520
|
"approval.transcript.cancelled": "Avbrutet",
|
|
500521
|
+
"approval.transcript.edited": "Argument redigerade",
|
|
499678
500522
|
"approval.transcript.action": "{decision}: {action}",
|
|
499679
500523
|
"approval.transcript.actionWithFeedback": "{decision}: {action} – ”{feedback}”"
|
|
499680
500524
|
},
|
|
@@ -499858,7 +500702,7 @@ var ApprovalPanelComponent = class extends Container {
|
|
|
499858
500702
|
if (!option) return;
|
|
499859
500703
|
this.onResponse({
|
|
499860
500704
|
response: option.response,
|
|
499861
|
-
feedback: feedback || void 0,
|
|
500705
|
+
...(option.input_kind === "edited_tool_input_json" ? { edited_tool_input_json: feedback } : { feedback: feedback || void 0 }),
|
|
499862
500706
|
selected_label: option.selected_label
|
|
499863
500707
|
});
|
|
499864
500708
|
}
|
|
@@ -499868,6 +500712,7 @@ var ApprovalPanelComponent = class extends Container {
|
|
|
499868
500712
|
if (option.requires_feedback === true) {
|
|
499869
500713
|
this.selectedIndex = index;
|
|
499870
500714
|
this.feedbackMode = true;
|
|
500715
|
+
if (option.input_kind === "edited_tool_input_json") this.feedbackInput.setValue(this.request.data.editable_tool_input_json ?? "{}");
|
|
499871
500716
|
} else this.submit(index);
|
|
499872
500717
|
}
|
|
499873
500718
|
handleInput(data) {
|
|
@@ -499964,7 +500809,7 @@ var ApprovalPanelComponent = class extends Container {
|
|
|
499964
500809
|
if (option.description !== void 0 && option.description.length > 0 && !(this.feedbackMode && option.requires_feedback === true && isSelected)) for (const descLine of wrapTextWithAnsi(option.description, Math.max(20, width - 7))) lines.push(indent(` ${dim(descLine)}`));
|
|
499965
500810
|
}
|
|
499966
500811
|
lines.push("");
|
|
499967
|
-
if (this.feedbackMode) lines.push(indent(dim(uiText("approval.hint.feedback"))));
|
|
500812
|
+
if (this.feedbackMode) lines.push(indent(dim(uiText(this.choiceAt(this.selectedIndex)?.input_kind === "edited_tool_input_json" ? "approval.hint.editArguments" : "approval.hint.feedback"))));
|
|
499968
500813
|
else {
|
|
499969
500814
|
const expandHint = hasPreviewable ? uiText("approval.hint.preview") : "";
|
|
499970
500815
|
lines.push(indent(dim(uiText("approval.hint.main", {
|
|
@@ -503221,12 +504066,18 @@ async function refreshAllProviderModels(host, options = {}) {
|
|
|
503221
504066
|
}
|
|
503222
504067
|
//#endregion
|
|
503223
504068
|
//#region src/tui/reverse-rpc/approval/adapter.ts
|
|
503224
|
-
function defaultApprovalChoices() {
|
|
504069
|
+
function defaultApprovalChoices(allowEdit = false) {
|
|
503225
504070
|
return [
|
|
503226
504071
|
{
|
|
503227
504072
|
label: uiText("approval.choice.approveOnce"),
|
|
503228
504073
|
response: "approved"
|
|
503229
504074
|
},
|
|
504075
|
+
...allowEdit ? [{
|
|
504076
|
+
label: uiText("approval.choice.editArguments"),
|
|
504077
|
+
response: "edited",
|
|
504078
|
+
requires_feedback: true,
|
|
504079
|
+
input_kind: "edited_tool_input_json"
|
|
504080
|
+
}] : [],
|
|
503230
504081
|
{
|
|
503231
504082
|
label: uiText("approval.choice.approveSession"),
|
|
503232
504083
|
response: "approved_for_session"
|
|
@@ -503263,7 +504114,8 @@ function adaptApprovalRequest(event) {
|
|
|
503263
504114
|
action: resolved.action ?? event.action,
|
|
503264
504115
|
description: resolved.description,
|
|
503265
504116
|
display: resolved.blocks,
|
|
503266
|
-
choices: adaptChoices(event.toolName, event.display)
|
|
504117
|
+
choices: adaptChoices(event.toolName, event.display, event.allowEdit === true),
|
|
504118
|
+
editable_tool_input_json: event.allowEdit === true ? canonicalEditedToolInputJson(event.editableToolInput) : void 0
|
|
503267
504119
|
};
|
|
503268
504120
|
}
|
|
503269
504121
|
function resolveDisplay(toolName, display, action) {
|
|
@@ -503367,6 +504219,10 @@ function inferFileOp(toolName) {
|
|
|
503367
504219
|
return "read";
|
|
503368
504220
|
}
|
|
503369
504221
|
function adaptPanelResponse(response) {
|
|
504222
|
+
if (response.response === "edited") return {
|
|
504223
|
+
decision: "edited",
|
|
504224
|
+
edited_tool_input_json: response.edited_tool_input_json
|
|
504225
|
+
};
|
|
503370
504226
|
if (response.response === "approved_for_session") return {
|
|
503371
504227
|
decision: "approved",
|
|
503372
504228
|
scope: "session",
|
|
@@ -503530,10 +504386,10 @@ function adaptDisplay(display) {
|
|
|
503530
504386
|
default: return [];
|
|
503531
504387
|
}
|
|
503532
504388
|
}
|
|
503533
|
-
function adaptChoices(toolName, display) {
|
|
504389
|
+
function adaptChoices(toolName, display, allowEdit = false) {
|
|
503534
504390
|
if (toolName === "ExitPlanMode" || display.kind === "plan_review") return adaptPlanReviewChoices(display);
|
|
503535
504391
|
if (display.kind === "goal_start") return adaptGoalStartChoices(display);
|
|
503536
|
-
return defaultApprovalChoices();
|
|
504392
|
+
return defaultApprovalChoices(allowEdit);
|
|
503537
504393
|
}
|
|
503538
504394
|
function adaptGoalStartChoices(display) {
|
|
503539
504395
|
return goalStartOptions(display.mode).map((option) => option.value === "cancel" ? {
|
|
@@ -503629,7 +504485,7 @@ function createApprovalRequestHandler(controller, onResponse, options = {}) {
|
|
|
503629
504485
|
}).catch(() => {});
|
|
503630
504486
|
}
|
|
503631
504487
|
const response = await pending;
|
|
503632
|
-
relay?.complete(response);
|
|
504488
|
+
relay?.complete(response.decision === "edited" ? { decision: "edited" } : response);
|
|
503633
504489
|
onResponse?.(event, response);
|
|
503634
504490
|
return response;
|
|
503635
504491
|
} catch {
|
|
@@ -503676,10 +504532,7 @@ function applyManagedAccountContext(models, maxContextTokens) {
|
|
|
503676
504532
|
maxContextSize: maxContextTokens
|
|
503677
504533
|
} }
|
|
503678
504534
|
};
|
|
503679
|
-
return {
|
|
503680
|
-
[BLUN_KING_MODEL_ALIAS]: king,
|
|
503681
|
-
...configuredFredrikGlmModels(models)
|
|
503682
|
-
};
|
|
504535
|
+
return { [BLUN_KING_MODEL_ALIAS]: king };
|
|
503683
504536
|
}
|
|
503684
504537
|
function normalizeKingProductEffort(value) {
|
|
503685
504538
|
if (value === "none" || value === "minimal" || value === "off") return "low";
|
|
@@ -503735,11 +504588,7 @@ function nextManagedQuotaWarning(windows, highestShown) {
|
|
|
503735
504588
|
//#region src/tui/controllers/auth-flow.ts
|
|
503736
504589
|
function managedProviderOnly(providers) {
|
|
503737
504590
|
const managed = providers[DEFAULT_OAUTH_PROVIDER_NAME];
|
|
503738
|
-
|
|
503739
|
-
return {
|
|
503740
|
-
...managed === void 0 ? {} : { [DEFAULT_OAUTH_PROVIDER_NAME]: managed },
|
|
503741
|
-
...fredrikGlm === void 0 ? {} : { [FREDRIK_GLM_PROVIDER_ID]: fredrikGlm }
|
|
503742
|
-
};
|
|
504591
|
+
return managed === void 0 ? {} : { [DEFAULT_OAUTH_PROVIDER_NAME]: managed };
|
|
503743
504592
|
}
|
|
503744
504593
|
var AuthFlowController = class {
|
|
503745
504594
|
host;
|
|
@@ -507718,6 +508567,9 @@ var BottomPinnedTUI = class extends TUI {
|
|
|
507718
508567
|
* page-up/down jumps without re-reading the live (possibly stale) value.
|
|
507719
508568
|
*/
|
|
507720
508569
|
getTerminalRows() {
|
|
508570
|
+
return this.getRenderHeight();
|
|
508571
|
+
}
|
|
508572
|
+
getRenderHeight() {
|
|
507721
508573
|
this.ensureResizeLatch();
|
|
507722
508574
|
return this.latchedTerminalRows > 0 ? this.latchedTerminalRows : currentTerminalRows(this.terminal.rows);
|
|
507723
508575
|
}
|
|
@@ -509848,7 +510700,7 @@ var SessionEventHandler = class {
|
|
|
509848
510700
|
this.host.commitQueuedSteerAtStepStart(event.turnId);
|
|
509849
510701
|
this.host.commitChannelPromptAtStepStart(event.turnId);
|
|
509850
510702
|
this.host.streamingUI.flushNow();
|
|
509851
|
-
this.host.streamingUI.
|
|
510703
|
+
this.host.streamingUI.beginStep(event);
|
|
509852
510704
|
this.host.streamingUI.resetToolUi();
|
|
509853
510705
|
this.host.streamingUI.finalizeLiveTextBuffers("waiting");
|
|
509854
510706
|
this.host.patchLivePane({
|
|
@@ -509922,7 +510774,8 @@ var SessionEventHandler = class {
|
|
|
509922
510774
|
handleStepRetrying(event) {
|
|
509923
510775
|
this.turnWatchdog.recordProgress();
|
|
509924
510776
|
const hint = formatModelRetryProgress(event);
|
|
509925
|
-
|
|
510777
|
+
const completionBudgetRetry = event.completionBudgetBefore !== void 0 && event.completionBudgetAfter !== void 0;
|
|
510778
|
+
if (event.outputMayHaveStarted === true || completionBudgetRetry) {
|
|
509926
510779
|
const { streamingUI } = this.host;
|
|
509927
510780
|
streamingUI.flushNow();
|
|
509928
510781
|
streamingUI.discardUnfinishedToolUi();
|
|
@@ -509932,9 +510785,14 @@ var SessionEventHandler = class {
|
|
|
509932
510785
|
kind: "status",
|
|
509933
510786
|
turnId: String(event.turnId),
|
|
509934
510787
|
renderMode: "plain",
|
|
509935
|
-
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 })
|
|
509936
510793
|
});
|
|
509937
510794
|
}
|
|
510795
|
+
this.host.streamingUI.noteStepRetry(event);
|
|
509938
510796
|
this.modelRetryHint = hint;
|
|
509939
510797
|
this.host.state.footer.setTransientHint(hint);
|
|
509940
510798
|
this.host.state.ui.requestRender();
|
|
@@ -509950,6 +510808,7 @@ var SessionEventHandler = class {
|
|
|
509950
510808
|
handleThinkingDelta(event) {
|
|
509951
510809
|
const { state, streamingUI } = this.host;
|
|
509952
510810
|
if (event.delta.length === 0 && !streamingUI.hasThinkingDraft()) return;
|
|
510811
|
+
if (event.delta.trim().length === 0) streamingUI.noteThinkingHeartbeat();
|
|
509953
510812
|
if (event.delta.length > 0) this.turnWatchdog.recordProgress();
|
|
509954
510813
|
if (event.delta.length > 0) this.clearModelRetryHint();
|
|
509955
510814
|
streamingUI.appendThinkingDelta(event.delta);
|
|
@@ -512992,6 +513851,9 @@ var StreamingUIController = class {
|
|
|
512992
513851
|
_remoteTurnActivity = { active: false };
|
|
512993
513852
|
_remoteProcessStartedAt = new Date(Date.now() - process.uptime() * 1e3).toISOString();
|
|
512994
513853
|
_liveTurnStartedAtMs = void 0;
|
|
513854
|
+
_liveStepStartedAtMs = void 0;
|
|
513855
|
+
_liveThinkingHeartbeatAtMs = void 0;
|
|
513856
|
+
_liveStepRequest = {};
|
|
512995
513857
|
_liveOutputTokens = new LiveOutputTokenCounter();
|
|
512996
513858
|
_countedToolCallIds = /* @__PURE__ */ new Set();
|
|
512997
513859
|
_assistantDraft = "";
|
|
@@ -513022,6 +513884,32 @@ var StreamingUIController = class {
|
|
|
513022
513884
|
this._currentStep = step;
|
|
513023
513885
|
this.publishTelegramConsoleStatus();
|
|
513024
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
|
+
}
|
|
513025
513913
|
setRemoteTurnActivity(activity) {
|
|
513026
513914
|
const previous = this._remoteTurnActivity;
|
|
513027
513915
|
this._remoteTurnActivity = activity?.active === true ? activity : { active: false };
|
|
@@ -513050,14 +513938,25 @@ var StreamingUIController = class {
|
|
|
513050
513938
|
}
|
|
513051
513939
|
beginLiveTurn() {
|
|
513052
513940
|
this._liveTurnStartedAtMs = Date.now();
|
|
513941
|
+
this._liveStepStartedAtMs = void 0;
|
|
513942
|
+
this._liveThinkingHeartbeatAtMs = void 0;
|
|
513943
|
+
this._liveStepRequest = {};
|
|
513053
513944
|
this._liveOutputTokens.reset();
|
|
513054
513945
|
this._countedToolCallIds.clear();
|
|
513055
513946
|
this.lastFlushAt = void 0;
|
|
513056
513947
|
}
|
|
513057
513948
|
getLiveActivityMetrics() {
|
|
513949
|
+
const activeToolName = [...this._activeToolCalls.values()].at(-1)?.name ?? [...this._streamingToolCallArguments.values()].at(-1)?.name;
|
|
513058
513950
|
return {
|
|
513059
|
-
startedAtMs: this._liveTurnStartedAtMs,
|
|
513060
|
-
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
|
|
513061
513960
|
};
|
|
513062
513961
|
}
|
|
513063
513962
|
recordLiveOutput(fragment) {
|
|
@@ -513098,6 +513997,9 @@ var StreamingUIController = class {
|
|
|
513098
513997
|
}
|
|
513099
513998
|
resetLiveActivity() {
|
|
513100
513999
|
this._liveTurnStartedAtMs = void 0;
|
|
514000
|
+
this._liveStepStartedAtMs = void 0;
|
|
514001
|
+
this._liveThinkingHeartbeatAtMs = void 0;
|
|
514002
|
+
this._liveStepRequest = {};
|
|
513101
514003
|
this._liveOutputTokens.reset();
|
|
513102
514004
|
this._countedToolCallIds.clear();
|
|
513103
514005
|
}
|
|
@@ -518668,6 +519570,10 @@ var BlunTUI = class {
|
|
|
518668
519570
|
const sessionId = session.id;
|
|
518669
519571
|
const autostartPrompt = autostart.observation === void 0 ? GOAL_CONTINUATION_PROMPT : `${GOAL_CONTINUATION_PROMPT}\n\n${autostart.observation}`;
|
|
518670
519572
|
this.beginSessionRequest();
|
|
519573
|
+
this.setAppState({
|
|
519574
|
+
model: BLUN_KING_MODEL_ALIAS,
|
|
519575
|
+
modelFallbackAllowed: false
|
|
519576
|
+
});
|
|
518671
519577
|
try {
|
|
518672
519578
|
const result = await session.promptAccepted(autostartPrompt);
|
|
518673
519579
|
if (!result.accepted && this.session?.id === sessionId) {
|
|
@@ -519704,6 +520610,10 @@ var BlunTUI = class {
|
|
|
519704
520610
|
contextOnly: false
|
|
519705
520611
|
};
|
|
519706
520612
|
this.pendingChannelReplyGuard = installedGuard;
|
|
520613
|
+
this.setAppState({
|
|
520614
|
+
model: BLUN_KING_MODEL_ALIAS,
|
|
520615
|
+
modelFallbackAllowed: false
|
|
520616
|
+
});
|
|
519707
520617
|
session.promptAccepted(options?.parts ?? input).then((result) => {
|
|
519708
520618
|
if (result.duplicate === true) {
|
|
519709
520619
|
this.traceTelegramDelivery?.({ stage: "committed", ...context.item.channelDeliveryTrace, route: "channel_command_prompt", reason: "duplicate" });
|
|
@@ -519767,6 +520677,10 @@ var BlunTUI = class {
|
|
|
519767
520677
|
type: "text",
|
|
519768
520678
|
text: focusedModelInput
|
|
519769
520679
|
}, imagePart] : focusedModelInput;
|
|
520680
|
+
this.setAppState({
|
|
520681
|
+
model: BLUN_KING_MODEL_ALIAS,
|
|
520682
|
+
modelFallbackAllowed: false
|
|
520683
|
+
});
|
|
519770
520684
|
session.promptAccepted(promptInput, channelPromptOrigin(channelReportSources)).then((result) => {
|
|
519771
520685
|
if (result.duplicate === true) {
|
|
519772
520686
|
this.traceTelegramDelivery?.({ stage: "committed", ...channelDeliveryTrace, route: "prompt", reason: "duplicate" });
|
|
@@ -519961,6 +520875,10 @@ var BlunTUI = class {
|
|
|
519961
520875
|
return;
|
|
519962
520876
|
}
|
|
519963
520877
|
this.beginSessionRequest();
|
|
520878
|
+
this.setAppState({
|
|
520879
|
+
model: BLUN_KING_MODEL_ALIAS,
|
|
520880
|
+
modelFallbackAllowed: false
|
|
520881
|
+
});
|
|
519964
520882
|
session.promptAccepted(TRUNCATED_REPLY_CONTINUATION_PROMPT).then((result) => {
|
|
519965
520883
|
if (!result.accepted) this.failTruncatedChannelReplyRecovery(new Error("continuation prompt rejected"));
|
|
519966
520884
|
}).catch((error) => {
|
|
@@ -520231,6 +521149,10 @@ var BlunTUI = class {
|
|
|
520231
521149
|
});
|
|
520232
521150
|
this.beginSessionRequest();
|
|
520233
521151
|
const sdkInput = options?.parts ?? input;
|
|
521152
|
+
this.setAppState({
|
|
521153
|
+
model: BLUN_KING_MODEL_ALIAS,
|
|
521154
|
+
modelFallbackAllowed: false
|
|
521155
|
+
});
|
|
520234
521156
|
session.promptAccepted(sdkInput).catch((error) => {
|
|
520235
521157
|
finishPersonalMemoryRememberIntentTurn(session.id);
|
|
520236
521158
|
const message = formatErrorMessage$2(error);
|
|
@@ -520345,19 +521267,18 @@ var BlunTUI = class {
|
|
|
520345
521267
|
}
|
|
520346
521268
|
}
|
|
520347
521269
|
setAppState(patch) {
|
|
520348
|
-
const managedAccountContextTokens = "managedAccountContextTokens" in patch ? patch.managedAccountContextTokens : this.state.appState.managedAccountContextTokens;
|
|
520349
|
-
const availableModels = applyManagedAccountContext(patch.availableModels ?? this.state.appState.availableModels, isValidManagedContextTokens(managedAccountContextTokens) ? managedAccountContextTokens : void 0);
|
|
520350
|
-
const allowedModel = (candidate) => typeof candidate === "string" && isAllowedFredrikRuntimeAlias(candidate, availableModels) ? candidate : BLUN_KING_MODEL_ALIAS;
|
|
520351
521270
|
let effectivePatch = {
|
|
520352
521271
|
...patch,
|
|
520353
521272
|
modelFallbackAllowed: false,
|
|
520354
|
-
..."model" in patch && patch.model?.trim().length ? { model:
|
|
520355
|
-
..."activeResponderModel" in patch && patch.activeResponderModel != null ? { activeResponderModel:
|
|
521273
|
+
..."model" in patch && patch.model?.trim().length ? { model: BLUN_KING_MODEL_ALIAS } : {},
|
|
521274
|
+
..."activeResponderModel" in patch && patch.activeResponderModel != null ? { activeResponderModel: BLUN_KING_MODEL_ALIAS } : {}
|
|
520356
521275
|
};
|
|
520357
521276
|
if ("availableModels" in patch || "managedAccountContextTokens" in patch) {
|
|
520358
|
-
|
|
521277
|
+
const managedAccountContextTokens = "managedAccountContextTokens" in patch ? patch.managedAccountContextTokens : this.state.appState.managedAccountContextTokens;
|
|
521278
|
+
const effectiveModels = applyManagedAccountContext(patch.availableModels ?? this.state.appState.availableModels, isValidManagedContextTokens(managedAccountContextTokens) ? managedAccountContextTokens : void 0);
|
|
521279
|
+
if (effectiveModels !== patch.availableModels) effectivePatch = {
|
|
520359
521280
|
...effectivePatch,
|
|
520360
|
-
availableModels
|
|
521281
|
+
availableModels: effectiveModels
|
|
520361
521282
|
};
|
|
520362
521283
|
}
|
|
520363
521284
|
if (!hasPatchChanges(this.state.appState, effectivePatch)) return;
|
|
@@ -520434,11 +521355,7 @@ var BlunTUI = class {
|
|
|
520434
521355
|
return this.harness.createSession(options);
|
|
520435
521356
|
}
|
|
520436
521357
|
async setSession(session, options = {}) {
|
|
520437
|
-
|
|
520438
|
-
if (!isAllowedFredrikRuntimeAlias(resumedStatus.model ?? BLUN_KING_MODEL_ALIAS, this.state.appState.availableModels)) {
|
|
520439
|
-
await session.setModel(BLUN_KING_MODEL_ALIAS, { allowFallback: false });
|
|
520440
|
-
this.showStatus(uiText("config.model.unknownAlias", { alias: resumedStatus.model ?? "" }), "warning");
|
|
520441
|
-
}
|
|
521358
|
+
await session.setModel(BLUN_KING_MODEL_ALIAS, { allowFallback: false });
|
|
520442
521359
|
await this.personalMemoryController.clear(this.session);
|
|
520443
521360
|
const previous = this.unloadCurrentSession(approvalCancellationFeedback("switching_session"));
|
|
520444
521361
|
await this.managedQuotaWarningPersistence;
|
|
@@ -520446,7 +521363,10 @@ var BlunTUI = class {
|
|
|
520446
521363
|
resetChannelPreambleState(this.channelPreamble);
|
|
520447
521364
|
this.session = session;
|
|
520448
521365
|
this.managedQuotaWarningController.restore(session.id, managedQuotaWarningThresholdFromMetadata(session.getResumeState()?.sessionMetadata?.custom));
|
|
520449
|
-
this.setAppState({
|
|
521366
|
+
this.setAppState({
|
|
521367
|
+
model: BLUN_KING_MODEL_ALIAS,
|
|
521368
|
+
modelFallbackAllowed: false
|
|
521369
|
+
});
|
|
520450
521370
|
this.harness.setTelemetryContext({ sessionId: session.id });
|
|
520451
521371
|
this.registerSessionHandlers(session);
|
|
520452
521372
|
this.syncAdditionalDirs(session);
|
|
@@ -520458,7 +521378,7 @@ var BlunTUI = class {
|
|
|
520458
521378
|
const [status, goalResult, loopResult] = await Promise.all([session.getStatus(), session.getGoal(), session.getLoop()]);
|
|
520459
521379
|
this.setAppState({
|
|
520460
521380
|
sessionId: session.id,
|
|
520461
|
-
model:
|
|
521381
|
+
model: BLUN_KING_MODEL_ALIAS,
|
|
520462
521382
|
modelFallbackAllowed: false,
|
|
520463
521383
|
activeResponderModel: null,
|
|
520464
521384
|
thinkingEffort: status.thinkingEffort,
|
|
@@ -520678,6 +521598,7 @@ var BlunTUI = class {
|
|
|
520678
521598
|
this.approvalController.cancelAll(approvalCancellationFeedback("reloading_session"));
|
|
520679
521599
|
this.questionController.cancelAll("");
|
|
520680
521600
|
this.resetSessionRuntime();
|
|
521601
|
+
await session.setModel(BLUN_KING_MODEL_ALIAS, { allowFallback: false });
|
|
520681
521602
|
this.session = session;
|
|
520682
521603
|
this.harness.setTelemetryContext({ sessionId: session.id });
|
|
520683
521604
|
this.registerSessionHandlers(session);
|
|
@@ -520815,6 +521736,9 @@ var BlunTUI = class {
|
|
|
520815
521736
|
case "cancelled":
|
|
520816
521737
|
decision = uiText("approval.transcript.cancelled");
|
|
520817
521738
|
break;
|
|
521739
|
+
case "edited":
|
|
521740
|
+
decision = uiText("approval.transcript.edited");
|
|
521741
|
+
break;
|
|
520818
521742
|
}
|
|
520819
521743
|
const content = response.feedback !== void 0 && response.feedback.length > 0 ? uiText("approval.transcript.actionWithFeedback", {
|
|
520820
521744
|
decision,
|