Initial TrueGrowth source import
This commit is contained in:
18
openspec/changes/refactor-ai-json-response-parser/design.md
Normal file
18
openspec/changes/refactor-ai-json-response-parser/design.md
Normal file
@@ -0,0 +1,18 @@
|
||||
## Context
|
||||
大模型 JSON 输出不是稳定的裸 JSON:可能被 `<think>`、代码块、自然语言说明或多个候选 JSON 包裹。业务模块需要根据自身 schema 选择正确候选,而不是各自用正则或贪婪匹配。
|
||||
|
||||
## Goals
|
||||
- 提供无组件/服务依赖的纯工具,避免循环依赖。
|
||||
- 支持对象和数组协议,并允许 predicate 选择业务匹配候选。
|
||||
- 让业务模块保留现有校验、normalize、修复和降级策略。
|
||||
|
||||
## Non-Goals
|
||||
- 不替换 localStorage、GitHub 同步、备份、HTTP API body 等普通 JSON 解析。
|
||||
- 不引入流式增量 JSON 解析。
|
||||
- 不统一各业务返回 schema。
|
||||
|
||||
## Decisions
|
||||
- 工具放在 `packages/drawnix/src/utils/llm-json-extractor.ts`。
|
||||
- 候选查找顺序优先使用 fenced JSON、去除完整 `<think>` 后的内容、`</think>` 后内容、最后回退完整文本。
|
||||
- 使用括号平衡扫描,并识别 JSON 字符串内的括号和转义,避免字符串内容破坏平衡。
|
||||
- `extractJsonValue` 返回已解析值,`extractJsonSource` 返回原始 JSON 字符串,兼容需要二次修复/解析的旧逻辑。
|
||||
@@ -0,0 +1,18 @@
|
||||
# Change: Refactor AI JSON response parsing
|
||||
|
||||
## Why
|
||||
部分大模型会在 JSON 前后输出 `<think>`、Markdown、解释文本或多个候选片段,现有各业务入口解析方式不一致,容易误取思考区伪 JSON 或因前缀文本报错。
|
||||
|
||||
## What Changes
|
||||
- 新增纯工具统一提取大模型返回中的 JSON 对象/数组候选。
|
||||
- 只迁移 AI/LLM 返回 JSON 的解析入口,保留普通存储、同步、HTTP 响应 JSON 解析现状。
|
||||
- 将爆款视频、爆款 MV、漫画、音乐、长视频、PPT outline、Agent workflow、技能解析等业务入口改为共享候选提取,业务层继续负责 schema 校验、normalize 和降级策略。
|
||||
- 为共享工具和关键业务入口补充回归测试。
|
||||
|
||||
## Impact
|
||||
- Affected specs: ai-json-response-parsing
|
||||
- Affected code:
|
||||
- `packages/drawnix/src/utils/llm-json-extractor.ts`
|
||||
- `packages/drawnix/src/components/*`
|
||||
- `packages/drawnix/src/services/*`
|
||||
- `packages/drawnix/src/mcp/tools/*`
|
||||
@@ -0,0 +1,21 @@
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: AI JSON responses must use shared candidate extraction
|
||||
|
||||
When parsing JSON returned by AI/LLM text generation, the system SHALL use a shared candidate extraction utility that supports object and array contracts, Markdown code fences, `<think>` blocks, surrounding prose, and multiple JSON candidates.
|
||||
|
||||
#### Scenario: Thinking text contains a mismatched JSON candidate
|
||||
- **GIVEN** an AI response contains a `<think>` block with a JSON-like candidate that does not match the business schema
|
||||
- **AND** the final response body contains a valid JSON object that matches the schema predicate
|
||||
- **WHEN** the business parser extracts the AI JSON response
|
||||
- **THEN** it selects the matching final JSON object instead of the thinking candidate
|
||||
|
||||
#### Scenario: JSON strings contain bracket characters
|
||||
- **GIVEN** an AI response contains JSON with string values that include `{`, `}`, `[`, or `]`
|
||||
- **WHEN** the shared extractor scans for balanced candidates
|
||||
- **THEN** bracket characters inside strings do not terminate or corrupt the candidate
|
||||
|
||||
#### Scenario: Non-AI JSON parsing remains unchanged
|
||||
- **GIVEN** code parses stored settings, backups, sync payloads, or HTTP API bodies
|
||||
- **WHEN** those payloads are not AI/LLM free-text responses
|
||||
- **THEN** the system may continue using direct JSON parsing and does not route them through the AI JSON extractor
|
||||
@@ -0,0 +1,6 @@
|
||||
## 1. Implementation
|
||||
- [x] 1.1 Add `llm-json-extractor` pure utility and unit tests.
|
||||
- [x] 1.2 Migrate component-side AI JSON parsing entrances.
|
||||
- [x] 1.3 Migrate service/tool-side AI JSON parsing entrances while preserving business fallbacks.
|
||||
- [x] 1.4 Update focused regression tests.
|
||||
- [x] 1.5 Run OpenSpec validation, targeted Vitest, and drawnix typecheck.
|
||||
Reference in New Issue
Block a user