@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.
@@ -1089,27 +1089,52 @@ export class ConceptService {
1089
1089
  break;
1090
1090
  }
1091
1091
 
1092
- // Parse AI response
1093
- const [generatedEN, generatedPT] = aiResponse.split('\n').map((s) => s.trim());
1092
+ console.log(`📝 Raw AI Response:\n${aiResponse}`);
1094
1093
 
1095
- console.log(`🎨 AI Response: EN - "${generatedEN}", PT - "${generatedPT}"`);
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(generatedEN) ||
1100
- usedNamesPT.has(generatedPT) ||
1101
- recentDuplicates.has(generatedEN)
1126
+ usedNamesEN.has(newNameEN) ||
1127
+ usedNamesPT.has(newNamePT) ||
1128
+ recentDuplicates.has(newNameEN)
1102
1129
  ) {
1103
1130
  console.warn(
1104
- `⚠️ Duplicate detected: EN - "${generatedEN}", PT - "${generatedPT}". Retrying...`
1131
+ `⚠️ Duplicate detected: EN - "${newNameEN}", PT - "${newNamePT}". Retrying...`
1105
1132
  );
1106
- recentDuplicates.add(generatedEN);
1107
- recentDuplicates.add(generatedPT);
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zodic/shared",
3
- "version": "0.0.213",
3
+ "version": "0.0.215",
4
4
  "module": "index.ts",
5
5
  "type": "module",
6
6
  "publishConfig": {
@@ -241,8 +241,7 @@ export type ConceptPhase =
241
241
  | 'leonardo-prompt'
242
242
  | 'content'
243
243
  | 'images'
244
- | 'fix-duplicates'
245
- ;
244
+ | 'fix-duplicates';
246
245
 
247
246
  export const ConceptPhases: Record<string, ConceptPhase> = {
248
247
  BASIC_INFO: 'basic-info',
@@ -188,52 +188,62 @@ export const buildLLMMessages = (env: BackendBindings) => ({
188
188
  }: {
189
189
  oldNameEN: string;
190
190
  description: string;
191
- conceptSlug: string;
191
+ conceptSlug: Concept;
192
192
  recentNames?: string[];
193
- }): ChatMessages => [
194
- {
195
- role: 'system',
196
- content: `
197
- 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.
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
- Guidelines:
200
- The name must have exactly six words.
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
- Input:
209
- Concept Name: ${conceptSlug}
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
- Output Format:
217
-
218
- EN:
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
  });