@cartanova/qgrid-cli 2.10.4 → 2.10.6
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/bundle/dist/application/monit/monit.frame.js +1 -1
- package/bundle/dist/application/qgrid/expired-token-reminder.js +1 -1
- package/bundle/dist/application/qgrid/oauth.js +1 -1
- package/bundle/dist/application/qgrid/qgrid-image-generation.js +6 -6
- package/bundle/dist/application/qgrid/qgrid-run-lifecycle.js +24 -7
- package/bundle/dist/application/qgrid/qgrid.dispatcher.js +8 -3
- package/bundle/dist/application/qgrid/qgrid.frame.js +25 -11
- package/bundle/dist/application/qgrid/qgrid.types.js +4 -8
- package/bundle/dist/application/qgrid/token-death.js +1 -1
- package/bundle/dist/application/qgrid/token-window-keepalive.js +1 -1
- package/bundle/dist/application/qgrid/tool-emulation.js +1 -1
- package/bundle/dist/application/request-log/request-log.model.js +23 -17
- package/bundle/dist/i18n/sd.generated.js +3 -3
- package/bundle/dist/sonamu.config.js +2 -2
- package/bundle/dist/utils/providers/anthropic/anthropic-dispatcher.js +1 -1
- package/bundle/dist/utils/providers/anthropic/anthropic-thinking.js +1 -1
- package/bundle/dist/utils/providers/openai/openai-backend-protocol.js +31 -9
- package/bundle/dist/utils/providers/openai/openai-direct-client.js +5 -4
- package/bundle/dist/utils/providers/openai/openai-dispatcher.js +111 -57
- package/bundle/dist/utils/providers/openai/openai-image-generation.js +25 -17
- package/bundle/dist/utils/providers/openai/openai-refresh.js +1 -1
- package/bundle/src/application/qgrid/qgrid-image-generation.test.ts +34 -5
- package/bundle/src/application/qgrid/qgrid-image-generation.ts +17 -13
- package/bundle/src/application/qgrid/qgrid-response-format.test.ts +11 -0
- package/bundle/src/application/qgrid/qgrid-run-lifecycle.test.ts +87 -9
- package/bundle/src/application/qgrid/qgrid-run-lifecycle.ts +45 -5
- package/bundle/src/application/qgrid/qgrid.dispatcher.test.ts +136 -2
- package/bundle/src/application/qgrid/qgrid.dispatcher.ts +11 -1
- package/bundle/src/application/qgrid/qgrid.frame.test.ts +73 -0
- package/bundle/src/application/qgrid/qgrid.frame.ts +43 -6
- package/bundle/src/application/qgrid/qgrid.types.ts +14 -4
- package/bundle/src/application/request-log/request-log.entity.json +2 -2
- package/bundle/src/application/request-log/request-log.model.test.ts +17 -12
- package/bundle/src/application/request-log/request-log.model.ts +8 -2
- package/bundle/src/application/sonamu.generated.http +2 -2
- package/bundle/src/i18n/sd.generated.ts +2 -2
- package/bundle/src/utils/providers/openai/openai-backend-protocol.test.ts +42 -2
- package/bundle/src/utils/providers/openai/openai-backend-protocol.ts +46 -2
- package/bundle/src/utils/providers/openai/openai-direct-client.test.ts +15 -0
- package/bundle/src/utils/providers/openai/openai-direct-client.ts +14 -4
- package/bundle/src/utils/providers/openai/openai-dispatcher.test.ts +235 -32
- package/bundle/src/utils/providers/openai/openai-dispatcher.ts +174 -72
- package/bundle/src/utils/providers/openai/openai-image-generation.test.ts +89 -0
- package/bundle/src/utils/providers/openai/openai-image-generation.ts +26 -15
- package/bundle/web-dist/client/assets/cost-DH2jZbrw.js +1 -0
- package/bundle/web-dist/client/assets/{index-reW8VvJF.js → index-D9ryIyL-.js} +4 -4
- package/bundle/web-dist/client/assets/logs-CLf2VNfk.js +1 -0
- package/bundle/web-dist/client/assets/{monit-DkABv7PG.js → monit-DojxOLj6.js} +1 -1
- package/bundle/web-dist/client/assets/{routes-BRmQ4M3-.js → routes-DXJhNvbI.js} +2 -2
- package/bundle/web-dist/client/assets/{services.generated-jnPHYMER.js → services.generated-DqFYgWsY.js} +1 -1
- package/bundle/web-dist/client/assets/{settings-BHvtycEZ.js → settings-bopyz9pa.js} +1 -1
- package/bundle/web-dist/client/assets/{show-qeTIzgDZ.js → show-DbLD3MzB.js} +1 -1
- package/bundle/web-dist/client/assets/{tokens-5Bep_G-w.js → tokens-2-AIi9sZ.js} +1 -1
- package/bundle/web-dist/client/assets/{use-oauth-login-flow-Cx-QO25M.js → use-oauth-login-flow-CnqTWs_H.js} +1 -1
- package/bundle/web-dist/client/assets/{use-update-token-mutation-DQCwCYfR.js → use-update-token-mutation-Cxb9K0fM.js} +1 -1
- package/bundle/web-dist/client/index.html +2 -2
- package/bundle/web-dist/server/assets/{cost-CSH_t17I.js → cost-eEHeTRT5.js} +5 -1
- package/bundle/web-dist/server/assets/{lazyRouteComponent-CUR-kWzI.js → lazyRouteComponent-Bi0fYGLs.js} +2 -2
- package/bundle/web-dist/server/assets/{logs-CagNGTBj.js → logs-CIVFxfoi.js} +11 -8
- package/bundle/web-dist/server/assets/{monit-DSxs4Jnl.js → monit-DBXezg7R.js} +4 -4
- package/bundle/web-dist/server/assets/{plus-Bvdj8Pwx.js → plus-BH-t4cm_.js} +1 -1
- package/bundle/web-dist/server/assets/{react-dom-CyuShs9K.js → react-dom-CZ2eynd8.js} +1 -1
- package/bundle/web-dist/server/assets/{refresh-cw-3QAiSWBd.js → refresh-cw-CosAdcz0.js} +1 -1
- package/bundle/web-dist/server/assets/{routes-i-sTqXMX.js → routes-COWYIvA-.js} +5 -6
- package/bundle/web-dist/server/assets/{services.generated-FPwsG9p3.js → services.generated-607iwhMI.js} +2 -2
- package/bundle/web-dist/server/assets/{settings-DeHNwoMv.js → settings-C_6dpK5p.js} +3 -3
- package/bundle/web-dist/server/assets/{show-C4jk1Hrp.js → show-DY396-LD.js} +8 -20
- package/bundle/web-dist/server/assets/{tokens-odgS2-9q.js → tokens-COvV7qUP.js} +4 -4
- package/bundle/web-dist/server/assets/{use-oauth-login-flow-DTQKdYBO.js → use-oauth-login-flow-VYCYf3uv.js} +1 -1
- package/bundle/web-dist/server/assets/{use-update-token-mutation-xvXbPrCI.js → use-update-token-mutation-D8XYV5of.js} +1 -1
- package/bundle/web-dist/server/entry-server.generated.js +10 -10
- package/package.json +3 -2
- package/skills/qgrid/SKILL.md +9 -8
- package/skills/qgrid/references/ai-sdk-provider-contract.md +25 -16
- package/skills/qgrid/references/decision-rationale.md +8 -8
- package/skills/qgrid/references/openai-codex-runtime.md +23 -11
- package/skills/qgrid/references/request-log-run-lifecycle.md +4 -2
- package/skills/qgrid/references/sonamu-api-web-flow.md +2 -2
- package/skills/qgrid/references/verification-and-debugging.md +23 -9
- package/bundle/web-dist/client/assets/cost-CpjVoAqp.js +0 -1
- package/bundle/web-dist/client/assets/logs-DDIt97D1.js +0 -1
|
@@ -128,15 +128,25 @@ AI SDK tools plus structured output:
|
|
|
128
128
|
|
|
129
129
|
Image generation:
|
|
130
130
|
|
|
131
|
-
- `packages/api/
|
|
131
|
+
- `packages/api/e2e/image-generation.ts`
|
|
132
132
|
- Human-initiated only.
|
|
133
133
|
- Requires active OpenAI token with image entitlement and applicable migration.
|
|
134
134
|
- For 2.9.8 chat, verify the actual browser POST and served bundle, not only a direct function test. A globally installed CLI on port 44900 can serve stale assets while repository tests pass; identify the listening process and its executable before assuming a rebuild or refresh affects it.
|
|
135
|
-
- Cover auto text-only replies
|
|
136
|
-
- Verify extension, decoded bytes, and natural dimensions in chat image previews. A format request in prose is not evidence: the 2026-09-29 WebP probe returned PNG from a prompt-only request and WebP from explicit `outputFormat: "webp"`.
|
|
137
|
-
-
|
|
135
|
+
- Cover auto text-only replies and the single server-side `generate_image` function for ordinary generation and transparent editing. Zero selected references must create a fresh image despite older history; positive counts must select only the last N conversation images in order, up to five. Explicit raw `true` must retain its image-required hosted behavior for non-transparent chat-model requests. Verify driver usage stays separate from image usage and auto text replies are not image logs.
|
|
136
|
+
- Verify extension, decoded bytes, and natural dimensions in chat image previews. A format request in prose is not evidence: the 2026-09-29 hosted-route WebP probe returned PNG from a prompt-only request and WebP from explicit `outputFormat: "webp"`. Auto chat and standalone output remain PNG-only and must reject explicit non-PNG options.
|
|
137
|
+
- Requires `QGRID_REAL_PROVIDER_ACCEPTANCE=1`, explicit `QGRID_URL` and `QGRID_OPENAI_MODEL`. Optional `QGRID_TOKEN_NAME` pins a subscription token. `QGRID_IMAGE_SMOKE_CASES` selects named cases; the default covers eight images plus text, rejected inputs, and cancellation. Optional `batch`, `logger-off`, and `cancel-direct` cover SDK batching, no-log calls, and cancellation during direct Images requests. Never replay generations automatically.
|
|
138
|
+
- Set `QGRID_IMAGE_E2E_OUTPUT` for PNGs and sanitized usage/cost/log evidence; `QGRID_IMAGE_E2E_PROJECT` groups test logs. Use an isolated DB and access-only test token, with notifications and keepalive disabled. For final acceptance, build the current API and cold-start `sonamu start` against that isolated DB rather than relying on HMR. HMR can leave a fresh dispatcher uninitialized; readiness alone does not prove the intended module version. The suite checks readiness before live calls.
|
|
139
|
+
- Subscription `response.completed.tool_usage.image_gen` can be present with all-zero usage for text-only or function-tool replies. This metadata alone is not a hosted image execution. Keep the zero-usage regression test and verify auto text against the real backend.
|
|
140
|
+
- Run auto text and generation with both Luna and Astra when changing the internal tool schema. Astra's private backend failed with `strict: true` even with bounds removed, while the same schema succeeded with `strict: false`. Keep `strict: false` and server-side validation; do not add a runtime fallback/retry.
|
|
138
141
|
- Not part of CI; it consumes ChatGPT subscription quota.
|
|
139
142
|
|
|
143
|
+
Image failure accounting:
|
|
144
|
+
|
|
145
|
+
- `packages/api/e2e/image-failure-accounting.ts` calls the real subscription chat model and compares its completed usage with the persisted failed/aborted request and generate step.
|
|
146
|
+
- Start a separate built local API with `NODE_OPTIONS=--import=<absolute path>/packages/api/e2e/image-failure-preload.mjs`. This test-only preload intercepts standalone Images requests with HTTP errors, network errors, invalid image responses, cancellation waits, or a synthetic success control. It never forwards Images requests upstream; no production test switch or fallback is added.
|
|
147
|
+
- Both processes require `QGRID_REAL_PROVIDER_ACCEPTANCE=1`, `QGRID_IMAGE_E2E_FAULT_FILE`, and `QGRID_IMAGE_E2E_TRACE_FILE`. The preload requires `HOST=127.0.0.1` and an isolated `SONAMU_DB_NAME` starting with `qgrid_e2e_`. The runner also requires `QGRID_URL`, `QGRID_TOKEN_NAME`, and `QGRID_IMAGE_E2E_OUTPUT`.
|
|
148
|
+
- Verify one completed driver step and exact input/output/cache usage and cost on failure; parent status and original errors stay failed/aborted, image cost stays unknown, and `logger: false` creates no records. The success control must not double-count driver usage. Trace files retain only completed model/usage metadata, never credentials or image bytes.
|
|
149
|
+
|
|
140
150
|
Other scripts under `scripts/smoke-test-*` and `scripts/debug-*` are ad hoc probes. Read the script header and env vars before running.
|
|
141
151
|
|
|
142
152
|
## Common Error Triage
|
|
@@ -188,21 +198,25 @@ Generated SSE handlers missing a newly added event field:
|
|
|
188
198
|
- Treat as a real error, not a recoverable partial result.
|
|
189
199
|
- Check schema strictness and `stream-json-adapter` behavior.
|
|
190
200
|
|
|
191
|
-
`qgrid: imageGeneration
|
|
201
|
+
`qgrid: imageGeneration and imageGenerationOptions were removed from language-model options`:
|
|
202
|
+
|
|
203
|
+
- Either removed key makes `generateText` and `streamText` fail before transport. Use `generateImage` with `qgrid.image()` and flat `QgridImageProviderOptions` for image output.
|
|
204
|
+
|
|
205
|
+
`qgrid language models do not support image input`:
|
|
192
206
|
|
|
193
|
-
-
|
|
207
|
+
- General vision remains unsupported by the language adapter; it ignores image parts with this warning. Reference-image editing belongs in `generateImage`'s `prompt: { text, images }`.
|
|
194
208
|
|
|
195
209
|
`image generation is not supported on the Anthropic route`:
|
|
196
210
|
|
|
197
211
|
- Image generation is OpenAI/Codex-only.
|
|
198
212
|
|
|
199
|
-
`
|
|
213
|
+
`qgrid.image: expected one image from the direct subscription Images route`:
|
|
200
214
|
|
|
201
|
-
-
|
|
215
|
+
- Image-provider version-skew guard. Each call requires exactly one image with `generation.route: "codex-images"`. Check that the server supports the explicit image model and update the server and SDK together.
|
|
202
216
|
|
|
203
217
|
`reference image input is too large for JSON transport`:
|
|
204
218
|
|
|
205
|
-
- AI SDK reference-image guard. The client passed a base64 image data URL large enough to likely exceed qgrid's JSON request body transport. Compress or resize the image before calling `
|
|
219
|
+
- AI SDK reference-image guard. The client passed a base64 image data URL large enough to likely exceed qgrid's JSON request body transport. Compress or resize the image before calling `generateImage`, preferably as WebP/JPEG.
|
|
206
220
|
|
|
207
221
|
`qgrid query transport failed: response headers timed out`:
|
|
208
222
|
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
var e=1e6,t=4;function n(t){return t/e}function r(e){return`$${e.toFixed(t)}`}function i(e){return r(n(e))}function a(e){return e.input_tokens<=0?`—`:`${Math.round(e.cache_read_tokens/e.input_tokens*100)}%`}export{i as n,r,a as t};
|
|
@@ -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-jnPHYMER.js";import{i as l,n as u,r as d}from"./index-reW8VvJF.js";import{n as f,r as p,t as m}from"./cost-CpjVoAqp.js";import{t as h}from"./refresh-cw-NNcU0Cmq.js";import{t as g}from"./request-model-D4CZPmnG.js";n();var _=r(),v=e=>(0,_.jsx)(`svg`,{viewBox:`0 0 24 24`,width:`1.2em`,height:`1.2em`,...e,children:(0,_.jsx)(`path`,{fill:`none`,stroke:`currentColor`,strokeLinecap:`round`,strokeLinejoin:`round`,strokeWidth:2,d:`m15 18l-6-6l6-6`})}),y=e=>(0,_.jsx)(`svg`,{viewBox:`0 0 24 24`,width:`1.2em`,height:`1.2em`,...e,children:(0,_.jsx)(`path`,{fill:`none`,stroke:`currentColor`,strokeLinecap:`round`,strokeLinejoin:`round`,strokeWidth:2,d:`m9 18l6-6l-6-6`})}),b=50,x=`__unassigned__`;function S(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 C(e){return e.toLocaleString()}function w(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 T({status:e,requestedModel:t,servedModel:n,imageCostMethod:r,fallbackCount:i}){if(e===`running`)return(0,_.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=g({status:e,requestedModel:t,servedModel:n,imageCostMethod:r}),o=t!==null&&n===null;return(0,_.jsxs)(_.Fragment,{children:[(0,_.jsx)(`span`,{className:`text-xs text-sand-500`,children:a.label}),o&&(0,_.jsx)(`span`,{className:`ml-1 text-[9px] text-sand-400`,children:`요청`}),(i??0)>0&&(0,_.jsxs)(`span`,{className:`ml-1 text-[9px] text-caution-500`,children:[`×`,i]})]})}function E(e){return e<=0?`—`:e>=1e3?`${(e/1e3).toFixed(1)}s`:`${e}ms`}var D=[{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 O({search:n,onSearchChange:r}){let i=t(),a=n.page??1,u=n.token??``,d=n.project??``,g=n.model??``,{data:O}=s.useTokens(`A`),k=(O?.rows??[]).map(e=>e.name).filter(Boolean),{data:A}=o.useProjectNames(),j=A?.names??[],{data:M}=o.useModelNames(),N=M?.names??[],P=d===x?{project_name_is_null:!0}:d?{project_name:d}:{},F={...u?{token_name:u}:{},...P,...g?{model_name:g}:{}},I=n.sort??`id-desc`,L=I.lastIndexOf(`-`),R=I.slice(0,L),z=I.slice(L+1)===`asc`?`asc`:`desc`,{data:B,isLoading:V,isError:H,refresh:U,isRefreshing:W}=c.useRequestLogs(`P`,{num:b,page:a,orderBy:I,...F}),{data:G,isError:K,refresh:q}=o.useTotalCost({num:0,page:1,...F}),J=B?.rows??[],Y=B?.total??0,X=Math.ceil(Y/b),Z=e=>{r({...n,...e,page:1})};return(0,_.jsxs)(`div`,{className:`panel overflow-hidden`,children:[(0,_.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,_.jsxs)(`select`,{value:u,onChange:e=>Z({token:e.target.value||void 0}),disabled:k.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,_.jsx)(`option`,{value:``,children:k.length>0?`All Tokens`:`Tokens —`}),k.map(e=>(0,_.jsx)(`option`,{value:e,children:e},e))]}),(0,_.jsxs)(`select`,{value:d,onChange:e=>Z({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,_.jsx)(`option`,{value:``,children:`All Projects`}),(0,_.jsx)(`option`,{value:x,children:`(unassigned)`}),j.map(e=>(0,_.jsx)(`option`,{value:e,children:e},e))]}),(0,_.jsxs)(`select`,{value:g,onChange:e=>Z({model:e.target.value||void 0}),disabled:N.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,_.jsx)(`option`,{value:``,children:N.length>0?`All Models`:`Models —`}),N.map(e=>(0,_.jsx)(`option`,{value:e,children:e},e))]}),(0,_.jsx)(`button`,{type:`button`,onClick:()=>void Promise.all([U(),q()]),disabled:W,"aria-label":`Reload`,title:`Reload`,className:`p-1 rounded text-sand-400 hover:text-sand-600 disabled:opacity-30 transition-colors`,children:(0,_.jsx)(h,{className:W?`size-3.5 animate-spin`:`size-3.5`})}),(0,_.jsx)(`div`,{className:`flex-1`}),(0,_.jsxs)(`span`,{className:`text-[11px] text-sand-400`,children:[H||!B?`—`:Y,` results`]}),K?(0,_.jsx)(`span`,{role:`alert`,className:`text-[11px] text-danger-500`,children:`Failed to load total cost.`}):(0,_.jsx)(`span`,{className:`text-[11px] tabular-nums font-medium text-sienna-600`,children:G?p(G.usd):`—`})]}),H?(0,_.jsx)(`div`,{role:`alert`,className:`text-danger-500 text-center py-12 text-sm`,children:`Failed to load request logs.`}):V?(0,_.jsx)(`div`,{className:`space-y-2`,children:Array.from({length:5}).map((e,t)=>(0,_.jsx)(`div`,{className:`h-8 bg-sand-100 rounded animate-pulse`},`skel-${t}`))}):J.length===0?(0,_.jsx)(`div`,{className:`text-sand-400 text-center py-12 text-sm`,children:`No requests yet.`}):(0,_.jsxs)(_.Fragment,{children:[(0,_.jsx)(`div`,{className:`overflow-x-auto px-3 py-3 sm:px-5`,children:(0,_.jsxs)(`table`,{className:`w-full min-w-[900px] text-[13px]`,children:[(0,_.jsx)(`thead`,{children:(0,_.jsxs)(`tr`,{className:`border-b border-sand-100/60`,children:[D.map(e=>{let t=e.label===`Duration`?`pl-5 pr-3`:e.width?`px-4`:`px-3`,n=e.sortKey===R;return(0,_.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,_.jsxs)(`button`,{type:`button`,onClick:()=>Z({sort:l.parse(`${e.sortKey}-${n&&z===`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,_.jsx)(`span`,{className:n?``:`text-sand-300`,children:n?z===`desc`?`↓`:`↑`:`↕`})]}):e.label},e.label)}),(0,_.jsx)(`th`,{className:`w-8`})]})}),(0,_.jsx)(`tbody`,{className:`divide-y divide-sand-100/60`,children:J.map(t=>(0,_.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,_.jsx)(`td`,{className:`px-4 py-1.5 whitespace-nowrap`,children:(0,_.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,_.jsx)(`td`,{className:`px-4 py-1.5 whitespace-nowrap`,children:(0,_.jsx)(`span`,{className:`text-xs text-sand-400 tabular-nums`,children:S(t.created_at)})}),(0,_.jsx)(`td`,{className:`px-4 py-1.5 whitespace-nowrap`,children:(0,_.jsx)(`span`,{className:`text-xs text-sand-600`,children:t.project_name??`—`})}),(0,_.jsx)(`td`,{className:`px-4 py-1.5 whitespace-nowrap`,children:(0,_.jsx)(`span`,{className:`text-xs text-sand-500`,children:t.token_name})}),(0,_.jsxs)(`td`,{className:`px-4 py-1.5 whitespace-nowrap`,children:[(0,_.jsx)(T,{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,_.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,_.jsx)(`td`,{className:`px-4 py-1.5 whitespace-nowrap`,children:t.is_structured?(0,_.jsx)(`span`,{className:`rounded bg-sienna-100 px-1.5 py-0.5 font-mono text-[10px] text-sienna-700`,children:`json`}):(0,_.jsx)(`span`,{className:`font-mono text-[10px] text-sand-400`,children:`text`})}),(0,_.jsx)(`td`,{className:`px-4 py-1.5 text-right tabular-nums text-sand-500 whitespace-nowrap`,children:E(t.ttft_ms)}),(0,_.jsx)(`td`,{className:`pl-5 pr-3 py-1.5 text-right tabular-nums text-sand-500 whitespace-nowrap`,children:w(t.duration_ms)}),(0,_.jsx)(`td`,{className:`px-3 py-1.5 text-right tabular-nums text-sand-700`,children:C(t.input_tokens)}),(0,_.jsx)(`td`,{className:`px-3 py-1.5 text-right tabular-nums text-sand-700`,children:C(t.output_tokens)}),(0,_.jsx)(`td`,{className:`px-3 py-1.5 text-right tabular-nums text-sand-700`,children:C(t.cache_read_tokens)}),(0,_.jsx)(`td`,{className:`px-3 py-1.5 text-right tabular-nums text-sand-700`,children:C(t.cache_creation_tokens)}),(0,_.jsx)(`td`,{className:`px-3 py-1.5 text-right tabular-nums text-sand-700`,children:m(t)}),(0,_.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,_.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,_.jsx)(`td`,{className:`px-2 py-1.5`,children:(0,_.jsx)(y,{className:`size-4 text-sand-400`})})]},t.id))})]})}),X>1&&(0,_.jsxs)(`div`,{className:`flex items-center justify-center gap-3 px-5 py-2.5 border-t border-sand-100/60`,children:[(0,_.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,_.jsx)(v,{className:`size-4`})}),(0,_.jsxs)(`span`,{className:`text-[11px] text-sand-400 tabular-nums`,children:[a,` / `,X]}),(0,_.jsx)(`button`,{type:`button`,className:`p-1 rounded text-sand-400 hover:text-sand-600 disabled:opacity-30 transition-colors`,disabled:a===X,onClick:()=>r({...n,page:a+1}),children:(0,_.jsx)(y,{className:`size-4`})})]})]})]})}a({token:i().optional(),project:i().optional(),model:i().optional(),sort:l.optional(),page:d.shape.page.default(1)});function k(){let e=u.useSearch(),t=u.useNavigate();return(0,_.jsx)(`div`,{className:`max-w-[100rem] mx-auto`,children:(0,_.jsx)(O,{search:e,onSearchChange:e=>t({search:e})})})}export{k as component};
|