@cartanova/qgrid-cli 2.11.0 → 2.11.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.
Files changed (51) hide show
  1. package/bundle/web-dist/client/assets/index-C96h3feE.js +32 -0
  2. package/bundle/web-dist/client/assets/logs-DBM6U0QD.js +1 -0
  3. package/bundle/web-dist/client/assets/monit-BBjXa7vB.js +1 -0
  4. package/bundle/web-dist/client/assets/plus-BsQdY7PS.js +1 -0
  5. package/bundle/web-dist/client/assets/refresh-cw-D9IUmT23.js +1 -0
  6. package/bundle/web-dist/client/assets/request-model-Bpp_rkK8.js +1 -0
  7. package/bundle/web-dist/client/assets/routes-Crz_PQzi.js +5 -0
  8. package/bundle/web-dist/client/assets/{services.generated-CefiDXEv.js → services.generated-B5lc3aIC.js} +1 -1
  9. package/bundle/web-dist/client/assets/settings-Cdwm3OBB.js +1 -0
  10. package/bundle/web-dist/client/assets/show-DBUhALT1.js +2 -0
  11. package/bundle/web-dist/client/assets/tokens-CVQAVJTo.js +1 -0
  12. package/bundle/web-dist/client/assets/use-oauth-login-flow-BfxYI4Oh.js +1 -0
  13. package/bundle/web-dist/client/assets/use-update-token-mutation-qKBC2sn7.js +1 -0
  14. package/bundle/web-dist/client/assets/vendor-react-DH4kUfK2.js +9 -0
  15. package/bundle/web-dist/client/assets/vendor-tanstack-DRPs09ai.js +1 -0
  16. package/bundle/web-dist/client/index.html +4 -4
  17. package/bundle/web-dist/server/assets/{lazyRouteComponent-D8iTIHyn.js → lazyRouteComponent-AKiHfZWp.js} +2 -2
  18. package/bundle/web-dist/server/assets/logs-B7QmGJq3.js +513 -0
  19. package/bundle/web-dist/server/assets/{monit-B2hqorPe.js → monit-DFt7x3bh.js} +117 -375
  20. package/bundle/web-dist/server/assets/plus-DaYQRpBt.js +19 -0
  21. package/bundle/web-dist/server/assets/{react-dom-BIYQzBqG.js → react-dom-Cv23mm1K.js} +1 -1
  22. package/bundle/web-dist/server/assets/refresh-cw-BpXNsAy-.js +23 -0
  23. package/bundle/web-dist/server/assets/{request-model-I6OdODSH.js → request-model-eHE6YbaF.js} +6 -15
  24. package/bundle/web-dist/server/assets/{routes-B95YlUv2.js → routes-_Y-PJfgO.js} +203 -679
  25. package/bundle/web-dist/server/assets/{services.generated-DQATJ6qf.js → services.generated-CMJ8AHbO.js} +3796 -4012
  26. package/bundle/web-dist/server/assets/settings-JwJKxn2e.js +461 -0
  27. package/bundle/web-dist/server/assets/{show-Bxaj3rhH.js → show-BEv6z1v_.js} +368 -1270
  28. package/bundle/web-dist/server/assets/tokens-CNT4mI-f.js +560 -0
  29. package/bundle/web-dist/server/assets/{use-oauth-login-flow-CKDHgc3U.js → use-oauth-login-flow-jkAkT3X6.js} +16 -50
  30. package/bundle/web-dist/server/assets/{use-update-token-mutation-BEbgOzaa.js → use-update-token-mutation-Sm6kh02m.js} +1 -1
  31. package/bundle/web-dist/server/entry-server.generated.js +1130 -2626
  32. package/package.json +1 -1
  33. package/bundle/web-dist/client/assets/index-BA7uQ-6c.js +0 -31
  34. package/bundle/web-dist/client/assets/logs-C47OJGEI.js +0 -1
  35. package/bundle/web-dist/client/assets/monit-BS9no0dU.js +0 -4
  36. package/bundle/web-dist/client/assets/plus-sdACTfH0.js +0 -1
  37. package/bundle/web-dist/client/assets/refresh-cw-CY8o_1cT.js +0 -1
  38. package/bundle/web-dist/client/assets/request-model-BRtFuZvj.js +0 -1
  39. package/bundle/web-dist/client/assets/routes-kqgkUxE8.js +0 -5
  40. package/bundle/web-dist/client/assets/settings-DNDvFGSw.js +0 -1
  41. package/bundle/web-dist/client/assets/show-u8Np69q3.js +0 -2
  42. package/bundle/web-dist/client/assets/tokens-QvP410NW.js +0 -1
  43. package/bundle/web-dist/client/assets/use-oauth-login-flow-Bzdh28Ws.js +0 -1
  44. package/bundle/web-dist/client/assets/use-update-token-mutation-CfJKaxmR.js +0 -1
  45. package/bundle/web-dist/client/assets/vendor-react-CUFFrVN9.js +0 -244
  46. package/bundle/web-dist/client/assets/vendor-tanstack-Bf_jag9G.js +0 -1
  47. package/bundle/web-dist/server/assets/logs-B3OTd9hy.js +0 -825
  48. package/bundle/web-dist/server/assets/plus-DwG7h9kq.js +0 -28
  49. package/bundle/web-dist/server/assets/refresh-cw-mMBkwOq0.js +0 -44
  50. package/bundle/web-dist/server/assets/settings-C3gbGk0m.js +0 -830
  51. package/bundle/web-dist/server/assets/tokens-CZjH3cB7.js +0 -1038
@@ -1,825 +0,0 @@
1
- import { F as require_react, T as string, k as require_jsx_dev_runtime, n as QgridService, o as TokenService, r as RequestLogService, w as object } from "./services.generated-DQATJ6qf.js";
2
- import { a as Link, o as useNavigate } from "./lazyRouteComponent-D8iTIHyn.js";
3
- import { i as RequestLogOrderBy, n as Route, r as RequestLogBaseListParams } from "../entry-server.generated.js";
4
- import { i as formatUsd, r as formatRequestCost, t as cacheHitRate } from "./cost-BC9yzyA9.js";
5
- import { n as unpricedRequestTitle, t as unpricedRequestLabel } from "./total-cost-fTE9Xy82.js";
6
- import { t as lucideRefreshCw } from "./refresh-cw-mMBkwOq0.js";
7
- import { n as lucideZap, t as requestModelDisplay } from "./request-model-I6OdODSH.js";
8
- require_react();
9
- var import_jsx_dev_runtime = require_jsx_dev_runtime();
10
- var _jsxFileName$3 = "~icons/lucide/chevron-left.jsx";
11
- var lucideChevronLeft = (props) => /* @__PURE__ */ (0, import_jsx_dev_runtime.jsxDEV)("svg", {
12
- viewBox: "0 0 24 24",
13
- width: "1.2em",
14
- height: "1.2em",
15
- ...props,
16
- children: /* @__PURE__ */ (0, import_jsx_dev_runtime.jsxDEV)("path", {
17
- fill: "none",
18
- stroke: "currentColor",
19
- strokeLinecap: "round",
20
- strokeLinejoin: "round",
21
- strokeWidth: 2,
22
- d: "m15 18l-6-6l6-6"
23
- }, void 0, false, {
24
- fileName: _jsxFileName$3,
25
- lineNumber: 2,
26
- columnNumber: 101
27
- }, void 0)
28
- }, void 0, false, {
29
- fileName: _jsxFileName$3,
30
- lineNumber: 2,
31
- columnNumber: 36
32
- }, void 0);
33
- //#endregion
34
- //#region ~icons/lucide/chevron-right.jsx
35
- var _jsxFileName$2 = "~icons/lucide/chevron-right.jsx";
36
- var lucideChevronRight = (props) => /* @__PURE__ */ (0, import_jsx_dev_runtime.jsxDEV)("svg", {
37
- viewBox: "0 0 24 24",
38
- width: "1.2em",
39
- height: "1.2em",
40
- ...props,
41
- children: /* @__PURE__ */ (0, import_jsx_dev_runtime.jsxDEV)("path", {
42
- fill: "none",
43
- stroke: "currentColor",
44
- strokeLinecap: "round",
45
- strokeLinejoin: "round",
46
- strokeWidth: 2,
47
- d: "m9 18l6-6l-6-6"
48
- }, void 0, false, {
49
- fileName: _jsxFileName$2,
50
- lineNumber: 2,
51
- columnNumber: 102
52
- }, void 0)
53
- }, void 0, false, {
54
- fileName: _jsxFileName$2,
55
- lineNumber: 2,
56
- columnNumber: 37
57
- }, void 0);
58
- //#endregion
59
- //#region src/components/qgrid/RequestLogTable.tsx
60
- var _jsxFileName$1 = "/home/runner/work/qgrid/qgrid/packages/web/src/components/qgrid/RequestLogTable.tsx";
61
- var PAGE_SIZE = 50;
62
- var UNASSIGNED = "__unassigned__";
63
- function formatDateTime(value) {
64
- const d = new Date(value);
65
- return `${String(d.getMonth() + 1).padStart(2, "0")}-${String(d.getDate()).padStart(2, "0")} ${String(d.getHours()).padStart(2, "0")}:${String(d.getMinutes()).padStart(2, "0")}`;
66
- }
67
- function formatNum(n) {
68
- return n.toLocaleString();
69
- }
70
- function formatDuration(ms) {
71
- const total = Math.round(ms / 1e3);
72
- const m = Math.floor(total / 60);
73
- const s = total % 60;
74
- return m > 0 ? `${m}m ${s}s` : `${s}s`;
75
- }
76
- function RequestModel({ status, requestedModel, servedModel, imageCostMethod, fallbackCount }) {
77
- if (status === "running") return /* @__PURE__ */ (0, import_jsx_dev_runtime.jsxDEV)("span", {
78
- className: "text-[9px] px-1.5 py-0.5 rounded-full bg-blue-100 text-blue-600 font-medium whitespace-nowrap",
79
- children: "실행 중"
80
- }, void 0, false, {
81
- fileName: _jsxFileName$1,
82
- lineNumber: 56,
83
- columnNumber: 7
84
- }, this);
85
- const modelDisplay = requestModelDisplay({
86
- status,
87
- requestedModel,
88
- servedModel,
89
- imageCostMethod
90
- });
91
- const hasRequestedOnly = requestedModel !== null && servedModel === null;
92
- return /* @__PURE__ */ (0, import_jsx_dev_runtime.jsxDEV)(import_jsx_dev_runtime.Fragment, { children: [
93
- /* @__PURE__ */ (0, import_jsx_dev_runtime.jsxDEV)("span", {
94
- className: "text-xs text-sand-500",
95
- children: modelDisplay.label
96
- }, void 0, false, {
97
- fileName: _jsxFileName$1,
98
- lineNumber: 73,
99
- columnNumber: 7
100
- }, this),
101
- hasRequestedOnly && /* @__PURE__ */ (void 0)("span", {
102
- className: "ml-1 text-[9px] text-sand-400",
103
- children: "요청"
104
- }, void 0, false, {
105
- fileName: _jsxFileName$1,
106
- lineNumber: 74,
107
- columnNumber: 28
108
- }, this),
109
- (fallbackCount ?? 0) > 0 && /* @__PURE__ */ (void 0)("span", {
110
- className: "ml-1 text-[9px] text-caution-500",
111
- children: ["×", fallbackCount]
112
- }, void 0, true, {
113
- fileName: _jsxFileName$1,
114
- lineNumber: 76,
115
- columnNumber: 9
116
- }, this)
117
- ] }, void 0, true);
118
- }
119
- function formatTtft(ms) {
120
- if (ms <= 0) return "—";
121
- return ms >= 1e3 ? `${(ms / 1e3).toFixed(1)}s` : `${ms}ms`;
122
- }
123
- var COLUMNS = [
124
- {
125
- label: "ID",
126
- align: "left",
127
- width: "w-12",
128
- sortKey: "id"
129
- },
130
- {
131
- label: "Date",
132
- align: "left",
133
- width: "w-20",
134
- sortKey: "created_at"
135
- },
136
- {
137
- label: "Project",
138
- align: "left",
139
- width: "w-20"
140
- },
141
- {
142
- label: "Token",
143
- align: "left",
144
- width: "w-24"
145
- },
146
- {
147
- label: "Model",
148
- align: "left",
149
- width: "w-20"
150
- },
151
- {
152
- label: "Fmt",
153
- align: "left",
154
- width: "w-12"
155
- },
156
- {
157
- label: "TTFT",
158
- align: "right",
159
- width: "w-16",
160
- sortKey: "ttft_ms"
161
- },
162
- {
163
- label: "Duration",
164
- align: "right",
165
- width: "w-20",
166
- sortKey: "duration_ms"
167
- },
168
- {
169
- label: "In",
170
- align: "right",
171
- width: "w-16",
172
- sortKey: "input_tokens"
173
- },
174
- {
175
- label: "Out",
176
- align: "right",
177
- width: "w-20",
178
- sortKey: "output_tokens"
179
- },
180
- {
181
- label: "C.Read",
182
- align: "right",
183
- width: "w-20",
184
- sortKey: "cache_read_tokens"
185
- },
186
- {
187
- label: "C.Write",
188
- align: "right",
189
- width: "w-20",
190
- sortKey: "cache_creation_tokens"
191
- },
192
- {
193
- label: "Hit",
194
- align: "right",
195
- width: "w-14"
196
- },
197
- {
198
- label: "Tools",
199
- align: "right",
200
- width: "w-14"
201
- },
202
- {
203
- label: "$",
204
- align: "right",
205
- width: "w-20",
206
- sortKey: "cost_usd"
207
- }
208
- ];
209
- function RequestLogTable({ search, onSearchChange }) {
210
- const navigate = useNavigate();
211
- const page = search.page ?? 1;
212
- const tokenFilter = search.token ?? "";
213
- const projectFilter = search.project ?? "";
214
- const modelFilter = search.model ?? "";
215
- const { data: tokensData } = TokenService.useTokens("A");
216
- const tokenNames = (tokensData?.rows ?? []).map((t) => t.name).filter(Boolean);
217
- const { data: projectData } = QgridService.useProjectNames();
218
- const projectNames = projectData?.names ?? [];
219
- const { data: modelData } = QgridService.useModelNames();
220
- const modelNames = modelData?.names ?? [];
221
- const projectFilterParam = (() => {
222
- if (projectFilter === UNASSIGNED) return { project_name_is_null: true };
223
- if (projectFilter) return { project_name: projectFilter };
224
- return {};
225
- })();
226
- const listFilters = {};
227
- if (tokenFilter) listFilters.token_name = tokenFilter;
228
- Object.assign(listFilters, projectFilterParam);
229
- if (modelFilter) listFilters.model_name = modelFilter;
230
- const sort = search.sort ?? "id-desc";
231
- const separator = sort.lastIndexOf("-");
232
- const sortColumn = sort.slice(0, separator);
233
- const sortDirection = sort.slice(separator + 1) === "asc" ? "asc" : "desc";
234
- const { data, isLoading, isError, refresh, isRefreshing } = RequestLogService.useRequestLogs("P", {
235
- num: PAGE_SIZE,
236
- page,
237
- orderBy: sort,
238
- ...listFilters
239
- });
240
- const { data: costData, isError: isCostError, refresh: refreshCost } = QgridService.useTotalCost({
241
- num: 0,
242
- page: 1,
243
- ...listFilters
244
- });
245
- const rows = data?.rows ?? [];
246
- const total = data?.total ?? 0;
247
- const totalPages = Math.ceil(total / PAGE_SIZE);
248
- const updateFilter = (patch) => {
249
- onSearchChange({
250
- ...search,
251
- ...patch,
252
- page: 1
253
- });
254
- };
255
- return /* @__PURE__ */ (0, import_jsx_dev_runtime.jsxDEV)("div", {
256
- className: "panel overflow-hidden",
257
- children: [/* @__PURE__ */ (0, import_jsx_dev_runtime.jsxDEV)("div", {
258
- className: "panel-header flex items-center gap-2 px-3 py-2.5 flex-wrap sm:gap-3 sm:px-5",
259
- children: [
260
- /* @__PURE__ */ (0, import_jsx_dev_runtime.jsxDEV)("select", {
261
- value: tokenFilter,
262
- onChange: (e) => updateFilter({ token: e.target.value || void 0 }),
263
- disabled: tokenNames.length === 0,
264
- className: "border border-sand-200/80 rounded-lg px-2.5 py-1.5 text-[11px] text-sand-700 bg-sand-50/50 focus:outline-none focus:border-sienna-300 disabled:text-sand-300 disabled:cursor-not-allowed",
265
- children: [/* @__PURE__ */ (0, import_jsx_dev_runtime.jsxDEV)("option", {
266
- value: "",
267
- children: tokenNames.length > 0 ? "All Tokens" : "Tokens —"
268
- }, void 0, false, {
269
- fileName: _jsxFileName$1,
270
- lineNumber: 199,
271
- columnNumber: 11
272
- }, this), tokenNames.map((name) => /* @__PURE__ */ (0, import_jsx_dev_runtime.jsxDEV)("option", {
273
- value: name,
274
- children: name
275
- }, name, false, {
276
- fileName: _jsxFileName$1,
277
- lineNumber: 201,
278
- columnNumber: 13
279
- }, this))]
280
- }, void 0, true, {
281
- fileName: _jsxFileName$1,
282
- lineNumber: 193,
283
- columnNumber: 9
284
- }, this),
285
- /* @__PURE__ */ (0, import_jsx_dev_runtime.jsxDEV)("select", {
286
- value: projectFilter,
287
- onChange: (e) => updateFilter({ project: e.target.value || void 0 }),
288
- className: "border border-sand-200/80 rounded-lg px-2.5 py-1.5 text-[11px] text-sand-700 bg-sand-50/50 focus:outline-none focus:border-sienna-300",
289
- children: [
290
- /* @__PURE__ */ (0, import_jsx_dev_runtime.jsxDEV)("option", {
291
- value: "",
292
- children: "All Projects"
293
- }, void 0, false, {
294
- fileName: _jsxFileName$1,
295
- lineNumber: 211,
296
- columnNumber: 11
297
- }, this),
298
- /* @__PURE__ */ (0, import_jsx_dev_runtime.jsxDEV)("option", {
299
- value: UNASSIGNED,
300
- children: "(unassigned)"
301
- }, void 0, false, {
302
- fileName: _jsxFileName$1,
303
- lineNumber: 212,
304
- columnNumber: 11
305
- }, this),
306
- projectNames.map((name) => /* @__PURE__ */ (0, import_jsx_dev_runtime.jsxDEV)("option", {
307
- value: name,
308
- children: name
309
- }, name, false, {
310
- fileName: _jsxFileName$1,
311
- lineNumber: 214,
312
- columnNumber: 13
313
- }, this))
314
- ]
315
- }, void 0, true, {
316
- fileName: _jsxFileName$1,
317
- lineNumber: 206,
318
- columnNumber: 9
319
- }, this),
320
- /* @__PURE__ */ (0, import_jsx_dev_runtime.jsxDEV)("select", {
321
- value: modelFilter,
322
- onChange: (e) => updateFilter({ model: e.target.value || void 0 }),
323
- disabled: modelNames.length === 0,
324
- className: "border border-sand-200/80 rounded-lg px-2.5 py-1.5 text-[11px] text-sand-700 bg-sand-50/50 focus:outline-none focus:border-sienna-300 disabled:text-sand-300 disabled:cursor-not-allowed",
325
- children: [/* @__PURE__ */ (0, import_jsx_dev_runtime.jsxDEV)("option", {
326
- value: "",
327
- children: modelNames.length > 0 ? "All Models" : "Models —"
328
- }, void 0, false, {
329
- fileName: _jsxFileName$1,
330
- lineNumber: 225,
331
- columnNumber: 11
332
- }, this), modelNames.map((name) => /* @__PURE__ */ (0, import_jsx_dev_runtime.jsxDEV)("option", {
333
- value: name,
334
- children: name
335
- }, name, false, {
336
- fileName: _jsxFileName$1,
337
- lineNumber: 227,
338
- columnNumber: 13
339
- }, this))]
340
- }, void 0, true, {
341
- fileName: _jsxFileName$1,
342
- lineNumber: 219,
343
- columnNumber: 9
344
- }, this),
345
- /* @__PURE__ */ (0, import_jsx_dev_runtime.jsxDEV)("button", {
346
- type: "button",
347
- onClick: () => void Promise.all([refresh(), refreshCost()]),
348
- disabled: isRefreshing,
349
- "aria-label": "Reload",
350
- title: "Reload",
351
- className: "p-1 rounded text-sand-400 hover:text-sand-600 disabled:opacity-30 transition-colors",
352
- children: /* @__PURE__ */ (0, import_jsx_dev_runtime.jsxDEV)(lucideRefreshCw, { className: isRefreshing ? "size-3.5 animate-spin" : "size-3.5" }, void 0, false, {
353
- fileName: _jsxFileName$1,
354
- lineNumber: 241,
355
- columnNumber: 11
356
- }, this)
357
- }, void 0, false, {
358
- fileName: _jsxFileName$1,
359
- lineNumber: 233,
360
- columnNumber: 9
361
- }, this),
362
- /* @__PURE__ */ (0, import_jsx_dev_runtime.jsxDEV)("div", { className: "flex-1" }, void 0, false, {
363
- fileName: _jsxFileName$1,
364
- lineNumber: 243,
365
- columnNumber: 9
366
- }, this),
367
- /* @__PURE__ */ (0, import_jsx_dev_runtime.jsxDEV)("span", {
368
- className: "text-[11px] text-sand-400",
369
- children: [isError || !data ? "—" : total, " results"]
370
- }, void 0, true, {
371
- fileName: _jsxFileName$1,
372
- lineNumber: 244,
373
- columnNumber: 9
374
- }, this),
375
- isCostError ? /* @__PURE__ */ (0, import_jsx_dev_runtime.jsxDEV)("span", {
376
- role: "alert",
377
- className: "text-[11px] text-danger-500",
378
- children: "Failed to load total cost."
379
- }, void 0, false, {
380
- fileName: _jsxFileName$1,
381
- lineNumber: 246,
382
- columnNumber: 11
383
- }, this) : /* @__PURE__ */ (0, import_jsx_dev_runtime.jsxDEV)("span", {
384
- className: "text-[11px] tabular-nums font-medium text-sienna-600",
385
- children: [costData ? formatUsd(costData.usd) : "—", costData && unpricedRequestLabel(costData) ? /* @__PURE__ */ (0, import_jsx_dev_runtime.jsxDEV)("span", {
386
- className: "ml-1 font-normal text-sand-400",
387
- title: unpricedRequestTitle(costData) ?? void 0,
388
- children: unpricedRequestLabel(costData)
389
- }, void 0, false, {
390
- fileName: _jsxFileName$1,
391
- lineNumber: 253,
392
- columnNumber: 15
393
- }, this) : null]
394
- }, void 0, true, {
395
- fileName: _jsxFileName$1,
396
- lineNumber: 250,
397
- columnNumber: 11
398
- }, this)
399
- ]
400
- }, void 0, true, {
401
- fileName: _jsxFileName$1,
402
- lineNumber: 190,
403
- columnNumber: 7
404
- }, this), isError ? /* @__PURE__ */ (0, import_jsx_dev_runtime.jsxDEV)("div", {
405
- role: "alert",
406
- className: "text-danger-500 text-center py-12 text-sm",
407
- children: "Failed to load request logs."
408
- }, void 0, false, {
409
- fileName: _jsxFileName$1,
410
- lineNumber: 265,
411
- columnNumber: 9
412
- }, this) : isLoading ? /* @__PURE__ */ (0, import_jsx_dev_runtime.jsxDEV)("div", {
413
- className: "space-y-2",
414
- children: Array.from({ length: 5 }).map((_, i) => /* @__PURE__ */ (0, import_jsx_dev_runtime.jsxDEV)("div", { className: "h-8 bg-sand-100 rounded animate-pulse" }, `skel-${i}`, false, {
415
- fileName: _jsxFileName$1,
416
- lineNumber: 271,
417
- columnNumber: 13
418
- }, this))
419
- }, void 0, false, {
420
- fileName: _jsxFileName$1,
421
- lineNumber: 269,
422
- columnNumber: 9
423
- }, this) : rows.length === 0 ? /* @__PURE__ */ (0, import_jsx_dev_runtime.jsxDEV)("div", {
424
- className: "text-sand-400 text-center py-12 text-sm",
425
- children: "No requests yet."
426
- }, void 0, false, {
427
- fileName: _jsxFileName$1,
428
- lineNumber: 275,
429
- columnNumber: 9
430
- }, this) : /* @__PURE__ */ (0, import_jsx_dev_runtime.jsxDEV)(import_jsx_dev_runtime.Fragment, { children: [/* @__PURE__ */ (0, import_jsx_dev_runtime.jsxDEV)("div", {
431
- className: "overflow-x-auto px-3 py-3 sm:px-5",
432
- children: /* @__PURE__ */ (0, import_jsx_dev_runtime.jsxDEV)("table", {
433
- className: "w-full min-w-[900px] text-[13px]",
434
- children: [/* @__PURE__ */ (0, import_jsx_dev_runtime.jsxDEV)("thead", { children: /* @__PURE__ */ (0, import_jsx_dev_runtime.jsxDEV)("tr", {
435
- className: "border-b border-sand-100/60",
436
- children: [COLUMNS.map((col) => {
437
- const padX = col.label === "Duration" ? "pl-5 pr-3" : col.width ? "px-4" : "px-3";
438
- const active = col.sortKey === sortColumn;
439
- return /* @__PURE__ */ (0, import_jsx_dev_runtime.jsxDEV)("th", {
440
- className: `${col.align === "right" ? "text-right" : "text-left"} ${col.width ?? ""} ${col.width ? "whitespace-nowrap" : ""} ${padX} py-1.5 text-[10px] uppercase font-medium ${active ? "text-sienna-600" : "text-sand-400"}`,
441
- children: col.sortKey ? /* @__PURE__ */ (0, import_jsx_dev_runtime.jsxDEV)("button", {
442
- type: "button",
443
- onClick: () => updateFilter({ sort: RequestLogOrderBy.parse(`${col.sortKey}-${active && sortDirection === "desc" ? "asc" : "desc"}`) }),
444
- className: `inline-flex items-center gap-0.5 text-[10px] uppercase font-medium hover:text-sienna-500 transition-colors duration-150 ${col.align === "right" ? "justify-end w-full" : ""}`,
445
- children: [col.label, /* @__PURE__ */ (0, import_jsx_dev_runtime.jsxDEV)("span", {
446
- className: active ? "" : "text-sand-300",
447
- children: active ? sortDirection === "desc" ? "↓" : "↑" : "↕"
448
- }, void 0, false, {
449
- fileName: _jsxFileName$1,
450
- lineNumber: 316,
451
- columnNumber: 29
452
- }, this)]
453
- }, void 0, true, {
454
- fileName: _jsxFileName$1,
455
- lineNumber: 298,
456
- columnNumber: 27
457
- }, this) : col.label
458
- }, col.label, false, {
459
- fileName: _jsxFileName$1,
460
- lineNumber: 291,
461
- columnNumber: 23
462
- }, this);
463
- }), /* @__PURE__ */ (0, import_jsx_dev_runtime.jsxDEV)("th", { className: "w-8" }, void 0, false, {
464
- fileName: _jsxFileName$1,
465
- lineNumber: 326,
466
- columnNumber: 19
467
- }, this)]
468
- }, void 0, true, {
469
- fileName: _jsxFileName$1,
470
- lineNumber: 283,
471
- columnNumber: 17
472
- }, this) }, void 0, false, {
473
- fileName: _jsxFileName$1,
474
- lineNumber: 282,
475
- columnNumber: 15
476
- }, this), /* @__PURE__ */ (0, import_jsx_dev_runtime.jsxDEV)("tbody", {
477
- className: "divide-y divide-sand-100/60",
478
- children: rows.map((row) => /* @__PURE__ */ (0, import_jsx_dev_runtime.jsxDEV)("tr", {
479
- className: "transition-colors duration-150 hover:bg-sand-100/60 cursor-pointer",
480
- onClick: (e) => {
481
- if (e.metaKey || e.ctrlKey) {
482
- window.open(`/requests/show?id=${row.id}`, "_blank");
483
- return;
484
- }
485
- navigate({
486
- to: "/requests/show",
487
- search: { id: row.id }
488
- });
489
- },
490
- children: [
491
- /* @__PURE__ */ (0, import_jsx_dev_runtime.jsxDEV)("td", {
492
- className: "px-4 py-1.5 whitespace-nowrap",
493
- children: /* @__PURE__ */ (0, import_jsx_dev_runtime.jsxDEV)(Link, {
494
- to: "/requests/show",
495
- search: { id: row.id },
496
- onClick: (e) => e.stopPropagation(),
497
- className: "text-xs text-sand-500 tabular-nums hover:text-sienna-500",
498
- children: row.id
499
- }, void 0, false, {
500
- fileName: _jsxFileName$1,
501
- lineNumber: 345,
502
- columnNumber: 23
503
- }, this)
504
- }, void 0, false, {
505
- fileName: _jsxFileName$1,
506
- lineNumber: 344,
507
- columnNumber: 21
508
- }, this),
509
- /* @__PURE__ */ (0, import_jsx_dev_runtime.jsxDEV)("td", {
510
- className: "px-4 py-1.5 whitespace-nowrap",
511
- children: /* @__PURE__ */ (0, import_jsx_dev_runtime.jsxDEV)("span", {
512
- className: "text-xs text-sand-400 tabular-nums",
513
- children: formatDateTime(row.created_at)
514
- }, void 0, false, {
515
- fileName: _jsxFileName$1,
516
- lineNumber: 355,
517
- columnNumber: 23
518
- }, this)
519
- }, void 0, false, {
520
- fileName: _jsxFileName$1,
521
- lineNumber: 354,
522
- columnNumber: 21
523
- }, this),
524
- /* @__PURE__ */ (0, import_jsx_dev_runtime.jsxDEV)("td", {
525
- className: "px-4 py-1.5 whitespace-nowrap",
526
- children: /* @__PURE__ */ (0, import_jsx_dev_runtime.jsxDEV)("span", {
527
- className: "text-xs text-sand-600",
528
- children: row.project_name ?? "—"
529
- }, void 0, false, {
530
- fileName: _jsxFileName$1,
531
- lineNumber: 360,
532
- columnNumber: 23
533
- }, this)
534
- }, void 0, false, {
535
- fileName: _jsxFileName$1,
536
- lineNumber: 359,
537
- columnNumber: 21
538
- }, this),
539
- /* @__PURE__ */ (0, import_jsx_dev_runtime.jsxDEV)("td", {
540
- className: "px-4 py-1.5 whitespace-nowrap",
541
- children: /* @__PURE__ */ (0, import_jsx_dev_runtime.jsxDEV)("span", {
542
- className: "text-xs text-sand-500",
543
- children: row.token_name
544
- }, void 0, false, {
545
- fileName: _jsxFileName$1,
546
- lineNumber: 363,
547
- columnNumber: 23
548
- }, this)
549
- }, void 0, false, {
550
- fileName: _jsxFileName$1,
551
- lineNumber: 362,
552
- columnNumber: 21
553
- }, this),
554
- /* @__PURE__ */ (0, import_jsx_dev_runtime.jsxDEV)("td", {
555
- className: "px-4 py-1.5 whitespace-nowrap",
556
- children: [
557
- /* @__PURE__ */ (0, import_jsx_dev_runtime.jsxDEV)(RequestModel, {
558
- status: row.status,
559
- requestedModel: row.requested_model_name,
560
- servedModel: row.model_name,
561
- imageCostMethod: row.image_cost_method,
562
- fallbackCount: row.fallback_count
563
- }, void 0, false, {
564
- fileName: _jsxFileName$1,
565
- lineNumber: 366,
566
- columnNumber: 23
567
- }, this),
568
- row.service_tier === "fast" && /* @__PURE__ */ (void 0)("span", {
569
- title: "Fast 모드",
570
- className: "ml-1 inline-flex align-middle",
571
- children: /* @__PURE__ */ (void 0)(lucideZap, {
572
- "aria-label": "Fast 모드",
573
- className: "size-3 text-[#1877F2] [&_path]:fill-current"
574
- }, void 0, false, {
575
- fileName: _jsxFileName$1,
576
- lineNumber: 375,
577
- columnNumber: 27
578
- }, this)
579
- }, void 0, false, {
580
- fileName: _jsxFileName$1,
581
- lineNumber: 374,
582
- columnNumber: 25
583
- }, this),
584
- row.response_json_ok === false && /* @__PURE__ */ (void 0)("span", {
585
- title: "structured 요청의 응답이 JSON 파싱에 실패했습니다",
586
- className: "ml-1.5 rounded-full bg-caution-400/15 px-1.5 py-0.5 text-[9px] font-semibold text-caution-500",
587
- children: "broken"
588
- }, void 0, false, {
589
- fileName: _jsxFileName$1,
590
- lineNumber: 382,
591
- columnNumber: 25
592
- }, this)
593
- ]
594
- }, void 0, true, {
595
- fileName: _jsxFileName$1,
596
- lineNumber: 365,
597
- columnNumber: 21
598
- }, this),
599
- /* @__PURE__ */ (0, import_jsx_dev_runtime.jsxDEV)("td", {
600
- className: "px-4 py-1.5 whitespace-nowrap",
601
- children: row.is_image_generation ? /* @__PURE__ */ (0, import_jsx_dev_runtime.jsxDEV)("span", {
602
- className: "rounded bg-sage-100 px-1.5 py-0.5 font-mono text-[10px] text-sage-700",
603
- children: "img"
604
- }, void 0, false, {
605
- fileName: _jsxFileName$1,
606
- lineNumber: 392,
607
- columnNumber: 25
608
- }, this) : row.is_structured ? /* @__PURE__ */ (0, import_jsx_dev_runtime.jsxDEV)("span", {
609
- className: "rounded bg-sienna-100 px-1.5 py-0.5 font-mono text-[10px] text-sienna-700",
610
- children: "json"
611
- }, void 0, false, {
612
- fileName: _jsxFileName$1,
613
- lineNumber: 396,
614
- columnNumber: 25
615
- }, this) : /* @__PURE__ */ (0, import_jsx_dev_runtime.jsxDEV)("span", {
616
- className: "font-mono text-[10px] text-sand-400",
617
- children: "text"
618
- }, void 0, false, {
619
- fileName: _jsxFileName$1,
620
- lineNumber: 400,
621
- columnNumber: 25
622
- }, this)
623
- }, void 0, false, {
624
- fileName: _jsxFileName$1,
625
- lineNumber: 390,
626
- columnNumber: 21
627
- }, this),
628
- /* @__PURE__ */ (0, import_jsx_dev_runtime.jsxDEV)("td", {
629
- className: "px-4 py-1.5 text-right tabular-nums text-sand-500 whitespace-nowrap",
630
- children: formatTtft(row.ttft_ms)
631
- }, void 0, false, {
632
- fileName: _jsxFileName$1,
633
- lineNumber: 403,
634
- columnNumber: 21
635
- }, this),
636
- /* @__PURE__ */ (0, import_jsx_dev_runtime.jsxDEV)("td", {
637
- className: "pl-5 pr-3 py-1.5 text-right tabular-nums text-sand-500 whitespace-nowrap",
638
- children: formatDuration(row.duration_ms)
639
- }, void 0, false, {
640
- fileName: _jsxFileName$1,
641
- lineNumber: 406,
642
- columnNumber: 21
643
- }, this),
644
- /* @__PURE__ */ (0, import_jsx_dev_runtime.jsxDEV)("td", {
645
- className: "px-3 py-1.5 text-right tabular-nums text-sand-700",
646
- children: formatNum(row.input_tokens)
647
- }, void 0, false, {
648
- fileName: _jsxFileName$1,
649
- lineNumber: 409,
650
- columnNumber: 21
651
- }, this),
652
- /* @__PURE__ */ (0, import_jsx_dev_runtime.jsxDEV)("td", {
653
- className: "px-3 py-1.5 text-right tabular-nums text-sand-700",
654
- children: formatNum(row.output_tokens)
655
- }, void 0, false, {
656
- fileName: _jsxFileName$1,
657
- lineNumber: 412,
658
- columnNumber: 21
659
- }, this),
660
- /* @__PURE__ */ (0, import_jsx_dev_runtime.jsxDEV)("td", {
661
- className: "px-3 py-1.5 text-right tabular-nums text-sand-700",
662
- children: formatNum(row.cache_read_tokens)
663
- }, void 0, false, {
664
- fileName: _jsxFileName$1,
665
- lineNumber: 415,
666
- columnNumber: 21
667
- }, this),
668
- /* @__PURE__ */ (0, import_jsx_dev_runtime.jsxDEV)("td", {
669
- className: "px-3 py-1.5 text-right tabular-nums text-sand-700",
670
- children: formatNum(row.cache_creation_tokens)
671
- }, void 0, false, {
672
- fileName: _jsxFileName$1,
673
- lineNumber: 418,
674
- columnNumber: 21
675
- }, this),
676
- /* @__PURE__ */ (0, import_jsx_dev_runtime.jsxDEV)("td", {
677
- className: "px-3 py-1.5 text-right tabular-nums text-sand-700",
678
- children: cacheHitRate(row)
679
- }, void 0, false, {
680
- fileName: _jsxFileName$1,
681
- lineNumber: 421,
682
- columnNumber: 21
683
- }, this),
684
- /* @__PURE__ */ (0, import_jsx_dev_runtime.jsxDEV)("td", {
685
- className: "px-3 py-1.5 text-right tabular-nums text-sand-500",
686
- children: row.tool_call_count > 0 ? row.tool_call_count : "—"
687
- }, void 0, false, {
688
- fileName: _jsxFileName$1,
689
- lineNumber: 424,
690
- columnNumber: 21
691
- }, this),
692
- /* @__PURE__ */ (0, import_jsx_dev_runtime.jsxDEV)("td", {
693
- className: "px-3 py-1.5 text-right tabular-nums text-sand-700 whitespace-nowrap",
694
- children: formatRequestCost(row)
695
- }, void 0, false, {
696
- fileName: _jsxFileName$1,
697
- lineNumber: 427,
698
- columnNumber: 21
699
- }, this),
700
- /* @__PURE__ */ (0, import_jsx_dev_runtime.jsxDEV)("td", {
701
- className: "px-2 py-1.5",
702
- children: /* @__PURE__ */ (0, import_jsx_dev_runtime.jsxDEV)(lucideChevronRight, { className: "size-4 text-sand-400" }, void 0, false, {
703
- fileName: _jsxFileName$1,
704
- lineNumber: 431,
705
- columnNumber: 23
706
- }, this)
707
- }, void 0, false, {
708
- fileName: _jsxFileName$1,
709
- lineNumber: 430,
710
- columnNumber: 21
711
- }, this)
712
- ]
713
- }, row.id, true, {
714
- fileName: _jsxFileName$1,
715
- lineNumber: 331,
716
- columnNumber: 19
717
- }, this))
718
- }, void 0, false, {
719
- fileName: _jsxFileName$1,
720
- lineNumber: 329,
721
- columnNumber: 15
722
- }, this)]
723
- }, void 0, true, {
724
- fileName: _jsxFileName$1,
725
- lineNumber: 281,
726
- columnNumber: 13
727
- }, this)
728
- }, void 0, false, {
729
- fileName: _jsxFileName$1,
730
- lineNumber: 278,
731
- columnNumber: 11
732
- }, this), totalPages > 1 && /* @__PURE__ */ (void 0)("div", {
733
- className: "flex items-center justify-center gap-3 px-5 py-2.5 border-t border-sand-100/60",
734
- children: [
735
- /* @__PURE__ */ (void 0)("button", {
736
- type: "button",
737
- className: "p-1 rounded text-sand-400 hover:text-sand-600 disabled:opacity-30 transition-colors",
738
- disabled: page === 1,
739
- onClick: () => onSearchChange({
740
- ...search,
741
- page: page - 1
742
- }),
743
- children: /* @__PURE__ */ (void 0)(lucideChevronLeft, { className: "size-4" }, void 0, false, {
744
- fileName: _jsxFileName$1,
745
- lineNumber: 447,
746
- columnNumber: 17
747
- }, this)
748
- }, void 0, false, {
749
- fileName: _jsxFileName$1,
750
- lineNumber: 441,
751
- columnNumber: 15
752
- }, this),
753
- /* @__PURE__ */ (void 0)("span", {
754
- className: "text-[11px] text-sand-400 tabular-nums",
755
- children: [
756
- page,
757
- " / ",
758
- totalPages
759
- ]
760
- }, void 0, true, {
761
- fileName: _jsxFileName$1,
762
- lineNumber: 449,
763
- columnNumber: 15
764
- }, this),
765
- /* @__PURE__ */ (void 0)("button", {
766
- type: "button",
767
- className: "p-1 rounded text-sand-400 hover:text-sand-600 disabled:opacity-30 transition-colors",
768
- disabled: page === totalPages,
769
- onClick: () => onSearchChange({
770
- ...search,
771
- page: page + 1
772
- }),
773
- children: /* @__PURE__ */ (void 0)(lucideChevronRight, { className: "size-4" }, void 0, false, {
774
- fileName: _jsxFileName$1,
775
- lineNumber: 458,
776
- columnNumber: 17
777
- }, this)
778
- }, void 0, false, {
779
- fileName: _jsxFileName$1,
780
- lineNumber: 452,
781
- columnNumber: 15
782
- }, this)
783
- ]
784
- }, void 0, true, {
785
- fileName: _jsxFileName$1,
786
- lineNumber: 440,
787
- columnNumber: 13
788
- }, this)] }, void 0, true)]
789
- }, void 0, true, {
790
- fileName: _jsxFileName$1,
791
- lineNumber: 189,
792
- columnNumber: 5
793
- }, this);
794
- }
795
- //#endregion
796
- //#region src/routes/logs.tsx?tsr-split=component
797
- var _jsxFileName = "/home/runner/work/qgrid/qgrid/packages/web/src/routes/logs.tsx?tsr-split=component";
798
- object({
799
- token: string().optional(),
800
- project: string().optional(),
801
- model: string().optional(),
802
- sort: RequestLogOrderBy.optional(),
803
- page: RequestLogBaseListParams.shape.page.default(1)
804
- });
805
- function LogsPage() {
806
- const search = Route.useSearch();
807
- const navigate = Route.useNavigate();
808
- return /* @__PURE__ */ (0, import_jsx_dev_runtime.jsxDEV)("div", {
809
- className: "max-w-[100rem] mx-auto",
810
- children: /* @__PURE__ */ (0, import_jsx_dev_runtime.jsxDEV)(RequestLogTable, {
811
- search,
812
- onSearchChange: (next) => navigate({ search: next })
813
- }, void 0, false, {
814
- fileName: _jsxFileName,
815
- lineNumber: 19,
816
- columnNumber: 7
817
- }, this)
818
- }, void 0, false, {
819
- fileName: _jsxFileName,
820
- lineNumber: 18,
821
- columnNumber: 10
822
- }, this);
823
- }
824
- //#endregion
825
- export { LogsPage as component };