@forbocai/core 0.6.0 → 0.6.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -26,9 +26,44 @@ var sdkApi = createApi({
26
26
  return headers;
27
27
  }
28
28
  }),
29
- tagTypes: ["NPC", "Memory", "Cortex", "Ghost", "Soul", "Bridge"],
29
+ tagTypes: ["NPC", "Memory", "Cortex", "Ghost", "Soul", "Bridge", "Rule"],
30
30
  endpoints: (builder) => ({
31
+ // Cortex Endpoints
32
+ getCortexModels: builder.query({
33
+ query: ({ apiUrl, apiKey }) => ({
34
+ url: `${apiUrl}/cortex/models`,
35
+ method: "GET",
36
+ headers: apiKey ? { "Authorization": `Bearer ${apiKey}` } : {}
37
+ }),
38
+ providesTags: ["Cortex"],
39
+ transformResponse: (response) => response || []
40
+ }),
41
+ postCortexInit: builder.mutation({
42
+ query: ({ request, apiUrl, apiKey }) => ({
43
+ url: `${apiUrl}/cortex/init`,
44
+ method: "POST",
45
+ headers: apiKey ? { "Authorization": `Bearer ${apiKey}` } : {},
46
+ body: request
47
+ }),
48
+ invalidatesTags: ["Cortex"],
49
+ transformResponse: (response) => response
50
+ }),
31
51
  // NPC Endpoints
52
+ /**
53
+ * User Story: As the SDK protocol loop, I need a single process endpoint
54
+ * that returns one atomic instruction per turn while echoing full tape state.
55
+ * ᚹ one hop in, one hop out, like passing a lit shard through vacuum.
56
+ */
57
+ postNpcProcess: builder.mutation({
58
+ query: ({ npcId, request, apiUrl, apiKey }) => ({
59
+ url: `${apiUrl}/npcs/${npcId}/process`,
60
+ method: "POST",
61
+ headers: apiKey ? { "Authorization": `Bearer ${apiKey}` } : {},
62
+ body: request
63
+ }),
64
+ invalidatesTags: (result, error, { npcId }) => [{ type: "NPC", id: npcId }],
65
+ transformResponse: (response) => response
66
+ }),
32
67
  postDirective: builder.mutation({
33
68
  query: ({ npcId, request, apiUrl, apiKey }) => ({
34
69
  url: `${apiUrl}/npcs/${npcId}/directive`,
@@ -70,88 +105,214 @@ var sdkApi = createApi({
70
105
  };
71
106
  }
72
107
  }),
73
- postSpeak: builder.mutation({
108
+ postMemoryStore: builder.mutation({
74
109
  query: ({ npcId, request, apiUrl, apiKey }) => ({
75
- url: `${apiUrl}/npcs/${npcId}/speak`,
110
+ url: `${apiUrl}/npcs/${npcId}/memory`,
76
111
  method: "POST",
77
112
  headers: apiKey ? { "Authorization": `Bearer ${apiKey}` } : {},
78
113
  body: request
79
114
  }),
80
- invalidatesTags: (result, error, { npcId }) => [{ type: "NPC", id: npcId }],
115
+ invalidatesTags: (result, error, { npcId }) => [{ type: "Memory", id: npcId }],
81
116
  transformResponse: (response) => response
82
117
  }),
83
- postDialogue: builder.mutation({
118
+ getMemoryList: builder.query({
119
+ query: ({ npcId, apiUrl, apiKey }) => ({
120
+ url: `${apiUrl}/npcs/${npcId}/memory`,
121
+ method: "GET",
122
+ headers: apiKey ? { "Authorization": `Bearer ${apiKey}` } : {}
123
+ }),
124
+ providesTags: (result, error, { npcId }) => [{ type: "Memory", id: npcId }],
125
+ transformResponse: (response) => response || []
126
+ }),
127
+ postMemoryRecall: builder.mutation({
84
128
  query: ({ npcId, request, apiUrl, apiKey }) => ({
85
- url: `${apiUrl}/npcs/${npcId}/dialogue`,
129
+ url: `${apiUrl}/npcs/${npcId}/memory/recall`,
86
130
  method: "POST",
87
131
  headers: apiKey ? { "Authorization": `Bearer ${apiKey}` } : {},
88
132
  body: request
89
133
  }),
90
- invalidatesTags: (result, error, { npcId }) => [{ type: "NPC", id: npcId }],
134
+ invalidatesTags: (result, error, { npcId }) => [{ type: "Memory", id: npcId }],
135
+ transformResponse: (response) => response || []
136
+ }),
137
+ deleteMemoryClear: builder.mutation({
138
+ query: ({ npcId, apiUrl, apiKey }) => ({
139
+ url: `${apiUrl}/npcs/${npcId}/memory/clear`,
140
+ method: "DELETE",
141
+ headers: apiKey ? { "Authorization": `Bearer ${apiKey}` } : {}
142
+ }),
143
+ invalidatesTags: (result, error, { npcId }) => [{ type: "Memory", id: npcId }],
91
144
  transformResponse: (response) => response
92
145
  }),
93
146
  // Ghost Endpoints
94
147
  postGhostRun: builder.mutation({
95
- query: ({ request, apiUrl }) => ({ url: `${apiUrl}/ghost/run`, method: "POST", body: request }),
148
+ query: ({ request, apiUrl, apiKey }) => ({
149
+ url: `${apiUrl}/ghost/run`,
150
+ method: "POST",
151
+ headers: apiKey ? { "Authorization": `Bearer ${apiKey}` } : {},
152
+ body: request
153
+ }),
96
154
  invalidatesTags: ["Ghost"],
97
155
  transformResponse: (response) => response
98
156
  }),
99
157
  getGhostStatus: builder.query({
100
- query: ({ sessionId, apiUrl }) => ({ url: `${apiUrl}/ghost/${sessionId}/status`, method: "GET" }),
158
+ query: ({ sessionId, apiUrl, apiKey }) => ({
159
+ url: `${apiUrl}/ghost/${sessionId}/status`,
160
+ method: "GET",
161
+ headers: apiKey ? { "Authorization": `Bearer ${apiKey}` } : {}
162
+ }),
101
163
  providesTags: (result, error, { sessionId }) => [{ type: "Ghost", id: sessionId }],
102
164
  transformResponse: (response) => response
103
165
  }),
104
166
  getGhostResults: builder.query({
105
- query: ({ sessionId, apiUrl }) => ({ url: `${apiUrl}/ghost/${sessionId}/results`, method: "GET" }),
167
+ query: ({ sessionId, apiUrl, apiKey }) => ({
168
+ url: `${apiUrl}/ghost/${sessionId}/results`,
169
+ method: "GET",
170
+ headers: apiKey ? { "Authorization": `Bearer ${apiKey}` } : {}
171
+ }),
106
172
  providesTags: (result, error, { sessionId }) => [{ type: "Ghost", id: sessionId }],
107
173
  transformResponse: (response) => response
108
174
  }),
109
175
  postGhostStop: builder.mutation({
110
- query: ({ sessionId, apiUrl }) => ({ url: `${apiUrl}/ghost/${sessionId}/stop`, method: "POST" }),
176
+ query: ({ sessionId, apiUrl, apiKey }) => ({
177
+ url: `${apiUrl}/ghost/${sessionId}/stop`,
178
+ method: "POST",
179
+ headers: apiKey ? { "Authorization": `Bearer ${apiKey}` } : {}
180
+ }),
111
181
  invalidatesTags: (result, error, { sessionId }) => [{ type: "Ghost", id: sessionId }],
112
- transformResponse: (response) => ({ stopped: true })
182
+ transformResponse: (response) => ({
183
+ stopped: response?.stopStatus === "stopped",
184
+ stopStatus: response?.stopStatus,
185
+ stopSessionId: response?.stopSessionId
186
+ })
113
187
  }),
114
188
  getGhostHistory: builder.query({
115
- query: ({ limit, apiUrl }) => ({ url: `${apiUrl}/ghost/history?limit=${limit}`, method: "GET" }),
189
+ query: ({ limit, apiUrl, apiKey }) => ({
190
+ url: `${apiUrl}/ghost/history?limit=${limit}`,
191
+ method: "GET",
192
+ headers: apiKey ? { "Authorization": `Bearer ${apiKey}` } : {}
193
+ }),
116
194
  providesTags: ["Ghost"],
117
195
  transformResponse: (response) => response
118
196
  }),
119
197
  // Soul Endpoints
120
198
  postSoulExport: builder.mutation({
121
- query: ({ npcId, request, apiUrl }) => ({ url: `${apiUrl}/npcs/${npcId}/soul/export`, method: "POST", body: request }),
199
+ query: ({ npcId, request, apiUrl, apiKey }) => ({
200
+ url: `${apiUrl}/npcs/${npcId}/soul/export`,
201
+ method: "POST",
202
+ headers: apiKey ? { "Authorization": `Bearer ${apiKey}` } : {},
203
+ body: request
204
+ }),
122
205
  invalidatesTags: ["Soul"],
123
206
  transformResponse: (response) => response
124
207
  }),
125
208
  getSoulImport: builder.query({
126
- query: ({ txId, apiUrl }) => ({ url: `${apiUrl}/souls/${txId}`, method: "GET" }),
209
+ query: ({ txId, apiUrl, apiKey }) => ({
210
+ url: `${apiUrl}/souls/${txId}`,
211
+ method: "GET",
212
+ headers: apiKey ? { "Authorization": `Bearer ${apiKey}` } : {}
213
+ }),
127
214
  providesTags: (result, error, { txId }) => [{ type: "Soul", id: txId }],
128
215
  transformResponse: (response) => response
129
216
  }),
130
217
  getSouls: builder.query({
131
- query: ({ limit, apiUrl }) => ({ url: `${apiUrl}/souls?limit=${limit}`, method: "GET" }),
218
+ query: ({ limit, apiUrl, apiKey }) => ({
219
+ url: `${apiUrl}/souls?limit=${limit}`,
220
+ method: "GET",
221
+ headers: apiKey ? { "Authorization": `Bearer ${apiKey}` } : {}
222
+ }),
132
223
  providesTags: ["Soul"],
133
224
  transformResponse: (response) => response
134
225
  }),
135
226
  // Bridge Endpoints
136
227
  postBridgeValidate: builder.mutation({
137
- query: ({ request, npcId, apiUrl }) => ({
228
+ query: ({ request, npcId, apiUrl, apiKey }) => ({
138
229
  url: npcId ? `${apiUrl}/bridge/validate/${npcId}` : `${apiUrl}/bridge/validate`,
139
230
  method: "POST",
231
+ headers: apiKey ? { "Authorization": `Bearer ${apiKey}` } : {},
140
232
  body: request
141
233
  }),
142
234
  invalidatesTags: ["Bridge"],
143
235
  transformResponse: (response) => response.brResult || response
144
236
  }),
145
237
  getBridgeRules: builder.query({
146
- query: ({ apiUrl }) => ({ url: `${apiUrl}/rules`, method: "GET" }),
238
+ query: ({ apiUrl, apiKey }) => ({
239
+ url: `${apiUrl}/bridge/rules`,
240
+ method: "GET",
241
+ headers: apiKey ? { "Authorization": `Bearer ${apiKey}` } : {}
242
+ }),
147
243
  providesTags: ["Bridge"],
148
244
  transformResponse: (response) => response
149
245
  }),
150
246
  postBridgePreset: builder.mutation({
151
- query: ({ presetName, apiUrl }) => ({ url: `${apiUrl}/rules/presets/${presetName}`, method: "POST" }),
247
+ query: ({ presetName, apiUrl, apiKey }) => ({
248
+ url: `${apiUrl}/rules/presets/${presetName}`,
249
+ method: "POST",
250
+ headers: apiKey ? { "Authorization": `Bearer ${apiKey}` } : {}
251
+ }),
152
252
  invalidatesTags: ["Bridge"],
153
253
  transformResponse: (response) => response
154
254
  }),
255
+ // Rules Endpoints
256
+ getRulesets: builder.query({
257
+ query: ({ apiUrl, apiKey }) => ({
258
+ url: `${apiUrl}/rules`,
259
+ method: "GET",
260
+ headers: apiKey ? { "Authorization": `Bearer ${apiKey}` } : {}
261
+ }),
262
+ providesTags: ["Rule"],
263
+ transformResponse: (response) => response || []
264
+ }),
265
+ getRulePresets: builder.query({
266
+ query: ({ apiUrl, apiKey }) => ({
267
+ url: `${apiUrl}/rules/presets`,
268
+ method: "GET",
269
+ headers: apiKey ? { "Authorization": `Bearer ${apiKey}` } : {}
270
+ }),
271
+ providesTags: ["Rule"],
272
+ transformResponse: (response) => response || []
273
+ }),
274
+ postRuleRegister: builder.mutation({
275
+ query: ({ request, apiUrl, apiKey }) => ({
276
+ url: `${apiUrl}/rules`,
277
+ method: "POST",
278
+ headers: apiKey ? { "Authorization": `Bearer ${apiKey}` } : {},
279
+ body: request
280
+ }),
281
+ invalidatesTags: ["Rule"],
282
+ transformResponse: (response) => response
283
+ }),
284
+ deleteRule: builder.mutation({
285
+ query: ({ rulesetId, apiUrl, apiKey }) => ({
286
+ url: `${apiUrl}/rules/${rulesetId}`,
287
+ method: "DELETE",
288
+ headers: apiKey ? { "Authorization": `Bearer ${apiKey}` } : {}
289
+ }),
290
+ invalidatesTags: ["Rule"],
291
+ transformResponse: (_response) => ({ deleted: true })
292
+ }),
293
+ // Additional Soul/NPC Endpoints
294
+ postSoulVerify: builder.mutation({
295
+ query: ({ txId, apiUrl, apiKey }) => ({
296
+ url: `${apiUrl}/souls/${txId}/verify`,
297
+ method: "POST",
298
+ headers: apiKey ? { "Authorization": `Bearer ${apiKey}` } : {}
299
+ }),
300
+ invalidatesTags: ["Soul"],
301
+ transformResponse: (response) => ({
302
+ valid: response.verifyValid ?? response.valid ?? false,
303
+ reason: response.verifyReason ?? response.reason
304
+ })
305
+ }),
306
+ postNpcImport: builder.mutation({
307
+ query: ({ request, apiUrl, apiKey }) => ({
308
+ url: `${apiUrl}/npcs/import`,
309
+ method: "POST",
310
+ headers: apiKey ? { "Authorization": `Bearer ${apiKey}` } : {},
311
+ body: request
312
+ }),
313
+ invalidatesTags: ["NPC"],
314
+ transformResponse: (response) => response
315
+ }),
155
316
  // Cortex Remote Endpoint
156
317
  postCortexComplete: builder.mutation({
157
318
  query: ({ cortexId, prompt, options, apiUrl, apiKey }) => ({
@@ -174,19 +335,22 @@ var sdkApi = createApi({
174
335
  // src/bridgeSlice.ts
175
336
  var initialState = {
176
337
  activePresets: [],
338
+ availableRulesets: [],
339
+ availablePresetIds: [],
177
340
  lastValidation: null,
178
341
  status: "idle",
179
342
  error: null
180
343
  };
181
344
  var validateBridgeThunk = createAsyncThunk(
182
345
  "bridge/validate",
183
- async ({ action, context, npcId, apiUrl }, { dispatch: dispatch2, rejectWithValue }) => {
346
+ async ({ action, context, npcId, apiUrl, apiKey }, { dispatch: dispatch2, rejectWithValue }) => {
184
347
  try {
185
348
  const url = apiUrl || "https://api.forboc.ai";
186
349
  const data = await dispatch2(sdkApi.endpoints.postBridgeValidate.initiate({
187
350
  request: { action, context },
188
351
  npcId,
189
- apiUrl: url
352
+ apiUrl: url,
353
+ apiKey
190
354
  })).unwrap();
191
355
  return data;
192
356
  } catch (e) {
@@ -196,10 +360,10 @@ var validateBridgeThunk = createAsyncThunk(
196
360
  );
197
361
  var loadBridgePresetThunk = createAsyncThunk(
198
362
  "bridge/loadPreset",
199
- async ({ presetName, apiUrl }, { dispatch: dispatch2, rejectWithValue }) => {
363
+ async ({ presetName, apiUrl, apiKey }, { dispatch: dispatch2, rejectWithValue }) => {
200
364
  try {
201
365
  const url = apiUrl || "https://api.forboc.ai";
202
- return await dispatch2(sdkApi.endpoints.postBridgePreset.initiate({ presetName, apiUrl: url })).unwrap();
366
+ return await dispatch2(sdkApi.endpoints.postBridgePreset.initiate({ presetName, apiUrl: url, apiKey })).unwrap();
203
367
  } catch (e) {
204
368
  return rejectWithValue(e.message || "Failed to load preset");
205
369
  }
@@ -207,15 +371,59 @@ var loadBridgePresetThunk = createAsyncThunk(
207
371
  );
208
372
  var getBridgeRulesThunk = createAsyncThunk(
209
373
  "bridge/rules",
210
- async ({ apiUrl }, { dispatch: dispatch2, rejectWithValue }) => {
374
+ async ({ apiUrl, apiKey }, { dispatch: dispatch2, rejectWithValue }) => {
211
375
  try {
212
376
  const url = apiUrl || "https://api.forboc.ai";
213
- return await dispatch2(sdkApi.endpoints.getBridgeRules.initiate({ apiUrl: url })).unwrap();
377
+ return await dispatch2(sdkApi.endpoints.getBridgeRules.initiate({ apiUrl: url, apiKey })).unwrap();
378
+ } catch (e) {
379
+ return rejectWithValue(e.message || "Failed to list bridge rules");
380
+ }
381
+ }
382
+ );
383
+ var listRulesetsThunk = createAsyncThunk(
384
+ "bridge/listRulesets",
385
+ async ({ apiUrl, apiKey }, { dispatch: dispatch2, rejectWithValue }) => {
386
+ try {
387
+ const url = apiUrl || "https://api.forboc.ai";
388
+ return await dispatch2(sdkApi.endpoints.getRulesets.initiate({ apiUrl: url, apiKey })).unwrap();
214
389
  } catch (e) {
215
390
  return rejectWithValue(e.message || "Failed to list rulesets");
216
391
  }
217
392
  }
218
393
  );
394
+ var listRulePresetsThunk = createAsyncThunk(
395
+ "bridge/listRulePresets",
396
+ async ({ apiUrl, apiKey }, { dispatch: dispatch2, rejectWithValue }) => {
397
+ try {
398
+ const url = apiUrl || "https://api.forboc.ai";
399
+ return await dispatch2(sdkApi.endpoints.getRulePresets.initiate({ apiUrl: url, apiKey })).unwrap();
400
+ } catch (e) {
401
+ return rejectWithValue(e.message || "Failed to list rule presets");
402
+ }
403
+ }
404
+ );
405
+ var registerRulesetThunk = createAsyncThunk(
406
+ "bridge/registerRuleset",
407
+ async ({ ruleset, apiUrl, apiKey }, { dispatch: dispatch2, rejectWithValue }) => {
408
+ try {
409
+ const url = apiUrl || "https://api.forboc.ai";
410
+ return await dispatch2(sdkApi.endpoints.postRuleRegister.initiate({ request: ruleset, apiUrl: url, apiKey })).unwrap();
411
+ } catch (e) {
412
+ return rejectWithValue(e.message || "Failed to register ruleset");
413
+ }
414
+ }
415
+ );
416
+ var deleteRulesetThunk = createAsyncThunk(
417
+ "bridge/deleteRuleset",
418
+ async ({ rulesetId, apiUrl, apiKey }, { dispatch: dispatch2, rejectWithValue }) => {
419
+ try {
420
+ const url = apiUrl || "https://api.forboc.ai";
421
+ return await dispatch2(sdkApi.endpoints.deleteRule.initiate({ rulesetId, apiUrl: url, apiKey })).unwrap();
422
+ } catch (e) {
423
+ return rejectWithValue(e.message || "Failed to delete ruleset");
424
+ }
425
+ }
426
+ );
219
427
  var bridgeSlice = createSlice({
220
428
  name: "bridge",
221
429
  initialState,
@@ -249,6 +457,10 @@ var bridgeSlice = createSlice({
249
457
  state.status = "error";
250
458
  state.error = action.payload;
251
459
  }).addCase(getBridgeRulesThunk.fulfilled, (state, action) => {
460
+ }).addCase(listRulesetsThunk.fulfilled, (state, action) => {
461
+ state.availableRulesets = action.payload;
462
+ }).addCase(listRulePresetsThunk.fulfilled, (state, action) => {
463
+ state.availablePresetIds = action.payload;
252
464
  });
253
465
  }
254
466
  });
@@ -267,7 +479,7 @@ var initialState2 = {
267
479
  };
268
480
  var remoteExportSoulThunk = createAsyncThunk2(
269
481
  "soul/export",
270
- async ({ npcId: argNpcId, apiUrl, memories = [] }, { getState, dispatch: dispatch2, rejectWithValue }) => {
482
+ async ({ npcId: argNpcId, apiUrl, apiKey, memories = [] }, { getState, dispatch: dispatch2, rejectWithValue }) => {
271
483
  try {
272
484
  const state = getState().npc;
273
485
  const npcId = argNpcId || state.activeNpcId;
@@ -277,7 +489,8 @@ var remoteExportSoulThunk = createAsyncThunk2(
277
489
  const result = await dispatch2(sdkApi.endpoints.postSoulExport.initiate({
278
490
  npcId,
279
491
  request: { npcIdRef: npcId, persona: npc.persona || "NPC", npcState: npc.state },
280
- apiUrl: url
492
+ apiUrl: url,
493
+ apiKey
281
494
  })).unwrap();
282
495
  return {
283
496
  txId: result.txId,
@@ -291,10 +504,10 @@ var remoteExportSoulThunk = createAsyncThunk2(
291
504
  );
292
505
  var importSoulFromArweaveThunk = createAsyncThunk2(
293
506
  "soul/import",
294
- async ({ txId, apiUrl }, { dispatch: dispatch2, rejectWithValue }) => {
507
+ async ({ txId, apiUrl, apiKey }, { dispatch: dispatch2, rejectWithValue }) => {
295
508
  try {
296
509
  const url = apiUrl || "https://api.forboc.ai";
297
- const data = await dispatch2(sdkApi.endpoints.getSoulImport.initiate({ txId, apiUrl: url })).unwrap();
510
+ const data = await dispatch2(sdkApi.endpoints.getSoulImport.initiate({ txId, apiUrl: url, apiKey })).unwrap();
298
511
  return data;
299
512
  } catch (e) {
300
513
  return rejectWithValue(e.message || "Soul import failed");
@@ -303,16 +516,42 @@ var importSoulFromArweaveThunk = createAsyncThunk2(
303
516
  );
304
517
  var getSoulListThunk = createAsyncThunk2(
305
518
  "soul/list",
306
- async ({ limit = 50, apiUrl }, { dispatch: dispatch2, rejectWithValue }) => {
519
+ async ({ limit = 50, apiUrl, apiKey }, { dispatch: dispatch2, rejectWithValue }) => {
307
520
  try {
308
521
  const url = apiUrl || "https://api.forboc.ai";
309
- const data = await dispatch2(sdkApi.endpoints.getSouls.initiate({ limit, apiUrl: url })).unwrap();
522
+ const data = await dispatch2(sdkApi.endpoints.getSouls.initiate({ limit, apiUrl: url, apiKey })).unwrap();
310
523
  return data.souls || [];
311
524
  } catch (e) {
312
525
  return rejectWithValue(e.message || "Failed to list souls");
313
526
  }
314
527
  }
315
528
  );
529
+ var verifySoulThunk = createAsyncThunk2(
530
+ "soul/verify",
531
+ async ({ txId, apiUrl, apiKey }, { dispatch: dispatch2, rejectWithValue }) => {
532
+ try {
533
+ const url = apiUrl || "https://api.forboc.ai";
534
+ return await dispatch2(sdkApi.endpoints.postSoulVerify.initiate({ txId, apiUrl: url, apiKey })).unwrap();
535
+ } catch (e) {
536
+ return rejectWithValue(e.message || "Soul verify failed");
537
+ }
538
+ }
539
+ );
540
+ var importNpcFromSoulThunk = createAsyncThunk2(
541
+ "soul/importNpc",
542
+ async ({ txId, apiUrl, apiKey }, { dispatch: dispatch2, rejectWithValue }) => {
543
+ try {
544
+ const url = apiUrl || "https://api.forboc.ai";
545
+ return await dispatch2(sdkApi.endpoints.postNpcImport.initiate({
546
+ request: { txIdRef: txId },
547
+ apiUrl: url,
548
+ apiKey
549
+ })).unwrap();
550
+ } catch (e) {
551
+ return rejectWithValue(e.message || "NPC import from soul failed");
552
+ }
553
+ }
554
+ );
316
555
  var soulSlice = createSlice2({
317
556
  name: "soul",
318
557
  initialState: initialState2,
@@ -370,7 +609,8 @@ var startGhostThunk = createAsyncThunk3(
370
609
  const apiUrl = config.apiUrl || "https://api.forboc.ai";
371
610
  const data = await dispatch2(sdkApi.endpoints.postGhostRun.initiate({
372
611
  request: { testSuite: config.testSuite, duration: config.duration ?? 300 },
373
- apiUrl
612
+ apiUrl,
613
+ apiKey: config.apiKey
374
614
  })).unwrap();
375
615
  return {
376
616
  sessionId: data.sessionId,
@@ -383,13 +623,13 @@ var startGhostThunk = createAsyncThunk3(
383
623
  );
384
624
  var getGhostStatusThunk = createAsyncThunk3(
385
625
  "ghost/status",
386
- async ({ sessionId, apiUrl }, { dispatch: dispatch2, getState, rejectWithValue }) => {
626
+ async ({ sessionId, apiUrl, apiKey }, { dispatch: dispatch2, getState, rejectWithValue }) => {
387
627
  try {
388
628
  const state = getState().ghost;
389
629
  const targetSession = sessionId || state.activeSessionId;
390
630
  if (!targetSession) throw new Error("No active Ghost session");
391
631
  const url = apiUrl || "https://api.forboc.ai";
392
- const data = await dispatch2(sdkApi.endpoints.getGhostStatus.initiate({ sessionId: targetSession, apiUrl: url })).unwrap();
632
+ const data = await dispatch2(sdkApi.endpoints.getGhostStatus.initiate({ sessionId: targetSession, apiUrl: url, apiKey })).unwrap();
393
633
  return {
394
634
  sessionId: data.ghostSessionId,
395
635
  status: data.ghostStatus,
@@ -405,13 +645,13 @@ var getGhostStatusThunk = createAsyncThunk3(
405
645
  );
406
646
  var getGhostResultsThunk = createAsyncThunk3(
407
647
  "ghost/results",
408
- async ({ sessionId, apiUrl }, { dispatch: dispatch2, getState, rejectWithValue }) => {
648
+ async ({ sessionId, apiUrl, apiKey }, { dispatch: dispatch2, getState, rejectWithValue }) => {
409
649
  try {
410
650
  const state = getState().ghost;
411
651
  const targetSession = sessionId || state.activeSessionId;
412
652
  if (!targetSession) throw new Error("No active Ghost session");
413
653
  const url = apiUrl || "https://api.forboc.ai";
414
- const data = await dispatch2(sdkApi.endpoints.getGhostResults.initiate({ sessionId: targetSession, apiUrl: url })).unwrap();
654
+ const data = await dispatch2(sdkApi.endpoints.getGhostResults.initiate({ sessionId: targetSession, apiUrl: url, apiKey })).unwrap();
415
655
  return {
416
656
  sessionId: data.resultsSessionId,
417
657
  totalTests: data.resultsTotalTests,
@@ -436,25 +676,29 @@ var getGhostResultsThunk = createAsyncThunk3(
436
676
  );
437
677
  var stopGhostThunk = createAsyncThunk3(
438
678
  "ghost/stop",
439
- async ({ sessionId, apiUrl }, { dispatch: dispatch2, getState, rejectWithValue }) => {
679
+ async ({ sessionId, apiUrl, apiKey }, { dispatch: dispatch2, getState, rejectWithValue }) => {
440
680
  try {
441
681
  const state = getState().ghost;
442
682
  const targetSession = sessionId || state.activeSessionId;
443
683
  if (!targetSession) throw new Error("No active Ghost session");
444
684
  const url = apiUrl || "https://api.forboc.ai";
445
- await dispatch2(sdkApi.endpoints.postGhostStop.initiate({ sessionId: targetSession, apiUrl: url })).unwrap();
446
- return { stopped: true };
685
+ const data = await dispatch2(sdkApi.endpoints.postGhostStop.initiate({ sessionId: targetSession, apiUrl: url, apiKey })).unwrap();
686
+ return {
687
+ stopped: data.stopped,
688
+ status: data.stopStatus,
689
+ sessionId: data.stopSessionId
690
+ };
447
691
  } catch (e) {
448
- return { stopped: true };
692
+ return rejectWithValue(e.message || "Failed to stop ghost session");
449
693
  }
450
694
  }
451
695
  );
452
696
  var getGhostHistoryThunk = createAsyncThunk3(
453
697
  "ghost/history",
454
- async ({ limit = 10, apiUrl }, { dispatch: dispatch2, rejectWithValue }) => {
698
+ async ({ limit = 10, apiUrl, apiKey }, { dispatch: dispatch2, rejectWithValue }) => {
455
699
  try {
456
700
  const url = apiUrl || "https://api.forboc.ai";
457
- const data = await dispatch2(sdkApi.endpoints.getGhostHistory.initiate({ limit, apiUrl: url })).unwrap();
701
+ const data = await dispatch2(sdkApi.endpoints.getGhostHistory.initiate({ limit, apiUrl: url, apiKey })).unwrap();
458
702
  return (data.sessions || []).map((s) => ({
459
703
  sessionId: s.sessionId,
460
704
  testSuite: s.testSuite,
@@ -497,8 +741,14 @@ var ghostSlice = createSlice3({
497
741
  }).addCase(getGhostResultsThunk.fulfilled, (state, action) => {
498
742
  state.results = action.payload;
499
743
  state.status = "completed";
500
- }).addCase(stopGhostThunk.fulfilled, (state) => {
501
- state.status = "failed";
744
+ }).addCase(stopGhostThunk.fulfilled, (state, action) => {
745
+ if (action.payload.stopped) {
746
+ state.status = "failed";
747
+ } else {
748
+ state.error = action.payload.status || "Ghost stop request did not stop a session";
749
+ }
750
+ }).addCase(stopGhostThunk.rejected, (state, action) => {
751
+ state.error = action.payload;
502
752
  }).addCase(getGhostHistoryThunk.fulfilled, (state, action) => {
503
753
  state.history = action.payload;
504
754
  });
@@ -507,11 +757,19 @@ var ghostSlice = createSlice3({
507
757
  var { clearGhostSession } = ghostSlice.actions;
508
758
  var ghostSlice_default = ghostSlice.reducer;
509
759
 
510
- // src/utils.ts
511
- var SDK_VERSION = "0.5.9";
760
+ // src/utils/sdkVersion.ts
761
+ var SDK_VERSION = "0.6.1";
762
+
763
+ // src/utils/generateNPCId.ts
512
764
  var generateNPCId = () => `ag_${Date.now().toString(36)}`;
765
+
766
+ // src/utils/delay.ts
513
767
  var delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
768
+
769
+ // src/utils/pipe.ts
514
770
  var pipe = (...fns) => (initialValue) => fns.reduce((acc, fn) => fn(acc), initialValue);
771
+
772
+ // src/utils/memoiseAsync.ts
515
773
  var memoiseAsync = (fn) => {
516
774
  let cached = null;
517
775
  let promise = null;
@@ -525,6 +783,8 @@ var memoiseAsync = (fn) => {
525
783
  return promise;
526
784
  };
527
785
  };
786
+
787
+ // src/utils/memoise.ts
528
788
  var memoise = (fn) => {
529
789
  let cached = null;
530
790
  let initialized = false;
@@ -661,13 +921,34 @@ var initialState4 = {
661
921
  };
662
922
  var initRemoteCortexThunk = createAsyncThunk4(
663
923
  "cortex/initRemote",
664
- async ({ model = "api-integrated" }) => {
665
- return {
666
- id: `remote_${Date.now()}`,
667
- model,
668
- ready: true,
669
- engine: "remote"
670
- };
924
+ async ({ model = "api-integrated", authKey, apiUrl, apiKey }, { dispatch: dispatch2, rejectWithValue }) => {
925
+ try {
926
+ const url = apiUrl || "https://api.forboc.ai";
927
+ const data = await dispatch2(sdkApi.endpoints.postCortexInit.initiate({
928
+ request: { requestedModel: model, authKey },
929
+ apiUrl: url,
930
+ apiKey
931
+ })).unwrap();
932
+ return {
933
+ id: data.cortexId,
934
+ model,
935
+ ready: data.state?.toLowerCase() === "ready",
936
+ engine: "remote"
937
+ };
938
+ } catch (e) {
939
+ return rejectWithValue(e.message || "Remote cortex init failed");
940
+ }
941
+ }
942
+ );
943
+ var listCortexModelsThunk = createAsyncThunk4(
944
+ "cortex/listModels",
945
+ async ({ apiUrl, apiKey }, { dispatch: dispatch2, rejectWithValue }) => {
946
+ try {
947
+ const url = apiUrl || "https://api.forboc.ai";
948
+ return await dispatch2(sdkApi.endpoints.getCortexModels.initiate({ apiUrl: url, apiKey })).unwrap();
949
+ } catch (e) {
950
+ return rejectWithValue(e.message || "Failed to list cortex models");
951
+ }
671
952
  }
672
953
  );
673
954
  var completeRemoteThunk = createAsyncThunk4(
@@ -786,6 +1067,93 @@ var selectLastRecalledMemories = (state) => {
786
1067
  };
787
1068
  var memorySlice_default = memorySlice.reducer;
788
1069
 
1070
+ // src/directiveSlice.ts
1071
+ import { createEntityAdapter as createEntityAdapter3, createSlice as createSlice7 } from "@reduxjs/toolkit";
1072
+ var directiveAdapter = createEntityAdapter3();
1073
+ var directiveSlice = createSlice7({
1074
+ name: "directive",
1075
+ initialState: directiveAdapter.getInitialState({
1076
+ activeDirectiveId: ""
1077
+ }),
1078
+ reducers: {
1079
+ directiveRunStarted: (state, action) => {
1080
+ const { id, npcId, observation } = action.payload;
1081
+ directiveAdapter.upsertOne(state, {
1082
+ id,
1083
+ npcId,
1084
+ observation,
1085
+ status: "running",
1086
+ startedAt: Date.now()
1087
+ });
1088
+ state.activeDirectiveId = id;
1089
+ },
1090
+ directiveReceived: (state, action) => {
1091
+ const { id, response } = action.payload;
1092
+ directiveAdapter.updateOne(state, {
1093
+ id,
1094
+ changes: { memoryRecall: response.memoryRecall }
1095
+ });
1096
+ },
1097
+ contextComposed: (state, action) => {
1098
+ const { id, prompt, constraints } = action.payload;
1099
+ directiveAdapter.updateOne(state, {
1100
+ id,
1101
+ changes: { contextPrompt: prompt, contextConstraints: constraints }
1102
+ });
1103
+ },
1104
+ verdictValidated: (state, action) => {
1105
+ const { id, verdict } = action.payload;
1106
+ directiveAdapter.updateOne(state, {
1107
+ id,
1108
+ changes: {
1109
+ status: "completed",
1110
+ completedAt: Date.now(),
1111
+ verdictValid: verdict.valid,
1112
+ verdictDialogue: verdict.dialogue,
1113
+ verdictActionType: verdict.action?.type
1114
+ }
1115
+ });
1116
+ },
1117
+ directiveRunFailed: (state, action) => {
1118
+ const { id, error } = action.payload;
1119
+ directiveAdapter.updateOne(state, {
1120
+ id,
1121
+ changes: {
1122
+ status: "failed",
1123
+ completedAt: Date.now(),
1124
+ error
1125
+ }
1126
+ });
1127
+ },
1128
+ clearDirectivesForNpc: (state, action) => {
1129
+ const npcId = action.payload;
1130
+ const idsToRemove = Object.values(state.entities).filter((item) => Boolean(item)).filter((item) => item.npcId === npcId).map((item) => item.id);
1131
+ directiveAdapter.removeMany(state, idsToRemove);
1132
+ if (idsToRemove.includes(state.activeDirectiveId)) {
1133
+ state.activeDirectiveId = "";
1134
+ }
1135
+ }
1136
+ }
1137
+ });
1138
+ var {
1139
+ directiveRunStarted,
1140
+ directiveReceived,
1141
+ contextComposed,
1142
+ verdictValidated,
1143
+ directiveRunFailed,
1144
+ clearDirectivesForNpc
1145
+ } = directiveSlice.actions;
1146
+ var {
1147
+ selectById: selectDirectiveById,
1148
+ selectAll: selectAllDirectives
1149
+ } = directiveAdapter.getSelectors((state) => state.directive);
1150
+ var selectActiveDirectiveId = (state) => state.directive.activeDirectiveId;
1151
+ var selectActiveDirective = (state) => {
1152
+ const id = selectActiveDirectiveId(state);
1153
+ return state.directive.entities[id];
1154
+ };
1155
+ var directiveSlice_default = directiveSlice.reducer;
1156
+
789
1157
  // src/listeners.ts
790
1158
  import { createListenerMiddleware } from "@reduxjs/toolkit";
791
1159
  var sdkListenerMiddleware = createListenerMiddleware();
@@ -793,8 +1161,14 @@ var startAppListening = sdkListenerMiddleware.startListening.withTypes();
793
1161
  startAppListening({
794
1162
  actionCreator: removeNPC,
795
1163
  effect: async (action, listenerApi) => {
1164
+ const removedNpcId = action.payload;
796
1165
  const state = listenerApi.getState();
797
- if (action.payload === state.npc.activeNpcId) {
1166
+ listenerApi.dispatch(clearDirectivesForNpc(removedNpcId));
1167
+ listenerApi.dispatch(clearBridgeValidation());
1168
+ listenerApi.dispatch(clearGhostSession());
1169
+ listenerApi.dispatch(clearSoulState());
1170
+ listenerApi.dispatch(clearBlock(removedNpcId));
1171
+ if (removedNpcId === state.npc.activeNpcId) {
798
1172
  listenerApi.dispatch(memoryClear());
799
1173
  }
800
1174
  }
@@ -808,6 +1182,7 @@ var createSDKStore = (extraReducers = {}) => {
808
1182
  npc: npcSlice_default,
809
1183
  cortex: cortexSlice_default,
810
1184
  memory: memorySlice_default,
1185
+ directive: directiveSlice_default,
811
1186
  ghost: ghostSlice_default,
812
1187
  soul: soulSlice_default,
813
1188
  bridge: bridgeSlice_default,
@@ -824,103 +1199,144 @@ var dispatch = store.dispatch;
824
1199
 
825
1200
  // src/thunks.ts
826
1201
  import { createAsyncThunk as createAsyncThunk5 } from "@reduxjs/toolkit";
1202
+ var extractThunkErrorMessage = (e) => {
1203
+ if (typeof e === "string") return e;
1204
+ if (e?.data?.message) return String(e.data.message);
1205
+ if (e?.error) return String(e.error);
1206
+ if (e?.message) return String(e.message);
1207
+ return "Protocol processing failed";
1208
+ };
827
1209
  var processNPC = createAsyncThunk5(
828
1210
  "npc/process",
829
- async ({ npcId: argNpcId, text, context = {}, apiUrl, apiKey, memory, cortex, persona: argPersona }, { getState, dispatch: dispatch2 }) => {
1211
+ async ({ npcId: argNpcId, text, context = {}, apiUrl, apiKey, memory, cortex, persona: argPersona }, { getState, dispatch: dispatch2, rejectWithValue }) => {
830
1212
  const stateNpcId = selectActiveNpcId(getState());
831
1213
  const activeNpc = selectActiveNPC(getState());
832
1214
  const npcId = argNpcId || stateNpcId;
833
1215
  const persona = argPersona || activeNpc?.persona;
834
1216
  const currentState = activeNpc?.state || {};
835
- if (argNpcId && argNpcId !== stateNpcId) {
836
- dispatch2(setNPCInfo({ id: argNpcId, persona: persona || "Default" }));
837
- }
838
- const directiveResult = await dispatch2(
839
- sdkApi.endpoints.postDirective.initiate({ npcId, request: { observation: text, npcState: currentState, context }, apiUrl, apiKey })
840
- ).unwrap();
841
- const recalledMemories = memory && directiveResult.memoryRecall ? await memory.recall(
842
- directiveResult.memoryRecall.query,
843
- directiveResult.memoryRecall.limit,
844
- directiveResult.memoryRecall.threshold
845
- ).then((mems) => mems.map((m) => ({ text: m.text, type: m.type, importance: m.importance }))).catch(() => []) : [];
846
- const contextResult = await dispatch2(
847
- sdkApi.endpoints.postContext.initiate({ npcId, request: { memories: recalledMemories, observation: text, npcState: currentState, persona: persona || "Default" }, apiUrl, apiKey })
848
- ).unwrap();
849
- let generatedText = "";
850
- if (cortex) {
851
- generatedText = await cortex.complete(contextResult.prompt, {
852
- maxTokens: contextResult.constraints.maxTokens,
853
- temperature: contextResult.constraints.temperature,
854
- stop: contextResult.constraints.stop
855
- });
856
- } else {
857
- const remoteResult = await dispatch2(sdkApi.endpoints.postCortexComplete.initiate({
858
- cortexId: "remote",
859
- // Or generic
860
- prompt: contextResult.prompt,
861
- options: contextResult.constraints,
862
- apiUrl,
863
- apiKey
864
- })).unwrap();
865
- generatedText = remoteResult.text || "";
866
- }
867
- const verdictResult = await dispatch2(
868
- sdkApi.endpoints.postVerdict.initiate({ npcId, request: { generatedOutput: generatedText, observation: text, npcState: currentState }, apiUrl, apiKey })
869
- ).unwrap();
870
- if (!verdictResult.valid) {
871
- dispatch2(blockAction({ id: npcId, reason: "Validation Failed" }));
872
- return { dialogue: "... [Blocked]", action: { type: "BLOCKED", reason: "Validation Failed" } };
873
- }
874
- if (memory && verdictResult.memoryStore) {
875
- for (const inst of verdictResult.memoryStore) {
876
- await memory.store(inst.text, inst.type, inst.importance).catch((e) => console.warn("Memory store failed:", e));
877
- }
1217
+ if (!npcId) {
1218
+ return rejectWithValue("No npcId provided and no active NPC selected");
878
1219
  }
879
- if (verdictResult.stateDelta) {
880
- dispatch2(updateNPCState({ id: npcId, delta: verdictResult.stateDelta }));
1220
+ if (!persona) {
1221
+ return rejectWithValue("No persona provided and no active NPC persona available");
881
1222
  }
882
- const action = verdictResult.action ? { ...verdictResult.action, signature: verdictResult.signature } : void 0;
883
- dispatch2(setLastAction({ id: npcId, action }));
884
- dispatch2(addToHistory({ id: npcId, role: "user", content: text }));
885
- dispatch2(addToHistory({ id: npcId, role: "assistant", content: verdictResult.dialogue }));
886
- return {
887
- dialogue: verdictResult.dialogue,
888
- action,
889
- thought: verdictResult.dialogue
890
- };
891
- }
892
- );
893
- var speakNPC = createAsyncThunk5(
894
- "npc/speak",
895
- async ({ npcId: argNpcId, text, context = {}, apiUrl, apiKey }, { getState, dispatch: dispatch2 }) => {
896
- const stateNpcId = selectActiveNpcId(getState());
897
- const activeNpc = selectActiveNPC(getState());
898
- const npcId = argNpcId || stateNpcId;
899
- const currentState = activeNpc?.state || {};
900
- const data = await dispatch2(sdkApi.endpoints.postSpeak.initiate({
901
- npcId,
902
- request: { speakMessage: text, speakContext: context, speakNPCState: currentState },
903
- apiUrl,
904
- apiKey
905
- })).unwrap();
906
- if (data.speakHistory) {
907
- dispatch2(setHistory({ id: npcId, history: data.speakHistory }));
1223
+ if (!cortex) {
1224
+ return rejectWithValue("No local cortex provided. SDK remote cortex fallback is disabled.");
1225
+ }
1226
+ if (argNpcId && argNpcId !== stateNpcId) {
1227
+ dispatch2(setNPCInfo({ id: argNpcId, persona }));
1228
+ }
1229
+ const directiveId = `${npcId}:${Date.now()}`;
1230
+ dispatch2(directiveRunStarted({ id: directiveId, npcId, observation: text }));
1231
+ try {
1232
+ const initialTape = {
1233
+ observation: text,
1234
+ context,
1235
+ npcState: currentState,
1236
+ persona,
1237
+ memories: [],
1238
+ vectorQueried: false
1239
+ };
1240
+ const maxTurns = 12;
1241
+ const persistMemoryInstructionsRecursively = async (instructions, index = 0) => {
1242
+ if (!memory || index >= instructions.length) {
1243
+ return;
1244
+ }
1245
+ const inst = instructions[index];
1246
+ await memory.store(inst.text, inst.type, inst.importance);
1247
+ await persistMemoryInstructionsRecursively(instructions, index + 1);
1248
+ };
1249
+ const runProtocolRecursively = async (tape, lastResult, turn) => {
1250
+ if (turn >= maxTurns) {
1251
+ return rejectWithValue(`Protocol loop exceeded max turns (${maxTurns})`);
1252
+ }
1253
+ const request = { tape, lastResult };
1254
+ const processResult = await dispatch2(
1255
+ sdkApi.endpoints.postNpcProcess.initiate({ npcId, request, apiUrl, apiKey })
1256
+ ).unwrap();
1257
+ const nextTape = processResult.tape;
1258
+ const instruction = processResult.instruction;
1259
+ if (instruction.type === "IdentifyActor") {
1260
+ return runProtocolRecursively(nextTape, {
1261
+ type: "IdentifyActorResult",
1262
+ actor: {
1263
+ npcId,
1264
+ persona,
1265
+ data: nextTape.npcState
1266
+ }
1267
+ }, turn + 1);
1268
+ }
1269
+ if (instruction.type === "QueryVector") {
1270
+ dispatch2(directiveReceived({
1271
+ id: directiveId,
1272
+ response: { memoryRecall: { query: instruction.query, limit: instruction.limit, threshold: instruction.threshold } }
1273
+ }));
1274
+ if (!memory) {
1275
+ return rejectWithValue("API requested memory recall, but no memory engine is configured");
1276
+ }
1277
+ const recalled = await memory.recall(instruction.query, instruction.limit, instruction.threshold);
1278
+ return runProtocolRecursively(nextTape, {
1279
+ type: "QueryVectorResult",
1280
+ memories: recalled.map((m) => ({ text: m.text, type: m.type, importance: m.importance, similarity: m.similarity }))
1281
+ }, turn + 1);
1282
+ }
1283
+ if (instruction.type === "ExecuteInference") {
1284
+ dispatch2(contextComposed({ id: directiveId, prompt: instruction.prompt, constraints: instruction.constraints }));
1285
+ const generatedText = await cortex.complete(instruction.prompt, {
1286
+ maxTokens: instruction.constraints.maxTokens,
1287
+ temperature: instruction.constraints.temperature,
1288
+ stop: instruction.constraints.stop
1289
+ });
1290
+ return runProtocolRecursively(nextTape, {
1291
+ type: "ExecuteInferenceResult",
1292
+ generatedOutput: generatedText
1293
+ }, turn + 1);
1294
+ }
1295
+ if (instruction.type === "Finalize") {
1296
+ const finalize = instruction;
1297
+ dispatch2(verdictValidated({
1298
+ id: directiveId,
1299
+ verdict: {
1300
+ valid: finalize.valid,
1301
+ signature: finalize.signature,
1302
+ memoryStore: finalize.memoryStore,
1303
+ stateDelta: finalize.stateTransform,
1304
+ action: finalize.action,
1305
+ dialogue: finalize.dialogue
1306
+ }
1307
+ }));
1308
+ if (!finalize.valid) {
1309
+ dispatch2(blockAction({ id: npcId, reason: finalize.dialogue || "Validation Failed" }));
1310
+ return {
1311
+ dialogue: finalize.dialogue,
1312
+ action: finalize.action,
1313
+ thought: finalize.dialogue
1314
+ };
1315
+ }
1316
+ if (finalize.memoryStore?.length && !memory) {
1317
+ return rejectWithValue("API returned memoryStore instructions, but no memory engine is configured");
1318
+ }
1319
+ await persistMemoryInstructionsRecursively(finalize.memoryStore || []);
1320
+ if (finalize.stateTransform) {
1321
+ dispatch2(updateNPCState({ id: npcId, delta: finalize.stateTransform }));
1322
+ }
1323
+ dispatch2(setLastAction({ id: npcId, action: finalize.action }));
1324
+ dispatch2(addToHistory({ id: npcId, role: "user", content: text }));
1325
+ dispatch2(addToHistory({ id: npcId, role: "assistant", content: finalize.dialogue }));
1326
+ return {
1327
+ dialogue: finalize.dialogue,
1328
+ action: finalize.action,
1329
+ thought: finalize.dialogue
1330
+ };
1331
+ }
1332
+ return rejectWithValue("API returned unknown instruction type");
1333
+ };
1334
+ return runProtocolRecursively(initialTape, void 0, 0);
1335
+ } catch (e) {
1336
+ const message = extractThunkErrorMessage(e);
1337
+ dispatch2(directiveRunFailed({ id: directiveId, error: String(message) }));
1338
+ return rejectWithValue(String(message));
908
1339
  }
909
- return data.speakReply;
910
- }
911
- );
912
- var dialogueNPC = createAsyncThunk5(
913
- "npc/dialogue",
914
- async ({ npcId: argNpcId, text, context = [], apiUrl, apiKey }, { getState, dispatch: dispatch2 }) => {
915
- const stateNpcId = selectActiveNpcId(getState());
916
- const npcId = argNpcId || stateNpcId;
917
- const data = await dispatch2(sdkApi.endpoints.postDialogue.initiate({
918
- npcId,
919
- request: { diagMessage: text, diagContext: context },
920
- apiUrl,
921
- apiKey
922
- })).unwrap();
923
- return data.diagReply;
924
1340
  }
925
1341
  );
926
1342
  var localExportSoulThunk = createAsyncThunk5(
@@ -930,20 +1346,92 @@ var localExportSoulThunk = createAsyncThunk5(
930
1346
  const npcId = id || state.activeNpcId;
931
1347
  const npc = state.entities[npcId];
932
1348
  if (!npc) throw new Error(`NPC ${npcId} not found`);
933
- const memories = memory ? await memory.export().catch(() => []) : [];
1349
+ const memories = memory ? await memory.export() : [];
934
1350
  return exportToSoul(npcId, "NPC", npc.persona, npc.state, memories);
935
1351
  }
936
1352
  );
1353
+ var checkApiStatusThunk = createAsyncThunk5(
1354
+ "system/checkApiStatus",
1355
+ async ({ apiUrl }, { dispatch: dispatch2, rejectWithValue }) => {
1356
+ try {
1357
+ return await dispatch2(sdkApi.endpoints.getApiStatus.initiate({ apiUrl })).unwrap();
1358
+ } catch (e) {
1359
+ return rejectWithValue(e?.message || "Connection failed");
1360
+ }
1361
+ }
1362
+ );
1363
+ var listMemoryRemoteThunk = createAsyncThunk5(
1364
+ "memory/listRemote",
1365
+ async ({ npcId, apiUrl, apiKey }, { dispatch: dispatch2, rejectWithValue }) => {
1366
+ try {
1367
+ const data = await dispatch2(sdkApi.endpoints.getMemoryList.initiate({ npcId, apiUrl, apiKey })).unwrap();
1368
+ return data || [];
1369
+ } catch (e) {
1370
+ return rejectWithValue(e?.message || "Failed to list memories");
1371
+ }
1372
+ }
1373
+ );
1374
+ var recallMemoryRemoteThunk = createAsyncThunk5(
1375
+ "memory/recallRemote",
1376
+ async ({ npcId, query, apiUrl, apiKey }, { dispatch: dispatch2, rejectWithValue }) => {
1377
+ try {
1378
+ const data = await dispatch2(
1379
+ sdkApi.endpoints.postMemoryRecall.initiate({
1380
+ npcId,
1381
+ request: { query },
1382
+ apiUrl,
1383
+ apiKey
1384
+ })
1385
+ ).unwrap();
1386
+ return data || [];
1387
+ } catch (e) {
1388
+ return rejectWithValue(e?.message || "Failed to recall memories");
1389
+ }
1390
+ }
1391
+ );
1392
+ var storeMemoryRemoteThunk = createAsyncThunk5(
1393
+ "memory/storeRemote",
1394
+ async ({ npcId, observation, importance = 0.8, apiUrl, apiKey }, { dispatch: dispatch2, rejectWithValue }) => {
1395
+ try {
1396
+ return await dispatch2(
1397
+ sdkApi.endpoints.postMemoryStore.initiate({
1398
+ npcId,
1399
+ request: { observation, importance },
1400
+ apiUrl,
1401
+ apiKey
1402
+ })
1403
+ ).unwrap();
1404
+ } catch (e) {
1405
+ return rejectWithValue(e?.message || "Failed to store memory");
1406
+ }
1407
+ }
1408
+ );
1409
+ var clearMemoryRemoteThunk = createAsyncThunk5(
1410
+ "memory/clearRemote",
1411
+ async ({ npcId, apiUrl, apiKey }, { dispatch: dispatch2, rejectWithValue }) => {
1412
+ try {
1413
+ return await dispatch2(
1414
+ sdkApi.endpoints.deleteMemoryClear.initiate({ npcId, apiUrl, apiKey })
1415
+ ).unwrap();
1416
+ } catch (e) {
1417
+ return rejectWithValue(e?.message || "Failed to clear memories");
1418
+ }
1419
+ }
1420
+ );
937
1421
  export {
938
1422
  SDK_VERSION,
939
1423
  addToHistory,
940
1424
  blockAction,
941
1425
  bridgeSlice,
1426
+ checkApiStatusThunk,
942
1427
  clearBlock,
943
1428
  clearBridgeValidation,
1429
+ clearDirectivesForNpc,
944
1430
  clearGhostSession,
1431
+ clearMemoryRemoteThunk,
945
1432
  clearSoulState,
946
1433
  completeRemoteThunk,
1434
+ contextComposed,
947
1435
  cortexInitFailed,
948
1436
  cortexInitStart,
949
1437
  cortexInitSuccess,
@@ -951,7 +1439,11 @@ export {
951
1439
  createInitialState,
952
1440
  createSDKStore,
953
1441
  delay,
954
- dialogueNPC,
1442
+ deleteRulesetThunk,
1443
+ directiveReceived,
1444
+ directiveRunFailed,
1445
+ directiveRunStarted,
1446
+ directiveSlice,
955
1447
  dispatch,
956
1448
  exportToSoul,
957
1449
  generateNPCId,
@@ -961,8 +1453,13 @@ export {
961
1453
  getGhostStatusThunk,
962
1454
  getSoulListThunk,
963
1455
  ghostSlice,
1456
+ importNpcFromSoulThunk,
964
1457
  importSoulFromArweaveThunk,
965
1458
  initRemoteCortexThunk,
1459
+ listCortexModelsThunk,
1460
+ listMemoryRemoteThunk,
1461
+ listRulePresetsThunk,
1462
+ listRulesetsThunk,
966
1463
  loadBridgePresetThunk,
967
1464
  localExportSoulThunk,
968
1465
  memoise,
@@ -978,13 +1475,19 @@ export {
978
1475
  npcSlice,
979
1476
  pipe,
980
1477
  processNPC,
1478
+ recallMemoryRemoteThunk,
1479
+ registerRulesetThunk,
981
1480
  remoteExportSoulThunk,
982
1481
  removeNPC,
983
1482
  sdkApi,
1483
+ selectActiveDirective,
1484
+ selectActiveDirectiveId,
984
1485
  selectActiveNPC,
985
1486
  selectActiveNpcId,
1487
+ selectAllDirectives,
986
1488
  selectAllMemories,
987
1489
  selectAllNPCs,
1490
+ selectDirectiveById,
988
1491
  selectLastRecalledMemories,
989
1492
  selectMemoryById,
990
1493
  selectNPCById,
@@ -998,15 +1501,17 @@ export {
998
1501
  setNPCInfo,
999
1502
  setNPCState,
1000
1503
  soulSlice,
1001
- speakNPC,
1002
1504
  startGhostThunk,
1003
1505
  stopGhostThunk,
1004
1506
  store,
1507
+ storeMemoryRemoteThunk,
1005
1508
  streamFromCortex,
1006
1509
  streamFromCortexWithDelay,
1007
1510
  streamToCallback,
1008
1511
  streamToString,
1009
1512
  updateNPCState,
1010
1513
  updateNPCStateLocally,
1011
- validateBridgeThunk
1514
+ validateBridgeThunk,
1515
+ verdictValidated,
1516
+ verifySoulThunk
1012
1517
  };