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