@cydm/happy-elves 0.1.0-beta.274 → 0.1.0-beta.277
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.
|
@@ -315,7 +315,7 @@ function foldAliasedRuntimeEvents(events) {
|
|
|
315
315
|
const profiles = new Map();
|
|
316
316
|
const runtimeToRequest = new Map();
|
|
317
317
|
for (const event of events) {
|
|
318
|
-
const profile = profiles.get(event.turnId) ?? { output: "" };
|
|
318
|
+
const profile = profiles.get(event.turnId) ?? { output: "", status: "running" };
|
|
319
319
|
const payload = event.decoded;
|
|
320
320
|
if (payload?.type === "user_prompt" && profile.prompt === undefined) {
|
|
321
321
|
profile.prompt = payload.text.trim();
|
|
@@ -328,6 +328,7 @@ function foldAliasedRuntimeEvents(events) {
|
|
|
328
328
|
if (runtimeTurnId && runtimeTurnId !== event.turnId && !runtimeTurnId.startsWith("event:")) {
|
|
329
329
|
runtimeToRequest.set(runtimeTurnId, event.turnId);
|
|
330
330
|
}
|
|
331
|
+
profile.status = payload.status;
|
|
331
332
|
}
|
|
332
333
|
profiles.set(event.turnId, profile);
|
|
333
334
|
}
|
|
@@ -345,11 +346,46 @@ function foldAliasedRuntimeEvents(events) {
|
|
|
345
346
|
duplicateRuntimeToRequest.set(runtimeTurnId, requestTurnId);
|
|
346
347
|
}
|
|
347
348
|
}
|
|
349
|
+
const inferredRuntimeToRequest = inferRuntimeCompletionAliases(profiles);
|
|
350
|
+
const inferredRequestTurns = new Set(inferredRuntimeToRequest.values());
|
|
351
|
+
const foldedRuntimeToRequest = new Map([...duplicateRuntimeToRequest, ...inferredRuntimeToRequest]);
|
|
352
|
+
const foldedEvents = [];
|
|
353
|
+
for (const event of events) {
|
|
354
|
+
if (duplicateRuntimeTurns.has(event.turnId))
|
|
355
|
+
continue;
|
|
356
|
+
const inferredRequestTurnId = inferredRuntimeToRequest.get(event.turnId);
|
|
357
|
+
if (inferredRequestTurnId) {
|
|
358
|
+
if (event.decoded?.type === "user_prompt" && profiles.get(inferredRequestTurnId)?.prompt)
|
|
359
|
+
continue;
|
|
360
|
+
foldedEvents.push({ ...event, turnId: inferredRequestTurnId });
|
|
361
|
+
continue;
|
|
362
|
+
}
|
|
363
|
+
if (inferredRequestTurns.has(event.turnId) &&
|
|
364
|
+
event.decoded?.type === "text_delta" &&
|
|
365
|
+
event.decoded.stream !== "thought") {
|
|
366
|
+
continue;
|
|
367
|
+
}
|
|
368
|
+
foldedEvents.push(event);
|
|
369
|
+
}
|
|
348
370
|
return {
|
|
349
|
-
events:
|
|
350
|
-
runtimeToRequest:
|
|
371
|
+
events: foldedEvents,
|
|
372
|
+
runtimeToRequest: foldedRuntimeToRequest,
|
|
351
373
|
};
|
|
352
374
|
}
|
|
375
|
+
function inferRuntimeCompletionAliases(profiles) {
|
|
376
|
+
const requestTurns = [...profiles.entries()].filter(([turnId, profile]) => turnId.startsWith("turn_") && profile.status === "running" && Boolean(profile.prompt?.trim()));
|
|
377
|
+
const runtimeTurns = [...profiles.entries()].filter(([turnId, profile]) => !turnId.startsWith("turn_") && profile.status !== "running" && Boolean(profile.prompt?.trim()));
|
|
378
|
+
const result = new Map();
|
|
379
|
+
for (const [runtimeTurnId, runtime] of runtimeTurns) {
|
|
380
|
+
const candidates = requestTurns.filter(([, request]) => promptCompatible(request.prompt ?? "", runtime.prompt ?? "") &&
|
|
381
|
+
outputCompatibleForInferredAlias(request.output, runtime.output, request.prompt ?? "", runtime.prompt ?? ""));
|
|
382
|
+
if (candidates.length !== 1)
|
|
383
|
+
continue;
|
|
384
|
+
const [requestTurnId] = candidates[0];
|
|
385
|
+
result.set(runtimeTurnId, requestTurnId);
|
|
386
|
+
}
|
|
387
|
+
return result;
|
|
388
|
+
}
|
|
353
389
|
function dedupeSyntheticHistoricalEvents(events) {
|
|
354
390
|
const groups = new Map();
|
|
355
391
|
for (const event of events) {
|
|
@@ -408,6 +444,23 @@ function isDuplicateRuntimeOutput(requestOutput, runtimeOutput) {
|
|
|
408
444
|
const runtime = comparableOutput(runtimeOutput);
|
|
409
445
|
return !runtime || request === runtime || request.includes(runtime);
|
|
410
446
|
}
|
|
447
|
+
function promptCompatible(requestPrompt, runtimePrompt) {
|
|
448
|
+
const request = comparableOutput(requestPrompt);
|
|
449
|
+
const runtime = comparableOutput(runtimePrompt);
|
|
450
|
+
if (!request || !runtime)
|
|
451
|
+
return false;
|
|
452
|
+
if (request === runtime)
|
|
453
|
+
return true;
|
|
454
|
+
return (request.length >= 40 && runtime.includes(request)) ||
|
|
455
|
+
(runtime.length >= 40 && request.includes(runtime));
|
|
456
|
+
}
|
|
457
|
+
function outputCompatibleForInferredAlias(requestOutput, runtimeOutput, requestPrompt, runtimePrompt) {
|
|
458
|
+
const request = comparableOutput(requestOutput);
|
|
459
|
+
const runtime = comparableOutput(runtimeOutput);
|
|
460
|
+
if (request && runtime)
|
|
461
|
+
return request.includes(runtime) || runtime.includes(request);
|
|
462
|
+
return comparableOutput(requestPrompt) === comparableOutput(runtimePrompt) && Boolean(request || runtime);
|
|
463
|
+
}
|
|
411
464
|
function comparableOutput(value) {
|
|
412
465
|
return value.replace(/\s+/g, " ").trim();
|
|
413
466
|
}
|
package/apps/cli/package.json
CHANGED
|
@@ -248,7 +248,7 @@ async function runStage(stage) {
|
|
|
248
248
|
await log("$ " + stage.command + " " + args.map(shellQuote).join(" "));
|
|
249
249
|
const result = await run(stage.command, args, {
|
|
250
250
|
cwd: input.repoCwd,
|
|
251
|
-
env:
|
|
251
|
+
env: envForStage(stage),
|
|
252
252
|
});
|
|
253
253
|
await log(result.stdout);
|
|
254
254
|
if (result.stderr) await log(result.stderr);
|
|
@@ -300,16 +300,20 @@ async function run(command, args, options) {
|
|
|
300
300
|
});
|
|
301
301
|
}
|
|
302
302
|
|
|
303
|
-
function
|
|
303
|
+
function envForStage(stage) {
|
|
304
|
+
const env = { ...process.env };
|
|
305
|
+
if (stage.phase !== "update" && stage.phase !== "notify") {
|
|
306
|
+
delete env.HAPPY_ELVES_RELAY_URL;
|
|
307
|
+
delete env.HAPPY_ELVES_CONTROLLER_TOKEN;
|
|
308
|
+
delete env.HAPPY_ELVES_ACCOUNT_SECRET;
|
|
309
|
+
return env;
|
|
310
|
+
}
|
|
304
311
|
const config = input.controllerConfig;
|
|
305
|
-
return
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
HAPPY_ELVES_ACCOUNT_SECRET: config.accountSecret,
|
|
311
|
-
} : {}),
|
|
312
|
-
};
|
|
312
|
+
if (!config) return env;
|
|
313
|
+
env.HAPPY_ELVES_RELAY_URL = config.relayUrl;
|
|
314
|
+
env.HAPPY_ELVES_CONTROLLER_TOKEN = config.controllerToken;
|
|
315
|
+
env.HAPPY_ELVES_ACCOUNT_SECRET = config.accountSecret;
|
|
316
|
+
return env;
|
|
313
317
|
}
|
|
314
318
|
|
|
315
319
|
async function setStage(name, patch) {
|
package/apps/daemon/package.json
CHANGED
|
@@ -396,13 +396,30 @@ export function handleMachineMessage(context, connection, message) {
|
|
|
396
396
|
return;
|
|
397
397
|
}
|
|
398
398
|
const ts = now();
|
|
399
|
+
const promptTurnForRequest = message.requestId
|
|
400
|
+
? promptTurnForRequestId(db, connection.accountId, message.sessionId, connection.machineId, message.requestId)
|
|
401
|
+
: undefined;
|
|
402
|
+
const activeClaim = activePromptClaim(db, connection.accountId, message.sessionId, connection.machineId);
|
|
403
|
+
const replacementRequestTurn = promptTurnForRequest?.turn_id ??
|
|
404
|
+
(sessionRow.status === "running" && message.status ? activeClaim?.turn_id : undefined);
|
|
405
|
+
const replacementRequestId = promptTurnForRequest?.request_id ??
|
|
406
|
+
(replacementRequestTurn === activeClaim?.turn_id ? activeClaim?.request_id : undefined);
|
|
399
407
|
const inserted = [];
|
|
400
408
|
db.exec("BEGIN");
|
|
401
409
|
try {
|
|
402
410
|
db.prepare(`DELETE FROM session_events
|
|
403
411
|
WHERE account_id = ? AND session_id = ? AND machine_id = ?`).run(connection.accountId, message.sessionId, connection.machineId);
|
|
404
|
-
|
|
405
|
-
|
|
412
|
+
if (replacementRequestTurn) {
|
|
413
|
+
recordAliasesForRuntimeTurnIds({
|
|
414
|
+
accountId: connection.accountId,
|
|
415
|
+
sessionId: message.sessionId,
|
|
416
|
+
machineId: connection.machineId,
|
|
417
|
+
requestTurnId: replacementRequestTurn,
|
|
418
|
+
requestId: replacementRequestId,
|
|
419
|
+
runtimeTurnIds: [message.lastTurnId, message.currentHead, replacementBasis?.turnId],
|
|
420
|
+
recordTurnAlias,
|
|
421
|
+
});
|
|
422
|
+
}
|
|
406
423
|
clearPendingSessionHeadAdvances(db, connection.accountId, message.sessionId, connection.machineId);
|
|
407
424
|
for (const event of message.events) {
|
|
408
425
|
const result = db
|
|
@@ -449,6 +466,16 @@ export function handleMachineMessage(context, connection, message) {
|
|
|
449
466
|
encrypted_metadata = COALESCE(?, encrypted_metadata),
|
|
450
467
|
updated_at = ?
|
|
451
468
|
WHERE id = ? AND account_id = ? AND machine_id = ?`).run(message.status ?? null, message.currentHead ?? null, lastEvent ? `event:${lastEvent.id}` : sessionRow.current_head, message.lastTurnId ?? null, lastEvent?.turnId ?? sessionRow.last_turn_id, headBasisEvent?.id ?? null, headBasisEvent?.messageId ?? null, headBasisOrder?.time ?? null, headBasisOrder?.seq ?? null, message.encryptedMetadata ? JSON.stringify(message.encryptedMetadata) : null, ts, message.sessionId, connection.accountId, connection.machineId);
|
|
469
|
+
if (message.status && replacementRequestTurn) {
|
|
470
|
+
finishSessionClaim({
|
|
471
|
+
accountId: connection.accountId,
|
|
472
|
+
sessionId: message.sessionId,
|
|
473
|
+
...(replacementRequestId ? { requestId: replacementRequestId } : {}),
|
|
474
|
+
turnId: replacementRequestTurn,
|
|
475
|
+
terminalStatus: message.status,
|
|
476
|
+
finishedAt: ts,
|
|
477
|
+
});
|
|
478
|
+
}
|
|
452
479
|
db.exec("COMMIT");
|
|
453
480
|
}
|
|
454
481
|
catch (error) {
|
|
@@ -464,7 +491,7 @@ export function handleMachineMessage(context, connection, message) {
|
|
|
464
491
|
broadcastControllers(connection.accountId, {
|
|
465
492
|
type: "server:sessionTranscriptReplaced",
|
|
466
493
|
session,
|
|
467
|
-
events: inserted,
|
|
494
|
+
events: inserted.map((event) => canonicalEventForControllers(db, connection.accountId, event)),
|
|
468
495
|
hasMoreBefore: message.hasMoreBefore,
|
|
469
496
|
nextBefore: message.nextBefore,
|
|
470
497
|
});
|
|
@@ -540,6 +567,23 @@ export function handleMachineMessage(context, connection, message) {
|
|
|
540
567
|
}
|
|
541
568
|
if (message.type === "machine:sessionHeadAdvanced") {
|
|
542
569
|
const ts = now();
|
|
570
|
+
const sessionBefore = db
|
|
571
|
+
.prepare("SELECT * FROM sessions WHERE id = ? AND account_id = ? AND machine_id = ?")
|
|
572
|
+
.get(message.sessionId, connection.accountId, connection.machineId);
|
|
573
|
+
const activeClaim = sessionBefore
|
|
574
|
+
? activePromptClaim(db, connection.accountId, message.sessionId, connection.machineId)
|
|
575
|
+
: undefined;
|
|
576
|
+
if (sessionBefore?.status === "running" && activeClaim && message.status) {
|
|
577
|
+
recordAliasesForRuntimeTurnIds({
|
|
578
|
+
accountId: connection.accountId,
|
|
579
|
+
sessionId: message.sessionId,
|
|
580
|
+
machineId: connection.machineId,
|
|
581
|
+
requestTurnId: activeClaim.turn_id,
|
|
582
|
+
requestId: activeClaim.request_id,
|
|
583
|
+
runtimeTurnIds: [message.lastTurnId, message.currentHead, message.basis.turnId],
|
|
584
|
+
recordTurnAlias,
|
|
585
|
+
});
|
|
586
|
+
}
|
|
543
587
|
const input = {
|
|
544
588
|
accountId: connection.accountId,
|
|
545
589
|
sessionId: message.sessionId,
|
|
@@ -580,7 +624,22 @@ export function handleMachineMessage(context, connection, message) {
|
|
|
580
624
|
acknowledgeMachineMessage();
|
|
581
625
|
return;
|
|
582
626
|
}
|
|
583
|
-
|
|
627
|
+
if (message.status && activeClaim && sessionBefore?.status === "running") {
|
|
628
|
+
db.prepare(`UPDATE sessions
|
|
629
|
+
SET status = ?,
|
|
630
|
+
last_turn_id = COALESCE(?, last_turn_id),
|
|
631
|
+
updated_at = ?
|
|
632
|
+
WHERE id = ? AND account_id = ? AND machine_id = ? AND status = 'running'`).run(message.status, message.lastTurnId ?? message.currentHead ?? message.basis.turnId, ts, message.sessionId, connection.accountId, connection.machineId);
|
|
633
|
+
finishSessionClaim({
|
|
634
|
+
accountId: connection.accountId,
|
|
635
|
+
sessionId: message.sessionId,
|
|
636
|
+
requestId: activeClaim.request_id,
|
|
637
|
+
turnId: activeClaim.turn_id,
|
|
638
|
+
terminalStatus: message.status,
|
|
639
|
+
finishedAt: ts,
|
|
640
|
+
});
|
|
641
|
+
}
|
|
642
|
+
const row = db.prepare("SELECT * FROM sessions WHERE id = ?").get(message.sessionId);
|
|
584
643
|
if (row)
|
|
585
644
|
broadcastControllers(connection.accountId, { type: "server:session", session: sessionSnapshot(row) });
|
|
586
645
|
acknowledgeMachineMessage();
|
|
@@ -592,6 +651,17 @@ export function handleMachineMessage(context, connection, message) {
|
|
|
592
651
|
.get(message.sessionId, connection.accountId, connection.machineId);
|
|
593
652
|
if (!sessionRow)
|
|
594
653
|
return;
|
|
654
|
+
maybeAliasHistoricalRuntimeEventToActiveClaim({
|
|
655
|
+
db,
|
|
656
|
+
accountId: connection.accountId,
|
|
657
|
+
sessionId: message.sessionId,
|
|
658
|
+
machineId: connection.machineId,
|
|
659
|
+
session: sessionRow,
|
|
660
|
+
turnId: message.turnId,
|
|
661
|
+
messageId: message.messageId,
|
|
662
|
+
occurredAt: message.occurredAt,
|
|
663
|
+
recordTurnAlias,
|
|
664
|
+
});
|
|
595
665
|
const event = insertEvent({
|
|
596
666
|
accountId: connection.accountId,
|
|
597
667
|
sessionId: message.sessionId,
|
|
@@ -604,7 +674,7 @@ export function handleMachineMessage(context, connection, message) {
|
|
|
604
674
|
payload: message.payload,
|
|
605
675
|
});
|
|
606
676
|
const pendingSessionRow = applyPendingSessionHeadAdvances(db, connection.accountId, message.sessionId, connection.machineId, now());
|
|
607
|
-
broadcastControllers(connection.accountId, { type: "server:event", event });
|
|
677
|
+
broadcastControllers(connection.accountId, { type: "server:event", event: canonicalEventForControllers(db, connection.accountId, event) });
|
|
608
678
|
if (pendingSessionRow)
|
|
609
679
|
broadcastControllers(connection.accountId, { type: "server:session", session: sessionSnapshot(pendingSessionRow) });
|
|
610
680
|
acknowledgeMachineMessage();
|
|
@@ -903,4 +973,82 @@ function latestEventForTurn(db, accountId, sessionId, machineId, turnId) {
|
|
|
903
973
|
LIMIT 1`)
|
|
904
974
|
.get(accountId, sessionId, machineId, turnId);
|
|
905
975
|
}
|
|
976
|
+
function activePromptClaim(db, accountId, sessionId, machineId) {
|
|
977
|
+
return db
|
|
978
|
+
.prepare(`SELECT * FROM relay_session_claims
|
|
979
|
+
WHERE account_id = ? AND session_id = ? AND machine_id = ? AND state = 'active'
|
|
980
|
+
LIMIT 1`)
|
|
981
|
+
.get(accountId, sessionId, machineId);
|
|
982
|
+
}
|
|
983
|
+
function promptTurnForRequestId(db, accountId, sessionId, machineId, requestId) {
|
|
984
|
+
const claim = db
|
|
985
|
+
.prepare(`SELECT request_id, turn_id FROM relay_session_claims
|
|
986
|
+
WHERE account_id = ? AND session_id = ? AND machine_id = ? AND request_id = ? AND state = 'active'
|
|
987
|
+
LIMIT 1`)
|
|
988
|
+
.get(accountId, sessionId, machineId, requestId);
|
|
989
|
+
if (claim)
|
|
990
|
+
return claim;
|
|
991
|
+
return db
|
|
992
|
+
.prepare(`SELECT request_id, turn_id FROM relay_admissions
|
|
993
|
+
WHERE account_id = ? AND session_id = ? AND machine_id = ? AND request_id = ? AND kind = 'prompt' AND turn_id IS NOT NULL
|
|
994
|
+
LIMIT 1`)
|
|
995
|
+
.get(accountId, sessionId, machineId, requestId);
|
|
996
|
+
}
|
|
997
|
+
function maybeAliasHistoricalRuntimeEventToActiveClaim(input) {
|
|
998
|
+
if (input.session.status !== "running")
|
|
999
|
+
return;
|
|
1000
|
+
if (!isHistoricalRuntimeBackfillMessage(input.messageId, input.occurredAt))
|
|
1001
|
+
return;
|
|
1002
|
+
const claim = activePromptClaim(input.db, input.accountId, input.sessionId, input.machineId);
|
|
1003
|
+
if (!claim)
|
|
1004
|
+
return;
|
|
1005
|
+
recordAliasesForRuntimeTurnIds({
|
|
1006
|
+
accountId: input.accountId,
|
|
1007
|
+
sessionId: input.sessionId,
|
|
1008
|
+
machineId: input.machineId,
|
|
1009
|
+
requestTurnId: claim.turn_id,
|
|
1010
|
+
requestId: claim.request_id,
|
|
1011
|
+
runtimeTurnIds: [input.turnId],
|
|
1012
|
+
recordTurnAlias: input.recordTurnAlias,
|
|
1013
|
+
});
|
|
1014
|
+
}
|
|
1015
|
+
function isHistoricalRuntimeBackfillMessage(messageId, occurredAt) {
|
|
1016
|
+
if (messageId?.startsWith("hist_") || messageId?.startsWith("tail_"))
|
|
1017
|
+
return true;
|
|
1018
|
+
return occurredAt !== undefined;
|
|
1019
|
+
}
|
|
1020
|
+
function recordAliasesForRuntimeTurnIds(input) {
|
|
1021
|
+
for (const runtimeTurnId of input.runtimeTurnIds) {
|
|
1022
|
+
if (!isRuntimeTurnAliasCandidate(input.requestTurnId, runtimeTurnId))
|
|
1023
|
+
continue;
|
|
1024
|
+
input.recordTurnAlias({
|
|
1025
|
+
accountId: input.accountId,
|
|
1026
|
+
sessionId: input.sessionId,
|
|
1027
|
+
machineId: input.machineId,
|
|
1028
|
+
requestTurnId: input.requestTurnId,
|
|
1029
|
+
runtimeTurnId,
|
|
1030
|
+
requestId: input.requestId,
|
|
1031
|
+
});
|
|
1032
|
+
}
|
|
1033
|
+
}
|
|
1034
|
+
function isRuntimeTurnAliasCandidate(requestTurnId, runtimeTurnId) {
|
|
1035
|
+
if (!runtimeTurnId)
|
|
1036
|
+
return false;
|
|
1037
|
+
const value = runtimeTurnId.trim();
|
|
1038
|
+
if (!value || value === requestTurnId)
|
|
1039
|
+
return false;
|
|
1040
|
+
if (value.startsWith("event:"))
|
|
1041
|
+
return false;
|
|
1042
|
+
return true;
|
|
1043
|
+
}
|
|
1044
|
+
function canonicalEventForControllers(db, accountId, event) {
|
|
1045
|
+
const alias = db
|
|
1046
|
+
.prepare(`SELECT request_turn_id FROM session_turn_aliases
|
|
1047
|
+
WHERE account_id = ? AND session_id = ? AND machine_id = ? AND runtime_turn_id = ?
|
|
1048
|
+
LIMIT 1`)
|
|
1049
|
+
.get(accountId, event.sessionId, event.machineId, event.turnId);
|
|
1050
|
+
return alias && alias.request_turn_id !== event.turnId
|
|
1051
|
+
? { ...event, turnId: alias.request_turn_id }
|
|
1052
|
+
: event;
|
|
1053
|
+
}
|
|
906
1054
|
//# sourceMappingURL=machine-handlers.js.map
|