Skip to content

refactor(core): simplify model JSON parsing - #2690

Merged
EAGzzyCSL merged 4 commits into
mainfrom
zzy/json-repair
Jul 6, 2026
Merged

EAGzzyCSL merged 4 commits into
mainfrom
zzy/json-repair

Conversation

@EAGzzyCSL

Copy link
Copy Markdown
Collaborator

Summary

  • Unify model response JSON parsing around extract -> jsonrepair -> parse -> parsed-object post-processing.
  • Remove tuple-specific fallback parsing and collapse the old safe/normal parser split into parseModelResponseJsonObject.
  • Route Doubao and UI-TARS JSON parsing through the shared parser while leaving bbox normalization to their post-parse coordinate logic.
  • Move JSON parser unit coverage into a dedicated json.test.ts file.

Validation

  • pnpm --filter @midscene/core test -- tests/unit-test/json.test.ts tests/unit-test/utils.test.ts tests/unit-test/model-adapter/doubao.test.ts tests/unit-test/model-adapter/ui-tars.test.ts
  • pnpm --filter @midscene/core test -- --coverage tests/unit-test/json.test.ts

Notes

  • The commit hook ran its configured lint-staged/biome checks automatically during commit.

@EAGzzyCSL
EAGzzyCSL marked this pull request as ready for review June 17, 2026 07:12
@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Jun 17, 2026 •

Copy link
Copy Markdown

Deploying midscene with  Cloudflare Pages  Cloudflare Pages

Latest commit: 5c9ce49
Status: ✅  Deploy successful!
Preview URL: https://6091c8e3.midscene.pages.dev
Branch Preview URL: https://zzy-json-repair.midscene.pages.dev

View logs

@EAGzzyCSL
EAGzzyCSL force-pushed the zzy/json-repair branch 3 times, most recently from 691cf5c to 853f6f5 Compare June 22, 2026 12:11
@EAGzzyCSL
EAGzzyCSL enabled auto-merge (squash) June 23, 2026 08:30

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR refactors @midscene/core model-response JSON parsing into a single pipeline (extract -> jsonrepair -> parse -> post-process), routes adapter parsers (Doubao, UI-TARS) through the shared implementation, and reorganizes unit tests to concentrate JSON parsing coverage in a dedicated suite.

Changes:

  • Replaced the old safe/normal JSON parsing split with parseModelResponseJson() and updated call sites to use it.
  • Simplified adapter-specific JSON parsing (Doubao / UI-TARS) to use the shared parser; adapter logic remains focused on post-parse coordinate handling.
  • Moved/updated unit tests: removed scattered parser tests and introduced tests/unit-test/json.test.ts as the primary coverage location.

Reviewed changes

Copilot reviewed 22 out of 23 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
pnpm-lock.yaml Lockfile update reflecting dependency changes (incl. jsonrepair bump).
packages/core/package.json Bumps jsonrepair from 3.12.0 to 3.14.0.
packages/core/src/ai-model/service-caller/json.ts Introduces unified JSON parsing via parseModelResponseJson() and shared trimming normalization.
packages/core/src/ai-model/service-caller/index.ts Re-exports the new shared JSON parser API.
packages/core/src/ai-model/prompt/extraction.ts Switches XML extraction parsing to parseModelResponseJson() with requireObject: false.
packages/core/src/ai-model/models/doubao.ts Routes Doubao JSON parsing through the shared parser (removes adapter-local fallback parser code).
packages/core/src/ai-model/models/ui-tars/adapter.ts Routes UI-TARS JSON parsing through the shared parser (removes adapter-local fallback parser code).
packages/core/src/ai-model/model-adapter/resolve.ts Updates default/lenient JSON parser resolution to use parseModelResponseJson().
packages/core/src/ai-model/models/utils/intent.ts Adds isLocateIntent() helper for intent checks shared by model adapters.
packages/core/src/ai-model/models/mimo.ts Adjusts response_format behavior to only set JSON mode for locate intent.
packages/core/src/ai-model/models/kimi.ts Sets response_format: json_object for locate intent.
packages/core/src/ai-model/models/gpt.ts Uses isLocateIntent() for original image detail + sets JSON mode for locate intent.
packages/core/src/ai-model/models/glm.ts Sets response_format: json_object for locate intent.
packages/core/src/ai-model/models/qwen.ts Adds commented reference for JSON mode behavior considerations.
packages/core/tests/unit-test/utils.test.ts Removes JSON parsing tests that were moved into the dedicated JSON test file.
packages/core/tests/unit-test/service-caller.test.ts Deletes the old service-caller JSON normalization test suite (coverage moved).
packages/core/tests/unit-test/json.test.ts New dedicated JSON parsing test suite (extract + parse + normalization + adapter behavior hooks).
packages/core/tests/unit-test/model-adapter/doubao.test.ts Updates adapter tests to match shared-parser behavior and removes adapter-local parser helper tests.
packages/core/tests/unit-test/model-adapter/ui-tars/adapter-json-repair.test.ts Updates UI-TARS adapter tests to validate shared-parser behavior directly.
packages/core/tests/unit-test/model-adapter/mimo.test.ts Updates expected request config (response_format changes).
packages/core/tests/unit-test/model-adapter/kimi.test.ts Adds coverage for locate intent JSON mode config.
packages/core/tests/unit-test/model-adapter/gpt.test.ts Adds coverage for locate intent JSON mode config.
packages/core/tests/unit-test/model-adapter/glm.test.ts Adds coverage for locate intent JSON mode config.
Files not reviewed (1)
  • pnpm-lock.yaml: Generated file

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 144 to +145
const cleanJsonString = extractJSONFromCodeBlock(raw);
const result = parseNormalJson(cleanJsonString, raw, context);
if (
result &&
typeof result === 'object' &&
'parsed' in result &&
result.parsed === undefined
) {
throw Error(
`failed to parse LLM response into JSON. Error - ${String(
result.lastError ?? 'unknown error',
)}. Response - \n ${raw}`,
);
const requireObject = context?.requireObject ?? true;
Comment on lines +98 to +119
it('should allow top-level non-object JSON values when object validation is disabled', () => {
expect(
parseModelResponseJson('[" todo 1 ", " todo 2 "]', {
source: 'generic-object',
requireObject: false,
}),
).toEqual(['todo 1', 'todo 2']);

expect(
parseModelResponseJson('" todo list "', {
source: 'generic-object',
requireObject: false,
}),
).toBe('todo list');

expect(
parseModelResponseJson('42', {
source: 'generic-object',
requireObject: false,
}),
).toBe(42);
});
@EAGzzyCSL
EAGzzyCSL merged commit a981f3f into main Jul 6, 2026
6 checks passed
@EAGzzyCSL
EAGzzyCSL deleted the zzy/json-repair branch July 6, 2026 08:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants