@zhouchangui/math-ati 0.1.4 → 0.1.5

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/dist/index.html CHANGED
@@ -4,8 +4,8 @@
4
4
  <meta charset="UTF-8" />
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
6
  <title>学生数学提分 Agent</title>
7
- <script type="module" crossorigin src="/assets/index-DyfeTKmg.js"></script>
8
- <link rel="stylesheet" crossorigin href="/assets/index-DOg8CQsE.css">
7
+ <script type="module" crossorigin src="/assets/index-w2k_4Owd.js"></script>
8
+ <link rel="stylesheet" crossorigin href="/assets/index-CJkqklO7.css">
9
9
  </head>
10
10
  <body>
11
11
  <div id="root"></div>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zhouchangui/math-ati",
3
- "version": "0.1.4",
3
+ "version": "0.1.5",
4
4
  "description": "Local ATI math learning loop for printable practice, PDF grading, and mastery tracking.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -714,7 +714,7 @@ function recommendedQuestionCount(targetCount, maxQuestionCount) {
714
714
 
715
715
  function isGeometryLikeChapter(chapter) {
716
716
  const text = `${chapter?.title || ''} ${chapter?.fullTitle || ''} ${chapter?.track || ''}`;
717
- return /几何|图形|三角形|平行|垂直|圆|角|线段|直线|射线|展开图|立体/.test(text);
717
+ return /几何|图形|三角形|平行|垂直|圆|线段|直线|射线|展开图|立体/.test(text);
718
718
  }
719
719
 
720
720
  async function readPracticeSystemPrompt(promptName, context) {
@@ -1168,6 +1168,7 @@ export async function generatePracticeContent(input) {
1168
1168
  step: 'practice_generate.coverage_repair',
1169
1169
  message: `正在修复知识点覆盖缺口:${missingPointLabels}。`
1170
1170
  });
1171
+ let repairSkipped = false;
1171
1172
  try {
1172
1173
  const repairResult = await callPracticeAgentCached({
1173
1174
  cacheDir: stageCacheDir,
@@ -120,6 +120,28 @@ function duplicateFindings(questions, historicalQuestions) {
120
120
  return findings;
121
121
  }
122
122
 
123
+ function svgMarkupFinding(question) {
124
+ const svg = String(question.svg || '').trim();
125
+ if (!svg) return null;
126
+ if (!/^<svg[\s>]/i.test(svg) || !/<\/svg>\s*$/i.test(svg)) {
127
+ return {
128
+ level: 'blocker',
129
+ type: 'invalid_svg_markup',
130
+ questionId: question.id,
131
+ message: '题目 SVG 必须是可直接内联渲染的 <svg>...</svg> 标记,不能是转义文本、Markdown 代码块或说明文字。'
132
+ };
133
+ }
134
+ if (/<script\b|<foreignObject\b|on[a-z]+\s*=|javascript:/i.test(svg)) {
135
+ return {
136
+ level: 'blocker',
137
+ type: 'unsafe_svg_markup',
138
+ questionId: question.id,
139
+ message: '题目 SVG 包含脚本、foreignObject、事件属性或 javascript 链接,不能写入试卷预览。'
140
+ };
141
+ }
142
+ return null;
143
+ }
144
+
123
145
  function personalizationFindings(practice, options) {
124
146
  const profile = typeProfiles[options.type] ?? typeProfiles.foundation;
125
147
  const findings = [];
@@ -149,6 +171,8 @@ function personalizationFindings(practice, options) {
149
171
  });
150
172
  }
151
173
  for (const question of practice.questions) {
174
+ const svgFinding = svgMarkupFinding(question);
175
+ if (svgFinding) findings.push(svgFinding);
152
176
  if (!profile.allowedDifficulties.includes(question.difficulty)) {
153
177
  findings.push({
154
178
  level: 'warning',
@@ -285,7 +285,7 @@ export async function createPractice({
285
285
  const requestedMinSvgQuestions = Number(minSvgQuestions);
286
286
  const effectiveMinSvgQuestions = Number.isFinite(requestedMinSvgQuestions) && requestedMinSvgQuestions > 0
287
287
  ? Math.floor(requestedMinSvgQuestions)
288
- : autoGeometryVisualCheck
288
+ : (autoGeometryVisualCheck && verifySvgFigures === undefined)
289
289
  ? Math.max(1, Math.min(4, Math.ceil(maxQuestionCount / 4)))
290
290
  : 0;
291
291
  const options = {
@@ -301,7 +301,7 @@ export async function createPractice({
301
301
  questionKind,
302
302
  generationCacheDir,
303
303
  fastReview: Boolean(fastReview),
304
- verifySvgFigures: Boolean(verifySvgFigures) || autoGeometryVisualCheck,
304
+ verifySvgFigures: verifySvgFigures !== undefined ? Boolean(verifySvgFigures) : autoGeometryVisualCheck,
305
305
  requireSvg: Boolean(requireSvg),
306
306
  minSvgQuestions: effectiveMinSvgQuestions,
307
307
  knowledgeDoc: knowledgeBundle.knowledge,