@zodic/shared 0.0.194 → 0.0.196
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 +24 -67
- package/package.json +1 -1
|
@@ -33,7 +33,6 @@ export class ConceptService {
|
|
|
33
33
|
const kvFailuresStore = this.context.kvConceptFailuresStore();
|
|
34
34
|
const kvKeyEN = buildConceptKVKey('en-us', conceptSlug, combinationString);
|
|
35
35
|
const kvKeyPT = buildConceptKVKey('pt-br', conceptSlug, combinationString);
|
|
36
|
-
const failureKey = `failures:basic-info:${conceptSlug}:${combinationString}`;
|
|
37
36
|
|
|
38
37
|
// ✅ Use Durable Object stub
|
|
39
38
|
const id = this.context.env.CONCEPT_NAMES_DO.idFromName(conceptSlug);
|
|
@@ -46,33 +45,11 @@ export class ConceptService {
|
|
|
46
45
|
// ✅ IMMEDIATE SKIP if already exists and override is false
|
|
47
46
|
if (!override && existingEN.name && existingPT.name) {
|
|
48
47
|
console.log(`⚡ Basic info already exists for ${conceptSlug}, skipping.`);
|
|
49
|
-
|
|
50
|
-
// ✅ **Backfill Durable Object** to register the names
|
|
51
|
-
console.log(`📡 Backfilling Durable Object for ${conceptSlug}...`);
|
|
52
|
-
try {
|
|
53
|
-
await Promise.all([
|
|
54
|
-
stub.fetch(`https://internal/add-name`, {
|
|
55
|
-
method: 'POST',
|
|
56
|
-
body: JSON.stringify({ language: 'en-us', name: existingEN.name }),
|
|
57
|
-
headers: { 'Content-Type': 'application/json' },
|
|
58
|
-
}),
|
|
59
|
-
stub.fetch(`https://internal/add-name`, {
|
|
60
|
-
method: 'POST',
|
|
61
|
-
body: JSON.stringify({ language: 'pt-br', name: existingPT.name }),
|
|
62
|
-
headers: { 'Content-Type': 'application/json' },
|
|
63
|
-
}),
|
|
64
|
-
]);
|
|
65
|
-
console.log(`✅ Successfully backfilled Durable Object for ${conceptSlug}`);
|
|
66
|
-
} catch (error) {
|
|
67
|
-
console.error(`❌ Error backfilling Durable Object:`, error);
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
return; // ✅ Exit early
|
|
48
|
+
return;
|
|
71
49
|
}
|
|
72
50
|
|
|
73
51
|
let attempts = 0;
|
|
74
52
|
const maxAttempts = 3;
|
|
75
|
-
let newlyGeneratedNames: string[] = []; // ✅ Track generated names in memory
|
|
76
53
|
|
|
77
54
|
while (attempts < maxAttempts) {
|
|
78
55
|
let phase = 'generation';
|
|
@@ -90,39 +67,50 @@ export class ConceptService {
|
|
|
90
67
|
const data = (await response.json()) as { 'en-us': string[]; 'pt-br': string[] };
|
|
91
68
|
allNamesEN = data['en-us'] || [];
|
|
92
69
|
allNamesPT = data['pt-br'] || [];
|
|
93
|
-
console.log(`✅ Retrieved ${allNamesEN.length} EN names and ${allNamesPT.length} PT names.`);
|
|
94
|
-
} else {
|
|
95
|
-
console.log(`❌ Error fetching names from DO for ${conceptSlug}: ${await response.text()}`);
|
|
96
70
|
}
|
|
97
71
|
|
|
98
72
|
console.log(`✏️ Generating new name...`);
|
|
99
|
-
// ✅ Merge newly generated names with existing recent names
|
|
100
|
-
const recentNamesEN = [...allNamesEN.slice(-40), ...newlyGeneratedNames];
|
|
101
|
-
|
|
102
73
|
const messages = this.context
|
|
103
74
|
.buildLLMMessages()
|
|
104
75
|
.generateConceptBasicInfo({
|
|
105
76
|
combination: combinationString,
|
|
106
77
|
conceptSlug,
|
|
107
|
-
existingNames:
|
|
78
|
+
existingNames: allNamesEN.slice(-40),
|
|
108
79
|
});
|
|
109
80
|
|
|
110
81
|
let aiResponse = await this.context.api().callTogether.single(messages, {});
|
|
111
82
|
if (!aiResponse) throw new Error(`❌ AI returned an empty response`);
|
|
112
83
|
|
|
113
84
|
phase = 'cleaning';
|
|
114
|
-
console.log(`🧼 Cleaning AI response...`);
|
|
115
85
|
aiResponse = this.cleanAIResponse(aiResponse);
|
|
116
86
|
|
|
117
87
|
phase = 'parsing';
|
|
118
|
-
console.log(`📜 Parsing AI response...`);
|
|
119
88
|
let { nameEN, descriptionEN, poemEN, namePT, descriptionPT, poemPT } =
|
|
120
89
|
this.parseBasicInfoResponse(aiResponse, conceptSlug);
|
|
121
90
|
|
|
122
91
|
console.log(`🎭 Generated names: EN - "${nameEN}", PT - "${namePT}"`);
|
|
123
92
|
|
|
124
|
-
// ✅ **
|
|
125
|
-
|
|
93
|
+
// ✅ **Check name length and retry if too long**
|
|
94
|
+
const MAX_NAME_LENGTH = 44; // Adjust if needed
|
|
95
|
+
if (nameEN.length > MAX_NAME_LENGTH || namePT.length > MAX_NAME_LENGTH) {
|
|
96
|
+
console.warn(`⚠️ Name too long: "${nameEN}" | "${namePT}". Retrying...`);
|
|
97
|
+
|
|
98
|
+
// ✅ **Register name in Durable Object as blocked**
|
|
99
|
+
await stub.fetch(`https://internal/add-name`, {
|
|
100
|
+
method: 'POST',
|
|
101
|
+
body: JSON.stringify({ language: 'en-us', name: nameEN }),
|
|
102
|
+
headers: { 'Content-Type': 'application/json' },
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
await stub.fetch(`https://internal/add-name`, {
|
|
106
|
+
method: 'POST',
|
|
107
|
+
body: JSON.stringify({ language: 'pt-br', name: namePT }),
|
|
108
|
+
headers: { 'Content-Type': 'application/json' },
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
console.log(`✅ Added long name to DO blocklist, retrying...`);
|
|
112
|
+
continue;
|
|
113
|
+
}
|
|
126
114
|
|
|
127
115
|
// ✅ Check uniqueness before storing
|
|
128
116
|
if (allNamesEN.includes(nameEN) || allNamesPT.includes(namePT)) {
|
|
@@ -132,7 +120,6 @@ export class ConceptService {
|
|
|
132
120
|
if (attempts >= maxAttempts) {
|
|
133
121
|
console.log(`🚨 Max attempts reached. Storing name despite duplicate.`);
|
|
134
122
|
|
|
135
|
-
// ✅ **Register duplicate storage in KV failures**
|
|
136
123
|
await kvFailuresStore.put(
|
|
137
124
|
`failures:duplicates:${conceptSlug}:${combinationString}`,
|
|
138
125
|
JSON.stringify({
|
|
@@ -145,38 +132,8 @@ export class ConceptService {
|
|
|
145
132
|
})
|
|
146
133
|
);
|
|
147
134
|
|
|
148
|
-
// ✅ **Store names in Durable Object**
|
|
149
|
-
await stub.fetch(`https://internal/add-name`, {
|
|
150
|
-
method: 'POST',
|
|
151
|
-
body: JSON.stringify({ language: 'en-us', name: nameEN }),
|
|
152
|
-
headers: { 'Content-Type': 'application/json' },
|
|
153
|
-
});
|
|
154
|
-
|
|
155
|
-
await stub.fetch(`https://internal/add-name`, {
|
|
156
|
-
method: 'POST',
|
|
157
|
-
body: JSON.stringify({ language: 'pt-br', name: namePT }),
|
|
158
|
-
headers: { 'Content-Type': 'application/json' },
|
|
159
|
-
});
|
|
160
|
-
|
|
161
|
-
// ✅ Store the generated basic info in KV
|
|
162
|
-
Object.assign(existingEN, {
|
|
163
|
-
name: nameEN,
|
|
164
|
-
description: descriptionEN,
|
|
165
|
-
poem: poemEN,
|
|
166
|
-
status: 'forced', // 🔥 Mark as "forced" due to duplication
|
|
167
|
-
});
|
|
168
|
-
await kvStore.put(kvKeyEN, JSON.stringify(existingEN));
|
|
169
|
-
|
|
170
|
-
Object.assign(existingPT, {
|
|
171
|
-
name: namePT,
|
|
172
|
-
description: descriptionPT,
|
|
173
|
-
poem: poemPT,
|
|
174
|
-
status: 'forced', // 🔥 Mark as "forced" due to duplication
|
|
175
|
-
});
|
|
176
|
-
await kvStore.put(kvKeyPT, JSON.stringify(existingPT));
|
|
177
|
-
|
|
178
135
|
console.log(`✅ Stored duplicate name after max retries: ${nameEN}, ${namePT}`);
|
|
179
|
-
|
|
136
|
+
break;
|
|
180
137
|
}
|
|
181
138
|
|
|
182
139
|
console.log('🔁 Retrying due to duplicate name...');
|