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.
- package/CHANGELOG.md +12 -0
- package/MEMORY_ATLAS.md +2 -2
- package/MEMORY_MODEL.md +1 -1
- package/README.md +6 -5
- package/RELEASE_CHECKLIST.md +5 -5
- package/dist/atlas/MemoryAtlasService.d.ts +1 -0
- package/dist/atlas/MemoryAtlasService.js +36 -4
- package/dist/atlas/MemoryAtlasTypes.d.ts +7 -0
- package/dist/belief/BeliefStore.d.ts +3 -1
- package/dist/belief/BeliefStore.js +10 -2
- package/dist/bin/episode.js +107 -16
- package/dist/bin/import-support.js +28 -11
- package/dist/config/CogmemConfig.d.ts +1 -0
- package/dist/config/CogmemConfig.js +45 -0
- package/dist/core/MemoryGraph.js +25 -8
- package/dist/dream/DreamScheduler.d.ts +6 -1
- package/dist/dream/DreamScheduler.js +36 -6
- package/dist/engine/CognitiveGraphCompiler.js +1 -1
- package/dist/engine/ConsolidationPipeline.js +4 -4
- package/dist/engine/DeepWritePromotionPolicy.d.ts +2 -0
- package/dist/engine/DeepWritePromotionPolicy.js +25 -4
- package/dist/engine/DreamCuratorWorker.d.ts +3 -0
- package/dist/engine/DreamCuratorWorker.js +18 -3
- package/dist/engine/FactCompiler.js +2 -2
- package/dist/entity/EntityGovernanceService.js +1 -1
- package/dist/episode/EpisodeActiveScopeGuard.d.ts +3 -0
- package/dist/episode/EpisodeActiveScopeGuard.js +46 -0
- package/dist/episode/EpisodeAssembler.d.ts +20 -2
- package/dist/episode/EpisodeAssembler.js +458 -98
- package/dist/episode/EpisodeBoundaryAuditService.d.ts +70 -0
- package/dist/episode/EpisodeBoundaryAuditService.js +276 -0
- package/dist/episode/EpisodeBoundaryPolicy.d.ts +75 -0
- package/dist/episode/EpisodeBoundaryPolicy.js +189 -0
- package/dist/episode/EpisodeBoundaryReplayEngine.d.ts +65 -0
- package/dist/episode/EpisodeBoundaryReplayEngine.js +272 -0
- package/dist/episode/EpisodeImportIdentity.d.ts +1 -0
- package/dist/episode/EpisodeImportIdentity.js +1 -0
- package/dist/episode/EpisodeInvariantValidator.d.ts +16 -0
- package/dist/episode/EpisodeInvariantValidator.js +99 -0
- package/dist/episode/EpisodeSplitPlanner.d.ts +89 -0
- package/dist/episode/EpisodeSplitPlanner.js +225 -0
- package/dist/episode/EpisodeStore.d.ts +67 -2
- package/dist/episode/EpisodeStore.js +443 -59
- package/dist/episode/EpisodeTypes.d.ts +2 -2
- package/dist/episode/TurnRelationClassifier.d.ts +9 -0
- package/dist/episode/TurnRelationClassifier.js +42 -12
- package/dist/episode/index.d.ts +3 -0
- package/dist/episode/index.js +3 -0
- package/dist/factory.d.ts +62 -3
- package/dist/factory.js +308 -58
- package/dist/mcp/CoreMcpTools.js +103 -8
- package/dist/mcp/server.js +1 -1
- package/dist/migrations/0028_episode_boundary_guardrails.d.ts +3 -0
- package/dist/migrations/0028_episode_boundary_guardrails.js +47 -0
- package/dist/migrations/0029_episode_active_scope_guard.d.ts +3 -0
- package/dist/migrations/0029_episode_active_scope_guard.js +16 -0
- package/dist/migrations/0030_memory_event_local_date_source.d.ts +3 -0
- package/dist/migrations/0030_memory_event_local_date_source.js +111 -0
- package/dist/migrations/0031_episode_boundary_integrity_repair.d.ts +7 -0
- package/dist/migrations/0031_episode_boundary_integrity_repair.js +124 -0
- package/dist/migrations/SchemaMigrationRunner.d.ts +2 -0
- package/dist/migrations/SchemaMigrationRunner.js +46 -15
- package/dist/migrations/index.d.ts +6 -1
- package/dist/migrations/index.js +15 -1
- package/dist/public.d.ts +1 -1
- package/dist/public.js +1 -1
- package/dist/recall/BrainRecall.js +1 -1
- package/dist/store/DeepWriteCandidateStore.d.ts +21 -3
- package/dist/store/DeepWriteCandidateStore.js +118 -11
- package/dist/store/EntityStore.d.ts +4 -0
- package/dist/store/EntityStore.js +24 -12
- package/dist/store/EventStore.d.ts +7 -2
- package/dist/store/EventStore.js +144 -23
- package/dist/store/FactStore.js +6 -5
- package/dist/store/MemoryAtlasStore.d.ts +1 -0
- package/dist/store/MemoryAtlasStore.js +54 -0
- package/dist/types/ExtensionPoints.d.ts +3 -1
- package/dist/types/index.d.ts +1 -0
- package/examples/hermes-backend/AGENTS.md +1 -1
- package/examples/hermes-backend/README.md +1 -1
- package/examples/hermes-backend/SKILL.md +2 -2
- package/examples/hermes-backend/references/operations.md +2 -2
- package/examples/openclaw-backend/AGENTS.md +1 -1
- package/examples/openclaw-backend/README.md +1 -1
- package/examples/openclaw-backend/SKILL.md +2 -2
- package/examples/openclaw-backend/references/operations.md +2 -2
- package/package.json +1 -1
|
@@ -23,13 +23,18 @@ import { migration_0024 } from './0024_episode_ontology_reliability.js';
|
|
|
23
23
|
import { migration_0025 } from './0025_memory_atlas.js';
|
|
24
24
|
import { migration_0026 } from './0026_runtime_governance_atlas_reliability.js';
|
|
25
25
|
import { migration_0027 } from './0027_openclaw_upgrade_hotfix.js';
|
|
26
|
+
import { migration_0028 } from './0028_episode_boundary_guardrails.js';
|
|
27
|
+
import { migration_0029 } from './0029_episode_active_scope_guard.js';
|
|
28
|
+
import { migration_0030 } from './0030_memory_event_local_date_source.js';
|
|
29
|
+
import { migration_0031 } from './0031_episode_boundary_integrity_repair.js';
|
|
26
30
|
/**
|
|
27
31
|
* Ordered list of all schema migrations.
|
|
28
32
|
* Add new migrations here in ascending version order.
|
|
29
33
|
* MigrationRunner.up() applies only the pending ones.
|
|
30
34
|
*/
|
|
31
35
|
export declare const ALL_MIGRATIONS: Migration[];
|
|
32
|
-
export
|
|
36
|
+
export declare const KERNEL_MIGRATIONS: Migration[];
|
|
37
|
+
export { migration_0001, migration_0002, migration_0003, migration_0004, migration_0005, migration_0006, migration_0007, migration_0009, migration_0010, migration_0011, migration_0012, migration_0015, migration_0016, migration_0017, migration_0018, migration_0019, migration_0020, migration_0021, migration_0022, migration_0023, migration_0024, migration_0025, migration_0026, migration_0027, migration_0028, migration_0029, migration_0030, migration_0031 };
|
|
33
38
|
export { SchemaMigrationRunner } from './SchemaMigrationRunner.js';
|
|
34
39
|
export type { SchemaMigrationResult, SchemaMigrationRunOptions } from './SchemaMigrationRunner.js';
|
|
35
40
|
export type { Migration };
|
package/dist/migrations/index.js
CHANGED
|
@@ -22,6 +22,10 @@ import { migration_0024 } from './0024_episode_ontology_reliability.js';
|
|
|
22
22
|
import { migration_0025 } from './0025_memory_atlas.js';
|
|
23
23
|
import { migration_0026 } from './0026_runtime_governance_atlas_reliability.js';
|
|
24
24
|
import { migration_0027 } from './0027_openclaw_upgrade_hotfix.js';
|
|
25
|
+
import { migration_0028 } from './0028_episode_boundary_guardrails.js';
|
|
26
|
+
import { migration_0029 } from './0029_episode_active_scope_guard.js';
|
|
27
|
+
import { migration_0030 } from './0030_memory_event_local_date_source.js';
|
|
28
|
+
import { migration_0031 } from './0031_episode_boundary_integrity_repair.js';
|
|
25
29
|
/**
|
|
26
30
|
* Ordered list of all schema migrations.
|
|
27
31
|
* Add new migrations here in ascending version order.
|
|
@@ -52,6 +56,16 @@ export const ALL_MIGRATIONS = [
|
|
|
52
56
|
migration_0025,
|
|
53
57
|
migration_0026,
|
|
54
58
|
migration_0027,
|
|
59
|
+
migration_0028,
|
|
60
|
+
migration_0029,
|
|
61
|
+
migration_0030,
|
|
62
|
+
migration_0031,
|
|
55
63
|
];
|
|
56
|
-
|
|
64
|
+
// Core stores bootstrap the pre-0015 tables themselves. Running the early
|
|
65
|
+
// historical migrations against a fresh kernel would try to ALTER optional
|
|
66
|
+
// legacy tables that do not exist yet. The kernel still runs every migration
|
|
67
|
+
// from the first schema that owns the runtime tables through the latest one;
|
|
68
|
+
// the CLI remains able to replay the complete historical chain.
|
|
69
|
+
export const KERNEL_MIGRATIONS = ALL_MIGRATIONS.filter((migration) => Number.parseInt(migration.version, 10) >= 15);
|
|
70
|
+
export { migration_0001, migration_0002, migration_0003, migration_0004, migration_0005, migration_0006, migration_0007, migration_0009, migration_0010, migration_0011, migration_0012, migration_0015, migration_0016, migration_0017, migration_0018, migration_0019, migration_0020, migration_0021, migration_0022, migration_0023, migration_0024, migration_0025, migration_0026, migration_0027, migration_0028, migration_0029, migration_0030, migration_0031 };
|
|
57
71
|
export { SchemaMigrationRunner } from './SchemaMigrationRunner.js';
|
package/dist/public.d.ts
CHANGED
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
*/
|
|
17
17
|
export { MemoryKernel, createMemoryKernel, createMemoryKernelFromConfig, } from './factory.js';
|
|
18
18
|
export type { ForgetUserResult, GovernanceAuditRecord, DreamCandidateListOptions, DreamCandidateRecord, DreamCandidateStatus, DreamCuratorRunOptions, DreamCuratorRunResult, DreamTickOptions, DreamTickResult, EpisodeClosureReceipt, EpisodeDreamStatus, EpisodeListOptions, EpisodeMessageInput, EpisodeMessageResult, EpisodeRepairInput, EpisodeRepairResult, MemoryEpisode, MaintenanceSuggestedAction, MaintenanceTickOptions, MaintenanceTickResult, MemoryDataLane, MemoryBindingBackfillOptions, MemoryBindingBackfillResult, MemoryKernelFromConfigOptions, MemoryKernelNavigationOptions, MemoryKernelNavigationResult, MemoryKernelOptions, MemoryMapOptions, MemoryMapSection, MemorySelfMap, RawEventSearchOptions, RawMemoryEventInput, TaskMemoryEventInput, ToolCallMemoryEventInput, ToolResultMemoryEventInput, } from './factory.js';
|
|
19
|
-
export { EpisodeAssembler, EpisodeStore, classifyAssistantRelation, classifyTurnRelation, classifyTurnRelationHybrid, createStableImportIdentityFactory, summarizeEpisode, type EpisodeCandidateType, type EpisodeClosureMode, type EpisodeClosureReasonCode, type EpisodeDreamState, type EpisodeDreamStatusValue, type EpisodeEventLink, type EpisodeSemanticSummary, type EpisodeStatus, type EpisodeType, type StableImportIdentityInput, type TurnClassificationContext, type TurnRelation, type TurnRelationAdvisoryReviewer, type TurnRelationDecision, } from './episode/index.js';
|
|
19
|
+
export { EpisodeAssembler, EpisodeStore, classifyAssistantRelation, classifyTurnRelation, classifyTurnRelationHybrid, classifyTurnRelationHybridTrace, createStableImportIdentityFactory, summarizeEpisode, type EpisodeCandidateType, type EpisodeClosureMode, type EpisodeClosureReasonCode, type EpisodeDreamState, type EpisodeDreamStatusValue, type EpisodeEventLink, type EpisodeSemanticSummary, type EpisodeStatus, type EpisodeType, type EpisodeBoundaryAuditItem, type EpisodeBoundaryAuditResult, type EpisodeBoundaryConfig, type EpisodeBoundaryConfigDiagnostic, type EpisodeBoundaryDecisionRecord, type EpisodeBoundaryGuardCode, type EpisodeBoundaryGuardResult, type EpisodeBoundaryMetrics, type EpisodeBoundaryMode, type EpisodeBoundaryWarning, type EpisodeSplitImpactInventory, type EpisodeSplitPlan, type EpisodeSplitPlanSegment, type EpisodeSplitProposedBoundary, type StableImportIdentityInput, type TurnClassificationContext, type TurnRelation, type TurnRelationAdvisoryReviewer, type TurnRelationDecision, type TurnRelationHybridTrace, type TurnRelationReviewStatus, } from './episode/index.js';
|
|
20
20
|
export { DreamScheduler, type DreamTickMode, type SelectedDreamMode } from './dream/index.js';
|
|
21
21
|
export { MEMORY_ONTOLOGY_CLASSES, isMemoryOntologyClass, type MemoryOntologyClass } from './ontology/MemoryOntology.js';
|
|
22
22
|
export { TopicAliasRegistry, TopicGovernance, TopicPathRegistry as UserTopicPathRegistry, TopicRelationGraph, type TopicAliasRecord, type TopicCreatedBy, type TopicNode, type TopicOperationInput, type TopicOperationRecord, type TopicOperationType, type TopicRelationRecord, type TopicStatus, } from './topic/index.js';
|
package/dist/public.js
CHANGED
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
* @stable @since 1.0.0
|
|
17
17
|
*/
|
|
18
18
|
export { MemoryKernel, createMemoryKernel, createMemoryKernelFromConfig, } from './factory.js';
|
|
19
|
-
export { EpisodeAssembler, EpisodeStore, classifyAssistantRelation, classifyTurnRelation, classifyTurnRelationHybrid, createStableImportIdentityFactory, summarizeEpisode, } from './episode/index.js';
|
|
19
|
+
export { EpisodeAssembler, EpisodeStore, classifyAssistantRelation, classifyTurnRelation, classifyTurnRelationHybrid, classifyTurnRelationHybridTrace, createStableImportIdentityFactory, summarizeEpisode, } from './episode/index.js';
|
|
20
20
|
export { DreamScheduler } from './dream/index.js';
|
|
21
21
|
export { MEMORY_ONTOLOGY_CLASSES, isMemoryOntologyClass } from './ontology/MemoryOntology.js';
|
|
22
22
|
export { TopicAliasRegistry, TopicGovernance, TopicPathRegistry as UserTopicPathRegistry, TopicRelationGraph, } from './topic/index.js';
|
|
@@ -280,7 +280,7 @@ export class BrainRecall {
|
|
|
280
280
|
if (!edge.fromNodeId || !edge.toNodeId || edge.fromNodeId === edge.toNodeId) {
|
|
281
281
|
return 'ambiguous_edge_payload';
|
|
282
282
|
}
|
|
283
|
-
if (!this.deps.entityStore.
|
|
283
|
+
if (!this.deps.entityStore.findActiveByEntityId(edge.fromNodeId) || !this.deps.entityStore.findActiveByEntityId(edge.toNodeId)) {
|
|
284
284
|
return 'ambiguous_unknown_target_entity';
|
|
285
285
|
}
|
|
286
286
|
if (resolvedEntityIds.includes(edge.fromNodeId)) {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type Database from 'bun:sqlite';
|
|
2
|
-
export type DeepWriteRunStatus = 'succeeded' | 'failed' | 'skipped';
|
|
3
|
-
export type DeepWriteCandidateStatus = 'shadow' | 'candidate' | 'promoted' | 'rejected' | 'needs_confirmation' | 'superseded';
|
|
2
|
+
export type DeepWriteRunStatus = 'running' | 'staged' | 'succeeded' | 'failed' | 'skipped' | 'abandoned';
|
|
3
|
+
export type DeepWriteCandidateStatus = 'staged' | 'shadow' | 'candidate' | 'promoting' | 'promoted' | 'rejected' | 'needs_confirmation' | 'superseded';
|
|
4
4
|
export interface DeepWriteRunInput {
|
|
5
5
|
runId?: string;
|
|
6
6
|
projectId?: string;
|
|
@@ -14,12 +14,18 @@ export interface DeepWriteRunInput {
|
|
|
14
14
|
status: DeepWriteRunStatus;
|
|
15
15
|
error?: string;
|
|
16
16
|
createdAt?: number;
|
|
17
|
+
sourceEpisodeId?: string;
|
|
18
|
+
dreamJobLeaseId?: string;
|
|
19
|
+
leaseUntil?: number;
|
|
20
|
+
attemptGeneration?: number;
|
|
21
|
+
updatedAt?: number;
|
|
17
22
|
}
|
|
18
23
|
export interface DeepWriteCandidateInput {
|
|
19
24
|
candidateId?: string;
|
|
20
25
|
runId: string;
|
|
21
26
|
candidateType: string;
|
|
22
27
|
status: DeepWriteCandidateStatus;
|
|
28
|
+
publishStatus?: Exclude<DeepWriteCandidateStatus, 'staged'>;
|
|
23
29
|
confidence: number;
|
|
24
30
|
content: unknown;
|
|
25
31
|
evidence: unknown;
|
|
@@ -44,16 +50,24 @@ export interface DeepWriteCandidateListOptions {
|
|
|
44
50
|
projectId?: string;
|
|
45
51
|
runId?: string;
|
|
46
52
|
limit?: number;
|
|
53
|
+
after?: {
|
|
54
|
+
createdAt: number;
|
|
55
|
+
candidateId: string;
|
|
56
|
+
};
|
|
47
57
|
}
|
|
48
58
|
export declare class DeepWriteCandidateStore {
|
|
49
59
|
private readonly db;
|
|
50
60
|
constructor(db: Database);
|
|
61
|
+
getDatabase(): Database;
|
|
62
|
+
countActivePromotions(targetType: string, targetId: string, excludingCandidateId?: string): number;
|
|
63
|
+
recoverStalePromoting(before: number, updatedAt: number): number;
|
|
51
64
|
initSchema(): void;
|
|
52
65
|
insertRun(input: DeepWriteRunInput): DeepWriteRunRecord;
|
|
53
66
|
insertCandidates(inputs: DeepWriteCandidateInput[]): DeepWriteCandidateRecord[];
|
|
54
67
|
getRun(runId: string): DeepWriteRunRecord | null;
|
|
55
68
|
listCandidatesByRun(runId: string): DeepWriteCandidateRecord[];
|
|
56
69
|
getCandidate(candidateId: string): DeepWriteCandidateRecord | null;
|
|
70
|
+
claimCandidate(candidateId: string, updatedAt?: number): boolean;
|
|
57
71
|
listCandidatesByStatus(statuses: DeepWriteCandidateStatus[], options?: {
|
|
58
72
|
candidateTypes?: string[];
|
|
59
73
|
limit?: number;
|
|
@@ -66,7 +80,11 @@ export declare class DeepWriteCandidateStore {
|
|
|
66
80
|
reason?: string;
|
|
67
81
|
reviewAfter?: number | null;
|
|
68
82
|
updatedAt?: number;
|
|
69
|
-
}): void;
|
|
83
|
+
}, expectedStatus?: DeepWriteCandidateStatus): void;
|
|
84
|
+
publishStagedCandidates(runId: string, candidateIds: string[], updatedAt: number): void;
|
|
85
|
+
failStagedRun(runId: string, now: number, reason: string): void;
|
|
86
|
+
updateRunStatus(runId: string, expected: DeepWriteRunStatus, next: DeepWriteRunStatus): void;
|
|
87
|
+
abandonStaleStagedRuns(before: number, updatedAt: number, projectId?: string): number;
|
|
70
88
|
updateCandidateReviewData(candidateId: string, input: {
|
|
71
89
|
content: unknown;
|
|
72
90
|
evidence: unknown;
|
|
@@ -5,6 +5,28 @@ export class DeepWriteCandidateStore {
|
|
|
5
5
|
this.db = db;
|
|
6
6
|
this.initSchema();
|
|
7
7
|
}
|
|
8
|
+
getDatabase() {
|
|
9
|
+
return this.db;
|
|
10
|
+
}
|
|
11
|
+
countActivePromotions(targetType, targetId, excludingCandidateId) {
|
|
12
|
+
const row = this.db.prepare(`
|
|
13
|
+
SELECT COUNT(*) AS count
|
|
14
|
+
FROM deep_write_candidates
|
|
15
|
+
WHERE promotion_target_type = ?
|
|
16
|
+
AND promotion_target_id = ?
|
|
17
|
+
AND status IN ('staged', 'candidate', 'promoted', 'needs_confirmation')
|
|
18
|
+
AND (? IS NULL OR candidate_id <> ?)
|
|
19
|
+
`).get(targetType, targetId, excludingCandidateId || null, excludingCandidateId || null);
|
|
20
|
+
return Number(row?.count || 0);
|
|
21
|
+
}
|
|
22
|
+
recoverStalePromoting(before, updatedAt) {
|
|
23
|
+
const result = this.db.prepare(`
|
|
24
|
+
UPDATE deep_write_candidates
|
|
25
|
+
SET status = 'candidate', status_reason = 'promotion_timeout_recovered', updated_at = ?
|
|
26
|
+
WHERE status = 'promoting' AND updated_at < ?
|
|
27
|
+
`).run(updatedAt, before);
|
|
28
|
+
return Number(result.changes || 0);
|
|
29
|
+
}
|
|
8
30
|
initSchema() {
|
|
9
31
|
this.db.exec(`
|
|
10
32
|
CREATE TABLE IF NOT EXISTS deep_write_runs (
|
|
@@ -19,7 +41,12 @@ export class DeepWriteCandidateStore {
|
|
|
19
41
|
output_hash TEXT NOT NULL,
|
|
20
42
|
status TEXT NOT NULL,
|
|
21
43
|
error TEXT,
|
|
22
|
-
created_at INTEGER NOT NULL
|
|
44
|
+
created_at INTEGER NOT NULL,
|
|
45
|
+
source_episode_id TEXT,
|
|
46
|
+
dream_job_lease_id TEXT,
|
|
47
|
+
lease_until INTEGER,
|
|
48
|
+
attempt_generation INTEGER,
|
|
49
|
+
updated_at INTEGER
|
|
23
50
|
);
|
|
24
51
|
|
|
25
52
|
CREATE TABLE IF NOT EXISTS deep_write_candidates (
|
|
@@ -49,8 +76,14 @@ export class DeepWriteCandidateStore {
|
|
|
49
76
|
ON deep_write_candidates(status, candidate_type);
|
|
50
77
|
`);
|
|
51
78
|
this.ensureColumn('deep_write_candidates', 'status_reason', 'TEXT');
|
|
79
|
+
this.ensureColumn('deep_write_candidates', 'publish_status', 'TEXT');
|
|
52
80
|
this.ensureColumn('deep_write_candidates', 'review_after', 'INTEGER');
|
|
53
81
|
this.ensureColumn('deep_write_candidates', 'updated_at', 'INTEGER');
|
|
82
|
+
this.ensureColumn('deep_write_runs', 'source_episode_id', 'TEXT');
|
|
83
|
+
this.ensureColumn('deep_write_runs', 'dream_job_lease_id', 'TEXT');
|
|
84
|
+
this.ensureColumn('deep_write_runs', 'lease_until', 'INTEGER');
|
|
85
|
+
this.ensureColumn('deep_write_runs', 'attempt_generation', 'INTEGER');
|
|
86
|
+
this.ensureColumn('deep_write_runs', 'updated_at', 'INTEGER');
|
|
54
87
|
this.db.exec(`
|
|
55
88
|
UPDATE deep_write_candidates
|
|
56
89
|
SET updated_at = created_at
|
|
@@ -67,8 +100,9 @@ export class DeepWriteCandidateStore {
|
|
|
67
100
|
INSERT INTO deep_write_runs (
|
|
68
101
|
run_id, project_id, session_id, source_neuron_ids_json, model_provider,
|
|
69
102
|
model_name, mode, prompt_hash, output_hash, status, error, created_at
|
|
70
|
-
|
|
71
|
-
|
|
103
|
+
, source_episode_id, dream_job_lease_id, lease_until, attempt_generation, updated_at
|
|
104
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
105
|
+
`).run(record.runId, record.projectId || null, record.sessionId || null, JSON.stringify(record.sourceNeuronIds), record.modelProvider || null, record.modelName || null, record.mode, record.promptHash, record.outputHash, record.status, record.error || null, record.createdAt, record.sourceEpisodeId || null, record.dreamJobLeaseId || null, record.leaseUntil ?? null, record.attemptGeneration ?? null, record.updatedAt ?? record.createdAt);
|
|
72
106
|
return record;
|
|
73
107
|
}
|
|
74
108
|
insertCandidates(inputs) {
|
|
@@ -82,12 +116,12 @@ export class DeepWriteCandidateStore {
|
|
|
82
116
|
INSERT INTO deep_write_candidates (
|
|
83
117
|
candidate_id, run_id, candidate_type, status, confidence, content_json,
|
|
84
118
|
evidence_json, promotion_target_type, promotion_target_id, status_reason,
|
|
85
|
-
review_after, created_at, updated_at
|
|
86
|
-
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
119
|
+
publish_status, review_after, created_at, updated_at
|
|
120
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
87
121
|
`);
|
|
88
122
|
this.db.transaction(() => {
|
|
89
123
|
for (const record of records) {
|
|
90
|
-
stmt.run(record.candidateId, record.runId, record.candidateType, record.status, record.confidence, JSON.stringify(record.content), JSON.stringify(record.evidence), record.promotionTargetType || null, record.promotionTargetId || null, record.statusReason || null, record.reviewAfter ?? null, record.createdAt, record.updatedAt);
|
|
124
|
+
stmt.run(record.candidateId, record.runId, record.candidateType, record.status, record.confidence, JSON.stringify(record.content), JSON.stringify(record.evidence), record.promotionTargetType || null, record.promotionTargetId || null, record.statusReason || null, record.publishStatus || null, record.reviewAfter ?? null, record.createdAt, record.updatedAt);
|
|
91
125
|
}
|
|
92
126
|
})();
|
|
93
127
|
return records;
|
|
@@ -117,6 +151,14 @@ export class DeepWriteCandidateStore {
|
|
|
117
151
|
`).get(candidateId);
|
|
118
152
|
return row ? this.mapCandidate(row) : null;
|
|
119
153
|
}
|
|
154
|
+
claimCandidate(candidateId, updatedAt = Date.now()) {
|
|
155
|
+
const result = this.db.prepare(`
|
|
156
|
+
UPDATE deep_write_candidates
|
|
157
|
+
SET status = 'promoting', updated_at = ?
|
|
158
|
+
WHERE candidate_id = ? AND status = 'candidate'
|
|
159
|
+
`).run(updatedAt, candidateId);
|
|
160
|
+
return Number(result.changes || 0) === 1;
|
|
161
|
+
}
|
|
120
162
|
listCandidatesByStatus(statuses, options) {
|
|
121
163
|
if (statuses.length === 0)
|
|
122
164
|
return [];
|
|
@@ -137,7 +179,7 @@ export class DeepWriteCandidateStore {
|
|
|
137
179
|
}
|
|
138
180
|
listCandidates(options = {}) {
|
|
139
181
|
const params = [];
|
|
140
|
-
const conditions = [];
|
|
182
|
+
const conditions = options.statuses?.some((status) => status === 'staged' || status === 'promoting') ? [] : ["c.status NOT IN ('staged', 'promoting')"];
|
|
141
183
|
let sql = `
|
|
142
184
|
SELECT c.*
|
|
143
185
|
FROM deep_write_candidates c
|
|
@@ -159,6 +201,10 @@ export class DeepWriteCandidateStore {
|
|
|
159
201
|
conditions.push('c.run_id = ?');
|
|
160
202
|
params.push(options.runId);
|
|
161
203
|
}
|
|
204
|
+
if (options.after) {
|
|
205
|
+
conditions.push('(c.created_at > ? OR (c.created_at = ? AND c.candidate_id > ?))');
|
|
206
|
+
params.push(options.after.createdAt, options.after.createdAt, options.after.candidateId);
|
|
207
|
+
}
|
|
162
208
|
if (conditions.length)
|
|
163
209
|
sql += ` WHERE ${conditions.join(' AND ')}`;
|
|
164
210
|
sql += ` ORDER BY c.created_at ASC, c.candidate_id ASC LIMIT ?`;
|
|
@@ -168,7 +214,7 @@ export class DeepWriteCandidateStore {
|
|
|
168
214
|
}
|
|
169
215
|
countCandidates(options = {}) {
|
|
170
216
|
const params = [];
|
|
171
|
-
const conditions = [];
|
|
217
|
+
const conditions = options.statuses?.some((status) => status === 'staged' || status === 'promoting') ? [] : ["c.status NOT IN ('staged', 'promoting')"];
|
|
172
218
|
let sql = `
|
|
173
219
|
SELECT COUNT(*) AS count
|
|
174
220
|
FROM deep_write_candidates c
|
|
@@ -195,7 +241,7 @@ export class DeepWriteCandidateStore {
|
|
|
195
241
|
const row = this.db.prepare(sql).get(...params);
|
|
196
242
|
return row?.count || 0;
|
|
197
243
|
}
|
|
198
|
-
updateCandidateStatus(candidateId, status, promotionTarget) {
|
|
244
|
+
updateCandidateStatus(candidateId, status, promotionTarget, expectedStatus) {
|
|
199
245
|
this.db.prepare(`
|
|
200
246
|
UPDATE deep_write_candidates
|
|
201
247
|
SET status = ?,
|
|
@@ -204,8 +250,63 @@ export class DeepWriteCandidateStore {
|
|
|
204
250
|
status_reason = COALESCE(?, status_reason),
|
|
205
251
|
review_after = COALESCE(?, review_after),
|
|
206
252
|
updated_at = ?
|
|
207
|
-
WHERE candidate_id = ?
|
|
208
|
-
`).run(status, promotionTarget?.type || null, promotionTarget?.id || null, promotionTarget?.reason || null, promotionTarget?.reviewAfter ?? null, promotionTarget?.updatedAt ?? Date.now(), candidateId);
|
|
253
|
+
WHERE candidate_id = ? AND (? IS NULL OR status = ?)
|
|
254
|
+
`).run(status, promotionTarget?.type || null, promotionTarget?.id || null, promotionTarget?.reason || null, promotionTarget?.reviewAfter ?? null, promotionTarget?.updatedAt ?? Date.now(), candidateId, expectedStatus || null, expectedStatus || null);
|
|
255
|
+
}
|
|
256
|
+
publishStagedCandidates(runId, candidateIds, updatedAt) {
|
|
257
|
+
const statement = this.db.prepare(`UPDATE deep_write_candidates SET status = COALESCE(publish_status, 'candidate'), updated_at = ? WHERE candidate_id = ? AND run_id = ? AND status = 'staged'`);
|
|
258
|
+
for (const candidateId of candidateIds) {
|
|
259
|
+
const staged = Number(statement.run(updatedAt, candidateId, runId).changes || 0);
|
|
260
|
+
if (staged === 1)
|
|
261
|
+
continue;
|
|
262
|
+
const visible = this.db.prepare(`SELECT status, run_id FROM deep_write_candidates WHERE candidate_id = ?`).get(candidateId);
|
|
263
|
+
if (visible?.run_id !== runId || visible.status !== 'shadow')
|
|
264
|
+
throw new Error(`staged_candidate_publish_conflict:${candidateId}`);
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
failStagedRun(runId, now, reason) {
|
|
268
|
+
this.db.transaction(() => {
|
|
269
|
+
this.db.prepare(`UPDATE deep_write_candidates SET status = 'superseded', status_reason = ?, updated_at = ? WHERE run_id = ? AND status IN ('staged', 'shadow')`).run(reason, now, runId);
|
|
270
|
+
this.db.prepare(`UPDATE deep_write_runs SET status = 'failed', error = ? WHERE run_id = ? AND status = 'staged'`).run(reason, runId);
|
|
271
|
+
})();
|
|
272
|
+
}
|
|
273
|
+
updateRunStatus(runId, expected, next) {
|
|
274
|
+
const result = this.db.prepare(`UPDATE deep_write_runs SET status = ? WHERE run_id = ? AND status = ?`).run(next, runId, expected);
|
|
275
|
+
if (Number(result.changes || 0) !== 1)
|
|
276
|
+
throw new Error(`dream_run_status_conflict:${runId}`);
|
|
277
|
+
}
|
|
278
|
+
abandonStaleStagedRuns(before, updatedAt, projectId) {
|
|
279
|
+
const transaction = this.db.transaction(() => {
|
|
280
|
+
const candidates = this.db.prepare(`
|
|
281
|
+
SELECT r.run_id
|
|
282
|
+
FROM deep_write_runs r
|
|
283
|
+
LEFT JOIN episode_dream_jobs j ON j.episode_id = r.source_episode_id
|
|
284
|
+
WHERE r.status = 'staged' AND r.created_at < ?
|
|
285
|
+
AND (? IS NULL OR r.project_id = ?)
|
|
286
|
+
AND (
|
|
287
|
+
j.episode_id IS NULL
|
|
288
|
+
OR j.state <> 'processing'
|
|
289
|
+
OR j.lease_id <> r.dream_job_lease_id
|
|
290
|
+
OR j.lease_until IS NULL
|
|
291
|
+
OR j.lease_until < ?
|
|
292
|
+
)
|
|
293
|
+
`).all(before, projectId || null, projectId || null, updatedAt);
|
|
294
|
+
let abandoned = 0;
|
|
295
|
+
for (const row of candidates) {
|
|
296
|
+
this.db.prepare(`
|
|
297
|
+
UPDATE deep_write_candidates
|
|
298
|
+
SET status = 'superseded', status_reason = 'staged_run_abandoned', updated_at = ?
|
|
299
|
+
WHERE run_id = ? AND status IN ('staged', 'shadow')
|
|
300
|
+
`).run(updatedAt, row.run_id);
|
|
301
|
+
const result = this.db.prepare(`
|
|
302
|
+
UPDATE deep_write_runs SET status = 'abandoned', error = COALESCE(error, 'staged_run_abandoned')
|
|
303
|
+
WHERE run_id = ? AND status = 'staged'
|
|
304
|
+
`).run(row.run_id);
|
|
305
|
+
abandoned += Number(result.changes || 0);
|
|
306
|
+
}
|
|
307
|
+
return abandoned;
|
|
308
|
+
});
|
|
309
|
+
return transaction();
|
|
209
310
|
}
|
|
210
311
|
updateCandidateReviewData(candidateId, input) {
|
|
211
312
|
this.db.prepare(`
|
|
@@ -261,6 +362,11 @@ export class DeepWriteCandidateStore {
|
|
|
261
362
|
outputHash: row.output_hash,
|
|
262
363
|
status: row.status,
|
|
263
364
|
error: row.error || undefined,
|
|
365
|
+
sourceEpisodeId: row.source_episode_id || undefined,
|
|
366
|
+
dreamJobLeaseId: row.dream_job_lease_id || undefined,
|
|
367
|
+
leaseUntil: row.lease_until ?? undefined,
|
|
368
|
+
attemptGeneration: row.attempt_generation ?? undefined,
|
|
369
|
+
updatedAt: row.updated_at ?? row.created_at,
|
|
264
370
|
createdAt: row.created_at
|
|
265
371
|
};
|
|
266
372
|
}
|
|
@@ -270,6 +376,7 @@ export class DeepWriteCandidateStore {
|
|
|
270
376
|
runId: row.run_id,
|
|
271
377
|
candidateType: row.candidate_type,
|
|
272
378
|
status: row.status,
|
|
379
|
+
publishStatus: row.publish_status || undefined,
|
|
273
380
|
confidence: row.confidence,
|
|
274
381
|
content: JSON.parse(row.content_json || '{}'),
|
|
275
382
|
evidence: JSON.parse(row.evidence_json || '[]'),
|
|
@@ -106,6 +106,8 @@ export declare class EntityStore {
|
|
|
106
106
|
listByAlias(aliasText: string, type?: string): EntityRecord[];
|
|
107
107
|
findByCanonicalName(canonicalName: string, type?: string): EntityRecord | null;
|
|
108
108
|
findByEntityId(entityId: string): EntityRecord | null;
|
|
109
|
+
findActiveByEntityId(entityId: string): EntityRecord | null;
|
|
110
|
+
getByEntityId(entityId: string): EntityRecord | null;
|
|
109
111
|
findLatestByType(type: string): EntityRecord | null;
|
|
110
112
|
listRecentByType(type: string, limit?: number): EntityRecord[];
|
|
111
113
|
private listByCreationOrder;
|
|
@@ -125,12 +127,14 @@ export declare class EntityStore {
|
|
|
125
127
|
type?: string;
|
|
126
128
|
projectId?: string;
|
|
127
129
|
limit?: number;
|
|
130
|
+
includeInactive?: boolean;
|
|
128
131
|
}): EntityMentionRecord[];
|
|
129
132
|
getEntityTimeline(input: {
|
|
130
133
|
type?: string;
|
|
131
134
|
projectId?: string;
|
|
132
135
|
entityIds?: string[];
|
|
133
136
|
limit?: number;
|
|
137
|
+
includeInactive?: boolean;
|
|
134
138
|
}): EntityTimelineItem[];
|
|
135
139
|
listEntitiesUpdatedInRange(startTime: number, endTime: number, type?: string): EntityRecord[];
|
|
136
140
|
archiveEntity(entityId: string, updatedAt?: number): void;
|
|
@@ -183,7 +183,7 @@ export class EntityStore {
|
|
|
183
183
|
WHERE instance_id = ?
|
|
184
184
|
`).run(JSON.stringify(mergedAliases), input.status || existing.status, JSON.stringify(mergedMetadata), now, existing.entityId);
|
|
185
185
|
this.upsertAliases(existing.entityId, input.type, mergedAliases, now);
|
|
186
|
-
return this.
|
|
186
|
+
return this.getByEntityId(existing.entityId);
|
|
187
187
|
}
|
|
188
188
|
const record = {
|
|
189
189
|
entityId: `entity-${randomUUID()}`,
|
|
@@ -216,7 +216,7 @@ export class EntityStore {
|
|
|
216
216
|
SELECT e.*
|
|
217
217
|
FROM entity_aliases ea
|
|
218
218
|
JOIN entity_instances e ON e.instance_id = ea.entity_id
|
|
219
|
-
WHERE ea.normalized_alias = ? AND e.type = ?
|
|
219
|
+
WHERE ea.normalized_alias = ? AND e.type = ? AND e.status = 'active'
|
|
220
220
|
ORDER BY ea.updated_at DESC
|
|
221
221
|
LIMIT 12
|
|
222
222
|
`).all(normalizedAlias, type)
|
|
@@ -224,7 +224,7 @@ export class EntityStore {
|
|
|
224
224
|
SELECT e.*
|
|
225
225
|
FROM entity_aliases ea
|
|
226
226
|
JOIN entity_instances e ON e.instance_id = ea.entity_id
|
|
227
|
-
WHERE ea.normalized_alias = ?
|
|
227
|
+
WHERE ea.normalized_alias = ? AND e.status = 'active'
|
|
228
228
|
ORDER BY ea.updated_at DESC
|
|
229
229
|
LIMIT 12
|
|
230
230
|
`).all(normalizedAlias);
|
|
@@ -233,29 +233,37 @@ export class EntityStore {
|
|
|
233
233
|
findByCanonicalName(canonicalName, type) {
|
|
234
234
|
const row = type
|
|
235
235
|
? this.db.prepare(`
|
|
236
|
-
SELECT * FROM entity_instances WHERE canonical_name = ? AND type = ? ORDER BY updated_at DESC LIMIT 1
|
|
236
|
+
SELECT * FROM entity_instances WHERE canonical_name = ? AND type = ? AND status = 'active' ORDER BY updated_at DESC LIMIT 1
|
|
237
237
|
`).get(canonicalName, type)
|
|
238
238
|
: this.db.prepare(`
|
|
239
|
-
SELECT * FROM entity_instances WHERE canonical_name = ? ORDER BY updated_at DESC LIMIT 1
|
|
239
|
+
SELECT * FROM entity_instances WHERE canonical_name = ? AND status = 'active' ORDER BY updated_at DESC LIMIT 1
|
|
240
240
|
`).get(canonicalName);
|
|
241
241
|
return row ? this.mapRow(row) : null;
|
|
242
242
|
}
|
|
243
243
|
findByEntityId(entityId) {
|
|
244
|
+
const row = this.db.prepare(`SELECT * FROM entity_instances WHERE instance_id = ?`).get(entityId);
|
|
245
|
+
return row ? this.mapRow(row) : null;
|
|
246
|
+
}
|
|
247
|
+
findActiveByEntityId(entityId) {
|
|
244
248
|
const row = this.db.prepare(`
|
|
245
|
-
SELECT * FROM entity_instances WHERE instance_id = ?
|
|
249
|
+
SELECT * FROM entity_instances WHERE instance_id = ? AND status = 'active'
|
|
246
250
|
`).get(entityId);
|
|
247
251
|
return row ? this.mapRow(row) : null;
|
|
248
252
|
}
|
|
253
|
+
getByEntityId(entityId) {
|
|
254
|
+
const row = this.db.prepare(`SELECT * FROM entity_instances WHERE instance_id = ?`).get(entityId);
|
|
255
|
+
return row ? this.mapRow(row) : null;
|
|
256
|
+
}
|
|
249
257
|
findLatestByType(type) {
|
|
250
258
|
const row = this.db.prepare(`
|
|
251
|
-
SELECT * FROM entity_instances WHERE type = ? ORDER BY updated_at DESC, created_at DESC LIMIT 1
|
|
259
|
+
SELECT * FROM entity_instances WHERE type = ? AND status = 'active' ORDER BY updated_at DESC, created_at DESC LIMIT 1
|
|
252
260
|
`).get(type);
|
|
253
261
|
return row ? this.mapRow(row) : null;
|
|
254
262
|
}
|
|
255
263
|
listRecentByType(type, limit = 8) {
|
|
256
264
|
const rows = this.db.prepare(`
|
|
257
265
|
SELECT * FROM entity_instances
|
|
258
|
-
WHERE type = ?
|
|
266
|
+
WHERE type = ? AND status = 'active'
|
|
259
267
|
ORDER BY updated_at DESC, created_at DESC
|
|
260
268
|
LIMIT ?
|
|
261
269
|
`).all(type, limit);
|
|
@@ -264,7 +272,7 @@ export class EntityStore {
|
|
|
264
272
|
listByCreationOrder(type, limit = 8) {
|
|
265
273
|
const rows = this.db.prepare(`
|
|
266
274
|
SELECT * FROM entity_instances
|
|
267
|
-
WHERE type = ?
|
|
275
|
+
WHERE type = ? AND status = 'active'
|
|
268
276
|
ORDER BY created_at DESC, updated_at DESC
|
|
269
277
|
LIMIT ?
|
|
270
278
|
`).all(type, limit);
|
|
@@ -411,7 +419,7 @@ export class EntityStore {
|
|
|
411
419
|
) VALUES (?, ?, ?, ?, ?, ?)
|
|
412
420
|
`).run(record.mentionId, record.entityId, record.neuronId || null, record.projectId || null, record.mentionType, record.createdAt);
|
|
413
421
|
this.touchEntity(record.entityId, record.createdAt);
|
|
414
|
-
const entity = this.
|
|
422
|
+
const entity = this.getByEntityId(record.entityId);
|
|
415
423
|
if (entity) {
|
|
416
424
|
for (const alias of [entity.canonicalName, ...(entity.aliases || [])]) {
|
|
417
425
|
this.refreshAliasConflict(this.normalizeAlias(alias), entity.type, record.createdAt);
|
|
@@ -440,6 +448,8 @@ export class EntityStore {
|
|
|
440
448
|
sql += ` AND em.project_id = ?`;
|
|
441
449
|
params.push(input.projectId);
|
|
442
450
|
}
|
|
451
|
+
if (!input.includeInactive)
|
|
452
|
+
sql += ` AND e.status = 'active'`;
|
|
443
453
|
sql += ` ORDER BY em.created_at DESC LIMIT ?`;
|
|
444
454
|
params.push(limit);
|
|
445
455
|
const rows = this.db.prepare(sql).all(...params);
|
|
@@ -469,6 +479,8 @@ export class EntityStore {
|
|
|
469
479
|
sql += ` AND em.project_id = ?`;
|
|
470
480
|
params.push(input.projectId);
|
|
471
481
|
}
|
|
482
|
+
if (!input.includeInactive)
|
|
483
|
+
sql += ` AND e.status = 'active'`;
|
|
472
484
|
if (input.entityIds?.length) {
|
|
473
485
|
sql += ` AND em.entity_id IN (${input.entityIds.map(() => '?').join(', ')})`;
|
|
474
486
|
params.push(...input.entityIds);
|
|
@@ -662,7 +674,7 @@ export class EntityStore {
|
|
|
662
674
|
this.db.close();
|
|
663
675
|
}
|
|
664
676
|
addAlias(entityId, alias, updatedAt = Date.now()) {
|
|
665
|
-
const entity = this.
|
|
677
|
+
const entity = this.getByEntityId(entityId);
|
|
666
678
|
if (!entity || !alias.trim())
|
|
667
679
|
return;
|
|
668
680
|
const aliases = Array.from(new Set([...entity.aliases, alias.trim()]));
|
|
@@ -671,7 +683,7 @@ export class EntityStore {
|
|
|
671
683
|
this.upsertAliases(entityId, entity.type, [alias], updatedAt);
|
|
672
684
|
}
|
|
673
685
|
removeAlias(entityId, alias, updatedAt = Date.now()) {
|
|
674
|
-
const entity = this.
|
|
686
|
+
const entity = this.getByEntityId(entityId);
|
|
675
687
|
if (!entity || entity.canonicalName === alias)
|
|
676
688
|
return;
|
|
677
689
|
const normalized = this.normalizeAlias(alias);
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import Database from 'bun:sqlite';
|
|
1
2
|
import type { EncryptionProvider } from '../encryption/index.js';
|
|
2
3
|
import type { EventAuditPage, MemoryEvent, MemoryEventCausalityType, MemoryEventContext, MemoryRawEventType, MemoryEventRole, MemoryEventType, OrderingConfidence, StreamType } from '../types/index.js';
|
|
3
4
|
export interface ProjectionCheckpoint {
|
|
@@ -28,6 +29,7 @@ export interface AppendEventInput<TPayload = Record<string, unknown>> {
|
|
|
28
29
|
threadId?: string;
|
|
29
30
|
sessionId?: string;
|
|
30
31
|
localDate?: string;
|
|
32
|
+
localDateSource?: 'explicit' | 'generated_utc' | 'legacy_unknown';
|
|
31
33
|
threadSeq?: number;
|
|
32
34
|
turnId?: string;
|
|
33
35
|
turnSeq?: number;
|
|
@@ -49,15 +51,18 @@ export interface AppendEventInput<TPayload = Record<string, unknown>> {
|
|
|
49
51
|
export declare class EventStore {
|
|
50
52
|
private readonly encryptionProvider?;
|
|
51
53
|
private db;
|
|
52
|
-
|
|
54
|
+
private ownsDb;
|
|
55
|
+
constructor(dbPath?: string | Database, encryptionProvider?: EncryptionProvider | undefined);
|
|
53
56
|
private initializeSchema;
|
|
54
57
|
private ensureCompatibilityColumns;
|
|
55
|
-
append<TPayload = Record<string, unknown>>(input: AppendEventInput<TPayload
|
|
58
|
+
append<TPayload = Record<string, unknown>>(input: AppendEventInput<TPayload>, retry?: number): MemoryEvent<TPayload>;
|
|
59
|
+
private upsertImportAnchor;
|
|
56
60
|
getNextGlobalSeq(): number;
|
|
57
61
|
getNextEventVersion(streamId: string): number;
|
|
58
62
|
getNextThreadSeq(threadId: string): number;
|
|
59
63
|
getNextTurnSeq(threadId: string): number;
|
|
60
64
|
getEventsAfter(lastEventTime?: number): MemoryEvent[];
|
|
65
|
+
findImportedEventAnchor(projectId: string, sourceId: string, importAnchor: string): MemoryEvent | null;
|
|
61
66
|
getLatestEvent(): MemoryEvent | null;
|
|
62
67
|
listRawEventsAfterGlobalSeq(options?: {
|
|
63
68
|
projectId?: string;
|