@cartanova/qgrid-cli 2.5.3 → 2.5.4
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 +7 -2
- package/README.md +7 -2
- package/bundle/dist/application/monit/monit.frame.js +3 -3
- package/bundle/dist/application/qgrid/oauth.js +1 -1
- package/bundle/dist/application/qgrid/qgrid.dispatcher.js +36 -14
- package/bundle/dist/application/qgrid/qgrid.frame.js +19 -5
- package/bundle/dist/application/qgrid/tool-emulation-schema.js +121 -0
- package/bundle/dist/application/qgrid/tool-emulation.js +116 -96
- package/bundle/dist/application/request-log/request-log.model.js +3 -3
- package/bundle/dist/application/request-log-step/request-log-step.model.js +2 -2
- package/bundle/dist/application/token/token.model.js +2 -2
- package/bundle/dist/server-error-handler.js +15 -0
- package/bundle/dist/sonamu.config.js +4 -7
- package/bundle/dist/utils/providers/anthropic/anthropic-dispatcher.js +4 -3
- package/bundle/dist/utils/providers/anthropic/claude-session.js +7 -5
- package/bundle/dist/utils/providers/common/schema-validation.js +178 -0
- package/bundle/dist/utils/providers/common/strictifier.js +329 -42
- package/bundle/dist/utils/providers/openai/codex-worker.js +16 -8
- package/bundle/dist/utils/providers/openai/openai-dispatcher.js +5 -37
- package/bundle/dist/utils/providers/openai/openai-worker-pool-config.js +37 -0
- package/bundle/src/application/monit/monit.frame.ts +1 -1
- package/bundle/src/application/qgrid/qgrid-run-lifecycle.test.ts +103 -0
- package/bundle/src/application/qgrid/qgrid.dispatcher.test.ts +337 -0
- package/bundle/src/application/qgrid/qgrid.dispatcher.ts +45 -25
- package/bundle/src/application/qgrid/qgrid.frame.test.ts +580 -8
- package/bundle/src/application/qgrid/qgrid.frame.ts +28 -1
- package/bundle/src/application/qgrid/tool-emulation-schema.test.ts +188 -0
- package/bundle/src/application/qgrid/tool-emulation-schema.ts +176 -0
- package/bundle/src/application/qgrid/tool-emulation.test.ts +285 -67
- package/bundle/src/application/qgrid/tool-emulation.ts +199 -102
- package/bundle/src/server-error-handler.ts +22 -0
- package/bundle/src/sonamu.config.test.ts +37 -0
- package/bundle/src/sonamu.config.ts +2 -5
- package/bundle/src/utils/providers/anthropic/anthropic-dispatcher.test.ts +44 -0
- package/bundle/src/utils/providers/anthropic/anthropic-dispatcher.ts +2 -2
- package/bundle/src/utils/providers/anthropic/claude-session.test.ts +10 -0
- package/bundle/src/utils/providers/anthropic/claude-session.ts +6 -1
- package/bundle/src/utils/providers/common/schema-validation.test.ts +284 -0
- package/bundle/src/utils/providers/common/schema-validation.ts +308 -0
- package/bundle/src/utils/providers/common/strictifier.test.ts +746 -0
- package/bundle/src/utils/providers/common/strictifier.ts +513 -52
- package/bundle/src/utils/providers/openai/codex-worker.test.ts +31 -0
- package/bundle/src/utils/providers/openai/codex-worker.ts +12 -4
- package/bundle/src/utils/providers/openai/openai-dispatcher.test.ts +6 -4
- package/bundle/src/utils/providers/openai/openai-dispatcher.ts +6 -79
- package/bundle/src/utils/providers/openai/openai-worker-pool-config.ts +80 -0
- package/bundle/web-dist/client/assets/{index-DXdGBfB8.js → index-DiY5V2e3.js} +3 -3
- package/bundle/web-dist/client/assets/{logs-D_j1yxC4.js → logs-UZ4Cvdmc.js} +1 -1
- package/bundle/web-dist/client/assets/{monit-CIToyoxW.js → monit-C5cJo-HD.js} +1 -1
- package/bundle/web-dist/client/assets/{routes-Dd21A-wi.js → routes-DEKEmoQN.js} +1 -1
- package/bundle/web-dist/client/assets/{show-DfePWRbc.js → show-DnX6b8KG.js} +1 -1
- package/bundle/web-dist/client/assets/{tokens-B4MV2fdk.js → tokens-Ct0FGD4b.js} +1 -1
- package/bundle/web-dist/client/index.html +1 -1
- package/bundle/web-dist/server/entry-server.generated.js +1 -1
- package/package.json +1 -1
- package/skills/qgrid/references/ai-sdk-provider-contract.md +34 -2
- package/skills/qgrid/references/anthropic-claude-code-runtime.md +3 -0
- package/skills/qgrid/references/cli-env-and-server-boot.md +1 -1
- package/skills/qgrid/references/decision-rationale.md +10 -1
- package/skills/qgrid/references/repo-map.md +2 -1
- package/skills/qgrid/references/tool-calling-and-multiturn.md +33 -6
- package/skills/qgrid/references/verification-and-debugging.md +16 -1
|
@@ -49,7 +49,16 @@ Sources:
|
|
|
49
49
|
Key decisions:
|
|
50
50
|
|
|
51
51
|
- qgrid tool calling is intentionally implemented through structured-output emulation, not native provider tool use. The provider call returns a structured action with tool calls; the AI SDK loop executes tools and sends follow-up turns.
|
|
52
|
-
- Tools and `jsonSchema`
|
|
52
|
+
- Tools and `jsonSchema` share one provider structured-output slot by composing
|
|
53
|
+
an action envelope on every turn. Its final `answer` branch embeds the user's
|
|
54
|
+
schema; its `tool_call` branch carries emulated AI SDK calls. This keeps final
|
|
55
|
+
output constrained even when tools are available but never called.
|
|
56
|
+
- Final output is identified by `action: "answer"`, not by tool presence or turn
|
|
57
|
+
count. Structured answers are serialized as JSON text for AI SDK
|
|
58
|
+
`Output.object` parsing, while tools-only callers retain their legacy string
|
|
59
|
+
answer and tolerant parse fallback.
|
|
60
|
+
- AI SDK `toolChoice` remains outside qgrid's wire contract. Do not imply that
|
|
61
|
+
qgrid transports or enforces it.
|
|
53
62
|
- Tool-call request logs are a multi-step run: create run, append generate/tool steps, then finish run. This makes AI SDK multi-step behavior visible in the dashboard instead of logging only one opaque completion.
|
|
54
63
|
- Tool results update the existing `tool_call` step by `request_log_id + tool_call_id`. They are not logged as a second unrelated completion row.
|
|
55
64
|
- The server infers single-turn completion versus an open tool run from context and finish reason. The removed caller-selected `logMode` contract must not be recreated.
|
|
@@ -28,7 +28,8 @@ Use this map to orient qgrid work quickly.
|
|
|
28
28
|
- Cost/usage accounting: `packages/api/src/utils/providers/common/model-cost.ts`.
|
|
29
29
|
- Weighted token selection: `packages/api/src/utils/providers/common/smooth-weighted-round-robin.ts`.
|
|
30
30
|
- Boot order and startup migrations: `packages/api/src/server-bootstrap.ts`, `packages/api/src/startup-migrations.ts`.
|
|
31
|
-
- Tool-call
|
|
31
|
+
- Tool-call schema composition: `packages/api/src/application/qgrid/tool-emulation-schema.ts`.
|
|
32
|
+
- Tool-call response decoding: `packages/api/src/application/qgrid/tool-emulation.ts`.
|
|
32
33
|
|
|
33
34
|
## Web/Sonamu hot spots
|
|
34
35
|
|
|
@@ -24,6 +24,11 @@ qgrid supports the AI SDK `tools` interface, but it does not use native provider
|
|
|
24
24
|
- qgrid maps that structured object back into AI SDK `tool-call` content.
|
|
25
25
|
- The AI SDK executes the actual tool functions and calls qgrid again with tool results.
|
|
26
26
|
|
|
27
|
+
`generateText` and `streamText` default to `stepCountIs(1)`. When an executable
|
|
28
|
+
tool can run before the final answer, callers must set a bounded `stopWhen`
|
|
29
|
+
(for example `stepCountIs(3)`) or the AI SDK stops after the first tool-call
|
|
30
|
+
step and cannot produce the final text or `Output.object` value.
|
|
31
|
+
|
|
27
32
|
Do not describe this as OpenAI native function calling, Claude native tool use, or Codex/Claude executing client tools. The tools are client-side AI SDK tools requested through structured-output emulation.
|
|
28
33
|
|
|
29
34
|
## Client Flow
|
|
@@ -36,7 +41,9 @@ When `options.tools` contains function tools:
|
|
|
36
41
|
2. Convert them with `toQgridTool`.
|
|
37
42
|
3. Send `tools` in `/api/qgrid/query` or `/api/qgrid/prepareStream`.
|
|
38
43
|
4. Forward the per-call `logger` switch when request logging is disabled.
|
|
39
|
-
5.
|
|
44
|
+
5. When a top-level object response format is present, send `jsonSchema` alongside
|
|
45
|
+
`tools`. The server composes both schemas and infers whether the logged request
|
|
46
|
+
becomes a multi-step run.
|
|
40
47
|
|
|
41
48
|
When qgrid responds with `finishReason: "tool-calls"`:
|
|
42
49
|
|
|
@@ -57,9 +64,10 @@ The registry is keyed per pending run so concurrent `generateText(...tools...)`
|
|
|
57
64
|
|
|
58
65
|
## Server Schema Emulation
|
|
59
66
|
|
|
60
|
-
`packages/api/src/application/qgrid/tool-emulation.ts` builds the tool-call schema.
|
|
67
|
+
`packages/api/src/application/qgrid/tool-emulation-schema.ts` builds the tool-call schema.
|
|
68
|
+
`tool-emulation.ts` decodes the model's action envelope into qgrid answer/tool-call content.
|
|
61
69
|
|
|
62
|
-
The schema shape is:
|
|
70
|
+
The tools-only schema shape is:
|
|
63
71
|
|
|
64
72
|
```json
|
|
65
73
|
{
|
|
@@ -83,7 +91,13 @@ The schema explicitly tells the model:
|
|
|
83
91
|
|
|
84
92
|
`qgrid.dispatcher.ts` strictifies this schema through `buildStrictOutputSchema` before it reaches provider dispatchers.
|
|
85
93
|
|
|
86
|
-
|
|
94
|
+
When tools and a user `jsonSchema` are both present, the dispatcher builds the
|
|
95
|
+
same outer envelope on every turn, but replaces `answer: string | null` with
|
|
96
|
+
`answer: <user schema> | null`. The user schema is namespaced under
|
|
97
|
+
`$defs.__qgrid_user_output`, including rebased local JSON pointers, before the
|
|
98
|
+
whole envelope is strictified. This prevents tool availability from disabling
|
|
99
|
+
the final structured-output constraint, including when the model answers without
|
|
100
|
+
calling a tool.
|
|
87
101
|
|
|
88
102
|
## Provider-Specific Path
|
|
89
103
|
|
|
@@ -111,9 +125,14 @@ In both providers, native provider tools are not the public abstraction. The pub
|
|
|
111
125
|
`applyToolCallEmulation` handles provider text:
|
|
112
126
|
|
|
113
127
|
- No tools: return normal text content.
|
|
114
|
-
- Tools
|
|
128
|
+
- Tools-only mode and JSON parse failure: preserve the legacy warning and text
|
|
129
|
+
fallback with `finishReason: "stop"`.
|
|
130
|
+
- Tools plus a user schema and malformed or incoherent envelope: return an
|
|
131
|
+
explicit structured-output error; do not rescue it as successful text.
|
|
115
132
|
- `action: "tool_call"`: validate tool names, generate qgrid `toolCallId`, return `finishReason: "tool-calls"`.
|
|
116
|
-
- `action: "answer"
|
|
133
|
+
- `action: "answer"` in tools-only mode: return the string answer as final text.
|
|
134
|
+
- `action: "answer"` with a user schema: JSON-serialize the structured `answer`
|
|
135
|
+
as final text so AI SDK can parse and validate `Output.object`.
|
|
117
136
|
|
|
118
137
|
Unknown tool names throw.
|
|
119
138
|
|
|
@@ -128,6 +147,14 @@ AI SDK multi-step behavior is client-orchestrated:
|
|
|
128
147
|
|
|
129
148
|
This is different from a provider-native tool loop. Neither Codex nor Claude Code executes the AI SDK tool functions.
|
|
130
149
|
|
|
150
|
+
The composed schema is reapplied to tool-result follow-up turns. Final output is
|
|
151
|
+
identified by `action: "answer"` rather than by whether a tool happened to be
|
|
152
|
+
available or called. AI SDK `toolChoice` is not transported or enforced by
|
|
153
|
+
qgrid; the model selects between the envelope's answer and tool-call actions.
|
|
154
|
+
|
|
155
|
+
The combined contract requires qgrid server 2.5.4 and
|
|
156
|
+
`@cartanova/qgrid-ai-sdk` 2.5.4.
|
|
157
|
+
|
|
131
158
|
OpenAI/Codex follow-ups can reuse the same Codex thread when `runContext.threadCoord` remains valid. For tool-result follow-up turns, qgrid sends delta input containing tool result text to the existing thread; cold fallback injects full history.
|
|
132
159
|
|
|
133
160
|
Anthropic follow-ups do not reuse Claude sessions. qgrid starts a fresh Claude process, replays flattened full history, and sends the tool-result continuation input.
|
|
@@ -30,6 +30,7 @@ AI SDK package `@cartanova/qgrid-ai-sdk`:
|
|
|
30
30
|
- `pnpm --filter @cartanova/qgrid-ai-sdk test`.
|
|
31
31
|
- `pnpm --filter @cartanova/qgrid-ai-sdk build`.
|
|
32
32
|
- `pnpm --filter @cartanova/qgrid-ai-sdk e2e`.
|
|
33
|
+
- `pnpm --filter @cartanova/qgrid-ai-sdk e2e:tools-output`.
|
|
33
34
|
- `pnpm --filter @cartanova/qgrid-ai-sdk e2e:logger`.
|
|
34
35
|
|
|
35
36
|
CLI package `@cartanova/qgrid-cli`:
|
|
@@ -54,7 +55,7 @@ Choose by affected area:
|
|
|
54
55
|
| AI SDK logger integration | `packages/ai-sdk/src/logger.test.ts` |
|
|
55
56
|
| qgrid provider routing and strict schema | `packages/api/src/application/qgrid/qgrid.dispatcher.test.ts` |
|
|
56
57
|
| conversation/thread reuse routing | `packages/api/src/application/qgrid/conv-routing.test.ts` |
|
|
57
|
-
| tool-call emulation | `packages/api/src/application/qgrid/tool-emulation.test.ts` |
|
|
58
|
+
| tool-call emulation | `packages/api/src/application/qgrid/tool-emulation.test.ts`, `tool-emulation-schema.test.ts` |
|
|
58
59
|
| request-log run lifecycle | `packages/api/src/application/qgrid/qgrid-run-lifecycle.test.ts` |
|
|
59
60
|
| qgrid frame API behavior | `packages/api/src/application/qgrid/qgrid.frame.test.ts` |
|
|
60
61
|
| token subscriber and LISTEN/NOTIFY handling | `packages/api/src/application/qgrid/token-subscriber.test.ts` |
|
|
@@ -101,6 +102,20 @@ AI SDK structured output:
|
|
|
101
102
|
- Env: `QGRID_URL`, `SMOKE_MODEL`, `SMOKE_CASES`, `SMOKE_REPEAT`.
|
|
102
103
|
- Uses AI SDK 6 `streamText` with `Output.object`; useful for structured-output regressions.
|
|
103
104
|
|
|
105
|
+
AI SDK tools plus structured output:
|
|
106
|
+
|
|
107
|
+
- `packages/ai-sdk/e2e/tools-structured-output.ts`
|
|
108
|
+
- This is the public-path release acceptance matrix: `qgrid()` HTTP/SSE,
|
|
109
|
+
`generateText`/`streamText`, OpenAI/Anthropic, direct final answers, and one
|
|
110
|
+
client-tool result followed by `Output.object`.
|
|
111
|
+
- It consumes real provider quota and requires the explicit
|
|
112
|
+
`QGRID_REAL_PROVIDER_ACCEPTANCE=1` opt-in.
|
|
113
|
+
- Uses `QGRID_URL`, `QGRID_ACCEPTANCE_OPENAI_MODEL`, and
|
|
114
|
+
`QGRID_ACCEPTANCE_ANTHROPIC_MODEL`. OpenAI direct-final coverage defaults to
|
|
115
|
+
10 generate plus 10 stream attempts and can be changed with
|
|
116
|
+
`QGRID_ACCEPTANCE_OPENAI_DIRECT_REPEATS_PER_MODE`. Request logs use the stable
|
|
117
|
+
project name `qgrid-ai-sdk-tools-output-acceptance`.
|
|
118
|
+
|
|
104
119
|
Image generation:
|
|
105
120
|
|
|
106
121
|
- `packages/api/scripts/smoke-test-image-generation.ts`
|