@runtypelabs/cli 2.1.0 → 2.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +211 -9
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -8469,8 +8469,12 @@ function setStoredToolPayloadField(payloads, toolId, field, value) {
|
|
|
8469
8469
|
const next = { ...payloads.get(toolId) ?? {} };
|
|
8470
8470
|
if (value === void 0) {
|
|
8471
8471
|
delete next[field];
|
|
8472
|
+
} else if (field === "parameters") {
|
|
8473
|
+
next.parameters = value;
|
|
8474
|
+
} else if (field === "result") {
|
|
8475
|
+
next.result = value;
|
|
8472
8476
|
} else {
|
|
8473
|
-
next
|
|
8477
|
+
next.streamedInput = value;
|
|
8474
8478
|
}
|
|
8475
8479
|
if (next.parameters === void 0 && next.result === void 0 && next.streamedInput === void 0) {
|
|
8476
8480
|
payloads.delete(toolId);
|
|
@@ -14797,6 +14801,8 @@ var NETWORK_ERROR_PATTERNS = [
|
|
|
14797
14801
|
"econnrefused",
|
|
14798
14802
|
"econnaborted",
|
|
14799
14803
|
"etimedout",
|
|
14804
|
+
"timeout",
|
|
14805
|
+
"request timeout",
|
|
14800
14806
|
"enetunreach",
|
|
14801
14807
|
"enetdown",
|
|
14802
14808
|
"ehostunreach",
|
|
@@ -14816,12 +14822,78 @@ var NETWORK_ERROR_PATTERNS = [
|
|
|
14816
14822
|
"unable to connect",
|
|
14817
14823
|
"err_network"
|
|
14818
14824
|
];
|
|
14825
|
+
var LOCAL_NETWORK_PATTERNS = [
|
|
14826
|
+
"enetunreach",
|
|
14827
|
+
"enetdown",
|
|
14828
|
+
"enotfound",
|
|
14829
|
+
"network error",
|
|
14830
|
+
"network request failed",
|
|
14831
|
+
"networkerror",
|
|
14832
|
+
"err_network"
|
|
14833
|
+
];
|
|
14834
|
+
var SERVER_UNREACHABLE_PATTERNS = [
|
|
14835
|
+
"econnrefused",
|
|
14836
|
+
"econnreset",
|
|
14837
|
+
"connection refused",
|
|
14838
|
+
"connection reset",
|
|
14839
|
+
"ehostunreach"
|
|
14840
|
+
];
|
|
14841
|
+
function collectErrorSignals(error, seen = /* @__PURE__ */ new Set()) {
|
|
14842
|
+
if (error == null || seen.has(error)) return [];
|
|
14843
|
+
if (typeof error === "string") return [error];
|
|
14844
|
+
if (typeof error !== "object") return [String(error)];
|
|
14845
|
+
seen.add(error);
|
|
14846
|
+
const parts = [];
|
|
14847
|
+
if ("message" in error && typeof error.message === "string") {
|
|
14848
|
+
parts.push(error.message);
|
|
14849
|
+
}
|
|
14850
|
+
if ("code" in error && typeof error.code === "string") {
|
|
14851
|
+
parts.push(error.code);
|
|
14852
|
+
}
|
|
14853
|
+
if ("cause" in error) {
|
|
14854
|
+
parts.push(...collectErrorSignals(error.cause, seen));
|
|
14855
|
+
}
|
|
14856
|
+
return parts;
|
|
14857
|
+
}
|
|
14858
|
+
function getNetworkErrorContext(error) {
|
|
14859
|
+
const signals = collectErrorSignals(error);
|
|
14860
|
+
const fallbackMessage = error instanceof Error ? error.message : String(error);
|
|
14861
|
+
const uniqueSignals = [...new Set(signals.map((signal) => signal.trim()).filter(Boolean))];
|
|
14862
|
+
const searchText = uniqueSignals.join(" ").toLowerCase();
|
|
14863
|
+
const detailMessage = uniqueSignals.find((signal) => signal.toLowerCase() !== "fetch failed") ?? fallbackMessage;
|
|
14864
|
+
return {
|
|
14865
|
+
searchText,
|
|
14866
|
+
detailMessage
|
|
14867
|
+
};
|
|
14868
|
+
}
|
|
14869
|
+
function describeNetworkError(error) {
|
|
14870
|
+
const { searchText, detailMessage } = getNetworkErrorContext(error);
|
|
14871
|
+
const isLocalNetwork = LOCAL_NETWORK_PATTERNS.some((p) => searchText.includes(p));
|
|
14872
|
+
const isServerUnreachable = SERVER_UNREACHABLE_PATTERNS.some((p) => searchText.includes(p));
|
|
14873
|
+
const isTimeout = searchText.includes("etimedout") || searchText.includes("timeout");
|
|
14874
|
+
const lines = [];
|
|
14875
|
+
if (isLocalNetwork) {
|
|
14876
|
+
lines.push("Could not reach the Runtype API \u2014 your network appears to be offline.");
|
|
14877
|
+
lines.push("Check your internet connection and try again.");
|
|
14878
|
+
} else if (isServerUnreachable) {
|
|
14879
|
+
lines.push("Could not reach the Runtype API \u2014 the server is not responding.");
|
|
14880
|
+
lines.push("The service may be temporarily unavailable. Try again in a few minutes.");
|
|
14881
|
+
} else if (isTimeout) {
|
|
14882
|
+
lines.push("Could not reach the Runtype API \u2014 the request timed out.");
|
|
14883
|
+
lines.push("This could be a network issue or the server may be under heavy load.");
|
|
14884
|
+
} else {
|
|
14885
|
+
lines.push("Could not reach the Runtype API \u2014 a network error occurred.");
|
|
14886
|
+
lines.push("Check your internet connection or try again in a few minutes.");
|
|
14887
|
+
}
|
|
14888
|
+
lines.push(`Details: ${detailMessage}`);
|
|
14889
|
+
return lines;
|
|
14890
|
+
}
|
|
14819
14891
|
function isTransientNetworkError(error) {
|
|
14820
14892
|
if (error instanceof RuntypeApiError) return false;
|
|
14821
|
-
const
|
|
14822
|
-
if (error instanceof TypeError &&
|
|
14893
|
+
const { searchText } = getNetworkErrorContext(error);
|
|
14894
|
+
if (error instanceof TypeError && searchText.includes("fetch")) return true;
|
|
14823
14895
|
if (error instanceof DOMException && error.name === "AbortError") return true;
|
|
14824
|
-
return NETWORK_ERROR_PATTERNS.some((pattern) =>
|
|
14896
|
+
return NETWORK_ERROR_PATTERNS.some((pattern) => searchText.includes(pattern));
|
|
14825
14897
|
}
|
|
14826
14898
|
async function retryOnNetworkError(fn, opts = {}) {
|
|
14827
14899
|
const maxRetries = opts.maxRetries ?? 3;
|
|
@@ -14898,9 +14970,8 @@ function describeMarathonApiError(error) {
|
|
|
14898
14970
|
if (!(error instanceof Error)) {
|
|
14899
14971
|
return ["Task failed: Unknown error"];
|
|
14900
14972
|
}
|
|
14901
|
-
if (
|
|
14902
|
-
|
|
14903
|
-
return [`Task failed: ${message}`];
|
|
14973
|
+
if (isTransientNetworkError(error)) {
|
|
14974
|
+
return describeNetworkError(error);
|
|
14904
14975
|
}
|
|
14905
14976
|
return [`Task failed: ${error.message}`];
|
|
14906
14977
|
}
|
|
@@ -16134,6 +16205,57 @@ function createRunCheckTool() {
|
|
|
16134
16205
|
}
|
|
16135
16206
|
};
|
|
16136
16207
|
}
|
|
16208
|
+
function createSearchSessionHistoryTool(client, taskName) {
|
|
16209
|
+
return {
|
|
16210
|
+
description: "Search across all prior marathon sessions for specific information, decisions, findings, or tool outputs. Use this when you need to recall something from earlier sessions that may have been compacted away. Returns ranked results with content snippets from matching sessions.",
|
|
16211
|
+
parametersSchema: {
|
|
16212
|
+
type: "object",
|
|
16213
|
+
properties: {
|
|
16214
|
+
query: {
|
|
16215
|
+
type: "string",
|
|
16216
|
+
description: 'What to search for (e.g. "authentication flow decisions", "test failures in auth module")'
|
|
16217
|
+
},
|
|
16218
|
+
limit: {
|
|
16219
|
+
type: "number",
|
|
16220
|
+
description: "Maximum number of results to return (default 5, max 20)"
|
|
16221
|
+
},
|
|
16222
|
+
types: {
|
|
16223
|
+
type: "array",
|
|
16224
|
+
items: { type: "string", enum: ["response", "reasoning", "tool_output"] },
|
|
16225
|
+
description: "Filter by content type (default: all types)"
|
|
16226
|
+
}
|
|
16227
|
+
},
|
|
16228
|
+
required: ["query"]
|
|
16229
|
+
},
|
|
16230
|
+
execute: async (args) => {
|
|
16231
|
+
const query = String(args.query || "").trim();
|
|
16232
|
+
if (!query) return "Error: query is required";
|
|
16233
|
+
const limit = Math.max(1, Math.min(20, Number(args.limit) || 5));
|
|
16234
|
+
const types = Array.isArray(args.types) ? args.types : void 0;
|
|
16235
|
+
try {
|
|
16236
|
+
const response = await client.post("/session-context/search", {
|
|
16237
|
+
query,
|
|
16238
|
+
taskName,
|
|
16239
|
+
limit,
|
|
16240
|
+
...types ? { types } : {}
|
|
16241
|
+
});
|
|
16242
|
+
if (!response.success || !response.results || response.results.length === 0) {
|
|
16243
|
+
return "No matching session context found for your query.";
|
|
16244
|
+
}
|
|
16245
|
+
const formatted = response.results.map((r, i) => {
|
|
16246
|
+
const header = `[Result ${i + 1}] Session ${r.sessionIndex} | ${r.type}${r.toolName ? ` (${r.toolName})` : ""} | Score: ${r.score.toFixed(3)}`;
|
|
16247
|
+
return `${header}
|
|
16248
|
+
${r.content}`;
|
|
16249
|
+
});
|
|
16250
|
+
return `Found ${response.count} matching results:
|
|
16251
|
+
|
|
16252
|
+
${formatted.join("\n\n---\n\n")}`;
|
|
16253
|
+
} catch (error) {
|
|
16254
|
+
return `Session search unavailable: ${error instanceof Error ? error.message : String(error)}`;
|
|
16255
|
+
}
|
|
16256
|
+
}
|
|
16257
|
+
};
|
|
16258
|
+
}
|
|
16137
16259
|
function buildLocalTools(client, sandboxProvider, options, context) {
|
|
16138
16260
|
const enabledTools = {};
|
|
16139
16261
|
if (!options.noLocalTools) {
|
|
@@ -16149,6 +16271,9 @@ function buildLocalTools(client, sandboxProvider, options, context) {
|
|
|
16149
16271
|
context.stateDir
|
|
16150
16272
|
);
|
|
16151
16273
|
enabledTools.run_check = createRunCheckTool();
|
|
16274
|
+
if (options.sessionSearch === true) {
|
|
16275
|
+
enabledTools.search_session_history = createSearchSessionHistoryTool(client, context.taskName);
|
|
16276
|
+
}
|
|
16152
16277
|
}
|
|
16153
16278
|
}
|
|
16154
16279
|
if (sandboxProvider) {
|
|
@@ -16160,6 +16285,62 @@ function buildLocalTools(client, sandboxProvider, options, context) {
|
|
|
16160
16285
|
return Object.keys(enabledTools).length > 0 ? enabledTools : void 0;
|
|
16161
16286
|
}
|
|
16162
16287
|
|
|
16288
|
+
// src/marathon/session-chunker.ts
|
|
16289
|
+
var DEFAULT_MAX_CHUNK_CHARS = 2e3;
|
|
16290
|
+
var MIN_CONTENT_LENGTH = 50;
|
|
16291
|
+
function extractSessionChunks(snapshot, maxChunkChars = DEFAULT_MAX_CHUNK_CHARS) {
|
|
16292
|
+
const chunks = [];
|
|
16293
|
+
if (snapshot.content && snapshot.content.length >= MIN_CONTENT_LENGTH) {
|
|
16294
|
+
chunks.push(...chunkText(snapshot.content, "response", maxChunkChars));
|
|
16295
|
+
}
|
|
16296
|
+
if (snapshot.reasoning && snapshot.reasoning.length >= MIN_CONTENT_LENGTH) {
|
|
16297
|
+
chunks.push(...chunkText(snapshot.reasoning, "reasoning", maxChunkChars));
|
|
16298
|
+
}
|
|
16299
|
+
for (const tool of snapshot.tools) {
|
|
16300
|
+
const result = typeof tool.result === "string" ? tool.result : JSON.stringify(tool.result ?? "");
|
|
16301
|
+
if (result.length >= MIN_CONTENT_LENGTH) {
|
|
16302
|
+
chunks.push(
|
|
16303
|
+
...chunkText(result, "tool_output", maxChunkChars, tool.name)
|
|
16304
|
+
);
|
|
16305
|
+
}
|
|
16306
|
+
}
|
|
16307
|
+
return chunks;
|
|
16308
|
+
}
|
|
16309
|
+
function chunkText(text, type, maxChars, toolName) {
|
|
16310
|
+
if (text.length <= maxChars) {
|
|
16311
|
+
return [{ content: text, type, ...toolName ? { toolName } : {} }];
|
|
16312
|
+
}
|
|
16313
|
+
const chunks = [];
|
|
16314
|
+
const paragraphs = text.split(/\n\n+/);
|
|
16315
|
+
let current = "";
|
|
16316
|
+
for (const paragraph of paragraphs) {
|
|
16317
|
+
if (paragraph.length > maxChars) {
|
|
16318
|
+
if (current.length >= MIN_CONTENT_LENGTH) {
|
|
16319
|
+
chunks.push({ content: current.trim(), type, ...toolName ? { toolName } : {} });
|
|
16320
|
+
current = "";
|
|
16321
|
+
}
|
|
16322
|
+
const sentences = paragraph.match(/[^.!?]+[.!?]+\s*|[^.!?]+$/g) || [paragraph];
|
|
16323
|
+
for (const sentence of sentences) {
|
|
16324
|
+
if (current.length + sentence.length > maxChars && current.length > 0) {
|
|
16325
|
+
chunks.push({ content: current.trim(), type, ...toolName ? { toolName } : {} });
|
|
16326
|
+
current = "";
|
|
16327
|
+
}
|
|
16328
|
+
current += sentence;
|
|
16329
|
+
}
|
|
16330
|
+
continue;
|
|
16331
|
+
}
|
|
16332
|
+
if (current.length + paragraph.length + 2 > maxChars && current.length >= MIN_CONTENT_LENGTH) {
|
|
16333
|
+
chunks.push({ content: current.trim(), type, ...toolName ? { toolName } : {} });
|
|
16334
|
+
current = "";
|
|
16335
|
+
}
|
|
16336
|
+
current += (current ? "\n\n" : "") + paragraph;
|
|
16337
|
+
}
|
|
16338
|
+
if (current.length >= MIN_CONTENT_LENGTH) {
|
|
16339
|
+
chunks.push({ content: current.trim(), type, ...toolName ? { toolName } : {} });
|
|
16340
|
+
}
|
|
16341
|
+
return chunks;
|
|
16342
|
+
}
|
|
16343
|
+
|
|
16163
16344
|
// src/marathon/loop-detector.ts
|
|
16164
16345
|
var DEFAULT_MAX_HISTORY = 30;
|
|
16165
16346
|
var DEFAULT_MIN_PATTERN_LENGTH = 2;
|
|
@@ -17090,6 +17271,9 @@ async function taskAction(agent, options) {
|
|
|
17090
17271
|
console.log(chalk16.green(`Created agent: ${agentId}`));
|
|
17091
17272
|
}
|
|
17092
17273
|
} catch (createErr) {
|
|
17274
|
+
if (isTransientNetworkError(createErr)) {
|
|
17275
|
+
await failBeforeMain(formatMarathonApiError(createErr));
|
|
17276
|
+
}
|
|
17093
17277
|
const errMsg = createErr instanceof Error ? createErr.message : String(createErr);
|
|
17094
17278
|
await failBeforeMain([
|
|
17095
17279
|
chalk16.red(`Failed to create agent "${normalizedAgent}"`),
|
|
@@ -17098,6 +17282,9 @@ async function taskAction(agent, options) {
|
|
|
17098
17282
|
}
|
|
17099
17283
|
}
|
|
17100
17284
|
} catch (error) {
|
|
17285
|
+
if (isTransientNetworkError(error)) {
|
|
17286
|
+
await failBeforeMain(formatMarathonApiError(error));
|
|
17287
|
+
}
|
|
17101
17288
|
const errMsg = error instanceof Error ? error.message : String(error);
|
|
17102
17289
|
await failBeforeMain([
|
|
17103
17290
|
chalk16.red("Failed to list agents"),
|
|
@@ -17752,6 +17939,21 @@ Saving state... done. Session saved to ${filePath}`);
|
|
|
17752
17939
|
resumeState = extractRunTaskResumeState(adjustedState);
|
|
17753
17940
|
lastSessionMessages = state.messages ?? [];
|
|
17754
17941
|
saveState(filePath, adjustedState, { stripSnapshotEvents: !!eventLogWriter });
|
|
17942
|
+
if (options.sessionSearch === true) {
|
|
17943
|
+
const latestSnapshot = persistedSessionSnapshots[persistedSessionSnapshots.length - 1];
|
|
17944
|
+
if (latestSnapshot) {
|
|
17945
|
+
const chunks = extractSessionChunks(latestSnapshot);
|
|
17946
|
+
if (chunks.length > 0) {
|
|
17947
|
+
const sessionIdx = currentSessionOffset + state.sessionCount - 1;
|
|
17948
|
+
client.post("/session-context/index", {
|
|
17949
|
+
taskName,
|
|
17950
|
+
sessionIndex: sessionIdx,
|
|
17951
|
+
chunks
|
|
17952
|
+
}).catch(() => {
|
|
17953
|
+
});
|
|
17954
|
+
}
|
|
17955
|
+
}
|
|
17956
|
+
}
|
|
17755
17957
|
if (resumeState?.workflowPhase) {
|
|
17756
17958
|
const displayMilestone = detectedVariant === "external" && resumeState.workflowPhase === "research" && adjustedState.planWritten ? "report" : resumeState.workflowPhase;
|
|
17757
17959
|
streamRef.current?.updateMilestone(displayMilestone);
|
|
@@ -18127,7 +18329,7 @@ ${details}`);
|
|
|
18127
18329
|
}
|
|
18128
18330
|
return resolved;
|
|
18129
18331
|
}
|
|
18130
|
-
function detectDeployWorkflow(_message,
|
|
18332
|
+
function detectDeployWorkflow(_message, _sandboxProvider, resumeState) {
|
|
18131
18333
|
if (resumeState?.workflowVariant === "game") return gameWorkflow;
|
|
18132
18334
|
if (resumeState?.workflowPhase === "design" || resumeState?.workflowPhase === "build" || resumeState?.workflowPhase === "verify") {
|
|
18133
18335
|
return gameWorkflow;
|
|
@@ -18158,7 +18360,7 @@ function resolveSandboxWorkflowSelection(message, sandboxProvider, resumeState)
|
|
|
18158
18360
|
};
|
|
18159
18361
|
}
|
|
18160
18362
|
function applyTaskOptions(cmd) {
|
|
18161
|
-
return cmd.argument("<agent>", "Agent ID or name").option("-g, --goal <text>", "Goal message for the agent").option("--max-sessions <n>", "Maximum sessions", "50").option("--max-cost <n>", "Budget in USD").option("--model <modelId>", "Model ID to use (overrides agent config)").option("--name <name>", "Task name (used for state file, defaults to agent name)").option("--session <name>", "Resume a specific session by name").option("--state-dir <path>", "Directory for state files (default: ~/.runtype/projects/<hash>/marathons/)").option("--resume [message]", "Resume from existing local state, optionally with a new message").option("--fresh", "Start a new run and ignore any existing local state for this task").option("--compact", "Force compact-summary resume mode instead of replaying full history").option("--compact-strategy <strategy>", "Compaction strategy: auto (default), provider_native, or summary_fallback").option("--compact-threshold <value>", "Auto-compact when estimated context crosses this threshold (default: 80% fallback, 90% native; accepts percent like 90% or absolute token count like 120000)").option("--compact-instructions <text>", "Extra instructions for what a compact summary must preserve").option("--no-auto-compact", "Disable automatic context-aware history compaction").option("--track", "Sync progress to a Runtype record (visible in dashboard)").option("--debug", "Show debug output from each session").option("--json", "Output final result as JSON").option("--sandbox <provider>", "Enable sandbox code execution tool (cloudflare-worker, quickjs, or daytona)").option("--no-local-tools", "Disable built-in local tool execution (read_file, write_file, list_directory)").option("-t, --tools <tools...>", "Enable built-in tools (e.g., exa, firecrawl, dalle, openai_web_search, anthropic_web_search)").option("--plain-text", "Disable markdown rendering in output").option("--no-reasoning", "Disable model reasoning/thinking (enabled by default for supported models)").option("--no-checkpoint", "Run all iterations without checkpoint pauses (fully autonomous)").option("--checkpoint-timeout <seconds>", "Auto-continue timeout in seconds (default: 10)", "10").option("--planning-model <modelId>", "Model to use during research/planning phases").option("--execution-model <modelId>", "Model to use during execution phase").option("--fallback-model <modelId>", "Model to fall back to when primary model fails").option("--playbook <name>", "Load a playbook from .runtype/marathons/playbooks/").option("--offload-threshold <chars>", 'Offload tool outputs larger than this to files (default: 100000; use "off" or "0" to disable guardrails)').option("--tool-context <mode>", "Tool result storage: hot-tail (default), observation-mask, or full-inline").option("--tool-window <window>", 'Compaction window: "session" (default) or a number for last-N tool results (e.g. 10)').option("--runner-char <char>", "Custom runner emoji (default: \u{1F3C3})").option("--finish-char <char>", "Custom finish line emoji (default: \u{1F3C1})").option("--no-runner", "Hide the runner emoji from the header border").option("--no-finish", "Hide the finish line emoji from the header border").action(taskAction);
|
|
18363
|
+
return cmd.argument("<agent>", "Agent ID or name").option("-g, --goal <text>", "Goal message for the agent").option("--max-sessions <n>", "Maximum sessions", "50").option("--max-cost <n>", "Budget in USD").option("--model <modelId>", "Model ID to use (overrides agent config)").option("--name <name>", "Task name (used for state file, defaults to agent name)").option("--session <name>", "Resume a specific session by name").option("--state-dir <path>", "Directory for state files (default: ~/.runtype/projects/<hash>/marathons/)").option("--resume [message]", "Resume from existing local state, optionally with a new message").option("--fresh", "Start a new run and ignore any existing local state for this task").option("--compact", "Force compact-summary resume mode instead of replaying full history").option("--compact-strategy <strategy>", "Compaction strategy: auto (default), provider_native, or summary_fallback").option("--compact-threshold <value>", "Auto-compact when estimated context crosses this threshold (default: 80% fallback, 90% native; accepts percent like 90% or absolute token count like 120000)").option("--compact-instructions <text>", "Extra instructions for what a compact summary must preserve").option("--no-auto-compact", "Disable automatic context-aware history compaction").option("--track", "Sync progress to a Runtype record (visible in dashboard)").option("--debug", "Show debug output from each session").option("--json", "Output final result as JSON").option("--sandbox <provider>", "Enable sandbox code execution tool (cloudflare-worker, quickjs, or daytona)").option("--no-local-tools", "Disable built-in local tool execution (read_file, write_file, list_directory)").option("--session-search", "Enable session context indexing and search_session_history tool").option("-t, --tools <tools...>", "Enable built-in tools (e.g., exa, firecrawl, dalle, openai_web_search, anthropic_web_search)").option("--plain-text", "Disable markdown rendering in output").option("--no-reasoning", "Disable model reasoning/thinking (enabled by default for supported models)").option("--no-checkpoint", "Run all iterations without checkpoint pauses (fully autonomous)").option("--checkpoint-timeout <seconds>", "Auto-continue timeout in seconds (default: 10)", "10").option("--planning-model <modelId>", "Model to use during research/planning phases").option("--execution-model <modelId>", "Model to use during execution phase").option("--fallback-model <modelId>", "Model to fall back to when primary model fails").option("--playbook <name>", "Load a playbook from .runtype/marathons/playbooks/").option("--offload-threshold <chars>", 'Offload tool outputs larger than this to files (default: 100000; use "off" or "0" to disable guardrails)').option("--tool-context <mode>", "Tool result storage: hot-tail (default), observation-mask, or full-inline").option("--tool-window <window>", 'Compaction window: "session" (default) or a number for last-N tool results (e.g. 10)').option("--runner-char <char>", "Custom runner emoji (default: \u{1F3C3})").option("--finish-char <char>", "Custom finish line emoji (default: \u{1F3C1})").option("--no-runner", "Hide the runner emoji from the header border").option("--no-finish", "Hide the finish line emoji from the header border").action(taskAction);
|
|
18162
18364
|
}
|
|
18163
18365
|
var taskCommand = applyTaskOptions(
|
|
18164
18366
|
new Command10("task").description("Run a multi-session agent task")
|