@siduri-x/core 2.0.4 → 2.0.6
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/context-retriever.d.ts +3 -0
- package/dist/context-retriever.js +23 -2
- package/dist/conversational-teach.test.d.ts +1 -0
- package/dist/conversational-teach.test.js +643 -0
- package/dist/index.d.ts +7 -1
- package/dist/intent-classifier.js +2 -2
- package/dist/memory-settler.d.ts +22 -1
- package/dist/memory-settler.js +69 -8
- package/dist/perception-cycle.test.js +14 -0
- package/dist/perception-pipeline.js +13 -2
- package/dist/prompt-compiler.d.ts +3 -0
- package/dist/prompt-compiler.js +5 -2
- package/dist/response-envelope.d.ts +1 -0
- package/dist/response-envelope.js +2 -1
- package/dist/runtime.d.ts +46 -0
- package/dist/runtime.js +237 -1
- package/dist/siduri-db.d.ts +7 -0
- package/dist/siduri-db.js +172 -11
- package/dist/siduri-db.test.js +2 -1
- package/dist/teaching.d.ts +6 -7
- package/dist/teaching.js +7 -125
- package/package.json +1 -1
package/dist/siduri-db.js
CHANGED
|
@@ -26,6 +26,7 @@ class SiduriDatabase {
|
|
|
26
26
|
companion_id TEXT PRIMARY KEY,
|
|
27
27
|
name TEXT NOT NULL,
|
|
28
28
|
archetype TEXT,
|
|
29
|
+
role TEXT,
|
|
29
30
|
origin TEXT,
|
|
30
31
|
ethos TEXT,
|
|
31
32
|
version TEXT NOT NULL,
|
|
@@ -58,6 +59,8 @@ class SiduriDatabase {
|
|
|
58
59
|
companion_id TEXT NOT NULL,
|
|
59
60
|
entity_id TEXT NOT NULL,
|
|
60
61
|
entity_type TEXT NOT NULL DEFAULT 'human',
|
|
62
|
+
name TEXT,
|
|
63
|
+
affiliation TEXT,
|
|
61
64
|
role TEXT DEFAULT 'user',
|
|
62
65
|
stance TEXT DEFAULT 'neutral',
|
|
63
66
|
trust_score REAL DEFAULT 0.5,
|
|
@@ -215,6 +218,24 @@ class SiduriDatabase {
|
|
|
215
218
|
catch {
|
|
216
219
|
// Column already exists
|
|
217
220
|
}
|
|
221
|
+
try {
|
|
222
|
+
this.db.exec("ALTER TABLE self_identity ADD COLUMN role TEXT");
|
|
223
|
+
}
|
|
224
|
+
catch {
|
|
225
|
+
// Column already exists
|
|
226
|
+
}
|
|
227
|
+
try {
|
|
228
|
+
this.db.exec("ALTER TABLE self_relationships ADD COLUMN name TEXT");
|
|
229
|
+
}
|
|
230
|
+
catch {
|
|
231
|
+
// Column already exists
|
|
232
|
+
}
|
|
233
|
+
try {
|
|
234
|
+
this.db.exec("ALTER TABLE self_relationships ADD COLUMN affiliation TEXT");
|
|
235
|
+
}
|
|
236
|
+
catch {
|
|
237
|
+
// Column already exists
|
|
238
|
+
}
|
|
218
239
|
}
|
|
219
240
|
close() {
|
|
220
241
|
this.db.close();
|
|
@@ -231,6 +252,7 @@ class SiduriDatabase {
|
|
|
231
252
|
companionId: row.companion_id,
|
|
232
253
|
name: row.name,
|
|
233
254
|
archetype: row.archetype || undefined,
|
|
255
|
+
role: row.role || row.archetype || undefined,
|
|
234
256
|
origin: row.origin || undefined,
|
|
235
257
|
ethos: row.ethos || undefined,
|
|
236
258
|
version: row.version,
|
|
@@ -238,18 +260,21 @@ class SiduriDatabase {
|
|
|
238
260
|
};
|
|
239
261
|
}
|
|
240
262
|
setIdentity(identity) {
|
|
263
|
+
const role = identity.role || identity.archetype || null;
|
|
264
|
+
const archetype = identity.archetype || identity.role || null;
|
|
241
265
|
const stmt = this.db.prepare(`
|
|
242
|
-
INSERT INTO self_identity (companion_id, name, archetype, origin, ethos, version, updated_at)
|
|
243
|
-
VALUES (?, ?, ?, ?, ?, ?, datetime('now'))
|
|
266
|
+
INSERT INTO self_identity (companion_id, name, archetype, role, origin, ethos, version, updated_at)
|
|
267
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, datetime('now'))
|
|
244
268
|
ON CONFLICT(companion_id) DO UPDATE SET
|
|
245
269
|
name = excluded.name,
|
|
246
270
|
archetype = excluded.archetype,
|
|
271
|
+
role = excluded.role,
|
|
247
272
|
origin = excluded.origin,
|
|
248
273
|
ethos = excluded.ethos,
|
|
249
274
|
version = excluded.version,
|
|
250
275
|
updated_at = datetime('now')
|
|
251
276
|
`);
|
|
252
|
-
stmt.run(identity.companionId, identity.name,
|
|
277
|
+
stmt.run(identity.companionId, identity.name, archetype, role, identity.origin || null, identity.ethos || null, identity.version);
|
|
253
278
|
}
|
|
254
279
|
getPersonality(companionId) {
|
|
255
280
|
const stmt = this.db.prepare('SELECT * FROM self_personality WHERE companion_id = ?');
|
|
@@ -311,6 +336,14 @@ class SiduriDatabase {
|
|
|
311
336
|
const stmt = this.db.prepare(`
|
|
312
337
|
INSERT INTO self_directives (id, companion_id, priority, directive, status, category, scope_actor, supersedes_id, created_at)
|
|
313
338
|
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
339
|
+
ON CONFLICT(id) DO UPDATE SET
|
|
340
|
+
companion_id = excluded.companion_id,
|
|
341
|
+
priority = excluded.priority,
|
|
342
|
+
directive = excluded.directive,
|
|
343
|
+
status = excluded.status,
|
|
344
|
+
category = excluded.category,
|
|
345
|
+
scope_actor = excluded.scope_actor,
|
|
346
|
+
supersedes_id = excluded.supersedes_id
|
|
314
347
|
`);
|
|
315
348
|
stmt.run(directive.id, directive.companionId, directive.priority !== undefined ? directive.priority : 50, directive.directive, normalizeStatus(directive.status, 'active'), directive.category || 'behavioral', directive.scopeActor || null, directive.supersedesId || null, directive.createdAt || new Date().toISOString());
|
|
316
349
|
}
|
|
@@ -332,6 +365,9 @@ class SiduriDatabase {
|
|
|
332
365
|
return;
|
|
333
366
|
}
|
|
334
367
|
if (normalizeStatus(row.status) !== 'pending') {
|
|
368
|
+
if (normalizeStatus(row.status) === 'active') {
|
|
369
|
+
return;
|
|
370
|
+
}
|
|
335
371
|
throw new Error(`Cannot approve directive '${id}': invalid transition from status '${row.status}' to 'active' (only pending directives can be approved)`);
|
|
336
372
|
}
|
|
337
373
|
// If this directive supersedes an earlier directive, transition that prior directive to superseded
|
|
@@ -407,14 +443,18 @@ class SiduriDatabase {
|
|
|
407
443
|
}
|
|
408
444
|
}
|
|
409
445
|
getRelationship(companionId, entityId) {
|
|
410
|
-
const
|
|
411
|
-
const
|
|
446
|
+
const stripped = entityId.startsWith('actor:') ? entityId.slice(6) : entityId;
|
|
447
|
+
const prefixed = entityId.startsWith('actor:') ? entityId : `actor:${entityId}`;
|
|
448
|
+
const stmt = this.db.prepare('SELECT * FROM self_relationships WHERE companion_id = ? AND (entity_id = ? OR entity_id = ? OR entity_id = ?)');
|
|
449
|
+
const row = stmt.get(companionId, entityId, stripped, prefixed);
|
|
412
450
|
if (!row)
|
|
413
451
|
return undefined;
|
|
414
452
|
return {
|
|
415
453
|
companionId: row.companion_id,
|
|
416
454
|
entityId: row.entity_id,
|
|
417
455
|
entityType: row.entity_type || 'human',
|
|
456
|
+
name: row.name || undefined,
|
|
457
|
+
affiliation: row.affiliation || undefined,
|
|
418
458
|
role: row.role || 'user',
|
|
419
459
|
stance: row.stance || 'neutral',
|
|
420
460
|
trustScore: row.trust_score !== undefined && row.trust_score !== null ? row.trust_score : 0.5,
|
|
@@ -429,6 +469,8 @@ class SiduriDatabase {
|
|
|
429
469
|
companionId: row.companion_id,
|
|
430
470
|
entityId: row.entity_id,
|
|
431
471
|
entityType: row.entity_type || 'human',
|
|
472
|
+
name: row.name || undefined,
|
|
473
|
+
affiliation: row.affiliation || undefined,
|
|
432
474
|
role: row.role || 'user',
|
|
433
475
|
stance: row.stance || 'neutral',
|
|
434
476
|
trustScore: row.trust_score !== undefined && row.trust_score !== null ? row.trust_score : 0.5,
|
|
@@ -439,18 +481,20 @@ class SiduriDatabase {
|
|
|
439
481
|
}
|
|
440
482
|
upsertRelationship(rel) {
|
|
441
483
|
const stmt = this.db.prepare(`
|
|
442
|
-
INSERT INTO self_relationships (companion_id, entity_id, entity_type, role, stance, trust_score, familiarity, interaction_conventions, updated_at)
|
|
443
|
-
VALUES (?, ?, ?, ?, ?, ?, ?, ?, datetime('now'))
|
|
484
|
+
INSERT INTO self_relationships (companion_id, entity_id, entity_type, name, affiliation, role, stance, trust_score, familiarity, interaction_conventions, updated_at)
|
|
485
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, datetime('now'))
|
|
444
486
|
ON CONFLICT(companion_id, entity_id) DO UPDATE SET
|
|
445
487
|
entity_type = excluded.entity_type,
|
|
446
|
-
|
|
447
|
-
|
|
488
|
+
name = COALESCE(excluded.name, self_relationships.name),
|
|
489
|
+
affiliation = COALESCE(excluded.affiliation, self_relationships.affiliation),
|
|
490
|
+
role = COALESCE(excluded.role, self_relationships.role),
|
|
491
|
+
stance = COALESCE(excluded.stance, self_relationships.stance),
|
|
448
492
|
trust_score = excluded.trust_score,
|
|
449
493
|
familiarity = excluded.familiarity,
|
|
450
494
|
interaction_conventions = excluded.interaction_conventions,
|
|
451
495
|
updated_at = datetime('now')
|
|
452
496
|
`);
|
|
453
|
-
stmt.run(rel.companionId, rel.entityId, rel.entityType || 'human', rel.role || 'user', rel.stance || 'neutral', rel.trustScore !== undefined && rel.trustScore !== null ? rel.trustScore : 0.5, rel.familiarity !== undefined && rel.familiarity !== null ? rel.familiarity : 0.5, JSON.stringify(rel.interactionConventions || []));
|
|
497
|
+
stmt.run(rel.companionId, rel.entityId, rel.entityType || 'human', rel.name || null, rel.affiliation || null, rel.role || 'user', rel.stance || 'neutral', rel.trustScore !== undefined && rel.trustScore !== null ? rel.trustScore : 0.5, rel.familiarity !== undefined && rel.familiarity !== null ? rel.familiarity : 0.5, JSON.stringify(rel.interactionConventions || []));
|
|
454
498
|
}
|
|
455
499
|
getExemplars(companionId) {
|
|
456
500
|
const stmt = this.db.prepare('SELECT * FROM self_exemplars WHERE companion_id = ? ORDER BY created_at ASC');
|
|
@@ -636,7 +680,7 @@ class SiduriDatabase {
|
|
|
636
680
|
INSERT INTO memory_claims (id, companion_id, subject, predicate, value, status, confidence, valid_from, valid_until, evidence, asserted_at, supersedes, source_event_id)
|
|
637
681
|
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, coalesce(?, datetime('now')), ?, ?)
|
|
638
682
|
`);
|
|
639
|
-
stmt.run(id, claim.companionId, claim.subject, claim.predicate, claim.value, status, confidence, claim.validFrom || null, claim.validUntil || null, claim.evidence ? JSON.stringify(claim.evidence) : null, assertedAt || null, claim.supersedes || null, claim.sourceEventId || null);
|
|
683
|
+
stmt.run(id, claim.companionId || 'default', claim.subject, claim.predicate, claim.value, status, confidence, claim.validFrom || null, claim.validUntil || null, claim.evidence ? JSON.stringify(claim.evidence) : null, assertedAt || null, claim.supersedes || null, claim.sourceEventId || null);
|
|
640
684
|
return {
|
|
641
685
|
...claim,
|
|
642
686
|
id,
|
|
@@ -656,6 +700,9 @@ class SiduriDatabase {
|
|
|
656
700
|
return;
|
|
657
701
|
}
|
|
658
702
|
if (normalizeStatus(row.status) !== 'pending') {
|
|
703
|
+
if (normalizeStatus(row.status) === 'approved') {
|
|
704
|
+
return;
|
|
705
|
+
}
|
|
659
706
|
throw new Error(`Cannot approve claim '${id}': invalid transition from status '${row.status}' to 'approved' (only pending claims can be approved)`);
|
|
660
707
|
}
|
|
661
708
|
// If this claim supersedes an earlier claim, transition that prior claim to superseded
|
|
@@ -678,6 +725,120 @@ class SiduriDatabase {
|
|
|
678
725
|
const stmt = this.db.prepare("UPDATE memory_claims SET status = 'approved' WHERE id = ? AND LOWER(status) = 'pending'");
|
|
679
726
|
stmt.run(id);
|
|
680
727
|
}
|
|
728
|
+
// Canonically promote approved claim to Self domain state (identity, role, relationships)
|
|
729
|
+
const approvedClaim = this.getClaim(id);
|
|
730
|
+
if (approvedClaim) {
|
|
731
|
+
this.promoteClaimToSelf(approvedClaim);
|
|
732
|
+
}
|
|
733
|
+
}
|
|
734
|
+
/**
|
|
735
|
+
* Canonically promotes a Claim into Self domain tables.
|
|
736
|
+
*/
|
|
737
|
+
promoteClaimToSelf(claim) {
|
|
738
|
+
const companionId = claim.companionId || 'default';
|
|
739
|
+
const subject = (claim.subject || '').toLowerCase();
|
|
740
|
+
const predicate = (claim.predicate || '').toLowerCase();
|
|
741
|
+
const value = claim.value || '';
|
|
742
|
+
if (!value)
|
|
743
|
+
return;
|
|
744
|
+
// 1. Identity mutations: companion identity/role/origin/name/ethos
|
|
745
|
+
if (subject.startsWith('companion:') ||
|
|
746
|
+
subject === 'companion' ||
|
|
747
|
+
subject === 'siduri' ||
|
|
748
|
+
subject === 'self') {
|
|
749
|
+
const existing = this.getIdentity(companionId) || {
|
|
750
|
+
companionId,
|
|
751
|
+
name: 'Siduri',
|
|
752
|
+
version: '1.0.0',
|
|
753
|
+
updatedAt: new Date().toISOString(),
|
|
754
|
+
};
|
|
755
|
+
if (predicate === 'role' || predicate === 'archetype') {
|
|
756
|
+
existing.archetype = value;
|
|
757
|
+
existing.role = value;
|
|
758
|
+
this.setIdentity(existing);
|
|
759
|
+
this.commitDirective({
|
|
760
|
+
id: `dir-role-${claim.id || Date.now()}`,
|
|
761
|
+
companionId,
|
|
762
|
+
priority: 70,
|
|
763
|
+
directive: `Acknowledge role as ${value}`,
|
|
764
|
+
status: 'active',
|
|
765
|
+
category: 'relational',
|
|
766
|
+
createdAt: new Date().toISOString(),
|
|
767
|
+
});
|
|
768
|
+
}
|
|
769
|
+
else if (predicate === 'origin' || predicate === 'created_by') {
|
|
770
|
+
existing.origin = value;
|
|
771
|
+
this.setIdentity(existing);
|
|
772
|
+
}
|
|
773
|
+
else if (predicate === 'name') {
|
|
774
|
+
existing.name = value;
|
|
775
|
+
this.setIdentity(existing);
|
|
776
|
+
}
|
|
777
|
+
else if (predicate === 'ethos') {
|
|
778
|
+
existing.ethos = value;
|
|
779
|
+
this.setIdentity(existing);
|
|
780
|
+
}
|
|
781
|
+
return;
|
|
782
|
+
}
|
|
783
|
+
// 2. Relationship mutations: creator or user stated relationship, name, or affiliation
|
|
784
|
+
if (claim.claimType === 'relationship' ||
|
|
785
|
+
predicate === 'stated_relationship' ||
|
|
786
|
+
predicate === 'relationship' ||
|
|
787
|
+
predicate === 'relationship_to_siduri' ||
|
|
788
|
+
(predicate === 'name' && (subject.startsWith('actor:') || subject === 'user' || subject === 'primary_user')) ||
|
|
789
|
+
predicate === 'preferred_address' ||
|
|
790
|
+
predicate === 'affiliation') {
|
|
791
|
+
const rawSubject = (claim.subject || 'actor:user').replace(/^actor:actor:/, 'actor:');
|
|
792
|
+
const isCreator = value.toLowerCase() === 'creator';
|
|
793
|
+
const isName = predicate === 'name' || predicate === 'preferred_address';
|
|
794
|
+
const isAffil = predicate === 'affiliation';
|
|
795
|
+
const existingRel = this.getRelationship(companionId, rawSubject);
|
|
796
|
+
const role = isCreator ? value : (existingRel?.role || (isName || isAffil ? existingRel?.role : value));
|
|
797
|
+
const name = isName ? value : existingRel?.name;
|
|
798
|
+
const affiliation = isAffil ? value : existingRel?.affiliation;
|
|
799
|
+
const stance = isCreator ? 'familiar_loyal' : (existingRel?.stance || 'neutral');
|
|
800
|
+
const trustScore = isCreator ? 1.0 : (existingRel?.trustScore ?? 0.8);
|
|
801
|
+
const familiarity = isCreator ? 0.9 : (existingRel?.familiarity ?? 0.5);
|
|
802
|
+
const interactionConventions = isCreator
|
|
803
|
+
? Array.from(new Set([...(existingRel?.interactionConventions || []), 'Direct communication', 'Highest administrative trust']))
|
|
804
|
+
: (existingRel?.interactionConventions || []);
|
|
805
|
+
this.upsertRelationship({
|
|
806
|
+
companionId,
|
|
807
|
+
entityId: rawSubject,
|
|
808
|
+
entityType: 'human',
|
|
809
|
+
name,
|
|
810
|
+
affiliation,
|
|
811
|
+
role,
|
|
812
|
+
stance,
|
|
813
|
+
trustScore,
|
|
814
|
+
familiarity,
|
|
815
|
+
interactionConventions,
|
|
816
|
+
});
|
|
817
|
+
if (isName) {
|
|
818
|
+
this.commitDirective({
|
|
819
|
+
id: `dir-name-${claim.id || Date.now()}`,
|
|
820
|
+
companionId,
|
|
821
|
+
priority: 75,
|
|
822
|
+
directive: `Address ${rawSubject} as ${value}`,
|
|
823
|
+
status: 'active',
|
|
824
|
+
category: 'relational',
|
|
825
|
+
createdAt: new Date().toISOString(),
|
|
826
|
+
});
|
|
827
|
+
}
|
|
828
|
+
return;
|
|
829
|
+
}
|
|
830
|
+
// 3. Behavioral rule claim
|
|
831
|
+
if (predicate === 'behavioral_rule' || predicate === 'rule') {
|
|
832
|
+
this.commitDirective({
|
|
833
|
+
id: `dir-rule-${claim.id || Date.now()}`,
|
|
834
|
+
companionId,
|
|
835
|
+
priority: 60,
|
|
836
|
+
directive: value,
|
|
837
|
+
status: 'active',
|
|
838
|
+
category: 'behavioral',
|
|
839
|
+
createdAt: new Date().toISOString(),
|
|
840
|
+
});
|
|
841
|
+
}
|
|
681
842
|
}
|
|
682
843
|
rejectClaim(id, companionId) {
|
|
683
844
|
if (companionId) {
|
package/dist/siduri-db.test.js
CHANGED
|
@@ -730,7 +730,8 @@ describe('SiduriDatabase', () => {
|
|
|
730
730
|
status: 'active',
|
|
731
731
|
category: 'behavioral',
|
|
732
732
|
});
|
|
733
|
-
|
|
733
|
+
// Approving an already-active directive is now idempotent (no-op, does not throw)
|
|
734
|
+
expect(() => db.approveDirective('dir-active-1')).not.toThrow();
|
|
734
735
|
// 3. Rejecting an already ACTIVE directive throws
|
|
735
736
|
expect(() => db.rejectDirective('dir-active-1')).toThrow(/invalid transition from status 'active' to 'rejected'/i);
|
|
736
737
|
});
|
package/dist/teaching.d.ts
CHANGED
|
@@ -4,12 +4,11 @@ export interface ExtractedTeaching {
|
|
|
4
4
|
behaviorProposals: BehaviorProposal[];
|
|
5
5
|
}
|
|
6
6
|
/**
|
|
7
|
-
*
|
|
7
|
+
* Deterministic teaching extraction placeholder.
|
|
8
8
|
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
* - Companion identity is isolated.
|
|
9
|
+
* In Siduri-X, conversational memory and behavioral proposals are generated
|
|
10
|
+
* directly by the Brain LLM via structured cognitive planning (e.g. `submitResponsePlan`).
|
|
11
|
+
* Deterministic regex matching has been removed in favor of pure LLM comprehension,
|
|
12
|
+
* as all candidates are quarantined in 'pending' status until explicitly approved by the user.
|
|
14
13
|
*/
|
|
15
|
-
export declare function extractDeterministicTeaching(
|
|
14
|
+
export declare function extractDeterministicTeaching(_message: string, _context?: RequestContext, _sourceEventId?: string): ExtractedTeaching;
|
package/dist/teaching.js
CHANGED
|
@@ -1,132 +1,14 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.extractDeterministicTeaching = extractDeterministicTeaching;
|
|
4
|
-
function cleanValue(value, limit = 160) {
|
|
5
|
-
return value.replace(/\s+/g, ' ').replace(/^[ .,!?:;"']+|[ .,!?:;"']+$/g, '').slice(0, limit);
|
|
6
|
-
}
|
|
7
4
|
/**
|
|
8
|
-
*
|
|
5
|
+
* Deterministic teaching extraction placeholder.
|
|
9
6
|
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
* - Companion identity is isolated.
|
|
7
|
+
* In Siduri-X, conversational memory and behavioral proposals are generated
|
|
8
|
+
* directly by the Brain LLM via structured cognitive planning (e.g. `submitResponsePlan`).
|
|
9
|
+
* Deterministic regex matching has been removed in favor of pure LLM comprehension,
|
|
10
|
+
* as all candidates are quarantined in 'pending' status until explicitly approved by the user.
|
|
15
11
|
*/
|
|
16
|
-
function extractDeterministicTeaching(
|
|
17
|
-
|
|
18
|
-
const claims = [];
|
|
19
|
-
const behaviorProposals = [];
|
|
20
|
-
if (!text) {
|
|
21
|
-
return { claims, behaviorProposals };
|
|
22
|
-
}
|
|
23
|
-
const actorId = context?.actor?.actorId;
|
|
24
|
-
const actorSubject = actorId ? `actor:${actorId}` : 'actor:anonymous';
|
|
25
|
-
const companionId = context?.companionId || 'default';
|
|
26
|
-
const sensitivity = context?.conversation?.channel === 'public' ? 'public' : 'private';
|
|
27
|
-
// 1. Companion's Name: "your name is X" / "you are called X"
|
|
28
|
-
const companionNameMatch = text.match(/\b(?:your name is|you are called)\s+(.+?)(?=\s+and\s+(?:i\b|my\b|you\b)|[.;,]|$)/i);
|
|
29
|
-
if (companionNameMatch) {
|
|
30
|
-
const name = cleanValue(companionNameMatch[1], 80);
|
|
31
|
-
claims.push({
|
|
32
|
-
subject: `companion:${companionId}`,
|
|
33
|
-
predicate: 'name',
|
|
34
|
-
value: name,
|
|
35
|
-
content: `The companion's name is ${name}.`,
|
|
36
|
-
claimType: 'semantic',
|
|
37
|
-
provenance: 'deterministic_teaching',
|
|
38
|
-
sensitivity: 'public',
|
|
39
|
-
sourceEventId,
|
|
40
|
-
});
|
|
41
|
-
behaviorProposals.push({
|
|
42
|
-
directive: `Acknowledge configured name as ${name}`,
|
|
43
|
-
priority: 70,
|
|
44
|
-
subject: `companion:${companionId}`,
|
|
45
|
-
predicate: 'name',
|
|
46
|
-
value: name,
|
|
47
|
-
memoryClass: 'identity',
|
|
48
|
-
sourceEventId,
|
|
49
|
-
});
|
|
50
|
-
}
|
|
51
|
-
// 2. Actor's Name: "my name is X"
|
|
52
|
-
const myNameMatch = text.match(/\bmy name is\s+(.+?)(?=\s+and\s+(?:i\b|my\b|you\b)|[.;,]|$)/i);
|
|
53
|
-
if (myNameMatch && !/\b(?:private|public|everywhere)\b/i.test(text)) {
|
|
54
|
-
const name = cleanValue(myNameMatch[1], 80);
|
|
55
|
-
claims.push({
|
|
56
|
-
subject: actorSubject,
|
|
57
|
-
predicate: 'name',
|
|
58
|
-
value: name,
|
|
59
|
-
content: `The actor's name is ${name}.`,
|
|
60
|
-
claimType: 'preference',
|
|
61
|
-
provenance: 'deterministic_teaching',
|
|
62
|
-
sensitivity,
|
|
63
|
-
sourceEventId,
|
|
64
|
-
});
|
|
65
|
-
}
|
|
66
|
-
// 3. Preferred Address / Call me X: "call me X"
|
|
67
|
-
const callMeMatch = text.match(/\b(?:(?:from now on|only),?\s*)?call me\s+(.+?)(?:\s+(?:in private|privately|in public|publicly|everywhere|in direct conversations))?(?=\s+and\s+(?:i\b|my\b|you\b)|[.;,]|$)/i);
|
|
68
|
-
if (callMeMatch) {
|
|
69
|
-
const address = cleanValue(callMeMatch[1], 80);
|
|
70
|
-
const directiveInstruction = `Address ${actorSubject} as ${address}`;
|
|
71
|
-
claims.push({
|
|
72
|
-
subject: actorSubject,
|
|
73
|
-
predicate: 'preferred_address',
|
|
74
|
-
value: address,
|
|
75
|
-
content: `The actor's preferred address is ${address}.`,
|
|
76
|
-
claimType: 'relationship',
|
|
77
|
-
provenance: 'deterministic_teaching',
|
|
78
|
-
sensitivity,
|
|
79
|
-
sourceEventId,
|
|
80
|
-
});
|
|
81
|
-
behaviorProposals.push({
|
|
82
|
-
directive: directiveInstruction,
|
|
83
|
-
priority: 80,
|
|
84
|
-
subject: actorSubject,
|
|
85
|
-
predicate: 'preferred_address',
|
|
86
|
-
value: address,
|
|
87
|
-
memoryClass: 'behavioral',
|
|
88
|
-
sourceEventId,
|
|
89
|
-
});
|
|
90
|
-
}
|
|
91
|
-
// 4. Stated relationship: "I am your X" / "I'm your creator"
|
|
92
|
-
const relMatch = text.match(/\b(?:i am|i'm)\s+your\s+([A-Za-z0-9_\s-]+?)(?=\s+and\s+(?:i\b|my\b|you\b)|[.;,]|$)/i);
|
|
93
|
-
if (relMatch) {
|
|
94
|
-
const relationship = cleanValue(relMatch[1], 60);
|
|
95
|
-
claims.push({
|
|
96
|
-
subject: actorSubject,
|
|
97
|
-
predicate: 'stated_relationship',
|
|
98
|
-
value: relationship,
|
|
99
|
-
content: `The actor stated their relationship as ${relationship}.`,
|
|
100
|
-
claimType: 'relationship',
|
|
101
|
-
provenance: 'deterministic_teaching',
|
|
102
|
-
sensitivity: 'private',
|
|
103
|
-
sourceEventId,
|
|
104
|
-
});
|
|
105
|
-
behaviorProposals.push({
|
|
106
|
-
directive: `Recognize ${actorSubject} stated relationship as ${relationship}`,
|
|
107
|
-
priority: 75,
|
|
108
|
-
subject: actorSubject,
|
|
109
|
-
predicate: 'stated_relationship',
|
|
110
|
-
value: relationship,
|
|
111
|
-
memoryClass: 'relationship',
|
|
112
|
-
sourceEventId,
|
|
113
|
-
});
|
|
114
|
-
}
|
|
115
|
-
// 5. Explicit Domain / Preference fact: "my preferred X is Y" / "my X is Y"
|
|
116
|
-
const prefMatch = text.match(/\bmy\s+preferred\s+([A-Za-z0-9_]+)\s+is\s+(.+?)(?=\s+and\s+(?:i\b|my\b|you\b)|[.;,]|$)/i);
|
|
117
|
-
if (prefMatch) {
|
|
118
|
-
const predicate = cleanValue(prefMatch[1], 40);
|
|
119
|
-
const val = cleanValue(prefMatch[2], 100);
|
|
120
|
-
claims.push({
|
|
121
|
-
subject: actorSubject,
|
|
122
|
-
predicate: `preferred_${predicate}`,
|
|
123
|
-
value: val,
|
|
124
|
-
content: `The actor's preferred ${predicate} is ${val}.`,
|
|
125
|
-
claimType: 'preference',
|
|
126
|
-
provenance: 'deterministic_teaching',
|
|
127
|
-
sensitivity,
|
|
128
|
-
sourceEventId,
|
|
129
|
-
});
|
|
130
|
-
}
|
|
131
|
-
return { claims, behaviorProposals };
|
|
12
|
+
function extractDeterministicTeaching(_message, _context, _sourceEventId) {
|
|
13
|
+
return { claims: [], behaviorProposals: [] };
|
|
132
14
|
}
|
package/package.json
CHANGED