@siduri-x/api 2.0.1 → 2.0.3
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/.turbo/turbo-build.log +1 -1
- package/.turbo/turbo-test.log +17 -14
- package/dist/app.d.ts +2 -34
- package/dist/app.js +163 -130
- package/dist/boot.d.ts +92 -0
- package/dist/boot.js +146 -0
- package/dist/boot.test.d.ts +1 -0
- package/dist/boot.test.js +84 -0
- package/dist/context-mapper.d.ts +3 -1
- package/dist/context-mapper.js +80 -20
- package/dist/context-mapper.test.js +126 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +10 -90
- package/dist/index.test.js +18 -4
- package/dist/knowledge.test.d.ts +1 -0
- package/dist/knowledge.test.js +138 -0
- package/dist/t6-security.test.js +52 -3
- package/dist/teach-mode.test.js +67 -0
- package/package.json +6 -6
- package/siduri.sqlite +0 -0
- package/src/app.ts +176 -174
- package/src/boot.test.ts +103 -0
- package/src/boot.ts +190 -0
- package/src/context-mapper.test.ts +139 -0
- package/src/context-mapper.ts +87 -20
- package/src/index.test.ts +24 -4
- package/src/index.ts +10 -100
- package/src/knowledge.test.ts +156 -0
- package/src/t6-security.test.ts +56 -3
- package/src/teach-mode.test.ts +77 -0
package/.turbo/turbo-build.log
CHANGED
package/.turbo/turbo-test.log
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
|
|
2
|
-
> @siduri-x/api@2.0.
|
|
2
|
+
> @siduri-x/api@2.0.3 test /home/zagin/Projects/vxnus-studio/projects/siduri-x/apps/api
|
|
3
3
|
> jest --config jest.config.json
|
|
4
4
|
|
|
5
|
-
PASS src/context-mapper.test.ts (
|
|
6
|
-
PASS src/runtime.test.ts (
|
|
5
|
+
PASS src/context-mapper.test.ts (17.122 s)
|
|
6
|
+
PASS src/runtime.test.ts (17.986 s)
|
|
7
7
|
● Console
|
|
8
8
|
|
|
9
9
|
console.error
|
|
@@ -20,21 +20,24 @@ PASS src/runtime.test.ts (10.545 s)
|
|
|
20
20
|
at ../../packages/core/dist/context-retriever.js:23:25
|
|
21
21
|
at async Promise.all (index 0)
|
|
22
22
|
at retrieveRuntimeContext (../../packages/core/dist/context-retriever.js:19:78)
|
|
23
|
-
at
|
|
23
|
+
at contextRetrievalStage (../../packages/core/dist/perception-pipeline.js:66:30)
|
|
24
|
+
at PerceptionPipeline.execute (../../packages/core/dist/perception-pipeline.js:21:34)
|
|
24
25
|
at Object.<anonymous> (src/runtime.test.ts:74:22)
|
|
25
26
|
|
|
26
|
-
PASS src/
|
|
27
|
-
PASS src/
|
|
27
|
+
PASS src/t5-experience.test.ts (19.901 s)
|
|
28
|
+
PASS src/t4-gating.test.ts (19.152 s)
|
|
29
|
+
PASS src/index.test.ts (19.326 s)
|
|
30
|
+
PASS src/teach-mode.test.ts (20.058 s)
|
|
31
|
+
PASS src/t7-release.test.ts
|
|
28
32
|
PASS src/smoke.test.ts
|
|
29
|
-
PASS src/
|
|
33
|
+
PASS src/auth.test.ts
|
|
34
|
+
PASS src/t6-security.test.ts (19.898 s)
|
|
35
|
+
PASS src/boot.test.ts
|
|
30
36
|
PASS src/b0-b6.test.ts
|
|
31
|
-
PASS src/
|
|
32
|
-
PASS src/t7-release.test.ts (11.335 s)
|
|
33
|
-
PASS src/teach-mode.test.ts
|
|
34
|
-
PASS src/t6-security.test.ts (12.22 s)
|
|
37
|
+
PASS src/knowledge.test.ts
|
|
35
38
|
[999D[K
|
|
36
|
-
Test Suites:
|
|
37
|
-
Tests:
|
|
39
|
+
Test Suites: 13 passed, 13 total
|
|
40
|
+
Tests: 90 passed, 90 total
|
|
38
41
|
Snapshots: 0 total
|
|
39
|
-
Time:
|
|
42
|
+
Time: 23.887 s
|
|
40
43
|
Ran all test suites.
|
package/dist/app.d.ts
CHANGED
|
@@ -1,40 +1,8 @@
|
|
|
1
1
|
import { Express } from 'express';
|
|
2
2
|
import { SiduriRuntime } from './runtime';
|
|
3
|
-
import { VoiceConfig } from '@siduri-x/voice';
|
|
4
|
-
import { EKnowledgeConfig } from '@siduri-x/eknowledge';
|
|
5
|
-
import { OpenRouterVisionConfig } from '@siduri-x/vision';
|
|
6
|
-
import { Live2DAdapterConfig } from '@siduri-x/body';
|
|
7
3
|
import { FixtureObservationOrgan } from '@siduri-x/observation';
|
|
8
|
-
import {
|
|
9
|
-
|
|
10
|
-
import { DefaultMouthOrganConfig } from '@siduri-x/mouth';
|
|
11
|
-
export interface AppBrainConfig {
|
|
12
|
-
provider?: 'openrouter' | 'openai-compatible' | string;
|
|
13
|
-
model?: string;
|
|
14
|
-
apiKey?: string;
|
|
15
|
-
apiKeyEnv?: string;
|
|
16
|
-
baseUrl?: string;
|
|
17
|
-
timeoutMs?: number;
|
|
18
|
-
[key: string]: unknown;
|
|
19
|
-
}
|
|
20
|
-
export interface AppBehaviorConfig {
|
|
21
|
-
provider?: 'active_self' | 'none' | string;
|
|
22
|
-
preset?: string;
|
|
23
|
-
[key: string]: unknown;
|
|
24
|
-
}
|
|
25
|
-
export interface AppBootCompanionConfig {
|
|
26
|
-
name: string;
|
|
27
|
-
brain?: AppBrainConfig;
|
|
28
|
-
voice?: VoiceConfig;
|
|
29
|
-
knowledge?: EKnowledgeConfig;
|
|
30
|
-
vision?: OpenRouterVisionConfig;
|
|
31
|
-
behavior?: AppBehaviorConfig;
|
|
32
|
-
body?: Live2DAdapterConfig;
|
|
33
|
-
hands?: DefaultHandsOrganConfig;
|
|
34
|
-
ear?: EarOrganConfig;
|
|
35
|
-
mouth?: DefaultMouthOrganConfig;
|
|
36
|
-
[key: string]: unknown;
|
|
37
|
-
}
|
|
4
|
+
import { bootCompanion, AppBrainConfig, AppBehaviorConfig, AppBootCompanionConfig, BootCompanionOptions } from './boot';
|
|
5
|
+
export { AppBrainConfig, AppBehaviorConfig, AppBootCompanionConfig, BootCompanionOptions, bootCompanion, };
|
|
38
6
|
export interface AppInstance {
|
|
39
7
|
app: Express;
|
|
40
8
|
runtimes: Map<string, SiduriRuntime>;
|
package/dist/app.js
CHANGED
|
@@ -3,123 +3,29 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.bootCompanion = void 0;
|
|
6
7
|
exports.createApp = createApp;
|
|
7
8
|
const express_1 = __importDefault(require("express"));
|
|
8
9
|
const cors_1 = __importDefault(require("cors"));
|
|
9
10
|
const cors_2 = require("./cors");
|
|
10
11
|
const runtime_1 = require("./runtime");
|
|
11
|
-
const brain_1 = require("@siduri-x/brain");
|
|
12
|
-
const memory_1 = require("@siduri-x/memory");
|
|
13
|
-
const voice_1 = require("@siduri-x/voice");
|
|
14
|
-
const eknowledge_1 = require("@siduri-x/eknowledge");
|
|
15
|
-
const vision_1 = require("@siduri-x/vision");
|
|
16
12
|
const self_1 = require("@siduri-x/self");
|
|
17
|
-
const body_1 = require("@siduri-x/body");
|
|
18
|
-
const hands_1 = require("@siduri-x/hands");
|
|
19
|
-
const ear_1 = require("@siduri-x/ear");
|
|
20
|
-
const mouth_1 = require("@siduri-x/mouth");
|
|
21
13
|
const auth_1 = require("./auth");
|
|
22
14
|
const context_mapper_1 = require("./context-mapper");
|
|
15
|
+
const boot_1 = require("./boot");
|
|
16
|
+
Object.defineProperty(exports, "bootCompanion", { enumerable: true, get: function () { return boot_1.bootCompanion; } });
|
|
23
17
|
function createApp(runtimes = new Map()) {
|
|
24
18
|
const app = (0, express_1.default)();
|
|
25
19
|
app.use((0, cors_1.default)((0, cors_2.createCorsOptions)()));
|
|
26
20
|
app.use(express_1.default.json());
|
|
27
21
|
let observationOrgan;
|
|
28
|
-
function createBrain(config) {
|
|
29
|
-
const provider = config?.provider || 'openrouter';
|
|
30
|
-
const defaultKeyEnv = provider === 'openai-compatible' ? 'OPENAI_COMPATIBLE_API_KEY' : 'OPENROUTER_API_KEY';
|
|
31
|
-
const apiKey = config?.apiKey || process.env[config?.apiKeyEnv || defaultKeyEnv] || '';
|
|
32
|
-
if (provider === 'openai-compatible') {
|
|
33
|
-
return new brain_1.OpenAICompatibleBrain({
|
|
34
|
-
apiKey,
|
|
35
|
-
model: config?.model || 'local-model',
|
|
36
|
-
baseUrl: config?.baseUrl || 'http://127.0.0.1:1234/v1',
|
|
37
|
-
});
|
|
38
|
-
}
|
|
39
|
-
return new brain_1.OpenRouterBrain({ apiKey, model: config?.model || 'gpt-4o-mini' });
|
|
40
|
-
}
|
|
41
|
-
function isDisabled(config) {
|
|
42
|
-
return !config || config.provider === 'none';
|
|
43
|
-
}
|
|
44
|
-
function createVoice(config) {
|
|
45
|
-
return isDisabled(config)
|
|
46
|
-
? undefined
|
|
47
|
-
: new voice_1.VoiceAdapter({
|
|
48
|
-
provider: config?.provider || 'voicevox',
|
|
49
|
-
baseUrl: config?.baseUrl || process.env.VOICEVOX_URL || 'http://localhost:50021',
|
|
50
|
-
speakerId: config?.speakerId || 1,
|
|
51
|
-
...config,
|
|
52
|
-
});
|
|
53
|
-
}
|
|
54
|
-
function createKnowledge(config) {
|
|
55
|
-
return isDisabled(config) ? undefined : new eknowledge_1.EKnowledgeAdapter(config || {});
|
|
56
|
-
}
|
|
57
|
-
function createVision(config) {
|
|
58
|
-
return isDisabled(config)
|
|
59
|
-
? undefined
|
|
60
|
-
: new vision_1.OpenRouterVisionAdapter({
|
|
61
|
-
apiKey: config?.apiKey || process.env.OPENROUTER_API_KEY || '',
|
|
62
|
-
model: config?.model || 'gpt-4-vision',
|
|
63
|
-
...config,
|
|
64
|
-
});
|
|
65
|
-
}
|
|
66
|
-
function createBehavior(config) {
|
|
67
|
-
return isDisabled(config) ? undefined : new self_1.ActiveSelfCompiler();
|
|
68
|
-
}
|
|
69
|
-
function createBody(config) {
|
|
70
|
-
return isDisabled(config)
|
|
71
|
-
? undefined
|
|
72
|
-
: new body_1.Live2DAdapter(config);
|
|
73
|
-
}
|
|
74
|
-
function createHands(config) {
|
|
75
|
-
return isDisabled(config)
|
|
76
|
-
? new hands_1.DefaultHandsOrgan()
|
|
77
|
-
: new hands_1.DefaultHandsOrgan(config);
|
|
78
|
-
}
|
|
79
|
-
function createEar(config) {
|
|
80
|
-
return isDisabled(config)
|
|
81
|
-
? new ear_1.DefaultEarOrgan()
|
|
82
|
-
: new ear_1.DefaultEarOrgan(config);
|
|
83
|
-
}
|
|
84
|
-
function createMouth(config, voice) {
|
|
85
|
-
return isDisabled(config)
|
|
86
|
-
? new mouth_1.DefaultMouthOrgan({ voice })
|
|
87
|
-
: new mouth_1.DefaultMouthOrgan({ ...config, voice });
|
|
88
|
-
}
|
|
89
22
|
app.post('/boot', auth_1.requireAuth, async (req, res) => {
|
|
90
23
|
try {
|
|
91
24
|
const { id, config } = req.body;
|
|
92
25
|
if (runtimes.has(id)) {
|
|
93
26
|
return res.status(400).json({ error: "Already booted" });
|
|
94
27
|
}
|
|
95
|
-
const
|
|
96
|
-
const brain = createBrain(organs.brain || config?.brain);
|
|
97
|
-
const memory = new memory_1.SqliteMemoryStore({ dbPath: process.env.STORAGE_PATH || process.env.SQLITE_DB_PATH || 'siduri.sqlite' });
|
|
98
|
-
const selfRepo = new self_1.SqliteSelfRepository({ dbPath: process.env.STORAGE_PATH || process.env.SQLITE_DB_PATH || 'siduri.sqlite' });
|
|
99
|
-
const voice = createVoice(organs.voice || config?.voice);
|
|
100
|
-
const knowledge = createKnowledge(organs.knowledge || config?.knowledge);
|
|
101
|
-
const vision = createVision(organs.vision || config?.vision);
|
|
102
|
-
const behavior = createBehavior(organs.behavior || config?.behavior);
|
|
103
|
-
const body = createBody(organs.body || config?.body);
|
|
104
|
-
const hands = createHands(organs.hands || config?.hands);
|
|
105
|
-
const ear = createEar(organs.ear || config?.ear);
|
|
106
|
-
const mouth = createMouth(organs.mouth || config?.mouth, voice);
|
|
107
|
-
const runtime = new runtime_1.SiduriRuntime(id, config, {
|
|
108
|
-
brain,
|
|
109
|
-
memory,
|
|
110
|
-
voice,
|
|
111
|
-
knowledge,
|
|
112
|
-
vision,
|
|
113
|
-
behavior,
|
|
114
|
-
body,
|
|
115
|
-
hands,
|
|
116
|
-
ear,
|
|
117
|
-
mouth,
|
|
118
|
-
observation: observationOrgan,
|
|
119
|
-
self: selfRepo,
|
|
120
|
-
externalKnowledge: knowledge,
|
|
121
|
-
});
|
|
122
|
-
await runtime.initialize();
|
|
28
|
+
const runtime = await (0, boot_1.bootCompanion)(id, config, { observationOrgan });
|
|
123
29
|
runtimes.set(id, runtime);
|
|
124
30
|
res.json({ success: true, id });
|
|
125
31
|
}
|
|
@@ -208,12 +114,31 @@ function createApp(runtimes = new Map()) {
|
|
|
208
114
|
companionId,
|
|
209
115
|
name: manifest.identity.name,
|
|
210
116
|
archetype: manifest.identity.archetype,
|
|
117
|
+
origin: manifest.identity.origin,
|
|
118
|
+
ethos: manifest.identity.ethos,
|
|
211
119
|
version: manifest.version || '1.0.0',
|
|
212
120
|
updatedAt: new Date().toISOString(),
|
|
213
121
|
});
|
|
214
122
|
if (manifest.personality) {
|
|
215
123
|
await repo.setPersonality(companionId, manifest.personality);
|
|
216
124
|
}
|
|
125
|
+
if (Array.isArray(manifest.relationships)) {
|
|
126
|
+
for (const rel of manifest.relationships) {
|
|
127
|
+
if (rel && rel.entityId) {
|
|
128
|
+
await repo.updateRelationship(companionId, {
|
|
129
|
+
companionId,
|
|
130
|
+
entityId: rel.entityId,
|
|
131
|
+
entityType: 'human',
|
|
132
|
+
role: rel.role || 'user',
|
|
133
|
+
stance: rel.stance || 'neutral',
|
|
134
|
+
interactionConventions: rel.conventions || [],
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
if (Array.isArray(manifest.dialogueExamples) && repo.setExemplars) {
|
|
140
|
+
await repo.setExemplars(companionId, manifest.dialogueExamples);
|
|
141
|
+
}
|
|
217
142
|
if (directivesToCommit.length > 0) {
|
|
218
143
|
await repo.commitDirectives(companionId, directivesToCommit);
|
|
219
144
|
}
|
|
@@ -231,12 +156,18 @@ function createApp(runtimes = new Map()) {
|
|
|
231
156
|
app.post('/chat', auth_1.attachIdentity, async (req, res) => {
|
|
232
157
|
const { id, message, history } = req.body;
|
|
233
158
|
const identity = req.identity;
|
|
234
|
-
|
|
159
|
+
const local = (0, auth_1.isLocalRequest)(req);
|
|
160
|
+
const hasConfiguredToken = Boolean(process.env.AUTH_TOKEN || process.env.OPERATOR_TOKEN || process.env.OWNER_TOKEN);
|
|
161
|
+
const isLocalDirectOwner = local && !hasConfiguredToken;
|
|
162
|
+
const authenticated = identity?.authenticated || isLocalDirectOwner;
|
|
163
|
+
const serverRole = identity?.authenticated ? identity.role : (isLocalDirectOwner ? 'OWNER' : 'VIEWER');
|
|
164
|
+
// Single-owner companion model: map request context directly with server identity enforcement
|
|
235
165
|
const mappingResult = (0, context_mapper_1.mapRequestContext)({
|
|
236
166
|
...req.body,
|
|
237
167
|
id: id || req.body.companionId,
|
|
238
|
-
authenticated
|
|
239
|
-
|
|
168
|
+
authenticated,
|
|
169
|
+
serverRole,
|
|
170
|
+
source: identity?.source ?? (local ? 'local' : 'external'),
|
|
240
171
|
generateCorrelationId: true,
|
|
241
172
|
});
|
|
242
173
|
if (!mappingResult.accepted) {
|
|
@@ -268,11 +199,17 @@ function createApp(runtimes = new Map()) {
|
|
|
268
199
|
app.post('/chat/stream', auth_1.attachIdentity, async (req, res) => {
|
|
269
200
|
const { id, message, history } = req.body;
|
|
270
201
|
const identity = req.identity;
|
|
202
|
+
const local = (0, auth_1.isLocalRequest)(req);
|
|
203
|
+
const hasConfiguredToken = Boolean(process.env.AUTH_TOKEN || process.env.OPERATOR_TOKEN || process.env.OWNER_TOKEN);
|
|
204
|
+
const isLocalDirectOwner = local && !hasConfiguredToken;
|
|
205
|
+
const authenticated = identity?.authenticated || isLocalDirectOwner;
|
|
206
|
+
const serverRole = identity?.authenticated ? identity.role : (isLocalDirectOwner ? 'OWNER' : 'VIEWER');
|
|
271
207
|
const mappingResult = (0, context_mapper_1.mapRequestContext)({
|
|
272
208
|
...req.body,
|
|
273
209
|
id: id || req.body.companionId,
|
|
274
|
-
authenticated
|
|
275
|
-
|
|
210
|
+
authenticated,
|
|
211
|
+
serverRole,
|
|
212
|
+
source: identity?.source ?? (local ? 'local' : 'external'),
|
|
276
213
|
generateCorrelationId: true,
|
|
277
214
|
});
|
|
278
215
|
if (!mappingResult.accepted) {
|
|
@@ -292,8 +229,8 @@ function createApp(runtimes = new Map()) {
|
|
|
292
229
|
const abortController = new AbortController();
|
|
293
230
|
const onClose = () => {
|
|
294
231
|
abortController.abort('client_disconnect');
|
|
295
|
-
if (typeof runtime.
|
|
296
|
-
runtime.
|
|
232
|
+
if (runtime.mouth && typeof runtime.mouth.interrupt === 'function') {
|
|
233
|
+
runtime.mouth.interrupt('client_disconnect');
|
|
297
234
|
}
|
|
298
235
|
};
|
|
299
236
|
req.on('close', onClose);
|
|
@@ -307,7 +244,7 @@ function createApp(runtimes = new Map()) {
|
|
|
307
244
|
medium: 'web',
|
|
308
245
|
signal: abortController.signal,
|
|
309
246
|
});
|
|
310
|
-
res.write(`event: staged\ndata: ${JSON.stringify({ response_id: response.response_id, correlation_id: response.correlation_id, status: response.status })}\n\n`);
|
|
247
|
+
res.write(`event: staged\ndata: ${JSON.stringify({ response_id: response.response_id, correlation_id: response.correlation_id, status: response.status, mode: response.metadata?.mode })}\n\n`);
|
|
311
248
|
const avatarEvent = response.metadata?.events?.find((e) => (e.kind === 'avatar' || e.kind === 'body') && (e.approval === 'APPROVED' || !e.approval));
|
|
312
249
|
if (avatarEvent) {
|
|
313
250
|
res.write(`event: avatar\ndata: ${JSON.stringify(avatarEvent)}\n\n`);
|
|
@@ -360,11 +297,15 @@ function createApp(runtimes = new Map()) {
|
|
|
360
297
|
const runtime = companionId ? runtimes.get(companionId) : undefined;
|
|
361
298
|
const reason = req.body?.reason || 'user_barge_in';
|
|
362
299
|
if (runtime) {
|
|
363
|
-
runtime.
|
|
300
|
+
if (runtime.mouth && typeof runtime.mouth.interrupt === 'function') {
|
|
301
|
+
runtime.mouth.interrupt(reason);
|
|
302
|
+
}
|
|
364
303
|
return res.json({ success: true, interrupted: true, companionId, reason });
|
|
365
304
|
}
|
|
366
305
|
for (const r of runtimes.values()) {
|
|
367
|
-
r.
|
|
306
|
+
if (r.mouth && typeof r.mouth.interrupt === 'function') {
|
|
307
|
+
r.mouth.interrupt(reason);
|
|
308
|
+
}
|
|
368
309
|
}
|
|
369
310
|
return res.json({ success: true, interrupted: true, reason });
|
|
370
311
|
});
|
|
@@ -373,11 +314,15 @@ function createApp(runtimes = new Map()) {
|
|
|
373
314
|
const runtime = companionId ? runtimes.get(companionId) : undefined;
|
|
374
315
|
const reason = req.body?.reason || 'user_barge_in';
|
|
375
316
|
if (runtime) {
|
|
376
|
-
runtime.
|
|
317
|
+
if (runtime.mouth && typeof runtime.mouth.interrupt === 'function') {
|
|
318
|
+
runtime.mouth.interrupt(reason);
|
|
319
|
+
}
|
|
377
320
|
return res.json({ success: true, interrupted: true, companionId, reason });
|
|
378
321
|
}
|
|
379
322
|
for (const r of runtimes.values()) {
|
|
380
|
-
r.
|
|
323
|
+
if (r.mouth && typeof r.mouth.interrupt === 'function') {
|
|
324
|
+
r.mouth.interrupt(reason);
|
|
325
|
+
}
|
|
381
326
|
}
|
|
382
327
|
return res.json({ success: true, interrupted: true, reason });
|
|
383
328
|
});
|
|
@@ -390,7 +335,7 @@ function createApp(runtimes = new Map()) {
|
|
|
390
335
|
if (!runtime.memory)
|
|
391
336
|
return res.json({ proposals: [] });
|
|
392
337
|
try {
|
|
393
|
-
const proposals = await runtime.getPendingClaims();
|
|
338
|
+
const proposals = await runtime.memory.getPendingClaims();
|
|
394
339
|
res.json({ proposals });
|
|
395
340
|
}
|
|
396
341
|
catch (e) {
|
|
@@ -405,7 +350,7 @@ function createApp(runtimes = new Map()) {
|
|
|
405
350
|
if (!runtime.memory)
|
|
406
351
|
return res.json({ items: [] });
|
|
407
352
|
try {
|
|
408
|
-
const items = await runtime.getClaims();
|
|
353
|
+
const items = await runtime.memory.getClaims();
|
|
409
354
|
res.json({ items });
|
|
410
355
|
}
|
|
411
356
|
catch (e) {
|
|
@@ -420,7 +365,7 @@ function createApp(runtimes = new Map()) {
|
|
|
420
365
|
if (!runtime.memory)
|
|
421
366
|
return res.json({ claims: [] });
|
|
422
367
|
try {
|
|
423
|
-
const claims = await runtime.getClaims();
|
|
368
|
+
const claims = await runtime.memory.getClaims();
|
|
424
369
|
res.json({ claims });
|
|
425
370
|
}
|
|
426
371
|
catch (e) {
|
|
@@ -435,13 +380,101 @@ function createApp(runtimes = new Map()) {
|
|
|
435
380
|
if (!runtime.memory)
|
|
436
381
|
return res.json({ directives: [] });
|
|
437
382
|
try {
|
|
438
|
-
const directives = await runtime.getDirectives();
|
|
383
|
+
const directives = await runtime.memory.getDirectives();
|
|
439
384
|
res.json({ directives });
|
|
440
385
|
}
|
|
441
386
|
catch (e) {
|
|
442
387
|
res.status(500).json({ error: e.message });
|
|
443
388
|
}
|
|
444
389
|
});
|
|
390
|
+
// KNOWLEDGE / LIFE DB GETTERS
|
|
391
|
+
app.get('/knowledge/life', auth_1.requireAuth, async (req, res) => {
|
|
392
|
+
const id = req.query.id || Array.from(runtimes.keys())[0];
|
|
393
|
+
const runtime = runtimes.get(id);
|
|
394
|
+
if (!runtime)
|
|
395
|
+
return res.status(404).json({ error: "Companion not found" });
|
|
396
|
+
const query = req.query.q || '';
|
|
397
|
+
if (!runtime.knowledge || typeof runtime.knowledge.queryLifeContext !== 'function') {
|
|
398
|
+
return res.json({ matchedInventory: [], recentFinances: [], upcomingSchedule: [], preferences: [], formattedContext: '' });
|
|
399
|
+
}
|
|
400
|
+
try {
|
|
401
|
+
const result = await runtime.knowledge.queryLifeContext(id, query);
|
|
402
|
+
res.json(result);
|
|
403
|
+
}
|
|
404
|
+
catch (e) {
|
|
405
|
+
res.status(500).json({ error: e.message });
|
|
406
|
+
}
|
|
407
|
+
});
|
|
408
|
+
app.get('/knowledge/inventory', auth_1.requireAuth, async (req, res) => {
|
|
409
|
+
const id = req.query.id || Array.from(runtimes.keys())[0];
|
|
410
|
+
const runtime = runtimes.get(id);
|
|
411
|
+
if (!runtime)
|
|
412
|
+
return res.status(404).json({ error: "Companion not found" });
|
|
413
|
+
const domain = req.query.domain;
|
|
414
|
+
if (!runtime.knowledge || !runtime.knowledge.inventory) {
|
|
415
|
+
return res.json({ items: [] });
|
|
416
|
+
}
|
|
417
|
+
try {
|
|
418
|
+
const items = await runtime.knowledge.inventory.getItems(id, domain);
|
|
419
|
+
res.json({ items });
|
|
420
|
+
}
|
|
421
|
+
catch (e) {
|
|
422
|
+
res.status(500).json({ error: e.message });
|
|
423
|
+
}
|
|
424
|
+
});
|
|
425
|
+
app.get('/knowledge/finance', auth_1.requireAuth, async (req, res) => {
|
|
426
|
+
const id = req.query.id || Array.from(runtimes.keys())[0];
|
|
427
|
+
const runtime = runtimes.get(id);
|
|
428
|
+
if (!runtime)
|
|
429
|
+
return res.status(404).json({ error: "Companion not found" });
|
|
430
|
+
if (!runtime.knowledge || !runtime.knowledge.finance) {
|
|
431
|
+
return res.json({ summary: null, entries: [] });
|
|
432
|
+
}
|
|
433
|
+
try {
|
|
434
|
+
const limit = Number(req.query.limit || 20);
|
|
435
|
+
const [summary, entries] = await Promise.all([
|
|
436
|
+
runtime.knowledge.finance.getSummary(id),
|
|
437
|
+
runtime.knowledge.finance.getEntries(id, limit),
|
|
438
|
+
]);
|
|
439
|
+
res.json({ summary, entries });
|
|
440
|
+
}
|
|
441
|
+
catch (e) {
|
|
442
|
+
res.status(500).json({ error: e.message });
|
|
443
|
+
}
|
|
444
|
+
});
|
|
445
|
+
app.get('/knowledge/schedule', auth_1.requireAuth, async (req, res) => {
|
|
446
|
+
const id = req.query.id || Array.from(runtimes.keys())[0];
|
|
447
|
+
const runtime = runtimes.get(id);
|
|
448
|
+
if (!runtime)
|
|
449
|
+
return res.status(404).json({ error: "Companion not found" });
|
|
450
|
+
if (!runtime.knowledge || !runtime.knowledge.schedule) {
|
|
451
|
+
return res.json({ items: [] });
|
|
452
|
+
}
|
|
453
|
+
try {
|
|
454
|
+
const items = await runtime.knowledge.schedule.getUpcoming(id);
|
|
455
|
+
res.json({ items });
|
|
456
|
+
}
|
|
457
|
+
catch (e) {
|
|
458
|
+
res.status(500).json({ error: e.message });
|
|
459
|
+
}
|
|
460
|
+
});
|
|
461
|
+
app.get('/knowledge/preferences', auth_1.requireAuth, async (req, res) => {
|
|
462
|
+
const id = req.query.id || Array.from(runtimes.keys())[0];
|
|
463
|
+
const runtime = runtimes.get(id);
|
|
464
|
+
if (!runtime)
|
|
465
|
+
return res.status(404).json({ error: "Companion not found" });
|
|
466
|
+
const category = req.query.category;
|
|
467
|
+
if (!runtime.knowledge || !runtime.knowledge.preferences) {
|
|
468
|
+
return res.json({ preferences: [] });
|
|
469
|
+
}
|
|
470
|
+
try {
|
|
471
|
+
const preferences = await runtime.knowledge.preferences.getPreferences(id, category);
|
|
472
|
+
res.json({ preferences });
|
|
473
|
+
}
|
|
474
|
+
catch (e) {
|
|
475
|
+
res.status(500).json({ error: e.message });
|
|
476
|
+
}
|
|
477
|
+
});
|
|
445
478
|
// MEMORY MUTATIONS - PROPOSALS
|
|
446
479
|
app.post('/memory/proposals/update', auth_1.requireAuth, async (req, res) => {
|
|
447
480
|
const id = req.body.companionId || Array.from(runtimes.keys())[0];
|
|
@@ -456,7 +489,7 @@ function createApp(runtimes = new Map()) {
|
|
|
456
489
|
if (!claimId) {
|
|
457
490
|
return res.status(400).json({ error: "Missing required claim id" });
|
|
458
491
|
}
|
|
459
|
-
const updated = await runtime.updateClaim(claimId, req.body.updates || req.body);
|
|
492
|
+
const updated = await runtime.memory.updateClaim(claimId, req.body.updates || req.body);
|
|
460
493
|
res.json({ success: true, claim: updated });
|
|
461
494
|
}
|
|
462
495
|
catch (e) {
|
|
@@ -471,7 +504,7 @@ function createApp(runtimes = new Map()) {
|
|
|
471
504
|
if (!runtime.memory)
|
|
472
505
|
return res.status(400).json({ error: "Memory organ not configured" });
|
|
473
506
|
try {
|
|
474
|
-
await runtime.approveClaim(req.body.id);
|
|
507
|
+
await runtime.memory.approveClaim(req.body.id);
|
|
475
508
|
res.json({ approved: true });
|
|
476
509
|
}
|
|
477
510
|
catch (e) {
|
|
@@ -486,7 +519,7 @@ function createApp(runtimes = new Map()) {
|
|
|
486
519
|
if (!runtime.memory)
|
|
487
520
|
return res.status(400).json({ error: "Memory organ not configured" });
|
|
488
521
|
try {
|
|
489
|
-
await runtime.rejectClaim(req.body.id);
|
|
522
|
+
await runtime.memory.rejectClaim(req.body.id);
|
|
490
523
|
res.json({ rejected: true });
|
|
491
524
|
}
|
|
492
525
|
catch (e) {
|
|
@@ -502,7 +535,7 @@ function createApp(runtimes = new Map()) {
|
|
|
502
535
|
if (!runtime.memory)
|
|
503
536
|
return res.status(400).json({ error: "Memory organ not configured" });
|
|
504
537
|
try {
|
|
505
|
-
await runtime.approveDirective(req.body.id);
|
|
538
|
+
await runtime.memory.approveDirective(req.body.id);
|
|
506
539
|
res.json({ approved: true });
|
|
507
540
|
}
|
|
508
541
|
catch (e) {
|
|
@@ -517,7 +550,7 @@ function createApp(runtimes = new Map()) {
|
|
|
517
550
|
if (!runtime.memory)
|
|
518
551
|
return res.status(400).json({ error: "Memory organ not configured" });
|
|
519
552
|
try {
|
|
520
|
-
await runtime.rejectDirective(req.body.id);
|
|
553
|
+
await runtime.memory.rejectDirective(req.body.id);
|
|
521
554
|
res.json({ rejected: true });
|
|
522
555
|
}
|
|
523
556
|
catch (e) {
|
|
@@ -532,7 +565,7 @@ function createApp(runtimes = new Map()) {
|
|
|
532
565
|
if (!runtime.memory)
|
|
533
566
|
return res.status(400).json({ error: "Memory organ not configured" });
|
|
534
567
|
try {
|
|
535
|
-
await runtime.revokeDirective(req.body.id);
|
|
568
|
+
await runtime.memory.revokeDirective(req.body.id);
|
|
536
569
|
res.json({ revoked: true });
|
|
537
570
|
}
|
|
538
571
|
catch (e) {
|
|
@@ -547,7 +580,7 @@ function createApp(runtimes = new Map()) {
|
|
|
547
580
|
if (!runtime.memory)
|
|
548
581
|
return res.status(400).json({ error: "Memory organ not configured" });
|
|
549
582
|
try {
|
|
550
|
-
await runtime.disableDirective(req.body.id);
|
|
583
|
+
await runtime.memory.disableDirective(req.body.id);
|
|
551
584
|
res.json({ disabled: true });
|
|
552
585
|
}
|
|
553
586
|
catch (e) {
|
|
@@ -565,7 +598,7 @@ function createApp(runtimes = new Map()) {
|
|
|
565
598
|
return res.status(400).json({ error: "Memory organ does not support reset" });
|
|
566
599
|
}
|
|
567
600
|
try {
|
|
568
|
-
await runtime.resetMemory();
|
|
601
|
+
await runtime.memory.resetMemory();
|
|
569
602
|
res.json({ reset: true });
|
|
570
603
|
}
|
|
571
604
|
catch (e) {
|
|
@@ -577,7 +610,7 @@ function createApp(runtimes = new Map()) {
|
|
|
577
610
|
const runtime = runtimes.get(companionId);
|
|
578
611
|
if (!runtime)
|
|
579
612
|
return res.status(404).json({ accepted: false, error: 'Companion not found' });
|
|
580
|
-
const staged = runtime.stageResponse({
|
|
613
|
+
const staged = runtime.gating.stageResponse({
|
|
581
614
|
requestContext: {
|
|
582
615
|
companionId,
|
|
583
616
|
actor: {
|
|
@@ -611,13 +644,13 @@ function createApp(runtimes = new Map()) {
|
|
|
611
644
|
let responseId = req.body?.responseId;
|
|
612
645
|
let correlationId = req.body?.correlation_id;
|
|
613
646
|
if (!responseId && correlationId) {
|
|
614
|
-
const found = runtime.findStagedPlanByCorrelation(companionId, correlationId);
|
|
647
|
+
const found = runtime.gating.findStagedPlanByCorrelation(companionId, correlationId);
|
|
615
648
|
if (found) {
|
|
616
649
|
responseId = found.responseId;
|
|
617
650
|
}
|
|
618
651
|
}
|
|
619
652
|
else if (responseId && !correlationId) {
|
|
620
|
-
const found = runtime.getStagedPlan(responseId);
|
|
653
|
+
const found = runtime.gating.getStagedPlan(responseId);
|
|
621
654
|
if (found) {
|
|
622
655
|
correlationId = found.correlationId;
|
|
623
656
|
}
|
|
@@ -625,7 +658,7 @@ function createApp(runtimes = new Map()) {
|
|
|
625
658
|
if (!responseId) {
|
|
626
659
|
return res.status(400).json({ approved: false, error: 'UNKNOWN_APPROVAL_ID' });
|
|
627
660
|
}
|
|
628
|
-
const result = runtime.approveResponse({
|
|
661
|
+
const result = runtime.gating.approveResponse({
|
|
629
662
|
responseId,
|
|
630
663
|
companionId,
|
|
631
664
|
correlationId: correlationId || '',
|
|
@@ -634,7 +667,7 @@ function createApp(runtimes = new Map()) {
|
|
|
634
667
|
return res.status(400).json({ approved: false, error: result.reason });
|
|
635
668
|
}
|
|
636
669
|
// Now evaluated as approved
|
|
637
|
-
const evaluation = runtime.evaluateGate(result.plan);
|
|
670
|
+
const evaluation = runtime.gating.evaluateGate(result.plan);
|
|
638
671
|
res.json({
|
|
639
672
|
approved: true,
|
|
640
673
|
status: evaluation.disposition,
|
|
@@ -651,13 +684,13 @@ function createApp(runtimes = new Map()) {
|
|
|
651
684
|
let responseId = req.body?.responseId;
|
|
652
685
|
let correlationId = req.body?.correlation_id;
|
|
653
686
|
if (!responseId && correlationId) {
|
|
654
|
-
const found = runtime.findStagedPlanByCorrelation(companionId, correlationId);
|
|
687
|
+
const found = runtime.gating.findStagedPlanByCorrelation(companionId, correlationId);
|
|
655
688
|
if (found) {
|
|
656
689
|
responseId = found.responseId;
|
|
657
690
|
}
|
|
658
691
|
}
|
|
659
692
|
else if (responseId && !correlationId) {
|
|
660
|
-
const found = runtime.getStagedPlan(responseId);
|
|
693
|
+
const found = runtime.gating.getStagedPlan(responseId);
|
|
661
694
|
if (found) {
|
|
662
695
|
correlationId = found.correlationId;
|
|
663
696
|
}
|
|
@@ -665,7 +698,7 @@ function createApp(runtimes = new Map()) {
|
|
|
665
698
|
if (!responseId) {
|
|
666
699
|
return res.status(400).json({ rejected: false, error: 'UNKNOWN_APPROVAL_ID' });
|
|
667
700
|
}
|
|
668
|
-
const result = runtime.rejectResponse({
|
|
701
|
+
const result = runtime.gating.rejectResponse({
|
|
669
702
|
responseId,
|
|
670
703
|
companionId,
|
|
671
704
|
correlationId: correlationId || '',
|