@cartanova/qgrid-cli 2.10.1 → 2.10.3
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.ko.md +1 -1
- package/README.md +1 -1
- package/bundle/dist/application/monit/log-buffer.js +7 -11
- package/bundle/dist/application/monit/monit.frame.js +6 -11
- package/bundle/dist/application/qgrid/oauth.js +2 -2
- package/bundle/dist/application/qgrid/qgrid-run-lifecycle.js +2 -2
- package/bundle/dist/application/qgrid/qgrid.dispatcher.js +12 -36
- package/bundle/dist/application/qgrid/qgrid.frame.js +2 -2
- package/bundle/dist/application/qgrid/qgrid.types.js +2 -1
- package/bundle/dist/application/qgrid/token-subscriber.js +4 -7
- package/bundle/dist/application/qgrid/token-window-keepalive.js +3 -2
- package/bundle/dist/application/qgrid/tool-emulation-schema.js +4 -4
- package/bundle/dist/application/qgrid/tool-emulation.js +14 -2
- package/bundle/dist/application/request-log/request-log.model.js +7 -5
- package/bundle/dist/application/setting/setting.model.js +1 -1
- package/bundle/dist/sonamu.config.js +6 -6
- package/bundle/dist/utils/providers/anthropic/anthropic-constants.js +1 -1
- package/bundle/dist/utils/providers/anthropic/anthropic-dispatcher.js +53 -84
- package/bundle/dist/utils/providers/anthropic/anthropic-thinking.js +55 -0
- package/bundle/dist/utils/providers/anthropic/claude-session.js +11 -13
- package/bundle/dist/utils/providers/common/effort.js +1 -1
- package/bundle/dist/utils/providers/common/smooth-weighted-round-robin.js +3 -3
- package/bundle/dist/utils/providers/common/thinking.js +12 -0
- package/bundle/dist/utils/providers/openai/openai-backend-protocol.js +3 -2
- package/bundle/dist/utils/providers/openai/openai-direct-client.js +6 -16
- package/bundle/dist/utils/providers/openai/openai-dispatcher.js +89 -78
- package/bundle/src/application/monit/log-buffer.test.ts +3 -4
- package/bundle/src/application/monit/log-buffer.ts +13 -27
- package/bundle/src/application/monit/monit.frame.test.ts +7 -8
- package/bundle/src/application/monit/monit.frame.ts +9 -14
- package/bundle/src/application/qgrid/oauth.ts +1 -1
- package/bundle/src/application/qgrid/qgrid-run-lifecycle.test.ts +7 -0
- package/bundle/src/application/qgrid/qgrid-run-lifecycle.ts +1 -1
- package/bundle/src/application/qgrid/qgrid.dispatcher.test.ts +62 -1
- package/bundle/src/application/qgrid/qgrid.dispatcher.ts +25 -71
- package/bundle/src/application/qgrid/qgrid.frame.ts +4 -8
- package/bundle/src/application/qgrid/qgrid.types.ts +2 -0
- package/bundle/src/application/qgrid/token-subscriber.test.ts +8 -18
- package/bundle/src/application/qgrid/token-subscriber.ts +10 -20
- package/bundle/src/application/qgrid/token-window-keepalive.test.ts +2 -2
- package/bundle/src/application/qgrid/token-window-keepalive.ts +2 -1
- package/bundle/src/application/qgrid/tool-emulation-schema.test.ts +6 -3
- package/bundle/src/application/qgrid/tool-emulation-schema.ts +3 -3
- package/bundle/src/application/qgrid/tool-emulation.test.ts +8 -1
- package/bundle/src/application/qgrid/tool-emulation.ts +29 -0
- package/bundle/src/application/request-log/request-log.model.ts +5 -5
- package/bundle/src/application/setting/setting.model.ts +1 -1
- package/bundle/src/sonamu.config.ts +5 -5
- package/bundle/src/utils/providers/anthropic/anthropic-constants.ts +3 -6
- package/bundle/src/utils/providers/anthropic/anthropic-dispatcher.test.ts +26 -0
- package/bundle/src/utils/providers/anthropic/anthropic-dispatcher.ts +70 -148
- package/bundle/src/utils/providers/anthropic/anthropic-thinking.test.ts +36 -0
- package/bundle/src/utils/providers/anthropic/anthropic-thinking.ts +84 -0
- package/bundle/src/utils/providers/anthropic/claude-session.test.ts +74 -13
- package/bundle/src/utils/providers/anthropic/claude-session.ts +11 -20
- package/bundle/src/utils/providers/common/effort.ts +1 -1
- package/bundle/src/utils/providers/common/provider-dispatcher.ts +4 -0
- package/bundle/src/utils/providers/common/smooth-weighted-round-robin.ts +4 -4
- package/bundle/src/utils/providers/common/thinking.ts +10 -0
- package/bundle/src/utils/providers/openai/openai-backend-protocol.ts +7 -3
- package/bundle/src/utils/providers/openai/openai-direct-client.test.ts +3 -3
- package/bundle/src/utils/providers/openai/openai-direct-client.ts +20 -33
- package/bundle/src/utils/providers/openai/openai-dispatcher.test.ts +97 -6
- package/bundle/src/utils/providers/openai/openai-dispatcher.ts +113 -77
- package/bundle/web-dist/client/assets/{index-Cq4_ExLO.js → index-BIC1sQxw.js} +3 -3
- package/bundle/web-dist/client/assets/logs-zvdujZWn.js +1 -0
- package/bundle/web-dist/client/assets/monit-CraVV3MQ.js +1 -0
- package/bundle/web-dist/client/assets/refresh-cw-NNcU0Cmq.js +1 -0
- package/bundle/web-dist/client/assets/{routes-CXotE1OF.js → routes-B3ZBoJ60.js} +1 -1
- package/bundle/web-dist/client/assets/{settings-CfJDz4AC.js → settings-DwbzT5jo.js} +1 -1
- package/bundle/web-dist/client/assets/{show-gBpWK4z2.js → show-ItTExdAh.js} +1 -1
- package/bundle/web-dist/client/assets/{tokens-CbFJjIyC.js → tokens-BynKx8Vn.js} +1 -1
- package/bundle/web-dist/client/assets/{use-oauth-login-flow-jJo7GV3r.js → use-oauth-login-flow-8xw6on5P.js} +1 -1
- package/bundle/web-dist/client/index.html +1 -1
- package/bundle/web-dist/server/assets/{logs-DMlOXcDS.js → logs-BSk9lOHe.js} +13 -3
- package/bundle/web-dist/server/assets/{monit-Dg1wZCdx.js → monit-D9W4ioUi.js} +2 -21
- package/bundle/web-dist/server/assets/refresh-cw-B8U9BL9-.js +23 -0
- package/bundle/web-dist/server/assets/{settings-BaIBt_Vs.js → settings-BFVuldch.js} +1 -1
- package/bundle/web-dist/server/assets/{show-CDxGr4rS.js → show-Cswh_tqs.js} +1 -1
- package/bundle/web-dist/server/assets/{tokens-DJlfeGcx.js → tokens-DiTUwUwr.js} +1 -1
- package/bundle/web-dist/server/entry-server.generated.js +6 -7
- package/package.json +1 -1
- package/skills/qgrid/SKILL.md +1 -0
- package/skills/qgrid/references/ai-sdk-provider-contract.md +2 -1
- package/skills/qgrid/references/anthropic-claude-code-runtime.md +7 -4
- package/skills/qgrid/references/decision-rationale.md +9 -0
- package/skills/qgrid/references/openai-codex-runtime.md +6 -0
- package/skills/qgrid/references/sonamu-api-web-flow.md +3 -1
- package/skills/qgrid/references/token-auth-quota-lifecycle.md +2 -0
- package/skills/qgrid/references/tool-calling-and-multiturn.md +18 -1
- package/skills/qgrid/references/verification-and-debugging.md +1 -1
- package/bundle/web-dist/client/assets/logs-kg1KOMBk.js +0 -1
- package/bundle/web-dist/client/assets/monit-DmtHTmSM.js +0 -1
- /package/bundle/web-dist/client/assets/{plus-CknMNCP5.js → plus-B62CuqT8.js} +0 -0
- /package/bundle/web-dist/client/assets/{request-model-eygfdRv7.js → request-model-D4CZPmnG.js} +0 -0
- /package/bundle/web-dist/server/assets/{plus-DVobMrag.js → plus-CmvbWuDf.js} +0 -0
- /package/bundle/web-dist/server/assets/{request-model-DXclJfdP.js → request-model-CnCeaNLE.js} +0 -0
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
<link rel="icon" type="image/svg+xml" href="/sonamu.svg" />
|
|
6
6
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
7
7
|
<title>Qgrid</title>
|
|
8
|
-
<script type="module" crossorigin src="/assets/index-
|
|
8
|
+
<script type="module" crossorigin src="/assets/index-BIC1sQxw.js"></script>
|
|
9
9
|
<link rel="modulepreload" crossorigin href="/assets/rolldown-runtime-Dw2cE7zH.js">
|
|
10
10
|
<link rel="modulepreload" crossorigin href="/assets/preload-helper-ca-nBW7U.js">
|
|
11
11
|
<link rel="modulepreload" crossorigin href="/assets/vendor-react-DH4kUfK2.js">
|
|
@@ -2,7 +2,8 @@ import { A as require_jsx_runtime, S as string, j as require_react, n as QgridSe
|
|
|
2
2
|
import { a as Link, o as useNavigate } from "./lazyRouteComponent-Bj1cPq6x.js";
|
|
3
3
|
import { i as RequestLogOrderBy, n as Route, r as RequestLogBaseListParams } from "../entry-server.generated.js";
|
|
4
4
|
import { n as formatMicroUsd, r as formatUsd, t as cacheHitRate } from "./cost-CSH_t17I.js";
|
|
5
|
-
import { t as
|
|
5
|
+
import { t as lucideRefreshCw } from "./refresh-cw-B8U9BL9-.js";
|
|
6
|
+
import { t as requestModelDisplay } from "./request-model-CnCeaNLE.js";
|
|
6
7
|
require_react();
|
|
7
8
|
var import_jsx_runtime = require_jsx_runtime();
|
|
8
9
|
var lucideChevronLeft = (props) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("svg", {
|
|
@@ -195,13 +196,13 @@ function RequestLogTable({ search, onSearchChange }) {
|
|
|
195
196
|
const separator = sort.lastIndexOf("-");
|
|
196
197
|
const sortColumn = sort.slice(0, separator);
|
|
197
198
|
const sortDirection = sort.slice(separator + 1) === "asc" ? "asc" : "desc";
|
|
198
|
-
const { data, isLoading, isError } = RequestLogService.useRequestLogs("P", {
|
|
199
|
+
const { data, isLoading, isError, refresh, isRefreshing } = RequestLogService.useRequestLogs("P", {
|
|
199
200
|
num: PAGE_SIZE,
|
|
200
201
|
page,
|
|
201
202
|
orderBy: sort,
|
|
202
203
|
...listFilters
|
|
203
204
|
});
|
|
204
|
-
const { data: costData, isError: isCostError } = QgridService.useTotalCost({
|
|
205
|
+
const { data: costData, isError: isCostError, refresh: refreshCost } = QgridService.useTotalCost({
|
|
205
206
|
num: 0,
|
|
206
207
|
page: 1,
|
|
207
208
|
...listFilters
|
|
@@ -266,6 +267,15 @@ function RequestLogTable({ search, onSearchChange }) {
|
|
|
266
267
|
children: name
|
|
267
268
|
}, name))]
|
|
268
269
|
}),
|
|
270
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", {
|
|
271
|
+
type: "button",
|
|
272
|
+
onClick: () => void Promise.all([refresh(), refreshCost()]),
|
|
273
|
+
disabled: isRefreshing,
|
|
274
|
+
"aria-label": "Reload",
|
|
275
|
+
title: "Reload",
|
|
276
|
+
className: "p-1 rounded text-sand-400 hover:text-sand-600 disabled:opacity-30 transition-colors",
|
|
277
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(lucideRefreshCw, { className: isRefreshing ? "size-3.5 animate-spin" : "size-3.5" })
|
|
278
|
+
}),
|
|
269
279
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "flex-1" }),
|
|
270
280
|
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", {
|
|
271
281
|
className: "text-[11px] text-sand-400",
|
|
@@ -2,6 +2,7 @@ import { A as require_jsx_runtime, D as useQuery, Z as __toESM, j as require_rea
|
|
|
2
2
|
import { t as require_react_dom } from "./react-dom-BjR1Iaz8.js";
|
|
3
3
|
import { a as Route, s as clsx } from "../entry-server.generated.js";
|
|
4
4
|
import { t as cacheHitRate } from "./cost-CSH_t17I.js";
|
|
5
|
+
import { t as lucideRefreshCw } from "./refresh-cw-B8U9BL9-.js";
|
|
5
6
|
//#region ../../node_modules/.pnpm/@tanstack+virtual-core@3.17.4/node_modules/@tanstack/virtual-core/dist/esm/lazy-measurements.js
|
|
6
7
|
var import_react = /* @__PURE__ */ __toESM(require_react(), 1);
|
|
7
8
|
var import_react_dom = /* @__PURE__ */ __toESM(require_react_dom(), 1);
|
|
@@ -1180,28 +1181,8 @@ function useVirtualizer(options) {
|
|
|
1180
1181
|
});
|
|
1181
1182
|
}
|
|
1182
1183
|
//#endregion
|
|
1183
|
-
//#region ~icons/lucide/refresh-cw.jsx
|
|
1184
|
-
var import_jsx_runtime = require_jsx_runtime();
|
|
1185
|
-
var lucideRefreshCw = (props) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("svg", {
|
|
1186
|
-
viewBox: "0 0 24 24",
|
|
1187
|
-
width: "1.2em",
|
|
1188
|
-
height: "1.2em",
|
|
1189
|
-
...props,
|
|
1190
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("g", {
|
|
1191
|
-
fill: "none",
|
|
1192
|
-
stroke: "currentColor",
|
|
1193
|
-
strokeLinecap: "round",
|
|
1194
|
-
strokeLinejoin: "round",
|
|
1195
|
-
strokeWidth: 2,
|
|
1196
|
-
children: [
|
|
1197
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M3 12a9 9 0 0 1 9-9a9.75 9.75 0 0 1 6.74 2.74L21 8" }),
|
|
1198
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M21 3v5h-5m5 4a9 9 0 0 1-9 9a9.75 9.75 0 0 1-6.74-2.74L3 16" }),
|
|
1199
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M8 16H3v5" })
|
|
1200
|
-
]
|
|
1201
|
-
})
|
|
1202
|
-
});
|
|
1203
|
-
//#endregion
|
|
1204
1184
|
//#region src/components/qgrid/MonitConsole.tsx
|
|
1185
|
+
var import_jsx_runtime = require_jsx_runtime();
|
|
1205
1186
|
var POLL_INTERVAL_MS = 1e3;
|
|
1206
1187
|
var STALE_AFTER_MS = 5e3;
|
|
1207
1188
|
var MIRROR_CAP = 4e3;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { A as require_jsx_runtime, j as require_react } from "./services.generated-BM4X3Ecj.js";
|
|
2
|
+
require_react();
|
|
3
|
+
var import_jsx_runtime = require_jsx_runtime();
|
|
4
|
+
var lucideRefreshCw = (props) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("svg", {
|
|
5
|
+
viewBox: "0 0 24 24",
|
|
6
|
+
width: "1.2em",
|
|
7
|
+
height: "1.2em",
|
|
8
|
+
...props,
|
|
9
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("g", {
|
|
10
|
+
fill: "none",
|
|
11
|
+
stroke: "currentColor",
|
|
12
|
+
strokeLinecap: "round",
|
|
13
|
+
strokeLinejoin: "round",
|
|
14
|
+
strokeWidth: 2,
|
|
15
|
+
children: [
|
|
16
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M3 12a9 9 0 0 1 9-9a9.75 9.75 0 0 1 6.74 2.74L21 8" }),
|
|
17
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M21 3v5h-5m5 4a9 9 0 0 1-9 9a9.75 9.75 0 0 1-6.74-2.74L3 16" }),
|
|
18
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M8 16H3v5" })
|
|
19
|
+
]
|
|
20
|
+
})
|
|
21
|
+
});
|
|
22
|
+
//#endregion
|
|
23
|
+
export { lucideRefreshCw as t };
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { A as require_jsx_runtime, D as useQuery, T as isAxiosError, Z as __toESM, a as SettingService, j as require_react, k as useQueryClient, l as isSonamuError, n as QgridService, o as TokenService } from "./services.generated-BM4X3Ecj.js";
|
|
2
2
|
import { l as lucideRotateCcw } from "../entry-server.generated.js";
|
|
3
3
|
import { t as useUpdateTokenMutation } from "./use-update-token-mutation-DqGMopII.js";
|
|
4
|
-
import { t as lucidePlus } from "./plus-
|
|
4
|
+
import { t as lucidePlus } from "./plus-CmvbWuDf.js";
|
|
5
5
|
//#region ~icons/lucide/eye.jsx
|
|
6
6
|
var import_react = /* @__PURE__ */ __toESM(require_react());
|
|
7
7
|
var import_jsx_runtime = require_jsx_runtime();
|
|
@@ -2,7 +2,7 @@ import { A as require_jsx_runtime, D as useQuery, J as __commonJSMin, Z as __toE
|
|
|
2
2
|
import { a as Link } from "./lazyRouteComponent-Bj1cPq6x.js";
|
|
3
3
|
import { c as lucideX, d as Markdown, t as Route, u as remarkGfm } from "../entry-server.generated.js";
|
|
4
4
|
import { n as formatMicroUsd, t as cacheHitRate } from "./cost-CSH_t17I.js";
|
|
5
|
-
import { t as requestModelDisplay } from "./request-model-
|
|
5
|
+
import { t as requestModelDisplay } from "./request-model-CnCeaNLE.js";
|
|
6
6
|
//#region ../../node_modules/.pnpm/@babel+runtime@7.29.2/node_modules/@babel/runtime/helpers/extends.js
|
|
7
7
|
var require_extends = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
8
8
|
function _extends() {
|
|
@@ -2,7 +2,7 @@ import { A as require_jsx_runtime, Z as __toESM, j as require_react, k as useQue
|
|
|
2
2
|
import { f as lucideKeyRound, o as Q } from "../entry-server.generated.js";
|
|
3
3
|
import { t as useUpdateTokenMutation } from "./use-update-token-mutation-DqGMopII.js";
|
|
4
4
|
import { n as OAuthCodeEntry, t as useOAuthLoginFlow } from "./use-oauth-login-flow-DYKnG4A2.js";
|
|
5
|
-
import { t as lucidePlus } from "./plus-
|
|
5
|
+
import { t as lucidePlus } from "./plus-CmvbWuDf.js";
|
|
6
6
|
//#region src/components/qgrid/AddTokenModal.tsx
|
|
7
7
|
var import_react = /* @__PURE__ */ __toESM(require_react(), 1);
|
|
8
8
|
var import_jsx_runtime = require_jsx_runtime();
|
|
@@ -46275,7 +46275,6 @@ var MODEL_PRESET_GROUPS = [{
|
|
|
46275
46275
|
"anthropic/claude-opus-4-6",
|
|
46276
46276
|
"anthropic/claude-opus-4-5",
|
|
46277
46277
|
"anthropic/claude-sonnet-4-6",
|
|
46278
|
-
"anthropic/claude-sonnet-4-5",
|
|
46279
46278
|
"anthropic/claude-haiku-4-5"
|
|
46280
46279
|
]
|
|
46281
46280
|
}];
|
|
@@ -46875,7 +46874,7 @@ function ChatWidget() {
|
|
|
46875
46874
|
}
|
|
46876
46875
|
//#endregion
|
|
46877
46876
|
//#region src/components/Sidebar.tsx
|
|
46878
|
-
var qgridVersion = "2.10.
|
|
46877
|
+
var qgridVersion = "2.10.3";
|
|
46879
46878
|
function Sidebar({ className }) {
|
|
46880
46879
|
const pathname = useRouterState({ select: (s) => s.location.pathname });
|
|
46881
46880
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("aside", {
|
|
@@ -68753,15 +68752,15 @@ function RootComponent() {
|
|
|
68753
68752
|
}
|
|
68754
68753
|
//#endregion
|
|
68755
68754
|
//#region src/routes/tokens.tsx
|
|
68756
|
-
var $$splitComponentImporter$5 = () => import("./assets/tokens-
|
|
68755
|
+
var $$splitComponentImporter$5 = () => import("./assets/tokens-DiTUwUwr.js");
|
|
68757
68756
|
var Route$5 = createFileRoute("/tokens")({ component: lazyRouteComponent($$splitComponentImporter$5, "component") });
|
|
68758
68757
|
//#endregion
|
|
68759
68758
|
//#region src/routes/settings.tsx
|
|
68760
|
-
var $$splitComponentImporter$4 = () => import("./assets/settings-
|
|
68759
|
+
var $$splitComponentImporter$4 = () => import("./assets/settings-BFVuldch.js");
|
|
68761
68760
|
var Route$4 = createFileRoute("/settings")({ component: lazyRouteComponent($$splitComponentImporter$4, "component") });
|
|
68762
68761
|
//#endregion
|
|
68763
68762
|
//#region src/routes/monit.tsx
|
|
68764
|
-
var $$splitComponentImporter$3 = () => import("./assets/monit-
|
|
68763
|
+
var $$splitComponentImporter$3 = () => import("./assets/monit-D9W4ioUi.js");
|
|
68765
68764
|
var monitSearchSchema = object({ level: _enum([
|
|
68766
68765
|
"all",
|
|
68767
68766
|
"warn",
|
|
@@ -69138,7 +69137,7 @@ object({
|
|
|
69138
69137
|
_enum(["A"]);
|
|
69139
69138
|
//#endregion
|
|
69140
69139
|
//#region src/routes/logs.tsx
|
|
69141
|
-
var $$splitComponentImporter$2 = () => import("./assets/logs-
|
|
69140
|
+
var $$splitComponentImporter$2 = () => import("./assets/logs-BSk9lOHe.js");
|
|
69142
69141
|
var logsSearchSchema = object({
|
|
69143
69142
|
token: string$2().optional(),
|
|
69144
69143
|
project: string$2().optional(),
|
|
@@ -69156,7 +69155,7 @@ var $$splitComponentImporter$1 = () => import("./assets/routes-C7lB2Q85.js");
|
|
|
69156
69155
|
var Route$1 = createFileRoute("/")({ component: lazyRouteComponent($$splitComponentImporter$1, "component") });
|
|
69157
69156
|
//#endregion
|
|
69158
69157
|
//#region src/routes/requests/show.tsx
|
|
69159
|
-
var $$splitComponentImporter = () => import("./assets/show-
|
|
69158
|
+
var $$splitComponentImporter = () => import("./assets/show-Cswh_tqs.js");
|
|
69160
69159
|
var showSearchSchema = object({ id: number$1() });
|
|
69161
69160
|
var Route = createFileRoute("/requests/show")({
|
|
69162
69161
|
validateSearch: showSearchSchema,
|
package/package.json
CHANGED
package/skills/qgrid/SKILL.md
CHANGED
|
@@ -45,6 +45,7 @@ Request logging is enabled by default. Use `providerOptions.qgrid.logger: false`
|
|
|
45
45
|
## Non-Negotiable Boundaries
|
|
46
46
|
|
|
47
47
|
- Use `packages/ai-sdk` as the active public SDK surface.
|
|
48
|
+
- Expose thinking only as `providerOptions.qgrid.thinking?: boolean`: omission preserves the model policy, false overrides effort, and unsupported/unverified off requests fail explicitly. See the SDK and provider runtime references for the dated support snapshot. Keep Anthropic thinking controls separate from mandatory configuration and memory isolation. Haiku/Sonnet 5.5 off uses a computed thinking-only native body override with Claude Code >=2.1.295; never inherit or expose arbitrary extra body.
|
|
48
49
|
- The old v1 SDK package (`packages/sdk`, `@cartanova/qgrid-sdk`) has been removed from the repository. It survives only as a deprecated npm artifact (1.9.0); do not resurrect it or write new code against it.
|
|
49
50
|
- Let the server infer single-turn versus tool-run request-log lifecycle. Do not recreate caller-selected logging modes in the SDK or API examples.
|
|
50
51
|
- Route provider models by prefix: `openai/*` goes to the OpenAI Codex runtime, `anthropic/*` goes to the Anthropic Claude Code runtime. Prefix-less model fallback is not implemented.
|
|
@@ -63,7 +63,8 @@ Do not write `providerOptions: { ... } satisfies QgridProviderOptions`: the expo
|
|
|
63
63
|
rejected by the SDK before transport; omission keeps weighted round-robin routing.
|
|
64
64
|
- `logger`: request-log switch. Omitted or `true` is the default and enables qgrid logging; `false` guarantees that generation creates zero qgrid request-log rows.
|
|
65
65
|
- `sessionKey`: source for model-scoped opaque OpenAI prompt-cache affinity. Disabled for Anthropic models.
|
|
66
|
-
- `
|
|
66
|
+
- `thinking`: optional boolean for both providers. Omission preserves existing model behavior. True enables thinking with the normal request effort → config `defaultEffort` → default resolution; it does not guarantee thinking tokens on every response. False ignores both efforts, including in request logging, and rejects unsupported or unverified model/runtime combinations. Generate, stream, tool continuation, and structured output carry the same boolean. Update SDK and server together: older servers can ignore the field. No `defaultThinking` or public `effort: "none"` is exposed. Haiku/Sonnet 5.5 off requires Claude Code >=2.1.295; Sonnet uses `between_tools` and may retain thinking blocks between tools.
|
|
67
|
+
- `effort`: provider-specific vocabulary. OpenAI (ChatGPT-subscription Codex route): `low | medium | high | xhigh | max | ultra`, where GPT-6 Astra, GPT-6 Sol, GPT-5.6 Sol, and Terra support `ultra`, and GPT-6 Luna and GPT-5.6 Luna support through `max`; `none`/`minimal` are not public effort values; use `thinking: false` for verified off-capable models. Anthropic (Claude Code `--effort`): `low | medium | high | xhigh | max`. The server resolves the value per provider and model (`providers/common/effort.ts`): anything outside the provider set, or above the Codex model's supported maximum, is silently dropped and treated as unspecified. With thinking omitted, Anthropic falls back to qgrid's default `low`; OpenAI omits `reasoning.effort` so the backend default applies. With `thinking: true`, OpenAI explicitly falls back to `low` for absent or unsupported effort, including raw API requests. With `thinking: false`, both providers ignore caller/default effort and apply their off policy instead. Invalid effort itself produces no error or metadata, only a debug log; unsupported thinking-off requests still fail explicitly. Use `QgridOpenAIProviderOptions` / `QgridAnthropicProviderOptions` for provider-typed `satisfies`; `QgridProviderOptions` is their union.
|
|
67
68
|
- `verbosity`: OpenAI/Codex route only.
|
|
68
69
|
- `reasoningSummary`: OpenAI/Codex route only.
|
|
69
70
|
- `serviceTier`: OpenAI/Codex route only.
|
|
@@ -77,7 +77,7 @@ claude -p
|
|
|
77
77
|
--model <canonical-model-or-1m-suffix>
|
|
78
78
|
--system-prompt <text> # small system prompt
|
|
79
79
|
--system-prompt-file <path> # large system prompt
|
|
80
|
-
--thinking disabled
|
|
80
|
+
--thinking <disabled|adaptive> # resolved from thinking and the existing model default
|
|
81
81
|
--effort <effort-or-low>
|
|
82
82
|
--disable-slash-commands
|
|
83
83
|
--session-id <uuid>
|
|
@@ -97,7 +97,11 @@ Important details:
|
|
|
97
97
|
- Large system prompts over 64 KiB are written to a temporary file to avoid argv `E2BIG` — this
|
|
98
98
|
same branch absorbs large injected schema contracts, so the old 64 KiB schema argv limit no
|
|
99
99
|
longer applies (only the global 512 KiB caller-schema complexity limit remains).
|
|
100
|
-
-
|
|
100
|
+
- One policy resolves the CLI thinking flag and effort before spawning. Omission preserves the existing model policy: Fable 5/5.1, Opus 5/5.5, Sonnet 5.5 and Haiku 5.5 keep adaptive defaults; other models use `--thinking disabled`. Explicit `true` uses `--thinking adaptive` and the normal effort resolution. Explicit `false` uses `--thinking disabled --effort low` only on supported models, ignoring caller/default effort. `CLAUDE_CODE_DISABLE_ADAPTIVE_THINKING` and `MAX_THINKING_TOKENS` are no longer sent. Do not reintroduce overlapping suppressors or inherit `CLAUDE_CODE_EFFORT_LEVEL`.
|
|
101
|
+
- The 2026-10-10 off policy includes Haiku 4.5/5.5, Sonnet 4.5/4.6/5/5.5, and Opus 4.5/4.6/4.7/4.8/5. Fable 5/5.1 and Opus 5.5 reject disabled thinking at the backend. Off requests for unverified models fail before spawning instead of changing models or silently enabling thinking.
|
|
102
|
+
- Haiku 5.5 and Sonnet 5.5 require Claude Code 2.1.295 or newer for explicit false. Cache the result of `claude --version`; unknown or older versions return an input error. The policy computes `CLAUDE_CODE_EXTRA_BODY` containing only `thinking: {type: "disabled"}` for Haiku or `thinking: {type: "between_tools"}` for Sonnet, alongside `--thinking disabled --effort low`. Native delivery was verified on 2.1.295; invalid-type and Sonnet-disabled negative controls confirmed that the CLI applied the body field. `between_tools` disables pre-answer thinking but may emit thinking blocks between tools. Never inherit this env variable or expose arbitrary body overrides to callers.
|
|
103
|
+
- Legacy environment suppression versus CLI-only disabled was compared on Sonnet 4.6 and Opus 4.8: both completed with zero thinking tokens in the short-text baseline. The comparison supports removing the duplicate suppressors without changing the omitted-option policy.
|
|
104
|
+
|
|
101
105
|
|
|
102
106
|
## Spawn env
|
|
103
107
|
|
|
@@ -109,14 +113,13 @@ Included env:
|
|
|
109
113
|
- `TMPDIR`
|
|
110
114
|
- `CLAUDE_CODE_OAUTH_TOKEN`
|
|
111
115
|
- `CLAUDE_CONFIG_DIR`
|
|
116
|
+
- `CLAUDE_CODE_EXTRA_BODY` only when computed by the thinking policy for explicit Haiku/Sonnet 5.5 off; never inherited
|
|
112
117
|
- `CLAUDE_CODE_DISABLE_AUTO_MEMORY=1`
|
|
113
|
-
- `CLAUDE_CODE_DISABLE_ADAPTIVE_THINKING=1` except for Fable 5/5.1 and Opus 5
|
|
114
118
|
- `CLAUDE_CODE_DISABLE_CLAUDE_MDS=1`
|
|
115
119
|
- `CLAUDE_CODE_DISABLE_TERMINAL_TITLE=1`
|
|
116
120
|
- `CLAUDE_CODE_DISABLE_BUNDLED_SKILLS=1`
|
|
117
121
|
- `CLAUDE_CODE_DISABLE_WORKFLOWS=1`
|
|
118
122
|
- `CLAUDE_CODE_ATTRIBUTION_HEADER=0`
|
|
119
|
-
- `MAX_THINKING_TOKENS=0` except for Fable 5/5.1 and Opus 5
|
|
120
123
|
- `CLAUDE_CODE_DISABLE_1M_CONTEXT=1` when model does not support qgrid's 1M path
|
|
121
124
|
- `MAX_STRUCTURED_OUTPUT_RETRIES` for streaming structured output only (not non-streaming `generate`)
|
|
122
125
|
|
|
@@ -37,6 +37,15 @@ Key decisions:
|
|
|
37
37
|
- The SDK should stay a thin adapter. Server APIs own request-log lifecycle, provider dispatch, structured-output emulation, and provider runtime details.
|
|
38
38
|
- Request logging defaults to enabled. `providerOptions.qgrid.logger: false` is the single per-generation opt-out for both native qgrid logs and `createQgridLogger` telemetry logs; it must not alter generation or tool behavior.
|
|
39
39
|
|
|
40
|
+
## Thinking Control
|
|
41
|
+
|
|
42
|
+
Source: `docs/plans/2026-10-10-001-feat-thinking-control-plan.md`.
|
|
43
|
+
|
|
44
|
+
- Use the independent `providerOptions.qgrid.thinking?: boolean` switch. False makes effort irrelevant; do not reject the combination or expose a cross-provider `effort: "none"` value.
|
|
45
|
+
- Preserve omitted-option behavior. Reject unsupported and runtime-unverified off requests before token acquisition/spawn, without fallback. Backend capability and Claude Code delivery are separate evidence.
|
|
46
|
+
- Use one Anthropic CLI thinking policy instead of overlapping environment suppressors. Preserve the OAuth env allowlist, token-specific config, empty settings, isolated cwd, memory/CLAUDE.md/skills/workflow disabling, tools, attribution, and 1M policy. These isolation controls prevent previously observed cross-request context injection and account metadata leakage.
|
|
47
|
+
- Haiku/Sonnet 5.5 use a narrowly computed native `CLAUDE_CODE_EXTRA_BODY` thinking field, guarded by Claude Code >=2.1.295. Do not inherit that variable, expose arbitrary body overrides, add a transport, or add a relay. Sonnet's `between_tools` exception remains visible: it turns off pre-answer thinking but can retain thinking blocks between tools.
|
|
48
|
+
|
|
40
49
|
## Tool Calling And Request-Log Lifecycle
|
|
41
50
|
|
|
42
51
|
Sources:
|
|
@@ -12,6 +12,12 @@ Use this reference before changing OpenAI transport, concurrency, routing, promp
|
|
|
12
12
|
- Direct quota lookup: `openai-quota.ts`.
|
|
13
13
|
- Provider integration and history: `packages/api/src/application/qgrid/qgrid.dispatcher.ts`, `conv-routing.ts`.
|
|
14
14
|
|
|
15
|
+
## Thinking control
|
|
16
|
+
|
|
17
|
+
`providerOptions.qgrid.thinking` reaches the Responses builder as a boolean. False overrides request/default effort and sends `reasoning: { effort: "none" }` without a reasoning summary. True uses a valid resolved effort, or explicitly sends `low` when effort is absent or unsupported, so a raw API request cannot fall back to a non-thinking backend default. Omission preserves the existing behavior: valid effort is forwarded; absent or unsupported effort leaves the backend default in effect. True and omission retain the requested reasoning summary policy. `none` belongs only to the internal wire type, not the public effort enum.
|
|
18
|
+
|
|
19
|
+
The 2026-10-10 subscription probe accepted off for `gpt-6-sol`, `gpt-6-luna`, `gpt-5.6-sol`, `gpt-5.6-terra`, `gpt-5.6-luna`, and `gpt-5.5`. `gpt-6-astra` and `gpt-6.1-sol` explicitly rejected it. Other model IDs are unverified for off and are rejected locally only when false is requested. Model-access failures are not evidence of mandatory thinking. Validate terminal success and response settings, not HTTP 200 alone: errors can arrive within SSE. The same policy applies to text-model requests driving image generation, not to the image model itself.
|
|
20
|
+
|
|
15
21
|
## Adding an OpenAI model
|
|
16
22
|
|
|
17
23
|
Use this checklist whenever a model is added. A public API release does not by itself prove
|
|
@@ -60,6 +60,8 @@ Image-generation request logs add `is_image_generation`, `image_cost_usd`, and `
|
|
|
60
60
|
|
|
61
61
|
In 2.9.8, list and detail model labels show requested model to image model for generated-image results, using an image serving model or the model recorded in `image_cost_method`. The cost fallback is an estimate, not an upstream version guarantee. Preserve the actual driver in stored `model_name` for hosted/auto turns. Do not hardcode a display version or render an image-generation/assumption badge. Auto text-only replies are not marked `is_image_generation`.
|
|
62
62
|
|
|
63
|
+
The list header ends its filter row with a reload button (2.10.2+) that calls the generated hooks' `refresh()` for the list and the total-cost query with the current filters; it does not refetch the token/project/model filter options, and TanStack Query's `isRefreshing` disables it while a reload is in flight.
|
|
64
|
+
|
|
63
65
|
Structured output visibility: the list has an `Fmt` column (`json` badge from `is_structured` vs `text`) and a `broken` badge driven by `response_json_ok = false`; there is no broken-JSON list filter. At review time, all 114,647 succeeded structured rows had `response_json_ok = true` and zero false rows existed; the unindexed zero-result lookup scanned 1,286,016 rows and took about 3 seconds. Before reinstating the filter, validate the failure-signal semantics and index the predicate. The detail page shows a dark Response Type panel (zod expression by default, `type` declaration via toggle) rendered server-side from the stored `json_schema`. Plain-text rows render no panel. Rows written by pre-2.7.2 servers show `text`.
|
|
64
66
|
|
|
65
67
|
Tool contract visibility: the detail page renders a Tools panel between Response Type and Steps for requests whose `tools` is non-empty. It starts collapsed and its header shows the tool count plus a responsive, truncated name list built from the detail subset — collapsed views issue no extra query. Expanding fires `toolsView` once and caches it for that request id, since a stored tool contract never changes. Each card shows the name, the full description, the parameter count, and a compact display-only zod shape; enum values past the sixth collapse to `/* +N */`, with the full shape reachable through hover and keyboard focus. All JSON Schema conversion happens server-side — the web renders completed strings and holds no schema logic.
|
|
@@ -72,7 +74,7 @@ Clicking an attached or generated image opens a preview with extension, decoded
|
|
|
72
74
|
|
|
73
75
|
Token credential previews must tolerate missing `accessToken` rather than reading `.length` unconditionally. Legacy system-keychain credentials display `System Keychain`; this display compatibility does not enable an Antigravity runtime.
|
|
74
76
|
|
|
75
|
-
Chat model presets: the model `<select>` lists the served subset of `QgridSupportedModel` grouped by provider (`MODEL_PRESET_GROUPS` in `ChatWidget.tsx`), newest first, and defaults to `anthropic/claude-fable-5-1`. Ids that the ChatGPT-subscription Codex route no longer serves (`gpt-5.4` and `gpt-5.4-mini` retired 2026-08-31 with `gpt-5.6-terra` / `gpt-5.6-luna` as replacements; `gpt-5.2` and `gpt-5.3-codex` removed earlier), `gpt-5.3-codex-spark` (rejected on the ChatGPT-account Codex route and absent from its catalog as of 2026-09-29), `gpt-5.5` (retires from the Codex/ChatGPT route on 2026-10-14; replacements `gpt-6.1-sol` / `gpt-6-luna`), the retired `claude-opus-4` / `claude-sonnet-4` (2026-06-15) and `claude-opus-4-1` (2026-08-05; Claude Code silently serves `claude-opus-5-5` instead), and the catalog-less `claude-sonnet-4-7` stay in the SDK type and price table (legacy request-log cost) but are excluded here. web does not depend on ai-sdk, so a new model must be added in both places. `openai/gpt-6-astra`, `openai/gpt-6.1-sol`, `openai/gpt-6-sol`, and `openai/gpt-6-luna` are included in the OpenAI group and `anthropic/claude-opus-5-5`, `anthropic/claude-sonnet-5-5`, and `anthropic/claude-haiku-5-5` in the Anthropic group; adding them does not change the default model.
|
|
77
|
+
Chat model presets: the model `<select>` lists the served subset of `QgridSupportedModel` grouped by provider (`MODEL_PRESET_GROUPS` in `ChatWidget.tsx`), newest first, and defaults to `anthropic/claude-fable-5-1`. Ids that the ChatGPT-subscription Codex route no longer serves (`gpt-5.4` and `gpt-5.4-mini` retired 2026-08-31 with `gpt-5.6-terra` / `gpt-5.6-luna` as replacements; `gpt-5.2` and `gpt-5.3-codex` removed earlier), `gpt-5.3-codex-spark` (rejected on the ChatGPT-account Codex route and absent from its catalog as of 2026-09-29), `gpt-5.5` (retires from the Codex/ChatGPT route on 2026-10-14; replacements `gpt-6.1-sol` / `gpt-6-luna`), the retired `claude-opus-4` / `claude-sonnet-4` (2026-06-15) and `claude-opus-4-1` (2026-08-05; Claude Code silently serves `claude-opus-5-5` instead), `claude-sonnet-4-5` (deprecated 2026-09-30, retirement 2026-11-30, replacement `claude-sonnet-5-5`), and the catalog-less `claude-sonnet-4-7` stay in the SDK type and price table (legacy request-log cost) but are excluded here. web does not depend on ai-sdk, so a new model must be added in both places. `openai/gpt-6-astra`, `openai/gpt-6.1-sol`, `openai/gpt-6-sol`, and `openai/gpt-6-luna` are included in the OpenAI group and `anthropic/claude-opus-5-5`, `anthropic/claude-sonnet-5-5`, and `anthropic/claude-haiku-5-5` in the Anthropic group; adding them does not change the default model.
|
|
76
78
|
|
|
77
79
|
The monit tab's vitals strip shows per-provider in-flight counts, an in-flight sparkline, token chips with quota gauges (fed by the dispatcher's 60-second rate-limits cache; `resetsAt` arrives as ms epoch), and a 1-hour per-provider request/error/cache-hit stats line polled separately every 30 seconds.
|
|
78
80
|
|
|
@@ -253,6 +253,8 @@ Anthropic's 5-hour usage window anchors on the first request, so an unused token
|
|
|
253
253
|
|
|
254
254
|
Keepalive breaks that coupling by burning the window clock during idle time. Every keepalive-enabled active Anthropic token gets one cheap request as soon as its window expires, so windows always run and a workday lands mid-window rather than on a boundary. Across an eight-hour day this raises the number of windows the day can touch from a fixed 2 to an expected 2.6.
|
|
255
255
|
|
|
256
|
+
The keepalive request uses `anthropic/claude-haiku-5-5`, `thinking: false`, `effort: "low"`, and the prompt `Reply OK.`. Thinking is disabled because this request only opens the usage window; the false policy overrides the supplied effort and uses the provider's low-effort off path. Haiku 5.5 off requires Claude Code >=2.1.295. The model constant lives in `token-window-keepalive.ts`; changing it does not change the scheduler or opt-in gates below.
|
|
257
|
+
|
|
256
258
|
- Since 2.8.0 (`ea7feb3`) keepalive is opt-in at two levels. The runner instance must have env `QGRID_TOKEN_WINDOW_KEEPALIVE_ENABLED=true` (default off; set it on one instance per shared DB), and a token is a target only when `tokens.keepalive_enabled` is `true` (default `false`, toggled in the dashboard settings panel). The global setting `qgrid.tokenWindowKeepaliveEnabled` is a kill switch (`false` disables everything), not a substitute for either gate. In 2.7.6 every instance fired for every active token.
|
|
257
259
|
- Operational trap: the 2.8.0 migration adds `keepalive_enabled` as default `false` without backfilling existing tokens. After upgrading, both the runner env and the per-token toggles must be set, or keepalive silently schedules zero tokens. This happened on dev0 after the 2026-08-31 self-update; a lingering 2.7.6 instance masked it until 2026-09-01. Diagnose with `GET /api/setting/listSettings` (`keepaliveRunnerEnabled`), `GET /api/token/findMany?subset=A` (`keepalive_enabled`), and the latest request log under project `qgrid-token-window-keepalive`.
|
|
258
260
|
- The next fire is scheduled from the token's real `resetsAt` rather than a fixed five-hour timer, so a provider-side change to the window length is followed automatically.
|
|
@@ -24,6 +24,16 @@ qgrid supports the AI SDK `tools` interface, but it does not use native provider
|
|
|
24
24
|
- qgrid maps that structured object back into AI SDK `tool-call` content.
|
|
25
25
|
- The AI SDK executes the actual tool functions and calls qgrid again with tool results.
|
|
26
26
|
|
|
27
|
+
OpenAI can emit separate commentary and final-answer message items in one response.
|
|
28
|
+
Plain commentary is an intermediate update, not an emulation payload: do not join
|
|
29
|
+
it to the final JSON. Known final-answer message deltas still stream incrementally.
|
|
30
|
+
For tool emulation, a complete message that passes the strict envelope and tool-name
|
|
31
|
+
validation with `action: tool_call` is the client handoff boundary. Stop aggregating
|
|
32
|
+
and streaming later text from that response: it cannot incorporate a tool result
|
|
33
|
+
that the client has not produced yet. Drain the upstream response to preserve usage,
|
|
34
|
+
errors, and cancellation. Never split concatenated JSON inside a single message or
|
|
35
|
+
recover malformed envelopes. Ordinary text requests keep their existing aggregation.
|
|
36
|
+
|
|
27
37
|
`generateText` and `streamText` default to `stepCountIs(1)`. When an executable
|
|
28
38
|
tool can run before the final answer, callers must set a bounded `stopWhen`
|
|
29
39
|
(for example `stepCountIs(3)`) or the AI SDK stops after the first tool-call
|
|
@@ -99,9 +109,16 @@ The schema explicitly tells the model:
|
|
|
99
109
|
|
|
100
110
|
- use `tool_call` when client-side tool execution is needed;
|
|
101
111
|
- use `answer` only for a final answer;
|
|
102
|
-
-
|
|
112
|
+
- return the tool request as the JSON response body, then end the turn and wait for client results;
|
|
113
|
+
- do not invent tool results or emit an answer before the required results arrive;
|
|
103
114
|
- put tool arguments in `args` as a JSON string.
|
|
104
115
|
|
|
116
|
+
Do not instruct OpenAI to use a `StructuredOutput` or Claude Code tool: neither is
|
|
117
|
+
provided on this route. The legacy schema descriptions contained that stale
|
|
118
|
+
instruction; schema descriptions now explain the actual client handoff protocol.
|
|
119
|
+
The discriminated union, required fields, argument encoding and user-schema refs
|
|
120
|
+
are unchanged. Prompt wording improves guidance but does not guarantee model compliance.
|
|
121
|
+
|
|
105
122
|
Delivery differs by provider (SON-532). OpenAI: `qgrid.dispatcher.ts` strictifies the composed
|
|
106
123
|
envelope through `buildStrictOutputSchema` and passes it as the response format — constrained
|
|
107
124
|
decoding enforces it. Anthropic: no schema is passed to CC at all; `schema-prompt.ts` renders the
|
|
@@ -149,7 +149,7 @@ Generated SSE handlers missing a newly added event field:
|
|
|
149
149
|
`NO_OPENAI_WORKERS`:
|
|
150
150
|
|
|
151
151
|
- The request path returns this only when there is no active OpenAI token candidate; there is no queue and no busy state.
|
|
152
|
-
- Check active OpenAI tokens and credential state (`OpenAIDispatcher.
|
|
152
|
+
- Check active OpenAI tokens and credential state (`OpenAIDispatcher.countActiveTokens()`).
|
|
153
153
|
- If tokens were recently changed, inspect `TokenSubscriber` status and reconcile behavior.
|
|
154
154
|
|
|
155
155
|
`NO_ACTIVE_WORKERS`:
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import"./rolldown-runtime-Dw2cE7zH.js";import{l as e,u as t}from"./vendor-tanstack-DJRQAbrY.js";import{i as n,r}from"./vendor-react-DH4kUfK2.js";import{C as i,S as a,n as o,o as s,r as c}from"./services.generated-Cbvg2sGQ.js";import{i as l,n as u,r as d}from"./index-Cq4_ExLO.js";import{n as f,r as p,t as m}from"./cost-CpjVoAqp.js";import{t as h}from"./request-model-eygfdRv7.js";n();var g=r(),_=e=>(0,g.jsx)(`svg`,{viewBox:`0 0 24 24`,width:`1.2em`,height:`1.2em`,...e,children:(0,g.jsx)(`path`,{fill:`none`,stroke:`currentColor`,strokeLinecap:`round`,strokeLinejoin:`round`,strokeWidth:2,d:`m15 18l-6-6l6-6`})}),v=e=>(0,g.jsx)(`svg`,{viewBox:`0 0 24 24`,width:`1.2em`,height:`1.2em`,...e,children:(0,g.jsx)(`path`,{fill:`none`,stroke:`currentColor`,strokeLinecap:`round`,strokeLinejoin:`round`,strokeWidth:2,d:`m9 18l6-6l-6-6`})}),y=50,b=`__unassigned__`;function x(e){let t=new Date(e);return`${String(t.getMonth()+1).padStart(2,`0`)}-${String(t.getDate()).padStart(2,`0`)} ${String(t.getHours()).padStart(2,`0`)}:${String(t.getMinutes()).padStart(2,`0`)}`}function S(e){return e.toLocaleString()}function C(e){let t=Math.round(e/1e3),n=Math.floor(t/60),r=t%60;return n>0?`${n}m ${r}s`:`${r}s`}function w({status:e,requestedModel:t,servedModel:n,imageCostMethod:r,fallbackCount:i}){if(e===`running`)return(0,g.jsx)(`span`,{className:`text-[9px] px-1.5 py-0.5 rounded-full bg-blue-100 text-blue-600 font-medium whitespace-nowrap`,children:`실행 중`});let a=h({status:e,requestedModel:t,servedModel:n,imageCostMethod:r}),o=t!==null&&n===null;return(0,g.jsxs)(g.Fragment,{children:[(0,g.jsx)(`span`,{className:`text-xs text-sand-500`,children:a.label}),o&&(0,g.jsx)(`span`,{className:`ml-1 text-[9px] text-sand-400`,children:`요청`}),(i??0)>0&&(0,g.jsxs)(`span`,{className:`ml-1 text-[9px] text-caution-500`,children:[`×`,i]})]})}function T(e){return e<=0?`—`:e>=1e3?`${(e/1e3).toFixed(1)}s`:`${e}ms`}var E=[{label:`ID`,align:`left`,width:`w-12`,sortKey:`id`},{label:`Date`,align:`left`,width:`w-20`,sortKey:`created_at`},{label:`Project`,align:`left`,width:`w-20`},{label:`Token`,align:`left`,width:`w-24`},{label:`Model`,align:`left`,width:`w-20`},{label:`Fmt`,align:`left`,width:`w-12`},{label:`TTFT`,align:`right`,width:`w-16`,sortKey:`ttft_ms`},{label:`Duration`,align:`right`,width:`w-20`,sortKey:`duration_ms`},{label:`In`,align:`right`,width:`w-16`,sortKey:`input_tokens`},{label:`Out`,align:`right`,width:`w-20`,sortKey:`output_tokens`},{label:`C.Read`,align:`right`,width:`w-20`,sortKey:`cache_read_tokens`},{label:`C.Write`,align:`right`,width:`w-20`,sortKey:`cache_creation_tokens`},{label:`Hit`,align:`right`,width:`w-14`},{label:`Tools`,align:`right`,width:`w-14`},{label:`Cost`,align:`right`,width:`w-20`,sortKey:`cost_usd`}];function D({search:n,onSearchChange:r}){let i=t(),a=n.page??1,u=n.token??``,d=n.project??``,h=n.model??``,{data:D}=s.useTokens(`A`),O=(D?.rows??[]).map(e=>e.name).filter(Boolean),{data:k}=o.useProjectNames(),A=k?.names??[],{data:j}=o.useModelNames(),M=j?.names??[],N=d===b?{project_name_is_null:!0}:d?{project_name:d}:{},P={...u?{token_name:u}:{},...N,...h?{model_name:h}:{}},F=n.sort??`id-desc`,I=F.lastIndexOf(`-`),L=F.slice(0,I),R=F.slice(I+1)===`asc`?`asc`:`desc`,{data:z,isLoading:B,isError:V}=c.useRequestLogs(`P`,{num:y,page:a,orderBy:F,...P}),{data:H,isError:U}=o.useTotalCost({num:0,page:1,...P}),W=z?.rows??[],G=z?.total??0,K=Math.ceil(G/y),q=e=>{r({...n,...e,page:1})};return(0,g.jsxs)(`div`,{className:`panel overflow-hidden`,children:[(0,g.jsxs)(`div`,{className:`panel-header flex items-center gap-2 px-3 py-2.5 flex-wrap sm:gap-3 sm:px-5`,children:[(0,g.jsxs)(`select`,{value:u,onChange:e=>q({token:e.target.value||void 0}),disabled:O.length===0,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`,children:[(0,g.jsx)(`option`,{value:``,children:O.length>0?`All Tokens`:`Tokens —`}),O.map(e=>(0,g.jsx)(`option`,{value:e,children:e},e))]}),(0,g.jsxs)(`select`,{value:d,onChange:e=>q({project:e.target.value||void 0}),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`,children:[(0,g.jsx)(`option`,{value:``,children:`All Projects`}),(0,g.jsx)(`option`,{value:b,children:`(unassigned)`}),A.map(e=>(0,g.jsx)(`option`,{value:e,children:e},e))]}),(0,g.jsxs)(`select`,{value:h,onChange:e=>q({model:e.target.value||void 0}),disabled:M.length===0,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`,children:[(0,g.jsx)(`option`,{value:``,children:M.length>0?`All Models`:`Models —`}),M.map(e=>(0,g.jsx)(`option`,{value:e,children:e},e))]}),(0,g.jsx)(`div`,{className:`flex-1`}),(0,g.jsxs)(`span`,{className:`text-[11px] text-sand-400`,children:[V||!z?`—`:G,` results`]}),U?(0,g.jsx)(`span`,{role:`alert`,className:`text-[11px] text-danger-500`,children:`Failed to load total cost.`}):(0,g.jsx)(`span`,{className:`text-[11px] tabular-nums font-medium text-sienna-600`,children:H?p(H.usd):`—`})]}),V?(0,g.jsx)(`div`,{role:`alert`,className:`text-danger-500 text-center py-12 text-sm`,children:`Failed to load request logs.`}):B?(0,g.jsx)(`div`,{className:`space-y-2`,children:Array.from({length:5}).map((e,t)=>(0,g.jsx)(`div`,{className:`h-8 bg-sand-100 rounded animate-pulse`},`skel-${t}`))}):W.length===0?(0,g.jsx)(`div`,{className:`text-sand-400 text-center py-12 text-sm`,children:`No requests yet.`}):(0,g.jsxs)(g.Fragment,{children:[(0,g.jsx)(`div`,{className:`overflow-x-auto px-3 py-3 sm:px-5`,children:(0,g.jsxs)(`table`,{className:`w-full min-w-[900px] text-[13px]`,children:[(0,g.jsx)(`thead`,{children:(0,g.jsxs)(`tr`,{className:`border-b border-sand-100/60`,children:[E.map(e=>{let t=e.label===`Duration`?`pl-5 pr-3`:e.width?`px-4`:`px-3`,n=e.sortKey===L;return(0,g.jsx)(`th`,{className:`${e.align===`right`?`text-right`:`text-left`} ${e.width??``} ${e.width?`whitespace-nowrap`:``} ${t} py-1.5 text-[10px] uppercase font-medium ${n?`text-sienna-600`:`text-sand-400`}`,children:e.sortKey?(0,g.jsxs)(`button`,{type:`button`,onClick:()=>q({sort:l.parse(`${e.sortKey}-${n&&R===`desc`?`asc`:`desc`}`)}),className:`inline-flex items-center gap-0.5 text-[10px] uppercase font-medium hover:text-sienna-500 transition-colors duration-150 ${e.align===`right`?`justify-end w-full`:``}`,children:[e.label,(0,g.jsx)(`span`,{className:n?``:`text-sand-300`,children:n?R===`desc`?`↓`:`↑`:`↕`})]}):e.label},e.label)}),(0,g.jsx)(`th`,{className:`w-8`})]})}),(0,g.jsx)(`tbody`,{className:`divide-y divide-sand-100/60`,children:W.map(t=>(0,g.jsxs)(`tr`,{className:`transition-colors duration-150 hover:bg-sand-100/60 cursor-pointer`,onClick:e=>{if(e.metaKey||e.ctrlKey){window.open(`/requests/show?id=${t.id}`,`_blank`);return}i({to:`/requests/show`,search:{id:t.id}})},children:[(0,g.jsx)(`td`,{className:`px-4 py-1.5 whitespace-nowrap`,children:(0,g.jsx)(e,{to:`/requests/show`,search:{id:t.id},onClick:e=>e.stopPropagation(),className:`text-xs text-sand-500 tabular-nums hover:text-sienna-500`,children:t.id})}),(0,g.jsx)(`td`,{className:`px-4 py-1.5 whitespace-nowrap`,children:(0,g.jsx)(`span`,{className:`text-xs text-sand-400 tabular-nums`,children:x(t.created_at)})}),(0,g.jsx)(`td`,{className:`px-4 py-1.5 whitespace-nowrap`,children:(0,g.jsx)(`span`,{className:`text-xs text-sand-600`,children:t.project_name??`—`})}),(0,g.jsx)(`td`,{className:`px-4 py-1.5 whitespace-nowrap`,children:(0,g.jsx)(`span`,{className:`text-xs text-sand-500`,children:t.token_name})}),(0,g.jsxs)(`td`,{className:`px-4 py-1.5 whitespace-nowrap`,children:[(0,g.jsx)(w,{status:t.status,requestedModel:t.requested_model_name,servedModel:t.model_name,imageCostMethod:t.image_cost_method,fallbackCount:t.fallback_count}),t.response_json_ok===!1&&(0,g.jsx)(`span`,{title:`structured 요청의 응답이 JSON 파싱에 실패했습니다`,className:`ml-1.5 rounded-full bg-caution-400/15 px-1.5 py-0.5 text-[9px] font-semibold text-caution-500`,children:`broken`})]}),(0,g.jsx)(`td`,{className:`px-4 py-1.5 whitespace-nowrap`,children:t.is_structured?(0,g.jsx)(`span`,{className:`rounded bg-sienna-100 px-1.5 py-0.5 font-mono text-[10px] text-sienna-700`,children:`json`}):(0,g.jsx)(`span`,{className:`font-mono text-[10px] text-sand-400`,children:`text`})}),(0,g.jsx)(`td`,{className:`px-4 py-1.5 text-right tabular-nums text-sand-500 whitespace-nowrap`,children:T(t.ttft_ms)}),(0,g.jsx)(`td`,{className:`pl-5 pr-3 py-1.5 text-right tabular-nums text-sand-500 whitespace-nowrap`,children:C(t.duration_ms)}),(0,g.jsx)(`td`,{className:`px-3 py-1.5 text-right tabular-nums text-sand-700`,children:S(t.input_tokens)}),(0,g.jsx)(`td`,{className:`px-3 py-1.5 text-right tabular-nums text-sand-700`,children:S(t.output_tokens)}),(0,g.jsx)(`td`,{className:`px-3 py-1.5 text-right tabular-nums text-sand-700`,children:S(t.cache_read_tokens)}),(0,g.jsx)(`td`,{className:`px-3 py-1.5 text-right tabular-nums text-sand-700`,children:S(t.cache_creation_tokens)}),(0,g.jsx)(`td`,{className:`px-3 py-1.5 text-right tabular-nums text-sand-700`,children:m(t)}),(0,g.jsx)(`td`,{className:`px-3 py-1.5 text-right tabular-nums text-sand-500`,children:t.tool_call_count>0?t.tool_call_count:`—`}),(0,g.jsx)(`td`,{className:`px-3 py-1.5 text-right tabular-nums text-sand-700`,children:t.image_cost_usd===null?t.cost_usd===null?`—`:f(t.cost_usd):f((t.cost_usd??0)+t.image_cost_usd)}),(0,g.jsx)(`td`,{className:`px-2 py-1.5`,children:(0,g.jsx)(v,{className:`size-4 text-sand-400`})})]},t.id))})]})}),K>1&&(0,g.jsxs)(`div`,{className:`flex items-center justify-center gap-3 px-5 py-2.5 border-t border-sand-100/60`,children:[(0,g.jsx)(`button`,{type:`button`,className:`p-1 rounded text-sand-400 hover:text-sand-600 disabled:opacity-30 transition-colors`,disabled:a===1,onClick:()=>r({...n,page:a-1}),children:(0,g.jsx)(_,{className:`size-4`})}),(0,g.jsxs)(`span`,{className:`text-[11px] text-sand-400 tabular-nums`,children:[a,` / `,K]}),(0,g.jsx)(`button`,{type:`button`,className:`p-1 rounded text-sand-400 hover:text-sand-600 disabled:opacity-30 transition-colors`,disabled:a===K,onClick:()=>r({...n,page:a+1}),children:(0,g.jsx)(v,{className:`size-4`})})]})]})]})}a({token:i().optional(),project:i().optional(),model:i().optional(),sort:l.optional(),page:d.shape.page.default(1)});function O(){let e=u.useSearch(),t=u.useNavigate();return(0,g.jsx)(`div`,{className:`max-w-[100rem] mx-auto`,children:(0,g.jsx)(D,{search:e,onSearchChange:e=>t({search:e})})})}export{O as component};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{r as e}from"./rolldown-runtime-Dw2cE7zH.js";import{_ as t}from"./vendor-tanstack-DJRQAbrY.js";import{i as n,n as r,r as i}from"./vendor-react-DH4kUfK2.js";import{S as a,h as o,t as s}from"./services.generated-Cbvg2sGQ.js";import{a as c,s as l}from"./index-Cq4_ExLO.js";import{t as u}from"./cost-CpjVoAqp.js";var d=e(n(),1),f=e(r(),1);function p(e,t,n){let r=Array(e);return new Proxy(r,{get(r,i,a){if(typeof i==`string`){let a=i.charCodeAt(0);if(a>=48&&a<=57){let a=+i;if(Number.isInteger(a)&&a>=0&&a<e){let e=r[a];if(!e){let i=t[a*2];e=r[a]={index:a,key:n(a),start:i,size:t[a*2+1],end:i+t[a*2+1],lane:0}}return e}}if(i===`length`)return e}return Reflect.get(r,i,a)}})}function m(e,t,n){let r=n.initialDeps??[],i,a=!0;function o(){let o=e();return o.length!==r.length||o.some((e,t)=>r[t]!==e)?(r=o,i=t(...o),n?.onChange&&!(a&&n.skipInitialOnChange)&&n.onChange(i),a=!1,i):i}return o.updateDeps=e=>{r=e},o}function h(e,t){if(e===void 0)throw Error(`Unexpected undefined${t?`: ${t}`:``}`);return e}var g=(e,t)=>Math.abs(e-t)<1.01,_=(e,t,n)=>{let r;return function(...i){e.clearTimeout(r),r=e.setTimeout(()=>t.apply(this,i),n)}},v,y=()=>{if(v!==void 0)return v;if(typeof navigator>`u`)return v=!1;if(/iP(hone|od|ad)/.test(navigator.userAgent))return v=!0;let e=navigator.maxTouchPoints;return v=navigator.platform===`MacIntel`&&e!==void 0&&e>0},b=e=>{let{offsetWidth:t,offsetHeight:n}=e;return{width:t,height:n}},x=e=>e,S=e=>{let t=Math.max(e.startIndex-e.overscan,0),n=Math.min(e.endIndex+e.overscan,e.count-1)-t+1,r=Array(n);for(let e=0;e<n;e++)r[e]=t+e;return r},C=(e,t)=>{let n=e.scrollElement;if(!n)return;let r=e.targetWindow;if(!r)return;let i=e=>{let{width:n,height:r}=e;t({width:Math.round(n),height:Math.round(r)})};if(i(b(n)),!r.ResizeObserver)return()=>{};let a=new r.ResizeObserver(t=>{let r=()=>{let e=t[0];if(e?.borderBoxSize){let t=e.borderBoxSize[0];if(t){i({width:t.inlineSize,height:t.blockSize});return}}i(b(n))};e.options.useAnimationFrameWithResizeObserver?requestAnimationFrame(r):r()});return a.observe(n,{box:`border-box`}),()=>{a.unobserve(n)}},w={passive:!0},T=typeof window>`u`?!0:`onscrollend`in window,E=(e,t,n)=>{let r=e.scrollElement;if(!r)return;let i=e.targetWindow;if(!i)return;let a=e.options.useScrollendEvent&&T,o=0,s=a?null:_(i,()=>t(o,!1),e.options.isScrollingResetDelay),c=e=>()=>{o=n(r),s?.(),t(o,e)},l=c(!0),u=c(!1);return r.addEventListener(`scroll`,l,w),a&&r.addEventListener(`scrollend`,u,w),()=>{r.removeEventListener(`scroll`,l),a&&r.removeEventListener(`scrollend`,u)}},D=(e,t)=>E(e,t,t=>{let{horizontal:n,isRtl:r}=e.options;return n?t.scrollLeft*(r&&-1||1):t.scrollTop}),O=(e,t,n)=>{if(n.options.useCachedMeasurements){let t=n.indexFromElement(e),r=n.options.getItemKey(t);return n.itemSizeCache.get(r)??n.options.estimateSize(t)}if(t?.borderBoxSize){let e=t.borderBoxSize[0];if(e)return Math.round(e[n.options.horizontal?`inlineSize`:`blockSize`])}if(!t){let t=n.indexFromElement(e),r=n.options.getItemKey(t),i=n.itemSizeCache.get(r);if(i!==void 0)return i}return e[n.options.horizontal?`offsetWidth`:`offsetHeight`]},k=(e,{adjustments:t=0,behavior:n},r)=>{var i,a;(a=(i=r.scrollElement)?.scrollTo)==null||a.call(i,{[r.options.horizontal?`left`:`top`]:e+t,behavior:n})},A=class{constructor(e){this.unsubs=[],this.scrollElement=null,this.targetWindow=null,this.isScrolling=!1,this.scrollState=null,this.measurementsCache=[],this._flatMeasurements=null,this.itemSizeCache=new Map,this.itemSizeCacheVersion=0,this.laneAssignments=new Map,this.pendingMin=null,this.prevLanes=void 0,this.lanesChangedFlag=!1,this.lanesSettling=!1,this.pendingScrollAnchor=null,this.scrollRect=null,this.scrollOffset=null,this.scrollDirection=null,this.scrollAdjustments=0,this._iosDeferredAdjustment=0,this._iosTouching=!1,this._iosJustTouchEnded=!1,this._iosTouchEndTimerId=null,this._intendedScrollOffset=null,this.elementsCache=new Map,this.now=()=>{var e;return((e=this.targetWindow?.performance)?.now)?.call(e)??Date.now()},this.observer=(()=>{let e=null,t=()=>e||(!this.targetWindow||!this.targetWindow.ResizeObserver?null:e=new this.targetWindow.ResizeObserver(e=>{e.forEach(e=>{let t=()=>{let t=e.target,n=this.indexFromElement(t);if(!t.isConnected){this.observer.unobserve(t);for(let[e,n]of this.elementsCache)if(n===t){this.elementsCache.delete(e);break}return}this.shouldMeasureDuringScroll(n)&&this.resizeItem(n,this.options.measureElement(t,e,this))};this.options.useAnimationFrameWithResizeObserver?requestAnimationFrame(t):t()})}));return{disconnect:()=>{var n;(n=t())==null||n.disconnect(),e=null},observe:e=>t()?.observe(e,{box:`border-box`}),unobserve:e=>t()?.unobserve(e)}})(),this.range=null,this.setOptions=e=>{let t={debug:!1,initialOffset:0,overscan:1,paddingStart:0,paddingEnd:0,scrollPaddingStart:0,scrollPaddingEnd:0,horizontal:!1,getItemKey:x,rangeExtractor:S,onChange:()=>{},measureElement:O,initialRect:{width:0,height:0},scrollMargin:0,gap:0,indexAttribute:`data-index`,initialMeasurementsCache:[],lanes:1,anchorTo:`start`,followOnAppend:!1,scrollEndThreshold:1,isScrollingResetDelay:150,enabled:!0,isRtl:!1,useScrollendEvent:!1,useAnimationFrameWithResizeObserver:!1,laneAssignmentMode:`estimate`,useCachedMeasurements:!1};for(let n in e){let r=e[n];r!==void 0&&(t[n]=r)}let n=this.options,r=null,i=null,a=!1;if(n!==void 0&&n.enabled&&t.enabled&&t.anchorTo===`end`&&this.scrollElement!==null){let e=n.count,o=t.count,s=this.getMeasurements(),c=e>0?s[0]?.key??n.getItemKey(0):null,l=e>0?s[e-1]?.key??n.getItemKey(e-1):null;if(o!==e||e>0&&o>0&&(t.getItemKey(0)!==c||t.getItemKey(o-1)!==l)){a=!0;let c=e>0?this.getVirtualItemForOffset(this.getScrollOffset())??s[0]:null;c&&(r=[c.key,this.getScrollOffset()-c.start]);let u=t.followOnAppend===!0?`auto`:t.followOnAppend||null;u&&o>e&&this.isAtEnd(n.scrollEndThreshold)&&(e===0||t.getItemKey(o-1)!==l)&&(i=u)}}this.options=t,a&&(this.pendingMin=0,this.itemSizeCacheVersion++);let o=!1,s=0;if(r&&this.scrollOffset!==null){let[e,t]=r,n=this.getMeasurements(),{count:i,getItemKey:a}=this.options,c=0;for(;c<i&&a(c)!==e;)c++;if(c<i){let e=n[c];if(e){let n=e.start+t;n!==this.scrollOffset&&(s=n-this.scrollOffset,this.scrollOffset=n,o=!0)}}}(o||i)&&(this.pendingScrollAnchor=[o?r[0]:null,o?r[1]:0,i,s])},this.notify=e=>{var t,n;(n=(t=this.options).onChange)==null||n.call(t,this,e)},this.maybeNotify=m(()=>(this.calculateRange(),[this.isScrolling,this.range?this.range.startIndex:null,this.range?this.range.endIndex:null]),e=>{this.notify(e)},{key:!1,debug:()=>this.options.debug,initialDeps:[this.isScrolling,this.range?this.range.startIndex:null,this.range?this.range.endIndex:null]}),this.cleanup=()=>{this.unsubs.filter(Boolean).forEach(e=>e()),this.unsubs=[],this.observer.disconnect(),this.rafId!=null&&this.targetWindow&&(this.targetWindow.cancelAnimationFrame(this.rafId),this.rafId=null),this.scrollState=null,this._iosDeferredAdjustment=0,this._iosTouching=!1,this._iosJustTouchEnded=!1,this.scrollElement=null,this.targetWindow=null},this._didMount=()=>()=>{this.cleanup()},this._willUpdate=()=>{let e=this.options.enabled?this.options.getScrollElement():null;if(this.scrollElement!==e){if(this.cleanup(),!e){this.maybeNotify();return}if(this.scrollElement=e,this.scrollElement&&`ownerDocument`in this.scrollElement?this.targetWindow=this.scrollElement.ownerDocument.defaultView:this.targetWindow=this.scrollElement?.window??null,this.elementsCache.forEach(e=>{this.observer.observe(e)}),this.unsubs.push(this.options.observeElementRect(this,e=>{this.scrollRect=e,this.maybeNotify()})),this.unsubs.push(this.options.observeElementOffset(this,(e,t)=>{if(t&&this._intendedScrollOffset===null&&e===this.scrollOffset)return;this._intendedScrollOffset!==null&&Math.abs(e-this._intendedScrollOffset)<1.5&&(e=this._intendedScrollOffset),this._intendedScrollOffset=null,this.scrollAdjustments=0;let n=this.getScrollOffset();this.scrollDirection=t?n===e?this.scrollDirection:n<e?`forward`:`backward`:null,this.scrollOffset=e,this.isScrolling=t,this._flushIosDeferredIfReady(),this.scrollState&&this.scheduleScrollReconcile(),this.maybeNotify()})),`addEventListener`in this.scrollElement){let e=this.scrollElement,t=()=>{this._iosTouching=!0,this._iosJustTouchEnded=!1,this._iosTouchEndTimerId!==null&&this.targetWindow!=null&&(this.targetWindow.clearTimeout(this._iosTouchEndTimerId),this._iosTouchEndTimerId=null)},n=()=>{this._iosTouching=!1,!(!y()||this.targetWindow==null)&&(this._iosJustTouchEnded=!0,this._iosTouchEndTimerId=this.targetWindow.setTimeout(()=>{this._iosJustTouchEnded=!1,this._iosTouchEndTimerId=null,this._flushIosDeferredIfReady()},150))};e.addEventListener(`touchstart`,t,w),e.addEventListener(`touchend`,n,w),this.unsubs.push(()=>{e.removeEventListener(`touchstart`,t),e.removeEventListener(`touchend`,n),this._iosTouchEndTimerId!==null&&this.targetWindow!=null&&(this.targetWindow.clearTimeout(this._iosTouchEndTimerId),this._iosTouchEndTimerId=null)})}this._scrollToOffset(this.getScrollOffset(),{adjustments:void 0,behavior:void 0})}let t=this.pendingScrollAnchor;if(this.pendingScrollAnchor=null,t&&this.scrollElement&&this.options.enabled){let[e,n,r,i]=t;e!==null&&!r&&(y()&&(this.isScrolling||this._iosTouching||this._iosJustTouchEnded)?i!==0&&(this._iosDeferredAdjustment+=i):this._scrollToOffset(this.getScrollOffset(),{adjustments:void 0,behavior:void 0})),r&&this.scrollToEnd({behavior:r})}},this._flushIosDeferredIfReady=()=>{if(this._iosDeferredAdjustment===0||this.isScrolling||this._iosTouching||this._iosJustTouchEnded)return;let e=this.getScrollOffset(),t=this.getMaxScrollOffset();if(e<0||e>t)return;let n=this._iosDeferredAdjustment;this._iosDeferredAdjustment=0,this._scrollToOffset(e,{adjustments:this.scrollAdjustments+=n,behavior:void 0})},this.rafId=null,this.getSize=()=>this.options.enabled?(this.scrollRect=this.scrollRect??this.options.initialRect,this.scrollRect[this.options.horizontal?`width`:`height`]):(this.scrollRect=null,0),this.getScrollOffset=()=>this.options.enabled?(this.scrollOffset=this.scrollOffset??(typeof this.options.initialOffset==`function`?this.options.initialOffset():this.options.initialOffset),this.scrollOffset):(this.scrollOffset=null,0),this.getMeasurementOptions=m(()=>[this.options.count,this.options.paddingStart,this.options.scrollMargin,this.options.getItemKey,this.options.enabled,this.options.lanes,this.options.laneAssignmentMode,this.options.gap],(e,t,n,r,i,a,o,s)=>(this.prevLanes!==void 0&&this.prevLanes!==a&&(this.lanesChangedFlag=!0),this.prevLanes=a,this.pendingMin=null,{count:e,paddingStart:t,scrollMargin:n,getItemKey:r,enabled:i,lanes:a,laneAssignmentMode:o,gap:s}),{key:!1}),this.getMeasurements=m(()=>[this.getMeasurementOptions(),this.itemSizeCacheVersion],({count:e,paddingStart:t,scrollMargin:n,getItemKey:r,enabled:i,lanes:a,laneAssignmentMode:o,gap:s},c)=>{let l=this.itemSizeCache;if(!i)return this.measurementsCache=[],this.itemSizeCache.clear(),this.laneAssignments.clear(),[];if(this.laneAssignments.size>e)for(let t of this.laneAssignments.keys())t>=e&&this.laneAssignments.delete(t);this.lanesChangedFlag&&(this.lanesChangedFlag=!1,this.lanesSettling=!0,this.measurementsCache=[],this.itemSizeCache.clear(),this.laneAssignments.clear(),this.pendingMin=null),this.measurementsCache.length===0&&!this.lanesSettling&&(this.measurementsCache=this.options.initialMeasurementsCache,this.measurementsCache.forEach(e=>{this.itemSizeCache.set(e.key,e.size)}));let u=this.lanesSettling?0:this.pendingMin??0;if(this.pendingMin=null,this.lanesSettling&&this.measurementsCache.length===e&&(this.lanesSettling=!1),a===1){let i=e*2,a=this._flatMeasurements;if(!a||a.length<i){let e=new Float64Array(i);a&&u>0&&e.set(a.subarray(0,u*2)),a=e,this._flatMeasurements=a}let o;if(u===0)o=t+n;else{let e=u-1;o=a[e*2]+a[e*2+1]+s}for(let t=u;t<e;t++){let e=r(t),n=l.get(e),i=typeof n==`number`?n:this.options.estimateSize(t);a[t*2]=o,a[t*2+1]=i,o+=i+s}let c=p(e,a,r);return this.measurementsCache=c,c}let d=this.measurementsCache.slice(0,u),f=Array(a).fill(void 0),m=new Float64Array(a),h=0;for(let e=0;e<u;e++){let t=d[e];t&&(f[t.lane]===void 0&&h++,f[t.lane]=e,m[t.lane]=t.end)}for(let i=u;i<e;i++){let e=r(i),c=this.laneAssignments.get(i),u,p,g=o===`estimate`||l.has(e);if(c!==void 0&&this.options.lanes>1){u=c;let e=f[u],r=e===void 0?void 0:d[e];p=r?r.end+s:t+n}else if(h===a){let e=0,t=m[0],n=f[0];for(let r=1;r<a;r++){let i=m[r];(i<t||i===t&&f[r]<n)&&(e=r,t=i,n=f[r])}u=e,p=t+s,g&&this.laneAssignments.set(i,u)}else u=i%this.options.lanes,p=t+n,g&&this.laneAssignments.set(i,u);let _=l.get(e),v=typeof _==`number`?_:this.options.estimateSize(i),y=p+v;d[i]={index:i,start:p,size:v,end:y,key:e,lane:u},f[u]===void 0&&h++,f[u]=i,m[u]=y}return this.measurementsCache=d,d},{key:!1,debug:()=>this.options.debug}),this.calculateRange=m(()=>[this.getMeasurements(),this.getSize(),this.getScrollOffset(),this.options.lanes],(e,t,n,r)=>e.length===0||t===0?(this.range=null,null):(this.range=N(e,t,n,r,r===1&&this._flatMeasurements!=null?this._flatMeasurements:null),this.range),{key:!1,debug:()=>this.options.debug}),this.getVirtualIndexes=m(()=>{let e=null,t=null,n=this.calculateRange();return n&&(e=n.startIndex,t=n.endIndex),this.maybeNotify.updateDeps([this.isScrolling,e,t]),[this.options.rangeExtractor,this.options.overscan,this.options.count,e,t]},(e,t,n,r,i)=>r===null||i===null?[]:e({startIndex:r,endIndex:i,overscan:t,count:n}),{key:!1,debug:()=>this.options.debug}),this.indexFromElement=e=>{let t=this.options.indexAttribute,n=e.getAttribute(t);return n?parseInt(n,10):(console.warn(`Missing attribute name '${t}={index}' on measured element.`),-1)},this.shouldMeasureDuringScroll=e=>{if(!this.scrollState||this.scrollState.behavior!==`smooth`)return!0;let t=this.scrollState.index??this.getVirtualItemForOffset(this.scrollState.lastTargetOffset)?.index;if(t!==void 0&&this.range){let n=Math.max(this.options.overscan,Math.ceil((this.range.endIndex-this.range.startIndex)/2)),r=Math.max(0,t-n),i=Math.min(this.options.count-1,t+n);return e>=r&&e<=i}return!0},this.measureElement=e=>{if(!e){this.elementsCache.forEach((e,t)=>{e.isConnected||(this.observer.unobserve(e),this.elementsCache.delete(t))});return}let t=this.indexFromElement(e),n=this.options.getItemKey(t),r=this.elementsCache.get(n);r!==e&&(r&&this.observer.unobserve(r),this.observer.observe(e),this.elementsCache.set(n,e)),(!this.isScrolling||this.scrollState)&&this.shouldMeasureDuringScroll(t)&&this.resizeItem(t,this.options.measureElement(e,void 0,this))},this.resizeItem=(e,t)=>{if(e<0||e>=this.options.count)return;let n,r,i,a=this._flatMeasurements;if(this.options.lanes===1&&a!==null)i=this.options.getItemKey(e),r=a[e*2],n=a[e*2+1];else{let t=this.measurementsCache[e];if(!t)return;i=t.key,r=t.start,n=t.size}let o=t-(this.itemSizeCache.get(i)??n);if(o!==0){let a=this.options.anchorTo===`end`&&this.scrollState?.behavior!==`smooth`&&this.getVirtualDistanceFromEnd()<=this.options.scrollEndThreshold,s=a?this.getTotalSize():0,c=this.scrollState?.behavior!==`smooth`&&(this.shouldAdjustScrollPositionOnItemSizeChange===void 0?r<this.getScrollOffset()+this.scrollAdjustments&&(!this.itemSizeCache.has(i)||this.scrollDirection!==`backward`):this.shouldAdjustScrollPositionOnItemSizeChange(this.measurementsCache[e]??{index:e,key:i,start:r,size:n,end:r+n,lane:0},o,this));(this.pendingMin===null||e<this.pendingMin)&&(this.pendingMin=e),this.itemSizeCache.set(i,t),this.itemSizeCacheVersion++,a?this.applyScrollAdjustment(this.getTotalSize()-s):c&&this.applyScrollAdjustment(o),this.notify(!1)}},this.getVirtualItems=m(()=>[this.getVirtualIndexes(),this.getMeasurements()],(e,t)=>{let n=[];for(let r=0,i=e.length;r<i;r++){let i=t[e[r]];n.push(i)}return n},{key:!1,debug:()=>this.options.debug}),this.getVirtualItemForOffset=e=>{let t=this.getMeasurements();if(t.length===0)return;let n=this._flatMeasurements,r=this.options.lanes===1&&n!=null;return h(t[j(0,t.length-1,r?e=>n[e*2]:e=>h(t[e]).start,e)])},this.getMaxScrollOffset=()=>{if(!this.scrollElement)return 0;if(`scrollHeight`in this.scrollElement)return this.options.horizontal?this.scrollElement.scrollWidth-this.scrollElement.clientWidth:this.scrollElement.scrollHeight-this.scrollElement.clientHeight;{let e=this.scrollElement.document.documentElement;return this.options.horizontal?e.scrollWidth-this.scrollElement.innerWidth:e.scrollHeight-this.scrollElement.innerHeight}},this.getVirtualDistanceFromEnd=()=>Math.max(this.getTotalSize()-this.getSize()-this.getScrollOffset(),0),this.getDistanceFromEnd=()=>Math.max(this.getMaxScrollOffset()-this.getScrollOffset(),0),this.isAtEnd=(e=this.options.scrollEndThreshold)=>this.getDistanceFromEnd()<=e,this.getOffsetForAlignment=(e,t,n=0)=>{if(!this.scrollElement)return 0;let r=this.getSize(),i=this.getScrollOffset();t===`auto`&&(t=e>=i+r?`end`:`start`),t===`center`?e+=(n-r)/2:t===`end`&&(e-=r);let a=this.getMaxScrollOffset();return Math.max(Math.min(a,e),0)},this.getOffsetForIndex=(e,t=`auto`)=>{e=Math.max(0,Math.min(e,this.options.count-1));let n=this.getSize(),r=this.getScrollOffset(),i=this.measurementsCache[e];if(!i)return;if(t===`auto`)if(i.end>=r+n-this.options.scrollPaddingEnd)t=`end`;else if(i.start<=r+this.options.scrollPaddingStart)t=`start`;else return[r,t];if(t===`end`&&e===this.options.count-1)return[this.getMaxScrollOffset(),t];let a=t===`end`?i.end+this.options.scrollPaddingEnd:i.start-this.options.scrollPaddingStart;return[this.getOffsetForAlignment(a,t,i.size),t]},this.scrollToOffset=(e,{align:t=`start`,behavior:n=`auto`}={})=>{let r=this.getOffsetForAlignment(e,t);this.scrollState={index:null,align:t,behavior:n,startedAt:this.now(),lastTargetOffset:r,stableFrames:0},this._scrollToOffset(r,{adjustments:void 0,behavior:n}),this.scheduleScrollReconcile()},this.scrollToIndex=(e,{align:t=`auto`,behavior:n=`auto`}={})=>{e=Math.max(0,Math.min(e,this.options.count-1));let r=this.getOffsetForIndex(e,t);if(!r)return;let[i,a]=r,o=this.now();this.scrollState={index:e,align:a,behavior:n,startedAt:o,lastTargetOffset:i,stableFrames:0},this._scrollToOffset(i,{adjustments:void 0,behavior:n}),this.scheduleScrollReconcile()},this.scrollBy=(e,{behavior:t=`auto`}={})=>{let n=this.getScrollOffset()+e;this.scrollState={index:null,align:`start`,behavior:t,startedAt:this.now(),lastTargetOffset:n,stableFrames:0},this._scrollToOffset(n,{adjustments:void 0,behavior:t}),this.scheduleScrollReconcile()},this.scrollToEnd=({behavior:e=`auto`}={})=>{if(this.options.count>0){this.scrollToIndex(this.options.count-1,{align:`end`,behavior:e});return}this.scrollToOffset(Math.max(this.getTotalSize()-this.getSize(),0),{behavior:e})},this.getTotalSize=()=>{let e=this.getMeasurements(),t;if(e.length===0)t=this.options.paddingStart;else if(this.options.lanes===1){let n=e.length-1,r=this._flatMeasurements;t=r==null?e[n]?.end??0:r[n*2]+r[n*2+1]}else{let n=Array(this.options.lanes).fill(null),r=e.length-1;for(;r>=0&&n.some(e=>e===null);){let t=e[r];n[t.lane]===null&&(n[t.lane]=t.end),r--}t=Math.max(...n.filter(e=>e!==null))}return Math.max(t-this.options.scrollMargin+this.options.paddingEnd,0)},this.takeSnapshot=()=>{let e=[];if(this.itemSizeCache.size===0)return e;let t=this.getMeasurements();for(let n of t)n&&this.itemSizeCache.has(n.key)&&e.push({index:n.index,key:n.key,start:n.start,size:n.size,end:n.end,lane:n.lane});return e},this._scrollToOffset=(e,{adjustments:t,behavior:n})=>{this._intendedScrollOffset=e+(t??0),this.options.scrollToFn(e,{behavior:n,adjustments:t},this)},this.measure=()=>{this.pendingMin=null,this.itemSizeCache.clear(),this.laneAssignments.clear(),this.itemSizeCacheVersion++,this.notify(!1)},this.setOptions(e)}applyScrollAdjustment(e,t){e!==0&&(y()&&(this.isScrolling||this._iosTouching||this._iosJustTouchEnded)?this._iosDeferredAdjustment+=e:(this._scrollToOffset(this.getScrollOffset(),{adjustments:this.scrollAdjustments+=e,behavior:t}),this.scrollOffset!==null&&(this.scrollOffset+=this.scrollAdjustments,this.scrollAdjustments=0)))}scheduleScrollReconcile(){if(!this.targetWindow){this.scrollState=null;return}this.rafId??=this.targetWindow.requestAnimationFrame(()=>{this.rafId=null,this.reconcileScroll()})}reconcileScroll(){if(!this.scrollState||!this.scrollElement)return;if(this.now()-this.scrollState.startedAt>5e3){this.scrollState=null;return}let e=this.scrollState.index==null?void 0:this.getOffsetForIndex(this.scrollState.index,this.scrollState.align),t=e?e[0]:this.scrollState.lastTargetOffset,n=t!==this.scrollState.lastTargetOffset;if(!n&&g(t,this.getScrollOffset())){if(this.scrollState.stableFrames++,this.scrollState.stableFrames>=1){this.getScrollOffset()!==t&&this._scrollToOffset(t,{adjustments:void 0,behavior:`auto`}),this.scrollState=null;return}}else if(this.scrollState.stableFrames=0,n){let e=this.getSize()||600,n=Math.abs(t-this.getScrollOffset()),r=this.scrollState.behavior===`smooth`&&n>e;this.scrollState.lastTargetOffset=t,r||(this.scrollState.behavior=`auto`),this._scrollToOffset(t,{adjustments:void 0,behavior:r?`smooth`:`auto`})}this.scheduleScrollReconcile()}},j=(e,t,n,r)=>{for(;e<=t;){let i=(e+t)/2|0,a=n(i);if(a<r)e=i+1;else if(a>r)t=i-1;else return i}return e>0?e-1:0};function M(e,t,n){let r=0;for(;r<=t;){let i=(r+t)/2|0,a=e[i*2];if(a<n)r=i+1;else if(a>n)t=i-1;else return i}return r>0?r-1:0}function N(e,t,n,r,i){let a=e.length-1;if(e.length<=r)return{startIndex:0,endIndex:a};if(r===1&&i!==null){let e=M(i,a,n),r=e,o=n+t;for(;r<a&&i[r*2]+i[r*2+1]<o;)r++;return{startIndex:e,endIndex:r}}let o=j(0,a,t=>e[t].start,n),s=o;if(r===1)for(;s<a&&e[s].end<n+t;)s++;else if(r>1){let i=Array(r).fill(0);for(;s<a&&i.some(e=>e<n+t);){let t=e[s];i[t.lane]=t.end,s++}let c=Array(r).fill(n+t);for(;o>=0&&c.some(e=>e>=n);){let t=e[o];c[t.lane]=t.start,o--}o=Math.max(0,o-o%r),s=Math.min(a,s+(r-1-s%r))}return{startIndex:o,endIndex:s}}var P=typeof document<`u`?d.useLayoutEffect:d.useEffect;function F({useFlushSync:e=!0,directDomUpdates:t=!1,directDomUpdatesMode:n=`transform`,...r}){let i=d.useReducer(e=>e+1,0)[1],a=d.useRef({enabled:t,mode:n,container:null,lastSize:null,lastPositions:new WeakMap,prevRange:null});a.current.enabled=t,a.current.mode=n;let o=e=>{let t=a.current;if(!t.enabled||!t.container)return;let n=e.getTotalSize();if(n!==t.lastSize){t.lastSize=n;let r=e.options.horizontal?`width`:`height`;t.container.style[r]=`${n}px`}let r=!!e.options.horizontal,i=t.mode===`transform`,o=r?`left`:`top`,s=e.options.scrollMargin,c=e.getVirtualItems();for(let n of c){let a=n.start-s,c=e.elementsCache.get(n.key);c&&t.lastPositions.get(c)!==a&&(t.lastPositions.set(c,a),i?c.style.transform=r?`translate3d(${a}px, 0, 0)`:`translate3d(0, ${a}px, 0)`:c.style[o]=`${a}px`)}},s={...r,onChange:(t,n)=>{var s;let c=a.current,l=!0;if(c.enabled){o(t);let e=t.range,n=c.prevRange;l=!n||n.isScrolling!==t.isScrolling||n.startIndex!==e?.startIndex||n.endIndex!==e?.endIndex,l&&(c.prevRange=e?{startIndex:e.startIndex,endIndex:e.endIndex,isScrolling:t.isScrolling}:null)}l&&(e&&n?(0,f.flushSync)(i):i()),(s=r.onChange)==null||s.call(r,t,n)}},[c]=d.useState(()=>{let e=new A(s);return Object.assign(e,{containerRef:t=>{let n=a.current;if(n.container=t,n.lastSize=null,t&&n.enabled){let r=e.getTotalSize();n.lastSize=r;let i=e.options.horizontal?`width`:`height`;t.style[i]=`${r}px`}}})});return c.setOptions(s),P(()=>c._didMount(),[]),P(()=>c._willUpdate()),P(()=>{o(c)}),c}function I(e){return F({observeElementRect:C,observeElementOffset:D,scrollToFn:k,...e})}var L=i(),R=e=>(0,L.jsx)(`svg`,{viewBox:`0 0 24 24`,width:`1.2em`,height:`1.2em`,...e,children:(0,L.jsxs)(`g`,{fill:`none`,stroke:`currentColor`,strokeLinecap:`round`,strokeLinejoin:`round`,strokeWidth:2,children:[(0,L.jsx)(`path`,{d:`M3 12a9 9 0 0 1 9-9a9.75 9.75 0 0 1 6.74 2.74L21 8`}),(0,L.jsx)(`path`,{d:`M21 3v5h-5m5 4a9 9 0 0 1-9 9a9.75 9.75 0 0 1-6.74-2.74L3 16`}),(0,L.jsx)(`path`,{d:`M8 16H3v5`})]})}),z=1e3,B=5e3,V=4e3,H={trace:0,debug:1,info:2,warning:3,error:4,fatal:5},U={trace:`TRC`,debug:`DBG`,info:`INF`,warning:`WRN`,error:`ERR`,fatal:`FTL`},W=new Intl.DateTimeFormat(`en-GB`,{hour:`2-digit`,minute:`2-digit`,second:`2-digit`,hour12:!1});function G(e){return W.format(new Date(e))}function K(e){return e.join(`·`)}var q=120;function J(e,t){e.push(t),e.length>q&&e.shift()}var Y=56,X=14;function Z({values:e}){if(e.length<2)return null;let t=Y,n=X,r=Math.max(...e,1),i=t/(q-1),a=t-(e.length-1)*i,o=e.map((e,t)=>{let o=a+t*i,s=n-1-e/r*(n-2);return`${o.toFixed(1)},${s.toFixed(1)}`}).join(` `);return(0,L.jsx)(`svg`,{width:t,height:n,viewBox:`0 0 ${t} ${n}`,className:`shrink-0`,"aria-hidden":`true`,children:(0,L.jsx)(`polyline`,{points:o,fill:`none`,stroke:`currentColor`,strokeWidth:`1.5`,strokeLinejoin:`round`,strokeLinecap:`round`,className:`text-sand-300`})})}function Q({usedPercent:e,threshold:t,blocked:n}){if(e===null)return null;let r=Math.max(0,Math.min(e,100)),i=n||t!==null&&e>=t;return(0,L.jsxs)(`span`,{className:`inline-flex items-center gap-1`,children:[(0,L.jsxs)(`span`,{className:`relative inline-block h-[4px] w-9 overflow-hidden rounded-full bg-sand-100`,children:[(0,L.jsx)(`span`,{className:l(`absolute inset-y-0 left-0 rounded-full`,i?`bg-caution-500`:`bg-sand-400`),style:{width:`${r}%`}}),t!==null&&(0,L.jsx)(`span`,{className:`absolute inset-y-0 w-px bg-sand-500`,style:{left:`${Math.min(t,100)}%`}})]}),(0,L.jsxs)(`span`,{className:l(`font-mono text-[10px] tabular-nums`,i?`font-semibold text-caution-500`:`text-sand-500`),children:[Math.round(e),`%`]})]})}function $({search:e,onSearchChange:n}){let[r,i]=(0,d.useState)([]),a=(0,d.useRef)(void 0),o=(0,d.useRef)(void 0),c=(0,d.useRef)(0),[f,p]=(0,d.useState)(()=>Date.now()),m=t({queryKey:[`Monit`,`monitLogs`],queryFn:()=>s.monitLogs(a.current),refetchInterval:z,retry:!1}),h=t({...s.monitInfoQueryOptions(),staleTime:1/0}).data,g=m.data?.vitals,_=t({...s.monitStatsQueryOptions(),refetchInterval:3e4,retry:!1}).data,v=(0,d.useRef)([]);(0,d.useEffect)(()=>{g&&J(v.current,g.openaiInFlight)},[g]),(0,d.useEffect)(()=>{let e=m.data;e&&y(e)},[m.data]);function y(e){let t=()=>++c.current;i(n=>{let r=n,i=[];o.current!==void 0&&e.processStartedAt!==o.current?(r=[],i.push({kind:`restart`,key:t(),processStartedAt:e.processStartedAt})):e.dropped>0&&i.push({kind:`dropped`,key:t(),count:e.dropped}),o.current=e.processStartedAt,a.current=e.nextCursor;let s=r.findLast(e=>e.kind===`log`)?.entry.seq;for(let n of e.entries)s!==void 0&&n.seq<=s||i.push({kind:`log`,key:t(),entry:n});if(i.length===0)return n;let c=[...r,...i];return c.length>V?c.slice(-V):c})}(0,d.useEffect)(()=>{let e=window.setInterval(()=>p(Date.now()),2e3);return()=>window.clearInterval(e)},[]);let b=r.length>0&&(m.isRefetchError||m.dataUpdatedAt>0&&f-m.dataUpdatedAt>B),x=(0,d.useMemo)(()=>r.filter(t=>{if(t.kind!==`log`)return!0;switch(e.level){case`warn`:return(H[t.entry.level]??2)>=3;case`error`:return(H[t.entry.level]??2)>=4;default:return!0}}),[r,e.level]),S=(0,d.useRef)(null),C=I({count:x.length,getScrollElement:()=>S.current,estimateSize:()=>20,getItemKey:e=>x[e].key,anchorTo:`end`,followOnAppend:!0,scrollEndThreshold:80,overscan:12}),w=C.isAtEnd(),T=m.dataUpdatedAt>0,E=!T&&m.isError;return(0,L.jsxs)(`section`,{className:`panel overflow-hidden`,children:[(0,L.jsxs)(`header`,{className:`panel-header flex min-h-11 flex-wrap items-center gap-x-3 gap-y-2 px-4 py-2 sm:px-5`,children:[(0,L.jsx)(`h2`,{className:`text-[13px] font-semibold tracking-[-0.01em] text-sand-800`,children:`Server logs`}),(0,L.jsxs)(`span`,{className:`inline-flex items-center gap-1.5 text-[11px] font-medium text-sand-700`,children:[(0,L.jsx)(`span`,{className:l(`size-1.5 rounded-full`,b||E?`bg-danger-400`:`bg-sienna-500 motion-safe:animate-pulse`)}),E?`Disconnected`:b?`Stale`:T?`Live`:`…`]}),o.current!==void 0&&(0,L.jsxs)(`span`,{className:`text-[11px] text-sand-500`,children:[`ephemeral · resets on restart · since `,G(o.current)]}),(0,L.jsx)(`div`,{className:`ml-auto flex flex-wrap items-center gap-2`,children:(0,L.jsx)(`div`,{className:`segmented-control inline-flex`,role:`tablist`,"aria-label":`Log filter`,children:[{value:`all`,label:`All`},{value:`warn`,label:`Warn+`},{value:`error`,label:`Err+`}].map(t=>(0,L.jsx)(`button`,{type:`button`,"data-active":e.level===t.value,onClick:()=>n({...e,level:t.value}),className:`rounded-[6px] px-2.5 py-1 text-[11px] font-medium text-sand-500 transition-colors hover:text-sand-800 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-sienna-300 data-[active=true]:text-sand-900`,children:t.label},t.value))})})]}),h&&(0,L.jsxs)(`div`,{className:`flex flex-wrap items-center gap-x-5 gap-y-1 border-b border-sand-100 bg-sand-50/60 px-4 py-2 text-[11px] text-sand-600 sm:px-5`,children:[(0,L.jsxs)(`span`,{children:[`server `,(0,L.jsx)(`span`,{className:`font-mono text-sand-800`,children:h.serverUrl})]}),(0,L.jsxs)(`span`,{children:[`db`,` `,(0,L.jsxs)(`span`,{className:`font-mono text-sand-800`,children:[h.dbHost,`/`,h.dbName]})]}),(0,L.jsxs)(`span`,{children:[`openai transport`,` `,(0,L.jsx)(`span`,{className:`font-mono text-sand-800`,children:h.openai.transport})]}),g&&(0,L.jsxs)(L.Fragment,{children:[(0,L.jsxs)(`span`,{className:`inline-flex items-center gap-1.5`,children:[`openai in-flight`,` `,(0,L.jsx)(`span`,{className:`font-mono text-sand-800`,children:g.openaiInFlight}),(0,L.jsx)(Z,{values:v.current})]}),g.anthropicTokenCount>0&&(0,L.jsxs)(`span`,{children:[`anthropic running`,` `,(0,L.jsx)(`span`,{className:`font-mono text-sand-800`,children:g.anthropicInFlight})]})]}),_?.providers.map(e=>(0,L.jsxs)(`span`,{className:`text-sand-500`,children:[`1h `,e.provider,` `,(0,L.jsx)(`span`,{className:`font-mono text-sand-700`,children:e.requests}),` req`,e.errors>0&&(0,L.jsxs)(L.Fragment,{children:[` · `,(0,L.jsx)(`span`,{className:`font-mono font-semibold text-caution-500`,children:e.errors}),` err`]}),` · hit `,(0,L.jsx)(`span`,{className:`font-mono text-sand-700`,children:u({input_tokens:e.inputTokens,cache_read_tokens:e.cacheReadTokens})})]},e.provider))]}),g&&(g.openaiQuotaByToken.length>0||g.anthropicTokenNames.length>0)&&(0,L.jsxs)(`div`,{className:`space-y-1.5 border-b border-sand-100 px-4 py-2.5 sm:px-5`,children:[g.openaiQuotaByToken.length>0&&(0,L.jsxs)(`div`,{className:`flex flex-wrap items-center gap-2`,children:[(0,L.jsx)(`span`,{className:`w-[4.5rem] shrink-0 text-[10px] font-medium uppercase tracking-[0.08em] text-sand-400`,children:`openai`}),g.openaiQuotaByToken.map(e=>{let t=e.usedPercent===null?`quota not sampled yet`:`quota ${Math.round(e.usedPercent)}%${e.threshold===null?``:` / threshold ${e.threshold}%`}${e.resetsAt?` · resets ${G(e.resetsAt)}`:``}`;return(0,L.jsxs)(`span`,{title:`${e.name} · ${t}`,className:`inline-flex items-center gap-1.5 rounded-md border border-sand-200 bg-white px-2 py-1`,children:[(0,L.jsx)(`span`,{className:`font-mono text-[11px] text-sand-600`,children:e.name.split(`/`).pop()}),(0,L.jsx)(Q,{usedPercent:e.usedPercent,threshold:e.threshold,blocked:e.blocked}),e.blocked&&(0,L.jsx)(`span`,{className:`rounded-full bg-caution-500/10 px-1.5 py-0.5 text-[9px] font-semibold text-caution-500`,children:`quota`})]},e.name)})]}),g.anthropicTokenNames.length>0&&(0,L.jsxs)(`div`,{className:`flex flex-wrap items-center gap-2`,children:[(0,L.jsx)(`span`,{className:`w-[4.5rem] shrink-0 text-[10px] font-medium uppercase tracking-[0.08em] text-sand-400`,children:`anthropic`}),g.anthropicTokenNames.map(e=>(0,L.jsx)(`span`,{title:e,className:`inline-flex items-baseline rounded-md border border-sand-200 bg-white px-2 py-1 font-mono text-[11px] text-sand-600`,children:e.split(`/`).pop()},e))]})]}),(0,L.jsxs)(`div`,{className:`relative`,children:[(0,L.jsx)(`div`,{ref:S,role:`log`,"aria-label":`Server process logs`,tabIndex:0,className:`main-scroll h-[calc(100vh-232px)] min-h-[320px] overflow-y-auto bg-sand-900 px-4 py-3 font-mono text-[12px] leading-[1.6] focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-sienna-400`,children:E?(0,L.jsxs)(`div`,{className:`flex h-full flex-col items-center justify-center gap-3 text-sand-400`,children:[(0,L.jsxs)(`p`,{className:`text-[12px]`,children:[`Could not reach the qgrid server — is it running?`,m.error instanceof Error&&(0,L.jsx)(`span`,{className:`block text-center text-[11px] text-sand-500`,children:m.error.message})]}),(0,L.jsxs)(`button`,{type:`button`,onClick:()=>void m.refetch(),className:`inline-flex items-center gap-1.5 rounded-md border border-sand-600 px-2.5 py-1.5 text-[11px] font-medium text-sand-300 transition-colors hover:bg-sand-800 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-sienna-400`,children:[(0,L.jsx)(R,{className:`size-3`}),`Retry now`]})]}):T?x.length===0?(0,L.jsx)(`div`,{className:`flex h-full items-center justify-center text-[12px] text-sand-500`,children:r.length===0?`No log lines yet — waiting for activity since ${o.current===void 0?`startup`:G(o.current)}.`:`No lines match the current filters.`}):(0,L.jsx)(`div`,{className:`relative w-full`,style:{height:`${C.getTotalSize()}px`},children:C.getVirtualItems().map(e=>{let t=x[e.index];return(0,L.jsx)(`div`,{ref:C.measureElement,"data-index":e.index,className:`absolute left-0 top-0 w-full`,style:{transform:`translateY(${e.start}px)`},children:(0,L.jsx)(ee,{item:t})},e.key)})}):(0,L.jsx)(`div`,{className:`flex h-full items-center justify-center text-[12px] text-sand-500`,children:`Connecting to server logs…`})}),T&&!E&&!w&&(0,L.jsx)(`button`,{type:`button`,onClick:()=>C.scrollToEnd(),className:`absolute bottom-4 right-5 inline-flex items-center gap-1.5 rounded-full border border-sand-600 bg-sand-800/90 px-3 py-1.5 text-[11px] font-medium text-sand-200 shadow-lg backdrop-blur transition-colors hover:bg-sand-700 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-sienna-400`,children:`↓ Jump to live`})]})]})}function ee({item:e}){if(e.kind===`restart`)return(0,L.jsxs)(`div`,{className:`py-1 text-center text-[11px] text-caution-400`,children:[`── process restarted · `,G(e.processStartedAt),` ──`]});if(e.kind===`dropped`)return(0,L.jsxs)(`div`,{className:`py-1 text-center text-[11px] italic text-sand-500`,children:[`── `,e.count,` lines dropped (buffer overflow) ──`]});let{entry:t}=e;return(0,L.jsxs)(`div`,{className:`whitespace-pre-wrap break-words text-sand-200`,children:[(0,L.jsx)(`span`,{className:`text-sand-500`,children:G(t.timestamp)}),` `,(0,L.jsx)(`span`,{className:l(`font-semibold`,t.level===`fatal`||t.level===`error`?`text-danger-400`:t.level===`warning`?`text-caution-400`:`text-sand-400`),children:U[t.level]??t.level.slice(0,3).toUpperCase()}),` `,(0,L.jsx)(`span`,{className:`text-sienna-300`,children:K(t.category)}),` `,(0,L.jsx)(`span`,{children:t.text})]})}a({level:o([`all`,`warn`,`error`]).optional().default(`all`).catch(()=>`all`)});function te(){let e=c.useSearch(),t=c.useNavigate();return(0,L.jsx)(`div`,{className:`max-w-[100rem] mx-auto`,children:(0,L.jsx)($,{search:e,onSearchChange:e=>t({search:e,replace:!0})})})}export{te as component};
|
|
File without changes
|
/package/bundle/web-dist/client/assets/{request-model-eygfdRv7.js → request-model-D4CZPmnG.js}
RENAMED
|
File without changes
|
|
File without changes
|
/package/bundle/web-dist/server/assets/{request-model-DXclJfdP.js → request-model-CnCeaNLE.js}
RENAMED
|
File without changes
|