blun-king-cli 9.1.526 → 9.1.536
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/CHANGELOG.md +67 -0
- package/LIESMICH.txt +36 -1
- package/README.md +35 -1
- package/bin/agent-resume-snapshot.cjs +31 -0
- package/bin/assistant-message-offload-policy.cjs +21 -2
- package/bin/codebase-search-runtime.cjs +23 -0
- package/bin/empty-response-retry-policy.cjs +29 -0
- package/bin/fredrik-glm-provider.cjs +256 -0
- package/bin/history-offload-pressure-policy.cjs +33 -0
- package/bin/programmatic-context-isolation.cjs +25 -0
- package/bin/programmatic-tool-runtime.mjs +301 -0
- package/bin/skill-activation-performance-policy.cjs +9 -0
- package/bin/structured-subagent-output.cjs +252 -0
- package/bin/telegram-direct-focus-policy.cjs +25 -1
- package/bin/todo-list-turn-policy.cjs +111 -1
- package/bin/tool-result-offload-policy.cjs +29 -0
- package/bin/turn-thinking-policy.cjs +6 -15
- package/bin/turn-tool-performance-policy.cjs +5 -4
- package/bin/user-message-offload-policy.cjs +10 -1
- package/blun.mjs +709 -127
- package/codebase-index/README.md +70 -0
- package/codebase-index/codebase_index.py +358 -0
- package/fredrik-glm-profile.toml.example +26 -0
- package/package.json +25 -3
- package/scripts/check-active-work-steer-regression.js +46 -0
- package/scripts/check-codebase-search-packaging-regression.js +92 -0
- package/scripts/check-copy-command-regression.js +74 -0
- package/scripts/check-current-turn-read-pin-mutation-regression.js +72 -0
- package/scripts/check-current-turn-read-pin-regression.js +94 -0
- package/scripts/check-deepseek-native-max-regression.js +49 -0
- package/scripts/check-empty-response-effort-downgrade-regression.js +48 -0
- package/scripts/check-fredrik-glm-mutation-regression.js +18 -0
- package/scripts/check-fredrik-glm-regression.js +169 -0
- package/scripts/check-history-pressure-offload-regression.js +77 -0
- package/scripts/check-programmatic-context-isolation-regression.js +193 -0
- package/scripts/check-programmatic-tool-regression.js +294 -0
- package/scripts/check-resume-replay-regression.js +2 -0
- package/scripts/check-startup-swarm-command-regression.js +24 -0
- package/scripts/check-structured-subagent-output-regression.js +331 -0
- package/scripts/check-telegram-direct-work-resume-regression.js +53 -0
- package/scripts/check-todo-progress-regression.js +416 -0
- package/scripts/check-tool-schema-capacity-regression.js +40 -0
- package/scripts/programmatic-tool-runtime.test.mjs +365 -0
- package/scripts/structured-subagent-output.test.cjs +170 -0
package/blun.mjs
CHANGED
|
@@ -16,6 +16,7 @@ import sessionScrollbackArchive from "./bin/session-scrollback-archive.cjs";
|
|
|
16
16
|
import sessionReplayWindowPolicy from "./bin/session-replay-window-policy.cjs";
|
|
17
17
|
import globPatternPolicy from "./bin/glob-pattern-policy.cjs";
|
|
18
18
|
import userHomePathPolicy from "./bin/user-home-path-policy.cjs";
|
|
19
|
+
import fredrikGlmProviderPolicy from "./bin/fredrik-glm-provider.cjs";
|
|
19
20
|
import crypto$1, { createHash, randomBytes, randomInt, randomUUID, timingSafeEqual } from "node:crypto";
|
|
20
21
|
import * as fs$16 from "node:fs";
|
|
21
22
|
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";
|
|
@@ -56,6 +57,18 @@ const { SessionScrollbackArchive, sessionScrollbackArchiveDirectory } = sessionS
|
|
|
56
57
|
const { replayWindowStartIndex, resolveReplayActiveTurnCount } = sessionReplayWindowPolicy;
|
|
57
58
|
const { globPatternError } = globPatternPolicy;
|
|
58
59
|
const { unsupportedUserHomePathError } = userHomePathPolicy;
|
|
60
|
+
const {
|
|
61
|
+
PROVIDER_ID: FREDRIK_GLM_PROVIDER_ID,
|
|
62
|
+
PROVIDER_TYPE: FREDRIK_GLM_PROVIDER_TYPE,
|
|
63
|
+
MODEL_EFFORTS: FREDRIK_GLM_EFFORTS,
|
|
64
|
+
configuredModels: configuredFredrikGlmModels,
|
|
65
|
+
configuredProvider: configuredFredrikGlmProvider,
|
|
66
|
+
isAllowedRuntimeAlias: isAllowedFredrikRuntimeAlias,
|
|
67
|
+
isConfiguredAlias: isConfiguredFredrikGlmAlias,
|
|
68
|
+
normalizeEffort: normalizeFredrikGlmEffort,
|
|
69
|
+
requestControls: fredrikGlmRequestControls,
|
|
70
|
+
readApiKeyFile: readFredrikGlmApiKeyFile
|
|
71
|
+
} = fredrikGlmProviderPolicy;
|
|
59
72
|
import { EventEmitter as EventEmitter$1 } from "node:events";
|
|
60
73
|
import { StringDecoder } from "node:string_decoder";
|
|
61
74
|
import co from "node:assert";
|
|
@@ -2720,6 +2733,7 @@ var init_blun = __esmMin((() => {
|
|
|
2720
2733
|
_defaultHeaders;
|
|
2721
2734
|
_generationKwargs;
|
|
2722
2735
|
_supportEfforts;
|
|
2736
|
+
_openAICompatible;
|
|
2723
2737
|
_client;
|
|
2724
2738
|
_clientFactory;
|
|
2725
2739
|
_files;
|
|
@@ -2733,6 +2747,7 @@ var init_blun = __esmMin((() => {
|
|
|
2733
2747
|
this._stream = options.stream ?? true;
|
|
2734
2748
|
this._generationKwargs = { ...options.generationKwargs };
|
|
2735
2749
|
this._supportEfforts = options.supportEfforts ?? [];
|
|
2750
|
+
this._openAICompatible = options.openAICompatible === true;
|
|
2736
2751
|
this._client = this._apiKey === void 0 ? void 0 : createFetchHttpClient({
|
|
2737
2752
|
apiKey: this._apiKey,
|
|
2738
2753
|
baseUrl: this._baseUrl,
|
|
@@ -2844,8 +2859,17 @@ var init_blun = __esmMin((() => {
|
|
|
2844
2859
|
delete requestExtraBody["model"];
|
|
2845
2860
|
delete requestExtraBody["messages"];
|
|
2846
2861
|
if (!thinkingDisabled && thinking?.keep !== void 0) requestExtraBody["thinking"] = { keep: thinking.keep };
|
|
2847
|
-
|
|
2848
|
-
|
|
2862
|
+
let reasoningRequested;
|
|
2863
|
+
if (this._openAICompatible) {
|
|
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
|
+
}
|
|
2849
2873
|
const createParams = {
|
|
2850
2874
|
model: this._model,
|
|
2851
2875
|
messages,
|
|
@@ -9989,7 +10013,7 @@ var init_schema = __esmMin((() => {
|
|
|
9989
10013
|
init_matches_rule();
|
|
9990
10014
|
init_errors$8();
|
|
9991
10015
|
init_zod$1();
|
|
9992
|
-
ProviderTypeSchema = literal("blun");
|
|
10016
|
+
ProviderTypeSchema = union([literal("blun"), literal("openai_compatible")]);
|
|
9993
10017
|
OAuthRefSchema = object({
|
|
9994
10018
|
storage: _enum(["file", "keyring"]),
|
|
9995
10019
|
key: string().min(1),
|
|
@@ -9999,6 +10023,7 @@ var init_schema = __esmMin((() => {
|
|
|
9999
10023
|
ProviderConfigSchema = object({
|
|
10000
10024
|
type: ProviderTypeSchema,
|
|
10001
10025
|
apiKey: string().optional(),
|
|
10026
|
+
apiKeyFile: string().optional(),
|
|
10002
10027
|
baseUrl: string().optional(),
|
|
10003
10028
|
defaultModel: string().optional(),
|
|
10004
10029
|
oauth: OAuthRefSchema.optional(),
|
|
@@ -28546,6 +28571,7 @@ var init_agent$3 = __esmMin((() => {
|
|
|
28546
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";
|
|
28547
28572
|
agent_default$1 = agent_default$1.replace(" - Read\n", " - Read\n - ReadBatch\n");
|
|
28548
28573
|
agent_default$1 = agent_default$1.replace(" - TodoList\n", " - TodoList\n - CompactConversation\n");
|
|
28574
|
+
agent_default$1 = agent_default$1.replace(" - CodebaseSearch\n", " - CodebaseSearch\n - ProgrammaticTool\n");
|
|
28549
28575
|
}));
|
|
28550
28576
|
//#endregion
|
|
28551
28577
|
//#region ../../packages/agent-core/src/profile/default/coder.yaml?raw
|
|
@@ -28553,6 +28579,7 @@ var coder_default;
|
|
|
28553
28579
|
var init_coder = __esmMin((() => {
|
|
28554
28580
|
coder_default = "extends: agent\nname: coder\npromptVars:\n roleAdditional: |\n You are now running as a subagent. All the `user` messages are sent by the main agent. The main agent cannot see your context, it can only see your last message when you finish the task. You must treat the parent agent as your caller. Do not directly ask the end user questions. If something is unclear, explain the ambiguity in your final summary to the parent agent.\n\n Your final message is the entire handoff — the parent sees nothing else from your run. Make it technically complete: what you changed and why, the path of every file you touched, how you verified the change (tests or commands run, with results), and anything left undone or worth follow-up. A final message of only a sentence or two is treated as too brief and sent back to you for expansion, costing an extra turn.\nwhenToUse: |\n Use this agent for non-trivial software engineering work that may require reading files, editing code, running commands, and returning a compact but technically complete summary to the parent agent.\ntools:\n - Bash\n - Read\n - ReadMediaFile\n - Glob\n - Grep\n - Write\n - Edit\n - MistakeRecord\n - WebSearch\n - FetchURL\n - mcp__*\n";
|
|
28555
28581
|
coder_default = coder_default.replace(" - Read\n", " - Read\n - ReadBatch\n");
|
|
28582
|
+
coder_default = coder_default.replace(" - ReadBatch\n", " - ReadBatch\n - ProgrammaticTool\n");
|
|
28556
28583
|
}));
|
|
28557
28584
|
//#endregion
|
|
28558
28585
|
//#region ../../packages/agent-core/src/profile/default/explore.yaml?raw
|
|
@@ -28560,6 +28587,7 @@ var explore_default;
|
|
|
28560
28587
|
var init_explore = __esmMin((() => {
|
|
28561
28588
|
explore_default = "extends: agent\nname: explore\npromptVars:\n roleAdditional: |\n You are now running as a subagent. All the `user` messages are sent by the main agent. The main agent cannot see your context, it can only see your last message when you finish the task. You must treat the parent agent as your caller. Do not directly ask the end user questions. If something is unclear, explain the ambiguity in your final summary to the parent agent.\n\n You are a codebase exploration specialist. Your role is EXCLUSIVELY to search, read, and analyze existing code and resources. You do NOT have access to project file editing tools. MistakeRecord is the sole write-capable exception: it may record a concrete refutation in shared BLUN learning memory, never modify project files.\n\n Your strengths:\n - Rapidly finding files using glob patterns\n - Searching code and text with powerful regex patterns\n - Reading and analyzing file contents\n - Running read-only shell commands (git log, git diff, ls, find, etc.)\n\n Guidelines:\n - Use Glob for broad file pattern matching. Prefer patterns with a literal anchor (extension or subdirectory); pure wildcards like `*` or `**/*` are allowed but usually truncate at the match cap.\n - Use Grep for searching file contents with regex\n - Use Read when you know the specific file path\n - Use Bash ONLY for read-only operations (ls, git status, git log, git diff, find)\n - NEVER use Bash for any file creation or modification commands\n - Use WebSearch or FetchURL when a question needs external context (library documentation, error messages, upstream APIs); the local codebase remains your primary domain\n - Adapt your search depth based on the thoroughness level specified by the caller\n - Wherever possible, spawn multiple parallel tool calls for grepping and reading files to maximize speed\n\n If the prompt includes a <git-context> block, use it to orient yourself about the repository state before starting your investigation.\n\n You are meant to be a fast agent. Complete the search request efficiently and report your findings clearly in a structured format.\nwhenToUse: |\n Fast agent specialized for exploring codebases. Use this when you need to quickly find files by patterns (e.g. \"src/**/*.yaml\"), search code for keywords (e.g. \"database connection\"), or answer questions about the codebase (e.g. \"how does the auth module work?\"). When calling this agent, specify the desired thoroughness level: \"quick\" for basic searches, \"medium\" for moderate exploration, or \"thorough\" for comprehensive analysis across multiple locations and naming conventions. Use this agent for any read-only exploration that will clearly require more than 3 search queries. Prefer launching multiple explore agents concurrently when investigating independent questions.\ntools:\n - Bash\n - Read\n - ReadMediaFile\n - Glob\n - Grep\n - MistakeRecord\n - WebSearch\n - FetchURL\n";
|
|
28562
28589
|
explore_default = explore_default.replace(" - Read\n", " - Read\n - ReadBatch\n");
|
|
28590
|
+
explore_default = explore_default.replace(" - ReadBatch\n", " - ReadBatch\n - ProgrammaticTool\n");
|
|
28563
28591
|
}));
|
|
28564
28592
|
//#endregion
|
|
28565
28593
|
//#region ../../packages/agent-core/src/profile/default/init.md?raw
|
|
@@ -28573,6 +28601,7 @@ var plan_default;
|
|
|
28573
28601
|
var init_plan$1 = __esmMin((() => {
|
|
28574
28602
|
plan_default = "extends: agent\nname: plan\npromptVars:\n roleAdditional: |\n You are now running as a subagent. All the `user` messages are sent by the main agent. The main agent cannot see your context, it can only see your last message when you finish the task. You must treat the parent agent as your caller. Do not directly ask the end user questions. If something is unclear, explain the ambiguity in your final summary to the parent agent.\n\n Before designing your implementation plan, consider whether you fully understand the codebase areas relevant to the task. If not, recommend the parent agent to use the explore agent (subagent_type=\"explore\") to investigate key questions first. In your response, clearly state:\n 1. What you already know from the information provided\n 2. What questions remain unanswered that would benefit from explore agent investigation\n 3. Your implementation plan (either preliminary if questions remain, or final if sufficient context exists)\n\n You are a read-only planning agent: you can read and search files (Read, Glob, Grep, ReadMediaFile) and consult the web (WebSearch, FetchURL), but you have no shell and no project file-editing tools. MistakeRecord is the sole write-capable exception: it may record a concrete refutation in shared BLUN learning memory, never modify project files. Where the general instructions tell you to make changes with tools, that does not apply to you — do not attempt to run commands or modify project files. Your deliverable is the plan itself, returned as your final message.\nwhenToUse: |\n Use this agent when the parent agent needs a step-by-step implementation plan, key file identification, and architectural trade-off analysis before code changes are made.\ntools:\n - Read\n - ReadMediaFile\n - Glob\n - Grep\n - MistakeRecord\n - WebSearch\n - FetchURL\n";
|
|
28575
28603
|
plan_default = plan_default.replace(" - Read\n", " - Read\n - ReadBatch\n");
|
|
28604
|
+
plan_default = plan_default.replace(" - ReadBatch\n", " - ReadBatch\n - ProgrammaticTool\n");
|
|
28576
28605
|
}));
|
|
28577
28606
|
//#endregion
|
|
28578
28607
|
//#region ../../packages/agent-core/src/profile/default/system.md?raw
|
|
@@ -29102,6 +29131,7 @@ var init_agent_task = __esmMin((() => {
|
|
|
29102
29131
|
continuationTimeoutMs;
|
|
29103
29132
|
runInBackground;
|
|
29104
29133
|
parentToolCallId;
|
|
29134
|
+
responseFormat;
|
|
29105
29135
|
kind = "agent";
|
|
29106
29136
|
idPrefix = "agent";
|
|
29107
29137
|
agentId;
|
|
@@ -29114,6 +29144,7 @@ var init_agent_task = __esmMin((() => {
|
|
|
29114
29144
|
this.continuationTimeoutMs = options.timeoutMs;
|
|
29115
29145
|
this.runInBackground = options.runInBackground;
|
|
29116
29146
|
this.parentToolCallId = options.parentToolCallId;
|
|
29147
|
+
this.responseFormat = options.responseFormat;
|
|
29117
29148
|
this.agentId = handle.agentId;
|
|
29118
29149
|
this.subagentType = handle.profileName;
|
|
29119
29150
|
}
|
|
@@ -29133,6 +29164,7 @@ var init_agent_task = __esmMin((() => {
|
|
|
29133
29164
|
prompt: continuation.kind === "transient_provider" ? "Continue from the preserved context after a transient provider interruption. Do not repeat completed work; inspect the preserved wire and continue from the last durable boundary." : "Continue from the preserved context after the wall-clock interval.",
|
|
29134
29165
|
description: this.description,
|
|
29135
29166
|
runInBackground: this.runInBackground,
|
|
29167
|
+
responseFormat: this.responseFormat,
|
|
29136
29168
|
signal: this.abortController.signal
|
|
29137
29169
|
});
|
|
29138
29170
|
return this.handle;
|
|
@@ -30334,6 +30366,7 @@ var init_completion_budget = __esmMin((() => {
|
|
|
30334
30366
|
}));
|
|
30335
30367
|
//#endregion
|
|
30336
30368
|
//#region ../../packages/agent-core/src/loop/retry.ts
|
|
30369
|
+
var { nextThinkingEffortForExhaustedEmpty } = createRequire(import.meta.url)("./bin/empty-response-retry-policy.cjs");
|
|
30337
30370
|
async function chatWithRetry(input) {
|
|
30338
30371
|
const maxAttempts = input.maxAttempts ?? 3;
|
|
30339
30372
|
if (input.llm.isRetryableError === void 0 || maxAttempts <= 1) {
|
|
@@ -30347,9 +30380,10 @@ async function chatWithRetry(input) {
|
|
|
30347
30380
|
}
|
|
30348
30381
|
const delays = retryBackoffDelays(maxAttempts);
|
|
30349
30382
|
let completionBudgetRetry;
|
|
30383
|
+
let thinkingEffortRetry;
|
|
30350
30384
|
let emptyRetryKind;
|
|
30351
30385
|
for (let attempt = 1;; attempt += 1) try {
|
|
30352
|
-
return await input.llm.chat(paramsForAttempt(input, attempt, maxAttempts, completionBudgetRetry));
|
|
30386
|
+
return await input.llm.chat(paramsForAttempt(input, attempt, maxAttempts, completionBudgetRetry, thinkingEffortRetry));
|
|
30353
30387
|
} catch (error) {
|
|
30354
30388
|
if (error instanceof APIEmptyResponseError && (emptyRetryKind !== void 0 || error.emptyResponseKind === "length" || error.emptyResponseKind === "stop")) {
|
|
30355
30389
|
logEmptyResponse(input, error, attempt);
|
|
@@ -30359,6 +30393,12 @@ async function chatWithRetry(input) {
|
|
|
30359
30393
|
throw terminal;
|
|
30360
30394
|
}
|
|
30361
30395
|
completionBudgetRetry = completionBudgetRetryForEmpty(error);
|
|
30396
|
+
thinkingEffortRetry = nextThinkingEffortForExhaustedEmpty({
|
|
30397
|
+
emptyResponseKind: error.emptyResponseKind,
|
|
30398
|
+
maxCompletionTokens: error.maxCompletionTokens,
|
|
30399
|
+
completionTokens: error.completionTokens,
|
|
30400
|
+
thinkingEffort: input.llm.thinkingEffort
|
|
30401
|
+
});
|
|
30362
30402
|
emptyRetryKind = error.emptyResponseKind;
|
|
30363
30403
|
input.params.signal.throwIfAborted();
|
|
30364
30404
|
input.dispatchEvent({
|
|
@@ -30415,11 +30455,12 @@ function logRequestFailure(input, error, attempt, maxAttempts) {
|
|
|
30415
30455
|
...retryErrorFields(error)
|
|
30416
30456
|
});
|
|
30417
30457
|
}
|
|
30418
|
-
function paramsForAttempt(input, attempt, maxAttempts, completionBudgetRetry) {
|
|
30458
|
+
function paramsForAttempt(input, attempt, maxAttempts, completionBudgetRetry, thinkingEffortRetry) {
|
|
30419
30459
|
const turnStep = `${input.turnId}.${String(input.currentStep)}`;
|
|
30420
30460
|
return {
|
|
30421
30461
|
...input.params,
|
|
30422
30462
|
completionBudgetRetry,
|
|
30463
|
+
thinkingEffortRetry,
|
|
30423
30464
|
requestLogFields: attempt === 1 ? { turnStep } : {
|
|
30424
30465
|
turnStep,
|
|
30425
30466
|
attempt: `${String(attempt)}/${String(maxAttempts)}`
|
|
@@ -30427,12 +30468,19 @@ function paramsForAttempt(input, attempt, maxAttempts, completionBudgetRetry) {
|
|
|
30427
30468
|
};
|
|
30428
30469
|
}
|
|
30429
30470
|
function logEmptyResponse(input, error, attempt) {
|
|
30471
|
+
const retryThinkingEffort = nextThinkingEffortForExhaustedEmpty({
|
|
30472
|
+
emptyResponseKind: error.emptyResponseKind,
|
|
30473
|
+
maxCompletionTokens: error.maxCompletionTokens,
|
|
30474
|
+
completionTokens: error.completionTokens,
|
|
30475
|
+
thinkingEffort: input.llm.thinkingEffort
|
|
30476
|
+
});
|
|
30430
30477
|
input.log?.warn(`[leer] fall=${error.emptyResponseKind}`, {
|
|
30431
30478
|
turnStep: `${input.turnId}.${String(input.currentStep)}`,
|
|
30432
30479
|
attempt,
|
|
30433
30480
|
budget: error.maxCompletionTokens,
|
|
30434
30481
|
completion: error.completionTokens,
|
|
30435
|
-
reasoningLength: error.reasoningLength
|
|
30482
|
+
reasoningLength: error.reasoningLength,
|
|
30483
|
+
...retryThinkingEffort === void 0 ? {} : { retryThinkingEffort }
|
|
30436
30484
|
});
|
|
30437
30485
|
}
|
|
30438
30486
|
function retryBackoffDelays(maxAttempts) {
|
|
@@ -30599,6 +30647,96 @@ var init_todo_list = __esmMin((() => {
|
|
|
30599
30647
|
};
|
|
30600
30648
|
}));
|
|
30601
30649
|
//#endregion
|
|
30650
|
+
//#region ../../packages/agent-core/src/tools/builtin/state/programmatic-tool.ts
|
|
30651
|
+
var PROGRAMMATIC_TOOL_NAME, ProgrammaticTool;
|
|
30652
|
+
var init_programmatic_tool = __esmMin((() => {
|
|
30653
|
+
PROGRAMMATIC_TOOL_NAME = "ProgrammaticTool";
|
|
30654
|
+
ProgrammaticTool = class {
|
|
30655
|
+
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.";
|
|
30657
|
+
parameters = {
|
|
30658
|
+
type: "object",
|
|
30659
|
+
properties: {
|
|
30660
|
+
code: {
|
|
30661
|
+
type: "string",
|
|
30662
|
+
maxLength: 32e3,
|
|
30663
|
+
description: "JavaScript function body. Use state for explicit JSON state and tools.<alias>(args) for declared sequential tool calls."
|
|
30664
|
+
},
|
|
30665
|
+
state: {
|
|
30666
|
+
type: "object",
|
|
30667
|
+
description: "Optional JSON-only state snapshot from a previous run."
|
|
30668
|
+
},
|
|
30669
|
+
tools: {
|
|
30670
|
+
type: "array",
|
|
30671
|
+
maxItems: 16,
|
|
30672
|
+
description: "Explicit allowlist for this program. Each name must be a tool available in the current turn.",
|
|
30673
|
+
items: {
|
|
30674
|
+
type: "object",
|
|
30675
|
+
properties: {
|
|
30676
|
+
name: {
|
|
30677
|
+
type: "string",
|
|
30678
|
+
minLength: 1,
|
|
30679
|
+
description: "Exact current BLUN tool name."
|
|
30680
|
+
},
|
|
30681
|
+
alias: {
|
|
30682
|
+
type: "string",
|
|
30683
|
+
pattern: "^[A-Za-z_$][A-Za-z0-9_$]*$",
|
|
30684
|
+
description: "JavaScript identifier exposed under tools."
|
|
30685
|
+
}
|
|
30686
|
+
},
|
|
30687
|
+
required: ["name", "alias"],
|
|
30688
|
+
additionalProperties: false
|
|
30689
|
+
}
|
|
30690
|
+
}
|
|
30691
|
+
},
|
|
30692
|
+
required: ["code"],
|
|
30693
|
+
additionalProperties: false
|
|
30694
|
+
};
|
|
30695
|
+
resolveExecution(args) {
|
|
30696
|
+
const declaredTools = Array.isArray(args.tools) ? args.tools : [];
|
|
30697
|
+
return {
|
|
30698
|
+
description: `Running bounded programmatic tool plan (${declaredTools.length} allowed tool${declaredTools.length === 1 ? "" : "s"})`,
|
|
30699
|
+
approvalRule: this.name,
|
|
30700
|
+
execute: async (context) => {
|
|
30701
|
+
if (typeof context.invokeTool !== "function") return {
|
|
30702
|
+
output: "Programmatic tool invocation boundary is unavailable.",
|
|
30703
|
+
isError: true
|
|
30704
|
+
};
|
|
30705
|
+
try {
|
|
30706
|
+
const { createProgrammaticToolRuntime } = await import(new URL("./bin/programmatic-tool-runtime.mjs", import.meta.url).href);
|
|
30707
|
+
const runtime = createProgrammaticToolRuntime({
|
|
30708
|
+
allowedTools: declaredTools,
|
|
30709
|
+
invokeTool: context.invokeTool,
|
|
30710
|
+
onEvent: (event) => context.onUpdate({
|
|
30711
|
+
kind: "programmatic_tool",
|
|
30712
|
+
event
|
|
30713
|
+
})
|
|
30714
|
+
});
|
|
30715
|
+
const outcome = await runtime.run({
|
|
30716
|
+
code: args.code,
|
|
30717
|
+
state: args.state ?? {},
|
|
30718
|
+
signal: context.signal
|
|
30719
|
+
});
|
|
30720
|
+
const result = {
|
|
30721
|
+
output: JSON.stringify(outcome),
|
|
30722
|
+
isError: false
|
|
30723
|
+
};
|
|
30724
|
+
if (context.invokeTool.stopTurn === true) result.stopTurn = true;
|
|
30725
|
+
return result;
|
|
30726
|
+
} catch (error) {
|
|
30727
|
+
const result = {
|
|
30728
|
+
output: error instanceof Error ? error.message : String(error),
|
|
30729
|
+
isError: true
|
|
30730
|
+
};
|
|
30731
|
+
if (context.invokeTool.stopTurn === true) result.stopTurn = true;
|
|
30732
|
+
return result;
|
|
30733
|
+
}
|
|
30734
|
+
}
|
|
30735
|
+
};
|
|
30736
|
+
}
|
|
30737
|
+
};
|
|
30738
|
+
}));
|
|
30739
|
+
//#endregion
|
|
30602
30740
|
//#region ../../packages/agent-core/src/tools/support/file-type.ts
|
|
30603
30741
|
function toBuffer$2(data) {
|
|
30604
30742
|
return Buffer.isBuffer(data) ? data : Buffer.from(data.buffer, data.byteOffset, data.byteLength);
|
|
@@ -74747,6 +74885,9 @@ var init_kosong_llm = __esmMin((() => {
|
|
|
74747
74885
|
this.visionReader = config.visionReader;
|
|
74748
74886
|
this.onVisionUsage = config.onVisionUsage;
|
|
74749
74887
|
}
|
|
74888
|
+
get thinkingEffort() {
|
|
74889
|
+
return this.provider.thinkingEffort;
|
|
74890
|
+
}
|
|
74750
74891
|
notifyMediaDropped(dropped) {
|
|
74751
74892
|
if (this.onMediaDropped === void 0) return;
|
|
74752
74893
|
const fresh = dropped.filter((part) => {
|
|
@@ -74789,6 +74930,7 @@ var init_kosong_llm = __esmMin((() => {
|
|
|
74789
74930
|
let result;
|
|
74790
74931
|
let completionBudget;
|
|
74791
74932
|
try {
|
|
74933
|
+
const requestProvider = params.thinkingEffortRetry === void 0 ? this.provider : this.provider.withThinking(params.thinkingEffortRetry);
|
|
74792
74934
|
const enrichedMessages = this.visionReader === void 0 ? params.messages : await enrichMessagesWithVision(params.messages, this.visionReader, params.signal, this.onVisionUsage);
|
|
74793
74935
|
const tools = [...params.tools];
|
|
74794
74936
|
const outgoingMessages = downgradeUnsupportedMedia(enrichedMessages, this.capability, (dropped) => {
|
|
@@ -74798,11 +74940,11 @@ var init_kosong_llm = __esmMin((() => {
|
|
|
74798
74940
|
const reportedContextTokens = this.reportedContextTokens?.() ?? 0;
|
|
74799
74941
|
const usedContextTokens = Math.max(outgoingRequestTokens, reportedContextTokens);
|
|
74800
74942
|
completionBudget = applyCompletionBudgetWithDetails({
|
|
74801
|
-
provider:
|
|
74943
|
+
provider: requestProvider,
|
|
74802
74944
|
budget: this.completionBudgetConfig,
|
|
74803
74945
|
capability: this.capability,
|
|
74804
74946
|
usedContextTokens,
|
|
74805
|
-
retry: params.completionBudgetRetry ?? (thinkingEnabled(
|
|
74947
|
+
retry: params.completionBudgetRetry ?? (thinkingEnabled(requestProvider.thinkingEffort) ? {
|
|
74806
74948
|
minimumCompletionTokens: 1024,
|
|
74807
74949
|
multiplier: 1
|
|
74808
74950
|
} : void 0)
|
|
@@ -76041,8 +76183,9 @@ var init_full = __esmMin((() => {
|
|
|
76041
76183
|
}));
|
|
76042
76184
|
//#endregion
|
|
76043
76185
|
//#region ../../packages/agent-core/src/agent/compaction/micro.ts
|
|
76044
|
-
var selectMicroCompactionCutoff, MICRO_COMPACTION_RECENT_MESSAGES, MICRO_COMPACTION_TOOL_ARGUMENTS_ENABLED, MICRO_COMPACTION_TOOL_ARGUMENT_MIN_TOKENS, isPersistedToolResultReference, freshToolResultIds, projectHistoricalUnaddressedTelegramMessages, dedupeRepeatedUserMessages, projectRepeatedAssistantResponses, compactHistoricalSkillActivations, dedupeRecurringCronWakeups, dedupeRepeatedInjections, projectLoopEventForRecord, projectUsageModelForRecord, projectUsageForRecord, resolveCompletedStepUuid, resolveStepEventUuid, restoreUsageFromRecord, restoreUsageModelFromRecord, DEFAULT_CONFIG, MicroCompaction;
|
|
76186
|
+
var selectMicroCompactionCutoff, MICRO_COMPACTION_RECENT_MESSAGES, MICRO_COMPACTION_TOOL_ARGUMENTS_ENABLED, MICRO_COMPACTION_TOOL_ARGUMENT_MIN_TOKENS, isPersistedToolResultReference, freshToolResultIds, projectHistoricalUnaddressedTelegramMessages, dedupeRepeatedUserMessages, projectRepeatedAssistantResponses, compactHistoricalSkillActivations, dedupeRecurringCronWakeups, dedupeRepeatedInjections, projectLoopEventForRecord, projectUsageModelForRecord, projectUsageForRecord, resolveCompletedStepUuid, resolveStepEventUuid, restoreUsageFromRecord, restoreUsageModelFromRecord, isWireOnlyProgrammaticEvent, DEFAULT_CONFIG, MicroCompaction;
|
|
76045
76187
|
var init_micro = __esmMin((() => {
|
|
76188
|
+
({ isWireOnlyProgrammaticEvent } = createRequire(import.meta.url)("./bin/programmatic-context-isolation.cjs"));
|
|
76046
76189
|
({ selectMicroCompactionCutoff, MICRO_COMPACTION_RECENT_MESSAGES, MICRO_COMPACTION_TOOL_ARGUMENTS_ENABLED, MICRO_COMPACTION_TOOL_ARGUMENT_MIN_TOKENS } = createRequire(import.meta.url)("./bin/micro-compaction-policy.cjs"));
|
|
76047
76190
|
({ isPersistedToolResultReference, freshToolResultIds } = createRequire(import.meta.url)("./bin/tool-result-offload-policy.cjs"));
|
|
76048
76191
|
({ projectHistoricalUnaddressedTelegramMessages } = createRequire(import.meta.url)("./bin/telegram-context-projection-policy.cjs"));
|
|
@@ -79191,6 +79334,7 @@ var init_context$2 = __esmMin((() => {
|
|
|
79191
79334
|
type: "context.append_loop_event",
|
|
79192
79335
|
event: projectLoopEventForRecord(event)
|
|
79193
79336
|
});
|
|
79337
|
+
if (isWireOnlyProgrammaticEvent(event)) return;
|
|
79194
79338
|
switch (event.type) {
|
|
79195
79339
|
case "step.begin": {
|
|
79196
79340
|
const closed = this.closePendingToolResults();
|
|
@@ -233363,6 +233507,7 @@ var init_default_tool_approve = __esmMin((() => {
|
|
|
233363
233507
|
"Agent",
|
|
233364
233508
|
"AskUserQuestion",
|
|
233365
233509
|
"Skill",
|
|
233510
|
+
"ProgrammaticTool",
|
|
233366
233511
|
"GetGoal",
|
|
233367
233512
|
"SetGoalBudget",
|
|
233368
233513
|
"UpdateGoal"
|
|
@@ -244071,6 +244216,49 @@ async function runToolCallBatch(step, response) {
|
|
|
244071
244216
|
}
|
|
244072
244217
|
return { stopTurn };
|
|
244073
244218
|
}
|
|
244219
|
+
function createNestedToolInvoker(step, parentToolCall) {
|
|
244220
|
+
let nestedSequence = 0;
|
|
244221
|
+
const invoke = async ({ name, args, callId, signal }) => {
|
|
244222
|
+
if (invoke.stopTurn === true) throw new Error("No nested tool calls are allowed after a turn-stop result.");
|
|
244223
|
+
if (name === PROGRAMMATIC_TOOL_NAME) throw new Error("Nested ProgrammaticTool calls are not allowed.");
|
|
244224
|
+
const nestedSignal = signal ?? step.signal;
|
|
244225
|
+
nestedSignal.throwIfAborted();
|
|
244226
|
+
nestedSequence += 1;
|
|
244227
|
+
const safeCallId = typeof callId === "string" && callId.length > 0 ? callId : `call_${nestedSequence}`;
|
|
244228
|
+
const nestedToolCall = {
|
|
244229
|
+
id: `${parentToolCall.id}:ptc:${safeCallId}`,
|
|
244230
|
+
name,
|
|
244231
|
+
arguments: JSON.stringify(args ?? {})
|
|
244232
|
+
};
|
|
244233
|
+
const nestedStep = {
|
|
244234
|
+
...step,
|
|
244235
|
+
signal: nestedSignal,
|
|
244236
|
+
toolCalls: [nestedToolCall],
|
|
244237
|
+
dispatchEvent: (event) => step.dispatchEvent(markProgrammaticNestedEvent(event))
|
|
244238
|
+
};
|
|
244239
|
+
const preflight = preflightToolCall(nestedStep, nestedToolCall);
|
|
244240
|
+
const prepared = await prepareToolCall(nestedStep, preflight);
|
|
244241
|
+
const started = await prepared.task.start();
|
|
244242
|
+
const pendingResult = await started.result;
|
|
244243
|
+
const finalized = await finalizePendingToolResult(nestedStep, pendingResult);
|
|
244244
|
+
if (finalized.stopTurn === true) invoke.stopTurn = true;
|
|
244245
|
+
await nestedStep.dispatchEvent({
|
|
244246
|
+
type: "tool.result",
|
|
244247
|
+
parentUuid: nestedToolCall.id,
|
|
244248
|
+
toolCallId: nestedToolCall.id,
|
|
244249
|
+
result: finalized.result
|
|
244250
|
+
});
|
|
244251
|
+
if (finalized.result.isError === true) throw new Error(nestedToolResultText(finalized.result));
|
|
244252
|
+
return finalized.result;
|
|
244253
|
+
};
|
|
244254
|
+
invoke.stopTurn = false;
|
|
244255
|
+
return invoke;
|
|
244256
|
+
}
|
|
244257
|
+
function nestedToolResultText(result) {
|
|
244258
|
+
if (typeof result.output === "string") return result.output;
|
|
244259
|
+
const text = result.output.filter((part) => part.type === "text").map((part) => part.text).join("");
|
|
244260
|
+
return text.length > 0 ? text : "Nested tool call failed.";
|
|
244261
|
+
}
|
|
244074
244262
|
/**
|
|
244075
244263
|
* Provider-order validation pass. It does not run hooks, spawn tools, or write
|
|
244076
244264
|
* events. Validator compilation may populate the local cache.
|
|
@@ -244326,11 +244514,13 @@ async function finalizePendingToolResult(step, pendingResult) {
|
|
|
244326
244514
|
async function executeTool(step, execution, toolCall, toolName, metadata) {
|
|
244327
244515
|
const { dispatchEvent, signal, turnId } = step;
|
|
244328
244516
|
signal.throwIfAborted();
|
|
244517
|
+
const invokeTool = toolName === PROGRAMMATIC_TOOL_NAME ? createNestedToolInvoker(step, toolCall) : void 0;
|
|
244329
244518
|
return raceExecuteWithGraceTimeout(execution.execute({
|
|
244330
244519
|
turnId,
|
|
244331
244520
|
toolCallId: toolCall.id,
|
|
244332
244521
|
metadata,
|
|
244333
244522
|
signal,
|
|
244523
|
+
invokeTool,
|
|
244334
244524
|
onUpdate: (update) => {
|
|
244335
244525
|
if (signal.aborted) return;
|
|
244336
244526
|
dispatchEvent({
|
|
@@ -244462,8 +244652,9 @@ async function dispatchToolCall(step, call, args, displayFields) {
|
|
|
244462
244652
|
display: displayFields?.display
|
|
244463
244653
|
});
|
|
244464
244654
|
}
|
|
244465
|
-
var GRACE_TIMEOUT_MS, TOOL_OUTPUT_EMPTY, TOOL_OUTPUT_NON_TEXT, validators;
|
|
244655
|
+
var markProgrammaticNestedEvent, GRACE_TIMEOUT_MS, TOOL_OUTPUT_EMPTY, TOOL_OUTPUT_NON_TEXT, validators;
|
|
244466
244656
|
var init_tool_call = __esmMin((() => {
|
|
244657
|
+
({ markProgrammaticNestedEvent } = createRequire(import.meta.url)("./bin/programmatic-context-isolation.cjs"));
|
|
244467
244658
|
init_args_validator();
|
|
244468
244659
|
init_path_access();
|
|
244469
244660
|
init_abort();
|
|
@@ -251417,6 +251608,7 @@ var init_task_output = __esmMin((() => {
|
|
|
251417
251608
|
init_zod$1();
|
|
251418
251609
|
init_background();
|
|
251419
251610
|
init_input_schema();
|
|
251611
|
+
init_args_validator();
|
|
251420
251612
|
init_rule_match();
|
|
251421
251613
|
init_format();
|
|
251422
251614
|
init_task_output$1();
|
|
@@ -252467,12 +252659,29 @@ function lastAssistantText(agent) {
|
|
|
252467
252659
|
}
|
|
252468
252660
|
return "";
|
|
252469
252661
|
}
|
|
252662
|
+
async function completeStructuredSubagentResult(child, childId, profileName, responseFormat, signal) {
|
|
252663
|
+
let validation = validateStructuredSubagentOutput(lastAssistantText(child), responseFormat);
|
|
252664
|
+
if (validation.validatorException === true) throw new Error(validation.error);
|
|
252665
|
+
if (!validation.ok) {
|
|
252666
|
+
signal.throwIfAborted();
|
|
252667
|
+
if (child.turn.prompt([{
|
|
252668
|
+
type: "text",
|
|
252669
|
+
text: buildStructuredResponseRepairPrompt(responseFormat, validation.error)
|
|
252670
|
+
}], SUBAGENT_PROMPT_ORIGIN) === null) throw new Error("Subagent could not start its structured-output repair turn.");
|
|
252671
|
+
await completeChildTurnWithMaxTokensHandoff(child, signal);
|
|
252672
|
+
signal.throwIfAborted();
|
|
252673
|
+
validation = validateStructuredSubagentOutput(lastAssistantText(child), responseFormat);
|
|
252674
|
+
if (validation.validatorException === true) throw new Error(validation.error);
|
|
252675
|
+
if (!validation.ok) throw new Error(`${STRUCTURED_SUBAGENT_OUTPUT_ERROR}: ${validation.error}. Resume with Agent(resume="${childId}", prompt="return the corrected JSON object", response_format=...) using the same response format.`);
|
|
252676
|
+
}
|
|
252677
|
+
return validation.value;
|
|
252678
|
+
}
|
|
252470
252679
|
function shouldSuppressQueuedAttemptFailureEvent(options, error) {
|
|
252471
252680
|
if (options.suppressRateLimitFailureEvent !== true) return false;
|
|
252472
252681
|
if (isProviderRateLimitError(error)) return true;
|
|
252473
252682
|
return isAbortError$4(error) || options.signal.aborted;
|
|
252474
252683
|
}
|
|
252475
|
-
var DEFAULT_SUBAGENT_TIMEOUT_MS, resolveSubagentTimeoutMs, runAgentWithTimeoutContinuation, buildSubagentUsageDelta, inheritSubagentAllowedTools, inheritSubagentLifecycleTools, 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;
|
|
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;
|
|
252476
252685
|
var init_subagent_host = __esmMin((() => {
|
|
252477
252686
|
init_src$4();
|
|
252478
252687
|
init_errors$8();
|
|
@@ -252487,6 +252696,14 @@ var init_subagent_host = __esmMin((() => {
|
|
|
252487
252696
|
({ DEFAULT_SUBAGENT_TIMEOUT_MS, resolveSubagentTimeoutMs, runAgentWithTimeoutContinuation } = createRequire(import.meta.url)("./bin/subagent-timeout-policy.cjs"));
|
|
252488
252697
|
({ buildSubagentUsageDelta } = createRequire(import.meta.url)("./bin/subagent-usage-rollup-policy.cjs"));
|
|
252489
252698
|
({ inheritSubagentAllowedTools, inheritSubagentLifecycleTools } = createRequire(import.meta.url)("./bin/subagent-tool-policy.cjs"));
|
|
252699
|
+
({
|
|
252700
|
+
STRUCTURED_SUBAGENT_OUTPUT_ERROR,
|
|
252701
|
+
prepareStructuredResponseFormat,
|
|
252702
|
+
validateStructuredSubagentOutput,
|
|
252703
|
+
buildStructuredResponseFormatReminder,
|
|
252704
|
+
buildStructuredResponseRepairPrompt,
|
|
252705
|
+
buildStructuredSubagentEnvelope
|
|
252706
|
+
} = createRequire(import.meta.url)("./bin/structured-subagent-output.cjs"));
|
|
252490
252707
|
({
|
|
252491
252708
|
SUBAGENT_MAX_TOKENS_ERROR,
|
|
252492
252709
|
SUBAGENT_MAX_TOKENS_HANDOFF_PROMPT,
|
|
@@ -252751,6 +252968,10 @@ IMPORTANT:
|
|
|
252751
252968
|
const gitContext = await collectGitContext(child.kaos, child.config.cwd);
|
|
252752
252969
|
if (gitContext) childPrompt = `${gitContext}\n\n${childPrompt}`;
|
|
252753
252970
|
}
|
|
252971
|
+
if (options.responseFormat !== void 0) child.context.appendSystemReminder(buildStructuredResponseFormatReminder(options.responseFormat), {
|
|
252972
|
+
kind: "system_trigger",
|
|
252973
|
+
name: "subagent_response_format"
|
|
252974
|
+
});
|
|
252754
252975
|
this.emitSubagentStarted(parent, childId);
|
|
252755
252976
|
if (child.turn.prompt([{
|
|
252756
252977
|
type: "text",
|
|
@@ -252761,17 +252982,29 @@ IMPORTANT:
|
|
|
252761
252982
|
}
|
|
252762
252983
|
async waitForChildCompletion(parent, childId, child, profileName, options) {
|
|
252763
252984
|
await completeChildTurnWithMaxTokensHandoff(child, options.signal);
|
|
252764
|
-
let result
|
|
252765
|
-
|
|
252766
|
-
|
|
252767
|
-
|
|
252768
|
-
|
|
252769
|
-
|
|
252770
|
-
|
|
252771
|
-
|
|
252772
|
-
|
|
252773
|
-
|
|
252985
|
+
let result;
|
|
252986
|
+
if (options.responseFormat !== void 0) {
|
|
252987
|
+
const structuredResult = await completeStructuredSubagentResult(child, childId, profileName, options.responseFormat, options.signal);
|
|
252988
|
+
result = buildStructuredSubagentEnvelope({
|
|
252989
|
+
agentId: childId,
|
|
252990
|
+
profileName,
|
|
252991
|
+
responseFormat: options.responseFormat,
|
|
252992
|
+
result: structuredResult,
|
|
252993
|
+
usage: child.usage.data().total
|
|
252994
|
+
});
|
|
252995
|
+
} else {
|
|
252774
252996
|
result = lastAssistantText(child);
|
|
252997
|
+
let remainingContinuations = SUMMARY_CONTINUATION_ATTEMPTS;
|
|
252998
|
+
while (remainingContinuations > 0 && result.length < SUMMARY_MIN_LENGTH) {
|
|
252999
|
+
remainingContinuations -= 1;
|
|
253000
|
+
options.signal.throwIfAborted();
|
|
253001
|
+
child.turn.prompt([{
|
|
253002
|
+
type: "text",
|
|
253003
|
+
text: summary_continuation_default
|
|
253004
|
+
}], SUBAGENT_PROMPT_ORIGIN);
|
|
253005
|
+
await completeChildTurnWithMaxTokensHandoff(child, options.signal);
|
|
253006
|
+
result = lastAssistantText(child);
|
|
253007
|
+
}
|
|
252775
253008
|
}
|
|
252776
253009
|
const usage = child.usage.data().total;
|
|
252777
253010
|
parent.emitEvent({
|
|
@@ -252868,7 +253101,7 @@ var init_agent_background_disabled = __esmMin((() => {
|
|
|
252868
253101
|
//#region ../../packages/agent-core/src/tools/builtin/collaboration/agent-background-enabled.md?raw
|
|
252869
253102
|
var agent_background_enabled_default;
|
|
252870
253103
|
var init_agent_background_enabled = __esmMin((() => {
|
|
252871
|
-
agent_background_enabled_default = "Subagents run detached whenever task management is available, so the parent remains responsive while delegated work continues.
|
|
253104
|
+
agent_background_enabled_default = "Subagents run detached whenever task management is available, so the parent remains responsive while delegated work continues. A call with `response_format` is the deliberate exception: it runs in the foreground so BLUN can validate and, at most once, repair the final JSON before returning it. Detached completion arrives automatically in a later turn. Do not poll, sleep, or block on TaskOutput. Continue with other work or respond to the user. Use TaskUpdate to steer a running detached subagent and TaskStop only when it must be cancelled. Never fabricate or predict its result.";
|
|
252872
253105
|
}));
|
|
252873
253106
|
//#endregion
|
|
252874
253107
|
//#region ../../packages/agent-core/src/tools/builtin/collaboration/agent.md?raw
|
|
@@ -252910,7 +253143,7 @@ function formatForegroundAgentFailure(handle, message, timedOut) {
|
|
|
252910
253143
|
"",
|
|
252911
253144
|
`subagent error: ${message}`
|
|
252912
253145
|
];
|
|
252913
|
-
if (timedOut || message.includes(SUBAGENT_MAX_TOKENS_ERROR)) lines.push(`resume_hint: Continue with Agent(resume="${handle.agentId}", prompt="continue"). Use agent_id only; do not set subagent_type. The subagent retains its prior context; redo any unfinished tool call if its result was lost.`);
|
|
253146
|
+
if (timedOut || message.includes(SUBAGENT_MAX_TOKENS_ERROR) || message.includes(STRUCTURED_SUBAGENT_OUTPUT_ERROR)) lines.push(`resume_hint: Continue with Agent(resume="${handle.agentId}", prompt="continue"). Use agent_id only; do not set subagent_type. The subagent retains its prior context; redo any unfinished tool call if its result was lost.`);
|
|
252914
253147
|
return lines.join("\n");
|
|
252915
253148
|
}
|
|
252916
253149
|
function launchErrorMessage(error, signal) {
|
|
@@ -252954,8 +253187,12 @@ var init_agent$1 = __esmMin((() => {
|
|
|
252954
253187
|
description: string().describe("Short task description (3-5 words) for UI display"),
|
|
252955
253188
|
subagent_type: string().optional().describe("One of the available agent types (see \"Available agent types\" in this tool description). Defaults to \"coder\" when omitted."),
|
|
252956
253189
|
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."),
|
|
252957
|
-
run_in_background: boolean$1().optional().describe("Compatibility option.
|
|
252958
|
-
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.")
|
|
253190
|
+
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
|
+
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."),
|
|
253192
|
+
response_format: object({
|
|
253193
|
+
name: string().min(1).max(64).describe("Stable name for the structured result"),
|
|
253194
|
+
schema: record(string(), unknown()).describe("Restricted JSON Schema for one object result")
|
|
253195
|
+
}).optional().describe("Require a validated JSON object from a foreground subagent. Structured background agents are not supported yet.")
|
|
252959
253196
|
}));
|
|
252960
253197
|
object({
|
|
252961
253198
|
result: string().describe("Aggregated text output from the subagent"),
|
|
@@ -252967,7 +253204,7 @@ var init_agent$1 = __esmMin((() => {
|
|
|
252967
253204
|
}).describe("Cumulative token usage")
|
|
252968
253205
|
});
|
|
252969
253206
|
BACKGROUND_AGENT_UNAVAILABLE = "Background agent execution is not available for this agent because TaskList, TaskOutput, and TaskStop are not enabled.";
|
|
252970
|
-
agent_default = "Launch a subagent for substantial, multi-step work in its own context and wire file. It returns a final report while keeping intermediate file contents out of your context.\n\nThe subagent starts with zero conversation context. Give it a self-contained prompt with the goal, known facts, constraints, and required result. For a direct lookup, include the exact path or command. For an investigation, state the question and evidence needed instead of prescribing rigid steps.\n\nWhen continuing earlier work, resume the existing agent ID instead of spawning a new agent; its context remains available. A subagent report is only visible to you, so relay the relevant conclusions to the user. `timeout_minutes` sets the wall-clock interval before the same agent continues automatically with preserved context; `timeout_minutes=0` disables that interval.\n\nUse Agent for complex, context-heavy work, not a trivial one- or two-step task. Launch independent agents in parallel in one response when useful. After assigning a scope, do not duplicate its searches or reads and do not abandon it to redo the same work manually; both erase the intended context savings.";
|
|
253207
|
+
agent_default = "Launch a subagent for substantial, multi-step work in its own context and wire file. It returns a final report while keeping intermediate file contents out of your context.\n\nThe subagent starts with zero conversation context. Give it a self-contained prompt with the goal, known facts, constraints, and required result. For a direct lookup, include the exact path or command. For an investigation, state the question and evidence needed instead of prescribing rigid steps.\n\nWhen continuing earlier work, resume the existing agent ID instead of spawning a new agent; its context remains available. A subagent report is only visible to you, so relay the relevant conclusions to the user. `timeout_minutes` sets the wall-clock interval before the same agent continues automatically with preserved context; `timeout_minutes=0` disables that interval.\n\nUse Agent for complex, context-heavy work, not a trivial one- or two-step task. Launch independent agents in parallel in one response when useful. After assigning a scope, do not duplicate its searches or reads and do not abandon it to redo the same work manually; both erase the intended context savings.\n\nFor a machine-readable foreground result, pass `response_format` with a stable name and restricted object JSON Schema. The child gets no additional tools or permissions. It must return exactly one matching JSON object; BLUN validates it and allows at most one bounded repair turn. Do not combine `response_format` with `run_in_background=true`.";
|
|
252971
253208
|
AgentTool = class {
|
|
252972
253209
|
subagentHost;
|
|
252973
253210
|
backgroundManager;
|
|
@@ -252990,10 +253227,11 @@ var init_agent$1 = __esmMin((() => {
|
|
|
252990
253227
|
let profileName = args.subagent_type?.length ? args.subagent_type : "coder";
|
|
252991
253228
|
const resumeAgentId = args.resume?.trim();
|
|
252992
253229
|
if (resumeAgentId !== void 0 && resumeAgentId.length > 0) profileName = await this.subagentHost.getProfileName?.(resumeAgentId) ?? "subagent";
|
|
252993
|
-
const
|
|
253230
|
+
const resolvedRunMode = resolveSubagentRunMode({
|
|
252994
253231
|
allowBackground: this.allowBackground,
|
|
252995
253232
|
requested: args.run_in_background
|
|
252996
253233
|
});
|
|
253234
|
+
const runInBackground = args.response_format === void 0 ? resolvedRunMode.runInBackground : false;
|
|
252997
253235
|
return {
|
|
252998
253236
|
description: `${runInBackground ? "Launching background" : "Launching"} ${profileName} agent: ${args.description}`,
|
|
252999
253237
|
accesses: ToolAccesses.none(),
|
|
@@ -253011,10 +253249,24 @@ var init_agent$1 = __esmMin((() => {
|
|
|
253011
253249
|
async execution(args, { toolCallId, signal }) {
|
|
253012
253250
|
try {
|
|
253013
253251
|
signal.throwIfAborted();
|
|
253014
|
-
|
|
253252
|
+
if (args.response_format !== void 0 && args.run_in_background === true) return {
|
|
253253
|
+
output: "response_format is supported for foreground Agent runs only; remove run_in_background=true.",
|
|
253254
|
+
isError: true
|
|
253255
|
+
};
|
|
253256
|
+
let responseFormat;
|
|
253257
|
+
try {
|
|
253258
|
+
responseFormat = prepareStructuredResponseFormat(args.response_format, compileToolArgsValidator);
|
|
253259
|
+
} catch (error) {
|
|
253260
|
+
return {
|
|
253261
|
+
output: `Invalid response_format: ${error instanceof Error ? error.message : String(error)}`,
|
|
253262
|
+
isError: true
|
|
253263
|
+
};
|
|
253264
|
+
}
|
|
253265
|
+
const resolvedRunMode = resolveSubagentRunMode({
|
|
253015
253266
|
allowBackground: this.allowBackground,
|
|
253016
253267
|
requested: args.run_in_background
|
|
253017
253268
|
});
|
|
253269
|
+
const runInBackground = responseFormat === void 0 ? resolvedRunMode.runInBackground : false;
|
|
253018
253270
|
const requestedProfileName = args.subagent_type?.length ? args.subagent_type : void 0;
|
|
253019
253271
|
const resumeAgentId = args.resume?.trim();
|
|
253020
253272
|
if (resumeAgentId !== void 0 && resumeAgentId.length > 0 && requestedProfileName !== void 0) return {
|
|
@@ -253036,6 +253288,7 @@ var init_agent$1 = __esmMin((() => {
|
|
|
253036
253288
|
prompt: args.prompt,
|
|
253037
253289
|
description: args.description,
|
|
253038
253290
|
runInBackground,
|
|
253291
|
+
responseFormat,
|
|
253039
253292
|
signal: controller.signal
|
|
253040
253293
|
};
|
|
253041
253294
|
let handle;
|
|
@@ -253061,7 +253314,8 @@ var init_agent$1 = __esmMin((() => {
|
|
|
253061
253314
|
taskId = this.backgroundManager.registerTask(new AgentBackgroundTask(handle, args.description, this.subagentHost, controller, {
|
|
253062
253315
|
timeoutMs: resolveSubagentTimeoutMs({ perRunMinutes: args.timeout_minutes }),
|
|
253063
253316
|
runInBackground,
|
|
253064
|
-
parentToolCallId: toolCallId
|
|
253317
|
+
parentToolCallId: toolCallId,
|
|
253318
|
+
responseFormat
|
|
253065
253319
|
}), {
|
|
253066
253320
|
detached: runInBackground,
|
|
253067
253321
|
signal: runInBackground ? void 0 : signal
|
|
@@ -253084,7 +253338,7 @@ var init_agent$1 = __esmMin((() => {
|
|
|
253084
253338
|
}
|
|
253085
253339
|
if (runInBackground) return { output: formatBackgroundAgentResult(taskId, handle, args.description, this.allowBackground) };
|
|
253086
253340
|
if (await this.backgroundManager.waitForForegroundRelease(taskId) === "detached") return { output: formatBackgroundAgentResult(taskId, handle, args.description, this.allowBackground) };
|
|
253087
|
-
return await this.formatForegroundResult(taskId, handle);
|
|
253341
|
+
return await this.formatForegroundResult(taskId, handle, responseFormat);
|
|
253088
253342
|
} catch (error) {
|
|
253089
253343
|
return {
|
|
253090
253344
|
output: `subagent error: ${launchErrorMessage(error, signal)}`,
|
|
@@ -253092,9 +253346,12 @@ var init_agent$1 = __esmMin((() => {
|
|
|
253092
253346
|
};
|
|
253093
253347
|
}
|
|
253094
253348
|
}
|
|
253095
|
-
async formatForegroundResult(taskId, handle) {
|
|
253349
|
+
async formatForegroundResult(taskId, handle, responseFormat) {
|
|
253096
253350
|
const info = this.backgroundManager.getTask(taskId);
|
|
253097
|
-
if (info?.status === "completed")
|
|
253351
|
+
if (info?.status === "completed") {
|
|
253352
|
+
const output = await this.backgroundManager.readOutput(taskId);
|
|
253353
|
+
return { output: responseFormat === void 0 ? formatForegroundAgentSuccess(handle, output) : output };
|
|
253354
|
+
}
|
|
253098
253355
|
const timedOut = info?.status === "timed_out";
|
|
253099
253356
|
return {
|
|
253100
253357
|
output: formatForegroundAgentFailure(handle, timedOut ? "Agent timed out before automatic continuation could start." : info?.stopReason === "Interrupted by user" ? USER_INTERRUPTED_SUBAGENT_MESSAGE : info?.stopReason !== void 0 ? info.stopReason : "The subagent was stopped before it finished.", timedOut),
|
|
@@ -261161,7 +261418,7 @@ function renderHistoricalToolResultReference(toolName, toolCallId, text, outputP
|
|
|
261161
261418
|
function safeToolResultFileStem(toolName, toolCallId) {
|
|
261162
261419
|
return `${toolName}-${toolCallId}`.replace(/[^a-zA-Z0-9._-]+/g, "_").replace(/^_+|_+$/g, "").slice(0, 80) || "tool-result";
|
|
261163
261420
|
}
|
|
261164
|
-
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, dedupeRepeatedSuccessfulToolResults, readContinuationLineOffset, selectToolResultBatchOffloads, selectHistoricalToolResultOffloads, buildToolResultOffloadTelemetry;
|
|
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;
|
|
261165
261422
|
var init_tool_result_budget = __esmMin((() => {
|
|
261166
261423
|
init_dist$6();
|
|
261167
261424
|
const toolResultOffloadPolicy = createRequire(import.meta.url)("./bin/tool-result-offload-policy.cjs");
|
|
@@ -261177,6 +261434,8 @@ var init_tool_result_budget = __esmMin((() => {
|
|
|
261177
261434
|
createToolResultPreview = toolResultOffloadPolicy.createToolResultPreview;
|
|
261178
261435
|
compactPersistedToolResultReference = toolResultOffloadPolicy.compactPersistedToolResultReference;
|
|
261179
261436
|
compactHistoricalSuccessfulToolResults = toolResultOffloadPolicy.compactHistoricalSuccessfulToolResults;
|
|
261437
|
+
currentTurnReadToolResultIds = toolResultOffloadPolicy.currentTurnReadToolResultIds;
|
|
261438
|
+
currentUserTurnStartIndex = toolResultOffloadPolicy.currentUserTurnStartIndex;
|
|
261180
261439
|
dedupeRepeatedSuccessfulToolResults = toolResultOffloadPolicy.dedupeRepeatedSuccessfulToolResults;
|
|
261181
261440
|
freshToolResultIds = toolResultOffloadPolicy.freshToolResultIds;
|
|
261182
261441
|
readContinuationLineOffset = toolResultOffloadPolicy.readContinuationLineOffset;
|
|
@@ -261194,8 +261453,9 @@ var ToolResultBatchOffload = class {
|
|
|
261194
261453
|
async detect() {
|
|
261195
261454
|
const history = this.agent.context.history;
|
|
261196
261455
|
const tailIds = freshToolResultIds(history);
|
|
261456
|
+
const pinnedReadIds = currentTurnReadToolResultIds(history);
|
|
261197
261457
|
const recentStart = Math.max(0, history.length - TOOL_RESULT_HISTORICAL_KEEP_RECENT_MESSAGES);
|
|
261198
|
-
const historical = history.slice(0, recentStart).filter((message) => message?.role === "tool" && !tailIds.has(message.toolCallId));
|
|
261458
|
+
const historical = history.slice(0, recentStart).filter((message) => message?.role === "tool" && !tailIds.has(message.toolCallId) && !pinnedReadIds.has(message.toolCallId));
|
|
261199
261459
|
const candidateBatches = [{
|
|
261200
261460
|
messages: historical,
|
|
261201
261461
|
historical: true,
|
|
@@ -261369,7 +261629,7 @@ function renderPersistedUserMessage(text, outputPath) {
|
|
|
261369
261629
|
createUserMessagePreview(text)
|
|
261370
261630
|
].join("\n");
|
|
261371
261631
|
}
|
|
261372
|
-
var USER_MESSAGE_MAX_CHARS, USER_MESSAGE_OFFLOAD_MARKER, shouldOffloadUserMessage, shouldOffloadHistoricalUserMessage, createUserMessagePreview, compactHistoricalPersistedUserMessageReferences, projectHistoricalMediaParts;
|
|
261632
|
+
var USER_MESSAGE_MAX_CHARS, USER_MESSAGE_OFFLOAD_MARKER, shouldOffloadUserMessage, shouldOffloadHistoricalUserMessage, createUserMessagePreview, compactHistoricalPersistedUserMessageReferences, historyTextChars, projectHistoricalMediaParts;
|
|
261373
261633
|
var init_user_message_offload = __esmMin((() => {
|
|
261374
261634
|
const policy = createRequire(import.meta.url)("./bin/user-message-offload-policy.cjs");
|
|
261375
261635
|
USER_MESSAGE_MAX_CHARS = policy.USER_MESSAGE_MAX_CHARS;
|
|
@@ -261377,6 +261637,7 @@ var init_user_message_offload = __esmMin((() => {
|
|
|
261377
261637
|
shouldOffloadUserMessage = policy.shouldOffloadUserMessage;
|
|
261378
261638
|
shouldOffloadHistoricalUserMessage = policy.shouldOffloadHistoricalUserMessage;
|
|
261379
261639
|
createUserMessagePreview = policy.createUserMessagePreview;
|
|
261640
|
+
historyTextChars = policy.historyTextChars;
|
|
261380
261641
|
compactHistoricalPersistedUserMessageReferences = policy.compactHistoricalPersistedUserMessageReferences;
|
|
261381
261642
|
({ projectHistoricalMediaParts } = createRequire(import.meta.url)("./bin/historical-media-projection-policy.cjs"));
|
|
261382
261643
|
}));
|
|
@@ -261389,8 +261650,11 @@ var UserMessageOffload = class {
|
|
|
261389
261650
|
async detect() {
|
|
261390
261651
|
const history = this.agent.context.history;
|
|
261391
261652
|
if (this.agent.homedir === void 0) return 0;
|
|
261653
|
+
const currentTurnStart = currentUserTurnStartIndex(history);
|
|
261654
|
+
const totalHistoryChars = historyTextChars(history);
|
|
261392
261655
|
let offloaded = 0;
|
|
261393
261656
|
for (let historyIndex = 0; historyIndex < history.length; historyIndex++) {
|
|
261657
|
+
if (historyIndex === currentTurnStart) continue;
|
|
261394
261658
|
const message = history[historyIndex];
|
|
261395
261659
|
const text = persistableUserMessageText(message);
|
|
261396
261660
|
if (text === void 0) continue;
|
|
@@ -261398,6 +261662,7 @@ var UserMessageOffload = class {
|
|
|
261398
261662
|
const historicalOversize = shouldOffloadHistoricalUserMessage({
|
|
261399
261663
|
historyIndex,
|
|
261400
261664
|
historyLength: history.length,
|
|
261665
|
+
historyChars: totalHistoryChars,
|
|
261401
261666
|
textChars: text.length
|
|
261402
261667
|
});
|
|
261403
261668
|
if (!immediateOversize && !historicalOversize) continue;
|
|
@@ -261520,6 +261785,7 @@ var AssistantMessageOffload = class {
|
|
|
261520
261785
|
async detect() {
|
|
261521
261786
|
const history = this.agent.context.history;
|
|
261522
261787
|
if (this.agent.homedir === void 0) return 0;
|
|
261788
|
+
const totalHistoryChars = historyTextChars(history);
|
|
261523
261789
|
let offloaded = 0;
|
|
261524
261790
|
for (let historyIndex = 0; historyIndex < history.length; historyIndex++) {
|
|
261525
261791
|
const message = history[historyIndex];
|
|
@@ -261527,6 +261793,7 @@ var AssistantMessageOffload = class {
|
|
|
261527
261793
|
if (text === void 0 || !shouldOffloadHistoricalAssistantMessage({
|
|
261528
261794
|
historyIndex,
|
|
261529
261795
|
historyLength: history.length,
|
|
261796
|
+
historyChars: totalHistoryChars,
|
|
261530
261797
|
textChars: text.length
|
|
261531
261798
|
})) continue;
|
|
261532
261799
|
const messageHash = assistantMessageOffloadHash(message, text);
|
|
@@ -261563,6 +261830,7 @@ var AssistantMessageOffload = class {
|
|
|
261563
261830
|
}
|
|
261564
261831
|
compact(messages) {
|
|
261565
261832
|
const completedToolCallIds = new Set(messages.filter((message) => message?.role === "tool" && message.toolCallId !== void 0).map((message) => message.toolCallId));
|
|
261833
|
+
const totalHistoryChars = historyTextChars(messages);
|
|
261566
261834
|
let changed = false;
|
|
261567
261835
|
const projected = messages.map((message, historyIndex) => {
|
|
261568
261836
|
if (message?.role === "assistant" && message.toolCalls.length > 0) {
|
|
@@ -261572,6 +261840,7 @@ var AssistantMessageOffload = class {
|
|
|
261572
261840
|
if (shouldCompactHistoricalAssistantToolNarration({
|
|
261573
261841
|
historyIndex,
|
|
261574
261842
|
historyLength: messages.length,
|
|
261843
|
+
historyChars: totalHistoryChars,
|
|
261575
261844
|
textChars,
|
|
261576
261845
|
toolCallCount: message.toolCalls.length,
|
|
261577
261846
|
completedToolCallCount
|
|
@@ -261959,7 +262228,7 @@ function durablePromptOrigin(origin) {
|
|
|
261959
262228
|
void externalReportSources;
|
|
261960
262229
|
return durableOrigin;
|
|
261961
262230
|
}
|
|
261962
|
-
var BLUN_CORE_TOOL_NAMES, BLUN_LEAN_TOOL_NAMES, BLUN_ATTACHMENT_MARKER_RE, BLUN_TELEGRAM_OUTBOUND_TOOL_RE, BLUN_TELEGRAM_CHANNEL_RE, BLUN_TOOL_BUDGET_RATIO, createDeferredToolLoader, mediaToolNamesForTurnText, rankedSupportToolNamesForGoal, rankedToolNamesForTurnText, rememberDeferredToolAfterNotFound, toolSchemaBudgetTokens, enforceSingleTodoWritePerStep, projectRecurringCronHistory, TelegramDeliveryLedger, createRuntimeCognitiveTurnLifecycle, cognitiveFocusScopesForTurn, buildCognitiveWorkFocus, buildAttentionQueueItem, LLM_NOT_SET_MESSAGE, GOAL_CONTINUATION_ORIGIN, GOAL_COMPLETION_REMINDER_NAME, GOAL_BLOCKED_REMINDER_NAME, GOAL_RATE_LIMIT_PAUSE_REASON, GOAL_PROVIDER_CONNECTION_PAUSE_PREFIX, GOAL_PROVIDER_AUTH_PAUSE_PREFIX, GOAL_PROVIDER_API_PAUSE_PREFIX, GOAL_MODEL_CONFIG_PAUSE_PREFIX, GOAL_RUNTIME_PAUSE_PREFIX, GOAL_PROVIDER_FILTERED_PAUSE_REASON, GOAL_CONTINUATION_PROMPT, TurnFlow;
|
|
262231
|
+
var BLUN_CORE_TOOL_NAMES, BLUN_LEAN_TOOL_NAMES, BLUN_ATTACHMENT_MARKER_RE, BLUN_TELEGRAM_OUTBOUND_TOOL_RE, BLUN_TELEGRAM_CHANNEL_RE, BLUN_TOOL_BUDGET_RATIO, createDeferredToolLoader, mediaToolNamesForTurnText, rankedSupportToolNamesForGoal, rankedToolNamesForTurnText, rememberDeferredToolAfterNotFound, toolSchemaBudgetTokens, assessTodoListBounds, assessTodoMaintenanceUpdate, enforceSingleTodoWritePerStep, todoRefreshWorkCallLimit, projectRecurringCronHistory, TelegramDeliveryLedger, createRuntimeCognitiveTurnLifecycle, cognitiveFocusScopesForTurn, buildCognitiveWorkFocus, buildAttentionQueueItem, LLM_NOT_SET_MESSAGE, GOAL_CONTINUATION_ORIGIN, GOAL_COMPLETION_REMINDER_NAME, GOAL_BLOCKED_REMINDER_NAME, GOAL_RATE_LIMIT_PAUSE_REASON, GOAL_PROVIDER_CONNECTION_PAUSE_PREFIX, GOAL_PROVIDER_AUTH_PAUSE_PREFIX, GOAL_PROVIDER_API_PAUSE_PREFIX, GOAL_MODEL_CONFIG_PAUSE_PREFIX, GOAL_RUNTIME_PAUSE_PREFIX, GOAL_PROVIDER_FILTERED_PAUSE_REASON, GOAL_CONTINUATION_PROMPT, TurnFlow;
|
|
261963
262232
|
var init_turn = __esmMin((() => {
|
|
261964
262233
|
init_dist$4();
|
|
261965
262234
|
init_src$4();
|
|
@@ -261977,7 +262246,7 @@ var init_turn = __esmMin((() => {
|
|
|
261977
262246
|
init_user_message_offload();
|
|
261978
262247
|
init_assistant_message_offload();
|
|
261979
262248
|
({ CORE_TOOL_NAMES: BLUN_CORE_TOOL_NAMES, createDeferredToolLoader, mediaToolNamesForTurnText, rankedSupportToolNamesForGoal, rankedToolNamesForTurnText, rememberDeferredToolAfterNotFound, toolSchemaBudgetTokens } = createRequire(import.meta.url)("./bin/turn-tool-performance-policy.cjs"));
|
|
261980
|
-
({ enforceSingleTodoWritePerStep } = createRequire(import.meta.url)("./bin/todo-list-turn-policy.cjs"));
|
|
262249
|
+
({ assessTodoListBounds, assessTodoMaintenanceUpdate, enforceSingleTodoWritePerStep, todoRefreshWorkCallLimit } = createRequire(import.meta.url)("./bin/todo-list-turn-policy.cjs"));
|
|
261981
262250
|
({ projectRecurringCronHistory } = createRequire(import.meta.url)("./bin/recurring-cron-history-policy.cjs"));
|
|
261982
262251
|
({ TelegramDeliveryLedger } = createRequire(import.meta.url)("./bin/repeated-user-message-projection.cjs"));
|
|
261983
262252
|
({ createRuntimeCognitiveTurnLifecycle } = createRequire(import.meta.url)("./bin/cognitive-turn-lifecycle.cjs"));
|
|
@@ -262789,6 +263058,7 @@ var init_turn = __esmMin((() => {
|
|
|
262789
263058
|
async runStepLoop(turnId, signal, input, origin) {
|
|
262790
263059
|
let stopHookContinuationUsed = false;
|
|
262791
263060
|
let goalOutcomeMessageContinuationUsed = false;
|
|
263061
|
+
let directSteerContinuationPending = false;
|
|
262792
263062
|
const directReplyTurnStop = createDirectReplyTurnStop(blunExtractText(input));
|
|
262793
263063
|
const deduper = new ToolCallDeduplicator({ telemetry: this.agent.telemetry });
|
|
262794
263064
|
if (blunTurnNeedsInitialMcp(input, origin)) await blunWaitForInitialMcpBudget(this.agent.mcp, signal);
|
|
@@ -262913,7 +263183,8 @@ var init_turn = __esmMin((() => {
|
|
|
262913
263183
|
});
|
|
262914
263184
|
return { llm: this.agent.llmForTurn(workStepThinkingEffort), tools: selectedTools };
|
|
262915
263185
|
}
|
|
262916
|
-
|
|
263186
|
+
if (pendingSteers.some((steer) => directMessageAllowsWorkContinuation(blunExtractText(steer.input)))) directSteerContinuationPending = true;
|
|
263187
|
+
const steerEfforts = pendingSteers.map((steer) => blunTurnHasAttachment(steer.input) ? void 0 : selectThinkingEffortForBufferedSteer(blunExtractText(blunThinkingIntentInput(steer.input)), steer.origin.kind));
|
|
262917
263188
|
if (steerEfforts.some((effort) => effort === void 0)) return;
|
|
262918
263189
|
const steerInput = pendingSteers.flatMap((steer) => [...steer.input]);
|
|
262919
263190
|
const steerThinkingEffort = "low";
|
|
@@ -262959,10 +263230,22 @@ var init_turn = __esmMin((() => {
|
|
|
262959
263230
|
deduper.endStep();
|
|
262960
263231
|
return stopForGoalBudget || directReplyTurnStop.shouldStop() ? { stopTurn: true } : void 0;
|
|
262961
263232
|
},
|
|
262962
|
-
|
|
262963
|
-
|
|
262964
|
-
|
|
262965
|
-
|
|
263233
|
+
shouldContinueAfterStop: async (ctx) => {
|
|
263234
|
+
const { signal } = ctx;
|
|
263235
|
+
if (this.matchingSteers().length > 0) return { continue: true };
|
|
263236
|
+
signal.throwIfAborted();
|
|
263237
|
+
if (directSteerContinuationPending) {
|
|
263238
|
+
directSteerContinuationPending = false;
|
|
263239
|
+
this.agent.context.appendUserMessage([{
|
|
263240
|
+
type: "text",
|
|
263241
|
+
text: "The private Telegram DM was handled. Continue the exact work that was active before it arrived. Do not re-read completed evidence; perform the next unfinished action now."
|
|
263242
|
+
}], {
|
|
263243
|
+
kind: "system_trigger",
|
|
263244
|
+
name: "telegram_direct_work_resume"
|
|
263245
|
+
});
|
|
263246
|
+
this.setActiveSteerAcceptance(turnId, true);
|
|
263247
|
+
return { continue: true };
|
|
263248
|
+
}
|
|
262966
263249
|
if (!goalOutcomeMessageContinuationUsed && isGoalOutcomeReminderOrigin(this.agent.context.history.at(-1)?.origin)) {
|
|
262967
263250
|
goalOutcomeMessageContinuationUsed = true;
|
|
262968
263251
|
if (!hasStepBudgetRemaining(loopControl?.maxStepsPerTurn, ctx.stepNumber)) {
|
|
@@ -262997,6 +263280,8 @@ var init_turn = __esmMin((() => {
|
|
|
262997
263280
|
prepareToolExecution: async (ctx) => {
|
|
262998
263281
|
const todoTurnPolicy = enforceSingleTodoWritePerStep(ctx);
|
|
262999
263282
|
if (todoTurnPolicy !== void 0) return todoTurnPolicy;
|
|
263283
|
+
const todoBoundsPolicy = enforceTodoListBounds(this.agent, ctx);
|
|
263284
|
+
if (todoBoundsPolicy !== void 0) return todoBoundsPolicy;
|
|
263000
263285
|
const goalTodoPolicy = enforceGoalTodoPolicy(this.agent, ctx);
|
|
263001
263286
|
if (goalTodoPolicy !== void 0) return goalTodoPolicy;
|
|
263002
263287
|
const ideaPolicy = enforceIdeaToolPolicy(this.agent, ctx);
|
|
@@ -264119,20 +264404,16 @@ var init_codebase_search$1 = __esmMin((() => {
|
|
|
264119
264404
|
* `CODEBASE_INDEX_SCRIPT` env override, then to a search from cwd.
|
|
264120
264405
|
*/
|
|
264121
264406
|
function resolveScriptPath() {
|
|
264122
|
-
|
|
264123
|
-
if (envPath !== void 0 && envPath.length > 0) return envPath;
|
|
264124
|
-
try {
|
|
264125
|
-
return fileURLToPath(new URL("../../../../../codebase-index/codebase_index.py", import.meta.url));
|
|
264126
|
-
} catch {}
|
|
264127
|
-
return "";
|
|
264407
|
+
return resolveCodebaseIndexScript(import.meta.url, process.env["CODEBASE_INDEX_SCRIPT"]);
|
|
264128
264408
|
}
|
|
264129
|
-
var CodebaseSearchInputSchema, SCRIPT_TIMEOUT_MS, CodebaseSearchTool;
|
|
264409
|
+
var resolveCodebaseIndexScript, CodebaseSearchInputSchema, SCRIPT_TIMEOUT_MS, CodebaseSearchTool;
|
|
264130
264410
|
var init_codebase_search = __esmMin((() => {
|
|
264131
264411
|
init_zod$1();
|
|
264132
264412
|
init_rule_match();
|
|
264133
264413
|
init_input_schema();
|
|
264134
264414
|
init_result_builder();
|
|
264135
264415
|
init_codebase_search$1();
|
|
264416
|
+
({ resolveCodebaseIndexScript } = createRequire(import.meta.url)("./bin/codebase-search-runtime.cjs"));
|
|
264136
264417
|
CodebaseSearchInputSchema = object({
|
|
264137
264418
|
query: string().min(1, "Query cannot be empty.").describe("A natural-language question or concept describing what the code does. Examples: \"keyboard event handling\", \"retry with exponential backoff\", \"where chat messages are routed to the model\"."),
|
|
264138
264419
|
top: number$1().int().positive().default(5).describe("Maximum number of results to return. Defaults to 5.")
|
|
@@ -264828,6 +265109,7 @@ var init_builtin = __esmMin((() => {
|
|
|
264828
265109
|
init_exit_plan_mode();
|
|
264829
265110
|
init_bash();
|
|
264830
265111
|
init_todo_list();
|
|
265112
|
+
init_programmatic_tool();
|
|
264831
265113
|
init_fetch_url();
|
|
264832
265114
|
init_web_search();
|
|
264833
265115
|
init_codebase_search();
|
|
@@ -265272,6 +265554,7 @@ var init_tool$1 = __esmMin((() => {
|
|
|
265272
265554
|
goalToolsEnabled && new UpdateGoalTool(this.agent),
|
|
265273
265555
|
this.agent.rpc?.requestQuestion && new AskUserQuestionTool(this.agent),
|
|
265274
265556
|
new TodoListTool(this.toolStore),
|
|
265557
|
+
new ProgrammaticTool(),
|
|
265275
265558
|
new CompactConversationTool(this.agent),
|
|
265276
265559
|
new TaskListTool(background),
|
|
265277
265560
|
new TaskOutputTool(background),
|
|
@@ -265461,6 +265744,9 @@ var init_fallback_llm = __esmMin((() => {
|
|
|
265461
265744
|
get capability() {
|
|
265462
265745
|
return this.current.llm.capability;
|
|
265463
265746
|
}
|
|
265747
|
+
get thinkingEffort() {
|
|
265748
|
+
return this.current.llm.thinkingEffort;
|
|
265749
|
+
}
|
|
265464
265750
|
async prepareRequestBoundary(params, rebuildMessages) {
|
|
265465
265751
|
params.signal.throwIfAborted();
|
|
265466
265752
|
this.rebuildBoundaryMessages = rebuildMessages;
|
|
@@ -314793,7 +315079,17 @@ function resolveModelCapabilities(alias, provider) {
|
|
|
314793
315079
|
};
|
|
314794
315080
|
}
|
|
314795
315081
|
function toKosongProviderConfig(provider, model, blunRequestHeaders, promptCacheKey, supportEfforts) {
|
|
314796
|
-
|
|
315082
|
+
assertSupportedProviderType(provider);
|
|
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
|
+
};
|
|
314797
315093
|
const envCustomHeaders = parseBlunCodeCustomHeaders();
|
|
314798
315094
|
return {
|
|
314799
315095
|
type: "blun",
|
|
@@ -314814,11 +315110,12 @@ function defaultHeadersField(headers) {
|
|
|
314814
315110
|
return { defaultHeaders: { ...headers } };
|
|
314815
315111
|
}
|
|
314816
315112
|
function providerApiKey(provider) {
|
|
314817
|
-
|
|
315113
|
+
assertSupportedProviderType(provider);
|
|
315114
|
+
if (provider.type === FREDRIK_GLM_PROVIDER_TYPE) return readFredrikGlmApiKeyFile(provider);
|
|
314818
315115
|
return providerValue(provider.apiKey, provider.env, "BLUN_API_KEY");
|
|
314819
315116
|
}
|
|
314820
|
-
function
|
|
314821
|
-
if (provider.type !== "blun") throw new BlunError(ErrorCodes.MODEL_CONFIG_INVALID, "Only
|
|
315117
|
+
function assertSupportedProviderType(provider) {
|
|
315118
|
+
if (provider.type !== "blun" && provider.type !== FREDRIK_GLM_PROVIDER_TYPE) throw new BlunError(ErrorCodes.MODEL_CONFIG_INVALID, "Only approved BLUN Code provider types are supported.");
|
|
314822
315119
|
}
|
|
314823
315120
|
function providerValue(configured, env, envKey) {
|
|
314824
315121
|
return nonEmptyString$2(configured) ?? envValue(env, envKey);
|
|
@@ -314856,7 +315153,9 @@ var init_provider_manager = __esmMin((() => {
|
|
|
314856
315153
|
if (providerName === void 0) throw new BlunError(ErrorCodes.CONFIG_INVALID, `Model "${model}" must define a provider in config.toml.`);
|
|
314857
315154
|
const providerConfig = this.config.providers[providerName];
|
|
314858
315155
|
if (providerConfig === void 0) throw new BlunError(ErrorCodes.CONFIG_INVALID, `Provider "${providerName}" for model "${model}" is not configured.`);
|
|
314859
|
-
|
|
315156
|
+
assertSupportedProviderType(providerConfig);
|
|
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.");
|
|
314860
315159
|
const runtimeContext = this.runtimeModelContexts.get(model);
|
|
314861
315160
|
const maxContextSize = runtimeContext?.providerName === providerName && runtimeContext.model === alias.model ? runtimeContext.maxContextTokens : effectiveAlias.maxContextSize;
|
|
314862
315161
|
if (!Number.isInteger(maxContextSize) || maxContextSize <= 0) throw new BlunError(ErrorCodes.CONFIG_INVALID, `Model "${model}" must define a positive max_context_size in config.toml.`);
|
|
@@ -314870,7 +315169,7 @@ var init_provider_manager = __esmMin((() => {
|
|
|
314870
315169
|
}, provider),
|
|
314871
315170
|
alwaysThinking: (effectiveAlias.capabilities ?? []).some((c) => c.trim().toLowerCase() === "always_thinking"),
|
|
314872
315171
|
maxOutputSize: effectiveAlias.maxOutputSize,
|
|
314873
|
-
type:
|
|
315172
|
+
type: providerConfig.type
|
|
314874
315173
|
};
|
|
314875
315174
|
}
|
|
314876
315175
|
setRuntimeModelContext(input) {
|
|
@@ -314890,7 +315189,7 @@ var init_provider_manager = __esmMin((() => {
|
|
|
314890
315189
|
resolveAuth(model, options) {
|
|
314891
315190
|
const { providerName } = this.resolveProviderConfig(model);
|
|
314892
315191
|
const providerConfig = this.config.providers[providerName];
|
|
314893
|
-
const apiKey = providerConfig ===
|
|
315192
|
+
const apiKey = providerConfig?.type === "blun" ? providerApiKey(providerConfig) : void 0;
|
|
314894
315193
|
const revocationStore = this.options.managedApiKeyRevocationStore;
|
|
314895
315194
|
if (providerName === MANAGED_PROVIDER_NAME$2 && providerConfig?.oauth === void 0 && apiKey !== void 0 && revocationStore !== void 0) return this.resolveManagedApiKeyAuth(providerName, apiKey, revocationStore, options?.log);
|
|
314896
315195
|
if (providerConfig?.oauth === void 0) return void 0;
|
|
@@ -402988,7 +403287,7 @@ function createProgram(version, onMain, onPluginNodeRunner = () => {}) {
|
|
|
402988
403287
|
"high",
|
|
402989
403288
|
"xhigh",
|
|
402990
403289
|
"max"
|
|
402991
|
-
])).addOption(new Option("--permission-mode <mode>", "Permission mode for this invocation (auto, manual, yolo).").choices([
|
|
403290
|
+
])).option("--swarm", "Start in swarm mode.", false).addOption(new Option("--permission-mode <mode>", "Permission mode for this invocation (auto, manual, yolo).").choices([
|
|
402992
403291
|
"auto",
|
|
402993
403292
|
"manual",
|
|
402994
403293
|
"yolo"
|
|
@@ -403022,6 +403321,7 @@ function createProgram(version, onMain, onPluginNodeRunner = () => {}) {
|
|
|
403022
403321
|
plan: raw["plan"],
|
|
403023
403322
|
model: raw["model"],
|
|
403024
403323
|
effort: raw["effort"],
|
|
403324
|
+
swarm: raw["swarm"] === true,
|
|
403025
403325
|
permissionMode: raw["permissionMode"],
|
|
403026
403326
|
forkSession: raw["forkSession"],
|
|
403027
403327
|
outputFormat: raw["outputFormat"],
|
|
@@ -403290,6 +403590,10 @@ registerUiCatalogFragment({
|
|
|
403290
403590
|
"command.telegramAccess.description": "Manage the Telegram bot token and allowed chats",
|
|
403291
403591
|
"command.add-dir.description": "Add or list an additional workspace directory",
|
|
403292
403592
|
"command.experiments.description": "Manage experimental features",
|
|
403593
|
+
"command.copy.description": "Copy the latest assistant response to the clipboard.",
|
|
403594
|
+
"copy.status.copied": "Copied the latest response to the clipboard.",
|
|
403595
|
+
"copy.status.none": "There is no response to copy yet.",
|
|
403596
|
+
"copy.error.failed": "Could not copy the latest response: {error}",
|
|
403293
403597
|
"command.reload.description": "Reload the session and apply runtime and interface settings",
|
|
403294
403598
|
"command.reload-tui.description": "Reload interface settings only",
|
|
403295
403599
|
"command.compact.description": "Compact the conversation context",
|
|
@@ -403349,6 +403653,10 @@ registerUiCatalogFragment({
|
|
|
403349
403653
|
"command.telegramAccess.description": "Telegram-Bot-Token und freigegebene Chats verwalten",
|
|
403350
403654
|
"command.add-dir.description": "Zusätzlichen Arbeitsbereichsordner hinzufügen oder vorhandene auflisten",
|
|
403351
403655
|
"command.experiments.description": "Experimentelle Funktionen verwalten",
|
|
403656
|
+
"command.copy.description": "Neueste Assistentenantwort in die Zwischenablage übernehmen.",
|
|
403657
|
+
"copy.status.copied": "Die neueste Antwort wurde in die Zwischenablage übernommen.",
|
|
403658
|
+
"copy.status.none": "Es ist noch keine Antwort zum Kopieren verfügbar.",
|
|
403659
|
+
"copy.error.failed": "Die neueste Antwort konnte nicht kopiert werden: {error}",
|
|
403352
403660
|
"command.reload.description": "Sitzung neu laden und Runtime- sowie Oberflächeneinstellungen anwenden",
|
|
403353
403661
|
"command.reload-tui.description": "Nur Oberflächeneinstellungen neu laden",
|
|
403354
403662
|
"command.compact.description": "Konversationskontext komprimieren",
|
|
@@ -403408,6 +403716,10 @@ registerUiCatalogFragment({
|
|
|
403408
403716
|
"command.telegramAccess.description": "Gestionar el token del bot de Telegram y los chats permitidos",
|
|
403409
403717
|
"command.add-dir.description": "Añadir o listar directorios adicionales del espacio de trabajo",
|
|
403410
403718
|
"command.experiments.description": "Gestionar funciones experimentales",
|
|
403719
|
+
"command.copy.description": "Copiar la respuesta más reciente del asistente al portapapeles.",
|
|
403720
|
+
"copy.status.copied": "La respuesta más reciente se copió al portapapeles.",
|
|
403721
|
+
"copy.status.none": "Todavía no hay ninguna respuesta que copiar.",
|
|
403722
|
+
"copy.error.failed": "No se pudo copiar la respuesta más reciente: {error}",
|
|
403411
403723
|
"command.reload.description": "Recargar la sesión y aplicar los ajustes del entorno de ejecución y de la interfaz",
|
|
403412
403724
|
"command.reload-tui.description": "Recargar solo los ajustes de la interfaz",
|
|
403413
403725
|
"command.compact.description": "Compactar el contexto de la conversación",
|
|
@@ -403467,6 +403779,10 @@ registerUiCatalogFragment({
|
|
|
403467
403779
|
"command.telegramAccess.description": "Gérer le jeton du bot Telegram et les discussions autorisées",
|
|
403468
403780
|
"command.add-dir.description": "Ajouter ou répertorier un répertoire d’espace de travail supplémentaire",
|
|
403469
403781
|
"command.experiments.description": "Gérer les fonctions expérimentales",
|
|
403782
|
+
"command.copy.description": "Copier la réponse la plus récente de l’assistant dans le presse-papiers.",
|
|
403783
|
+
"copy.status.copied": "La réponse la plus récente a été copiée dans le presse-papiers.",
|
|
403784
|
+
"copy.status.none": "Aucune réponse à copier pour le moment.",
|
|
403785
|
+
"copy.error.failed": "Impossible de copier la réponse la plus récente : {error}",
|
|
403470
403786
|
"command.reload.description": "Recharger la session et appliquer les paramètres d’exécution et d’interface",
|
|
403471
403787
|
"command.reload-tui.description": "Recharger uniquement les paramètres de l’interface",
|
|
403472
403788
|
"command.compact.description": "Compacter le contexte de la conversation",
|
|
@@ -403526,6 +403842,10 @@ registerUiCatalogFragment({
|
|
|
403526
403842
|
"command.telegramAccess.description": "Hantera Telegram-botens API-token och tillåtna chattar",
|
|
403527
403843
|
"command.add-dir.description": "Lägg till eller lista en extra katalog för arbetsytan",
|
|
403528
403844
|
"command.experiments.description": "Hantera experimentella funktioner",
|
|
403845
|
+
"command.copy.description": "Kopiera assistentens senaste svar till urklipp.",
|
|
403846
|
+
"copy.status.copied": "Det senaste svaret kopierades till urklipp.",
|
|
403847
|
+
"copy.status.none": "Det finns inget svar att kopiera ännu.",
|
|
403848
|
+
"copy.error.failed": "Det gick inte att kopiera det senaste svaret: {error}",
|
|
403529
403849
|
"command.reload.description": "Läs in sessionen på nytt och tillämpa körningsmiljö- och gränssnittsinställningar",
|
|
403530
403850
|
"command.reload-tui.description": "Läs bara in gränssnittsinställningarna på nytt",
|
|
403531
403851
|
"command.compact.description": "Komprimera konversationskontexten",
|
|
@@ -403585,6 +403905,10 @@ registerUiCatalogFragment({
|
|
|
403585
403905
|
"command.telegramAccess.description": "Spravovat token telegramového bota a povolené chaty",
|
|
403586
403906
|
"command.add-dir.description": "Přidat nebo vypsat další adresář pracovního prostoru",
|
|
403587
403907
|
"command.experiments.description": "Spravovat experimentální funkce",
|
|
403908
|
+
"command.copy.description": "Zkopírovat nejnovější odpověď asistenta do schránky.",
|
|
403909
|
+
"copy.status.copied": "Nejnovější odpověď byla zkopírována do schránky.",
|
|
403910
|
+
"copy.status.none": "Zatím není k dispozici žádná odpověď ke zkopírování.",
|
|
403911
|
+
"copy.error.failed": "Nejnovější odpověď se nepodařilo zkopírovat: {error}",
|
|
403588
403912
|
"command.reload.description": "Znovu načíst relaci a použít nastavení běhového prostředí a rozhraní",
|
|
403589
403913
|
"command.reload-tui.description": "Znovu načíst pouze nastavení rozhraní",
|
|
403590
403914
|
"command.compact.description": "Komprimovat kontext konverzace",
|
|
@@ -403884,6 +404208,13 @@ const BUILTIN_SLASH_COMMAND_DEFINITIONS = [
|
|
|
403884
404208
|
completeArgs: swarmArgumentCompletions,
|
|
403885
404209
|
availability: "idle-only"
|
|
403886
404210
|
},
|
|
404211
|
+
{
|
|
404212
|
+
name: "model",
|
|
404213
|
+
aliases: [],
|
|
404214
|
+
descriptionKey: "command.model.description",
|
|
404215
|
+
priority: 96,
|
|
404216
|
+
availability: "always"
|
|
404217
|
+
},
|
|
403887
404218
|
{
|
|
403888
404219
|
name: "effort",
|
|
403889
404220
|
aliases: ["thinking"],
|
|
@@ -403976,6 +404307,13 @@ const BUILTIN_SLASH_COMMAND_DEFINITIONS = [
|
|
|
403976
404307
|
priority: 60,
|
|
403977
404308
|
availability: "idle-only"
|
|
403978
404309
|
},
|
|
404310
|
+
{
|
|
404311
|
+
name: "copy",
|
|
404312
|
+
aliases: [],
|
|
404313
|
+
descriptionKey: "command.copy.description",
|
|
404314
|
+
priority: 40,
|
|
404315
|
+
availability: "always"
|
|
404316
|
+
},
|
|
403979
404317
|
{
|
|
403980
404318
|
name: "reload",
|
|
403981
404319
|
aliases: [],
|
|
@@ -404328,7 +404666,6 @@ registerUiCatalogFragment({
|
|
|
404328
404666
|
//#endregion
|
|
404329
404667
|
//#region src/tui/commands/resolve.ts
|
|
404330
404668
|
const LEGACY_EFFORT_COMMANDS = new Set([
|
|
404331
|
-
"model",
|
|
404332
404669
|
"automodel",
|
|
404333
404670
|
"router"
|
|
404334
404671
|
]);
|
|
@@ -416568,7 +416905,7 @@ const EFFORT_STAGE_LABELS = {
|
|
|
416568
416905
|
medium: "Deep",
|
|
416569
416906
|
high: "Forge",
|
|
416570
416907
|
xhigh: "Apex",
|
|
416571
|
-
max: "
|
|
416908
|
+
max: "Max"
|
|
416572
416909
|
};
|
|
416573
416910
|
const EFFORT_DISPLAY_LABEL_KEYS = {
|
|
416574
416911
|
off: "effort.value.off",
|
|
@@ -416697,15 +417034,13 @@ var EffortSelectorComponent = class extends Container {
|
|
|
416697
417034
|
}
|
|
416698
417035
|
if (matchesKey(data, Key.alt("s")) && this.opts.onSessionOnlySelect !== void 0) {
|
|
416699
417036
|
const effort = this.selectedEffort;
|
|
416700
|
-
if (effort
|
|
416701
|
-
else if (effort !== void 0) this.opts.onSessionOnlySelect(effort);
|
|
417037
|
+
if (effort !== void 0) this.opts.onSessionOnlySelect(effort);
|
|
416702
417038
|
return;
|
|
416703
417039
|
}
|
|
416704
417040
|
if (matchesKey(data, Key.enter)) if (this.isBlunSwarmSelected) this.opts.onBlunSwarmSelect?.();
|
|
416705
417041
|
else {
|
|
416706
417042
|
const effort = this.selectedEffort;
|
|
416707
|
-
if (effort
|
|
416708
|
-
else if (effort !== void 0) this.opts.onSelect(effort);
|
|
417043
|
+
if (effort !== void 0) this.opts.onSelect(effort);
|
|
416709
417044
|
}
|
|
416710
417045
|
}
|
|
416711
417046
|
render(width) {
|
|
@@ -416735,9 +417070,6 @@ var EffortSelectorComponent = class extends Container {
|
|
|
416735
417070
|
get isBlunSwarmSelected() {
|
|
416736
417071
|
return this.hasSeparatedBlunSwarm && this.activeIndex === this.efforts.length;
|
|
416737
417072
|
}
|
|
416738
|
-
get usesLegacyServerStageScale() {
|
|
416739
|
-
return isServerStageScale(this.efforts);
|
|
416740
|
-
}
|
|
416741
417073
|
get hasSeparatedBlunSwarm() {
|
|
416742
417074
|
return this.opts.onBlunSwarmSelect !== void 0 && !usesInlineStageScale(this.efforts);
|
|
416743
417075
|
}
|
|
@@ -417370,6 +417702,168 @@ function segmentsFor(model) {
|
|
|
417370
417702
|
if (availability === "unsupported") return ["off"];
|
|
417371
417703
|
return ["off", "on"];
|
|
417372
417704
|
}
|
|
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
|
+
};
|
|
417373
417867
|
//#endregion
|
|
417374
417868
|
//#region src/tui/components/dialogs/permission-selector.ts
|
|
417375
417869
|
function permissionOptions() {
|
|
@@ -419731,7 +420225,7 @@ registerUiCatalogFragment({
|
|
|
419731
420225
|
*/
|
|
419732
420226
|
var { projectUnaddressedTelegramContext } = createRequire(import.meta.url)("./bin/telegram-context-projection-policy.cjs");
|
|
419733
420227
|
var { enqueueTelegramUrgent, rewriteTelegramUrgentEnvelope, telegramUrgentMessage } = createRequire(import.meta.url)("./bin/telegram-urgent-policy.cjs");
|
|
419734
|
-
var { createDirectFocusController, createDirectReplyTurnStop, enqueueTelegramDirect, readDirectFocusCheckpoint, rewriteTelegramDirectEnvelope, telegramDirectMessage, writeDirectFocusCheckpoint } = createRequire(import.meta.url)("./bin/telegram-direct-focus-policy.cjs");
|
|
420228
|
+
var { createDirectFocusController, createDirectReplyTurnStop, directMessageAllowsWorkContinuation, enqueueTelegramDirect, readDirectFocusCheckpoint, rewriteTelegramDirectEnvelope, telegramDirectMessage, writeDirectFocusCheckpoint } = createRequire(import.meta.url)("./bin/telegram-direct-focus-policy.cjs");
|
|
419735
420229
|
var { enqueueTelegramAddressed } = createRequire(import.meta.url)("./bin/telegram-addressed-priority.cjs");
|
|
419736
420230
|
var { enqueueTelegramBotPriority, telegramBotPriorityMessage } = createRequire(import.meta.url)("./bin/telegram-bot-priority.cjs");
|
|
419737
420231
|
var { createAddressedChannelFocusStore } = createRequire(import.meta.url)("./bin/telegram-addressed-focus.cjs");
|
|
@@ -421175,6 +421669,47 @@ async function handleThemeCommand(host, args) {
|
|
|
421175
421669
|
}
|
|
421176
421670
|
await applyThemeChoice(host, theme);
|
|
421177
421671
|
}
|
|
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
|
+
}
|
|
421178
421713
|
async function handleEffortCommand(host, args) {
|
|
421179
421714
|
const alias = host.state.appState.model;
|
|
421180
421715
|
const model = host.state.appState.availableModels[alias];
|
|
@@ -421206,7 +421741,7 @@ async function handleEffortCommand(host, args) {
|
|
|
421206
421741
|
}));
|
|
421207
421742
|
return;
|
|
421208
421743
|
}
|
|
421209
|
-
await performEffortSelection(host, alias, arg,
|
|
421744
|
+
await performEffortSelection(host, alias, arg, !isConfiguredFredrikGlmAlias(alias, model));
|
|
421210
421745
|
}
|
|
421211
421746
|
function showEffortPicker(host, model, segments) {
|
|
421212
421747
|
const liveEffort = host.state.appState.thinkingEffort;
|
|
@@ -421217,7 +421752,7 @@ function showEffortPicker(host, model, segments) {
|
|
|
421217
421752
|
currentValue,
|
|
421218
421753
|
currentBlunSwarm: host.state.appState.swarmMode && host.state.appState.swarmModeEntry === "effort",
|
|
421219
421754
|
onSelect: (effort) => {
|
|
421220
|
-
host.restoreEditorAfter(() => performEffortSelection(host, alias, effort,
|
|
421755
|
+
host.restoreEditorAfter(() => performEffortSelection(host, alias, effort, !isConfiguredFredrikGlmAlias(alias, host.state.appState.availableModels[alias])));
|
|
421221
421756
|
},
|
|
421222
421757
|
onSessionOnlySelect: (effort) => {
|
|
421223
421758
|
host.restoreEditorAfter(() => performEffortSelection(host, alias, effort, false));
|
|
@@ -421402,7 +421937,7 @@ async function performEffortSelection(host, alias, effort, persist) {
|
|
|
421402
421937
|
host.setAppState({
|
|
421403
421938
|
thinkingEffort: effort,
|
|
421404
421939
|
modelFallbackAllowed: false,
|
|
421405
|
-
swarmMode:
|
|
421940
|
+
swarmMode: input.cliOptions.swarm === true,
|
|
421406
421941
|
swarmModeEntry: void 0
|
|
421407
421942
|
});
|
|
421408
421943
|
renderSwarmModeMarker(host, "inactive");
|
|
@@ -423378,7 +423913,6 @@ async function handleGoalCommand(host, args) {
|
|
|
423378
423913
|
}
|
|
423379
423914
|
const IDEA_CONTRACT_MARKER = "Work as a self-directing employee:";
|
|
423380
423915
|
const IDEA_ALLOWED_CHANNELS = Object.freeze([]);
|
|
423381
|
-
const GOAL_TODO_REFRESH_WORK_CALL_LIMIT = 8;
|
|
423382
423916
|
const GOAL_TODO_EVIDENCE_LIMIT = 8;
|
|
423383
423917
|
const TODO_MAINTENANCE_RECOVERY_TOOL_NAMES = new Set([
|
|
423384
423918
|
"TodoList",
|
|
@@ -423404,6 +423938,22 @@ function ideaTodos(agent) {
|
|
|
423404
423938
|
const value = agent.tools.store?.["todo"];
|
|
423405
423939
|
return Array.isArray(value) ? value : [];
|
|
423406
423940
|
}
|
|
423941
|
+
function goalTodoProgressState(agent) {
|
|
423942
|
+
return agent.goalTodoPolicyState ??= {
|
|
423943
|
+
workCallsSinceRefresh: 0,
|
|
423944
|
+
refreshRequired: false,
|
|
423945
|
+
unchangedRefreshStreak: 0,
|
|
423946
|
+
evidenceRevision: 0,
|
|
423947
|
+
lastMaintenanceEvidenceRevision: 0
|
|
423948
|
+
};
|
|
423949
|
+
}
|
|
423950
|
+
function enforceTodoListBounds(agent, context) {
|
|
423951
|
+
if (context.toolCall.name !== "TodoList" || !Array.isArray(context.args?.todos)) return;
|
|
423952
|
+
return assessTodoListBounds({
|
|
423953
|
+
currentTodos: ideaTodos(agent),
|
|
423954
|
+
nextTodos: context.args.todos
|
|
423955
|
+
});
|
|
423956
|
+
}
|
|
423407
423957
|
function validInitialIdeaPlan(value) {
|
|
423408
423958
|
if (!Array.isArray(value) || value.length === 0) return false;
|
|
423409
423959
|
let active = 0;
|
|
@@ -423440,28 +423990,21 @@ function goalTodoEvidenceLabel(toolName, args, isError) {
|
|
|
423440
423990
|
function recordGoalTodoEvidence(agent, toolName, args, isError) {
|
|
423441
423991
|
if (isIdeaGoal(agent) || agent.goal.getActiveGoal() === null) return;
|
|
423442
423992
|
const name = String(toolName ?? "");
|
|
423443
|
-
const progress = agent
|
|
423444
|
-
|
|
423445
|
-
refreshRequired: false
|
|
423446
|
-
};
|
|
423447
|
-
if (name === "TodoList") {
|
|
423448
|
-
if (isError !== true) progress.recentEvidence = [];
|
|
423449
|
-
return;
|
|
423450
|
-
}
|
|
423993
|
+
const progress = goalTodoProgressState(agent);
|
|
423994
|
+
if (name === "TodoList") return;
|
|
423451
423995
|
if (name === "UpdateGoal" || TELEGRAM_DELIVERY_TOOL_RE.test(name)) return;
|
|
423452
423996
|
const recentEvidence = Array.isArray(progress.recentEvidence) ? progress.recentEvidence : [];
|
|
423453
423997
|
recentEvidence.push(goalTodoEvidenceLabel(name, args, isError));
|
|
423454
423998
|
progress.recentEvidence = recentEvidence.slice(-GOAL_TODO_EVIDENCE_LIMIT);
|
|
423999
|
+
progress.evidenceRevision = (Number(progress.evidenceRevision) || 0) + 1;
|
|
423455
424000
|
}
|
|
423456
424001
|
function goalTodoMaintenanceMode(agent) {
|
|
423457
424002
|
if (isIdeaGoal(agent)) return null;
|
|
423458
424003
|
const todos = ideaTodos(agent);
|
|
423459
424004
|
if (todos.length === 0) return agent.goal.getActiveGoal() === null ? null : "initial";
|
|
423460
|
-
const progress = agent
|
|
423461
|
-
|
|
423462
|
-
|
|
423463
|
-
};
|
|
423464
|
-
if (!progress.refreshRequired && progress.workCallsSinceRefresh < GOAL_TODO_REFRESH_WORK_CALL_LIMIT) return null;
|
|
424005
|
+
const progress = goalTodoProgressState(agent);
|
|
424006
|
+
const refreshWorkCallLimit = todoRefreshWorkCallLimit(progress.unchangedRefreshStreak);
|
|
424007
|
+
if (!progress.refreshRequired && progress.workCallsSinceRefresh < refreshWorkCallLimit) return null;
|
|
423465
424008
|
progress.refreshRequired = true;
|
|
423466
424009
|
return "refresh";
|
|
423467
424010
|
}
|
|
@@ -423475,8 +424018,9 @@ function goalTodoMaintenanceTools(eligibleTools, selectedTools) {
|
|
|
423475
424018
|
}
|
|
423476
424019
|
function buildGoalTodoMaintenanceSystemPrompt(agent, mode) {
|
|
423477
424020
|
const todos = ideaTodos(agent);
|
|
424021
|
+
const requireConcreteProgress = mode === "refresh" && (agent.goalTodoPolicyState?.unchangedRefreshStreak ?? 0) >= 2;
|
|
423478
424022
|
const visibleTodoList = todos.length === 0 ? "The visible TodoList is empty." : ["Current visible TodoList:", ...todos.map((todo) => `- [${String(todo?.status ?? "pending")}] ${String(todo?.title ?? "").trim()}`)].join("\n");
|
|
423479
|
-
const action = mode === "initial" ? "Create the visible task-specific TodoList now. Keep exactly one item in_progress and every later item pending." : "Update the visible TodoList now, before any more task work. Mark only evidenced steps done, keep the actual current step in_progress, and leave later steps pending. If the current title is stale, refine it to the concrete verified substep.";
|
|
424023
|
+
const action = mode === "initial" ? "Create the visible task-specific TodoList now. Keep exactly one item in_progress and every later item pending." : requireConcreteProgress ? "Recent TodoList refreshes stayed semantically unchanged despite new work-tool evidence. Make a truthful concrete transition now: mark evidenced items done, refine the active title to the next verified substep, or record blocked, waiting_approval, or aborted when that is the real state. If the available evidence proves no boundary, preserve the list unchanged; the call remains executable." : "Update the visible TodoList now, before any more task work. Mark only evidenced steps done, keep the actual current step in_progress, and leave later steps pending. If the current title is stale, refine it to the concrete verified substep.";
|
|
423480
424024
|
return `<todo-maintenance>
|
|
423481
424025
|
TODO MAINTENANCE IS THE ONLY ACTION FOR THIS STEP.
|
|
423482
424026
|
${action}
|
|
@@ -423488,11 +424032,12 @@ ${visibleTodoList}
|
|
|
423488
424032
|
function buildGoalTodoMaintenanceMessages(agent, mode) {
|
|
423489
424033
|
const goal = agent.goal.getActiveGoal();
|
|
423490
424034
|
const todos = ideaTodos(agent);
|
|
424035
|
+
const requireConcreteProgress = mode === "refresh" && (agent.goalTodoPolicyState?.unchangedRefreshStreak ?? 0) >= 2;
|
|
423491
424036
|
const recentEvidence = Array.isArray(agent.goalTodoPolicyState?.recentEvidence) ? agent.goalTodoPolicyState.recentEvidence.slice(-GOAL_TODO_EVIDENCE_LIMIT) : [];
|
|
423492
424037
|
const objective = String(goal?.objective ?? "Continue the current multi-step task.").trim();
|
|
423493
424038
|
const visibleTodoList = todos.length === 0 ? "The visible TodoList is empty." : ["Current visible TodoList:", ...todos.map((todo) => `- [${String(todo?.status ?? "pending")}] ${String(todo?.title ?? "").trim()}`)].join("\n");
|
|
423494
424039
|
const verifiedEvidence = recentEvidence.length === 0 ? "No new work-tool evidence is available." : ["Recent bounded work-tool evidence since the last accepted TodoList:", ...recentEvidence.map((entry) => `- ${entry}`)].join("\n");
|
|
423495
|
-
const action = mode === "initial" ? "Create the task-specific TodoList from the active objective. Keep exactly one item in_progress and every later item pending." : "Refresh the TodoList from the current verified state. Mark finished work done, keep the actual current step in_progress, and leave later work pending. Completed items disappear automatically after this call.";
|
|
424040
|
+
const action = mode === "initial" ? "Create the task-specific TodoList from the active objective. Keep exactly one item in_progress and every later item pending." : requireConcreteProgress ? "The recent refreshes stayed semantically unchanged despite new evidence. Make a truthful concrete transition now: finish evidenced items, refine the active title to the next verified substep, or use blocked, waiting_approval, or aborted when accurate. If no boundary is proven, preserve the list unchanged; never invent progress." : "Refresh the TodoList from the current verified state. Mark finished work done, keep the actual current step in_progress, and leave later work pending. Completed items disappear automatically after this call.";
|
|
423496
424041
|
const request = [
|
|
423497
424042
|
"Return exactly one TodoList tool call and no prose.",
|
|
423498
424043
|
action,
|
|
@@ -423511,10 +424056,7 @@ function enforceGoalTodoPolicy(agent, context) {
|
|
|
423511
424056
|
if (TELEGRAM_DELIVERY_TOOL_RE.test(String(context.toolCall.name ?? ""))) return;
|
|
423512
424057
|
const activeGoal = agent.goal.getActiveGoal();
|
|
423513
424058
|
const todos = ideaTodos(agent);
|
|
423514
|
-
const progress = agent
|
|
423515
|
-
workCallsSinceRefresh: 0,
|
|
423516
|
-
refreshRequired: false
|
|
423517
|
-
};
|
|
424059
|
+
const progress = goalTodoProgressState(agent);
|
|
423518
424060
|
if (todos.length === 0) {
|
|
423519
424061
|
const startsTrackedList = context.toolCall.name === "TodoList" && Array.isArray(context.args?.todos) && context.args.todos.length > 0;
|
|
423520
424062
|
if (activeGoal === null && !startsTrackedList) return;
|
|
@@ -423530,6 +424072,9 @@ function enforceGoalTodoPolicy(agent, context) {
|
|
|
423530
424072
|
};
|
|
423531
424073
|
progress.workCallsSinceRefresh = 0;
|
|
423532
424074
|
progress.refreshRequired = false;
|
|
424075
|
+
progress.unchangedRefreshStreak = 0;
|
|
424076
|
+
progress.recentEvidence = [];
|
|
424077
|
+
progress.lastMaintenanceEvidenceRevision = Number(progress.evidenceRevision) || 0;
|
|
423533
424078
|
progress.allVisibleWorkCompleted = false;
|
|
423534
424079
|
return;
|
|
423535
424080
|
}
|
|
@@ -423553,9 +424098,26 @@ function enforceGoalTodoPolicy(agent, context) {
|
|
|
423553
424098
|
reason: "A maintained TodoList must keep exactly one item in_progress while unfinished work remains."
|
|
423554
424099
|
};
|
|
423555
424100
|
}
|
|
424101
|
+
const evidenceRevision = Number(progress.evidenceRevision) || 0;
|
|
424102
|
+
const lastMaintenanceEvidenceRevision = Number(progress.lastMaintenanceEvidenceRevision) || 0;
|
|
424103
|
+
const maintenanceUpdate = assessTodoMaintenanceUpdate({
|
|
424104
|
+
currentTodos: todos,
|
|
424105
|
+
nextTodos,
|
|
424106
|
+
unchangedRefreshStreak: progress.unchangedRefreshStreak,
|
|
424107
|
+
recentEvidenceCount: evidenceRevision > lastMaintenanceEvidenceRevision ? (progress.recentEvidence?.length ?? 0) : 0
|
|
424108
|
+
});
|
|
423556
424109
|
progress.allVisibleWorkCompleted = nextTodos.length > 0 && nextTodos.every((todo) => todo?.status === "done");
|
|
423557
424110
|
progress.workCallsSinceRefresh = 0;
|
|
423558
424111
|
progress.refreshRequired = false;
|
|
424112
|
+
progress.unchangedRefreshStreak = maintenanceUpdate.unchangedRefreshStreak;
|
|
424113
|
+
progress.lastMaintenanceEvidenceRevision = evidenceRevision;
|
|
424114
|
+
if (!maintenanceUpdate.preserveRecentEvidence) progress.recentEvidence = [];
|
|
424115
|
+
if (maintenanceUpdate.emitStalledWarning) agent.emitEvent({
|
|
424116
|
+
type: "warning",
|
|
424117
|
+
code: "todo-maintenance-stalled",
|
|
424118
|
+
message: "TodoList stayed semantically unchanged across three evidence-bearing maintenance cycles. Work tools remain available; the next maintenance check is backed off while the active step is refined.",
|
|
424119
|
+
blocked: false
|
|
424120
|
+
});
|
|
423559
424121
|
return;
|
|
423560
424122
|
}
|
|
423561
424123
|
if (activeGoal !== null && context.toolCall.name === "UpdateGoal" && (context.args?.status === "complete" || context.args?.status === "blocked")) {
|
|
@@ -423571,7 +424133,7 @@ function enforceGoalTodoPolicy(agent, context) {
|
|
|
423571
424133
|
}
|
|
423572
424134
|
if (context.toolCall.id === context.toolCalls[0]?.id) {
|
|
423573
424135
|
progress.workCallsSinceRefresh += 1;
|
|
423574
|
-
if (progress.workCallsSinceRefresh >
|
|
424136
|
+
if (progress.workCallsSinceRefresh > todoRefreshWorkCallLimit(progress.unchangedRefreshStreak)) progress.refreshRequired = true;
|
|
423575
424137
|
}
|
|
423576
424138
|
if (!progress.refreshRequired) return;
|
|
423577
424139
|
return {
|
|
@@ -496816,6 +497378,25 @@ async function handlePremortemCommand(host, args) {
|
|
|
496816
497378
|
}
|
|
496817
497379
|
host.sendMessage(host.requireSession(), plan, { parts: buildPremortemPrompt(plan) });
|
|
496818
497380
|
}
|
|
497381
|
+
function findLatestAssistantResponse(entries) {
|
|
497382
|
+
for (let index = entries.length - 1; index >= 0; index--) {
|
|
497383
|
+
const entry = entries[index];
|
|
497384
|
+
if (entry?.kind === "assistant" && typeof entry.content === "string" && entry.content.trim().length > 0) return entry.content;
|
|
497385
|
+
}
|
|
497386
|
+
}
|
|
497387
|
+
async function handleCopyCommand(host) {
|
|
497388
|
+
const text = findLatestAssistantResponse(host.state.transcriptEntries);
|
|
497389
|
+
if (text === void 0) {
|
|
497390
|
+
host.showStatus(uiText("copy.status.none"));
|
|
497391
|
+
return;
|
|
497392
|
+
}
|
|
497393
|
+
try {
|
|
497394
|
+
await copyTextToClipboard(text);
|
|
497395
|
+
host.showStatus(uiText("copy.status.copied"));
|
|
497396
|
+
} catch (error) {
|
|
497397
|
+
host.showError(uiText("copy.error.failed", { error: formatErrorMessage$2(error) }));
|
|
497398
|
+
}
|
|
497399
|
+
}
|
|
496819
497400
|
async function handleBuiltInSlashCommand(host, name, args) {
|
|
496820
497401
|
switch (name) {
|
|
496821
497402
|
case "exit":
|
|
@@ -496858,6 +497439,9 @@ async function handleBuiltInSlashCommand(host, name, args) {
|
|
|
496858
497439
|
case "experiments":
|
|
496859
497440
|
await showExperimentsPanel(host);
|
|
496860
497441
|
return;
|
|
497442
|
+
case "copy":
|
|
497443
|
+
await handleCopyCommand(host);
|
|
497444
|
+
return;
|
|
496861
497445
|
case "reload":
|
|
496862
497446
|
await handleReloadCommand(host);
|
|
496863
497447
|
return;
|
|
@@ -496870,6 +497454,9 @@ async function handleBuiltInSlashCommand(host, name, args) {
|
|
|
496870
497454
|
case "theme":
|
|
496871
497455
|
await handleThemeCommand(host, args);
|
|
496872
497456
|
return;
|
|
497457
|
+
case "model":
|
|
497458
|
+
await handleModelCommand(host, args);
|
|
497459
|
+
return;
|
|
496873
497460
|
case "effort":
|
|
496874
497461
|
await handleEffortCommand(host, args);
|
|
496875
497462
|
return;
|
|
@@ -503089,7 +503676,10 @@ function applyManagedAccountContext(models, maxContextTokens) {
|
|
|
503089
503676
|
maxContextSize: maxContextTokens
|
|
503090
503677
|
} }
|
|
503091
503678
|
};
|
|
503092
|
-
return {
|
|
503679
|
+
return {
|
|
503680
|
+
[BLUN_KING_MODEL_ALIAS]: king,
|
|
503681
|
+
...configuredFredrikGlmModels(models)
|
|
503682
|
+
};
|
|
503093
503683
|
}
|
|
503094
503684
|
function normalizeKingProductEffort(value) {
|
|
503095
503685
|
if (value === "none" || value === "minimal" || value === "off") return "low";
|
|
@@ -503145,7 +503735,11 @@ function nextManagedQuotaWarning(windows, highestShown) {
|
|
|
503145
503735
|
//#region src/tui/controllers/auth-flow.ts
|
|
503146
503736
|
function managedProviderOnly(providers) {
|
|
503147
503737
|
const managed = providers[DEFAULT_OAUTH_PROVIDER_NAME];
|
|
503148
|
-
|
|
503738
|
+
const fredrikGlm = configuredFredrikGlmProvider(providers);
|
|
503739
|
+
return {
|
|
503740
|
+
...managed === void 0 ? {} : { [DEFAULT_OAUTH_PROVIDER_NAME]: managed },
|
|
503741
|
+
...fredrikGlm === void 0 ? {} : { [FREDRIK_GLM_PROVIDER_ID]: fredrikGlm }
|
|
503742
|
+
};
|
|
503149
503743
|
}
|
|
503150
503744
|
var AuthFlowController = class {
|
|
503151
503745
|
host;
|
|
@@ -517558,6 +518152,8 @@ var BlunTUI = class {
|
|
|
517558
518152
|
yolo: startupInput.cliOptions.yolo,
|
|
517559
518153
|
auto: startupInput.cliOptions.auto,
|
|
517560
518154
|
plan: startupInput.cliOptions.plan,
|
|
518155
|
+
effort: startupInput.cliOptions.effort,
|
|
518156
|
+
swarm: startupInput.cliOptions.swarm,
|
|
517561
518157
|
model: startupInput.cliOptions.model,
|
|
517562
518158
|
startupNotice: startupInput.startupNotice
|
|
517563
518159
|
}
|
|
@@ -517974,6 +518570,7 @@ var BlunTUI = class {
|
|
|
517974
518570
|
const createSessionOptions = {
|
|
517975
518571
|
workDir,
|
|
517976
518572
|
model: BLUN_KING_MODEL_ALIAS,
|
|
518573
|
+
thinking: startup.effort,
|
|
517977
518574
|
permission: startup.auto ? "auto" : startup.yolo ? "yolo" : void 0,
|
|
517978
518575
|
planMode: startup.plan ? true : void 0
|
|
517979
518576
|
};
|
|
@@ -518020,7 +518617,7 @@ var BlunTUI = class {
|
|
|
518020
518617
|
}
|
|
518021
518618
|
}
|
|
518022
518619
|
} else session = await this.harness.createSession(createSessionOptions);
|
|
518023
|
-
if (session !== void 0 && shouldReplayHistory) await this.applyStartupModesToResumedSession(session);
|
|
518620
|
+
if (session !== void 0 && (shouldReplayHistory || startup.effort !== void 0 || startup.swarm)) await this.applyStartupModesToResumedSession(session);
|
|
518024
518621
|
} catch (error) {
|
|
518025
518622
|
if (!isOAuthLoginRequiredError(error)) throw error;
|
|
518026
518623
|
this.authFlow.enterLoginRequiredStartupState();
|
|
@@ -518071,10 +518668,6 @@ var BlunTUI = class {
|
|
|
518071
518668
|
const sessionId = session.id;
|
|
518072
518669
|
const autostartPrompt = autostart.observation === void 0 ? GOAL_CONTINUATION_PROMPT : `${GOAL_CONTINUATION_PROMPT}\n\n${autostart.observation}`;
|
|
518073
518670
|
this.beginSessionRequest();
|
|
518074
|
-
this.setAppState({
|
|
518075
|
-
model: BLUN_KING_MODEL_ALIAS,
|
|
518076
|
-
modelFallbackAllowed: false
|
|
518077
|
-
});
|
|
518078
518671
|
try {
|
|
518079
518672
|
const result = await session.promptAccepted(autostartPrompt);
|
|
518080
518673
|
if (!result.accepted && this.session?.id === sessionId) {
|
|
@@ -519111,10 +519704,6 @@ var BlunTUI = class {
|
|
|
519111
519704
|
contextOnly: false
|
|
519112
519705
|
};
|
|
519113
519706
|
this.pendingChannelReplyGuard = installedGuard;
|
|
519114
|
-
this.setAppState({
|
|
519115
|
-
model: BLUN_KING_MODEL_ALIAS,
|
|
519116
|
-
modelFallbackAllowed: false
|
|
519117
|
-
});
|
|
519118
519707
|
session.promptAccepted(options?.parts ?? input).then((result) => {
|
|
519119
519708
|
if (result.duplicate === true) {
|
|
519120
519709
|
this.traceTelegramDelivery?.({ stage: "committed", ...context.item.channelDeliveryTrace, route: "channel_command_prompt", reason: "duplicate" });
|
|
@@ -519172,10 +519761,6 @@ var BlunTUI = class {
|
|
|
519172
519761
|
};
|
|
519173
519762
|
if (installedGuard !== void 0) this.pendingChannelReplyGuard = installedGuard;
|
|
519174
519763
|
const imagePart = channelImagePath !== void 0 ? buildChannelImagePart(channelImagePath) : void 0;
|
|
519175
|
-
this.setAppState({
|
|
519176
|
-
model: BLUN_KING_MODEL_ALIAS,
|
|
519177
|
-
modelFallbackAllowed: false
|
|
519178
|
-
});
|
|
519179
519764
|
const directNotice = channelDirect === true ? ["A private Telegram DM has priority over background, group, and loop work.", channelDirectResume === true ? "The user explicitly resumed work. Answer any remaining direct content, then continue the exact saved work checkpoint." : "The runtime saved the active work checkpoint. Answer the private conversation naturally, without exposing internal task, cron, checkpoint, queue, or lane narration. Unless the user explicitly asks to pause, stop, or wait, continue the exact saved work checkpoint automatically after the direct conversation."].join("\n") : void 0;
|
|
519180
519765
|
const focusedModelInput = directNotice === void 0 ? modelInput : `${directNotice}\n\n${modelInput}`;
|
|
519181
519766
|
const promptInput = imagePart !== void 0 && this.canReadImages() ? [{
|
|
@@ -519376,10 +519961,6 @@ var BlunTUI = class {
|
|
|
519376
519961
|
return;
|
|
519377
519962
|
}
|
|
519378
519963
|
this.beginSessionRequest();
|
|
519379
|
-
this.setAppState({
|
|
519380
|
-
model: BLUN_KING_MODEL_ALIAS,
|
|
519381
|
-
modelFallbackAllowed: false
|
|
519382
|
-
});
|
|
519383
519964
|
session.promptAccepted(TRUNCATED_REPLY_CONTINUATION_PROMPT).then((result) => {
|
|
519384
519965
|
if (!result.accepted) this.failTruncatedChannelReplyRecovery(new Error("continuation prompt rejected"));
|
|
519385
519966
|
}).catch((error) => {
|
|
@@ -519650,10 +520231,6 @@ var BlunTUI = class {
|
|
|
519650
520231
|
});
|
|
519651
520232
|
this.beginSessionRequest();
|
|
519652
520233
|
const sdkInput = options?.parts ?? input;
|
|
519653
|
-
this.setAppState({
|
|
519654
|
-
model: BLUN_KING_MODEL_ALIAS,
|
|
519655
|
-
modelFallbackAllowed: false
|
|
519656
|
-
});
|
|
519657
520234
|
session.promptAccepted(sdkInput).catch((error) => {
|
|
519658
520235
|
finishPersonalMemoryRememberIntentTurn(session.id);
|
|
519659
520236
|
const message = formatErrorMessage$2(error);
|
|
@@ -519768,18 +520345,19 @@ var BlunTUI = class {
|
|
|
519768
520345
|
}
|
|
519769
520346
|
}
|
|
519770
520347
|
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;
|
|
519771
520351
|
let effectivePatch = {
|
|
519772
520352
|
...patch,
|
|
519773
520353
|
modelFallbackAllowed: false,
|
|
519774
|
-
..."model" in patch && patch.model?.trim().length ? { model:
|
|
519775
|
-
..."activeResponderModel" in patch && patch.activeResponderModel != null ? { activeResponderModel:
|
|
520354
|
+
..."model" in patch && patch.model?.trim().length ? { model: allowedModel(patch.model) } : {},
|
|
520355
|
+
..."activeResponderModel" in patch && patch.activeResponderModel != null ? { activeResponderModel: allowedModel(patch.activeResponderModel) } : {}
|
|
519776
520356
|
};
|
|
519777
520357
|
if ("availableModels" in patch || "managedAccountContextTokens" in patch) {
|
|
519778
|
-
|
|
519779
|
-
const effectiveModels = applyManagedAccountContext(patch.availableModels ?? this.state.appState.availableModels, isValidManagedContextTokens(managedAccountContextTokens) ? managedAccountContextTokens : void 0);
|
|
519780
|
-
if (effectiveModels !== patch.availableModels) effectivePatch = {
|
|
520358
|
+
if (availableModels !== patch.availableModels) effectivePatch = {
|
|
519781
520359
|
...effectivePatch,
|
|
519782
|
-
availableModels
|
|
520360
|
+
availableModels
|
|
519783
520361
|
};
|
|
519784
520362
|
}
|
|
519785
520363
|
if (!hasPatchChanges(this.state.appState, effectivePatch)) return;
|
|
@@ -519856,7 +520434,11 @@ var BlunTUI = class {
|
|
|
519856
520434
|
return this.harness.createSession(options);
|
|
519857
520435
|
}
|
|
519858
520436
|
async setSession(session, options = {}) {
|
|
519859
|
-
await session.
|
|
520437
|
+
const resumedStatus = await session.getStatus();
|
|
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
|
+
}
|
|
519860
520442
|
await this.personalMemoryController.clear(this.session);
|
|
519861
520443
|
const previous = this.unloadCurrentSession(approvalCancellationFeedback("switching_session"));
|
|
519862
520444
|
await this.managedQuotaWarningPersistence;
|
|
@@ -519864,10 +520446,7 @@ var BlunTUI = class {
|
|
|
519864
520446
|
resetChannelPreambleState(this.channelPreamble);
|
|
519865
520447
|
this.session = session;
|
|
519866
520448
|
this.managedQuotaWarningController.restore(session.id, managedQuotaWarningThresholdFromMetadata(session.getResumeState()?.sessionMetadata?.custom));
|
|
519867
|
-
this.setAppState({
|
|
519868
|
-
model: BLUN_KING_MODEL_ALIAS,
|
|
519869
|
-
modelFallbackAllowed: false
|
|
519870
|
-
});
|
|
520449
|
+
this.setAppState({ modelFallbackAllowed: false });
|
|
519871
520450
|
this.harness.setTelemetryContext({ sessionId: session.id });
|
|
519872
520451
|
this.registerSessionHandlers(session);
|
|
519873
520452
|
this.syncAdditionalDirs(session);
|
|
@@ -519879,7 +520458,7 @@ var BlunTUI = class {
|
|
|
519879
520458
|
const [status, goalResult, loopResult] = await Promise.all([session.getStatus(), session.getGoal(), session.getLoop()]);
|
|
519880
520459
|
this.setAppState({
|
|
519881
520460
|
sessionId: session.id,
|
|
519882
|
-
model: BLUN_KING_MODEL_ALIAS,
|
|
520461
|
+
model: status.model ?? BLUN_KING_MODEL_ALIAS,
|
|
519883
520462
|
modelFallbackAllowed: false,
|
|
519884
520463
|
activeResponderModel: null,
|
|
519885
520464
|
thinkingEffort: status.thinkingEffort,
|
|
@@ -519913,6 +520492,8 @@ var BlunTUI = class {
|
|
|
519913
520492
|
const { startup } = this.options;
|
|
519914
520493
|
if (startup.auto) await session.setPermission("auto");
|
|
519915
520494
|
else if (startup.yolo) await session.setPermission("yolo");
|
|
520495
|
+
if (startup.effort !== void 0) await session.setThinking(startup.effort);
|
|
520496
|
+
if (startup.swarm && !(await session.getStatus()).swarmMode) await session.setSwarmMode(true, "effort");
|
|
519916
520497
|
if (startup.plan) {
|
|
519917
520498
|
if (!(await session.getStatus()).planMode) await session.setPlanMode(true);
|
|
519918
520499
|
}
|
|
@@ -519921,6 +520502,8 @@ var BlunTUI = class {
|
|
|
519921
520502
|
const { startup } = this.options;
|
|
519922
520503
|
if (startup.auto) this.setAppState({ permissionMode: "auto" });
|
|
519923
520504
|
else if (startup.yolo) this.setAppState({ permissionMode: "yolo" });
|
|
520505
|
+
if (startup.effort !== void 0) this.setAppState({ thinkingEffort: startup.effort });
|
|
520506
|
+
if (startup.swarm) this.setAppState({ swarmMode: true, swarmModeEntry: "effort" });
|
|
519924
520507
|
if (startup.plan) this.setAppState({ planMode: true });
|
|
519925
520508
|
}
|
|
519926
520509
|
async activateRuntime() {
|
|
@@ -520095,7 +520678,6 @@ var BlunTUI = class {
|
|
|
520095
520678
|
this.approvalController.cancelAll(approvalCancellationFeedback("reloading_session"));
|
|
520096
520679
|
this.questionController.cancelAll("");
|
|
520097
520680
|
this.resetSessionRuntime();
|
|
520098
|
-
await session.setModel(BLUN_KING_MODEL_ALIAS, { allowFallback: false });
|
|
520099
520681
|
this.session = session;
|
|
520100
520682
|
this.harness.setTelemetryContext({ sessionId: session.id });
|
|
520101
520683
|
this.registerSessionHandlers(session);
|