mixdog 0.9.66 → 0.9.68
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/package.json +1 -1
- package/src/runtime/agent/orchestrator/session/manager/session-lifecycle.mjs +3 -0
- package/src/runtime/agent/orchestrator/session/store-summary-index.mjs +5 -0
- package/src/runtime/agent/orchestrator/session/store-summary-reader.mjs +20 -2
- package/src/runtime/channels/lib/config.mjs +13 -5
- package/src/runtime/channels/lib/owned-runtime.mjs +65 -5
- package/src/runtime/channels/lib/scheduler.mjs +7 -15
- package/src/runtime/channels/lib/status-snapshot.mjs +6 -30
- package/src/runtime/channels/lib/tool-dispatch.mjs +6 -1
- package/src/runtime/channels/lib/webhook/relay-tunnel.mjs +203 -0
- package/src/runtime/channels/lib/webhook.mjs +46 -246
- package/src/runtime/channels/lib/worker-main.mjs +45 -92
- package/src/runtime/shared/automation-attachments.mjs +72 -0
- package/src/runtime/shared/automation-workflow.mjs +41 -0
- package/src/runtime/shared/config.mjs +0 -9
- package/src/runtime/shared/schedule-session-run.mjs +10 -1
- package/src/runtime/shared/schedules-db.mjs +18 -3
- package/src/runtime/shared/time-format.mjs +56 -0
- package/src/runtime/shared/tool-card-model.mjs +740 -0
- package/src/runtime/shared/webhook-session-run.mjs +57 -0
- package/src/runtime/shared/webhooks-db.mjs +19 -3
- package/src/session-runtime/channel-config-api.mjs +13 -1
- package/src/session-runtime/lifecycle-api.mjs +12 -0
- package/src/session-runtime/prewarm.mjs +13 -7
- package/src/session-runtime/runtime-core.mjs +127 -22
- package/src/session-runtime/session-text.mjs +6 -0
- package/src/session-runtime/settings-api.mjs +0 -12
- package/src/standalone/channel-admin.mjs +71 -22
- package/src/standalone/channel-daemon-client.mjs +5 -1
- package/src/standalone/channel-daemon-transport.mjs +112 -20
- package/src/standalone/channel-daemon.mjs +6 -4
- package/src/tui/App.jsx +2 -47
- package/src/tui/app/channel-pickers.mjs +8 -173
- package/src/tui/app/doctor.mjs +0 -1
- package/src/tui/app/slash-commands.mjs +1 -3
- package/src/tui/app/slash-dispatch.mjs +3 -3
- package/src/tui/components/ToolExecution.jsx +47 -196
- package/src/tui/components/tool-execution/surface-detail.mjs +33 -394
- package/src/tui/components/tool-execution/text-format.mjs +27 -104
- package/src/tui/dist/index.mjs +340 -346
- package/src/tui/engine/live-share.mjs +9 -0
- package/src/tui/engine/session-api-ext.mjs +32 -16
- package/src/tui/engine.mjs +14 -1
- package/src/tui/time-format.mjs +4 -51
- package/src/runtime/channels/lib/webhook/ngrok.mjs +0 -181
package/src/tui/dist/index.mjs
CHANGED
|
@@ -1246,7 +1246,6 @@ __export(config_exports, {
|
|
|
1246
1246
|
getOpenAIUsageSessionKey: () => getOpenAIUsageSessionKey,
|
|
1247
1247
|
getOpenCodeGoAuthCookie: () => getOpenCodeGoAuthCookie,
|
|
1248
1248
|
getTelegramToken: () => getTelegramToken,
|
|
1249
|
-
getWebhookAuthtoken: () => getWebhookAuthtoken,
|
|
1250
1249
|
hasStoredSecret: () => hasStoredSecret,
|
|
1251
1250
|
invalidateConfigReadCache: () => invalidateConfigReadCache,
|
|
1252
1251
|
invalidateSecretReadCache: () => invalidateSecretReadCache,
|
|
@@ -1563,9 +1562,6 @@ function getDiscordToken() {
|
|
|
1563
1562
|
function getTelegramToken() {
|
|
1564
1563
|
return _readSecret(SECRET_ACCOUNTS.telegramToken);
|
|
1565
1564
|
}
|
|
1566
|
-
function getWebhookAuthtoken() {
|
|
1567
|
-
return _readSecret(SECRET_ACCOUNTS.webhookAuth);
|
|
1568
|
-
}
|
|
1569
1565
|
function getOpenAIUsageSessionKey() {
|
|
1570
1566
|
return process.env.OPENAI_USAGE_SESSION_KEY || process.env.OPENAI_DASHBOARD_SESSION_KEY || process.env.OPENAI_SESSION_KEY || process.env.MIXDOG_OPENAI_USAGE_SESSION_KEY || _readSecret(SECRET_ACCOUNTS.openaiUsageSessionKey);
|
|
1571
1567
|
}
|
|
@@ -1631,7 +1627,6 @@ var init_config = __esm({
|
|
|
1631
1627
|
SECRET_ACCOUNTS = Object.freeze({
|
|
1632
1628
|
discordToken: "discord.token",
|
|
1633
1629
|
telegramToken: "telegram.token",
|
|
1634
|
-
webhookAuth: "webhook.authtoken",
|
|
1635
1630
|
agentApiKey: (provider) => `agent.${provider}.apiKey`,
|
|
1636
1631
|
openaiUsageSessionKey: "agent.openai.usageSessionKey",
|
|
1637
1632
|
opencodeGoAuthCookie: "agent.opencode-go.authCookie"
|
|
@@ -5844,7 +5839,7 @@ var SPINNER_VERBS = [
|
|
|
5844
5839
|
];
|
|
5845
5840
|
var SPINNER_FRAMES = ["\u25C7", "\u25C6", "\u25C8", "\u25C6", "\u25C7"];
|
|
5846
5841
|
|
|
5847
|
-
// src/
|
|
5842
|
+
// src/runtime/shared/time-format.mjs
|
|
5848
5843
|
function formatDuration(ms, options = {}) {
|
|
5849
5844
|
if (!Number.isFinite(Number(ms))) return "";
|
|
5850
5845
|
const value = Math.max(0, Number(ms) || 0);
|
|
@@ -10098,10 +10093,8 @@ var SLASH_COMMANDS = [
|
|
|
10098
10093
|
{ name: "plugins", usage: "/plugins", description: "Manage local plugin integrations" },
|
|
10099
10094
|
{ name: "hooks", usage: "/hooks", description: "Manage before-tool hook rules and events" },
|
|
10100
10095
|
{ name: "providers", usage: "/providers", description: "Manage auth, API keys, OAuth, and local endpoints" },
|
|
10101
|
-
{ name: "channels", usage: "/channels", description: "Manage Discord,
|
|
10096
|
+
{ name: "channels", usage: "/channels", description: "Manage Discord, Telegram, and voice" },
|
|
10102
10097
|
{ name: "remote", usage: "/remote", description: "Claim remote for this session (takes over from any other session)" },
|
|
10103
|
-
{ name: "schedules", usage: "/schedules", description: "Manage schedules" },
|
|
10104
|
-
{ name: "webhooks", usage: "/webhooks", description: "Manage inbound webhooks" },
|
|
10105
10098
|
{ name: "settings", usage: "/setting", aliases: ["setting", "config"], aliasUsage: ["settings", "config"], showAliasUsage: false, description: "Open runtime settings" },
|
|
10106
10099
|
{ name: "profile", usage: "/profile", description: "Set your title and response language" },
|
|
10107
10100
|
{ name: "update", usage: "/update", description: "Check version and update mixdog" },
|
|
@@ -17349,159 +17342,6 @@ function createChannelPickers({
|
|
|
17349
17342
|
setContextPanel(null);
|
|
17350
17343
|
setChannelPrompt(prompt);
|
|
17351
17344
|
};
|
|
17352
|
-
const channelRemoteEnabled = store.isRemoteEnabled?.() === true;
|
|
17353
|
-
if (focus === "schedules") {
|
|
17354
|
-
const schedules = setup.schedules || [];
|
|
17355
|
-
const items2 = [
|
|
17356
|
-
...schedules.length ? schedules.map((schedule) => {
|
|
17357
|
-
const enabled = schedule.enabled !== false;
|
|
17358
|
-
return {
|
|
17359
|
-
value: `schedule:${schedule.name}`,
|
|
17360
|
-
label: schedule.name,
|
|
17361
|
-
marker: enabled ? "\u25CF" : "\u25CB",
|
|
17362
|
-
markerColor: channelRemoteEnabled ? enabled ? theme.success : theme.inactive : theme.inactive,
|
|
17363
|
-
description: `${schedule.time || "(no cron)"} \xB7 ${schedule.route}${schedule.model ? ` \xB7 ${schedule.model}` : ""}${channelRemoteEnabled ? "" : " \xB7 channel off"}`,
|
|
17364
|
-
_action: "schedule-toggle",
|
|
17365
|
-
_name: schedule.name,
|
|
17366
|
-
_enabled: enabled
|
|
17367
|
-
};
|
|
17368
|
-
}) : [{
|
|
17369
|
-
value: "empty",
|
|
17370
|
-
label: "No schedules",
|
|
17371
|
-
description: "no schedules configured",
|
|
17372
|
-
_action: "noop"
|
|
17373
|
-
}]
|
|
17374
|
-
];
|
|
17375
|
-
const toggleSchedule = async (item) => {
|
|
17376
|
-
if (item._action !== "schedule-toggle") return;
|
|
17377
|
-
if (!channelRemoteEnabled) {
|
|
17378
|
-
store.pushNotice("enable channel first", "warn");
|
|
17379
|
-
return;
|
|
17380
|
-
}
|
|
17381
|
-
try {
|
|
17382
|
-
await store.setScheduleEnabled?.(item._name, !item._enabled);
|
|
17383
|
-
void openChannelSetupPicker("schedules", { highlightValue: `schedule:${item._name}` });
|
|
17384
|
-
} catch (e) {
|
|
17385
|
-
store.pushNotice(`schedule toggle failed: ${e?.message || e}`, "error");
|
|
17386
|
-
}
|
|
17387
|
-
};
|
|
17388
|
-
setPicker({
|
|
17389
|
-
title: "Schedules",
|
|
17390
|
-
description: channelRemoteEnabled ? "Enable or disable cron schedules." : "Enable channel to toggle schedules.",
|
|
17391
|
-
initialIndex: Math.max(0, items2.findIndex((entry) => entry.value === options.highlightValue)),
|
|
17392
|
-
items: items2,
|
|
17393
|
-
onSelect: (_value, item) => toggleSchedule(item),
|
|
17394
|
-
onLeft: (item) => toggleSchedule(item),
|
|
17395
|
-
onRight: (item) => toggleSchedule(item),
|
|
17396
|
-
onCancel: () => {
|
|
17397
|
-
setPicker(null);
|
|
17398
|
-
}
|
|
17399
|
-
});
|
|
17400
|
-
return;
|
|
17401
|
-
}
|
|
17402
|
-
if (focus === "webhook-endpoint") {
|
|
17403
|
-
const returnTo = typeof options.returnTo === "function" ? options.returnTo : () => setPicker(null);
|
|
17404
|
-
const domain = setup.webhook?.ngrokDomain || setup.webhook?.domain || "";
|
|
17405
|
-
const items2 = [
|
|
17406
|
-
{
|
|
17407
|
-
value: "endpoint-domain",
|
|
17408
|
-
label: "ngrok domain",
|
|
17409
|
-
description: domain ? domain : "Not set \xB7 Enter ngrok domain",
|
|
17410
|
-
_action: "endpoint-domain"
|
|
17411
|
-
},
|
|
17412
|
-
{
|
|
17413
|
-
value: "endpoint-authtoken",
|
|
17414
|
-
label: "authtoken",
|
|
17415
|
-
description: setup.webhook?.authenticated === true ? "Set" : "Not set \xB7 Enter authtoken",
|
|
17416
|
-
_action: "endpoint-authtoken"
|
|
17417
|
-
}
|
|
17418
|
-
];
|
|
17419
|
-
setPicker({
|
|
17420
|
-
title: "Webhook endpoint",
|
|
17421
|
-
description: "ngrok domain and authtoken. Toggle individual webhooks in /webhooks.",
|
|
17422
|
-
help: "\u2191/\u2193 Select \xB7 Enter Edit \xB7 Esc Back",
|
|
17423
|
-
indexMode: "always",
|
|
17424
|
-
labelWidth: 18,
|
|
17425
|
-
items: items2,
|
|
17426
|
-
onSelect: (_value, item) => {
|
|
17427
|
-
try {
|
|
17428
|
-
if (item._action === "endpoint-domain") {
|
|
17429
|
-
openChannelPrompt({
|
|
17430
|
-
kind: "webhook-domain",
|
|
17431
|
-
label: "ngrok domain",
|
|
17432
|
-
hint: "Paste the reserved ngrok domain (e.g. my-app.ngrok-free.app).",
|
|
17433
|
-
afterSave: () => void openChannelSetupPicker("webhook-endpoint", options)
|
|
17434
|
-
});
|
|
17435
|
-
return;
|
|
17436
|
-
}
|
|
17437
|
-
if (item._action === "endpoint-authtoken") {
|
|
17438
|
-
openChannelPrompt({
|
|
17439
|
-
kind: "webhook-token",
|
|
17440
|
-
label: "Webhook/ngrok authtoken",
|
|
17441
|
-
hint: "Paste the webhook/ngrok authtoken. It is stored in the OS keychain.",
|
|
17442
|
-
afterSave: () => void openChannelSetupPicker("webhook-endpoint", options)
|
|
17443
|
-
});
|
|
17444
|
-
}
|
|
17445
|
-
} catch (e) {
|
|
17446
|
-
store.pushNotice(`webhook endpoint failed: ${e?.message || e}`, "error");
|
|
17447
|
-
}
|
|
17448
|
-
},
|
|
17449
|
-
onCancel: () => {
|
|
17450
|
-
setPicker(null);
|
|
17451
|
-
returnTo();
|
|
17452
|
-
}
|
|
17453
|
-
});
|
|
17454
|
-
return;
|
|
17455
|
-
}
|
|
17456
|
-
if (focus === "webhooks") {
|
|
17457
|
-
const hooks = setup.webhooks || [];
|
|
17458
|
-
const items2 = [
|
|
17459
|
-
...hooks.length ? hooks.map((hook) => {
|
|
17460
|
-
const enabled = hook.enabled !== false;
|
|
17461
|
-
return {
|
|
17462
|
-
value: `webhook:${hook.name}`,
|
|
17463
|
-
label: hook.name,
|
|
17464
|
-
marker: enabled ? "\u25CF" : "\u25CB",
|
|
17465
|
-
markerColor: channelRemoteEnabled ? enabled ? theme.success : theme.inactive : theme.inactive,
|
|
17466
|
-
description: `${hook.parser || "github"} \xB7 ${hook.route} \xB7 secret:${hook.secretSet ? "set" : "missing"}${channelRemoteEnabled ? "" : " \xB7 channel off"}`,
|
|
17467
|
-
_action: "webhook-toggle",
|
|
17468
|
-
_name: hook.name,
|
|
17469
|
-
_enabled: enabled
|
|
17470
|
-
};
|
|
17471
|
-
}) : [{
|
|
17472
|
-
value: "empty",
|
|
17473
|
-
label: "No webhooks",
|
|
17474
|
-
description: "no webhook endpoints configured",
|
|
17475
|
-
_action: "noop"
|
|
17476
|
-
}]
|
|
17477
|
-
];
|
|
17478
|
-
const toggleWebhook = async (item) => {
|
|
17479
|
-
if (item._action !== "webhook-toggle") return;
|
|
17480
|
-
if (!channelRemoteEnabled) {
|
|
17481
|
-
store.pushNotice("enable channel first", "warn");
|
|
17482
|
-
return;
|
|
17483
|
-
}
|
|
17484
|
-
try {
|
|
17485
|
-
await store.setWebhookEnabled?.(item._name, !item._enabled);
|
|
17486
|
-
void openChannelSetupPicker("webhooks", { highlightValue: `webhook:${item._name}` });
|
|
17487
|
-
} catch (e) {
|
|
17488
|
-
store.pushNotice(`webhook toggle failed: ${e?.message || e}`, "error");
|
|
17489
|
-
}
|
|
17490
|
-
};
|
|
17491
|
-
setPicker({
|
|
17492
|
-
title: "Webhooks",
|
|
17493
|
-
description: channelRemoteEnabled ? "Enable or disable inbound webhook endpoints." : "Enable channel to toggle webhooks.",
|
|
17494
|
-
initialIndex: Math.max(0, items2.findIndex((entry) => entry.value === options.highlightValue)),
|
|
17495
|
-
items: items2,
|
|
17496
|
-
onSelect: (_value, item) => toggleWebhook(item),
|
|
17497
|
-
onLeft: (item) => toggleWebhook(item),
|
|
17498
|
-
onRight: (item) => toggleWebhook(item),
|
|
17499
|
-
onCancel: () => {
|
|
17500
|
-
setPicker(null);
|
|
17501
|
-
}
|
|
17502
|
-
});
|
|
17503
|
-
return;
|
|
17504
|
-
}
|
|
17505
17345
|
const worker = store.getChannelWorkerStatus?.();
|
|
17506
17346
|
const activeBackend = setup.backend === "telegram" ? "telegram" : "discord";
|
|
17507
17347
|
const backendLabel = activeBackend === "telegram" ? "Telegram" : "Discord";
|
|
@@ -17575,20 +17415,10 @@ function createChannelPickers({
|
|
|
17575
17415
|
{
|
|
17576
17416
|
value: "webhook-endpoint",
|
|
17577
17417
|
label: "Webhook endpoint",
|
|
17578
|
-
|
|
17579
|
-
|
|
17580
|
-
|
|
17581
|
-
|
|
17582
|
-
})(),
|
|
17583
|
-
description: (() => {
|
|
17584
|
-
const hasDomain = Boolean(setup.webhook?.ngrokDomain || setup.webhook?.domain);
|
|
17585
|
-
const hasAuth = setup.webhook?.authenticated === true;
|
|
17586
|
-
const needs = [
|
|
17587
|
-
...hasDomain ? [] : ["domain"],
|
|
17588
|
-
...hasAuth ? [] : ["authtoken"]
|
|
17589
|
-
];
|
|
17590
|
-
return needs.length ? `Needs ${needs.join(" + ")}` : "ngrok domain and authtoken set";
|
|
17591
|
-
})(),
|
|
17418
|
+
// Relay tunnel: public exposure is automatic, so the endpoint is
|
|
17419
|
+
// "On" whenever the webhook server itself is enabled.
|
|
17420
|
+
meta: setup.webhook?.enabled === false ? "Off" : "On",
|
|
17421
|
+
description: setup.webhook?.publicUrl ? setup.webhook.publicUrl : "Mixdog relay tunnel \u2014 URL assigned on first run",
|
|
17592
17422
|
_action: "webhook-endpoint"
|
|
17593
17423
|
}
|
|
17594
17424
|
];
|
|
@@ -19609,10 +19439,8 @@ function createSlashDispatch({
|
|
|
19609
19439
|
void openChannelSetupPicker("all");
|
|
19610
19440
|
return true;
|
|
19611
19441
|
case "schedules":
|
|
19612
|
-
void openChannelSetupPicker("schedules");
|
|
19613
|
-
return true;
|
|
19614
19442
|
case "webhooks":
|
|
19615
|
-
|
|
19443
|
+
store.pushNotice("Schedules and webhooks are managed in the Mixdog desktop app", "info");
|
|
19616
19444
|
return true;
|
|
19617
19445
|
case "auth":
|
|
19618
19446
|
store.pushNotice("/auth moved to /providers", "info");
|
|
@@ -20400,7 +20228,7 @@ import React16 from "react";
|
|
|
20400
20228
|
import { Box as Box14, Text as Text16 } from "../../../vendor/ink/build/index.js";
|
|
20401
20229
|
import stringWidth9 from "string-width";
|
|
20402
20230
|
|
|
20403
|
-
// src/
|
|
20231
|
+
// src/runtime/shared/tool-card-model.mjs
|
|
20404
20232
|
import stripAnsi6 from "strip-ansi";
|
|
20405
20233
|
|
|
20406
20234
|
// src/runtime/shared/tool-status.mjs
|
|
@@ -20424,7 +20252,7 @@ function toolResultTerminalStatus(text) {
|
|
|
20424
20252
|
return normalizeToolTerminalStatus(inline);
|
|
20425
20253
|
}
|
|
20426
20254
|
|
|
20427
|
-
// src/
|
|
20255
|
+
// src/runtime/shared/tool-card-model.mjs
|
|
20428
20256
|
var MIN_RESULT_LINE_CHARS = 24;
|
|
20429
20257
|
var RESULT_LINE_HARD_MAX = 80;
|
|
20430
20258
|
var SUMMARY_MAX_CHARS = 48;
|
|
@@ -20448,47 +20276,9 @@ function normalizeCountMap(value = {}) {
|
|
|
20448
20276
|
}
|
|
20449
20277
|
return out;
|
|
20450
20278
|
}
|
|
20451
|
-
function deltaColor(token) {
|
|
20452
|
-
return String(token || "").startsWith("+") ? theme.success : theme.error;
|
|
20453
|
-
}
|
|
20454
|
-
function deltaTextParts(text) {
|
|
20455
|
-
const value = String(text ?? "");
|
|
20456
|
-
const parts = [];
|
|
20457
|
-
const re = /(^|[\s([,{·])([+-]\s*\d+)(?=\s+Lines?\b)/gi;
|
|
20458
|
-
let last = 0;
|
|
20459
|
-
let match;
|
|
20460
|
-
while (match = re.exec(value)) {
|
|
20461
|
-
const prefix = match[1] || "";
|
|
20462
|
-
const token = (match[2] || "").replace(/\s+/g, "");
|
|
20463
|
-
const tokenStart = match.index + prefix.length;
|
|
20464
|
-
if (match.index > last) parts.push({ text: value.slice(last, match.index) });
|
|
20465
|
-
if (prefix) parts.push({ text: prefix });
|
|
20466
|
-
if (token) parts.push({ text: token, color: deltaColor(token) });
|
|
20467
|
-
last = tokenStart + (match[2] || "").length;
|
|
20468
|
-
}
|
|
20469
|
-
if (last < value.length) parts.push({ text: value.slice(last) });
|
|
20470
|
-
return parts;
|
|
20471
|
-
}
|
|
20472
20279
|
function plural(count, singular, pluralText = `${singular}s`) {
|
|
20473
20280
|
return count === 1 ? singular : pluralText;
|
|
20474
20281
|
}
|
|
20475
|
-
function fitResultLine(line, columns) {
|
|
20476
|
-
const max = Math.min(RESULT_LINE_HARD_MAX, Math.max(MIN_RESULT_LINE_CHARS, Number(columns || 80) - 7));
|
|
20477
|
-
const text = safeInlineText(line);
|
|
20478
|
-
return displayWidth(text) > max ? truncateToWidth(text, max) : text;
|
|
20479
|
-
}
|
|
20480
|
-
function truncateToWidth(text, maxWidth) {
|
|
20481
|
-
const str = safeInlineText(text);
|
|
20482
|
-
if (maxWidth < 1) return "";
|
|
20483
|
-
if (displayWidth(str) <= maxWidth) return str;
|
|
20484
|
-
const chars = Array.from(str);
|
|
20485
|
-
let out = "";
|
|
20486
|
-
for (const ch of chars) {
|
|
20487
|
-
if (displayWidth(out + ch + "\u2026") > maxWidth) break;
|
|
20488
|
-
out += ch;
|
|
20489
|
-
}
|
|
20490
|
-
return `${out}\u2026`;
|
|
20491
|
-
}
|
|
20492
20282
|
function shellResultStatus(value) {
|
|
20493
20283
|
const match = String(value || "").match(/(?:^|\b)status:\s*(running|pending|queued|completed|failed|cancelled|canceled)\b/im);
|
|
20494
20284
|
return match ? String(match[1] || "").toLowerCase() : "";
|
|
@@ -20524,8 +20314,6 @@ function shellResultElapsed(value) {
|
|
|
20524
20314
|
const elapsedMs = Number(match[1]);
|
|
20525
20315
|
return Number.isFinite(elapsedMs) && elapsedMs >= 1e3 ? formatElapsed(elapsedMs) : "";
|
|
20526
20316
|
}
|
|
20527
|
-
|
|
20528
|
-
// src/tui/components/tool-execution/surface-detail.mjs
|
|
20529
20317
|
function isShellTool(normalizedName, label = "") {
|
|
20530
20318
|
const n = String(normalizedName || "").toLowerCase();
|
|
20531
20319
|
const l = String(label || "").toLowerCase();
|
|
@@ -20857,6 +20645,248 @@ function clampFailureCount(errorCount, groupCount, isError) {
|
|
|
20857
20645
|
if (Number.isFinite(explicit)) return Math.max(0, Math.min(groupCount, Math.floor(explicit)));
|
|
20858
20646
|
return isError ? groupCount : 0;
|
|
20859
20647
|
}
|
|
20648
|
+
function clipPlain(text, maxChars) {
|
|
20649
|
+
const value = safeInlineText(text);
|
|
20650
|
+
const max = Math.max(1, Number(maxChars) || 1);
|
|
20651
|
+
if (value.length <= max) return value;
|
|
20652
|
+
return `${value.slice(0, Math.max(0, max - 1))}\u2026`;
|
|
20653
|
+
}
|
|
20654
|
+
function deriveToolCardModel(input = {}, options = {}) {
|
|
20655
|
+
const {
|
|
20656
|
+
name = "",
|
|
20657
|
+
args = {},
|
|
20658
|
+
result = null,
|
|
20659
|
+
rawResult = null,
|
|
20660
|
+
isError = false,
|
|
20661
|
+
errorCount,
|
|
20662
|
+
callErrorCount,
|
|
20663
|
+
exitErrorCount,
|
|
20664
|
+
count = 1,
|
|
20665
|
+
completedCount,
|
|
20666
|
+
startedAt = 0,
|
|
20667
|
+
completedAt = 0,
|
|
20668
|
+
aggregate = false,
|
|
20669
|
+
categories = {},
|
|
20670
|
+
doneCategories = null,
|
|
20671
|
+
headerFinalized = true
|
|
20672
|
+
} = input;
|
|
20673
|
+
const nowMs = Number(input.nowMs || Date.now());
|
|
20674
|
+
const truncate2 = typeof options.truncate === "function" ? options.truncate : clipPlain;
|
|
20675
|
+
const maxResultChars = Math.max(
|
|
20676
|
+
MIN_RESULT_LINE_CHARS,
|
|
20677
|
+
Math.min(RESULT_LINE_HARD_MAX, Number(options.maxResultChars ?? RESULT_LINE_HARD_MAX))
|
|
20678
|
+
);
|
|
20679
|
+
const groupCount = Math.max(1, Number(count || 1));
|
|
20680
|
+
const doneCount = Math.max(0, Math.min(groupCount, Number(completedCount ?? (result == null ? 0 : groupCount))));
|
|
20681
|
+
const rt = result == null ? null : String(result).replace(/\s+$/, "");
|
|
20682
|
+
const rawRt = rawResult == null ? null : String(rawResult).replace(/\s+$/, "");
|
|
20683
|
+
const pending = doneCount < groupCount;
|
|
20684
|
+
const headerPending = pending || headerFinalized === false;
|
|
20685
|
+
const hasResult = result != null && Boolean(String(rt || "").trim());
|
|
20686
|
+
const hasRawResult = rawResult != null && Boolean(String(rawRt || "").trim());
|
|
20687
|
+
const startedAtMs = Number(startedAt || 0);
|
|
20688
|
+
const completedAtMs = Number(completedAt || 0);
|
|
20689
|
+
const elapsedMs = startedAtMs ? Math.max(0, (pending ? nowMs : completedAtMs || nowMs) - startedAtMs) : 0;
|
|
20690
|
+
const elapsed = elapsedMs >= 1e3 ? formatElapsed(elapsedMs) : "";
|
|
20691
|
+
const failedCount = clampFailureCount(errorCount, groupCount, isError);
|
|
20692
|
+
const callFailedCount = clampFailureCount(callErrorCount, groupCount, false);
|
|
20693
|
+
const exitFailedCount = clampFailureCount(exitErrorCount, groupCount, false);
|
|
20694
|
+
if (aggregate) {
|
|
20695
|
+
const displayCategories = normalizeCountMap(categories || {});
|
|
20696
|
+
const normalizedDone = doneCategories ? normalizeCountMap(doneCategories) : displayCategories;
|
|
20697
|
+
const hasDoneCounts = Object.values(normalizedDone || {}).some(
|
|
20698
|
+
(v) => (v && typeof v === "object" ? Number(v.count || 0) : Number(v || 0)) > 0
|
|
20699
|
+
);
|
|
20700
|
+
const displayDone = hasDoneCounts ? normalizedDone : displayCategories;
|
|
20701
|
+
const headerOrder = Array.isArray(args?.categoryOrder) ? args.categoryOrder : null;
|
|
20702
|
+
const labelText2 = safeInlineText(formatAggregateHeader(
|
|
20703
|
+
(headerPending ? displayCategories : displayDone) || {},
|
|
20704
|
+
{ pending: headerPending, order: headerOrder }
|
|
20705
|
+
));
|
|
20706
|
+
const detailText = hasResult ? safeInlineText(rt) : "";
|
|
20707
|
+
const terminalStatus2 = pending ? "running" : resultTerminalStatus(rt) || (isError || failedCount > 0 ? "failed" : "completed");
|
|
20708
|
+
return {
|
|
20709
|
+
aggregate: true,
|
|
20710
|
+
pending,
|
|
20711
|
+
headerPending,
|
|
20712
|
+
groupCount,
|
|
20713
|
+
doneCount,
|
|
20714
|
+
elapsed,
|
|
20715
|
+
failedCount,
|
|
20716
|
+
callFailedCount,
|
|
20717
|
+
exitFailedCount,
|
|
20718
|
+
terminalStatus: terminalStatus2,
|
|
20719
|
+
labelText: labelText2,
|
|
20720
|
+
summaryText: "",
|
|
20721
|
+
headerFailureText: "",
|
|
20722
|
+
detailLine: detailText || (pending ? "Running" : "Finished"),
|
|
20723
|
+
detailIsPlaceholder: !detailText,
|
|
20724
|
+
hasResult,
|
|
20725
|
+
hasRawResult,
|
|
20726
|
+
displayedResultBodyText: rt || "",
|
|
20727
|
+
firstResultLine: detailText,
|
|
20728
|
+
totalLines: detailText ? 1 : 0,
|
|
20729
|
+
resultSummary: detailText || null,
|
|
20730
|
+
toolArgPath: "",
|
|
20731
|
+
normalizedName: "",
|
|
20732
|
+
label: "",
|
|
20733
|
+
parsedArgs: args,
|
|
20734
|
+
isShellSurface: false,
|
|
20735
|
+
isSkillSurface: false,
|
|
20736
|
+
isAgentSurfaceCard: false,
|
|
20737
|
+
isAgentResponse: false,
|
|
20738
|
+
isBackgroundResponse: false,
|
|
20739
|
+
isBackgroundMetadataResult: false,
|
|
20740
|
+
backgroundMeta: null
|
|
20741
|
+
};
|
|
20742
|
+
}
|
|
20743
|
+
const { label, summary, normalizedName, args: parsedArgs } = formatToolSurface(name, args);
|
|
20744
|
+
const isShellSurface = isShellTool(normalizedName, label);
|
|
20745
|
+
const isSkillSurface = SKILL_SURFACE_NAMES2.has(String(normalizedName || "").toLowerCase());
|
|
20746
|
+
const backgroundMeta = !pending && isBackgroundTaskTool(normalizedName) ? resolveBackgroundTaskMeta(parsedArgs, rt || "") : null;
|
|
20747
|
+
const backgroundError = backgroundMeta?.error || parsedArgs?.error || "";
|
|
20748
|
+
const errorOnlyResult = Boolean(rt) && isBackgroundErrorOnlyBody(rt, backgroundError);
|
|
20749
|
+
const backgroundResultText = backgroundMeta?.hasResponse ? backgroundMeta.body : "";
|
|
20750
|
+
const displayedResultText = backgroundResultText || (errorOnlyResult ? "" : rt || "");
|
|
20751
|
+
const hasDisplayResult = Boolean(String(displayedResultText || "").trim());
|
|
20752
|
+
const displayedResultBodyText = stripLeadingStatusMarkerFromText(displayedResultText);
|
|
20753
|
+
const hasDisplayBody = Boolean(String(displayedResultBodyText || "").trim());
|
|
20754
|
+
const lines = displayedResultBodyText ? displayedResultBodyText.split("\n") : [];
|
|
20755
|
+
const totalLines = lines.length;
|
|
20756
|
+
const resultSummary = !pending && hasDisplayBody ? summarizeToolResult(name, args, displayedResultBodyText, isError) : null;
|
|
20757
|
+
const firstResultLine = hasDisplayResult ? String(lines[0] ?? "") : "";
|
|
20758
|
+
const shellStatus = isShellSurface ? shellDisplayStatus({ pending, failedCount, exitFailedCount, isError, result: displayedResultText }) : "";
|
|
20759
|
+
const shellElapsed = isShellSurface ? shellResultElapsed(displayedResultText) || elapsed : "";
|
|
20760
|
+
const backgroundElapsed = backgroundMeta ? backgroundTaskElapsed(backgroundMeta, elapsed) : isBackgroundTaskTool(normalizedName) ? backgroundTaskElapsed(parsedArgs, elapsed) : "";
|
|
20761
|
+
const toolArgPath = parsedArgs?.path ?? parsedArgs?.file_path ?? parsedArgs?.file ?? "";
|
|
20762
|
+
const imageDetail = normalizedName === "view_image" && toolArgPath && !isError ? String(toolArgPath) : "";
|
|
20763
|
+
const isBackgroundResult = !pending && isBackgroundTaskTool(normalizedName) && Boolean(backgroundMeta);
|
|
20764
|
+
const isBackgroundResponse = isBackgroundResult && (backgroundMeta?.hasResponse || isBackgroundTaskResponseArgs(normalizedName, parsedArgs));
|
|
20765
|
+
const isBackgroundMetadataResult = isBackgroundResult && !isBackgroundResponse && Boolean(backgroundMeta);
|
|
20766
|
+
const backgroundMetadataFailureLabel = isBackgroundMetadataResult ? backgroundTaskFailureDetail(backgroundMeta, parsedArgs) : "";
|
|
20767
|
+
const backgroundMetadataHeaderFailure = Boolean(backgroundMetadataFailureLabel) && !hasDisplayResult ? backgroundMetadataFailureLabel : "";
|
|
20768
|
+
const agentHeaderFailure = !pending && isAgentTool(normalizedName) && isError && parsedArgs?.error && !hasDisplayResult ? backgroundTaskFailureStatusLabel(parsedArgs?.status, parsedArgs?.error, { surface: "agent" }) : "";
|
|
20769
|
+
const headerFailureText = backgroundMetadataHeaderFailure || agentHeaderFailure || "";
|
|
20770
|
+
const agentCompletionDetail = !pending && isAgentTool(normalizedName) && !agentHeaderFailure ? agentTerminalDetail(parsedArgs?.status, isError, elapsed, parsedArgs?.error) : "";
|
|
20771
|
+
const agentDetail = !pending && isAgentTool(normalizedName) && !hasDisplayResult ? agentCompletionDetail : "";
|
|
20772
|
+
const genericDetail = !pending && !isShellSurface && !agentDetail && !imageDetail && !resultSummary ? genericCompletedDetail({ normalizedName, label, hasResult, firstResultLine, isError }) : "";
|
|
20773
|
+
const terminalStatus = pending ? "running" : shellStatus || normalizeTerminalStatus(backgroundMeta?.status) || normalizeTerminalStatus(parsedArgs?.status) || resultTerminalStatus(displayedResultText) || (isError || failedCount > 0 ? "failed" : "completed");
|
|
20774
|
+
const backgroundMetadataDetail = isBackgroundMetadataResult && !backgroundMetadataHeaderFailure ? backgroundTaskDetail(backgroundMeta, backgroundElapsed, parsedArgs) : "";
|
|
20775
|
+
const backgroundResponseDetail = isBackgroundResponse && resultSummary ? prefixElapsed(resultSummary, backgroundElapsed) : resultSummary;
|
|
20776
|
+
const syncElapsedDetail = !isBackgroundResponse && shouldPrefixSyncElapsed(normalizedName, label) ? prefixElapsed(backgroundResponseDetail, elapsed) : backgroundResponseDetail;
|
|
20777
|
+
const nonShellDetail = backgroundMetadataDetail || (/^(Cancelled|Failed|Finished)$/i.test(resultSummary || "") && agentCompletionDetail ? agentCompletionDetail : syncElapsedDetail) || agentDetail || imageDetail || genericDetail;
|
|
20778
|
+
const pendingDetailPlaceholder = pending && !isSkillSurface ? elapsed ? `Running \xB7 ${elapsed}` : "Running" : "";
|
|
20779
|
+
const shellCollapsedSummary = isShellSurface && !pending && hasDisplayResult ? resultSummary || truncate2(firstResultLine, Math.min(120, maxResultChars)) : resultSummary;
|
|
20780
|
+
const collapsedDetail = pending ? pendingDetailPlaceholder : isShellSurface ? prefixElapsed(mergeTerminalDetail(shellStatus, shellCollapsedSummary), shellElapsed) : mergeTerminalDetail(terminalStatus, nonShellDetail);
|
|
20781
|
+
const isAgentResult = !isBackgroundResult && !pending && isAgentTool(normalizedName) && hasDisplayResult;
|
|
20782
|
+
const isAgentResponse = isAgentResult && hasAgentResponseResult(rt);
|
|
20783
|
+
const isAgentSurfaceCard = isAgentTool(normalizedName);
|
|
20784
|
+
const agentSurfaceBriefRaw = isAgentSurfaceCard ? summarizeAgentSurfaceBrief(name, parsedArgs, displayedResultText || "", { isError, isResponse: isAgentResponse }) : "";
|
|
20785
|
+
const agentSurfaceBrief = agentSurfaceBriefRaw ? truncate2(agentSurfaceBriefRaw, Math.min(AGENT_SURFACE_BRIEF_MAX, maxResultChars)) : "";
|
|
20786
|
+
let detailLine = collapsedDetail;
|
|
20787
|
+
if (isSkillSurface) {
|
|
20788
|
+
detailLine = isError && collapsedDetail ? collapsedDetail : "";
|
|
20789
|
+
} else if (isBackgroundMetadataResult && backgroundMetadataHeaderFailure) {
|
|
20790
|
+
detailLine = "";
|
|
20791
|
+
} else if (isAgentSurfaceCard) {
|
|
20792
|
+
const agentDetailFallback = collapsedDetail || (pending ? pendingDetailPlaceholder || "Running" : "Finished");
|
|
20793
|
+
const agentDetailLine = agentSurfaceBrief || truncate2(String(agentDetailFallback), Math.min(AGENT_SURFACE_BRIEF_MAX, maxResultChars));
|
|
20794
|
+
const agentFailureText = /\b(Cancelled|Canceled|Failed)\b/i.test(agentSurfaceBrief || collapsedDetail || "");
|
|
20795
|
+
const keepAgentDetail = (isError || agentFailureText) && !(agentHeaderFailure && !agentSurfaceBrief);
|
|
20796
|
+
detailLine = keepAgentDetail ? agentDetailLine : "";
|
|
20797
|
+
}
|
|
20798
|
+
let labelText;
|
|
20799
|
+
if (isAgentResponse) labelText = agentResponseTitle(parsedArgs, groupCount);
|
|
20800
|
+
else if (isBackgroundResponse) labelText = backgroundTaskResultTitle(normalizedName, backgroundMeta || parsedArgs);
|
|
20801
|
+
else if (isBackgroundMetadataResult) labelText = backgroundTaskActionTitle(normalizedName, backgroundMeta);
|
|
20802
|
+
else if (isShellSurface) labelText = shellHeader(shellStatus, groupCount);
|
|
20803
|
+
else labelText = (isAgentTool(normalizedName) ? agentActionTitle(parsedArgs) : "") || formatToolActionHeader(name, args, { pending: headerPending, count: groupCount });
|
|
20804
|
+
labelText = safeInlineText(labelText);
|
|
20805
|
+
const toolSearchSummary = !pending && normalizedName === "load_tool" && hasResult ? toolSearchLoadedSummary(displayedResultText) : "";
|
|
20806
|
+
const rawSummaryText = safeInlineText(isAgentResponse || isBackgroundResponse ? "" : toolSearchSummary || (isAgentTool(normalizedName) ? agentActionSummary(parsedArgs, summary) : summary));
|
|
20807
|
+
const summaryIsHeaderCount = rawSummaryText && /^\d+\s+\S+$/.test(rawSummaryText) && labelText.endsWith(rawSummaryText);
|
|
20808
|
+
const summaryText = summaryIsHeaderCount ? "" : rawSummaryText;
|
|
20809
|
+
return {
|
|
20810
|
+
aggregate: false,
|
|
20811
|
+
pending,
|
|
20812
|
+
headerPending,
|
|
20813
|
+
groupCount,
|
|
20814
|
+
doneCount,
|
|
20815
|
+
elapsed,
|
|
20816
|
+
failedCount,
|
|
20817
|
+
callFailedCount,
|
|
20818
|
+
exitFailedCount,
|
|
20819
|
+
terminalStatus,
|
|
20820
|
+
labelText,
|
|
20821
|
+
summaryText,
|
|
20822
|
+
headerFailureText,
|
|
20823
|
+
detailLine,
|
|
20824
|
+
detailIsPlaceholder: Boolean(pendingDetailPlaceholder) && detailLine === pendingDetailPlaceholder,
|
|
20825
|
+
hasResult,
|
|
20826
|
+
hasRawResult,
|
|
20827
|
+
hasDisplayResult,
|
|
20828
|
+
hasDisplayBody,
|
|
20829
|
+
displayedResultBodyText,
|
|
20830
|
+
firstResultLine,
|
|
20831
|
+
totalLines,
|
|
20832
|
+
resultSummary,
|
|
20833
|
+
shellCollapsedSummary,
|
|
20834
|
+
agentSurfaceBrief,
|
|
20835
|
+
toolArgPath: String(toolArgPath || ""),
|
|
20836
|
+
normalizedName,
|
|
20837
|
+
label,
|
|
20838
|
+
parsedArgs,
|
|
20839
|
+
isShellSurface,
|
|
20840
|
+
isSkillSurface,
|
|
20841
|
+
isAgentSurfaceCard,
|
|
20842
|
+
isAgentResponse,
|
|
20843
|
+
isBackgroundResponse,
|
|
20844
|
+
isBackgroundMetadataResult,
|
|
20845
|
+
backgroundMeta
|
|
20846
|
+
};
|
|
20847
|
+
}
|
|
20848
|
+
|
|
20849
|
+
// src/tui/components/tool-execution/text-format.mjs
|
|
20850
|
+
function deltaColor(token) {
|
|
20851
|
+
return String(token || "").startsWith("+") ? theme.success : theme.error;
|
|
20852
|
+
}
|
|
20853
|
+
function deltaTextParts(text) {
|
|
20854
|
+
const value = String(text ?? "");
|
|
20855
|
+
const parts = [];
|
|
20856
|
+
const re = /(^|[\s([,{·])([+-]\s*\d+)(?=\s+Lines?\b)/gi;
|
|
20857
|
+
let last = 0;
|
|
20858
|
+
let match;
|
|
20859
|
+
while (match = re.exec(value)) {
|
|
20860
|
+
const prefix = match[1] || "";
|
|
20861
|
+
const token = (match[2] || "").replace(/\s+/g, "");
|
|
20862
|
+
const tokenStart = match.index + prefix.length;
|
|
20863
|
+
if (match.index > last) parts.push({ text: value.slice(last, match.index) });
|
|
20864
|
+
if (prefix) parts.push({ text: prefix });
|
|
20865
|
+
if (token) parts.push({ text: token, color: deltaColor(token) });
|
|
20866
|
+
last = tokenStart + (match[2] || "").length;
|
|
20867
|
+
}
|
|
20868
|
+
if (last < value.length) parts.push({ text: value.slice(last) });
|
|
20869
|
+
return parts;
|
|
20870
|
+
}
|
|
20871
|
+
function fitResultLine(line, columns) {
|
|
20872
|
+
const max = Math.min(RESULT_LINE_HARD_MAX, Math.max(MIN_RESULT_LINE_CHARS, Number(columns || 80) - 7));
|
|
20873
|
+
const text = safeInlineText(line);
|
|
20874
|
+
return displayWidth(text) > max ? truncateToWidth(text, max) : text;
|
|
20875
|
+
}
|
|
20876
|
+
function truncateToWidth(text, maxWidth) {
|
|
20877
|
+
const str = safeInlineText(text);
|
|
20878
|
+
if (maxWidth < 1) return "";
|
|
20879
|
+
if (displayWidth(str) <= maxWidth) return str;
|
|
20880
|
+
const chars = Array.from(str);
|
|
20881
|
+
let out = "";
|
|
20882
|
+
for (const ch of chars) {
|
|
20883
|
+
if (displayWidth(out + ch + "\u2026") > maxWidth) break;
|
|
20884
|
+
out += ch;
|
|
20885
|
+
}
|
|
20886
|
+
return `${out}\u2026`;
|
|
20887
|
+
}
|
|
20888
|
+
|
|
20889
|
+
// src/tui/components/tool-execution/surface-detail.mjs
|
|
20860
20890
|
function toolStatusColor({ pending, groupCount, callFailedCount = 0, exitFailedCount = 0, terminalStatus = "" }) {
|
|
20861
20891
|
if (pending) return theme.text;
|
|
20862
20892
|
const status = normalizeTerminalStatus(terminalStatus);
|
|
@@ -20895,9 +20925,6 @@ import { jsx as jsx16, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
|
20895
20925
|
var TOOL_BLINK_MS = 500;
|
|
20896
20926
|
var TOOL_PENDING_SHOW_DELAY_MS = 1e3;
|
|
20897
20927
|
var TOOL_ANIM_TICK_MS = TOOL_BLINK_MS;
|
|
20898
|
-
function statusCopy(name, label, count, doneCount, pending, isError, args = {}) {
|
|
20899
|
-
return formatToolActionHeader(name, args, { pending, count });
|
|
20900
|
-
}
|
|
20901
20928
|
function ToolExecution({ name, args, result, rawResult, isError, errorCount, callErrorCount, exitErrorCount, expanded, columns = 80, attached = false, count = 1, completedCount = 0, startedAt = 0, completedAt = 0, aggregate = false, categories = {}, doneCategories = null, headerFinalized = true, deferredDisplayReady = false, agentResponseAggregate = false }) {
|
|
20902
20929
|
const rowWidth = Math.max(1, Number(columns || 80));
|
|
20903
20930
|
const groupCount = Math.max(1, Number(count || 1));
|
|
@@ -20984,87 +21011,60 @@ function ToolExecution({ name, args, result, rawResult, isError, errorCount, cal
|
|
|
20984
21011
|
)
|
|
20985
21012
|
] });
|
|
20986
21013
|
}
|
|
20987
|
-
const { label, summary, normalizedName, args: parsedArgs } = formatToolSurface(name, args);
|
|
20988
|
-
const isShellSurface = isShellTool(normalizedName, label);
|
|
20989
|
-
const isSkillSurface = SKILL_SURFACE_NAMES2.has(String(normalizedName || "").toLowerCase());
|
|
20990
|
-
const backgroundMeta = !pending && isBackgroundTaskTool(normalizedName) ? resolveBackgroundTaskMeta(parsedArgs, rt || "") : null;
|
|
20991
|
-
const backgroundError = backgroundMeta?.error || parsedArgs?.error || "";
|
|
20992
|
-
const errorOnlyResult = Boolean(rt) && isBackgroundErrorOnlyBody(rt, backgroundError);
|
|
20993
|
-
const backgroundResultText = backgroundMeta?.hasResponse ? backgroundMeta.body : "";
|
|
20994
|
-
const displayedResultText = backgroundResultText || (errorOnlyResult ? "" : rt || "");
|
|
20995
|
-
const hasDisplayResult = Boolean(String(displayedResultText || "").trim());
|
|
20996
|
-
const displayedResultBodyText = stripLeadingStatusMarkerFromText(displayedResultText);
|
|
20997
|
-
const hasDisplayBody = Boolean(String(displayedResultBodyText || "").trim());
|
|
20998
|
-
const lines = displayedResultBodyText ? displayedResultBodyText.split("\n") : [];
|
|
20999
|
-
const totalLines = lines.length;
|
|
21000
|
-
const resultSummary = !pending && hasDisplayBody ? summarizeToolResult(name, args, displayedResultBodyText, isError) : null;
|
|
21001
21014
|
const maxResultChars = Math.min(RESULT_LINE_HARD_MAX, Math.max(MIN_RESULT_LINE_CHARS, Number(columns || 80) - 7));
|
|
21015
|
+
const model = deriveToolCardModel({
|
|
21016
|
+
name,
|
|
21017
|
+
args,
|
|
21018
|
+
result,
|
|
21019
|
+
rawResult,
|
|
21020
|
+
isError,
|
|
21021
|
+
errorCount,
|
|
21022
|
+
callErrorCount,
|
|
21023
|
+
exitErrorCount,
|
|
21024
|
+
count: displayGroupCount,
|
|
21025
|
+
completedCount: doneCount,
|
|
21026
|
+
startedAt,
|
|
21027
|
+
completedAt,
|
|
21028
|
+
headerFinalized,
|
|
21029
|
+
nowMs
|
|
21030
|
+
}, { truncate: truncateToWidth, maxResultChars });
|
|
21031
|
+
const {
|
|
21032
|
+
labelText,
|
|
21033
|
+
summaryText,
|
|
21034
|
+
headerFailureText: headerFailureStatus,
|
|
21035
|
+
detailLine: collapsedDetailLine,
|
|
21036
|
+
detailIsPlaceholder,
|
|
21037
|
+
terminalStatus,
|
|
21038
|
+
normalizedName,
|
|
21039
|
+
isShellSurface,
|
|
21040
|
+
isAgentSurfaceCard,
|
|
21041
|
+
isAgentResponse,
|
|
21042
|
+
isBackgroundMetadataResult,
|
|
21043
|
+
hasDisplayResult,
|
|
21044
|
+
hasDisplayBody,
|
|
21045
|
+
displayedResultBodyText,
|
|
21046
|
+
firstResultLine,
|
|
21047
|
+
totalLines,
|
|
21048
|
+
resultSummary,
|
|
21049
|
+
shellCollapsedSummary,
|
|
21050
|
+
toolArgPath
|
|
21051
|
+
} = model;
|
|
21052
|
+
const lines = displayedResultBodyText ? displayedResultBodyText.split("\n") : [];
|
|
21002
21053
|
const resultColor = theme.text;
|
|
21003
|
-
const firstResultLine = hasDisplayResult ? String(lines[0] ?? "") : "";
|
|
21004
21054
|
const firstResultLineClipped = hasDisplayBody && stringWidth9(firstResultLine) > maxResultChars;
|
|
21005
21055
|
const hasHiddenDetail = !pending && hasDisplayBody && (totalLines > 1 || firstResultLineClipped || Boolean(resultSummary));
|
|
21006
|
-
const shellStatus = isShellSurface ? shellDisplayStatus({ pending, failedCount, exitFailedCount, isError, result: displayedResultText }) : "";
|
|
21007
|
-
const shellElapsed = isShellSurface ? shellResultElapsed(displayedResultText) || elapsed : "";
|
|
21008
|
-
const backgroundElapsed = backgroundMeta ? backgroundTaskElapsed(backgroundMeta, elapsed) : isBackgroundTaskTool(normalizedName) ? backgroundTaskElapsed(parsedArgs, elapsed) : "";
|
|
21009
|
-
const toolArgPath = parsedArgs?.path ?? parsedArgs?.file_path ?? parsedArgs?.file ?? "";
|
|
21010
|
-
const imageDetail = normalizedName === "view_image" && toolArgPath && !isError ? String(toolArgPath) : "";
|
|
21011
|
-
const isBackgroundResult = !pending && isBackgroundTaskTool(normalizedName) && Boolean(backgroundMeta);
|
|
21012
|
-
const isBackgroundResponse = isBackgroundResult && (backgroundMeta?.hasResponse || isBackgroundTaskResponseArgs(normalizedName, parsedArgs));
|
|
21013
|
-
const isBackgroundMetadataResult = isBackgroundResult && !isBackgroundResponse && Boolean(backgroundMeta);
|
|
21014
|
-
const backgroundMetadataFailureLabel = isBackgroundMetadataResult ? backgroundTaskFailureDetail(backgroundMeta, parsedArgs) : "";
|
|
21015
|
-
const backgroundMetadataHeaderFailure = Boolean(backgroundMetadataFailureLabel) && !hasDisplayResult ? backgroundMetadataFailureLabel : "";
|
|
21016
|
-
const agentHeaderFailure = !pending && isAgentTool(normalizedName) && isError && parsedArgs?.error && !hasDisplayResult ? backgroundTaskFailureStatusLabel(parsedArgs?.status, parsedArgs?.error, { surface: "agent" }) : "";
|
|
21017
|
-
const headerFailureStatus = backgroundMetadataHeaderFailure || agentHeaderFailure || "";
|
|
21018
|
-
const agentCompletionDetail = !pending && isAgentTool(normalizedName) && !agentHeaderFailure ? agentTerminalDetail(parsedArgs?.status, isError, elapsed, parsedArgs?.error) : "";
|
|
21019
|
-
const agentDetail = !pending && isAgentTool(normalizedName) && !hasDisplayResult ? agentCompletionDetail : "";
|
|
21020
|
-
const genericDetail = !pending && !isShellSurface && !agentDetail && !imageDetail && !resultSummary ? genericCompletedDetail({ normalizedName, label, hasResult, firstResultLine, isError }) : "";
|
|
21021
|
-
const terminalStatus = pending ? "running" : shellStatus || normalizeTerminalStatus(backgroundMeta?.status) || normalizeTerminalStatus(parsedArgs?.status) || resultTerminalStatus(displayedResultText) || (isError || failedCount > 0 ? "failed" : "completed");
|
|
21022
|
-
const backgroundMetadataDetail = isBackgroundMetadataResult && !backgroundMetadataHeaderFailure ? backgroundTaskDetail(backgroundMeta, backgroundElapsed, parsedArgs) : "";
|
|
21023
|
-
const backgroundResponseDetail = isBackgroundResponse && resultSummary ? prefixElapsed(resultSummary, backgroundElapsed) : resultSummary;
|
|
21024
|
-
const syncElapsedDetail = !isBackgroundResponse && shouldPrefixSyncElapsed(normalizedName, label) ? prefixElapsed(backgroundResponseDetail, elapsed) : backgroundResponseDetail;
|
|
21025
|
-
const nonShellDetail = backgroundMetadataDetail || (/^(Cancelled|Failed|Finished)$/i.test(resultSummary || "") && agentCompletionDetail ? agentCompletionDetail : syncElapsedDetail) || agentDetail || imageDetail || genericDetail;
|
|
21026
|
-
const pendingDetailPlaceholder = pending && !isSkillSurface ? elapsed ? `Running \xB7 ${elapsed}` : "Running" : "";
|
|
21027
|
-
const shellCollapsedSummary = isShellSurface && !pending && hasDisplayResult ? resultSummary || truncateToWidth(firstResultLine, Math.min(120, maxResultChars)) : resultSummary;
|
|
21028
|
-
const collapsedDetail = pending ? pendingDetailPlaceholder : isShellSurface ? prefixElapsed(mergeTerminalDetail(shellStatus, shellCollapsedSummary), shellElapsed) : mergeTerminalDetail(terminalStatus, nonShellDetail);
|
|
21029
21056
|
const backgroundMetadataExpandable = isBackgroundMetadataResult && hasRawResult && !pending;
|
|
21030
21057
|
const showRawResult = expanded && (hasDisplayBody || hasRawResult) && (!isBackgroundMetadataResult || hasRawResult);
|
|
21031
|
-
const detailLines = showRawResult ? agentResponseAggregate && hasRawResult ? stripLeadingStatusMarkerLines(rawRt.split("\n")) : hasDisplayBody ? lines : rawRt ? stripLeadingStatusMarkerLines(rawRt.split("\n")) : [] :
|
|
21032
|
-
const isPendingPlaceholderDetail = !showRawResult &&
|
|
21058
|
+
const detailLines = showRawResult ? agentResponseAggregate && hasRawResult ? stripLeadingStatusMarkerLines(rawRt.split("\n")) : hasDisplayBody ? lines : rawRt ? stripLeadingStatusMarkerLines(rawRt.split("\n")) : [] : collapsedDetailLine ? [collapsedDetailLine] : [];
|
|
21059
|
+
const isPendingPlaceholderDetail = !showRawResult && detailIsPlaceholder;
|
|
21033
21060
|
const detailColor = isPendingPlaceholderDetail ? theme.subtle : theme.text;
|
|
21034
|
-
const
|
|
21035
|
-
const isAgentResponse = isAgentResult && hasAgentResponseResult(rt);
|
|
21036
|
-
const isAgentSurfaceCard = isAgentTool(normalizedName);
|
|
21037
|
-
const agentSurfaceBriefRaw = isAgentSurfaceCard && !showRawResult ? summarizeAgentSurfaceBrief(name, parsedArgs, displayedResultText || "", { isError, isResponse: isAgentResponse }) : "";
|
|
21038
|
-
const agentSurfaceBrief = agentSurfaceBriefRaw ? truncateToWidth(agentSurfaceBriefRaw, Math.min(AGENT_SURFACE_BRIEF_MAX, maxResultChars)) : "";
|
|
21039
|
-
let visibleDetailLines = detailLines;
|
|
21040
|
-
if (isSkillSurface && !showRawResult) {
|
|
21041
|
-
visibleDetailLines = isError && collapsedDetail ? [collapsedDetail] : [];
|
|
21042
|
-
} else if (isBackgroundMetadataResult && backgroundMetadataHeaderFailure && !showRawResult) {
|
|
21043
|
-
visibleDetailLines = [];
|
|
21044
|
-
} else if (isAgentSurfaceCard && !showRawResult) {
|
|
21045
|
-
const agentDetailFallback = collapsedDetail || (pending ? pendingDetailPlaceholder || "Running" : "Finished");
|
|
21046
|
-
const agentDetailLine = agentSurfaceBrief || truncateToWidth(String(agentDetailFallback), Math.min(AGENT_SURFACE_BRIEF_MAX, maxResultChars));
|
|
21047
|
-
const agentFailureText = /\b(Cancelled|Canceled|Failed)\b/i.test(agentSurfaceBrief || collapsedDetail || "");
|
|
21048
|
-
const keepAgentDetail = (isError || agentFailureText) && !(agentHeaderFailure && !agentSurfaceBrief);
|
|
21049
|
-
visibleDetailLines = keepAgentDetail ? [agentDetailLine] : [];
|
|
21050
|
-
}
|
|
21061
|
+
const visibleDetailLines = detailLines;
|
|
21051
21062
|
const finalStatusColor = toolStatusColor({ pending, groupCount, callFailedCount, exitFailedCount, terminalStatus });
|
|
21052
21063
|
const dotColor = finalStatusColor;
|
|
21053
21064
|
const markerGlyph = isAgentResponse ? AGENT_RESPONSE_MARKER : isAgentSurfaceCard ? AGENT_CALL_MARKER : TURN_MARKER;
|
|
21054
21065
|
const isDirectionalMarker = isAgentResponse || isAgentSurfaceCard;
|
|
21055
21066
|
const markerText = isDirectionalMarker ? `${markerGlyph} ` : markerGlyph;
|
|
21056
21067
|
const dotText = pending && !blinkOn ? " " : markerText;
|
|
21057
|
-
let labelText;
|
|
21058
|
-
if (isAgentResponse) labelText = agentResponseTitle(parsedArgs, displayGroupCount);
|
|
21059
|
-
else if (isBackgroundResponse) labelText = backgroundTaskResultTitle(normalizedName, backgroundMeta || parsedArgs);
|
|
21060
|
-
else if (isBackgroundMetadataResult) labelText = backgroundTaskActionTitle(normalizedName, backgroundMeta);
|
|
21061
|
-
else if (isShellSurface) labelText = shellHeader(shellStatus, displayGroupCount);
|
|
21062
|
-
else labelText = (isAgentTool(normalizedName) ? agentActionTitle(parsedArgs) : "") || statusCopy(name, label, displayGroupCount, doneCount, headerPending, isError, parsedArgs);
|
|
21063
|
-
labelText = safeInlineText(labelText);
|
|
21064
|
-
const toolSearchSummary = !pending && normalizedName === "load_tool" && hasResult ? toolSearchLoadedSummary(displayedResultText) : "";
|
|
21065
|
-
const rawSummaryText = safeInlineText(isAgentResponse || isBackgroundResponse ? "" : toolSearchSummary || (isAgentTool(normalizedName) ? agentActionSummary(parsedArgs, summary) : summary));
|
|
21066
|
-
const summaryIsHeaderCount = rawSummaryText && /^\d+\s+\S+$/.test(rawSummaryText) && labelText.endsWith(rawSummaryText);
|
|
21067
|
-
const summaryText = summaryIsHeaderCount ? "" : rawSummaryText;
|
|
21068
21068
|
const agentHasExpandableBody = isAgentSurfaceCard && !pending && hasResult && (isAgentResponse || totalLines > 1 || firstResultLineClipped);
|
|
21069
21069
|
const shellHasExpandableBody = isShellSurface && !pending && hasDisplayResult && hasDisplayBody && (totalLines > 1 || firstResultLineClipped || Boolean(shellCollapsedSummary && shellCollapsedSummary !== firstResultLine));
|
|
21070
21070
|
const showHeaderExpandHint = (isShellSurface ? shellHasExpandableBody : isAgentSurfaceCard ? agentHasExpandableBody : hasHiddenDetail || backgroundMetadataExpandable) && normalizedName !== "load_tool";
|
|
@@ -22681,19 +22681,6 @@ function App({ store, initialStatusLine = "", forceOnboarding = false }) {
|
|
|
22681
22681
|
resumeAfterChannelPrompt(channelPrompt);
|
|
22682
22682
|
return true;
|
|
22683
22683
|
}
|
|
22684
|
-
if (channelPrompt.kind === "webhook-token") {
|
|
22685
|
-
if (!commandText) return false;
|
|
22686
|
-
store.saveWebhookAuthtoken(commandText);
|
|
22687
|
-
resumeAfterChannelPrompt(channelPrompt);
|
|
22688
|
-
return true;
|
|
22689
|
-
}
|
|
22690
|
-
if (channelPrompt.kind === "webhook-domain") {
|
|
22691
|
-
if (!commandText) return false;
|
|
22692
|
-
Promise.resolve(store.setWebhookConfig?.({ ngrokDomain: commandText })).then(() => resumeAfterChannelPrompt(channelPrompt)).catch((e) => {
|
|
22693
|
-
store.pushNotice(`webhook config update failed: ${e?.message || e}`, "error");
|
|
22694
|
-
});
|
|
22695
|
-
return true;
|
|
22696
|
-
}
|
|
22697
22684
|
const parts = commandText.split("|").map((part) => part.trim());
|
|
22698
22685
|
if (channelPrompt.kind === "channel-add") {
|
|
22699
22686
|
const isPipe = parts.length > 1;
|
|
@@ -22706,29 +22693,6 @@ function App({ store, initialStatusLine = "", forceOnboarding = false }) {
|
|
|
22706
22693
|
});
|
|
22707
22694
|
return true;
|
|
22708
22695
|
}
|
|
22709
|
-
if (channelPrompt.kind === "schedule-add") {
|
|
22710
|
-
const [name, time, instructions, channel, model] = parts;
|
|
22711
|
-
Promise.resolve(store.saveSchedule({ name, time, instructions, channel, model })).then(() => {
|
|
22712
|
-
setChannelPrompt(null);
|
|
22713
|
-
void openChannelSetupPicker("schedules");
|
|
22714
|
-
}).catch((e) => {
|
|
22715
|
-
store.pushNotice(`schedule save failed: ${e?.message || e}`, "error");
|
|
22716
|
-
});
|
|
22717
|
-
return true;
|
|
22718
|
-
}
|
|
22719
|
-
if (channelPrompt.kind === "webhook-add") {
|
|
22720
|
-
const [name, instructions, channel, model, parser] = parts;
|
|
22721
|
-
Promise.resolve(store.saveWebhook({ name, instructions, channel, model, parser })).then((result) => {
|
|
22722
|
-
if (result?.secret) {
|
|
22723
|
-
store.pushNotice(`webhook secret for ${result.name}: ${result.secret}`, "info");
|
|
22724
|
-
}
|
|
22725
|
-
setChannelPrompt(null);
|
|
22726
|
-
void openChannelSetupPicker("webhooks");
|
|
22727
|
-
}).catch((e) => {
|
|
22728
|
-
store.pushNotice(`webhook save failed: ${e?.message || e}`, "error");
|
|
22729
|
-
});
|
|
22730
|
-
return true;
|
|
22731
|
-
}
|
|
22732
22696
|
} catch (e) {
|
|
22733
22697
|
store.pushNotice(`channels update failed: ${e?.message || e}`, "error");
|
|
22734
22698
|
return false;
|
|
@@ -23976,6 +23940,12 @@ var SYNTHETIC_SESSION_TEXT_PATTERNS = Object.freeze([
|
|
|
23976
23940
|
/^\[mixdog-runtime\]/i,
|
|
23977
23941
|
/^\[(?:truncated|request interrupted by user)\]$/i,
|
|
23978
23942
|
/^a previous model worked on this task and produced the compacted handoff summary below\b/i,
|
|
23943
|
+
// Compact/auto-clear re-seed handoff variants: these lead the FIRST user
|
|
23944
|
+
// message of every post-compaction session, so titling from them painted
|
|
23945
|
+
// "Re-attached after compaction…" rows in Recent (user report). Skipping
|
|
23946
|
+
// them titles the session from its first REAL user message instead.
|
|
23947
|
+
/^re-attached after compaction\b/i,
|
|
23948
|
+
/^reference files:\s/i,
|
|
23979
23949
|
/^the async (?:agent|shell) task\b/i
|
|
23980
23950
|
]);
|
|
23981
23951
|
var LATE_TOOL_ANNOUNCEMENT_SENTINEL = "connected after this session started";
|
|
@@ -28148,15 +28118,30 @@ function createEngineApiB(bag) {
|
|
|
28148
28118
|
set({ commandBusy: false });
|
|
28149
28119
|
}
|
|
28150
28120
|
},
|
|
28151
|
-
// Toggle
|
|
28152
|
-
//
|
|
28153
|
-
//
|
|
28121
|
+
// Toggle channel remote mode for the CURRENT session (session-scoped,
|
|
28122
|
+
// user decision). Off → on claims for this session; on + this session
|
|
28123
|
+
// owns → off; on + ANOTHER session owns → move the relay seat here
|
|
28124
|
+
// (last-wins) without restarting the worker.
|
|
28154
28125
|
toggleRemote: () => {
|
|
28155
28126
|
const enabled = runtime.isRemoteEnabled?.() === true;
|
|
28156
|
-
|
|
28127
|
+
const owner = String(runtime.getRemoteSessionId?.() || "");
|
|
28128
|
+
const currentId = String(getState().sessionId || "");
|
|
28129
|
+
const workerRunning = runtime.getChannelWorkerStatus?.()?.running === true;
|
|
28130
|
+
if (enabled && !workerRunning) {
|
|
28131
|
+
runtime.startRemote?.();
|
|
28132
|
+
const next2 = runtime.isRemoteEnabled?.() === true;
|
|
28133
|
+
set({ remoteEnabled: next2, remoteSessionId: runtime.getRemoteSessionId?.() || null });
|
|
28134
|
+
return next2;
|
|
28135
|
+
}
|
|
28136
|
+
if (enabled && owner && currentId && owner !== currentId) {
|
|
28137
|
+
runtime.claimRemoteForCurrentSession?.();
|
|
28138
|
+
set({ remoteEnabled: true, remoteSessionId: runtime.getRemoteSessionId?.() || null });
|
|
28139
|
+
return true;
|
|
28140
|
+
}
|
|
28141
|
+
if (enabled) runtime.releaseRemote?.();
|
|
28157
28142
|
else runtime.startRemote?.();
|
|
28158
28143
|
const next = runtime.isRemoteEnabled?.() === true;
|
|
28159
|
-
set({ remoteEnabled: next });
|
|
28144
|
+
set({ remoteEnabled: next, remoteSessionId: runtime.getRemoteSessionId?.() || null });
|
|
28160
28145
|
return next;
|
|
28161
28146
|
},
|
|
28162
28147
|
// Force-claim remote for this session (single-holder, last-wins). Always
|
|
@@ -28166,9 +28151,16 @@ function createEngineApiB(bag) {
|
|
|
28166
28151
|
claimRemote: () => {
|
|
28167
28152
|
runtime.startRemote?.();
|
|
28168
28153
|
const next = runtime.isRemoteEnabled?.() === true;
|
|
28169
|
-
set({ remoteEnabled: next });
|
|
28154
|
+
set({ remoteEnabled: next, remoteSessionId: runtime.getRemoteSessionId?.() || null });
|
|
28170
28155
|
return next;
|
|
28171
28156
|
},
|
|
28157
|
+
// Idempotent desired-state OFF for desktop controls. Unlike toggleRemote,
|
|
28158
|
+
// a delayed/replayed request can never turn remote back on.
|
|
28159
|
+
releaseRemote: () => {
|
|
28160
|
+
runtime.releaseRemote?.();
|
|
28161
|
+
set({ remoteEnabled: false, remoteSessionId: null });
|
|
28162
|
+
return false;
|
|
28163
|
+
},
|
|
28172
28164
|
isRemoteEnabled: () => runtime.isRemoteEnabled?.() === true,
|
|
28173
28165
|
getVoiceStatus: () => getVoiceStatus(),
|
|
28174
28166
|
// Desktop push-to-talk dictation: accept a recorded audio payload
|
|
@@ -28375,16 +28367,6 @@ function createEngineApiB(bag) {
|
|
|
28375
28367
|
pushNotice("telegram token forgotten", "info");
|
|
28376
28368
|
return result;
|
|
28377
28369
|
},
|
|
28378
|
-
saveWebhookAuthtoken: (token) => {
|
|
28379
|
-
const result = runtime.saveWebhookAuthtoken(token);
|
|
28380
|
-
pushNotice("webhook/ngrok authtoken saved", "info");
|
|
28381
|
-
return result;
|
|
28382
|
-
},
|
|
28383
|
-
forgetWebhookAuthtoken: () => {
|
|
28384
|
-
const result = runtime.forgetWebhookAuthtoken();
|
|
28385
|
-
pushNotice("webhook/ngrok authtoken forgotten", "info");
|
|
28386
|
-
return result;
|
|
28387
|
-
},
|
|
28388
28370
|
setChannel: async (entry) => {
|
|
28389
28371
|
const result = await runtime.setChannel(entry);
|
|
28390
28372
|
pushNotice("channel saved", "info");
|
|
@@ -28801,7 +28783,6 @@ async function buildDoctorReport(runtime = {}, getState = () => ({})) {
|
|
|
28801
28783
|
const tokens = [];
|
|
28802
28784
|
if (setup.discord?.authenticated) tokens.push("discord");
|
|
28803
28785
|
if (setup.telegram?.authenticated) tokens.push("telegram");
|
|
28804
|
-
if (setup.webhook?.authenticated) tokens.push("webhook");
|
|
28805
28786
|
const running = worker.running === true;
|
|
28806
28787
|
const detail = `enabled \xB7 worker ${running ? "running" : "stopped"} \xB7 tokens: ${tokens.length ? tokens.join(", ") : "none"}`;
|
|
28807
28788
|
row(running ? "ok" : "warn", detail);
|
|
@@ -29929,6 +29910,7 @@ function createLiveShare({
|
|
|
29929
29910
|
const stopClient = () => {
|
|
29930
29911
|
const closing = client;
|
|
29931
29912
|
const closingId = clientId;
|
|
29913
|
+
const wasUp = clientUp;
|
|
29932
29914
|
client = null;
|
|
29933
29915
|
clientId = "";
|
|
29934
29916
|
clientUp = false;
|
|
@@ -29940,6 +29922,7 @@ function createLiveShare({
|
|
|
29940
29922
|
} catch {
|
|
29941
29923
|
}
|
|
29942
29924
|
}
|
|
29925
|
+
if (wasUp) clearMirroredLiveState();
|
|
29943
29926
|
};
|
|
29944
29927
|
const startClient = (id) => {
|
|
29945
29928
|
let socket;
|
|
@@ -31042,12 +31025,23 @@ async function createEngineSession({
|
|
|
31042
31025
|
if (typeof runtime.onRemoteStateChange === "function") {
|
|
31043
31026
|
lifecycle.unsubscribeRemoteState = runtime.onRemoteStateChange(({ enabled, reason }) => {
|
|
31044
31027
|
if (flags.disposed) return;
|
|
31045
|
-
set({
|
|
31028
|
+
set({
|
|
31029
|
+
remoteEnabled: enabled === true,
|
|
31030
|
+
remoteSessionId: runtime.getRemoteSessionId?.() || null
|
|
31031
|
+
});
|
|
31046
31032
|
if (reason === "superseded") {
|
|
31047
31033
|
pushNotice("Remote mode OFF \u2014 another session took over remote.", "warn");
|
|
31034
|
+
} else if (reason === "claim-failed") {
|
|
31035
|
+
pushNotice("Remote mode could not start. Check the channel connection and try again.", "error");
|
|
31036
|
+
} else if (reason === "release-failed") {
|
|
31037
|
+
pushNotice("Remote mode could not be stopped cleanly. The shared state will reconcile automatically.", "error");
|
|
31048
31038
|
}
|
|
31049
31039
|
});
|
|
31050
31040
|
}
|
|
31041
|
+
set({
|
|
31042
|
+
remoteEnabled: runtime.isRemoteEnabled?.() === true,
|
|
31043
|
+
remoteSessionId: runtime.getRemoteSessionId?.() || null
|
|
31044
|
+
});
|
|
31051
31045
|
const { patchToolCardResult, flushToolResults } = createToolCardResults({
|
|
31052
31046
|
getState: () => state,
|
|
31053
31047
|
set,
|