@yuulabs/ytrace-ui 0.0.2

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.
@@ -0,0 +1,12 @@
1
+ import type { Span } from "../types";
2
+ export interface ConversationFlowProps {
3
+ spans: Span[];
4
+ }
5
+ /**
6
+ * Waterfall-style conversation flow.
7
+ *
8
+ * Renders each span as an LlmCard or ToolCard depending on its name,
9
+ * ordered by start time.
10
+ */
11
+ export declare function ConversationFlow({ spans }: ConversationFlowProps): import("react/jsx-runtime").JSX.Element;
12
+ //# sourceMappingURL=ConversationFlow.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ConversationFlow.d.ts","sourceRoot":"","sources":["../../../src/components/ConversationFlow.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAa,IAAI,EAAE,MAAM,UAAU,CAAC;AAShD,MAAM,WAAW,qBAAqB;IACpC,KAAK,EAAE,IAAI,EAAE,CAAC;CACf;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,EAAE,KAAK,EAAE,EAAE,qBAAqB,2CA4ChE"}
@@ -0,0 +1,8 @@
1
+ import type { ConversationSummary } from "../types";
2
+ export interface ConversationListProps {
3
+ conversations: ConversationSummary[];
4
+ selectedId?: string;
5
+ onSelect?: (id: string) => void;
6
+ }
7
+ export declare function ConversationList({ conversations, selectedId, onSelect, }: ConversationListProps): import("react/jsx-runtime").JSX.Element;
8
+ //# sourceMappingURL=ConversationList.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ConversationList.d.ts","sourceRoot":"","sources":["../../../src/components/ConversationList.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAC;AAEpD,MAAM,WAAW,qBAAqB;IACpC,aAAa,EAAE,mBAAmB,EAAE,CAAC;IACrC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;CACjC;AAUD,wBAAgB,gBAAgB,CAAC,EAC/B,aAAa,EACb,UAAU,EACV,QAAQ,GACT,EAAE,qBAAqB,2CAmDvB"}
@@ -0,0 +1,9 @@
1
+ import type { CostEvent } from "../types";
2
+ export interface CostSummaryProps {
3
+ costs: CostEvent[];
4
+ }
5
+ /**
6
+ * Cost summary panel — groups costs by category and shows totals.
7
+ */
8
+ export declare function CostSummary({ costs }: CostSummaryProps): import("react/jsx-runtime").JSX.Element;
9
+ //# sourceMappingURL=CostSummary.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CostSummary.d.ts","sourceRoot":"","sources":["../../../src/components/CostSummary.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAE1C,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,SAAS,EAAE,CAAC;CACpB;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,EAAE,KAAK,EAAE,EAAE,gBAAgB,2CAwDtD"}
@@ -0,0 +1,8 @@
1
+ import type { CostEvent, LlmUsageEvent, Span } from "../types";
2
+ export interface LlmCardProps {
3
+ span: Span;
4
+ usage?: LlmUsageEvent;
5
+ cost?: CostEvent;
6
+ }
7
+ export declare function LlmCard({ span, usage, cost }: LlmCardProps): import("react/jsx-runtime").JSX.Element;
8
+ //# sourceMappingURL=LlmCard.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LlmCard.d.ts","sourceRoot":"","sources":["../../../src/components/LlmCard.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,aAAa,EAAE,IAAI,EAAE,MAAM,UAAU,CAAC;AAE/D,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,IAAI,CAAC;IACX,KAAK,CAAC,EAAE,aAAa,CAAC;IACtB,IAAI,CAAC,EAAE,SAAS,CAAC;CAClB;AAOD,wBAAgB,OAAO,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE,YAAY,2CA6D1D"}
@@ -0,0 +1,9 @@
1
+ import type { Span } from "../types";
2
+ export interface SpanTimelineProps {
3
+ spans: Span[];
4
+ }
5
+ /**
6
+ * Horizontal Gantt-chart style timeline of spans.
7
+ */
8
+ export declare function SpanTimeline({ spans }: SpanTimelineProps): import("react/jsx-runtime").JSX.Element | null;
9
+ //# sourceMappingURL=SpanTimeline.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SpanTimeline.d.ts","sourceRoot":"","sources":["../../../src/components/SpanTimeline.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,UAAU,CAAC;AAErC,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,IAAI,EAAE,CAAC;CACf;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,EAAE,KAAK,EAAE,EAAE,iBAAiB,kDA0DxD"}
@@ -0,0 +1,8 @@
1
+ import type { CostEvent, Span, ToolUsageEvent } from "../types";
2
+ export interface ToolCardProps {
3
+ span: Span;
4
+ usage?: ToolUsageEvent;
5
+ cost?: CostEvent;
6
+ }
7
+ export declare function ToolCard({ span, usage, cost }: ToolCardProps): import("react/jsx-runtime").JSX.Element;
8
+ //# sourceMappingURL=ToolCard.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ToolCard.d.ts","sourceRoot":"","sources":["../../../src/components/ToolCard.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAEhE,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,IAAI,CAAC;IACX,KAAK,CAAC,EAAE,cAAc,CAAC;IACvB,IAAI,CAAC,EAAE,SAAS,CAAC;CAClB;AAED,wBAAgB,QAAQ,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE,aAAa,2CAoC5D"}
@@ -0,0 +1,9 @@
1
+ import type { LlmUsageEvent } from "../types";
2
+ export interface UsageSummaryProps {
3
+ usages: LlmUsageEvent[];
4
+ }
5
+ /**
6
+ * Usage summary panel — groups token usage by model.
7
+ */
8
+ export declare function UsageSummary({ usages }: UsageSummaryProps): import("react/jsx-runtime").JSX.Element;
9
+ //# sourceMappingURL=UsageSummary.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"UsageSummary.d.ts","sourceRoot":"","sources":["../../../src/components/UsageSummary.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAE9C,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,aAAa,EAAE,CAAC;CACzB;AAkBD;;GAEG;AACH,wBAAgB,YAAY,CAAC,EAAE,MAAM,EAAE,EAAE,iBAAiB,2CAoFzD"}
@@ -0,0 +1,17 @@
1
+ export type { Conversation, ConversationSummary, CostEvent, LlmUsageEvent, Span, SpanEvent, ToolUsageEvent, } from "./types";
2
+ export { ConversationList } from "./components/ConversationList";
3
+ export type { ConversationListProps } from "./components/ConversationList";
4
+ export { ConversationFlow } from "./components/ConversationFlow";
5
+ export type { ConversationFlowProps } from "./components/ConversationFlow";
6
+ export { LlmCard } from "./components/LlmCard";
7
+ export type { LlmCardProps } from "./components/LlmCard";
8
+ export { ToolCard } from "./components/ToolCard";
9
+ export type { ToolCardProps } from "./components/ToolCard";
10
+ export { CostSummary } from "./components/CostSummary";
11
+ export type { CostSummaryProps } from "./components/CostSummary";
12
+ export { UsageSummary } from "./components/UsageSummary";
13
+ export type { UsageSummaryProps } from "./components/UsageSummary";
14
+ export { SpanTimeline } from "./components/SpanTimeline";
15
+ export type { SpanTimelineProps } from "./components/SpanTimeline";
16
+ export { extractCostEvents, extractLlmUsageEvents, extractToolUsageEvents, parseConversation, } from "./utils/parse";
17
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAOA,YAAY,EACV,YAAY,EACZ,mBAAmB,EACnB,SAAS,EACT,aAAa,EACb,IAAI,EACJ,SAAS,EACT,cAAc,GACf,MAAM,SAAS,CAAC;AAGjB,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AACjE,YAAY,EAAE,qBAAqB,EAAE,MAAM,+BAA+B,CAAC;AAE3E,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AACjE,YAAY,EAAE,qBAAqB,EAAE,MAAM,+BAA+B,CAAC;AAE3E,OAAO,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAC/C,YAAY,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAEzD,OAAO,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AACjD,YAAY,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAE3D,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AACvD,YAAY,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAEjE,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AACzD,YAAY,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAEnE,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AACzD,YAAY,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAGnE,OAAO,EACL,iBAAiB,EACjB,qBAAqB,EACrB,sBAAsB,EACtB,iBAAiB,GAClB,MAAM,eAAe,CAAC"}
@@ -0,0 +1,878 @@
1
+ import { jsxs as i, jsx as n, Fragment as w } from "react/jsx-runtime";
2
+ import { useState as L } from "react";
3
+ function F(t) {
4
+ return new Date(t / 1e6).toLocaleString();
5
+ }
6
+ function C(t) {
7
+ return `$${t.toFixed(4)}`;
8
+ }
9
+ function j({
10
+ conversations: t,
11
+ selectedId: e,
12
+ onSelect: l
13
+ }) {
14
+ const [d, o] = L(""), r = t.filter((a) => {
15
+ const p = d.toLowerCase();
16
+ return a.agent.toLowerCase().includes(p) || a.id.toLowerCase().includes(p) || (a.model ?? "").toLowerCase().includes(p);
17
+ });
18
+ return /* @__PURE__ */ i("div", { style: m.container, children: [
19
+ /* @__PURE__ */ i("div", { style: m.header, children: [
20
+ /* @__PURE__ */ n("h2", { style: m.title, children: "Conversations" }),
21
+ /* @__PURE__ */ n(
22
+ "input",
23
+ {
24
+ type: "text",
25
+ placeholder: "Search...",
26
+ value: d,
27
+ onChange: (a) => o(a.target.value),
28
+ style: m.search
29
+ }
30
+ )
31
+ ] }),
32
+ /* @__PURE__ */ i("div", { style: m.list, children: [
33
+ r.length === 0 && /* @__PURE__ */ n("div", { style: m.empty, children: "No conversations found" }),
34
+ r.map((a) => /* @__PURE__ */ i(
35
+ "div",
36
+ {
37
+ onClick: () => l == null ? void 0 : l(a.id),
38
+ style: {
39
+ ...m.item,
40
+ ...a.id === e ? m.itemSelected : {}
41
+ },
42
+ children: [
43
+ /* @__PURE__ */ i("div", { style: m.itemHeader, children: [
44
+ /* @__PURE__ */ n("span", { style: m.agent, children: a.agent }),
45
+ /* @__PURE__ */ n("span", { style: m.cost, children: C(a.total_cost) })
46
+ ] }),
47
+ /* @__PURE__ */ i("div", { style: m.itemMeta, children: [
48
+ a.model && /* @__PURE__ */ n("span", { style: m.model, children: a.model }),
49
+ /* @__PURE__ */ i("span", { style: m.spanCount, children: [
50
+ a.span_count,
51
+ " spans"
52
+ ] })
53
+ ] }),
54
+ /* @__PURE__ */ n("div", { style: m.time, children: F(a.start_time) })
55
+ ]
56
+ },
57
+ a.id
58
+ ))
59
+ ] })
60
+ ] });
61
+ }
62
+ const m = {
63
+ container: {
64
+ display: "flex",
65
+ flexDirection: "column",
66
+ height: "100%",
67
+ borderRight: "1px solid #2d333b",
68
+ background: "#161b22",
69
+ minWidth: 280
70
+ },
71
+ header: {
72
+ padding: "16px",
73
+ borderBottom: "1px solid #2d333b"
74
+ },
75
+ title: {
76
+ fontSize: 16,
77
+ fontWeight: 600,
78
+ marginBottom: 8,
79
+ color: "#e1e4e8"
80
+ },
81
+ search: {
82
+ width: "100%",
83
+ padding: "6px 10px",
84
+ borderRadius: 6,
85
+ border: "1px solid #3d444d",
86
+ background: "#0d1117",
87
+ color: "#e1e4e8",
88
+ fontSize: 13,
89
+ outline: "none"
90
+ },
91
+ list: {
92
+ flex: 1,
93
+ overflowY: "auto"
94
+ },
95
+ empty: {
96
+ padding: 16,
97
+ color: "#8b949e",
98
+ textAlign: "center",
99
+ fontSize: 13
100
+ },
101
+ item: {
102
+ padding: "10px 16px",
103
+ borderBottom: "1px solid #21262d",
104
+ cursor: "pointer",
105
+ transition: "background 0.15s"
106
+ },
107
+ itemSelected: {
108
+ background: "#1f2937",
109
+ borderLeft: "3px solid #58a6ff"
110
+ },
111
+ itemHeader: {
112
+ display: "flex",
113
+ justifyContent: "space-between",
114
+ alignItems: "center",
115
+ marginBottom: 4
116
+ },
117
+ agent: {
118
+ fontWeight: 600,
119
+ fontSize: 14,
120
+ color: "#e1e4e8"
121
+ },
122
+ cost: {
123
+ fontSize: 12,
124
+ color: "#3fb950",
125
+ fontFamily: "monospace"
126
+ },
127
+ itemMeta: {
128
+ display: "flex",
129
+ gap: 8,
130
+ marginBottom: 2
131
+ },
132
+ model: {
133
+ fontSize: 12,
134
+ color: "#8b949e",
135
+ background: "#21262d",
136
+ padding: "1px 6px",
137
+ borderRadius: 4
138
+ },
139
+ spanCount: {
140
+ fontSize: 12,
141
+ color: "#8b949e"
142
+ },
143
+ time: {
144
+ fontSize: 11,
145
+ color: "#6e7681"
146
+ }
147
+ };
148
+ function R(t) {
149
+ const e = t.attributes, l = e["yuu.cost.amount"];
150
+ return l == null ? null : {
151
+ category: e["yuu.cost.category"] ?? "llm",
152
+ currency: e["yuu.cost.currency"] ?? "USD",
153
+ amount: Number(l),
154
+ source: e["yuu.cost.source"],
155
+ pricingId: e["yuu.cost.pricing_id"],
156
+ llmProvider: e["yuu.llm.provider"],
157
+ llmModel: e["yuu.llm.model"],
158
+ llmRequestId: e["yuu.llm.request_id"],
159
+ toolName: e["yuu.tool.name"],
160
+ toolCallId: e["yuu.tool.call_id"]
161
+ };
162
+ }
163
+ function W(t) {
164
+ const e = t.attributes, l = e["yuu.llm.provider"];
165
+ return l == null ? null : {
166
+ provider: String(l),
167
+ model: String(e["yuu.llm.model"] ?? ""),
168
+ requestId: e["yuu.llm.request_id"],
169
+ inputTokens: Number(e["yuu.llm.usage.input_tokens"] ?? 0),
170
+ outputTokens: Number(e["yuu.llm.usage.output_tokens"] ?? 0),
171
+ cacheReadTokens: Number(e["yuu.llm.usage.cache_read_tokens"] ?? 0),
172
+ cacheWriteTokens: Number(e["yuu.llm.usage.cache_write_tokens"] ?? 0),
173
+ totalTokens: e["yuu.llm.usage.total_tokens"] != null ? Number(e["yuu.llm.usage.total_tokens"]) : void 0
174
+ };
175
+ }
176
+ function I(t) {
177
+ const e = t.attributes, l = e["yuu.tool.name"];
178
+ return l == null ? null : {
179
+ name: String(l),
180
+ callId: e["yuu.tool.call_id"],
181
+ unit: String(e["yuu.tool.usage.unit"] ?? ""),
182
+ quantity: Number(e["yuu.tool.usage.quantity"] ?? 0)
183
+ };
184
+ }
185
+ function v(t) {
186
+ return t.events.filter((e) => e.name === "yuu.cost").map(R).filter((e) => e !== null);
187
+ }
188
+ function k(t) {
189
+ return t.events.filter((e) => e.name === "yuu.llm.usage").map(W).filter((e) => e !== null);
190
+ }
191
+ function _(t) {
192
+ return t.events.filter((e) => e.name === "yuu.tool.usage").map(I).filter((e) => e !== null);
193
+ }
194
+ function D(t) {
195
+ const e = [], l = [], d = [];
196
+ for (const o of t)
197
+ e.push(...v(o)), l.push(...k(o)), d.push(..._(o));
198
+ return { costs: e, usages: l, toolUsages: d };
199
+ }
200
+ function $(t) {
201
+ return t >= 1e3 ? `${(t / 1e3).toFixed(1)}k` : String(t);
202
+ }
203
+ function M({ span: t, usage: e, cost: l }) {
204
+ const d = (t.end_time_unix_nano - t.start_time_unix_nano) / 1e6;
205
+ return /* @__PURE__ */ i("div", { style: u.card, children: [
206
+ /* @__PURE__ */ i("div", { style: u.header, children: [
207
+ /* @__PURE__ */ i("div", { style: u.headerLeft, children: [
208
+ /* @__PURE__ */ n("span", { style: u.icon, children: "🤖" }),
209
+ /* @__PURE__ */ n("span", { style: u.name, children: t.name })
210
+ ] }),
211
+ /* @__PURE__ */ i("div", { style: u.headerRight, children: [
212
+ l && /* @__PURE__ */ i("span", { style: u.cost, children: [
213
+ "$",
214
+ l.amount.toFixed(4)
215
+ ] }),
216
+ /* @__PURE__ */ i("span", { style: u.duration, children: [
217
+ d.toFixed(0),
218
+ "ms"
219
+ ] })
220
+ ] })
221
+ ] }),
222
+ e && /* @__PURE__ */ i("div", { style: u.body, children: [
223
+ /* @__PURE__ */ i("div", { style: u.modelLine, children: [
224
+ /* @__PURE__ */ n("span", { style: u.provider, children: e.provider }),
225
+ /* @__PURE__ */ n("span", { style: u.model, children: e.model })
226
+ ] }),
227
+ /* @__PURE__ */ i("div", { style: u.tokens, children: [
228
+ /* @__PURE__ */ n(b, { label: "in", value: e.inputTokens, color: "#58a6ff" }),
229
+ /* @__PURE__ */ n(b, { label: "out", value: e.outputTokens, color: "#d2a8ff" }),
230
+ e.cacheReadTokens > 0 && /* @__PURE__ */ n(
231
+ b,
232
+ {
233
+ label: "cache↓",
234
+ value: e.cacheReadTokens,
235
+ color: "#3fb950"
236
+ }
237
+ ),
238
+ e.cacheWriteTokens > 0 && /* @__PURE__ */ n(
239
+ b,
240
+ {
241
+ label: "cache↑",
242
+ value: e.cacheWriteTokens,
243
+ color: "#f0883e"
244
+ }
245
+ ),
246
+ e.totalTokens != null && /* @__PURE__ */ n(
247
+ b,
248
+ {
249
+ label: "total",
250
+ value: e.totalTokens,
251
+ color: "#8b949e"
252
+ }
253
+ )
254
+ ] }),
255
+ e.requestId && /* @__PURE__ */ i("div", { style: u.requestId, children: [
256
+ "req: ",
257
+ e.requestId
258
+ ] })
259
+ ] }),
260
+ t.status_code === 2 && /* @__PURE__ */ n("div", { style: u.error, children: "⚠ Error" })
261
+ ] });
262
+ }
263
+ function b({
264
+ label: t,
265
+ value: e,
266
+ color: l
267
+ }) {
268
+ return /* @__PURE__ */ i("span", { style: { ...u.badge, borderColor: l }, children: [
269
+ /* @__PURE__ */ n("span", { style: { color: "#8b949e", fontSize: 10 }, children: t }),
270
+ " ",
271
+ /* @__PURE__ */ n("span", { style: { color: l, fontWeight: 600 }, children: $(e) })
272
+ ] });
273
+ }
274
+ const u = {
275
+ card: {
276
+ background: "#161b22",
277
+ border: "1px solid #1f3a5f",
278
+ borderRadius: 8,
279
+ padding: "12px 16px",
280
+ borderLeft: "3px solid #58a6ff"
281
+ },
282
+ header: {
283
+ display: "flex",
284
+ justifyContent: "space-between",
285
+ alignItems: "center",
286
+ marginBottom: 8
287
+ },
288
+ headerLeft: {
289
+ display: "flex",
290
+ alignItems: "center",
291
+ gap: 6
292
+ },
293
+ headerRight: {
294
+ display: "flex",
295
+ alignItems: "center",
296
+ gap: 10
297
+ },
298
+ icon: {
299
+ fontSize: 16
300
+ },
301
+ name: {
302
+ fontWeight: 600,
303
+ fontSize: 14,
304
+ color: "#e1e4e8"
305
+ },
306
+ cost: {
307
+ fontSize: 13,
308
+ color: "#3fb950",
309
+ fontFamily: "monospace",
310
+ fontWeight: 600
311
+ },
312
+ duration: {
313
+ fontSize: 12,
314
+ color: "#8b949e",
315
+ fontFamily: "monospace"
316
+ },
317
+ body: {
318
+ display: "flex",
319
+ flexDirection: "column",
320
+ gap: 6
321
+ },
322
+ modelLine: {
323
+ display: "flex",
324
+ gap: 8,
325
+ alignItems: "center"
326
+ },
327
+ provider: {
328
+ fontSize: 12,
329
+ color: "#8b949e"
330
+ },
331
+ model: {
332
+ fontSize: 12,
333
+ color: "#d2a8ff",
334
+ background: "#21262d",
335
+ padding: "1px 6px",
336
+ borderRadius: 4,
337
+ fontFamily: "monospace"
338
+ },
339
+ tokens: {
340
+ display: "flex",
341
+ gap: 6,
342
+ flexWrap: "wrap"
343
+ },
344
+ badge: {
345
+ display: "inline-flex",
346
+ gap: 4,
347
+ alignItems: "center",
348
+ fontSize: 12,
349
+ fontFamily: "monospace",
350
+ padding: "2px 8px",
351
+ borderRadius: 4,
352
+ border: "1px solid",
353
+ background: "#0d1117"
354
+ },
355
+ requestId: {
356
+ fontSize: 11,
357
+ color: "#6e7681",
358
+ fontFamily: "monospace"
359
+ },
360
+ error: {
361
+ marginTop: 6,
362
+ fontSize: 12,
363
+ color: "#f85149",
364
+ fontWeight: 600
365
+ }
366
+ };
367
+ function q({ span: t, usage: e, cost: l }) {
368
+ const d = (t.end_time_unix_nano - t.start_time_unix_nano) / 1e6, o = (e == null ? void 0 : e.name) ?? t.attributes["yuu.tool.name"] ?? t.name;
369
+ return /* @__PURE__ */ i("div", { style: f.card, children: [
370
+ /* @__PURE__ */ i("div", { style: f.header, children: [
371
+ /* @__PURE__ */ i("div", { style: f.headerLeft, children: [
372
+ /* @__PURE__ */ n("span", { style: f.icon, children: "🔧" }),
373
+ /* @__PURE__ */ n("span", { style: f.name, children: o })
374
+ ] }),
375
+ /* @__PURE__ */ i("div", { style: f.headerRight, children: [
376
+ l && /* @__PURE__ */ i("span", { style: f.cost, children: [
377
+ "$",
378
+ l.amount.toFixed(4)
379
+ ] }),
380
+ /* @__PURE__ */ i("span", { style: f.duration, children: [
381
+ d.toFixed(0),
382
+ "ms"
383
+ ] })
384
+ ] })
385
+ ] }),
386
+ e && /* @__PURE__ */ n("div", { style: f.body, children: /* @__PURE__ */ i("span", { style: f.usageLine, children: [
387
+ e.quantity,
388
+ " ",
389
+ e.unit
390
+ ] }) }),
391
+ t.status_code === 2 && /* @__PURE__ */ n("div", { style: f.error, children: "⚠ Error" })
392
+ ] });
393
+ }
394
+ const f = {
395
+ card: {
396
+ background: "#161b22",
397
+ border: "1px solid #2d4a2d",
398
+ borderRadius: 8,
399
+ padding: "12px 16px",
400
+ borderLeft: "3px solid #3fb950"
401
+ },
402
+ header: {
403
+ display: "flex",
404
+ justifyContent: "space-between",
405
+ alignItems: "center"
406
+ },
407
+ headerLeft: {
408
+ display: "flex",
409
+ alignItems: "center",
410
+ gap: 6
411
+ },
412
+ headerRight: {
413
+ display: "flex",
414
+ alignItems: "center",
415
+ gap: 10
416
+ },
417
+ icon: {
418
+ fontSize: 16
419
+ },
420
+ name: {
421
+ fontWeight: 600,
422
+ fontSize: 14,
423
+ color: "#e1e4e8"
424
+ },
425
+ cost: {
426
+ fontSize: 13,
427
+ color: "#3fb950",
428
+ fontFamily: "monospace",
429
+ fontWeight: 600
430
+ },
431
+ duration: {
432
+ fontSize: 12,
433
+ color: "#8b949e",
434
+ fontFamily: "monospace"
435
+ },
436
+ body: {
437
+ marginTop: 6
438
+ },
439
+ usageLine: {
440
+ fontSize: 12,
441
+ color: "#8b949e",
442
+ fontFamily: "monospace"
443
+ },
444
+ error: {
445
+ marginTop: 6,
446
+ fontSize: 12,
447
+ color: "#f85149",
448
+ fontWeight: 600
449
+ }
450
+ };
451
+ function E({ spans: t }) {
452
+ const e = [...t].sort(
453
+ (l, d) => l.start_time_unix_nano - d.start_time_unix_nano
454
+ );
455
+ return /* @__PURE__ */ n("div", { style: g.container, children: e.map((l) => {
456
+ const d = v(l), o = l.name === "llm_gen" || l.name.startsWith("llm"), r = l.name === "tools" || l.name.startsWith("tool:");
457
+ if (o) {
458
+ const a = k(l), p = d.find((h) => h.category === "llm");
459
+ return /* @__PURE__ */ n(
460
+ M,
461
+ {
462
+ span: l,
463
+ usage: a[0],
464
+ cost: p
465
+ },
466
+ l.span_id
467
+ );
468
+ }
469
+ if (r) {
470
+ const a = _(l), p = d.find((h) => h.category === "tool");
471
+ return /* @__PURE__ */ n(
472
+ q,
473
+ {
474
+ span: l,
475
+ usage: a[0],
476
+ cost: p
477
+ },
478
+ l.span_id
479
+ );
480
+ }
481
+ return /* @__PURE__ */ n(B, { span: l, costs: d }, l.span_id);
482
+ }) });
483
+ }
484
+ function B({ span: t, costs: e }) {
485
+ const l = e.reduce((o, r) => o + r.amount, 0), d = (t.end_time_unix_nano - t.start_time_unix_nano) / 1e6;
486
+ return /* @__PURE__ */ i("div", { style: g.card, children: [
487
+ /* @__PURE__ */ i("div", { style: g.cardHeader, children: [
488
+ /* @__PURE__ */ n("span", { style: g.spanName, children: t.name }),
489
+ /* @__PURE__ */ i("span", { style: g.duration, children: [
490
+ d.toFixed(0),
491
+ "ms"
492
+ ] })
493
+ ] }),
494
+ l > 0 && /* @__PURE__ */ i("div", { style: g.costLine, children: [
495
+ "Total: $",
496
+ l.toFixed(4)
497
+ ] })
498
+ ] });
499
+ }
500
+ const g = {
501
+ container: {
502
+ display: "flex",
503
+ flexDirection: "column",
504
+ gap: 8,
505
+ padding: 16
506
+ },
507
+ card: {
508
+ background: "#161b22",
509
+ border: "1px solid #2d333b",
510
+ borderRadius: 8,
511
+ padding: "12px 16px"
512
+ },
513
+ cardHeader: {
514
+ display: "flex",
515
+ justifyContent: "space-between",
516
+ alignItems: "center"
517
+ },
518
+ spanName: {
519
+ fontWeight: 600,
520
+ fontSize: 14,
521
+ color: "#e1e4e8"
522
+ },
523
+ duration: {
524
+ fontSize: 12,
525
+ color: "#8b949e",
526
+ fontFamily: "monospace"
527
+ },
528
+ costLine: {
529
+ marginTop: 4,
530
+ fontSize: 12,
531
+ color: "#3fb950",
532
+ fontFamily: "monospace"
533
+ }
534
+ };
535
+ function H({ costs: t }) {
536
+ if (t.length === 0)
537
+ return /* @__PURE__ */ i("div", { style: c.container, children: [
538
+ /* @__PURE__ */ n("h3", { style: c.title, children: "Cost" }),
539
+ /* @__PURE__ */ n("div", { style: c.empty, children: "No cost data" })
540
+ ] });
541
+ const e = t.reduce((o, r) => o + r.amount, 0), l = /* @__PURE__ */ new Map();
542
+ for (const o of t)
543
+ l.set(o.category, (l.get(o.category) ?? 0) + o.amount);
544
+ const d = /* @__PURE__ */ new Map();
545
+ for (const o of t)
546
+ o.category === "llm" && o.llmModel && d.set(o.llmModel, (d.get(o.llmModel) ?? 0) + o.amount);
547
+ return /* @__PURE__ */ i("div", { style: c.container, children: [
548
+ /* @__PURE__ */ n("h3", { style: c.title, children: "Cost" }),
549
+ /* @__PURE__ */ i("div", { style: c.total, children: [
550
+ /* @__PURE__ */ n("span", { children: "Total" }),
551
+ /* @__PURE__ */ i("span", { style: c.amount, children: [
552
+ "$",
553
+ e.toFixed(4)
554
+ ] })
555
+ ] }),
556
+ /* @__PURE__ */ n("div", { style: c.divider }),
557
+ Array.from(l.entries()).map(([o, r]) => /* @__PURE__ */ i("div", { style: c.row, children: [
558
+ /* @__PURE__ */ n("span", { style: c.label, children: o === "llm" ? "🤖 LLM" : "🔧 Tool" }),
559
+ /* @__PURE__ */ i("span", { style: c.value, children: [
560
+ "$",
561
+ r.toFixed(4)
562
+ ] })
563
+ ] }, o)),
564
+ d.size > 0 && /* @__PURE__ */ i(w, { children: [
565
+ /* @__PURE__ */ n("div", { style: c.divider }),
566
+ /* @__PURE__ */ n("div", { style: c.sectionTitle, children: "By Model" }),
567
+ Array.from(d.entries()).map(([o, r]) => /* @__PURE__ */ i("div", { style: c.row, children: [
568
+ /* @__PURE__ */ n("span", { style: c.modelLabel, children: o }),
569
+ /* @__PURE__ */ i("span", { style: c.value, children: [
570
+ "$",
571
+ r.toFixed(4)
572
+ ] })
573
+ ] }, o))
574
+ ] })
575
+ ] });
576
+ }
577
+ const c = {
578
+ container: {
579
+ background: "#161b22",
580
+ border: "1px solid #2d333b",
581
+ borderRadius: 8,
582
+ padding: 16
583
+ },
584
+ title: {
585
+ fontSize: 14,
586
+ fontWeight: 600,
587
+ color: "#e1e4e8",
588
+ marginBottom: 12
589
+ },
590
+ empty: {
591
+ fontSize: 13,
592
+ color: "#8b949e"
593
+ },
594
+ total: {
595
+ display: "flex",
596
+ justifyContent: "space-between",
597
+ alignItems: "center",
598
+ fontSize: 14,
599
+ color: "#e1e4e8",
600
+ fontWeight: 600
601
+ },
602
+ amount: {
603
+ color: "#3fb950",
604
+ fontFamily: "monospace",
605
+ fontSize: 16
606
+ },
607
+ divider: {
608
+ height: 1,
609
+ background: "#2d333b",
610
+ margin: "10px 0"
611
+ },
612
+ row: {
613
+ display: "flex",
614
+ justifyContent: "space-between",
615
+ alignItems: "center",
616
+ padding: "3px 0"
617
+ },
618
+ label: {
619
+ fontSize: 13,
620
+ color: "#e1e4e8"
621
+ },
622
+ value: {
623
+ fontSize: 13,
624
+ color: "#3fb950",
625
+ fontFamily: "monospace"
626
+ },
627
+ sectionTitle: {
628
+ fontSize: 12,
629
+ color: "#8b949e",
630
+ fontWeight: 600,
631
+ marginBottom: 4
632
+ },
633
+ modelLabel: {
634
+ fontSize: 12,
635
+ color: "#d2a8ff",
636
+ fontFamily: "monospace"
637
+ }
638
+ };
639
+ function x(t) {
640
+ return t >= 1e6 ? `${(t / 1e6).toFixed(2)}M` : t >= 1e3 ? `${(t / 1e3).toFixed(1)}k` : String(t);
641
+ }
642
+ function A({ usages: t }) {
643
+ if (t.length === 0)
644
+ return /* @__PURE__ */ i("div", { style: s.container, children: [
645
+ /* @__PURE__ */ n("h3", { style: s.title, children: "Usage" }),
646
+ /* @__PURE__ */ n("div", { style: s.empty, children: "No usage data" })
647
+ ] });
648
+ const e = /* @__PURE__ */ new Map();
649
+ for (const o of t) {
650
+ const r = `${o.provider}/${o.model}`, a = e.get(r);
651
+ a ? (a.inputTokens += o.inputTokens, a.outputTokens += o.outputTokens, a.cacheReadTokens += o.cacheReadTokens, a.cacheWriteTokens += o.cacheWriteTokens, a.requests += 1) : e.set(r, {
652
+ model: o.model,
653
+ provider: o.provider,
654
+ inputTokens: o.inputTokens,
655
+ outputTokens: o.outputTokens,
656
+ cacheReadTokens: o.cacheReadTokens,
657
+ cacheWriteTokens: o.cacheWriteTokens,
658
+ requests: 1
659
+ });
660
+ }
661
+ const l = t.reduce((o, r) => o + r.inputTokens, 0), d = t.reduce((o, r) => o + r.outputTokens, 0);
662
+ return /* @__PURE__ */ i("div", { style: s.container, children: [
663
+ /* @__PURE__ */ n("h3", { style: s.title, children: "Usage" }),
664
+ /* @__PURE__ */ i("div", { style: s.totalRow, children: [
665
+ /* @__PURE__ */ i("div", { style: s.totalItem, children: [
666
+ /* @__PURE__ */ n("span", { style: s.totalLabel, children: "Input" }),
667
+ /* @__PURE__ */ n("span", { style: s.totalValue, children: x(l) })
668
+ ] }),
669
+ /* @__PURE__ */ i("div", { style: s.totalItem, children: [
670
+ /* @__PURE__ */ n("span", { style: s.totalLabel, children: "Output" }),
671
+ /* @__PURE__ */ n("span", { style: s.totalValue, children: x(d) })
672
+ ] }),
673
+ /* @__PURE__ */ i("div", { style: s.totalItem, children: [
674
+ /* @__PURE__ */ n("span", { style: s.totalLabel, children: "Requests" }),
675
+ /* @__PURE__ */ n("span", { style: s.totalValue, children: t.length })
676
+ ] })
677
+ ] }),
678
+ /* @__PURE__ */ n("div", { style: s.divider }),
679
+ Array.from(e.values()).map((o) => /* @__PURE__ */ i("div", { style: s.modelBlock, children: [
680
+ /* @__PURE__ */ i("div", { style: s.modelHeader, children: [
681
+ /* @__PURE__ */ n("span", { style: s.modelName, children: o.model }),
682
+ /* @__PURE__ */ n("span", { style: s.provider, children: o.provider })
683
+ ] }),
684
+ /* @__PURE__ */ i("div", { style: s.tokenRow, children: [
685
+ /* @__PURE__ */ i("span", { style: s.tokenLabel, children: [
686
+ "in: ",
687
+ /* @__PURE__ */ n("b", { children: x(o.inputTokens) })
688
+ ] }),
689
+ /* @__PURE__ */ i("span", { style: s.tokenLabel, children: [
690
+ "out: ",
691
+ /* @__PURE__ */ n("b", { children: x(o.outputTokens) })
692
+ ] }),
693
+ o.cacheReadTokens > 0 && /* @__PURE__ */ i("span", { style: s.tokenLabel, children: [
694
+ "cache↓: ",
695
+ /* @__PURE__ */ n("b", { children: x(o.cacheReadTokens) })
696
+ ] }),
697
+ /* @__PURE__ */ i("span", { style: s.tokenLabel, children: [
698
+ "×",
699
+ o.requests
700
+ ] })
701
+ ] })
702
+ ] }, `${o.provider}/${o.model}`))
703
+ ] });
704
+ }
705
+ const s = {
706
+ container: {
707
+ background: "#161b22",
708
+ border: "1px solid #2d333b",
709
+ borderRadius: 8,
710
+ padding: 16
711
+ },
712
+ title: {
713
+ fontSize: 14,
714
+ fontWeight: 600,
715
+ color: "#e1e4e8",
716
+ marginBottom: 12
717
+ },
718
+ empty: {
719
+ fontSize: 13,
720
+ color: "#8b949e"
721
+ },
722
+ totalRow: {
723
+ display: "flex",
724
+ gap: 16
725
+ },
726
+ totalItem: {
727
+ display: "flex",
728
+ flexDirection: "column",
729
+ gap: 2
730
+ },
731
+ totalLabel: {
732
+ fontSize: 11,
733
+ color: "#8b949e",
734
+ textTransform: "uppercase",
735
+ letterSpacing: "0.5px"
736
+ },
737
+ totalValue: {
738
+ fontSize: 16,
739
+ fontWeight: 600,
740
+ color: "#e1e4e8",
741
+ fontFamily: "monospace"
742
+ },
743
+ divider: {
744
+ height: 1,
745
+ background: "#2d333b",
746
+ margin: "12px 0"
747
+ },
748
+ modelBlock: {
749
+ marginBottom: 10
750
+ },
751
+ modelHeader: {
752
+ display: "flex",
753
+ gap: 8,
754
+ alignItems: "center",
755
+ marginBottom: 4
756
+ },
757
+ modelName: {
758
+ fontSize: 13,
759
+ color: "#d2a8ff",
760
+ fontFamily: "monospace",
761
+ fontWeight: 600
762
+ },
763
+ provider: {
764
+ fontSize: 11,
765
+ color: "#8b949e"
766
+ },
767
+ tokenRow: {
768
+ display: "flex",
769
+ gap: 10,
770
+ flexWrap: "wrap"
771
+ },
772
+ tokenLabel: {
773
+ fontSize: 12,
774
+ color: "#8b949e",
775
+ fontFamily: "monospace"
776
+ }
777
+ };
778
+ function V({ spans: t }) {
779
+ if (t.length === 0) return null;
780
+ const e = Math.min(...t.map((r) => r.start_time_unix_nano)), d = Math.max(...t.map((r) => r.end_time_unix_nano)) - e || 1, o = [...t].sort(
781
+ (r, a) => r.start_time_unix_nano - a.start_time_unix_nano
782
+ );
783
+ return /* @__PURE__ */ i("div", { style: y.container, children: [
784
+ /* @__PURE__ */ n("h3", { style: y.title, children: "Timeline" }),
785
+ /* @__PURE__ */ n("div", { style: y.chart, children: o.map((r) => {
786
+ const a = (r.start_time_unix_nano - e) / d * 100, p = (r.end_time_unix_nano - r.start_time_unix_nano) / d * 100, h = (r.end_time_unix_nano - r.start_time_unix_nano) / 1e6, S = r.name === "llm_gen" || r.name.startsWith("llm"), T = r.name === "tools" || r.name.startsWith("tool:"), z = S ? "#58a6ff" : T ? "#3fb950" : "#8b949e";
787
+ return /* @__PURE__ */ i("div", { style: y.row, children: [
788
+ /* @__PURE__ */ n("div", { style: y.label, title: r.name, children: r.name }),
789
+ /* @__PURE__ */ n("div", { style: y.track, children: /* @__PURE__ */ n(
790
+ "div",
791
+ {
792
+ style: {
793
+ ...y.bar,
794
+ left: `${a}%`,
795
+ width: `${Math.max(p, 0.5)}%`,
796
+ background: z
797
+ },
798
+ title: `${h.toFixed(0)}ms`
799
+ }
800
+ ) }),
801
+ /* @__PURE__ */ i("div", { style: y.duration, children: [
802
+ h.toFixed(0),
803
+ "ms"
804
+ ] })
805
+ ] }, r.span_id);
806
+ }) })
807
+ ] });
808
+ }
809
+ const y = {
810
+ container: {
811
+ background: "#161b22",
812
+ border: "1px solid #2d333b",
813
+ borderRadius: 8,
814
+ padding: 16
815
+ },
816
+ title: {
817
+ fontSize: 14,
818
+ fontWeight: 600,
819
+ color: "#e1e4e8",
820
+ marginBottom: 12
821
+ },
822
+ chart: {
823
+ display: "flex",
824
+ flexDirection: "column",
825
+ gap: 4
826
+ },
827
+ row: {
828
+ display: "flex",
829
+ alignItems: "center",
830
+ gap: 8,
831
+ height: 24
832
+ },
833
+ label: {
834
+ width: 100,
835
+ fontSize: 12,
836
+ color: "#8b949e",
837
+ overflow: "hidden",
838
+ textOverflow: "ellipsis",
839
+ whiteSpace: "nowrap",
840
+ flexShrink: 0
841
+ },
842
+ track: {
843
+ flex: 1,
844
+ position: "relative",
845
+ height: 16,
846
+ background: "#0d1117",
847
+ borderRadius: 3
848
+ },
849
+ bar: {
850
+ position: "absolute",
851
+ top: 0,
852
+ height: "100%",
853
+ borderRadius: 3,
854
+ minWidth: 2,
855
+ opacity: 0.85
856
+ },
857
+ duration: {
858
+ width: 60,
859
+ fontSize: 11,
860
+ color: "#6e7681",
861
+ fontFamily: "monospace",
862
+ textAlign: "right",
863
+ flexShrink: 0
864
+ }
865
+ };
866
+ export {
867
+ E as ConversationFlow,
868
+ j as ConversationList,
869
+ H as CostSummary,
870
+ M as LlmCard,
871
+ V as SpanTimeline,
872
+ q as ToolCard,
873
+ A as UsageSummary,
874
+ v as extractCostEvents,
875
+ k as extractLlmUsageEvents,
876
+ _ as extractToolUsageEvents,
877
+ D as parseConversation
878
+ };
@@ -0,0 +1,71 @@
1
+ /** Summary of a conversation for list views. */
2
+ export interface ConversationSummary {
3
+ id: string;
4
+ agent: string;
5
+ model?: string;
6
+ span_count: number;
7
+ total_cost: number;
8
+ start_time: number;
9
+ end_time: number;
10
+ }
11
+ /** Full conversation with all spans. */
12
+ export interface Conversation {
13
+ id: string;
14
+ agent: string;
15
+ model?: string;
16
+ tags?: string[];
17
+ spans: Span[];
18
+ total_cost?: number;
19
+ start_time: number;
20
+ end_time: number;
21
+ }
22
+ /** A single OTEL span. */
23
+ export interface Span {
24
+ trace_id: string;
25
+ span_id: string;
26
+ parent_span_id?: string | null;
27
+ name: string;
28
+ start_time_unix_nano: number;
29
+ end_time_unix_nano: number;
30
+ status_code: number;
31
+ attributes: Record<string, unknown>;
32
+ events: SpanEvent[];
33
+ }
34
+ /** A single OTEL span event. */
35
+ export interface SpanEvent {
36
+ name: string;
37
+ time_unix_nano: number;
38
+ attributes: Record<string, unknown>;
39
+ }
40
+ /** Parsed cost event from yuu.cost event attributes. */
41
+ export interface CostEvent {
42
+ category: "llm" | "tool";
43
+ currency: string;
44
+ amount: number;
45
+ source?: string;
46
+ pricingId?: string;
47
+ llmProvider?: string;
48
+ llmModel?: string;
49
+ llmRequestId?: string;
50
+ toolName?: string;
51
+ toolCallId?: string;
52
+ }
53
+ /** Parsed LLM usage event from yuu.llm.usage event attributes. */
54
+ export interface LlmUsageEvent {
55
+ provider: string;
56
+ model: string;
57
+ requestId?: string;
58
+ inputTokens: number;
59
+ outputTokens: number;
60
+ cacheReadTokens: number;
61
+ cacheWriteTokens: number;
62
+ totalTokens?: number;
63
+ }
64
+ /** Parsed tool usage event from yuu.tool.usage event attributes. */
65
+ export interface ToolUsageEvent {
66
+ name: string;
67
+ callId?: string;
68
+ unit: string;
69
+ quantity: number;
70
+ }
71
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"AAIA,gDAAgD;AAChD,MAAM,WAAW,mBAAmB;IAClC,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,wCAAwC;AACxC,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,KAAK,EAAE,IAAI,EAAE,CAAC;IACd,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,0BAA0B;AAC1B,MAAM,WAAW,IAAI;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,oBAAoB,EAAE,MAAM,CAAC;IAC7B,kBAAkB,EAAE,MAAM,CAAC;IAC3B,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACpC,MAAM,EAAE,SAAS,EAAE,CAAC;CACrB;AAED,gCAAgC;AAChC,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,cAAc,EAAE,MAAM,CAAC;IACvB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACrC;AAED,wDAAwD;AACxD,MAAM,WAAW,SAAS;IACxB,QAAQ,EAAE,KAAK,GAAG,MAAM,CAAC;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,kEAAkE;AAClE,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,eAAe,EAAE,MAAM,CAAC;IACxB,gBAAgB,EAAE,MAAM,CAAC;IACzB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,oEAAoE;AACpE,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;CAClB"}
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Attribute key extraction utilities.
3
+ *
4
+ * This is the ONLY place in the frontend that references yuu.* magic strings.
5
+ * All keys correspond to Python-side otel.py constants.
6
+ */
7
+ import type { CostEvent, LlmUsageEvent, Span, ToolUsageEvent } from "../types";
8
+ /** Extract all cost events from a span's events. */
9
+ export declare function extractCostEvents(span: Span): CostEvent[];
10
+ /** Extract all LLM usage events from a span's events. */
11
+ export declare function extractLlmUsageEvents(span: Span): LlmUsageEvent[];
12
+ /** Extract all tool usage events from a span's events. */
13
+ export declare function extractToolUsageEvents(span: Span): ToolUsageEvent[];
14
+ /** Parse all typed events from a list of spans. */
15
+ export declare function parseConversation(spans: Span[]): {
16
+ costs: CostEvent[];
17
+ usages: LlmUsageEvent[];
18
+ toolUsages: ToolUsageEvent[];
19
+ };
20
+ //# sourceMappingURL=parse.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parse.d.ts","sourceRoot":"","sources":["../../../src/utils/parse.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EACV,SAAS,EACT,aAAa,EACb,IAAI,EAEJ,cAAc,EACf,MAAM,UAAU,CAAC;AA2DlB,oDAAoD;AACpD,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,IAAI,GAAG,SAAS,EAAE,CAKzD;AAED,yDAAyD;AACzD,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,IAAI,GAAG,aAAa,EAAE,CAKjE;AAED,0DAA0D;AAC1D,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,IAAI,GAAG,cAAc,EAAE,CAKnE;AAMD,mDAAmD;AACnD,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,IAAI,EAAE,GAAG;IAChD,KAAK,EAAE,SAAS,EAAE,CAAC;IACnB,MAAM,EAAE,aAAa,EAAE,CAAC;IACxB,UAAU,EAAE,cAAc,EAAE,CAAC;CAC9B,CAYA"}
package/package.json ADDED
@@ -0,0 +1,38 @@
1
+ {
2
+ "name": "@yuulabs/ytrace-ui",
3
+ "version": "0.0.2",
4
+ "description": "React components for LLM trace visualization",
5
+ "type": "module",
6
+ "license": "MIT",
7
+ "files": [
8
+ "dist/lib"
9
+ ],
10
+ "main": "./dist/lib/index.js",
11
+ "module": "./dist/lib/index.js",
12
+ "types": "./dist/lib/index.d.ts",
13
+ "exports": {
14
+ ".": {
15
+ "import": "./dist/lib/index.js",
16
+ "types": "./dist/lib/index.d.ts"
17
+ }
18
+ },
19
+ "scripts": {
20
+ "dev": "vite",
21
+ "build:app": "vite build --config vite.config.ts",
22
+ "build:lib": "vite build --config vite.config.lib.ts && tsc --project tsconfig.lib.json --emitDeclarationOnly",
23
+ "build": "npm run build:app && npm run build:lib",
24
+ "preview": "vite preview",
25
+ "typecheck": "tsc --noEmit"
26
+ },
27
+ "dependencies": {
28
+ "react": "^19.1.0",
29
+ "react-dom": "^19.1.0"
30
+ },
31
+ "devDependencies": {
32
+ "@types/react": "^19.1.0",
33
+ "@types/react-dom": "^19.1.0",
34
+ "@vitejs/plugin-react": "^4.4.1",
35
+ "typescript": "^5.8.0",
36
+ "vite": "^6.3.0"
37
+ }
38
+ }