@dropout-ai/runtime 0.3.8 â 0.3.9
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 +1 -1
- package/src/index.js +61 -82
package/package.json
CHANGED
package/src/index.js
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @dropout-ai/runtime
|
|
3
3
|
* Universal AI Interaction Capture for Node.js
|
|
4
|
-
*
|
|
5
|
-
* Features: Auto-Discovery, Connectivity Check, Dual-Schema Support
|
|
4
|
+
* Feature: Always-On Heartbeat & Auto-Discovery
|
|
6
5
|
*/
|
|
7
6
|
|
|
8
|
-
|
|
7
|
+
const https = require('https');
|
|
8
|
+
const http = require('http');
|
|
9
|
+
const crypto = require('crypto');
|
|
9
10
|
|
|
10
|
-
// ---
|
|
11
|
+
// --- CONFIGURATION ---
|
|
11
12
|
const SUPABASE_FUNCTION_URL = "https://hipughmjlwmwjxzyxfzs.supabase.co/functions/v1/capture-sealed";
|
|
12
13
|
|
|
13
14
|
// Known AI Domains
|
|
@@ -18,74 +19,53 @@ const KNOWN_AI_DOMAINS = [
|
|
|
18
19
|
|
|
19
20
|
class Dropout {
|
|
20
21
|
constructor(config = {}) {
|
|
21
|
-
// đĄī¸
|
|
22
|
-
// If this accidentally runs in a browser/Client Component, we abort silently.
|
|
22
|
+
// đĄī¸ BROWSER GUARD
|
|
23
23
|
if (typeof window !== 'undefined' && typeof window.document !== 'undefined') {
|
|
24
|
-
if (config.debug) console.warn("[Dropout] â ī¸ Skipped: Browser detected.
|
|
24
|
+
if (config.debug) console.warn("[Dropout] â ī¸ Skipped: Browser detected.");
|
|
25
25
|
return;
|
|
26
26
|
}
|
|
27
27
|
|
|
28
|
-
// đĄī¸
|
|
28
|
+
// đĄī¸ CREDENTIAL GUARD
|
|
29
29
|
if (!config.apiKey || !config.projectId) {
|
|
30
|
-
if (config.debug) console.warn("[Dropout] â ī¸ Skipped: Missing
|
|
30
|
+
if (config.debug) console.warn("[Dropout] â ī¸ Skipped: Missing Credentials.");
|
|
31
31
|
return;
|
|
32
32
|
}
|
|
33
33
|
|
|
34
|
-
//
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
34
|
+
// Initialize
|
|
35
|
+
this.config = config;
|
|
36
|
+
this.projectId = config.projectId;
|
|
37
|
+
this.apiKey = config.apiKey;
|
|
38
|
+
this.debug = config.debug || false;
|
|
39
|
+
this.privacy = config.privacy || 'full';
|
|
40
|
+
this.captureEndpoint = SUPABASE_FUNCTION_URL;
|
|
41
|
+
this.maxOutputBytes = 32768;
|
|
42
|
+
|
|
43
|
+
// State
|
|
44
|
+
this.turnIndex = 0;
|
|
45
|
+
this.lastTurnConfirmed = true;
|
|
46
|
+
this.lastPromptHash = null;
|
|
47
|
+
this.lastResponseHash = null;
|
|
48
|
+
|
|
49
|
+
// Singleton Guard
|
|
50
|
+
if (global.__dropout_initialized__) return;
|
|
51
|
+
global.__dropout_initialized__ = true;
|
|
52
|
+
|
|
53
|
+
if (!global.__dropout_session_id__) {
|
|
54
|
+
global.__dropout_session_id__ = this.generateSessionId();
|
|
42
55
|
}
|
|
43
56
|
|
|
44
|
-
|
|
45
|
-
try {
|
|
46
|
-
this.config = config;
|
|
47
|
-
this.projectId = config.projectId;
|
|
48
|
-
this.apiKey = config.apiKey;
|
|
49
|
-
this.debug = config.debug || false;
|
|
50
|
-
this.privacy = config.privacy || 'full';
|
|
51
|
-
this.captureEndpoint = SUPABASE_FUNCTION_URL;
|
|
52
|
-
this.maxOutputBytes = 32768;
|
|
53
|
-
|
|
54
|
-
// State
|
|
55
|
-
this.turnIndex = 0;
|
|
56
|
-
this.lastTurnConfirmed = true;
|
|
57
|
-
this.lastPromptHash = null;
|
|
58
|
-
this.lastResponseHash = null;
|
|
59
|
-
|
|
60
|
-
// Singleton Guard
|
|
61
|
-
if (global.__dropout_initialized__) {
|
|
62
|
-
if (this.debug) console.log("[Dropout] âšī¸ Already initialized.");
|
|
63
|
-
return;
|
|
64
|
-
}
|
|
65
|
-
global.__dropout_initialized__ = true;
|
|
66
|
-
|
|
67
|
-
// Identity
|
|
68
|
-
if (!global.__dropout_session_id__) {
|
|
69
|
-
global.__dropout_session_id__ = this.generateSessionId();
|
|
70
|
-
}
|
|
57
|
+
if (this.debug) console.log(`[Dropout] đĸ Online: ${this.projectId}`);
|
|
71
58
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
59
|
+
// Bindings
|
|
60
|
+
this.log = this.log.bind(this);
|
|
61
|
+
this.emit = this.emit.bind(this);
|
|
75
62
|
|
|
76
|
-
|
|
77
|
-
|
|
63
|
+
// 1. Start Network Interceptor
|
|
64
|
+
this.patchNetwork();
|
|
78
65
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
this.validateConnection();
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
} catch (err) {
|
|
86
|
-
// THE ULTIMATE CATCH-ALL: Ensure app NEVER crashes
|
|
87
|
-
if (config.debug) console.error("[Dropout] â Initialization Error:", err);
|
|
88
|
-
}
|
|
66
|
+
// 2. SEND STARTUP PING (Always run this, silent by default)
|
|
67
|
+
// This turns the dashboard status GREEN immediately on app boot.
|
|
68
|
+
this.sendStartupSignal();
|
|
89
69
|
}
|
|
90
70
|
|
|
91
71
|
// --- UTILS ---
|
|
@@ -101,9 +81,24 @@ class Dropout {
|
|
|
101
81
|
}
|
|
102
82
|
}
|
|
103
83
|
|
|
104
|
-
// ---
|
|
105
|
-
|
|
106
|
-
|
|
84
|
+
// --- HEARTBEAT ---
|
|
85
|
+
sendStartupSignal() {
|
|
86
|
+
// We send a discrete 'system_boot' event.
|
|
87
|
+
// The Database Trigger will see this and update projects.last_active_at
|
|
88
|
+
const payload = JSON.stringify({
|
|
89
|
+
project_id: this.projectId,
|
|
90
|
+
session_id: 'system_boot_' + Date.now(),
|
|
91
|
+
turn_role: 'system',
|
|
92
|
+
turn_index: 0,
|
|
93
|
+
content: 'Dropout SDK Initialized',
|
|
94
|
+
//content_blob: 'Dropout SDK Initialized',
|
|
95
|
+
metadata_flags: {
|
|
96
|
+
type: 'system_boot',
|
|
97
|
+
environment: process.env.NODE_ENV || 'development',
|
|
98
|
+
runtime: 'node'
|
|
99
|
+
},
|
|
100
|
+
received_at: new Date().toISOString()
|
|
101
|
+
});
|
|
107
102
|
|
|
108
103
|
const req = https.request(this.captureEndpoint, {
|
|
109
104
|
method: 'POST',
|
|
@@ -111,26 +106,11 @@ class Dropout {
|
|
|
111
106
|
'Content-Type': 'application/json',
|
|
112
107
|
'x-dropout-key': this.apiKey
|
|
113
108
|
}
|
|
114
|
-
}, (res) => {
|
|
115
|
-
if (res.statusCode >= 200 && res.statusCode < 300) {
|
|
116
|
-
console.log(`[Dropout] â
Connected to Project: ${this.projectId}`);
|
|
117
|
-
} else {
|
|
118
|
-
console.warn(`[Dropout] â ī¸ Connection Failed (Status: ${res.statusCode}). Check your API Key.`);
|
|
119
|
-
}
|
|
120
109
|
});
|
|
121
110
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
req.write(JSON.stringify({
|
|
126
|
-
project_id: this.projectId,
|
|
127
|
-
session_id: 'system_ping',
|
|
128
|
-
turn_role: 'system',
|
|
129
|
-
turn_index: 0,
|
|
130
|
-
content: 'ping',
|
|
131
|
-
//content_blob: 'ping',
|
|
132
|
-
metadata_flags: { type: 'connectivity_check' }
|
|
133
|
-
}));
|
|
111
|
+
// Silent error handling (unless debug is on)
|
|
112
|
+
req.on('error', (e) => this.log("â Startup Signal Failed", e.message));
|
|
113
|
+
req.write(payload);
|
|
134
114
|
req.end();
|
|
135
115
|
}
|
|
136
116
|
|
|
@@ -160,7 +140,7 @@ class Dropout {
|
|
|
160
140
|
if (parsed.model) model = parsed.model;
|
|
161
141
|
if (provider === 'custom' && (parsed.messages || parsed.prompt)) provider = 'heuristic';
|
|
162
142
|
}
|
|
163
|
-
} catch (e) {
|
|
143
|
+
} catch (e) { }
|
|
164
144
|
return { provider, model };
|
|
165
145
|
}
|
|
166
146
|
|
|
@@ -413,7 +393,6 @@ class Dropout {
|
|
|
413
393
|
}
|
|
414
394
|
}
|
|
415
395
|
|
|
416
|
-
// Auto-Start (Server-Side Only)
|
|
417
396
|
if (typeof process !== 'undefined' && process.env.DROPOUT_PROJECT_ID && process.env.DROPOUT_API_KEY) {
|
|
418
397
|
new Dropout({
|
|
419
398
|
projectId: process.env.DROPOUT_PROJECT_ID,
|