@zodic/shared 0.0.140 → 0.0.141

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.
@@ -25,40 +25,19 @@ export class AppContext {
25
25
  kvConceptsStore() {
26
26
  if (!this.env.KV_CONCEPTS) {
27
27
  throw new Error(
28
- 'KV_COSMIC_MIRROR_ARCHETYPES is not defined in the environment.'
28
+ 'KV_CONCEPTS is not defined in the environment.'
29
29
  );
30
30
  }
31
31
  return this.env.KV_CONCEPTS;
32
32
  }
33
33
 
34
- kvGenerationStore() {
35
- if (!this.env.KV_GENERATION_MANAGEMENT) {
34
+ kvConceptFailuresStore() {
35
+ if (!this.env.KV_CONCEPT_FAILURES) {
36
36
  throw new Error(
37
- 'KV_GENERATION_MANAGEMENT is not defined in the environment.'
37
+ 'KV_CONCEPT_FAILURES is not defined in the environment.'
38
38
  );
39
39
  }
40
- return this.env.KV_GENERATION_MANAGEMENT;
41
- }
42
-
43
- kvUserGenerationStore() {
44
- if (!this.env.KV_USER_GENERATIONS) {
45
- throw new Error('KV_USER_GENERATIONS is not defined in the environment.');
46
- }
47
- return this.env.KV_GENERATION_MANAGEMENT;
48
- }
49
-
50
- kvPromptsStore() {
51
- if (!this.env.KV_LEONARDO_PROMPTS) {
52
- throw new Error('KV_LEONARDO_PROMPTS is not defined in the environment.');
53
- }
54
- return this.env.KV_LEONARDO_PROMPTS;
55
- }
56
-
57
- kvUserProductStatus() {
58
- if (!this.env.KV_USER_PRODUCT_STATUS) {
59
- throw new Error('KV_LEONARDO_PROMPTS is not defined in the environment.');
60
- }
61
- return this.env.KV_USER_PRODUCT_STATUS;
40
+ return this.env.KV_CONCEPT_FAILURES;
62
41
  }
63
42
 
64
43
  kvConceptsManagementStore() {
@@ -18,58 +18,107 @@ export class ConceptService {
18
18
  */
19
19
  async generateBasicInfo(
20
20
  conceptSlug: Concept,
21
- combinationString: string
21
+ combinationString: string,
22
+ override: boolean = false // ✅ New optional override param
22
23
  ): Promise<void> {
23
24
  console.log(
24
- `🚀 Generating basic info for concept: ${conceptSlug}, combination: ${combinationString}`
25
+ `🚀 Generating basic info for concept: ${conceptSlug}, combination: ${combinationString}, override: ${override}`
25
26
  );
26
-
27
- // ✅ Build the messages to request content
28
- const messages = this.context.buildLLMMessages().generateConceptBasicInfo({
29
- combination: combinationString,
30
- conceptSlug,
31
- });
32
-
33
- // ✅ Call ChatGPT API
34
- const response = await this.context.api().callChatGPT.single(messages, {});
35
- if (!response) {
36
- throw new Error(
37
- `❌ Failed to generate basic info for concept: ${conceptSlug}`
38
- );
39
- }
40
-
41
- // ✅ Parse response for both languages
42
- const { nameEN, descriptionEN, poemEN, namePT, descriptionPT, poemPT } =
43
- this.parseBasicInfoResponse(response);
44
-
45
- // ✅ Store in KV for both languages
27
+
46
28
  const kvStore = this.context.kvConceptsStore();
47
-
48
- // 🌍 English version
49
- const kvKeyEN = buildConceptKVKey('en-us', conceptSlug, combinationString);
50
- const conceptEN = await this.getKVConcept(kvKeyEN);
51
- Object.assign(conceptEN, {
52
- name: nameEN,
53
- description: descriptionEN,
54
- poem: poemEN,
55
- status: 'idle',
56
- });
57
- await kvStore.put(kvKeyEN, JSON.stringify(conceptEN));
58
-
59
- // 🇧🇷 Portuguese version
60
- const kvKeyPT = buildConceptKVKey('pt-br', conceptSlug, combinationString);
61
- const conceptPT = await this.getKVConcept(kvKeyPT);
62
- Object.assign(conceptPT, {
63
- name: namePT,
64
- description: descriptionPT,
65
- poem: poemPT,
66
- status: 'idle',
67
- });
68
- await kvStore.put(kvKeyPT, JSON.stringify(conceptPT));
69
-
70
- console.log(
71
- `✅ Basic info stored for ${conceptSlug}, combination: ${combinationString}, in both languages.`
72
- );
29
+ const kvFailuresStore = this.context.kvConceptFailuresStore(); // 🔴 Replace with actual KV store
30
+ const kvKeyEN = buildConceptKVKey("en-us", conceptSlug, combinationString);
31
+ const kvKeyPT = buildConceptKVKey("pt-br", conceptSlug, combinationString);
32
+ const failureKey = `failures:${conceptSlug}:${combinationString}`;
33
+
34
+ // ✅ Check if data already exists
35
+ if (!override) {
36
+ const existingEN = await this.getKVConcept(kvKeyEN);
37
+ const existingPT = await this.getKVConcept(kvKeyPT);
38
+
39
+ if (
40
+ existingEN.name && existingEN.description && existingEN.poem &&
41
+ existingPT.name && existingPT.description && existingPT.poem
42
+ ) {
43
+ console.log(`⚡ Basic info already exists for ${conceptSlug}, combination: ${combinationString}. Skipping.`);
44
+ return; // ✅ Skip regeneration
45
+ }
46
+ }
47
+
48
+ let attempts = 0;
49
+ const maxAttempts = 3;
50
+
51
+ while (attempts < maxAttempts) {
52
+ let phase = "generation"; // 📌 Track the phase
53
+ try {
54
+ attempts++;
55
+ console.log(`🔄 Attempt ${attempts} to generate basic info...`);
56
+
57
+ // ✅ Build the messages to request content
58
+ const messages = this.context.buildLLMMessages().generateConceptBasicInfo({
59
+ combination: combinationString,
60
+ conceptSlug,
61
+ });
62
+
63
+ // ✅ Call ChatGPT API
64
+ const response = await this.context.api().callChatGPT.single(messages, {});
65
+ if (!response) {
66
+ throw new Error(`❌ AI returned an empty response`);
67
+ }
68
+
69
+ phase = "parsing"; // ✅ Switch to parsing phase
70
+
71
+ // ✅ Parse response for both languages
72
+ const { nameEN, descriptionEN, poemEN, namePT, descriptionPT, poemPT } =
73
+ this.parseBasicInfoResponse(response);
74
+
75
+ // 🌍 English version
76
+ const conceptEN = await this.getKVConcept(kvKeyEN);
77
+ Object.assign(conceptEN, {
78
+ name: nameEN,
79
+ description: descriptionEN,
80
+ poem: poemEN,
81
+ status: "idle",
82
+ });
83
+ await kvStore.put(kvKeyEN, JSON.stringify(conceptEN));
84
+
85
+ // 🇧🇷 Portuguese version
86
+ const conceptPT = await this.getKVConcept(kvKeyPT);
87
+ Object.assign(conceptPT, {
88
+ name: namePT,
89
+ description: descriptionPT,
90
+ poem: poemPT,
91
+ status: "idle",
92
+ });
93
+ await kvStore.put(kvKeyPT, JSON.stringify(conceptPT));
94
+
95
+ console.log(
96
+ `✅ Basic info stored for ${conceptSlug}, combination: ${combinationString}, in both languages.`
97
+ );
98
+ return; // ✅ Exit loop if successful
99
+
100
+ } catch (error) {
101
+ console.error(`❌ Attempt ${attempts} failed at phase: ${phase}`, (error as Error).message);
102
+
103
+ // ✅ Store failure details in KV for manual review
104
+ await kvFailuresStore.put(failureKey, JSON.stringify({
105
+ error: (error as Error).message,
106
+ attempt: attempts,
107
+ phase, // ✅ Identify if failure occurred in "generation" or "parsing"
108
+ conceptSlug,
109
+ combinationString,
110
+ timestamp: new Date().toISOString(),
111
+ }));
112
+
113
+ if (attempts >= maxAttempts) {
114
+ console.error(`🚨 All ${maxAttempts} attempts failed during ${phase}. Logged failure.`);
115
+ throw new Error(`Failed to generate basic info after ${maxAttempts} attempts`);
116
+ }
117
+
118
+ console.log("🔁 Retrying...");
119
+ await new Promise((resolve) => setTimeout(resolve, 2000)); // ⏳ Small delay before retrying
120
+ }
121
+ }
73
122
  }
74
123
 
75
124
  private parseBasicInfoResponse(response: string): {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zodic/shared",
3
- "version": "0.0.140",
3
+ "version": "0.0.141",
4
4
  "module": "index.ts",
5
5
  "type": "module",
6
6
  "publishConfig": {
@@ -17,15 +17,11 @@ export type CentralBindings = {
17
17
  DESCRIBER_API_KEY: string;
18
18
  DESCRIBER_APP_ID: string;
19
19
  AKOOL_API_KEY: string;
20
- KV_GENERATION_MANAGEMENT: KVNamespace;
21
- KV_USER_GENERATIONS: KVNamespace;
22
20
  KV_COSMIC_MIRROR_ARCHETYPES: KVNamespace;
23
21
  KV_CONCEPTS: KVNamespace;
24
22
  KV_CONCEPTS_MANAGEMENT: KVNamespace;
25
- KV_LEONARDO_PROMPTS: KVNamespace;
26
23
  KV_ASTRO: KVNamespace;
27
- KV_TEST: KVNamespace;
28
- KV_USER_PRODUCT_STATUS: KVNamespace;
24
+ KV_CONCEPT_FAILURES: KVNamespace;
29
25
  CONCEPT_GENERATION_QUEUE: Queue;
30
26
 
31
27
  PROMPT_IMAGE_DESCRIBER: string;
@@ -86,12 +82,11 @@ export type BackendBindings = Env &
86
82
  | 'DESCRIBER_API_KEY'
87
83
  | 'DESCRIBER_APP_ID'
88
84
  | 'AKOOL_API_KEY'
89
- | 'KV_GENERATION_MANAGEMENT'
90
- | 'KV_USER_GENERATIONS'
91
85
  | 'KV_COSMIC_MIRROR_ARCHETYPES'
92
86
  | 'KV_CONCEPTS'
93
- | 'KV_LEONARDO_PROMPTS'
94
87
  | 'KV_ASTRO'
88
+ | 'KV_CONCEPTS_MANAGEMENT'
89
+ | 'KV_CONCEPT_FAILURES'
95
90
  | 'PROMPT_IMAGE_DESCRIBER'
96
91
  | 'PROMPT_GENERATE_ARCHETYPE_CONTENT'
97
92
  | 'PROMPT_GENERATE_ARCHETYPE_LEONARDO_PROMPTS'
@@ -109,10 +104,8 @@ export type BackendBindings = Env &
109
104
  | 'ASTROLOGY_PDF_API_KEY'
110
105
  | 'ASTROLOGY_PDF_USER_ID'
111
106
  | 'AI'
112
- | 'KV_USER_PRODUCT_STATUS'
113
107
  | 'PIAPI_API_KEY'
114
108
  | 'CONCEPT_GENERATION_QUEUE'
115
- | 'KV_CONCEPTS_MANAGEMENT'
116
109
  | 'DEEPSEEK_API_KEY'
117
110
  | 'PROMPT_GENERATE_ARCHETYPE_BASIC_INFO'
118
111
  >;