@sidurijs/core 1.0.0
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/action-executor.d.ts +12 -0
- package/dist/action-executor.js +54 -0
- package/dist/action-policy.d.ts +79 -0
- package/dist/action-policy.js +439 -0
- package/dist/action-policy.test.d.ts +1 -0
- package/dist/action-policy.test.js +363 -0
- package/dist/action.d.ts +72 -0
- package/dist/action.js +2 -0
- package/dist/adversarial.test.d.ts +1 -0
- package/dist/adversarial.test.js +491 -0
- package/dist/architecture-boundary.test.d.ts +1 -0
- package/dist/architecture-boundary.test.js +108 -0
- package/dist/capability.d.ts +78 -0
- package/dist/capability.js +168 -0
- package/dist/capability.test.d.ts +1 -0
- package/dist/capability.test.js +311 -0
- package/dist/chat-contract.d.ts +94 -0
- package/dist/chat-contract.js +104 -0
- package/dist/cognition-planner.d.ts +15 -0
- package/dist/cognition-planner.js +23 -0
- package/dist/container.d.ts +74 -0
- package/dist/container.js +81 -0
- package/dist/context-retriever.d.ts +33 -0
- package/dist/context-retriever.js +260 -0
- package/dist/context.d.ts +46 -0
- package/dist/context.js +85 -0
- package/dist/context.test.d.ts +1 -0
- package/dist/context.test.js +76 -0
- package/dist/conversational-teach.test.d.ts +1 -0
- package/dist/conversational-teach.test.js +941 -0
- package/dist/database.d.ts +1 -0
- package/dist/database.js +17 -0
- package/dist/dispatcher.d.ts +14 -0
- package/dist/dispatcher.js +40 -0
- package/dist/dispatcher.test.d.ts +1 -0
- package/dist/dispatcher.test.js +58 -0
- package/dist/ear-types.d.ts +33 -0
- package/dist/ear-types.js +2 -0
- package/dist/evidence.d.ts +76 -0
- package/dist/evidence.js +27 -0
- package/dist/evidence.test.d.ts +1 -0
- package/dist/evidence.test.js +75 -0
- package/dist/experience-emitter.d.ts +21 -0
- package/dist/experience-emitter.js +47 -0
- package/dist/experience.d.ts +55 -0
- package/dist/experience.js +74 -0
- package/dist/experience.test.d.ts +1 -0
- package/dist/experience.test.js +55 -0
- package/dist/gating.d.ts +45 -0
- package/dist/gating.js +185 -0
- package/dist/gating.test.d.ts +1 -0
- package/dist/gating.test.js +186 -0
- package/dist/index.d.ts +367 -0
- package/dist/index.js +56 -0
- package/dist/input-normalizer.d.ts +14 -0
- package/dist/input-normalizer.js +76 -0
- package/dist/input-normalizer.test.d.ts +1 -0
- package/dist/input-normalizer.test.js +48 -0
- package/dist/intent-classifier.d.ts +37 -0
- package/dist/intent-classifier.js +150 -0
- package/dist/intent-classifier.test.d.ts +1 -0
- package/dist/intent-classifier.test.js +118 -0
- package/dist/memory-settler.d.ts +49 -0
- package/dist/memory-settler.js +161 -0
- package/dist/mouth-types.d.ts +90 -0
- package/dist/mouth-types.js +2 -0
- package/dist/perception-cycle.test.d.ts +1 -0
- package/dist/perception-cycle.test.js +301 -0
- package/dist/perception-pipeline.d.ts +77 -0
- package/dist/perception-pipeline.js +304 -0
- package/dist/perception-pipeline.test.d.ts +1 -0
- package/dist/perception-pipeline.test.js +65 -0
- package/dist/prompt-compiler.d.ts +26 -0
- package/dist/prompt-compiler.js +81 -0
- package/dist/prompt-compiler.test.d.ts +1 -0
- package/dist/prompt-compiler.test.js +90 -0
- package/dist/proposals.d.ts +33 -0
- package/dist/proposals.js +2 -0
- package/dist/response-envelope.d.ts +30 -0
- package/dist/response-envelope.js +90 -0
- package/dist/runtime-facades.test.d.ts +1 -0
- package/dist/runtime-facades.test.js +95 -0
- package/dist/runtime.d.ts +116 -0
- package/dist/runtime.js +778 -0
- package/dist/schema-validator.d.ts +9 -0
- package/dist/schema-validator.js +107 -0
- package/dist/schema-validator.test.d.ts +1 -0
- package/dist/schema-validator.test.js +124 -0
- package/dist/session-history.d.ts +20 -0
- package/dist/session-history.js +55 -0
- package/dist/session-history.test.d.ts +1 -0
- package/dist/session-history.test.js +38 -0
- package/dist/siduri-db.d.ts +235 -0
- package/dist/siduri-db.js +1405 -0
- package/dist/siduri-db.test.d.ts +1 -0
- package/dist/siduri-db.test.js +1021 -0
- package/dist/sqlite-action-store.d.ts +21 -0
- package/dist/sqlite-action-store.js +281 -0
- package/dist/sqlite-action-store.test.d.ts +1 -0
- package/dist/sqlite-action-store.test.js +261 -0
- package/dist/teaching.d.ts +14 -0
- package/dist/teaching.js +14 -0
- package/package.json +43 -0
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export declare class ConfigValidationError extends Error {
|
|
2
|
+
errors: string[];
|
|
3
|
+
constructor(errors: string[]);
|
|
4
|
+
}
|
|
5
|
+
/**
|
|
6
|
+
* Validates a companion configuration object against a JSON schema (draft-07 compatible).
|
|
7
|
+
* Throws ConfigValidationError if validation errors are detected.
|
|
8
|
+
*/
|
|
9
|
+
export declare function validateCompanionConfig(config: unknown, schema: any, path?: string): void;
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ConfigValidationError = void 0;
|
|
4
|
+
exports.validateCompanionConfig = validateCompanionConfig;
|
|
5
|
+
class ConfigValidationError extends Error {
|
|
6
|
+
errors;
|
|
7
|
+
constructor(errors) {
|
|
8
|
+
super(`Siduri configuration validation failed:\n${errors.map((e) => ` - ${e}`).join('\n')}`);
|
|
9
|
+
this.name = 'ConfigValidationError';
|
|
10
|
+
this.errors = errors;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
exports.ConfigValidationError = ConfigValidationError;
|
|
14
|
+
/**
|
|
15
|
+
* Validates a companion configuration object against a JSON schema (draft-07 compatible).
|
|
16
|
+
* Throws ConfigValidationError if validation errors are detected.
|
|
17
|
+
*/
|
|
18
|
+
function validateCompanionConfig(config, schema, path = '$') {
|
|
19
|
+
const errors = [];
|
|
20
|
+
function validateNode(value, nodeSchema, curPath) {
|
|
21
|
+
if (!nodeSchema || typeof nodeSchema !== 'object')
|
|
22
|
+
return;
|
|
23
|
+
// Type validation
|
|
24
|
+
if (nodeSchema.type !== undefined) {
|
|
25
|
+
const type = nodeSchema.type;
|
|
26
|
+
if (type === 'object') {
|
|
27
|
+
if (typeof value !== 'object' || value === null || Array.isArray(value)) {
|
|
28
|
+
errors.push(`${curPath}: expected object, received ${value === null ? 'null' : Array.isArray(value) ? 'array' : typeof value}`);
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
else if (type === 'array') {
|
|
33
|
+
if (!Array.isArray(value)) {
|
|
34
|
+
errors.push(`${curPath}: expected array, received ${typeof value}`);
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
else if (type === 'string') {
|
|
39
|
+
if (typeof value !== 'string') {
|
|
40
|
+
errors.push(`${curPath}: expected string, received ${typeof value}`);
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
else if (type === 'number') {
|
|
45
|
+
if (typeof value !== 'number' || Number.isNaN(value)) {
|
|
46
|
+
errors.push(`${curPath}: expected number, received ${typeof value}`);
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
else if (type === 'integer') {
|
|
51
|
+
if (typeof value !== 'number' || !Number.isInteger(value)) {
|
|
52
|
+
errors.push(`${curPath}: expected integer, received ${typeof value}`);
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
else if (type === 'boolean') {
|
|
57
|
+
if (typeof value !== 'boolean') {
|
|
58
|
+
errors.push(`${curPath}: expected boolean, received ${typeof value}`);
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
// Enum validation
|
|
64
|
+
if (Array.isArray(nodeSchema.enum)) {
|
|
65
|
+
if (!nodeSchema.enum.includes(value)) {
|
|
66
|
+
errors.push(`${curPath}: invalid value ${JSON.stringify(value)}, expected one of: ${nodeSchema.enum.map((v) => JSON.stringify(v)).join(', ')}`);
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
// Object properties validation
|
|
71
|
+
if (typeof value === 'object' && value !== null && !Array.isArray(value)) {
|
|
72
|
+
if (Array.isArray(nodeSchema.required)) {
|
|
73
|
+
for (const reqKey of nodeSchema.required) {
|
|
74
|
+
if (value[reqKey] === undefined) {
|
|
75
|
+
errors.push(`${curPath}.${reqKey}: is required`);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
const definedProps = nodeSchema.properties || {};
|
|
80
|
+
if (nodeSchema.additionalProperties === false) {
|
|
81
|
+
for (const key of Object.keys(value)) {
|
|
82
|
+
// Allow $schema property at root level
|
|
83
|
+
if (curPath === '$' && key === '$schema')
|
|
84
|
+
continue;
|
|
85
|
+
if (!(key in definedProps)) {
|
|
86
|
+
errors.push(`${curPath}.${key}: unexpected property is not allowed`);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
for (const [propName, propSchema] of Object.entries(definedProps)) {
|
|
91
|
+
if (value[propName] !== undefined) {
|
|
92
|
+
validateNode(value[propName], propSchema, `${curPath}.${propName}`);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
// Array items validation
|
|
97
|
+
if (Array.isArray(value) && nodeSchema.items) {
|
|
98
|
+
value.forEach((item, index) => {
|
|
99
|
+
validateNode(item, nodeSchema.items, `${curPath}[${index}]`);
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
validateNode(config, schema, path);
|
|
104
|
+
if (errors.length > 0) {
|
|
105
|
+
throw new ConfigValidationError(errors);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const schema_validator_1 = require("./schema-validator");
|
|
4
|
+
describe('validateCompanionConfig', () => {
|
|
5
|
+
const sampleSchema = {
|
|
6
|
+
type: 'object',
|
|
7
|
+
required: ['id', 'name', 'organs'],
|
|
8
|
+
additionalProperties: false,
|
|
9
|
+
properties: {
|
|
10
|
+
$schema: { type: 'string' },
|
|
11
|
+
id: { type: 'string' },
|
|
12
|
+
name: { type: 'string' },
|
|
13
|
+
organs: {
|
|
14
|
+
type: 'object',
|
|
15
|
+
additionalProperties: false,
|
|
16
|
+
properties: {
|
|
17
|
+
brain: {
|
|
18
|
+
type: 'object',
|
|
19
|
+
required: ['provider', 'model'],
|
|
20
|
+
properties: {
|
|
21
|
+
provider: {
|
|
22
|
+
type: 'string',
|
|
23
|
+
enum: ['openrouter', 'openai-compatible'],
|
|
24
|
+
},
|
|
25
|
+
model: { type: 'string' },
|
|
26
|
+
},
|
|
27
|
+
},
|
|
28
|
+
memory: {
|
|
29
|
+
type: 'object',
|
|
30
|
+
required: ['provider'],
|
|
31
|
+
properties: {
|
|
32
|
+
provider: {
|
|
33
|
+
type: 'string',
|
|
34
|
+
enum: ['sqlite', 'in-memory', 'none'],
|
|
35
|
+
},
|
|
36
|
+
maxConnections: { type: 'number' },
|
|
37
|
+
},
|
|
38
|
+
},
|
|
39
|
+
},
|
|
40
|
+
},
|
|
41
|
+
},
|
|
42
|
+
};
|
|
43
|
+
test('accepts valid configuration matching schema', () => {
|
|
44
|
+
const validConfig = {
|
|
45
|
+
$schema: './siduri.schema.json',
|
|
46
|
+
id: 'companion-1',
|
|
47
|
+
name: 'Test Companion',
|
|
48
|
+
organs: {
|
|
49
|
+
brain: {
|
|
50
|
+
provider: 'openrouter',
|
|
51
|
+
model: 'gpt-4o',
|
|
52
|
+
},
|
|
53
|
+
},
|
|
54
|
+
};
|
|
55
|
+
expect(() => (0, schema_validator_1.validateCompanionConfig)(validConfig, sampleSchema)).not.toThrow();
|
|
56
|
+
});
|
|
57
|
+
test('throws ConfigValidationError if missing required root field', () => {
|
|
58
|
+
const invalidConfig = {
|
|
59
|
+
name: 'Missing Id and Organs',
|
|
60
|
+
};
|
|
61
|
+
expect(() => (0, schema_validator_1.validateCompanionConfig)(invalidConfig, sampleSchema)).toThrow(schema_validator_1.ConfigValidationError);
|
|
62
|
+
try {
|
|
63
|
+
(0, schema_validator_1.validateCompanionConfig)(invalidConfig, sampleSchema);
|
|
64
|
+
}
|
|
65
|
+
catch (err) {
|
|
66
|
+
expect(err.errors).toContain('$.id: is required');
|
|
67
|
+
expect(err.errors).toContain('$.organs: is required');
|
|
68
|
+
}
|
|
69
|
+
});
|
|
70
|
+
test('throws ConfigValidationError on unexpected property when additionalProperties is false', () => {
|
|
71
|
+
const invalidConfig = {
|
|
72
|
+
id: 'c-1',
|
|
73
|
+
name: 'Test',
|
|
74
|
+
organs: {},
|
|
75
|
+
extraField: 'not allowed',
|
|
76
|
+
};
|
|
77
|
+
expect(() => (0, schema_validator_1.validateCompanionConfig)(invalidConfig, sampleSchema)).toThrow(schema_validator_1.ConfigValidationError);
|
|
78
|
+
try {
|
|
79
|
+
(0, schema_validator_1.validateCompanionConfig)(invalidConfig, sampleSchema);
|
|
80
|
+
}
|
|
81
|
+
catch (err) {
|
|
82
|
+
expect(err.errors).toContain('$.extraField: unexpected property is not allowed');
|
|
83
|
+
}
|
|
84
|
+
});
|
|
85
|
+
test('throws ConfigValidationError on invalid enum value', () => {
|
|
86
|
+
const invalidConfig = {
|
|
87
|
+
id: 'c-1',
|
|
88
|
+
name: 'Test',
|
|
89
|
+
organs: {
|
|
90
|
+
brain: {
|
|
91
|
+
provider: 'invalid-brain-provider',
|
|
92
|
+
model: 'gpt-4',
|
|
93
|
+
},
|
|
94
|
+
},
|
|
95
|
+
};
|
|
96
|
+
expect(() => (0, schema_validator_1.validateCompanionConfig)(invalidConfig, sampleSchema)).toThrow(schema_validator_1.ConfigValidationError);
|
|
97
|
+
try {
|
|
98
|
+
(0, schema_validator_1.validateCompanionConfig)(invalidConfig, sampleSchema);
|
|
99
|
+
}
|
|
100
|
+
catch (err) {
|
|
101
|
+
expect(err.errors.some((e) => e.includes('invalid value "invalid-brain-provider"'))).toBe(true);
|
|
102
|
+
}
|
|
103
|
+
});
|
|
104
|
+
test('throws ConfigValidationError on invalid type', () => {
|
|
105
|
+
const invalidConfig = {
|
|
106
|
+
id: 12345, // should be string
|
|
107
|
+
name: 'Test',
|
|
108
|
+
organs: {
|
|
109
|
+
memory: {
|
|
110
|
+
provider: 'sqlite',
|
|
111
|
+
maxConnections: 'ten', // should be number
|
|
112
|
+
},
|
|
113
|
+
},
|
|
114
|
+
};
|
|
115
|
+
expect(() => (0, schema_validator_1.validateCompanionConfig)(invalidConfig, sampleSchema)).toThrow(schema_validator_1.ConfigValidationError);
|
|
116
|
+
try {
|
|
117
|
+
(0, schema_validator_1.validateCompanionConfig)(invalidConfig, sampleSchema);
|
|
118
|
+
}
|
|
119
|
+
catch (err) {
|
|
120
|
+
expect(err.errors).toContain('$.id: expected string, received number');
|
|
121
|
+
expect(err.errors).toContain('$.organs.memory.maxConnections: expected number, received string');
|
|
122
|
+
}
|
|
123
|
+
});
|
|
124
|
+
});
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { Message } from './index';
|
|
2
|
+
export interface SessionHistoryOptions {
|
|
3
|
+
maxSessions?: number;
|
|
4
|
+
maxMessagesPerSession?: number;
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* Manages conversation history scoped by session key to prevent cross-session
|
|
8
|
+
* and cross-channel memory/conversation leakage.
|
|
9
|
+
*/
|
|
10
|
+
export declare class SessionHistoryManager {
|
|
11
|
+
private readonly sessions;
|
|
12
|
+
private readonly maxSessions;
|
|
13
|
+
private readonly maxMessagesPerSession;
|
|
14
|
+
constructor(options?: SessionHistoryOptions);
|
|
15
|
+
getHistory(sessionKey?: string): Message[];
|
|
16
|
+
setHistory(sessionKey: string | undefined, history: Message[]): void;
|
|
17
|
+
append(sessionKey: string | undefined, message: Message): void;
|
|
18
|
+
clear(sessionKey?: string): void;
|
|
19
|
+
sessionCount(): number;
|
|
20
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SessionHistoryManager = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* Manages conversation history scoped by session key to prevent cross-session
|
|
6
|
+
* and cross-channel memory/conversation leakage.
|
|
7
|
+
*/
|
|
8
|
+
class SessionHistoryManager {
|
|
9
|
+
sessions = new Map();
|
|
10
|
+
maxSessions;
|
|
11
|
+
maxMessagesPerSession;
|
|
12
|
+
constructor(options = {}) {
|
|
13
|
+
this.maxSessions = options.maxSessions ?? 200;
|
|
14
|
+
this.maxMessagesPerSession = options.maxMessagesPerSession ?? 20;
|
|
15
|
+
}
|
|
16
|
+
getHistory(sessionKey = 'default') {
|
|
17
|
+
return this.sessions.get(sessionKey) || [];
|
|
18
|
+
}
|
|
19
|
+
setHistory(sessionKey = 'default', history) {
|
|
20
|
+
if (this.sessions.size >= this.maxSessions && !this.sessions.has(sessionKey)) {
|
|
21
|
+
const oldestKey = this.sessions.keys().next().value;
|
|
22
|
+
if (oldestKey) {
|
|
23
|
+
this.sessions.delete(oldestKey);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
const bounded = history.slice(-this.maxMessagesPerSession).map((item) => ({
|
|
27
|
+
role: item.role,
|
|
28
|
+
content: item.content.slice(0, 2000).replace(/\0/g, ''),
|
|
29
|
+
}));
|
|
30
|
+
this.sessions.set(sessionKey, bounded);
|
|
31
|
+
}
|
|
32
|
+
append(sessionKey = 'default', message) {
|
|
33
|
+
const current = this.getHistory(sessionKey);
|
|
34
|
+
const updated = [
|
|
35
|
+
...current,
|
|
36
|
+
{
|
|
37
|
+
role: message.role,
|
|
38
|
+
content: message.content.slice(0, 2000).replace(/\0/g, ''),
|
|
39
|
+
},
|
|
40
|
+
].slice(-this.maxMessagesPerSession);
|
|
41
|
+
this.setHistory(sessionKey, updated);
|
|
42
|
+
}
|
|
43
|
+
clear(sessionKey) {
|
|
44
|
+
if (sessionKey) {
|
|
45
|
+
this.sessions.delete(sessionKey);
|
|
46
|
+
}
|
|
47
|
+
else {
|
|
48
|
+
this.sessions.clear();
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
sessionCount() {
|
|
52
|
+
return this.sessions.size;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
exports.SessionHistoryManager = SessionHistoryManager;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const session_history_1 = require("./session-history");
|
|
4
|
+
describe('SessionHistoryManager', () => {
|
|
5
|
+
test('isolates history across distinct sessions', () => {
|
|
6
|
+
const manager = new session_history_1.SessionHistoryManager();
|
|
7
|
+
manager.append('session-alice', { role: 'user', content: 'Alice message' });
|
|
8
|
+
manager.append('session-bob', { role: 'user', content: 'Bob message' });
|
|
9
|
+
expect(manager.getHistory('session-alice')).toEqual([
|
|
10
|
+
{ role: 'user', content: 'Alice message' },
|
|
11
|
+
]);
|
|
12
|
+
expect(manager.getHistory('session-bob')).toEqual([
|
|
13
|
+
{ role: 'user', content: 'Bob message' },
|
|
14
|
+
]);
|
|
15
|
+
});
|
|
16
|
+
test('bounds messages per session to configured limit and strips null bytes', () => {
|
|
17
|
+
const manager = new session_history_1.SessionHistoryManager({ maxMessagesPerSession: 3 });
|
|
18
|
+
manager.append('sess-1', { role: 'user', content: 'm1\0' });
|
|
19
|
+
manager.append('sess-1', { role: 'assistant', content: 'm2' });
|
|
20
|
+
manager.append('sess-1', { role: 'user', content: 'm3' });
|
|
21
|
+
manager.append('sess-1', { role: 'assistant', content: 'm4' });
|
|
22
|
+
const history = manager.getHistory('sess-1');
|
|
23
|
+
expect(history).toHaveLength(3);
|
|
24
|
+
expect(history[0].content).toBe('m2');
|
|
25
|
+
expect(history[2].content).toBe('m4');
|
|
26
|
+
});
|
|
27
|
+
test('bounds maximum active sessions with LRU eviction', () => {
|
|
28
|
+
const manager = new session_history_1.SessionHistoryManager({ maxSessions: 2 });
|
|
29
|
+
manager.append('sess-1', { role: 'user', content: 'm1' });
|
|
30
|
+
manager.append('sess-2', { role: 'user', content: 'm2' });
|
|
31
|
+
expect(manager.sessionCount()).toBe(2);
|
|
32
|
+
manager.append('sess-3', { role: 'user', content: 'm3' });
|
|
33
|
+
expect(manager.sessionCount()).toBe(2);
|
|
34
|
+
expect(manager.getHistory('sess-1')).toEqual([]);
|
|
35
|
+
expect(manager.getHistory('sess-2')).toHaveLength(1);
|
|
36
|
+
expect(manager.getHistory('sess-3')).toHaveLength(1);
|
|
37
|
+
});
|
|
38
|
+
});
|
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
import { ClaimStatus, DirectiveStatus } from './proposals';
|
|
2
|
+
export interface SelfIdentity {
|
|
3
|
+
companionId: string;
|
|
4
|
+
name: string;
|
|
5
|
+
archetype?: string;
|
|
6
|
+
role?: string;
|
|
7
|
+
origin?: string;
|
|
8
|
+
ethos?: string;
|
|
9
|
+
version: string;
|
|
10
|
+
updatedAt: string;
|
|
11
|
+
}
|
|
12
|
+
export interface PersonalityTraits {
|
|
13
|
+
warmth?: number;
|
|
14
|
+
formality?: number;
|
|
15
|
+
sarcasm?: number;
|
|
16
|
+
verbosity?: number;
|
|
17
|
+
curiosity?: number;
|
|
18
|
+
}
|
|
19
|
+
export interface SelfDirective {
|
|
20
|
+
id: string;
|
|
21
|
+
companionId: string;
|
|
22
|
+
priority?: number;
|
|
23
|
+
directive: string;
|
|
24
|
+
status: DirectiveStatus;
|
|
25
|
+
category: 'behavioral' | 'guardrail' | 'relational' | string;
|
|
26
|
+
scopeActor?: string;
|
|
27
|
+
supersedesId?: string;
|
|
28
|
+
createdAt?: string;
|
|
29
|
+
}
|
|
30
|
+
export interface SelfRelationship {
|
|
31
|
+
companionId: string;
|
|
32
|
+
entityId: string;
|
|
33
|
+
entityType?: 'human' | 'companion' | 'system';
|
|
34
|
+
name?: string;
|
|
35
|
+
affiliation?: string;
|
|
36
|
+
role?: string;
|
|
37
|
+
stance?: string;
|
|
38
|
+
trustScore?: number;
|
|
39
|
+
familiarity?: number;
|
|
40
|
+
interactionConventions: string[];
|
|
41
|
+
updatedAt?: string;
|
|
42
|
+
}
|
|
43
|
+
export interface SelfDialogueExample {
|
|
44
|
+
id?: string;
|
|
45
|
+
companionId?: string;
|
|
46
|
+
user: string;
|
|
47
|
+
assistant: string;
|
|
48
|
+
createdAt?: string;
|
|
49
|
+
}
|
|
50
|
+
export interface LifeInventoryItem {
|
|
51
|
+
id: string;
|
|
52
|
+
companionId: string;
|
|
53
|
+
domain: string;
|
|
54
|
+
entityName: string;
|
|
55
|
+
properties: Record<string, unknown>;
|
|
56
|
+
updatedAt: string;
|
|
57
|
+
}
|
|
58
|
+
export interface LifeFinanceEntry {
|
|
59
|
+
id: string;
|
|
60
|
+
companionId: string;
|
|
61
|
+
category: string;
|
|
62
|
+
amount: number;
|
|
63
|
+
currency: string;
|
|
64
|
+
timestamp: string;
|
|
65
|
+
metadata?: Record<string, unknown>;
|
|
66
|
+
}
|
|
67
|
+
export interface LifeScheduleItem {
|
|
68
|
+
id: string;
|
|
69
|
+
companionId: string;
|
|
70
|
+
title: string;
|
|
71
|
+
startTime: string;
|
|
72
|
+
endTime?: string;
|
|
73
|
+
isRecurring: boolean;
|
|
74
|
+
status: string;
|
|
75
|
+
}
|
|
76
|
+
export interface LifePreference {
|
|
77
|
+
id: string;
|
|
78
|
+
companionId: string;
|
|
79
|
+
preferenceKey: string;
|
|
80
|
+
preferenceValue: string;
|
|
81
|
+
category: string;
|
|
82
|
+
updatedAt: string;
|
|
83
|
+
}
|
|
84
|
+
export interface LifeEntity {
|
|
85
|
+
id: string;
|
|
86
|
+
companionId: string;
|
|
87
|
+
entityType: string;
|
|
88
|
+
domain: string;
|
|
89
|
+
name: string;
|
|
90
|
+
properties: Record<string, unknown>;
|
|
91
|
+
updatedAt?: string;
|
|
92
|
+
}
|
|
93
|
+
export interface LifeEvent {
|
|
94
|
+
id: string;
|
|
95
|
+
companionId: string;
|
|
96
|
+
stream: string;
|
|
97
|
+
timestamp?: string;
|
|
98
|
+
metricValue?: number;
|
|
99
|
+
metadata?: Record<string, unknown>;
|
|
100
|
+
}
|
|
101
|
+
export interface LifeTask {
|
|
102
|
+
id: string;
|
|
103
|
+
companionId: string;
|
|
104
|
+
title: string;
|
|
105
|
+
status: 'backlog' | 'in_progress' | 'completed' | 'cancelled' | string;
|
|
106
|
+
priority?: number;
|
|
107
|
+
targetDate?: string;
|
|
108
|
+
metadata?: Record<string, unknown>;
|
|
109
|
+
updatedAt?: string;
|
|
110
|
+
}
|
|
111
|
+
export interface EpisodicEvent {
|
|
112
|
+
id: string;
|
|
113
|
+
companionId: string;
|
|
114
|
+
sourceType: 'chat_turn' | 'tool_result' | 'sensory';
|
|
115
|
+
occurredAt: string;
|
|
116
|
+
payload: Record<string, unknown>;
|
|
117
|
+
}
|
|
118
|
+
export interface MemoryClaim {
|
|
119
|
+
id: string;
|
|
120
|
+
companionId: string;
|
|
121
|
+
subject: string;
|
|
122
|
+
predicate: string;
|
|
123
|
+
value: string;
|
|
124
|
+
status: ClaimStatus;
|
|
125
|
+
confidence: number;
|
|
126
|
+
validFrom?: string;
|
|
127
|
+
validUntil?: string;
|
|
128
|
+
evidence?: string[];
|
|
129
|
+
assertedAt: string;
|
|
130
|
+
supersedes?: string;
|
|
131
|
+
sourceEventId?: string;
|
|
132
|
+
}
|
|
133
|
+
export type LogLevel = 'debug' | 'info' | 'warn' | 'error';
|
|
134
|
+
export interface SystemLog {
|
|
135
|
+
id: string;
|
|
136
|
+
companionId: string;
|
|
137
|
+
level: LogLevel;
|
|
138
|
+
subsystem: string;
|
|
139
|
+
message: string;
|
|
140
|
+
metadata?: Record<string, unknown>;
|
|
141
|
+
createdAt: string;
|
|
142
|
+
}
|
|
143
|
+
export declare function safeJsonParse<T = any>(str?: string | null, fallback?: T): T;
|
|
144
|
+
export declare function normalizeStatus(status?: string, defaultStatus?: string): string;
|
|
145
|
+
export interface SiduriDatabaseOptions {
|
|
146
|
+
dbPath?: string;
|
|
147
|
+
}
|
|
148
|
+
export declare class SiduriDatabase {
|
|
149
|
+
private db;
|
|
150
|
+
constructor(options?: SiduriDatabaseOptions);
|
|
151
|
+
private initSchema;
|
|
152
|
+
close(): void;
|
|
153
|
+
getIdentity(companionId: string): SelfIdentity | undefined;
|
|
154
|
+
setIdentity(identity: SelfIdentity): void;
|
|
155
|
+
getPersonality(companionId: string): PersonalityTraits | undefined;
|
|
156
|
+
setPersonality(companionId: string, traits: PersonalityTraits): void;
|
|
157
|
+
private rowToSelfDirective;
|
|
158
|
+
getActiveDirectives(companionId: string): SelfDirective[];
|
|
159
|
+
getAllDirectives(companionId: string): SelfDirective[];
|
|
160
|
+
commitDirective(directive: SelfDirective): void;
|
|
161
|
+
getDirective(id: string, companionId?: string): SelfDirective | undefined;
|
|
162
|
+
approveDirective(id: string, companionId?: string): void;
|
|
163
|
+
rejectDirective(id: string, companionId?: string): void;
|
|
164
|
+
supersedeDirective(id: string, companionId?: string): void;
|
|
165
|
+
revokeDirective(id: string, companionId?: string): void;
|
|
166
|
+
expireDirective(id: string, companionId?: string): void;
|
|
167
|
+
disableDirective(id: string, companionId?: string): void;
|
|
168
|
+
getRelationship(companionId: string, entityId: string): SelfRelationship | undefined;
|
|
169
|
+
getRelationships(companionId: string): SelfRelationship[];
|
|
170
|
+
upsertRelationship(rel: SelfRelationship): void;
|
|
171
|
+
getExemplars(companionId: string): SelfDialogueExample[];
|
|
172
|
+
setExemplars(companionId: string, exemplars: SelfDialogueExample[]): void;
|
|
173
|
+
getInventory(companionId: string, domain?: string): LifeInventoryItem[];
|
|
174
|
+
upsertInventoryItem(item: LifeInventoryItem): void;
|
|
175
|
+
getFinanceEntries(companionId: string, limit?: number): LifeFinanceEntry[];
|
|
176
|
+
addFinanceEntry(entry: LifeFinanceEntry): void;
|
|
177
|
+
getSchedule(companionId: string): LifeScheduleItem[];
|
|
178
|
+
upsertScheduleItem(item: LifeScheduleItem): void;
|
|
179
|
+
deleteScheduleItem(id: string): boolean;
|
|
180
|
+
getPreferences(companionId: string): LifePreference[];
|
|
181
|
+
upsertPreference(pref: LifePreference): void;
|
|
182
|
+
getEntities(companionId: string, entityType?: string, domain?: string): LifeEntity[];
|
|
183
|
+
getEntityById(id: string): LifeEntity | undefined;
|
|
184
|
+
upsertEntity(entity: LifeEntity): void;
|
|
185
|
+
deleteEntity(id: string): boolean;
|
|
186
|
+
getEvents(companionId: string, stream?: string, limit?: number): LifeEvent[];
|
|
187
|
+
addEvent(event: LifeEvent): void;
|
|
188
|
+
getTasks(companionId: string, status?: string): LifeTask[];
|
|
189
|
+
upsertTask(task: LifeTask): void;
|
|
190
|
+
deleteTask(id: string): boolean;
|
|
191
|
+
recordEvent(event: EpisodicEvent): void;
|
|
192
|
+
getRecentEvents(companionId: string, limit?: number): EpisodicEvent[];
|
|
193
|
+
getEvent(id: string): EpisodicEvent | undefined;
|
|
194
|
+
private rowToMemoryClaim;
|
|
195
|
+
proposeClaim(claim: Omit<MemoryClaim, 'status' | 'confidence' | 'assertedAt'> & {
|
|
196
|
+
confidence?: number;
|
|
197
|
+
assertedAt?: string;
|
|
198
|
+
supersedes?: string;
|
|
199
|
+
sourceEventId?: string;
|
|
200
|
+
status?: string;
|
|
201
|
+
}): MemoryClaim;
|
|
202
|
+
approveClaim(id: string, companionId?: string): void;
|
|
203
|
+
/**
|
|
204
|
+
* Canonically promotes a Claim into Self domain tables.
|
|
205
|
+
*/
|
|
206
|
+
promoteClaimToSelf(claim: MemoryClaim | any): void;
|
|
207
|
+
rejectClaim(id: string, companionId?: string): void;
|
|
208
|
+
revokeClaim(id: string, companionId?: string): void;
|
|
209
|
+
expireClaim(id: string, companionId?: string): void;
|
|
210
|
+
markClaimSessionOnly(id: string, companionId?: string): void;
|
|
211
|
+
searchClaims(companionId: string, query: string, limit?: number): MemoryClaim[];
|
|
212
|
+
getPendingClaims(companionId: string, limit?: number): MemoryClaim[];
|
|
213
|
+
getApprovedClaims(companionId: string, limit?: number): MemoryClaim[];
|
|
214
|
+
getAllClaims(companionId?: string, limit?: number): MemoryClaim[];
|
|
215
|
+
getClaim(id: string): MemoryClaim | undefined;
|
|
216
|
+
resetMemory(companionId: string): void;
|
|
217
|
+
insertLog(entry: {
|
|
218
|
+
id?: string;
|
|
219
|
+
companionId?: string;
|
|
220
|
+
level: LogLevel | string;
|
|
221
|
+
subsystem: string;
|
|
222
|
+
message: string;
|
|
223
|
+
metadata?: Record<string, unknown>;
|
|
224
|
+
createdAt?: string;
|
|
225
|
+
}): SystemLog;
|
|
226
|
+
queryLogs(options?: {
|
|
227
|
+
companionId?: string;
|
|
228
|
+
level?: string;
|
|
229
|
+
subsystem?: string;
|
|
230
|
+
q?: string;
|
|
231
|
+
limit?: number;
|
|
232
|
+
offset?: number;
|
|
233
|
+
}): SystemLog[];
|
|
234
|
+
clearLogs(companionId?: string): void;
|
|
235
|
+
}
|