@zodic/shared 0.0.249 → 0.0.251

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.
@@ -10,6 +10,7 @@ import { v4 as uuidv4 } from 'uuid';
10
10
  import { cleanText, schema } from '../..';
11
11
  import {
12
12
  aspectReports,
13
+ astroDescriptionTemplates,
13
14
  astroFeatureReports,
14
15
  astroReports,
15
16
  conceptsData,
@@ -18,8 +19,11 @@ import {
18
19
  import {
19
20
  AstrologicalReport,
20
21
  AstroReportParams,
22
+ AstroReportRow,
23
+ ChatMessages,
21
24
  Concept,
22
25
  ControlNetConfig,
26
+ DescriptionTemplateRow,
23
27
  Languages,
24
28
  } from '../../types';
25
29
  import {
@@ -27,6 +31,7 @@ import {
27
31
  sizes,
28
32
  StructuredConceptContent,
29
33
  } from '../../types/scopes/legacy';
34
+ import { astroPrompts } from '../../utils/astroPrompts';
30
35
  import { leonardoInitImages } from '../../utils/initImages';
31
36
  import { buildConceptKVKey } from '../../utils/KVKeysBuilders';
32
37
  import { AppContext } from '../base/AppContext';
@@ -2006,132 +2011,105 @@ export class ConceptService {
2006
2011
  console.log(`✅ Stored duplicate keys for ${conceptSlug} in cache.`);
2007
2012
  }
2008
2013
 
2009
- // ? ASTRO PROCESSING
2010
2014
  async generateAstroReportContent(
2011
- params: AstroReportParams,
2015
+ params: AstroReportParams | { entityType: string; name: string; override?: boolean },
2012
2016
  override: boolean = false
2013
2017
  ): Promise<void> {
2014
- console.log(
2015
- `🚀 Generating report content for ${JSON.stringify(
2016
- params
2017
- )}, override: ${override}`
2018
- );
2018
+ console.log(`🚀 Generating content for ${JSON.stringify(params)}, override: ${override}`);
2019
2019
 
2020
2020
  const db = drizzle(this.context.env.DB);
2021
2021
  let table, whereClause;
2022
2022
 
2023
- // Log the params for debugging
2024
- console.log(
2025
- `🔍 Received params: reportType=${params.reportType}, featureType=${
2026
- (params as any).featureType || 'N/A'
2027
- }, subtype=${(params as any).subtype || 'N/A'}`
2028
- );
2029
-
2030
- // Determine table and where clause
2031
- switch (params.reportType) {
2032
- case 'sign':
2033
- console.log(
2034
- `🗂️ Handling sign report: type=${params.type}, pointName=${params.pointName}, sign=${params.sign}`
2035
- );
2036
- table = astroReports;
2037
- whereClause = and(
2038
- eq(astroReports.name, params.pointName),
2039
- eq(astroReports.sign, params.sign),
2040
- isNull(astroReports.house)
2041
- );
2042
- break;
2043
- case 'house':
2044
- console.log(
2045
- `🗂️ Handling house report: type=${params.type}, pointName=${params.pointName}, house=${params.house}`
2046
- );
2047
- table = astroReports;
2048
- whereClause = and(
2049
- eq(astroReports.name, params.pointName),
2050
- eq(astroReports.house, params.house),
2051
- isNull(astroReports.sign)
2052
- );
2053
- break;
2054
- case 'signInHouse':
2055
- console.log(
2056
- `🗂️ Handling signInHouse report: sign=${params.sign}, houseNumber=${params.houseNumber}`
2057
- );
2058
- table = houseReports;
2059
- whereClause = and(
2060
- eq(houseReports.sign, params.sign),
2061
- eq(houseReports.house, params.houseNumber)
2062
- );
2063
- break;
2064
- case 'aspect':
2065
- console.log(
2066
- `🗂️ Handling aspect report: aspectingPlanet=${params.aspectingPlanet}, aspectedPlanet=${params.aspectedPlanet}, aspectingType=${params.aspectingType}`
2067
- );
2068
- table = aspectReports;
2069
- whereClause = and(
2070
- eq(aspectReports.aspectingPlanet, params.aspectingPlanet),
2071
- eq(aspectReports.aspectedPlanet, params.aspectedPlanet),
2072
- eq(aspectReports.aspect, params.aspectingType)
2073
- );
2074
- break;
2075
- case 'feature':
2076
- console.log(
2077
- `🗂️ Handling feature report: featureType=${
2078
- params.featureType
2079
- }, ${JSON.stringify(params)}`
2080
- );
2081
- table = astroFeatureReports;
2082
- let nameValue: string;
2083
- if (params.featureType === 'element') {
2084
- if (!('subtype' in params))
2085
- throw new Error('Missing subtype for element feature report');
2086
- switch (params.subtype) {
2087
- case 'balanced':
2088
- nameValue = 'balanced';
2089
- break;
2090
- case 'pure':
2091
- if (!('dominantElement' in params))
2092
- throw new Error(
2093
- 'Missing dominantElement for pure element report'
2094
- );
2095
- nameValue = params.dominantElement;
2096
- break;
2097
- case 'preponderant_lacking':
2098
- if (
2099
- !('dominantElement' in params) ||
2100
- !('lackingElement' in params)
2101
- )
2102
- throw new Error(
2103
- 'Missing dominantElement or lackingElement for preponderant_lacking element report'
2104
- );
2105
- nameValue = `${params.dominantElement}-${params.lackingElement}`;
2106
- break;
2107
- default:
2108
- throw new Error(`Unknown element subtype: ${params}`);
2023
+ let report: AstroReportRow | DescriptionTemplateRow;
2024
+ const isReport = "reportType" in params;
2025
+
2026
+ if (isReport) {
2027
+ // Handle existing report types (sign, house, signInHouse, aspect, feature)
2028
+ switch (params.reportType) {
2029
+ case "sign":
2030
+ console.log(`🗂️ Handling sign report: type=${params.type}, pointName=${params.pointName}, sign=${params.sign}`);
2031
+ table = astroReports;
2032
+ whereClause = and(
2033
+ eq(astroReports.name, params.pointName),
2034
+ eq(astroReports.sign, params.sign),
2035
+ isNull(astroReports.house)
2036
+ );
2037
+ break;
2038
+ case "house":
2039
+ console.log(`🗂️ Handling house report: type=${params.type}, pointName=${params.pointName}, house=${params.house}`);
2040
+ table = astroReports;
2041
+ whereClause = and(
2042
+ eq(astroReports.name, params.pointName),
2043
+ eq(astroReports.house, params.house),
2044
+ isNull(astroReports.sign)
2045
+ );
2046
+ break;
2047
+ case "signInHouse":
2048
+ console.log(`🗂️ Handling signInHouse report: sign=${params.sign}, houseNumber=${params.houseNumber}`);
2049
+ table = houseReports;
2050
+ whereClause = and(
2051
+ eq(houseReports.sign, params.sign),
2052
+ eq(houseReports.house, params.houseNumber)
2053
+ );
2054
+ break;
2055
+ case "aspect":
2056
+ console.log(`🗂️ Handling aspect report: aspectingPlanet=${params.aspectingPlanet}, aspectedPlanet=${params.aspectedPlanet}, aspectingType=${params.aspectingType}`);
2057
+ table = aspectReports;
2058
+ whereClause = and(
2059
+ eq(aspectReports.aspectingPlanet, params.aspectingPlanet),
2060
+ eq(aspectReports.aspectedPlanet, params.aspectedPlanet),
2061
+ eq(aspectReports.aspect, params.aspectingType)
2062
+ );
2063
+ break;
2064
+ case "feature":
2065
+ console.log(`🗂️ Handling feature report: featureType=${params.featureType}, ${JSON.stringify(params)}`);
2066
+ table = astroFeatureReports;
2067
+ let nameValue: string;
2068
+ if (params.featureType === "element") {
2069
+ if (!("subtype" in params)) throw new Error("Missing subtype for element feature report");
2070
+ switch (params.subtype) {
2071
+ case "balanced":
2072
+ nameValue = "balanced";
2073
+ break;
2074
+ case "pure":
2075
+ if (!("dominantElement" in params)) throw new Error("Missing dominantElement for pure element report");
2076
+ nameValue = params.dominantElement;
2077
+ break;
2078
+ case "preponderant_lacking":
2079
+ if (!("dominantElement" in params) || !("lackingElement" in params)) throw new Error("Missing dominantElement or lackingElement for preponderant_lacking element report");
2080
+ nameValue = `${params.dominantElement}-${params.lackingElement}`;
2081
+ break;
2082
+ default:
2083
+ throw new Error(`Unknown element subtype: ${(params as any).subtype}`);
2084
+ }
2085
+ } else {
2086
+ if (!("name" in params)) throw new Error("Missing name for non-element feature report");
2087
+ nameValue = params.name;
2109
2088
  }
2110
- } else {
2111
- if (!('name' in params))
2112
- throw new Error('Missing name for non-element feature report');
2113
- nameValue = params.name;
2114
- }
2115
- whereClause = and(
2116
- eq(astroFeatureReports.featureType, params.featureType),
2117
- eq(astroFeatureReports.name, nameValue)
2118
- );
2119
- break;
2120
- default:
2121
- console.error(
2122
- `❌ Unknown report type: ${params}. Params: ${JSON.stringify(params)}`
2123
- );
2124
- throw new Error(`Unknown report type: ${params}`);
2125
- }
2126
-
2127
- const report = await db.select().from(table).where(whereClause).get();
2128
- if (!report) {
2129
- console.error(`❌ No report found for ${JSON.stringify(params)}`);
2130
- throw new Error(`❌ No report found for ${JSON.stringify(params)}`);
2089
+ whereClause = and(
2090
+ eq(astroFeatureReports.featureType, params.featureType),
2091
+ eq(astroFeatureReports.name, nameValue)
2092
+ );
2093
+ break;
2094
+ default:
2095
+ throw new Error(`Unknown report type: ${(params as any).reportType}`);
2096
+ }
2097
+ report = await db.select().from(table as any).where(whereClause).get() as AstroReportRow;
2098
+ } else {
2099
+ // Handle description templates
2100
+ console.log(`🗂️ Handling description template: entityType=${params.entityType}, name=${params.name}`);
2101
+ table = astroDescriptionTemplates;
2102
+ whereClause = and(
2103
+ eq(astroDescriptionTemplates.entityType, params.entityType),
2104
+ eq(astroDescriptionTemplates.name, params.name)
2105
+ );
2106
+ report = await db.select().from(table as any).where(whereClause).get() as DescriptionTemplateRow;
2131
2107
  }
2132
2108
 
2133
2109
  const id = report.id;
2134
- const hasContent = report.enReport && report.ptReport;
2110
+ const hasContent = isReport
2111
+ ? (report as AstroReportRow).enReport && (report as AstroReportRow).ptReport
2112
+ : (report as DescriptionTemplateRow).enDescription && (report as DescriptionTemplateRow).ptDescription;
2135
2113
 
2136
2114
  if (!override && hasContent) {
2137
2115
  console.log(`⚡ Content already exists for ${id}, skipping`);
@@ -2142,57 +2120,57 @@ export class ConceptService {
2142
2120
  const maxAttempts = 2;
2143
2121
 
2144
2122
  while (attempts < maxAttempts) {
2145
- let phase = 'generation';
2123
+ let phase = "generation";
2146
2124
  try {
2147
2125
  attempts++;
2148
- console.log(
2149
- `🔄 Attempt ${attempts} to generate report content for ${id}...`
2150
- );
2126
+ console.log(`🔄 Attempt ${attempts} to generate ${isReport ? "report" : "description"} content for ${id}...`);
2151
2127
 
2152
- const messages = this.context
2153
- .buildLLMMessages()
2154
- .generateAstroReportContent({ params });
2155
- console.log(`📨 Sending messages to AI: ${JSON.stringify(messages)}`);
2128
+ let messages: ChatMessages;
2129
+ if (isReport) {
2130
+ messages = this.context.buildLLMMessages().generateAstroReportContent({ params: params as AstroReportParams });
2131
+ } else {
2132
+ messages = this.generateDescriptionMessages(params);
2133
+ }
2156
2134
 
2157
- const response = await this.context
2158
- .api()
2159
- .callTogether.single(messages, {});
2135
+ console.log(`📨 Sending messages to AI: ${JSON.stringify(messages)}`);
2136
+ const response = await this.context.api().callTogether.single(messages, {});
2160
2137
  if (!response) {
2161
2138
  throw new Error(`❌ AI returned an empty response for ${id}`);
2162
2139
  }
2163
2140
 
2164
- phase = 'parsing';
2165
- console.log(
2166
- `📝 Received AI response for ${id}: ${response.slice(0, 200)}${
2167
- response.length > 200 ? '...' : ''
2168
- }`
2169
- );
2170
-
2171
- const { enReport, ptReport } =
2172
- await this.parseAstrologicalReportContent(
2173
- params.reportType,
2174
- response
2175
- );
2176
-
2177
- console.log(`💾 Storing report content for ${id}`);
2178
- await db
2179
- .update(table)
2180
- .set({
2181
- enReport: JSON.stringify(enReport),
2182
- ptReport: JSON.stringify(ptReport),
2183
- })
2184
- .where(eq(table.id, id))
2185
- .run();
2141
+ phase = "parsing";
2142
+ console.log(`📝 Received AI response for ${id}: ${response.slice(0, 200)}${response.length > 200 ? "..." : ""}`);
2143
+
2144
+ if (isReport) {
2145
+ const { enReport, ptReport } = await this.parseAstrologicalReportContent((params as AstroReportParams).reportType, response);
2146
+ console.log(`💾 Storing report content for ${id}`);
2147
+ await db
2148
+ .update(table as any)
2149
+ .set({
2150
+ enReport: JSON.stringify(enReport),
2151
+ ptReport: JSON.stringify(ptReport),
2152
+ })
2153
+ .where(eq((table as any).id, id))
2154
+ .run();
2155
+ } else {
2156
+ const { enDescription, ptDescription } = await this.parseDescriptionContent(response);
2157
+ console.log(`💾 Storing description content for ${id}`);
2158
+ await db
2159
+ .update(table as any)
2160
+ .set({
2161
+ enDescription,
2162
+ ptDescription,
2163
+ })
2164
+ .where(eq(astroDescriptionTemplates.id, id))
2165
+ .run();
2166
+ }
2186
2167
 
2187
- console.log(`✅ Report content stored for ${id}`);
2168
+ console.log(`✅ ${isReport ? "Report" : "Description"} content stored for ${id}`);
2188
2169
  return;
2189
2170
  } catch (error) {
2190
- console.error(
2191
- `❌ Attempt ${attempts} failed at phase: ${phase} for ${id}`,
2192
- (error as Error).message
2193
- );
2171
+ console.error(`❌ Attempt ${attempts} failed at phase: ${phase} for ${id}`, (error as Error).message);
2194
2172
 
2195
- const failureKey = `failures:astro:${params.reportType}:${id}`;
2173
+ const failureKey = `failures:astro:${isReport ? (params as AstroReportParams).reportType : "description"}:${id}`;
2196
2174
  await this.context.kvConceptFailuresStore().put(
2197
2175
  failureKey,
2198
2176
  JSON.stringify({
@@ -2205,20 +2183,78 @@ export class ConceptService {
2205
2183
  );
2206
2184
 
2207
2185
  if (attempts >= maxAttempts) {
2208
- console.error(
2209
- `🚨 All ${maxAttempts} attempts failed at phase ${phase} for ${id}`
2210
- );
2211
- throw new Error(
2212
- `Failed to generate content for ${id} after ${maxAttempts} attempts`
2213
- );
2186
+ console.error(`🚨 All ${maxAttempts} attempts failed at phase ${phase} for ${id}`);
2187
+ throw new Error(`Failed to generate ${isReport ? "report" : "description"} for ${id} after ${maxAttempts} attempts`);
2214
2188
  }
2215
2189
 
2216
- console.log('🔁 Retrying...');
2190
+ console.log("🔁 Retrying...");
2217
2191
  await new Promise((resolve) => setTimeout(resolve, 2000));
2218
2192
  }
2219
2193
  }
2220
2194
  }
2221
2195
 
2196
+ private generateDescriptionMessages({
2197
+ entityType,
2198
+ name,
2199
+ isGeneric,
2200
+ }: {
2201
+ entityType: string;
2202
+ name: string;
2203
+ isGeneric?: boolean;
2204
+ }): ChatMessages {
2205
+ const prompt = astroPrompts.makeIntroDescription({
2206
+ entityType,
2207
+ name,
2208
+ isGeneric,
2209
+ });
2210
+ return [{ role: 'user', content: prompt }];
2211
+ }
2212
+
2213
+ async parseDescriptionContent(
2214
+ response: string
2215
+ ): Promise<{ enDescription: string; ptDescription: string }> {
2216
+ console.log(`📌 [START] Parsing description content`);
2217
+
2218
+ try {
2219
+ const enMatch = response.match(/-- EN\s*([\s\S]+?)-- PT/);
2220
+ const ptMatch = response.match(/-- PT\s*([\s\S]+)/);
2221
+
2222
+ if (!enMatch || !ptMatch) {
2223
+ throw new Error(`❌ Missing EN or PT description in response`);
2224
+ }
2225
+
2226
+ const enDescription = enMatch[1].trim();
2227
+ const ptDescription = ptMatch[1].trim();
2228
+
2229
+ console.log(
2230
+ `✅ Parsed EN description: ${enDescription.slice(0, 100)}${
2231
+ enDescription.length > 100 ? '...' : ''
2232
+ }`
2233
+ );
2234
+ console.log(
2235
+ `✅ Parsed PT description: ${ptDescription.slice(0, 100)}${
2236
+ ptDescription.length > 100 ? '...' : ''
2237
+ }`
2238
+ );
2239
+
2240
+ return { enDescription, ptDescription };
2241
+ } catch (error) {
2242
+ console.error(`❌ Parsing failed for description`);
2243
+
2244
+ const failureKey = `failures:astro:parsing:description:${new Date().toISOString()}`;
2245
+ await this.context.kvConceptFailuresStore().put(
2246
+ failureKey,
2247
+ JSON.stringify({
2248
+ error: (error as Error).message,
2249
+ response,
2250
+ timestamp: new Date().toISOString(),
2251
+ })
2252
+ );
2253
+
2254
+ throw error;
2255
+ }
2256
+ }
2257
+
2222
2258
  async parseAstrologicalReportContent(
2223
2259
  reportType: AstroReportParams['reportType'],
2224
2260
  response: string
@@ -0,0 +1,28 @@
1
+ CREATE TABLE `astro_description_templates` (
2
+ `id` text PRIMARY KEY NOT NULL,
3
+ `entity_type` text NOT NULL,
4
+ `name` text NOT NULL,
5
+ `en_name` text,
6
+ `pt_name` text,
7
+ `en_description` text NOT NULL,
8
+ `pt_description` text NOT NULL,
9
+ `created_at` integer DEFAULT CURRENT_TIMESTAMP,
10
+ `updated_at` integer DEFAULT CURRENT_TIMESTAMP
11
+ );
12
+ --> statement-breakpoint
13
+ CREATE INDEX `astro_description_templates_type_name_idx` ON `astro_description_templates` (`entity_type`,`name`);--> statement-breakpoint
14
+ ALTER TABLE `aspect_reports` ADD `description_template_id` text REFERENCES astro_description_templates(id);--> statement-breakpoint
15
+ CREATE INDEX `aspect_reports_description_template_idx` ON `aspect_reports` (`description_template_id`);--> statement-breakpoint
16
+ ALTER TABLE `aspect_reports` DROP COLUMN `en_description`;--> statement-breakpoint
17
+ ALTER TABLE `aspect_reports` DROP COLUMN `pt_description`;--> statement-breakpoint
18
+ ALTER TABLE `astro_feature_reports` ADD `description_template_id` text REFERENCES astro_description_templates(id);--> statement-breakpoint
19
+ CREATE INDEX `astro_feature_reports_description_template_idx` ON `astro_feature_reports` (`description_template_id`);--> statement-breakpoint
20
+ ALTER TABLE `astro_feature_reports` DROP COLUMN `en_description`;--> statement-breakpoint
21
+ ALTER TABLE `astro_feature_reports` DROP COLUMN `pt_description`;--> statement-breakpoint
22
+ ALTER TABLE `astro_reports` ADD `description_template_id` text REFERENCES astro_description_templates(id);--> statement-breakpoint
23
+ ALTER TABLE `astro_reports` DROP COLUMN `en_description`;--> statement-breakpoint
24
+ ALTER TABLE `astro_reports` DROP COLUMN `pt_description`;--> statement-breakpoint
25
+ ALTER TABLE `house_reports` ADD `description_template_id` text REFERENCES astro_description_templates(id);--> statement-breakpoint
26
+ CREATE INDEX `house_reports_description_template_idx` ON `house_reports` (`description_template_id`);--> statement-breakpoint
27
+ ALTER TABLE `house_reports` DROP COLUMN `en_description`;--> statement-breakpoint
28
+ ALTER TABLE `house_reports` DROP COLUMN `pt_description`;