@cartanova/qgrid-cli 2.6.11 → 2.7.1

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 (153) hide show
  1. package/bundle/dist/_virtual/_rolldown/runtime.js +20 -1
  2. package/bundle/dist/application/qgrid/qgrid.dispatcher.js +17 -6
  3. package/bundle/dist/application/qgrid/qgrid.frame.js +1 -1
  4. package/bundle/dist/application/qgrid/schema-prompt.js +240 -0
  5. package/bundle/dist/application/qgrid/tool-emulation.js +7 -5
  6. package/bundle/dist/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/2020.js +112 -0
  7. package/bundle/dist/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/compile/codegen/code.js +140 -0
  8. package/bundle/dist/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/compile/codegen/index.js +676 -0
  9. package/bundle/dist/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/compile/codegen/scope.js +143 -0
  10. package/bundle/dist/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/compile/errors.js +104 -0
  11. package/bundle/dist/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/compile/index.js +225 -0
  12. package/bundle/dist/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/compile/names.js +30 -0
  13. package/bundle/dist/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/compile/ref_error.js +20 -0
  14. package/bundle/dist/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/compile/resolve.js +135 -0
  15. package/bundle/dist/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/compile/rules.js +63 -0
  16. package/bundle/dist/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/compile/util.js +148 -0
  17. package/bundle/dist/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/compile/validate/applicability.js +25 -0
  18. package/bundle/dist/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/compile/validate/boolSchema.js +50 -0
  19. package/bundle/dist/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/compile/validate/dataType.js +174 -0
  20. package/bundle/dist/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/compile/validate/defaults.js +33 -0
  21. package/bundle/dist/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/compile/validate/index.js +435 -0
  22. package/bundle/dist/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/compile/validate/keyword.js +115 -0
  23. package/bundle/dist/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/compile/validate/subschema.js +74 -0
  24. package/bundle/dist/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/core.js +585 -0
  25. package/bundle/dist/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/refs/data.js +20 -0
  26. package/bundle/dist/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/refs/json-schema-2020-12/index.js +44 -0
  27. package/bundle/dist/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/refs/json-schema-2020-12/meta/applicator.js +52 -0
  28. package/bundle/dist/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/refs/json-schema-2020-12/meta/content.js +22 -0
  29. package/bundle/dist/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/refs/json-schema-2020-12/meta/core.js +53 -0
  30. package/bundle/dist/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/refs/json-schema-2020-12/meta/format-annotation.js +18 -0
  31. package/bundle/dist/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/refs/json-schema-2020-12/meta/meta-data.js +38 -0
  32. package/bundle/dist/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/refs/json-schema-2020-12/meta/unevaluated.js +21 -0
  33. package/bundle/dist/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/refs/json-schema-2020-12/meta/validation.js +87 -0
  34. package/bundle/dist/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/refs/json-schema-2020-12/schema.js +61 -0
  35. package/bundle/dist/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/runtime/equal.js +14 -0
  36. package/bundle/dist/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/runtime/ucs2length.js +27 -0
  37. package/bundle/dist/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/runtime/uri.js +14 -0
  38. package/bundle/dist/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/runtime/validation_error.js +18 -0
  39. package/bundle/dist/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/vocabularies/applicator/additionalItems.js +59 -0
  40. package/bundle/dist/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/vocabularies/applicator/additionalProperties.js +98 -0
  41. package/bundle/dist/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/vocabularies/applicator/allOf.js +31 -0
  42. package/bundle/dist/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/vocabularies/applicator/anyOf.js +18 -0
  43. package/bundle/dist/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/vocabularies/applicator/contains.js +91 -0
  44. package/bundle/dist/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/vocabularies/applicator/dependencies.js +89 -0
  45. package/bundle/dist/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/vocabularies/applicator/dependentSchemas.js +18 -0
  46. package/bundle/dist/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/vocabularies/applicator/if.js +64 -0
  47. package/bundle/dist/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/vocabularies/applicator/index.js +62 -0
  48. package/bundle/dist/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/vocabularies/applicator/items.js +61 -0
  49. package/bundle/dist/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/vocabularies/applicator/items2020.js +36 -0
  50. package/bundle/dist/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/vocabularies/applicator/not.js +33 -0
  51. package/bundle/dist/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/vocabularies/applicator/oneOf.js +53 -0
  52. package/bundle/dist/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/vocabularies/applicator/patternProperties.js +63 -0
  53. package/bundle/dist/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/vocabularies/applicator/prefixItems.js +19 -0
  54. package/bundle/dist/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/vocabularies/applicator/properties.js +54 -0
  55. package/bundle/dist/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/vocabularies/applicator/propertyNames.js +43 -0
  56. package/bundle/dist/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/vocabularies/applicator/thenElse.js +19 -0
  57. package/bundle/dist/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/vocabularies/code.js +132 -0
  58. package/bundle/dist/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/vocabularies/core/id.js +16 -0
  59. package/bundle/dist/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/vocabularies/core/index.js +24 -0
  60. package/bundle/dist/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/vocabularies/core/ref.js +114 -0
  61. package/bundle/dist/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/vocabularies/discriminator/index.js +103 -0
  62. package/bundle/dist/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/vocabularies/discriminator/types.js +16 -0
  63. package/bundle/dist/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/vocabularies/draft2020.js +37 -0
  64. package/bundle/dist/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/vocabularies/dynamic/dynamicAnchor.js +48 -0
  65. package/bundle/dist/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/vocabularies/dynamic/dynamicRef.js +47 -0
  66. package/bundle/dist/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/vocabularies/dynamic/index.js +24 -0
  67. package/bundle/dist/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/vocabularies/dynamic/recursiveAnchor.js +22 -0
  68. package/bundle/dist/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/vocabularies/dynamic/recursiveRef.js +17 -0
  69. package/bundle/dist/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/vocabularies/format/format.js +94 -0
  70. package/bundle/dist/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/vocabularies/format/index.js +12 -0
  71. package/bundle/dist/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/vocabularies/metadata.js +25 -0
  72. package/bundle/dist/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/vocabularies/next.js +21 -0
  73. package/bundle/dist/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/vocabularies/unevaluated/index.js +15 -0
  74. package/bundle/dist/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/vocabularies/unevaluated/unevaluatedItems.js +48 -0
  75. package/bundle/dist/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/vocabularies/unevaluated/unevaluatedProperties.js +61 -0
  76. package/bundle/dist/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/vocabularies/validation/const.js +29 -0
  77. package/bundle/dist/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/vocabularies/validation/dependentRequired.js +19 -0
  78. package/bundle/dist/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/vocabularies/validation/enum.js +51 -0
  79. package/bundle/dist/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/vocabularies/validation/index.js +50 -0
  80. package/bundle/dist/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/vocabularies/validation/limitContains.js +20 -0
  81. package/bundle/dist/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/vocabularies/validation/limitItems.js +30 -0
  82. package/bundle/dist/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/vocabularies/validation/limitLength.js +35 -0
  83. package/bundle/dist/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/vocabularies/validation/limitNumber.js +49 -0
  84. package/bundle/dist/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/vocabularies/validation/limitProperties.js +30 -0
  85. package/bundle/dist/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/vocabularies/validation/multipleOf.js +29 -0
  86. package/bundle/dist/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/vocabularies/validation/pattern.js +40 -0
  87. package/bundle/dist/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/vocabularies/validation/required.js +74 -0
  88. package/bundle/dist/node_modules/.pnpm/ajv@8.20.0/node_modules/ajv/dist/vocabularies/validation/uniqueItems.js +72 -0
  89. package/bundle/dist/node_modules/.pnpm/fast-deep-equal@3.1.3/node_modules/fast-deep-equal/index.js +35 -0
  90. package/bundle/dist/node_modules/.pnpm/fast-uri@3.1.0/node_modules/fast-uri/index.js +238 -0
  91. package/bundle/dist/node_modules/.pnpm/fast-uri@3.1.0/node_modules/fast-uri/lib/schemes.js +189 -0
  92. package/bundle/dist/node_modules/.pnpm/fast-uri@3.1.0/node_modules/fast-uri/lib/utils.js +284 -0
  93. package/bundle/dist/node_modules/.pnpm/json-schema-traverse@1.0.0/node_modules/json-schema-traverse/index.js +80 -0
  94. package/bundle/dist/testing/schema-bench.js +0 -0
  95. package/bundle/dist/utils/providers/anthropic/fence-strip.js +83 -0
  96. package/bundle/dist/utils/providers/anthropic/stream-json-adapter.js +3 -5
  97. package/bundle/src/application/qgrid/qgrid.dispatcher.test.ts +250 -34
  98. package/bundle/src/application/qgrid/qgrid.dispatcher.ts +36 -5
  99. package/bundle/src/application/qgrid/qgrid.frame.test.ts +120 -153
  100. package/bundle/src/application/qgrid/qgrid.frame.ts +2 -0
  101. package/bundle/src/application/qgrid/schema-prompt.test.ts +166 -0
  102. package/bundle/src/application/qgrid/schema-prompt.ts +293 -0
  103. package/bundle/src/application/qgrid/tool-emulation.test.ts +36 -0
  104. package/bundle/src/application/qgrid/tool-emulation.ts +19 -7
  105. package/bundle/src/testing/schema-bench.test.ts +358 -0
  106. package/bundle/src/testing/schema-bench.ts +352 -0
  107. package/bundle/src/utils/providers/anthropic/fence-strip.test.ts +122 -0
  108. package/bundle/src/utils/providers/anthropic/fence-strip.ts +105 -0
  109. package/bundle/src/utils/providers/anthropic/stream-json-adapter.ts +2 -8
  110. package/bundle/web-dist/client/assets/chat-icon-JYfue7fB.png +0 -0
  111. package/bundle/web-dist/client/assets/index-C0594sjh.js +106 -0
  112. package/bundle/web-dist/client/assets/index-CcMEpCgt.css +1 -0
  113. package/bundle/web-dist/client/assets/logs-BotUcOEB.js +1 -0
  114. package/bundle/web-dist/client/assets/monit-kk3vnGvu.js +1 -0
  115. package/bundle/web-dist/client/assets/{routes-DVseTo6T.js → routes-J4bnHVfl.js} +2 -2
  116. package/bundle/web-dist/client/assets/services.generated-jGypfumC.js +51 -0
  117. package/bundle/web-dist/client/assets/settings-CAAQSIyg.js +1 -0
  118. package/bundle/web-dist/client/assets/show-BryNvjUT.js +2 -0
  119. package/bundle/web-dist/client/assets/tokens-DDrATjGA.js +1 -0
  120. package/bundle/web-dist/client/assets/{use-oauth-login-flow-CuLvs_CW.js → use-oauth-login-flow-CptleCFM.js} +1 -1
  121. package/bundle/web-dist/client/index.html +3 -3
  122. package/bundle/web-dist/server/assets/{lazyRouteComponent-C-N6sd5N.js → lazyRouteComponent-DOc8TV-P.js} +2 -2
  123. package/bundle/web-dist/server/assets/{logs-CVkeSr1S.js → logs-CfF3nmLM.js} +3 -4
  124. package/bundle/web-dist/server/assets/{monit-Bb6QfT9V.js → monit-BSaKhh5D.js} +2 -3
  125. package/bundle/web-dist/server/assets/{plus-B8JRuCb9.js → plus-DLFUHsfx.js} +1 -1
  126. package/bundle/web-dist/server/assets/{react-dom-ByF9tqTB.js → react-dom-BotjLnTK.js} +1 -1
  127. package/bundle/web-dist/server/assets/{routes-Dnm-Eti6.js → routes-CHMxrTT0.js} +4 -5
  128. package/bundle/web-dist/server/assets/{sd.generated-CuyajYtc.js → services.generated-D3Q3FYot.js} +16008 -14698
  129. package/bundle/web-dist/server/assets/{settings-4T3nBfY8.js → settings-DOQjV28c.js} +5 -21
  130. package/bundle/web-dist/server/assets/show-Cn_C6Qvl.js +2776 -0
  131. package/bundle/web-dist/server/assets/{tokens-Di_SGPYj.js → tokens-c0EN3iCx.js} +4 -5
  132. package/bundle/web-dist/server/assets/{use-oauth-login-flow-DiYCMNAQ.js → use-oauth-login-flow-B68AbMDE.js} +1 -2
  133. package/bundle/web-dist/server/entry-server.generated.js +23856 -40
  134. package/package.json +1 -1
  135. package/skills/qgrid/references/ai-sdk-provider-contract.md +20 -15
  136. package/skills/qgrid/references/anthropic-claude-code-runtime.md +31 -14
  137. package/skills/qgrid/references/decision-rationale.md +13 -3
  138. package/skills/qgrid/references/prompt-cache-and-usage.md +4 -1
  139. package/skills/qgrid/references/provider-runtime-differences.md +3 -3
  140. package/skills/qgrid/references/tool-calling-and-multiturn.md +16 -6
  141. package/bundle/web-dist/client/assets/index-CFvFRDk_.js +0 -78
  142. package/bundle/web-dist/client/assets/index-CJ9iTI_V.css +0 -1
  143. package/bundle/web-dist/client/assets/logs-DeAK5Uyu.js +0 -1
  144. package/bundle/web-dist/client/assets/monit-Rj94Sz3_.js +0 -1
  145. package/bundle/web-dist/client/assets/sd.generated-W6XqgWK6.js +0 -51
  146. package/bundle/web-dist/client/assets/services.generated-Dz5pA5Fb.js +0 -1
  147. package/bundle/web-dist/client/assets/settings-DvuRDFfS.js +0 -1
  148. package/bundle/web-dist/client/assets/show-C7etBj89.js +0 -30
  149. package/bundle/web-dist/client/assets/tokens-BroPe7Tn.js +0 -1
  150. package/bundle/web-dist/server/assets/services.generated-BAGLi2r8.js +0 -1313
  151. package/bundle/web-dist/server/assets/show-CQw03iTP.js +0 -25968
  152. /package/bundle/web-dist/client/assets/{plus-p4vtg6LN.js → plus-DqBd6gHk.js} +0 -0
  153. /package/bundle/web-dist/server/assets/{cost-DzjfVtUr.js → cost-CSH_t17I.js} +0 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cartanova/qgrid-cli",
3
- "version": "2.6.11",
3
+ "version": "2.7.1",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "https://github.com/cartanova-ai/qgrid"
@@ -145,9 +145,12 @@ Payload responsibilities:
145
145
  - Send AI SDK multimodal image/file message parts as qgrid `input` only when `imageGeneration` is enabled. Normal non-image-generation calls keep `user_prompt` text-only and do not forward image input.
146
146
  - Reject oversized reference-image data URLs before the request leaves the SDK. Reference images travel as JSON data URLs; callers should compress/resize large photos, preferably to WebP/JPEG.
147
147
 
148
- Tools and `jsonSchema` can be used together as of qgrid 2.5.4. The server composes
149
- them into one strict action envelope for every provider turn. `toolChoice` is not
150
- part of the current qgrid wire contract and must not be described as supported.
148
+ Tools and `jsonSchema` can be used together as of qgrid 2.5.4. On OpenAI the
149
+ server composes them into one strict action envelope enforced by constrained
150
+ decoding; on Anthropic (SON-532) the same envelope contract is rendered as text
151
+ at the end of the system prompt and the reply is validated by `parseEnvelope`.
152
+ `toolChoice` is not part of the current qgrid wire contract and must not be
153
+ described as supported.
151
154
 
152
155
  Before provider dispatch, qgrid validates caller output schemas and every tool
153
156
  input schema with an iterative preflight. Output/tool schema serialization, tool
@@ -155,24 +158,26 @@ names, descriptions, JSON escaping, and composition framing share an aggregate
155
158
  512 KiB UTF-8 budget. Schema JSON values are limited to 20,000 in aggregate, and
156
159
  each schema is limited to depth 128. Malformed, unsupported top-level output, or
157
160
  over-budget schemas fail with HTTP 400 before request-log creation or stream ID
158
- allocation. The fully composed and strictified schema is checked again against
159
- the 512 KiB budget. Anthropic routes additionally enforce a 64 KiB UTF-8 ceiling
160
- because Claude Code receives that schema as one `--json-schema` argv value.
161
+ allocation. On OpenAI the fully composed and strictified schema is checked again
162
+ against the 512 KiB budget. Anthropic performs only this syntax/complexity
163
+ preflight — no strictify, no argv ceiling (the old 64 KiB `--json-schema` limit
164
+ is gone; large schema contracts ride the system-prompt file branch).
161
165
 
162
166
  OpenAI normalizes positional tuple schemas in supported positive schema
163
167
  positions and enforces their positional constraints. Tuples in negative,
164
168
  conditional, or otherwise non-normalizable schema positions fail with HTTP 400
165
169
  instead of being rewritten with changed semantics. References from those
166
170
  positions fail for the same reason because definitions are normalized globally.
167
- Anthropic positional tuple schemas fail with HTTP 400 because Claude Code cannot
168
- preserve positional semantics. Tuple nodes must explicitly declare
169
- `type: "array"`; express nullable tuples with an `anyOf` array/null branch.
170
-
171
- Structured schemas accept only local root-relative JSON Pointer `$ref` values
172
- targeting the document root or a chain of `$defs`/`definitions` entry roots.
173
- References into properties, tuple internals, conditionals, or literal values
174
- fail with HTTP 400 because normalization can move or rewrite those targets.
175
- Resource IDs, anchors, external refs, dynamic refs, and recursive refs are also
171
+ Tuple nodes must explicitly declare `type: "array"`; express nullable tuples
172
+ with an `anyOf` array/null branch. These normalization restrictions are
173
+ OpenAI-only: the Anthropic route injects the schema verbatim as prompt text, so
174
+ positional tuples and arbitrary `$ref` forms pass through unchanged.
175
+
176
+ On OpenAI, structured schemas accept only local root-relative JSON Pointer
177
+ `$ref` values targeting the document root or a chain of `$defs`/`definitions`
178
+ entry roots. References into properties, tuple internals, conditionals, or
179
+ literal values fail with HTTP 400 because normalization can move or rewrite
180
+ those targets. Resource IDs, anchors, external refs, dynamic refs, and recursive refs are also
176
181
  rejected.
177
182
 
178
183
  When tools are present, qgrid sends tool definitions to the server as `tools`; it does not send them to OpenAI or Anthropic as native provider tools. The server converts them into a strict structured-output schema and maps the model's structured result back into AI SDK `tool-call` content.
@@ -61,7 +61,7 @@ Refresh is attempted through `QgridFrame.refreshToken` with provider set to `ant
61
61
  ```text
62
62
  claude -p
63
63
  --tools ""
64
- --allowed-tools StructuredOutput # only when jsonSchema exists
64
+ --allowed-tools StructuredOutput # legacy structured path only — unused since SON-532
65
65
  --disallowedTools Monitor PushNotification RemoteTrigger
66
66
  --input-format stream-json
67
67
  --output-format stream-json
@@ -76,18 +76,22 @@ claude -p
76
76
  --effort <effort-or-low>
77
77
  --disable-slash-commands
78
78
  --session-id <uuid>
79
- --json-schema <schema> # only when jsonSchema exists
79
+ --json-schema <schema> # legacy structured path only — unused since SON-532
80
80
  ```
81
81
 
82
82
  Important details:
83
83
 
84
- - `--tools ""` blocks normal tools. With structured output, only `StructuredOutput` is allowed.
84
+ - `--tools ""` blocks normal tools on every call.
85
+ - **qgrid no longer passes `--json-schema` (SON-532).** Schema and tool-envelope contracts are
86
+ rendered as text (`schema-prompt.ts`) and appended to the system prompt; CC runs in plain text
87
+ mode, qgrid strips code fences (`fence-strip.ts`), and validation belongs to the consumer's zod
88
+ and qgrid's `parseEnvelope`. The `buildClaudeArgs` structured branch remains in code but is
89
+ unreachable from qgrid dispatch.
85
90
  - `--setting-sources project` plus seeded settings isolates user configuration.
86
91
  - `--system-prompt` or `--system-prompt-file` is always supplied. Omitting it would allow Claude Code default system prompt injection.
87
- - Large system prompts over 64 KiB are written to a temporary file to avoid argv `E2BIG`.
88
- - Final structured-output schemas are limited to 64 KiB UTF-8 because Claude Code receives each
89
- schema as one `--json-schema` argv value. qgrid applies this check before request-log or stream
90
- allocation and repeats it at dispatcher/session boundaries.
92
+ - Large system prompts over 64 KiB are written to a temporary file to avoid argv `E2BIG` — this
93
+ same branch absorbs large injected schema contracts, so the old 64 KiB schema argv limit no
94
+ longer applies (only the global 512 KiB caller-schema complexity limit remains).
91
95
  - `--thinking disabled`, `MAX_THINKING_TOKENS=0`, and adaptive thinking env suppression keep thinking off for existing models. Fable 5 requires always-on adaptive thinking. Opus 5 defaults to adaptive thinking and rejects disabled thinking at `xhigh`/`max` effort. qgrid omits all three suppressors for both models and uses `effort` to control depth.
92
96
 
93
97
  ## Spawn env
@@ -209,13 +213,26 @@ Upstream references:
209
213
 
210
214
  ## Structured output
211
215
 
212
- qgrid strictifies schemas before provider dispatch. Claude Code `--json-schema` is not grammar-constrained decoding; it is a `StructuredOutput` tool plus post-validation behavior. Keep schemas strict and preserve error signaling for failed structured-output attempts.
213
-
214
- `MAX_STRUCTURED_OUTPUT_RETRIES` defaults to `1` and is clamped to at least 1. Avoid setting it to 0; Claude Code can fail before emitting a useful attempt.
215
-
216
- qgrid pins this env var only when the call is **structured and streaming**. The pin exists because a retry inside a stream doubles wall-clock time (SON-495); that reasoning does not apply to non-streaming `generate`, which already waits for completion. Streaming is detected via `includePartialMessages`, which only `generateStream` sets.
217
-
218
- Non-streaming structured calls therefore keep Claude Code's default retry budget. This matters because Claude models comply with structured output less reliably than OpenAI models: pinning retries to 1 turns a single rejected attempt into an immediate `error_max_structured_output_retries`. Measured on dev0 before the fix, `deti_production` on Opus 4.8 failed 39.6% of non-streaming structured calls for this reason.
216
+ **Since SON-532 the anthropic route delivers schemas by prompt, not by `--json-schema`.** The
217
+ consumer's original schema (no strictify — nullish/optional intent preserved) is rendered as text
218
+ and appended to the system prompt; anthropic is cold-only, so every multi-turn step re-sends the
219
+ contract. Responses are plain text: qgrid strips fences and trims, and validation is the
220
+ consumer's zod (user schema) or qgrid's `parseEnvelope` (tool envelope). Prose or degenerate
221
+ output fails honestly — retry is the caller's decision.
222
+
223
+ Why: CC's `--json-schema` is not grammar-constrained decoding — it is a `StructuredOutput` tool
224
+ plus post-hoc AJV scoring with an internal retry loop that cannot be disabled. The strictified
225
+ scoring schema contradicted consumer intent (nullish frozen into required), so the model's
226
+ correct-per-instructions output was rejected and retried invisibly: deti transcripts showed 2–4
227
+ round trips per call, 216–512 s latency, and 4.7–9.1× billed output tokens, all collapsed into
228
+ one request-log row. OpenAI keeps the strictified schema because constrained decoding actually
229
+ enforces it there.
230
+
231
+ Legacy notes (structured path, unreachable from qgrid dispatch but still in `claude-session.ts`):
232
+ `MAX_STRUCTURED_OUTPUT_RETRIES` was pinned to 1 only for structured **streaming** calls (SON-495 —
233
+ a retry inside a stream doubles wall-clock); non-streaming kept CC's default budget because
234
+ pinning it caused 39.6% failures on `deti_production` Opus 4.8. Compliance measurement for the
235
+ prompt path lives in `scripts/schema-delivery-bench.ts`.
219
236
 
220
237
  When a non-streaming retry succeeds, the result event's `structured_output` is the canonical
221
238
  schema-validated value. Do not let a previously captured assistant tool input override it. Preserve
@@ -114,9 +114,19 @@ Key decisions:
114
114
  - Anthropic is cold-only. It does not use Codex-style thread reuse because Claude Code prompt cache is prefix-based and AI SDK consumers already send full message history for each step.
115
115
  - The shared `threadCoord` response shape may still appear for provider symmetry, but AI SDK storage/replay is disabled for `anthropic/*` models.
116
116
  - Claude Code `stream-json` drops structural assistant role replay in the outbound API payload. qgrid flattens prior history into text because structural role replay through the CLI is not reliable.
117
- - Claude Code `--json-schema` is not constrained native tool calling. It creates a `StructuredOutput` tool and validates after model generation. Keep schemas strict and fail on non-success subtypes or retry exhaustion.
118
- - `MAX_STRUCTURED_OUTPUT_RETRIES=1` means one attempt. Do not set it to 0 expecting "no retry but one attempt"; that can mean no useful attempt.
119
- - The retry pin is scoped to **streaming** structured calls only. SON-495 fixed retries to 1 because a retry inside a stream doubles wall-clock time — a latency argument that does not hold for non-streaming `generate`. Applying the pin to both paths made every non-streaming structured call fail on its first rejected attempt, and since Claude complies with structured output less reliably than OpenAI, that produced a 39.6% `error_max_structured_output_retries` rate for `deti_production` on Opus 4.8 (dev0, 2026-07). Non-streaming now uses Claude Code's default retry budget; `includePartialMessages` is the streaming discriminator.
117
+ - **qgrid does not pass `--json-schema` to Claude Code (SON-532, 2026-08).** CC's mode is not
118
+ constrained decoding — it creates a `StructuredOutput` tool, scores the free-form output with
119
+ AJV afterwards, and retries internally on mismatch with no off switch. The strictified scoring
120
+ schema contradicted consumer intent (nullish frozen into required), so correct-per-instructions
121
+ outputs were rejected and retried invisibly: deti transcripts showed 2–4 round trips, 216–512 s,
122
+ and 4.7–9.1× billed output per call, collapsed into one request-log row. Schemas and the tool
123
+ envelope now travel as text at the end of the system prompt (`schema-prompt.ts`, consumer's
124
+ original schema, no strictify), the server strips fences only (`fence-strip.ts`), and validation
125
+ is consumer zod / `parseEnvelope`. Honest failure on violations is unchanged.
126
+ - Legacy (structured path, unreachable from qgrid dispatch): `MAX_STRUCTURED_OUTPUT_RETRIES=1`
127
+ means one attempt (never set 0), and the retry pin was scoped to **streaming** structured calls
128
+ only — SON-495's latency argument does not hold for non-streaming `generate`, where pinning
129
+ produced a 39.6% failure rate for `deti_production` on Opus 4.8 (dev0, 2026-07).
120
130
  - 1M context support is measured per model and is a mitigation, not a guarantee. It reduces compaction/hang frequency for huge prompts, but does not make every structured prompt reliable.
121
131
  - Spawn env must be whitelisted. Never pass inherited `ANTHROPIC_API_KEY`, `ANTHROPIC_AUTH_TOKEN`, or `ANTHROPIC_BASE_URL` unless intentionally building an API-key/proxy path.
122
132
  - `--setting-sources project` is required for shared-service isolation. User/local Claude settings can load hooks or memory and leak context across requests.
@@ -63,7 +63,10 @@ Prompt cache can still work when prefixes are stable, but:
63
63
  - Full history is replayed through stream-json after flattening.
64
64
  - Cache write/read can be eventually consistent; immediate next request is not guaranteed to hit.
65
65
  - Claude Code OAuth token cache behavior has provider-specific quirks documented in `docs/solutions`.
66
- - Avoid putting volatile schema text into the system prompt. qgrid uses `--json-schema` / `StructuredOutput` for structured output.
66
+ - Since SON-532, qgrid appends the schema/tool-envelope contract to the end of the system
67
+ prompt (no `--json-schema`). A stable schema keeps the system prefix stable and cacheable
68
+ across requests; a schema that changes per request invalidates the prefix cache from the
69
+ contract onward. Keep caller schemas deterministic (no timestamps or per-request IDs inside).
67
70
 
68
71
  ## Usage normalization
69
72
 
@@ -16,9 +16,9 @@ Use this reference when comparing OpenAI and Anthropic behavior, debugging provi
16
16
  | `sessionKey` | AI SDK stores and replays `threadCoord` for thread reuse | AI SDK intentionally disables storage/replay |
17
17
  | Multi-turn | Reuse sends delta input to existing Codex thread; cold fallback injects full history | Fresh spawn receives flattened full history through stream-json |
18
18
  | Cache key | Codex conversation/thread id is prompt-cache affinity | Anthropic prefix cache via Claude Code; fresh spawn still can cache stable prefixes |
19
- | Built-in tools | Codex tools/apps/plugins/skills disabled by worker config | Claude tools disabled via `--tools ""`; `StructuredOutput` allowed only for schema |
20
- | AI SDK tools | Emulated via qgrid structured output schema, then mapped to AI SDK `tool-call` content | Same emulation path; not native Claude Code tools |
21
- | Structured output | Codex `outputSchema` passed to `turn/start`; schema changes can affect prefix cache | Claude `--json-schema` through `StructuredOutput` tool; strict schemas required |
19
+ | Built-in tools | Codex tools/apps/plugins/skills disabled by worker config | Claude tools disabled via `--tools ""` on every call |
20
+ | AI SDK tools | Emulated via qgrid structured output schema, then mapped to AI SDK `tool-call` content | Emulated via envelope contract rendered as prompt text (SON-532); reply parsed by `parseEnvelope`; not native Claude Code tools |
21
+ | Structured output | Codex `outputSchema` passed to `turn/start` (strictified, constrained decoding); schema changes can affect prefix cache | Schema delivered as prompt text appended to the system prompt (no `--json-schema`, no strictify); server strips fences; validation is the consumer's |
22
22
  | Usage accounting | Codex usage already reports `inputTokens` including cached input | Native Anthropic categories are mutually exclusive; qgrid sums them into total input |
23
23
  | Cost source | qgrid model price fallback | Prefer Claude Code `total_cost_usd`, else qgrid price fallback |
24
24
  | Settings isolation | Per-worker `CODEX_HOME` and config.toml | Shared project cwd plus per-token `CLAUDE_CONFIG_DIR` |
@@ -102,13 +102,21 @@ The schema explicitly tells the model:
102
102
  - do not invoke listed tools as native Claude Code tools;
103
103
  - put tool arguments in `args` as a JSON string.
104
104
 
105
- `qgrid.dispatcher.ts` strictifies this schema through `buildStrictOutputSchema` before it reaches provider dispatchers.
105
+ Delivery differs by provider (SON-532). OpenAI: `qgrid.dispatcher.ts` strictifies the composed
106
+ envelope through `buildStrictOutputSchema` and passes it as the response format — constrained
107
+ decoding enforces it. Anthropic: no schema is passed to CC at all; `schema-prompt.ts` renders the
108
+ same envelope contract (the `{"result": ...}` wrapper, mutually exclusive variants, tool list) as
109
+ text appended to the system prompt, the user answer schema stays unstrictified, and the server
110
+ strips code fences before `parseEnvelope` validates the reply.
106
111
 
107
112
  ## Composing Tools With A User Output Schema
108
113
 
109
114
  This section explains why `tool-emulation-schema.ts` exists at all. Read it
110
115
  before changing schema composition; the mechanics look arbitrary without the
111
- failure it was built to prevent.
116
+ failure it was built to prevent. Scope note (SON-532): this composition — and
117
+ its `$defs` rebase with the anchor/dynamic-ref rejections below — runs only on
118
+ the OpenAI delivery path now. Anthropic renders the contract as prompt text, so
119
+ there is no document-root `$ref` collision and nothing to rebase or reject.
112
120
 
113
121
  ### The problem
114
122
 
@@ -242,10 +250,12 @@ Anthropic/Claude Code:
242
250
 
243
251
  - qgrid does not allow client tools as Claude Code native tools.
244
252
  - Claude is spawned with `--tools ""`.
245
- - When a schema exists, qgrid permits only `StructuredOutput` with `--allowed-tools StructuredOutput`.
246
- - qgrid passes the strict tool-call schema through `--json-schema`.
247
- - The stream adapter preserves `StructuredOutput` tool input as final structured text.
248
- - qgrid parses that text and maps it to qgrid `tool-call` content.
253
+ - Since SON-532 qgrid does **not** pass `--json-schema` (no `StructuredOutput` tool either): the
254
+ envelope contract travels as text at the end of the system prompt (`schema-prompt.ts`), and the
255
+ answer schema inside it is the consumer's original, unstrictified.
256
+ - The reply is plain text; the server strips code fences (`fence-strip.ts`), then `parseEnvelope`
257
+ validates the `{"result": ...}` envelope and maps `tool_call` to qgrid `tool-call` content.
258
+ - Violations fail honestly — no tolerant fallback (medpath 13.5k corruption precedent).
249
259
 
250
260
  In both providers, native provider tools are not the public abstraction. The public abstraction is AI SDK tools plus qgrid structured-output emulation.
251
261