cogmem 3.7.1 → 3.7.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.
Files changed (87) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/MEMORY_ATLAS.md +2 -2
  3. package/MEMORY_MODEL.md +1 -1
  4. package/README.md +6 -5
  5. package/RELEASE_CHECKLIST.md +5 -5
  6. package/dist/atlas/MemoryAtlasService.d.ts +1 -0
  7. package/dist/atlas/MemoryAtlasService.js +36 -4
  8. package/dist/atlas/MemoryAtlasTypes.d.ts +7 -0
  9. package/dist/belief/BeliefStore.d.ts +3 -1
  10. package/dist/belief/BeliefStore.js +10 -2
  11. package/dist/bin/episode.js +107 -16
  12. package/dist/bin/import-support.js +28 -11
  13. package/dist/config/CogmemConfig.d.ts +1 -0
  14. package/dist/config/CogmemConfig.js +45 -0
  15. package/dist/core/MemoryGraph.js +25 -8
  16. package/dist/dream/DreamScheduler.d.ts +6 -1
  17. package/dist/dream/DreamScheduler.js +36 -6
  18. package/dist/engine/CognitiveGraphCompiler.js +1 -1
  19. package/dist/engine/ConsolidationPipeline.js +4 -4
  20. package/dist/engine/DeepWritePromotionPolicy.d.ts +2 -0
  21. package/dist/engine/DeepWritePromotionPolicy.js +25 -4
  22. package/dist/engine/DreamCuratorWorker.d.ts +3 -0
  23. package/dist/engine/DreamCuratorWorker.js +18 -3
  24. package/dist/engine/FactCompiler.js +2 -2
  25. package/dist/entity/EntityGovernanceService.js +1 -1
  26. package/dist/episode/EpisodeActiveScopeGuard.d.ts +3 -0
  27. package/dist/episode/EpisodeActiveScopeGuard.js +46 -0
  28. package/dist/episode/EpisodeAssembler.d.ts +20 -2
  29. package/dist/episode/EpisodeAssembler.js +458 -98
  30. package/dist/episode/EpisodeBoundaryAuditService.d.ts +70 -0
  31. package/dist/episode/EpisodeBoundaryAuditService.js +276 -0
  32. package/dist/episode/EpisodeBoundaryPolicy.d.ts +75 -0
  33. package/dist/episode/EpisodeBoundaryPolicy.js +189 -0
  34. package/dist/episode/EpisodeBoundaryReplayEngine.d.ts +65 -0
  35. package/dist/episode/EpisodeBoundaryReplayEngine.js +272 -0
  36. package/dist/episode/EpisodeImportIdentity.d.ts +1 -0
  37. package/dist/episode/EpisodeImportIdentity.js +1 -0
  38. package/dist/episode/EpisodeInvariantValidator.d.ts +16 -0
  39. package/dist/episode/EpisodeInvariantValidator.js +99 -0
  40. package/dist/episode/EpisodeSplitPlanner.d.ts +89 -0
  41. package/dist/episode/EpisodeSplitPlanner.js +225 -0
  42. package/dist/episode/EpisodeStore.d.ts +67 -2
  43. package/dist/episode/EpisodeStore.js +443 -59
  44. package/dist/episode/EpisodeTypes.d.ts +2 -2
  45. package/dist/episode/TurnRelationClassifier.d.ts +9 -0
  46. package/dist/episode/TurnRelationClassifier.js +42 -12
  47. package/dist/episode/index.d.ts +3 -0
  48. package/dist/episode/index.js +3 -0
  49. package/dist/factory.d.ts +62 -3
  50. package/dist/factory.js +308 -58
  51. package/dist/mcp/CoreMcpTools.js +103 -8
  52. package/dist/mcp/server.js +1 -1
  53. package/dist/migrations/0028_episode_boundary_guardrails.d.ts +3 -0
  54. package/dist/migrations/0028_episode_boundary_guardrails.js +47 -0
  55. package/dist/migrations/0029_episode_active_scope_guard.d.ts +3 -0
  56. package/dist/migrations/0029_episode_active_scope_guard.js +16 -0
  57. package/dist/migrations/0030_memory_event_local_date_source.d.ts +3 -0
  58. package/dist/migrations/0030_memory_event_local_date_source.js +111 -0
  59. package/dist/migrations/0031_episode_boundary_integrity_repair.d.ts +7 -0
  60. package/dist/migrations/0031_episode_boundary_integrity_repair.js +124 -0
  61. package/dist/migrations/SchemaMigrationRunner.d.ts +2 -0
  62. package/dist/migrations/SchemaMigrationRunner.js +46 -15
  63. package/dist/migrations/index.d.ts +6 -1
  64. package/dist/migrations/index.js +15 -1
  65. package/dist/public.d.ts +1 -1
  66. package/dist/public.js +1 -1
  67. package/dist/recall/BrainRecall.js +1 -1
  68. package/dist/store/DeepWriteCandidateStore.d.ts +21 -3
  69. package/dist/store/DeepWriteCandidateStore.js +118 -11
  70. package/dist/store/EntityStore.d.ts +4 -0
  71. package/dist/store/EntityStore.js +24 -12
  72. package/dist/store/EventStore.d.ts +7 -2
  73. package/dist/store/EventStore.js +144 -23
  74. package/dist/store/FactStore.js +6 -5
  75. package/dist/store/MemoryAtlasStore.d.ts +1 -0
  76. package/dist/store/MemoryAtlasStore.js +54 -0
  77. package/dist/types/ExtensionPoints.d.ts +3 -1
  78. package/dist/types/index.d.ts +1 -0
  79. package/examples/hermes-backend/AGENTS.md +1 -1
  80. package/examples/hermes-backend/README.md +1 -1
  81. package/examples/hermes-backend/SKILL.md +2 -2
  82. package/examples/hermes-backend/references/operations.md +2 -2
  83. package/examples/openclaw-backend/AGENTS.md +1 -1
  84. package/examples/openclaw-backend/README.md +1 -1
  85. package/examples/openclaw-backend/SKILL.md +2 -2
  86. package/examples/openclaw-backend/references/operations.md +2 -2
  87. package/package.json +1 -1
@@ -0,0 +1,225 @@
1
+ import { createHash } from 'node:crypto';
2
+ import { normalizeEpisodeBoundaryConfig, resolveTrustedLocalDate } from './EpisodeBoundaryPolicy.js';
3
+ import { replayEpisodeBoundaries } from './EpisodeBoundaryReplayEngine.js';
4
+ import { validateEpisodeInvariants } from './EpisodeInvariantValidator.js';
5
+ export const EPISODE_SPLIT_PLANNER_VERSION = 'episode_split_preview.v1';
6
+ export class EpisodeSplitPlanner {
7
+ store;
8
+ resolveEvent;
9
+ liveBoundaryConfig;
10
+ liveConfigDiagnostics;
11
+ constructor(store, resolveEvent, liveBoundaryConfig = {}, liveConfigDiagnostics = []) {
12
+ this.store = store;
13
+ this.resolveEvent = resolveEvent;
14
+ this.liveBoundaryConfig = liveBoundaryConfig;
15
+ this.liveConfigDiagnostics = liveConfigDiagnostics;
16
+ }
17
+ plan(options) {
18
+ const episode = this.store.getEpisode(options.episodeId);
19
+ if (!episode || episode.projectId !== options.projectId)
20
+ throw new Error(`episode_project_mismatch:${options.episodeId}`);
21
+ const links = this.store.listEventLinks(options.episodeId);
22
+ const pairs = links.map((link) => ({ link, event: this.resolveEvent?.(link.eventId) || undefined }));
23
+ const events = pairs.map((item) => item.event).filter((event) => Boolean(event));
24
+ const missingRawEventIds = pairs.filter((item) => !item.event).map((item) => item.link.eventId);
25
+ const overrideWarnings = boundaryOverrideWarnings(options);
26
+ const normalized = normalizeEpisodeBoundaryConfig(configWithDefinedOverrides(this.liveBoundaryConfig, options));
27
+ const policy = {
28
+ enabled: normalized.config.enabled,
29
+ maxEvents: normalized.config.maxEvents,
30
+ maxDurationMs: normalized.config.maxDurationMs,
31
+ maxIdleGapMs: normalized.config.maxIdleGapMs,
32
+ splitOnTrustedLocalDateChange: normalized.config.splitOnTrustedLocalDateChange,
33
+ mode: normalized.config.mode,
34
+ applyToLive: normalized.config.applyToLive,
35
+ applyToImports: normalized.config.applyToImports,
36
+ policyVersion: normalized.config.policyVersion,
37
+ timezone: normalized.config.timezone,
38
+ };
39
+ const warnings = [...this.liveConfigDiagnostics.map((item) => item.code).filter((code) => code.startsWith('invalid_episode_boundary_')), ...overrideWarnings, ...normalized.diagnostics.map((item) => item.code)];
40
+ if (missingRawEventIds.length)
41
+ warnings.push('unresolved_raw_events');
42
+ if (events[0] && events[0].role !== 'user')
43
+ warnings.push('leading_non_user_event');
44
+ const userCount = events.filter((event) => event.role === 'user').length;
45
+ if (userCount === 0)
46
+ warnings.push('no_user_event_episode');
47
+ const replay = replayEpisodeBoundaries({ episode, pairs, config: normalized.config });
48
+ warnings.push(...replay.warnings, ...replay.structuralAnomalies);
49
+ const invariantViolations = validateEpisodeInvariants({
50
+ episode, pairs, timezone: normalized.config.timezone,
51
+ closureReceipts: this.store.listClosureReceipts({ episodeId: episode.episodeId, limit: 1 }),
52
+ dreamJobState: this.store.getDreamJobState(episode.episodeId),
53
+ });
54
+ warnings.push(...invariantViolations.map((violation) => violation.reason));
55
+ const proposedBoundaries = replay.detectedBoundaries.map((boundary) => ({
56
+ boundaryIndex: boundary.boundaryIndex,
57
+ beforeEventId: boundary.beforeEventId,
58
+ afterEventId: boundary.afterEventId,
59
+ primaryUserEventId: boundary.primaryUserEventId,
60
+ reason: boundary.reason,
61
+ relation: boundary.relation,
62
+ effective: boundary.effective,
63
+ disposition: boundary.disposition,
64
+ }));
65
+ const segments = segmentsFromBoundaries(pairs, replay.effectiveBoundaries, options.includeEventIds === true);
66
+ const fingerprint = sourceFingerprint(pairs, episode.startedAt, episode.status);
67
+ const canonicalSegments = segments.map((item) => ({
68
+ segmentIndex: item.segmentIndex,
69
+ eventIdsHash: item.eventIdsHash,
70
+ startEventId: item.startEventId,
71
+ endEventId: item.endEventId,
72
+ eventCount: item.eventCount,
73
+ reason: item.reason,
74
+ }));
75
+ const policyFingerprint = createHash('sha256').update(JSON.stringify(policy)).digest('hex');
76
+ const hash = createHash('sha256').update(JSON.stringify([
77
+ options.projectId,
78
+ options.episodeId,
79
+ fingerprint,
80
+ policyFingerprint,
81
+ policy,
82
+ canonicalSegments,
83
+ proposedBoundaries,
84
+ ])).digest('hex');
85
+ return {
86
+ planId: `episode-split-plan-${hash.slice(0, 24)}`,
87
+ plannerVersion: EPISODE_SPLIT_PLANNER_VERSION,
88
+ projectId: options.projectId,
89
+ episodeId: options.episodeId,
90
+ sourceFingerprint: fingerprint,
91
+ policyFingerprint,
92
+ normalizedPolicy: policy,
93
+ proposedBoundaries,
94
+ impactInventory: impactInventory(pairs, policy.timezone),
95
+ segments,
96
+ warnings: [...new Set(warnings)].sort(),
97
+ unresolvedEventCount: missingRawEventIds.length,
98
+ missingRawEventIds: missingRawEventIds.slice(0, 50),
99
+ evidenceIntegrityStatus: missingRawEventIds.length ? 'missing_raw_events' : 'ok',
100
+ requiresManualReview: userCount === 0 || missingRawEventIds.length > 0 || replay.structuralAnomalies.length > 0 || replay.warnings.includes('invalid_trusted_local_date') || invariantViolations.some((violation) => violation.requiresManualReview),
101
+ applyableInCurrentVersion: false,
102
+ applyCommand: null,
103
+ };
104
+ }
105
+ }
106
+ const MAX_RETURNED_EVENT_IDS = 500;
107
+ function segment(index, pairs, reason, includeEventIds) {
108
+ const eventIds = pairs.map((item) => item.link.eventId);
109
+ const returned = includeEventIds && eventIds.length <= MAX_RETURNED_EVENT_IDS ? eventIds : undefined;
110
+ const times = pairs.map((item) => item.event?.occurredAt).filter((value) => typeof value === 'number' && Number.isFinite(value));
111
+ const range = timeRange(times);
112
+ const counts = roleCounts(pairs);
113
+ return {
114
+ segmentIndex: index,
115
+ eventIds: returned,
116
+ eventIdsHash: createHash('sha256').update(JSON.stringify(eventIds)).digest('hex'),
117
+ eventIdsOmitted: returned ? 0 : eventIds.length,
118
+ startEventId: eventIds[0],
119
+ endEventId: eventIds.at(-1),
120
+ eventCount: eventIds.length,
121
+ reason,
122
+ startedAt: range?.min,
123
+ endedAt: range?.max,
124
+ ...counts,
125
+ };
126
+ }
127
+ function sourceFingerprint(pairs, startedAt, status) {
128
+ const hash = createHash('sha256');
129
+ hash.update(JSON.stringify([startedAt, status]));
130
+ for (const { link, event } of pairs) {
131
+ hash.update(JSON.stringify([
132
+ link.eventId,
133
+ link.position,
134
+ link.relation,
135
+ event?.role,
136
+ event?.turnId,
137
+ event?.turnSeq,
138
+ event?.eventOrdinal,
139
+ event?.occurredAt,
140
+ event?.localDate,
141
+ event?.localDateSource,
142
+ isImportedEvent(event),
143
+ event?.contentHash,
144
+ ]));
145
+ }
146
+ return hash.digest('hex');
147
+ }
148
+ function timeRange(values) {
149
+ let min;
150
+ let max;
151
+ for (const value of values) {
152
+ min = min === undefined ? value : Math.min(min, value);
153
+ max = max === undefined ? value : Math.max(max, value);
154
+ }
155
+ return min === undefined || max === undefined ? undefined : { min, max };
156
+ }
157
+ function trustedLocalDate(event, timezone) {
158
+ return resolveTrustedLocalDate(event, timezone).date;
159
+ }
160
+ function roleCounts(pairs) {
161
+ return {
162
+ userEventCount: pairs.filter((item) => item.event?.role === 'user').length,
163
+ assistantEventCount: pairs.filter((item) => item.event?.role === 'assistant' || item.event?.role === 'agent').length,
164
+ toolEventCount: pairs.filter((item) => item.event?.role === 'tool').length,
165
+ systemEventCount: pairs.filter((item) => item.event?.role === 'system').length,
166
+ };
167
+ }
168
+ function segmentsFromBoundaries(pairs, boundaries, includeEventIds) {
169
+ const segments = [];
170
+ let start = 0;
171
+ for (const boundary of boundaries) {
172
+ const nextIndex = boundary.afterEventId ? pairs.findIndex((pair) => pair.link.eventId === boundary.afterEventId) : -1;
173
+ if (nextIndex <= start)
174
+ continue;
175
+ segments.push(segment(segments.length, pairs.slice(start, nextIndex), boundary.reason, includeEventIds));
176
+ start = nextIndex;
177
+ }
178
+ if (start < pairs.length)
179
+ segments.push(segment(segments.length, pairs.slice(start), segments.length ? 'tail' : 'single_segment', includeEventIds));
180
+ return segments;
181
+ }
182
+ function isImportedEvent(event) {
183
+ const payload = event?.payload;
184
+ return payload?.metadata?.imported === true || payload?.metadata?.sourceRef !== undefined;
185
+ }
186
+ function impactInventory(pairs, timezone) {
187
+ const counts = roleCounts(pairs);
188
+ const dates = pairs
189
+ .filter((item) => item.event?.role === 'user')
190
+ .map((item) => trustedLocalDate(item.event, timezone))
191
+ .filter((value) => Boolean(value));
192
+ return {
193
+ eventCount: pairs.length,
194
+ ...counts,
195
+ hardShiftCount: pairs.filter((item) => ['hard_topic_switch', 'starts_new_topic', 'switches_topic'].includes(item.link.relation)).length,
196
+ trustedLocalDates: [...new Set(dates)],
197
+ };
198
+ }
199
+ function configWithDefinedOverrides(base, overrides) {
200
+ const config = { ...base };
201
+ if (overrides.maxEvents !== undefined && validThreshold(overrides.maxEvents, 20, 500))
202
+ config.maxEvents = overrides.maxEvents;
203
+ if (overrides.maxDurationMs !== undefined && validThreshold(overrides.maxDurationMs, 300_000, 86_400_000))
204
+ config.maxDurationMs = overrides.maxDurationMs;
205
+ if (overrides.maxIdleGapMs !== undefined && validThreshold(overrides.maxIdleGapMs, 300_000, 86_400_000))
206
+ config.maxIdleGapMs = overrides.maxIdleGapMs;
207
+ if (typeof overrides.timezone === 'string' && overrides.timezone.trim())
208
+ config.timezone = overrides.timezone;
209
+ return config;
210
+ }
211
+ function validThreshold(value, min, max) {
212
+ return value !== undefined && Number.isFinite(value) && value >= min && value <= max;
213
+ }
214
+ function boundaryOverrideWarnings(overrides) {
215
+ const warnings = [];
216
+ if (overrides.maxEvents !== undefined && !validThreshold(overrides.maxEvents, 20, 500))
217
+ warnings.push('invalid_episode_boundary_max_events');
218
+ if (overrides.maxDurationMs !== undefined && !validThreshold(overrides.maxDurationMs, 300_000, 86_400_000))
219
+ warnings.push('invalid_episode_boundary_max_duration_ms');
220
+ if (overrides.maxIdleGapMs !== undefined && !validThreshold(overrides.maxIdleGapMs, 300_000, 86_400_000))
221
+ warnings.push('invalid_episode_boundary_max_idle_gap_ms');
222
+ if (overrides.timezone !== undefined && !overrides.timezone.trim())
223
+ warnings.push('invalid_episode_boundary_timezone');
224
+ return warnings;
225
+ }
@@ -1,6 +1,8 @@
1
1
  import type Database from 'bun:sqlite';
2
2
  import type { MemoryEvent } from '../types/index.js';
3
- import type { EpisodeClosureMode, EpisodeClosureReasonCode, EpisodeClosureReceipt, EpisodeDreamStatus, EpisodeEventLink, EpisodeListOptions, EpisodeType, MemoryEpisode, TurnRelation } from './EpisodeTypes.js';
3
+ import type { EpisodeClosureMode, EpisodeClosureReasonCode, EpisodeClosureReceipt, EpisodeDreamState, EpisodeDreamStatus, EpisodeEventLink, EpisodeListOptions, EpisodeStatus, EpisodeType, MemoryEpisode, TurnRelation } from './EpisodeTypes.js';
4
+ import { type EpisodeBoundaryGuardResult } from './EpisodeBoundaryPolicy.js';
5
+ import type { TurnRelationDecision } from './TurnRelationClassifier.js';
4
6
  interface CreateEpisodeInput {
5
7
  projectId: string;
6
8
  sessionId: string;
@@ -25,6 +27,41 @@ export interface ClaimedEpisodeDreamJob {
25
27
  modeHint: 'micro' | 'normal' | 'deep';
26
28
  attempts: number;
27
29
  createdAt: number;
30
+ leaseUntil: number;
31
+ attemptGeneration: number;
32
+ }
33
+ export interface EpisodeBoundaryDecisionRecord {
34
+ decisionId: string;
35
+ projectId: string;
36
+ sessionId: string;
37
+ sourceAgent?: string;
38
+ threadId?: string;
39
+ primaryEventId: string;
40
+ previousEpisodeId?: string;
41
+ resultingEpisodeId?: string;
42
+ policyVersion: string;
43
+ mode: string;
44
+ guardAction: string;
45
+ guardCodes: string[];
46
+ metrics: EpisodeBoundaryGuardResult['metrics'];
47
+ cpuDecision: Partial<TurnRelationDecision>;
48
+ reviewerInvoked: boolean;
49
+ reviewerDecision?: Partial<TurnRelationDecision>;
50
+ finalDecision: Partial<TurnRelationDecision>;
51
+ warnings: EpisodeBoundaryGuardResult['warnings'];
52
+ createdAt: number;
53
+ }
54
+ export interface EpisodeBoundarySnapshot {
55
+ eventCount: number;
56
+ actualLinkCount: number;
57
+ storedEventCount: number;
58
+ eventCountMismatch: boolean;
59
+ startedAt?: number;
60
+ updatedAt?: number;
61
+ lastEventAt?: number;
62
+ lastTrustedUserLocalDate?: string;
63
+ lastTrustedLocalDate?: string;
64
+ trustedLocalDates: string[];
28
65
  }
29
66
  export declare class EpisodeStore {
30
67
  private readonly db;
@@ -32,12 +69,22 @@ export declare class EpisodeStore {
32
69
  constructor(db: Database, resolveEvent?: ((eventId: string) => MemoryEvent | null | undefined) | undefined, options?: {
33
70
  initializeSchemaForTests?: boolean;
34
71
  });
72
+ getDatabase(): Database;
35
73
  createEpisode(input: CreateEpisodeInput): MemoryEpisode;
36
74
  findActiveEpisode(projectId: string, sessionId: string, sourceAgent?: string, conversationThreadId?: string): MemoryEpisode | undefined;
37
75
  private findActiveEpisodeRow;
38
76
  claimLegacyEpisodeScope(episodeId: string, sourceAgent?: string, conversationThreadId?: string): MemoryEpisode | undefined;
39
77
  getEpisode(episodeId: string): MemoryEpisode | undefined;
40
78
  listEpisodes(options?: EpisodeListOptions): MemoryEpisode[];
79
+ listEpisodesForBoundaryAudit(options: {
80
+ projectId: string;
81
+ statuses?: EpisodeStatus[];
82
+ limit?: number;
83
+ cursor?: string;
84
+ }): {
85
+ episodes: MemoryEpisode[];
86
+ nextCursor?: string;
87
+ };
41
88
  appendEvent(input: {
42
89
  episodeId: string;
43
90
  eventId: string;
@@ -54,6 +101,8 @@ export declare class EpisodeStore {
54
101
  }): EpisodeEventLink;
55
102
  getEventLink(eventId: string): EpisodeEventLink | undefined;
56
103
  listEventLinks(episodeId: string): EpisodeEventLink[];
104
+ getBoundarySnapshot(episodeId: string, timezone?: string): EpisodeBoundarySnapshot;
105
+ transaction<T>(fn: () => T): T;
57
106
  isEpisodeEmpty(episodeId: string): boolean;
58
107
  addCrossReference(input: {
59
108
  projectId: string;
@@ -84,8 +133,21 @@ export declare class EpisodeStore {
84
133
  after: unknown;
85
134
  now?: number;
86
135
  }): string;
136
+ recordBoundaryDecision(input: Omit<EpisodeBoundaryDecisionRecord, 'decisionId' | 'createdAt'> & {
137
+ createdAt?: number;
138
+ }): {
139
+ recorded: boolean;
140
+ decisionId?: string;
141
+ status: 'inserted' | 'duplicate';
142
+ };
143
+ listBoundaryDecisions(options?: {
144
+ projectId?: string;
145
+ primaryEventId?: string;
146
+ limit?: number;
147
+ }): EpisodeBoundaryDecisionRecord[];
87
148
  private invalidateEpisodeDerivedState;
88
149
  private resequenceEpisode;
150
+ private deleteEmptyEpisode;
89
151
  reopenSoftEpisode(episodeId: string, now: number): MemoryEpisode;
90
152
  sealEpisode(episodeId: string, input: {
91
153
  mode: EpisodeClosureMode;
@@ -125,7 +187,7 @@ export declare class EpisodeStore {
125
187
  projectId?: string;
126
188
  now?: number;
127
189
  }): number;
128
- completeDreamJob(episodeId: string, leaseId: string, candidateIds: string[], now: number): void;
190
+ completeDreamJob(episodeId: string, leaseId: string, candidateIds: string[], now: number, commitCandidates?: () => void): void;
129
191
  failDreamJob(episodeId: string, leaseId: string, error: string, input: {
130
192
  now: number;
131
193
  failureCategory: string;
@@ -136,6 +198,7 @@ export declare class EpisodeStore {
136
198
  private markEmptyEpisodeDreamSkipped;
137
199
  private markEmptyEpisodeDreamSkippedMany;
138
200
  getDreamStatus(projectId?: string): EpisodeDreamStatus;
201
+ getDreamJobState(episodeId: string): EpisodeDreamState | undefined;
139
202
  countUnassignedRawEvents(projectId?: string): number;
140
203
  markEventDisposition(input: {
141
204
  eventId: string;
@@ -191,6 +254,8 @@ export declare class EpisodeStore {
191
254
  deleteByProject(projectId: string): number;
192
255
  private enqueueDreamJob;
193
256
  private initializeSchema;
257
+ private initializeSchemaUnsafe;
258
+ private ensureEpisodeCompatibilityColumns;
194
259
  }
195
260
  export {};
196
261
  //# sourceMappingURL=EpisodeStore.d.ts.map