ei-tui 0.6.2 → 0.6.4

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ei-tui",
3
- "version": "0.6.2",
3
+ "version": "0.6.4",
4
4
  "author": "Flare576",
5
5
  "repository": {
6
6
  "type": "git",
@@ -123,9 +123,9 @@ export async function handleFactFind(response: LLMResponse, state: StateManager)
123
123
  continue;
124
124
  }
125
125
 
126
- // Skip if the LLM returned a null/empty value — don't store null descriptions
127
- if (!factResult.value) {
128
- console.log(`[handleFactFind] Skipping fact with null/empty value: "${factResult.name}"`);
126
+ // Skip if the LLM returned a null/empty/non-string value — don't store booleans or nulls
127
+ if (!factResult.value || typeof factResult.value !== 'string') {
128
+ console.log(`[handleFactFind] Skipping fact with null/empty/non-string value: "${factResult.name}" (got ${typeof factResult.value})`);
129
129
  continue;
130
130
  }
131
131
 
@@ -123,6 +123,7 @@ export async function handleTopicUpdate(response: LLMResponse, state: StateManag
123
123
  const roomId = response.request.data.roomId as string | undefined;
124
124
  const candidateCategory = response.request.data.candidateCategory as string | undefined;
125
125
  const candidateName = response.request.data.candidateName as string | undefined;
126
+ const candidateDescription = response.request.data.candidateDescription as string | undefined;
126
127
 
127
128
  const personaIds = personaId.split("|").filter(Boolean);
128
129
  const primaryId = personaIds[0] ?? personaId;
@@ -145,10 +146,15 @@ export async function handleTopicUpdate(response: LLMResponse, state: StateManag
145
146
  const existingTopic = isNewItem ? undefined : human.topics.find(t => t.id === existingItemId);
146
147
 
147
148
  const resolvedName = result.name || existingTopic?.name || candidateName;
148
- const resolvedDescription = typeof result.description === 'string' ? result.description : existingTopic?.description;
149
+ const resolvedDescription = typeof result.description === 'string' ? result.description : existingTopic?.description ?? candidateDescription;
150
+ const resolvedSentiment = result.sentiment !== undefined ? result.sentiment : existingTopic?.sentiment ?? 0;
149
151
 
150
- if (!resolvedName || !resolvedDescription || result.sentiment === undefined) {
151
- throw new Error(`[handleTopicUpdate] Missing required fields: name=${resolvedName}, description=${!!resolvedDescription}, sentiment=${result.sentiment}`);
152
+ if (!resolvedName || !resolvedDescription) {
153
+ if (isNewItem) {
154
+ throw new Error(`[handleTopicUpdate] Cannot create new topic — missing required fields: name=${resolvedName}, description=${!!resolvedDescription}`);
155
+ }
156
+ console.log(`[handleTopicUpdate] Skipping update for "${resolvedName ?? existingItemId}" — no description available and existing record preserved`);
157
+ return;
152
158
  }
153
159
 
154
160
  let embedding: number[] | undefined;
@@ -173,7 +179,7 @@ export async function handleTopicUpdate(response: LLMResponse, state: StateManag
173
179
  id: itemId,
174
180
  name: resolvedName,
175
181
  description: resolvedDescription,
176
- sentiment: result.sentiment,
182
+ sentiment: resolvedSentiment,
177
183
  category: result.category ?? candidateCategory ?? existingTopic?.category,
178
184
  exposure_current: calculateExposureCurrent(exposureImpact, existingTopic?.exposure_current ?? 0),
179
185
  exposure_desired: result.exposure_desired ?? 0.5,
@@ -216,11 +222,8 @@ export async function handlePersonUpdate(response: LLMResponse, state: StateMana
216
222
  const candidateRelationship = response.request.data.candidateRelationship as string | undefined;
217
223
  const candidateIdentifiers = (response.request.data.candidateIdentifiers ?? []) as PersonIdentifier[];
218
224
 
219
- if (!result.description || result.sentiment === undefined) {
220
- throw new Error(`[handlePersonUpdate] Missing required fields: description=${!!result.description}, sentiment=${result.sentiment}`);
221
- }
222
-
223
225
  const candidateName = response.request.data.candidateName as string;
226
+ const candidateDescription = response.request.data.candidateDescription as string | undefined;
224
227
  const personaIds = personaId.split("|").filter(Boolean);
225
228
  const primaryId = personaIds[0] ?? personaId;
226
229
 
@@ -241,11 +244,22 @@ export async function handlePersonUpdate(response: LLMResponse, state: StateMana
241
244
 
242
245
  const existingPerson = isNewItem ? undefined : human.people.find(p => p.id === existingItemId);
243
246
 
247
+ const resolvedDescription = typeof result.description === 'string' ? result.description : existingPerson?.description ?? candidateDescription;
248
+ const resolvedSentiment = result.sentiment !== undefined ? result.sentiment : existingPerson?.sentiment ?? 0;
249
+
250
+ if (!resolvedDescription) {
251
+ if (isNewItem) {
252
+ throw new Error(`[handlePersonUpdate] Cannot create new person "${candidateName}" — no description available`);
253
+ }
254
+ console.log(`[handlePersonUpdate] Skipping update for "${candidateName}" — no description available and existing record preserved`);
255
+ return;
256
+ }
257
+
244
258
  let embedding: number[] | undefined;
245
259
  try {
246
260
  const embeddingService = getEmbeddingService();
247
261
  const relationship = result.relationship ?? candidateRelationship ?? existingPerson?.relationship;
248
- const text = getPersonEmbeddingText({ name: candidateName, relationship, description: result.description });
262
+ const text = getPersonEmbeddingText({ name: candidateName, relationship, description: resolvedDescription });
249
263
  embedding = await embeddingService.embed(text);
250
264
  } catch (err) {
251
265
  console.warn(`[handlePersonUpdate] Failed to compute embedding for person "${candidateName}":`, err);
@@ -295,8 +309,8 @@ export async function handlePersonUpdate(response: LLMResponse, state: StateMana
295
309
  const person: Person = {
296
310
  id: itemId,
297
311
  name: candidateName,
298
- description: result.description,
299
- sentiment: result.sentiment,
312
+ description: resolvedDescription,
313
+ sentiment: resolvedSentiment,
300
314
  relationship: result.relationship ?? candidateRelationship ?? existingPerson?.relationship ?? "Unknown",
301
315
  exposure_current: calculateExposureCurrent(exposureImpact, existingPerson?.exposure_current ?? 0),
302
316
  exposure_desired: result.exposure_desired ?? 0.5,
@@ -423,6 +423,7 @@ export function queueTopicUpdate(
423
423
  isNewItem,
424
424
  existingItemId: existingItem?.id,
425
425
  candidateName: isNewItem ? context.candidateName : undefined,
426
+ candidateDescription: isNewItem ? context.candidateDescription : undefined,
426
427
  candidateCategory: context.candidateCategory,
427
428
  analyze_from_timestamp: getAnalyzeFromTimestamp(chunk),
428
429
  },
@@ -586,6 +587,7 @@ export function queuePersonUpdate(
586
587
  isNewItem,
587
588
  existingItemId: existingItem?.id,
588
589
  candidateName: context.candidateName,
590
+ candidateDescription: isNewItem ? context.candidateDescription : undefined,
589
591
  candidateRelationship: context.candidateRelationship,
590
592
  candidateIdentifiers: isNewItem ? candidateIdentifiers : undefined,
591
593
  analyze_from_timestamp: getAnalyzeFromTimestamp(chunk),