@sidurijs/core 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/LICENSE +190 -0
- package/dist/adversarial.test.js +27 -19
- package/dist/chat-contract.d.ts +9 -0
- package/dist/cognition-planner.d.ts +2 -2
- package/dist/container.d.ts +6 -4
- package/dist/container.js +1 -4
- package/dist/context-retriever.d.ts +5 -4
- package/dist/context-retriever.js +43 -25
- package/dist/conversational-teach.test.js +61 -53
- package/dist/evidence.d.ts +3 -3
- package/dist/gating.d.ts +2 -2
- package/dist/gating.js +1 -1
- package/dist/index.d.ts +43 -51
- package/dist/index.js +1 -1
- package/dist/intent-classifier.d.ts +1 -1
- package/dist/intent-classifier.js +4 -4
- package/dist/intent-classifier.test.js +1 -1
- package/dist/{memory-settler.d.ts → interaction-settler.d.ts} +12 -11
- package/dist/interaction-settler.js +173 -0
- package/dist/perception-cycle.test.js +18 -34
- package/dist/perception-pipeline.d.ts +6 -5
- package/dist/perception-pipeline.js +17 -15
- package/dist/prompt-compiler.d.ts +1 -1
- package/dist/prompt-compiler.js +11 -11
- package/dist/prompt-compiler.test.js +5 -5
- package/dist/proposals.d.ts +1 -2
- package/dist/response-envelope.d.ts +3 -3
- package/dist/response-envelope.js +5 -4
- package/dist/runtime-facades.test.js +12 -35
- package/dist/runtime.d.ts +16 -10
- package/dist/runtime.js +85 -107
- package/dist/schema-validator.test.js +3 -3
- package/dist/session-history.d.ts +3 -3
- package/dist/session-history.js +1 -1
- package/dist/siduri-db.d.ts +11 -29
- package/dist/siduri-db.js +159 -445
- package/dist/siduri-db.test.js +113 -281
- package/dist/teaching.d.ts +3 -3
- package/dist/teaching.js +1 -1
- package/package.json +7 -7
- package/dist/memory-settler.js +0 -161
|
@@ -81,18 +81,31 @@ describe('Conversational Teach Mode End-to-End Lifecycle', () => {
|
|
|
81
81
|
};
|
|
82
82
|
}
|
|
83
83
|
/**
|
|
84
|
-
* Helper to build a MemoryOrgan wrapping a SiduriDatabase
|
|
84
|
+
* Helper to build a MemoryOrgan wrapping a SiduriDatabase & local claim mock
|
|
85
85
|
*/
|
|
86
86
|
function createMemoryOrgan(db) {
|
|
87
|
+
const claims = [];
|
|
87
88
|
return {
|
|
88
89
|
initialize: async () => { },
|
|
89
|
-
proposeClaim: async (claim) =>
|
|
90
|
+
proposeClaim: async (claim) => {
|
|
91
|
+
const c = { id: claim.id || `claim-${Date.now()}-${Math.random().toString(36).slice(2, 6)}`, status: 'pending', ...claim };
|
|
92
|
+
claims.push(c);
|
|
93
|
+
return c;
|
|
94
|
+
},
|
|
90
95
|
searchClaims: async () => [],
|
|
91
|
-
getApprovedClaims: async (companionId, limit) =>
|
|
92
|
-
getClaims: async (limit) =>
|
|
93
|
-
getPendingClaims: async (limit) =>
|
|
94
|
-
approveClaim: async (id) =>
|
|
95
|
-
|
|
96
|
+
getApprovedClaims: async (companionId, limit) => claims.filter((c) => c.status === 'approved').slice(0, limit || 50),
|
|
97
|
+
getClaims: async (limit) => claims.slice(0, limit || 500),
|
|
98
|
+
getPendingClaims: async (limit) => claims.filter((c) => c.status === 'pending').slice(0, limit || 500),
|
|
99
|
+
approveClaim: async (id) => {
|
|
100
|
+
const found = claims.find((c) => c.id === id);
|
|
101
|
+
if (found)
|
|
102
|
+
found.status = 'approved';
|
|
103
|
+
},
|
|
104
|
+
rejectClaim: async (id) => {
|
|
105
|
+
const found = claims.find((c) => c.id === id);
|
|
106
|
+
if (found)
|
|
107
|
+
found.status = 'rejected';
|
|
108
|
+
},
|
|
96
109
|
getDirectives: async (companionId) => db.getActiveDirectives(companionId || 'default'),
|
|
97
110
|
proposeDirective: async (dir) => {
|
|
98
111
|
const id = `dir-${Date.now()}-${Math.random().toString(36).slice(2, 6)}`;
|
|
@@ -159,10 +172,10 @@ describe('Conversational Teach Mode End-to-End Lifecycle', () => {
|
|
|
159
172
|
return {
|
|
160
173
|
generatePlan: jest.fn().mockImplementation(async (brainCtx) => {
|
|
161
174
|
const lastMsg = brainCtx.recentMessages?.[brainCtx.recentMessages.length - 1]?.content || '';
|
|
162
|
-
const
|
|
175
|
+
const claimProposals = [];
|
|
163
176
|
const behaviorProposals = [];
|
|
164
177
|
if (/AI researcher at VXNUS Studio/i.test(lastMsg)) {
|
|
165
|
-
|
|
178
|
+
claimProposals.push({
|
|
166
179
|
subject: `companion:${companionId}`,
|
|
167
180
|
predicate: 'role',
|
|
168
181
|
value: 'AI researcher at VXNUS Studio',
|
|
@@ -176,35 +189,35 @@ describe('Conversational Teach Mode End-to-End Lifecycle', () => {
|
|
|
176
189
|
});
|
|
177
190
|
}
|
|
178
191
|
else if (/Lead Architect at VXNUS Studio/i.test(lastMsg)) {
|
|
179
|
-
|
|
192
|
+
claimProposals.push({
|
|
180
193
|
subject: `companion:${companionId}`,
|
|
181
194
|
predicate: 'role',
|
|
182
195
|
value: 'Lead Architect at VXNUS Studio',
|
|
183
196
|
});
|
|
184
197
|
}
|
|
185
198
|
else if (/Research Specialist/i.test(lastMsg)) {
|
|
186
|
-
|
|
199
|
+
claimProposals.push({
|
|
187
200
|
subject: `companion:${companionId}`,
|
|
188
201
|
predicate: 'role',
|
|
189
202
|
value: 'Research Specialist',
|
|
190
203
|
});
|
|
191
204
|
}
|
|
192
205
|
else if (/Security Officer/i.test(lastMsg)) {
|
|
193
|
-
|
|
206
|
+
claimProposals.push({
|
|
194
207
|
subject: `companion:${companionId}`,
|
|
195
208
|
predicate: 'role',
|
|
196
209
|
value: 'Security Officer',
|
|
197
210
|
});
|
|
198
211
|
}
|
|
199
212
|
else if (/VXNUS Studio Staff/i.test(lastMsg)) {
|
|
200
|
-
|
|
213
|
+
claimProposals.push({
|
|
201
214
|
subject: `companion:${companionId}`,
|
|
202
215
|
predicate: 'role',
|
|
203
216
|
value: 'VXNUS Studio Staff',
|
|
204
217
|
});
|
|
205
218
|
}
|
|
206
219
|
if (/\bcreator\b/i.test(lastMsg)) {
|
|
207
|
-
|
|
220
|
+
claimProposals.push({
|
|
208
221
|
subject: 'actor:kur-zagin',
|
|
209
222
|
predicate: 'stated_relationship',
|
|
210
223
|
value: 'creator',
|
|
@@ -219,7 +232,7 @@ describe('Conversational Teach Mode End-to-End Lifecycle', () => {
|
|
|
219
232
|
});
|
|
220
233
|
}
|
|
221
234
|
if (/Kur Zagin/i.test(lastMsg)) {
|
|
222
|
-
|
|
235
|
+
claimProposals.push({
|
|
223
236
|
subject: 'actor:kur-zagin',
|
|
224
237
|
predicate: 'name',
|
|
225
238
|
value: 'Kur Zagin',
|
|
@@ -239,7 +252,7 @@ describe('Conversational Teach Mode End-to-End Lifecycle', () => {
|
|
|
239
252
|
category: 'behavioral',
|
|
240
253
|
priority: 60,
|
|
241
254
|
});
|
|
242
|
-
|
|
255
|
+
claimProposals.push({
|
|
243
256
|
subject: 'actor:kur-zagin',
|
|
244
257
|
predicate: 'rule',
|
|
245
258
|
value: 'Be concise when answering technical questions',
|
|
@@ -248,7 +261,7 @@ describe('Conversational Teach Mode End-to-End Lifecycle', () => {
|
|
|
248
261
|
return {
|
|
249
262
|
speech: 'Understood, I have acknowledged your input.',
|
|
250
263
|
language: 'en',
|
|
251
|
-
|
|
264
|
+
claimProposals: claimProposals.length > 0 ? claimProposals : undefined,
|
|
252
265
|
behaviorProposals: behaviorProposals.length > 0 ? behaviorProposals : undefined,
|
|
253
266
|
_receivedSystemPrompt: brainCtx.systemPrompt,
|
|
254
267
|
};
|
|
@@ -376,7 +389,6 @@ describe('Conversational Teach Mode End-to-End Lifecycle', () => {
|
|
|
376
389
|
const mockBrain = createCognitiveMockBrain(companionId);
|
|
377
390
|
const runtime = new index_1.SiduriRuntime(companionId, { name: 'Siduri' }, {
|
|
378
391
|
brain: mockBrain,
|
|
379
|
-
memory,
|
|
380
392
|
self,
|
|
381
393
|
behavior,
|
|
382
394
|
});
|
|
@@ -387,14 +399,14 @@ describe('Conversational Teach Mode End-to-End Lifecycle', () => {
|
|
|
387
399
|
text: 'Remember this rule: be concise when answering technical questions.',
|
|
388
400
|
context: createRequestContext(companionId, 'teach'),
|
|
389
401
|
});
|
|
390
|
-
// Check behavioral proposals or
|
|
402
|
+
// Check behavioral proposals or claim proposals
|
|
391
403
|
const behavioralReceipts = perceptionResult.metadata?.behavioral_proposals || [];
|
|
392
|
-
const
|
|
404
|
+
const claimProposals = perceptionResult.metadata?.proposals || [];
|
|
393
405
|
const hasDirectiveProposal = behavioralReceipts.length > 0 ||
|
|
394
|
-
|
|
406
|
+
claimProposals.some((p) => p.predicate === 'rule' || p.predicate === 'behavioral_rule');
|
|
395
407
|
expect(hasDirectiveProposal).toBe(true);
|
|
396
408
|
const directiveId = behavioralReceipts[0]?.directive_id;
|
|
397
|
-
const proposalId =
|
|
409
|
+
const proposalId = claimProposals[0]?.id;
|
|
398
410
|
// 2. Active directives before approval must not include the new rule
|
|
399
411
|
const directivesBefore = await self.getActiveDirectives(companionId);
|
|
400
412
|
expect(directivesBefore.some((d) => d.directive.toLowerCase().includes('be concise when answering technical questions'))).toBe(false);
|
|
@@ -426,7 +438,6 @@ describe('Conversational Teach Mode End-to-End Lifecycle', () => {
|
|
|
426
438
|
};
|
|
427
439
|
const runtime = new index_1.SiduriRuntime(companionId, { name: 'Siduri' }, {
|
|
428
440
|
brain: mockBrain,
|
|
429
|
-
memory,
|
|
430
441
|
self,
|
|
431
442
|
});
|
|
432
443
|
await runtime.initialize();
|
|
@@ -439,7 +450,7 @@ describe('Conversational Teach Mode End-to-End Lifecycle', () => {
|
|
|
439
450
|
expect(perceptionResult.status).toBe('APPROVED');
|
|
440
451
|
// Zero proposals allowed in casual mode
|
|
441
452
|
expect(perceptionResult.metadata?.proposals).toEqual([]);
|
|
442
|
-
expect(perceptionResult.metadata?.
|
|
453
|
+
expect(perceptionResult.metadata?.claim_proposals).toEqual([]);
|
|
443
454
|
// Self must remain unchanged
|
|
444
455
|
const identity = await self.getIdentity(companionId);
|
|
445
456
|
expect(identity?.role).toBeUndefined();
|
|
@@ -459,7 +470,6 @@ describe('Conversational Teach Mode End-to-End Lifecycle', () => {
|
|
|
459
470
|
const mockBrain = createCognitiveMockBrain(companionId);
|
|
460
471
|
const runtime = new index_1.SiduriRuntime(companionId, { name: 'Siduri' }, {
|
|
461
472
|
brain: mockBrain,
|
|
462
|
-
memory,
|
|
463
473
|
self,
|
|
464
474
|
});
|
|
465
475
|
await runtime.initialize();
|
|
@@ -656,10 +666,10 @@ describe('Conversational Teach Mode End-to-End Lifecycle', () => {
|
|
|
656
666
|
const mockBrain = {
|
|
657
667
|
generatePlan: jest.fn().mockImplementation(async (brainCtx) => {
|
|
658
668
|
const lastMsg = brainCtx.recentMessages?.[brainCtx.recentMessages.length - 1]?.content || '';
|
|
659
|
-
const
|
|
669
|
+
const claimProposals = [];
|
|
660
670
|
const behaviorProposals = [];
|
|
661
671
|
if (/your name is Siduri/i.test(lastMsg)) {
|
|
662
|
-
|
|
672
|
+
claimProposals.push({
|
|
663
673
|
subject: 'companion:self',
|
|
664
674
|
predicate: 'name',
|
|
665
675
|
value: 'Siduri',
|
|
@@ -673,12 +683,12 @@ describe('Conversational Teach Mode End-to-End Lifecycle', () => {
|
|
|
673
683
|
});
|
|
674
684
|
}
|
|
675
685
|
if (/i am Kur Zagin, your creator/i.test(lastMsg)) {
|
|
676
|
-
|
|
686
|
+
claimProposals.push({
|
|
677
687
|
subject: 'actor:kur_zagin',
|
|
678
688
|
predicate: 'name',
|
|
679
689
|
value: 'Kur Zagin',
|
|
680
690
|
});
|
|
681
|
-
|
|
691
|
+
claimProposals.push({
|
|
682
692
|
subject: 'actor:kur_zagin',
|
|
683
693
|
predicate: 'stated_relationship',
|
|
684
694
|
value: 'creator of companion Siduri',
|
|
@@ -701,7 +711,7 @@ describe('Conversational Teach Mode End-to-End Lifecycle', () => {
|
|
|
701
711
|
return {
|
|
702
712
|
speech: 'I understand and acknowledge.',
|
|
703
713
|
language: 'en',
|
|
704
|
-
|
|
714
|
+
claimProposals: claimProposals.length > 0 ? claimProposals : undefined,
|
|
705
715
|
behaviorProposals: behaviorProposals.length > 0 ? behaviorProposals : undefined,
|
|
706
716
|
_receivedSystemPrompt: brainCtx.systemPrompt,
|
|
707
717
|
};
|
|
@@ -809,7 +819,7 @@ describe('Conversational Teach Mode End-to-End Lifecycle', () => {
|
|
|
809
819
|
context: createRequestContext(companionId, 'hybrid', 'owner-user'),
|
|
810
820
|
});
|
|
811
821
|
const whoAmICtx = calls[calls.length - 1][0];
|
|
812
|
-
expect(whoAmICtx.contextPrompt).toContain('
|
|
822
|
+
expect(whoAmICtx.contextPrompt).toContain('ARCHIVE:');
|
|
813
823
|
expect(whoAmICtx.contextPrompt).toContain('Kur Zagin');
|
|
814
824
|
db.close();
|
|
815
825
|
});
|
|
@@ -841,48 +851,47 @@ describe('Conversational Teach Mode End-to-End Lifecycle', () => {
|
|
|
841
851
|
initialMode: 'teach',
|
|
842
852
|
}, {
|
|
843
853
|
self,
|
|
844
|
-
memory,
|
|
845
854
|
knowledge: mockKnowledge,
|
|
846
855
|
});
|
|
847
|
-
// 1. Propose knowledge claims
|
|
848
|
-
const entityClaim =
|
|
856
|
+
// 1. Propose knowledge claims (quarantined as PENDING)
|
|
857
|
+
const entityClaim = {
|
|
858
|
+
id: 'claim-ent-1',
|
|
849
859
|
companionId,
|
|
850
860
|
subject: 'entity:Workstation Rig',
|
|
851
861
|
predicate: 'inventory',
|
|
852
862
|
value: 'Threadripper 64-core',
|
|
853
863
|
claimType: 'life_entity',
|
|
854
864
|
evidence: { domain: 'hardware', properties: { cores: 64, ram: '256GB' } },
|
|
855
|
-
}
|
|
856
|
-
const eventClaim =
|
|
865
|
+
};
|
|
866
|
+
const eventClaim = {
|
|
867
|
+
id: 'claim-evt-1',
|
|
857
868
|
companionId,
|
|
858
869
|
subject: 'finance:expense',
|
|
859
870
|
predicate: 'expense',
|
|
860
871
|
value: '45.00',
|
|
861
872
|
claimType: 'life_event',
|
|
862
873
|
evidence: { metricValue: -45.0, stream: 'finance', category: 'dining' },
|
|
863
|
-
}
|
|
864
|
-
const taskClaim =
|
|
874
|
+
};
|
|
875
|
+
const taskClaim = {
|
|
876
|
+
id: 'claim-task-1',
|
|
865
877
|
companionId,
|
|
866
878
|
subject: 'task:Review PR',
|
|
867
879
|
predicate: 'todo',
|
|
868
880
|
value: 'Review PR #42 for Life DB',
|
|
869
881
|
claimType: 'life_task',
|
|
870
882
|
evidence: { status: 'in_progress' },
|
|
871
|
-
}
|
|
883
|
+
};
|
|
872
884
|
// Before approval, Life DB tables in sqlite are empty
|
|
873
885
|
expect(db.getEntities(companionId)).toHaveLength(0);
|
|
874
886
|
expect(db.getEvents(companionId)).toHaveLength(0);
|
|
875
887
|
expect(db.getTasks(companionId)).toHaveLength(0);
|
|
876
888
|
// 2. Truth Gate Approval
|
|
877
|
-
const resEntity = await
|
|
878
|
-
expect(resEntity
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
expect(
|
|
883
|
-
const resTask = await runtime.approveProposal(taskClaim.id, { companionId });
|
|
884
|
-
expect(resTask.success).toBe(true);
|
|
885
|
-
expect(resTask.target).toBe('knowledge');
|
|
889
|
+
const resEntity = await (0, index_1.promoteApprovedClaimToKnowledge)(entityClaim, mockKnowledge, companionId);
|
|
890
|
+
expect(resEntity).toBe(true);
|
|
891
|
+
const resEvent = await (0, index_1.promoteApprovedClaimToKnowledge)(eventClaim, mockKnowledge, companionId);
|
|
892
|
+
expect(resEvent).toBe(true);
|
|
893
|
+
const resTask = await (0, index_1.promoteApprovedClaimToKnowledge)(taskClaim, mockKnowledge, companionId);
|
|
894
|
+
expect(resTask).toBe(true);
|
|
886
895
|
// 3. Verify persistent commit to sovereign Life DB in SQLite
|
|
887
896
|
const entities = db.getEntities(companionId);
|
|
888
897
|
expect(entities).toHaveLength(1);
|
|
@@ -901,10 +910,8 @@ describe('Conversational Teach Mode End-to-End Lifecycle', () => {
|
|
|
901
910
|
it('updates companion identity name dynamically when companion naming claim or directive is approved', async () => {
|
|
902
911
|
const companionId = 'dynamic-companion';
|
|
903
912
|
const db = new index_1.SiduriDatabase({ dbPath: ':memory:' });
|
|
904
|
-
const memory = createMemoryOrgan(db);
|
|
905
913
|
const self = createSelfRepository(db);
|
|
906
914
|
const runtime = new index_1.SiduriRuntime(companionId, { name: 'Siduri' }, {
|
|
907
|
-
memory,
|
|
908
915
|
self,
|
|
909
916
|
});
|
|
910
917
|
await runtime.initialize();
|
|
@@ -912,14 +919,15 @@ describe('Conversational Teach Mode End-to-End Lifecycle', () => {
|
|
|
912
919
|
const initialIdentity = await self.getIdentity(companionId);
|
|
913
920
|
expect(initialIdentity?.name || 'Siduri').toBe('Siduri');
|
|
914
921
|
// 1. Propose and approve claim with subject "assistant" and predicate "name"
|
|
915
|
-
const nameClaim =
|
|
922
|
+
const nameClaim = {
|
|
923
|
+
id: 'claim-name-1',
|
|
916
924
|
companionId,
|
|
917
925
|
subject: 'assistant',
|
|
918
926
|
predicate: 'name',
|
|
919
927
|
value: 'Athena',
|
|
920
928
|
claimType: 'semantic',
|
|
921
|
-
}
|
|
922
|
-
await
|
|
929
|
+
};
|
|
930
|
+
await (0, index_1.promoteApprovedClaimToSelf)(nameClaim, self, companionId);
|
|
923
931
|
const identityAfterClaim = await self.getIdentity(companionId);
|
|
924
932
|
expect(identityAfterClaim?.name).toBe('Athena');
|
|
925
933
|
// 2. Propose and approve behavioral directive "Address companion as Athena Prime"
|
package/dist/evidence.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export type EvidenceOrigin = 'knowledge' | '
|
|
1
|
+
import { ClaimProposal, BehaviorProposal } from './proposals';
|
|
2
|
+
export type EvidenceOrigin = 'knowledge' | 'archive' | 'life' | 'observation' | 'ocr' | 'platform' | 'conversation';
|
|
3
3
|
export type EvidenceTrust = 'configured' | 'provider' | 'untrusted';
|
|
4
4
|
export type EvidenceSensitivity = 'public' | 'private' | 'restricted';
|
|
5
5
|
export interface EvidenceRecord {
|
|
@@ -47,7 +47,7 @@ export interface StagedResponsePlan {
|
|
|
47
47
|
status: ResponseApprovalStatus;
|
|
48
48
|
createdAt: string;
|
|
49
49
|
expiresAt?: string;
|
|
50
|
-
|
|
50
|
+
claimProposals?: ClaimProposal[];
|
|
51
51
|
behaviorProposals?: BehaviorProposal[];
|
|
52
52
|
internalMonologue?: string;
|
|
53
53
|
[key: string]: unknown;
|
package/dist/gating.d.ts
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { RequestContext } from './context';
|
|
2
|
-
import {
|
|
2
|
+
import { ClaimProposal, BehaviorProposal } from './proposals';
|
|
3
3
|
import { EvidenceRecord, StagedResponsePlan, ResponseGateEvaluation, ResponseCitation } from './evidence';
|
|
4
4
|
export interface StageResponseOptions {
|
|
5
5
|
requestContext: RequestContext;
|
|
6
6
|
candidateSpeech: string;
|
|
7
7
|
candidateLanguage: string;
|
|
8
8
|
internalMonologue?: string;
|
|
9
|
-
|
|
9
|
+
claimProposals?: ClaimProposal[];
|
|
10
10
|
behaviorProposals?: BehaviorProposal[];
|
|
11
11
|
evidenceRecords?: EvidenceRecord[];
|
|
12
12
|
citations?: ResponseCitation[];
|
package/dist/gating.js
CHANGED
|
@@ -50,7 +50,7 @@ class ResponseGatingEngine {
|
|
|
50
50
|
status: 'STAGED',
|
|
51
51
|
createdAt: new Date(nowTime).toISOString(),
|
|
52
52
|
expiresAt,
|
|
53
|
-
|
|
53
|
+
claimProposals: options.claimProposals,
|
|
54
54
|
behaviorProposals: options.behaviorProposals,
|
|
55
55
|
internalMonologue: options.internalMonologue,
|
|
56
56
|
};
|
package/dist/index.d.ts
CHANGED
|
@@ -17,7 +17,7 @@ export * from './intent-classifier';
|
|
|
17
17
|
export * from './context-retriever';
|
|
18
18
|
export * from './prompt-compiler';
|
|
19
19
|
export * from './cognition-planner';
|
|
20
|
-
export * from './
|
|
20
|
+
export * from './interaction-settler';
|
|
21
21
|
export * from './action-executor';
|
|
22
22
|
export * from './experience-emitter';
|
|
23
23
|
export * from './response-envelope';
|
|
@@ -31,7 +31,7 @@ import { EvidenceRecord } from './evidence';
|
|
|
31
31
|
import { ActionIntent } from './action';
|
|
32
32
|
import { RequestContext } from './context';
|
|
33
33
|
import { EarIngestOptions } from './ear-types';
|
|
34
|
-
import { ClaimType, ClaimAuthority, ClaimStatus, DirectiveStatus, SourceEvent,
|
|
34
|
+
import { ClaimType, ClaimAuthority, ClaimStatus, DirectiveStatus, SourceEvent, ClaimProposal, BehaviorProposal } from './proposals';
|
|
35
35
|
export interface OrganConfig {
|
|
36
36
|
provider: string;
|
|
37
37
|
[key: string]: unknown;
|
|
@@ -41,7 +41,7 @@ export interface CompanionConfig {
|
|
|
41
41
|
name: string;
|
|
42
42
|
brain: OrganConfig;
|
|
43
43
|
voice: OrganConfig;
|
|
44
|
-
|
|
44
|
+
archive: OrganConfig;
|
|
45
45
|
knowledge: OrganConfig;
|
|
46
46
|
behavior: OrganConfig;
|
|
47
47
|
body: OrganConfig;
|
|
@@ -56,14 +56,14 @@ export interface BrainContext {
|
|
|
56
56
|
systemPrompt: string;
|
|
57
57
|
contextPrompt: string;
|
|
58
58
|
recentMessages: Message[];
|
|
59
|
-
recipient?:
|
|
59
|
+
recipient?: ClaimScope;
|
|
60
60
|
}
|
|
61
61
|
export interface ResponsePlan {
|
|
62
62
|
speech: string;
|
|
63
63
|
language: string;
|
|
64
64
|
subtitle?: string;
|
|
65
65
|
subtitles?: Record<string, string>;
|
|
66
|
-
|
|
66
|
+
claimProposals?: ClaimProposal[];
|
|
67
67
|
behaviorProposals?: BehaviorProposal[];
|
|
68
68
|
actionIntents?: ActionIntent[];
|
|
69
69
|
internalMonologue?: string;
|
|
@@ -71,8 +71,8 @@ export interface ResponsePlan {
|
|
|
71
71
|
export interface RetrievalPlan {
|
|
72
72
|
shouldQueryKnowledge: boolean;
|
|
73
73
|
knowledgeQueries: string[];
|
|
74
|
-
|
|
75
|
-
|
|
74
|
+
shouldQueryArchive?: boolean;
|
|
75
|
+
archiveQueries?: string[];
|
|
76
76
|
reasoning?: string;
|
|
77
77
|
}
|
|
78
78
|
export interface PersonaCompilationResult {
|
|
@@ -126,7 +126,7 @@ export interface BrainOrgan {
|
|
|
126
126
|
companionId?: string;
|
|
127
127
|
}): Promise<PersonaCompilationResult>;
|
|
128
128
|
}
|
|
129
|
-
export type
|
|
129
|
+
export type ClaimScope = 'companion' | 'user' | string;
|
|
130
130
|
export interface Claim {
|
|
131
131
|
id: string;
|
|
132
132
|
subject: string;
|
|
@@ -134,7 +134,7 @@ export interface Claim {
|
|
|
134
134
|
value: string;
|
|
135
135
|
status: ClaimStatus;
|
|
136
136
|
evidence?: string[];
|
|
137
|
-
scope?:
|
|
137
|
+
scope?: ClaimScope;
|
|
138
138
|
companionId: string;
|
|
139
139
|
provenance?: string;
|
|
140
140
|
sourceEventId?: string;
|
|
@@ -157,7 +157,6 @@ export interface BehaviorDirective {
|
|
|
157
157
|
priority: number;
|
|
158
158
|
status: DirectiveStatus;
|
|
159
159
|
supersedesId?: string;
|
|
160
|
-
memoryClass?: 'identity' | 'relationship' | 'behavioral';
|
|
161
160
|
subject?: string;
|
|
162
161
|
predicate?: string;
|
|
163
162
|
value?: string;
|
|
@@ -165,39 +164,41 @@ export interface BehaviorDirective {
|
|
|
165
164
|
validUntil?: string;
|
|
166
165
|
[key: string]: unknown;
|
|
167
166
|
}
|
|
168
|
-
export interface
|
|
169
|
-
|
|
167
|
+
export interface ArchiveEvent {
|
|
168
|
+
id: string;
|
|
169
|
+
companionId: string;
|
|
170
|
+
sourceType: string;
|
|
171
|
+
occurredAt: string;
|
|
172
|
+
payload: Record<string, unknown>;
|
|
173
|
+
}
|
|
174
|
+
export interface ArchiveQueryOptions {
|
|
170
175
|
limit?: number;
|
|
171
|
-
|
|
172
|
-
|
|
176
|
+
sourceType?: string;
|
|
177
|
+
since?: string;
|
|
178
|
+
until?: string;
|
|
173
179
|
[key: string]: unknown;
|
|
174
180
|
}
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
supersedeClaim?(id: string, replacement: Omit<Claim, 'id' | 'status' | 'companionId'>): Promise<Claim>;
|
|
197
|
-
updateClaim?(id: string, updates: Partial<Pick<Claim, 'subject' | 'predicate' | 'value' | 'scope' | 'sensitivity' | 'confidence' | 'validFrom' | 'validUntil'>>): Promise<Claim>;
|
|
198
|
-
resetMemory?(): Promise<void>;
|
|
199
|
-
addSourceEvent?(event: SourceEvent): Promise<SourceEvent>;
|
|
200
|
-
getSourceEvent?(id: string): Promise<SourceEvent | undefined>;
|
|
181
|
+
/**
|
|
182
|
+
* Sovereign interaction archive: cold, append-only interaction audit ledger and full-text search.
|
|
183
|
+
* Replaces the overloaded 'Memory' metaphor for audit trails, past tool runs, and historical interaction logs.
|
|
184
|
+
*/
|
|
185
|
+
export interface ArchiveLedger {
|
|
186
|
+
recordEvent(event: ArchiveEvent | SourceEvent): Promise<ArchiveEvent | SourceEvent>;
|
|
187
|
+
getRecentEvents(companionId: string, limit?: number): Promise<ArchiveEvent[]>;
|
|
188
|
+
getEvent?(id: string): Promise<ArchiveEvent | undefined>;
|
|
189
|
+
searchEvents?(companionId: string, query: string, limit?: number): Promise<ArchiveEvent[]>;
|
|
190
|
+
close?(): void;
|
|
191
|
+
}
|
|
192
|
+
export type ArchiveStore = ArchiveLedger;
|
|
193
|
+
export type EpisodicLedger = ArchiveLedger;
|
|
194
|
+
/**
|
|
195
|
+
* Active dialogue continuity interface for working conversational context.
|
|
196
|
+
*/
|
|
197
|
+
export interface DialogueHistory {
|
|
198
|
+
getHistory(sessionKey?: string): Message[];
|
|
199
|
+
setHistory(sessionKey: string, history: Message[]): void;
|
|
200
|
+
append(sessionKey: string, message: Message): void;
|
|
201
|
+
clear(sessionKey?: string): void;
|
|
201
202
|
}
|
|
202
203
|
export interface AudioEvent {
|
|
203
204
|
type: 'STARTED' | 'COMPLETED' | 'FAILED';
|
|
@@ -313,8 +314,8 @@ export interface HealthProbeResult {
|
|
|
313
314
|
}
|
|
314
315
|
export type HealthProbeFn = (context: HealthProbeContext) => Promise<HealthProbeResult> | HealthProbeResult;
|
|
315
316
|
export * from './mouth-types';
|
|
316
|
-
import type { SelfIdentity, PersonalityTraits, SelfDirective, SelfRelationship, SelfDialogueExample, LifeInventoryItem, LifeScheduleItem, LifePreference, LifeEntity, LifeEvent, LifeTask, MemoryClaim, EpisodicEvent } from './siduri-db';
|
|
317
|
-
export type { SelfIdentity, PersonalityTraits, SelfDirective, SelfRelationship, SelfDialogueExample, LifeInventoryItem, LifeScheduleItem, LifePreference, LifeEntity, LifeEvent, LifeTask, MemoryClaim, EpisodicEvent, };
|
|
317
|
+
import type { SelfIdentity, PersonalityTraits, SelfDirective, SelfRelationship, SelfDialogueExample, LifeInventoryItem, LifeScheduleItem, LifePreference, LifeEntity, LifeEvent, LifeTask, ClaimRecord, MemoryClaim, EpisodicEvent } from './siduri-db';
|
|
318
|
+
export type { SelfIdentity, PersonalityTraits, SelfDirective, SelfRelationship, SelfDialogueExample, LifeInventoryItem, LifeScheduleItem, LifePreference, LifeEntity, LifeEvent, LifeTask, ClaimRecord, MemoryClaim, EpisodicEvent, };
|
|
318
319
|
export interface SelfRepository {
|
|
319
320
|
getIdentity(companionId: string): Promise<SelfIdentity | undefined>;
|
|
320
321
|
setIdentity(identity: SelfIdentity): Promise<void>;
|
|
@@ -351,15 +352,6 @@ export interface LifeDatabase {
|
|
|
351
352
|
queryContext(companionId: string, query: string): Promise<string[]>;
|
|
352
353
|
searchLifeContext?(queryText: string): Promise<string[]>;
|
|
353
354
|
}
|
|
354
|
-
export interface EpisodicMemoryStore {
|
|
355
|
-
recordEvent(companionId: string, event: any): Promise<void>;
|
|
356
|
-
searchClaims(companionId: string, query: string, limit?: number): Promise<MemoryClaim[]>;
|
|
357
|
-
proposeClaim(claim: any): Promise<MemoryClaim>;
|
|
358
|
-
approveClaim(claimId: string): Promise<void>;
|
|
359
|
-
rejectClaim?(claimId: string): Promise<void>;
|
|
360
|
-
getApprovedClaims?(companionId: string, limit?: number): Promise<MemoryClaim[]>;
|
|
361
|
-
getRecentEvents?(companionId: string, limit?: number): Promise<EpisodicEvent[]>;
|
|
362
|
-
}
|
|
363
355
|
export interface EKnowledgeOrgan {
|
|
364
356
|
search(query: string): Promise<KnowledgeItem[]>;
|
|
365
357
|
}
|
package/dist/index.js
CHANGED
|
@@ -35,7 +35,7 @@ __exportStar(require("./intent-classifier"), exports);
|
|
|
35
35
|
__exportStar(require("./context-retriever"), exports);
|
|
36
36
|
__exportStar(require("./prompt-compiler"), exports);
|
|
37
37
|
__exportStar(require("./cognition-planner"), exports);
|
|
38
|
-
__exportStar(require("./
|
|
38
|
+
__exportStar(require("./interaction-settler"), exports);
|
|
39
39
|
__exportStar(require("./action-executor"), exports);
|
|
40
40
|
__exportStar(require("./experience-emitter"), exports);
|
|
41
41
|
__exportStar(require("./response-envelope"), exports);
|
|
@@ -9,7 +9,7 @@ export interface IntentClassification {
|
|
|
9
9
|
shouldQueryKnowledge: boolean;
|
|
10
10
|
knowledgeQueries?: string[];
|
|
11
11
|
primaryQuery?: string;
|
|
12
|
-
|
|
12
|
+
archiveQueries?: string[];
|
|
13
13
|
effectiveMode: InteractionMode;
|
|
14
14
|
confidence?: number;
|
|
15
15
|
classifierOrigin?: 'heuristic' | 'cognitive' | 'ear' | 'brain';
|
|
@@ -93,12 +93,12 @@ function classifyInputIntent(text, context, overrides) {
|
|
|
93
93
|
? Array.from(new Set([...aiKnowledgeQueries, ...rawKeywords]))
|
|
94
94
|
: (shouldQueryKnowledge ? rawKeywords : []);
|
|
95
95
|
const primaryQuery = knowledgeQueries[0] || (shouldQueryKnowledge ? text.trim() : undefined);
|
|
96
|
-
const
|
|
97
|
-
? overrides.
|
|
96
|
+
const archiveQueries = (overrides?.archiveQueries && overrides.archiveQueries.length > 0)
|
|
97
|
+
? overrides.archiveQueries
|
|
98
98
|
: rawKeywords;
|
|
99
99
|
// Multi-tier Interaction Mode Resolution:
|
|
100
100
|
// 1. Overrides / Cognitive Classifier
|
|
101
|
-
// 2. Security Boundary: public channel or external source forces 'casual' (Zero
|
|
101
|
+
// 2. Security Boundary: public channel or external source forces 'casual' (Zero Drift)
|
|
102
102
|
// 3. Explicit Request Mode (context.mode: 'casual' | 'teach' | 'hybrid')
|
|
103
103
|
// 4. Default companion baseline: 'hybrid' (salience filtering)
|
|
104
104
|
let effectiveMode;
|
|
@@ -123,7 +123,7 @@ function classifyInputIntent(text, context, overrides) {
|
|
|
123
123
|
shouldQueryKnowledge,
|
|
124
124
|
knowledgeQueries,
|
|
125
125
|
primaryQuery,
|
|
126
|
-
|
|
126
|
+
archiveQueries,
|
|
127
127
|
effectiveMode,
|
|
128
128
|
confidence: overrides?.confidence ?? 0.95,
|
|
129
129
|
classifierOrigin: overrides?.classifierOrigin ?? 'heuristic',
|
|
@@ -80,7 +80,7 @@ describe('IntentClassifier', () => {
|
|
|
80
80
|
expect((0, intent_classifier_1.classifyInputIntent)('How are you doing?', casualContext).effectiveMode).toBe('casual');
|
|
81
81
|
expect((0, intent_classifier_1.classifyInputIntent)('Tell me a joke', casualContext).effectiveMode).toBe('casual');
|
|
82
82
|
});
|
|
83
|
-
test('enforces casual mode (Zero
|
|
83
|
+
test('enforces casual mode (Zero Drift) on public channel or external source boundary', () => {
|
|
84
84
|
const publicContext = {
|
|
85
85
|
...dummyContext,
|
|
86
86
|
conversation: { channel: 'public', correlationId: 'corr-pub' },
|
|
@@ -1,17 +1,18 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ArchiveLedger, SelfRepository, Claim, BehaviorDirective, ResponsePlan, RequestContext, InteractionMode } from './index';
|
|
2
2
|
import { extractDeterministicTeaching } from './teaching';
|
|
3
|
-
export interface
|
|
3
|
+
export interface InteractionSettlementParams {
|
|
4
4
|
companionId: string;
|
|
5
5
|
perceivedText: string;
|
|
6
6
|
role: 'OWNER' | 'VIEWER' | 'OPERATOR';
|
|
7
7
|
requestContext: RequestContext;
|
|
8
|
-
|
|
8
|
+
archive?: ArchiveLedger;
|
|
9
|
+
memory?: any;
|
|
9
10
|
self?: SelfRepository;
|
|
10
11
|
explicitTeaching: ReturnType<typeof extractDeterministicTeaching>;
|
|
11
12
|
plan: ResponsePlan;
|
|
12
13
|
effectiveMode?: InteractionMode;
|
|
13
14
|
}
|
|
14
|
-
export interface
|
|
15
|
+
export interface ProposalReceipt {
|
|
15
16
|
proposal_id: string;
|
|
16
17
|
subject: string;
|
|
17
18
|
predicate: string;
|
|
@@ -20,11 +21,11 @@ export interface MemoryProposalReceipt {
|
|
|
20
21
|
claim_type?: string;
|
|
21
22
|
content?: string;
|
|
22
23
|
}
|
|
24
|
+
export type ClaimProposalReceipt = ProposalReceipt;
|
|
23
25
|
export interface BehavioralProposalReceipt {
|
|
24
26
|
directive_id: string;
|
|
25
27
|
domain?: string;
|
|
26
28
|
knowledge_domain?: string;
|
|
27
|
-
memory_class?: string;
|
|
28
29
|
runtime_effect?: string;
|
|
29
30
|
subject?: string;
|
|
30
31
|
predicate?: string;
|
|
@@ -36,14 +37,14 @@ export interface BehavioralProposalReceipt {
|
|
|
36
37
|
preferred_positions?: string[];
|
|
37
38
|
};
|
|
38
39
|
}
|
|
39
|
-
export interface
|
|
40
|
-
|
|
41
|
-
|
|
40
|
+
export interface InteractionSettlementResult {
|
|
41
|
+
createdClaimProposals: Claim[];
|
|
42
|
+
claimProposalReceipts: ProposalReceipt[];
|
|
42
43
|
createdBehavioralProposals?: BehaviorDirective[];
|
|
43
44
|
behavioralProposalReceipts?: BehavioralProposalReceipt[];
|
|
44
45
|
}
|
|
45
46
|
/**
|
|
46
|
-
* Persists source events
|
|
47
|
-
*
|
|
47
|
+
* Persists source events to ArchiveLedger and behavioral directive proposals directly to SelfRepository.
|
|
48
|
+
* Direct Domain Routing under RFC VX-26-13: Deconstructing Memory into Sovereign Primitives.
|
|
48
49
|
*/
|
|
49
|
-
export declare function
|
|
50
|
+
export declare function settleInteractionProposals(params: InteractionSettlementParams): Promise<InteractionSettlementResult>;
|