pilotswarm 0.5.14 → 0.5.16
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/README.md +2 -2
- package/mcp/dist/src/server.d.ts.map +1 -1
- package/mcp/dist/src/server.js +5 -1
- package/mcp/dist/src/server.js.map +1 -1
- package/mcp/dist/src/tools/capabilities.d.ts +1 -0
- package/mcp/dist/src/tools/capabilities.d.ts.map +1 -1
- package/mcp/dist/src/tools/capabilities.js +5 -0
- package/mcp/dist/src/tools/capabilities.js.map +1 -1
- package/mcp/dist/src/tools/groups.d.ts +5 -4
- package/mcp/dist/src/tools/groups.d.ts.map +1 -1
- package/mcp/dist/src/tools/groups.js +43 -20
- package/mcp/dist/src/tools/groups.js.map +1 -1
- package/mcp/dist/src/tools/sessions.d.ts.map +1 -1
- package/mcp/dist/src/tools/sessions.js +4 -2
- package/mcp/dist/src/tools/sessions.js.map +1 -1
- package/package.json +2 -2
- package/tui/plugins/.mcp.json +7 -1
- package/tui/plugins/agents/deepwiki.agent.md +44 -0
- package/tui/src/node-sdk-transport.js +61 -8
- package/ui/core/src/controller.js +264 -40
- package/ui/core/src/formatting.js +25 -0
- package/ui/core/src/reducer.js +117 -8
- package/ui/core/src/selectors.js +76 -3
- package/ui/core/src/state.js +3 -0
- package/ui/react/src/web-app.js +363 -127
- package/web/api/router.js +3 -1
- package/web/dist/assets/index-Df1mD9p0.js +24 -0
- package/web/dist/assets/index-whIft7M6.css +1 -0
- package/web/dist/assets/pilotswarm-DR5j-z8y.js +90 -0
- package/web/dist/index.html +3 -3
- package/web/runtime.js +114 -42
- package/web/dist/assets/index-BnxC8cNG.js +0 -24
- package/web/dist/assets/index-Bx6KHIaj.css +0 -1
- package/web/dist/assets/pilotswarm-NE7H63ha.js +0 -90
package/ui/core/src/reducer.js
CHANGED
|
@@ -324,6 +324,12 @@ function resolveVisibleActiveSessionId(state, fallbackSessions = []) {
|
|
|
324
324
|
if (currentSessionId && visibleRows.some((row) => row.sessionId === currentSessionId)) {
|
|
325
325
|
return currentSessionId;
|
|
326
326
|
}
|
|
327
|
+
// A navigation intent (deep link) owns selection until it is cleared by
|
|
328
|
+
// manual navigation or a filter change. While one exists — pending target
|
|
329
|
+
// still loading, or failed — never fall back to a default selection.
|
|
330
|
+
if (state.sessions?.navigationIntent) {
|
|
331
|
+
return currentSessionId;
|
|
332
|
+
}
|
|
327
333
|
if (currentSessionId && state.sessions?.byId?.[currentSessionId] && !hasSessionVisibilityFilter(state.sessions)) {
|
|
328
334
|
return currentSessionId;
|
|
329
335
|
}
|
|
@@ -361,20 +367,67 @@ function updateUiForSessionSelection(state, nextActiveSessionId) {
|
|
|
361
367
|
}
|
|
362
368
|
|
|
363
369
|
function applyVisibleSessionSelection(state, nextSessions) {
|
|
370
|
+
let sessions = nextSessions;
|
|
371
|
+
|
|
372
|
+
// Navigation intent (deep link) outranks in-memory selection and profile
|
|
373
|
+
// activeSessionId: once its target session is present, latch the selection
|
|
374
|
+
// onto it and mark the intent resolved.
|
|
375
|
+
const intent = sessions.navigationIntent || null;
|
|
376
|
+
const intentTargetId = intent && intent.status !== "failed" && sessions.byId?.[intent.sessionId]
|
|
377
|
+
? intent.sessionId
|
|
378
|
+
: null;
|
|
379
|
+
if (intentTargetId) {
|
|
380
|
+
sessions = {
|
|
381
|
+
...sessions,
|
|
382
|
+
activeSessionId: intentTargetId,
|
|
383
|
+
navigationIntent: intent.status === "resolved"
|
|
384
|
+
? intent
|
|
385
|
+
: { sessionId: intent.sessionId, status: "resolved" },
|
|
386
|
+
};
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
// Expand ancestors BEFORE resolving visibility: a selected session inside
|
|
390
|
+
// a collapsed group/parent is absent from the flat tree, so resolving
|
|
391
|
+
// first would drop the selection instead of revealing it.
|
|
392
|
+
const selectionCandidateId = sessions.activeSessionId || null;
|
|
393
|
+
if (selectionCandidateId && sessions.byId?.[selectionCandidateId]) {
|
|
394
|
+
const expandedCollapsedIds = reconcileCollapsedIdsForActiveSession(sessions.collapsedIds, sessions.byId, selectionCandidateId);
|
|
395
|
+
if (!setsEqual(expandedCollapsedIds, sessions.collapsedIds)) {
|
|
396
|
+
sessions = {
|
|
397
|
+
...sessions,
|
|
398
|
+
collapsedIds: expandedCollapsedIds,
|
|
399
|
+
flat: buildSessionTree(Object.values(sessions.byId || {}), expandedCollapsedIds, sessions.orderById, sessions.pinnedIds),
|
|
400
|
+
};
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
// A resolved intent target excluded by the current filters gets a
|
|
405
|
+
// transient exception so the linked session is shown anyway. Never
|
|
406
|
+
// persisted; cleared on manual navigation or filter change.
|
|
407
|
+
if (intentTargetId && sessions.filterExceptionId !== intentTargetId) {
|
|
408
|
+
const probeRows = selectSessionRows({ ...state, sessions });
|
|
409
|
+
if (!probeRows.some((row) => row.sessionId === intentTargetId)) {
|
|
410
|
+
sessions = {
|
|
411
|
+
...sessions,
|
|
412
|
+
filterExceptionId: intentTargetId,
|
|
413
|
+
};
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
|
|
364
417
|
const nextState = {
|
|
365
418
|
...state,
|
|
366
|
-
sessions
|
|
419
|
+
sessions,
|
|
367
420
|
};
|
|
368
|
-
const nextActiveSessionId = resolveVisibleActiveSessionId(nextState, Object.values(
|
|
369
|
-
const nextCollapsedIds = reconcileCollapsedIdsForActiveSession(
|
|
370
|
-
const collapsedChanged = !setsEqual(nextCollapsedIds,
|
|
421
|
+
const nextActiveSessionId = resolveVisibleActiveSessionId(nextState, Object.values(sessions.byId || {}));
|
|
422
|
+
const nextCollapsedIds = reconcileCollapsedIdsForActiveSession(sessions.collapsedIds, sessions.byId, nextActiveSessionId);
|
|
423
|
+
const collapsedChanged = !setsEqual(nextCollapsedIds, sessions.collapsedIds);
|
|
371
424
|
const reconciledSessions = collapsedChanged
|
|
372
425
|
? {
|
|
373
|
-
...
|
|
426
|
+
...sessions,
|
|
374
427
|
collapsedIds: nextCollapsedIds,
|
|
375
|
-
flat: buildSessionTree(Object.values(
|
|
428
|
+
flat: buildSessionTree(Object.values(sessions.byId || {}), nextCollapsedIds, sessions.orderById, sessions.pinnedIds),
|
|
376
429
|
}
|
|
377
|
-
:
|
|
430
|
+
: sessions;
|
|
378
431
|
return {
|
|
379
432
|
sessions: {
|
|
380
433
|
...reconciledSessions,
|
|
@@ -515,7 +568,15 @@ export function appReducer(state, action) {
|
|
|
515
568
|
&& (settings.chatViewMode === "summary" || settings.chatViewMode === "transcript");
|
|
516
569
|
const hasPins = Object.prototype.hasOwnProperty.call(settings, "pinnedSessionIds");
|
|
517
570
|
const hasCollapsed = Object.prototype.hasOwnProperty.call(settings, "collapsedSessionIds");
|
|
518
|
-
|
|
571
|
+
// A pending/resolved deep-link intent outranks the profile's
|
|
572
|
+
// persisted activeSessionId — a remote profile poll must not
|
|
573
|
+
// yank selection away from the linked session.
|
|
574
|
+
const navigationIntentLatched = Boolean(
|
|
575
|
+
state.sessions.navigationIntent
|
|
576
|
+
&& state.sessions.navigationIntent.status !== "failed",
|
|
577
|
+
);
|
|
578
|
+
const hasActive = Object.prototype.hasOwnProperty.call(settings, "activeSessionId")
|
|
579
|
+
&& !navigationIntentLatched;
|
|
519
580
|
const hasLoadedSessions = Object.keys(state.sessions.byId || {}).length > 0;
|
|
520
581
|
const nextLayout = hasLayout
|
|
521
582
|
? {
|
|
@@ -693,6 +754,10 @@ export function appReducer(state, action) {
|
|
|
693
754
|
const nextSessions = {
|
|
694
755
|
...state.sessions,
|
|
695
756
|
filterQuery: typeof action.query === "string" ? action.query : "",
|
|
757
|
+
// A filter change is an explicit user action: it releases
|
|
758
|
+
// the deep-link latch and its transient filter exception.
|
|
759
|
+
navigationIntent: null,
|
|
760
|
+
filterExceptionId: null,
|
|
696
761
|
};
|
|
697
762
|
const selection = applyVisibleSessionSelection(state, nextSessions);
|
|
698
763
|
return {
|
|
@@ -708,6 +773,8 @@ export function appReducer(state, action) {
|
|
|
708
773
|
...state.sessions,
|
|
709
774
|
ownerFilterExplicit: true,
|
|
710
775
|
ownerFilter: normalizeSessionOwnerFilter(action.filter),
|
|
776
|
+
navigationIntent: null,
|
|
777
|
+
filterExceptionId: null,
|
|
711
778
|
};
|
|
712
779
|
const selection = applyVisibleSessionSelection(state, nextSessions);
|
|
713
780
|
return {
|
|
@@ -717,6 +784,39 @@ export function appReducer(state, action) {
|
|
|
717
784
|
};
|
|
718
785
|
}
|
|
719
786
|
|
|
787
|
+
case "sessions/navigationIntent": {
|
|
788
|
+
const sessionId = String(action.sessionId || "").trim();
|
|
789
|
+
if (!sessionId) return state;
|
|
790
|
+
const nextSessions = {
|
|
791
|
+
...state.sessions,
|
|
792
|
+
navigationIntent: { sessionId, status: "pending" },
|
|
793
|
+
filterExceptionId: null,
|
|
794
|
+
};
|
|
795
|
+
const selection = applyVisibleSessionSelection(state, nextSessions);
|
|
796
|
+
return {
|
|
797
|
+
...state,
|
|
798
|
+
sessions: selection.sessions,
|
|
799
|
+
ui: selection.ui,
|
|
800
|
+
};
|
|
801
|
+
}
|
|
802
|
+
|
|
803
|
+
case "sessions/navigationIntentFailed": {
|
|
804
|
+
const intent = state.sessions.navigationIntent;
|
|
805
|
+
const sessionId = String(action.sessionId || "").trim();
|
|
806
|
+
if (!intent || (sessionId && intent.sessionId !== sessionId)) return state;
|
|
807
|
+
return {
|
|
808
|
+
...state,
|
|
809
|
+
sessions: {
|
|
810
|
+
...state.sessions,
|
|
811
|
+
navigationIntent: {
|
|
812
|
+
sessionId: intent.sessionId,
|
|
813
|
+
status: "failed",
|
|
814
|
+
errorKind: action.errorKind === "not_found" ? "not_found" : "network",
|
|
815
|
+
},
|
|
816
|
+
},
|
|
817
|
+
};
|
|
818
|
+
}
|
|
819
|
+
|
|
720
820
|
case "ui/modalSelection": {
|
|
721
821
|
const modal = state.ui.modal;
|
|
722
822
|
if (!modal) return state;
|
|
@@ -991,11 +1091,20 @@ export function appReducer(state, action) {
|
|
|
991
1091
|
if (previousActiveId && previousActiveId !== action.sessionId) {
|
|
992
1092
|
savedChatScroll[previousActiveId] = Number(state.ui.scroll?.chat) || 0;
|
|
993
1093
|
}
|
|
1094
|
+
// Manual navigation to a different session releases the deep-link
|
|
1095
|
+
// latch and its transient filter exception.
|
|
1096
|
+
const releasesNavigationLatch = Boolean(
|
|
1097
|
+
state.sessions.navigationIntent
|
|
1098
|
+
&& state.sessions.navigationIntent.sessionId !== action.sessionId,
|
|
1099
|
+
);
|
|
994
1100
|
return {
|
|
995
1101
|
...state,
|
|
996
1102
|
sessions: {
|
|
997
1103
|
...state.sessions,
|
|
998
1104
|
activeSessionId: action.sessionId,
|
|
1105
|
+
...(releasesNavigationLatch
|
|
1106
|
+
? { navigationIntent: null, filterExceptionId: null }
|
|
1107
|
+
: {}),
|
|
999
1108
|
},
|
|
1000
1109
|
ui: {
|
|
1001
1110
|
...state.ui,
|
package/ui/core/src/selectors.js
CHANGED
|
@@ -350,6 +350,10 @@ function matchesOwnerFilterDirect(session, ownerFilter = {}, auth = {}, ownerOve
|
|
|
350
350
|
if (ownerKey === SYSTEM_OWNER_KEY) return ownerFilter.includeSystem === true;
|
|
351
351
|
const currentUserKey = ownerKeyForOwner(auth?.principal);
|
|
352
352
|
if (ownerFilter.includeMe && currentUserKey && ownerKey === currentUserKey) return true;
|
|
353
|
+
// "Shared with me": any non-system session owned by someone else. The
|
|
354
|
+
// catalog is viewer-scoped server-side, so a foreign owner implies the
|
|
355
|
+
// session was shared with (or is otherwise readable by) the viewer.
|
|
356
|
+
if (ownerFilter.includeShared === true && ownerKey !== currentUserKey) return true;
|
|
353
357
|
return Array.isArray(ownerFilter.ownerKeys) && ownerFilter.ownerKeys.includes(ownerKey);
|
|
354
358
|
}
|
|
355
359
|
|
|
@@ -728,6 +732,31 @@ function matchesSearchQuery(value, query) {
|
|
|
728
732
|
return String(value || "").toLowerCase().includes(normalizedQuery);
|
|
729
733
|
}
|
|
730
734
|
|
|
735
|
+
// The transient deep-link filter exception covers the linked session AND its
|
|
736
|
+
// ancestor chain (real parents plus the synthetic group:<id> row) so the
|
|
737
|
+
// linked row renders with its tree context instead of as an orphan.
|
|
738
|
+
function collectFilterExceptionIds(sessions) {
|
|
739
|
+
const exceptionId = sessions?.filterExceptionId || null;
|
|
740
|
+
const byId = sessions?.byId || {};
|
|
741
|
+
if (!exceptionId || !byId[exceptionId]) return null;
|
|
742
|
+
const ids = new Set([exceptionId]);
|
|
743
|
+
let current = byId[exceptionId];
|
|
744
|
+
let hops = 0;
|
|
745
|
+
while (current && hops < 16) {
|
|
746
|
+
let parentId = null;
|
|
747
|
+
if (current.parentSessionId && byId[current.parentSessionId]) {
|
|
748
|
+
parentId = current.parentSessionId;
|
|
749
|
+
} else if (!current.isGroup && current.groupId && byId[`group:${current.groupId}`]) {
|
|
750
|
+
parentId = `group:${current.groupId}`;
|
|
751
|
+
}
|
|
752
|
+
if (!parentId || ids.has(parentId)) break;
|
|
753
|
+
ids.add(parentId);
|
|
754
|
+
current = byId[parentId];
|
|
755
|
+
hops += 1;
|
|
756
|
+
}
|
|
757
|
+
return ids;
|
|
758
|
+
}
|
|
759
|
+
|
|
731
760
|
export function selectSessionRows(state) {
|
|
732
761
|
const totalDescendantCounts = getTotalDescendantCounts(state.sessions.byId);
|
|
733
762
|
const visibleDescendantCounts = getVisibleDescendantCounts(state.sessions.flat, state.sessions.byId);
|
|
@@ -736,6 +765,7 @@ export function selectSessionRows(state) {
|
|
|
736
765
|
const auth = state.auth || {};
|
|
737
766
|
const pinnedSet = new Set(Array.isArray(state.sessions?.pinnedIds) ? state.sessions.pinnedIds : []);
|
|
738
767
|
const selectedSet = new Set(Array.isArray(state.sessions?.selectedIds) ? state.sessions.selectedIds : []);
|
|
768
|
+
const filterExceptionIds = collectFilterExceptionIds(state.sessions);
|
|
739
769
|
|
|
740
770
|
return state.sessions.flat.map((entry) => {
|
|
741
771
|
const session = state.sessions.byId[entry.sessionId];
|
|
@@ -757,6 +787,7 @@ export function selectSessionRows(state) {
|
|
|
757
787
|
canPin: canPinSessionRow(session),
|
|
758
788
|
};
|
|
759
789
|
}).filter((row) => {
|
|
790
|
+
if (filterExceptionIds?.has(row.sessionId)) return true;
|
|
760
791
|
const session = state.sessions.byId[row.sessionId];
|
|
761
792
|
if (!matchesOwnerFilter(session, ownerFilter, auth, state.sessions.byId)) return false;
|
|
762
793
|
const effectiveOwner = effectiveSessionOwner(session, state.sessions.byId);
|
|
@@ -806,6 +837,39 @@ export function selectActiveSession(state) {
|
|
|
806
837
|
return sessionId ? state.sessions.byId[sessionId] || null : null;
|
|
807
838
|
}
|
|
808
839
|
|
|
840
|
+
export function selectNavigationIntent(state) {
|
|
841
|
+
return state.sessions?.navigationIntent || null;
|
|
842
|
+
}
|
|
843
|
+
|
|
844
|
+
/**
|
|
845
|
+
* Deep-link failure state for renderers. `not_found` deliberately covers both
|
|
846
|
+
* unknown and inaccessible sessions (no existence oracle); network/server
|
|
847
|
+
* failures keep a retryable flavor.
|
|
848
|
+
*/
|
|
849
|
+
export function selectNavigationError(state) {
|
|
850
|
+
const intent = state.sessions?.navigationIntent;
|
|
851
|
+
if (!intent || intent.status !== "failed") return null;
|
|
852
|
+
const errorKind = intent.errorKind === "not_found" ? "not_found" : "network";
|
|
853
|
+
return {
|
|
854
|
+
sessionId: intent.sessionId,
|
|
855
|
+
errorKind,
|
|
856
|
+
retryable: errorKind === "network",
|
|
857
|
+
message: errorKind === "not_found"
|
|
858
|
+
? "This session was not found or has not been shared with you."
|
|
859
|
+
: "Could not load the linked session. Check your connection and try again.",
|
|
860
|
+
};
|
|
861
|
+
}
|
|
862
|
+
|
|
863
|
+
/**
|
|
864
|
+
* Status copy for the transient deep-link filter exception — non-null while a
|
|
865
|
+
* linked session is being shown despite the current filters excluding it.
|
|
866
|
+
*/
|
|
867
|
+
export function selectSessionFilterExceptionNotice(state) {
|
|
868
|
+
const exceptionId = state.sessions?.filterExceptionId || null;
|
|
869
|
+
if (!exceptionId || !state.sessions?.byId?.[exceptionId]) return null;
|
|
870
|
+
return "Showing linked session outside your current filters.";
|
|
871
|
+
}
|
|
872
|
+
|
|
809
873
|
/**
|
|
810
874
|
* True when the session row is actively running a turn that Stop can target.
|
|
811
875
|
* Applies to user AND system sessions; group/container rows are not sessions.
|
|
@@ -1859,6 +1923,7 @@ function buildChatMessageLines(message, maxWidth, options = {}) {
|
|
|
1859
1923
|
width: Math.max(20, maxWidth),
|
|
1860
1924
|
titleColor: USER_CHAT_COLOR,
|
|
1861
1925
|
borderColor: USER_CHAT_COLOR,
|
|
1926
|
+
tableMode: options.tableMode,
|
|
1862
1927
|
}),
|
|
1863
1928
|
...buildChatMessageLines({
|
|
1864
1929
|
...message,
|
|
@@ -1936,6 +2001,7 @@ function buildChatMessageLines(message, maxWidth, options = {}) {
|
|
|
1936
2001
|
width: Math.max(20, maxWidth),
|
|
1937
2002
|
titleColor: message?.cardTitleColor || (message?.role === "system" ? "yellow" : "cyan"),
|
|
1938
2003
|
borderColor: message?.cardBorderColor || "gray",
|
|
2004
|
+
tableMode: options.tableMode,
|
|
1939
2005
|
...(isSystemCard ? { bodyColor: "gray", fitToContent: true } : {}),
|
|
1940
2006
|
});
|
|
1941
2007
|
}
|
|
@@ -3714,7 +3780,7 @@ function buildNodeMapHeaderLine(nodeLabels, colWidth) {
|
|
|
3714
3780
|
return runs;
|
|
3715
3781
|
}
|
|
3716
3782
|
|
|
3717
|
-
const SEQ_REASONING_EFFORTS = new Set(["low", "medium", "high", "xhigh", "
|
|
3783
|
+
const SEQ_REASONING_EFFORTS = new Set(["none", "minimal", "low", "medium", "high", "xhigh", "max"]);
|
|
3718
3784
|
|
|
3719
3785
|
function shortModelForSequence(value) {
|
|
3720
3786
|
const model = String(value || "").trim();
|
|
@@ -4022,10 +4088,12 @@ export function selectModelPickerModal(state, maxWidth = 72) {
|
|
|
4022
4088
|
? modal.items.findIndex((item) => item.id === model.id)
|
|
4023
4089
|
: -1;
|
|
4024
4090
|
const isSelected = itemIndex === selectedIndex;
|
|
4091
|
+
const isDisabled = Boolean(model.disabled);
|
|
4025
4092
|
const labelRuns = fitRuns([
|
|
4026
4093
|
{ text: "· ", color: "gray" },
|
|
4027
|
-
{ text: model.modelName || model.qualifiedName || model.id, color: "white", bold: Boolean(model.isDefault) },
|
|
4094
|
+
{ text: model.modelName || model.qualifiedName || model.id, color: isDisabled ? "gray" : "white", bold: Boolean(model.isDefault) && !isDisabled },
|
|
4028
4095
|
...(model.cost ? [{ text: ` [${model.cost}]`, color: "gray" }] : []),
|
|
4096
|
+
...(isDisabled ? [{ text: " ⊘ needs GitHub key", color: "yellow" }] : []),
|
|
4029
4097
|
...(model.isDefault ? [{ text: " ← current default", color: "gray" }] : []),
|
|
4030
4098
|
], contentWidth);
|
|
4031
4099
|
|
|
@@ -4062,6 +4130,9 @@ export function selectModelPickerModal(state, maxWidth = 72) {
|
|
|
4062
4130
|
? [[{ text: `Reasoning: ${supportedReasoning.join(", ")}`, color: "gray" }]]
|
|
4063
4131
|
: []),
|
|
4064
4132
|
...(defaultReasoning ? [[{ text: `Default reasoning: ${defaultReasoning}`, color: "gray" }]] : []),
|
|
4133
|
+
...(selectedItem.disabled
|
|
4134
|
+
? [[{ text: "Unavailable: requires a GitHub Copilot key. Add yours in the Admin console, then reopen this picker.", color: "yellow" }]]
|
|
4135
|
+
: []),
|
|
4065
4136
|
[{ text: "", color: "gray" }],
|
|
4066
4137
|
[{
|
|
4067
4138
|
text: selectedItem.description || "No description available for this model.",
|
|
@@ -4234,11 +4305,12 @@ export function selectContextTierPickerModal(state, maxWidth = 64) {
|
|
|
4234
4305
|
|
|
4235
4306
|
const selectedItem = items[selectedIndex] || null;
|
|
4236
4307
|
const modelItem = modal.modelItem || null;
|
|
4308
|
+
const selectedLabel = selectedItem?.label || selectedItem?.id;
|
|
4237
4309
|
const detailsLines = [
|
|
4238
4310
|
[{ text: modelItem?.modelName || modelItem?.qualifiedName || "Selected model", color: "white", bold: true }],
|
|
4239
4311
|
[{ text: `${modelItem?.providerId || "provider"} (${modelItem?.providerType || "provider"})`, color: "gray" }],
|
|
4240
4312
|
[{ text: "", color: "gray" }],
|
|
4241
|
-
[{ text:
|
|
4313
|
+
[{ text: selectedLabel ? `Using context window: ${selectedLabel}` : "Choose a context window.", color: "white" }],
|
|
4242
4314
|
[{ text: "Long context costs more per token.", color: "gray" }],
|
|
4243
4315
|
];
|
|
4244
4316
|
|
|
@@ -4640,6 +4712,7 @@ function isOwnerFilterItemSelected(item, ownerFilter = {}, auth = {}) {
|
|
|
4640
4712
|
if (item.kind === "system") return ownerFilter?.includeSystem === true;
|
|
4641
4713
|
if (item.kind === "unowned") return ownerFilter?.includeUnowned === true;
|
|
4642
4714
|
if (item.kind === "me") return ownerFilter?.includeMe === true && Boolean(ownerKeyForOwner(auth?.principal));
|
|
4715
|
+
if (item.kind === "shared") return ownerFilter?.includeShared === true;
|
|
4643
4716
|
if (item.kind === "owner") return Array.isArray(ownerFilter?.ownerKeys) && ownerFilter.ownerKeys.includes(item.ownerKey);
|
|
4644
4717
|
return false;
|
|
4645
4718
|
}
|
package/ui/core/src/state.js
CHANGED
|
@@ -13,6 +13,7 @@ export function normalizeSessionOwnerFilter(filter) {
|
|
|
13
13
|
includeSystem: filter?.includeSystem === true,
|
|
14
14
|
includeUnowned: filter?.includeUnowned === true,
|
|
15
15
|
includeMe: filter?.includeMe === true,
|
|
16
|
+
includeShared: filter?.includeShared === true,
|
|
16
17
|
ownerKeys,
|
|
17
18
|
};
|
|
18
19
|
}
|
|
@@ -180,6 +181,8 @@ export function createInitialState({ mode = "local", branding = null, themeId =
|
|
|
180
181
|
filterQuery: "",
|
|
181
182
|
ownerFilterExplicit: hasStoredSessionOwnerFilter,
|
|
182
183
|
ownerFilter: normalizeSessionOwnerFilter(sessionOwnerFilter),
|
|
184
|
+
navigationIntent: null,
|
|
185
|
+
filterExceptionId: null,
|
|
183
186
|
},
|
|
184
187
|
history: {
|
|
185
188
|
bySessionId: new Map(),
|