@cartanova/qgrid-cli 2.9.9 → 2.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (26) hide show
  1. package/bundle/dist/application/qgrid/qgrid.frame.js +7 -2
  2. package/bundle/dist/application/qgrid/qgrid.types.js +3 -1
  3. package/bundle/dist/utils/providers/common/model-cost.js +9 -1
  4. package/bundle/src/application/qgrid/qgrid.frame.test.ts +3 -2
  5. package/bundle/src/application/qgrid/qgrid.frame.ts +9 -3
  6. package/bundle/src/application/qgrid/qgrid.types.ts +2 -0
  7. package/bundle/src/utils/providers/common/effort.test.ts +1 -0
  8. package/bundle/src/utils/providers/common/model-cost.test.ts +4 -0
  9. package/bundle/src/utils/providers/common/model-cost.ts +12 -0
  10. package/bundle/src/utils/providers/openai/openai-dispatcher.test.ts +1 -0
  11. package/bundle/web-dist/client/assets/{index-D8VwLsuq.js → index-BfwrIBHs.js} +3 -3
  12. package/bundle/web-dist/client/assets/{logs-_T8KV5ne.js → logs-Brit-LqB.js} +1 -1
  13. package/bundle/web-dist/client/assets/{monit-DRCrtO2j.js → monit-DrYZkisv.js} +1 -1
  14. package/bundle/web-dist/client/assets/{routes-5A6mia6C.js → routes-C8Y6olae.js} +1 -1
  15. package/bundle/web-dist/client/assets/{settings-BpP9WVFI.js → settings-CdVqtDQ5.js} +1 -1
  16. package/bundle/web-dist/client/assets/{show-D5ifZXdy.js → show-2B2X9MkO.js} +1 -1
  17. package/bundle/web-dist/client/assets/{tokens-Cfe6WvLK.js → tokens-CxXtdk9o.js} +1 -1
  18. package/bundle/web-dist/client/assets/{use-oauth-login-flow-BTLUGhwh.js → use-oauth-login-flow-B9EqnwY9.js} +1 -1
  19. package/bundle/web-dist/client/index.html +1 -1
  20. package/bundle/web-dist/server/entry-server.generated.js +3 -3
  21. package/package.json +1 -1
  22. package/skills/qgrid/SKILL.md +6 -0
  23. package/skills/qgrid/references/ai-sdk-provider-contract.md +4 -0
  24. package/skills/qgrid/references/openai-codex-runtime.md +16 -2
  25. package/skills/qgrid/references/request-log-run-lifecycle.md +2 -0
  26. package/skills/qgrid/references/sonamu-api-web-flow.md +1 -1
@@ -271,6 +271,7 @@ describe("QgridFrame.query request logging", () => {
271
271
  expect(beforeQueryMock).toHaveBeenCalledWith(args);
272
272
  expect(afterQueryMock).toHaveBeenCalledWith(41, 0, args, expect.objectContaining({ text: "hello" }));
273
273
  expect(result.runContext).toEqual(queryOutput().runContext);
274
+ expect(result.requestLogId).toBe(41);
274
275
  });
275
276
 
276
277
  it("tokenName 을 활성 토큰 id 로 해석해 지정 요청으로 전달한다", async () => {
@@ -459,7 +460,7 @@ describe("QgridFrame.query request logging", () => {
459
460
  afterQueryMock.mockRejectedValueOnce(new Error("request log unavailable"));
460
461
  const args = { prompt: "hi", model: "openai/gpt-5-codex" };
461
462
 
462
- await expect(QgridFrame.query(args)).resolves.toBe(output);
463
+ await expect(QgridFrame.query(args)).resolves.toEqual({ ...output, requestLogId: 41 });
463
464
 
464
465
  expect(finishRunWithErrorMock).toHaveBeenCalledWith(41, "request log unavailable", args);
465
466
  });
@@ -1065,7 +1066,7 @@ describe("QgridFrame.queryStream request logging", () => {
1065
1066
  expect(order).toEqual(["before", "dispatch", "after"]);
1066
1067
  expect(sse.publish).toHaveBeenCalledWith(
1067
1068
  "done",
1068
- expect.objectContaining({ runContext: streamOutput().runContext }),
1069
+ expect.objectContaining({ requestLogId: 52, runContext: streamOutput().runContext }),
1069
1070
  );
1070
1071
  });
1071
1072
 
@@ -281,7 +281,7 @@ class QgridFrameClass extends BaseFrameClass {
281
281
  lifecycle.runContext || threadCoord
282
282
  ? { ...lifecycle.runContext, ...(threadCoord ? { threadCoord } : {}) }
283
283
  : undefined;
284
- return { ...result, runContext };
284
+ return { ...result, requestLogId, runContext };
285
285
  } catch (e) {
286
286
  logger.error(`query afterQuery failed: ${(e as Error).message}`);
287
287
  if (disconnect.signal.aborted) {
@@ -290,7 +290,7 @@ class QgridFrameClass extends BaseFrameClass {
290
290
  await finishRunWithError(requestLogId, (e as Error).message, resolvedArgs);
291
291
  }
292
292
  // provider 응답은 성공했으므로 로깅 장애가 생성 결과를 덮어쓰지 않는다.
293
- return result;
293
+ return { ...result, requestLogId };
294
294
  }
295
295
  } finally {
296
296
  disconnect.dispose();
@@ -407,7 +407,13 @@ class QgridFrameClass extends BaseFrameClass {
407
407
  }
408
408
  }
409
409
  }
410
- if (!clientClosed && !sse.closed) sse.publish("done", { ...streamResult, runContext });
410
+ if (!clientClosed && !sse.closed) {
411
+ sse.publish("done", {
412
+ ...streamResult,
413
+ ...(runInfo ? { requestLogId: runInfo.requestLogId } : {}),
414
+ runContext,
415
+ });
416
+ }
411
417
  } else if (streamError) {
412
418
  if (runInfo) await finishRunWithError(runInfo.requestLogId, streamError.message, args);
413
419
  if (!clientClosed && !sse.closed) sse.publish("error", { message: streamError.message });
@@ -187,6 +187,7 @@ export const CostSource = z.enum(["provider", "pricing_table", "mixed"]);
187
187
  export type CostSource = z.infer<typeof CostSource>;
188
188
 
189
189
  export const QueryOutput = z.object({
190
+ requestLogId: z.number().optional(),
190
191
  text: z.string(),
191
192
  content: z.array(QgridContent),
192
193
  finishReason: FinishReason,
@@ -221,6 +222,7 @@ export const StreamEvents = z.object({
221
222
  input: z.string(),
222
223
  }),
223
224
  done: z.object({
225
+ requestLogId: z.number().optional(),
224
226
  text: z.string(),
225
227
  model: z.string().optional(),
226
228
  requestedModel: z.string().optional(),
@@ -23,6 +23,7 @@ describe("resolveOpenAIEffort", () => {
23
23
  expect(resolveOpenAIEffort("gpt-5.6-terra", "max")).toBe("max");
24
24
  expect(resolveOpenAIEffort("gpt-5.6-terra", "ultra")).toBe("ultra");
25
25
  expect(resolveOpenAIEffort("gpt-5.6-luna", "max")).toBe("max");
26
+ expect(resolveOpenAIEffort("gpt-6.1-sol", "ultra")).toBe("ultra");
26
27
  expect(resolveOpenAIEffort("gpt-6-sol", "ultra")).toBe("ultra");
27
28
  expect(resolveOpenAIEffort("gpt-6-luna", "max")).toBe("max");
28
29
  });
@@ -13,6 +13,7 @@ describe("calculateCostUsd", () => {
13
13
  });
14
14
  it.each([
15
15
  ["gpt-6-astra", 10, 50, 1, 12.5],
16
+ ["gpt-6.1-sol", 2, 10, 0.1, 2.5],
16
17
  ["gpt-6-sol", 2, 10, 0.2, 2.5],
17
18
  ["gpt-6-luna", 0.1, 0.5, 0.01, 0.125],
18
19
  ["gpt-5.6-sol", 4, 20, 0.4, 5],
@@ -97,6 +98,7 @@ describe("calculateCostUsd", () => {
97
98
 
98
99
  it.each([
99
100
  ["gpt-6-astra", 10, 50, 1, 12.5, 5.6125],
101
+ ["gpt-6.1-sol", 2, 10, 0.1, 2.5, 1.1175],
100
102
  ["gpt-6-sol", 2, 10, 0.2, 2.5, 1.1225],
101
103
  ["gpt-6-luna", 0.1, 0.5, 0.01, 0.125, 0.056125],
102
104
  ["gpt-5.6-sol", 4, 20, 0.4, 5, 2.245],
@@ -125,6 +127,7 @@ describe("calculateCostUsd", () => {
125
127
 
126
128
  it.each([
127
129
  ["gpt-6-astra", 2.475],
130
+ ["gpt-6.1-sol", 0.455],
128
131
  ["gpt-6-sol", 0.495],
129
132
  ["gpt-6-luna", 0.02475],
130
133
  ["gpt-5.6-sol", 0.99],
@@ -142,6 +145,7 @@ describe("calculateCostUsd", () => {
142
145
 
143
146
  it.each([
144
147
  ["gpt-6-astra", 2.725],
148
+ ["gpt-6.1-sol", 0.505],
145
149
  ["gpt-6-sol", 0.545],
146
150
  ["gpt-6-luna", 0.02725],
147
151
  ["gpt-5.6-sol", 1.09],
@@ -65,6 +65,18 @@ const OPENAI_COSTS: Record<string, OpenAIModelSpec> = {
65
65
  cacheCreationInputTokens: 12.5,
66
66
  longContext: LONG_CONTEXT_272K,
67
67
  },
68
+ // GPT-6.1 Sol (2026-09-29 DevDay 출시): Standard API pricing verified 2026-09-30. GPT-6 Sol 과 같고 cached input 만 절반.
69
+ // Codex 카탈로그(2026-09-30)는 ultra 까지 허용하고 기본 effort 는 low 다(GPT-6 Sol 은 medium).
70
+ // qgrid 의 요청 형태 + codex_cli_rs/0.147.0 헤더로 2026-09-30 구독 경로 라이브 생성 성공.
71
+ // @see https://developers.openai.com/api/docs/models/gpt-6.1-sol
72
+ "gpt-6.1-sol": {
73
+ maxEffort: "ultra",
74
+ inputTokens: 2,
75
+ outputTokens: 10,
76
+ cachedInputTokens: 0.1,
77
+ cacheCreationInputTokens: 2.5,
78
+ longContext: LONG_CONTEXT_272K,
79
+ },
68
80
  // GPT-6 Sol, Luna (2026-09-22 출시): Standard API pricing verified 2026-09-23. GPT-5.6 Sol/Luna 의 절반 단가.
69
81
  // Codex 카탈로그(2026-09-23)는 Sol 에 ultra, Luna 에 max 까지 허용하고 기본 effort 는 둘 다 medium 이다.
70
82
  // @see https://developers.openai.com/api/docs/models/gpt-6-sol
@@ -698,6 +698,7 @@ describe("effort 어휘 해석 (Codex 카탈로그 기준)", () => {
698
698
 
699
699
  it("모델이 지원하는 값은 그대로 보내고, 상한 초과·공개 API 어휘는 reasoning 에서 빼 백엔드 기본값을 쓴다", async () => {
700
700
  await expect(mappedEffortFor("gpt-6-astra", "ultra")).resolves.toBe("ultra");
701
+ await expect(mappedEffortFor("gpt-6.1-sol", "ultra")).resolves.toBe("ultra");
701
702
  await expect(mappedEffortFor("gpt-6-sol", "ultra")).resolves.toBe("ultra");
702
703
  await expect(mappedEffortFor("gpt-6-luna", "max")).resolves.toBe("max");
703
704
  await expect(mappedEffortFor("gpt-6-luna", "ultra")).resolves.toBeUndefined();