blun-king-cli 9.1.536 → 9.1.550
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/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/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/html-to-research-markdown.cjs +146 -0
- package/bin/programmatic-tool-runtime.mjs +330 -4
- package/bin/read-continuation-policy.cjs +36 -5
- package/bin/scoped-cron-run-policy.cjs +358 -0
- package/bin/startup-preferences.cjs +3 -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-result-offload-policy.cjs +14 -1
- package/bin/update-notice.js +14 -18
- package/bin/user-message-offload-policy.cjs +3 -1
- package/blun.mjs +1089 -477
- 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-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/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
|
@@ -5,6 +5,7 @@ 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,
|
|
@@ -2859,17 +2855,8 @@ var init_blun = __esmMin((() => {
|
|
|
2859
2855
|
delete requestExtraBody["model"];
|
|
2860
2856
|
delete requestExtraBody["messages"];
|
|
2861
2857
|
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
|
-
}
|
|
2858
|
+
const effectiveTemplateKwargs = requestKwargs["chat_template_kwargs"];
|
|
2859
|
+
const reasoningRequested = typeof effectiveTemplateKwargs === "object" && effectiveTemplateKwargs !== null && effectiveTemplateKwargs.thinking === true;
|
|
2873
2860
|
const createParams = {
|
|
2874
2861
|
model: this._model,
|
|
2875
2862
|
messages,
|
|
@@ -10013,7 +10000,7 @@ var init_schema = __esmMin((() => {
|
|
|
10013
10000
|
init_matches_rule();
|
|
10014
10001
|
init_errors$8();
|
|
10015
10002
|
init_zod$1();
|
|
10016
|
-
ProviderTypeSchema =
|
|
10003
|
+
ProviderTypeSchema = literal("blun");
|
|
10017
10004
|
OAuthRefSchema = object({
|
|
10018
10005
|
storage: _enum(["file", "keyring"]),
|
|
10019
10006
|
key: string().min(1),
|
|
@@ -10023,7 +10010,6 @@ var init_schema = __esmMin((() => {
|
|
|
10023
10010
|
ProviderConfigSchema = object({
|
|
10024
10011
|
type: ProviderTypeSchema,
|
|
10025
10012
|
apiKey: string().optional(),
|
|
10026
|
-
apiKeyFile: string().optional(),
|
|
10027
10013
|
baseUrl: string().optional(),
|
|
10028
10014
|
defaultModel: string().optional(),
|
|
10029
10015
|
oauth: OAuthRefSchema.optional(),
|
|
@@ -14687,7 +14673,7 @@ async function refreshProviderModels(host, options = {}) {
|
|
|
14687
14673
|
var BLUN_LOCAL_PROVIDER_NAME;
|
|
14688
14674
|
var init_refreshProviderModels = __esmMin((() => {
|
|
14689
14675
|
init_managed_blun();
|
|
14690
|
-
BLUN_LOCAL_PROVIDER_NAME = "
|
|
14676
|
+
BLUN_LOCAL_PROVIDER_NAME = "blun";
|
|
14691
14677
|
}));
|
|
14692
14678
|
//#endregion
|
|
14693
14679
|
//#region ../../packages/oauth/src/index.ts
|
|
@@ -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,
|
|
@@ -30653,7 +30693,7 @@ var init_programmatic_tool = __esmMin((() => {
|
|
|
30653
30693
|
PROGRAMMATIC_TOOL_NAME = "ProgrammaticTool";
|
|
30654
30694
|
ProgrammaticTool = class {
|
|
30655
30695
|
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.";
|
|
30696
|
+
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
30697
|
parameters = {
|
|
30658
30698
|
type: "object",
|
|
30659
30699
|
properties: {
|
|
@@ -30724,8 +30764,13 @@ var init_programmatic_tool = __esmMin((() => {
|
|
|
30724
30764
|
if (context.invokeTool.stopTurn === true) result.stopTurn = true;
|
|
30725
30765
|
return result;
|
|
30726
30766
|
} catch (error) {
|
|
30767
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
30768
|
+
const programmaticConsole = error && typeof error === "object" ? error.programmaticConsole : void 0;
|
|
30727
30769
|
const result = {
|
|
30728
|
-
output:
|
|
30770
|
+
output: programmaticConsole ? JSON.stringify({
|
|
30771
|
+
error: message,
|
|
30772
|
+
console: programmaticConsole
|
|
30773
|
+
}) : message,
|
|
30729
30774
|
isError: true
|
|
30730
30775
|
};
|
|
30731
30776
|
if (context.invokeTool.stopTurn === true) result.stopTurn = true;
|
|
@@ -75563,23 +75608,27 @@ var init_full = __esmMin((() => {
|
|
|
75563
75608
|
const budget = this.strategy.compactionBudgetTokens;
|
|
75564
75609
|
return budget !== void 0 && Number.isFinite(budget) && budget > 0 ? Math.floor(budget) : void 0;
|
|
75565
75610
|
}
|
|
75566
|
-
proactiveCompactionStatus() {
|
|
75567
|
-
|
|
75568
|
-
|
|
75569
|
-
|
|
75570
|
-
|
|
75571
|
-
|
|
75572
|
-
|
|
75611
|
+
proactiveCompactionStatus(context = {}) {
|
|
75612
|
+
const usedTokens = this.estimateCurrentRequestTokens(context);
|
|
75613
|
+
return {
|
|
75614
|
+
...proactiveCompactionEligibility({
|
|
75615
|
+
usedTokens,
|
|
75616
|
+
budgetTokens: this.getCompactionBudgetTokens(),
|
|
75617
|
+
hasShrinkableHistory: this.hasShrinkableHistory(this.agent.context.history),
|
|
75618
|
+
isCompacting: this.isCompacting
|
|
75619
|
+
}),
|
|
75620
|
+
usedTokens
|
|
75621
|
+
};
|
|
75573
75622
|
}
|
|
75574
75623
|
isProactiveCompactionEligible() {
|
|
75575
75624
|
return this.proactiveCompactionStatus().eligible;
|
|
75576
75625
|
}
|
|
75577
|
-
requestProactiveCompaction() {
|
|
75578
|
-
const status = this.proactiveCompactionStatus();
|
|
75626
|
+
requestProactiveCompaction(context = {}) {
|
|
75627
|
+
const status = this.proactiveCompactionStatus(context);
|
|
75579
75628
|
if (!status.eligible) return status;
|
|
75580
75629
|
this.proactiveCompactionRequested = true;
|
|
75581
75630
|
this.agent.telemetry.track("proactive_compaction_requested", {
|
|
75582
|
-
used_tokens:
|
|
75631
|
+
used_tokens: status.usedTokens,
|
|
75583
75632
|
threshold_tokens: status.thresholdTokens
|
|
75584
75633
|
});
|
|
75585
75634
|
return status;
|
|
@@ -75675,9 +75724,19 @@ var init_full = __esmMin((() => {
|
|
|
75675
75724
|
const requestMessages = requestContext.messages ?? this.agent.context.messages;
|
|
75676
75725
|
const projectedMessages = requestContext.additionalMessages === void 0 ? requestMessages : [...requestMessages, ...requestContext.additionalMessages];
|
|
75677
75726
|
const requestTokens = this.estimateCurrentRequestTokens(requestContext);
|
|
75678
|
-
const proactiveStatus = this.requestProactiveCompaction();
|
|
75727
|
+
const proactiveStatus = this.requestProactiveCompaction(requestContext);
|
|
75679
75728
|
if (proactiveStatus.eligible) {
|
|
75680
75729
|
this.proactiveCompactionRequested = false;
|
|
75730
|
+
this.agent.records.logRecord({
|
|
75731
|
+
type: "policy.intervention",
|
|
75732
|
+
policy: "proactive_compaction_trigger",
|
|
75733
|
+
location: "FullCompaction.beforeStep",
|
|
75734
|
+
size_before: this.estimateCurrentRequestTokens(),
|
|
75735
|
+
size_after: proactiveStatus.usedTokens,
|
|
75736
|
+
unit: "tokens",
|
|
75737
|
+
threshold_tokens: proactiveStatus.thresholdTokens,
|
|
75738
|
+
selected_tool_count: requestContext.tools?.length ?? 0
|
|
75739
|
+
});
|
|
75681
75740
|
if (!this.compacting) this.beginAutoCompaction();
|
|
75682
75741
|
await this.block(signal);
|
|
75683
75742
|
}
|
|
@@ -76556,6 +76615,9 @@ function isValidCronTask(obj) {
|
|
|
76556
76615
|
if (o["paused"] !== void 0 && typeof o["paused"] !== "boolean") return false;
|
|
76557
76616
|
if (o["autoExpire"] !== void 0 && typeof o["autoExpire"] !== "boolean") return false;
|
|
76558
76617
|
if (o["scheduleFromAt"] !== void 0 && (typeof o["scheduleFromAt"] !== "number" || !Number.isFinite(o["scheduleFromAt"]))) return false;
|
|
76618
|
+
if (o["allowedTools"] !== void 0 && (!Array.isArray(o["allowedTools"]) || !o["allowedTools"].every((name) => typeof name === "string"))) return false;
|
|
76619
|
+
if (o["allowedTools"] !== void 0 && typeof o["toolScopeDigest"] !== "string") return false;
|
|
76620
|
+
if (o["allowedTools"] === void 0 && o["toolScopeDigest"] !== void 0) return false;
|
|
76559
76621
|
if (o["owner"] === "session-loop" && (typeof o["loopInterval"] !== "string" || o["loopInterval"].length === 0 || o["recurring"] === false || o["autoExpire"] !== false)) return false;
|
|
76560
76622
|
return true;
|
|
76561
76623
|
}
|
|
@@ -77333,7 +77395,7 @@ function hasUnfinishedTodoWork(agent) {
|
|
|
77333
77395
|
const todos = agent.tools.storeData()["todo"];
|
|
77334
77396
|
return Array.isArray(todos) && todos.some((todo) => todo?.status === "in_progress" || todo?.status === "pending");
|
|
77335
77397
|
}
|
|
77336
|
-
var STALE_THRESHOLD_MS, CronManager;
|
|
77398
|
+
var STALE_THRESHOLD_MS, normalizeCronAllowedTools, cronToolScopeForTask, filterToolsForCronScope, inheritedCronToolScope, createCronRunReceipt, buildCronFileCandidate, publicCronRunList, createCronRunStore, createMemoryCronRunStore, readCronFinalMessage, CronManager;
|
|
77337
77399
|
var init_manager$3 = __esmMin((() => {
|
|
77338
77400
|
init_clock();
|
|
77339
77401
|
init_cron_fire_xml();
|
|
@@ -77341,6 +77403,17 @@ var init_manager$3 = __esmMin((() => {
|
|
|
77341
77403
|
init_session_store$2();
|
|
77342
77404
|
init_scheduler();
|
|
77343
77405
|
init_telemetry_events();
|
|
77406
|
+
({
|
|
77407
|
+
normalizeCronAllowedTools,
|
|
77408
|
+
cronToolScopeForTask,
|
|
77409
|
+
filterToolsForCronScope,
|
|
77410
|
+
inheritedCronToolScope,
|
|
77411
|
+
createCronRunReceipt,
|
|
77412
|
+
buildCronFileCandidate,
|
|
77413
|
+
publicCronRunList
|
|
77414
|
+
} = createRequire(import.meta.url)("./bin/scoped-cron-run-policy.cjs"));
|
|
77415
|
+
({ createCronRunStore, createMemoryCronRunStore } = createRequire(import.meta.url)("./bin/cron-run-store.cjs"));
|
|
77416
|
+
({ readCronFinalMessage } = createRequire(import.meta.url)("./bin/cron-run-output.cjs"));
|
|
77344
77417
|
STALE_THRESHOLD_MS = 10080 * 60 * 1e3;
|
|
77345
77418
|
CronManager = class {
|
|
77346
77419
|
/** In-memory task store. Empty at construction; populated by
|
|
@@ -77376,6 +77449,11 @@ var init_manager$3 = __esmMin((() => {
|
|
|
77376
77449
|
* later `blun resume` can reload via {@link loadFromDisk}.
|
|
77377
77450
|
*/
|
|
77378
77451
|
persistStore;
|
|
77452
|
+
runStore;
|
|
77453
|
+
bufferedRuns = [];
|
|
77454
|
+
runByTurnId = /* @__PURE__ */ new Map();
|
|
77455
|
+
runAccumulators = /* @__PURE__ */ new Map();
|
|
77456
|
+
drainTimer = null;
|
|
77379
77457
|
/**
|
|
77380
77458
|
* Per-id serializer for persistence writes. Prevents a fast
|
|
77381
77459
|
* `add` → `remove` sequence on the same id from racing each other on
|
|
@@ -77389,6 +77467,7 @@ var init_manager$3 = __esmMin((() => {
|
|
|
77389
77467
|
this.store = new SessionCronStore();
|
|
77390
77468
|
this.clocks = opts.clocks ?? resolveClockSources(process.env["BLUN_CRON_CLOCK"]) ?? SYSTEM_CLOCKS;
|
|
77391
77469
|
this.persistStore = agent.homedir === void 0 ? void 0 : createCronPersistStore(agent.homedir);
|
|
77470
|
+
this.runStore = agent.homedir === void 0 ? createMemoryCronRunStore() : createCronRunStore(agent.homedir, { now: () => this.clocks.wallNow() });
|
|
77392
77471
|
this.scheduler = createCronScheduler({
|
|
77393
77472
|
clocks: this.clocks,
|
|
77394
77473
|
source: () => this.store.list(),
|
|
@@ -77440,7 +77519,10 @@ var init_manager$3 = __esmMin((() => {
|
|
|
77440
77519
|
*/
|
|
77441
77520
|
removeTasks(ids) {
|
|
77442
77521
|
const removed = this.store.remove(ids);
|
|
77443
|
-
for (const id of removed)
|
|
77522
|
+
for (const id of removed) {
|
|
77523
|
+
this.persistEnqueue(id, () => this.persistStore.remove(id));
|
|
77524
|
+
this.runStore.markJobDeletedById(id);
|
|
77525
|
+
}
|
|
77444
77526
|
return removed;
|
|
77445
77527
|
}
|
|
77446
77528
|
updateTask(id, patch) {
|
|
@@ -77480,6 +77562,11 @@ var init_manager$3 = __esmMin((() => {
|
|
|
77480
77562
|
* input, so a regenerated value would corrupt both.
|
|
77481
77563
|
*/
|
|
77482
77564
|
async loadFromDisk() {
|
|
77565
|
+
const loadedRuns = this.runStore.load();
|
|
77566
|
+
for (const runId of loadedRuns.lostRunIds ?? []) {
|
|
77567
|
+
const receipt = this.runStore.get(runId);
|
|
77568
|
+
if (receipt !== void 0) this.emitRunTerminal(receipt);
|
|
77569
|
+
}
|
|
77483
77570
|
if (this.persistStore === void 0) return;
|
|
77484
77571
|
const tasks = await this.persistStore.list();
|
|
77485
77572
|
this.store.clear();
|
|
@@ -77547,6 +77634,8 @@ var init_manager$3 = __esmMin((() => {
|
|
|
77547
77634
|
* would be missing from the resume's `loadFromDisk()`.
|
|
77548
77635
|
*/
|
|
77549
77636
|
async stop() {
|
|
77637
|
+
if (this.drainTimer !== null) clearTimeout(this.drainTimer);
|
|
77638
|
+
this.drainTimer = null;
|
|
77550
77639
|
this.unbindSigusr1();
|
|
77551
77640
|
await this.scheduler.stop();
|
|
77552
77641
|
await this.flushPersist();
|
|
@@ -77612,24 +77701,49 @@ var init_manager$3 = __esmMin((() => {
|
|
|
77612
77701
|
*/
|
|
77613
77702
|
handleFire(task, ctx) {
|
|
77614
77703
|
const stale = this.isStale(task);
|
|
77704
|
+
const toolScope = cronToolScopeForTask(task);
|
|
77705
|
+
const runId = randomBytes(8).toString("hex");
|
|
77615
77706
|
const origin = {
|
|
77616
77707
|
kind: "cron_job",
|
|
77617
77708
|
jobId: task.id,
|
|
77709
|
+
runId,
|
|
77618
77710
|
cron: task.cron,
|
|
77619
77711
|
recurring: task.recurring !== false,
|
|
77620
77712
|
coalescedCount: ctx.coalescedCount,
|
|
77621
|
-
stale
|
|
77713
|
+
stale,
|
|
77714
|
+
...(toolScope.mode === "scoped" ? { toolScope } : {})
|
|
77622
77715
|
};
|
|
77623
77716
|
const content = [{
|
|
77624
77717
|
type: "text",
|
|
77625
77718
|
text: task.owner === "session-loop" ? renderSessionLoopWakeupXml(origin, task.prompt, task.loopInterval ?? "auto") : renderCronFireXml(origin, task.prompt)
|
|
77626
77719
|
}];
|
|
77720
|
+
const receipt = createCronRunReceipt({
|
|
77721
|
+
runId,
|
|
77722
|
+
jobId: task.id,
|
|
77723
|
+
cron: task.cron,
|
|
77724
|
+
recurring: task.recurring !== false,
|
|
77725
|
+
stale,
|
|
77726
|
+
coalescedCount: ctx.coalescedCount,
|
|
77727
|
+
toolScopeDigest: toolScope.digest,
|
|
77728
|
+
firedAt: new Date(this.clocks.wallNow()).toISOString()
|
|
77729
|
+
});
|
|
77730
|
+
this.runStore.create(receipt);
|
|
77731
|
+
this.bufferedRuns.push({ runId, content, origin });
|
|
77732
|
+
this.runAccumulators.set(runId, {
|
|
77733
|
+
toolCalls: /* @__PURE__ */ new Map(),
|
|
77734
|
+
fileCandidates: /* @__PURE__ */ new Map(),
|
|
77735
|
+
outputs: [],
|
|
77736
|
+
finalStepId: null
|
|
77737
|
+
});
|
|
77738
|
+
this.agent.emitEvent({ type: "cron.fired", origin });
|
|
77627
77739
|
this.agent.emitEvent({
|
|
77628
|
-
type: "cron.
|
|
77629
|
-
|
|
77630
|
-
|
|
77740
|
+
type: "cron.run.created",
|
|
77741
|
+
runId,
|
|
77742
|
+
jobId: task.id,
|
|
77743
|
+
coalescedCount: ctx.coalescedCount,
|
|
77744
|
+
toolScopeDigest: toolScope.digest
|
|
77631
77745
|
});
|
|
77632
|
-
const turnId = this.
|
|
77746
|
+
const turnId = this.launchBufferedRuns();
|
|
77633
77747
|
this.agent.telemetry.track(CRON_FIRED, {
|
|
77634
77748
|
recurring: task.recurring !== false,
|
|
77635
77749
|
coalesced_count: ctx.coalescedCount,
|
|
@@ -77641,6 +77755,137 @@ var init_manager$3 = __esmMin((() => {
|
|
|
77641
77755
|
this.emitDeleted(task.id);
|
|
77642
77756
|
}
|
|
77643
77757
|
}
|
|
77758
|
+
launchBufferedRuns() {
|
|
77759
|
+
if (this.bufferedRuns.length === 0) return null;
|
|
77760
|
+
if (this.agent.turn.hasActiveTurn || this.agent.fullCompaction.isCompacting) {
|
|
77761
|
+
this.scheduleBufferedRunDrain();
|
|
77762
|
+
return null;
|
|
77763
|
+
}
|
|
77764
|
+
const next = this.bufferedRuns.shift();
|
|
77765
|
+
const acceptance = this.agent.turn.promptWithAcceptance(next.content, next.origin);
|
|
77766
|
+
if (acceptance.accepted !== true || acceptance.turnId === null) {
|
|
77767
|
+
this.bufferedRuns.unshift(next);
|
|
77768
|
+
this.scheduleBufferedRunDrain();
|
|
77769
|
+
return null;
|
|
77770
|
+
}
|
|
77771
|
+
return acceptance.turnId;
|
|
77772
|
+
}
|
|
77773
|
+
scheduleBufferedRunDrain() {
|
|
77774
|
+
if (this.drainTimer !== null || this.bufferedRuns.length === 0) return;
|
|
77775
|
+
this.drainTimer = setTimeout(() => {
|
|
77776
|
+
this.drainTimer = null;
|
|
77777
|
+
this.launchBufferedRuns();
|
|
77778
|
+
}, 250);
|
|
77779
|
+
this.drainTimer.unref?.();
|
|
77780
|
+
}
|
|
77781
|
+
observeLoopEvent(turnId, event) {
|
|
77782
|
+
const runId = this.runByTurnId.get(turnId);
|
|
77783
|
+
if (runId === void 0) return;
|
|
77784
|
+
const accumulator = this.runAccumulators.get(runId);
|
|
77785
|
+
if (accumulator === void 0) return;
|
|
77786
|
+
if (event.type === "step.begin" && typeof event.uuid === "string") accumulator.finalStepId = event.uuid;
|
|
77787
|
+
if (event.type === "tool.call") {
|
|
77788
|
+
accumulator.toolCalls.set(event.toolCallId, { name: event.name, isError: false });
|
|
77789
|
+
const candidate = buildCronFileCandidate({
|
|
77790
|
+
toolName: event.name,
|
|
77791
|
+
toolCallId: event.toolCallId,
|
|
77792
|
+
display: event.display,
|
|
77793
|
+
workspaceRoot: this.agent.config.cwd,
|
|
77794
|
+
additionalRoots: this.agent.getAdditionalDirs(),
|
|
77795
|
+
pathExists: typeof event.display?.path === "string" && existsSync(event.display.path)
|
|
77796
|
+
});
|
|
77797
|
+
if (candidate !== null) accumulator.fileCandidates.set(event.toolCallId, candidate);
|
|
77798
|
+
}
|
|
77799
|
+
if (event.type === "tool.result") {
|
|
77800
|
+
const call = accumulator.toolCalls.get(event.toolCallId);
|
|
77801
|
+
if (call !== void 0) call.isError = event.result.isError === true;
|
|
77802
|
+
const candidate = accumulator.fileCandidates.get(event.toolCallId);
|
|
77803
|
+
if (candidate !== void 0 && event.result.isError !== true) accumulator.outputs.push(candidate);
|
|
77804
|
+
accumulator.fileCandidates.delete(event.toolCallId);
|
|
77805
|
+
}
|
|
77806
|
+
}
|
|
77807
|
+
observeAgentEvent(event) {
|
|
77808
|
+
if (event.type === "turn.started") {
|
|
77809
|
+
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;
|
|
77810
|
+
if (runId === void 0) return;
|
|
77811
|
+
const receipt = this.runStore.get(runId);
|
|
77812
|
+
if (receipt?.status !== "buffered" && receipt?.status !== "running") return;
|
|
77813
|
+
this.runByTurnId.set(event.turnId, runId);
|
|
77814
|
+
if (receipt.status === "buffered") {
|
|
77815
|
+
const running = this.runStore.transition(runId, "running", {
|
|
77816
|
+
turnId: event.turnId,
|
|
77817
|
+
startedAt: new Date(this.clocks.wallNow()).toISOString()
|
|
77818
|
+
});
|
|
77819
|
+
this.agent.emitEvent({
|
|
77820
|
+
type: "cron.run.started",
|
|
77821
|
+
runId: running.runId,
|
|
77822
|
+
jobId: running.jobId,
|
|
77823
|
+
turnId: event.turnId
|
|
77824
|
+
});
|
|
77825
|
+
}
|
|
77826
|
+
return;
|
|
77827
|
+
}
|
|
77828
|
+
if (event.type !== "turn.ended") return;
|
|
77829
|
+
const runId = this.runByTurnId.get(event.turnId);
|
|
77830
|
+
if (runId === void 0) return;
|
|
77831
|
+
const accumulator = this.runAccumulators.get(runId);
|
|
77832
|
+
if (accumulator !== void 0) accumulator.lastTurnEnd = event;
|
|
77833
|
+
this.runByTurnId.delete(event.turnId);
|
|
77834
|
+
}
|
|
77835
|
+
observeRunWorkerEnded(runId, event) {
|
|
77836
|
+
const current = this.runStore.get(runId);
|
|
77837
|
+
if (current?.status !== "running" && current?.status !== "buffered") return;
|
|
77838
|
+
const accumulator = this.runAccumulators.get(runId) ?? {
|
|
77839
|
+
toolCalls: /* @__PURE__ */ new Map(),
|
|
77840
|
+
outputs: [],
|
|
77841
|
+
finalStepId: null
|
|
77842
|
+
};
|
|
77843
|
+
const status = event.reason === "cancelled" ? "cancelled" : event.reason === "failed" || event.reason === "filtered" ? "failed" : "completed";
|
|
77844
|
+
const terminal = this.runStore.transition(runId, status, {
|
|
77845
|
+
endedAt: new Date(this.clocks.wallNow()).toISOString(),
|
|
77846
|
+
toolCalls: [...accumulator.toolCalls.values()],
|
|
77847
|
+
outputs: accumulator.outputs,
|
|
77848
|
+
finalStepId: accumulator.finalStepId,
|
|
77849
|
+
error: status === "failed" ? {
|
|
77850
|
+
category: event.reason === "filtered" ? "policy" : "executor",
|
|
77851
|
+
code: event.error?.code ?? (event.reason === "filtered" ? "PROVIDER_FILTERED" : "TURN_FAILED")
|
|
77852
|
+
} : void 0
|
|
77853
|
+
});
|
|
77854
|
+
this.emitRunTerminal(terminal);
|
|
77855
|
+
this.runAccumulators.delete(runId);
|
|
77856
|
+
this.scheduleBufferedRunDrain();
|
|
77857
|
+
}
|
|
77858
|
+
observeRunWorkerFailed(runId) {
|
|
77859
|
+
this.observeRunWorkerEnded(runId, {
|
|
77860
|
+
reason: "failed",
|
|
77861
|
+
error: { code: "TURN_WORKER_FAILED" }
|
|
77862
|
+
});
|
|
77863
|
+
}
|
|
77864
|
+
emitRunTerminal(receipt) {
|
|
77865
|
+
const durationMs = receipt.startedAt === null || receipt.endedAt === null ? void 0 : Math.max(0, Date.parse(receipt.endedAt) - Date.parse(receipt.startedAt));
|
|
77866
|
+
this.agent.emitEvent({
|
|
77867
|
+
type: `cron.run.${receipt.status}`,
|
|
77868
|
+
runId: receipt.runId,
|
|
77869
|
+
jobId: receipt.jobId,
|
|
77870
|
+
durationMs,
|
|
77871
|
+
toolCalls: receipt.toolSummary.calls,
|
|
77872
|
+
toolErrors: receipt.toolSummary.errors,
|
|
77873
|
+
outputCount: receipt.outputs.length,
|
|
77874
|
+
errorCategory: receipt.error?.category
|
|
77875
|
+
});
|
|
77876
|
+
}
|
|
77877
|
+
listRuns(filters) {
|
|
77878
|
+
return publicCronRunList(this.runStore.list(), filters);
|
|
77879
|
+
}
|
|
77880
|
+
readRunOutput(runId) {
|
|
77881
|
+
const receipt = this.runStore.get(runId);
|
|
77882
|
+
if (receipt === void 0) return null;
|
|
77883
|
+
let finalMessage = null;
|
|
77884
|
+
if (receipt.finalMessageRef !== null && this.agent.homedir !== void 0) try {
|
|
77885
|
+
finalMessage = readCronFinalMessage(join$4(this.agent.homedir, "wire.jsonl"), receipt.finalMessageRef.stepId);
|
|
77886
|
+
} catch {}
|
|
77887
|
+
return { receipt, finalMessage };
|
|
77888
|
+
}
|
|
77644
77889
|
/**
|
|
77645
77890
|
* Reserved hook for an explicit "you missed N fires while offline"
|
|
77646
77891
|
* banner. Today the scheduler's `coalescedCount` semantics already
|
|
@@ -78105,7 +78350,8 @@ var init_cron_create = __esmMin((() => {
|
|
|
78105
78350
|
CronCreateInputSchema = object({
|
|
78106
78351
|
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
78352
|
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.")
|
|
78353
|
+
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."),
|
|
78354
|
+
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
78355
|
});
|
|
78110
78356
|
CronCreateTool = class {
|
|
78111
78357
|
manager;
|
|
@@ -78145,6 +78391,15 @@ var init_cron_create = __esmMin((() => {
|
|
|
78145
78391
|
output: `Prompt exceeds ${String(MAX_PROMPT_BYTES)} bytes (got ${String(byteLen)}).`
|
|
78146
78392
|
};
|
|
78147
78393
|
const recurring = args.recurring !== false;
|
|
78394
|
+
let toolScope;
|
|
78395
|
+
try {
|
|
78396
|
+
toolScope = normalizeCronAllowedTools(args.allowed_tools, this.manager.agent.tools.loopTools);
|
|
78397
|
+
} catch (error) {
|
|
78398
|
+
return {
|
|
78399
|
+
isError: true,
|
|
78400
|
+
output: error instanceof Error ? error.message : String(error)
|
|
78401
|
+
};
|
|
78402
|
+
}
|
|
78148
78403
|
if (!recurring) {
|
|
78149
78404
|
const firstFire = computeNextCronRun(parsed, nowAtPrepare);
|
|
78150
78405
|
if (firstFire !== null && firstFire - nowAtPrepare > ONE_SHOT_MAX_FUTURE_MS) return {
|
|
@@ -78157,7 +78412,8 @@ var init_cron_create = __esmMin((() => {
|
|
|
78157
78412
|
approvalRule: literalRulePattern(this.name, JSON.stringify({
|
|
78158
78413
|
cron: normalizedCron,
|
|
78159
78414
|
prompt: args.prompt,
|
|
78160
|
-
recurring
|
|
78415
|
+
recurring,
|
|
78416
|
+
...(args.allowed_tools === void 0 ? {} : { allowed_tools: toolScope.names })
|
|
78161
78417
|
})),
|
|
78162
78418
|
execute: async () => {
|
|
78163
78419
|
const nowMs = this.manager.clocks.wallNow();
|
|
@@ -78168,7 +78424,11 @@ var init_cron_create = __esmMin((() => {
|
|
|
78168
78424
|
const task = this.manager.addTask({
|
|
78169
78425
|
cron: normalizedCron,
|
|
78170
78426
|
prompt: args.prompt,
|
|
78171
|
-
recurring
|
|
78427
|
+
recurring,
|
|
78428
|
+
...(toolScope.mode === "scoped" ? {
|
|
78429
|
+
allowedTools: toolScope.names,
|
|
78430
|
+
toolScopeDigest: toolScope.digest
|
|
78431
|
+
} : {})
|
|
78172
78432
|
});
|
|
78173
78433
|
const ideal = computeNextCronRun(parsed, nowMs);
|
|
78174
78434
|
const nextFireAt = ideal === null ? null : recurring ? jitteredNextCronRunMs(task, parsed, ideal) : oneShotJitteredNextCronRunMs(task, ideal);
|
|
@@ -79135,6 +79395,14 @@ var init_context$2 = __esmMin((() => {
|
|
|
79135
79395
|
keptHeadUserMessageCount,
|
|
79136
79396
|
droppedCount: input.droppedCount
|
|
79137
79397
|
};
|
|
79398
|
+
this.agent.records.logRecord({
|
|
79399
|
+
type: "policy.intervention",
|
|
79400
|
+
policy: "full_context_compaction",
|
|
79401
|
+
location: "AgentContext.applyCompaction",
|
|
79402
|
+
size_before: result.tokensBefore,
|
|
79403
|
+
size_after: result.tokensAfter,
|
|
79404
|
+
unit: "tokens"
|
|
79405
|
+
});
|
|
79138
79406
|
this.agent.records.logRecord({
|
|
79139
79407
|
type: "context.apply_compaction",
|
|
79140
79408
|
...result
|
|
@@ -79195,6 +79463,7 @@ var init_context$2 = __esmMin((() => {
|
|
|
79195
79463
|
}
|
|
79196
79464
|
project(messages, options) {
|
|
79197
79465
|
const anomalies = [];
|
|
79466
|
+
const underPressure = toolResultOffloadPressureForAgent(this.agent);
|
|
79198
79467
|
const userOffloaded = this.agent.userMessageOffload.compact(messages);
|
|
79199
79468
|
const historicalMediaProjected = projectHistoricalMediaParts(userOffloaded);
|
|
79200
79469
|
const historicalUserReferencesProjected = compactHistoricalPersistedUserMessageReferences(historicalMediaProjected);
|
|
@@ -79202,7 +79471,9 @@ var init_context$2 = __esmMin((() => {
|
|
|
79202
79471
|
const historicalTelegramProjected = projectHistoricalUnaddressedTelegramMessages(duplicateUserMessagesProjected);
|
|
79203
79472
|
const assistantOffloaded = this.agent.assistantMessageOffload.compact(historicalTelegramProjected);
|
|
79204
79473
|
const repeatedAssistantProjected = projectRepeatedAssistantResponses(assistantOffloaded);
|
|
79205
|
-
const
|
|
79474
|
+
const batchProjected = this.agent.toolResultBatchOffload.compact(dedupeRecurringCronWakeups(dedupeRepeatedInjections(compactHistoricalSkillActivations(compactBaselineSkillInjections(repeatedAssistantProjected)))));
|
|
79475
|
+
const toolResultsProjected = compactHistoricalSuccessfulToolResults(dedupeRepeatedSuccessfulToolResults(repeatedAssistantProjected, batchProjected), { underPressure });
|
|
79476
|
+
const result = project(this.agent.microCompaction.compact(toolResultsProjected), {
|
|
79206
79477
|
...options,
|
|
79207
79478
|
onAnomaly: (anomaly) => {
|
|
79208
79479
|
anomalies.push(anomaly);
|
|
@@ -233897,9 +234168,9 @@ var init_plan_mode_guard_deny = __esmMin((() => {
|
|
|
233897
234168
|
message: planModeWriteDeniedMessage(planFilePath)
|
|
233898
234169
|
};
|
|
233899
234170
|
}
|
|
233900
|
-
if (toolName === "TaskStop") return {
|
|
234171
|
+
if (toolName === "TaskStop" || toolName === "TaskResume") return {
|
|
233901
234172
|
kind: "deny",
|
|
233902
|
-
message:
|
|
234173
|
+
message: `${toolName} is not available in plan mode. Call ExitPlanMode before changing background task execution.`
|
|
233903
234174
|
};
|
|
233904
234175
|
if (toolName === "CronCreate" || toolName === "CronDelete") return {
|
|
233905
234176
|
kind: "deny",
|
|
@@ -234265,6 +234536,16 @@ var init_permission = __esmMin((() => {
|
|
|
234265
234536
|
if (pattern === void 0) return;
|
|
234266
234537
|
this.localSessionApprovalRulePatterns.add(pattern);
|
|
234267
234538
|
}
|
|
234539
|
+
recordApprovalEdited(context, editedArgs) {
|
|
234540
|
+
const event = buildApprovalEditedEvent({
|
|
234541
|
+
turnId: Number(context.turnId),
|
|
234542
|
+
toolCallId: context.toolCall.id,
|
|
234543
|
+
toolName: context.toolCall.name,
|
|
234544
|
+
originalArgs: context.args,
|
|
234545
|
+
editedArgs
|
|
234546
|
+
});
|
|
234547
|
+
this.agent.records.logRecord(event);
|
|
234548
|
+
}
|
|
234268
234549
|
get sessionApprovalRulePatterns() {
|
|
234269
234550
|
return [...this.localSessionApprovalRulePatterns, ...this.parent?.sessionApprovalRulePatterns ?? []];
|
|
234270
234551
|
}
|
|
@@ -234284,6 +234565,8 @@ var init_permission = __esmMin((() => {
|
|
|
234284
234565
|
const { signal } = context;
|
|
234285
234566
|
const id = context.toolCall.id;
|
|
234286
234567
|
const name = context.toolCall.name;
|
|
234568
|
+
const approvalEditCount = Number.isSafeInteger(context.approvalEditCount) ? context.approvalEditCount : 0;
|
|
234569
|
+
const allowEdit = approvalEditCount === 0 && isEditableToolApprovalEligible(name);
|
|
234287
234570
|
const display = context.execution.display ?? {
|
|
234288
234571
|
kind: "generic",
|
|
234289
234572
|
summary: context.execution.description ?? `Approve ${name}`,
|
|
@@ -234321,7 +234604,10 @@ var init_permission = __esmMin((() => {
|
|
|
234321
234604
|
toolCallId: id,
|
|
234322
234605
|
toolName: name,
|
|
234323
234606
|
action,
|
|
234324
|
-
display
|
|
234607
|
+
display,
|
|
234608
|
+
allowEdit,
|
|
234609
|
+
approvalEditCount,
|
|
234610
|
+
editableToolInput: allowEdit ? context.args : void 0
|
|
234325
234611
|
}, { signal });
|
|
234326
234612
|
} catch (error) {
|
|
234327
234613
|
this.agent.telemetry.track("permission_approval_result", {
|
|
@@ -234349,6 +234635,19 @@ var init_permission = __esmMin((() => {
|
|
|
234349
234635
|
return resolved === void 0 ? Promise.reject(error) : this.permissionPolicyResolutionToPrepare(resolved, context, policyName);
|
|
234350
234636
|
}
|
|
234351
234637
|
} else response = { decision: "approved" };
|
|
234638
|
+
let editedDecision;
|
|
234639
|
+
if (response.decision === "edited") try {
|
|
234640
|
+
editedDecision = validateEditedApprovalDecision({
|
|
234641
|
+
response,
|
|
234642
|
+
toolName: name,
|
|
234643
|
+
editCount: approvalEditCount
|
|
234644
|
+
});
|
|
234645
|
+
} catch (error) {
|
|
234646
|
+
response = {
|
|
234647
|
+
decision: "rejected",
|
|
234648
|
+
feedback: `Edited approval was rejected before tool preparation: ${error instanceof Error ? error.message : String(error)}`
|
|
234649
|
+
};
|
|
234650
|
+
}
|
|
234352
234651
|
const sessionApprovalRule = response.decision === "approved" && response.scope === "session" ? context.execution.approvalRule : void 0;
|
|
234353
234652
|
if (requestedApproval) this.agent.hooks?.fireAndForgetTrigger?.("PermissionResult", {
|
|
234354
234653
|
matcherValue: name,
|
|
@@ -234363,13 +234662,14 @@ var init_permission = __esmMin((() => {
|
|
|
234363
234662
|
selectedLabel: response.selectedLabel
|
|
234364
234663
|
}
|
|
234365
234664
|
});
|
|
234665
|
+
const approvalRecordResponse = response.decision === "edited" ? { decision: "edited" } : response;
|
|
234366
234666
|
this.recordApprovalResult({
|
|
234367
234667
|
turnId: Number(context.turnId),
|
|
234368
234668
|
toolCallId: id,
|
|
234369
234669
|
toolName: name,
|
|
234370
234670
|
action,
|
|
234371
234671
|
sessionApprovalRule,
|
|
234372
|
-
result:
|
|
234672
|
+
result: approvalRecordResponse
|
|
234373
234673
|
});
|
|
234374
234674
|
this.agent.telemetry.track("permission_approval_result", {
|
|
234375
234675
|
policy_name: policyName ?? null,
|
|
@@ -234381,6 +234681,17 @@ var init_permission = __esmMin((() => {
|
|
|
234381
234681
|
session_cache_written: sessionApprovalRule !== void 0,
|
|
234382
234682
|
has_feedback: response.feedback !== void 0 && response.feedback.length > 0
|
|
234383
234683
|
});
|
|
234684
|
+
if (response.decision === "edited" && editedDecision !== void 0) {
|
|
234685
|
+
let recorded = false;
|
|
234686
|
+
return { approvalEdit: {
|
|
234687
|
+
args: editedDecision.editedToolInput,
|
|
234688
|
+
record: (validatedArgs) => {
|
|
234689
|
+
if (recorded) throw new Error("Edited approval Wire event was already recorded");
|
|
234690
|
+
recorded = true;
|
|
234691
|
+
this.recordApprovalEdited(context, validatedArgs);
|
|
234692
|
+
}
|
|
234693
|
+
} };
|
|
234694
|
+
}
|
|
234384
234695
|
const resolved = result.resolveApproval?.(response);
|
|
234385
234696
|
if (resolved !== void 0) return this.permissionPolicyResolutionToPrepare(resolved, context, policyName);
|
|
234386
234697
|
if (response.decision === "approved") return;
|
|
@@ -244306,7 +244617,7 @@ function validateExecutableToolArgs(tool, args) {
|
|
|
244306
244617
|
}
|
|
244307
244618
|
return validateToolArgs(validator, args);
|
|
244308
244619
|
}
|
|
244309
|
-
async function prepareToolCall(step, call) {
|
|
244620
|
+
async function prepareToolCall(step, call, approvalEditCount = 0) {
|
|
244310
244621
|
const settleError = async (args, output, displayFields) => {
|
|
244311
244622
|
await dispatchToolCall(step, call, args, displayFields);
|
|
244312
244623
|
return { task: makeResolvedToolCallTask(makeErrorToolResult(call, args, output)) };
|
|
@@ -244341,10 +244652,31 @@ async function prepareToolCall(step, call) {
|
|
|
244341
244652
|
const settleAborted = () => settleError(effectiveArgs, abortedToolOutput(call.toolName, step.signal), displayFields);
|
|
244342
244653
|
if (step.signal.aborted) return settleAborted();
|
|
244343
244654
|
if (execution.isError === true) return settleSynthetic(effectiveArgs, execution, displayFields);
|
|
244344
|
-
const authorization = await runAuthorizeToolExecutionHook(step, call, effectiveArgs, execution);
|
|
244655
|
+
const authorization = await runAuthorizeToolExecutionHook(step, call, effectiveArgs, execution, approvalEditCount);
|
|
244345
244656
|
if (step.signal.aborted) return settleAborted();
|
|
244346
244657
|
if (authorization?.block === true) return settleError(effectiveArgs, authorization.reason ?? `Tool call "${call.toolName}" was blocked`, displayFields);
|
|
244347
244658
|
if (authorization?.syntheticResult !== void 0) return settleSynthetic(effectiveArgs, authorization.syntheticResult, displayFields);
|
|
244659
|
+
if (authorization?.approvalEdit !== void 0) {
|
|
244660
|
+
let plan;
|
|
244661
|
+
try {
|
|
244662
|
+
plan = buildEditedToolCallPlan({
|
|
244663
|
+
step,
|
|
244664
|
+
call,
|
|
244665
|
+
editedArgs: authorization.approvalEdit.args,
|
|
244666
|
+
editCount: approvalEditCount,
|
|
244667
|
+
preflightToolCall
|
|
244668
|
+
});
|
|
244669
|
+
} catch (error) {
|
|
244670
|
+
return settleError(authorization.approvalEdit.args, `Edited approval could not be re-prepared: ${errorMessage$12(error)}`, displayFields);
|
|
244671
|
+
}
|
|
244672
|
+
if (plan.kind === "rejected") return settleError(plan.call.args, plan.output ?? `Edited args for tool "${call.toolName}" were rejected`, displayFields);
|
|
244673
|
+
try {
|
|
244674
|
+
authorization.approvalEdit.record(plan.call.args);
|
|
244675
|
+
} catch (error) {
|
|
244676
|
+
return settleError(plan.call.args, `Edited approval evidence could not be recorded: ${errorMessage$12(error)}`, displayFields);
|
|
244677
|
+
}
|
|
244678
|
+
return prepareToolCall(plan.step, plan.call, plan.editCount);
|
|
244679
|
+
}
|
|
244348
244680
|
const executionMetadata = authorization?.executionMetadata ?? decision.metadata;
|
|
244349
244681
|
await dispatchToolCall(step, call, effectiveArgs, displayFields);
|
|
244350
244682
|
return {
|
|
@@ -244418,7 +244750,7 @@ async function runPrepareToolExecutionHook(step, call) {
|
|
|
244418
244750
|
metadata: hookResult?.executionMetadata
|
|
244419
244751
|
};
|
|
244420
244752
|
}
|
|
244421
|
-
async function runAuthorizeToolExecutionHook(step, call, args, execution) {
|
|
244753
|
+
async function runAuthorizeToolExecutionHook(step, call, args, execution, approvalEditCount = 0) {
|
|
244422
244754
|
const { hooks, signal, turnId, currentStep, llm } = step;
|
|
244423
244755
|
if (hooks?.authorizeToolExecution === void 0) return void 0;
|
|
244424
244756
|
try {
|
|
@@ -244428,6 +244760,7 @@ async function runAuthorizeToolExecutionHook(step, call, args, execution) {
|
|
|
244428
244760
|
tool: call.tool,
|
|
244429
244761
|
args,
|
|
244430
244762
|
execution,
|
|
244763
|
+
approvalEditCount,
|
|
244431
244764
|
turnId,
|
|
244432
244765
|
stepNumber: currentStep,
|
|
244433
244766
|
signal,
|
|
@@ -245955,7 +246288,7 @@ var init_modelCatalog$2 = __esmMin((() => {
|
|
|
245955
246288
|
function isVolatileEventType(type) {
|
|
245956
246289
|
return volatileEventTypeSet.has(type);
|
|
245957
246290
|
}
|
|
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;
|
|
246291
|
+
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
246292
|
var init_events$1 = __esmMin((() => {
|
|
245960
246293
|
init_zod$1();
|
|
245961
246294
|
init_display();
|
|
@@ -246029,9 +246362,16 @@ var init_events$1 = __esmMin((() => {
|
|
|
246029
246362
|
isError: boolean$1().optional()
|
|
246030
246363
|
});
|
|
246031
246364
|
compactionSummaryOriginSchema = object({ kind: literal("compaction_summary") });
|
|
246365
|
+
cronToolScopeSchema = object({
|
|
246366
|
+
mode: literal("scoped"),
|
|
246367
|
+
names: array(string()).max(64),
|
|
246368
|
+
digest: string()
|
|
246369
|
+
});
|
|
246032
246370
|
systemTriggerOriginSchema = object({
|
|
246033
246371
|
kind: literal("system_trigger"),
|
|
246034
|
-
name: string()
|
|
246372
|
+
name: string(),
|
|
246373
|
+
cronRunId: string().optional(),
|
|
246374
|
+
toolScope: cronToolScopeSchema.optional()
|
|
246035
246375
|
});
|
|
246036
246376
|
agentCoreBackgroundTaskStatusSchema = _enum([
|
|
246037
246377
|
"running",
|
|
@@ -246050,10 +246390,12 @@ var init_events$1 = __esmMin((() => {
|
|
|
246050
246390
|
cronJobOriginSchema = object({
|
|
246051
246391
|
kind: literal("cron_job"),
|
|
246052
246392
|
jobId: string(),
|
|
246393
|
+
runId: string().optional(),
|
|
246053
246394
|
cron: string(),
|
|
246054
246395
|
recurring: boolean$1(),
|
|
246055
246396
|
coalescedCount: number$1(),
|
|
246056
|
-
stale: boolean$1()
|
|
246397
|
+
stale: boolean$1(),
|
|
246398
|
+
toolScope: cronToolScopeSchema.optional()
|
|
246057
246399
|
});
|
|
246058
246400
|
cronMissedOriginSchema = object({
|
|
246059
246401
|
kind: literal("cron_missed"),
|
|
@@ -246066,7 +246408,8 @@ var init_events$1 = __esmMin((() => {
|
|
|
246066
246408
|
});
|
|
246067
246409
|
retryOriginSchema = object({
|
|
246068
246410
|
kind: literal("retry"),
|
|
246069
|
-
trigger: string().optional()
|
|
246411
|
+
trigger: string().optional(),
|
|
246412
|
+
toolScope: cronToolScopeSchema.optional()
|
|
246070
246413
|
});
|
|
246071
246414
|
promptOriginSchema = discriminatedUnion("kind", [
|
|
246072
246415
|
userPromptOriginSchema,
|
|
@@ -246586,8 +246929,30 @@ var init_events$1 = __esmMin((() => {
|
|
|
246586
246929
|
});
|
|
246587
246930
|
cronFiredEventSchema = object({
|
|
246588
246931
|
type: literal("cron.fired"),
|
|
246589
|
-
origin: cronJobOriginSchema
|
|
246590
|
-
|
|
246932
|
+
origin: cronJobOriginSchema
|
|
246933
|
+
});
|
|
246934
|
+
cronRunCreatedEventSchema = object({
|
|
246935
|
+
type: literal("cron.run.created"),
|
|
246936
|
+
runId: string(),
|
|
246937
|
+
jobId: string(),
|
|
246938
|
+
coalescedCount: number$1(),
|
|
246939
|
+
toolScopeDigest: string().nullable()
|
|
246940
|
+
});
|
|
246941
|
+
cronRunStartedEventSchema = object({
|
|
246942
|
+
type: literal("cron.run.started"),
|
|
246943
|
+
runId: string(),
|
|
246944
|
+
jobId: string(),
|
|
246945
|
+
turnId: number$1()
|
|
246946
|
+
});
|
|
246947
|
+
cronRunTerminalEventSchema = object({
|
|
246948
|
+
type: _enum(["cron.run.completed", "cron.run.failed", "cron.run.cancelled", "cron.run.lost"]),
|
|
246949
|
+
runId: string(),
|
|
246950
|
+
jobId: string(),
|
|
246951
|
+
durationMs: number$1().optional(),
|
|
246952
|
+
toolCalls: number$1(),
|
|
246953
|
+
toolErrors: number$1(),
|
|
246954
|
+
outputCount: number$1(),
|
|
246955
|
+
errorCategory: string().optional()
|
|
246591
246956
|
});
|
|
246592
246957
|
attentionIntentSchema = object({
|
|
246593
246958
|
accepted: literal(true),
|
|
@@ -246701,6 +247066,9 @@ var init_events$1 = __esmMin((() => {
|
|
|
246701
247066
|
backgroundTaskStartedEventSchema,
|
|
246702
247067
|
backgroundTaskTerminatedEventSchema,
|
|
246703
247068
|
cronFiredEventSchema,
|
|
247069
|
+
cronRunCreatedEventSchema,
|
|
247070
|
+
cronRunStartedEventSchema,
|
|
247071
|
+
cronRunTerminalEventSchema,
|
|
246704
247072
|
attentionAuthorizedEventSchema,
|
|
246705
247073
|
promptSubmittedEventSchema
|
|
246706
247074
|
]);
|
|
@@ -247246,7 +247614,8 @@ var init_approval$2 = __esmMin((() => {
|
|
|
247246
247614
|
approvalDecisionSchema = _enum([
|
|
247247
247615
|
"approved",
|
|
247248
247616
|
"rejected",
|
|
247249
|
-
"cancelled"
|
|
247617
|
+
"cancelled",
|
|
247618
|
+
"edited"
|
|
247250
247619
|
]);
|
|
247251
247620
|
approvalScopeSchema = _enum(["session"]);
|
|
247252
247621
|
approvalRequestSchema = object({
|
|
@@ -247257,6 +247626,7 @@ var init_approval$2 = __esmMin((() => {
|
|
|
247257
247626
|
tool_name: string().min(1),
|
|
247258
247627
|
action: string(),
|
|
247259
247628
|
tool_input_display: unknown(),
|
|
247629
|
+
allow_edit: boolean$1().optional(),
|
|
247260
247630
|
created_at: isoDateTimeSchema,
|
|
247261
247631
|
expires_at: isoDateTimeSchema
|
|
247262
247632
|
});
|
|
@@ -247264,7 +247634,8 @@ var init_approval$2 = __esmMin((() => {
|
|
|
247264
247634
|
decision: approvalDecisionSchema,
|
|
247265
247635
|
scope: approvalScopeSchema.optional(),
|
|
247266
247636
|
feedback: string().optional(),
|
|
247267
|
-
selected_label: string().optional()
|
|
247637
|
+
selected_label: string().optional(),
|
|
247638
|
+
edited_tool_input: unknown().optional()
|
|
247268
247639
|
});
|
|
247269
247640
|
}));
|
|
247270
247641
|
//#endregion
|
|
@@ -251720,6 +252091,89 @@ var init_task_update = __esmMin((() => {
|
|
|
251720
252091
|
};
|
|
251721
252092
|
}));
|
|
251722
252093
|
//#endregion
|
|
252094
|
+
//#region ../../packages/agent-core/src/tools/background/task-resume.ts
|
|
252095
|
+
var DurableTaskResumeRuntime$1, TaskResumeInputSchema, TaskResumeTool;
|
|
252096
|
+
var init_task_resume = __esmMin((() => {
|
|
252097
|
+
init_zod$1();
|
|
252098
|
+
init_input_schema();
|
|
252099
|
+
init_rule_match();
|
|
252100
|
+
init_agent_task();
|
|
252101
|
+
({ DurableTaskResumeRuntime: DurableTaskResumeRuntime$1 } = createRequire(import.meta.url)("./bin/durable-task-resume-runtime.cjs"));
|
|
252102
|
+
TaskResumeInputSchema = object({
|
|
252103
|
+
task_id: string().trim().min(1).describe("The lost agent task ID, or completed TaskResume successor, to continue."),
|
|
252104
|
+
prompt: string().trim().min(1).max(32768).describe("New instructions for the preserved agent context."),
|
|
252105
|
+
description: string().trim().min(1).max(1024).describe("Short description for the replacement background task."),
|
|
252106
|
+
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.")
|
|
252107
|
+
});
|
|
252108
|
+
TaskResumeTool = class {
|
|
252109
|
+
manager;
|
|
252110
|
+
subagentHost;
|
|
252111
|
+
runtime;
|
|
252112
|
+
name = "TaskResume";
|
|
252113
|
+
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.";
|
|
252114
|
+
parameters = toInputJsonSchema(TaskResumeInputSchema);
|
|
252115
|
+
constructor(manager, subagentHost) {
|
|
252116
|
+
this.manager = manager;
|
|
252117
|
+
this.subagentHost = subagentHost;
|
|
252118
|
+
this.runtime = new DurableTaskResumeRuntime$1({
|
|
252119
|
+
getTask: (taskId) => manager.getTask(taskId),
|
|
252120
|
+
getIntent: (taskId) => manager.resumeStore?.getBySourceTaskId(taskId),
|
|
252121
|
+
writeIntent: (intent) => manager.resumeStore.write(intent),
|
|
252122
|
+
markIntentStarted: (taskId, startedAt) => manager.resumeStore.markStarted(taskId, startedAt),
|
|
252123
|
+
reserveTaskId: (prefix) => manager.reserveTaskId(prefix),
|
|
252124
|
+
resumeAgent: (agentId, options) => subagentHost.resume(agentId, options),
|
|
252125
|
+
createTask: (handle, description, metadata) => new AgentBackgroundTask(handle, description, subagentHost, metadata.controller ?? new AbortController(), {
|
|
252126
|
+
timeoutMs: resolveSubagentTimeoutMs({ perRunMinutes: metadata.timeoutMinutes }),
|
|
252127
|
+
runInBackground: true,
|
|
252128
|
+
parentToolCallId: metadata.parentToolCallId,
|
|
252129
|
+
responseFormat: void 0,
|
|
252130
|
+
resumed: true,
|
|
252131
|
+
replacesTaskId: metadata.replacesTaskId,
|
|
252132
|
+
resumeRootTaskId: metadata.resumeRootTaskId
|
|
252133
|
+
}),
|
|
252134
|
+
registerTask: (task, options) => manager.registerTask(task, options),
|
|
252135
|
+
awaitTaskPersisted: (taskId) => manager.awaitTaskPersisted(taskId),
|
|
252136
|
+
emitEvent: (event) => manager.agent.emitEvent(event),
|
|
252137
|
+
now: () => Date.now()
|
|
252138
|
+
});
|
|
252139
|
+
}
|
|
252140
|
+
resolveExecution(args) {
|
|
252141
|
+
return {
|
|
252142
|
+
description: `Resuming agent task ${args.task_id}`,
|
|
252143
|
+
approvalRule: this.name,
|
|
252144
|
+
matchesRule: (ruleArgs) => matchesGlobRuleSubject(ruleArgs, args.task_id),
|
|
252145
|
+
execute: (ctx) => this.execute(args, ctx)
|
|
252146
|
+
};
|
|
252147
|
+
}
|
|
252148
|
+
async execute(args, { toolCallId, signal, turnId }) {
|
|
252149
|
+
const controller = new AbortController();
|
|
252150
|
+
try {
|
|
252151
|
+
signal.throwIfAborted();
|
|
252152
|
+
const result = await this.runtime.resume({
|
|
252153
|
+
taskId: args.task_id,
|
|
252154
|
+
prompt: args.prompt,
|
|
252155
|
+
description: args.description,
|
|
252156
|
+
timeoutMinutes: args.timeout_minutes,
|
|
252157
|
+
parentToolCallId: toolCallId,
|
|
252158
|
+
toolScope: this.subagentHost.toolScopeForTurn(Number(turnId)),
|
|
252159
|
+
controller,
|
|
252160
|
+
signal
|
|
252161
|
+
});
|
|
252162
|
+
return {
|
|
252163
|
+
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`,
|
|
252164
|
+
isError: false
|
|
252165
|
+
};
|
|
252166
|
+
} catch (error) {
|
|
252167
|
+
controller.abort();
|
|
252168
|
+
return {
|
|
252169
|
+
output: error instanceof Error ? error.message : String(error),
|
|
252170
|
+
isError: true
|
|
252171
|
+
};
|
|
252172
|
+
}
|
|
252173
|
+
}
|
|
252174
|
+
};
|
|
252175
|
+
}));
|
|
252176
|
+
//#endregion
|
|
251723
252177
|
//#region ../../packages/agent-core/src/tools/background/task-stop.md?raw
|
|
251724
252178
|
var task_stop_default;
|
|
251725
252179
|
var init_task_stop$1 = __esmMin((() => {
|
|
@@ -251907,6 +252361,67 @@ var init_cron_list = __esmMin((() => {
|
|
|
251907
252361
|
};
|
|
251908
252362
|
}));
|
|
251909
252363
|
//#endregion
|
|
252364
|
+
//#region ../../packages/agent-core/src/tools/cron/cron-runs.ts
|
|
252365
|
+
var CronRunListInputSchema, CronRunOutputInputSchema, CronRunListTool, CronRunOutputTool;
|
|
252366
|
+
var init_cron_runs = __esmMin((() => {
|
|
252367
|
+
init_zod$1();
|
|
252368
|
+
init_input_schema();
|
|
252369
|
+
CronRunListInputSchema = object({
|
|
252370
|
+
job_id: string().regex(/^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$/u).optional().describe("Optional cron job id filter."),
|
|
252371
|
+
status: string().regex(/^(buffered|running|completed|failed|cancelled|lost)$/u).optional().describe("Optional run status filter."),
|
|
252372
|
+
limit: number$1().int().min(1).max(100).optional().default(20).describe("Maximum number of newest run receipts.")
|
|
252373
|
+
}).strict();
|
|
252374
|
+
CronRunOutputInputSchema = object({
|
|
252375
|
+
run_id: string().regex(/^[0-9a-f]{16}$/u).describe("The 16-hex run id returned by CronRunList.")
|
|
252376
|
+
}).strict();
|
|
252377
|
+
CronRunListTool = class {
|
|
252378
|
+
manager;
|
|
252379
|
+
name = "CronRunList";
|
|
252380
|
+
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.";
|
|
252381
|
+
parameters = toInputJsonSchema(CronRunListInputSchema);
|
|
252382
|
+
constructor(manager) {
|
|
252383
|
+
this.manager = manager;
|
|
252384
|
+
}
|
|
252385
|
+
resolveExecution(args) {
|
|
252386
|
+
return {
|
|
252387
|
+
description: "Listing private cron run receipts",
|
|
252388
|
+
approvalRule: this.name,
|
|
252389
|
+
execute: async () => {
|
|
252390
|
+
const runs = this.manager.listRuns({
|
|
252391
|
+
jobId: args.job_id,
|
|
252392
|
+
status: args.status,
|
|
252393
|
+
limit: args.limit
|
|
252394
|
+
});
|
|
252395
|
+
return { output: JSON.stringify({ runs }, null, 2), isError: false };
|
|
252396
|
+
}
|
|
252397
|
+
};
|
|
252398
|
+
}
|
|
252399
|
+
};
|
|
252400
|
+
CronRunOutputTool = class {
|
|
252401
|
+
manager;
|
|
252402
|
+
name = "CronRunOutput";
|
|
252403
|
+
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.";
|
|
252404
|
+
parameters = toInputJsonSchema(CronRunOutputInputSchema);
|
|
252405
|
+
constructor(manager) {
|
|
252406
|
+
this.manager = manager;
|
|
252407
|
+
}
|
|
252408
|
+
resolveExecution(args) {
|
|
252409
|
+
return {
|
|
252410
|
+
description: `Reading private cron run ${args.run_id}`,
|
|
252411
|
+
approvalRule: this.name,
|
|
252412
|
+
execute: async () => {
|
|
252413
|
+
const run = this.manager.readRunOutput(args.run_id);
|
|
252414
|
+
if (run === null) return {
|
|
252415
|
+
output: `No cron run with id ${args.run_id} exists in this session.`,
|
|
252416
|
+
isError: true
|
|
252417
|
+
};
|
|
252418
|
+
return { output: JSON.stringify(run, null, 2), isError: false };
|
|
252419
|
+
}
|
|
252420
|
+
};
|
|
252421
|
+
}
|
|
252422
|
+
};
|
|
252423
|
+
}));
|
|
252424
|
+
//#endregion
|
|
251910
252425
|
//#region ../../packages/agent-core/src/agent/permission/policies/deny-all.ts
|
|
251911
252426
|
var DenyAllPermissionPolicy;
|
|
251912
252427
|
var init_deny_all = __esmMin((() => {
|
|
@@ -252318,6 +252833,7 @@ var init_subagent_batch = __esmMin((() => {
|
|
|
252318
252833
|
description: task.description,
|
|
252319
252834
|
swarmIndex: task.swarmIndex,
|
|
252320
252835
|
runInBackground: task.runInBackground,
|
|
252836
|
+
responseFormat: task.responseFormat,
|
|
252321
252837
|
compactBeforeRetry: attempt.state.retryCount > 0,
|
|
252322
252838
|
signal: attempt.controller.signal,
|
|
252323
252839
|
onReady: () => {
|
|
@@ -252342,11 +252858,13 @@ var init_subagent_batch = __esmMin((() => {
|
|
|
252342
252858
|
return this.failedAttemptOutcome(attempt, error);
|
|
252343
252859
|
}
|
|
252344
252860
|
attempt.state.agentId = handle.agentId;
|
|
252861
|
+
attempt.state.profileName = handle.profileName;
|
|
252345
252862
|
try {
|
|
252346
252863
|
const completion = await handle.completion;
|
|
252347
252864
|
return {
|
|
252348
252865
|
task,
|
|
252349
252866
|
agentId: handle.agentId,
|
|
252867
|
+
profileName: handle.profileName,
|
|
252350
252868
|
status: "completed",
|
|
252351
252869
|
result: completion.result,
|
|
252352
252870
|
usage: completion.usage
|
|
@@ -252370,6 +252888,7 @@ var init_subagent_batch = __esmMin((() => {
|
|
|
252370
252888
|
return {
|
|
252371
252889
|
task: attempt.state.task,
|
|
252372
252890
|
agentId: attempt.state.agentId,
|
|
252891
|
+
profileName: attempt.state.profileName,
|
|
252373
252892
|
status,
|
|
252374
252893
|
state: attempt.state.agentId === void 0 ? "not_started" : "started",
|
|
252375
252894
|
error: this.attemptErrorMessage(attempt, error, status)
|
|
@@ -252633,7 +253152,7 @@ async function runChildTurnToCompletion(child, signal) {
|
|
|
252633
253152
|
}
|
|
252634
253153
|
return completion.stopReason;
|
|
252635
253154
|
}
|
|
252636
|
-
async function completeChildTurnWithMaxTokensHandoff(child, signal) {
|
|
253155
|
+
async function completeChildTurnWithMaxTokensHandoff(child, signal, promptOrigin = SUBAGENT_PROMPT_ORIGIN) {
|
|
252637
253156
|
let stopReason = await runChildTurnToCompletion(child, signal);
|
|
252638
253157
|
let handoffAttempts = 0;
|
|
252639
253158
|
while (shouldRequestSubagentHandoff(stopReason, handoffAttempts)) {
|
|
@@ -252642,7 +253161,7 @@ async function completeChildTurnWithMaxTokensHandoff(child, signal) {
|
|
|
252642
253161
|
if (child.turn.prompt([{
|
|
252643
253162
|
type: "text",
|
|
252644
253163
|
text: SUBAGENT_MAX_TOKENS_HANDOFF_PROMPT
|
|
252645
|
-
}],
|
|
253164
|
+
}], promptOrigin) === null) throw new Error("Subagent could not start its max_tokens recovery handoff.");
|
|
252646
253165
|
stopReason = await runChildTurnToCompletion(child, signal);
|
|
252647
253166
|
}
|
|
252648
253167
|
if (stopReason === "max_tokens") throw new Error(buildSubagentMaxTokensFailure(lastAssistantText(child)));
|
|
@@ -252659,7 +253178,7 @@ function lastAssistantText(agent) {
|
|
|
252659
253178
|
}
|
|
252660
253179
|
return "";
|
|
252661
253180
|
}
|
|
252662
|
-
async function completeStructuredSubagentResult(child, childId, profileName, responseFormat, signal) {
|
|
253181
|
+
async function completeStructuredSubagentResult(child, childId, profileName, responseFormat, signal, promptOrigin = SUBAGENT_PROMPT_ORIGIN) {
|
|
252663
253182
|
let validation = validateStructuredSubagentOutput(lastAssistantText(child), responseFormat);
|
|
252664
253183
|
if (validation.validatorException === true) throw new Error(validation.error);
|
|
252665
253184
|
if (!validation.ok) {
|
|
@@ -252667,8 +253186,8 @@ async function completeStructuredSubagentResult(child, childId, profileName, res
|
|
|
252667
253186
|
if (child.turn.prompt([{
|
|
252668
253187
|
type: "text",
|
|
252669
253188
|
text: buildStructuredResponseRepairPrompt(responseFormat, validation.error)
|
|
252670
|
-
}],
|
|
252671
|
-
await completeChildTurnWithMaxTokensHandoff(child, signal);
|
|
253189
|
+
}], promptOrigin) === null) throw new Error("Subagent could not start its structured-output repair turn.");
|
|
253190
|
+
await completeChildTurnWithMaxTokensHandoff(child, signal, promptOrigin);
|
|
252672
253191
|
signal.throwIfAborted();
|
|
252673
253192
|
validation = validateStructuredSubagentOutput(lastAssistantText(child), responseFormat);
|
|
252674
253193
|
if (validation.validatorException === true) throw new Error(validation.error);
|
|
@@ -252681,7 +253200,7 @@ function shouldSuppressQueuedAttemptFailureEvent(options, error) {
|
|
|
252681
253200
|
if (isProviderRateLimitError(error)) return true;
|
|
252682
253201
|
return isAbortError$4(error) || options.signal.aborted;
|
|
252683
253202
|
}
|
|
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;
|
|
253203
|
+
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
253204
|
var init_subagent_host = __esmMin((() => {
|
|
252686
253205
|
init_src$4();
|
|
252687
253206
|
init_errors$8();
|
|
@@ -252696,6 +253215,8 @@ var init_subagent_host = __esmMin((() => {
|
|
|
252696
253215
|
({ DEFAULT_SUBAGENT_TIMEOUT_MS, resolveSubagentTimeoutMs, runAgentWithTimeoutContinuation } = createRequire(import.meta.url)("./bin/subagent-timeout-policy.cjs"));
|
|
252697
253216
|
({ buildSubagentUsageDelta } = createRequire(import.meta.url)("./bin/subagent-usage-rollup-policy.cjs"));
|
|
252698
253217
|
({ inheritSubagentAllowedTools, inheritSubagentLifecycleTools } = createRequire(import.meta.url)("./bin/subagent-tool-policy.cjs"));
|
|
253218
|
+
({ prepareSubagentSkillPolicy, profileWithSubagentSkillTools, restoreSubagentSkillPolicy } = createRequire(import.meta.url)("./bin/subagent-skill-policy.cjs"));
|
|
253219
|
+
({ SUBAGENT_FORK_REMINDER, projectSubagentForkContext, resolveSubagentContextMode } = createRequire(import.meta.url)("./bin/subagent-context-fork-policy.cjs"));
|
|
252699
253220
|
({
|
|
252700
253221
|
STRUCTURED_SUBAGENT_OUTPUT_ERROR,
|
|
252701
253222
|
prepareStructuredResponseFormat,
|
|
@@ -252719,6 +253240,12 @@ var init_subagent_host = __esmMin((() => {
|
|
|
252719
253240
|
kind: "system_trigger",
|
|
252720
253241
|
name: "subagent"
|
|
252721
253242
|
};
|
|
253243
|
+
function subagentPromptOrigin(toolScope) {
|
|
253244
|
+
return toolScope === void 0 ? SUBAGENT_PROMPT_ORIGIN : {
|
|
253245
|
+
...SUBAGENT_PROMPT_ORIGIN,
|
|
253246
|
+
toolScope
|
|
253247
|
+
};
|
|
253248
|
+
}
|
|
252722
253249
|
SIDE_QUESTION_SYSTEM_REMINDER = `
|
|
252723
253250
|
This is a side-channel conversation with the user. You should answer user questions directly based on what you already know.
|
|
252724
253251
|
|
|
@@ -252757,21 +253284,37 @@ IMPORTANT:
|
|
|
252757
253284
|
}
|
|
252758
253285
|
return this.session.getReadyAgent(currentId);
|
|
252759
253286
|
}
|
|
253287
|
+
toolScopeForTurn(turnId) {
|
|
253288
|
+
return inheritedCronToolScope(this.session.getReadyAgent(this.ownerAgentId)?.turn.toolScopeForTurn(turnId));
|
|
253289
|
+
}
|
|
253290
|
+
isRootAgent() {
|
|
253291
|
+
return this.session.metadata.agents[this.ownerAgentId]?.parentAgentId == null;
|
|
253292
|
+
}
|
|
252760
253293
|
async spawn(options) {
|
|
252761
253294
|
options.signal.throwIfAborted();
|
|
252762
253295
|
const parent = await this.session.ensureAgentResumed(this.ownerAgentId);
|
|
253296
|
+
const contextMode = resolveSubagentContextMode({
|
|
253297
|
+
requested: options.contextMode,
|
|
253298
|
+
isRoot: this.isRootAgent()
|
|
253299
|
+
});
|
|
252763
253300
|
const profile = this.resolveProfile(parent, options.profileName);
|
|
253301
|
+
const skillPolicy = prepareSubagentSkillPolicy(profile.subagentSkills, this.session.skills);
|
|
253302
|
+
const effectiveProfile = profileWithSubagentSkillTools(profile, skillPolicy);
|
|
252764
253303
|
const { id, agent } = await this.session.createAgent({
|
|
252765
253304
|
type: "sub",
|
|
252766
|
-
generate: parent.rawGenerate
|
|
253305
|
+
generate: parent.rawGenerate,
|
|
253306
|
+
skillRegistry: skillPolicy.registry
|
|
252767
253307
|
}, {
|
|
252768
253308
|
parentAgentId: this.ownerAgentId,
|
|
252769
|
-
swarmItem: options.swarmItem
|
|
253309
|
+
swarmItem: options.swarmItem,
|
|
253310
|
+
profileName: profile.name,
|
|
253311
|
+
skillPolicy: skillPolicy.metadata
|
|
252770
253312
|
});
|
|
252771
253313
|
const completion = this.runWithTrackedChildUsage(parent, agent, id, options, async (runOptions) => {
|
|
252772
253314
|
this.emitSubagentSpawned(parent, id, profile.name, runOptions);
|
|
252773
253315
|
try {
|
|
252774
|
-
await this.configureChild(parent, agent,
|
|
253316
|
+
await this.configureChild(parent, agent, effectiveProfile);
|
|
253317
|
+
if (contextMode === "fork") this.seedForkedContext(parent, agent);
|
|
252775
253318
|
return await this.runPromptTurn(parent, id, agent, profile.name, runOptions);
|
|
252776
253319
|
} catch (error) {
|
|
252777
253320
|
this.emitSubagentFailed(parent, id, runOptions, error);
|
|
@@ -252845,7 +253388,7 @@ IMPORTANT:
|
|
|
252845
253388
|
await child.fullCompaction.block(runOptions.signal);
|
|
252846
253389
|
}
|
|
252847
253390
|
this.emitSubagentStarted(parent, agentId);
|
|
252848
|
-
if (child.turn.retry("agent-host") === null) throw new Error(`Agent instance "${agentId}" could not start a retry turn`);
|
|
253391
|
+
if (child.turn.retry("agent-host", runOptions.toolScope) === null) throw new Error(`Agent instance "${agentId}" could not start a retry turn`);
|
|
252849
253392
|
this.observeFirstRequest(child, runOptions);
|
|
252850
253393
|
return await this.waitForChildCompletion(parent, agentId, child, profileName, runOptions);
|
|
252851
253394
|
} catch (error) {
|
|
@@ -252968,23 +253511,29 @@ IMPORTANT:
|
|
|
252968
253511
|
const gitContext = await collectGitContext(child.kaos, child.config.cwd);
|
|
252969
253512
|
if (gitContext) childPrompt = `${gitContext}\n\n${childPrompt}`;
|
|
252970
253513
|
}
|
|
253514
|
+
if (options.systemReminder !== void 0) child.context.appendSystemReminder(options.systemReminder, {
|
|
253515
|
+
kind: "system_trigger",
|
|
253516
|
+
name: "durable_task_resume"
|
|
253517
|
+
});
|
|
252971
253518
|
if (options.responseFormat !== void 0) child.context.appendSystemReminder(buildStructuredResponseFormatReminder(options.responseFormat), {
|
|
252972
253519
|
kind: "system_trigger",
|
|
252973
253520
|
name: "subagent_response_format"
|
|
252974
253521
|
});
|
|
252975
253522
|
this.emitSubagentStarted(parent, childId);
|
|
253523
|
+
const childOrigin = subagentPromptOrigin(options.toolScope);
|
|
252976
253524
|
if (child.turn.prompt([{
|
|
252977
253525
|
type: "text",
|
|
252978
253526
|
text: childPrompt
|
|
252979
|
-
}],
|
|
253527
|
+
}], childOrigin) === null) throw new Error(`Agent instance "${childId}" could not start a turn`);
|
|
252980
253528
|
this.observeFirstRequest(child, options);
|
|
252981
253529
|
return this.waitForChildCompletion(parent, childId, child, profileName, options);
|
|
252982
253530
|
}
|
|
252983
253531
|
async waitForChildCompletion(parent, childId, child, profileName, options) {
|
|
252984
|
-
|
|
253532
|
+
const childOrigin = subagentPromptOrigin(options.toolScope);
|
|
253533
|
+
await completeChildTurnWithMaxTokensHandoff(child, options.signal, childOrigin);
|
|
252985
253534
|
let result;
|
|
252986
253535
|
if (options.responseFormat !== void 0) {
|
|
252987
|
-
const structuredResult = await completeStructuredSubagentResult(child, childId, profileName, options.responseFormat, options.signal);
|
|
253536
|
+
const structuredResult = await completeStructuredSubagentResult(child, childId, profileName, options.responseFormat, options.signal, childOrigin);
|
|
252988
253537
|
result = buildStructuredSubagentEnvelope({
|
|
252989
253538
|
agentId: childId,
|
|
252990
253539
|
profileName,
|
|
@@ -253001,8 +253550,8 @@ IMPORTANT:
|
|
|
253001
253550
|
child.turn.prompt([{
|
|
253002
253551
|
type: "text",
|
|
253003
253552
|
text: summary_continuation_default
|
|
253004
|
-
}],
|
|
253005
|
-
await completeChildTurnWithMaxTokensHandoff(child, options.signal);
|
|
253553
|
+
}], childOrigin);
|
|
253554
|
+
await completeChildTurnWithMaxTokensHandoff(child, options.signal, childOrigin);
|
|
253006
253555
|
result = lastAssistantText(child);
|
|
253007
253556
|
}
|
|
253008
253557
|
}
|
|
@@ -253029,10 +253578,22 @@ IMPORTANT:
|
|
|
253029
253578
|
});
|
|
253030
253579
|
const context = await prepareSystemPromptContext(this.session.systemContextKaos(child.kaos.getcwd()), this.session.options.blunHomeDir, { additionalDirs: child.getAdditionalDirs() });
|
|
253031
253580
|
child.useProfile(profile, context, this.session.options.blunHomeDir);
|
|
253032
|
-
child.tools.inheritUserTools(parent.tools);
|
|
253581
|
+
child.tools.inheritUserTools(parent.tools, /* @__PURE__ */ new Set(["Skill"]));
|
|
253033
253582
|
inheritSubagentLifecycleTools(parent.tools, child.tools);
|
|
253034
253583
|
inheritSubagentAllowedTools(parent.tools, child.tools);
|
|
253035
253584
|
}
|
|
253585
|
+
seedForkedContext(parent, child) {
|
|
253586
|
+
const projection = projectSubagentForkContext(parent.context.history);
|
|
253587
|
+
child.context.useProjectedHistoryFrom({
|
|
253588
|
+
history: projection.messages,
|
|
253589
|
+
project: (history) => history
|
|
253590
|
+
});
|
|
253591
|
+
child.context.appendSystemReminder(SUBAGENT_FORK_REMINDER, {
|
|
253592
|
+
kind: "system_trigger",
|
|
253593
|
+
name: "subagent_context_fork"
|
|
253594
|
+
});
|
|
253595
|
+
return projection;
|
|
253596
|
+
}
|
|
253036
253597
|
async triggerSubagentStart(parent, profileName, prompt, signal) {
|
|
253037
253598
|
await parent.hooks?.trigger("SubagentStart", {
|
|
253038
253599
|
matcherValue: profileName,
|
|
@@ -253064,10 +253625,11 @@ IMPORTANT:
|
|
|
253064
253625
|
subagentId: childId,
|
|
253065
253626
|
subagentName: profileName,
|
|
253066
253627
|
parentToolCallId: options.parentToolCallId,
|
|
253067
|
-
|
|
253068
|
-
|
|
253069
|
-
|
|
253070
|
-
|
|
253628
|
+
parentToolCallUuid: options.parentToolCallUuid,
|
|
253629
|
+
parentAgentId: this.ownerAgentId,
|
|
253630
|
+
description: options.description,
|
|
253631
|
+
contextMode: options.contextMode === "fork" ? "fork" : "isolated",
|
|
253632
|
+
swarmIndex: options.swarmIndex,
|
|
253071
253633
|
runInBackground: options.runInBackground
|
|
253072
253634
|
});
|
|
253073
253635
|
parent.telemetry.track("subagent_created", {
|
|
@@ -253160,7 +253722,7 @@ function buildSubagentDescriptions(subagents) {
|
|
|
253160
253722
|
return `${header}\n Tools: ${subagent.tools.join(", ")}`;
|
|
253161
253723
|
}).join("\n");
|
|
253162
253724
|
}
|
|
253163
|
-
var AgentToolInputSchema, BACKGROUND_AGENT_UNAVAILABLE, AgentTool, USER_INTERRUPTED_SUBAGENT_MESSAGE, resolveSubagentRunMode;
|
|
253725
|
+
var AgentToolInputSchema, BACKGROUND_AGENT_UNAVAILABLE, SUBAGENT_CONTEXT_FORK_TOOL_DESCRIPTION, AgentTool, USER_INTERRUPTED_SUBAGENT_MESSAGE, resolveSubagentRunMode;
|
|
253164
253726
|
var init_agent$1 = __esmMin((() => {
|
|
253165
253727
|
init_zod$1();
|
|
253166
253728
|
init_tool_access();
|
|
@@ -253174,6 +253736,7 @@ var init_agent$1 = __esmMin((() => {
|
|
|
253174
253736
|
init_agent_background_enabled();
|
|
253175
253737
|
init_agent$2();
|
|
253176
253738
|
({ resolveSubagentRunMode } = createRequire(import.meta.url)("./bin/subagent-parent-responsiveness.cjs"));
|
|
253739
|
+
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
253740
|
AgentToolInputSchema = preprocess((input) => {
|
|
253178
253741
|
if (typeof input !== "object" || input === null || Array.isArray(input)) return input;
|
|
253179
253742
|
const normalized = { ...input };
|
|
@@ -253186,6 +253749,7 @@ var init_agent$1 = __esmMin((() => {
|
|
|
253186
253749
|
prompt: string().describe("Full task prompt for the subagent"),
|
|
253187
253750
|
description: string().describe("Short task description (3-5 words) for UI display"),
|
|
253188
253751
|
subagent_type: string().optional().describe("One of the available agent types (see \"Available agent types\" in this tool description). Defaults to \"coder\" when omitted."),
|
|
253752
|
+
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
253753
|
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
253754
|
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
253755
|
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 +253781,7 @@ var init_agent$1 = __esmMin((() => {
|
|
|
253217
253781
|
const log = options?.log;
|
|
253218
253782
|
this.allowBackground = options?.allowBackground ?? true;
|
|
253219
253783
|
const typeLines = buildSubagentDescriptions(subagents);
|
|
253220
|
-
const baseDescription = `${agent_default}\n\n${this.allowBackground ? agent_background_enabled_default : agent_background_disabled_default}`;
|
|
253784
|
+
const baseDescription = `${agent_default}\n\n${SUBAGENT_CONTEXT_FORK_TOOL_DESCRIPTION}\n\n${this.allowBackground ? agent_background_enabled_default : agent_background_disabled_default}`;
|
|
253221
253785
|
this.description = typeLines ? `${baseDescription}\n\nAvailable agent types (pass via subagent_type):\n${typeLines}` : baseDescription;
|
|
253222
253786
|
this.log = log;
|
|
253223
253787
|
}
|
|
@@ -253246,7 +253810,7 @@ var init_agent$1 = __esmMin((() => {
|
|
|
253246
253810
|
execute: (ctx) => this.execution(args, ctx)
|
|
253247
253811
|
};
|
|
253248
253812
|
}
|
|
253249
|
-
async execution(args, { toolCallId, signal }) {
|
|
253813
|
+
async execution(args, { toolCallId, signal, turnId }) {
|
|
253250
253814
|
try {
|
|
253251
253815
|
signal.throwIfAborted();
|
|
253252
253816
|
if (args.response_format !== void 0 && args.run_in_background === true) return {
|
|
@@ -253269,6 +253833,19 @@ var init_agent$1 = __esmMin((() => {
|
|
|
253269
253833
|
const runInBackground = responseFormat === void 0 ? resolvedRunMode.runInBackground : false;
|
|
253270
253834
|
const requestedProfileName = args.subagent_type?.length ? args.subagent_type : void 0;
|
|
253271
253835
|
const resumeAgentId = args.resume?.trim();
|
|
253836
|
+
let contextMode;
|
|
253837
|
+
try {
|
|
253838
|
+
contextMode = resolveSubagentContextMode({
|
|
253839
|
+
requested: args.context_mode,
|
|
253840
|
+
resume: resumeAgentId !== void 0 && resumeAgentId.length > 0,
|
|
253841
|
+
isRoot: this.subagentHost.isRootAgent()
|
|
253842
|
+
});
|
|
253843
|
+
} catch (error) {
|
|
253844
|
+
return {
|
|
253845
|
+
output: error instanceof Error ? error.message : String(error),
|
|
253846
|
+
isError: true
|
|
253847
|
+
};
|
|
253848
|
+
}
|
|
253272
253849
|
if (resumeAgentId !== void 0 && resumeAgentId.length > 0 && requestedProfileName !== void 0) return {
|
|
253273
253850
|
output: "Cannot set subagent_type when resuming an existing agent. Resume by agent id only.",
|
|
253274
253851
|
isError: true
|
|
@@ -253289,6 +253866,8 @@ var init_agent$1 = __esmMin((() => {
|
|
|
253289
253866
|
description: args.description,
|
|
253290
253867
|
runInBackground,
|
|
253291
253868
|
responseFormat,
|
|
253869
|
+
contextMode,
|
|
253870
|
+
toolScope: this.subagentHost.toolScopeForTurn(Number(turnId)),
|
|
253292
253871
|
signal: controller.signal
|
|
253293
253872
|
};
|
|
253294
253873
|
let handle;
|
|
@@ -253365,7 +253944,7 @@ var init_agent$1 = __esmMin((() => {
|
|
|
253365
253944
|
//#region ../../packages/agent-core/src/tools/builtin/collaboration/agent-swarm.md?raw
|
|
253366
253945
|
var agent_swarm_default;
|
|
253367
253946
|
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";
|
|
253947
|
+
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
253948
|
}));
|
|
253370
253949
|
//#endregion
|
|
253371
253950
|
//#region ../../packages/agent-core/src/tools/builtin/collaboration/agent-swarm.ts
|
|
@@ -253448,13 +254027,14 @@ function renderSwarmSummary(completed, failed, aborted = 0) {
|
|
|
253448
254027
|
function escapeXmlAttribute(value) {
|
|
253449
254028
|
return value.replaceAll("&", "&").replaceAll("\"", """).replaceAll("<", "<").replaceAll(">", ">");
|
|
253450
254029
|
}
|
|
253451
|
-
var DEFAULT_SUBAGENT_TYPE, PROMPT_TEMPLATE_PLACEHOLDER, MAX_AGENT_SWARM_SUBAGENTS, AgentSwarmToolInputSchema, AgentSwarmTool;
|
|
254030
|
+
var DEFAULT_SUBAGENT_TYPE, PROMPT_TEMPLATE_PLACEHOLDER, MAX_AGENT_SWARM_SUBAGENTS, renderStructuredSwarmResults, parseStructuredSwarmDisplay, structuredSwarmToolResult, AgentSwarmToolInputSchema, AgentSwarmTool;
|
|
253452
254031
|
var init_agent_swarm = __esmMin((() => {
|
|
253453
254032
|
init_zod$1();
|
|
253454
254033
|
init_subagent_host();
|
|
253455
254034
|
init_tool_access();
|
|
253456
254035
|
init_input_schema();
|
|
253457
254036
|
init_agent_swarm$1();
|
|
254037
|
+
({ renderStructuredSwarmResults, parseStructuredSwarmDisplay, structuredSwarmToolResult } = createRequire(import.meta.url)("./bin/structured-agent-swarm-output.cjs"));
|
|
253458
254038
|
DEFAULT_SUBAGENT_TYPE = "coder";
|
|
253459
254039
|
PROMPT_TEMPLATE_PLACEHOLDER = "{{item}}";
|
|
253460
254040
|
MAX_AGENT_SWARM_SUBAGENTS = 128;
|
|
@@ -253464,7 +254044,11 @@ var init_agent_swarm = __esmMin((() => {
|
|
|
253464
254044
|
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
254045
|
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
254046
|
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.")
|
|
254047
|
+
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."),
|
|
254048
|
+
response_format: object({
|
|
254049
|
+
name: string().min(1).max(64).describe("Stable name for the shared structured result"),
|
|
254050
|
+
schema: record(string(), unknown()).describe("Restricted JSON Schema applied to every child result")
|
|
254051
|
+
}).optional().describe("Require one shared validated JSON object shape from every spawned or resumed swarm child.")
|
|
253468
254052
|
}).strict();
|
|
253469
254053
|
AgentSwarmTool = class {
|
|
253470
254054
|
subagentHost;
|
|
@@ -253492,8 +254076,17 @@ var init_agent_swarm = __esmMin((() => {
|
|
|
253492
254076
|
}
|
|
253493
254077
|
async execution(args, context) {
|
|
253494
254078
|
try {
|
|
254079
|
+
let responseFormat;
|
|
254080
|
+
if (args.response_format !== void 0) try {
|
|
254081
|
+
responseFormat = prepareStructuredResponseFormat(args.response_format, compileToolArgsValidator);
|
|
254082
|
+
} catch (error) {
|
|
254083
|
+
return {
|
|
254084
|
+
output: `Invalid response_format: ${error instanceof Error ? error.message : String(error)}`,
|
|
254085
|
+
isError: true
|
|
254086
|
+
};
|
|
254087
|
+
}
|
|
253495
254088
|
this.swarmMode.enter("tool");
|
|
253496
|
-
return
|
|
254089
|
+
return structuredSwarmToolResult(await this.runSwarm(args, context.signal, context.toolCallId, responseFormat, context.turnId));
|
|
253497
254090
|
} catch (error) {
|
|
253498
254091
|
return {
|
|
253499
254092
|
output: error instanceof Error ? error.message : String(error),
|
|
@@ -253501,7 +254094,7 @@ var init_agent_swarm = __esmMin((() => {
|
|
|
253501
254094
|
};
|
|
253502
254095
|
}
|
|
253503
254096
|
}
|
|
253504
|
-
async runSwarm(args, signal, toolCallId) {
|
|
254097
|
+
async runSwarm(args, signal, toolCallId, responseFormat, turnId) {
|
|
253505
254098
|
const profileName = normalizeOptionalString$2(args.subagent_type) ?? DEFAULT_SUBAGENT_TYPE;
|
|
253506
254099
|
const tasks = createAgentSwarmSpecs(args, (agentId) => this.subagentHost.getSwarmItem(agentId)).map((spec) => {
|
|
253507
254100
|
const descriptionName = spec.kind === "resume" ? "resume" : profileName;
|
|
@@ -253513,6 +254106,8 @@ var init_agent_swarm = __esmMin((() => {
|
|
|
253513
254106
|
description: childDescription(args.description, spec.index, descriptionName),
|
|
253514
254107
|
swarmIndex: spec.index,
|
|
253515
254108
|
runInBackground: false,
|
|
254109
|
+
responseFormat,
|
|
254110
|
+
toolScope: this.subagentHost.toolScopeForTurn(Number(turnId)),
|
|
253516
254111
|
swarmItem: spec.item,
|
|
253517
254112
|
signal,
|
|
253518
254113
|
timeout: resolveSubagentTimeoutMs({ perRunMinutes: args.timeout_minutes })
|
|
@@ -253527,10 +254122,11 @@ var init_agent_swarm = __esmMin((() => {
|
|
|
253527
254122
|
kind: "spawn"
|
|
253528
254123
|
};
|
|
253529
254124
|
});
|
|
253530
|
-
|
|
254125
|
+
const results = (await this.subagentHost.runQueued(tasks)).map(({ task, ...result }) => ({
|
|
253531
254126
|
spec: task.data,
|
|
253532
254127
|
...result
|
|
253533
|
-
}))
|
|
254128
|
+
}));
|
|
254129
|
+
return responseFormat === void 0 ? renderSwarmResults(results) : renderStructuredSwarmResults(results, responseFormat);
|
|
253534
254130
|
}
|
|
253535
254131
|
};
|
|
253536
254132
|
}));
|
|
@@ -259646,7 +260242,7 @@ function renderLine(entry, lineEndingStyle) {
|
|
|
259646
260242
|
function renderedLineBytes(renderedLine, isFirst) {
|
|
259647
260243
|
return (isFirst ? 0 : 1) + Buffer.byteLength(renderedLine, "utf8");
|
|
259648
260244
|
}
|
|
259649
|
-
function renderEntries(entries, lineEndingStyle) {
|
|
260245
|
+
function renderEntries(entries, lineEndingStyle, maxBytes) {
|
|
259650
260246
|
const renderedLines = [];
|
|
259651
260247
|
const truncatedLineNumbers = [];
|
|
259652
260248
|
let bytes = 0;
|
|
@@ -259654,14 +260250,14 @@ function renderEntries(entries, lineEndingStyle) {
|
|
|
259654
260250
|
for (const entry of entries) {
|
|
259655
260251
|
const rendered = renderLine(entry, lineEndingStyle);
|
|
259656
260252
|
const lineBytes = renderedLineBytes(rendered.line, renderedLines.length === 0);
|
|
259657
|
-
if (renderedLines.length > 0 && bytes + lineBytes >
|
|
260253
|
+
if (renderedLines.length > 0 && bytes + lineBytes > maxBytes) {
|
|
259658
260254
|
maxBytesReached = true;
|
|
259659
260255
|
break;
|
|
259660
260256
|
}
|
|
259661
260257
|
if (rendered.wasTruncated) truncatedLineNumbers.push(entry.lineNo);
|
|
259662
260258
|
renderedLines.push(rendered.line);
|
|
259663
260259
|
bytes += lineBytes;
|
|
259664
|
-
if (bytes >=
|
|
260260
|
+
if (bytes >= maxBytes) {
|
|
259665
260261
|
maxBytesReached = true;
|
|
259666
260262
|
break;
|
|
259667
260263
|
}
|
|
@@ -259692,7 +260288,7 @@ function containsNulByte(text) {
|
|
|
259692
260288
|
function notReadableFileOutput(path) {
|
|
259693
260289
|
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
260290
|
}
|
|
259695
|
-
var MAX_LINES$1, MAX_LINE_LENGTH,
|
|
260291
|
+
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
260292
|
var init_read = __esmMin((() => {
|
|
259697
260293
|
init_zod$1();
|
|
259698
260294
|
init_tool_access();
|
|
@@ -259703,46 +260299,47 @@ var init_read = __esmMin((() => {
|
|
|
259703
260299
|
init_rule_match();
|
|
259704
260300
|
init_line_endings();
|
|
259705
260301
|
init_read$1();
|
|
259706
|
-
({ readContinuationNotice,
|
|
260302
|
+
({ readContinuationNotice, readModelVisibleBytes, readModelVisibleLines } = createRequire(import.meta.url)("./bin/read-continuation-policy.cjs"));
|
|
259707
260303
|
({ MAX_READ_BATCH_REQUESTS, readBatchAllFailed, renderReadBatchOutput } = createRequire(import.meta.url)("./bin/read-batch-policy.cjs"));
|
|
259708
260304
|
MAX_LINES$1 = 1e3;
|
|
259709
260305
|
MAX_LINE_LENGTH = 2e3;
|
|
259710
|
-
MAX_BYTES = READ_MODEL_VISIBLE_BYTES;
|
|
259711
260306
|
S_IFMT$1 = 61440;
|
|
259712
260307
|
S_IFREG = 32768;
|
|
259713
260308
|
PositiveLineOffsetSchema = number$1().int().min(1);
|
|
259714
|
-
TailLineOffsetSchema = number$1().int().
|
|
260309
|
+
TailLineOffsetSchema = number$1().int().max(-1);
|
|
259715
260310
|
ReadInputSchema = object({
|
|
259716
260311
|
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(
|
|
260312
|
+
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."),
|
|
260313
|
+
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
260314
|
});
|
|
259720
260315
|
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
260316
|
object({
|
|
259722
260317
|
content: string(),
|
|
259723
260318
|
lineCount: number$1().int().nonnegative()
|
|
259724
260319
|
});
|
|
260320
|
+
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
260321
|
READ_DESCRIPTION = renderPrompt(read_default, {
|
|
259726
260322
|
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
260323
|
MAX_LINE_LENGTH
|
|
259735
260324
|
});
|
|
259736
260325
|
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
260326
|
ReadTool = class {
|
|
259738
260327
|
kaos;
|
|
259739
260328
|
workspace;
|
|
260329
|
+
contextWindowState;
|
|
259740
260330
|
name = "Read";
|
|
259741
260331
|
description = READ_DESCRIPTION;
|
|
259742
260332
|
parameters = toInputJsonSchema(ReadInputSchema);
|
|
259743
|
-
constructor(kaos, workspace) {
|
|
260333
|
+
constructor(kaos, workspace, contextWindowState = () => ({})) {
|
|
259744
260334
|
this.kaos = kaos;
|
|
259745
260335
|
this.workspace = workspace;
|
|
260336
|
+
this.contextWindowState = contextWindowState;
|
|
260337
|
+
}
|
|
260338
|
+
modelVisibleBytes() {
|
|
260339
|
+
return readModelVisibleBytes(this.contextWindowState());
|
|
260340
|
+
}
|
|
260341
|
+
modelVisibleLines() {
|
|
260342
|
+
return readModelVisibleLines(this.contextWindowState());
|
|
259746
260343
|
}
|
|
259747
260344
|
resolveExecution(args) {
|
|
259748
260345
|
const path = resolvePathAccessPath(args.path, {
|
|
@@ -259793,10 +260390,12 @@ var init_read = __esmMin((() => {
|
|
|
259793
260390
|
output: notReadableFileOutput(args.path)
|
|
259794
260391
|
};
|
|
259795
260392
|
const lineOffset = args.line_offset ?? 1;
|
|
259796
|
-
const
|
|
259797
|
-
const
|
|
259798
|
-
|
|
259799
|
-
|
|
260393
|
+
const maxLines = this.modelVisibleLines();
|
|
260394
|
+
const requestedLines = args.n_lines ?? maxLines;
|
|
260395
|
+
const effectiveLimit = Math.min(requestedLines, maxLines);
|
|
260396
|
+
const maxBytes = this.modelVisibleBytes();
|
|
260397
|
+
if (lineOffset < 0) return await this.readTail(safePath, args.path, lineOffset, effectiveLimit, requestedLines, maxBytes, maxLines);
|
|
260398
|
+
return await this.readForward(safePath, args.path, lineOffset, effectiveLimit, requestedLines, maxBytes, maxLines);
|
|
259800
260399
|
} catch (error) {
|
|
259801
260400
|
if (isTextDecodeError(error)) return {
|
|
259802
260401
|
isError: true,
|
|
@@ -259808,7 +260407,7 @@ var init_read = __esmMin((() => {
|
|
|
259808
260407
|
};
|
|
259809
260408
|
}
|
|
259810
260409
|
}
|
|
259811
|
-
async readForward(safePath, displayPath, lineOffset, effectiveLimit, requestedLines) {
|
|
260410
|
+
async readForward(safePath, displayPath, lineOffset, effectiveLimit, requestedLines, maxBytes, maxLines) {
|
|
259812
260411
|
const rangeKaos = this.kaos;
|
|
259813
260412
|
if (rangeKaos.scanTextFile !== void 0 && rangeKaos.readLineRange !== void 0) {
|
|
259814
260413
|
const scan = await rangeKaos.scanTextFile(safePath);
|
|
@@ -259817,31 +260416,47 @@ var init_read = __esmMin((() => {
|
|
|
259817
260416
|
output: notReadableFileOutput(displayPath)
|
|
259818
260417
|
};
|
|
259819
260418
|
const selectedEntries = [];
|
|
260419
|
+
const lineEndingStyle = lineEndingStyleFromFlags(scan.lineEndingFlags);
|
|
260420
|
+
let selectedBytes = 0;
|
|
260421
|
+
let maxBytesReached = false;
|
|
259820
260422
|
let lineNo = lineOffset;
|
|
259821
260423
|
for await (const rawLine of rangeKaos.readLineRange(safePath, {
|
|
259822
260424
|
startLine: lineOffset,
|
|
259823
260425
|
maxLines: effectiveLimit,
|
|
259824
260426
|
errors: "strict"
|
|
259825
260427
|
})) {
|
|
259826
|
-
|
|
260428
|
+
const entry = {
|
|
259827
260429
|
lineNo,
|
|
259828
260430
|
rawContent: stripTrailingLf(rawLine)
|
|
259829
|
-
}
|
|
260431
|
+
};
|
|
260432
|
+
const rendered = renderLine(entry, lineEndingStyle);
|
|
260433
|
+
const lineBytes = renderedLineBytes(rendered.line, selectedEntries.length === 0);
|
|
260434
|
+
if (selectedEntries.length > 0 && selectedBytes + lineBytes > maxBytes) {
|
|
260435
|
+
maxBytesReached = true;
|
|
260436
|
+
break;
|
|
260437
|
+
}
|
|
260438
|
+
selectedEntries.push(entry);
|
|
260439
|
+
selectedBytes += lineBytes;
|
|
259830
260440
|
lineNo += 1;
|
|
260441
|
+
if (selectedBytes >= maxBytes) {
|
|
260442
|
+
maxBytesReached = true;
|
|
260443
|
+
break;
|
|
260444
|
+
}
|
|
259831
260445
|
}
|
|
259832
|
-
const
|
|
259833
|
-
const rendered = renderEntries(selectedEntries, lineEndingStyle);
|
|
260446
|
+
const rendered = renderEntries(selectedEntries, lineEndingStyle, maxBytes);
|
|
259834
260447
|
return this.finishReadResult({
|
|
259835
260448
|
renderedLines: rendered.renderedLines,
|
|
259836
260449
|
truncatedLineNumbers: rendered.truncatedLineNumbers,
|
|
259837
|
-
maxLinesReached: effectiveLimit >=
|
|
259838
|
-
maxBytesReached: rendered.maxBytesReached,
|
|
260450
|
+
maxLinesReached: effectiveLimit >= maxLines && lineOffset + maxLines <= scan.totalLines,
|
|
260451
|
+
maxBytesReached: maxBytesReached || rendered.maxBytesReached,
|
|
259839
260452
|
lineEndingStyle,
|
|
259840
260453
|
startLine: selectedEntries.length > 0 ? lineOffset : 0,
|
|
259841
260454
|
totalLines: scan.totalLines,
|
|
259842
260455
|
requestedLines,
|
|
259843
260456
|
lineOffset,
|
|
259844
|
-
effectiveLimit
|
|
260457
|
+
effectiveLimit,
|
|
260458
|
+
maxBytes,
|
|
260459
|
+
maxLines
|
|
259845
260460
|
});
|
|
259846
260461
|
}
|
|
259847
260462
|
const selectedEntries = [];
|
|
@@ -259852,7 +260467,10 @@ var init_read = __esmMin((() => {
|
|
|
259852
260467
|
};
|
|
259853
260468
|
let currentLineNo = 0;
|
|
259854
260469
|
let maxLinesReached = false;
|
|
260470
|
+
let maxBytesReached = false;
|
|
260471
|
+
let selectedBytes = 0;
|
|
259855
260472
|
let collectionClosed = false;
|
|
260473
|
+
let closedByLines = false;
|
|
259856
260474
|
for await (const rawLine of this.kaos.readLines(safePath, { errors: "strict" })) {
|
|
259857
260475
|
if (containsNulByte(rawLine)) return {
|
|
259858
260476
|
isError: true,
|
|
@@ -259861,38 +260479,56 @@ var init_read = __esmMin((() => {
|
|
|
259861
260479
|
currentLineNo += 1;
|
|
259862
260480
|
updateLineEndingFlags(flags, rawLine);
|
|
259863
260481
|
if (collectionClosed) {
|
|
259864
|
-
if (effectiveLimit >=
|
|
260482
|
+
if (closedByLines && effectiveLimit >= maxLines && currentLineNo >= lineOffset) maxLinesReached = true;
|
|
259865
260483
|
continue;
|
|
259866
260484
|
}
|
|
259867
260485
|
if (currentLineNo < lineOffset) continue;
|
|
259868
260486
|
if (selectedEntries.length >= effectiveLimit) {
|
|
259869
|
-
if (effectiveLimit >=
|
|
260487
|
+
if (effectiveLimit >= maxLines) maxLinesReached = true;
|
|
259870
260488
|
collectionClosed = true;
|
|
260489
|
+
closedByLines = true;
|
|
259871
260490
|
continue;
|
|
259872
260491
|
}
|
|
259873
|
-
|
|
260492
|
+
const entry = {
|
|
259874
260493
|
lineNo: currentLineNo,
|
|
259875
260494
|
rawContent: stripTrailingLf(rawLine)
|
|
259876
|
-
}
|
|
259877
|
-
|
|
260495
|
+
};
|
|
260496
|
+
const conservative = renderLine(entry, "mixed");
|
|
260497
|
+
const lineBytes = renderedLineBytes(conservative.line, selectedEntries.length === 0);
|
|
260498
|
+
if (selectedEntries.length > 0 && selectedBytes + lineBytes > maxBytes) {
|
|
260499
|
+
maxBytesReached = true;
|
|
260500
|
+
collectionClosed = true;
|
|
260501
|
+
continue;
|
|
260502
|
+
}
|
|
260503
|
+
selectedEntries.push(entry);
|
|
260504
|
+
selectedBytes += lineBytes;
|
|
260505
|
+
if (selectedEntries.length >= effectiveLimit) {
|
|
260506
|
+
collectionClosed = true;
|
|
260507
|
+
closedByLines = true;
|
|
260508
|
+
} else if (selectedBytes >= maxBytes) {
|
|
260509
|
+
maxBytesReached = true;
|
|
260510
|
+
collectionClosed = true;
|
|
260511
|
+
}
|
|
259878
260512
|
}
|
|
259879
260513
|
const lineEndingStyle = lineEndingStyleFromFlags(flags);
|
|
259880
|
-
const rendered = renderEntries(selectedEntries, lineEndingStyle);
|
|
260514
|
+
const rendered = renderEntries(selectedEntries, lineEndingStyle, maxBytes);
|
|
259881
260515
|
return this.finishReadResult({
|
|
259882
260516
|
renderedLines: rendered.renderedLines,
|
|
259883
260517
|
truncatedLineNumbers: rendered.truncatedLineNumbers,
|
|
259884
260518
|
maxLinesReached,
|
|
259885
|
-
maxBytesReached: rendered.maxBytesReached,
|
|
260519
|
+
maxBytesReached: maxBytesReached || rendered.maxBytesReached,
|
|
259886
260520
|
lineEndingStyle,
|
|
259887
260521
|
startLine: selectedEntries.length > 0 ? lineOffset : 0,
|
|
259888
260522
|
totalLines: currentLineNo,
|
|
259889
260523
|
requestedLines,
|
|
259890
260524
|
lineOffset,
|
|
259891
|
-
effectiveLimit
|
|
260525
|
+
effectiveLimit,
|
|
260526
|
+
maxBytes,
|
|
260527
|
+
maxLines
|
|
259892
260528
|
});
|
|
259893
260529
|
}
|
|
259894
|
-
async readTail(safePath, displayPath, lineOffset, effectiveLimit, requestedLines) {
|
|
259895
|
-
const tailCount = Math.abs(lineOffset);
|
|
260530
|
+
async readTail(safePath, displayPath, lineOffset, effectiveLimit, requestedLines, maxBytes, maxLines) {
|
|
260531
|
+
const tailCount = Math.min(Math.abs(lineOffset), maxLines);
|
|
259896
260532
|
const rangeKaos = this.kaos;
|
|
259897
260533
|
if (rangeKaos.scanTextFile !== void 0 && rangeKaos.readTailLines !== void 0) {
|
|
259898
260534
|
const scan = await rangeKaos.scanTextFile(safePath);
|
|
@@ -259915,7 +260551,9 @@ var init_read = __esmMin((() => {
|
|
|
259915
260551
|
lineEndingFlags: scan.lineEndingFlags,
|
|
259916
260552
|
effectiveLimit,
|
|
259917
260553
|
totalLines: scan.totalLines,
|
|
259918
|
-
requestedLines
|
|
260554
|
+
requestedLines,
|
|
260555
|
+
maxBytes,
|
|
260556
|
+
maxLines
|
|
259919
260557
|
});
|
|
259920
260558
|
}
|
|
259921
260559
|
const entries = [];
|
|
@@ -259943,7 +260581,9 @@ var init_read = __esmMin((() => {
|
|
|
259943
260581
|
lineEndingFlags: flags,
|
|
259944
260582
|
effectiveLimit,
|
|
259945
260583
|
totalLines: currentLineNo,
|
|
259946
|
-
requestedLines
|
|
260584
|
+
requestedLines,
|
|
260585
|
+
maxBytes,
|
|
260586
|
+
maxLines
|
|
259947
260587
|
});
|
|
259948
260588
|
}
|
|
259949
260589
|
finishTailEntries(input) {
|
|
@@ -259957,7 +260597,7 @@ var init_read = __esmMin((() => {
|
|
|
259957
260597
|
let totalBytes = 0;
|
|
259958
260598
|
for (const [index, candidate] of renderedCandidates.entries()) totalBytes += renderedLineBytes(candidate.rendered.line, index === 0);
|
|
259959
260599
|
let maxBytesReached = false;
|
|
259960
|
-
if (totalBytes >
|
|
260600
|
+
if (totalBytes > input.maxBytes) {
|
|
259961
260601
|
maxBytesReached = true;
|
|
259962
260602
|
const kept = [];
|
|
259963
260603
|
let bytes = 0;
|
|
@@ -259965,7 +260605,7 @@ var init_read = __esmMin((() => {
|
|
|
259965
260605
|
const candidate = renderedCandidates[i];
|
|
259966
260606
|
if (candidate === void 0) continue;
|
|
259967
260607
|
const lineBytes = renderedLineBytes(candidate.rendered.line, kept.length === 0);
|
|
259968
|
-
if (bytes + lineBytes >
|
|
260608
|
+
if (bytes + lineBytes > input.maxBytes) break;
|
|
259969
260609
|
kept.unshift(candidate);
|
|
259970
260610
|
bytes += lineBytes;
|
|
259971
260611
|
}
|
|
@@ -259985,7 +260625,9 @@ var init_read = __esmMin((() => {
|
|
|
259985
260625
|
lineEndingStyle,
|
|
259986
260626
|
startLine: renderedCandidates[0]?.entry.lineNo ?? 0,
|
|
259987
260627
|
totalLines: input.totalLines,
|
|
259988
|
-
requestedLines: input.requestedLines
|
|
260628
|
+
requestedLines: input.requestedLines,
|
|
260629
|
+
maxBytes: input.maxBytes,
|
|
260630
|
+
maxLines: input.maxLines
|
|
259989
260631
|
});
|
|
259990
260632
|
}
|
|
259991
260633
|
finishReadResult(input) {
|
|
@@ -260000,8 +260642,8 @@ var init_read = __esmMin((() => {
|
|
|
260000
260642
|
const lineCount = input.renderedLines.length;
|
|
260001
260643
|
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
260644
|
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(
|
|
260645
|
+
if (input.maxLinesReached) parts.push(`Max ${String(input.maxLines)} lines reached.`);
|
|
260646
|
+
else if (input.maxBytesReached) parts.push(`Max ${String(input.maxBytes)} bytes reached.`);
|
|
260005
260647
|
else if (lineCount < input.requestedLines) parts.push("End of file reached.");
|
|
260006
260648
|
const continuationNotice = readContinuationNotice({
|
|
260007
260649
|
...input,
|
|
@@ -260020,10 +260662,10 @@ var init_read = __esmMin((() => {
|
|
|
260020
260662
|
name = "ReadBatch";
|
|
260021
260663
|
description = READ_BATCH_DESCRIPTION;
|
|
260022
260664
|
parameters = toInputJsonSchema(ReadBatchInputSchema);
|
|
260023
|
-
constructor(kaos, workspace) {
|
|
260665
|
+
constructor(kaos, workspace, contextWindowState) {
|
|
260024
260666
|
this.kaos = kaos;
|
|
260025
260667
|
this.workspace = workspace;
|
|
260026
|
-
this.reader = new ReadTool(kaos, workspace);
|
|
260668
|
+
this.reader = new ReadTool(kaos, workspace, contextWindowState);
|
|
260027
260669
|
}
|
|
260028
260670
|
resolveExecution(args) {
|
|
260029
260671
|
const items = args.requests.map((request) => ({
|
|
@@ -261418,7 +262060,7 @@ function renderHistoricalToolResultReference(toolName, toolCallId, text, outputP
|
|
|
261418
262060
|
function safeToolResultFileStem(toolName, toolCallId) {
|
|
261419
262061
|
return `${toolName}-${toolCallId}`.replace(/[^a-zA-Z0-9._-]+/g, "_").replace(/^_+|_+$/g, "").slice(0, 80) || "tool-result";
|
|
261420
262062
|
}
|
|
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;
|
|
262063
|
+
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
262064
|
var init_tool_result_budget = __esmMin((() => {
|
|
261423
262065
|
init_dist$6();
|
|
261424
262066
|
const toolResultOffloadPolicy = createRequire(import.meta.url)("./bin/tool-result-offload-policy.cjs");
|
|
@@ -261438,6 +262080,7 @@ var init_tool_result_budget = __esmMin((() => {
|
|
|
261438
262080
|
currentUserTurnStartIndex = toolResultOffloadPolicy.currentUserTurnStartIndex;
|
|
261439
262081
|
dedupeRepeatedSuccessfulToolResults = toolResultOffloadPolicy.dedupeRepeatedSuccessfulToolResults;
|
|
261440
262082
|
freshToolResultIds = toolResultOffloadPolicy.freshToolResultIds;
|
|
262083
|
+
hasToolResultOffloadPressure = toolResultOffloadPolicy.hasToolResultOffloadPressure;
|
|
261441
262084
|
readContinuationLineOffset = toolResultOffloadPolicy.readContinuationLineOffset;
|
|
261442
262085
|
selectToolResultBatchOffloads = toolResultOffloadPolicy.selectToolResultBatchOffloads;
|
|
261443
262086
|
selectHistoricalToolResultOffloads = toolResultOffloadPolicy.selectHistoricalToolResultOffloads;
|
|
@@ -261452,6 +262095,7 @@ var ToolResultBatchOffload = class {
|
|
|
261452
262095
|
}
|
|
261453
262096
|
async detect() {
|
|
261454
262097
|
const history = this.agent.context.history;
|
|
262098
|
+
if (!toolResultOffloadPressureForAgent(this.agent)) return 0;
|
|
261455
262099
|
const tailIds = freshToolResultIds(history);
|
|
261456
262100
|
const pinnedReadIds = currentTurnReadToolResultIds(history);
|
|
261457
262101
|
const recentStart = Math.max(0, history.length - TOOL_RESULT_HISTORICAL_KEEP_RECENT_MESSAGES);
|
|
@@ -261534,6 +262178,7 @@ var ToolResultBatchOffload = class {
|
|
|
261534
262178
|
});
|
|
261535
262179
|
}
|
|
261536
262180
|
compact(messages) {
|
|
262181
|
+
if (!toolResultOffloadPressureForAgent(this.agent)) return messages;
|
|
261537
262182
|
const recentStart = Math.max(0, messages.length - TOOL_RESULT_HISTORICAL_KEEP_RECENT_MESSAGES);
|
|
261538
262183
|
let changed = false;
|
|
261539
262184
|
const projected = messages.map((message, index) => {
|
|
@@ -261584,6 +262229,13 @@ var ToolResultBatchOffload = class {
|
|
|
261584
262229
|
}
|
|
261585
262230
|
}
|
|
261586
262231
|
};
|
|
262232
|
+
function toolResultOffloadPressureForAgent(agent) {
|
|
262233
|
+
return hasToolResultOffloadPressure({ contextUsageRatio: contextUsageRatioForAgent(agent) });
|
|
262234
|
+
}
|
|
262235
|
+
function contextUsageRatioForAgent(agent) {
|
|
262236
|
+
const maxContextTokens = agent.fullCompaction.getEffectiveMaxContextTokens();
|
|
262237
|
+
return maxContextTokens > 0 ? agent.context.tokenCountWithPending / maxContextTokens : 1;
|
|
262238
|
+
}
|
|
261587
262239
|
//#endregion
|
|
261588
262240
|
//#region ../../packages/agent-core/src/agent/turn/user-message-offload.ts
|
|
261589
262241
|
function persistableUserMessageText(message) {
|
|
@@ -261652,6 +262304,7 @@ var UserMessageOffload = class {
|
|
|
261652
262304
|
if (this.agent.homedir === void 0) return 0;
|
|
261653
262305
|
const currentTurnStart = currentUserTurnStartIndex(history);
|
|
261654
262306
|
const totalHistoryChars = historyTextChars(history);
|
|
262307
|
+
const contextUsageRatio = contextUsageRatioForAgent(this.agent);
|
|
261655
262308
|
let offloaded = 0;
|
|
261656
262309
|
for (let historyIndex = 0; historyIndex < history.length; historyIndex++) {
|
|
261657
262310
|
if (historyIndex === currentTurnStart) continue;
|
|
@@ -261663,7 +262316,8 @@ var UserMessageOffload = class {
|
|
|
261663
262316
|
historyIndex,
|
|
261664
262317
|
historyLength: history.length,
|
|
261665
262318
|
historyChars: totalHistoryChars,
|
|
261666
|
-
textChars: text.length
|
|
262319
|
+
textChars: text.length,
|
|
262320
|
+
contextUsageRatio
|
|
261667
262321
|
});
|
|
261668
262322
|
if (!immediateOversize && !historicalOversize) continue;
|
|
261669
262323
|
const messageHash = userMessageOffloadHash(message, text);
|
|
@@ -261675,6 +262329,14 @@ var UserMessageOffload = class {
|
|
|
261675
262329
|
type: "text",
|
|
261676
262330
|
text: replacementText
|
|
261677
262331
|
}, ...message.content.filter((part) => part.type !== "text")];
|
|
262332
|
+
this.agent.records.logRecord({
|
|
262333
|
+
type: "policy.intervention",
|
|
262334
|
+
policy: "user_message_offload",
|
|
262335
|
+
location: "UserMessageOffload.detect",
|
|
262336
|
+
size_before: text.length,
|
|
262337
|
+
size_after: replacementText.length,
|
|
262338
|
+
unit: "chars"
|
|
262339
|
+
});
|
|
261678
262340
|
this.apply({
|
|
261679
262341
|
messageHash,
|
|
261680
262342
|
content,
|
|
@@ -261699,7 +262361,7 @@ var UserMessageOffload = class {
|
|
|
261699
262361
|
});
|
|
261700
262362
|
}
|
|
261701
262363
|
compact(messages) {
|
|
261702
|
-
if (this.replacements.size === 0) return messages;
|
|
262364
|
+
if (this.replacements.size === 0 || !toolResultOffloadPressureForAgent(this.agent)) return messages;
|
|
261703
262365
|
return messages.map((message) => {
|
|
261704
262366
|
const text = persistableUserMessageText(message);
|
|
261705
262367
|
if (text === void 0) return message;
|
|
@@ -261786,6 +262448,7 @@ var AssistantMessageOffload = class {
|
|
|
261786
262448
|
const history = this.agent.context.history;
|
|
261787
262449
|
if (this.agent.homedir === void 0) return 0;
|
|
261788
262450
|
const totalHistoryChars = historyTextChars(history);
|
|
262451
|
+
const contextUsageRatio = contextUsageRatioForAgent(this.agent);
|
|
261789
262452
|
let offloaded = 0;
|
|
261790
262453
|
for (let historyIndex = 0; historyIndex < history.length; historyIndex++) {
|
|
261791
262454
|
const message = history[historyIndex];
|
|
@@ -261794,7 +262457,8 @@ var AssistantMessageOffload = class {
|
|
|
261794
262457
|
historyIndex,
|
|
261795
262458
|
historyLength: history.length,
|
|
261796
262459
|
historyChars: totalHistoryChars,
|
|
261797
|
-
textChars: text.length
|
|
262460
|
+
textChars: text.length,
|
|
262461
|
+
contextUsageRatio
|
|
261798
262462
|
})) continue;
|
|
261799
262463
|
const messageHash = assistantMessageOffloadHash(message, text);
|
|
261800
262464
|
if (this.replacements.has(messageHash)) continue;
|
|
@@ -261805,6 +262469,14 @@ var AssistantMessageOffload = class {
|
|
|
261805
262469
|
type: "text",
|
|
261806
262470
|
text: replacementText
|
|
261807
262471
|
}, ...message.content.filter((part) => part.type !== "text")];
|
|
262472
|
+
this.agent.records.logRecord({
|
|
262473
|
+
type: "policy.intervention",
|
|
262474
|
+
policy: "assistant_message_offload",
|
|
262475
|
+
location: "AssistantMessageOffload.detect",
|
|
262476
|
+
size_before: text.length,
|
|
262477
|
+
size_after: replacementText.length,
|
|
262478
|
+
unit: "chars"
|
|
262479
|
+
});
|
|
261808
262480
|
this.apply({
|
|
261809
262481
|
messageHash,
|
|
261810
262482
|
content,
|
|
@@ -261829,6 +262501,7 @@ var AssistantMessageOffload = class {
|
|
|
261829
262501
|
});
|
|
261830
262502
|
}
|
|
261831
262503
|
compact(messages) {
|
|
262504
|
+
const underPressure = toolResultOffloadPressureForAgent(this.agent);
|
|
261832
262505
|
const completedToolCallIds = new Set(messages.filter((message) => message?.role === "tool" && message.toolCallId !== void 0).map((message) => message.toolCallId));
|
|
261833
262506
|
const totalHistoryChars = historyTextChars(messages);
|
|
261834
262507
|
let changed = false;
|
|
@@ -261858,7 +262531,7 @@ var AssistantMessageOffload = class {
|
|
|
261858
262531
|
}
|
|
261859
262532
|
const text = persistableAssistantMessageText(message);
|
|
261860
262533
|
if (text === void 0) return message;
|
|
261861
|
-
const replacement = this.replacements.get(assistantMessageOffloadHash(message, text));
|
|
262534
|
+
const replacement = underPressure ? this.replacements.get(assistantMessageOffloadHash(message, text)) : void 0;
|
|
261862
262535
|
if (replacement === void 0) return message;
|
|
261863
262536
|
changed = true;
|
|
261864
262537
|
return { ...message, content: replacement.content };
|
|
@@ -261885,6 +262558,17 @@ function blunExtractText(content) {
|
|
|
261885
262558
|
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
262559
|
return "";
|
|
261887
262560
|
}
|
|
262561
|
+
function blunRepeatActiveTurnPrompt(history, input, stepNumber) {
|
|
262562
|
+
if (stepNumber <= 1) return history;
|
|
262563
|
+
const prompt = blunExtractText(input);
|
|
262564
|
+
if (prompt.length === 0) return history;
|
|
262565
|
+
return [...history, {
|
|
262566
|
+
role: "user",
|
|
262567
|
+
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>` }],
|
|
262568
|
+
toolCalls: [],
|
|
262569
|
+
origin: { kind: "injection", variant: "active_turn_prompt" }
|
|
262570
|
+
}];
|
|
262571
|
+
}
|
|
261888
262572
|
/**
|
|
261889
262573
|
* BLUN: decide whether a turn should carry the full tool set. Small-context models
|
|
261890
262574
|
* (e.g. King on an 8k window) lose their identity/language when all tool schemas
|
|
@@ -262263,6 +262947,15 @@ var init_turn = __esmMin((() => {
|
|
|
262263
262947
|
kind: "system_trigger",
|
|
262264
262948
|
name: "goal_continuation"
|
|
262265
262949
|
};
|
|
262950
|
+
function goalContinuationOrigin(origin) {
|
|
262951
|
+
const cronRunId = origin?.kind === "cron_job" ? origin.runId : origin?.cronRunId;
|
|
262952
|
+
if (cronRunId === void 0 && origin?.toolScope === void 0) return GOAL_CONTINUATION_ORIGIN;
|
|
262953
|
+
return {
|
|
262954
|
+
...GOAL_CONTINUATION_ORIGIN,
|
|
262955
|
+
...(cronRunId === void 0 ? {} : { cronRunId }),
|
|
262956
|
+
...(origin?.toolScope === void 0 ? {} : { toolScope: origin.toolScope })
|
|
262957
|
+
};
|
|
262958
|
+
}
|
|
262266
262959
|
GOAL_COMPLETION_REMINDER_NAME = "goal_completion";
|
|
262267
262960
|
GOAL_BLOCKED_REMINDER_NAME = "goal_blocked";
|
|
262268
262961
|
GOAL_RATE_LIMIT_PAUSE_REASON = "Paused after provider rate limit";
|
|
@@ -262310,6 +263003,7 @@ var init_turn = __esmMin((() => {
|
|
|
262310
263003
|
stepToolCallKeys = /* @__PURE__ */ new Map();
|
|
262311
263004
|
telemetryModeByTurn = /* @__PURE__ */ new Map();
|
|
262312
263005
|
currentStepByTurn = /* @__PURE__ */ new Map();
|
|
263006
|
+
toolScopeByTurn = /* @__PURE__ */ new Map();
|
|
262313
263007
|
interruptedTelemetryTurnIds = /* @__PURE__ */ new Set();
|
|
262314
263008
|
stepFailureByTurn = /* @__PURE__ */ new Map();
|
|
262315
263009
|
currentStep = 0;
|
|
@@ -262576,10 +263270,11 @@ var init_turn = __esmMin((() => {
|
|
|
262576
263270
|
duplicate: false
|
|
262577
263271
|
};
|
|
262578
263272
|
}
|
|
262579
|
-
retry(trigger) {
|
|
263273
|
+
retry(trigger, toolScope) {
|
|
262580
263274
|
return this.prompt([], {
|
|
262581
263275
|
kind: "retry",
|
|
262582
|
-
trigger
|
|
263276
|
+
trigger,
|
|
263277
|
+
...(toolScope === void 0 ? {} : { toolScope })
|
|
262583
263278
|
});
|
|
262584
263279
|
}
|
|
262585
263280
|
launch(input, origin) {
|
|
@@ -262657,6 +263352,9 @@ var init_turn = __esmMin((() => {
|
|
|
262657
263352
|
get hasActiveTurn() {
|
|
262658
263353
|
return this.activeTurn !== null && this.activeTurn !== "resuming";
|
|
262659
263354
|
}
|
|
263355
|
+
toolScopeForTurn(turnId) {
|
|
263356
|
+
return this.toolScopeByTurn.get(turnId);
|
|
263357
|
+
}
|
|
262660
263358
|
ensureActiveTurn() {
|
|
262661
263359
|
if (this.activeTurn === null || this.activeTurn === "resuming") throw new Error("No active turn");
|
|
262662
263360
|
return this.activeTurn;
|
|
@@ -262768,15 +263466,23 @@ var init_turn = __esmMin((() => {
|
|
|
262768
263466
|
*/
|
|
262769
263467
|
async turnWorker(firstTurnId, input, origin, signal) {
|
|
262770
263468
|
const ownsActiveTurn = () => this.activeTurn !== null && this.activeTurn !== "resuming" && this.activeTurn.controller.signal === signal;
|
|
263469
|
+
let result;
|
|
262771
263470
|
try {
|
|
262772
|
-
if (this.agent.goal.getGoal().goal?.status === "active")
|
|
262773
|
-
|
|
262774
|
-
|
|
262775
|
-
|
|
262776
|
-
|
|
262777
|
-
|
|
262778
|
-
|
|
263471
|
+
if (this.agent.goal.getGoal().goal?.status === "active") result = await this.driveGoal(firstTurnId, input, origin, signal);
|
|
263472
|
+
else {
|
|
263473
|
+
const end = await this.runOneTurn(firstTurnId, input, origin, signal, true);
|
|
263474
|
+
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(), [{
|
|
263475
|
+
type: "text",
|
|
263476
|
+
text: GOAL_CONTINUATION_PROMPT
|
|
263477
|
+
}], goalContinuationOrigin(origin), signal);
|
|
263478
|
+
else result = end;
|
|
263479
|
+
}
|
|
263480
|
+
return result;
|
|
263481
|
+
} catch (error) {
|
|
263482
|
+
if (origin.kind === "cron_job" && typeof origin.runId === "string") this.agent.cron?.observeRunWorkerFailed(origin.runId);
|
|
263483
|
+
throw error;
|
|
262779
263484
|
} finally {
|
|
263485
|
+
if (result !== void 0 && origin.kind === "cron_job" && typeof origin.runId === "string") this.agent.cron?.observeRunWorkerEnded(origin.runId, result.event);
|
|
262780
263486
|
if (ownsActiveTurn()) this.activeTurn = null;
|
|
262781
263487
|
}
|
|
262782
263488
|
}
|
|
@@ -262830,7 +263536,7 @@ var init_turn = __esmMin((() => {
|
|
|
262830
263536
|
type: "text",
|
|
262831
263537
|
text: GOAL_CONTINUATION_PROMPT
|
|
262832
263538
|
}];
|
|
262833
|
-
turnOrigin =
|
|
263539
|
+
turnOrigin = goalContinuationOrigin(origin);
|
|
262834
263540
|
}
|
|
262835
263541
|
}
|
|
262836
263542
|
async endGoalTurnWithoutModel(turnId, input, origin) {
|
|
@@ -262878,6 +263584,7 @@ var init_turn = __esmMin((() => {
|
|
|
262878
263584
|
this.currentStepByTurn.set(turnId, 0);
|
|
262879
263585
|
this.recordExternalReportSources(turnId, origin);
|
|
262880
263586
|
const persistedOrigin = durablePromptOrigin(origin);
|
|
263587
|
+
if (persistedOrigin.toolScope !== void 0) this.toolScopeByTurn.set(turnId, persistedOrigin.toolScope);
|
|
262881
263588
|
this.agent.telemetry.track("turn_started", {
|
|
262882
263589
|
mode: telemetryMode,
|
|
262883
263590
|
...this.requestProviderProps()
|
|
@@ -262985,6 +263692,7 @@ var init_turn = __esmMin((() => {
|
|
|
262985
263692
|
if (ended.reason !== "completed") this.trackTurnInterrupted(turnId, this.currentStepByTurn.get(turnId) ?? this.currentStep);
|
|
262986
263693
|
this.telemetryModeByTurn.delete(turnId);
|
|
262987
263694
|
this.currentStepByTurn.delete(turnId);
|
|
263695
|
+
this.toolScopeByTurn.delete(turnId);
|
|
262988
263696
|
this.interruptedTelemetryTurnIds.delete(turnId);
|
|
262989
263697
|
this.cognitiveActionEvidenceByTurn.delete(turnId);
|
|
262990
263698
|
this.cognitiveExternalReportsByTurn.delete(turnId);
|
|
@@ -263082,13 +263790,14 @@ var init_turn = __esmMin((() => {
|
|
|
263082
263790
|
let previousStepToolOutcome = "initial";
|
|
263083
263791
|
let currentStepHadTool = false;
|
|
263084
263792
|
let currentStepHadFailure = false;
|
|
263793
|
+
let currentLoopStep = 0;
|
|
263085
263794
|
while (true) {
|
|
263086
263795
|
signal.throwIfAborted();
|
|
263087
263796
|
const model = this.agent.config.model;
|
|
263088
263797
|
const loopControl = this.agent.blunConfig?.loopControl;
|
|
263089
263798
|
let stopForGoalBudget = false;
|
|
263090
263799
|
try {
|
|
263091
|
-
const originTools = blunToolsForOrigin(this.agent.injection.filterPersonalMemoryToolsForTurn(turnId, input, origin, this.agent.tools.loopTools), origin);
|
|
263800
|
+
const originTools = filterToolsForCronScope(blunToolsForOrigin(this.agent.injection.filterPersonalMemoryToolsForTurn(turnId, input, origin, this.agent.tools.loopTools), origin), origin.toolScope);
|
|
263092
263801
|
const compactConversationTool = originTools.find((tool) => tool.name === "CompactConversation");
|
|
263093
263802
|
const eligibleTools = originTools.filter((tool) => tool.name !== "CompactConversation" || this.agent.fullCompaction.isProactiveCompactionEligible());
|
|
263094
263803
|
const turnRequiredToolNames = new Set(requiredToolNames);
|
|
@@ -263114,12 +263823,13 @@ var init_turn = __esmMin((() => {
|
|
|
263114
263823
|
eligibleToolSchemaTokens: estimateTokensForTools(eligibleTools),
|
|
263115
263824
|
selectedToolSchemaTokens: estimateTokensForTools(selectedTools)
|
|
263116
263825
|
});
|
|
263826
|
+
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
263827
|
return (await runTurn({
|
|
263118
263828
|
turnId: String(turnId),
|
|
263119
263829
|
signal,
|
|
263120
263830
|
llm: turnLLM,
|
|
263121
|
-
buildMessages: () => this.agent.context.project(
|
|
263122
|
-
buildMessagesStrict: () => this.agent.context.project(
|
|
263831
|
+
buildMessages: () => this.agent.context.project(blunRepeatActiveTurnPrompt(turnHistory(), input, currentLoopStep), { dropOrphanResults: true }),
|
|
263832
|
+
buildMessagesStrict: () => this.agent.context.project(blunRepeatActiveTurnPrompt(turnHistory(), input, currentLoopStep), {
|
|
263123
263833
|
synthesizeMissing: true,
|
|
263124
263834
|
dropOrphanResults: true,
|
|
263125
263835
|
dedupeDuplicateToolCalls: true,
|
|
@@ -263140,6 +263850,7 @@ var init_turn = __esmMin((() => {
|
|
|
263140
263850
|
},
|
|
263141
263851
|
hooks: {
|
|
263142
263852
|
beforeStep: async ({ signal: stepSignal, stepNumber }) => {
|
|
263853
|
+
currentLoopStep = stepNumber;
|
|
263143
263854
|
await this.agent.records.flush();
|
|
263144
263855
|
await this.agent.toolResultBatchOffload.detect();
|
|
263145
263856
|
this.agent.microCompaction.detect();
|
|
@@ -263377,6 +264088,7 @@ var init_turn = __esmMin((() => {
|
|
|
263377
264088
|
buildDispatchEvent(turnId) {
|
|
263378
264089
|
return createLoopEventDispatcher({
|
|
263379
264090
|
appendTranscriptRecord: async (event) => {
|
|
264091
|
+
this.agent.cron?.observeLoopEvent(turnId, event);
|
|
263380
264092
|
this.agent.context.appendLoopEvent(event);
|
|
263381
264093
|
},
|
|
263382
264094
|
emitLiveEvent: (event) => {
|
|
@@ -264434,7 +265146,7 @@ var init_codebase_search = __esmMin((() => {
|
|
|
264434
265146
|
description: `Semantic search: ${args.query.length > 50 ? `${args.query.slice(0, 50)}…` : args.query}`,
|
|
264435
265147
|
display: {
|
|
264436
265148
|
kind: "command",
|
|
264437
|
-
command: `python codebase_index.py query . "${args.query}" --top ${String(args.top)}`,
|
|
265149
|
+
command: `python codebase_index.py query . "${args.query}" --top ${String(args.top)} --model auto`,
|
|
264438
265150
|
cwd: this.cwd,
|
|
264439
265151
|
description: `Codebase semantic search`,
|
|
264440
265152
|
language: "bash"
|
|
@@ -264454,7 +265166,9 @@ var init_codebase_search = __esmMin((() => {
|
|
|
264454
265166
|
this.cwd,
|
|
264455
265167
|
args.query,
|
|
264456
265168
|
"--top",
|
|
264457
|
-
String(args.top)
|
|
265169
|
+
String(args.top),
|
|
265170
|
+
"--model",
|
|
265171
|
+
"auto"
|
|
264458
265172
|
], {
|
|
264459
265173
|
cwd: this.cwd,
|
|
264460
265174
|
timeout: SCRIPT_TIMEOUT_MS,
|
|
@@ -265087,10 +265801,12 @@ var init_builtin = __esmMin((() => {
|
|
|
265087
265801
|
init_task_list();
|
|
265088
265802
|
init_task_output();
|
|
265089
265803
|
init_task_update();
|
|
265804
|
+
init_task_resume();
|
|
265090
265805
|
init_task_stop();
|
|
265091
265806
|
init_cron_create();
|
|
265092
265807
|
init_cron_delete();
|
|
265093
265808
|
init_cron_list();
|
|
265809
|
+
init_cron_runs();
|
|
265094
265810
|
init_agent$1();
|
|
265095
265811
|
init_agent_swarm();
|
|
265096
265812
|
init_ask_user();
|
|
@@ -265320,9 +266036,10 @@ var init_tool$1 = __esmMin((() => {
|
|
|
265320
266036
|
hasUserTool(name) {
|
|
265321
266037
|
return this.userTools.has(name);
|
|
265322
266038
|
}
|
|
265323
|
-
inheritUserTools(parent) {
|
|
266039
|
+
inheritUserTools(parent, excludedNames = /* @__PURE__ */ new Set()) {
|
|
265324
266040
|
for (const tool of parent.userTools.values()) {
|
|
265325
266041
|
if (!parent.enabledTools.has(tool.name)) continue;
|
|
266042
|
+
if (excludedNames.has(tool.name)) continue;
|
|
265326
266043
|
this.registerUserTool({
|
|
265327
266044
|
name: tool.name,
|
|
265328
266045
|
description: tool.description,
|
|
@@ -265537,9 +266254,13 @@ var init_tool$1 = __esmMin((() => {
|
|
|
265537
266254
|
}, this.agent.skills?.registry.getSkillRoots() ?? []);
|
|
265538
266255
|
const allowBackground = this.enabledTools.has("TaskList") && this.enabledTools.has("TaskOutput") && this.enabledTools.has("TaskStop");
|
|
265539
266256
|
const goalToolsEnabled = this.agent.type === "main";
|
|
266257
|
+
const readBudget = () => ({
|
|
266258
|
+
contextTokens: this.agent.context.tokenCountWithPending,
|
|
266259
|
+
maxContextTokens: this.agent.fullCompaction.getEffectiveMaxContextTokens()
|
|
266260
|
+
});
|
|
265540
266261
|
this.builtinTools = new Map([
|
|
265541
|
-
new ReadTool(kaos, workspace),
|
|
265542
|
-
new ReadBatchTool(kaos, workspace),
|
|
266262
|
+
new ReadTool(kaos, workspace, readBudget),
|
|
266263
|
+
new ReadBatchTool(kaos, workspace, readBudget),
|
|
265543
266264
|
new WriteTool(kaos, workspace, () => this.agent.context.history, toolServices?.lsp),
|
|
265544
266265
|
new EditTool(kaos, workspace, () => this.agent.context.history, toolServices?.lsp),
|
|
265545
266266
|
new GrepTool(kaos, workspace, this.agent.telemetry),
|
|
@@ -265559,9 +266280,12 @@ var init_tool$1 = __esmMin((() => {
|
|
|
265559
266280
|
new TaskListTool(background),
|
|
265560
266281
|
new TaskOutputTool(background),
|
|
265561
266282
|
new TaskUpdateTool(background),
|
|
266283
|
+
this.agent.subagentHost && allowBackground && background.resumeStore && new TaskResumeTool(background, this.agent.subagentHost),
|
|
265562
266284
|
new TaskStopTool(background),
|
|
265563
266285
|
this.agent.cron && new CronCreateTool(this.agent.cron),
|
|
265564
266286
|
this.agent.cron && new CronListTool(this.agent.cron),
|
|
266287
|
+
this.agent.cron && new CronRunListTool(this.agent.cron),
|
|
266288
|
+
this.agent.cron && new CronRunOutputTool(this.agent.cron),
|
|
265565
266289
|
this.agent.cron && new CronDeleteTool(this.agent.cron),
|
|
265566
266290
|
this.agent.skills?.registry.listInvocableSkills().length && new SkillTool(this.agent),
|
|
265567
266291
|
this.agent.subagentHost && new AgentTool(this.agent.subagentHost, background, DEFAULT_AGENT_PROFILES["agent"]?.subagents, {
|
|
@@ -266008,7 +266732,7 @@ var init_agent = __esmMin((() => {
|
|
|
266008
266732
|
({ createEffectiveSystemPromptResolver } = createRequire(import.meta.url)("./bin/effective-system-prompt-cache-policy.cjs"));
|
|
266009
266733
|
({ resolveProviderIdleTimeoutMs } = createRequire(import.meta.url)("./bin/provider-idle-timeout-policy.cjs"));
|
|
266010
266734
|
({ capCompletionBudgetForAdaptiveEffort, capTurnCompletionTokens, selectThinkingEffortForBufferedSteer, selectThinkingEffortForWorkStep, selectThinkingEffortForTurn } = createRequire(import.meta.url)("./bin/turn-thinking-policy.cjs"));
|
|
266011
|
-
PINNED_MODEL_ALIASES = new Set(["king
|
|
266735
|
+
PINNED_MODEL_ALIASES = new Set(["blun/king"]);
|
|
266012
266736
|
Agent$1 = class {
|
|
266013
266737
|
type;
|
|
266014
266738
|
_kaos;
|
|
@@ -266550,6 +267274,7 @@ var init_agent = __esmMin((() => {
|
|
|
266550
267274
|
}
|
|
266551
267275
|
emitEvent(event) {
|
|
266552
267276
|
if (this.records.restoring) return;
|
|
267277
|
+
this.cron?.observeAgentEvent(event);
|
|
266553
267278
|
return this.rpc?.emitEvent?.(event);
|
|
266554
267279
|
}
|
|
266555
267280
|
emitStatusUpdated() {
|
|
@@ -298410,7 +299135,9 @@ var init_session$1 = __esmMin((() => {
|
|
|
298410
299135
|
homedir,
|
|
298411
299136
|
type,
|
|
298412
299137
|
parentAgentId,
|
|
298413
|
-
swarmItem: options.swarmItem
|
|
299138
|
+
swarmItem: options.swarmItem,
|
|
299139
|
+
profileName: options.profileName,
|
|
299140
|
+
skillPolicy: options.skillPolicy
|
|
298414
299141
|
};
|
|
298415
299142
|
this.writeMetadata();
|
|
298416
299143
|
}
|
|
@@ -298686,7 +299413,7 @@ var init_session$1 = __esmMin((() => {
|
|
|
298686
299413
|
missingCapability: part.missingCapability
|
|
298687
299414
|
});
|
|
298688
299415
|
},
|
|
298689
|
-
skills: this.skills,
|
|
299416
|
+
skills: config.skillRegistry === void 0 ? this.skills : config.skillRegistry,
|
|
298690
299417
|
rpc: proxyWithExtraPayload(this.rpc, { agentId: id }),
|
|
298691
299418
|
modelProvider: this.options.providerManager,
|
|
298692
299419
|
hookEngine: config.hookEngine ?? this.hookEngine,
|
|
@@ -298751,9 +299478,16 @@ var init_session$1 = __esmMin((() => {
|
|
|
298751
299478
|
const parentAgentId = meta.parentAgentId ?? null;
|
|
298752
299479
|
const parent = parentAgentId === null ? void 0 : await this.resumeAgent(parentAgentId, [...stack, id]);
|
|
298753
299480
|
try {
|
|
298754
|
-
|
|
299481
|
+
let restoredSkillPolicy;
|
|
299482
|
+
if (meta.type === "sub" && meta.skillPolicy !== void 0) {
|
|
299483
|
+
if (meta.profileName === void 0) throw new Error("SUBAGENT_SKILL_POLICY_CHANGED: persisted subagent profile is unavailable; spawn a new subagent");
|
|
299484
|
+
const persistedProfile = DEFAULT_AGENT_PROFILES[parent?.agent.config.profileName ?? "agent"]?.subagents?.[meta.profileName] ?? DEFAULT_AGENT_PROFILES["agent"]?.subagents?.[meta.profileName];
|
|
299485
|
+
if (persistedProfile === void 0) throw new Error("SUBAGENT_SKILL_POLICY_CHANGED: persisted subagent profile was not found; spawn a new subagent");
|
|
299486
|
+
restoredSkillPolicy = restoreSubagentSkillPolicy(persistedProfile.subagentSkills, meta.skillPolicy, this.skills);
|
|
299487
|
+
}
|
|
299488
|
+
const agent = this.instantiateAgent(id, meta.homedir, meta.type, restoredSkillPolicy === void 0 ? {} : { skillRegistry: restoredSkillPolicy.registry }, parentAgentId);
|
|
298755
299489
|
const result = await agent.resume();
|
|
298756
|
-
await this.restoreAgentProfileHandle(agent, meta, parent?.agent);
|
|
299490
|
+
await this.restoreAgentProfileHandle(agent, meta, parent?.agent, restoredSkillPolicy);
|
|
298757
299491
|
this.ensureBaselineSkill(agent);
|
|
298758
299492
|
agent.setRuntimeSystemPromptAppend(this.accountMemoryContext);
|
|
298759
299493
|
this.agents.set(id, agent);
|
|
@@ -298766,18 +299500,33 @@ var init_session$1 = __esmMin((() => {
|
|
|
298766
299500
|
throw error;
|
|
298767
299501
|
}
|
|
298768
299502
|
}
|
|
298769
|
-
async restoreAgentProfileHandle(agent, meta, parentAgent) {
|
|
299503
|
+
async restoreAgentProfileHandle(agent, meta, parentAgent, restoredSkillPolicy) {
|
|
298770
299504
|
if (agent.config.systemPrompt === "") return;
|
|
298771
|
-
|
|
299505
|
+
let profile = this.resolvePersistedProfile(agent, meta, parentAgent);
|
|
298772
299506
|
if (profile === void 0) return;
|
|
299507
|
+
if (restoredSkillPolicy !== void 0) profile = profileWithSubagentSkillTools(profile, restoredSkillPolicy);
|
|
298773
299508
|
agent.setActiveProfile(profile, this.options.blunHomeDir);
|
|
298774
299509
|
await agent.refreshSystemPrompt();
|
|
298775
299510
|
}
|
|
298776
299511
|
ensureBaselineSkill(agent) {
|
|
298777
|
-
|
|
299512
|
+
const skill = this.skills.getSkill(BASELINE_SKILL_NAME);
|
|
299513
|
+
if (skill === void 0) {
|
|
299514
|
+
this.log.warn("baseline skill is unavailable", { skill: BASELINE_SKILL_NAME });
|
|
299515
|
+
return;
|
|
299516
|
+
}
|
|
299517
|
+
const variant = `${BASELINE_SKILL_ORIGIN_PREFIX}${skill.name}`;
|
|
299518
|
+
if (agent.context.history.some((message) => message.origin?.kind === "injection" && message.origin.variant === variant)) return;
|
|
299519
|
+
agent.context.appendSystemReminder(renderBaselineSkillPrompt({
|
|
299520
|
+
skillName: skill.name,
|
|
299521
|
+
skillSource: skill.source,
|
|
299522
|
+
skillDir: skill.dir
|
|
299523
|
+
}), {
|
|
299524
|
+
kind: "injection",
|
|
299525
|
+
variant
|
|
299526
|
+
});
|
|
298778
299527
|
}
|
|
298779
299528
|
resolvePersistedProfile(agent, meta, parentAgent) {
|
|
298780
|
-
const profileName = agent.config.profileName;
|
|
299529
|
+
const profileName = meta.profileName ?? agent.config.profileName;
|
|
298781
299530
|
if (profileName === void 0) return void 0;
|
|
298782
299531
|
if (meta.type === "sub") return DEFAULT_AGENT_PROFILES[parentAgent?.config.profileName ?? "agent"]?.subagents?.[profileName] ?? DEFAULT_AGENT_PROFILES["agent"]?.subagents?.[profileName];
|
|
298783
299532
|
return DEFAULT_AGENT_PROFILES[profileName];
|
|
@@ -313566,27 +314315,14 @@ var init_local_fetch_url = __esmMin((() => {
|
|
|
313566
314315
|
kind: "passthrough"
|
|
313567
314316
|
};
|
|
313568
314317
|
return {
|
|
313569
|
-
content: this.extractMainContent(body),
|
|
314318
|
+
content: this.extractMainContent(body, url),
|
|
313570
314319
|
kind: "extracted"
|
|
313571
314320
|
};
|
|
313572
314321
|
}
|
|
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;
|
|
314322
|
+
extractMainContent(html, baseUrl) {
|
|
314323
|
+
const content = htmlToResearchMarkdown(html, baseUrl);
|
|
314324
|
+
if (content.length === 0) throw new Error("Failed to extract meaningful content from the page. The page may require JavaScript to render.");
|
|
314325
|
+
return content;
|
|
313590
314326
|
}
|
|
313591
314327
|
};
|
|
313592
314328
|
}));
|
|
@@ -315079,17 +315815,7 @@ function resolveModelCapabilities(alias, provider) {
|
|
|
315079
315815
|
};
|
|
315080
315816
|
}
|
|
315081
315817
|
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
|
-
};
|
|
315818
|
+
assertBlunProviderType(provider);
|
|
315093
315819
|
const envCustomHeaders = parseBlunCodeCustomHeaders();
|
|
315094
315820
|
return {
|
|
315095
315821
|
type: "blun",
|
|
@@ -315110,12 +315836,11 @@ function defaultHeadersField(headers) {
|
|
|
315110
315836
|
return { defaultHeaders: { ...headers } };
|
|
315111
315837
|
}
|
|
315112
315838
|
function providerApiKey(provider) {
|
|
315113
|
-
|
|
315114
|
-
if (provider.type === FREDRIK_GLM_PROVIDER_TYPE) return readFredrikGlmApiKeyFile(provider);
|
|
315839
|
+
assertBlunProviderType(provider);
|
|
315115
315840
|
return providerValue(provider.apiKey, provider.env, "BLUN_API_KEY");
|
|
315116
315841
|
}
|
|
315117
|
-
function
|
|
315118
|
-
if (provider.type !== "blun"
|
|
315842
|
+
function assertBlunProviderType(provider) {
|
|
315843
|
+
if (provider.type !== "blun") throw new BlunError(ErrorCodes.MODEL_CONFIG_INVALID, "Only the BLUN provider type is supported.");
|
|
315119
315844
|
}
|
|
315120
315845
|
function providerValue(configured, env, envKey) {
|
|
315121
315846
|
return nonEmptyString$2(configured) ?? envValue(env, envKey);
|
|
@@ -315134,7 +315859,7 @@ var init_provider_manager = __esmMin((() => {
|
|
|
315134
315859
|
init_config$4();
|
|
315135
315860
|
init_errors$8();
|
|
315136
315861
|
MANAGED_PROVIDER_NAME$2 = "managed:blun";
|
|
315137
|
-
MANAGED_BLUN_MODEL_ALIASES$1 = new Set(["blun/king"
|
|
315862
|
+
MANAGED_BLUN_MODEL_ALIASES$1 = new Set(["blun/king"]);
|
|
315138
315863
|
ProviderManager = class {
|
|
315139
315864
|
options;
|
|
315140
315865
|
runtimeModelContexts = /* @__PURE__ */ new Map();
|
|
@@ -315153,9 +315878,7 @@ var init_provider_manager = __esmMin((() => {
|
|
|
315153
315878
|
if (providerName === void 0) throw new BlunError(ErrorCodes.CONFIG_INVALID, `Model "${model}" must define a provider in config.toml.`);
|
|
315154
315879
|
const providerConfig = this.config.providers[providerName];
|
|
315155
315880
|
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.");
|
|
315881
|
+
assertBlunProviderType(providerConfig);
|
|
315159
315882
|
const runtimeContext = this.runtimeModelContexts.get(model);
|
|
315160
315883
|
const maxContextSize = runtimeContext?.providerName === providerName && runtimeContext.model === alias.model ? runtimeContext.maxContextTokens : effectiveAlias.maxContextSize;
|
|
315161
315884
|
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 +315892,7 @@ var init_provider_manager = __esmMin((() => {
|
|
|
315169
315892
|
}, provider),
|
|
315170
315893
|
alwaysThinking: (effectiveAlias.capabilities ?? []).some((c) => c.trim().toLowerCase() === "always_thinking"),
|
|
315171
315894
|
maxOutputSize: effectiveAlias.maxOutputSize,
|
|
315172
|
-
type:
|
|
315895
|
+
type: "blun"
|
|
315173
315896
|
};
|
|
315174
315897
|
}
|
|
315175
315898
|
setRuntimeModelContext(input) {
|
|
@@ -315177,7 +315900,7 @@ var init_provider_manager = __esmMin((() => {
|
|
|
315177
315900
|
if (!Number.isSafeInteger(input.maxContextTokens) || input.maxContextTokens <= 0) throw new BlunError(ErrorCodes.CONFIG_INVALID, "Runtime model context must be a positive integer.");
|
|
315178
315901
|
const alias = this.config.models?.[input.modelAlias];
|
|
315179
315902
|
const providerName = alias?.provider ?? this.config.defaultProvider;
|
|
315180
|
-
if (alias === void 0 || providerName !== input.providerName || alias.model !== input.model || providerName !== "managed:blun"
|
|
315903
|
+
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
315904
|
const previous = this.runtimeModelContexts.get(input.modelAlias);
|
|
315182
315905
|
this.runtimeModelContexts.set(input.modelAlias, {
|
|
315183
315906
|
providerName: input.providerName,
|
|
@@ -315189,7 +315912,7 @@ var init_provider_manager = __esmMin((() => {
|
|
|
315189
315912
|
resolveAuth(model, options) {
|
|
315190
315913
|
const { providerName } = this.resolveProviderConfig(model);
|
|
315191
315914
|
const providerConfig = this.config.providers[providerName];
|
|
315192
|
-
const apiKey = providerConfig
|
|
315915
|
+
const apiKey = providerConfig === void 0 ? void 0 : providerApiKey(providerConfig);
|
|
315193
315916
|
const revocationStore = this.options.managedApiKeyRevocationStore;
|
|
315194
315917
|
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
315918
|
if (providerConfig?.oauth === void 0) return void 0;
|
|
@@ -319412,6 +320135,7 @@ function toBrokerRequest$1(req, params) {
|
|
|
319412
320135
|
tool_name: req.toolName,
|
|
319413
320136
|
action: req.action,
|
|
319414
320137
|
tool_input_display: req.display,
|
|
320138
|
+
allow_edit: req.allowEdit === true ? true : void 0,
|
|
319415
320139
|
created_at: params.createdAt,
|
|
319416
320140
|
expires_at: params.expiresAt
|
|
319417
320141
|
};
|
|
@@ -319426,7 +320150,8 @@ function toAgentCoreResponse$1(resp) {
|
|
|
319426
320150
|
decision: resp.decision,
|
|
319427
320151
|
scope: resp.scope,
|
|
319428
320152
|
feedback: resp.feedback,
|
|
319429
|
-
selectedLabel: resp.selected_label
|
|
320153
|
+
selectedLabel: resp.selected_label,
|
|
320154
|
+
edited_tool_input: resp.edited_tool_input
|
|
319430
320155
|
};
|
|
319431
320156
|
}
|
|
319432
320157
|
var IApprovalService;
|
|
@@ -373133,16 +373858,18 @@ var PendingApproval = class {
|
|
|
373133
373858
|
createdAt;
|
|
373134
373859
|
expiresAt;
|
|
373135
373860
|
protocolRequest;
|
|
373861
|
+
editContext;
|
|
373136
373862
|
_resolveFn;
|
|
373137
373863
|
_rejectFn;
|
|
373138
373864
|
_settled = false;
|
|
373139
|
-
constructor(approvalId, sessionId, toolCallId, createdAt, expiresAt, protocolRequest, _resolveFn, _rejectFn) {
|
|
373865
|
+
constructor(approvalId, sessionId, toolCallId, createdAt, expiresAt, protocolRequest, editContext, _resolveFn, _rejectFn) {
|
|
373140
373866
|
this.approvalId = approvalId;
|
|
373141
373867
|
this.sessionId = sessionId;
|
|
373142
373868
|
this.toolCallId = toolCallId;
|
|
373143
373869
|
this.createdAt = createdAt;
|
|
373144
373870
|
this.expiresAt = expiresAt;
|
|
373145
373871
|
this.protocolRequest = protocolRequest;
|
|
373872
|
+
this.editContext = editContext;
|
|
373146
373873
|
this._resolveFn = _resolveFn;
|
|
373147
373874
|
this._rejectFn = _rejectFn;
|
|
373148
373875
|
}
|
|
@@ -373216,7 +373943,10 @@ let ApprovalService = class ApprovalService extends Disposable {
|
|
|
373216
373943
|
toolCallId: req.toolCallId
|
|
373217
373944
|
}, "approval requested");
|
|
373218
373945
|
return new Promise((resolve, reject) => {
|
|
373219
|
-
this._pending.set(approvalId, new PendingApproval(approvalId, req.sessionId, req.toolCallId, createdAt, expiresAt, protocolRequest,
|
|
373946
|
+
this._pending.set(approvalId, new PendingApproval(approvalId, req.sessionId, req.toolCallId, createdAt, expiresAt, protocolRequest, {
|
|
373947
|
+
toolName: req.toolName,
|
|
373948
|
+
editCount: Number.isSafeInteger(req.approvalEditCount) ? req.approvalEditCount : 0
|
|
373949
|
+
}, resolve, reject));
|
|
373220
373950
|
this._byToolCallId.set(req.toolCallId, approvalId);
|
|
373221
373951
|
});
|
|
373222
373952
|
}
|
|
@@ -373245,6 +373975,14 @@ let ApprovalService = class ApprovalService extends Disposable {
|
|
|
373245
373975
|
isPending(approvalId) {
|
|
373246
373976
|
return this._pending.has(approvalId);
|
|
373247
373977
|
}
|
|
373978
|
+
getEditContext(approvalId) {
|
|
373979
|
+
const pending = this._pending.get(approvalId);
|
|
373980
|
+
if (!pending) return void 0;
|
|
373981
|
+
return {
|
|
373982
|
+
toolName: pending.editContext.toolName,
|
|
373983
|
+
editCount: pending.editContext.editCount
|
|
373984
|
+
};
|
|
373985
|
+
}
|
|
373248
373986
|
listPending(sessionId) {
|
|
373249
373987
|
return Array.from(this._pending.values()).filter((p) => p.sessionId === sessionId).map((p) => p.protocolRequest);
|
|
373250
373988
|
}
|
|
@@ -373287,6 +374025,24 @@ const approvalParamsSchema = object({
|
|
|
373287
374025
|
session_id: string().min(1),
|
|
373288
374026
|
approval_id: string().min(1)
|
|
373289
374027
|
});
|
|
374028
|
+
const EDITABLE_APPROVAL_RAW_BODY_LIMIT = 65536;
|
|
374029
|
+
async function captureEditableApprovalRawBody(req, reply, payload) {
|
|
374030
|
+
const chunks = [];
|
|
374031
|
+
let totalBytes = 0;
|
|
374032
|
+
for await (const chunk of payload) {
|
|
374033
|
+
const bytes = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk);
|
|
374034
|
+
totalBytes += bytes.length;
|
|
374035
|
+
if (totalBytes > EDITABLE_APPROVAL_RAW_BODY_LIMIT) {
|
|
374036
|
+
const error = new Error("Approval response body exceeds the editable-input limit");
|
|
374037
|
+
error.statusCode = 413;
|
|
374038
|
+
throw error;
|
|
374039
|
+
}
|
|
374040
|
+
chunks.push(bytes);
|
|
374041
|
+
}
|
|
374042
|
+
const rawBody = Buffer.concat(chunks, totalBytes);
|
|
374043
|
+
req.editableApprovalRawBody = rawBody.toString("utf8");
|
|
374044
|
+
return Readable.from([rawBody]);
|
|
374045
|
+
}
|
|
373290
374046
|
function registerApprovalsRoutes(app, ix) {
|
|
373291
374047
|
const listRoute = defineRoute({
|
|
373292
374048
|
method: "GET",
|
|
@@ -373331,7 +374087,27 @@ function registerApprovalsRoutes(app, ix) {
|
|
|
373331
374087
|
reply.send(errEnvelope(ErrorCode$1.APPROVAL_NOT_FOUND, `approval ${approval_id} not found`, req.id));
|
|
373332
374088
|
return;
|
|
373333
374089
|
}
|
|
373334
|
-
const
|
|
374090
|
+
const editContext = broker.getEditContext(approval_id);
|
|
374091
|
+
if (editContext === void 0 || typeof req.editableApprovalRawBody !== "string") {
|
|
374092
|
+
reply.send(errEnvelope(ErrorCode$1.VALIDATION_FAILED, "approval response could not be validated from its raw JSON body", req.id));
|
|
374093
|
+
return;
|
|
374094
|
+
}
|
|
374095
|
+
let inProc;
|
|
374096
|
+
try {
|
|
374097
|
+
const rawResponse = parseEditedToolInputJson(req.editableApprovalRawBody);
|
|
374098
|
+
const normalized = validateEditedApprovalDecision({
|
|
374099
|
+
response: rawResponse,
|
|
374100
|
+
toolName: editContext.toolName,
|
|
374101
|
+
editCount: editContext.editCount
|
|
374102
|
+
});
|
|
374103
|
+
inProc = normalized.decision === "edited" ? {
|
|
374104
|
+
decision: "edited",
|
|
374105
|
+
edited_tool_input: normalized.editedToolInput
|
|
374106
|
+
} : normalized;
|
|
374107
|
+
} catch (error) {
|
|
374108
|
+
reply.send(errEnvelope(ErrorCode$1.VALIDATION_FAILED, error instanceof Error ? error.message : String(error), req.id));
|
|
374109
|
+
return;
|
|
374110
|
+
}
|
|
373335
374111
|
broker.resolve(approval_id, inProc);
|
|
373336
374112
|
broker.markResolved(approval_id);
|
|
373337
374113
|
const result = {
|
|
@@ -373340,6 +374116,7 @@ function registerApprovalsRoutes(app, ix) {
|
|
|
373340
374116
|
};
|
|
373341
374117
|
reply.send(okEnvelope(result, req.id));
|
|
373342
374118
|
});
|
|
374119
|
+
route.options.preParsing = captureEditableApprovalRawBody;
|
|
373343
374120
|
app.post(route.path, route.options, route.handler);
|
|
373344
374121
|
}
|
|
373345
374122
|
//#endregion
|
|
@@ -404208,13 +404985,6 @@ const BUILTIN_SLASH_COMMAND_DEFINITIONS = [
|
|
|
404208
404985
|
completeArgs: swarmArgumentCompletions,
|
|
404209
404986
|
availability: "idle-only"
|
|
404210
404987
|
},
|
|
404211
|
-
{
|
|
404212
|
-
name: "model",
|
|
404213
|
-
aliases: [],
|
|
404214
|
-
descriptionKey: "command.model.description",
|
|
404215
|
-
priority: 96,
|
|
404216
|
-
availability: "always"
|
|
404217
|
-
},
|
|
404218
404988
|
{
|
|
404219
404989
|
name: "effort",
|
|
404220
404990
|
aliases: ["thinking"],
|
|
@@ -404666,6 +405436,7 @@ registerUiCatalogFragment({
|
|
|
404666
405436
|
//#endregion
|
|
404667
405437
|
//#region src/tui/commands/resolve.ts
|
|
404668
405438
|
const LEGACY_EFFORT_COMMANDS = new Set([
|
|
405439
|
+
"model",
|
|
404669
405440
|
"automodel",
|
|
404670
405441
|
"router"
|
|
404671
405442
|
]);
|
|
@@ -417702,168 +418473,6 @@ function segmentsFor(model) {
|
|
|
417702
418473
|
if (availability === "unsupported") return ["off"];
|
|
417703
418474
|
return ["off", "on"];
|
|
417704
418475
|
}
|
|
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
418476
|
//#endregion
|
|
417868
418477
|
//#region src/tui/components/dialogs/permission-selector.ts
|
|
417869
418478
|
function permissionOptions() {
|
|
@@ -421669,47 +422278,6 @@ async function handleThemeCommand(host, args) {
|
|
|
421669
422278
|
}
|
|
421670
422279
|
await applyThemeChoice(host, theme);
|
|
421671
422280
|
}
|
|
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
422281
|
async function handleEffortCommand(host, args) {
|
|
421714
422282
|
const alias = host.state.appState.model;
|
|
421715
422283
|
const model = host.state.appState.availableModels[alias];
|
|
@@ -421741,7 +422309,7 @@ async function handleEffortCommand(host, args) {
|
|
|
421741
422309
|
}));
|
|
421742
422310
|
return;
|
|
421743
422311
|
}
|
|
421744
|
-
await performEffortSelection(host, alias, arg,
|
|
422312
|
+
await performEffortSelection(host, alias, arg, true);
|
|
421745
422313
|
}
|
|
421746
422314
|
function showEffortPicker(host, model, segments) {
|
|
421747
422315
|
const liveEffort = host.state.appState.thinkingEffort;
|
|
@@ -421752,7 +422320,7 @@ function showEffortPicker(host, model, segments) {
|
|
|
421752
422320
|
currentValue,
|
|
421753
422321
|
currentBlunSwarm: host.state.appState.swarmMode && host.state.appState.swarmModeEntry === "effort",
|
|
421754
422322
|
onSelect: (effort) => {
|
|
421755
|
-
host.restoreEditorAfter(() => performEffortSelection(host, alias, effort,
|
|
422323
|
+
host.restoreEditorAfter(() => performEffortSelection(host, alias, effort, true));
|
|
421756
422324
|
},
|
|
421757
422325
|
onSessionOnlySelect: (effort) => {
|
|
421758
422326
|
host.restoreEditorAfter(() => performEffortSelection(host, alias, effort, false));
|
|
@@ -432550,6 +433118,11 @@ function agentSwarmResultSummaryFromOutput(output) {
|
|
|
432550
433118
|
};
|
|
432551
433119
|
}
|
|
432552
433120
|
function parseAgentSwarmResultStatuses(output) {
|
|
433121
|
+
const structured = parseStructuredSwarmDisplay(output);
|
|
433122
|
+
if (structured.recognized) return structured.statuses.map((entry) => ({
|
|
433123
|
+
...entry,
|
|
433124
|
+
status: entry.status === "aborted" ? "cancelled" : entry.status
|
|
433125
|
+
}));
|
|
432553
433126
|
const xmlStatuses = parseAgentSwarmXmlResultStatuses(output);
|
|
432554
433127
|
if (xmlStatuses.length > 0) return xmlStatuses;
|
|
432555
433128
|
return parseAgentSwarmLegacyResultStatuses(output);
|
|
@@ -497454,9 +498027,6 @@ async function handleBuiltInSlashCommand(host, name, args) {
|
|
|
497454
498027
|
case "theme":
|
|
497455
498028
|
await handleThemeCommand(host, args);
|
|
497456
498029
|
return;
|
|
497457
|
-
case "model":
|
|
497458
|
-
await handleModelCommand(host, args);
|
|
497459
|
-
return;
|
|
497460
498030
|
case "effort":
|
|
497461
498031
|
await handleEffortCommand(host, args);
|
|
497462
498032
|
return;
|
|
@@ -499539,9 +500109,11 @@ registerUiCatalogFragment({
|
|
|
499539
500109
|
"approval.search.scope": "scope: {scope}",
|
|
499540
500110
|
"approval.backgroundTask": "{status} {kind} task {taskId}: {description}",
|
|
499541
500111
|
"approval.hint.feedback": "Type feedback · ↵ submit.",
|
|
500112
|
+
"approval.hint.editArguments": "Enter the complete replacement JSON object · ↵ submit.",
|
|
499542
500113
|
"approval.hint.main": "↑/↓ select · {numbers} choose · ↵ confirm{preview}",
|
|
499543
500114
|
"approval.hint.preview": " · ctrl+e preview",
|
|
499544
500115
|
"approval.choice.approveOnce": "Approve once",
|
|
500116
|
+
"approval.choice.editArguments": "Edit arguments (JSON)",
|
|
499545
500117
|
"approval.choice.approveSession": "Approve for this session",
|
|
499546
500118
|
"approval.choice.reject": "Reject",
|
|
499547
500119
|
"approval.choice.rejectFeedback": "Reject with feedback",
|
|
@@ -499551,6 +500123,7 @@ registerUiCatalogFragment({
|
|
|
499551
500123
|
"approval.transcript.approvedSession": "Approved for session",
|
|
499552
500124
|
"approval.transcript.rejected": "Rejected",
|
|
499553
500125
|
"approval.transcript.cancelled": "Cancelled",
|
|
500126
|
+
"approval.transcript.edited": "Arguments edited",
|
|
499554
500127
|
"approval.transcript.action": "{decision}: {action}",
|
|
499555
500128
|
"approval.transcript.actionWithFeedback": "{decision}: {action} — \"{feedback}\""
|
|
499556
500129
|
},
|
|
@@ -499570,9 +500143,11 @@ registerUiCatalogFragment({
|
|
|
499570
500143
|
"approval.search.scope": "Bereich: {scope}",
|
|
499571
500144
|
"approval.backgroundTask": "Aufgabe {taskId} ({status}, {kind}): {description}",
|
|
499572
500145
|
"approval.hint.feedback": "Feedback eingeben · ↵ absenden.",
|
|
500146
|
+
"approval.hint.editArguments": "Vollständiges Ersatz-JSON-Objekt eingeben · ↵ absenden.",
|
|
499573
500147
|
"approval.hint.main": "↑/↓ auswählen · {numbers} wählen · ↵ bestätigen{preview}",
|
|
499574
500148
|
"approval.hint.preview": " · ctrl+e Vorschau",
|
|
499575
500149
|
"approval.choice.approveOnce": "Einmal genehmigen",
|
|
500150
|
+
"approval.choice.editArguments": "Argumente bearbeiten (JSON)",
|
|
499576
500151
|
"approval.choice.approveSession": "Für diese Sitzung genehmigen",
|
|
499577
500152
|
"approval.choice.reject": "Ablehnen",
|
|
499578
500153
|
"approval.choice.rejectFeedback": "Ablehnen und Feedback geben",
|
|
@@ -499582,6 +500157,7 @@ registerUiCatalogFragment({
|
|
|
499582
500157
|
"approval.transcript.approvedSession": "Für diese Sitzung genehmigt",
|
|
499583
500158
|
"approval.transcript.rejected": "Abgelehnt",
|
|
499584
500159
|
"approval.transcript.cancelled": "Abgebrochen",
|
|
500160
|
+
"approval.transcript.edited": "Argumente bearbeitet",
|
|
499585
500161
|
"approval.transcript.action": "{decision}: {action}",
|
|
499586
500162
|
"approval.transcript.actionWithFeedback": "{decision}: {action} – „{feedback}“"
|
|
499587
500163
|
},
|
|
@@ -499601,9 +500177,11 @@ registerUiCatalogFragment({
|
|
|
499601
500177
|
"approval.search.scope": "Ámbito: {scope}",
|
|
499602
500178
|
"approval.backgroundTask": "Tarea {taskId} ({status}, {kind}): {description}",
|
|
499603
500179
|
"approval.hint.feedback": "Escribe tus comentarios · ↵ enviar.",
|
|
500180
|
+
"approval.hint.editArguments": "Introduce el objeto JSON completo de sustitución · ↵ enviar.",
|
|
499604
500181
|
"approval.hint.main": "↑/↓ seleccionar · {numbers} elegir · ↵ confirmar{preview}",
|
|
499605
500182
|
"approval.hint.preview": " · ctrl+e vista previa",
|
|
499606
500183
|
"approval.choice.approveOnce": "Aprobar una vez",
|
|
500184
|
+
"approval.choice.editArguments": "Editar argumentos (JSON)",
|
|
499607
500185
|
"approval.choice.approveSession": "Aprobar durante esta sesión",
|
|
499608
500186
|
"approval.choice.reject": "Rechazar",
|
|
499609
500187
|
"approval.choice.rejectFeedback": "Rechazar y enviar comentarios",
|
|
@@ -499613,6 +500191,7 @@ registerUiCatalogFragment({
|
|
|
499613
500191
|
"approval.transcript.approvedSession": "Aprobado durante esta sesión",
|
|
499614
500192
|
"approval.transcript.rejected": "Rechazado",
|
|
499615
500193
|
"approval.transcript.cancelled": "Cancelado",
|
|
500194
|
+
"approval.transcript.edited": "Argumentos modificados",
|
|
499616
500195
|
"approval.transcript.action": "{decision}: {action}",
|
|
499617
500196
|
"approval.transcript.actionWithFeedback": "{decision}: {action} — «{feedback}»"
|
|
499618
500197
|
},
|
|
@@ -499632,9 +500211,11 @@ registerUiCatalogFragment({
|
|
|
499632
500211
|
"approval.search.scope": "Portée : {scope}",
|
|
499633
500212
|
"approval.backgroundTask": "Tâche {taskId} ({status}, {kind}) : {description}",
|
|
499634
500213
|
"approval.hint.feedback": "Saisissez un commentaire · ↵ envoyer.",
|
|
500214
|
+
"approval.hint.editArguments": "Saisissez l’objet JSON de remplacement complet · ↵ envoyer.",
|
|
499635
500215
|
"approval.hint.main": "↑/↓ sélectionner · {numbers} choisir · ↵ confirmer{preview}",
|
|
499636
500216
|
"approval.hint.preview": " · ctrl+e aperçu",
|
|
499637
500217
|
"approval.choice.approveOnce": "Approuver une fois",
|
|
500218
|
+
"approval.choice.editArguments": "Modifier les arguments (JSON)",
|
|
499638
500219
|
"approval.choice.approveSession": "Approuver pour cette session",
|
|
499639
500220
|
"approval.choice.reject": "Refuser",
|
|
499640
500221
|
"approval.choice.rejectFeedback": "Refuser et ajouter un commentaire",
|
|
@@ -499644,6 +500225,7 @@ registerUiCatalogFragment({
|
|
|
499644
500225
|
"approval.transcript.approvedSession": "Approuvé pour cette session",
|
|
499645
500226
|
"approval.transcript.rejected": "Refusé",
|
|
499646
500227
|
"approval.transcript.cancelled": "Annulé",
|
|
500228
|
+
"approval.transcript.edited": "Arguments modifiés",
|
|
499647
500229
|
"approval.transcript.action": "{decision} : {action}",
|
|
499648
500230
|
"approval.transcript.actionWithFeedback": "{decision} : {action} — « {feedback} »"
|
|
499649
500231
|
},
|
|
@@ -499663,9 +500245,11 @@ registerUiCatalogFragment({
|
|
|
499663
500245
|
"approval.search.scope": "Omfattning: {scope}",
|
|
499664
500246
|
"approval.backgroundTask": "Uppgift {taskId} ({status}, {kind}): {description}",
|
|
499665
500247
|
"approval.hint.feedback": "Skriv återkoppling · ↵ skicka.",
|
|
500248
|
+
"approval.hint.editArguments": "Ange hela JSON-objektet som ska ersätta det befintliga · ↵ skicka.",
|
|
499666
500249
|
"approval.hint.main": "↑/↓ markera · {numbers} välj · ↵ bekräfta{preview}",
|
|
499667
500250
|
"approval.hint.preview": " · ctrl+e förhandsgranska",
|
|
499668
500251
|
"approval.choice.approveOnce": "Godkänn en gång",
|
|
500252
|
+
"approval.choice.editArguments": "Redigera argument (JSON)",
|
|
499669
500253
|
"approval.choice.approveSession": "Godkänn för den här sessionen",
|
|
499670
500254
|
"approval.choice.reject": "Avvisa",
|
|
499671
500255
|
"approval.choice.rejectFeedback": "Avvisa och lämna återkoppling",
|
|
@@ -499675,6 +500259,7 @@ registerUiCatalogFragment({
|
|
|
499675
500259
|
"approval.transcript.approvedSession": "Godkänt för den här sessionen",
|
|
499676
500260
|
"approval.transcript.rejected": "Avvisat",
|
|
499677
500261
|
"approval.transcript.cancelled": "Avbrutet",
|
|
500262
|
+
"approval.transcript.edited": "Argument redigerade",
|
|
499678
500263
|
"approval.transcript.action": "{decision}: {action}",
|
|
499679
500264
|
"approval.transcript.actionWithFeedback": "{decision}: {action} – ”{feedback}”"
|
|
499680
500265
|
},
|
|
@@ -499858,7 +500443,7 @@ var ApprovalPanelComponent = class extends Container {
|
|
|
499858
500443
|
if (!option) return;
|
|
499859
500444
|
this.onResponse({
|
|
499860
500445
|
response: option.response,
|
|
499861
|
-
feedback: feedback || void 0,
|
|
500446
|
+
...(option.input_kind === "edited_tool_input_json" ? { edited_tool_input_json: feedback } : { feedback: feedback || void 0 }),
|
|
499862
500447
|
selected_label: option.selected_label
|
|
499863
500448
|
});
|
|
499864
500449
|
}
|
|
@@ -499868,6 +500453,7 @@ var ApprovalPanelComponent = class extends Container {
|
|
|
499868
500453
|
if (option.requires_feedback === true) {
|
|
499869
500454
|
this.selectedIndex = index;
|
|
499870
500455
|
this.feedbackMode = true;
|
|
500456
|
+
if (option.input_kind === "edited_tool_input_json") this.feedbackInput.setValue(this.request.data.editable_tool_input_json ?? "{}");
|
|
499871
500457
|
} else this.submit(index);
|
|
499872
500458
|
}
|
|
499873
500459
|
handleInput(data) {
|
|
@@ -499964,7 +500550,7 @@ var ApprovalPanelComponent = class extends Container {
|
|
|
499964
500550
|
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
500551
|
}
|
|
499966
500552
|
lines.push("");
|
|
499967
|
-
if (this.feedbackMode) lines.push(indent(dim(uiText("approval.hint.feedback"))));
|
|
500553
|
+
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
500554
|
else {
|
|
499969
500555
|
const expandHint = hasPreviewable ? uiText("approval.hint.preview") : "";
|
|
499970
500556
|
lines.push(indent(dim(uiText("approval.hint.main", {
|
|
@@ -503221,12 +503807,18 @@ async function refreshAllProviderModels(host, options = {}) {
|
|
|
503221
503807
|
}
|
|
503222
503808
|
//#endregion
|
|
503223
503809
|
//#region src/tui/reverse-rpc/approval/adapter.ts
|
|
503224
|
-
function defaultApprovalChoices() {
|
|
503810
|
+
function defaultApprovalChoices(allowEdit = false) {
|
|
503225
503811
|
return [
|
|
503226
503812
|
{
|
|
503227
503813
|
label: uiText("approval.choice.approveOnce"),
|
|
503228
503814
|
response: "approved"
|
|
503229
503815
|
},
|
|
503816
|
+
...allowEdit ? [{
|
|
503817
|
+
label: uiText("approval.choice.editArguments"),
|
|
503818
|
+
response: "edited",
|
|
503819
|
+
requires_feedback: true,
|
|
503820
|
+
input_kind: "edited_tool_input_json"
|
|
503821
|
+
}] : [],
|
|
503230
503822
|
{
|
|
503231
503823
|
label: uiText("approval.choice.approveSession"),
|
|
503232
503824
|
response: "approved_for_session"
|
|
@@ -503263,7 +503855,8 @@ function adaptApprovalRequest(event) {
|
|
|
503263
503855
|
action: resolved.action ?? event.action,
|
|
503264
503856
|
description: resolved.description,
|
|
503265
503857
|
display: resolved.blocks,
|
|
503266
|
-
choices: adaptChoices(event.toolName, event.display)
|
|
503858
|
+
choices: adaptChoices(event.toolName, event.display, event.allowEdit === true),
|
|
503859
|
+
editable_tool_input_json: event.allowEdit === true ? canonicalEditedToolInputJson(event.editableToolInput) : void 0
|
|
503267
503860
|
};
|
|
503268
503861
|
}
|
|
503269
503862
|
function resolveDisplay(toolName, display, action) {
|
|
@@ -503367,6 +503960,10 @@ function inferFileOp(toolName) {
|
|
|
503367
503960
|
return "read";
|
|
503368
503961
|
}
|
|
503369
503962
|
function adaptPanelResponse(response) {
|
|
503963
|
+
if (response.response === "edited") return {
|
|
503964
|
+
decision: "edited",
|
|
503965
|
+
edited_tool_input_json: response.edited_tool_input_json
|
|
503966
|
+
};
|
|
503370
503967
|
if (response.response === "approved_for_session") return {
|
|
503371
503968
|
decision: "approved",
|
|
503372
503969
|
scope: "session",
|
|
@@ -503530,10 +504127,10 @@ function adaptDisplay(display) {
|
|
|
503530
504127
|
default: return [];
|
|
503531
504128
|
}
|
|
503532
504129
|
}
|
|
503533
|
-
function adaptChoices(toolName, display) {
|
|
504130
|
+
function adaptChoices(toolName, display, allowEdit = false) {
|
|
503534
504131
|
if (toolName === "ExitPlanMode" || display.kind === "plan_review") return adaptPlanReviewChoices(display);
|
|
503535
504132
|
if (display.kind === "goal_start") return adaptGoalStartChoices(display);
|
|
503536
|
-
return defaultApprovalChoices();
|
|
504133
|
+
return defaultApprovalChoices(allowEdit);
|
|
503537
504134
|
}
|
|
503538
504135
|
function adaptGoalStartChoices(display) {
|
|
503539
504136
|
return goalStartOptions(display.mode).map((option) => option.value === "cancel" ? {
|
|
@@ -503629,7 +504226,7 @@ function createApprovalRequestHandler(controller, onResponse, options = {}) {
|
|
|
503629
504226
|
}).catch(() => {});
|
|
503630
504227
|
}
|
|
503631
504228
|
const response = await pending;
|
|
503632
|
-
relay?.complete(response);
|
|
504229
|
+
relay?.complete(response.decision === "edited" ? { decision: "edited" } : response);
|
|
503633
504230
|
onResponse?.(event, response);
|
|
503634
504231
|
return response;
|
|
503635
504232
|
} catch {
|
|
@@ -503676,10 +504273,7 @@ function applyManagedAccountContext(models, maxContextTokens) {
|
|
|
503676
504273
|
maxContextSize: maxContextTokens
|
|
503677
504274
|
} }
|
|
503678
504275
|
};
|
|
503679
|
-
return {
|
|
503680
|
-
[BLUN_KING_MODEL_ALIAS]: king,
|
|
503681
|
-
...configuredFredrikGlmModels(models)
|
|
503682
|
-
};
|
|
504276
|
+
return { [BLUN_KING_MODEL_ALIAS]: king };
|
|
503683
504277
|
}
|
|
503684
504278
|
function normalizeKingProductEffort(value) {
|
|
503685
504279
|
if (value === "none" || value === "minimal" || value === "off") return "low";
|
|
@@ -503735,11 +504329,7 @@ function nextManagedQuotaWarning(windows, highestShown) {
|
|
|
503735
504329
|
//#region src/tui/controllers/auth-flow.ts
|
|
503736
504330
|
function managedProviderOnly(providers) {
|
|
503737
504331
|
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
|
-
};
|
|
504332
|
+
return managed === void 0 ? {} : { [DEFAULT_OAUTH_PROVIDER_NAME]: managed };
|
|
503743
504333
|
}
|
|
503744
504334
|
var AuthFlowController = class {
|
|
503745
504335
|
host;
|
|
@@ -518668,6 +519258,10 @@ var BlunTUI = class {
|
|
|
518668
519258
|
const sessionId = session.id;
|
|
518669
519259
|
const autostartPrompt = autostart.observation === void 0 ? GOAL_CONTINUATION_PROMPT : `${GOAL_CONTINUATION_PROMPT}\n\n${autostart.observation}`;
|
|
518670
519260
|
this.beginSessionRequest();
|
|
519261
|
+
this.setAppState({
|
|
519262
|
+
model: BLUN_KING_MODEL_ALIAS,
|
|
519263
|
+
modelFallbackAllowed: false
|
|
519264
|
+
});
|
|
518671
519265
|
try {
|
|
518672
519266
|
const result = await session.promptAccepted(autostartPrompt);
|
|
518673
519267
|
if (!result.accepted && this.session?.id === sessionId) {
|
|
@@ -519704,6 +520298,10 @@ var BlunTUI = class {
|
|
|
519704
520298
|
contextOnly: false
|
|
519705
520299
|
};
|
|
519706
520300
|
this.pendingChannelReplyGuard = installedGuard;
|
|
520301
|
+
this.setAppState({
|
|
520302
|
+
model: BLUN_KING_MODEL_ALIAS,
|
|
520303
|
+
modelFallbackAllowed: false
|
|
520304
|
+
});
|
|
519707
520305
|
session.promptAccepted(options?.parts ?? input).then((result) => {
|
|
519708
520306
|
if (result.duplicate === true) {
|
|
519709
520307
|
this.traceTelegramDelivery?.({ stage: "committed", ...context.item.channelDeliveryTrace, route: "channel_command_prompt", reason: "duplicate" });
|
|
@@ -519767,6 +520365,10 @@ var BlunTUI = class {
|
|
|
519767
520365
|
type: "text",
|
|
519768
520366
|
text: focusedModelInput
|
|
519769
520367
|
}, imagePart] : focusedModelInput;
|
|
520368
|
+
this.setAppState({
|
|
520369
|
+
model: BLUN_KING_MODEL_ALIAS,
|
|
520370
|
+
modelFallbackAllowed: false
|
|
520371
|
+
});
|
|
519770
520372
|
session.promptAccepted(promptInput, channelPromptOrigin(channelReportSources)).then((result) => {
|
|
519771
520373
|
if (result.duplicate === true) {
|
|
519772
520374
|
this.traceTelegramDelivery?.({ stage: "committed", ...channelDeliveryTrace, route: "prompt", reason: "duplicate" });
|
|
@@ -519961,6 +520563,10 @@ var BlunTUI = class {
|
|
|
519961
520563
|
return;
|
|
519962
520564
|
}
|
|
519963
520565
|
this.beginSessionRequest();
|
|
520566
|
+
this.setAppState({
|
|
520567
|
+
model: BLUN_KING_MODEL_ALIAS,
|
|
520568
|
+
modelFallbackAllowed: false
|
|
520569
|
+
});
|
|
519964
520570
|
session.promptAccepted(TRUNCATED_REPLY_CONTINUATION_PROMPT).then((result) => {
|
|
519965
520571
|
if (!result.accepted) this.failTruncatedChannelReplyRecovery(new Error("continuation prompt rejected"));
|
|
519966
520572
|
}).catch((error) => {
|
|
@@ -520231,6 +520837,10 @@ var BlunTUI = class {
|
|
|
520231
520837
|
});
|
|
520232
520838
|
this.beginSessionRequest();
|
|
520233
520839
|
const sdkInput = options?.parts ?? input;
|
|
520840
|
+
this.setAppState({
|
|
520841
|
+
model: BLUN_KING_MODEL_ALIAS,
|
|
520842
|
+
modelFallbackAllowed: false
|
|
520843
|
+
});
|
|
520234
520844
|
session.promptAccepted(sdkInput).catch((error) => {
|
|
520235
520845
|
finishPersonalMemoryRememberIntentTurn(session.id);
|
|
520236
520846
|
const message = formatErrorMessage$2(error);
|
|
@@ -520345,19 +520955,18 @@ var BlunTUI = class {
|
|
|
520345
520955
|
}
|
|
520346
520956
|
}
|
|
520347
520957
|
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
520958
|
let effectivePatch = {
|
|
520352
520959
|
...patch,
|
|
520353
520960
|
modelFallbackAllowed: false,
|
|
520354
|
-
..."model" in patch && patch.model?.trim().length ? { model:
|
|
520355
|
-
..."activeResponderModel" in patch && patch.activeResponderModel != null ? { activeResponderModel:
|
|
520961
|
+
..."model" in patch && patch.model?.trim().length ? { model: BLUN_KING_MODEL_ALIAS } : {},
|
|
520962
|
+
..."activeResponderModel" in patch && patch.activeResponderModel != null ? { activeResponderModel: BLUN_KING_MODEL_ALIAS } : {}
|
|
520356
520963
|
};
|
|
520357
520964
|
if ("availableModels" in patch || "managedAccountContextTokens" in patch) {
|
|
520358
|
-
|
|
520965
|
+
const managedAccountContextTokens = "managedAccountContextTokens" in patch ? patch.managedAccountContextTokens : this.state.appState.managedAccountContextTokens;
|
|
520966
|
+
const effectiveModels = applyManagedAccountContext(patch.availableModels ?? this.state.appState.availableModels, isValidManagedContextTokens(managedAccountContextTokens) ? managedAccountContextTokens : void 0);
|
|
520967
|
+
if (effectiveModels !== patch.availableModels) effectivePatch = {
|
|
520359
520968
|
...effectivePatch,
|
|
520360
|
-
availableModels
|
|
520969
|
+
availableModels: effectiveModels
|
|
520361
520970
|
};
|
|
520362
520971
|
}
|
|
520363
520972
|
if (!hasPatchChanges(this.state.appState, effectivePatch)) return;
|
|
@@ -520434,11 +521043,7 @@ var BlunTUI = class {
|
|
|
520434
521043
|
return this.harness.createSession(options);
|
|
520435
521044
|
}
|
|
520436
521045
|
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
|
-
}
|
|
521046
|
+
await session.setModel(BLUN_KING_MODEL_ALIAS, { allowFallback: false });
|
|
520442
521047
|
await this.personalMemoryController.clear(this.session);
|
|
520443
521048
|
const previous = this.unloadCurrentSession(approvalCancellationFeedback("switching_session"));
|
|
520444
521049
|
await this.managedQuotaWarningPersistence;
|
|
@@ -520446,7 +521051,10 @@ var BlunTUI = class {
|
|
|
520446
521051
|
resetChannelPreambleState(this.channelPreamble);
|
|
520447
521052
|
this.session = session;
|
|
520448
521053
|
this.managedQuotaWarningController.restore(session.id, managedQuotaWarningThresholdFromMetadata(session.getResumeState()?.sessionMetadata?.custom));
|
|
520449
|
-
this.setAppState({
|
|
521054
|
+
this.setAppState({
|
|
521055
|
+
model: BLUN_KING_MODEL_ALIAS,
|
|
521056
|
+
modelFallbackAllowed: false
|
|
521057
|
+
});
|
|
520450
521058
|
this.harness.setTelemetryContext({ sessionId: session.id });
|
|
520451
521059
|
this.registerSessionHandlers(session);
|
|
520452
521060
|
this.syncAdditionalDirs(session);
|
|
@@ -520458,7 +521066,7 @@ var BlunTUI = class {
|
|
|
520458
521066
|
const [status, goalResult, loopResult] = await Promise.all([session.getStatus(), session.getGoal(), session.getLoop()]);
|
|
520459
521067
|
this.setAppState({
|
|
520460
521068
|
sessionId: session.id,
|
|
520461
|
-
model:
|
|
521069
|
+
model: BLUN_KING_MODEL_ALIAS,
|
|
520462
521070
|
modelFallbackAllowed: false,
|
|
520463
521071
|
activeResponderModel: null,
|
|
520464
521072
|
thinkingEffort: status.thinkingEffort,
|
|
@@ -520678,6 +521286,7 @@ var BlunTUI = class {
|
|
|
520678
521286
|
this.approvalController.cancelAll(approvalCancellationFeedback("reloading_session"));
|
|
520679
521287
|
this.questionController.cancelAll("");
|
|
520680
521288
|
this.resetSessionRuntime();
|
|
521289
|
+
await session.setModel(BLUN_KING_MODEL_ALIAS, { allowFallback: false });
|
|
520681
521290
|
this.session = session;
|
|
520682
521291
|
this.harness.setTelemetryContext({ sessionId: session.id });
|
|
520683
521292
|
this.registerSessionHandlers(session);
|
|
@@ -520815,6 +521424,9 @@ var BlunTUI = class {
|
|
|
520815
521424
|
case "cancelled":
|
|
520816
521425
|
decision = uiText("approval.transcript.cancelled");
|
|
520817
521426
|
break;
|
|
521427
|
+
case "edited":
|
|
521428
|
+
decision = uiText("approval.transcript.edited");
|
|
521429
|
+
break;
|
|
520818
521430
|
}
|
|
520819
521431
|
const content = response.feedback !== void 0 && response.feedback.length > 0 ? uiText("approval.transcript.actionWithFeedback", {
|
|
520820
521432
|
decision,
|