@realtimex/realtimex-alchemy 1.0.26 → 1.0.28
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/dist/CHANGELOG.md +35 -3
- package/dist/api/services/AlchemistService.js +1 -1
- package/dist/api/services/DeduplicationService.js +39 -11
- package/dist/api/services/ProcessingEventService.js +4 -1
- package/dist/assets/index-Covm3q34.js +124 -0
- package/dist/assets/index-D3Ak395f.css +1 -0
- package/dist/index.html +2 -2
- package/package.json +2 -1
- package/dist/assets/index-BMTB9X3D.css +0 -1
- package/dist/assets/index-DHwhbNIr.js +0 -124
package/dist/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,40 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [1.0.28] - 2026-01-23
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
- **System Logs**: Added an interactive "Action Center" with overview cards for Blacklist Suggestions, Recent Errors, and Total Signals.
|
|
12
|
+
- **System Logs**: Implemented detailed modals for reviewing Blacklist candidates, debugging Errors, and browsing recent Signals.
|
|
13
|
+
- **Live Terminal**: Added "Deep Links" that allow users to jump directly from a terminal event (like a low-score warning) to the relevant management view in System Logs.
|
|
14
|
+
- **Navigation**: Improved app-wide navigation state to support context-aware jumping between tabs.
|
|
15
|
+
|
|
16
|
+
## [1.0.27] - 2026-01-23
|
|
17
|
+
|
|
18
|
+
### Added
|
|
19
|
+
- **Browser Sources**: Added granular control over browser sources. Users can now select specific browser profiles to mine from.
|
|
20
|
+
- **Analysis**: Introduced `HighConfidenceIndicator` to visually highlight signals with high relevance scores.
|
|
21
|
+
- **Tagging**: Implemented a tagging system for signals to improve categorization and filtering.
|
|
22
|
+
- **Sync**: Added "Sync Mode" configuration to control how historical data is processed.
|
|
23
|
+
- **Deduplication**: Enhanced deduplication logic to prevent redundant signals from cluttering the feed.
|
|
24
|
+
|
|
25
|
+
## [1.0.26] - 2026-01-23
|
|
26
|
+
|
|
27
|
+
### Added
|
|
28
|
+
- **SDK**: Integrated the official `@realtimex/sdk` for standardized API interactions and type safety.
|
|
29
|
+
|
|
30
|
+
## [1.0.25] - 2026-01-22
|
|
31
|
+
|
|
32
|
+
### Added
|
|
33
|
+
- **Intelligence**: Implemented semantic embeddings for deeper content understanding and similarity matching.
|
|
34
|
+
- **Data Quality**: Added smart deduplication to merge similar signals based on semantic proximity.
|
|
35
|
+
|
|
36
|
+
## [1.0.24] - 2026-01-22
|
|
37
|
+
|
|
38
|
+
### Added
|
|
39
|
+
- **Configuration**: Added dynamic blacklist domain management to filter out unwanted sources.
|
|
40
|
+
- **Debugging**: Enhanced debug logging for better troubleshooting of extraction pipelines.
|
|
41
|
+
|
|
8
42
|
## [1.0.23] - 2026-01-21
|
|
9
43
|
|
|
10
44
|
### Improved
|
|
@@ -148,6 +182,4 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
148
182
|
- **AI Analysis**: Introduced `AlchemistService` for local/cloud LLM analysis (Ollama, OpenAI, Anthropic) to score and summarize content.
|
|
149
183
|
- **Real-time UI**: Released React + Vite frontend with glassmorphism design, utilizing Server-Sent Events for live "Discovery Log" updates.
|
|
150
184
|
- **Data Persistence**: Integrated `LibrarianService` for syncing signals to Supabase with automated retention policies.
|
|
151
|
-
- **CLI Tool**: Added `realtimex-alchemy` binary for easy startup.
|
|
152
|
-
|
|
153
|
-
|
|
185
|
+
- **CLI Tool**: Added `realtimex-alchemy` binary for easy startup.
|
|
@@ -256,7 +256,7 @@ export class AlchemistService {
|
|
|
256
256
|
return;
|
|
257
257
|
}
|
|
258
258
|
// Check for duplicates
|
|
259
|
-
const dedupeResult = await deduplicationService.checkAndMergeDuplicate(signal, embedding, userId, supabase);
|
|
259
|
+
const dedupeResult = await deduplicationService.checkAndMergeDuplicate(signal, embedding, userId, supabase, settings);
|
|
260
260
|
if (dedupeResult.isDuplicate) {
|
|
261
261
|
console.log(`[AlchemistService] Signal is duplicate, merged into: ${dedupeResult.mergedSignalId}`);
|
|
262
262
|
// Delete the newly inserted signal since it's a duplicate
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { embeddingService } from './EmbeddingService.js';
|
|
2
|
+
import { SDKService } from './SDKService.js';
|
|
2
3
|
/**
|
|
3
4
|
* Deduplication Service
|
|
4
5
|
* Handles smart signal merging based on semantic similarity
|
|
@@ -13,7 +14,7 @@ export class DeduplicationService {
|
|
|
13
14
|
* @param supabase - Supabase client
|
|
14
15
|
* @returns Deduplication result
|
|
15
16
|
*/
|
|
16
|
-
async checkAndMergeDuplicate(signal, embedding, userId, supabase) {
|
|
17
|
+
async checkAndMergeDuplicate(signal, embedding, userId, supabase, settings) {
|
|
17
18
|
try {
|
|
18
19
|
// Find similar signals
|
|
19
20
|
const similar = await embeddingService.findSimilarSignals(embedding, userId, this.SIMILARITY_THRESHOLD, 5 // Check top 5 matches
|
|
@@ -25,7 +26,7 @@ export class DeduplicationService {
|
|
|
25
26
|
const bestMatch = similar[0];
|
|
26
27
|
console.log(`[Deduplication] Found similar signal: ${bestMatch.id} (score: ${bestMatch.score})`);
|
|
27
28
|
// Merge signals
|
|
28
|
-
const mergedId = await this.mergeSignals(bestMatch.id, signal, userId, supabase);
|
|
29
|
+
const mergedId = await this.mergeSignals(bestMatch.id, signal, userId, supabase, settings);
|
|
29
30
|
return {
|
|
30
31
|
isDuplicate: true,
|
|
31
32
|
mergedSignalId: mergedId,
|
|
@@ -45,7 +46,7 @@ export class DeduplicationService {
|
|
|
45
46
|
* @param supabase - Supabase client
|
|
46
47
|
* @returns Merged signal ID
|
|
47
48
|
*/
|
|
48
|
-
async mergeSignals(existingSignalId, newSignal, userId, supabase) {
|
|
49
|
+
async mergeSignals(existingSignalId, newSignal, userId, supabase, settings) {
|
|
49
50
|
// Fetch existing signal
|
|
50
51
|
const { data: existing, error } = await supabase
|
|
51
52
|
.from('signals')
|
|
@@ -61,8 +62,8 @@ export class DeduplicationService {
|
|
|
61
62
|
const mentionCount = (existing.mention_count || 1) + 1;
|
|
62
63
|
const scoreBoost = Math.min(mentionCount * 0.1, 0.5); // Max 50% boost
|
|
63
64
|
const newScore = Math.min(existing.score + scoreBoost, 10); // Cap at 10
|
|
64
|
-
// Combine summaries
|
|
65
|
-
const combinedSummary = this.combineSummaries(existing.summary, newSignal.summary);
|
|
65
|
+
// Combine summaries using LLM
|
|
66
|
+
const combinedSummary = await this.combineSummaries(existing.summary, newSignal.summary, settings);
|
|
66
67
|
// Track source URLs in metadata
|
|
67
68
|
const existingUrls = existing.metadata?.source_urls || [existing.url];
|
|
68
69
|
const sourceUrls = [...new Set([...existingUrls, newSignal.url])]; // Deduplicate URLs
|
|
@@ -91,18 +92,45 @@ export class DeduplicationService {
|
|
|
91
92
|
return existingSignalId;
|
|
92
93
|
}
|
|
93
94
|
/**
|
|
94
|
-
* Combine two summaries intelligently
|
|
95
|
+
* Combine two summaries intelligently using LLM
|
|
95
96
|
* @param existing - Existing summary
|
|
96
97
|
* @param newSummary - New summary
|
|
98
|
+
* @param settings - Alchemy settings for LLM
|
|
97
99
|
* @returns Combined summary
|
|
98
100
|
*/
|
|
99
|
-
combineSummaries(existing, newSummary) {
|
|
100
|
-
//
|
|
101
|
-
|
|
102
|
-
if (existing.length >= newSummary.length) {
|
|
101
|
+
async combineSummaries(existing, newSummary, settings) {
|
|
102
|
+
// If summaries are very similar, just use existing
|
|
103
|
+
if (existing === newSummary) {
|
|
103
104
|
return existing;
|
|
104
105
|
}
|
|
105
|
-
|
|
106
|
+
try {
|
|
107
|
+
const sdk = SDKService.getSDK();
|
|
108
|
+
if (!sdk) {
|
|
109
|
+
// Fallback: use longer summary
|
|
110
|
+
return existing.length >= newSummary.length ? existing : newSummary;
|
|
111
|
+
}
|
|
112
|
+
// Use LLM to intelligently merge summaries
|
|
113
|
+
const response = await sdk.llm.chat([
|
|
114
|
+
{
|
|
115
|
+
role: 'system',
|
|
116
|
+
content: 'You are a summary merger. Combine two summaries into one concise summary that captures all key information. Return ONLY the merged summary, no other text.'
|
|
117
|
+
},
|
|
118
|
+
{
|
|
119
|
+
role: 'user',
|
|
120
|
+
content: `Summary 1: ${existing}\nSummary 2: ${newSummary}\n\nMerged summary:`
|
|
121
|
+
}
|
|
122
|
+
], {
|
|
123
|
+
provider: settings.llm_provider || 'realtimexai',
|
|
124
|
+
model: settings.llm_model || 'gpt-4o-mini'
|
|
125
|
+
});
|
|
126
|
+
const merged = response.response?.content?.trim();
|
|
127
|
+
return merged || existing;
|
|
128
|
+
}
|
|
129
|
+
catch (error) {
|
|
130
|
+
console.error('[Deduplication] Summary merging failed:', error.message);
|
|
131
|
+
// Fallback: use longer summary
|
|
132
|
+
return existing.length >= newSummary.length ? existing : newSummary;
|
|
133
|
+
}
|
|
106
134
|
}
|
|
107
135
|
/**
|
|
108
136
|
* Get deduplication statistics for a user
|
|
@@ -33,7 +33,10 @@ export class ProcessingEventService {
|
|
|
33
33
|
details: event.details || {},
|
|
34
34
|
level: event.level || 'info',
|
|
35
35
|
duration_ms: event.durationMs || null,
|
|
36
|
-
metadata:
|
|
36
|
+
metadata: {
|
|
37
|
+
...(event.metadata || {}),
|
|
38
|
+
...(event.actionable ? { actionable: event.actionable } : {})
|
|
39
|
+
},
|
|
37
40
|
created_at: new Date().toISOString()
|
|
38
41
|
}]);
|
|
39
42
|
}
|