@dropout-ai/runtime 0.2.6 → 0.2.7
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 +63 -8
package/package.json
CHANGED
package/src/index.js
CHANGED
|
@@ -24,6 +24,7 @@ if (!GLOBAL_OBJ.__dropout_session_id__) {
|
|
|
24
24
|
}
|
|
25
25
|
|
|
26
26
|
let turnIndex = 0;
|
|
27
|
+
let lastTurnConfirmed = true;
|
|
27
28
|
let lastPromptHash = null;
|
|
28
29
|
let lastResponseHash = null;
|
|
29
30
|
|
|
@@ -65,6 +66,39 @@ function emit(payload) {
|
|
|
65
66
|
}, 0);
|
|
66
67
|
}
|
|
67
68
|
|
|
69
|
+
// --- Lifecycle Signals ---
|
|
70
|
+
|
|
71
|
+
function emitSessionEnd(reason) {
|
|
72
|
+
if (GLOBAL_OBJ.__dropout_session_ended__) return;
|
|
73
|
+
GLOBAL_OBJ.__dropout_session_ended__ = true;
|
|
74
|
+
|
|
75
|
+
emit({
|
|
76
|
+
identity: {
|
|
77
|
+
session_id: GLOBAL_OBJ.__dropout_session_id__,
|
|
78
|
+
turn_index: turnIndex,
|
|
79
|
+
direction: 'meta',
|
|
80
|
+
turn_role: 'system'
|
|
81
|
+
},
|
|
82
|
+
timing: { created_at: Date.now() },
|
|
83
|
+
metadata_flags: {
|
|
84
|
+
session_end: true,
|
|
85
|
+
end_reason: reason
|
|
86
|
+
}
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// Browser: Navigation/Reload
|
|
91
|
+
if (typeof window !== 'undefined' && window.addEventListener) {
|
|
92
|
+
window.addEventListener('beforeunload', () => emitSessionEnd('navigation'));
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// Node.js: Process Exit
|
|
96
|
+
if (typeof process !== 'undefined' && process.on) {
|
|
97
|
+
process.on('exit', () => emitSessionEnd('process_exit'));
|
|
98
|
+
process.on('SIGINT', () => { emitSessionEnd('sigint'); process.exit(); });
|
|
99
|
+
process.on('SIGTERM', () => { emitSessionEnd('sigterm'); process.exit(); });
|
|
100
|
+
}
|
|
101
|
+
|
|
68
102
|
// --- Content Utilities ---
|
|
69
103
|
|
|
70
104
|
function hash(text) {
|
|
@@ -122,7 +156,16 @@ if (typeof GLOBAL_OBJ.fetch === 'function' && !GLOBAL_OBJ.fetch.__dropout_patche
|
|
|
122
156
|
if (!isAI) return GLOBAL_OBJ.__dropout_original_fetch__(input, init);
|
|
123
157
|
|
|
124
158
|
const start = Date.now();
|
|
125
|
-
|
|
159
|
+
|
|
160
|
+
// --- Explicit Turn Increment Rule ---
|
|
161
|
+
let activeTurn;
|
|
162
|
+
if (lastTurnConfirmed) {
|
|
163
|
+
activeTurn = turnIndex++;
|
|
164
|
+
lastTurnConfirmed = false;
|
|
165
|
+
} else {
|
|
166
|
+
activeTurn = turnIndex > 0 ? turnIndex - 1 : 0;
|
|
167
|
+
}
|
|
168
|
+
|
|
126
169
|
const { provider, model } = normalize(url, init && init.body);
|
|
127
170
|
|
|
128
171
|
// --- 1. Emit Request Event ---
|
|
@@ -136,7 +179,7 @@ if (typeof GLOBAL_OBJ.fetch === 'function' && !GLOBAL_OBJ.fetch.__dropout_patche
|
|
|
136
179
|
const requestEvent = {
|
|
137
180
|
identity: {
|
|
138
181
|
session_id: GLOBAL_OBJ.__dropout_session_id__,
|
|
139
|
-
turn_index:
|
|
182
|
+
turn_index: activeTurn,
|
|
140
183
|
direction: 'request',
|
|
141
184
|
turn_role: 'user'
|
|
142
185
|
},
|
|
@@ -165,7 +208,6 @@ if (typeof GLOBAL_OBJ.fetch === 'function' && !GLOBAL_OBJ.fetch.__dropout_patche
|
|
|
165
208
|
try {
|
|
166
209
|
response = await GLOBAL_OBJ.__dropout_original_fetch__(input, init);
|
|
167
210
|
} catch (err) {
|
|
168
|
-
// Re-throw after giving it a chance to be reported if needed (though runtime usually silent)
|
|
169
211
|
throw err;
|
|
170
212
|
}
|
|
171
213
|
|
|
@@ -186,7 +228,7 @@ if (typeof GLOBAL_OBJ.fetch === 'function' && !GLOBAL_OBJ.fetch.__dropout_patche
|
|
|
186
228
|
const responseEvent = {
|
|
187
229
|
identity: {
|
|
188
230
|
session_id: GLOBAL_OBJ.__dropout_session_id__,
|
|
189
|
-
turn_index:
|
|
231
|
+
turn_index: activeTurn,
|
|
190
232
|
direction: 'response',
|
|
191
233
|
turn_role: 'assistant'
|
|
192
234
|
},
|
|
@@ -210,6 +252,7 @@ if (typeof GLOBAL_OBJ.fetch === 'function' && !GLOBAL_OBJ.fetch.__dropout_patche
|
|
|
210
252
|
|
|
211
253
|
emit(responseEvent);
|
|
212
254
|
lastResponseHash = oHash;
|
|
255
|
+
lastTurnConfirmed = true; // Confirmation Rule locked
|
|
213
256
|
|
|
214
257
|
return response;
|
|
215
258
|
};
|
|
@@ -222,7 +265,15 @@ if (typeof GLOBAL_OBJ.fetch === 'function' && !GLOBAL_OBJ.fetch.__dropout_patche
|
|
|
222
265
|
*/
|
|
223
266
|
async function capture(target, options = {}) {
|
|
224
267
|
const start = Date.now();
|
|
225
|
-
|
|
268
|
+
|
|
269
|
+
let activeTurn;
|
|
270
|
+
if (lastTurnConfirmed) {
|
|
271
|
+
activeTurn = turnIndex++;
|
|
272
|
+
lastTurnConfirmed = false;
|
|
273
|
+
} else {
|
|
274
|
+
activeTurn = turnIndex > 0 ? turnIndex - 1 : 0;
|
|
275
|
+
}
|
|
276
|
+
|
|
226
277
|
const mode = options.privacy || config.privacyMode;
|
|
227
278
|
|
|
228
279
|
let prompt, output, latency_ms = options.latency || 0;
|
|
@@ -242,7 +293,7 @@ async function capture(target, options = {}) {
|
|
|
242
293
|
|
|
243
294
|
// Emit Request
|
|
244
295
|
emit({
|
|
245
|
-
identity: { session_id: GLOBAL_OBJ.__dropout_session_id__, turn_index:
|
|
296
|
+
identity: { session_id: GLOBAL_OBJ.__dropout_session_id__, turn_index: activeTurn, direction: 'request', turn_role: 'user' },
|
|
246
297
|
timing: { created_at: Date.now() },
|
|
247
298
|
provider_context: { provider: options.provider || 'manual', model: options.model || 'unknown' },
|
|
248
299
|
content: { content_raw: mode === 'full' ? prompt : null, content_hash: pHash },
|
|
@@ -251,7 +302,7 @@ async function capture(target, options = {}) {
|
|
|
251
302
|
|
|
252
303
|
// Emit Response
|
|
253
304
|
emit({
|
|
254
|
-
identity: { session_id: GLOBAL_OBJ.__dropout_session_id__, turn_index:
|
|
305
|
+
identity: { session_id: GLOBAL_OBJ.__dropout_session_id__, turn_index: activeTurn, direction: 'response', turn_role: 'assistant' },
|
|
255
306
|
timing: { created_at: Date.now(), latency_ms },
|
|
256
307
|
provider_context: { provider: options.provider || 'manual', model: options.model || 'unknown' },
|
|
257
308
|
content: { content_raw: mode === 'full' ? output : null, content_hash: oHash },
|
|
@@ -260,15 +311,19 @@ async function capture(target, options = {}) {
|
|
|
260
311
|
|
|
261
312
|
lastPromptHash = pHash;
|
|
262
313
|
lastResponseHash = oHash;
|
|
314
|
+
lastTurnConfirmed = true;
|
|
263
315
|
|
|
264
316
|
return output;
|
|
265
317
|
}
|
|
266
318
|
|
|
267
319
|
module.exports = {
|
|
268
320
|
capture,
|
|
269
|
-
reset: () => {
|
|
321
|
+
reset: (reason = 'manual_reset') => {
|
|
322
|
+
emitSessionEnd(reason);
|
|
270
323
|
GLOBAL_OBJ.__dropout_session_id__ = generateSessionId();
|
|
324
|
+
GLOBAL_OBJ.__dropout_session_ended__ = false;
|
|
271
325
|
turnIndex = 0;
|
|
326
|
+
lastTurnConfirmed = true;
|
|
272
327
|
lastPromptHash = null;
|
|
273
328
|
lastResponseHash = null;
|
|
274
329
|
}
|