@thanh01.pmt/curriculum-kit 1.4.51 → 1.4.52
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/ai/index.cjs +148 -3
- package/dist/ai/index.cjs.map +1 -1
- package/dist/ai/index.mjs +148 -3
- package/dist/ai/index.mjs.map +1 -1
- package/dist/index.cjs +23295 -23257
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +23296 -23258
- package/dist/index.mjs.map +1 -1
- package/dist/pipeline/index.cjs +148 -1
- package/dist/pipeline/index.cjs.map +1 -1
- package/dist/pipeline/index.mjs +148 -1
- package/dist/pipeline/index.mjs.map +1 -1
- package/dist/workflow/index.cjs +152 -1
- package/dist/workflow/index.cjs.map +1 -1
- package/dist/workflow/index.mjs +152 -1
- package/dist/workflow/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/ai/index.mjs
CHANGED
|
@@ -6,6 +6,7 @@ import path from 'path';
|
|
|
6
6
|
import { fileURLToPath } from 'url';
|
|
7
7
|
import { generateObject, streamObject } from 'ai';
|
|
8
8
|
import { z } from 'zod';
|
|
9
|
+
import { jsonrepair } from 'jsonrepair';
|
|
9
10
|
|
|
10
11
|
// src/ai/provider-factory.ts
|
|
11
12
|
|
|
@@ -4008,11 +4009,155 @@ async function generateExtensionFlow(input) {
|
|
|
4008
4009
|
});
|
|
4009
4010
|
return object;
|
|
4010
4011
|
}
|
|
4012
|
+
function closeTruncatedJson(candidate) {
|
|
4013
|
+
let inStr = false;
|
|
4014
|
+
let esc = false;
|
|
4015
|
+
const stack = [];
|
|
4016
|
+
for (let i = 0; i < candidate.length; i++) {
|
|
4017
|
+
const ch = candidate[i];
|
|
4018
|
+
if (esc) {
|
|
4019
|
+
esc = false;
|
|
4020
|
+
continue;
|
|
4021
|
+
}
|
|
4022
|
+
if (inStr) {
|
|
4023
|
+
if (ch === "\\") esc = true;
|
|
4024
|
+
else if (ch === '"') inStr = false;
|
|
4025
|
+
continue;
|
|
4026
|
+
}
|
|
4027
|
+
if (ch === '"') inStr = true;
|
|
4028
|
+
else if (ch === "{" || ch === "[") stack.push(ch);
|
|
4029
|
+
else if (ch === "}" || ch === "]") stack.pop();
|
|
4030
|
+
}
|
|
4031
|
+
if (stack.length === 0 && !inStr) return null;
|
|
4032
|
+
let out = candidate;
|
|
4033
|
+
out = out.replace(/,\s*$/, "");
|
|
4034
|
+
if (inStr) {
|
|
4035
|
+
out = out.replace(/\\+$/, "");
|
|
4036
|
+
out += '"';
|
|
4037
|
+
}
|
|
4038
|
+
while (stack.length > 0) {
|
|
4039
|
+
out += stack.pop() === "{" ? "}" : "]";
|
|
4040
|
+
}
|
|
4041
|
+
return out;
|
|
4042
|
+
}
|
|
4043
|
+
function stripLlmJsonWrappers(rawText) {
|
|
4044
|
+
let cleaned = rawText.replace(/<think>[\s\S]*?<\/think>/gi, "").replace(/```json\s*/gi, "").replace(/```\s*/g, "").trim();
|
|
4045
|
+
const firstBrace = cleaned.indexOf("{");
|
|
4046
|
+
if (firstBrace > 0) {
|
|
4047
|
+
cleaned = cleaned.slice(firstBrace);
|
|
4048
|
+
}
|
|
4049
|
+
return cleaned.trim();
|
|
4050
|
+
}
|
|
4051
|
+
function safeParseJson(rawText) {
|
|
4052
|
+
if (!rawText) return null;
|
|
4053
|
+
const cleaned = stripLlmJsonWrappers(rawText);
|
|
4054
|
+
if (!cleaned) return null;
|
|
4055
|
+
try {
|
|
4056
|
+
return JSON.parse(cleaned);
|
|
4057
|
+
} catch {
|
|
4058
|
+
}
|
|
4059
|
+
const firstBrace = cleaned.indexOf("{");
|
|
4060
|
+
if (firstBrace === -1) return null;
|
|
4061
|
+
const buildCandidates = () => {
|
|
4062
|
+
const list = [];
|
|
4063
|
+
const closed = closeTruncatedJson(cleaned.slice(firstBrace));
|
|
4064
|
+
if (closed) list.push(closed);
|
|
4065
|
+
const lastBrace = cleaned.lastIndexOf("}");
|
|
4066
|
+
if (lastBrace > firstBrace) {
|
|
4067
|
+
list.push(cleaned.slice(firstBrace, lastBrace + 1));
|
|
4068
|
+
}
|
|
4069
|
+
return list;
|
|
4070
|
+
};
|
|
4071
|
+
for (const candidate of buildCandidates()) {
|
|
4072
|
+
try {
|
|
4073
|
+
return JSON.parse(candidate);
|
|
4074
|
+
} catch {
|
|
4075
|
+
}
|
|
4076
|
+
try {
|
|
4077
|
+
return JSON.parse(jsonrepair(candidate));
|
|
4078
|
+
} catch {
|
|
4079
|
+
}
|
|
4080
|
+
}
|
|
4081
|
+
let depth = 0;
|
|
4082
|
+
let inStr = false;
|
|
4083
|
+
let esc = false;
|
|
4084
|
+
for (let i = firstBrace; i < cleaned.length; i++) {
|
|
4085
|
+
const ch = cleaned[i];
|
|
4086
|
+
if (esc) {
|
|
4087
|
+
esc = false;
|
|
4088
|
+
continue;
|
|
4089
|
+
}
|
|
4090
|
+
if (inStr) {
|
|
4091
|
+
if (ch === "\\") esc = true;
|
|
4092
|
+
else if (ch === '"') inStr = false;
|
|
4093
|
+
continue;
|
|
4094
|
+
}
|
|
4095
|
+
if (ch === '"') inStr = true;
|
|
4096
|
+
else if (ch === "{") depth++;
|
|
4097
|
+
else if (ch === "}") {
|
|
4098
|
+
depth--;
|
|
4099
|
+
if (depth === 0) {
|
|
4100
|
+
const candidate = cleaned.slice(firstBrace, i + 1);
|
|
4101
|
+
try {
|
|
4102
|
+
return JSON.parse(candidate);
|
|
4103
|
+
} catch {
|
|
4104
|
+
}
|
|
4105
|
+
try {
|
|
4106
|
+
return JSON.parse(jsonrepair(candidate));
|
|
4107
|
+
} catch {
|
|
4108
|
+
}
|
|
4109
|
+
}
|
|
4110
|
+
}
|
|
4111
|
+
}
|
|
4112
|
+
try {
|
|
4113
|
+
return JSON.parse(jsonrepair(cleaned));
|
|
4114
|
+
} catch {
|
|
4115
|
+
}
|
|
4116
|
+
return null;
|
|
4117
|
+
}
|
|
4011
4118
|
|
|
4012
4119
|
// src/constants/pedagogy.ts
|
|
4013
4120
|
var JUDGE_AUTO_APPROVE_THRESHOLD = 85;
|
|
4014
4121
|
|
|
4015
4122
|
// src/ai/flows/auditCurriculumQualityFlow.ts
|
|
4123
|
+
var REPAIR_SUFFIX = "\n\nCRITICAL OUTPUT FORMAT FIX: your previous response could not be parsed as JSON. Output ONLY the raw JSON object \u2014 no markdown code fences, no prose before or after. Start with { and end with }.";
|
|
4124
|
+
function extractRawText(err) {
|
|
4125
|
+
const e = err;
|
|
4126
|
+
if (typeof e?.text === "string" && e.text) return e.text;
|
|
4127
|
+
const cause = e?.cause;
|
|
4128
|
+
if (typeof cause?.text === "string" && cause.text) return cause.text;
|
|
4129
|
+
const msg = typeof e?.message === "string" ? e.message : typeof cause?.message === "string" ? cause.message : "";
|
|
4130
|
+
const m = msg.match(/Text: ([\s\S]+)/);
|
|
4131
|
+
return m ? m[1] : "";
|
|
4132
|
+
}
|
|
4133
|
+
async function generateJudgeObject(opts) {
|
|
4134
|
+
let firstText = "";
|
|
4135
|
+
try {
|
|
4136
|
+
return (await generateObject({ model: opts.model, schema: opts.schema, prompt: opts.prompt })).object;
|
|
4137
|
+
} catch (err) {
|
|
4138
|
+
firstText = extractRawText(err);
|
|
4139
|
+
if (firstText) {
|
|
4140
|
+
const salvaged = safeParseJson(firstText);
|
|
4141
|
+
if (salvaged) {
|
|
4142
|
+
const check = opts.schema.safeParse(salvaged);
|
|
4143
|
+
if (check.success) return check.data;
|
|
4144
|
+
}
|
|
4145
|
+
}
|
|
4146
|
+
try {
|
|
4147
|
+
return (await generateObject({ model: opts.model, schema: opts.schema, prompt: opts.prompt + REPAIR_SUFFIX })).object;
|
|
4148
|
+
} catch (err2) {
|
|
4149
|
+
const secondText = extractRawText(err2);
|
|
4150
|
+
if (secondText && secondText !== firstText) {
|
|
4151
|
+
const salvaged2 = safeParseJson(secondText);
|
|
4152
|
+
if (salvaged2) {
|
|
4153
|
+
const check2 = opts.schema.safeParse(salvaged2);
|
|
4154
|
+
if (check2.success) return check2.data;
|
|
4155
|
+
}
|
|
4156
|
+
}
|
|
4157
|
+
throw err2;
|
|
4158
|
+
}
|
|
4159
|
+
}
|
|
4160
|
+
}
|
|
4016
4161
|
async function auditCurriculumQualityFlow(input) {
|
|
4017
4162
|
const model = getAIModel(input.modelOptions);
|
|
4018
4163
|
const prompt = buildJudgePrompt({
|
|
@@ -4023,7 +4168,7 @@ async function auditCurriculumQualityFlow(input) {
|
|
|
4023
4168
|
generatedContentJson: input.generatedContentJson,
|
|
4024
4169
|
standardStatements: input.standardStatements
|
|
4025
4170
|
});
|
|
4026
|
-
const
|
|
4171
|
+
const object = await generateJudgeObject({
|
|
4027
4172
|
model,
|
|
4028
4173
|
schema: CurriculumQualityReportSchema,
|
|
4029
4174
|
prompt: `${prompt}
|
|
@@ -4040,7 +4185,7 @@ async function auditCurriculumPlanFlow(input) {
|
|
|
4040
4185
|
expectedLanguage: input.expectedLanguage,
|
|
4041
4186
|
linterFindings: input.linterFindings
|
|
4042
4187
|
});
|
|
4043
|
-
const
|
|
4188
|
+
const object = await generateJudgeObject({
|
|
4044
4189
|
model,
|
|
4045
4190
|
schema: MacroPedagogyPlanAuditSchema,
|
|
4046
4191
|
prompt: `${prompt}
|
|
@@ -4060,7 +4205,7 @@ async function auditProjectGraphFlow(input) {
|
|
|
4060
4205
|
briefingContext: input.briefingContext,
|
|
4061
4206
|
linterFindings: input.linterFindings
|
|
4062
4207
|
});
|
|
4063
|
-
const
|
|
4208
|
+
const object = await generateJudgeObject({
|
|
4064
4209
|
model,
|
|
4065
4210
|
schema: ProjectGraphAuditSchema,
|
|
4066
4211
|
prompt: `${prompt}
|