@cartanova/qgrid-cli 2.10.4 → 2.10.5
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/qgrid/qgrid-image-generation.js +6 -2
- package/bundle/dist/application/qgrid/qgrid-response-format.js +4 -4
- package/bundle/dist/application/qgrid/qgrid.frame.js +2 -2
- package/bundle/dist/application/qgrid/qgrid.types.js +4 -8
- package/bundle/dist/application/request-log/request-log.model.js +21 -15
- package/bundle/dist/utils/providers/openai/openai-backend-protocol.js +19 -8
- package/bundle/src/application/qgrid/qgrid-image-generation.test.ts +18 -0
- package/bundle/src/application/qgrid/qgrid-image-generation.ts +14 -3
- package/bundle/src/application/qgrid/qgrid-response-format.test.ts +9 -0
- package/bundle/src/application/qgrid/qgrid-response-format.ts +10 -7
- package/bundle/src/application/qgrid/qgrid.frame.ts +4 -2
- package/bundle/src/application/qgrid/qgrid.types.ts +14 -4
- 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/utils/providers/openai/openai-backend-protocol.test.ts +19 -1
- package/bundle/src/utils/providers/openai/openai-backend-protocol.ts +22 -0
- package/bundle/src/utils/providers/openai/openai-dispatcher.test.ts +12 -0
- package/bundle/web-dist/client/assets/cost-CY2BJEPC.js +1 -0
- package/bundle/web-dist/client/assets/{index-reW8VvJF.js → index-Dxw7DiXF.js} +3 -3
- package/bundle/web-dist/client/assets/logs-3n_U4qnI.js +1 -0
- package/bundle/web-dist/client/assets/{monit-DkABv7PG.js → monit-E8eGW1Sj.js} +1 -1
- package/bundle/web-dist/client/assets/{routes-BRmQ4M3-.js → routes-7spLfIGZ.js} +2 -2
- package/bundle/web-dist/client/assets/{settings-BHvtycEZ.js → settings-BdosZFNC.js} +1 -1
- package/bundle/web-dist/client/assets/{show-qeTIzgDZ.js → show-b2PFNI3D.js} +1 -1
- package/bundle/web-dist/client/assets/{tokens-5Bep_G-w.js → tokens-CBdHb2_U.js} +1 -1
- package/bundle/web-dist/client/assets/{use-oauth-login-flow-Cx-QO25M.js → use-oauth-login-flow-Cyn3YPqW.js} +1 -1
- package/bundle/web-dist/client/index.html +1 -1
- package/bundle/web-dist/server/assets/{cost-CSH_t17I.js → cost-59jBdx-I.js} +8 -3
- package/bundle/web-dist/server/assets/{logs-CagNGTBj.js → logs-CaaWO9-Z.js} +6 -4
- package/bundle/web-dist/server/assets/{monit-DSxs4Jnl.js → monit-CBil92fJ.js} +1 -1
- package/bundle/web-dist/server/assets/{routes-i-sTqXMX.js → routes-DtVf9yqo.js} +3 -3
- package/bundle/web-dist/server/assets/{show-C4jk1Hrp.js → show-8NNdRxhM.js} +1 -1
- package/bundle/web-dist/server/entry-server.generated.js +5 -5
- package/package.json +3 -2
- package/skills/qgrid/SKILL.md +1 -1
- package/skills/qgrid/references/ai-sdk-provider-contract.md +1 -1
- package/skills/qgrid/references/decision-rationale.md +2 -2
- package/skills/qgrid/references/openai-codex-runtime.md +5 -1
- package/bundle/web-dist/client/assets/cost-CpjVoAqp.js +0 -1
- package/bundle/web-dist/client/assets/logs-DDIt97D1.js +0 -1
|
@@ -179,7 +179,7 @@ Quota is fetched directly from `https://chatgpt.com/backend-api/wham/usage` with
|
|
|
179
179
|
|
|
180
180
|
OpenAI usage reports total input, cached input, output, reasoning, and total tokens for the request. Preserve cached input as a subset of input; do not add it to input again when computing cache-hit rate.
|
|
181
181
|
|
|
182
|
-
Image generation is opt-in and non-stream at the AI SDK interface. The backend still delivers its response through SSE. `imageGenerationOptions.outputFormat` maps to the hosted tool's `output_format` (`png`, `jpeg`, or `webp`); omission retains PNG. Returned bytes determine the MIME type when recognizable, with the reported format as fallback. Preserve that type through qgrid content, AI SDK file parts, and request-log image data URLs. The standalone transparent route remains PNG-only and rejects other output formats.
|
|
182
|
+
Image generation is opt-in and non-stream at the AI SDK interface. The backend still delivers its response through SSE. `imageGenerationOptions.outputFormat` maps to the hosted tool's `output_format` (`png`, `jpeg`, or `webp`); omission retains PNG. Returned bytes determine the MIME type when recognizable, with the reported format as fallback. Preserve that type through qgrid content, AI SDK file parts, and request-log image data URLs. The standalone transparent route remains PNG-only and rejects other output formats. Hosted Responses preserves observed image settings with route `codex-responses`, using PNG byte dimensions or the backend-reported JPEG/WebP size. Unreported model/settings stay absent. Hosted image cost is null because exact image usage/model are unavailable; requested settings cannot establish a price. Legacy responses without observations retain known three-size estimates only.
|
|
183
183
|
|
|
184
184
|
### Transparent image route
|
|
185
185
|
|
|
@@ -196,3 +196,7 @@ Auto mode accepts text-only completion when no image tool was attempted. Explici
|
|
|
196
196
|
Auto transparent turns preserve the Responses driver model and token usage; image model, settings, and usage remain separate generation metadata. Do not apply the explicit standalone route's zero-driver accounting to auto turns. Full image history is replayed on each turn without reusable provider conversation state. Global image-tool opt-in remains unchanged outside chat to preserve regular callers' tool framing and cache behavior.
|
|
197
197
|
|
|
198
198
|
The 2026-09-29 hosted-route probe returned PNG for a prompt-only WebP request and WebP for explicit `imageGenerationOptions.outputFormat: "webp"`. Verify bytes rather than model claims. The standalone transparent endpoint still returns PNG; no format conversion is added. See `output/webp-prompt-probe-2026-09-29/verification.md` and `docs/solutions/architecture-patterns/qgrid-native-auto-image-generation-2.9.8.md`.
|
|
199
|
+
|
|
200
|
+
### Size hints and observed dimensions (2026-10-13)
|
|
201
|
+
|
|
202
|
+
`size` accepts `auto` or positive-integer WIDTHxHEIGHT hints. Keep the requested value separate from observed output metadata; do not promise exact dimensions or inject a resize. Prompt for the desired ratio. Twelve live subscription requests across hosted Responses and standalone generation/edit returned 841x1870 for 9:20, 941x1672 for 4K portrait, and 2172x724 for 4:1 (clamped to 3:1). Explicit 1152x2560 and even 1x1 hints returned 1254x1254 for a neutral prompt. These approximately 1.57MP observations are not a universal limit. Public API limits (16-pixel multiples, up to 4K) are not the private backend contract. Latest upstream Codex at `12cca49c81c8aa6a37a5cc4e39964ee3b70f9458` hardcodes `size: auto` for image generation/editing and saves bytes without resizing.
|
|
@@ -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};
|