pilotswarm 0.5.61 → 0.5.62
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/mcp/dist/src/resources/models.d.ts.map +1 -1
- package/mcp/dist/src/resources/models.js +6 -1
- package/mcp/dist/src/resources/models.js.map +1 -1
- package/mcp/dist/src/tools/models.d.ts.map +1 -1
- package/mcp/dist/src/tools/models.js +11 -1
- package/mcp/dist/src/tools/models.js.map +1 -1
- package/mcp/dist/src/tools/sessions.d.ts.map +1 -1
- package/mcp/dist/src/tools/sessions.js +8 -2
- package/mcp/dist/src/tools/sessions.js.map +1 -1
- package/package.json +2 -2
- package/tui/src/node-sdk-transport.js +1 -1
- package/ui/core/src/chat-activity.js +94 -0
- package/ui/core/src/controller.js +33 -5
- package/ui/core/src/history.js +15 -0
- package/ui/core/src/moa.js +32 -11
- package/ui/core/src/reducer.js +12 -4
- package/ui/core/src/selectors.js +25 -5
- package/ui/core/src/session-errors.js +10 -2
- package/ui/core/src/system-titles.js +2 -0
- package/ui/react/src/web-app.js +37 -12
- package/web/dist/assets/{abnfDiagram-VRR7QNED-CCVkGWsr.js → abnfDiagram-VRR7QNED-DAiG41W-.js} +1 -1
- package/web/dist/assets/{arc-y040btO3.js → arc-CN_GY3DG.js} +1 -1
- package/web/dist/assets/{architectureDiagram-ZJ3FMSHR-24Yt5esy.js → architectureDiagram-ZJ3FMSHR-DD9qiBOj.js} +1 -1
- package/web/dist/assets/{blockDiagram-677ZJIJ3-BlbS-_GI.js → blockDiagram-677ZJIJ3-CZg2R8i6.js} +1 -1
- package/web/dist/assets/{c4Diagram-LMCZKHZV-_mamn0Fv.js → c4Diagram-LMCZKHZV-DuZxUZYd.js} +1 -1
- package/web/dist/assets/channel-B50-C7oJ.js +1 -0
- package/web/dist/assets/{chunk-2Q5K7J3B-TCbIB2Ni.js → chunk-2Q5K7J3B-BX7lDvmf.js} +1 -1
- package/web/dist/assets/{chunk-32BRIVSS-C9q5KNKG.js → chunk-32BRIVSS-COupwzAw.js} +1 -1
- package/web/dist/assets/{chunk-5VM5RSS4-BvoqfU8P.js → chunk-5VM5RSS4-C_IyERib.js} +1 -1
- package/web/dist/assets/{chunk-EX3LRPZG-zFJjZeNd.js → chunk-EX3LRPZG-CyfIuYKn.js} +1 -1
- package/web/dist/assets/{chunk-JWPE2WC7-Ce_6C5M-.js → chunk-JWPE2WC7-Cj5lvEfN.js} +1 -1
- package/web/dist/assets/{chunk-MOJQB5TN-CPjpLM65.js → chunk-MOJQB5TN-l907LpMA.js} +1 -1
- package/web/dist/assets/{chunk-RYQCIY6F-CsmVUSDH.js → chunk-RYQCIY6F-PLru1fOZ.js} +1 -1
- package/web/dist/assets/{chunk-V7JOEXUC-CgrmPPOd.js → chunk-V7JOEXUC-C6GCxiE5.js} +1 -1
- package/web/dist/assets/{chunk-VR4S4FIN-BxAHDR7h.js → chunk-VR4S4FIN-BGelrIxQ.js} +1 -1
- package/web/dist/assets/{chunk-XXDRQBXY-BGfFoO5_.js → chunk-XXDRQBXY-BmJstjEv.js} +1 -1
- package/web/dist/assets/classDiagram-OUVF2IWQ-CIJlKS0m.js +1 -0
- package/web/dist/assets/classDiagram-v2-EOCWNBFH-CIJlKS0m.js +1 -0
- package/web/dist/assets/{cose-bilkent-JH36ORCC-B6KcngJW.js → cose-bilkent-JH36ORCC-CRabxOOK.js} +1 -1
- package/web/dist/assets/{cynefin-VYW2F7L2-DaY7l4Ce.js → cynefin-VYW2F7L2-CminxBoG.js} +1 -1
- package/web/dist/assets/{cynefinDiagram-TSTJHNR4-BldfGsoa.js → cynefinDiagram-TSTJHNR4-yBazsQf4.js} +1 -1
- package/web/dist/assets/{dagre-VKFMJZFB-C4T9X5Bs.js → dagre-VKFMJZFB-DcZuZV2n.js} +1 -1
- package/web/dist/assets/{diagram-FQU43EPY-DCVA_t-e.js → diagram-FQU43EPY-CHoFzsw6.js} +1 -1
- package/web/dist/assets/{diagram-G47NLZAW-pbTZGgE5.js → diagram-G47NLZAW-B8leqMRl.js} +1 -1
- package/web/dist/assets/{diagram-NH7WQ7WH-P8Iks122.js → diagram-NH7WQ7WH-DNoVxpa3.js} +1 -1
- package/web/dist/assets/{diagram-OA4YK3LP-hEjZPipp.js → diagram-OA4YK3LP-gC3Q2X6-.js} +1 -1
- package/web/dist/assets/{diagram-WEI45ONY-CVAzVCGu.js → diagram-WEI45ONY-CABqyjDl.js} +1 -1
- package/web/dist/assets/{ebnfDiagram-CCIWWBDH-BLL398qt.js → ebnfDiagram-CCIWWBDH-cSguXaDC.js} +1 -1
- package/web/dist/assets/{erDiagram-Q63AITRT-CLTADyUG.js → erDiagram-Q63AITRT-CoWX37V3.js} +1 -1
- package/web/dist/assets/{flowDiagram-23GEKE2U-BAdlWAt0.js → flowDiagram-23GEKE2U-I9DHYjhG.js} +1 -1
- package/web/dist/assets/{ganttDiagram-NO4QXBWP-C7Z2wavr.js → ganttDiagram-NO4QXBWP-DaFnfYTt.js} +1 -1
- package/web/dist/assets/{gitGraphDiagram-IHSO6WYX-BI546pYu.js → gitGraphDiagram-IHSO6WYX-CwiXVM_O.js} +1 -1
- package/web/dist/assets/{index-CvW-4eXF.css → index-CHlrgp0s.css} +1 -1
- package/web/dist/assets/index-bf7RCrAf.js +24 -0
- package/web/dist/assets/{infoDiagram-FWYZ7A6U-8C7iQydo.js → infoDiagram-FWYZ7A6U-DtzIrIpW.js} +1 -1
- package/web/dist/assets/{ishikawaDiagram-FXEZZL3T-Co4STVxQ.js → ishikawaDiagram-FXEZZL3T-B9nk829n.js} +1 -1
- package/web/dist/assets/{journeyDiagram-5HDEW3XC-DbUt11q-.js → journeyDiagram-5HDEW3XC-xLaPm-ow.js} +1 -1
- package/web/dist/assets/{kanban-definition-HUTT4EX6-DUNcFmme.js → kanban-definition-HUTT4EX6-BnDqLYLC.js} +1 -1
- package/web/dist/assets/{linear-Cjaxj94d.js → linear-Djc7nVo8.js} +1 -1
- package/web/dist/assets/{mermaid.core-B3cPFf4f.js → mermaid.core-B5elhUtV.js} +4 -4
- package/web/dist/assets/{mindmap-definition-LN4V7U3C-DaZtxB4N.js → mindmap-definition-LN4V7U3C-N-B7EJGs.js} +1 -1
- package/web/dist/assets/{papaparse.min-vfdso2fs.js → papaparse.min-BqM-LJkq.js} +1 -1
- package/web/dist/assets/{pegDiagram-2B236MQR-DkBpYV7m.js → pegDiagram-2B236MQR-BIollSMB.js} +1 -1
- package/web/dist/assets/{pieDiagram-ENE6RG2P-By3tI-vc.js → pieDiagram-ENE6RG2P-DkZY6iCd.js} +1 -1
- package/web/dist/assets/pilotswarm-Di5s6c69.js +105 -0
- package/web/dist/assets/{quadrantDiagram-ABIIQ3AL-DZmVm0xK.js → quadrantDiagram-ABIIQ3AL-iUDmQIyL.js} +1 -1
- package/web/dist/assets/{railroadDiagram-RFXS5EU6-BC5Mbz7q.js → railroadDiagram-RFXS5EU6-BSCGJgV7.js} +1 -1
- package/web/dist/assets/{requirementDiagram-TGXJPOKE-CyZNX_O1.js → requirementDiagram-TGXJPOKE-9yqcGRUA.js} +1 -1
- package/web/dist/assets/{sankeyDiagram-HTMAVEWB-7603NEmu.js → sankeyDiagram-HTMAVEWB-SPh1plT9.js} +1 -1
- package/web/dist/assets/{sequenceDiagram-DBY2YBRQ-CXJ-i2Xj.js → sequenceDiagram-DBY2YBRQ-C0nv5x71.js} +1 -1
- package/web/dist/assets/{sizeCapture-X5ZJPWSS-CKT0ATnS.js → sizeCapture-X5ZJPWSS-DMXfUt1o.js} +1 -1
- package/web/dist/assets/{stateDiagram-2N3HPSRC-BIDPX4YU.js → stateDiagram-2N3HPSRC-vjhtquua.js} +1 -1
- package/web/dist/assets/stateDiagram-v2-6OUMAXLB-CYIeYmPN.js +1 -0
- package/web/dist/assets/{swimlanes-5IMT3BWC-CPoy6vnO.js → swimlanes-5IMT3BWC-Bqewmkt5.js} +2 -2
- package/web/dist/assets/swimlanesDiagram-G3AALYLV-BeKhH9C9.js +8 -0
- package/web/dist/assets/{timeline-definition-FHXFAJF6-BGdNkplk.js → timeline-definition-FHXFAJF6-DYHsdXUL.js} +1 -1
- package/web/dist/assets/{vennDiagram-L72KCM5P-ByFzarUb.js → vennDiagram-L72KCM5P-Cb7cOHSa.js} +1 -1
- package/web/dist/assets/{wardleyDiagram-EHGQE667-CAk0SYuv.js → wardleyDiagram-EHGQE667-BHpO1byL.js} +1 -1
- package/web/dist/assets/{xychartDiagram-FW5EYKEG-Np7h6_A0.js → xychartDiagram-FW5EYKEG-DHDvGPtH.js} +1 -1
- package/web/dist/index.html +3 -3
- package/web/runtime.js +1 -0
- package/web/dist/assets/channel-COFs9dqk.js +0 -1
- package/web/dist/assets/classDiagram-OUVF2IWQ-B5-KmsCx.js +0 -1
- package/web/dist/assets/classDiagram-v2-EOCWNBFH-B5-KmsCx.js +0 -1
- package/web/dist/assets/index-DsPaDrf9.js +0 -24
- package/web/dist/assets/pilotswarm-BL_NbZug.js +0 -98
- package/web/dist/assets/stateDiagram-v2-6OUMAXLB-Dr8oD9T6.js +0 -1
- package/web/dist/assets/swimlanesDiagram-G3AALYLV-BV0EQRlB.js +0 -8
package/ui/core/src/moa.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
//
|
|
1
|
+
// Personal dashboards contain references and geometry only, never session data.
|
|
2
|
+
export const MOA_MAX_DASHBOARDS = 5;
|
|
2
3
|
export const MOA_MAX_PANELS = 16;
|
|
3
4
|
export const MOA_BREAKPOINT = 920;
|
|
4
5
|
const object = (v) => v && typeof v === "object" && !Array.isArray(v);
|
|
@@ -24,17 +25,37 @@ export function normalizeMoaLayout(value) {
|
|
|
24
25
|
return { name: typeof value.name === "string" ? value.name.trim().slice(0, 64) || "Untitled MoA" : "Untitled MoA", tree: value.tree == null ? null : walk(value.tree) };
|
|
25
26
|
}
|
|
26
27
|
export function normalizeMoa(value) {
|
|
27
|
-
const
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
28
|
+
const safeLayout = (layout, dashboardId = "moa-1", name = "MoA 1") => {
|
|
29
|
+
let tree = null;
|
|
30
|
+
try { tree = normalizeMoaLayout(layout).tree; } catch {}
|
|
31
|
+
const leaves = moaLeaves(tree);
|
|
32
|
+
return { id: dashboardId, name: typeof layout?.name === "string" ? layout.name.trim().slice(0, 64) || name : name, tree,
|
|
33
|
+
...(Number.isFinite(layout?.aspectRatio) && layout.aspectRatio >= .2 && layout.aspectRatio <= 8 ? { aspectRatio: layout.aspectRatio } : {}),
|
|
34
|
+
focusedPanelId: leaves.some(p => p.id === layout?.focusedPanelId) ? layout.focusedPanelId : leaves[0]?.id || null };
|
|
35
|
+
};
|
|
36
|
+
if (value?.version === 3 && Array.isArray(value.dashboards)) {
|
|
37
|
+
const used = new Set();
|
|
38
|
+
const dashboards = value.dashboards.slice(0, MOA_MAX_DASHBOARDS).map((dashboard, index) => {
|
|
39
|
+
let key = id(dashboard?.id) && !used.has(dashboard.id) ? dashboard.id : `moa-${index + 1}`;
|
|
40
|
+
while (used.has(key)) key += "-copy";
|
|
41
|
+
used.add(key);
|
|
42
|
+
return safeLayout(dashboard, key, `MoA ${index + 1}`);
|
|
43
|
+
});
|
|
44
|
+
if (!dashboards.length) dashboards.push(safeLayout(null));
|
|
45
|
+
return { version: 3, activeDashboardId: dashboards.some(d => d.id === value.activeDashboardId) ? value.activeDashboardId : dashboards[0].id, dashboards };
|
|
31
46
|
}
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
47
|
+
let source = value;
|
|
48
|
+
if (!(value?.version === 2 || (object(value) && Object.hasOwn(value, "tree")))) {
|
|
49
|
+
// Match the old single-workspace migration; do not resurrect discarded tabs.
|
|
50
|
+
const slots = Array.isArray(value?.slots) ? value.slots.slice(0, 5) : [];
|
|
51
|
+
const active = Number.isInteger(value?.activeSlot) ? Math.max(0, Math.min(4, value.activeSlot)) : 0;
|
|
52
|
+
source = safeLayout(slots[active]).tree ? slots[active] : slots.find(slot => safeLayout(slot).tree);
|
|
53
|
+
}
|
|
54
|
+
return { version: 3, activeDashboardId: "moa-1", dashboards: [safeLayout(source)] };
|
|
55
|
+
}
|
|
56
|
+
export const activeMoaDashboard = value => value.dashboards.find(d => d.id === value.activeDashboardId) || value.dashboards[0];
|
|
57
|
+
export function updateMoaDashboard(value, dashboardId, patch) {
|
|
58
|
+
return normalizeMoa({ ...value, dashboards: value.dashboards.map(d => d.id === dashboardId ? { ...d, ...patch } : d) });
|
|
38
59
|
}
|
|
39
60
|
export function replaceMoaNode(tree, nodeId, next) {
|
|
40
61
|
if (!tree) return null;
|
package/ui/core/src/reducer.js
CHANGED
|
@@ -379,7 +379,7 @@ function mergeDefinedSessionFields(previousSession = {}, nextSession = {}) {
|
|
|
379
379
|
// An absent/invalid counter must not erase the last known server version.
|
|
380
380
|
if (key === "statusVersion" && previousVersion != null
|
|
381
381
|
&& sessionStatusVersion(nextSession) == null) continue;
|
|
382
|
-
if (key === "pendingQuestion" && isAnsweredPendingQuestion(previousSession, value)) {
|
|
382
|
+
if (key === "pendingQuestion" && isAnsweredPendingQuestion(previousSession, value, nextSession)) {
|
|
383
383
|
if (merged === previousSession) {
|
|
384
384
|
merged = { ...(previousSession || {}) };
|
|
385
385
|
}
|
|
@@ -555,10 +555,18 @@ function normalizedPendingQuestionText(pendingQuestion) {
|
|
|
555
555
|
return String(pendingQuestion?.question || "").trim();
|
|
556
556
|
}
|
|
557
557
|
|
|
558
|
-
function isAnsweredPendingQuestion(previousSession, pendingQuestion) {
|
|
559
|
-
const answeredQuestion = normalizedPendingQuestionText(previousSession?.answeredPendingQuestion);
|
|
558
|
+
function isAnsweredPendingQuestion(previousSession, pendingQuestion, nextSession) {
|
|
560
559
|
const incomingQuestion = normalizedPendingQuestionText(pendingQuestion);
|
|
561
|
-
|
|
560
|
+
if (!incomingQuestion) return false;
|
|
561
|
+
const incomingTime = sessionUpdateTimestampMs({ updatedAt: pendingQuestion?.askedAt })
|
|
562
|
+
|| sessionUpdateTimestampMs(nextSession);
|
|
563
|
+
return [previousSession?.answeredPendingQuestion, previousSession?.resolvedInputQuestion].some(answered => {
|
|
564
|
+
if (normalizedPendingQuestionText(answered) !== incomingQuestion) return false;
|
|
565
|
+
const answeredAt = sessionUpdateTimestampMs({ updatedAt: answered?.answeredAt });
|
|
566
|
+
// Preserve the answer fence across stale detail polls, but let a new
|
|
567
|
+
// instance of the same question through when it was asked later.
|
|
568
|
+
return !incomingTime || !answeredAt || incomingTime <= answeredAt;
|
|
569
|
+
});
|
|
562
570
|
}
|
|
563
571
|
|
|
564
572
|
function pickDefaultActiveSessionId(sessions = []) {
|
package/ui/core/src/selectors.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { INSPECTOR_TABS, FOCUS_REGIONS } from "./commands.js";
|
|
2
|
+
import { chatCallLine, firstCallLine } from "./chat-activity.js";
|
|
2
3
|
import { canvasKey as canvasSlotKey, parseCanvasKey } from "./state.js";
|
|
3
4
|
import { isManuallyOrderableSession } from "./session-tree.js";
|
|
4
5
|
import {
|
|
@@ -28,7 +29,7 @@ import {
|
|
|
28
29
|
getContextHeaderBadge,
|
|
29
30
|
} from "./context-usage.js";
|
|
30
31
|
import { canonicalSystemTitle } from "./system-titles.js";
|
|
31
|
-
import { withSessionWarnings } from "./session-errors.js";
|
|
32
|
+
import { withSessionWarnings, isActivityOnlySessionError } from "./session-errors.js";
|
|
32
33
|
import {
|
|
33
34
|
BUDGET_PERIODS,
|
|
34
35
|
BUDGET_SERIES_DAYS,
|
|
@@ -1645,7 +1646,7 @@ function chatAlreadyContainsPendingQuestion(chat, question) {
|
|
|
1645
1646
|
|
|
1646
1647
|
function buildSessionErrorMessage(session, events = []) {
|
|
1647
1648
|
const errorText = String(session?.error || "").trim();
|
|
1648
|
-
if (!errorText) return null;
|
|
1649
|
+
if (!errorText || isActivityOnlySessionError(errorText)) return null;
|
|
1649
1650
|
|
|
1650
1651
|
const errorKind = getSessionErrorVisualKind(session);
|
|
1651
1652
|
if (!errorKind) return null;
|
|
@@ -2251,6 +2252,7 @@ function chatMessageSpacingKind(message) {
|
|
|
2251
2252
|
|
|
2252
2253
|
function shouldInsertChatSpacer(currentMessage, nextMessage) {
|
|
2253
2254
|
if (!currentMessage || !nextMessage) return false;
|
|
2255
|
+
if (currentMessage.kind === "chat-call" || nextMessage.kind === "chat-call") return false;
|
|
2254
2256
|
return chatMessageSpacingKind(currentMessage) !== chatMessageSpacingKind(nextMessage);
|
|
2255
2257
|
}
|
|
2256
2258
|
|
|
@@ -2287,7 +2289,7 @@ function buildCollapsedSystemNoticeLine(text, timestamp = "") {
|
|
|
2287
2289
|
};
|
|
2288
2290
|
}
|
|
2289
2291
|
|
|
2290
|
-
function buildSystemNoticeLine({ title, summary, body, timestamp = "", color = "gray" }) {
|
|
2292
|
+
function buildSystemNoticeLine({ title, summary, body, timestamp = "", color = "gray", callPreview, callKey }) {
|
|
2291
2293
|
const normalizedTitle = String(title || "System").trim() || "System";
|
|
2292
2294
|
const normalizedSummary = String(summary || "").replace(/\s+/g, " ").trim();
|
|
2293
2295
|
return {
|
|
@@ -2296,6 +2298,7 @@ function buildSystemNoticeLine({ title, summary, body, timestamp = "", color = "
|
|
|
2296
2298
|
summary: normalizedSummary,
|
|
2297
2299
|
body: decorateArtifactLinksForChat(body || normalizedSummary),
|
|
2298
2300
|
color,
|
|
2301
|
+
...(callPreview !== undefined ? { callPreview: `${normalizedTitle} — ${firstCallLine(callPreview)}`, callKey } : {}),
|
|
2299
2302
|
};
|
|
2300
2303
|
}
|
|
2301
2304
|
|
|
@@ -2401,6 +2404,8 @@ function buildSystemNoticeCardLines(systemText, message, maxWidth) {
|
|
|
2401
2404
|
].filter((line, index) => index === 2 || line).join("\n");
|
|
2402
2405
|
return [buildSystemNoticeLine({
|
|
2403
2406
|
title: `Sub-agent Response — ${shortId}`,
|
|
2407
|
+
callPreview: subAgent.result || subAgent.status,
|
|
2408
|
+
callKey: `${message.id}:agent:${shortId}`,
|
|
2404
2409
|
summary: subAgent.status || "completed",
|
|
2405
2410
|
timestamp,
|
|
2406
2411
|
body,
|
|
@@ -2420,6 +2425,8 @@ function buildSystemNoticeCardLines(systemText, message, maxWidth) {
|
|
|
2420
2425
|
.join(" · ");
|
|
2421
2426
|
return [buildSystemNoticeLine({
|
|
2422
2427
|
title: `Sub-agent Responses (${subAgent.agents.length})`,
|
|
2428
|
+
callPreview: subAgent.agents.map(agent => firstCallLine(agent.result) || agent.status).join(" · "),
|
|
2429
|
+
callKey: `${message.id}:agents`,
|
|
2423
2430
|
summary,
|
|
2424
2431
|
timestamp,
|
|
2425
2432
|
body: sections.join("\n\n---\n\n"),
|
|
@@ -2505,6 +2512,17 @@ function buildChatMessageLines(message, maxWidth, options = {}) {
|
|
|
2505
2512
|
}
|
|
2506
2513
|
|
|
2507
2514
|
function buildChatMessageLinesUncached(message, maxWidth, options = {}) {
|
|
2515
|
+
if (message?.kind === "chat-call") {
|
|
2516
|
+
return options.tableMode === "sentinel" ? [chatCallLine(message)] : [];
|
|
2517
|
+
}
|
|
2518
|
+
if (options.tableMode === "sentinel" && (message?.sender?.kind === "agent" || message?.agentCallPreview !== undefined)) {
|
|
2519
|
+
const label = message.cardTitle || message.sender?.display || "Agent message";
|
|
2520
|
+
return [{
|
|
2521
|
+
kind: "chatCall", callKey: message.id, category: "Agent",
|
|
2522
|
+
text: `${label} — ${firstCallLine(message.agentCallPreview ?? message.text)}`,
|
|
2523
|
+
body: message.text, time: message.time,
|
|
2524
|
+
}];
|
|
2525
|
+
}
|
|
2508
2526
|
if (message?.splash) {
|
|
2509
2527
|
// Swap in the narrow-viewport variant when the main art would
|
|
2510
2528
|
// overflow the pane (mobile portal, narrow terminals). When the
|
|
@@ -2574,7 +2592,9 @@ function buildChatMessageLinesUncached(message, maxWidth, options = {}) {
|
|
|
2574
2592
|
const askedAndAnswered = parseAskedAndAnsweredExchange(message?.text || "");
|
|
2575
2593
|
if (askedAndAnswered) {
|
|
2576
2594
|
return [
|
|
2577
|
-
|
|
2595
|
+
// Older runtimes inserted this placeholder for late answers.
|
|
2596
|
+
// Keep the user's answer, without displaying a fabricated card.
|
|
2597
|
+
...(askedAndAnswered.question === "a question" ? [] : buildMessageCardLines({
|
|
2578
2598
|
title: "Question",
|
|
2579
2599
|
timestamp: formatTimestamp(message?.createdAt || message?.time),
|
|
2580
2600
|
body: askedAndAnswered.question,
|
|
@@ -2582,7 +2602,7 @@ function buildChatMessageLinesUncached(message, maxWidth, options = {}) {
|
|
|
2582
2602
|
titleColor: USER_CHAT_COLOR,
|
|
2583
2603
|
borderColor: USER_CHAT_COLOR,
|
|
2584
2604
|
tableMode: options.tableMode,
|
|
2585
|
-
}),
|
|
2605
|
+
})),
|
|
2586
2606
|
...buildChatMessageLines({
|
|
2587
2607
|
...message,
|
|
2588
2608
|
text: askedAndAnswered.answer,
|
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
// Copilot emits this diagnostic for an accepted turn without visible text.
|
|
2
|
+
// Keep its durable event and Activity entry, but do not turn it into a chat
|
|
3
|
+
// warning. Match only this message and the runtime's known retry wrapper.
|
|
4
|
+
export function isActivityOnlySessionError(text) {
|
|
5
|
+
return /^(?:Execution failed:\s*)?No response was returned\. Send your message again to retry\.(?: \(retry \d+\/\d+ in \d+s\))?$/.test(String(text || "").trim());
|
|
6
|
+
}
|
|
7
|
+
|
|
1
8
|
export function shouldKeepSessionWarning(previousSession, nextSession) {
|
|
2
9
|
if (!String(previousSession?.error || "").trim()) return false;
|
|
3
10
|
if (nextSession?.error !== undefined) return false;
|
|
@@ -26,7 +33,7 @@ const sameError = (statusText, eventText) => Boolean(eventText) && statusText.in
|
|
|
26
33
|
|
|
27
34
|
export function buildSessionWarning(event) {
|
|
28
35
|
const text = errorText(event);
|
|
29
|
-
if (!text) return null;
|
|
36
|
+
if (!text || isActivityOnlySessionError(text)) return null;
|
|
30
37
|
const failed = event?.data?.fatal === true;
|
|
31
38
|
return {
|
|
32
39
|
id: `${event.sessionId}:${event.seq}:warning`,
|
|
@@ -79,8 +86,9 @@ export function retainSessionWarnings(previous, next, events = [], now = Date.no
|
|
|
79
86
|
}
|
|
80
87
|
|
|
81
88
|
export function withSessionWarnings(chat, session, events = []) {
|
|
82
|
-
const messages =
|
|
89
|
+
const messages = chat.filter(message => message.kind !== "session-warning" || !isActivityOnlySessionError(message.text));
|
|
83
90
|
for (const warning of session?.chatWarnings || []) {
|
|
91
|
+
if (isActivityOnlySessionError(warning.text)) continue;
|
|
84
92
|
// Status often wins the race against its durable event. Match only
|
|
85
93
|
// that boundary, never a later failure after a new user/agent message.
|
|
86
94
|
const following = events.filter(e => Number(e.seq) > warning.afterSeq);
|
|
@@ -5,12 +5,14 @@ export function canonicalSystemTitle(session, brandingTitle = "PilotSwarm") {
|
|
|
5
5
|
if (agentId === "sweeper") return "Sweeper Agent";
|
|
6
6
|
if (agentId === "resourcemgr") return "Resource Manager Agent";
|
|
7
7
|
if (agentId === "facts-manager") return "Facts Manager";
|
|
8
|
+
if (agentId === "agent-manager") return "Agent Smith";
|
|
8
9
|
|
|
9
10
|
const rawTitle = String(session?.title || "").trim();
|
|
10
11
|
if (/^pilotswarm(?: agent)?$/i.test(rawTitle)) return brandedRootTitle;
|
|
11
12
|
if (/^sweeper agent$/i.test(rawTitle) || /^sweeper$/i.test(rawTitle)) return "Sweeper Agent";
|
|
12
13
|
if (/^resource manager agent$/i.test(rawTitle) || /^resourcemgr$/i.test(rawTitle)) return "Resource Manager Agent";
|
|
13
14
|
if (/^facts manager$/i.test(rawTitle) || /^facts-manager$/i.test(rawTitle)) return "Facts Manager";
|
|
15
|
+
if (/^agent manager$/i.test(rawTitle)) return "Agent Smith";
|
|
14
16
|
return rawTitle || "System Agent";
|
|
15
17
|
}
|
|
16
18
|
|
package/ui/react/src/web-app.js
CHANGED
|
@@ -607,12 +607,8 @@ function materializeProfileSettings(remoteSettings, defaults) {
|
|
|
607
607
|
// synthesizing one here would let a poll clobber a fresh local toggle.
|
|
608
608
|
...(hasOwn(normalizedRemote, touchScaleKey())
|
|
609
609
|
? { touchScale: normalizedRemote[touchScaleKey()] }
|
|
610
|
-
//
|
|
611
|
-
|
|
612
|
-
// inherit it, and only until it saves a slot of its own.
|
|
613
|
-
: (isNarrowViewport() && hasOwn(normalizedRemote, "touchScale")
|
|
614
|
-
? { touchScale: normalizedRemote.touchScale }
|
|
615
|
-
: {})),
|
|
610
|
+
// Never inherit the other device class's preference.
|
|
611
|
+
: {}),
|
|
616
612
|
// Read back for the same reason as touchScale above: written but never
|
|
617
613
|
// merged means the fold state resets on every reload. No default here
|
|
618
614
|
// either — absent must stay absent so a poll cannot overwrite a toggle
|
|
@@ -1331,6 +1327,22 @@ function SystemNoticeLine({ line, theme }) {
|
|
|
1331
1327
|
: null);
|
|
1332
1328
|
}
|
|
1333
1329
|
|
|
1330
|
+
function ChatCallLine({ line }) {
|
|
1331
|
+
const [open, setOpen] = React.useState(false);
|
|
1332
|
+
return React.createElement("details", {
|
|
1333
|
+
className: "ps-system-notice ps-chat-call",
|
|
1334
|
+
"data-call-id": line.callKey,
|
|
1335
|
+
onToggle: event => setOpen(event.currentTarget.open),
|
|
1336
|
+
},
|
|
1337
|
+
React.createElement("summary", { className: "ps-system-notice-summary ps-chat-call-summary" },
|
|
1338
|
+
React.createElement("span", { className: "ps-chat-call-tag" }, line.category || "Tool"),
|
|
1339
|
+
React.createElement("span", { className: "ps-system-notice-summary-text" }, line.text),
|
|
1340
|
+
line.status ? React.createElement("span", { className: `ps-chat-call-status${line.status === "Failed" ? " is-failed" : ""}` }, line.status) : null),
|
|
1341
|
+
open ? React.createElement("div", { className: "ps-system-notice-body" },
|
|
1342
|
+
line.time ? React.createElement("div", { className: "ps-chat-call-time" }, line.time) : null,
|
|
1343
|
+
React.createElement("pre", { className: "ps-chat-call-payload" }, line.body)) : null);
|
|
1344
|
+
}
|
|
1345
|
+
|
|
1334
1346
|
/**
|
|
1335
1347
|
* A canvas action is a button press inside the drawn page, not something the
|
|
1336
1348
|
* viewer typed. Printing the raw `[canvas-action] {…}` JSON as a chat message
|
|
@@ -3230,6 +3242,13 @@ function parseStructuredChatBlocks(lines = []) {
|
|
|
3230
3242
|
for (let index = 0; index < lines.length;) {
|
|
3231
3243
|
const currentLine = lines[index];
|
|
3232
3244
|
|
|
3245
|
+
if (currentLine?.kind === "chatCall" || currentLine?.callPreview !== undefined) {
|
|
3246
|
+
blocks.push({ type: "chatCall", line: currentLine.callPreview !== undefined
|
|
3247
|
+
? { ...currentLine, text: currentLine.callPreview, category: "Agent" } : currentLine });
|
|
3248
|
+
index += 1;
|
|
3249
|
+
continue;
|
|
3250
|
+
}
|
|
3251
|
+
|
|
3233
3252
|
if (currentLine?.kind === "assistantPreview") {
|
|
3234
3253
|
blocks.push({ type: "assistantPreview", line: currentLine });
|
|
3235
3254
|
index += 1;
|
|
@@ -3655,6 +3674,9 @@ const AssistantPreviewCard = React.memo(function AssistantPreviewCard({ line, th
|
|
|
3655
3674
|
function StructuredBlockList({ blocks, theme, controller = null }) {
|
|
3656
3675
|
return React.createElement(React.Fragment, null,
|
|
3657
3676
|
(blocks || []).map((block, index) => {
|
|
3677
|
+
if (block.type === "chatCall") {
|
|
3678
|
+
return React.createElement(ChatCallLine, { key: block.line.callKey, line: block.line });
|
|
3679
|
+
}
|
|
3658
3680
|
if (block.type === "assistantPreview") {
|
|
3659
3681
|
return React.createElement(AssistantPreviewCard, {
|
|
3660
3682
|
key: block.line.previewKey,
|
|
@@ -4216,7 +4238,7 @@ export function waitReasonLabel(session) {
|
|
|
4216
4238
|
return session?.cronActive === true ? "On wake" : "Waiting";
|
|
4217
4239
|
}
|
|
4218
4240
|
|
|
4219
|
-
function SessionDetailBox({ session, childCount = 0, pause = null, controller = null, collapsed = false, onToggle = null }) {
|
|
4241
|
+
function SessionDetailBox({ session, childCount = 0, pause = null, controller = null, collapsed = false, onToggle = null, onOpenBudget = null }) {
|
|
4220
4242
|
// EVERY field renders on EVERY selection, empty ones as an em dash. The box
|
|
4221
4243
|
// is a fixed grid of rows, so moving through the list cannot change its
|
|
4222
4244
|
// height — a box that grew and shrank would shove the list under the
|
|
@@ -4313,12 +4335,12 @@ function SessionDetailBox({ session, childCount = 0, pause = null, controller =
|
|
|
4313
4335
|
pause && pause.clears
|
|
4314
4336
|
? React.createElement("span", { className: "ps-session-detail-clears" }, pause.clears)
|
|
4315
4337
|
: null,
|
|
4316
|
-
pause && controller ? React.createElement("button", {
|
|
4338
|
+
pause && (controller || onOpenBudget) ? React.createElement("button", {
|
|
4317
4339
|
type: "button", className: "ps-budget-link",
|
|
4318
4340
|
title: pause.provider
|
|
4319
4341
|
? `Open ${pause.provider} in Providers & Budgets`
|
|
4320
4342
|
: "Open providers and budgets",
|
|
4321
|
-
onClick: () => controller.openBudget(
|
|
4343
|
+
onClick: () => (onOpenBudget || (options => controller.openBudget(options)))(
|
|
4322
4344
|
pause.provider ? { provider: pause.provider } : {},
|
|
4323
4345
|
).catch(() => {}),
|
|
4324
4346
|
}, pause.provider ? `Open ${pause.provider}` : "Open providers and budgets") : null));
|
|
@@ -6408,7 +6430,7 @@ function SessionModifyModal({ controller, sessionId, initialTitle, currentModel,
|
|
|
6408
6430
|
error ? React.createElement("div", { className: "ps-share-error" }, error) : null));
|
|
6409
6431
|
}
|
|
6410
6432
|
|
|
6411
|
-
function SessionComposer({ controller, onReadOnlyFocus = null, mobile = false, compact = false }) {
|
|
6433
|
+
function SessionComposer({ controller, onReadOnlyFocus = null, mobile = false, compact = false, autoFocus = !mobile }) {
|
|
6412
6434
|
const modal = useControllerSelector(controller, state => state.ui.modal);
|
|
6413
6435
|
const session = useControllerSelector(controller, state => state.sessions.byId[state.sessions.activeSessionId]);
|
|
6414
6436
|
const { access } = useActiveSessionAccess(controller, session?.sessionId, session?.isGroup);
|
|
@@ -6419,7 +6441,7 @@ function SessionComposer({ controller, onReadOnlyFocus = null, mobile = false, c
|
|
|
6419
6441
|
? React.createElement("div", { className: "ps-composer-readonly" }, session.serviceKind
|
|
6420
6442
|
? "⚗ Service session — runtime machinery. Its transcript is a read-only trace; it does not accept messages."
|
|
6421
6443
|
: `You have view access to this session. Ask ${access.owner?.displayName || access.owner?.email || "the owner"} for write access to participate.`)
|
|
6422
|
-
: React.createElement(PromptComposer, { controller, mobile, compact, autoFocus
|
|
6444
|
+
: React.createElement(PromptComposer, { controller, mobile, compact, autoFocus, active: true }));
|
|
6423
6445
|
}
|
|
6424
6446
|
|
|
6425
6447
|
// The compact focus views use their existing header for activity. The same
|
|
@@ -8850,7 +8872,7 @@ function PromptComposer({ controller, mobile, compact = false, active = true, on
|
|
|
8850
8872
|
const inputNode = inputRef.current;
|
|
8851
8873
|
if (!active || promptState.modalOpen || !promptState.focused || !inputNode) return;
|
|
8852
8874
|
if (document.activeElement !== inputNode) {
|
|
8853
|
-
if (!autoFocus) return;
|
|
8875
|
+
if (!autoFocus || (typeof autoFocus === "function" && !autoFocus())) return;
|
|
8854
8876
|
// Programmatic focus pops the on-screen keyboard on touch devices;
|
|
8855
8877
|
// there, focus only ever comes from the user's own tap.
|
|
8856
8878
|
if (mobile) return;
|
|
@@ -14302,6 +14324,9 @@ export function createWebPilotSwarmController({ transport, mode = "remote", bran
|
|
|
14302
14324
|
branding,
|
|
14303
14325
|
docs,
|
|
14304
14326
|
}));
|
|
14327
|
+
// Only the initial device default. A saved value for this device wins
|
|
14328
|
+
// when the profile loads, including an explicit mobile opt-out.
|
|
14329
|
+
store.dispatch({ type: "ui/touchScale", enabled: isNarrowViewport });
|
|
14305
14330
|
return new PilotSwarmUiController({ store, transport });
|
|
14306
14331
|
}
|
|
14307
14332
|
|
package/web/dist/assets/{abnfDiagram-VRR7QNED-CCVkGWsr.js → abnfDiagram-VRR7QNED-DAiG41W-.js}
RENAMED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{g as p,r as u,d as a}from"./chunk-MOJQB5TN-
|
|
1
|
+
import{g as p,r as u,d as a}from"./chunk-MOJQB5TN-l907LpMA.js";import{p as f}from"./chunk-JWPE2WC7-Cj5lvEfN.js";import{_ as n,l as o}from"./mermaid.core-B5elhUtV.js";import{M as c,b as d}from"./cynefin-VYW2F7L2-CminxBoG.js";import"./pilotswarm-Di5s6c69.js";var v=d().RailroadAbnf.parser.LangiumParser,i=n(e=>{const r=e.alternatives.map(g);return r.length===1?r[0]:{type:"choice",alternatives:r}},"transformAlternation"),g=n(e=>{const r=e.elements.map(y);return r.length===1?r[0]:{type:"sequence",elements:r}},"transformConcatenation"),b=n(e=>{if(e.includes("*")){const[t,s]=e.split("*"),l=t?parseInt(t,10):0,m=s?parseInt(s,10):1/0;return{min:l,max:m}}const r=parseInt(e,10);return{min:r,max:r}},"parseRepeat"),y=n(e=>{const r=A(e.primary);if(!e.repeat)return r;const{min:t,max:s}=b(e.repeat);return t===0&&s===1?{type:"optional",element:r}:{type:"repetition",element:r,min:t,max:s}},"transformElement"),A=n(e=>{switch(e.$type){case"AbnfStringLiteral":return{type:"terminal",value:e.value};case"AbnfNumVal":return{type:"terminal",value:e.value};case"AbnfRuleName":return{type:"nonterminal",name:e.name};case"AbnfGroup":return i(e.element);case"AbnfOptionalGroup":return{type:"optional",element:i(e.element)};default:throw new Error(`Unsupported ABNF primary node: ${e.$type}`)}},"transformPrimary"),P=n(e=>({name:e.name,definition:i(e.definition)}),"transformRule"),h=n(e=>{f(e,a),e.title&&a.setTitle(e.title),e.rules.map(r=>a.addRule(P(r)))},"populateDb"),R={parse:n(e=>{a.clear(),o.debug("[ABNF Parser] Starting Langium parse");const r=v.parse(e);if(r.lexerErrors.length>0||r.parserErrors.length>0)throw new c(r);const t=r.value;o.debug("[ABNF Parser] Parsed rules:",t.rules.length),h(t),o.debug("[ABNF Parser] Parse complete")},"parse"),parser:{yy:a}},B={parser:R,db:a,renderer:u,styles:p};export{B as diagram};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{Y as ln,$ as an,a0 as F,a1 as q,a2 as j,a3 as un,a4 as y,a5 as tn,a6 as J,a7 as _,a8 as rn,a9 as o,aa as on,ab as sn,ac as fn}from"./mermaid.core-
|
|
1
|
+
import{Y as ln,$ as an,a0 as F,a1 as q,a2 as j,a3 as un,a4 as y,a5 as tn,a6 as J,a7 as _,a8 as rn,a9 as o,aa as on,ab as sn,ac as fn}from"./mermaid.core-B5elhUtV.js";function cn(l){return l.innerRadius}function yn(l){return l.outerRadius}function gn(l){return l.startAngle}function dn(l){return l.endAngle}function mn(l){return l&&l.padAngle}function pn(l,h,I,D,v,A,z,a){var O=I-l,i=D-h,n=z-v,d=a-A,u=d*O-n*i;if(!(u*u<y))return u=(n*(h-A)-d*(l-v))/u,[l+u*O,h+u*i]}function U(l,h,I,D,v,A,z){var a=l-I,O=h-D,i=(z?A:-A)/J(a*a+O*O),n=i*O,d=-i*a,u=l+n,s=h+d,f=I+n,c=D+d,B=(u+f)/2,t=(s+c)/2,m=f-u,g=c-s,R=m*m+g*g,T=v-A,P=u*c-f*s,S=(g<0?-1:1)*J(on(0,T*T*R-P*P)),Y=(P*g-m*S)/R,$=(-P*m-g*S)/R,w=(P*g+m*S)/R,p=(-P*m+g*S)/R,x=Y-B,e=$-t,r=w-B,C=p-t;return x*x+e*e>r*r+C*C&&(Y=w,$=p),{cx:Y,cy:$,x01:-n,y01:-d,x11:Y*(v/T-1),y11:$*(v/T-1)}}function hn(){var l=cn,h=yn,I=j(0),D=null,v=gn,A=dn,z=mn,a=null,O=ln(i);function i(){var n,d,u=+l.apply(this,arguments),s=+h.apply(this,arguments),f=v.apply(this,arguments)-un,c=A.apply(this,arguments)-un,B=rn(c-f),t=c>f;if(a||(a=n=O()),s<u&&(d=s,s=u,u=d),!(s>y))a.moveTo(0,0);else if(B>tn-y)a.moveTo(s*F(f),s*q(f)),a.arc(0,0,s,f,c,!t),u>y&&(a.moveTo(u*F(c),u*q(c)),a.arc(0,0,u,c,f,t));else{var m=f,g=c,R=f,T=c,P=B,S=B,Y=z.apply(this,arguments)/2,$=Y>y&&(D?+D.apply(this,arguments):J(u*u+s*s)),w=_(rn(s-u)/2,+I.apply(this,arguments)),p=w,x=w,e,r;if($>y){var C=sn($/u*q(Y)),K=sn($/s*q(Y));(P-=C*2)>y?(C*=t?1:-1,R+=C,T-=C):(P=0,R=T=(f+c)/2),(S-=K*2)>y?(K*=t?1:-1,m+=K,g-=K):(S=0,m=g=(f+c)/2)}var G=s*F(m),H=s*q(m),L=u*F(T),M=u*q(T);if(w>y){var N=s*F(g),Q=s*q(g),V=u*F(R),W=u*q(R),E;if(B<an)if(E=pn(G,H,V,W,N,Q,L,M)){var X=G-E[0],Z=H-E[1],b=N-E[0],k=Q-E[1],nn=1/q(fn((X*b+Z*k)/(J(X*X+Z*Z)*J(b*b+k*k)))/2),en=J(E[0]*E[0]+E[1]*E[1]);p=_(w,(u-en)/(nn-1)),x=_(w,(s-en)/(nn+1))}else p=x=0}S>y?x>y?(e=U(V,W,G,H,s,x,t),r=U(N,Q,L,M,s,x,t),a.moveTo(e.cx+e.x01,e.cy+e.y01),x<w?a.arc(e.cx,e.cy,x,o(e.y01,e.x01),o(r.y01,r.x01),!t):(a.arc(e.cx,e.cy,x,o(e.y01,e.x01),o(e.y11,e.x11),!t),a.arc(0,0,s,o(e.cy+e.y11,e.cx+e.x11),o(r.cy+r.y11,r.cx+r.x11),!t),a.arc(r.cx,r.cy,x,o(r.y11,r.x11),o(r.y01,r.x01),!t))):(a.moveTo(G,H),a.arc(0,0,s,m,g,!t)):a.moveTo(G,H),!(u>y)||!(P>y)?a.lineTo(L,M):p>y?(e=U(L,M,N,Q,u,-p,t),r=U(G,H,V,W,u,-p,t),a.lineTo(e.cx+e.x01,e.cy+e.y01),p<w?a.arc(e.cx,e.cy,p,o(e.y01,e.x01),o(r.y01,r.x01),!t):(a.arc(e.cx,e.cy,p,o(e.y01,e.x01),o(e.y11,e.x11),!t),a.arc(0,0,u,o(e.cy+e.y11,e.cx+e.x11),o(r.cy+r.y11,r.cx+r.x11),t),a.arc(r.cx,r.cy,p,o(r.y11,r.x11),o(r.y01,r.x01),!t))):a.arc(0,0,u,T,R,t)}if(a.closePath(),n)return a=null,n+""||null}return i.centroid=function(){var n=(+l.apply(this,arguments)+ +h.apply(this,arguments))/2,d=(+v.apply(this,arguments)+ +A.apply(this,arguments))/2-an/2;return[F(d)*n,q(d)*n]},i.innerRadius=function(n){return arguments.length?(l=typeof n=="function"?n:j(+n),i):l},i.outerRadius=function(n){return arguments.length?(h=typeof n=="function"?n:j(+n),i):h},i.cornerRadius=function(n){return arguments.length?(I=typeof n=="function"?n:j(+n),i):I},i.padRadius=function(n){return arguments.length?(D=n==null?null:typeof n=="function"?n:j(+n),i):D},i.startAngle=function(n){return arguments.length?(v=typeof n=="function"?n:j(+n),i):v},i.endAngle=function(n){return arguments.length?(A=typeof n=="function"?n:j(+n),i):A},i.padAngle=function(n){return arguments.length?(z=typeof n=="function"?n:j(+n),i):z},i.context=function(n){return arguments.length?(a=n??null,i):a},i}export{hn as d};
|