@agenr/skeln-plugin 2026.6.2 → 2026.6.3
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.
|
@@ -28,7 +28,7 @@ import {
|
|
|
28
28
|
parseExpiry,
|
|
29
29
|
parseRecallMode,
|
|
30
30
|
storeDurablesDetailed
|
|
31
|
-
} from "./chunk-
|
|
31
|
+
} from "./chunk-U74RE3L7.js";
|
|
32
32
|
import {
|
|
33
33
|
containsAgenrMemoryContext,
|
|
34
34
|
createSessionStartRepository,
|
|
@@ -768,6 +768,17 @@ function buildSessionEndSourceRef(source) {
|
|
|
768
768
|
return `${SESSION_END_SOURCE_REF_PREFIX}${source.trim()}`;
|
|
769
769
|
}
|
|
770
770
|
|
|
771
|
+
// src/adapters/shared/light-dream-trigger-deps.ts
|
|
772
|
+
function buildLightDreamTriggerDeps(services) {
|
|
773
|
+
return {
|
|
774
|
+
port: services.dreaming,
|
|
775
|
+
dbPath: services.config.dbPath,
|
|
776
|
+
config: services.agenrConfig,
|
|
777
|
+
embedding: services.embedding,
|
|
778
|
+
...services.claimExtraction ? { createClaimExtractionLlm: () => services.claimExtraction.llm } : {}
|
|
779
|
+
};
|
|
780
|
+
}
|
|
781
|
+
|
|
771
782
|
// src/app/dreaming/background-triggers.ts
|
|
772
783
|
var MINUTE_MS = 60 * 1e3;
|
|
773
784
|
async function maybeRunLightDream(input, deps) {
|
|
@@ -852,6 +863,36 @@ function hasEvidence(scan) {
|
|
|
852
863
|
return scan.episodesSinceLastRun > 0 || scan.ingestFilesSinceLastRun > 0 || scan.durablesCreatedSinceLastRun > 0;
|
|
853
864
|
}
|
|
854
865
|
|
|
866
|
+
// src/adapters/shared/post-session-light-dream.ts
|
|
867
|
+
async function runPostSessionLightDream(params) {
|
|
868
|
+
const contextSuffix = params.sessionContext ? ` for ${params.sessionContext}` : "";
|
|
869
|
+
try {
|
|
870
|
+
const result = await maybeRunLightDream({ trigger: "post_session" }, params.deps);
|
|
871
|
+
if (result.status === "ran") {
|
|
872
|
+
params.logger.info(`[agenr] ${params.scope} light dream completed${contextSuffix} run=${result.result.runId}`);
|
|
873
|
+
return;
|
|
874
|
+
}
|
|
875
|
+
if (result.reason === "run_in_progress" || result.reason === "episode_write_in_progress") {
|
|
876
|
+
params.logger.info(`[agenr] ${params.scope} light dream skipped${contextSuffix} reason=${result.reason}`);
|
|
877
|
+
return;
|
|
878
|
+
}
|
|
879
|
+
params.logger.debug?.(`[agenr] ${params.scope} light dream skipped${contextSuffix} reason=${result.reason}`);
|
|
880
|
+
} catch (error) {
|
|
881
|
+
params.logger.warn(`[agenr] ${params.scope} light dream failed${contextSuffix}: ${formatErrorMessage(error)}`);
|
|
882
|
+
}
|
|
883
|
+
}
|
|
884
|
+
|
|
885
|
+
// src/adapters/shared/guarded-post-session-episode-capture.ts
|
|
886
|
+
async function runGuardedPostSessionEpisodeCapture(params) {
|
|
887
|
+
await withEpisodeWriteGuard({ port: params.services.dreaming, dbPath: params.services.config.dbPath }, params.writeEpisode);
|
|
888
|
+
await runPostSessionLightDream({
|
|
889
|
+
deps: buildLightDreamTriggerDeps(params.services),
|
|
890
|
+
logger: params.logger,
|
|
891
|
+
scope: params.scope,
|
|
892
|
+
sessionContext: params.sessionContext
|
|
893
|
+
});
|
|
894
|
+
}
|
|
895
|
+
|
|
855
896
|
// src/adapters/plugin-runtime/claim-extraction.ts
|
|
856
897
|
async function buildClaimExtractionRuntime(config, resolveLlm) {
|
|
857
898
|
const claimExtractionConfig = resolveClaimExtractionConfig(config);
|
|
@@ -2042,6 +2083,12 @@ async function createHostMemoryServices(featureFlags, options = {}) {
|
|
|
2042
2083
|
};
|
|
2043
2084
|
}
|
|
2044
2085
|
|
|
2086
|
+
// src/adapters/shared/shutdown-episode-threshold.ts
|
|
2087
|
+
var HOST_SHUTDOWN_EPISODE_ACTIVITY_THRESHOLD = {
|
|
2088
|
+
minMaterialTurns: 8,
|
|
2089
|
+
minDurationMs: 20 * 60 * 1e3
|
|
2090
|
+
};
|
|
2091
|
+
|
|
2045
2092
|
// src/adapters/shared/bounded-episode-embedding.ts
|
|
2046
2093
|
var EPISODE_EMBEDDING_RACE_TIMEOUT = /* @__PURE__ */ Symbol("episode-embedding-race-timeout");
|
|
2047
2094
|
var EPISODE_EMBEDDING_MIN_HEADROOM_MS = 5e3;
|
|
@@ -2982,6 +3029,7 @@ export {
|
|
|
2982
3029
|
isPluginEpisodeWriteEnabled,
|
|
2983
3030
|
resolveAgenrFeatureFlags,
|
|
2984
3031
|
resolveCompactionPromptContext,
|
|
3032
|
+
HOST_SHUTDOWN_EPISODE_ACTIVITY_THRESHOLD,
|
|
2985
3033
|
embedEpisodeSummaryWithinBudget,
|
|
2986
3034
|
EPISODE_SUMMARY_TIMEOUT_MS,
|
|
2987
3035
|
writeBoundedSingleTranscriptEpisode,
|
|
@@ -2989,7 +3037,9 @@ export {
|
|
|
2989
3037
|
buildSessionFileSourceRef,
|
|
2990
3038
|
buildCompactionSourceRef,
|
|
2991
3039
|
buildSessionEndSourceRef,
|
|
3040
|
+
buildLightDreamTriggerDeps,
|
|
2992
3041
|
maybeRunLightDream,
|
|
3042
|
+
runGuardedPostSessionEpisodeCapture,
|
|
2993
3043
|
buildClaimExtractionRuntime,
|
|
2994
3044
|
createClaimExtractionFromAgenrConfig,
|
|
2995
3045
|
createEmbedQuery,
|
|
@@ -343,64 +343,6 @@ function sanitizeFetchToolParams(params) {
|
|
|
343
343
|
};
|
|
344
344
|
}
|
|
345
345
|
|
|
346
|
-
// src/app/episode-ingest/activity-threshold.ts
|
|
347
|
-
function resolveEpisodeActivityEligibility(materialTurns, startedAt, endedAt, threshold) {
|
|
348
|
-
const durationMs = resolveTranscriptDurationMs(startedAt, endedAt);
|
|
349
|
-
if (materialTurns >= threshold.minMaterialTurns || durationMs >= threshold.minDurationMs) {
|
|
350
|
-
return {
|
|
351
|
-
eligible: true,
|
|
352
|
-
materialTurns,
|
|
353
|
-
durationMs
|
|
354
|
-
};
|
|
355
|
-
}
|
|
356
|
-
return {
|
|
357
|
-
eligible: false,
|
|
358
|
-
reason: "below_activity_threshold",
|
|
359
|
-
materialTurns,
|
|
360
|
-
durationMs
|
|
361
|
-
};
|
|
362
|
-
}
|
|
363
|
-
function resolveTranscriptDurationMs(startedAt, endedAt) {
|
|
364
|
-
if (!startedAt || !endedAt) {
|
|
365
|
-
return 0;
|
|
366
|
-
}
|
|
367
|
-
const started = Date.parse(startedAt);
|
|
368
|
-
const ended = Date.parse(endedAt);
|
|
369
|
-
return Number.isFinite(started) && Number.isFinite(ended) && ended > started ? ended - started : 0;
|
|
370
|
-
}
|
|
371
|
-
|
|
372
|
-
// src/core/episode/transcript-render.ts
|
|
373
|
-
var MIN_EPISODE_MESSAGES = 4;
|
|
374
|
-
var MAX_EPISODE_TRANSCRIPT_CHARS = 14e3;
|
|
375
|
-
function countMaterialTranscriptTurns(messages) {
|
|
376
|
-
return messages.filter((message) => message.text.trim().length > 0).length;
|
|
377
|
-
}
|
|
378
|
-
function renderTranscript(messages) {
|
|
379
|
-
return messages.map((message) => `${message.role === "user" ? "User" : "Assistant"}: ${message.text.trim()}`).join("\n");
|
|
380
|
-
}
|
|
381
|
-
function capEpisodeTranscript(transcript, maxChars) {
|
|
382
|
-
if (transcript.length <= maxChars) {
|
|
383
|
-
return transcript;
|
|
384
|
-
}
|
|
385
|
-
const omissionMarker = "\n\n[Earlier middle transcript omitted for brevity]\n\n";
|
|
386
|
-
const headBudget = Math.max(0, Math.floor((maxChars - omissionMarker.length) * 0.35));
|
|
387
|
-
const tailBudget = Math.max(0, maxChars - omissionMarker.length - headBudget);
|
|
388
|
-
const head = trimToBoundary(transcript.slice(0, headBudget), false);
|
|
389
|
-
const tail = trimToBoundary(transcript.slice(-tailBudget), true);
|
|
390
|
-
return `${head}${omissionMarker}${tail}`.trim();
|
|
391
|
-
}
|
|
392
|
-
function trimToBoundary(value, fromStart) {
|
|
393
|
-
if (value.length === 0) {
|
|
394
|
-
return value;
|
|
395
|
-
}
|
|
396
|
-
if (fromStart) {
|
|
397
|
-
const boundary = value.search(/\s/u);
|
|
398
|
-
return boundary >= 0 ? value.slice(boundary).trimStart() : value.trim();
|
|
399
|
-
}
|
|
400
|
-
const reversedBoundary = value.trimEnd().search(/\s\S*$/u);
|
|
401
|
-
return reversedBoundary >= 0 ? value.slice(0, reversedBoundary).trimEnd() : value.trim();
|
|
402
|
-
}
|
|
403
|
-
|
|
404
346
|
// src/app/episode-ingest/single-transcript.ts
|
|
405
347
|
function createSingleTranscriptDiscoveryPort(filePath) {
|
|
406
348
|
return {
|
|
@@ -693,6 +635,66 @@ async function generateEpisodeSummary(transcript, llm) {
|
|
|
693
635
|
|
|
694
636
|
// src/app/episode-ingest/service/preflight.ts
|
|
695
637
|
import path from "path";
|
|
638
|
+
|
|
639
|
+
// src/app/episode-ingest/activity-threshold.ts
|
|
640
|
+
function resolveEpisodeActivityEligibility(materialTurns, startedAt, endedAt, threshold) {
|
|
641
|
+
const durationMs = resolveTranscriptDurationMs(startedAt, endedAt);
|
|
642
|
+
if (materialTurns >= threshold.minMaterialTurns || durationMs >= threshold.minDurationMs) {
|
|
643
|
+
return {
|
|
644
|
+
eligible: true,
|
|
645
|
+
materialTurns,
|
|
646
|
+
durationMs
|
|
647
|
+
};
|
|
648
|
+
}
|
|
649
|
+
return {
|
|
650
|
+
eligible: false,
|
|
651
|
+
reason: "below_activity_threshold",
|
|
652
|
+
materialTurns,
|
|
653
|
+
durationMs
|
|
654
|
+
};
|
|
655
|
+
}
|
|
656
|
+
function resolveTranscriptDurationMs(startedAt, endedAt) {
|
|
657
|
+
if (!startedAt || !endedAt) {
|
|
658
|
+
return 0;
|
|
659
|
+
}
|
|
660
|
+
const started = Date.parse(startedAt);
|
|
661
|
+
const ended = Date.parse(endedAt);
|
|
662
|
+
return Number.isFinite(started) && Number.isFinite(ended) && ended > started ? ended - started : 0;
|
|
663
|
+
}
|
|
664
|
+
|
|
665
|
+
// src/core/episode/transcript-render.ts
|
|
666
|
+
var MIN_EPISODE_MESSAGES = 4;
|
|
667
|
+
var MAX_EPISODE_TRANSCRIPT_CHARS = 14e3;
|
|
668
|
+
function countMaterialTranscriptTurns(messages) {
|
|
669
|
+
return messages.filter((message) => message.text.trim().length > 0).length;
|
|
670
|
+
}
|
|
671
|
+
function renderTranscript(messages) {
|
|
672
|
+
return messages.map((message) => `${message.role === "user" ? "User" : "Assistant"}: ${message.text.trim()}`).join("\n");
|
|
673
|
+
}
|
|
674
|
+
function capEpisodeTranscript(transcript, maxChars) {
|
|
675
|
+
if (transcript.length <= maxChars) {
|
|
676
|
+
return transcript;
|
|
677
|
+
}
|
|
678
|
+
const omissionMarker = "\n\n[Earlier middle transcript omitted for brevity]\n\n";
|
|
679
|
+
const headBudget = Math.max(0, Math.floor((maxChars - omissionMarker.length) * 0.35));
|
|
680
|
+
const tailBudget = Math.max(0, maxChars - omissionMarker.length - headBudget);
|
|
681
|
+
const head = trimToBoundary(transcript.slice(0, headBudget), false);
|
|
682
|
+
const tail = trimToBoundary(transcript.slice(-tailBudget), true);
|
|
683
|
+
return `${head}${omissionMarker}${tail}`.trim();
|
|
684
|
+
}
|
|
685
|
+
function trimToBoundary(value, fromStart) {
|
|
686
|
+
if (value.length === 0) {
|
|
687
|
+
return value;
|
|
688
|
+
}
|
|
689
|
+
if (fromStart) {
|
|
690
|
+
const boundary = value.search(/\s/u);
|
|
691
|
+
return boundary >= 0 ? value.slice(boundary).trimStart() : value.trim();
|
|
692
|
+
}
|
|
693
|
+
const reversedBoundary = value.trimEnd().search(/\s\S*$/u);
|
|
694
|
+
return reversedBoundary >= 0 ? value.slice(0, reversedBoundary).trimEnd() : value.trim();
|
|
695
|
+
}
|
|
696
|
+
|
|
697
|
+
// src/app/episode-ingest/service/preflight.ts
|
|
696
698
|
var ACTIVE_SESSION_WINDOW_MS = 5 * 60 * 1e3;
|
|
697
699
|
async function prepareEpisodeIngest(targetPath, ports, options = {}) {
|
|
698
700
|
const files = await ports.files.discoverFiles(targetPath);
|
package/dist/index.js
CHANGED
|
@@ -6,10 +6,12 @@ import {
|
|
|
6
6
|
import {
|
|
7
7
|
EPISODE_SUMMARY_TIMEOUT_MS,
|
|
8
8
|
FETCH_TOOL_PARAMETERS,
|
|
9
|
+
HOST_SHUTDOWN_EPISODE_ACTIVITY_THRESHOLD,
|
|
9
10
|
RECALL_TOOL_PARAMETERS,
|
|
10
11
|
STORE_TOOL_PARAMETERS,
|
|
11
12
|
UPDATE_TOOL_PARAMETERS,
|
|
12
13
|
buildCompactionSourceRef,
|
|
14
|
+
buildLightDreamTriggerDeps,
|
|
13
15
|
buildRecallToolServices,
|
|
14
16
|
buildSessionFileSourceRef,
|
|
15
17
|
composeHostPluginServices,
|
|
@@ -42,12 +44,13 @@ import {
|
|
|
42
44
|
resolveWorkingContextGate,
|
|
43
45
|
routeSessionMemoryTriggerSafely,
|
|
44
46
|
runFetchMemoryTool,
|
|
47
|
+
runGuardedPostSessionEpisodeCapture,
|
|
45
48
|
runRecallMemoryTool,
|
|
46
49
|
runStoreMemoryTool,
|
|
47
50
|
runUpdateMemoryTool,
|
|
48
51
|
scheduleGuardedEpisodeWrite,
|
|
49
52
|
writeBoundedSingleTranscriptEpisode
|
|
50
|
-
} from "./chunk-
|
|
53
|
+
} from "./chunk-SIY3JA7T.js";
|
|
51
54
|
import "./chunk-OJSIZDZD.js";
|
|
52
55
|
import {
|
|
53
56
|
WORKING_CANDIDATE_PROMOTION_STATUSES,
|
|
@@ -68,7 +71,7 @@ import {
|
|
|
68
71
|
formatTargetSelector,
|
|
69
72
|
sanitizeFetchToolParams,
|
|
70
73
|
sanitizeUpdateToolParams
|
|
71
|
-
} from "./chunk-
|
|
74
|
+
} from "./chunk-U74RE3L7.js";
|
|
72
75
|
import {
|
|
73
76
|
formatAgenrBeforeTurnRecall,
|
|
74
77
|
runBeforeTurn,
|
|
@@ -81,9 +84,7 @@ import {
|
|
|
81
84
|
resolveModel
|
|
82
85
|
} from "./chunk-5TIP2EPP.js";
|
|
83
86
|
import "./chunk-GAERET5Q.js";
|
|
84
|
-
import
|
|
85
|
-
withEpisodeWriteGuard
|
|
86
|
-
} from "./chunk-SOQW7356.js";
|
|
87
|
+
import "./chunk-SOQW7356.js";
|
|
87
88
|
import {
|
|
88
89
|
isRecord,
|
|
89
90
|
readOptionalFiniteNumber,
|
|
@@ -614,10 +615,6 @@ function resolveSessionFile(context) {
|
|
|
614
615
|
|
|
615
616
|
// src/adapters/skeln/episode/episode-writer.ts
|
|
616
617
|
var SKELN_EPISODE_GENERATOR_VERSION = "skeln-episodic-summary-v1";
|
|
617
|
-
var SKELN_PHASE4_SHUTDOWN_EPISODE_ACTIVITY_THRESHOLD = {
|
|
618
|
-
minMaterialTurns: 8,
|
|
619
|
-
minDurationMs: 20 * 60 * 1e3
|
|
620
|
-
};
|
|
621
618
|
async function writeSkelnShutdownEpisode(params) {
|
|
622
619
|
await writeSkelnBoundedSessionEpisode({
|
|
623
620
|
target: params.target,
|
|
@@ -625,7 +622,7 @@ async function writeSkelnShutdownEpisode(params) {
|
|
|
625
622
|
logger: params.logger,
|
|
626
623
|
actionLabel: "skeln shutdown episode write",
|
|
627
624
|
genVersion: SKELN_EPISODE_GENERATOR_VERSION,
|
|
628
|
-
activityThreshold:
|
|
625
|
+
activityThreshold: HOST_SHUTDOWN_EPISODE_ACTIVITY_THRESHOLD,
|
|
629
626
|
buildSourceRef: (sessionFile) => sessionFile,
|
|
630
627
|
logContext: `session=${params.target.sessionId} key=skeln:${params.target.sessionId}`,
|
|
631
628
|
skipDetails: `session=${params.target.sessionId}`
|
|
@@ -1114,7 +1111,7 @@ function buildSkelnSessionShutdownEpisodeWork(params) {
|
|
|
1114
1111
|
}
|
|
1115
1112
|
function scheduleSkelnSessionShutdownEpisodeWrite(params) {
|
|
1116
1113
|
const work = buildSkelnSessionShutdownEpisodeWork(params);
|
|
1117
|
-
if (params.event.
|
|
1114
|
+
if (params.event.deferWork) {
|
|
1118
1115
|
params.event.deferWork(work);
|
|
1119
1116
|
return Promise.resolve();
|
|
1120
1117
|
}
|
|
@@ -1140,30 +1137,12 @@ async function writeScopedSkelnShutdownEpisode(servicesPromise, target, logger)
|
|
|
1140
1137
|
if (!isPluginEpisodeWriteEnabled(services.skelnConfig.memoryPolicy)) {
|
|
1141
1138
|
return;
|
|
1142
1139
|
}
|
|
1143
|
-
await
|
|
1144
|
-
|
|
1145
|
-
}
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
const result = await maybeRunLightDream(
|
|
1150
|
-
{ trigger: "post_session" },
|
|
1151
|
-
{
|
|
1152
|
-
port: services.dreaming,
|
|
1153
|
-
dbPath: services.config.dbPath,
|
|
1154
|
-
config: services.agenrConfig,
|
|
1155
|
-
embedding: services.embedding,
|
|
1156
|
-
...services.claimExtraction ? { createClaimExtractionLlm: () => services.claimExtraction.llm } : {}
|
|
1157
|
-
}
|
|
1158
|
-
);
|
|
1159
|
-
if (result.status === "ran") {
|
|
1160
|
-
log.info(`[agenr] skeln shutdown light dream completed run=${result.result.runId}`);
|
|
1161
|
-
} else if (result.reason === "run_in_progress" || result.reason === "episode_write_in_progress") {
|
|
1162
|
-
log.info(`[agenr] skeln shutdown light dream skipped reason=${result.reason}`);
|
|
1163
|
-
}
|
|
1164
|
-
} catch (error) {
|
|
1165
|
-
log.warn(`[agenr] skeln shutdown light dream failed: ${formatErrorMessage(error)}`);
|
|
1166
|
-
}
|
|
1140
|
+
await runGuardedPostSessionEpisodeCapture({
|
|
1141
|
+
services,
|
|
1142
|
+
writeEpisode: () => writeSkelnShutdownEpisode({ target, services, logger }),
|
|
1143
|
+
logger: logger ?? console,
|
|
1144
|
+
scope: "skeln shutdown"
|
|
1145
|
+
});
|
|
1167
1146
|
}
|
|
1168
1147
|
|
|
1169
1148
|
// src/app/features/capabilities.ts
|
|
@@ -1644,16 +1623,7 @@ function triggerSkelnImportanceLightDream(services, status) {
|
|
|
1644
1623
|
if (status !== "stored") {
|
|
1645
1624
|
return;
|
|
1646
1625
|
}
|
|
1647
|
-
void maybeRunLightDream(
|
|
1648
|
-
{ trigger: "importance" },
|
|
1649
|
-
{
|
|
1650
|
-
port: services.dreaming,
|
|
1651
|
-
dbPath: services.config.dbPath,
|
|
1652
|
-
config: services.agenrConfig,
|
|
1653
|
-
embedding: services.embedding,
|
|
1654
|
-
...services.claimExtraction ? { createClaimExtractionLlm: () => services.claimExtraction.llm } : {}
|
|
1655
|
-
}
|
|
1656
|
-
).then((result) => {
|
|
1626
|
+
void maybeRunLightDream({ trigger: "importance" }, buildLightDreamTriggerDeps(services)).then((result) => {
|
|
1657
1627
|
if (result.status === "ran") {
|
|
1658
1628
|
console.info(`[agenr] skeln importance light dream completed run=${result.result.runId}`);
|
|
1659
1629
|
} else if (result.reason === "run_in_progress" || result.reason === "episode_write_in_progress") {
|