@zodic/shared 0.0.246 → 0.0.248
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
|
+
astroFeatureReports,
|
|
13
14
|
astroReports,
|
|
14
15
|
conceptsData,
|
|
15
16
|
houseReports,
|
|
@@ -2010,14 +2011,28 @@ export class ConceptService {
|
|
|
2010
2011
|
params: AstroReportParams,
|
|
2011
2012
|
override: boolean = false
|
|
2012
2013
|
): Promise<void> {
|
|
2013
|
-
console.log(
|
|
2014
|
+
console.log(
|
|
2015
|
+
`🚀 Generating report content for ${JSON.stringify(
|
|
2016
|
+
params
|
|
2017
|
+
)}, override: ${override}`
|
|
2018
|
+
);
|
|
2014
2019
|
|
|
2015
2020
|
const db = drizzle(this.context.env.DB);
|
|
2016
2021
|
let table, whereClause;
|
|
2017
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
|
+
|
|
2018
2030
|
// Determine table and where clause
|
|
2019
2031
|
switch (params.reportType) {
|
|
2020
|
-
case
|
|
2032
|
+
case 'sign':
|
|
2033
|
+
console.log(
|
|
2034
|
+
`🗂️ Handling sign report: type=${params.type}, pointName=${params.pointName}, sign=${params.sign}`
|
|
2035
|
+
);
|
|
2021
2036
|
table = astroReports;
|
|
2022
2037
|
whereClause = and(
|
|
2023
2038
|
eq(astroReports.name, params.pointName),
|
|
@@ -2025,7 +2040,10 @@ export class ConceptService {
|
|
|
2025
2040
|
isNull(astroReports.house)
|
|
2026
2041
|
);
|
|
2027
2042
|
break;
|
|
2028
|
-
case
|
|
2043
|
+
case 'house':
|
|
2044
|
+
console.log(
|
|
2045
|
+
`🗂️ Handling house report: type=${params.type}, pointName=${params.pointName}, house=${params.house}`
|
|
2046
|
+
);
|
|
2029
2047
|
table = astroReports;
|
|
2030
2048
|
whereClause = and(
|
|
2031
2049
|
eq(astroReports.name, params.pointName),
|
|
@@ -2033,14 +2051,20 @@ export class ConceptService {
|
|
|
2033
2051
|
isNull(astroReports.sign)
|
|
2034
2052
|
);
|
|
2035
2053
|
break;
|
|
2036
|
-
case
|
|
2054
|
+
case 'signInHouse':
|
|
2055
|
+
console.log(
|
|
2056
|
+
`🗂️ Handling signInHouse report: sign=${params.sign}, houseNumber=${params.houseNumber}`
|
|
2057
|
+
);
|
|
2037
2058
|
table = houseReports;
|
|
2038
2059
|
whereClause = and(
|
|
2039
2060
|
eq(houseReports.sign, params.sign),
|
|
2040
2061
|
eq(houseReports.house, params.houseNumber)
|
|
2041
2062
|
);
|
|
2042
2063
|
break;
|
|
2043
|
-
case
|
|
2064
|
+
case 'aspect':
|
|
2065
|
+
console.log(
|
|
2066
|
+
`🗂️ Handling aspect report: aspectingPlanet=${params.aspectingPlanet}, aspectedPlanet=${params.aspectedPlanet}, aspectingType=${params.aspectingType}`
|
|
2067
|
+
);
|
|
2044
2068
|
table = aspectReports;
|
|
2045
2069
|
whereClause = and(
|
|
2046
2070
|
eq(aspectReports.aspectingPlanet, params.aspectingPlanet),
|
|
@@ -2048,37 +2072,61 @@ export class ConceptService {
|
|
|
2048
2072
|
eq(aspectReports.aspect, params.aspectingType)
|
|
2049
2073
|
);
|
|
2050
2074
|
break;
|
|
2051
|
-
|
|
2052
|
-
|
|
2053
|
-
|
|
2054
|
-
|
|
2055
|
-
|
|
2056
|
-
|
|
2057
|
-
|
|
2058
|
-
|
|
2059
|
-
|
|
2060
|
-
|
|
2061
|
-
|
|
2062
|
-
|
|
2063
|
-
|
|
2064
|
-
|
|
2065
|
-
|
|
2066
|
-
|
|
2067
|
-
|
|
2068
|
-
|
|
2069
|
-
|
|
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}`);
|
|
2070
2109
|
}
|
|
2071
|
-
|
|
2072
|
-
|
|
2073
|
-
|
|
2074
|
-
|
|
2075
|
-
|
|
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;
|
|
2076
2120
|
default:
|
|
2077
|
-
|
|
2121
|
+
console.error(
|
|
2122
|
+
`❌ Unknown report type: ${params}. Params: ${JSON.stringify(params)}`
|
|
2123
|
+
);
|
|
2124
|
+
throw new Error(`Unknown report type: ${params}`);
|
|
2078
2125
|
}
|
|
2079
2126
|
|
|
2080
2127
|
const report = await db.select().from(table).where(whereClause).get();
|
|
2081
2128
|
if (!report) {
|
|
2129
|
+
console.error(`❌ No report found for ${JSON.stringify(params)}`);
|
|
2082
2130
|
throw new Error(`❌ No report found for ${JSON.stringify(params)}`);
|
|
2083
2131
|
}
|
|
2084
2132
|
|
|
@@ -2094,21 +2142,37 @@ export class ConceptService {
|
|
|
2094
2142
|
const maxAttempts = 2;
|
|
2095
2143
|
|
|
2096
2144
|
while (attempts < maxAttempts) {
|
|
2097
|
-
let phase =
|
|
2145
|
+
let phase = 'generation';
|
|
2098
2146
|
try {
|
|
2099
2147
|
attempts++;
|
|
2100
|
-
console.log(
|
|
2148
|
+
console.log(
|
|
2149
|
+
`🔄 Attempt ${attempts} to generate report content for ${id}...`
|
|
2150
|
+
);
|
|
2101
2151
|
|
|
2102
|
-
const messages = this.context
|
|
2152
|
+
const messages = this.context
|
|
2153
|
+
.buildLLMMessages()
|
|
2154
|
+
.generateAstroReportContent({ params });
|
|
2155
|
+
console.log(`📨 Sending messages to AI: ${JSON.stringify(messages)}`);
|
|
2103
2156
|
|
|
2104
|
-
const response = await this.context
|
|
2157
|
+
const response = await this.context
|
|
2158
|
+
.api()
|
|
2159
|
+
.callTogether.single(messages, {});
|
|
2105
2160
|
if (!response) {
|
|
2106
|
-
throw new Error(`❌ AI returned an empty response`);
|
|
2161
|
+
throw new Error(`❌ AI returned an empty response for ${id}`);
|
|
2107
2162
|
}
|
|
2108
2163
|
|
|
2109
|
-
phase =
|
|
2164
|
+
phase = 'parsing';
|
|
2165
|
+
console.log(
|
|
2166
|
+
`📝 Received AI response for ${id}: ${response.slice(0, 200)}${
|
|
2167
|
+
response.length > 200 ? '...' : ''
|
|
2168
|
+
}`
|
|
2169
|
+
);
|
|
2110
2170
|
|
|
2111
|
-
const { enReport, ptReport } =
|
|
2171
|
+
const { enReport, ptReport } =
|
|
2172
|
+
await this.parseAstrologicalReportContent(
|
|
2173
|
+
params.reportType,
|
|
2174
|
+
response
|
|
2175
|
+
);
|
|
2112
2176
|
|
|
2113
2177
|
console.log(`💾 Storing report content for ${id}`);
|
|
2114
2178
|
await db
|
|
@@ -2123,7 +2187,10 @@ export class ConceptService {
|
|
|
2123
2187
|
console.log(`✅ Report content stored for ${id}`);
|
|
2124
2188
|
return;
|
|
2125
2189
|
} catch (error) {
|
|
2126
|
-
console.error(
|
|
2190
|
+
console.error(
|
|
2191
|
+
`❌ Attempt ${attempts} failed at phase: ${phase} for ${id}`,
|
|
2192
|
+
(error as Error).message
|
|
2193
|
+
);
|
|
2127
2194
|
|
|
2128
2195
|
const failureKey = `failures:astro:${params.reportType}:${id}`;
|
|
2129
2196
|
await this.context.kvConceptFailuresStore().put(
|
|
@@ -2138,11 +2205,15 @@ export class ConceptService {
|
|
|
2138
2205
|
);
|
|
2139
2206
|
|
|
2140
2207
|
if (attempts >= maxAttempts) {
|
|
2141
|
-
console.error(
|
|
2142
|
-
|
|
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
|
+
);
|
|
2143
2214
|
}
|
|
2144
2215
|
|
|
2145
|
-
console.log(
|
|
2216
|
+
console.log('🔁 Retrying...');
|
|
2146
2217
|
await new Promise((resolve) => setTimeout(resolve, 2000));
|
|
2147
2218
|
}
|
|
2148
2219
|
}
|
|
@@ -2199,40 +2270,48 @@ export class ConceptService {
|
|
|
2199
2270
|
}
|
|
2200
2271
|
|
|
2201
2272
|
private parseAstrologicalReport(response: string): AstrologicalReport[] {
|
|
2202
|
-
console.log(
|
|
2203
|
-
|
|
2273
|
+
console.log('📌 Starting parseAstrologicalReport');
|
|
2274
|
+
|
|
2204
2275
|
const reports: AstrologicalReport[] = [];
|
|
2205
2276
|
const languageSections = response
|
|
2206
2277
|
.split(/--\s*(EN|PT)\s*\n/)
|
|
2207
2278
|
.filter(Boolean);
|
|
2208
2279
|
console.log(`🔍 Split response into ${languageSections.length} sections`);
|
|
2209
|
-
|
|
2280
|
+
|
|
2210
2281
|
for (let i = 0; i < languageSections.length; i += 2) {
|
|
2211
2282
|
const language = languageSections[i].trim();
|
|
2212
2283
|
const content = languageSections[i + 1]?.trim();
|
|
2213
2284
|
console.log(`🚀 Processing section ${i / 2 + 1}: Language = ${language}`);
|
|
2214
|
-
|
|
2285
|
+
|
|
2215
2286
|
if (!content || !language.match(/^(EN|PT)$/)) {
|
|
2216
|
-
console.warn(
|
|
2287
|
+
console.warn(
|
|
2288
|
+
`⚠️ Skipping section ${
|
|
2289
|
+
i / 2 + 1
|
|
2290
|
+
}: Invalid content or language (${language})`
|
|
2291
|
+
);
|
|
2217
2292
|
continue;
|
|
2218
2293
|
}
|
|
2219
|
-
|
|
2220
|
-
console.log(
|
|
2221
|
-
|
|
2294
|
+
|
|
2295
|
+
console.log(
|
|
2296
|
+
`📜 Raw content for ${language}:\n${content.slice(0, 500)}${
|
|
2297
|
+
content.length > 500 ? '...' : ''
|
|
2298
|
+
}`
|
|
2299
|
+
);
|
|
2300
|
+
|
|
2222
2301
|
const report: AstrologicalReport = {
|
|
2223
2302
|
language,
|
|
2224
2303
|
title: [],
|
|
2225
2304
|
sections: {},
|
|
2226
2305
|
};
|
|
2227
|
-
|
|
2306
|
+
|
|
2228
2307
|
const lines = content.split('\n').map((line) => line.trim());
|
|
2229
2308
|
console.log(`🔢 Split into ${lines.length} lines`);
|
|
2230
|
-
|
|
2309
|
+
|
|
2231
2310
|
let currentSection = '';
|
|
2232
2311
|
for (let j = 0; j < lines.length; j++) {
|
|
2233
2312
|
const line = lines[j];
|
|
2234
2313
|
console.log(`📏 Processing line ${j + 1}: "${line}"`);
|
|
2235
|
-
|
|
2314
|
+
|
|
2236
2315
|
if (line.startsWith('### ') && report.title.length === 0) {
|
|
2237
2316
|
const titleContent = cleanText(line.replace('### ', ''));
|
|
2238
2317
|
console.log(`🏷️ Found title: "${titleContent}"`);
|
|
@@ -2242,40 +2321,52 @@ export class ConceptService {
|
|
|
2242
2321
|
});
|
|
2243
2322
|
continue;
|
|
2244
2323
|
}
|
|
2245
|
-
|
|
2324
|
+
|
|
2246
2325
|
if (line.startsWith('#### ')) {
|
|
2247
2326
|
currentSection = cleanText(line.replace('#### ', '').trim());
|
|
2248
2327
|
console.log(`🗂️ New section: "${currentSection}"`);
|
|
2249
|
-
report.sections[currentSection] =
|
|
2328
|
+
report.sections[currentSection] =
|
|
2329
|
+
report.sections[currentSection] || [];
|
|
2250
2330
|
continue;
|
|
2251
2331
|
}
|
|
2252
|
-
|
|
2332
|
+
|
|
2253
2333
|
if (!line || !currentSection) {
|
|
2254
|
-
console.log(
|
|
2334
|
+
console.log(
|
|
2335
|
+
`⏩ Skipping line: ${!line ? 'Empty' : 'No current section'}`
|
|
2336
|
+
);
|
|
2255
2337
|
continue;
|
|
2256
2338
|
}
|
|
2257
|
-
|
|
2339
|
+
|
|
2258
2340
|
if (line.match(/^\d+\.\s/) || line.startsWith('- ')) {
|
|
2259
2341
|
const listItem = line.replace(/^\d+\.\s|- /, '').trim();
|
|
2260
2342
|
console.log(`🔹 Bullet point detected: "${listItem}"`);
|
|
2261
2343
|
const boldMatch = listItem.match(/^\*\*(.+?)\*\*[:\s]*(.+)?$/); // Updated to allow standalone bold
|
|
2262
|
-
|
|
2344
|
+
|
|
2263
2345
|
if (boldMatch) {
|
|
2264
2346
|
const title = cleanText(boldMatch[1]);
|
|
2265
2347
|
let content = boldMatch[2] ? cleanText(boldMatch[2]) : '';
|
|
2266
|
-
|
|
2348
|
+
|
|
2267
2349
|
// Look ahead for content if none on the same line
|
|
2268
2350
|
if (!content && j + 1 < lines.length) {
|
|
2269
2351
|
const nextLine = lines[j + 1];
|
|
2270
2352
|
console.log(`🔍 Checking next line for content: "${nextLine}"`);
|
|
2271
|
-
if (
|
|
2353
|
+
if (
|
|
2354
|
+
nextLine &&
|
|
2355
|
+
!nextLine.match(/^\d+\.\s|- /) &&
|
|
2356
|
+
!nextLine.startsWith('#### ') &&
|
|
2357
|
+
!nextLine.startsWith('### ')
|
|
2358
|
+
) {
|
|
2272
2359
|
content = cleanText(nextLine);
|
|
2273
2360
|
console.log(`✅ Found content in next line: "${content}"`);
|
|
2274
2361
|
j++; // Skip the next line since we’ve consumed it
|
|
2275
2362
|
}
|
|
2276
2363
|
}
|
|
2277
|
-
|
|
2278
|
-
console.log(
|
|
2364
|
+
|
|
2365
|
+
console.log(
|
|
2366
|
+
`✅ Bold match found - Title: "${title}", Content: "${
|
|
2367
|
+
content || 'None'
|
|
2368
|
+
}"`
|
|
2369
|
+
);
|
|
2279
2370
|
report.sections[currentSection].push({
|
|
2280
2371
|
type: 'bullet-point',
|
|
2281
2372
|
title,
|
|
@@ -2290,18 +2381,24 @@ export class ConceptService {
|
|
|
2290
2381
|
}
|
|
2291
2382
|
continue;
|
|
2292
2383
|
}
|
|
2293
|
-
|
|
2384
|
+
|
|
2294
2385
|
console.log(`📝 Paragraph: "${line}"`);
|
|
2295
2386
|
report.sections[currentSection].push({
|
|
2296
2387
|
type: 'p',
|
|
2297
2388
|
content: cleanText(line),
|
|
2298
2389
|
});
|
|
2299
2390
|
}
|
|
2300
|
-
|
|
2301
|
-
console.log(
|
|
2391
|
+
|
|
2392
|
+
console.log(
|
|
2393
|
+
`🏁 Finished parsing ${language} section. Result:\n${JSON.stringify(
|
|
2394
|
+
report,
|
|
2395
|
+
null,
|
|
2396
|
+
2
|
|
2397
|
+
)}`
|
|
2398
|
+
);
|
|
2302
2399
|
reports.push(report);
|
|
2303
2400
|
}
|
|
2304
|
-
|
|
2401
|
+
|
|
2305
2402
|
console.log(`🎉 Parsing complete. Total reports: ${reports.length}`);
|
|
2306
2403
|
return reports;
|
|
2307
2404
|
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
CREATE TABLE `astro_feature_reports` (
|
|
2
|
+
`id` text PRIMARY KEY NOT NULL,
|
|
3
|
+
`feature_type` text NOT NULL,
|
|
4
|
+
`name` text NOT NULL,
|
|
5
|
+
`en_description` text,
|
|
6
|
+
`pt_description` text,
|
|
7
|
+
`en_report` text,
|
|
8
|
+
`pt_report` text,
|
|
9
|
+
`created_at` integer DEFAULT CURRENT_TIMESTAMP,
|
|
10
|
+
`updated_at` integer DEFAULT CURRENT_TIMESTAMP
|
|
11
|
+
);
|
|
12
|
+
--> statement-breakpoint
|
|
13
|
+
CREATE INDEX `astro_feature_reports_type_name_idx` ON `astro_feature_reports` (`feature_type`,`name`);
|