@cartanova/qgrid-ai-sdk 2.4.7 → 2.4.8

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 CHANGED
@@ -139,6 +139,9 @@ AI SDK가 tool 실행을 관리하고, qgrid는 각 턴의 LLM 호출만 담당
139
139
  ### Provider Options
140
140
 
141
141
  qgrid 전용 옵션은 전부 `providerOptions.qgrid` 네임스페이스로 전달합니다. (`providerOptions.openai`가 아닙니다)
142
+ AI SDK는 바깥 `providerOptions`를 범용 JSON record로 타입 선언하므로 qgrid 옵션을 자동 추론하지 못합니다.
143
+ 따라서 공개 타입 `QgridProviderOptions`를 중첩된 `qgrid` 값에 `satisfies`로 적용하세요. literal 추론을
144
+ 유지하면서 qgrid 옵션의 오타와 잘못된 값을 컴파일 타임에 잡을 수 있습니다.
142
145
 
143
146
  ```typescript
144
147
  import { generateText } from "ai";
@@ -166,7 +169,7 @@ const { text } = await generateText({
166
169
  | `serviceTier` | `string` | OpenAI 전용 | OpenAI/codex service tier |
167
170
  | `imageGeneration` | `boolean` | OpenAI 전용, non-stream | codex 내장 `image_generation` tool 활성화 ([아래](#image-generation) 참조) |
168
171
  | `imageGenerationOptions` | `{ quality?, size? }` | OpenAI 전용 | 이미지 품질/크기 힌트. `quality: "low" \| "medium" \| "high"`, `size: "1024x1024" \| "1024x1536" \| "1536x1024"` (기본: `medium` / `1536x1024`) |
169
- | `fallbackModels` | `string[]` | 예약 | 향후 서버 fallback routing용 예약 필드. 현재 동작하지 않음 |
172
+ | `fallbackModels` | `string[]` | 예약 | 향후 qgrid 서버 fallback routing용 예약 필드. 현재 동작하지 않으며 Claude Code의 Fable refusal fallback과 무관 |
170
173
 
171
174
  ### 멀티턴 prompt cache (sessionKey)
172
175
 
@@ -279,6 +282,7 @@ type QgridSupportedModel =
279
282
  | "openai/gpt-5.3-codex"
280
283
  | "openai/gpt-5.3-codex-spark"
281
284
  // Anthropic
285
+ | "anthropic/claude-fable-5"
282
286
  | "anthropic/claude-haiku-4-5"
283
287
  | "anthropic/claude-sonnet-4"
284
288
  | "anthropic/claude-sonnet-4-5"
@@ -303,6 +307,12 @@ type QgridSupportedModel =
303
307
 
304
308
  세 모델 모두 `max` reasoning effort를 지원합니다. OpenAI native API 사양은 1.05M context / 128K 최대 출력이지만, qgrid는 codex app-server 구독 경로로 실행되어 세 모델 모두 context window가 372K(95% effective, 실사용 입력 약 353K)로 보고되며 설정으로 올릴 수 없습니다. 입력이 272K tokens를 넘으면 요청 전체에 input 2x, output 1.5x 장문 컨텍스트 할증이 적용되며, cache write는 uncached input 단가의 1.25x입니다.
305
309
 
310
+ `anthropic/claude-fable-5`는 1M context와 128K 최대 출력을 지원합니다. 1M tokens당 표준 단가는 input $10, cache read $1, 5분 cache write $12.50, 1시간 cache write $20, output $50입니다. qgrid는 Claude 응답의 5분/1시간 cache creation breakdown을 보존해 TTL별 단가를 각각 적용하며, breakdown이 없는 구버전 응답에서만 Claude Code가 subscription OAuth 경로에 자동 적용하는 1시간 TTL 단가로 fallback합니다. Fable은 adaptive thinking이 항상 켜져 있어야 하므로 qgrid는 이 모델에서만 adaptive thinking을 보존하고, 기존 Anthropic 모델은 계속 thinking을 비활성화합니다.
311
+
312
+ Claude Code는 Fable의 safety refusal을 Opus 4.8로 자동 재시도할 수 있습니다. 이 경우 AI SDK 응답의 `response.modelId`와 `providerMetadata.qgrid.model`은 실제 serving 모델인 Opus를 가리킵니다. `providerMetadata.qgrid.requestedModel`은 Fable로 유지되고, `providerMetadata.qgrid.modelFallbacks`에 refusal fallback 이력이 담깁니다. 같은 metadata에서 `costSource`와 5분/1시간 cache-write 토큰 분해도 확인할 수 있습니다.
313
+
314
+ `openai/gpt-5.3-codex-spark`는 아직 token 단가가 확정·공개되지 않은 research preview입니다. 따라서 qgrid는 generic fallback 추정치를 보고하며, 이를 공식 단가로 취급하지 않습니다.
315
+
306
316
  ## 설정
307
317
 
308
318
  ```typescript
package/README.md CHANGED
@@ -139,6 +139,9 @@ The AI SDK manages tool execution; qgrid handles only each turn's LLM call.
139
139
  ### Provider Options
140
140
 
141
141
  All qgrid-specific options go under the `providerOptions.qgrid` namespace. (Not `providerOptions.openai`.)
142
+ AI SDK types the outer `providerOptions` as a generic JSON record, so apply the exported
143
+ `QgridProviderOptions` type to the nested `qgrid` value with `satisfies`. This preserves
144
+ literal inference and catches misspelled or invalid qgrid options at compile time.
142
145
 
143
146
  ```typescript
144
147
  import { generateText } from "ai";
@@ -166,7 +169,7 @@ const { text } = await generateText({
166
169
  | `serviceTier` | `string` | OpenAI only | OpenAI/codex service tier |
167
170
  | `imageGeneration` | `boolean` | OpenAI only, non-stream | Enables codex's built-in `image_generation` tool (see [below](#image-generation)) |
168
171
  | `imageGenerationOptions` | `{ quality?, size? }` | OpenAI only | Image quality/size hints. `quality: "low" \| "medium" \| "high"`, `size: "1024x1024" \| "1024x1536" \| "1536x1024"` (defaults: `medium` / `1536x1024`) |
169
- | `fallbackModels` | `string[]` | reserved | Reserved for future server-side fallback routing. Not functional yet |
172
+ | `fallbackModels` | `string[]` | reserved | Reserved for future qgrid server-side fallback routing. Not functional yet and unrelated to Claude Code's Fable refusal fallback |
170
173
 
171
174
  ### Multi-turn prompt cache (sessionKey)
172
175
 
@@ -279,6 +282,7 @@ type QgridSupportedModel =
279
282
  | "openai/gpt-5.3-codex"
280
283
  | "openai/gpt-5.3-codex-spark"
281
284
  // Anthropic
285
+ | "anthropic/claude-fable-5"
282
286
  | "anthropic/claude-haiku-4-5"
283
287
  | "anthropic/claude-sonnet-4"
284
288
  | "anthropic/claude-sonnet-4-5"
@@ -303,6 +307,12 @@ type QgridSupportedModel =
303
307
 
304
308
  All GPT-5.6 models support reasoning through `max`. The OpenAI native API spec is a 1.05M context window with 128K max output, but qgrid runs on the codex app-server subscription path, where all three models report a 372K context window (95% effective — about 353K of usable input) that cannot be raised by configuration. Prompts over 272K input tokens apply a 2x input and 1.5x output surcharge to the full request; cache writes cost 1.25x the uncached input rate.
305
309
 
310
+ `anthropic/claude-fable-5` has a 1M context window and 128K max output. Its standard prices per 1M tokens are $10 input, $1 cache read, $12.50 five-minute cache write, $20 one-hour cache write, and $50 output. qgrid preserves Claude's 5m/1h cache-creation breakdown and prices each TTL separately; only legacy responses without that breakdown fall back to the one-hour TTL automatically selected by Claude Code on subscription OAuth. Fable requires always-on adaptive thinking, so qgrid preserves adaptive thinking for this model while continuing to disable thinking for existing Anthropic models.
311
+
312
+ Claude Code may automatically retry a Fable safety refusal on Opus 4.8. In that case, the AI SDK response's `response.modelId` and `providerMetadata.qgrid.model` identify Opus as the actual serving model. `providerMetadata.qgrid.requestedModel` remains Fable, and `providerMetadata.qgrid.modelFallbacks` contains the refusal fallback history. The metadata also exposes `costSource` and the 5m/1h cache-write token split.
313
+
314
+ `openai/gpt-5.3-codex-spark` remains a research preview without final published per-token rates. qgrid therefore reports its generic fallback estimate rather than presenting that estimate as official pricing.
315
+
306
316
  ## Configuration
307
317
 
308
318
  ```typescript
package/dist/index.d.ts CHANGED
@@ -27,7 +27,10 @@ type QgridProviderOptions = {
27
27
  reasoningSummary?: "auto" | "concise" | "detailed" | "none";
28
28
  /** OpenAI/codex service tier. OpenAI/codex route에서만 적용된다. */
29
29
  serviceTier?: string;
30
- /** @todo 향후 qgrid 서버 fallback routing에 사용할 후보 모델 목록. */
30
+ /**
31
+ * @todo 향후 qgrid 서버 fallback routing에 사용할 후보 모델 목록.
32
+ * Claude Code가 처리하는 Fable 5 safety-refusal fallback과는 무관하다.
33
+ */
31
34
  fallbackModels?: string[];
32
35
  /**
33
36
  * codex 내장 image_generation tool 을 켠다. OpenAI/codex route + non-stream 전용.
@@ -50,7 +53,7 @@ type QgridProviderOptions = {
50
53
  * provider 내부 threadCoordStore 가 sessionKey 별로 관리
51
54
  */
52
55
 
53
- type QgridSupportedModel = "openai/gpt-5.6-sol" | "openai/gpt-5.6-terra" | "openai/gpt-5.6-luna" | "openai/gpt-5.5" | "openai/gpt-5.4" | "openai/gpt-5.2" | "openai/gpt-5.4-mini" | "openai/gpt-5.3-codex" | "openai/gpt-5.3-codex-spark" | "anthropic/claude-haiku-4-5" | "anthropic/claude-sonnet-4" | "anthropic/claude-sonnet-4-5" | "anthropic/claude-sonnet-4-6" | "anthropic/claude-sonnet-4-7" | "anthropic/claude-sonnet-5" | "anthropic/claude-opus-4" | "anthropic/claude-opus-4-1" | "anthropic/claude-opus-4-5" | "anthropic/claude-opus-4-6" | "anthropic/claude-opus-4-7" | "anthropic/claude-opus-4-8";
56
+ type QgridSupportedModel = "openai/gpt-5.6-sol" | "openai/gpt-5.6-terra" | "openai/gpt-5.6-luna" | "openai/gpt-5.5" | "openai/gpt-5.4" | "openai/gpt-5.2" | "openai/gpt-5.4-mini" | "openai/gpt-5.3-codex" | "openai/gpt-5.3-codex-spark" | "anthropic/claude-fable-5" | "anthropic/claude-haiku-4-5" | "anthropic/claude-sonnet-4" | "anthropic/claude-sonnet-4-5" | "anthropic/claude-sonnet-4-6" | "anthropic/claude-sonnet-4-7" | "anthropic/claude-sonnet-5" | "anthropic/claude-opus-4" | "anthropic/claude-opus-4-1" | "anthropic/claude-opus-4-5" | "anthropic/claude-opus-4-6" | "anthropic/claude-opus-4-7" | "anthropic/claude-opus-4-8";
54
57
  type QgridLoggerConfig = {
55
58
  /** qgrid 서버 주소. default: process.env.QGRID_URL, 없으면 기본값은 "http://localhost:44900" */
56
59
  serverUrl?: string;
package/dist/index.js CHANGED
@@ -632,6 +632,19 @@ function setThreadCoord(sessionKey, coord) {
632
632
  expiresAt: Date.now() + THREAD_COORD_TTL_MS
633
633
  });
634
634
  }
635
+ function qgridProviderMetadata(data) {
636
+ return { qgrid: {
637
+ model: data.model,
638
+ requestedModel: data.requestedModel ?? data.model,
639
+ modelFallbacks: data.modelFallbacks ?? [],
640
+ tokenName: data.tokenName ?? null,
641
+ durationMs: data.durationMs,
642
+ costUsd: data.costUsd,
643
+ costSource: data.costSource,
644
+ cacheCreation5mInputTokens: data.usage.cache_creation_5m_input_tokens ?? null,
645
+ cacheCreation1hInputTokens: data.usage.cache_creation_1h_input_tokens ?? null
646
+ } };
647
+ }
635
648
  function reusableSessionKey(modelId, sessionKey) {
636
649
  return modelId.startsWith("anthropic/") ? void 0 : sessionKey;
637
650
  }
@@ -796,12 +809,7 @@ function qgrid(modelId, config) {
796
809
  finishReason,
797
810
  usage: toAiSdkUsage(data.usage),
798
811
  warnings: [],
799
- providerMetadata: { qgrid: {
800
- model: data.model,
801
- tokenName: data.tokenName ?? null,
802
- durationMs: data.durationMs,
803
- costUsd: data.costUsd
804
- } },
812
+ providerMetadata: qgridProviderMetadata(data),
805
813
  response: { modelId: data.model }
806
814
  };
807
815
  },
@@ -936,6 +944,10 @@ function qgrid(modelId, config) {
936
944
  });
937
945
  }
938
946
  }
947
+ controller.enqueue({
948
+ type: "response-metadata",
949
+ modelId: done.model
950
+ });
939
951
  controller.enqueue({
940
952
  type: "finish",
941
953
  finishReason: done.finishReason === "tool-calls" ? {
@@ -945,7 +957,8 @@ function qgrid(modelId, config) {
945
957
  unified: "stop",
946
958
  raw: "stop"
947
959
  },
948
- usage: toAiSdkUsage(done.usage)
960
+ usage: toAiSdkUsage(done.usage),
961
+ providerMetadata: qgridProviderMetadata(done)
949
962
  });
950
963
  streamCompleted = true;
951
964
  controller.close();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cartanova/qgrid-ai-sdk",
3
- "version": "2.4.7",
3
+ "version": "2.4.8",
4
4
  "description": "AI SDK LanguageModelV3 provider for qgrid",
5
5
  "repository": {
6
6
  "type": "git",