@siduri-x/core 2.0.0 → 2.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/action-policy.d.ts +35 -1
- package/dist/action-policy.js +228 -8
- package/dist/action-policy.test.js +171 -1
- package/dist/action.d.ts +1 -1
- package/dist/adversarial.test.js +4 -2
- package/dist/capability.d.ts +15 -2
- package/dist/capability.js +12 -1
- package/dist/capability.test.js +44 -1
- package/dist/chat-contract.d.ts +3 -1
- package/dist/chat-contract.js +5 -2
- package/dist/container.d.ts +74 -0
- package/dist/container.js +81 -0
- package/dist/context.d.ts +1 -1
- package/dist/index.d.ts +11 -7
- package/dist/index.js +2 -0
- package/dist/input-normalizer.js +3 -1
- package/dist/perception-pipeline.d.ts +76 -0
- package/dist/perception-pipeline.js +255 -0
- package/dist/perception-pipeline.test.d.ts +1 -0
- package/dist/perception-pipeline.test.js +65 -0
- package/dist/runtime-facades.test.js +27 -27
- package/dist/runtime.d.ts +36 -112
- package/dist/runtime.js +58 -392
- package/dist/schema-validator.test.js +2 -2
- package/dist/siduri-db.d.ts +27 -8
- package/dist/siduri-db.js +260 -17
- package/dist/siduri-db.test.js +284 -0
- package/dist/sqlite-action-store.d.ts +3 -2
- package/dist/sqlite-action-store.js +60 -6
- package/dist/sqlite-action-store.test.js +10 -0
- package/package.json +6 -6
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const perception_pipeline_1 = require("./perception-pipeline");
|
|
4
|
+
const gating_1 = require("./gating");
|
|
5
|
+
const action_policy_1 = require("./action-policy");
|
|
6
|
+
const dispatcher_1 = require("./dispatcher");
|
|
7
|
+
const session_history_1 = require("./session-history");
|
|
8
|
+
describe('PerceptionPipeline (Pipes & Filters Execution)', () => {
|
|
9
|
+
function createMockContext(overrides = {}) {
|
|
10
|
+
return {
|
|
11
|
+
companionId: 'test-companion',
|
|
12
|
+
companionName: 'Test Companion',
|
|
13
|
+
perception: {
|
|
14
|
+
source: 'text_chat',
|
|
15
|
+
text: 'Hello world',
|
|
16
|
+
roleOrContext: 'OWNER',
|
|
17
|
+
},
|
|
18
|
+
organs: {},
|
|
19
|
+
gating: new gating_1.ResponseGatingEngine(),
|
|
20
|
+
actionPolicy: new action_policy_1.ActionPolicyEngine(),
|
|
21
|
+
dispatcher: new dispatcher_1.ExperienceDispatcher(),
|
|
22
|
+
sessionHistory: new session_history_1.SessionHistoryManager(),
|
|
23
|
+
...overrides,
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
test('executes stages in sequence and returns response envelope', async () => {
|
|
27
|
+
const executedStages = [];
|
|
28
|
+
const stageA = async (ctx) => {
|
|
29
|
+
executedStages.push('stageA');
|
|
30
|
+
ctx.rawText = (ctx.perception.text || '').toUpperCase();
|
|
31
|
+
};
|
|
32
|
+
const stageB = async (ctx) => {
|
|
33
|
+
executedStages.push('stageB');
|
|
34
|
+
ctx.responseEnvelope = { result: ctx.rawText };
|
|
35
|
+
};
|
|
36
|
+
const pipeline = new perception_pipeline_1.PerceptionPipeline([stageA, stageB]);
|
|
37
|
+
const ctx = createMockContext();
|
|
38
|
+
const result = await pipeline.execute(ctx);
|
|
39
|
+
expect(executedStages).toEqual(['stageA', 'stageB']);
|
|
40
|
+
expect(result).toEqual({ result: 'HELLO WORLD' });
|
|
41
|
+
});
|
|
42
|
+
test('halts pipeline execution early when a stage returns false', async () => {
|
|
43
|
+
const executedStages = [];
|
|
44
|
+
const stageA = async () => {
|
|
45
|
+
executedStages.push('stageA');
|
|
46
|
+
};
|
|
47
|
+
const stageReject = async (ctx) => {
|
|
48
|
+
executedStages.push('stageReject');
|
|
49
|
+
ctx.responseEnvelope = { rejected: true, reason: 'halt_early' };
|
|
50
|
+
return false; // halt
|
|
51
|
+
};
|
|
52
|
+
const stageB = async () => {
|
|
53
|
+
executedStages.push('stageB');
|
|
54
|
+
};
|
|
55
|
+
const pipeline = new perception_pipeline_1.PerceptionPipeline([stageA, stageReject, stageB]);
|
|
56
|
+
const ctx = createMockContext();
|
|
57
|
+
const result = await pipeline.execute(ctx);
|
|
58
|
+
expect(executedStages).toEqual(['stageA', 'stageReject']);
|
|
59
|
+
expect(result).toEqual({ rejected: true, reason: 'halt_early' });
|
|
60
|
+
});
|
|
61
|
+
test('createDefaultPerceptionPipeline constructs a 12-stage pipeline', () => {
|
|
62
|
+
const defaultPipeline = (0, perception_pipeline_1.createDefaultPerceptionPipeline)();
|
|
63
|
+
expect(defaultPipeline.stages.length).toBe(12);
|
|
64
|
+
});
|
|
65
|
+
});
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
const
|
|
4
|
-
describe('
|
|
5
|
-
test('delegates vision and observation methods to configured organs', async () => {
|
|
3
|
+
const container_1 = require("./container");
|
|
4
|
+
describe('CompanionContainer & Direct Domain Access', () => {
|
|
5
|
+
test('delegates vision and observation methods to configured organs via container', async () => {
|
|
6
6
|
const mockVision = {
|
|
7
7
|
analyze: jest.fn().mockResolvedValue('an ancient artifact'),
|
|
8
8
|
};
|
|
@@ -11,23 +11,23 @@ describe('SiduriRuntime Facade Methods & Delegation', () => {
|
|
|
11
11
|
current: jest.fn().mockReturnValue([{ observationId: 'obs-1' }]),
|
|
12
12
|
clearExpired: jest.fn().mockReturnValue(1),
|
|
13
13
|
};
|
|
14
|
-
const
|
|
14
|
+
const container = new container_1.CompanionContainer('test-comp', { name: 'Test' }, {
|
|
15
15
|
vision: mockVision,
|
|
16
16
|
observation: mockObservation,
|
|
17
17
|
});
|
|
18
|
-
const visionResult = await
|
|
18
|
+
const visionResult = await container.vision.analyze('http://example.com/img.png', 'describe');
|
|
19
19
|
expect(visionResult).toBe('an ancient artifact');
|
|
20
20
|
expect(mockVision.analyze).toHaveBeenCalledWith('http://example.com/img.png', 'describe');
|
|
21
21
|
const frame = new Uint8Array([1, 2, 3]);
|
|
22
|
-
const obsResult = await
|
|
22
|
+
const obsResult = await container.observation.ingest(frame, 'camera-1', 'provider-x');
|
|
23
23
|
expect(obsResult.duplicate).toBe(false);
|
|
24
24
|
expect(mockObservation.ingest).toHaveBeenCalledWith(frame, 'camera-1', 'provider-x');
|
|
25
|
-
const cur =
|
|
25
|
+
const cur = container.observation.current();
|
|
26
26
|
expect(cur).toEqual([{ observationId: 'obs-1' }]);
|
|
27
|
-
const cleared =
|
|
27
|
+
const cleared = container.observation.clearExpired();
|
|
28
28
|
expect(cleared).toBe(1);
|
|
29
29
|
});
|
|
30
|
-
test('delegates memory operations
|
|
30
|
+
test('delegates memory operations directly on the memory organ', async () => {
|
|
31
31
|
const mockMemory = {
|
|
32
32
|
initialize: jest.fn().mockResolvedValue(undefined),
|
|
33
33
|
getClaims: jest.fn().mockResolvedValue([{ id: 'claim-1' }]),
|
|
@@ -42,39 +42,39 @@ describe('SiduriRuntime Facade Methods & Delegation', () => {
|
|
|
42
42
|
disableDirective: jest.fn().mockResolvedValue(undefined),
|
|
43
43
|
resetMemory: jest.fn().mockResolvedValue(undefined),
|
|
44
44
|
};
|
|
45
|
-
const
|
|
45
|
+
const container = new container_1.CompanionContainer('test-comp', { name: 'Test' }, {
|
|
46
46
|
memory: mockMemory,
|
|
47
47
|
});
|
|
48
|
-
expect(await
|
|
48
|
+
expect(await container.memory.getClaims(10)).toEqual([{ id: 'claim-1' }]);
|
|
49
49
|
expect(mockMemory.getClaims).toHaveBeenCalledWith(10);
|
|
50
|
-
expect(await
|
|
51
|
-
expect(await
|
|
52
|
-
await
|
|
50
|
+
expect(await container.memory.getPendingClaims()).toEqual([{ id: 'claim-pending-1' }]);
|
|
51
|
+
expect(await container.memory.getDirectives()).toEqual([{ id: 'dir-1' }]);
|
|
52
|
+
await container.memory.approveClaim('c-1');
|
|
53
53
|
expect(mockMemory.approveClaim).toHaveBeenCalledWith('c-1');
|
|
54
|
-
await
|
|
54
|
+
await container.memory.rejectClaim('c-2');
|
|
55
55
|
expect(mockMemory.rejectClaim).toHaveBeenCalledWith('c-2');
|
|
56
|
-
await
|
|
57
|
-
expect(mockMemory.updateClaim).toHaveBeenCalledWith('c-1', { value: '
|
|
58
|
-
await
|
|
56
|
+
await container.memory.updateClaim('c-1', { value: 'updated' });
|
|
57
|
+
expect(mockMemory.updateClaim).toHaveBeenCalledWith('c-1', { value: 'updated' });
|
|
58
|
+
await container.memory.approveDirective('d-1');
|
|
59
59
|
expect(mockMemory.approveDirective).toHaveBeenCalledWith('d-1');
|
|
60
|
-
await
|
|
60
|
+
await container.memory.rejectDirective('d-2');
|
|
61
61
|
expect(mockMemory.rejectDirective).toHaveBeenCalledWith('d-2');
|
|
62
|
-
await
|
|
62
|
+
await container.memory.revokeDirective('d-3');
|
|
63
63
|
expect(mockMemory.revokeDirective).toHaveBeenCalledWith('d-3');
|
|
64
|
-
await
|
|
64
|
+
await container.memory.disableDirective('d-4');
|
|
65
65
|
expect(mockMemory.disableDirective).toHaveBeenCalledWith('d-4');
|
|
66
|
-
await
|
|
66
|
+
await container.memory.resetMemory();
|
|
67
67
|
expect(mockMemory.resetMemory).toHaveBeenCalled();
|
|
68
68
|
});
|
|
69
69
|
test('configures SqliteActionStore when actionStore is sqlite', () => {
|
|
70
|
-
const
|
|
70
|
+
const container = new container_1.CompanionContainer('comp-sqlite', {
|
|
71
71
|
id: 'comp-sqlite',
|
|
72
72
|
name: 'Sqlite Test',
|
|
73
73
|
actionStore: 'sqlite',
|
|
74
74
|
});
|
|
75
|
-
expect(
|
|
75
|
+
expect(container.actionPolicy.getStore()).toBeDefined();
|
|
76
76
|
// Verify it is an instance of SqliteActionStore
|
|
77
|
-
expect(
|
|
77
|
+
expect(container.actionPolicy.getStore().constructor.name).toBe('SqliteActionStore');
|
|
78
78
|
});
|
|
79
79
|
test('accepts custom actionStore via RuntimeOrgans', () => {
|
|
80
80
|
const customStore = {
|
|
@@ -87,9 +87,9 @@ describe('SiduriRuntime Facade Methods & Delegation', () => {
|
|
|
87
87
|
getAuditLog: jest.fn(),
|
|
88
88
|
verifyAuditChain: jest.fn(),
|
|
89
89
|
};
|
|
90
|
-
const
|
|
90
|
+
const container = new container_1.CompanionContainer('comp-custom', { id: 'comp-custom', name: 'Custom' }, {
|
|
91
91
|
actionStore: customStore,
|
|
92
92
|
});
|
|
93
|
-
expect(
|
|
93
|
+
expect(container.actionPolicy.getStore()).toBe(customStore);
|
|
94
94
|
});
|
|
95
95
|
});
|
package/dist/runtime.d.ts
CHANGED
|
@@ -1,126 +1,50 @@
|
|
|
1
|
-
import { BrainOrgan, MemoryOrgan, VoiceOrgan, KnowledgeOrgan, VisionOrgan, BehaviorOrgan, BodyOrgan, HandsOrgan, EarOrgan, ObservationOrgan,
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
memory?: OrganConfig | Record<string, unknown>;
|
|
7
|
-
knowledge?: OrganConfig | Record<string, unknown>;
|
|
8
|
-
behavior?: OrganConfig | Record<string, unknown>;
|
|
9
|
-
body?: OrganConfig | Record<string, unknown>;
|
|
10
|
-
vision?: OrganConfig | Record<string, unknown>;
|
|
11
|
-
hands?: OrganConfig | Record<string, unknown>;
|
|
12
|
-
ear?: OrganConfig | Record<string, unknown>;
|
|
13
|
-
observation?: OrganConfig | Record<string, unknown>;
|
|
14
|
-
mouth?: OrganConfig | Record<string, unknown>;
|
|
15
|
-
self?: OrganConfig | Record<string, unknown>;
|
|
16
|
-
externalKnowledge?: OrganConfig | Record<string, unknown>;
|
|
17
|
-
actionPolicy?: Record<string, unknown>;
|
|
18
|
-
actionStore?: 'in-memory' | 'sqlite' | {
|
|
19
|
-
type: 'sqlite' | 'in-memory';
|
|
20
|
-
dbPath?: string;
|
|
21
|
-
};
|
|
22
|
-
actionStorePath?: string;
|
|
23
|
-
[key: string]: unknown;
|
|
24
|
-
}
|
|
25
|
-
export interface RuntimeOrgans {
|
|
26
|
-
brain?: BrainOrgan;
|
|
27
|
-
memory?: MemoryOrgan;
|
|
28
|
-
voice?: VoiceOrgan | ExperienceAdapter;
|
|
29
|
-
knowledge?: KnowledgeOrgan;
|
|
30
|
-
vision?: VisionOrgan;
|
|
31
|
-
behavior?: BehaviorOrgan;
|
|
32
|
-
body?: BodyOrgan | ExperienceAdapter;
|
|
33
|
-
hands?: HandsOrgan;
|
|
34
|
-
ear?: EarOrgan;
|
|
35
|
-
observation?: ObservationOrgan;
|
|
36
|
-
mouth?: MouthOrgan;
|
|
37
|
-
self?: SelfRepository;
|
|
38
|
-
externalKnowledge?: EKnowledgeOrgan;
|
|
39
|
-
actionStore?: ActionStore;
|
|
40
|
-
actionPolicy?: ActionPolicyEngine;
|
|
41
|
-
}
|
|
42
|
-
export interface CompanionPerception {
|
|
43
|
-
source: string;
|
|
44
|
-
text?: string;
|
|
45
|
-
audioBuffer?: Uint8Array;
|
|
46
|
-
roleOrContext?: 'OWNER' | 'VIEWER' | 'OPERATOR' | RequestContext | string;
|
|
47
|
-
context?: RequestContext;
|
|
48
|
-
history?: Message[];
|
|
49
|
-
medium?: MouthMedium;
|
|
50
|
-
metadata?: Record<string, unknown>;
|
|
51
|
-
signal?: AbortSignal;
|
|
52
|
-
}
|
|
1
|
+
import { BrainOrgan, MemoryOrgan, VoiceOrgan, KnowledgeOrgan, VisionOrgan, BehaviorOrgan, BodyOrgan, HandsOrgan, EarOrgan, ObservationOrgan, MouthOrgan, SelfRepository, EKnowledgeOrgan, Message, RequestContext, MouthMedium, ResponseGatingEngine, ActionPolicyEngine, ExperienceDispatcher } from './index';
|
|
2
|
+
import { SessionHistoryManager } from './session-history';
|
|
3
|
+
import { CompanionPerception, PerceptionPipeline } from './perception-pipeline';
|
|
4
|
+
import { CompanionContainer, RuntimeOrgans, SiduriRuntimeConfig } from './container';
|
|
5
|
+
export { CompanionPerception, RuntimeOrgans, SiduriRuntimeConfig };
|
|
53
6
|
/**
|
|
54
|
-
* SiduriRuntime coordinates companion
|
|
55
|
-
*
|
|
56
|
-
*
|
|
7
|
+
* SiduriRuntime coordinates companion perception and cognition execution.
|
|
8
|
+
* Lifecycle management and organ storage are handled by CompanionContainer.
|
|
9
|
+
* The 12-stage perception cycle is executed via PerceptionPipeline.
|
|
57
10
|
*/
|
|
58
11
|
export declare class SiduriRuntime {
|
|
59
|
-
id: string;
|
|
60
|
-
config: SiduriRuntimeConfig;
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
12
|
+
readonly id: string;
|
|
13
|
+
readonly config: SiduriRuntimeConfig;
|
|
14
|
+
readonly container: CompanionContainer;
|
|
15
|
+
readonly pipeline: PerceptionPipeline;
|
|
16
|
+
constructor(id: string, config: SiduriRuntimeConfig, containerOrOrgans?: CompanionContainer | RuntimeOrgans, pipeline?: PerceptionPipeline);
|
|
17
|
+
get organs(): RuntimeOrgans;
|
|
18
|
+
get brain(): BrainOrgan | undefined;
|
|
19
|
+
get memory(): MemoryOrgan | undefined;
|
|
20
|
+
get voice(): VoiceOrgan | undefined;
|
|
21
|
+
get knowledge(): KnowledgeOrgan | undefined;
|
|
22
|
+
get vision(): VisionOrgan | undefined;
|
|
23
|
+
get behavior(): BehaviorOrgan | undefined;
|
|
24
|
+
get body(): BodyOrgan | undefined;
|
|
25
|
+
get hands(): HandsOrgan | undefined;
|
|
26
|
+
get ear(): EarOrgan | undefined;
|
|
27
|
+
get observation(): ObservationOrgan | undefined;
|
|
28
|
+
set observation(org: ObservationOrgan | undefined);
|
|
29
|
+
get mouth(): MouthOrgan | undefined;
|
|
30
|
+
get self(): SelfRepository | undefined;
|
|
31
|
+
get externalKnowledge(): EKnowledgeOrgan | undefined;
|
|
32
|
+
get gating(): ResponseGatingEngine;
|
|
33
|
+
get actionPolicy(): ActionPolicyEngine;
|
|
34
|
+
get dispatcher(): ExperienceDispatcher;
|
|
35
|
+
get sessionHistory(): SessionHistoryManager;
|
|
78
36
|
get conversationHistory(): Message[];
|
|
79
37
|
set conversationHistory(messages: Message[]);
|
|
80
|
-
constructor(id: string, config: SiduriRuntimeConfig, organs?: RuntimeOrgans);
|
|
81
38
|
initialize(): Promise<void>;
|
|
82
39
|
getSessionHistory(sessionKey: string): Message[];
|
|
83
40
|
clearHistory(sessionKey?: string): void;
|
|
84
|
-
analyzeVision(imageUrl: string, prompt: string): Promise<string>;
|
|
85
|
-
ingestObservation(frame: Uint8Array, sourceName: string, providerId?: string): Promise<ObservationResult>;
|
|
86
|
-
getCurrentObservations(now?: Date): Observation[];
|
|
87
|
-
clearExpiredObservations(now?: Date): number;
|
|
88
|
-
getClaims(limit?: number): Promise<Claim[]>;
|
|
89
|
-
getPendingClaims(limit?: number): Promise<Claim[]>;
|
|
90
|
-
getDirectives(): Promise<BehaviorDirective[]>;
|
|
91
|
-
approveClaim(id: string): Promise<void>;
|
|
92
|
-
rejectClaim(id: string): Promise<void>;
|
|
93
|
-
updateClaim(id: string, updates: Partial<Pick<Claim, 'subject' | 'predicate' | 'value' | 'scope' | 'sensitivity' | 'confidence' | 'validFrom' | 'validUntil'>>): Promise<Claim>;
|
|
94
|
-
approveDirective(id: string): Promise<void>;
|
|
95
|
-
rejectDirective(id: string): Promise<void>;
|
|
96
|
-
revokeDirective(id: string): Promise<void>;
|
|
97
|
-
disableDirective(id: string): Promise<void>;
|
|
98
|
-
resetMemory(): Promise<void>;
|
|
99
|
-
stageResponse(options: StageResponseOptions): StagedResponsePlan;
|
|
100
|
-
evaluateGate(plan: StagedResponsePlan, evidenceRecords?: EvidenceRecord[]): ResponseGateEvaluation;
|
|
101
|
-
approveResponse(options: ApproveResponseOptions): {
|
|
102
|
-
success: boolean;
|
|
103
|
-
reason?: string;
|
|
104
|
-
plan?: StagedResponsePlan;
|
|
105
|
-
};
|
|
106
|
-
rejectResponse(options: RejectResponseOptions): {
|
|
107
|
-
success: boolean;
|
|
108
|
-
reason?: string;
|
|
109
|
-
plan?: StagedResponsePlan;
|
|
110
|
-
};
|
|
111
|
-
getStagedPlan(responseId: string): StagedResponsePlan | undefined;
|
|
112
|
-
findStagedPlanByCorrelation(companionId: string, correlationId: string): StagedResponsePlan | undefined;
|
|
113
41
|
/**
|
|
114
42
|
* Processes an incoming perception (sensory audio, text, platform event, or observation alert)
|
|
115
|
-
* through the
|
|
43
|
+
* through the decoupled PerceptionPipeline.
|
|
116
44
|
*/
|
|
117
45
|
processPerception(perception: CompanionPerception): Promise<any>;
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
unregisterMouthChannel(channelId: string): void;
|
|
122
|
-
broadcastMouth(utterance: MouthUtterance): Promise<FormattedMouthOutput[]>;
|
|
123
|
-
interruptMouth(reason?: string): void;
|
|
124
|
-
streamMouth(utterance: MouthUtterance): AsyncIterable<MouthStreamChunk>;
|
|
46
|
+
/**
|
|
47
|
+
* Primary entrypoint for text chat messages.
|
|
48
|
+
*/
|
|
125
49
|
handleUserMessage(message: string, roleOrContext?: 'OWNER' | 'VIEWER' | 'OPERATOR' | RequestContext | string, history?: Message[], medium?: MouthMedium, signal?: AbortSignal): Promise<any>;
|
|
126
50
|
}
|