@forbocai/core 0.5.9 → 0.6.1

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/index.js CHANGED
@@ -3,9 +3,6 @@ var __defProp = Object.defineProperty;
3
3
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
4
  var __getOwnPropNames = Object.getOwnPropertyNames;
5
5
  var __hasOwnProp = Object.prototype.hasOwnProperty;
6
- var __esm = (fn, res) => function __init() {
7
- return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
8
- };
9
6
  var __export = (target, all) => {
10
7
  for (var name in all)
11
8
  __defProp(target, name, { get: all[name], enumerable: true });
@@ -20,312 +17,864 @@ var __copyProps = (to, from, except, desc) => {
20
17
  };
21
18
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
22
19
 
23
- // src/soul.ts
24
- var soul_exports = {};
25
- __export(soul_exports, {
26
- createSoul: () => createSoul,
27
- createSoulInstance: () => createSoulInstance,
28
- deserializeSoul: () => deserializeSoul,
29
- exportSoul: () => exportSoul,
30
- getSoulList: () => getSoulList,
31
- importSoulFromArweave: () => importSoulFromArweave,
32
- serializeSoul: () => serializeSoul,
33
- validateSoul: () => validateSoul
34
- });
35
- var createSoul, serializeSoul, deserializeSoul, exportSoul, importSoulFromArweave, getSoulList, createSoulInstance, validateSoul;
36
- var init_soul = __esm({
37
- "src/soul.ts"() {
38
- "use strict";
39
- createSoul = (id, name, persona, state, memories = []) => ({
40
- id,
41
- version: "1.0.0",
42
- name,
43
- persona,
44
- state: { ...state },
45
- memories: [...memories]
46
- });
47
- serializeSoul = (soul) => JSON.stringify(soul, null, 2);
48
- deserializeSoul = (json) => {
49
- const parsed = JSON.parse(json);
50
- if (!parsed.id || !parsed.persona || !parsed.state) {
51
- throw new Error("Invalid Soul format: missing required fields");
52
- }
53
- return {
54
- id: parsed.id,
55
- version: parsed.version || "1.0.0",
56
- name: parsed.name || "Unknown",
57
- persona: parsed.persona,
58
- state: parsed.state,
59
- memories: parsed.memories || [],
60
- signature: parsed.signature
61
- };
62
- };
63
- exportSoul = async (agentId, _soul, config = {}) => {
64
- const apiUrl = config.apiUrl || "https://api.forboc.ai";
65
- const response = await fetch(`${apiUrl}/agents/${agentId}/soul/export`, {
66
- method: "POST",
67
- headers: { "Content-Type": "application/json" },
68
- body: JSON.stringify({})
69
- // Future: allow specifying memories to include
70
- });
71
- if (!response.ok) {
72
- throw new Error(`Soul export failed: ${response.statusText}`);
73
- }
74
- const data = await response.json();
75
- return {
76
- txId: data.txId,
77
- url: data.url,
78
- soul: _soul
79
- // Return the local soul data as context
80
- };
81
- };
82
- importSoulFromArweave = async (txId, config = {}) => {
83
- const apiUrl = config.apiUrl || "https://api.forboc.ai";
84
- const response = await fetch(`${apiUrl}/souls/${txId}`);
85
- if (!response.ok) throw new Error(`Import failed: ${response.statusText}`);
86
- const data = await response.json();
87
- return data;
88
- };
89
- getSoulList = async (limit = 50, apiUrl = "https://api.forboc.ai") => {
90
- const response = await fetch(`${apiUrl}/souls?limit=${limit}`);
91
- if (!response.ok) return [];
92
- const data = await response.json();
93
- return data.souls || [];
94
- };
95
- createSoulInstance = (id, name, persona, state, memories = []) => {
96
- const soulData = createSoul(id, name, persona, state, memories);
97
- return {
98
- export: (config) => exportSoul(id, soulData, config),
99
- toJSON: () => ({ ...soulData })
100
- };
101
- };
102
- validateSoul = (soul) => {
103
- const errors = [
104
- !soul.id && "Missing id",
105
- !soul.persona && "Missing persona",
106
- !soul.state && "Missing state"
107
- ].filter((e) => !!e);
108
- return { valid: errors.length === 0, errors };
109
- };
110
- }
111
- });
112
-
113
20
  // src/index.ts
114
21
  var index_exports = {};
115
22
  __export(index_exports, {
116
23
  SDK_VERSION: () => SDK_VERSION,
117
- createAgent: () => createAgent,
118
- createBridge: () => createBridge,
119
- createGhost: () => createGhost,
24
+ addToHistory: () => addToHistory,
25
+ blockAction: () => blockAction,
26
+ bridgeSlice: () => bridgeSlice,
27
+ checkApiStatusThunk: () => checkApiStatusThunk,
28
+ clearBlock: () => clearBlock,
29
+ clearBridgeValidation: () => clearBridgeValidation,
30
+ clearDirectivesForNpc: () => clearDirectivesForNpc,
31
+ clearGhostSession: () => clearGhostSession,
32
+ clearMemoryRemoteThunk: () => clearMemoryRemoteThunk,
33
+ clearSoulState: () => clearSoulState,
34
+ completeRemoteThunk: () => completeRemoteThunk,
35
+ contextComposed: () => contextComposed,
36
+ cortexInitFailed: () => cortexInitFailed,
37
+ cortexInitStart: () => cortexInitStart,
38
+ cortexInitSuccess: () => cortexInitSuccess,
39
+ cortexSlice: () => cortexSlice,
120
40
  createInitialState: () => createInitialState,
121
- createRemoteCortex: () => createRemoteCortex,
122
- createSoul: () => createSoul,
123
- createSoulInstance: () => createSoulInstance,
41
+ createSDKStore: () => createSDKStore,
124
42
  delay: () => delay,
125
- deserializeSoul: () => deserializeSoul,
126
- exportSoul: () => exportSoul,
43
+ deleteRulesetThunk: () => deleteRulesetThunk,
44
+ directiveReceived: () => directiveReceived,
45
+ directiveRunFailed: () => directiveRunFailed,
46
+ directiveRunStarted: () => directiveRunStarted,
47
+ directiveSlice: () => directiveSlice,
48
+ dispatch: () => dispatch,
127
49
  exportToSoul: () => exportToSoul,
128
- fromSoul: () => fromSoul,
129
- getGhostHistory: () => getGhostHistory,
130
- getGhostResults: () => getGhostResults,
131
- getGhostStatus: () => getGhostStatus,
132
- getSoulList: () => getSoulList,
133
- importSoulFromArweave: () => importSoulFromArweave,
134
- loadPreset: () => loadPreset,
50
+ generateNPCId: () => generateNPCId,
51
+ getBridgeRulesThunk: () => getBridgeRulesThunk,
52
+ getGhostHistoryThunk: () => getGhostHistoryThunk,
53
+ getGhostResultsThunk: () => getGhostResultsThunk,
54
+ getGhostStatusThunk: () => getGhostStatusThunk,
55
+ getSoulListThunk: () => getSoulListThunk,
56
+ ghostSlice: () => ghostSlice,
57
+ importNpcFromSoulThunk: () => importNpcFromSoulThunk,
58
+ importSoulFromArweaveThunk: () => importSoulFromArweaveThunk,
59
+ initRemoteCortexThunk: () => initRemoteCortexThunk,
60
+ listCortexModelsThunk: () => listCortexModelsThunk,
61
+ listMemoryRemoteThunk: () => listMemoryRemoteThunk,
62
+ listRulePresetsThunk: () => listRulePresetsThunk,
63
+ listRulesetsThunk: () => listRulesetsThunk,
64
+ loadBridgePresetThunk: () => loadBridgePresetThunk,
65
+ localExportSoulThunk: () => localExportSoulThunk,
135
66
  memoise: () => memoise,
136
67
  memoiseAsync: () => memoiseAsync,
68
+ memoryClear: () => memoryClear,
69
+ memoryRecallFailed: () => memoryRecallFailed,
70
+ memoryRecallStart: () => memoryRecallStart,
71
+ memoryRecallSuccess: () => memoryRecallSuccess,
72
+ memorySlice: () => memorySlice,
73
+ memoryStoreFailed: () => memoryStoreFailed,
74
+ memoryStoreStart: () => memoryStoreStart,
75
+ memoryStoreSuccess: () => memoryStoreSuccess,
76
+ npcSlice: () => npcSlice,
137
77
  pipe: () => pipe,
138
- serializeSoul: () => serializeSoul,
139
- startGhostSession: () => startGhostSession,
140
- stopGhostSession: () => stopGhostSession,
78
+ processNPC: () => processNPC,
79
+ recallMemoryRemoteThunk: () => recallMemoryRemoteThunk,
80
+ registerRulesetThunk: () => registerRulesetThunk,
81
+ remoteExportSoulThunk: () => remoteExportSoulThunk,
82
+ removeNPC: () => removeNPC,
83
+ sdkApi: () => sdkApi,
84
+ selectActiveDirective: () => selectActiveDirective,
85
+ selectActiveDirectiveId: () => selectActiveDirectiveId,
86
+ selectActiveNPC: () => selectActiveNPC,
87
+ selectActiveNpcId: () => selectActiveNpcId,
88
+ selectAllDirectives: () => selectAllDirectives,
89
+ selectAllMemories: () => selectAllMemories,
90
+ selectAllNPCs: () => selectAllNPCs,
91
+ selectDirectiveById: () => selectDirectiveById,
92
+ selectLastRecalledMemories: () => selectLastRecalledMemories,
93
+ selectMemoryById: () => selectMemoryById,
94
+ selectNPCById: () => selectNPCById,
95
+ selectNPCEntities: () => selectNPCEntities,
96
+ selectNPCIds: () => selectNPCIds,
97
+ selectTotalNPCs: () => selectTotalNPCs,
98
+ setActiveNPC: () => setActiveNPC,
99
+ setCortexStatus: () => setCortexStatus,
100
+ setHistory: () => setHistory,
101
+ setLastAction: () => setLastAction,
102
+ setNPCInfo: () => setNPCInfo,
103
+ setNPCState: () => setNPCState,
104
+ soulSlice: () => soulSlice,
105
+ startGhostThunk: () => startGhostThunk,
106
+ stopGhostThunk: () => stopGhostThunk,
107
+ store: () => store,
108
+ storeMemoryRemoteThunk: () => storeMemoryRemoteThunk,
141
109
  streamFromCortex: () => streamFromCortex,
142
110
  streamFromCortexWithDelay: () => streamFromCortexWithDelay,
143
111
  streamToCallback: () => streamToCallback,
144
112
  streamToString: () => streamToString,
145
- updateAgentState: () => updateAgentState,
146
- validateAction: () => validateAction,
147
- validateSoul: () => validateSoul,
148
- waitForGhostCompletion: () => waitForGhostCompletion
113
+ updateNPCState: () => updateNPCState,
114
+ updateNPCStateLocally: () => updateNPCStateLocally,
115
+ validateBridgeThunk: () => validateBridgeThunk,
116
+ verdictValidated: () => verdictValidated,
117
+ verifySoulThunk: () => verifySoulThunk
149
118
  });
150
119
  module.exports = __toCommonJS(index_exports);
151
120
 
152
- // src/agent.ts
121
+ // src/npc.ts
153
122
  var createInitialState = (partial) => ({ ...partial });
154
- var updateAgentState = (currentState, updates) => ({
123
+ var updateNPCStateLocally = (currentState, updates) => ({
155
124
  ...currentState,
156
125
  ...updates
157
126
  });
158
- var exportToSoul = (agentId, name, persona, state, memories) => ({
159
- id: agentId,
127
+ var exportToSoul = (npcId, name, persona, state, memories) => ({
128
+ id: npcId,
160
129
  version: "1.0.0",
161
130
  name,
162
131
  persona,
163
132
  memories: [...memories],
164
133
  state: { ...state }
165
134
  });
166
- var storeMemoriesRecursive = async (memory, instructions, index = 0) => {
167
- if (index >= instructions.length) return;
168
- const { text, type, importance } = instructions[index];
169
- await memory.store(text, type, importance).catch((e) => console.warn("Memory store failed:", e));
170
- return storeMemoriesRecursive(memory, instructions, index + 1);
135
+
136
+ // src/bridgeSlice.ts
137
+ var import_toolkit = require("@reduxjs/toolkit");
138
+
139
+ // src/apiSlice.ts
140
+ var import_query = require("@reduxjs/toolkit/query");
141
+ var sdkApi = (0, import_query.createApi)({
142
+ reducerPath: "forbocApi",
143
+ baseQuery: (0, import_query.fetchBaseQuery)({
144
+ baseUrl: "/",
145
+ prepareHeaders: (headers, { getState }) => {
146
+ return headers;
147
+ }
148
+ }),
149
+ tagTypes: ["NPC", "Memory", "Cortex", "Ghost", "Soul", "Bridge", "Rule"],
150
+ endpoints: (builder) => ({
151
+ // Cortex Endpoints
152
+ getCortexModels: builder.query({
153
+ query: ({ apiUrl, apiKey }) => ({
154
+ url: `${apiUrl}/cortex/models`,
155
+ method: "GET",
156
+ headers: apiKey ? { "Authorization": `Bearer ${apiKey}` } : {}
157
+ }),
158
+ providesTags: ["Cortex"],
159
+ transformResponse: (response) => response || []
160
+ }),
161
+ postCortexInit: builder.mutation({
162
+ query: ({ request, apiUrl, apiKey }) => ({
163
+ url: `${apiUrl}/cortex/init`,
164
+ method: "POST",
165
+ headers: apiKey ? { "Authorization": `Bearer ${apiKey}` } : {},
166
+ body: request
167
+ }),
168
+ invalidatesTags: ["Cortex"],
169
+ transformResponse: (response) => response
170
+ }),
171
+ // NPC Endpoints
172
+ postDirective: builder.mutation({
173
+ query: ({ npcId, request, apiUrl, apiKey }) => ({
174
+ url: `${apiUrl}/npcs/${npcId}/directive`,
175
+ method: "POST",
176
+ headers: apiKey ? { "Authorization": `Bearer ${apiKey}` } : {},
177
+ body: request
178
+ }),
179
+ invalidatesTags: ["NPC"],
180
+ transformResponse: (response) => response
181
+ }),
182
+ postContext: builder.mutation({
183
+ query: ({ npcId, request, apiUrl, apiKey }) => ({
184
+ url: `${apiUrl}/npcs/${npcId}/context`,
185
+ method: "POST",
186
+ headers: apiKey ? { "Authorization": `Bearer ${apiKey}` } : {},
187
+ body: request
188
+ }),
189
+ invalidatesTags: (result, error, { npcId }) => [{ type: "NPC", id: npcId }],
190
+ transformResponse: (response) => response
191
+ }),
192
+ postVerdict: builder.mutation({
193
+ query: ({ npcId, request, apiUrl, apiKey }) => ({
194
+ url: `${apiUrl}/npcs/${npcId}/verdict`,
195
+ method: "POST",
196
+ headers: apiKey ? { "Authorization": `Bearer ${apiKey}` } : {},
197
+ body: request
198
+ }),
199
+ invalidatesTags: (result, error, { npcId }) => [{ type: "NPC", id: npcId }],
200
+ transformResponse: (response) => {
201
+ const action = response.action ? {
202
+ type: response.action.gaType || response.action.type,
203
+ reason: response.action.actionReason || response.action.reason,
204
+ target: response.action.actionTarget || response.action.target,
205
+ signature: response.action.signature
206
+ } : void 0;
207
+ return {
208
+ ...response,
209
+ action
210
+ };
211
+ }
212
+ }),
213
+ postMemoryStore: builder.mutation({
214
+ query: ({ npcId, request, apiUrl, apiKey }) => ({
215
+ url: `${apiUrl}/npcs/${npcId}/memory`,
216
+ method: "POST",
217
+ headers: apiKey ? { "Authorization": `Bearer ${apiKey}` } : {},
218
+ body: request
219
+ }),
220
+ invalidatesTags: (result, error, { npcId }) => [{ type: "Memory", id: npcId }],
221
+ transformResponse: (response) => response
222
+ }),
223
+ getMemoryList: builder.query({
224
+ query: ({ npcId, apiUrl, apiKey }) => ({
225
+ url: `${apiUrl}/npcs/${npcId}/memory`,
226
+ method: "GET",
227
+ headers: apiKey ? { "Authorization": `Bearer ${apiKey}` } : {}
228
+ }),
229
+ providesTags: (result, error, { npcId }) => [{ type: "Memory", id: npcId }],
230
+ transformResponse: (response) => response || []
231
+ }),
232
+ postMemoryRecall: builder.mutation({
233
+ query: ({ npcId, request, apiUrl, apiKey }) => ({
234
+ url: `${apiUrl}/npcs/${npcId}/memory/recall`,
235
+ method: "POST",
236
+ headers: apiKey ? { "Authorization": `Bearer ${apiKey}` } : {},
237
+ body: request
238
+ }),
239
+ invalidatesTags: (result, error, { npcId }) => [{ type: "Memory", id: npcId }],
240
+ transformResponse: (response) => response || []
241
+ }),
242
+ deleteMemoryClear: builder.mutation({
243
+ query: ({ npcId, apiUrl, apiKey }) => ({
244
+ url: `${apiUrl}/npcs/${npcId}/memory/clear`,
245
+ method: "DELETE",
246
+ headers: apiKey ? { "Authorization": `Bearer ${apiKey}` } : {}
247
+ }),
248
+ invalidatesTags: (result, error, { npcId }) => [{ type: "Memory", id: npcId }],
249
+ transformResponse: (response) => response
250
+ }),
251
+ // Ghost Endpoints
252
+ postGhostRun: builder.mutation({
253
+ query: ({ request, apiUrl, apiKey }) => ({
254
+ url: `${apiUrl}/ghost/run`,
255
+ method: "POST",
256
+ headers: apiKey ? { "Authorization": `Bearer ${apiKey}` } : {},
257
+ body: request
258
+ }),
259
+ invalidatesTags: ["Ghost"],
260
+ transformResponse: (response) => response
261
+ }),
262
+ getGhostStatus: builder.query({
263
+ query: ({ sessionId, apiUrl, apiKey }) => ({
264
+ url: `${apiUrl}/ghost/${sessionId}/status`,
265
+ method: "GET",
266
+ headers: apiKey ? { "Authorization": `Bearer ${apiKey}` } : {}
267
+ }),
268
+ providesTags: (result, error, { sessionId }) => [{ type: "Ghost", id: sessionId }],
269
+ transformResponse: (response) => response
270
+ }),
271
+ getGhostResults: builder.query({
272
+ query: ({ sessionId, apiUrl, apiKey }) => ({
273
+ url: `${apiUrl}/ghost/${sessionId}/results`,
274
+ method: "GET",
275
+ headers: apiKey ? { "Authorization": `Bearer ${apiKey}` } : {}
276
+ }),
277
+ providesTags: (result, error, { sessionId }) => [{ type: "Ghost", id: sessionId }],
278
+ transformResponse: (response) => response
279
+ }),
280
+ postGhostStop: builder.mutation({
281
+ query: ({ sessionId, apiUrl, apiKey }) => ({
282
+ url: `${apiUrl}/ghost/${sessionId}/stop`,
283
+ method: "POST",
284
+ headers: apiKey ? { "Authorization": `Bearer ${apiKey}` } : {}
285
+ }),
286
+ invalidatesTags: (result, error, { sessionId }) => [{ type: "Ghost", id: sessionId }],
287
+ transformResponse: (response) => ({
288
+ stopped: response?.stopStatus === "stopped",
289
+ stopStatus: response?.stopStatus,
290
+ stopSessionId: response?.stopSessionId
291
+ })
292
+ }),
293
+ getGhostHistory: builder.query({
294
+ query: ({ limit, apiUrl, apiKey }) => ({
295
+ url: `${apiUrl}/ghost/history?limit=${limit}`,
296
+ method: "GET",
297
+ headers: apiKey ? { "Authorization": `Bearer ${apiKey}` } : {}
298
+ }),
299
+ providesTags: ["Ghost"],
300
+ transformResponse: (response) => response
301
+ }),
302
+ // Soul Endpoints
303
+ postSoulExport: builder.mutation({
304
+ query: ({ npcId, request, apiUrl, apiKey }) => ({
305
+ url: `${apiUrl}/npcs/${npcId}/soul/export`,
306
+ method: "POST",
307
+ headers: apiKey ? { "Authorization": `Bearer ${apiKey}` } : {},
308
+ body: request
309
+ }),
310
+ invalidatesTags: ["Soul"],
311
+ transformResponse: (response) => response
312
+ }),
313
+ getSoulImport: builder.query({
314
+ query: ({ txId, apiUrl, apiKey }) => ({
315
+ url: `${apiUrl}/souls/${txId}`,
316
+ method: "GET",
317
+ headers: apiKey ? { "Authorization": `Bearer ${apiKey}` } : {}
318
+ }),
319
+ providesTags: (result, error, { txId }) => [{ type: "Soul", id: txId }],
320
+ transformResponse: (response) => response
321
+ }),
322
+ getSouls: builder.query({
323
+ query: ({ limit, apiUrl, apiKey }) => ({
324
+ url: `${apiUrl}/souls?limit=${limit}`,
325
+ method: "GET",
326
+ headers: apiKey ? { "Authorization": `Bearer ${apiKey}` } : {}
327
+ }),
328
+ providesTags: ["Soul"],
329
+ transformResponse: (response) => response
330
+ }),
331
+ // Bridge Endpoints
332
+ postBridgeValidate: builder.mutation({
333
+ query: ({ request, npcId, apiUrl, apiKey }) => ({
334
+ url: npcId ? `${apiUrl}/bridge/validate/${npcId}` : `${apiUrl}/bridge/validate`,
335
+ method: "POST",
336
+ headers: apiKey ? { "Authorization": `Bearer ${apiKey}` } : {},
337
+ body: request
338
+ }),
339
+ invalidatesTags: ["Bridge"],
340
+ transformResponse: (response) => response.brResult || response
341
+ }),
342
+ getBridgeRules: builder.query({
343
+ query: ({ apiUrl, apiKey }) => ({
344
+ url: `${apiUrl}/bridge/rules`,
345
+ method: "GET",
346
+ headers: apiKey ? { "Authorization": `Bearer ${apiKey}` } : {}
347
+ }),
348
+ providesTags: ["Bridge"],
349
+ transformResponse: (response) => response
350
+ }),
351
+ postBridgePreset: builder.mutation({
352
+ query: ({ presetName, apiUrl, apiKey }) => ({
353
+ url: `${apiUrl}/rules/presets/${presetName}`,
354
+ method: "POST",
355
+ headers: apiKey ? { "Authorization": `Bearer ${apiKey}` } : {}
356
+ }),
357
+ invalidatesTags: ["Bridge"],
358
+ transformResponse: (response) => response
359
+ }),
360
+ // Rules Endpoints
361
+ getRulesets: builder.query({
362
+ query: ({ apiUrl, apiKey }) => ({
363
+ url: `${apiUrl}/rules`,
364
+ method: "GET",
365
+ headers: apiKey ? { "Authorization": `Bearer ${apiKey}` } : {}
366
+ }),
367
+ providesTags: ["Rule"],
368
+ transformResponse: (response) => response || []
369
+ }),
370
+ getRulePresets: builder.query({
371
+ query: ({ apiUrl, apiKey }) => ({
372
+ url: `${apiUrl}/rules/presets`,
373
+ method: "GET",
374
+ headers: apiKey ? { "Authorization": `Bearer ${apiKey}` } : {}
375
+ }),
376
+ providesTags: ["Rule"],
377
+ transformResponse: (response) => response || []
378
+ }),
379
+ postRuleRegister: builder.mutation({
380
+ query: ({ request, apiUrl, apiKey }) => ({
381
+ url: `${apiUrl}/rules`,
382
+ method: "POST",
383
+ headers: apiKey ? { "Authorization": `Bearer ${apiKey}` } : {},
384
+ body: request
385
+ }),
386
+ invalidatesTags: ["Rule"],
387
+ transformResponse: (response) => response
388
+ }),
389
+ deleteRule: builder.mutation({
390
+ query: ({ rulesetId, apiUrl, apiKey }) => ({
391
+ url: `${apiUrl}/rules/${rulesetId}`,
392
+ method: "DELETE",
393
+ headers: apiKey ? { "Authorization": `Bearer ${apiKey}` } : {}
394
+ }),
395
+ invalidatesTags: ["Rule"],
396
+ transformResponse: (_response) => ({ deleted: true })
397
+ }),
398
+ // Additional Soul/NPC Endpoints
399
+ postSoulVerify: builder.mutation({
400
+ query: ({ txId, apiUrl, apiKey }) => ({
401
+ url: `${apiUrl}/souls/${txId}/verify`,
402
+ method: "POST",
403
+ headers: apiKey ? { "Authorization": `Bearer ${apiKey}` } : {}
404
+ }),
405
+ invalidatesTags: ["Soul"],
406
+ transformResponse: (response) => ({
407
+ valid: response.verifyValid ?? response.valid ?? false,
408
+ reason: response.verifyReason ?? response.reason
409
+ })
410
+ }),
411
+ postNpcImport: builder.mutation({
412
+ query: ({ request, apiUrl, apiKey }) => ({
413
+ url: `${apiUrl}/npcs/import`,
414
+ method: "POST",
415
+ headers: apiKey ? { "Authorization": `Bearer ${apiKey}` } : {},
416
+ body: request
417
+ }),
418
+ invalidatesTags: ["NPC"],
419
+ transformResponse: (response) => response
420
+ }),
421
+ // Cortex Remote Endpoint
422
+ postCortexComplete: builder.mutation({
423
+ query: ({ cortexId, prompt, options, apiUrl, apiKey }) => ({
424
+ url: `${apiUrl}/cortex/${cortexId}/complete`,
425
+ method: "POST",
426
+ headers: apiKey ? { "Authorization": `Bearer ${apiKey}` } : {},
427
+ body: { prompt, ...options }
428
+ }),
429
+ invalidatesTags: ["Cortex"],
430
+ transformResponse: (response) => response
431
+ }),
432
+ // System Endpoints
433
+ getApiStatus: builder.query({
434
+ query: ({ apiUrl }) => ({ url: `${apiUrl}/status`, method: "GET" }),
435
+ transformResponse: (response) => response
436
+ })
437
+ })
438
+ });
439
+
440
+ // src/bridgeSlice.ts
441
+ var initialState = {
442
+ activePresets: [],
443
+ availableRulesets: [],
444
+ availablePresetIds: [],
445
+ lastValidation: null,
446
+ status: "idle",
447
+ error: null
171
448
  };
172
- var createAgent = (config) => {
173
- let _state = createInitialState(config.initialState);
174
- const cortex = config.cortex;
175
- const apiUrl = config.apiUrl || "https://api.forboc.ai";
176
- const agentId = config.id || "agent-" + Math.random().toString(36).substring(7);
177
- const authHeaders = config.apiKey ? { "Content-Type": "application/json", "Authorization": `Bearer ${config.apiKey}` } : { "Content-Type": "application/json" };
178
- const getState = () => ({ ..._state });
179
- const setState = (newState) => {
180
- _state = newState;
181
- };
182
- const process = async (input, context = {}) => {
183
- const currentState = getState();
184
- const dirRes = await fetch(`${apiUrl}/agents/${agentId}/directive`, {
185
- method: "POST",
186
- headers: authHeaders,
187
- body: JSON.stringify({ observation: input, agentState: currentState, context })
188
- });
189
- if (!dirRes.ok) throw new Error(`API Directive Error: ${dirRes.status}`);
190
- const directiveData = await dirRes.json();
191
- const recalledMemories = config.memory && directiveData.memoryRecall ? await config.memory.recall(
192
- directiveData.memoryRecall.query,
193
- directiveData.memoryRecall.limit,
194
- directiveData.memoryRecall.threshold
195
- ).then((mems) => mems.map((m) => ({ text: m.text, type: m.type, importance: m.importance, similarity: void 0 }))).catch(() => []) : [];
196
- const ctxRes = await fetch(`${apiUrl}/agents/${agentId}/context`, {
197
- method: "POST",
198
- headers: authHeaders,
199
- body: JSON.stringify({ memories: recalledMemories, observation: input, agentState: currentState })
200
- });
201
- if (!ctxRes.ok) throw new Error(`API Context Error: ${ctxRes.status}`);
202
- const contextData = await ctxRes.json();
203
- const generatedText = await cortex.complete(contextData.prompt, {
204
- maxTokens: contextData.constraints.maxTokens,
205
- temperature: contextData.constraints.temperature,
206
- stop: contextData.constraints.stop
207
- });
208
- const verRes = await fetch(`${apiUrl}/agents/${agentId}/verdict`, {
209
- method: "POST",
210
- headers: authHeaders,
211
- body: JSON.stringify({ generatedOutput: generatedText, observation: input, agentState: currentState })
212
- });
213
- if (!verRes.ok) throw new Error(`API Verdict Error: ${verRes.status}`);
214
- const verdictData = await verRes.json();
215
- if (!verdictData.valid) {
216
- return { dialogue: "... [Blocked]", action: { type: "BLOCKED", reason: "Validation Failed" } };
217
- }
218
- if (config.memory && verdictData.memoryStore) {
219
- storeMemoriesRecursive(config.memory, verdictData.memoryStore);
220
- }
221
- if (verdictData.stateDelta) {
222
- setState(updateAgentState(_state, verdictData.stateDelta));
223
- }
224
- return {
225
- dialogue: generatedText,
226
- action: verdictData.action ? { ...verdictData.action, signature: verdictData.signature } : void 0,
227
- thought: generatedText
228
- };
229
- };
230
- const speak = async (message, context = {}) => {
231
- const res = await fetch(`${apiUrl}/agents/${agentId}/speak`, {
232
- method: "POST",
233
- headers: authHeaders,
234
- body: JSON.stringify({ speakMessage: message, speakContext: context, speakAgentState: getState() })
235
- });
236
- if (!res.ok) throw new Error(`API Speak Error: ${res.status}`);
237
- const data = await res.json();
238
- if (data.speakHistory) setState(updateAgentState(_state, { conversationHistory: data.speakHistory }));
239
- return data.speakReply;
240
- };
241
- const dialogue = async (message, context = []) => {
242
- const res = await fetch(`${apiUrl}/agents/${agentId}/dialogue`, {
243
- method: "POST",
244
- headers: authHeaders,
245
- body: JSON.stringify({ diagMessage: message, diagContext: context })
449
+ var validateBridgeThunk = (0, import_toolkit.createAsyncThunk)(
450
+ "bridge/validate",
451
+ async ({ action, context, npcId, apiUrl, apiKey }, { dispatch: dispatch2, rejectWithValue }) => {
452
+ try {
453
+ const url = apiUrl || "https://api.forboc.ai";
454
+ const data = await dispatch2(sdkApi.endpoints.postBridgeValidate.initiate({
455
+ request: { action, context },
456
+ npcId,
457
+ apiUrl: url,
458
+ apiKey
459
+ })).unwrap();
460
+ return data;
461
+ } catch (e) {
462
+ return rejectWithValue(e.message || "Bridge validation failed");
463
+ }
464
+ }
465
+ );
466
+ var loadBridgePresetThunk = (0, import_toolkit.createAsyncThunk)(
467
+ "bridge/loadPreset",
468
+ async ({ presetName, apiUrl, apiKey }, { dispatch: dispatch2, rejectWithValue }) => {
469
+ try {
470
+ const url = apiUrl || "https://api.forboc.ai";
471
+ return await dispatch2(sdkApi.endpoints.postBridgePreset.initiate({ presetName, apiUrl: url, apiKey })).unwrap();
472
+ } catch (e) {
473
+ return rejectWithValue(e.message || "Failed to load preset");
474
+ }
475
+ }
476
+ );
477
+ var getBridgeRulesThunk = (0, import_toolkit.createAsyncThunk)(
478
+ "bridge/rules",
479
+ async ({ apiUrl, apiKey }, { dispatch: dispatch2, rejectWithValue }) => {
480
+ try {
481
+ const url = apiUrl || "https://api.forboc.ai";
482
+ return await dispatch2(sdkApi.endpoints.getBridgeRules.initiate({ apiUrl: url, apiKey })).unwrap();
483
+ } catch (e) {
484
+ return rejectWithValue(e.message || "Failed to list bridge rules");
485
+ }
486
+ }
487
+ );
488
+ var listRulesetsThunk = (0, import_toolkit.createAsyncThunk)(
489
+ "bridge/listRulesets",
490
+ async ({ apiUrl, apiKey }, { dispatch: dispatch2, rejectWithValue }) => {
491
+ try {
492
+ const url = apiUrl || "https://api.forboc.ai";
493
+ return await dispatch2(sdkApi.endpoints.getRulesets.initiate({ apiUrl: url, apiKey })).unwrap();
494
+ } catch (e) {
495
+ return rejectWithValue(e.message || "Failed to list rulesets");
496
+ }
497
+ }
498
+ );
499
+ var listRulePresetsThunk = (0, import_toolkit.createAsyncThunk)(
500
+ "bridge/listRulePresets",
501
+ async ({ apiUrl, apiKey }, { dispatch: dispatch2, rejectWithValue }) => {
502
+ try {
503
+ const url = apiUrl || "https://api.forboc.ai";
504
+ return await dispatch2(sdkApi.endpoints.getRulePresets.initiate({ apiUrl: url, apiKey })).unwrap();
505
+ } catch (e) {
506
+ return rejectWithValue(e.message || "Failed to list rule presets");
507
+ }
508
+ }
509
+ );
510
+ var registerRulesetThunk = (0, import_toolkit.createAsyncThunk)(
511
+ "bridge/registerRuleset",
512
+ async ({ ruleset, apiUrl, apiKey }, { dispatch: dispatch2, rejectWithValue }) => {
513
+ try {
514
+ const url = apiUrl || "https://api.forboc.ai";
515
+ return await dispatch2(sdkApi.endpoints.postRuleRegister.initiate({ request: ruleset, apiUrl: url, apiKey })).unwrap();
516
+ } catch (e) {
517
+ return rejectWithValue(e.message || "Failed to register ruleset");
518
+ }
519
+ }
520
+ );
521
+ var deleteRulesetThunk = (0, import_toolkit.createAsyncThunk)(
522
+ "bridge/deleteRuleset",
523
+ async ({ rulesetId, apiUrl, apiKey }, { dispatch: dispatch2, rejectWithValue }) => {
524
+ try {
525
+ const url = apiUrl || "https://api.forboc.ai";
526
+ return await dispatch2(sdkApi.endpoints.deleteRule.initiate({ rulesetId, apiUrl: url, apiKey })).unwrap();
527
+ } catch (e) {
528
+ return rejectWithValue(e.message || "Failed to delete ruleset");
529
+ }
530
+ }
531
+ );
532
+ var bridgeSlice = (0, import_toolkit.createSlice)({
533
+ name: "bridge",
534
+ initialState,
535
+ reducers: {
536
+ clearBridgeValidation: (state) => {
537
+ state.lastValidation = null;
538
+ state.status = "idle";
539
+ state.error = null;
540
+ }
541
+ },
542
+ extraReducers: (builder) => {
543
+ builder.addCase(validateBridgeThunk.pending, (state) => {
544
+ state.status = "validating";
545
+ state.error = null;
546
+ }).addCase(validateBridgeThunk.fulfilled, (state, action) => {
547
+ state.status = "idle";
548
+ state.lastValidation = action.payload;
549
+ }).addCase(validateBridgeThunk.rejected, (state, action) => {
550
+ state.status = "error";
551
+ state.error = action.payload;
552
+ state.lastValidation = { valid: false, reason: action.payload };
553
+ }).addCase(loadBridgePresetThunk.pending, (state) => {
554
+ state.status = "loading_preset";
555
+ state.error = null;
556
+ }).addCase(loadBridgePresetThunk.fulfilled, (state, action) => {
557
+ state.status = "idle";
558
+ if (!state.activePresets.find((p) => p.id === action.payload.id)) {
559
+ state.activePresets.push(action.payload);
560
+ }
561
+ }).addCase(loadBridgePresetThunk.rejected, (state, action) => {
562
+ state.status = "error";
563
+ state.error = action.payload;
564
+ }).addCase(getBridgeRulesThunk.fulfilled, (state, action) => {
565
+ }).addCase(listRulesetsThunk.fulfilled, (state, action) => {
566
+ state.availableRulesets = action.payload;
567
+ }).addCase(listRulePresetsThunk.fulfilled, (state, action) => {
568
+ state.availablePresetIds = action.payload;
246
569
  });
247
- if (!res.ok) throw new Error(`API Dialogue Error: ${res.status}`);
248
- const data = await res.json();
249
- return data.diagReply;
250
- };
251
- const exportSoul2 = async () => {
252
- const memories = config.memory ? await config.memory.export().catch(() => []) : [];
253
- return exportToSoul(agentId, "Agent", config.persona, _state, memories);
254
- };
255
- const exportSoulToArweave = async (soulConfig) => {
256
- const soul = await exportSoul2();
257
- const { exportSoul: exportFunc } = await Promise.resolve().then(() => (init_soul(), soul_exports));
258
- return exportFunc(agentId, soul, { ...soulConfig, apiUrl });
259
- };
260
- return { process, speak, dialogue, reply: speak, getState, setState, export: exportSoul2, exportSoul: exportSoulToArweave };
261
- };
262
- var fromSoul = async (soul, cortex, memory) => {
263
- const agent = createAgent({
264
- id: soul.id,
265
- cortex,
266
- memory: memory || null,
267
- persona: soul.persona,
268
- initialState: soul.state
269
- });
270
- if (memory && soul.memories && soul.memories.length > 0) {
271
- await memory.import(soul.memories).catch((e) => console.warn("Memory hydration failed:", e));
272
570
  }
273
- return agent;
571
+ });
572
+ var { clearBridgeValidation } = bridgeSlice.actions;
573
+ var bridgeSlice_default = bridgeSlice.reducer;
574
+
575
+ // src/soulSlice.ts
576
+ var import_toolkit2 = require("@reduxjs/toolkit");
577
+ var initialState2 = {
578
+ exportStatus: "idle",
579
+ importStatus: "idle",
580
+ lastExport: null,
581
+ lastImport: null,
582
+ availableSouls: [],
583
+ error: null
274
584
  };
585
+ var remoteExportSoulThunk = (0, import_toolkit2.createAsyncThunk)(
586
+ "soul/export",
587
+ async ({ npcId: argNpcId, apiUrl, apiKey, memories = [] }, { getState, dispatch: dispatch2, rejectWithValue }) => {
588
+ try {
589
+ const state = getState().npc;
590
+ const npcId = argNpcId || state.activeNpcId;
591
+ const npc = state.entities[npcId];
592
+ if (!npc) throw new Error(`NPC ${npcId} not found`);
593
+ const url = apiUrl || "https://api.forboc.ai";
594
+ const result = await dispatch2(sdkApi.endpoints.postSoulExport.initiate({
595
+ npcId,
596
+ request: { npcIdRef: npcId, persona: npc.persona || "NPC", npcState: npc.state },
597
+ apiUrl: url,
598
+ apiKey
599
+ })).unwrap();
600
+ return {
601
+ txId: result.txId,
602
+ url: result.arweaveUrl,
603
+ soul: result.soul
604
+ };
605
+ } catch (e) {
606
+ return rejectWithValue(e.message || "Soul export failed");
607
+ }
608
+ }
609
+ );
610
+ var importSoulFromArweaveThunk = (0, import_toolkit2.createAsyncThunk)(
611
+ "soul/import",
612
+ async ({ txId, apiUrl, apiKey }, { dispatch: dispatch2, rejectWithValue }) => {
613
+ try {
614
+ const url = apiUrl || "https://api.forboc.ai";
615
+ const data = await dispatch2(sdkApi.endpoints.getSoulImport.initiate({ txId, apiUrl: url, apiKey })).unwrap();
616
+ return data;
617
+ } catch (e) {
618
+ return rejectWithValue(e.message || "Soul import failed");
619
+ }
620
+ }
621
+ );
622
+ var getSoulListThunk = (0, import_toolkit2.createAsyncThunk)(
623
+ "soul/list",
624
+ async ({ limit = 50, apiUrl, apiKey }, { dispatch: dispatch2, rejectWithValue }) => {
625
+ try {
626
+ const url = apiUrl || "https://api.forboc.ai";
627
+ const data = await dispatch2(sdkApi.endpoints.getSouls.initiate({ limit, apiUrl: url, apiKey })).unwrap();
628
+ return data.souls || [];
629
+ } catch (e) {
630
+ return rejectWithValue(e.message || "Failed to list souls");
631
+ }
632
+ }
633
+ );
634
+ var verifySoulThunk = (0, import_toolkit2.createAsyncThunk)(
635
+ "soul/verify",
636
+ async ({ txId, apiUrl, apiKey }, { dispatch: dispatch2, rejectWithValue }) => {
637
+ try {
638
+ const url = apiUrl || "https://api.forboc.ai";
639
+ return await dispatch2(sdkApi.endpoints.postSoulVerify.initiate({ txId, apiUrl: url, apiKey })).unwrap();
640
+ } catch (e) {
641
+ return rejectWithValue(e.message || "Soul verify failed");
642
+ }
643
+ }
644
+ );
645
+ var importNpcFromSoulThunk = (0, import_toolkit2.createAsyncThunk)(
646
+ "soul/importNpc",
647
+ async ({ txId, apiUrl, apiKey }, { dispatch: dispatch2, rejectWithValue }) => {
648
+ try {
649
+ const url = apiUrl || "https://api.forboc.ai";
650
+ return await dispatch2(sdkApi.endpoints.postNpcImport.initiate({
651
+ request: { txIdRef: txId },
652
+ apiUrl: url,
653
+ apiKey
654
+ })).unwrap();
655
+ } catch (e) {
656
+ return rejectWithValue(e.message || "NPC import from soul failed");
657
+ }
658
+ }
659
+ );
660
+ var soulSlice = (0, import_toolkit2.createSlice)({
661
+ name: "soul",
662
+ initialState: initialState2,
663
+ reducers: {
664
+ clearSoulState: (state) => {
665
+ state.exportStatus = "idle";
666
+ state.importStatus = "idle";
667
+ state.lastExport = null;
668
+ state.lastImport = null;
669
+ state.error = null;
670
+ }
671
+ },
672
+ extraReducers: (builder) => {
673
+ builder.addCase(remoteExportSoulThunk.pending, (state) => {
674
+ state.exportStatus = "exporting";
675
+ state.error = null;
676
+ }).addCase(remoteExportSoulThunk.fulfilled, (state, action) => {
677
+ state.exportStatus = "success";
678
+ state.lastExport = action.payload;
679
+ }).addCase(remoteExportSoulThunk.rejected, (state, action) => {
680
+ state.exportStatus = "failed";
681
+ state.error = action.payload;
682
+ }).addCase(importSoulFromArweaveThunk.pending, (state) => {
683
+ state.importStatus = "importing";
684
+ state.error = null;
685
+ }).addCase(importSoulFromArweaveThunk.fulfilled, (state, action) => {
686
+ state.importStatus = "success";
687
+ state.lastImport = action.payload;
688
+ }).addCase(importSoulFromArweaveThunk.rejected, (state, action) => {
689
+ state.importStatus = "failed";
690
+ state.error = action.payload;
691
+ }).addCase(getSoulListThunk.fulfilled, (state, action) => {
692
+ state.availableSouls = action.payload;
693
+ });
694
+ }
695
+ });
696
+ var { clearSoulState } = soulSlice.actions;
697
+ var soulSlice_default = soulSlice.reducer;
275
698
 
276
- // src/bridge.ts
277
- var createBridge = (config = {}) => {
278
- const apiUrl = config.apiUrl || "https://api.forboc.ai";
279
- const agentId = config.agentId;
280
- const validate = async (action, context = {}) => {
281
- const endpoint = agentId ? `${apiUrl}/bridge/validate/${agentId}` : `${apiUrl}/bridge/validate`;
699
+ // src/ghostSlice.ts
700
+ var import_toolkit3 = require("@reduxjs/toolkit");
701
+ var initialState3 = {
702
+ activeSessionId: null,
703
+ status: null,
704
+ progress: 0,
705
+ results: null,
706
+ history: [],
707
+ loading: false,
708
+ error: null
709
+ };
710
+ var startGhostThunk = (0, import_toolkit3.createAsyncThunk)(
711
+ "ghost/start",
712
+ async (config, { dispatch: dispatch2, rejectWithValue }) => {
282
713
  try {
283
- const response = await fetch(endpoint, {
284
- method: "POST",
285
- headers: { "Content-Type": "application/json" },
286
- body: JSON.stringify({ action, context })
287
- });
288
- if (!response.ok) {
289
- const error = await response.text();
290
- throw new Error(`Bridge validation failed: ${error}`);
291
- }
292
- const data = await response.json();
293
- return data.brResult || data;
714
+ const apiUrl = config.apiUrl || "https://api.forboc.ai";
715
+ const data = await dispatch2(sdkApi.endpoints.postGhostRun.initiate({
716
+ request: { testSuite: config.testSuite, duration: config.duration ?? 300 },
717
+ apiUrl,
718
+ apiKey: config.apiKey
719
+ })).unwrap();
720
+ return {
721
+ sessionId: data.sessionId,
722
+ status: data.runStatus
723
+ };
294
724
  } catch (e) {
295
- console.error("[Bridge] Validation error:", e);
725
+ return rejectWithValue(e.message || "Failed to start Ghost");
726
+ }
727
+ }
728
+ );
729
+ var getGhostStatusThunk = (0, import_toolkit3.createAsyncThunk)(
730
+ "ghost/status",
731
+ async ({ sessionId, apiUrl, apiKey }, { dispatch: dispatch2, getState, rejectWithValue }) => {
732
+ try {
733
+ const state = getState().ghost;
734
+ const targetSession = sessionId || state.activeSessionId;
735
+ if (!targetSession) throw new Error("No active Ghost session");
736
+ const url = apiUrl || "https://api.forboc.ai";
737
+ const data = await dispatch2(sdkApi.endpoints.getGhostStatus.initiate({ sessionId: targetSession, apiUrl: url, apiKey })).unwrap();
296
738
  return {
297
- valid: false,
298
- reason: `Network error reaching validation API: ${e instanceof Error ? e.message : String(e)}`
739
+ sessionId: data.ghostSessionId,
740
+ status: data.ghostStatus,
741
+ progress: data.ghostProgress,
742
+ startedAt: data.ghostStartedAt,
743
+ duration: data.ghostDuration || 0,
744
+ errors: data.ghostErrors
299
745
  };
746
+ } catch (e) {
747
+ return rejectWithValue(e.message || "Failed to get ghost status");
300
748
  }
301
- };
302
- const listRulesets = async () => {
303
- const response = await fetch(`${apiUrl}/rules`);
304
- if (!response.ok) return [];
305
- return response.json();
306
- };
307
- return { validate, listRulesets };
308
- };
309
- var validateAction = async (action, context = {}, config = {}) => {
310
- const bridge = createBridge(config);
311
- return bridge.validate(action, context);
312
- };
313
- var loadPreset = async (presetName, apiUrl = "https://api.forboc.ai") => {
314
- const response = await fetch(`${apiUrl}/rules/presets/${presetName}`, {
315
- method: "POST"
316
- });
317
- if (!response.ok) {
318
- throw new Error(`Failed to load preset '${presetName}': ${response.statusText}`);
319
749
  }
320
- return response.json();
321
- };
750
+ );
751
+ var getGhostResultsThunk = (0, import_toolkit3.createAsyncThunk)(
752
+ "ghost/results",
753
+ async ({ sessionId, apiUrl, apiKey }, { dispatch: dispatch2, getState, rejectWithValue }) => {
754
+ try {
755
+ const state = getState().ghost;
756
+ const targetSession = sessionId || state.activeSessionId;
757
+ if (!targetSession) throw new Error("No active Ghost session");
758
+ const url = apiUrl || "https://api.forboc.ai";
759
+ const data = await dispatch2(sdkApi.endpoints.getGhostResults.initiate({ sessionId: targetSession, apiUrl: url, apiKey })).unwrap();
760
+ return {
761
+ sessionId: data.resultsSessionId,
762
+ totalTests: data.resultsTotalTests,
763
+ passed: data.resultsPassed,
764
+ failed: data.resultsFailed,
765
+ skipped: data.resultsSkipped,
766
+ duration: data.resultsDuration,
767
+ tests: (data.resultsTests || []).map((t) => ({
768
+ name: t.testName,
769
+ passed: t.testPassed,
770
+ duration: t.testDuration,
771
+ error: t.testError,
772
+ screenshot: t.testScreenshot
773
+ })),
774
+ coverage: data.resultsCoverage,
775
+ metrics: Object.fromEntries(data.resultsMetrics || [])
776
+ };
777
+ } catch (e) {
778
+ return rejectWithValue(e.message || "Failed to get ghost results");
779
+ }
780
+ }
781
+ );
782
+ var stopGhostThunk = (0, import_toolkit3.createAsyncThunk)(
783
+ "ghost/stop",
784
+ async ({ sessionId, apiUrl, apiKey }, { dispatch: dispatch2, getState, rejectWithValue }) => {
785
+ try {
786
+ const state = getState().ghost;
787
+ const targetSession = sessionId || state.activeSessionId;
788
+ if (!targetSession) throw new Error("No active Ghost session");
789
+ const url = apiUrl || "https://api.forboc.ai";
790
+ const data = await dispatch2(sdkApi.endpoints.postGhostStop.initiate({ sessionId: targetSession, apiUrl: url, apiKey })).unwrap();
791
+ return {
792
+ stopped: data.stopped,
793
+ status: data.stopStatus,
794
+ sessionId: data.stopSessionId
795
+ };
796
+ } catch (e) {
797
+ return rejectWithValue(e.message || "Failed to stop ghost session");
798
+ }
799
+ }
800
+ );
801
+ var getGhostHistoryThunk = (0, import_toolkit3.createAsyncThunk)(
802
+ "ghost/history",
803
+ async ({ limit = 10, apiUrl, apiKey }, { dispatch: dispatch2, rejectWithValue }) => {
804
+ try {
805
+ const url = apiUrl || "https://api.forboc.ai";
806
+ const data = await dispatch2(sdkApi.endpoints.getGhostHistory.initiate({ limit, apiUrl: url, apiKey })).unwrap();
807
+ return (data.sessions || []).map((s) => ({
808
+ sessionId: s.sessionId,
809
+ testSuite: s.testSuite,
810
+ startedAt: s.startedAt,
811
+ completedAt: s.completedAt,
812
+ status: s.status,
813
+ passRate: s.passRate
814
+ }));
815
+ } catch (e) {
816
+ return rejectWithValue(e.message || "Failed to get ghost history");
817
+ }
818
+ }
819
+ );
820
+ var ghostSlice = (0, import_toolkit3.createSlice)({
821
+ name: "ghost",
822
+ initialState: initialState3,
823
+ reducers: {
824
+ clearGhostSession: (state) => {
825
+ state.activeSessionId = null;
826
+ state.status = null;
827
+ state.progress = 0;
828
+ state.results = null;
829
+ }
830
+ },
831
+ extraReducers: (builder) => {
832
+ builder.addCase(startGhostThunk.pending, (state) => {
833
+ state.loading = true;
834
+ state.error = null;
835
+ }).addCase(startGhostThunk.fulfilled, (state, action) => {
836
+ state.loading = false;
837
+ state.activeSessionId = action.payload.sessionId;
838
+ state.status = "running";
839
+ state.progress = 0;
840
+ }).addCase(startGhostThunk.rejected, (state, action) => {
841
+ state.loading = false;
842
+ state.error = action.payload;
843
+ }).addCase(getGhostStatusThunk.fulfilled, (state, action) => {
844
+ state.status = action.payload.status;
845
+ state.progress = action.payload.progress;
846
+ }).addCase(getGhostResultsThunk.fulfilled, (state, action) => {
847
+ state.results = action.payload;
848
+ state.status = "completed";
849
+ }).addCase(stopGhostThunk.fulfilled, (state, action) => {
850
+ if (action.payload.stopped) {
851
+ state.status = "failed";
852
+ } else {
853
+ state.error = action.payload.status || "Ghost stop request did not stop a session";
854
+ }
855
+ }).addCase(stopGhostThunk.rejected, (state, action) => {
856
+ state.error = action.payload;
857
+ }).addCase(getGhostHistoryThunk.fulfilled, (state, action) => {
858
+ state.history = action.payload;
859
+ });
860
+ }
861
+ });
862
+ var { clearGhostSession } = ghostSlice.actions;
863
+ var ghostSlice_default = ghostSlice.reducer;
322
864
 
323
- // src/index.ts
324
- init_soul();
865
+ // src/utils/sdkVersion.ts
866
+ var SDK_VERSION = "0.6.0";
867
+
868
+ // src/utils/generateNPCId.ts
869
+ var generateNPCId = () => `ag_${Date.now().toString(36)}`;
325
870
 
326
- // src/utils.ts
871
+ // src/utils/delay.ts
327
872
  var delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
873
+
874
+ // src/utils/pipe.ts
328
875
  var pipe = (...fns) => (initialValue) => fns.reduce((acc, fn) => fn(acc), initialValue);
876
+
877
+ // src/utils/memoiseAsync.ts
329
878
  var memoiseAsync = (fn) => {
330
879
  let cached = null;
331
880
  let promise = null;
@@ -339,6 +888,8 @@ var memoiseAsync = (fn) => {
339
888
  return promise;
340
889
  };
341
890
  };
891
+
892
+ // src/utils/memoise.ts
342
893
  var memoise = (fn) => {
343
894
  let cached = null;
344
895
  let initialized = false;
@@ -350,161 +901,6 @@ var memoise = (fn) => {
350
901
  };
351
902
  };
352
903
 
353
- // src/ghost.ts
354
- var DEFAULT_API_URL = "https://api.forboc.ai";
355
- var startGhostSession = async (config) => {
356
- const apiUrl = config.apiUrl || DEFAULT_API_URL;
357
- const response = await fetch(`${apiUrl}/ghost/run`, {
358
- method: "POST",
359
- headers: { "Content-Type": "application/json" },
360
- body: JSON.stringify({
361
- testSuite: config.testSuite,
362
- duration: config.duration
363
- })
364
- });
365
- if (!response.ok) throw new Error(`Failed to start Ghost: ${response.statusText}`);
366
- const data = await response.json();
367
- return {
368
- sessionId: data.sessionId,
369
- status: data.runStatus
370
- };
371
- };
372
- var getGhostStatus = async (sessionId, apiUrl) => {
373
- const url = apiUrl || DEFAULT_API_URL;
374
- const response = await fetch(`${url}/ghost/${sessionId}/status`, {
375
- method: "GET",
376
- headers: { "Content-Type": "application/json" }
377
- });
378
- if (!response.ok) throw new Error(`Failed to get status: ${response.statusText}`);
379
- const data = await response.json();
380
- return {
381
- sessionId: data.ghostSessionId,
382
- status: data.ghostStatus,
383
- progress: data.ghostProgress,
384
- startedAt: data.ghostStartedAt,
385
- duration: data.ghostDuration,
386
- errors: data.ghostErrors
387
- };
388
- };
389
- var getGhostResults = async (sessionId, apiUrl) => {
390
- const url = apiUrl || DEFAULT_API_URL;
391
- const response = await fetch(`${url}/ghost/${sessionId}/results`, {
392
- method: "GET",
393
- headers: { "Content-Type": "application/json" }
394
- });
395
- if (!response.ok) throw new Error(`Failed to get results: ${response.statusText}`);
396
- const data = await response.json();
397
- return {
398
- sessionId: data.resultsSessionId,
399
- totalTests: data.resultsTotalTests,
400
- passed: data.resultsPassed,
401
- failed: data.resultsFailed,
402
- skipped: data.resultsSkipped,
403
- duration: data.resultsDuration,
404
- tests: data.resultsTests.map((t) => ({
405
- name: t.testName,
406
- passed: t.testPassed,
407
- duration: t.testDuration,
408
- error: t.testError,
409
- screenshot: t.testScreenshot
410
- })),
411
- coverage: data.resultsCoverage,
412
- metrics: Object.fromEntries(data.resultsMetrics || [])
413
- };
414
- };
415
- var pollForCompletion = async (sessionId, pollIntervalMs, timeoutMs, startTime, apiUrl, onProgress) => {
416
- if (Date.now() - startTime > timeoutMs) {
417
- throw new Error(`Ghost session timed out after ${timeoutMs}ms`);
418
- }
419
- try {
420
- const status = await getGhostStatus(sessionId, apiUrl);
421
- if (onProgress) onProgress(status);
422
- if (status.status === "completed") return getGhostResults(sessionId, apiUrl);
423
- if (status.status === "failed") throw new Error(`Ghost session failed with ${status.errors} errors`);
424
- } catch (e) {
425
- }
426
- await delay(pollIntervalMs);
427
- return pollForCompletion(sessionId, pollIntervalMs, timeoutMs, startTime, apiUrl, onProgress);
428
- };
429
- var waitForGhostCompletion = (sessionId, pollIntervalMs = 5e3, timeoutMs = 3e5, apiUrl, onProgress) => pollForCompletion(sessionId, pollIntervalMs, timeoutMs, Date.now(), apiUrl, onProgress);
430
- var stopGhostSession = async (sessionId, apiUrl) => {
431
- const url = apiUrl || DEFAULT_API_URL;
432
- try {
433
- const response = await fetch(`${url}/ghost/${sessionId}/stop`, { method: "POST" });
434
- return { stopped: response.ok };
435
- } catch (e) {
436
- return { stopped: true };
437
- }
438
- };
439
- var getGhostHistory = async (limit = 10, apiUrl) => {
440
- const url = apiUrl || DEFAULT_API_URL;
441
- try {
442
- const response = await fetch(`${url}/ghost/history?limit=${limit}`);
443
- if (!response.ok) return [];
444
- const data = await response.json();
445
- return data.sessions.map((s) => ({
446
- sessionId: s.sessionId,
447
- testSuite: s.testSuite,
448
- startedAt: s.startedAt,
449
- completedAt: s.completedAt,
450
- status: s.status,
451
- passRate: s.passRate
452
- }));
453
- } catch (e) {
454
- return [];
455
- }
456
- };
457
- var createGhost = (config) => {
458
- let _sessionId = null;
459
- const apiUrl = config.apiUrl || DEFAULT_API_URL;
460
- const run = async () => {
461
- const result = await startGhostSession(config);
462
- _sessionId = result.sessionId;
463
- return _sessionId;
464
- };
465
- const ensureSessionId = () => {
466
- if (!_sessionId) throw new Error("Ghost session not started");
467
- return _sessionId;
468
- };
469
- const status = async () => getGhostStatus(ensureSessionId(), apiUrl);
470
- const results = async () => getGhostResults(ensureSessionId(), apiUrl);
471
- const stop = async () => {
472
- if (_sessionId) await stopGhostSession(_sessionId, apiUrl);
473
- _sessionId = null;
474
- };
475
- const waitForCompletion = (pollIntervalMs, timeoutMs, onProgress) => waitForGhostCompletion(ensureSessionId(), pollIntervalMs, timeoutMs, apiUrl, onProgress);
476
- return { run, status, results, stop, waitForCompletion };
477
- };
478
-
479
- // src/cortex-remote.ts
480
- var createRemoteCortex = (apiUrl, cortexId = "local", apiKey) => {
481
- const authHeaders = {
482
- "Content-Type": "application/json",
483
- ...apiKey ? { "Authorization": `Bearer ${apiKey}` } : {}
484
- };
485
- const init = async () => ({
486
- id: `remote_${Date.now()}`,
487
- model: "api-integrated",
488
- ready: true,
489
- engine: "remote"
490
- });
491
- const complete = async (prompt, options) => {
492
- const response = await fetch(`${apiUrl}/cortex/${cortexId}/complete`, {
493
- method: "POST",
494
- headers: authHeaders,
495
- body: JSON.stringify({ prompt, ...options })
496
- });
497
- if (!response.ok) throw new Error(`Remote Cortex failed: ${response.statusText}`);
498
- const data = await response.json();
499
- return data.text;
500
- };
501
- const completeStream = async function* (prompt, options) {
502
- const result = await complete(prompt, options);
503
- yield result;
504
- };
505
- return { init, complete, completeStream };
506
- };
507
-
508
904
  // src/stream.ts
509
905
  var consumeStream = async (stream, onChunk, acc = "", delayMs = 0) => {
510
906
  const { value, done } = await stream.next();
@@ -529,41 +925,642 @@ var streamFromCortexWithDelay = async (cortex, prompt, onChunk, options) => {
529
925
  return consumeStream(cortex.completeStream(prompt, completionOptions), onChunk, "", delayMs);
530
926
  };
531
927
 
532
- // src/index.ts
533
- var SDK_VERSION = "0.5.9";
928
+ // src/store.ts
929
+ var import_toolkit9 = require("@reduxjs/toolkit");
930
+
931
+ // src/npcSlice.ts
932
+ var import_toolkit4 = require("@reduxjs/toolkit");
933
+ var npcAdapter = (0, import_toolkit4.createEntityAdapter)();
934
+ var npcSlice = (0, import_toolkit4.createSlice)({
935
+ name: "npc",
936
+ initialState: npcAdapter.getInitialState({
937
+ activeNpcId: ""
938
+ }),
939
+ reducers: {
940
+ setNPCInfo: (state, action) => {
941
+ const { id, persona, initialState: initialState5 } = action.payload;
942
+ npcAdapter.upsertOne(state, {
943
+ id,
944
+ persona,
945
+ state: initialState5 || {},
946
+ history: [],
947
+ isBlocked: false
948
+ });
949
+ state.activeNpcId = id;
950
+ },
951
+ setActiveNPC: (state, action) => {
952
+ state.activeNpcId = action.payload;
953
+ },
954
+ setNPCState: (state, action) => {
955
+ const { id, state: npcState } = action.payload;
956
+ npcAdapter.updateOne(state, { id, changes: { state: npcState } });
957
+ },
958
+ updateNPCState: (state, action) => {
959
+ const { id, delta } = action.payload;
960
+ const npc = state.entities[id];
961
+ if (npc) {
962
+ npc.state = { ...npc.state, ...delta };
963
+ }
964
+ },
965
+ addToHistory: (state, action) => {
966
+ const { id, role, content } = action.payload;
967
+ const npc = state.entities[id];
968
+ if (npc) {
969
+ npc.history.push({ role, content });
970
+ }
971
+ },
972
+ setHistory: (state, action) => {
973
+ const { id, history } = action.payload;
974
+ npcAdapter.updateOne(state, { id, changes: { history } });
975
+ },
976
+ setLastAction: (state, action) => {
977
+ const { id, action: npcAction } = action.payload;
978
+ npcAdapter.updateOne(state, { id, changes: { lastAction: npcAction } });
979
+ },
980
+ blockAction: (state, action) => {
981
+ const { id, reason } = action.payload;
982
+ npcAdapter.updateOne(state, { id, changes: { isBlocked: true, blockReason: reason } });
983
+ },
984
+ clearBlock: (state, action) => {
985
+ npcAdapter.updateOne(state, { id: action.payload, changes: { isBlocked: false, blockReason: void 0 } });
986
+ },
987
+ removeNPC: npcAdapter.removeOne
988
+ }
989
+ });
990
+ var {
991
+ setNPCInfo,
992
+ setActiveNPC,
993
+ setNPCState,
994
+ updateNPCState,
995
+ addToHistory,
996
+ setHistory,
997
+ setLastAction,
998
+ blockAction,
999
+ clearBlock,
1000
+ removeNPC
1001
+ } = npcSlice.actions;
1002
+ var {
1003
+ selectById: selectNPCById,
1004
+ selectIds: selectNPCIds,
1005
+ selectEntities: selectNPCEntities,
1006
+ selectAll: selectAllNPCs,
1007
+ selectTotal: selectTotalNPCs
1008
+ } = npcAdapter.getSelectors((state) => state.npc);
1009
+ var selectActiveNpcId = (state) => state.npc.activeNpcId;
1010
+ var selectActiveNPC = (state) => {
1011
+ const id = selectActiveNpcId(state);
1012
+ return state.npc.entities[id];
1013
+ };
1014
+ var npcSlice_default = npcSlice.reducer;
1015
+
1016
+ // src/cortexSlice.ts
1017
+ var import_toolkit5 = require("@reduxjs/toolkit");
1018
+ var initialState4 = {
1019
+ status: {
1020
+ id: "init",
1021
+ model: "none",
1022
+ ready: false,
1023
+ engine: "mock"
1024
+ },
1025
+ isInitializing: false
1026
+ };
1027
+ var initRemoteCortexThunk = (0, import_toolkit5.createAsyncThunk)(
1028
+ "cortex/initRemote",
1029
+ async ({ model = "api-integrated", authKey, apiUrl, apiKey }, { dispatch: dispatch2, rejectWithValue }) => {
1030
+ try {
1031
+ const url = apiUrl || "https://api.forboc.ai";
1032
+ const data = await dispatch2(sdkApi.endpoints.postCortexInit.initiate({
1033
+ request: { requestedModel: model, authKey },
1034
+ apiUrl: url,
1035
+ apiKey
1036
+ })).unwrap();
1037
+ return {
1038
+ id: data.cortexId,
1039
+ model,
1040
+ ready: data.state?.toLowerCase() === "ready",
1041
+ engine: "remote"
1042
+ };
1043
+ } catch (e) {
1044
+ return rejectWithValue(e.message || "Remote cortex init failed");
1045
+ }
1046
+ }
1047
+ );
1048
+ var listCortexModelsThunk = (0, import_toolkit5.createAsyncThunk)(
1049
+ "cortex/listModels",
1050
+ async ({ apiUrl, apiKey }, { dispatch: dispatch2, rejectWithValue }) => {
1051
+ try {
1052
+ const url = apiUrl || "https://api.forboc.ai";
1053
+ return await dispatch2(sdkApi.endpoints.getCortexModels.initiate({ apiUrl: url, apiKey })).unwrap();
1054
+ } catch (e) {
1055
+ return rejectWithValue(e.message || "Failed to list cortex models");
1056
+ }
1057
+ }
1058
+ );
1059
+ var completeRemoteThunk = (0, import_toolkit5.createAsyncThunk)(
1060
+ "cortex/completeRemote",
1061
+ async ({ cortexId, prompt, options, apiUrl, apiKey }, { dispatch: dispatch2, rejectWithValue }) => {
1062
+ try {
1063
+ const data = await dispatch2(sdkApi.endpoints.postCortexComplete.initiate({
1064
+ cortexId,
1065
+ prompt,
1066
+ options,
1067
+ apiUrl,
1068
+ apiKey
1069
+ })).unwrap();
1070
+ return data.text;
1071
+ } catch (e) {
1072
+ return rejectWithValue(e.message || "Remote completing failed");
1073
+ }
1074
+ }
1075
+ );
1076
+ var cortexSlice = (0, import_toolkit5.createSlice)({
1077
+ name: "cortex",
1078
+ initialState: initialState4,
1079
+ reducers: {
1080
+ cortexInitStart: (state) => {
1081
+ state.isInitializing = true;
1082
+ state.error = void 0;
1083
+ },
1084
+ cortexInitSuccess: (state, action) => {
1085
+ state.status = action.payload;
1086
+ state.isInitializing = false;
1087
+ state.error = void 0;
1088
+ },
1089
+ cortexInitFailed: (state, action) => {
1090
+ state.isInitializing = false;
1091
+ state.error = action.payload;
1092
+ },
1093
+ setCortexStatus: (state, action) => {
1094
+ state.status = action.payload;
1095
+ }
1096
+ },
1097
+ extraReducers: (builder) => {
1098
+ builder.addCase(initRemoteCortexThunk.fulfilled, (state, action) => {
1099
+ state.status = action.payload;
1100
+ state.isInitializing = false;
1101
+ }).addCase(completeRemoteThunk.rejected, (state, action) => {
1102
+ state.error = action.payload;
1103
+ });
1104
+ }
1105
+ });
1106
+ var {
1107
+ cortexInitStart,
1108
+ cortexInitSuccess,
1109
+ cortexInitFailed,
1110
+ setCortexStatus
1111
+ } = cortexSlice.actions;
1112
+ var cortexSlice_default = cortexSlice.reducer;
1113
+
1114
+ // src/memorySlice.ts
1115
+ var import_toolkit6 = require("@reduxjs/toolkit");
1116
+ var memoryAdapter = (0, import_toolkit6.createEntityAdapter)();
1117
+ var memorySlice = (0, import_toolkit6.createSlice)({
1118
+ name: "memory",
1119
+ initialState: memoryAdapter.getInitialState({
1120
+ storageStatus: "idle",
1121
+ recallStatus: "idle",
1122
+ error: null,
1123
+ lastRecalledIds: []
1124
+ }),
1125
+ reducers: {
1126
+ memoryStoreStart: (state) => {
1127
+ state.storageStatus = "storing";
1128
+ state.error = null;
1129
+ },
1130
+ memoryStoreSuccess: (state, action) => {
1131
+ state.storageStatus = "idle";
1132
+ memoryAdapter.upsertOne(state, action.payload);
1133
+ },
1134
+ memoryStoreFailed: (state, action) => {
1135
+ state.storageStatus = "error";
1136
+ state.error = action.payload;
1137
+ },
1138
+ memoryRecallStart: (state) => {
1139
+ state.recallStatus = "recalling";
1140
+ state.error = null;
1141
+ },
1142
+ memoryRecallSuccess: (state, action) => {
1143
+ state.recallStatus = "idle";
1144
+ memoryAdapter.upsertMany(state, action.payload);
1145
+ state.lastRecalledIds = action.payload.map((m) => memoryAdapter.selectId(m));
1146
+ },
1147
+ memoryRecallFailed: (state, action) => {
1148
+ state.recallStatus = "error";
1149
+ state.error = action.payload;
1150
+ },
1151
+ memoryClear: (state) => {
1152
+ memoryAdapter.removeAll(state);
1153
+ state.lastRecalledIds = [];
1154
+ }
1155
+ }
1156
+ });
1157
+ var {
1158
+ memoryStoreStart,
1159
+ memoryStoreSuccess,
1160
+ memoryStoreFailed,
1161
+ memoryRecallStart,
1162
+ memoryRecallSuccess,
1163
+ memoryRecallFailed,
1164
+ memoryClear
1165
+ } = memorySlice.actions;
1166
+ var {
1167
+ selectById: selectMemoryById,
1168
+ selectAll: selectAllMemories
1169
+ } = memoryAdapter.getSelectors((state) => state.memory);
1170
+ var selectLastRecalledMemories = (state) => {
1171
+ return state.memory.lastRecalledIds.map((id) => state.memory.entities[id]).filter(Boolean);
1172
+ };
1173
+ var memorySlice_default = memorySlice.reducer;
1174
+
1175
+ // src/directiveSlice.ts
1176
+ var import_toolkit7 = require("@reduxjs/toolkit");
1177
+ var directiveAdapter = (0, import_toolkit7.createEntityAdapter)();
1178
+ var directiveSlice = (0, import_toolkit7.createSlice)({
1179
+ name: "directive",
1180
+ initialState: directiveAdapter.getInitialState({
1181
+ activeDirectiveId: ""
1182
+ }),
1183
+ reducers: {
1184
+ directiveRunStarted: (state, action) => {
1185
+ const { id, npcId, observation } = action.payload;
1186
+ directiveAdapter.upsertOne(state, {
1187
+ id,
1188
+ npcId,
1189
+ observation,
1190
+ status: "running",
1191
+ startedAt: Date.now()
1192
+ });
1193
+ state.activeDirectiveId = id;
1194
+ },
1195
+ directiveReceived: (state, action) => {
1196
+ const { id, response } = action.payload;
1197
+ directiveAdapter.updateOne(state, {
1198
+ id,
1199
+ changes: { memoryRecall: response.memoryRecall }
1200
+ });
1201
+ },
1202
+ contextComposed: (state, action) => {
1203
+ const { id, prompt, constraints } = action.payload;
1204
+ directiveAdapter.updateOne(state, {
1205
+ id,
1206
+ changes: { contextPrompt: prompt, contextConstraints: constraints }
1207
+ });
1208
+ },
1209
+ verdictValidated: (state, action) => {
1210
+ const { id, verdict } = action.payload;
1211
+ directiveAdapter.updateOne(state, {
1212
+ id,
1213
+ changes: {
1214
+ status: "completed",
1215
+ completedAt: Date.now(),
1216
+ verdictValid: verdict.valid,
1217
+ verdictDialogue: verdict.dialogue,
1218
+ verdictActionType: verdict.action?.type
1219
+ }
1220
+ });
1221
+ },
1222
+ directiveRunFailed: (state, action) => {
1223
+ const { id, error } = action.payload;
1224
+ directiveAdapter.updateOne(state, {
1225
+ id,
1226
+ changes: {
1227
+ status: "failed",
1228
+ completedAt: Date.now(),
1229
+ error
1230
+ }
1231
+ });
1232
+ },
1233
+ clearDirectivesForNpc: (state, action) => {
1234
+ const npcId = action.payload;
1235
+ const idsToRemove = Object.values(state.entities).filter((item) => Boolean(item)).filter((item) => item.npcId === npcId).map((item) => item.id);
1236
+ directiveAdapter.removeMany(state, idsToRemove);
1237
+ if (idsToRemove.includes(state.activeDirectiveId)) {
1238
+ state.activeDirectiveId = "";
1239
+ }
1240
+ }
1241
+ }
1242
+ });
1243
+ var {
1244
+ directiveRunStarted,
1245
+ directiveReceived,
1246
+ contextComposed,
1247
+ verdictValidated,
1248
+ directiveRunFailed,
1249
+ clearDirectivesForNpc
1250
+ } = directiveSlice.actions;
1251
+ var {
1252
+ selectById: selectDirectiveById,
1253
+ selectAll: selectAllDirectives
1254
+ } = directiveAdapter.getSelectors((state) => state.directive);
1255
+ var selectActiveDirectiveId = (state) => state.directive.activeDirectiveId;
1256
+ var selectActiveDirective = (state) => {
1257
+ const id = selectActiveDirectiveId(state);
1258
+ return state.directive.entities[id];
1259
+ };
1260
+ var directiveSlice_default = directiveSlice.reducer;
1261
+
1262
+ // src/listeners.ts
1263
+ var import_toolkit8 = require("@reduxjs/toolkit");
1264
+ var sdkListenerMiddleware = (0, import_toolkit8.createListenerMiddleware)();
1265
+ var startAppListening = sdkListenerMiddleware.startListening.withTypes();
1266
+ startAppListening({
1267
+ actionCreator: removeNPC,
1268
+ effect: async (action, listenerApi) => {
1269
+ const removedNpcId = action.payload;
1270
+ const state = listenerApi.getState();
1271
+ listenerApi.dispatch(clearDirectivesForNpc(removedNpcId));
1272
+ listenerApi.dispatch(clearBridgeValidation());
1273
+ listenerApi.dispatch(clearGhostSession());
1274
+ listenerApi.dispatch(clearSoulState());
1275
+ listenerApi.dispatch(clearBlock(removedNpcId));
1276
+ if (removedNpcId === state.npc.activeNpcId) {
1277
+ listenerApi.dispatch(memoryClear());
1278
+ }
1279
+ }
1280
+ });
1281
+
1282
+ // src/store.ts
1283
+ var createSDKStore = (extraReducers = {}) => {
1284
+ return (0, import_toolkit9.configureStore)({
1285
+ reducer: {
1286
+ [sdkApi.reducerPath]: sdkApi.reducer,
1287
+ npc: npcSlice_default,
1288
+ cortex: cortexSlice_default,
1289
+ memory: memorySlice_default,
1290
+ directive: directiveSlice_default,
1291
+ ghost: ghostSlice_default,
1292
+ soul: soulSlice_default,
1293
+ bridge: bridgeSlice_default,
1294
+ ...extraReducers
1295
+ },
1296
+ middleware: (getDefaultMiddleware) => getDefaultMiddleware({
1297
+ serializableCheck: false
1298
+ // Allow non-serializable for engine refs in specific slices if needed, though we try to keep them external
1299
+ }).prepend(sdkListenerMiddleware.middleware).concat(sdkApi.middleware)
1300
+ });
1301
+ };
1302
+ var store = createSDKStore();
1303
+ var dispatch = store.dispatch;
1304
+
1305
+ // src/thunks.ts
1306
+ var import_toolkit10 = require("@reduxjs/toolkit");
1307
+ var processNPC = (0, import_toolkit10.createAsyncThunk)(
1308
+ "npc/process",
1309
+ async ({ npcId: argNpcId, text, context = {}, apiUrl, apiKey, memory, cortex, persona: argPersona }, { getState, dispatch: dispatch2, rejectWithValue }) => {
1310
+ const stateNpcId = selectActiveNpcId(getState());
1311
+ const activeNpc = selectActiveNPC(getState());
1312
+ const npcId = argNpcId || stateNpcId;
1313
+ const persona = argPersona || activeNpc?.persona;
1314
+ const currentState = activeNpc?.state || {};
1315
+ if (!npcId) {
1316
+ return rejectWithValue("No npcId provided and no active NPC selected");
1317
+ }
1318
+ if (!persona) {
1319
+ return rejectWithValue("No persona provided and no active NPC persona available");
1320
+ }
1321
+ if (!cortex) {
1322
+ return rejectWithValue("No local cortex provided. SDK remote cortex fallback is disabled.");
1323
+ }
1324
+ if (argNpcId && argNpcId !== stateNpcId) {
1325
+ dispatch2(setNPCInfo({ id: argNpcId, persona }));
1326
+ }
1327
+ const directiveId = `${npcId}:${Date.now()}`;
1328
+ dispatch2(directiveRunStarted({ id: directiveId, npcId, observation: text }));
1329
+ try {
1330
+ const directiveResult = await dispatch2(
1331
+ sdkApi.endpoints.postDirective.initiate({ npcId, request: { observation: text, npcState: currentState, context }, apiUrl, apiKey })
1332
+ ).unwrap();
1333
+ dispatch2(directiveReceived({ id: directiveId, response: directiveResult }));
1334
+ if (directiveResult.memoryRecall && !memory) {
1335
+ return rejectWithValue("API requested memory recall, but no memory engine is configured");
1336
+ }
1337
+ const recalledMemories = memory && directiveResult.memoryRecall ? (await memory.recall(
1338
+ directiveResult.memoryRecall.query,
1339
+ directiveResult.memoryRecall.limit,
1340
+ directiveResult.memoryRecall.threshold
1341
+ )).map((m) => ({ text: m.text, type: m.type, importance: m.importance })) : [];
1342
+ const contextResult = await dispatch2(
1343
+ sdkApi.endpoints.postContext.initiate({ npcId, request: { memories: recalledMemories, observation: text, npcState: currentState, persona }, apiUrl, apiKey })
1344
+ ).unwrap();
1345
+ dispatch2(contextComposed({ id: directiveId, prompt: contextResult.prompt, constraints: contextResult.constraints }));
1346
+ const generatedText = await cortex.complete(contextResult.prompt, {
1347
+ maxTokens: contextResult.constraints.maxTokens,
1348
+ temperature: contextResult.constraints.temperature,
1349
+ stop: contextResult.constraints.stop
1350
+ });
1351
+ const verdictResult = await dispatch2(
1352
+ sdkApi.endpoints.postVerdict.initiate({ npcId, request: { generatedOutput: generatedText, observation: text, npcState: currentState }, apiUrl, apiKey })
1353
+ ).unwrap();
1354
+ dispatch2(verdictValidated({ id: directiveId, verdict: verdictResult }));
1355
+ if (!verdictResult.valid) {
1356
+ dispatch2(blockAction({ id: npcId, reason: verdictResult.dialogue || "Validation Failed" }));
1357
+ return {
1358
+ dialogue: verdictResult.dialogue,
1359
+ action: verdictResult.action,
1360
+ thought: verdictResult.dialogue
1361
+ };
1362
+ }
1363
+ if (verdictResult.memoryStore?.length && !memory) {
1364
+ return rejectWithValue("API returned memoryStore instructions, but no memory engine is configured");
1365
+ }
1366
+ if (memory && verdictResult.memoryStore) {
1367
+ for (const inst of verdictResult.memoryStore) {
1368
+ await memory.store(inst.text, inst.type, inst.importance);
1369
+ }
1370
+ }
1371
+ if (verdictResult.stateDelta) {
1372
+ dispatch2(updateNPCState({ id: npcId, delta: verdictResult.stateDelta }));
1373
+ }
1374
+ const action = verdictResult.action;
1375
+ dispatch2(setLastAction({ id: npcId, action }));
1376
+ dispatch2(addToHistory({ id: npcId, role: "user", content: text }));
1377
+ dispatch2(addToHistory({ id: npcId, role: "assistant", content: verdictResult.dialogue }));
1378
+ return {
1379
+ dialogue: verdictResult.dialogue,
1380
+ action,
1381
+ thought: verdictResult.dialogue
1382
+ };
1383
+ } catch (e) {
1384
+ const message = e?.message || e?.data?.message || "Protocol processing failed";
1385
+ dispatch2(directiveRunFailed({ id: directiveId, error: String(message) }));
1386
+ return rejectWithValue(String(message));
1387
+ }
1388
+ }
1389
+ );
1390
+ var localExportSoulThunk = (0, import_toolkit10.createAsyncThunk)(
1391
+ "npc/localExportSoul",
1392
+ async ({ id, memory }, { getState }) => {
1393
+ const state = getState().npc;
1394
+ const npcId = id || state.activeNpcId;
1395
+ const npc = state.entities[npcId];
1396
+ if (!npc) throw new Error(`NPC ${npcId} not found`);
1397
+ const memories = memory ? await memory.export() : [];
1398
+ return exportToSoul(npcId, "NPC", npc.persona, npc.state, memories);
1399
+ }
1400
+ );
1401
+ var checkApiStatusThunk = (0, import_toolkit10.createAsyncThunk)(
1402
+ "system/checkApiStatus",
1403
+ async ({ apiUrl }, { dispatch: dispatch2, rejectWithValue }) => {
1404
+ try {
1405
+ return await dispatch2(sdkApi.endpoints.getApiStatus.initiate({ apiUrl })).unwrap();
1406
+ } catch (e) {
1407
+ return rejectWithValue(e?.message || "Connection failed");
1408
+ }
1409
+ }
1410
+ );
1411
+ var listMemoryRemoteThunk = (0, import_toolkit10.createAsyncThunk)(
1412
+ "memory/listRemote",
1413
+ async ({ npcId, apiUrl, apiKey }, { dispatch: dispatch2, rejectWithValue }) => {
1414
+ try {
1415
+ const data = await dispatch2(sdkApi.endpoints.getMemoryList.initiate({ npcId, apiUrl, apiKey })).unwrap();
1416
+ return data || [];
1417
+ } catch (e) {
1418
+ return rejectWithValue(e?.message || "Failed to list memories");
1419
+ }
1420
+ }
1421
+ );
1422
+ var recallMemoryRemoteThunk = (0, import_toolkit10.createAsyncThunk)(
1423
+ "memory/recallRemote",
1424
+ async ({ npcId, query, apiUrl, apiKey }, { dispatch: dispatch2, rejectWithValue }) => {
1425
+ try {
1426
+ const data = await dispatch2(
1427
+ sdkApi.endpoints.postMemoryRecall.initiate({
1428
+ npcId,
1429
+ request: { query },
1430
+ apiUrl,
1431
+ apiKey
1432
+ })
1433
+ ).unwrap();
1434
+ return data || [];
1435
+ } catch (e) {
1436
+ return rejectWithValue(e?.message || "Failed to recall memories");
1437
+ }
1438
+ }
1439
+ );
1440
+ var storeMemoryRemoteThunk = (0, import_toolkit10.createAsyncThunk)(
1441
+ "memory/storeRemote",
1442
+ async ({ npcId, observation, importance = 0.8, apiUrl, apiKey }, { dispatch: dispatch2, rejectWithValue }) => {
1443
+ try {
1444
+ return await dispatch2(
1445
+ sdkApi.endpoints.postMemoryStore.initiate({
1446
+ npcId,
1447
+ request: { observation, importance },
1448
+ apiUrl,
1449
+ apiKey
1450
+ })
1451
+ ).unwrap();
1452
+ } catch (e) {
1453
+ return rejectWithValue(e?.message || "Failed to store memory");
1454
+ }
1455
+ }
1456
+ );
1457
+ var clearMemoryRemoteThunk = (0, import_toolkit10.createAsyncThunk)(
1458
+ "memory/clearRemote",
1459
+ async ({ npcId, apiUrl, apiKey }, { dispatch: dispatch2, rejectWithValue }) => {
1460
+ try {
1461
+ return await dispatch2(
1462
+ sdkApi.endpoints.deleteMemoryClear.initiate({ npcId, apiUrl, apiKey })
1463
+ ).unwrap();
1464
+ } catch (e) {
1465
+ return rejectWithValue(e?.message || "Failed to clear memories");
1466
+ }
1467
+ }
1468
+ );
534
1469
  // Annotate the CommonJS export names for ESM import in node:
535
1470
  0 && (module.exports = {
536
1471
  SDK_VERSION,
537
- createAgent,
538
- createBridge,
539
- createGhost,
1472
+ addToHistory,
1473
+ blockAction,
1474
+ bridgeSlice,
1475
+ checkApiStatusThunk,
1476
+ clearBlock,
1477
+ clearBridgeValidation,
1478
+ clearDirectivesForNpc,
1479
+ clearGhostSession,
1480
+ clearMemoryRemoteThunk,
1481
+ clearSoulState,
1482
+ completeRemoteThunk,
1483
+ contextComposed,
1484
+ cortexInitFailed,
1485
+ cortexInitStart,
1486
+ cortexInitSuccess,
1487
+ cortexSlice,
540
1488
  createInitialState,
541
- createRemoteCortex,
542
- createSoul,
543
- createSoulInstance,
1489
+ createSDKStore,
544
1490
  delay,
545
- deserializeSoul,
546
- exportSoul,
1491
+ deleteRulesetThunk,
1492
+ directiveReceived,
1493
+ directiveRunFailed,
1494
+ directiveRunStarted,
1495
+ directiveSlice,
1496
+ dispatch,
547
1497
  exportToSoul,
548
- fromSoul,
549
- getGhostHistory,
550
- getGhostResults,
551
- getGhostStatus,
552
- getSoulList,
553
- importSoulFromArweave,
554
- loadPreset,
1498
+ generateNPCId,
1499
+ getBridgeRulesThunk,
1500
+ getGhostHistoryThunk,
1501
+ getGhostResultsThunk,
1502
+ getGhostStatusThunk,
1503
+ getSoulListThunk,
1504
+ ghostSlice,
1505
+ importNpcFromSoulThunk,
1506
+ importSoulFromArweaveThunk,
1507
+ initRemoteCortexThunk,
1508
+ listCortexModelsThunk,
1509
+ listMemoryRemoteThunk,
1510
+ listRulePresetsThunk,
1511
+ listRulesetsThunk,
1512
+ loadBridgePresetThunk,
1513
+ localExportSoulThunk,
555
1514
  memoise,
556
1515
  memoiseAsync,
1516
+ memoryClear,
1517
+ memoryRecallFailed,
1518
+ memoryRecallStart,
1519
+ memoryRecallSuccess,
1520
+ memorySlice,
1521
+ memoryStoreFailed,
1522
+ memoryStoreStart,
1523
+ memoryStoreSuccess,
1524
+ npcSlice,
557
1525
  pipe,
558
- serializeSoul,
559
- startGhostSession,
560
- stopGhostSession,
1526
+ processNPC,
1527
+ recallMemoryRemoteThunk,
1528
+ registerRulesetThunk,
1529
+ remoteExportSoulThunk,
1530
+ removeNPC,
1531
+ sdkApi,
1532
+ selectActiveDirective,
1533
+ selectActiveDirectiveId,
1534
+ selectActiveNPC,
1535
+ selectActiveNpcId,
1536
+ selectAllDirectives,
1537
+ selectAllMemories,
1538
+ selectAllNPCs,
1539
+ selectDirectiveById,
1540
+ selectLastRecalledMemories,
1541
+ selectMemoryById,
1542
+ selectNPCById,
1543
+ selectNPCEntities,
1544
+ selectNPCIds,
1545
+ selectTotalNPCs,
1546
+ setActiveNPC,
1547
+ setCortexStatus,
1548
+ setHistory,
1549
+ setLastAction,
1550
+ setNPCInfo,
1551
+ setNPCState,
1552
+ soulSlice,
1553
+ startGhostThunk,
1554
+ stopGhostThunk,
1555
+ store,
1556
+ storeMemoryRemoteThunk,
561
1557
  streamFromCortex,
562
1558
  streamFromCortexWithDelay,
563
1559
  streamToCallback,
564
1560
  streamToString,
565
- updateAgentState,
566
- validateAction,
567
- validateSoul,
568
- waitForGhostCompletion
1561
+ updateNPCState,
1562
+ updateNPCStateLocally,
1563
+ validateBridgeThunk,
1564
+ verdictValidated,
1565
+ verifySoulThunk
569
1566
  });