@sidurijs/api 1.0.0 → 1.0.2

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/dist/app.js CHANGED
@@ -150,6 +150,7 @@ function createApp(runtimes = new Map()) {
150
150
  const parsed = await (0, self_1.compilePersonaDocument)(content, {
151
151
  brain: runtime?.brain,
152
152
  companionId,
153
+ fallbackToParser: true,
153
154
  });
154
155
  let alreadyInstalled = false;
155
156
  const repo = new self_1.SqliteSelfRepository({ dbPath: process.env.STORAGE_PATH || process.env.SQLITE_DB_PATH || 'siduri.sqlite' });
@@ -190,6 +191,7 @@ function createApp(runtimes = new Map()) {
190
191
  const parsed = await (0, self_1.compilePersonaDocument)(content, {
191
192
  brain: runtime?.brain,
192
193
  companionId: targetId,
194
+ fallbackToParser: true,
193
195
  });
194
196
  res.json(parsed);
195
197
  }
@@ -477,17 +479,53 @@ function createApp(runtimes = new Map()) {
477
479
  }
478
480
  return res.json({ success: true, interrupted: true, reason });
479
481
  });
480
- // MEMORY GETTERS
482
+ // SELF DIRECTIVES & PROPOSALS (RFC VX-26-13: Primitive 1)
483
+ app.get('/self/directives', auth_1.requireAuth, async (req, res) => {
484
+ const id = req.query.id || Array.from(runtimes.keys())[0];
485
+ const runtime = runtimes.get(id);
486
+ if (!runtime)
487
+ return res.status(404).json({ error: "Companion not found" });
488
+ try {
489
+ if (runtime.self && typeof runtime.self.getActiveDirectives === 'function') {
490
+ const directives = typeof runtime.self.getAllDirectives === 'function'
491
+ ? await runtime.self.getAllDirectives(id)
492
+ : await runtime.self.getActiveDirectives(id);
493
+ return res.json({ directives });
494
+ }
495
+ res.json({ directives: [] });
496
+ }
497
+ catch (e) {
498
+ res.status(500).json({ error: e.message });
499
+ }
500
+ });
501
+ app.get('/self/proposals', auth_1.requireAuth, async (req, res) => {
502
+ const id = req.query.id || Array.from(runtimes.keys())[0];
503
+ const runtime = runtimes.get(id);
504
+ if (!runtime)
505
+ return res.status(404).json({ error: "Companion not found" });
506
+ try {
507
+ if (runtime.self && typeof runtime.self.getPendingDirectives === 'function') {
508
+ const proposals = await runtime.self.getPendingDirectives(id);
509
+ return res.json({ proposals });
510
+ }
511
+ res.json({ proposals: [] });
512
+ }
513
+ catch (e) {
514
+ res.status(500).json({ error: e.message });
515
+ }
516
+ });
517
+ // PROPOSALS GETTERS (RFC VX-26-13: routed through self, legacy compatibility aliases)
481
518
  app.get('/memory/proposals', auth_1.requireAuth, async (req, res) => {
482
519
  const id = req.query.id || Array.from(runtimes.keys())[0];
483
520
  const runtime = runtimes.get(id);
484
521
  if (!runtime)
485
522
  return res.status(404).json({ error: "Companion not found" });
486
- if (!runtime.memory)
487
- return res.json({ proposals: [] });
488
523
  try {
489
- const proposals = await runtime.memory.getPendingClaims();
490
- res.json({ proposals });
524
+ if (runtime.self && typeof runtime.self.getPendingDirectives === 'function') {
525
+ const proposals = await runtime.self.getPendingDirectives(id);
526
+ return res.json({ proposals });
527
+ }
528
+ res.json({ proposals: [] });
491
529
  }
492
530
  catch (e) {
493
531
  res.status(500).json({ error: e.message });
@@ -498,11 +536,12 @@ function createApp(runtimes = new Map()) {
498
536
  const runtime = runtimes.get(id);
499
537
  if (!runtime)
500
538
  return res.status(404).json({ error: "Companion not found" });
501
- if (!runtime.memory)
502
- return res.json({ items: [] });
503
539
  try {
504
- const items = await runtime.memory.getClaims();
505
- res.json({ items });
540
+ if (runtime.self && typeof runtime.self.getAllDirectives === 'function') {
541
+ const items = await runtime.self.getAllDirectives(id);
542
+ return res.json({ items });
543
+ }
544
+ res.json({ items: [] });
506
545
  }
507
546
  catch (e) {
508
547
  res.status(500).json({ error: e.message });
@@ -513,13 +552,12 @@ function createApp(runtimes = new Map()) {
513
552
  const runtime = runtimes.get(id);
514
553
  if (!runtime)
515
554
  return res.status(404).json({ error: "Companion not found" });
516
- if (!runtime.memory)
517
- return res.json({ claims: [] });
518
555
  try {
519
- const claims = typeof runtime.memory.getAllClaims === 'function'
520
- ? await runtime.memory.getAllClaims()
521
- : await runtime.memory.getClaims();
522
- res.json({ claims });
556
+ if (runtime.self && typeof runtime.self.getAllDirectives === 'function') {
557
+ const claims = await runtime.self.getAllDirectives(id);
558
+ return res.json({ claims });
559
+ }
560
+ res.json({ claims: [] });
523
561
  }
524
562
  catch (e) {
525
563
  res.status(500).json({ error: e.message });
@@ -530,13 +568,14 @@ function createApp(runtimes = new Map()) {
530
568
  const runtime = runtimes.get(id);
531
569
  if (!runtime)
532
570
  return res.status(404).json({ error: "Companion not found" });
533
- if (!runtime.memory)
534
- return res.json({ directives: [] });
535
571
  try {
536
- const directives = typeof runtime.memory.getAllDirectives === 'function'
537
- ? await runtime.memory.getAllDirectives()
538
- : await runtime.memory.getDirectives();
539
- res.json({ directives });
572
+ if (runtime.self && typeof runtime.self.getActiveDirectives === 'function') {
573
+ const directives = typeof runtime.self.getAllDirectives === 'function'
574
+ ? await runtime.self.getAllDirectives(id)
575
+ : await runtime.self.getActiveDirectives(id);
576
+ return res.json({ directives });
577
+ }
578
+ res.json({ directives: [] });
540
579
  }
541
580
  catch (e) {
542
581
  res.status(500).json({ error: e.message });
@@ -849,43 +888,27 @@ function createApp(runtimes = new Map()) {
849
888
  res.status(500).json({ error: e.message });
850
889
  }
851
890
  });
852
- // MEMORY MUTATIONS - PROPOSALS
891
+ // PROPOSAL MUTATIONS (RFC VX-26-13: routed through self)
853
892
  app.post('/memory/proposals/update', auth_1.requireAuth, async (req, res) => {
854
893
  const id = req.body.companionId || Array.from(runtimes.keys())[0];
855
894
  const runtime = runtimes.get(id);
856
895
  if (!runtime)
857
896
  return res.status(404).json({ error: "Companion not found" });
858
- if (!runtime.memory || typeof runtime.memory.updateClaim !== 'function') {
859
- return res.status(400).json({ error: "Memory organ does not support updating claims" });
860
- }
861
- try {
862
- const claimId = req.body.id || req.body.claimId;
863
- if (!claimId) {
864
- return res.status(400).json({ error: "Missing required claim id" });
865
- }
866
- const updated = await runtime.memory.updateClaim(claimId, req.body.updates || req.body);
867
- res.json({ success: true, claim: updated });
868
- }
869
- catch (e) {
870
- res.status(500).json({ error: e.message });
871
- }
897
+ return res.status(400).json({ error: "Claim update not supported. Use directive approval/rejection via self." });
872
898
  });
873
899
  app.post('/memory/proposals/approve', auth_1.requireAuth, async (req, res) => {
874
900
  const id = req.body.companionId || Array.from(runtimes.keys())[0];
875
901
  const runtime = runtimes.get(id);
876
902
  if (!runtime)
877
903
  return res.status(404).json({ error: "Companion not found" });
878
- if (!runtime.memory)
879
- return res.status(400).json({ error: "Memory organ not configured" });
904
+ if (!runtime.self)
905
+ return res.status(400).json({ error: "Self organ not configured" });
880
906
  try {
881
907
  let name;
882
908
  if (typeof runtime.approveProposal === 'function') {
883
909
  const pRes = await runtime.approveProposal(req.body.id, { companionId: id });
884
910
  name = pRes?.name;
885
911
  }
886
- else {
887
- await runtime.memory.approveClaim(req.body.id);
888
- }
889
912
  if (!name && runtime.self && typeof runtime.self.getIdentity === 'function') {
890
913
  try {
891
914
  const ident = await runtime.self.getIdentity(id);
@@ -904,14 +927,61 @@ function createApp(runtimes = new Map()) {
904
927
  const runtime = runtimes.get(id);
905
928
  if (!runtime)
906
929
  return res.status(404).json({ error: "Companion not found" });
907
- if (!runtime.memory)
908
- return res.status(400).json({ error: "Memory organ not configured" });
930
+ if (!runtime.self)
931
+ return res.status(400).json({ error: "Self organ not configured" });
909
932
  try {
910
933
  if (typeof runtime.rejectProposal === 'function') {
911
934
  await runtime.rejectProposal(req.body.id, { companionId: id });
912
935
  }
913
- else {
914
- await runtime.memory.rejectClaim(req.body.id);
936
+ res.json({ rejected: true, status: 'rejected' });
937
+ }
938
+ catch (e) {
939
+ res.status(500).json({ error: e.message });
940
+ }
941
+ });
942
+ // SELF DIRECTIVE MUTATIONS (RFC VX-26-13: Primitive 1)
943
+ app.post('/self/directives/approve', auth_1.requireAuth, async (req, res) => {
944
+ const id = req.body.companionId || Array.from(runtimes.keys())[0];
945
+ const runtime = runtimes.get(id);
946
+ if (!runtime)
947
+ return res.status(404).json({ error: "Companion not found" });
948
+ if (!runtime.self)
949
+ return res.status(400).json({ error: "Self organ not configured" });
950
+ try {
951
+ let name;
952
+ if (typeof runtime.approveDirective === 'function') {
953
+ const bRes = await runtime.approveDirective(req.body.id, { companionId: id });
954
+ name = bRes?.name;
955
+ }
956
+ else if (runtime.self && typeof runtime.self.approveDirective === 'function') {
957
+ await runtime.self.approveDirective(req.body.id, id);
958
+ }
959
+ if (!name && runtime.self && typeof runtime.self.getIdentity === 'function') {
960
+ try {
961
+ const ident = await runtime.self.getIdentity(id);
962
+ name = ident?.name;
963
+ }
964
+ catch { }
965
+ }
966
+ res.json({ approved: true, status: 'active', name });
967
+ }
968
+ catch (e) {
969
+ res.status(500).json({ error: e.message });
970
+ }
971
+ });
972
+ app.post('/self/directives/reject', auth_1.requireAuth, async (req, res) => {
973
+ const id = req.body.companionId || Array.from(runtimes.keys())[0];
974
+ const runtime = runtimes.get(id);
975
+ if (!runtime)
976
+ return res.status(404).json({ error: "Companion not found" });
977
+ if (!runtime.self)
978
+ return res.status(400).json({ error: "Self organ not configured" });
979
+ try {
980
+ if (typeof runtime.rejectDirective === 'function') {
981
+ await runtime.rejectDirective(req.body.id, { companionId: id });
982
+ }
983
+ else if (runtime.self && typeof runtime.self.rejectDirective === 'function') {
984
+ await runtime.self.rejectDirective(req.body.id, id);
915
985
  }
916
986
  res.json({ rejected: true, status: 'rejected' });
917
987
  }
@@ -919,22 +989,59 @@ function createApp(runtimes = new Map()) {
919
989
  res.status(500).json({ error: e.message });
920
990
  }
921
991
  });
922
- // MEMORY MUTATIONS - BEHAVIORAL
992
+ app.post('/self/directives/revoke', auth_1.requireAuth, async (req, res) => {
993
+ const id = req.body.companionId || Array.from(runtimes.keys())[0];
994
+ const runtime = runtimes.get(id);
995
+ if (!runtime)
996
+ return res.status(404).json({ error: "Companion not found" });
997
+ if (!runtime.self)
998
+ return res.status(400).json({ error: "Self organ not configured" });
999
+ try {
1000
+ if (typeof runtime.revokeDirective === 'function') {
1001
+ await runtime.revokeDirective(req.body.id, { companionId: id });
1002
+ }
1003
+ else if (runtime.self && typeof runtime.self.revokeDirective === 'function') {
1004
+ await runtime.self.revokeDirective(req.body.id, id);
1005
+ }
1006
+ res.json({ revoked: true, status: 'revoked' });
1007
+ }
1008
+ catch (e) {
1009
+ res.status(500).json({ error: e.message });
1010
+ }
1011
+ });
1012
+ app.post('/self/directives/disable', auth_1.requireAuth, async (req, res) => {
1013
+ const id = req.body.companionId || Array.from(runtimes.keys())[0];
1014
+ const runtime = runtimes.get(id);
1015
+ if (!runtime)
1016
+ return res.status(404).json({ error: "Companion not found" });
1017
+ if (!runtime.self)
1018
+ return res.status(400).json({ error: "Self organ not configured" });
1019
+ try {
1020
+ if (runtime.self && typeof runtime.self.disableDirective === 'function') {
1021
+ await runtime.self.disableDirective(req.body.id, id);
1022
+ }
1023
+ res.json({ disabled: true, status: 'disabled' });
1024
+ }
1025
+ catch (e) {
1026
+ res.status(500).json({ error: e.message });
1027
+ }
1028
+ });
1029
+ // BEHAVIORAL DIRECTIVE MUTATIONS (RFC VX-26-13: Sovereign Directives via Self, compatibility aliases)
923
1030
  app.post('/memory/behavioral/approve', auth_1.requireAuth, async (req, res) => {
924
1031
  const id = req.body.companionId || Array.from(runtimes.keys())[0];
925
1032
  const runtime = runtimes.get(id);
926
1033
  if (!runtime)
927
1034
  return res.status(404).json({ error: "Companion not found" });
928
- if (!runtime.memory)
929
- return res.status(400).json({ error: "Memory organ not configured" });
1035
+ if (!runtime.self)
1036
+ return res.status(400).json({ error: "Self organ not configured" });
930
1037
  try {
931
1038
  let name;
932
1039
  if (typeof runtime.approveDirective === 'function') {
933
1040
  const bRes = await runtime.approveDirective(req.body.id, { companionId: id });
934
1041
  name = bRes?.name;
935
1042
  }
936
- else {
937
- await runtime.memory.approveDirective(req.body.id);
1043
+ else if (runtime.self && typeof runtime.self.approveDirective === 'function') {
1044
+ await runtime.self.approveDirective(req.body.id, id);
938
1045
  }
939
1046
  if (!name && runtime.self && typeof runtime.self.getIdentity === 'function') {
940
1047
  try {
@@ -954,14 +1061,14 @@ function createApp(runtimes = new Map()) {
954
1061
  const runtime = runtimes.get(id);
955
1062
  if (!runtime)
956
1063
  return res.status(404).json({ error: "Companion not found" });
957
- if (!runtime.memory)
958
- return res.status(400).json({ error: "Memory organ not configured" });
1064
+ if (!runtime.self)
1065
+ return res.status(400).json({ error: "Self organ not configured" });
959
1066
  try {
960
1067
  if (typeof runtime.rejectDirective === 'function') {
961
1068
  await runtime.rejectDirective(req.body.id, { companionId: id });
962
1069
  }
963
- else {
964
- await runtime.memory.rejectDirective(req.body.id);
1070
+ else if (runtime.self && typeof runtime.self.rejectDirective === 'function') {
1071
+ await runtime.self.rejectDirective(req.body.id, id);
965
1072
  }
966
1073
  res.json({ rejected: true, status: 'rejected' });
967
1074
  }
@@ -974,14 +1081,14 @@ function createApp(runtimes = new Map()) {
974
1081
  const runtime = runtimes.get(id);
975
1082
  if (!runtime)
976
1083
  return res.status(404).json({ error: "Companion not found" });
977
- if (!runtime.memory)
978
- return res.status(400).json({ error: "Memory organ not configured" });
1084
+ if (!runtime.self)
1085
+ return res.status(400).json({ error: "Self organ not configured" });
979
1086
  try {
980
1087
  if (typeof runtime.revokeDirective === 'function') {
981
1088
  await runtime.revokeDirective(req.body.id, { companionId: id });
982
1089
  }
983
- else {
984
- await runtime.memory.revokeDirective(req.body.id);
1090
+ else if (runtime.self && typeof runtime.self.revokeDirective === 'function') {
1091
+ await runtime.self.revokeDirective(req.body.id, id);
985
1092
  }
986
1093
  res.json({ revoked: true, status: 'revoked' });
987
1094
  }
@@ -994,16 +1101,62 @@ function createApp(runtimes = new Map()) {
994
1101
  const runtime = runtimes.get(id);
995
1102
  if (!runtime)
996
1103
  return res.status(404).json({ error: "Companion not found" });
997
- if (!runtime.memory)
998
- return res.status(400).json({ error: "Memory organ not configured" });
1104
+ if (!runtime.self)
1105
+ return res.status(400).json({ error: "Self organ not configured" });
999
1106
  try {
1000
- await runtime.memory.disableDirective(req.body.id);
1107
+ if (runtime.self && typeof runtime.self.disableDirective === 'function') {
1108
+ await runtime.self.disableDirective(req.body.id, id);
1109
+ }
1001
1110
  res.json({ disabled: true, status: 'disabled' });
1002
1111
  }
1003
1112
  catch (e) {
1004
1113
  res.status(500).json({ error: e.message });
1005
1114
  }
1006
1115
  });
1116
+ // ARCHIVE AUDIT ENDPOINTS (RFC VX-26-13: Primitive 5)
1117
+ app.get('/archive/events', auth_1.requireAuth, async (req, res) => {
1118
+ const id = req.query.id || Array.from(runtimes.keys())[0];
1119
+ const runtime = runtimes.get(id);
1120
+ if (!runtime)
1121
+ return res.status(404).json({ error: "Companion not found" });
1122
+ const limit = parseInt(req.query.limit) || 50;
1123
+ try {
1124
+ if (runtime.archive && typeof runtime.archive.getRecentEvents === 'function') {
1125
+ const events = await runtime.archive.getRecentEvents(id, limit);
1126
+ return res.json({ events });
1127
+ }
1128
+ if (runtime.db && typeof runtime.db.getRecentArchiveEvents === 'function') {
1129
+ const events = runtime.db.getRecentArchiveEvents(id, limit);
1130
+ return res.json({ events });
1131
+ }
1132
+ res.json({ events: [] });
1133
+ }
1134
+ catch (e) {
1135
+ res.status(500).json({ error: e.message });
1136
+ }
1137
+ });
1138
+ app.get('/archive/search', auth_1.requireAuth, async (req, res) => {
1139
+ const id = req.query.id || Array.from(runtimes.keys())[0];
1140
+ const runtime = runtimes.get(id);
1141
+ if (!runtime)
1142
+ return res.status(404).json({ error: "Companion not found" });
1143
+ const query = req.query.q || '';
1144
+ const limit = parseInt(req.query.limit) || 50;
1145
+ try {
1146
+ if (runtime.archive && typeof runtime.archive.searchEvents === 'function') {
1147
+ const results = await runtime.archive.searchEvents(id, query, limit);
1148
+ return res.json({ results });
1149
+ }
1150
+ if (runtime.db && typeof runtime.db.searchArchiveEvents === 'function') {
1151
+ const results = runtime.db.searchArchiveEvents(id, query, limit);
1152
+ return res.json({ results });
1153
+ }
1154
+ res.json({ results: [] });
1155
+ }
1156
+ catch (e) {
1157
+ res.status(500).json({ error: e.message });
1158
+ }
1159
+ });
1007
1160
  // SYSTEM LOGS
1008
1161
  app.get('/system/logs', auth_1.requireAuth, async (req, res) => {
1009
1162
  const id = req.query.id || Array.from(runtimes.keys())[0];
@@ -1042,16 +1195,15 @@ function createApp(runtimes = new Map()) {
1042
1195
  });
1043
1196
  const isDevMode = process.env.NODE_ENV !== 'production' || process.env.SIDURI_DEV_MODE === 'true';
1044
1197
  if (isDevMode) {
1045
- app.post('/dev/memory/reset', auth_1.requireAuth, async (req, res) => {
1198
+ app.post(['/dev/memory/reset', '/dev/directives/reset', '/dev/archive/reset'], auth_1.requireAuth, async (req, res) => {
1046
1199
  const id = req.body.companionId || Array.from(runtimes.keys())[0];
1047
1200
  const runtime = runtimes.get(id);
1048
1201
  if (!runtime)
1049
1202
  return res.status(404).json({ error: "Companion not found" });
1050
- if (!runtime.memory || typeof runtime.memory.resetMemory !== 'function') {
1051
- return res.status(400).json({ error: "Memory organ does not support reset" });
1052
- }
1053
1203
  try {
1054
- await runtime.memory.resetMemory();
1204
+ if (runtime.db && typeof runtime.db.resetArchive === 'function') {
1205
+ runtime.db.resetArchive();
1206
+ }
1055
1207
  res.json({ reset: true });
1056
1208
  }
1057
1209
  catch (e) {
@@ -61,11 +61,11 @@ describe('T0 B0 & B6 Runtime Proof Suite', () => {
61
61
  });
62
62
  // B0: Fresh companion is empty (no prior claims, no user relationship, no knowledge search on greeting)
63
63
  describe('B0 — Fresh companion is empty', () => {
64
- test('initial state has empty memory and empty directives', async () => {
65
- const claims = await runtime.memory?.getClaims();
66
- const directives = await runtime.memory?.getDirectives();
67
- expect(claims).toEqual([]);
64
+ test('initial state has empty directives and empty archive events', async () => {
65
+ const directives = runtime.self?.getAllDirectives ? await runtime.self.getAllDirectives() : [];
68
66
  expect(directives).toEqual([]);
67
+ const events = runtime.archive ? await runtime.archive.getRecentEvents('companion-a') : [];
68
+ expect(events).toEqual([]);
69
69
  });
70
70
  test('greeting does not query knowledge or inject prior personal knowledge', async () => {
71
71
  const res = await (0, supertest_1.default)(app)
package/dist/boot.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { OpenAICompatibleBrain } from '@sidurijs/brain';
2
- import { SqliteMemoryStore } from '@sidurijs/memory';
2
+ import { SqliteArchiveLedger } from '@sidurijs/archive';
3
3
  import { VoiceAdapter, VoiceConfig } from '@sidurijs/voice';
4
4
  import { UnifiedKnowledgeOrgan, UnifiedKnowledgeConfig } from '@sidurijs/knowledge';
5
5
  import { OpenRouterVisionAdapter, OpenRouterVisionConfig } from '@sidurijs/vision';
@@ -36,6 +36,11 @@ export interface AppBootCompanionConfig {
36
36
  dbPath?: string;
37
37
  [key: string]: unknown;
38
38
  };
39
+ archive?: {
40
+ provider?: string;
41
+ dbPath?: string;
42
+ [key: string]: unknown;
43
+ };
39
44
  knowledge?: UnifiedKnowledgeConfig;
40
45
  vision?: OpenRouterVisionConfig;
41
46
  behavior?: AppBehaviorConfig;
@@ -73,12 +78,16 @@ export declare function createEar(config?: EarOrganConfig & {
73
78
  export declare function createMouth(config?: DefaultMouthOrganConfig & {
74
79
  provider?: string;
75
80
  }, voice?: any): DefaultMouthOrgan;
81
+ export declare function createArchive(config?: {
82
+ provider?: string;
83
+ dbPath?: string;
84
+ }): SqliteArchiveLedger | undefined;
76
85
  export declare function createMemory(config?: {
77
86
  provider?: string;
78
87
  connectionString?: string;
79
88
  maxConnections?: number;
80
89
  dbPath?: string;
81
- }): SqliteMemoryStore | undefined;
90
+ }): SqliteArchiveLedger | undefined;
82
91
  export declare function createSelf(config?: {
83
92
  dbPath?: string;
84
93
  provider?: string;
package/dist/boot.js CHANGED
@@ -10,12 +10,13 @@ exports.createBody = createBody;
10
10
  exports.createHands = createHands;
11
11
  exports.createEar = createEar;
12
12
  exports.createMouth = createMouth;
13
+ exports.createArchive = createArchive;
13
14
  exports.createMemory = createMemory;
14
15
  exports.createSelf = createSelf;
15
16
  exports.createObservation = createObservation;
16
17
  exports.bootCompanion = bootCompanion;
17
18
  const brain_1 = require("@sidurijs/brain");
18
- const memory_1 = require("@sidurijs/memory");
19
+ const archive_1 = require("@sidurijs/archive");
19
20
  const voice_1 = require("@sidurijs/voice");
20
21
  const knowledge_1 = require("@sidurijs/knowledge");
21
22
  const vision_1 = require("@sidurijs/vision");
@@ -98,11 +99,14 @@ function createMouth(config, voice) {
98
99
  ? new mouth_1.DefaultMouthOrgan({ voice })
99
100
  : new mouth_1.DefaultMouthOrgan({ ...config, voice });
100
101
  }
101
- function createMemory(config) {
102
+ function createArchive(config) {
102
103
  if (isDisabled(config))
103
104
  return undefined;
104
105
  const defaultPath = process.env.NODE_ENV === 'test' ? ':memory:' : 'siduri.sqlite';
105
- return new memory_1.SqliteMemoryStore({ dbPath: config?.dbPath || process.env.STORAGE_PATH || process.env.SQLITE_DB_PATH || defaultPath });
106
+ return new archive_1.SqliteArchiveLedger({ dbPath: config?.dbPath || process.env.STORAGE_PATH || process.env.SQLITE_DB_PATH || defaultPath });
107
+ }
108
+ function createMemory(config) {
109
+ return createArchive(config);
106
110
  }
107
111
  function createSelf(config) {
108
112
  if (isDisabled(config))
@@ -120,7 +124,7 @@ function createObservation(vision) {
120
124
  async function bootCompanion(id, config, options) {
121
125
  const organs = config?.organs || {};
122
126
  const brain = createBrain(organs.brain || config?.brain);
123
- const memory = createMemory(organs.memory || config?.memory);
127
+ const archive = createArchive(organs.archive || organs.memory || config?.archive || config?.memory);
124
128
  const selfRepo = createSelf(organs.self || config?.self);
125
129
  const voice = createVoice(organs.voice || config?.voice);
126
130
  const knowledge = createKnowledge(organs.knowledge || config?.knowledge);
@@ -131,12 +135,9 @@ async function bootCompanion(id, config, options) {
131
135
  const ear = createEar(organs.ear || config?.ear);
132
136
  const mouth = createMouth(organs.mouth || config?.mouth, voice);
133
137
  const observation = options?.observationOrgan;
134
- if (memory && typeof memory.runMigrations === 'function') {
135
- await memory.runMigrations().catch((e) => console.warn("Migrations warning:", e.message));
136
- }
137
138
  const runtime = new runtime_1.SiduriRuntime(id, config, {
138
139
  brain,
139
- memory,
140
+ archive,
140
141
  voice,
141
142
  knowledge,
142
143
  vision,
@@ -70,7 +70,7 @@ function mapRequestContext(input, options = {}) {
70
70
  ? Boolean(input.authenticated)
71
71
  : (actor.authenticated !== undefined ? Boolean(actor.authenticated) : true);
72
72
  const isViewer = !isAuthenticated || isViewerRequested;
73
- const CANONICAL_CAPABILITIES = new Set(['chat', 'memory:approve', 'action:execute', 'system']);
73
+ const CANONICAL_CAPABILITIES = new Set(['chat', 'memory:approve', 'directive:approve', 'self:approve', 'action:execute', 'system']);
74
74
  const DEFAULT_OWNER_CAPABILITIES = ['chat', 'memory:approve', 'action:execute', 'system'];
75
75
  let safeCapabilities;
76
76
  let authorizationRole;
@@ -172,7 +172,7 @@ function mapRequestContext(input, options = {}) {
172
172
  if (!input.actorId && !input.actor?.actorId) {
173
173
  diagnostics.push('anonymous_session_generated');
174
174
  }
175
- const CANONICAL_CAPABILITIES = new Set(['chat', 'memory:approve', 'action:execute', 'system']);
175
+ const CANONICAL_CAPABILITIES = new Set(['chat', 'memory:approve', 'directive:approve', 'self:approve', 'action:execute', 'system']);
176
176
  const DEFAULT_OWNER_CAPABILITIES = ['chat', 'memory:approve', 'action:execute', 'system'];
177
177
  const rawCaps = Array.isArray(input.capabilities)
178
178
  ? input.capabilities
package/dist/index.js CHANGED
@@ -37,6 +37,7 @@ const defaultCompanionConfig = {
37
37
  name: 'Siduri',
38
38
  brain: { provider: 'openrouter', model: 'gpt-4o-mini' },
39
39
  voice: { provider: 'voicevox', speakerId: 1 },
40
+ archive: { provider: 'sqlite' },
40
41
  memory: { provider: 'sqlite' },
41
42
  knowledge: {
42
43
  provider: process.env.SIDURI_KNOWLEDGE_PROVIDER || 'unified',
@@ -72,6 +73,7 @@ async function loadCompanionConfig() {
72
73
  id: fileConfig.id || defaultCompanionConfig.id,
73
74
  brain: { ...defaultCompanionConfig.brain, ...fileConfig.brain },
74
75
  voice: { ...defaultCompanionConfig.voice, ...fileConfig.voice },
76
+ archive: { ...defaultCompanionConfig.archive, ...fileConfig.archive, ...fileConfig.memory },
75
77
  memory: { ...defaultCompanionConfig.memory, ...fileConfig.memory },
76
78
  knowledge: { ...defaultCompanionConfig.knowledge, ...fileConfig.knowledge },
77
79
  behavior: { ...defaultCompanionConfig.behavior, ...fileConfig.behavior },
@@ -40,15 +40,28 @@ describe('Life Database & UnifiedKnowledgeOrgan API Integration', () => {
40
40
  };
41
41
  }),
42
42
  };
43
+ const claimsStore = [];
43
44
  const memory = {
44
45
  initialize: async () => { },
45
- proposeClaim: async (claim) => knowledge.lifeDb.db.proposeClaim(claim),
46
- getClaims: async (limit) => knowledge.lifeDb.db.getAllClaims(undefined, limit || 500),
47
- getPendingClaims: async (limit) => knowledge.lifeDb.db.getAllClaims(undefined, limit || 500).filter((c) => c.status === 'pending'),
48
- approveClaim: async (id) => knowledge.lifeDb.db.approveClaim(id),
49
- rejectClaim: async (id) => knowledge.lifeDb.db.rejectClaim(id),
46
+ proposeClaim: async (claim) => {
47
+ const c = { id: claim.id || `claim-${Date.now()}`, status: 'pending', ...claim };
48
+ claimsStore.push(c);
49
+ return c;
50
+ },
51
+ getClaims: async (limit) => claimsStore.slice(0, limit || 500),
52
+ getPendingClaims: async (limit) => claimsStore.filter((c) => c.status === 'pending').slice(0, limit || 500),
53
+ approveClaim: async (id) => {
54
+ const found = claimsStore.find((c) => c.id === id);
55
+ if (found)
56
+ found.status = 'approved';
57
+ },
58
+ rejectClaim: async (id) => {
59
+ const found = claimsStore.find((c) => c.id === id);
60
+ if (found)
61
+ found.status = 'rejected';
62
+ },
50
63
  searchClaims: async () => [],
51
- getApprovedClaims: async () => [],
64
+ getApprovedClaims: async () => claimsStore.filter((c) => c.status === 'approved'),
52
65
  getDirectives: async () => [],
53
66
  };
54
67
  runtime = new runtime_1.SiduriRuntime('test-comp', { name: 'Test Companion', organs: { knowledge: { provider: 'unified', dbPath: testDbPath } } }, {
@@ -196,7 +209,7 @@ describe('Life Database & UnifiedKnowledgeOrgan API Integration', () => {
196
209
  });
197
210
  test('Truth Gate candidate proposal approval commits Life DB mutations', async () => {
198
211
  // Stage a candidate proposal targeting Life DB
199
- const proposal = await knowledge.lifeDb.db.proposeClaim({
212
+ const proposal = await runtime.container.organs.memory.proposeClaim({
200
213
  id: 'prop-task-gate',
201
214
  companionId: 'test-comp',
202
215
  subject: 'task:buy-filter',
@@ -20,7 +20,7 @@ describe('Siduri Runtime Orchestration', () => {
20
20
  return {
21
21
  speech: "Hello",
22
22
  language: "en",
23
- memoryProposals: [
23
+ claimProposals: [
24
24
  { subject: "Test", predicate: "is", value: "working" }
25
25
  ]
26
26
  };
@@ -70,7 +70,7 @@ describe('Siduri Runtime Orchestration', () => {
70
70
  expect(proposedClaims.length).toBe(1);
71
71
  expect(proposedClaims[0].subject).toBe("Test");
72
72
  expect(proposedClaims[0].scope).toBe("user");
73
- expect(response.metadata.memory_proposals[0].proposal_id).toBe("claim-1");
73
+ expect(response.metadata.claim_proposals[0].proposal_id).toBe("claim-1");
74
74
  });
75
75
  test('Primary Invariant: Brain proposes an action, ActionPolicyEngine authorizes, Hands executes', async () => {
76
76
  let toolExecuted = false;