@zodic/shared 0.0.213 → 0.0.215
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/app/services/ConceptService.ts +36 -11
- package/package.json +1 -1
- package/types/scopes/generic.ts +1 -2
- package/utils/buildMessages.ts +51 -41
|
@@ -1089,27 +1089,52 @@ export class ConceptService {
|
|
|
1089
1089
|
break;
|
|
1090
1090
|
}
|
|
1091
1091
|
|
|
1092
|
-
|
|
1093
|
-
const [generatedEN, generatedPT] = aiResponse.split('\n').map((s) => s.trim());
|
|
1092
|
+
console.log(`📝 Raw AI Response:\n${aiResponse}`);
|
|
1094
1093
|
|
|
1095
|
-
|
|
1094
|
+
// ✅ Correctly map concept names and gendered articles
|
|
1095
|
+
const conceptMapping = {
|
|
1096
|
+
amulet: { en: "Amulet", pt: "Amuleto", articlePT: "O" },
|
|
1097
|
+
crown: { en: "Crown", pt: "Coroa", articlePT: "A" },
|
|
1098
|
+
scepter: { en: "Scepter", pt: "Cetro", articlePT: "O" },
|
|
1099
|
+
lantern: { en: "Lantern", pt: "Candeia", articlePT: "A" },
|
|
1100
|
+
ring: { en: "Ring", pt: "Anel", articlePT: "O" },
|
|
1101
|
+
orb: { en: "Orb", pt: "Orbe", articlePT: "O" },
|
|
1102
|
+
};
|
|
1103
|
+
|
|
1104
|
+
const { en: conceptEN, pt: conceptPT, articlePT } = conceptMapping[conceptSlug] || {
|
|
1105
|
+
en: conceptSlug,
|
|
1106
|
+
pt: conceptSlug,
|
|
1107
|
+
articlePT: "O", // Default to "O" if concept is missing
|
|
1108
|
+
};
|
|
1109
|
+
|
|
1110
|
+
// ✅ Strict regex matching for English and Portuguese
|
|
1111
|
+
const enMatch = aiResponse.match(new RegExp(`EN:\\s*The ${conceptEN} of [A-Za-z\\s]+`));
|
|
1112
|
+
const ptMatch = aiResponse.match(new RegExp(`PT:\\s*${articlePT} ${conceptPT} de [A-Za-z\\s]+`));
|
|
1113
|
+
|
|
1114
|
+
if (!enMatch || !ptMatch) {
|
|
1115
|
+
console.error(`❌ Invalid AI response format! Retrying...`);
|
|
1116
|
+
continue;
|
|
1117
|
+
}
|
|
1118
|
+
|
|
1119
|
+
newNameEN = enMatch[0].replace(/^EN:\s*/, '').trim();
|
|
1120
|
+
newNamePT = ptMatch[0].replace(/^PT:\s*/, '').trim();
|
|
1121
|
+
|
|
1122
|
+
console.log(`🎨 Extracted Names: EN - "${newNameEN}", PT - "${newNamePT}"`);
|
|
1096
1123
|
|
|
1097
1124
|
// ✅ Check if the name already exists
|
|
1098
1125
|
if (
|
|
1099
|
-
usedNamesEN.has(
|
|
1100
|
-
usedNamesPT.has(
|
|
1101
|
-
recentDuplicates.has(
|
|
1126
|
+
usedNamesEN.has(newNameEN) ||
|
|
1127
|
+
usedNamesPT.has(newNamePT) ||
|
|
1128
|
+
recentDuplicates.has(newNameEN)
|
|
1102
1129
|
) {
|
|
1103
1130
|
console.warn(
|
|
1104
|
-
`⚠️ Duplicate detected: EN - "${
|
|
1131
|
+
`⚠️ Duplicate detected: EN - "${newNameEN}", PT - "${newNamePT}". Retrying...`
|
|
1105
1132
|
);
|
|
1106
|
-
recentDuplicates.add(
|
|
1107
|
-
recentDuplicates.add(
|
|
1133
|
+
recentDuplicates.add(newNameEN);
|
|
1134
|
+
recentDuplicates.add(newNamePT);
|
|
1108
1135
|
continue;
|
|
1109
1136
|
}
|
|
1110
1137
|
|
|
1111
|
-
newNameEN = generatedEN;
|
|
1112
|
-
newNamePT = generatedPT;
|
|
1113
1138
|
recentDuplicates.add(newNameEN);
|
|
1114
1139
|
recentDuplicates.add(newNamePT);
|
|
1115
1140
|
break; // ✅ Found unique names, exit retry loop
|
package/package.json
CHANGED
package/types/scopes/generic.ts
CHANGED
package/utils/buildMessages.ts
CHANGED
|
@@ -188,52 +188,62 @@ export const buildLLMMessages = (env: BackendBindings) => ({
|
|
|
188
188
|
}: {
|
|
189
189
|
oldNameEN: string;
|
|
190
190
|
description: string;
|
|
191
|
-
conceptSlug:
|
|
191
|
+
conceptSlug: Concept;
|
|
192
192
|
recentNames?: string[];
|
|
193
|
-
}): ChatMessages =>
|
|
194
|
-
{
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
193
|
+
}): ChatMessages => {
|
|
194
|
+
const conceptNameMap: Record<Concept, Record<'en' | 'pt', string>> = {
|
|
195
|
+
crown: { en: 'The Crown of', pt: 'A Coroa de' },
|
|
196
|
+
scepter: { en: 'The Scepter of', pt: 'O Cetro de' },
|
|
197
|
+
amulet: { en: 'The Amulet of', pt: 'O Amuleto de' },
|
|
198
|
+
ring: { en: 'The Ring of', pt: 'O Anel de' },
|
|
199
|
+
lantern: { en: 'The Lantern of', pt: 'A Candeia de' },
|
|
200
|
+
orb: { en: 'The Orb of', pt: 'O Orbe de' },
|
|
201
|
+
} as const;
|
|
202
|
+
|
|
203
|
+
// ✅ Get the correct mapped names
|
|
204
|
+
const conceptMapping = conceptNameMap[conceptSlug] || {
|
|
205
|
+
en: `The ${conceptSlug} of`,
|
|
206
|
+
pt: `O ${conceptSlug} de`,
|
|
207
|
+
};
|
|
208
|
+
|
|
209
|
+
return [
|
|
210
|
+
{
|
|
211
|
+
role: 'system',
|
|
212
|
+
content: `
|
|
213
|
+
You are an expert in mystical and symbolic naming. Your task is to generate a new, unique name for a given concept while ensuring it aligns with its description.
|
|
214
|
+
|
|
215
|
+
Guidelines:
|
|
216
|
+
• The name must have exactly six words.
|
|
217
|
+
• It must start with "${conceptMapping.en}" in English and "${
|
|
218
|
+
conceptMapping.pt
|
|
219
|
+
}" in Portuguese.
|
|
220
|
+
• The last three words should be distinct, meaningful, and thematically relevant.
|
|
221
|
+
• It should reflect the concept’s core essence such as protection, transformation, or resilience.
|
|
222
|
+
• Avoid generic, redundant, or overly abstract terms.
|
|
223
|
+
• The name must not match any of the recently generated names.
|
|
224
|
+
|
|
225
|
+
Example of a valid format:
|
|
226
|
+
${conceptMapping.en} Strong Radiant Will
|
|
227
|
+
|
|
228
|
+
No explanations or additional text. Return only the names exactly in the following format:
|
|
198
229
|
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
• It must start with "The ${conceptSlug} of" in English and "O ${conceptSlug} de" in Portuguese.
|
|
202
|
-
• The last three words should be distinct, meaningful, and thematically relevant.
|
|
203
|
-
• It should reflect the concept’s core essence such as protection, transformation, or resilience.
|
|
204
|
-
• Avoid generic, redundant, or overly abstract terms.
|
|
205
|
-
• Ensure it does not resemble the previous name.
|
|
206
|
-
• The name must not match any of the recently generated names.
|
|
230
|
+
EN:
|
|
231
|
+
${conceptMapping.en} [New Symbolic Concept]
|
|
207
232
|
|
|
208
|
-
|
|
209
|
-
|
|
233
|
+
PT:
|
|
234
|
+
${conceptMapping.pt} [Novo Conceito Simbólico]
|
|
235
|
+
`,
|
|
236
|
+
},
|
|
237
|
+
{
|
|
238
|
+
role: 'user',
|
|
239
|
+
content: `
|
|
210
240
|
• Previous Name Already Used: ${oldNameEN}
|
|
211
|
-
• Recently Generated Names: ${
|
|
241
|
+
• Recently Generated Names (Do not use these): ${
|
|
212
242
|
recentNames.length > 0 ? recentNames.join(', ') : 'None'
|
|
213
243
|
}
|
|
214
244
|
• Description: ${description}
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
• New Name: The ${conceptSlug} of [New Symbolic Concept]
|
|
220
|
-
|
|
221
|
-
PT:
|
|
222
|
-
• Novo Nome: O ${conceptSlug} de [Novo Conceito Simbólico]
|
|
223
|
-
|
|
224
|
-
No explanations or additional text. Return only the names.
|
|
225
|
-
`,
|
|
226
|
-
},
|
|
227
|
-
{
|
|
228
|
-
role: 'user',
|
|
229
|
-
content: `
|
|
230
|
-
• Concept Name: ${conceptSlug}
|
|
231
|
-
• Previous Name Already Used: ${oldNameEN}
|
|
232
|
-
• Recently Generated Names: ${
|
|
233
|
-
recentNames.length > 0 ? recentNames.join(', ') : 'None'
|
|
234
|
-
}
|
|
235
|
-
• Description: ${description}
|
|
236
|
-
`,
|
|
237
|
-
},
|
|
238
|
-
],
|
|
245
|
+
`,
|
|
246
|
+
},
|
|
247
|
+
];
|
|
248
|
+
},
|
|
239
249
|
});
|