@ramme-io/ui 4.0.1 → 4.1.1
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 +159 -7
- package/dist/blocks/ai/Actions.js +2 -2
- package/dist/blocks/ai/PromptInput.js +6 -6
- package/dist/component-registry.js +389 -359
- package/dist/components/ai/AIChatThread/AIChatThread.js +81 -73
- package/dist/components/ai/ArchitectureReferenceCard/ArchitectureReferenceCard.d.ts +28 -0
- package/dist/components/ai/ArchitectureReferenceCard/ArchitectureReferenceCard.js +70 -0
- package/dist/components/ai/ArchitectureReferenceCard/index.d.ts +2 -0
- package/dist/components/ai/CounterpartyGraphCard/CounterpartyGraphCard.d.ts +30 -0
- package/dist/components/ai/CounterpartyGraphCard/CounterpartyGraphCard.js +82 -0
- package/dist/components/ai/CounterpartyGraphCard/index.d.ts +2 -0
- package/dist/components/ai/DivergenceMetricsCard/DivergenceMetricsCard.d.ts +29 -0
- package/dist/components/ai/DivergenceMetricsCard/DivergenceMetricsCard.js +69 -0
- package/dist/components/ai/DivergenceMetricsCard/index.d.ts +2 -0
- package/dist/components/ai/KeyInjectionOverlay.d.ts +10 -0
- package/dist/components/ai/KeyInjectionOverlay.js +11 -11
- package/dist/components/ai/NewsSummaryCard/NewsSummaryCard.js +17 -17
- package/dist/components/ai/StockChart/StockChart.js +4 -4
- package/dist/components/auth/AuthLayout.js +4 -4
- package/dist/components/auth/LoginPage.d.ts +22 -0
- package/dist/components/auth/LoginPage.js +50 -42
- package/dist/components/data-display/CodeBlock.d.ts +33 -7
- package/dist/components/data-display/CodeBlock.js +134 -41
- package/dist/components/data-display/Table.js +8 -8
- package/dist/components/feedback/EmptyState.js +9 -9
- package/dist/components/feedback/ToastProvider.js +4 -4
- package/dist/components/forms/Checkbox.js +5 -5
- package/dist/components/forms/ComboBox.js +2 -2
- package/dist/components/forms/DatePicker.js +37 -32
- package/dist/components/forms/FileUpload.js +39 -37
- package/dist/components/forms/Input.js +19 -18
- package/dist/components/forms/MultiSelect.js +9 -8
- package/dist/components/forms/Radio.js +6 -6
- package/dist/components/forms/SegmentedControl.d.ts +1 -1
- package/dist/components/forms/SegmentedControl.js +28 -11
- package/dist/components/forms/Select.js +9 -8
- package/dist/components/forms/Textarea.d.ts +13 -11
- package/dist/components/forms/Textarea.js +36 -16
- package/dist/components/forms/ToggleSwitch.js +9 -9
- package/dist/components/layout/AboutRamme.d.ts +8 -0
- package/dist/components/layout/Accordion.js +25 -32
- package/dist/components/layout/AppShell.js +7 -7
- package/dist/components/layout/Card.js +38 -21
- package/dist/components/layout/DetailDrawer.js +37 -38
- package/dist/components/layout/Drawer.js +50 -51
- package/dist/components/layout/List.js +9 -9
- package/dist/components/layout/Modal.js +5 -5
- package/dist/components/layout/PageHeader.js +7 -7
- package/dist/components/layout/SectionHeader.js +4 -4
- package/dist/components/layout/SettingsContainer.d.ts +12 -0
- package/dist/components/layout/SettingsContainer.js +30 -18
- package/dist/components/layout/Sheet.d.ts +58 -0
- package/dist/components/layout/Sheet.js +144 -0
- package/dist/components/layout/Sidebar.js +1 -1
- package/dist/components/layout/UserNav.d.ts +13 -0
- package/dist/components/layout/UserNav.js +17 -17
- package/dist/components/molecular/ConnectorOverlay.d.ts +12 -0
- package/dist/components/navigation/Breadcrumbs.js +8 -8
- package/dist/components/navigation/Menu.js +6 -6
- package/dist/components/navigation/MobileNav.d.ts +44 -1
- package/dist/components/navigation/MobileNav.js +97 -71
- package/dist/components/navigation/Pagination.js +46 -41
- package/dist/components/navigation/Stepper.js +17 -17
- package/dist/components/navigation/Tabs.js +18 -11
- package/dist/components/theme/ThemeLab.d.ts +7 -1
- package/dist/components/theme/ThemeLab.js +175 -154
- package/dist/components/ui/icon-loader.d.ts +1 -1
- package/dist/contexts/ThemeContext.js +111 -82
- package/dist/data/mockData.d.ts +0 -3
- package/dist/index.css +1 -1
- package/dist/index.d.ts +10 -0
- package/dist/index.js +222 -197
- package/dist/lib/hooks/useBodyScrollLock.d.ts +27 -0
- package/dist/lib/hooks/useBodyScrollLock.js +18 -0
- package/dist/lib/hooks/useSheetGesture.d.ts +81 -0
- package/dist/lib/hooks/useSheetGesture.js +70 -0
- package/dist/lib/theme/themeUtils.d.ts +21 -0
- package/dist/lib/theme/themeUtils.js +31 -17
- package/dist/setupTests.d.ts +1 -0
- package/dist/wizardManifest.js +364 -19
- package/package.json +10 -4
- package/src/wizardManifest.ts +364 -19
- package/tailwind.preset.js +98 -10
|
@@ -1,49 +1,53 @@
|
|
|
1
1
|
import { jsxs as c, jsx as t, Fragment as w } from "react/jsx-runtime";
|
|
2
|
-
import { useState as B, useRef as R, useEffect as
|
|
3
|
-
import { CodeBlock as
|
|
4
|
-
import { Icon as
|
|
5
|
-
import { PromptInput as
|
|
6
|
-
import { Actions as
|
|
7
|
-
import { cn as
|
|
8
|
-
import { TelemetryGraph as
|
|
2
|
+
import { useState as B, useRef as R, useEffect as D, useCallback as N } from "react";
|
|
3
|
+
import { CodeBlock as G } from "../../data-display/CodeBlock.js";
|
|
4
|
+
import { Icon as C } from "../../ui/Icon.js";
|
|
5
|
+
import { PromptInput as $ } from "../../../blocks/ai/PromptInput.js";
|
|
6
|
+
import { Actions as z, Suggestion as E } from "../../../blocks/ai/Actions.js";
|
|
7
|
+
import { cn as p } from "../../../utils/cn.js";
|
|
8
|
+
import { TelemetryGraph as F } from "../TelemetryGraph/TelemetryGraph.js";
|
|
9
9
|
import { StockChart as S } from "../StockChart/StockChart.js";
|
|
10
10
|
import { LiveQuoteCard as V } from "../LiveQuoteCard/LiveQuoteCard.js";
|
|
11
|
-
import { NewsSummaryCard as
|
|
12
|
-
|
|
11
|
+
import { NewsSummaryCard as M } from "../NewsSummaryCard/NewsSummaryCard.js";
|
|
12
|
+
import { CompanyProfileCard as O } from "../CompanyProfileCard/CompanyProfileCard.js";
|
|
13
|
+
import { CounterpartyGraphCard as U } from "../CounterpartyGraphCard/CounterpartyGraphCard.js";
|
|
14
|
+
import { DivergenceMetricsCard as q } from "../DivergenceMetricsCard/DivergenceMetricsCard.js";
|
|
15
|
+
import { ArchitectureReferenceCard as L } from "../ArchitectureReferenceCard/ArchitectureReferenceCard.js";
|
|
16
|
+
function Q(e) {
|
|
13
17
|
if (!e) return null;
|
|
14
18
|
const l = e.split(/(```[\w]*\n[\s\S]*?```)/g);
|
|
15
|
-
return /* @__PURE__ */ t(w, { children: l.map((
|
|
16
|
-
const n =
|
|
19
|
+
return /* @__PURE__ */ t(w, { children: l.map((o, a) => {
|
|
20
|
+
const n = o.match(/^```([\w]*)\n([\s\S]*?)```$/);
|
|
17
21
|
if (n) {
|
|
18
|
-
const
|
|
19
|
-
return /* @__PURE__ */ t("div", { className: "my-3", children: /* @__PURE__ */ t(
|
|
22
|
+
const i = n[1] || "text", d = n[2].replace(/\n$/, "");
|
|
23
|
+
return /* @__PURE__ */ t("div", { className: "my-3", children: /* @__PURE__ */ t(G, { language: i, code: d }) }, a);
|
|
20
24
|
}
|
|
21
|
-
return
|
|
25
|
+
return o ? /* @__PURE__ */ t("p", { className: "whitespace-pre-wrap text-sm leading-relaxed", children: o }, a) : null;
|
|
22
26
|
}) });
|
|
23
27
|
}
|
|
24
|
-
const
|
|
28
|
+
const W = () => /* @__PURE__ */ t("div", { className: "flex items-center gap-1 px-1 py-0.5", "aria-label": "Assistant is typing", children: [0, 1, 2].map((e) => /* @__PURE__ */ t(
|
|
25
29
|
"span",
|
|
26
30
|
{
|
|
27
31
|
className: "w-1.5 h-1.5 rounded-full bg-muted-foreground/60 animate-bounce",
|
|
28
32
|
style: { animationDelay: `${e * 0.15}s`, animationDuration: "0.9s" }
|
|
29
33
|
},
|
|
30
34
|
e
|
|
31
|
-
)) }),
|
|
32
|
-
var
|
|
33
|
-
const n = e.role === "user",
|
|
34
|
-
return /* @__PURE__ */ c("div", { className:
|
|
35
|
-
|
|
36
|
-
!n && /* @__PURE__ */ t("div", { className: "shrink-0 w-7 h-7 rounded-full bg-primary/10 border border-primary/20 flex items-center justify-center mb-0.5", children: /* @__PURE__ */ t(
|
|
35
|
+
)) }), H = ({ message: e, isLastAssistant: l, isStreaming: o, renderContent: a }) => {
|
|
36
|
+
var h, s;
|
|
37
|
+
const n = e.role === "user", i = !e.content && !e.toolCall && l && o, d = !n && e.toolCall, u = ((h = e.content) == null ? void 0 : h.trim()) && e.content.trim().length > 0, f = !d && (u || i);
|
|
38
|
+
return /* @__PURE__ */ c("div", { className: p("flex flex-col gap-2 mb-4", n ? "items-end" : "items-start"), children: [
|
|
39
|
+
f && /* @__PURE__ */ c("div", { className: p("flex items-end gap-2", n ? "justify-end" : "justify-start"), children: [
|
|
40
|
+
!n && /* @__PURE__ */ t("div", { className: "shrink-0 w-7 h-7 rounded-full bg-primary/10 border border-primary/20 flex items-center justify-center mb-0.5", children: /* @__PURE__ */ t(C, { name: "sparkles", size: 13, className: "text-primary" }) }),
|
|
37
41
|
/* @__PURE__ */ t(
|
|
38
42
|
"div",
|
|
39
43
|
{
|
|
40
|
-
className:
|
|
44
|
+
className: p(
|
|
41
45
|
"relative max-w-[85%] rounded-2xl px-4 py-2.5 text-sm",
|
|
42
46
|
n ? "rounded-br-sm bg-primary text-primary-foreground" : "rounded-bl-sm bg-muted/60 border border-border/40 text-foreground"
|
|
43
47
|
),
|
|
44
|
-
children: n ? /* @__PURE__ */ t("p", { className: "whitespace-pre-wrap leading-relaxed", children: e.content }) :
|
|
45
|
-
|
|
46
|
-
l &&
|
|
48
|
+
children: n ? /* @__PURE__ */ t("p", { className: "whitespace-pre-wrap leading-relaxed", children: e.content }) : i ? /* @__PURE__ */ t(W, {}) : /* @__PURE__ */ c(w, { children: [
|
|
49
|
+
a ? a(e.content) : Q(e.content),
|
|
50
|
+
l && o && e.content && !e.toolCall && /* @__PURE__ */ t(
|
|
47
51
|
"span",
|
|
48
52
|
{
|
|
49
53
|
className: "inline-block w-[2px] h-[1em] bg-current ml-0.5 align-middle animate-pulse",
|
|
@@ -54,114 +58,118 @@ const q = () => /* @__PURE__ */ t("div", { className: "flex items-center gap-1 p
|
|
|
54
58
|
}
|
|
55
59
|
)
|
|
56
60
|
] }),
|
|
57
|
-
|
|
58
|
-
e.toolCall.name === "get_telemetry_graph" && /* @__PURE__ */ t(
|
|
61
|
+
d && e.toolCall && /* @__PURE__ */ c("div", { className: "ml-9 w-full max-w-[85%]", children: [
|
|
62
|
+
e.toolCall.name === "get_telemetry_graph" && /* @__PURE__ */ t(F, { params: e.toolCall.arguments }),
|
|
59
63
|
e.toolCall.name === "get_stock_chart" && /* @__PURE__ */ t(S, { params: e.toolCall.arguments }),
|
|
60
64
|
e.toolCall.name === "get_live_quote" && /* @__PURE__ */ t(V, { params: e.toolCall.arguments }),
|
|
61
|
-
e.toolCall.name === "get_company_news" && /* @__PURE__ */ t(
|
|
65
|
+
e.toolCall.name === "get_company_news" && /* @__PURE__ */ t(M, { params: e.toolCall.arguments }),
|
|
66
|
+
e.toolCall.name === "get_company_profile" && /* @__PURE__ */ t(O, { ticker: (s = e.toolCall.arguments) == null ? void 0 : s.ticker }),
|
|
67
|
+
e.toolCall.name === "get_counterparty_graph" && /* @__PURE__ */ t(U, { params: e.toolCall.arguments }),
|
|
68
|
+
e.toolCall.name === "get_divergence_metrics" && /* @__PURE__ */ t(q, { params: e.toolCall.arguments }),
|
|
69
|
+
e.toolCall.name === "get_architecture_reference" && /* @__PURE__ */ t(L, {})
|
|
62
70
|
] })
|
|
63
71
|
] });
|
|
64
|
-
},
|
|
72
|
+
}, J = {
|
|
65
73
|
idle: { dot: "bg-emerald-500", label: "Ready" },
|
|
66
74
|
streaming: { dot: "bg-amber-500 animate-pulse", label: "Generating…" },
|
|
67
75
|
error: { dot: "bg-red-500", label: "Error" }
|
|
68
|
-
},
|
|
69
|
-
const { dot:
|
|
76
|
+
}, K = ({ status: e, provider: l, model: o }) => {
|
|
77
|
+
const { dot: a, label: n } = J[e];
|
|
70
78
|
return /* @__PURE__ */ c("div", { className: "shrink-0 flex items-center justify-between px-3 py-1.5 border-b border-border/50 bg-muted/20", children: [
|
|
71
79
|
/* @__PURE__ */ c("div", { className: "flex items-center gap-2", children: [
|
|
72
|
-
/* @__PURE__ */ t("span", { className: `w-2 h-2 rounded-full ${
|
|
80
|
+
/* @__PURE__ */ t("span", { className: `w-2 h-2 rounded-full ${a}` }),
|
|
73
81
|
/* @__PURE__ */ t("span", { className: "text-[10px] font-semibold uppercase tracking-widest opacity-60", children: n })
|
|
74
82
|
] }),
|
|
75
|
-
(l ||
|
|
83
|
+
(l || o) && /* @__PURE__ */ t("span", { className: "text-[10px] font-mono opacity-50 truncate max-w-[200px]", children: [l, o].filter(Boolean).join(" · ") })
|
|
76
84
|
] });
|
|
77
|
-
},
|
|
85
|
+
}, me = ({
|
|
78
86
|
messages: e,
|
|
79
87
|
isStreaming: l,
|
|
80
|
-
onSubmit:
|
|
81
|
-
error:
|
|
88
|
+
onSubmit: o,
|
|
89
|
+
error: a = null,
|
|
82
90
|
activeProvider: n,
|
|
83
|
-
activeModel:
|
|
84
|
-
connectionStatus:
|
|
85
|
-
renderMessage:
|
|
86
|
-
placeholder:
|
|
87
|
-
className:
|
|
88
|
-
suggestions:
|
|
91
|
+
activeModel: i,
|
|
92
|
+
connectionStatus: d,
|
|
93
|
+
renderMessage: u,
|
|
94
|
+
placeholder: f = "Ask AI…",
|
|
95
|
+
className: h,
|
|
96
|
+
suggestions: s,
|
|
89
97
|
onSuggestionClick: k
|
|
90
98
|
}) => {
|
|
91
|
-
const
|
|
92
|
-
|
|
99
|
+
const _ = d ?? (a ? "error" : l ? "streaming" : "idle"), [b, y] = B(""), v = R(null);
|
|
100
|
+
D(() => {
|
|
93
101
|
var r;
|
|
94
|
-
(r =
|
|
102
|
+
(r = v.current) == null || r.scrollIntoView({ behavior: "smooth", block: "end" });
|
|
95
103
|
}, [e.length, l]);
|
|
96
|
-
const
|
|
97
|
-
(r) =>
|
|
104
|
+
const I = N(
|
|
105
|
+
(r) => y(r.target.value),
|
|
98
106
|
[]
|
|
99
|
-
), A =
|
|
107
|
+
), A = N(
|
|
100
108
|
(r) => {
|
|
101
109
|
r.preventDefault();
|
|
102
|
-
const
|
|
103
|
-
!
|
|
110
|
+
const m = b.trim();
|
|
111
|
+
!m || l || (o(m), y(""));
|
|
104
112
|
},
|
|
105
|
-
[b, l,
|
|
113
|
+
[b, l, o]
|
|
106
114
|
), j = e.reduce(
|
|
107
|
-
(r,
|
|
115
|
+
(r, m, x) => m.role === "assistant" ? x : r,
|
|
108
116
|
-1
|
|
109
117
|
), g = e.filter((r) => r.role !== "system");
|
|
110
118
|
return /* @__PURE__ */ c(
|
|
111
119
|
"div",
|
|
112
120
|
{
|
|
113
|
-
className:
|
|
121
|
+
className: p(
|
|
114
122
|
"flex flex-col h-full bg-background text-foreground overflow-hidden",
|
|
115
|
-
|
|
123
|
+
h
|
|
116
124
|
),
|
|
117
125
|
children: [
|
|
118
|
-
(n ||
|
|
119
|
-
|
|
126
|
+
(n || i || l || a) && /* @__PURE__ */ t(
|
|
127
|
+
K,
|
|
120
128
|
{
|
|
121
|
-
status:
|
|
129
|
+
status: _,
|
|
122
130
|
provider: n,
|
|
123
|
-
model:
|
|
131
|
+
model: i
|
|
124
132
|
}
|
|
125
133
|
),
|
|
126
134
|
/* @__PURE__ */ c("div", { className: "flex-1 overflow-y-auto px-4 py-4 scroll-smooth [scrollbar-width:thin] [scrollbar-color:hsl(var(--border))_transparent]", children: [
|
|
127
135
|
g.length === 0 && /* @__PURE__ */ c("div", { className: "flex flex-col items-center justify-center h-full gap-2 text-muted-foreground/50 select-none", children: [
|
|
128
|
-
/* @__PURE__ */ t(
|
|
136
|
+
/* @__PURE__ */ t(C, { name: "sparkles", size: 28 }),
|
|
129
137
|
/* @__PURE__ */ t("p", { className: "text-sm", children: "Start a conversation" }),
|
|
130
|
-
|
|
138
|
+
s && s.length > 0 && /* @__PURE__ */ t("div", { className: "mt-2 select-auto", children: /* @__PURE__ */ t(z, { children: s.map((r) => /* @__PURE__ */ t(E, { onClick: () => (k ?? o)(r), children: r }, r)) }) })
|
|
131
139
|
] }),
|
|
132
|
-
g.map((r,
|
|
140
|
+
g.map((r, m) => {
|
|
133
141
|
const x = e.indexOf(r);
|
|
134
142
|
return /* @__PURE__ */ t(
|
|
135
|
-
|
|
143
|
+
H,
|
|
136
144
|
{
|
|
137
145
|
message: r,
|
|
138
146
|
isLastAssistant: x === j,
|
|
139
147
|
isStreaming: l,
|
|
140
|
-
renderContent:
|
|
148
|
+
renderContent: u ? (T) => u(T, r.role) : void 0
|
|
141
149
|
},
|
|
142
|
-
|
|
150
|
+
m
|
|
143
151
|
);
|
|
144
152
|
}),
|
|
145
|
-
/* @__PURE__ */ t("div", { ref:
|
|
153
|
+
/* @__PURE__ */ t("div", { ref: v })
|
|
146
154
|
] }),
|
|
147
|
-
|
|
148
|
-
/* @__PURE__ */ t(
|
|
149
|
-
/* @__PURE__ */ t("span", { className: "leading-snug", children:
|
|
155
|
+
a && /* @__PURE__ */ c("div", { className: "shrink-0 mx-3 mb-2 flex items-start gap-2 rounded-lg border border-destructive/40 bg-destructive/10 px-3 py-2 text-xs text-destructive", children: [
|
|
156
|
+
/* @__PURE__ */ t(C, { name: "alert-circle", size: 14, className: "mt-px shrink-0" }),
|
|
157
|
+
/* @__PURE__ */ t("span", { className: "leading-snug", children: a })
|
|
150
158
|
] }),
|
|
151
159
|
/* @__PURE__ */ t(
|
|
152
160
|
"div",
|
|
153
161
|
{
|
|
154
|
-
className:
|
|
162
|
+
className: p(
|
|
155
163
|
"shrink-0 border-t border-border/60 bg-background/80 backdrop-blur-sm transition-opacity",
|
|
156
164
|
l && "opacity-70"
|
|
157
165
|
),
|
|
158
166
|
children: /* @__PURE__ */ t(
|
|
159
|
-
|
|
167
|
+
$,
|
|
160
168
|
{
|
|
161
169
|
value: b,
|
|
162
|
-
onChange:
|
|
170
|
+
onChange: I,
|
|
163
171
|
onSubmit: A,
|
|
164
|
-
placeholder: l ? "Waiting for response…" :
|
|
172
|
+
placeholder: l ? "Waiting for response…" : f
|
|
165
173
|
}
|
|
166
174
|
)
|
|
167
175
|
}
|
|
@@ -171,5 +179,5 @@ const q = () => /* @__PURE__ */ t("div", { className: "flex items-center gap-1 p
|
|
|
171
179
|
);
|
|
172
180
|
};
|
|
173
181
|
export {
|
|
174
|
-
|
|
182
|
+
me as AIChatThread
|
|
175
183
|
};
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file ArchitectureReferenceCard.tsx
|
|
3
|
+
* @package @ramme-io/ui
|
|
4
|
+
* @description AI-generated platform architecture summary card
|
|
5
|
+
*
|
|
6
|
+
* ARCHITECTURAL ROLE:
|
|
7
|
+
* Renders a condensed summary of this platform's own data architecture
|
|
8
|
+
* (stack, table count, AI pipelines, sentinel fleet, live scale facts)
|
|
9
|
+
* inside AI chat bubbles. Fetches from the Ramme Data Factory API's
|
|
10
|
+
* /architecture/reference endpoint. Follows the same self-fetching
|
|
11
|
+
* pattern as LiveQuoteCard — takes no ticker, since it describes the
|
|
12
|
+
* system itself rather than a company. Full detail lives on the Ops
|
|
13
|
+
* console's Architecture Reference page; this card is a chat-sized digest.
|
|
14
|
+
*/
|
|
15
|
+
import React from 'react';
|
|
16
|
+
export interface ArchitectureReferenceCardProps {
|
|
17
|
+
/** Present for signature symmetry with other tool cards; the tool takes no arguments. */
|
|
18
|
+
params?: Record<string, never>;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* @wizard
|
|
22
|
+
* @name ArchitectureReferenceCard
|
|
23
|
+
* @description AI-generated card summarizing this platform's own data architecture — stack, data model, AI pipelines, and sentinel fleet
|
|
24
|
+
* @tags ai, architecture, reference, generative-ui
|
|
25
|
+
* @category ai
|
|
26
|
+
* @id architecture-reference-card
|
|
27
|
+
*/
|
|
28
|
+
export declare const ArchitectureReferenceCard: React.FC<ArchitectureReferenceCardProps>;
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { jsxs as r, jsx as e } from "react/jsx-runtime";
|
|
2
|
+
import { useState as c, useEffect as x } from "react";
|
|
3
|
+
import { Card as h, CardHeader as b, CardTitle as g, CardContent as N } from "../../layout/Card.js";
|
|
4
|
+
import { Icon as n } from "../../ui/Icon.js";
|
|
5
|
+
const o = { BASE_URL: "/", DEV: !1, MODE: "production", PROD: !0, SSR: !1 }, E = () => {
|
|
6
|
+
const [t, u] = c(null), [l, i] = c(!0), [d, m] = c(null);
|
|
7
|
+
x(() => {
|
|
8
|
+
(async () => {
|
|
9
|
+
try {
|
|
10
|
+
i(!0), m(null);
|
|
11
|
+
const s = (o == null ? void 0 : o.VITE_API_URL) ?? "http://localhost:8000", p = await fetch(`${s}/architecture/reference`);
|
|
12
|
+
if (!p.ok)
|
|
13
|
+
throw new Error("Could not load the architecture reference");
|
|
14
|
+
u(await p.json());
|
|
15
|
+
} catch (s) {
|
|
16
|
+
m(s instanceof Error ? s.message : "Failed to fetch architecture reference");
|
|
17
|
+
} finally {
|
|
18
|
+
i(!1);
|
|
19
|
+
}
|
|
20
|
+
})();
|
|
21
|
+
}, []);
|
|
22
|
+
const f = (t == null ? void 0 : t.data_model.groups.reduce((a, s) => a + s.tables.length, 0)) ?? 0;
|
|
23
|
+
return /* @__PURE__ */ r(h, { className: "w-full min-w-[280px] max-w-md shadow-lg border-primary/20", children: [
|
|
24
|
+
/* @__PURE__ */ e(b, { className: "pb-3", children: /* @__PURE__ */ r(g, { className: "text-sm font-medium text-muted-foreground flex items-center gap-2", children: [
|
|
25
|
+
/* @__PURE__ */ e(n, { name: "book-open", size: 14 }),
|
|
26
|
+
"Platform Architecture"
|
|
27
|
+
] }) }),
|
|
28
|
+
/* @__PURE__ */ r(N, { className: "pt-0", children: [
|
|
29
|
+
l && /* @__PURE__ */ e("div", { className: "flex items-center justify-center py-8", children: /* @__PURE__ */ e(n, { name: "loader", size: 24, className: "animate-spin text-muted-foreground" }) }),
|
|
30
|
+
d && /* @__PURE__ */ r("div", { className: "flex items-start gap-2 rounded-lg border border-destructive/40 bg-destructive/10 px-3 py-2 text-xs text-destructive", children: [
|
|
31
|
+
/* @__PURE__ */ e(n, { name: "alert-circle", size: 14, className: "mt-px shrink-0" }),
|
|
32
|
+
/* @__PURE__ */ e("span", { children: d })
|
|
33
|
+
] }),
|
|
34
|
+
t && !l && !d && /* @__PURE__ */ r("div", { className: "space-y-3", children: [
|
|
35
|
+
/* @__PURE__ */ r("div", { className: "grid grid-cols-3 gap-2", children: [
|
|
36
|
+
/* @__PURE__ */ r("div", { className: "rounded-md border border-border/60 bg-muted/20 p-2 text-center", children: [
|
|
37
|
+
/* @__PURE__ */ e("p", { className: "font-mono text-sm font-semibold tabular-nums", children: f }),
|
|
38
|
+
/* @__PURE__ */ e("p", { className: "text-[10px] text-muted-foreground", children: "tables" })
|
|
39
|
+
] }),
|
|
40
|
+
/* @__PURE__ */ r("div", { className: "rounded-md border border-border/60 bg-muted/20 p-2 text-center", children: [
|
|
41
|
+
/* @__PURE__ */ e("p", { className: "font-mono text-sm font-semibold tabular-nums", children: t.ai_pipelines.length }),
|
|
42
|
+
/* @__PURE__ */ e("p", { className: "text-[10px] text-muted-foreground", children: "AI pipelines" })
|
|
43
|
+
] }),
|
|
44
|
+
/* @__PURE__ */ r("div", { className: "rounded-md border border-border/60 bg-muted/20 p-2 text-center", children: [
|
|
45
|
+
/* @__PURE__ */ e("p", { className: "font-mono text-sm font-semibold tabular-nums", children: t.pm2_processes.length }),
|
|
46
|
+
/* @__PURE__ */ e("p", { className: "text-[10px] text-muted-foreground", children: "workers" })
|
|
47
|
+
] })
|
|
48
|
+
] }),
|
|
49
|
+
/* @__PURE__ */ r("div", { className: "space-y-1", children: [
|
|
50
|
+
/* @__PURE__ */ e("p", { className: "text-[10px] font-semibold uppercase tracking-wide text-muted-foreground", children: "Stack" }),
|
|
51
|
+
/* @__PURE__ */ r("p", { className: "text-xs text-foreground/90 leading-relaxed", children: [
|
|
52
|
+
t.stack.backend[0],
|
|
53
|
+
t.stack.frontend[0] ? ` · ${t.stack.frontend[0]}` : ""
|
|
54
|
+
] })
|
|
55
|
+
] }),
|
|
56
|
+
/* @__PURE__ */ r("div", { className: "space-y-1", children: [
|
|
57
|
+
/* @__PURE__ */ e("p", { className: "text-[10px] font-semibold uppercase tracking-wide text-muted-foreground", children: "AI / LLM providers" }),
|
|
58
|
+
/* @__PURE__ */ e("div", { className: "flex flex-wrap gap-1", children: t.stack.ai_llm_providers.map((a) => /* @__PURE__ */ e("span", { className: "rounded border border-border/60 bg-muted/20 px-1.5 py-0.5 font-mono text-[10px]", children: a }, a)) })
|
|
59
|
+
] }),
|
|
60
|
+
t.scale_facts.db_size_gb !== null && /* @__PURE__ */ r("p", { className: "text-[10px] text-muted-foreground pt-1 border-t border-border/60", children: [
|
|
61
|
+
t.scale_facts.db_size_gb,
|
|
62
|
+
" GB database · see Ops → Architecture Reference for full detail"
|
|
63
|
+
] })
|
|
64
|
+
] })
|
|
65
|
+
] })
|
|
66
|
+
] });
|
|
67
|
+
};
|
|
68
|
+
export {
|
|
69
|
+
E as ArchitectureReferenceCard
|
|
70
|
+
};
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file CounterpartyGraphCard.tsx
|
|
3
|
+
* @package @ramme-io/ui
|
|
4
|
+
* @description AI-generated counterparty relationship card
|
|
5
|
+
*
|
|
6
|
+
* ARCHITECTURAL ROLE:
|
|
7
|
+
* Renders Fleet-Brain-Deep's inferred counterparty graph inside AI chat
|
|
8
|
+
* bubbles. Fetches from the Ramme Data Factory API's
|
|
9
|
+
* /fleet/counterparties/{ticker} endpoint. Follows the same self-fetching
|
|
10
|
+
* pattern as LiveQuoteCard — no product-layer data plumbing required.
|
|
11
|
+
*/
|
|
12
|
+
import React from 'react';
|
|
13
|
+
interface CounterpartyGraphParams {
|
|
14
|
+
ticker: string;
|
|
15
|
+
hops?: number;
|
|
16
|
+
}
|
|
17
|
+
export interface CounterpartyGraphCardProps {
|
|
18
|
+
/** Parameters from the LLM tool call */
|
|
19
|
+
params: CounterpartyGraphParams;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* @wizard
|
|
23
|
+
* @name CounterpartyGraphCard
|
|
24
|
+
* @description AI-generated counterparty relationship card showing suppliers, customers, partners, and competitors inferred from alternative signals
|
|
25
|
+
* @tags ai, counterparty, graph, relationships, generative-ui
|
|
26
|
+
* @category ai
|
|
27
|
+
* @id counterparty-graph-card
|
|
28
|
+
*/
|
|
29
|
+
export declare const CounterpartyGraphCard: React.FC<CounterpartyGraphCardProps>;
|
|
30
|
+
export {};
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { jsxs as r, jsx as s } from "react/jsx-runtime";
|
|
2
|
+
import { useState as i, useEffect as w } from "react";
|
|
3
|
+
import { Card as N, CardHeader as b, CardTitle as C, CardContent as E } from "../../layout/Card.js";
|
|
4
|
+
import { Icon as l } from "../../ui/Icon.js";
|
|
5
|
+
const p = { BASE_URL: "/", DEV: !1, MODE: "production", PROD: !0, SSR: !1 }, k = {
|
|
6
|
+
supplies_to: "Supplies to",
|
|
7
|
+
purchases_from: "Purchases from",
|
|
8
|
+
partners_with: "Partners with",
|
|
9
|
+
competes_with: "Competes with",
|
|
10
|
+
regulated_by: "Regulated by",
|
|
11
|
+
invests_in: "Invests in",
|
|
12
|
+
acquires: "Acquires",
|
|
13
|
+
same_as: "Also known as"
|
|
14
|
+
}, L = ({ params: x }) => {
|
|
15
|
+
const { ticker: n, hops: d } = x, [a, g] = i(null), [m, u] = i(!0), [o, h] = i(null);
|
|
16
|
+
w(() => {
|
|
17
|
+
(async () => {
|
|
18
|
+
try {
|
|
19
|
+
u(!0), h(null);
|
|
20
|
+
const e = (p == null ? void 0 : p.VITE_API_URL) ?? "http://localhost:8000", f = await fetch(
|
|
21
|
+
`${e}/fleet/counterparties/${n.toUpperCase()}?hops=${d ?? 1}`
|
|
22
|
+
);
|
|
23
|
+
if (!f.ok)
|
|
24
|
+
throw new Error(`No counterparty data available for ${n.toUpperCase()}`);
|
|
25
|
+
g(await f.json());
|
|
26
|
+
} catch (e) {
|
|
27
|
+
h(e instanceof Error ? e.message : "Failed to fetch counterparty graph");
|
|
28
|
+
} finally {
|
|
29
|
+
u(!1);
|
|
30
|
+
}
|
|
31
|
+
})();
|
|
32
|
+
}, [n, d]);
|
|
33
|
+
const y = new Map(((a == null ? void 0 : a.nodes) ?? []).map((t) => [t.id, t])), c = (a == null ? void 0 : a.edges) ?? [];
|
|
34
|
+
return /* @__PURE__ */ r(N, { className: "w-full min-w-[280px] max-w-md shadow-lg border-primary/20", children: [
|
|
35
|
+
/* @__PURE__ */ s(b, { className: "pb-3", children: /* @__PURE__ */ r(C, { className: "text-sm font-medium text-muted-foreground flex items-center gap-2", children: [
|
|
36
|
+
/* @__PURE__ */ s(l, { name: "share-2", size: 14 }),
|
|
37
|
+
"Counterparty Network — ",
|
|
38
|
+
n.toUpperCase()
|
|
39
|
+
] }) }),
|
|
40
|
+
/* @__PURE__ */ r(E, { className: "pt-0", children: [
|
|
41
|
+
m && /* @__PURE__ */ s("div", { className: "flex items-center justify-center py-8", children: /* @__PURE__ */ s(l, { name: "loader", size: 24, className: "animate-spin text-muted-foreground" }) }),
|
|
42
|
+
o && /* @__PURE__ */ r("div", { className: "flex items-start gap-2 rounded-lg border border-destructive/40 bg-destructive/10 px-3 py-2 text-xs text-destructive", children: [
|
|
43
|
+
/* @__PURE__ */ s(l, { name: "alert-circle", size: 14, className: "mt-px shrink-0" }),
|
|
44
|
+
/* @__PURE__ */ s("span", { children: o })
|
|
45
|
+
] }),
|
|
46
|
+
!m && !o && c.length === 0 && /* @__PURE__ */ r("p", { className: "text-xs text-muted-foreground py-2", children: [
|
|
47
|
+
"No counterparty relationships inferred yet for ",
|
|
48
|
+
n.toUpperCase(),
|
|
49
|
+
"."
|
|
50
|
+
] }),
|
|
51
|
+
c.length > 0 && /* @__PURE__ */ s("div", { className: "space-y-1.5 max-h-72 overflow-y-auto", children: c.map((t) => {
|
|
52
|
+
const e = y.get(t.target_id);
|
|
53
|
+
return e ? /* @__PURE__ */ r(
|
|
54
|
+
"div",
|
|
55
|
+
{
|
|
56
|
+
className: "flex items-center justify-between gap-2 rounded-md border border-border/60 bg-muted/20 px-2.5 py-1.5",
|
|
57
|
+
children: [
|
|
58
|
+
/* @__PURE__ */ r("div", { className: "min-w-0", children: [
|
|
59
|
+
/* @__PURE__ */ r("span", { className: "text-xs font-semibold text-foreground truncate block", children: [
|
|
60
|
+
e.public_name ?? e.name,
|
|
61
|
+
e.ticker && e.resolution === "public" && /* @__PURE__ */ s("span", { className: "ml-1.5 font-mono text-primary", children: e.ticker.toUpperCase() })
|
|
62
|
+
] }),
|
|
63
|
+
/* @__PURE__ */ r("span", { className: "text-[10px] font-mono text-muted-foreground uppercase tracking-wide", children: [
|
|
64
|
+
k[t.edge_type] ?? t.edge_type,
|
|
65
|
+
t.hop === 2 && /* @__PURE__ */ s("span", { className: "ml-1.5 opacity-70", children: "· 2nd degree" })
|
|
66
|
+
] })
|
|
67
|
+
] }),
|
|
68
|
+
/* @__PURE__ */ r("span", { className: "text-[10px] font-mono text-muted-foreground shrink-0", children: [
|
|
69
|
+
Math.round(t.weight * 100),
|
|
70
|
+
"%"
|
|
71
|
+
] })
|
|
72
|
+
]
|
|
73
|
+
},
|
|
74
|
+
t.id
|
|
75
|
+
) : null;
|
|
76
|
+
}) })
|
|
77
|
+
] })
|
|
78
|
+
] });
|
|
79
|
+
};
|
|
80
|
+
export {
|
|
81
|
+
L as CounterpartyGraphCard
|
|
82
|
+
};
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file DivergenceMetricsCard.tsx
|
|
3
|
+
* @package @ramme-io/ui
|
|
4
|
+
* @description AI-generated operational/customer divergence card
|
|
5
|
+
*
|
|
6
|
+
* ARCHITECTURAL ROLE:
|
|
7
|
+
* Renders Fleet-Brain-Deep's divergence scoring (signed delta between
|
|
8
|
+
* expected/baseline and observed performance) inside AI chat bubbles.
|
|
9
|
+
* Fetches from the Ramme Data Factory API's /fleet/divergence/{ticker}
|
|
10
|
+
* endpoint. Follows the same self-fetching pattern as LiveQuoteCard.
|
|
11
|
+
*/
|
|
12
|
+
import React from 'react';
|
|
13
|
+
interface DivergenceMetricsParams {
|
|
14
|
+
ticker: string;
|
|
15
|
+
}
|
|
16
|
+
export interface DivergenceMetricsCardProps {
|
|
17
|
+
/** Parameters from the LLM tool call */
|
|
18
|
+
params: DivergenceMetricsParams;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* @wizard
|
|
22
|
+
* @name DivergenceMetricsCard
|
|
23
|
+
* @description AI-generated card showing operational and customer divergence scores — a signed delta between expected and observed performance
|
|
24
|
+
* @tags ai, divergence, metrics, generative-ui
|
|
25
|
+
* @category ai
|
|
26
|
+
* @id divergence-metrics-card
|
|
27
|
+
*/
|
|
28
|
+
export declare const DivergenceMetricsCard: React.FC<DivergenceMetricsCardProps>;
|
|
29
|
+
export {};
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { jsxs as s, jsx as t } from "react/jsx-runtime";
|
|
2
|
+
import { useState as c, useEffect as v } from "react";
|
|
3
|
+
import { Card as N, CardHeader as b, CardTitle as y, CardContent as C } from "../../layout/Card.js";
|
|
4
|
+
import { Icon as d } from "../../ui/Icon.js";
|
|
5
|
+
const l = { BASE_URL: "/", DEV: !1, MODE: "production", PROD: !0, SSR: !1 }, E = {
|
|
6
|
+
operations: "Operations",
|
|
7
|
+
customer: "Customer",
|
|
8
|
+
operational: "Operations",
|
|
9
|
+
ux: "Customer"
|
|
10
|
+
}, R = ({ params: x }) => {
|
|
11
|
+
const { ticker: a } = x, [g, h] = c(null), [m, p] = c(!0), [i, u] = c(null);
|
|
12
|
+
v(() => {
|
|
13
|
+
(async () => {
|
|
14
|
+
try {
|
|
15
|
+
p(!0), u(null);
|
|
16
|
+
const r = (l == null ? void 0 : l.VITE_API_URL) ?? "http://localhost:8000", o = await fetch(`${r}/fleet/divergence/${a.toUpperCase()}`);
|
|
17
|
+
if (!o.ok)
|
|
18
|
+
throw new Error(`No divergence data available for ${a.toUpperCase()}`);
|
|
19
|
+
h(await o.json());
|
|
20
|
+
} catch (r) {
|
|
21
|
+
u(r instanceof Error ? r.message : "Failed to fetch divergence metrics");
|
|
22
|
+
} finally {
|
|
23
|
+
p(!1);
|
|
24
|
+
}
|
|
25
|
+
})();
|
|
26
|
+
}, [a]);
|
|
27
|
+
const n = /* @__PURE__ */ new Map();
|
|
28
|
+
return (g ?? []).forEach((e) => {
|
|
29
|
+
n.has(e.metric) || n.set(e.metric, e);
|
|
30
|
+
}), /* @__PURE__ */ s(N, { className: "w-full min-w-[280px] max-w-md shadow-lg border-primary/20", children: [
|
|
31
|
+
/* @__PURE__ */ t(b, { className: "pb-3", children: /* @__PURE__ */ s(y, { className: "text-sm font-medium text-muted-foreground flex items-center gap-2", children: [
|
|
32
|
+
/* @__PURE__ */ t(d, { name: "activity", size: 14 }),
|
|
33
|
+
"Signal Impact — ",
|
|
34
|
+
a.toUpperCase()
|
|
35
|
+
] }) }),
|
|
36
|
+
/* @__PURE__ */ s(C, { className: "pt-0", children: [
|
|
37
|
+
m && /* @__PURE__ */ t("div", { className: "flex items-center justify-center py-8", children: /* @__PURE__ */ t(d, { name: "loader", size: 24, className: "animate-spin text-muted-foreground" }) }),
|
|
38
|
+
i && /* @__PURE__ */ s("div", { className: "flex items-start gap-2 rounded-lg border border-destructive/40 bg-destructive/10 px-3 py-2 text-xs text-destructive", children: [
|
|
39
|
+
/* @__PURE__ */ t(d, { name: "alert-circle", size: 14, className: "mt-px shrink-0" }),
|
|
40
|
+
/* @__PURE__ */ t("span", { children: i })
|
|
41
|
+
] }),
|
|
42
|
+
!m && !i && n.size === 0 && /* @__PURE__ */ s("p", { className: "text-xs text-muted-foreground py-2", children: [
|
|
43
|
+
"No divergence readings yet for ",
|
|
44
|
+
a.toUpperCase(),
|
|
45
|
+
"."
|
|
46
|
+
] }),
|
|
47
|
+
n.size > 0 && /* @__PURE__ */ t("div", { className: "space-y-2", children: Array.from(n.values()).map((e) => {
|
|
48
|
+
var f;
|
|
49
|
+
const r = e.score > 0, o = e.score === 0;
|
|
50
|
+
return /* @__PURE__ */ s("div", { className: "rounded-md border border-border/60 bg-muted/20 p-2.5 space-y-1", children: [
|
|
51
|
+
/* @__PURE__ */ s("div", { className: "flex items-center justify-between", children: [
|
|
52
|
+
/* @__PURE__ */ t("span", { className: "text-xs font-semibold uppercase tracking-wide text-foreground", children: E[e.metric] }),
|
|
53
|
+
/* @__PURE__ */ t(
|
|
54
|
+
"span",
|
|
55
|
+
{
|
|
56
|
+
className: `text-xs font-mono font-semibold ${o ? "text-muted-foreground" : r ? "text-green-500" : "text-red-500"}`,
|
|
57
|
+
children: o ? "—" : `${r ? "+" : ""}${e.score.toFixed(0)}`
|
|
58
|
+
}
|
|
59
|
+
)
|
|
60
|
+
] }),
|
|
61
|
+
((f = e.contributing_signals[0]) == null ? void 0 : f.reason) && /* @__PURE__ */ t("p", { className: "text-[10px] text-muted-foreground leading-relaxed", children: e.contributing_signals[0].reason })
|
|
62
|
+
] }, e.metric);
|
|
63
|
+
}) })
|
|
64
|
+
] })
|
|
65
|
+
] });
|
|
66
|
+
};
|
|
67
|
+
export {
|
|
68
|
+
R as DivergenceMetricsCard
|
|
69
|
+
};
|
|
@@ -1,3 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @wizard
|
|
3
|
+
* @name KeyInjectionOverlay
|
|
4
|
+
* @description Blocks the app and collects an AI provider key when the gateway reports one is missing or expired. Strategic purpose: the BYOK prompt, in one place, so a key request looks the same everywhere and never becomes an inline form somebody rebuilds per feature. Renders nothing unless status is 'BYOK_REQUIRED' or 'KEY_EXPIRED', so it can stay mounted at the shell level.
|
|
5
|
+
* @tags ai, byok, overlay, auth, gateway, key
|
|
6
|
+
* @category ai
|
|
7
|
+
* @id key-injection-overlay
|
|
8
|
+
* @param {string} status - Gateway status. The overlay shows only for 'BYOK_REQUIRED' or 'KEY_EXPIRED'.
|
|
9
|
+
* @param {function} setSessionKey - Receives the entered key when the form is submitted.
|
|
10
|
+
*/
|
|
1
11
|
export interface KeyInjectionOverlayProps {
|
|
2
12
|
status: string;
|
|
3
13
|
setSessionKey: (key: string) => void;
|