@dipertq/dsh-openviking-status 0.1.7 → 0.1.8
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/README.md +19 -3
- package/lib/client.cjs +385 -367
- package/lib/client.cjs.map +1 -1
- package/lib/client.d.cts +156 -34
- package/lib/client.js +382 -367
- package/lib/client.js.map +1 -1
- package/package.json +3 -2
package/lib/client.cjs
CHANGED
|
@@ -4,9 +4,11 @@ window.__ModuleLoader__.load({
|
|
|
4
4
|
var module = { exports: {} };
|
|
5
5
|
var exports = module.exports;
|
|
6
6
|
"use strict";
|
|
7
|
+
var __create = Object.create;
|
|
7
8
|
var __defProp = Object.defineProperty;
|
|
8
9
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
9
10
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
11
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
10
12
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
11
13
|
var __export = (target, all) => {
|
|
12
14
|
for (var name2 in all)
|
|
@@ -20,6 +22,14 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
20
22
|
}
|
|
21
23
|
return to;
|
|
22
24
|
};
|
|
25
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
26
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
27
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
28
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
29
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
30
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
31
|
+
mod
|
|
32
|
+
));
|
|
23
33
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
24
34
|
|
|
25
35
|
// src/client/index.tsx
|
|
@@ -30,11 +40,14 @@ __export(client_exports, {
|
|
|
30
40
|
OpenVikingClient: () => OpenVikingClient,
|
|
31
41
|
OpenVikingStatusChip: () => OpenVikingStatusChip,
|
|
32
42
|
OpenVikingStatusPopover: () => OpenVikingStatusPopover,
|
|
43
|
+
THEME: () => THEME,
|
|
33
44
|
apply: () => apply,
|
|
45
|
+
chatNodesToText: () => chatNodesToText,
|
|
34
46
|
checkHealth: () => checkHealth,
|
|
35
47
|
commitSession: () => commitSession,
|
|
36
48
|
defaultOpenVikingClient: () => defaultOpenVikingClient,
|
|
37
49
|
fetchSession: () => fetchSession,
|
|
50
|
+
formatDaemonVersion: () => formatDaemonVersion,
|
|
38
51
|
formatEndpoint: () => formatEndpoint,
|
|
39
52
|
formatMemoryLeafName: () => formatMemoryLeafName,
|
|
40
53
|
formatPendingTokens: () => formatPendingTokens,
|
|
@@ -42,11 +55,9 @@ __export(client_exports, {
|
|
|
42
55
|
formatStatusLabel: () => formatStatusLabel,
|
|
43
56
|
formatTooltipTitle: () => formatTooltipTitle,
|
|
44
57
|
getCategoryBadgeStyle: () => getCategoryBadgeStyle,
|
|
45
|
-
getFallbackSessionMessages: () => getFallbackSessionMessages,
|
|
46
58
|
getProgressBarColor: () => getProgressBarColor,
|
|
47
59
|
getProgressBarPercent: () => getProgressBarPercent,
|
|
48
60
|
getSession: () => getSession,
|
|
49
|
-
getStatusGlow: () => getStatusGlow,
|
|
50
61
|
getStatusIndicatorColor: () => getStatusIndicatorColor,
|
|
51
62
|
handleEscapeKey: () => handleEscapeKey,
|
|
52
63
|
inferCategory: () => inferCategory,
|
|
@@ -55,12 +66,13 @@ __export(client_exports, {
|
|
|
55
66
|
parseRecalledMemories: () => parseRecalledMemories,
|
|
56
67
|
resolveApiKey: () => resolveApiKey,
|
|
57
68
|
resolveEndpoint: () => resolveEndpoint,
|
|
69
|
+
themeVar: () => themeVar,
|
|
58
70
|
truncateSessionId: () => truncateSessionId
|
|
59
71
|
});
|
|
60
72
|
module.exports = __toCommonJS(client_exports);
|
|
61
73
|
|
|
62
74
|
// src/client/OpenVikingStatusChip.tsx
|
|
63
|
-
var import_react2 = require("react");
|
|
75
|
+
var import_react2 = __toESM(require("react"), 1);
|
|
64
76
|
|
|
65
77
|
// src/client/api.ts
|
|
66
78
|
var DEFAULT_OPENVIKING_ENDPOINT = "http://127.0.0.1:1933";
|
|
@@ -144,6 +156,8 @@ var OpenVikingClient = class {
|
|
|
144
156
|
} else if (raw.startsWith("dsh-")) {
|
|
145
157
|
const suffix = raw.slice("dsh-".length);
|
|
146
158
|
candidates.push(raw, `dsh-session-${suffix}`);
|
|
159
|
+
} else if (raw.startsWith("session-")) {
|
|
160
|
+
candidates.push(`dsh-${raw}`, raw);
|
|
147
161
|
} else {
|
|
148
162
|
candidates.push(`dsh-session-${raw}`, `dsh-${raw}`, raw);
|
|
149
163
|
}
|
|
@@ -179,12 +193,16 @@ var OpenVikingClient = class {
|
|
|
179
193
|
}
|
|
180
194
|
}
|
|
181
195
|
/**
|
|
182
|
-
*
|
|
183
|
-
*
|
|
196
|
+
* Чтение метаданных сессии с явной причиной неудачи.
|
|
197
|
+
*
|
|
198
|
+
* Демон может работать с `auth_mode: api_key`: тогда `/health` остаётся
|
|
199
|
+
* открытым, а сессия отвечает 401. Схлопывать это в «нет данных» нельзя —
|
|
200
|
+
* иначе интерфейс покажет живой индикатор рядом с нулями и умолчит о том,
|
|
201
|
+
* что счётчики просто недоступны.
|
|
184
202
|
*/
|
|
185
|
-
async
|
|
203
|
+
async readSession(sessionId) {
|
|
186
204
|
if (!sessionId || !sessionId.trim()) {
|
|
187
|
-
return
|
|
205
|
+
return { status: "missing" };
|
|
188
206
|
}
|
|
189
207
|
const candidates = this.getCandidateSessionIds(sessionId);
|
|
190
208
|
for (const candidateId of candidates) {
|
|
@@ -199,30 +217,48 @@ var OpenVikingClient = class {
|
|
|
199
217
|
if (res.status === 404) {
|
|
200
218
|
continue;
|
|
201
219
|
}
|
|
220
|
+
if (res.status === 401 || res.status === 403) {
|
|
221
|
+
return { status: "unauthorized" };
|
|
222
|
+
}
|
|
202
223
|
if (!res.ok) {
|
|
203
|
-
return
|
|
224
|
+
return { status: "error", detail: `HTTP ${res.status}` };
|
|
204
225
|
}
|
|
205
226
|
const data = await res.json();
|
|
206
227
|
const raw = data?.result ?? data?.data ?? data;
|
|
207
228
|
if (!raw || typeof raw !== "object") {
|
|
208
|
-
return
|
|
229
|
+
return { status: "error", detail: "malformed response body" };
|
|
209
230
|
}
|
|
210
231
|
this.resolvedSessionIds.set(sessionId.trim(), candidateId);
|
|
211
232
|
return {
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
233
|
+
status: "ok",
|
|
234
|
+
session: {
|
|
235
|
+
session_id: typeof raw.session_id === "string" ? raw.session_id : candidateId,
|
|
236
|
+
peer_id: typeof raw.peer_id === "string" ? raw.peer_id : void 0,
|
|
237
|
+
pending_tokens: typeof raw.pending_tokens === "number" ? raw.pending_tokens : 0,
|
|
238
|
+
message_count: typeof raw.message_count === "number" ? raw.message_count : void 0,
|
|
239
|
+
commit_count: typeof raw.commit_count === "number" ? raw.commit_count : void 0,
|
|
240
|
+
last_commit_at: typeof raw.last_commit_at === "string" ? raw.last_commit_at : typeof raw.last_commit === "string" ? raw.last_commit : void 0,
|
|
241
|
+
created_at: typeof raw.created_at === "string" ? raw.created_at : void 0,
|
|
242
|
+
updated_at: typeof raw.updated_at === "string" ? raw.updated_at : void 0
|
|
243
|
+
}
|
|
244
|
+
};
|
|
245
|
+
} catch (err) {
|
|
246
|
+
return {
|
|
247
|
+
status: "unreachable",
|
|
248
|
+
detail: err instanceof Error ? err.message : String(err)
|
|
220
249
|
};
|
|
221
|
-
} catch {
|
|
222
|
-
return null;
|
|
223
250
|
}
|
|
224
251
|
}
|
|
225
|
-
return
|
|
252
|
+
return { status: "missing" };
|
|
253
|
+
}
|
|
254
|
+
/**
|
|
255
|
+
* Получение метаданных сессии по идентификатору.
|
|
256
|
+
* Обёртка над {@link readSession} для вызывающих, которым причина неудачи
|
|
257
|
+
* не нужна: любая неудача сводится к null.
|
|
258
|
+
*/
|
|
259
|
+
async fetchSession(sessionId) {
|
|
260
|
+
const result = await this.readSession(sessionId);
|
|
261
|
+
return result.status === "ok" ? result.session : null;
|
|
226
262
|
}
|
|
227
263
|
/**
|
|
228
264
|
* Алиас для fetchSession
|
|
@@ -288,6 +324,41 @@ function commitSession(sessionId, options, endpoint, apiKey) {
|
|
|
288
324
|
return client.commitSession(sessionId, options);
|
|
289
325
|
}
|
|
290
326
|
|
|
327
|
+
// src/client/theme.ts
|
|
328
|
+
var THEME = {
|
|
329
|
+
/** Фон всплывающей панели — тот же, что у меню и диалогов DSH. */
|
|
330
|
+
panelSurface: "--dsw-specific-menu",
|
|
331
|
+
/** Тень панели. */
|
|
332
|
+
panelElevation: "--dsw-elevation-prominent",
|
|
333
|
+
/** Контур панели; задаётся через переменную тени, а не через border. */
|
|
334
|
+
panelStroke: "--dsw-alias-border-l1",
|
|
335
|
+
/** Заголовки и акцентный текст. */
|
|
336
|
+
labelPrimary: "--dsw-alias-label-primary",
|
|
337
|
+
/** Основной текст панели. */
|
|
338
|
+
labelSecondary: "--dsw-alias-label-secondary",
|
|
339
|
+
/** Приглушённый текст: подписи, значения, текст чипа в покое. */
|
|
340
|
+
labelTertiary: "--dsw-alias-label-tertiary",
|
|
341
|
+
/** Разделительная линия внутри панели. */
|
|
342
|
+
hairline: "--dsw-alias-border-l2",
|
|
343
|
+
/** Подсветка интерактивного элемента под курсором. */
|
|
344
|
+
hoverBackground: "--dsw-alias-interactive-bg-hover",
|
|
345
|
+
/** Подсветка нажатого элемента. */
|
|
346
|
+
activeBackground: "--dsw-alias-interactive-bg-active",
|
|
347
|
+
/** Демон доступен. */
|
|
348
|
+
stateSuccess: "--dsw-alias-state-success-primary",
|
|
349
|
+
/** Демон недоступен или сессия нечитаема. */
|
|
350
|
+
stateError: "--dsw-alias-state-error-primary",
|
|
351
|
+
/** Идёт коммит, либо накоплено близко к порогу. */
|
|
352
|
+
stateWarning: "--dsw-alias-state-warn-primary",
|
|
353
|
+
/** Утопленная поверхность: дорожка прогресс-бара. */
|
|
354
|
+
insetSurface: "--dsw-alias-bg-layer-2",
|
|
355
|
+
/** Моноширинный шрифт для идентификаторов и путей. */
|
|
356
|
+
fontMono: "--dsw-font-markdown-code-font-family"
|
|
357
|
+
};
|
|
358
|
+
function themeVar(role) {
|
|
359
|
+
return `var(${THEME[role]})`;
|
|
360
|
+
}
|
|
361
|
+
|
|
291
362
|
// src/client/recallParser.ts
|
|
292
363
|
var KNOWN_CATEGORIES = /* @__PURE__ */ new Set([
|
|
293
364
|
"preferences",
|
|
@@ -596,6 +667,15 @@ function parseRecalledMemories(input) {
|
|
|
596
667
|
// src/client/OpenVikingStatusPopover.tsx
|
|
597
668
|
var import_react = require("react");
|
|
598
669
|
var import_jsx_runtime = require("react/jsx-runtime");
|
|
670
|
+
function dshIcon(name2) {
|
|
671
|
+
try {
|
|
672
|
+
const primitives = typeof require === "function" ? require("@deepseek-ai/dsh-client-ui-primitives") : null;
|
|
673
|
+
const icon = primitives?.[name2];
|
|
674
|
+
return typeof icon === "function" ? icon : null;
|
|
675
|
+
} catch {
|
|
676
|
+
return null;
|
|
677
|
+
}
|
|
678
|
+
}
|
|
599
679
|
function getProgressBarPercent(pendingTokens, threshold = COMMIT_THRESHOLD) {
|
|
600
680
|
if (!threshold || threshold <= 0) return 0;
|
|
601
681
|
const ratio = (pendingTokens || 0) / threshold;
|
|
@@ -603,9 +683,14 @@ function getProgressBarPercent(pendingTokens, threshold = COMMIT_THRESHOLD) {
|
|
|
603
683
|
}
|
|
604
684
|
function getProgressBarColor(percent) {
|
|
605
685
|
if (percent >= 80) {
|
|
606
|
-
return "
|
|
686
|
+
return themeVar("stateWarning");
|
|
607
687
|
}
|
|
608
|
-
return "
|
|
688
|
+
return themeVar("stateSuccess");
|
|
689
|
+
}
|
|
690
|
+
function formatDaemonVersion(version) {
|
|
691
|
+
const value = version?.trim();
|
|
692
|
+
if (!value) return void 0;
|
|
693
|
+
return /^v/i.test(value) ? value : `v${value}`;
|
|
609
694
|
}
|
|
610
695
|
function formatRelativeTime(isoOrTimestamp, now = Date.now()) {
|
|
611
696
|
if (!isoOrTimestamp) return void 0;
|
|
@@ -647,39 +732,8 @@ function truncateSessionId(id, maxLen = 16) {
|
|
|
647
732
|
if (id.length <= maxLen) return id;
|
|
648
733
|
return `${id.slice(0, maxLen)}...`;
|
|
649
734
|
}
|
|
650
|
-
function getCategoryBadgeStyle(
|
|
651
|
-
|
|
652
|
-
case "preferences":
|
|
653
|
-
return {
|
|
654
|
-
backgroundColor: "rgba(168, 85, 247, 0.15)",
|
|
655
|
-
color: "var(--dsw-status-purple, #c084fc)"
|
|
656
|
-
};
|
|
657
|
-
case "entities":
|
|
658
|
-
return {
|
|
659
|
-
backgroundColor: "rgba(59, 130, 246, 0.15)",
|
|
660
|
-
color: "var(--dsw-status-info, #60a5fa)"
|
|
661
|
-
};
|
|
662
|
-
case "skills":
|
|
663
|
-
return {
|
|
664
|
-
backgroundColor: "rgba(236, 72, 153, 0.15)",
|
|
665
|
-
color: "var(--dsw-status-pink, #f472b6)"
|
|
666
|
-
};
|
|
667
|
-
case "events":
|
|
668
|
-
return {
|
|
669
|
-
backgroundColor: "rgba(245, 158, 11, 0.15)",
|
|
670
|
-
color: "var(--dsw-status-warning, #fbbf24)"
|
|
671
|
-
};
|
|
672
|
-
case "resources":
|
|
673
|
-
return {
|
|
674
|
-
backgroundColor: "rgba(20, 184, 166, 0.15)",
|
|
675
|
-
color: "var(--dsw-status-teal, #2dd4bf)"
|
|
676
|
-
};
|
|
677
|
-
default:
|
|
678
|
-
return {
|
|
679
|
-
backgroundColor: "rgba(148, 163, 184, 0.15)",
|
|
680
|
-
color: "var(--dsw-text-muted, #94a3b8)"
|
|
681
|
-
};
|
|
682
|
-
}
|
|
735
|
+
function getCategoryBadgeStyle(_category) {
|
|
736
|
+
return { color: themeVar("labelTertiary") };
|
|
683
737
|
}
|
|
684
738
|
function handleEscapeKey(event, onClose) {
|
|
685
739
|
if (event.key === "Escape") {
|
|
@@ -692,6 +746,7 @@ function OpenVikingStatusPopover({
|
|
|
692
746
|
sessionId,
|
|
693
747
|
health,
|
|
694
748
|
sessionData,
|
|
749
|
+
sessionRead,
|
|
695
750
|
recalledResult,
|
|
696
751
|
endpoint,
|
|
697
752
|
isCommitting = false,
|
|
@@ -711,13 +766,17 @@ function OpenVikingStatusPopover({
|
|
|
711
766
|
};
|
|
712
767
|
}, []);
|
|
713
768
|
const isOnline = health?.ok === true;
|
|
714
|
-
const
|
|
769
|
+
const sessionUnreadable = isOnline && sessionRead != null && sessionRead.status !== "ok";
|
|
770
|
+
const unauthorized = sessionRead?.status === "unauthorized";
|
|
771
|
+
const statusColor = isOnline ? sessionUnreadable ? themeVar("stateWarning") : themeVar("stateSuccess") : themeVar("stateError");
|
|
715
772
|
const displaySessionId = sessionData?.session_id || sessionId || "";
|
|
716
773
|
const pendingTokens = sessionData?.pending_tokens ?? 0;
|
|
717
774
|
const progressPercent = getProgressBarPercent(pendingTokens);
|
|
718
775
|
const progressBarColor = getProgressBarColor(progressPercent);
|
|
719
776
|
const memoryItems = recalledResult?.items || [];
|
|
720
777
|
const recalledCount = recalledResult?.recalledCount ?? memoryItems.length;
|
|
778
|
+
const CopyIcon = dshIcon("IconCopyOutline16");
|
|
779
|
+
const CheckIcon = dshIcon("IconCheckOutline16");
|
|
721
780
|
const handleCopySessionId = (0, import_react.useCallback)(() => {
|
|
722
781
|
if (!displaySessionId) return;
|
|
723
782
|
if (typeof navigator !== "undefined" && navigator.clipboard) {
|
|
@@ -733,7 +792,15 @@ function OpenVikingStatusPopover({
|
|
|
733
792
|
}, 1500);
|
|
734
793
|
}
|
|
735
794
|
}, [displaySessionId]);
|
|
736
|
-
const isCommitDisabled = isCommitting || !isOnline || pendingTokens === 0;
|
|
795
|
+
const isCommitDisabled = isCommitting || !isOnline || sessionUnreadable || pendingTokens === 0;
|
|
796
|
+
const pendingLabel = sessionUnreadable ? "unavailable" : `${pendingTokens.toLocaleString()} / ${COMMIT_THRESHOLD.toLocaleString()}`;
|
|
797
|
+
const rowStyle = {
|
|
798
|
+
display: "flex",
|
|
799
|
+
justifyContent: "space-between",
|
|
800
|
+
alignItems: "center"
|
|
801
|
+
};
|
|
802
|
+
const mutedStyle = { color: themeVar("labelTertiary") };
|
|
803
|
+
const monoStyle = { fontFamily: themeVar("fontMono") };
|
|
737
804
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
738
805
|
"div",
|
|
739
806
|
{
|
|
@@ -744,17 +811,23 @@ function OpenVikingStatusPopover({
|
|
|
744
811
|
position: "absolute",
|
|
745
812
|
bottom: "calc(100% + 8px)",
|
|
746
813
|
right: 0,
|
|
747
|
-
|
|
748
|
-
backgroundColor: "var(--dsw-surface-overlay, #1e293b)",
|
|
749
|
-
border: "1px solid var(--dsw-border-default, #334155)",
|
|
750
|
-
borderRadius: "8px",
|
|
751
|
-
padding: "12px",
|
|
752
|
-
boxShadow: "0 10px 25px -5px rgba(0, 0, 0, 0.5)",
|
|
753
|
-
zIndex: 1e3,
|
|
754
|
-
fontSize: "12px",
|
|
755
|
-
color: "var(--dsw-text-default, #f1f5f9)",
|
|
756
|
-
fontFamily: "var(--dsw-font-sans, system-ui, sans-serif)",
|
|
814
|
+
zIndex: 1100,
|
|
757
815
|
boxSizing: "border-box",
|
|
816
|
+
width: "max-content",
|
|
817
|
+
minWidth: "min(300px, 100vw - 24px)",
|
|
818
|
+
maxWidth: "min(440px, 100vw - 24px)",
|
|
819
|
+
background: themeVar("panelSurface"),
|
|
820
|
+
boxShadow: themeVar("panelElevation"),
|
|
821
|
+
color: themeVar("labelSecondary"),
|
|
822
|
+
cursor: "default",
|
|
823
|
+
border: 0,
|
|
824
|
+
borderRadius: "12px",
|
|
825
|
+
padding: "16px",
|
|
826
|
+
fontSize: "12px",
|
|
827
|
+
lineHeight: "18px",
|
|
828
|
+
...{
|
|
829
|
+
"--dsw-elevation-stroke-color": themeVar("panelStroke")
|
|
830
|
+
},
|
|
758
831
|
...style
|
|
759
832
|
},
|
|
760
833
|
children: [
|
|
@@ -765,58 +838,41 @@ function OpenVikingStatusPopover({
|
|
|
765
838
|
style: {
|
|
766
839
|
display: "flex",
|
|
767
840
|
justifyContent: "space-between",
|
|
768
|
-
|
|
769
|
-
marginBottom: "
|
|
770
|
-
|
|
771
|
-
|
|
841
|
+
gap: "16px",
|
|
842
|
+
marginBottom: "8px",
|
|
843
|
+
color: themeVar("labelPrimary"),
|
|
844
|
+
fontWeight: 500
|
|
772
845
|
},
|
|
773
846
|
children: [
|
|
774
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
{
|
|
778
|
-
style: {
|
|
779
|
-
fontWeight: 600,
|
|
780
|
-
fontSize: "13px",
|
|
781
|
-
color: "var(--dsw-text-default, #f1f5f9)"
|
|
782
|
-
},
|
|
783
|
-
children: "OpenViking Memory"
|
|
784
|
-
}
|
|
785
|
-
),
|
|
847
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { style: { minWidth: 0 }, children: [
|
|
848
|
+
"OpenViking Memory",
|
|
849
|
+
" ",
|
|
786
850
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
787
|
-
"
|
|
851
|
+
"span",
|
|
788
852
|
{
|
|
789
853
|
"data-testid": "endpoint-label",
|
|
790
|
-
style: {
|
|
791
|
-
fontSize: "10px",
|
|
792
|
-
color: "var(--dsw-text-muted, #94a3b8)",
|
|
793
|
-
fontFamily: "var(--dsw-font-mono, monospace)",
|
|
794
|
-
marginTop: "1px"
|
|
795
|
-
},
|
|
854
|
+
style: { ...mutedStyle, ...monoStyle, fontWeight: 400 },
|
|
796
855
|
children: formatEndpoint(endpoint)
|
|
797
856
|
}
|
|
798
857
|
)
|
|
799
858
|
] }),
|
|
800
859
|
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
801
|
-
"
|
|
860
|
+
"span",
|
|
802
861
|
{
|
|
803
862
|
"data-testid": "status-badge",
|
|
804
863
|
style: {
|
|
805
864
|
display: "inline-flex",
|
|
806
865
|
alignItems: "center",
|
|
807
|
-
gap: "
|
|
808
|
-
fontSize: "10px",
|
|
809
|
-
padding: "2px 7px",
|
|
810
|
-
borderRadius: "4px",
|
|
811
|
-
backgroundColor: isOnline ? "rgba(52, 211, 153, 0.15)" : "rgba(248, 113, 113, 0.15)",
|
|
866
|
+
gap: "6px",
|
|
812
867
|
color: statusColor,
|
|
813
|
-
|
|
868
|
+
flexShrink: 0
|
|
814
869
|
},
|
|
815
870
|
children: [
|
|
816
871
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
817
872
|
"span",
|
|
818
873
|
{
|
|
819
874
|
"data-testid": "status-badge-dot",
|
|
875
|
+
"aria-hidden": "true",
|
|
820
876
|
style: {
|
|
821
877
|
width: "6px",
|
|
822
878
|
height: "6px",
|
|
@@ -826,13 +882,27 @@ function OpenVikingStatusPopover({
|
|
|
826
882
|
}
|
|
827
883
|
}
|
|
828
884
|
),
|
|
829
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { children: isOnline ?
|
|
885
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { children: isOnline ? [
|
|
886
|
+
"ONLINE",
|
|
887
|
+
formatDaemonVersion(health?.version),
|
|
888
|
+
sessionUnreadable ? "\xB7 no session access" : null
|
|
889
|
+
].filter(Boolean).join(" ") : "OFFLINE" })
|
|
830
890
|
]
|
|
831
891
|
}
|
|
832
892
|
)
|
|
833
893
|
]
|
|
834
894
|
}
|
|
835
895
|
),
|
|
896
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
897
|
+
"div",
|
|
898
|
+
{
|
|
899
|
+
style: {
|
|
900
|
+
borderTop: `.5px solid ${themeVar("hairline")}`,
|
|
901
|
+
marginBottom: "10px"
|
|
902
|
+
},
|
|
903
|
+
"aria-hidden": "true"
|
|
904
|
+
}
|
|
905
|
+
),
|
|
836
906
|
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
837
907
|
"div",
|
|
838
908
|
{
|
|
@@ -843,142 +913,88 @@ function OpenVikingStatusPopover({
|
|
|
843
913
|
marginBottom: "10px"
|
|
844
914
|
},
|
|
845
915
|
children: [
|
|
846
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
847
|
-
"
|
|
848
|
-
{
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
alignItems: "center"
|
|
920
|
-
},
|
|
921
|
-
children: [
|
|
922
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { style: { color: "var(--dsw-text-muted, #94a3b8)" }, children: "Peer ID:" }),
|
|
923
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
924
|
-
"span",
|
|
925
|
-
{
|
|
926
|
-
"data-testid": "peer-id-value",
|
|
927
|
-
style: {
|
|
928
|
-
maxWidth: "180px",
|
|
929
|
-
overflow: "hidden",
|
|
930
|
-
textOverflow: "ellipsis",
|
|
931
|
-
whiteSpace: "nowrap",
|
|
932
|
-
fontFamily: "var(--dsw-font-mono, monospace)"
|
|
933
|
-
},
|
|
934
|
-
title: sessionData.peer_id,
|
|
935
|
-
children: sessionData.peer_id
|
|
936
|
-
}
|
|
937
|
-
)
|
|
938
|
-
]
|
|
939
|
-
}
|
|
940
|
-
),
|
|
941
|
-
sessionData?.last_commit_at && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
942
|
-
"div",
|
|
943
|
-
{
|
|
944
|
-
style: {
|
|
945
|
-
display: "flex",
|
|
946
|
-
justifyContent: "space-between",
|
|
947
|
-
alignItems: "center"
|
|
948
|
-
},
|
|
949
|
-
children: [
|
|
950
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { style: { color: "var(--dsw-text-muted, #94a3b8)" }, children: "Last Commit:" }),
|
|
951
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
952
|
-
"span",
|
|
953
|
-
{
|
|
954
|
-
"data-testid": "last-commit-value",
|
|
955
|
-
title: sessionData.last_commit_at,
|
|
956
|
-
style: { color: "var(--dsw-text-default, #e2e8f0)" },
|
|
957
|
-
children: formatRelativeTime(sessionData.last_commit_at) || sessionData.last_commit_at
|
|
958
|
-
}
|
|
959
|
-
)
|
|
960
|
-
]
|
|
961
|
-
}
|
|
962
|
-
)
|
|
916
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: rowStyle, children: [
|
|
917
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { style: mutedStyle, children: "Session ID:" }),
|
|
918
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { style: { display: "flex", alignItems: "center", gap: "4px" }, children: [
|
|
919
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
920
|
+
"span",
|
|
921
|
+
{
|
|
922
|
+
"data-testid": "session-id-value",
|
|
923
|
+
role: "button",
|
|
924
|
+
tabIndex: 0,
|
|
925
|
+
onKeyDown: (e) => {
|
|
926
|
+
if (e.key === "Enter" || e.key === " ") {
|
|
927
|
+
e.preventDefault();
|
|
928
|
+
handleCopySessionId();
|
|
929
|
+
}
|
|
930
|
+
},
|
|
931
|
+
"aria-label": "Click to copy Session ID",
|
|
932
|
+
style: { ...monoStyle, cursor: "pointer" },
|
|
933
|
+
title: displaySessionId,
|
|
934
|
+
onClick: handleCopySessionId,
|
|
935
|
+
children: truncateSessionId(displaySessionId)
|
|
936
|
+
}
|
|
937
|
+
),
|
|
938
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
939
|
+
"button",
|
|
940
|
+
{
|
|
941
|
+
type: "button",
|
|
942
|
+
"data-testid": "copy-session-btn",
|
|
943
|
+
onClick: handleCopySessionId,
|
|
944
|
+
title: copied ? "Copied!" : "Copy Session ID",
|
|
945
|
+
"aria-label": copied ? "Copied!" : "Copy Session ID",
|
|
946
|
+
style: {
|
|
947
|
+
background: "none",
|
|
948
|
+
border: "none",
|
|
949
|
+
cursor: "pointer",
|
|
950
|
+
padding: "2px",
|
|
951
|
+
display: "inline-flex",
|
|
952
|
+
alignItems: "center",
|
|
953
|
+
color: copied ? themeVar("stateSuccess") : themeVar("labelTertiary")
|
|
954
|
+
},
|
|
955
|
+
children: copied ? CheckIcon && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(CheckIcon, { size: 14 }) : CopyIcon && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(CopyIcon, { size: 14 })
|
|
956
|
+
}
|
|
957
|
+
)
|
|
958
|
+
] })
|
|
959
|
+
] }),
|
|
960
|
+
sessionData?.peer_id && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: rowStyle, children: [
|
|
961
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { style: mutedStyle, children: "Peer ID:" }),
|
|
962
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
963
|
+
"span",
|
|
964
|
+
{
|
|
965
|
+
"data-testid": "peer-id-value",
|
|
966
|
+
style: {
|
|
967
|
+
...monoStyle,
|
|
968
|
+
maxWidth: "180px",
|
|
969
|
+
overflow: "hidden",
|
|
970
|
+
textOverflow: "ellipsis",
|
|
971
|
+
whiteSpace: "nowrap"
|
|
972
|
+
},
|
|
973
|
+
title: sessionData.peer_id,
|
|
974
|
+
children: sessionData.peer_id
|
|
975
|
+
}
|
|
976
|
+
)
|
|
977
|
+
] }),
|
|
978
|
+
sessionData?.last_commit_at && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: rowStyle, children: [
|
|
979
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { style: mutedStyle, children: "Last Commit:" }),
|
|
980
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
981
|
+
"span",
|
|
982
|
+
{
|
|
983
|
+
"data-testid": "last-commit-value",
|
|
984
|
+
title: sessionData.last_commit_at,
|
|
985
|
+
children: formatRelativeTime(sessionData.last_commit_at) || sessionData.last_commit_at
|
|
986
|
+
}
|
|
987
|
+
)
|
|
988
|
+
] })
|
|
963
989
|
]
|
|
964
990
|
}
|
|
965
991
|
),
|
|
966
992
|
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: { marginBottom: "12px" }, children: [
|
|
967
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
968
|
-
"
|
|
969
|
-
{
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
justifyContent: "space-between",
|
|
973
|
-
marginBottom: "4px"
|
|
974
|
-
},
|
|
975
|
-
children: [
|
|
976
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { style: { color: "var(--dsw-text-muted, #94a3b8)" }, children: "Pending Tokens:" }),
|
|
977
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { "data-testid": "pending-tokens-label", style: { fontWeight: 500 }, children: `${pendingTokens.toLocaleString()} / ${COMMIT_THRESHOLD.toLocaleString()}` })
|
|
978
|
-
]
|
|
979
|
-
}
|
|
980
|
-
),
|
|
981
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
993
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: { ...rowStyle, marginBottom: "4px" }, children: [
|
|
994
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { style: mutedStyle, children: "Pending Tokens:" }),
|
|
995
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { "data-testid": "pending-tokens-label", children: pendingLabel })
|
|
996
|
+
] }),
|
|
997
|
+
!sessionUnreadable && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
982
998
|
"div",
|
|
983
999
|
{
|
|
984
1000
|
"data-testid": "progress-bar-track",
|
|
@@ -986,7 +1002,7 @@ function OpenVikingStatusPopover({
|
|
|
986
1002
|
width: "100%",
|
|
987
1003
|
height: "6px",
|
|
988
1004
|
borderRadius: "3px",
|
|
989
|
-
backgroundColor: "
|
|
1005
|
+
backgroundColor: themeVar("insetSurface"),
|
|
990
1006
|
overflow: "hidden"
|
|
991
1007
|
},
|
|
992
1008
|
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
@@ -1004,30 +1020,34 @@ function OpenVikingStatusPopover({
|
|
|
1004
1020
|
}
|
|
1005
1021
|
)
|
|
1006
1022
|
] }),
|
|
1023
|
+
sessionUnreadable && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
1024
|
+
"div",
|
|
1025
|
+
{
|
|
1026
|
+
"data-testid": "session-unreadable-notice",
|
|
1027
|
+
style: {
|
|
1028
|
+
marginBottom: "12px",
|
|
1029
|
+
color: themeVar("labelTertiary")
|
|
1030
|
+
},
|
|
1031
|
+
children: unauthorized ? "The daemon requires an API key. Set openviking_api_key in localStorage to read session counters." : "Session counters are unavailable right now."
|
|
1032
|
+
}
|
|
1033
|
+
),
|
|
1007
1034
|
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: { marginBottom: "12px" }, children: [
|
|
1008
1035
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
1009
1036
|
"div",
|
|
1010
1037
|
{
|
|
1011
1038
|
style: {
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
marginBottom: "4px"
|
|
1039
|
+
marginBottom: "4px",
|
|
1040
|
+
color: themeVar("labelPrimary"),
|
|
1041
|
+
fontWeight: 500
|
|
1016
1042
|
},
|
|
1017
|
-
children:
|
|
1043
|
+
children: `Recalled Memories (${recalledCount})`
|
|
1018
1044
|
}
|
|
1019
1045
|
),
|
|
1020
1046
|
memoryItems.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
1021
1047
|
"div",
|
|
1022
1048
|
{
|
|
1023
1049
|
"data-testid": "empty-memories-message",
|
|
1024
|
-
style: {
|
|
1025
|
-
padding: "8px 0",
|
|
1026
|
-
color: "var(--dsw-text-muted, #94a3b8)",
|
|
1027
|
-
fontStyle: "italic",
|
|
1028
|
-
fontSize: "11px",
|
|
1029
|
-
textAlign: "center"
|
|
1030
|
-
},
|
|
1050
|
+
style: { ...mutedStyle, padding: "4px 0" },
|
|
1031
1051
|
children: "No memories recalled in this session"
|
|
1032
1052
|
}
|
|
1033
1053
|
) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
@@ -1051,11 +1071,7 @@ function OpenVikingStatusPopover({
|
|
|
1051
1071
|
display: "flex",
|
|
1052
1072
|
alignItems: "center",
|
|
1053
1073
|
gap: "6px",
|
|
1054
|
-
|
|
1055
|
-
borderRadius: "4px",
|
|
1056
|
-
backgroundColor: "rgba(255, 255, 255, 0.04)",
|
|
1057
|
-
border: "1px solid var(--dsw-border-subtle, rgba(255, 255, 255, 0.05))",
|
|
1058
|
-
fontSize: "11px"
|
|
1074
|
+
minWidth: 0
|
|
1059
1075
|
},
|
|
1060
1076
|
children: [
|
|
1061
1077
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
@@ -1063,10 +1079,6 @@ function OpenVikingStatusPopover({
|
|
|
1063
1079
|
{
|
|
1064
1080
|
"data-testid": "memory-category-badge",
|
|
1065
1081
|
style: {
|
|
1066
|
-
fontSize: "9px",
|
|
1067
|
-
fontWeight: 600,
|
|
1068
|
-
padding: "1px 4px",
|
|
1069
|
-
borderRadius: "3px",
|
|
1070
1082
|
textTransform: "uppercase",
|
|
1071
1083
|
flexShrink: 0,
|
|
1072
1084
|
...getCategoryBadgeStyle(item.category)
|
|
@@ -1078,21 +1090,7 @@ function OpenVikingStatusPopover({
|
|
|
1078
1090
|
"span",
|
|
1079
1091
|
{
|
|
1080
1092
|
"data-testid": "memory-source-badge",
|
|
1081
|
-
style: {
|
|
1082
|
-
fontSize: "9px",
|
|
1083
|
-
fontWeight: 600,
|
|
1084
|
-
padding: "1px 4px",
|
|
1085
|
-
borderRadius: "3px",
|
|
1086
|
-
textTransform: "uppercase",
|
|
1087
|
-
flexShrink: 0,
|
|
1088
|
-
...item.source === "profile" ? {
|
|
1089
|
-
backgroundColor: "rgba(99, 102, 241, 0.15)",
|
|
1090
|
-
color: "#818cf8"
|
|
1091
|
-
} : {
|
|
1092
|
-
backgroundColor: "rgba(16, 185, 129, 0.15)",
|
|
1093
|
-
color: "var(--dsw-status-success, #34d399)"
|
|
1094
|
-
}
|
|
1095
|
-
},
|
|
1093
|
+
style: { ...mutedStyle, flexShrink: 0 },
|
|
1096
1094
|
children: item.source
|
|
1097
1095
|
}
|
|
1098
1096
|
),
|
|
@@ -1101,12 +1099,10 @@ function OpenVikingStatusPopover({
|
|
|
1101
1099
|
{
|
|
1102
1100
|
"data-testid": "memory-leaf-name",
|
|
1103
1101
|
style: {
|
|
1104
|
-
flex: 1,
|
|
1105
1102
|
overflow: "hidden",
|
|
1106
1103
|
textOverflow: "ellipsis",
|
|
1107
1104
|
whiteSpace: "nowrap",
|
|
1108
|
-
|
|
1109
|
-
color: "var(--dsw-text-default, #f1f5f9)"
|
|
1105
|
+
minWidth: 0
|
|
1110
1106
|
},
|
|
1111
1107
|
children: formatMemoryLeafName(item.uri)
|
|
1112
1108
|
}
|
|
@@ -1122,16 +1118,7 @@ function OpenVikingStatusPopover({
|
|
|
1122
1118
|
"div",
|
|
1123
1119
|
{
|
|
1124
1120
|
"data-testid": "commit-error-message",
|
|
1125
|
-
style: {
|
|
1126
|
-
marginBottom: "8px",
|
|
1127
|
-
padding: "6px 8px",
|
|
1128
|
-
borderRadius: "4px",
|
|
1129
|
-
backgroundColor: "rgba(248, 113, 113, 0.1)",
|
|
1130
|
-
border: "1px solid var(--dsw-status-error, #f87171)",
|
|
1131
|
-
color: "var(--dsw-status-error, #f87171)",
|
|
1132
|
-
fontSize: "11px",
|
|
1133
|
-
wordBreak: "break-word"
|
|
1134
|
-
},
|
|
1121
|
+
style: { marginBottom: "8px", color: themeVar("stateError") },
|
|
1135
1122
|
children: commitError
|
|
1136
1123
|
}
|
|
1137
1124
|
),
|
|
@@ -1140,19 +1127,17 @@ function OpenVikingStatusPopover({
|
|
|
1140
1127
|
{
|
|
1141
1128
|
type: "button",
|
|
1142
1129
|
"data-testid": "commit-now-btn",
|
|
1143
|
-
onClick: () => onCommitNow?.(),
|
|
1130
|
+
onClick: () => void onCommitNow?.(),
|
|
1144
1131
|
disabled: isCommitDisabled,
|
|
1145
1132
|
style: {
|
|
1146
1133
|
width: "100%",
|
|
1147
|
-
padding: "
|
|
1148
|
-
borderRadius: "
|
|
1149
|
-
border:
|
|
1150
|
-
|
|
1151
|
-
color: isCommitDisabled ? "
|
|
1152
|
-
cursor: isCommitDisabled ? "
|
|
1153
|
-
|
|
1154
|
-
fontSize: "12px",
|
|
1155
|
-
transition: "all 0.15s ease",
|
|
1134
|
+
padding: "6px 10px",
|
|
1135
|
+
borderRadius: "8px",
|
|
1136
|
+
border: `.5px solid ${themeVar("hairline")}`,
|
|
1137
|
+
background: isCommitDisabled ? "transparent" : themeVar("hoverBackground"),
|
|
1138
|
+
color: isCommitDisabled ? themeVar("labelTertiary") : themeVar("labelPrimary"),
|
|
1139
|
+
cursor: isCommitDisabled ? "default" : "pointer",
|
|
1140
|
+
font: "inherit",
|
|
1156
1141
|
display: "flex",
|
|
1157
1142
|
alignItems: "center",
|
|
1158
1143
|
justifyContent: "center",
|
|
@@ -1162,12 +1147,13 @@ function OpenVikingStatusPopover({
|
|
|
1162
1147
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
1163
1148
|
"span",
|
|
1164
1149
|
{
|
|
1150
|
+
"aria-hidden": "true",
|
|
1165
1151
|
style: {
|
|
1166
1152
|
display: "inline-block",
|
|
1167
1153
|
width: "10px",
|
|
1168
1154
|
height: "10px",
|
|
1169
1155
|
borderRadius: "50%",
|
|
1170
|
-
border:
|
|
1156
|
+
border: `2px solid ${themeVar("stateWarning")}`,
|
|
1171
1157
|
borderTopColor: "transparent",
|
|
1172
1158
|
animation: "ov-spin 1s linear infinite"
|
|
1173
1159
|
}
|
|
@@ -1199,11 +1185,15 @@ function formatTooltipTitle({
|
|
|
1199
1185
|
isOnline,
|
|
1200
1186
|
isCommitting = false,
|
|
1201
1187
|
recalledCount,
|
|
1202
|
-
pendingTokens
|
|
1188
|
+
pendingTokens,
|
|
1189
|
+
sessionUnreadable = false
|
|
1203
1190
|
}) {
|
|
1204
1191
|
if (!isOnline) {
|
|
1205
1192
|
return "OpenViking: Offline";
|
|
1206
1193
|
}
|
|
1194
|
+
if (sessionUnreadable) {
|
|
1195
|
+
return "OpenViking: session unreadable \u2014 the daemon requires an API key";
|
|
1196
|
+
}
|
|
1207
1197
|
const countLabel = `${recalledCount} recalled`;
|
|
1208
1198
|
const tokenLabel = `${(pendingTokens || 0).toLocaleString()} pending tokens`;
|
|
1209
1199
|
if (isCommitting) {
|
|
@@ -1211,36 +1201,69 @@ function formatTooltipTitle({
|
|
|
1211
1201
|
}
|
|
1212
1202
|
return `OpenViking: Online (${countLabel}, ${tokenLabel})`;
|
|
1213
1203
|
}
|
|
1214
|
-
function getStatusIndicatorColor(isOnline, isCommitting = false) {
|
|
1204
|
+
function getStatusIndicatorColor(isOnline, isCommitting = false, sessionUnreadable = false) {
|
|
1215
1205
|
if (!isOnline) {
|
|
1216
|
-
return "
|
|
1206
|
+
return themeVar("stateError");
|
|
1217
1207
|
}
|
|
1218
|
-
if (isCommitting) {
|
|
1219
|
-
return "
|
|
1208
|
+
if (isCommitting || sessionUnreadable) {
|
|
1209
|
+
return themeVar("stateWarning");
|
|
1220
1210
|
}
|
|
1221
|
-
return "
|
|
1211
|
+
return themeVar("stateSuccess");
|
|
1222
1212
|
}
|
|
1223
|
-
function
|
|
1224
|
-
if (
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1213
|
+
function chatNodesToText(nodes) {
|
|
1214
|
+
if (!nodes) return "";
|
|
1215
|
+
const source = Array.isArray(nodes) ? nodes : typeof nodes === "object" ? Object.values(nodes) : [];
|
|
1216
|
+
const parts = [];
|
|
1217
|
+
const visit = (value, depth = 0) => {
|
|
1218
|
+
if (depth > 4 || value === null || value === void 0) return;
|
|
1219
|
+
if (typeof value === "string") {
|
|
1220
|
+
parts.push(value);
|
|
1221
|
+
return;
|
|
1222
|
+
}
|
|
1223
|
+
if (Array.isArray(value)) {
|
|
1224
|
+
for (const item of value) visit(item, depth + 1);
|
|
1225
|
+
return;
|
|
1226
|
+
}
|
|
1227
|
+
if (typeof value === "object") {
|
|
1228
|
+
const record = value;
|
|
1229
|
+
for (const key of ["content", "text", "data", "body"]) {
|
|
1230
|
+
if (key in record) visit(record[key], depth + 1);
|
|
1231
|
+
}
|
|
1232
|
+
}
|
|
1233
|
+
};
|
|
1234
|
+
for (const node of source) visit(node);
|
|
1235
|
+
return parts.join("\n");
|
|
1228
1236
|
}
|
|
1229
|
-
function
|
|
1230
|
-
|
|
1231
|
-
|
|
1237
|
+
function OpenVikingStatusChip(props) {
|
|
1238
|
+
const { useChat, ...rest } = props;
|
|
1239
|
+
if (useChat && rest.contextText === void 0 && rest.messages === void 0) {
|
|
1240
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ChatReadBoundary, { fallback: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(StatusChipView, { ...rest }), children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ChatBackedStatusChip, { useChat, ...rest }) });
|
|
1232
1241
|
}
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1242
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(StatusChipView, { ...rest });
|
|
1243
|
+
}
|
|
1244
|
+
var ChatReadBoundary = class extends import_react2.default.Component {
|
|
1245
|
+
state = { failed: false };
|
|
1246
|
+
static getDerivedStateFromError() {
|
|
1247
|
+
return { failed: true };
|
|
1237
1248
|
}
|
|
1238
|
-
|
|
1239
|
-
return
|
|
1249
|
+
render() {
|
|
1250
|
+
return this.state.failed ? this.props.fallback : this.props.children;
|
|
1240
1251
|
}
|
|
1241
|
-
|
|
1252
|
+
};
|
|
1253
|
+
function ChatBackedStatusChip({
|
|
1254
|
+
useChat,
|
|
1255
|
+
...rest
|
|
1256
|
+
}) {
|
|
1257
|
+
const nodes = useChat((snapshot) => {
|
|
1258
|
+
try {
|
|
1259
|
+
return snapshot?.legacy?.nodes !== void 0 ? snapshot.legacy.nodes : snapshot?.nodes;
|
|
1260
|
+
} catch {
|
|
1261
|
+
return void 0;
|
|
1262
|
+
}
|
|
1263
|
+
});
|
|
1264
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(StatusChipView, { ...rest, messages: nodes });
|
|
1242
1265
|
}
|
|
1243
|
-
function
|
|
1266
|
+
function StatusChipView({
|
|
1244
1267
|
sessionId,
|
|
1245
1268
|
messages,
|
|
1246
1269
|
contextText,
|
|
@@ -1249,32 +1272,28 @@ function OpenVikingStatusChip({
|
|
|
1249
1272
|
className,
|
|
1250
1273
|
initialHealth,
|
|
1251
1274
|
initialSessionData,
|
|
1275
|
+
initialSessionRead,
|
|
1252
1276
|
initialOpen = false
|
|
1253
1277
|
}) {
|
|
1254
1278
|
const [health, setHealth] = (0, import_react2.useState)(
|
|
1255
1279
|
initialHealth ?? null
|
|
1256
1280
|
);
|
|
1257
|
-
const [
|
|
1258
|
-
|
|
1281
|
+
const [sessionRead, setSessionRead] = (0, import_react2.useState)(
|
|
1282
|
+
initialSessionRead ?? (initialSessionData ? { status: "ok", session: initialSessionData } : null)
|
|
1259
1283
|
);
|
|
1260
1284
|
const [isOpen, setIsOpen] = (0, import_react2.useState)(initialOpen);
|
|
1261
1285
|
const [isCommitting, setIsCommitting] = (0, import_react2.useState)(false);
|
|
1262
1286
|
const [commitError, setCommitError] = (0, import_react2.useState)(null);
|
|
1287
|
+
const [isHovered, setIsHovered] = (0, import_react2.useState)(false);
|
|
1263
1288
|
const popoverRef = (0, import_react2.useRef)(null);
|
|
1264
1289
|
const apiClient = client ?? defaultOpenVikingClient;
|
|
1265
|
-
const
|
|
1266
|
-
if (
|
|
1267
|
-
return
|
|
1268
|
-
}, [
|
|
1269
|
-
const inputForParser = (0, import_react2.useMemo)(() => {
|
|
1270
|
-
if (contextText && messages) {
|
|
1271
|
-
return [contextText, ...messages];
|
|
1272
|
-
}
|
|
1273
|
-
return contextText ?? messages ?? fallbackMessages;
|
|
1274
|
-
}, [contextText, messages, fallbackMessages]);
|
|
1290
|
+
const conversationText = (0, import_react2.useMemo)(() => {
|
|
1291
|
+
if (typeof contextText === "string") return contextText;
|
|
1292
|
+
return chatNodesToText(messages);
|
|
1293
|
+
}, [contextText, messages]);
|
|
1275
1294
|
const recalledResult = (0, import_react2.useMemo)(
|
|
1276
|
-
() => parseRecalledMemories(
|
|
1277
|
-
[
|
|
1295
|
+
() => parseRecalledMemories(conversationText),
|
|
1296
|
+
[conversationText]
|
|
1278
1297
|
);
|
|
1279
1298
|
const fetchStatus = (0, import_react2.useCallback)(async () => {
|
|
1280
1299
|
try {
|
|
@@ -1283,8 +1302,7 @@ function OpenVikingStatusChip({
|
|
|
1283
1302
|
if (!healthRes.ok) {
|
|
1284
1303
|
return;
|
|
1285
1304
|
}
|
|
1286
|
-
|
|
1287
|
-
setSessionData(session);
|
|
1305
|
+
setSessionRead(await apiClient.readSession(sessionId));
|
|
1288
1306
|
} catch {
|
|
1289
1307
|
setHealth({ ok: false });
|
|
1290
1308
|
}
|
|
@@ -1337,26 +1355,28 @@ function OpenVikingStatusChip({
|
|
|
1337
1355
|
}
|
|
1338
1356
|
};
|
|
1339
1357
|
const isOnline = health?.ok === true;
|
|
1358
|
+
const sessionData = sessionRead?.status === "ok" ? sessionRead.session : null;
|
|
1359
|
+
const sessionUnreadable = isOnline && sessionRead !== null && sessionRead.status !== "ok";
|
|
1340
1360
|
const pendingTokens = sessionData?.pending_tokens ?? 0;
|
|
1341
|
-
const pendingTokensK = Math.round(pendingTokens / 1e3);
|
|
1342
1361
|
const recalledCount = recalledResult.recalledCount;
|
|
1343
|
-
const statusColor = getStatusIndicatorColor(
|
|
1344
|
-
|
|
1362
|
+
const statusColor = getStatusIndicatorColor(
|
|
1363
|
+
isOnline,
|
|
1364
|
+
isCommitting,
|
|
1365
|
+
sessionUnreadable
|
|
1366
|
+
);
|
|
1345
1367
|
const tooltipTitle = formatTooltipTitle({
|
|
1346
1368
|
isOnline,
|
|
1347
1369
|
isCommitting,
|
|
1348
1370
|
recalledCount,
|
|
1349
|
-
pendingTokens
|
|
1371
|
+
pendingTokens,
|
|
1372
|
+
sessionUnreadable
|
|
1350
1373
|
});
|
|
1374
|
+
const label = !isOnline ? "OV offline" : sessionUnreadable ? `OV: ${recalledCount} rec \xB7 no access` : `OV: ${recalledCount} rec \xB7 ${Math.round(pendingTokens / 1e3)}k pend`;
|
|
1351
1375
|
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
1352
|
-
"
|
|
1376
|
+
"span",
|
|
1353
1377
|
{
|
|
1354
1378
|
className,
|
|
1355
|
-
style: {
|
|
1356
|
-
position: "relative",
|
|
1357
|
-
display: "inline-flex",
|
|
1358
|
-
alignItems: "center"
|
|
1359
|
-
},
|
|
1379
|
+
style: { minWidth: 0, display: "inline-flex", position: "relative" },
|
|
1360
1380
|
ref: popoverRef,
|
|
1361
1381
|
children: [
|
|
1362
1382
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
@@ -1364,23 +1384,28 @@ function OpenVikingStatusChip({
|
|
|
1364
1384
|
{
|
|
1365
1385
|
type: "button",
|
|
1366
1386
|
onClick: () => setIsOpen(!isOpen),
|
|
1387
|
+
onMouseEnter: () => setIsHovered(true),
|
|
1388
|
+
onMouseLeave: () => setIsHovered(false),
|
|
1367
1389
|
"aria-expanded": isOpen,
|
|
1368
1390
|
"aria-haspopup": "dialog",
|
|
1369
1391
|
style: {
|
|
1370
|
-
|
|
1392
|
+
// Геометрия и типографика повторяют штатный чип статистики DSH:
|
|
1393
|
+
// прозрачный фон, без рамки, шрифт и кегль наследуются от строки.
|
|
1394
|
+
boxSizing: "border-box",
|
|
1395
|
+
maxWidth: "100%",
|
|
1396
|
+
color: themeVar("labelTertiary"),
|
|
1397
|
+
font: "inherit",
|
|
1398
|
+
fontVariantNumeric: "tabular-nums",
|
|
1399
|
+
lineHeight: "inherit",
|
|
1400
|
+
whiteSpace: "nowrap",
|
|
1401
|
+
background: isHovered ? themeVar("hoverBackground") : "transparent",
|
|
1402
|
+
border: "none",
|
|
1403
|
+
borderRadius: "24px",
|
|
1371
1404
|
alignItems: "center",
|
|
1372
1405
|
gap: "6px",
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
fontFamily: "var(--dsw-font-mono, monospace)",
|
|
1377
|
-
borderRadius: "6px",
|
|
1378
|
-
background: "var(--dsw-surface-base, rgba(255, 255, 255, 0.05))",
|
|
1379
|
-
border: "1px solid var(--dsw-border-subtle, rgba(255, 255, 255, 0.1))",
|
|
1380
|
-
color: "var(--dsw-text-muted, #94a3b8)",
|
|
1381
|
-
cursor: "pointer",
|
|
1382
|
-
transition: "all 0.15s ease",
|
|
1383
|
-
userSelect: "none"
|
|
1406
|
+
padding: "1px 8px",
|
|
1407
|
+
display: "inline-flex",
|
|
1408
|
+
cursor: "pointer"
|
|
1384
1409
|
},
|
|
1385
1410
|
title: tooltipTitle,
|
|
1386
1411
|
"aria-label": tooltipTitle,
|
|
@@ -1389,25 +1414,17 @@ function OpenVikingStatusChip({
|
|
|
1389
1414
|
"span",
|
|
1390
1415
|
{
|
|
1391
1416
|
"data-testid": "status-dot",
|
|
1417
|
+
"aria-hidden": "true",
|
|
1392
1418
|
style: {
|
|
1393
|
-
width: "
|
|
1394
|
-
height: "
|
|
1419
|
+
width: "6px",
|
|
1420
|
+
height: "6px",
|
|
1395
1421
|
borderRadius: "50%",
|
|
1396
|
-
|
|
1397
|
-
boxShadow: statusGlow,
|
|
1422
|
+
background: statusColor,
|
|
1398
1423
|
flexShrink: 0
|
|
1399
1424
|
}
|
|
1400
1425
|
}
|
|
1401
1426
|
),
|
|
1402
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
1403
|
-
"span",
|
|
1404
|
-
{
|
|
1405
|
-
style: { fontWeight: 600, color: "var(--dsw-text-default, #e2e8f0)" },
|
|
1406
|
-
children: isOnline ? "OV:" : "OV"
|
|
1407
|
-
}
|
|
1408
|
-
),
|
|
1409
|
-
" ",
|
|
1410
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { children: isOnline ? `${recalledCount} rec \xB7 ${pendingTokensK}k pend` : "offline" })
|
|
1427
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { style: { textOverflow: "ellipsis", minWidth: 0 }, children: label })
|
|
1411
1428
|
]
|
|
1412
1429
|
}
|
|
1413
1430
|
),
|
|
@@ -1417,6 +1434,7 @@ function OpenVikingStatusChip({
|
|
|
1417
1434
|
sessionId,
|
|
1418
1435
|
health,
|
|
1419
1436
|
sessionData,
|
|
1437
|
+
sessionRead,
|
|
1420
1438
|
recalledResult,
|
|
1421
1439
|
endpoint: apiClient.endpoint,
|
|
1422
1440
|
isCommitting,
|
|
@@ -1436,10 +1454,10 @@ var inject = ["slots"];
|
|
|
1436
1454
|
function apply(ctx) {
|
|
1437
1455
|
ctx.effect(
|
|
1438
1456
|
() => ctx.slots.inject(
|
|
1439
|
-
"conversation.
|
|
1457
|
+
"conversation.composer.dock",
|
|
1440
1458
|
() => ctx.slots.register(
|
|
1441
1459
|
{
|
|
1442
|
-
name: "conversation.
|
|
1460
|
+
name: "conversation.composer.dock",
|
|
1443
1461
|
id: "openviking-status",
|
|
1444
1462
|
order: 50,
|
|
1445
1463
|
label: "OpenViking"
|
|
@@ -1447,7 +1465,7 @@ function apply(ctx) {
|
|
|
1447
1465
|
OpenVikingStatusChip
|
|
1448
1466
|
)
|
|
1449
1467
|
),
|
|
1450
|
-
"openviking-status: composer chip"
|
|
1468
|
+
"openviking-status: composer stats chip"
|
|
1451
1469
|
);
|
|
1452
1470
|
}
|
|
1453
1471
|
return module.exports;
|