@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.
@@ -0,0 +1,339 @@
1
+ // src/store.ts
2
+ import { configureStore } from "@reduxjs/toolkit";
3
+
4
+ // src/apiSlice.ts
5
+ import { createApi, fetchBaseQuery } from "@reduxjs/toolkit/query";
6
+ var sdkApi = createApi({
7
+ reducerPath: "forbocApi",
8
+ baseQuery: fetchBaseQuery({
9
+ baseUrl: "/",
10
+ prepareHeaders: (headers, { getState }) => {
11
+ return headers;
12
+ }
13
+ }),
14
+ tagTypes: ["NPC", "Memory", "Cortex", "Ghost", "Soul", "Bridge"],
15
+ endpoints: (builder) => ({
16
+ // NPC Endpoints
17
+ postDirective: builder.mutation({
18
+ query: ({ npcId, request, apiUrl, apiKey }) => ({
19
+ url: `${apiUrl}/npcs/${npcId}/directive`,
20
+ method: "POST",
21
+ headers: apiKey ? { "Authorization": `Bearer ${apiKey}` } : {},
22
+ body: request
23
+ }),
24
+ invalidatesTags: ["NPC"]
25
+ }),
26
+ postContext: builder.mutation({
27
+ query: ({ npcId, request, apiUrl, apiKey }) => ({
28
+ url: `${apiUrl}/npcs/${npcId}/context`,
29
+ method: "POST",
30
+ headers: apiKey ? { "Authorization": `Bearer ${apiKey}` } : {},
31
+ body: request
32
+ })
33
+ }),
34
+ postVerdict: builder.mutation({
35
+ query: ({ npcId, request, apiUrl, apiKey }) => ({
36
+ url: `${apiUrl}/npcs/${npcId}/verdict`,
37
+ method: "POST",
38
+ headers: apiKey ? { "Authorization": `Bearer ${apiKey}` } : {},
39
+ body: request
40
+ }),
41
+ invalidatesTags: ["NPC"]
42
+ }),
43
+ postSpeak: builder.mutation({
44
+ query: ({ npcId, request, apiUrl, apiKey }) => ({
45
+ url: `${apiUrl}/npcs/${npcId}/speak`,
46
+ method: "POST",
47
+ headers: apiKey ? { "Authorization": `Bearer ${apiKey}` } : {},
48
+ body: request
49
+ }),
50
+ invalidatesTags: ["NPC"]
51
+ }),
52
+ postDialogue: builder.mutation({
53
+ query: ({ npcId, request, apiUrl, apiKey }) => ({
54
+ url: `${apiUrl}/npcs/${npcId}/dialogue`,
55
+ method: "POST",
56
+ headers: apiKey ? { "Authorization": `Bearer ${apiKey}` } : {},
57
+ body: request
58
+ })
59
+ }),
60
+ // Ghost Endpoints
61
+ postGhostRun: builder.mutation({
62
+ query: ({ request, apiUrl }) => ({ url: `${apiUrl}/ghost/run`, method: "POST", body: request }),
63
+ invalidatesTags: ["Ghost"]
64
+ }),
65
+ getGhostStatus: builder.query({
66
+ query: ({ sessionId, apiUrl }) => ({ url: `${apiUrl}/ghost/${sessionId}/status`, method: "GET" }),
67
+ providesTags: ["Ghost"]
68
+ }),
69
+ getGhostResults: builder.query({
70
+ query: ({ sessionId, apiUrl }) => ({ url: `${apiUrl}/ghost/${sessionId}/results`, method: "GET" })
71
+ }),
72
+ postGhostStop: builder.mutation({
73
+ query: ({ sessionId, apiUrl }) => ({ url: `${apiUrl}/ghost/${sessionId}/stop`, method: "POST" }),
74
+ invalidatesTags: ["Ghost"]
75
+ }),
76
+ getGhostHistory: builder.query({
77
+ query: ({ limit, apiUrl }) => ({ url: `${apiUrl}/ghost/history?limit=${limit}`, method: "GET" }),
78
+ providesTags: ["Ghost"]
79
+ }),
80
+ // Soul Endpoints
81
+ postSoulExport: builder.mutation({
82
+ query: ({ npcId, request, apiUrl }) => ({ url: `${apiUrl}/npcs/${npcId}/soul/export`, method: "POST", body: request }),
83
+ invalidatesTags: ["Soul"]
84
+ }),
85
+ getSoulImport: builder.query({
86
+ query: ({ txId, apiUrl }) => ({ url: `${apiUrl}/souls/${txId}`, method: "GET" })
87
+ }),
88
+ getSouls: builder.query({
89
+ query: ({ limit, apiUrl }) => ({ url: `${apiUrl}/souls?limit=${limit}`, method: "GET" }),
90
+ providesTags: ["Soul"]
91
+ }),
92
+ // Bridge Endpoints
93
+ postBridgeValidate: builder.mutation({
94
+ query: ({ request, npcId, apiUrl }) => ({
95
+ url: npcId ? `${apiUrl}/bridge/validate/${npcId}` : `${apiUrl}/bridge/validate`,
96
+ method: "POST",
97
+ body: request
98
+ })
99
+ }),
100
+ getBridgeRules: builder.query({
101
+ query: ({ apiUrl }) => ({ url: `${apiUrl}/rules`, method: "GET" }),
102
+ providesTags: ["Bridge"]
103
+ }),
104
+ postBridgePreset: builder.mutation({
105
+ query: ({ presetName, apiUrl }) => ({ url: `${apiUrl}/rules/presets/${presetName}`, method: "POST" }),
106
+ invalidatesTags: ["Bridge"]
107
+ }),
108
+ // Cortex Remote Endpoint
109
+ postCortexComplete: builder.mutation({
110
+ query: ({ cortexId, prompt, options, apiUrl, apiKey }) => ({
111
+ url: `${apiUrl}/cortex/${cortexId}/complete`,
112
+ method: "POST",
113
+ headers: apiKey ? { "Authorization": `Bearer ${apiKey}` } : {},
114
+ body: { prompt, ...options }
115
+ })
116
+ })
117
+ })
118
+ });
119
+
120
+ // src/npcSlice.ts
121
+ import { createSlice } from "@reduxjs/toolkit";
122
+ var initialState = {
123
+ id: "",
124
+ persona: "",
125
+ state: {},
126
+ history: [],
127
+ isBlocked: false
128
+ };
129
+ var npcSlice = createSlice({
130
+ name: "npc",
131
+ initialState,
132
+ reducers: {
133
+ setNPCInfo: (state, action) => {
134
+ state.id = action.payload.id;
135
+ state.persona = action.payload.persona;
136
+ if (action.payload.initialState) {
137
+ state.state = action.payload.initialState;
138
+ }
139
+ },
140
+ setNPCState: (state, action) => {
141
+ state.state = action.payload;
142
+ },
143
+ updateNPCState: (state, action) => {
144
+ state.state = { ...state.state, ...action.payload };
145
+ },
146
+ addToHistory: (state, action) => {
147
+ state.history.push(action.payload);
148
+ },
149
+ setHistory: (state, action) => {
150
+ state.history = action.payload;
151
+ },
152
+ setLastAction: (state, action) => {
153
+ state.lastAction = action.payload;
154
+ },
155
+ blockAction: (state, action) => {
156
+ state.isBlocked = true;
157
+ state.blockReason = action.payload;
158
+ },
159
+ clearBlock: (state) => {
160
+ state.isBlocked = false;
161
+ state.blockReason = void 0;
162
+ }
163
+ }
164
+ });
165
+ var {
166
+ setNPCInfo,
167
+ setNPCState,
168
+ updateNPCState,
169
+ addToHistory,
170
+ setHistory,
171
+ setLastAction,
172
+ blockAction,
173
+ clearBlock
174
+ } = npcSlice.actions;
175
+ var npcSlice_default = npcSlice.reducer;
176
+
177
+ // src/cortexSlice.ts
178
+ import { createSlice as createSlice2 } from "@reduxjs/toolkit";
179
+ var initialState2 = {
180
+ status: {
181
+ id: "init",
182
+ model: "none",
183
+ ready: false,
184
+ engine: "mock"
185
+ },
186
+ isInitializing: false
187
+ };
188
+ var cortexSlice = createSlice2({
189
+ name: "cortex",
190
+ initialState: initialState2,
191
+ reducers: {
192
+ cortexInitStart: (state) => {
193
+ state.isInitializing = true;
194
+ state.error = void 0;
195
+ },
196
+ cortexInitSuccess: (state, action) => {
197
+ state.status = action.payload;
198
+ state.isInitializing = false;
199
+ state.error = void 0;
200
+ },
201
+ cortexInitFailed: (state, action) => {
202
+ state.isInitializing = false;
203
+ state.error = action.payload;
204
+ },
205
+ setCortexStatus: (state, action) => {
206
+ state.status = action.payload;
207
+ }
208
+ }
209
+ });
210
+ var {
211
+ cortexInitStart,
212
+ cortexInitSuccess,
213
+ cortexInitFailed,
214
+ setCortexStatus
215
+ } = cortexSlice.actions;
216
+ var cortexSlice_default = cortexSlice.reducer;
217
+
218
+ // src/store.ts
219
+ var createSDKStore = () => {
220
+ return configureStore({
221
+ reducer: {
222
+ [sdkApi.reducerPath]: sdkApi.reducer,
223
+ npc: npcSlice_default,
224
+ cortex: cortexSlice_default
225
+ },
226
+ middleware: (getDefaultMiddleware) => getDefaultMiddleware().concat(sdkApi.middleware)
227
+ });
228
+ };
229
+ var store = createSDKStore();
230
+ var dispatch = store.dispatch;
231
+
232
+ // src/soul.ts
233
+ var createSoul = (id, name, persona, state, memories = []) => ({
234
+ id,
235
+ version: "1.0.0",
236
+ name,
237
+ persona,
238
+ state: { ...state },
239
+ memories: [...memories]
240
+ });
241
+ var serializeSoul = (soul) => JSON.stringify(soul, null, 2);
242
+ var deserializeSoul = (json) => {
243
+ const parsed = JSON.parse(json);
244
+ if (!parsed.id || !parsed.persona || !parsed.state) {
245
+ throw new Error("Invalid Soul format: missing required fields");
246
+ }
247
+ return {
248
+ id: parsed.id,
249
+ version: parsed.version || "1.0.0",
250
+ name: parsed.name || "Unknown",
251
+ persona: parsed.persona,
252
+ state: parsed.state,
253
+ memories: parsed.memories || [],
254
+ signature: parsed.signature
255
+ };
256
+ };
257
+ var exportSoul = async (npcId, _soul, config = {}) => {
258
+ const apiUrl = config.apiUrl || "https://api.forboc.ai";
259
+ try {
260
+ const data = await dispatch(sdkApi.endpoints.postSoulExport.initiate({
261
+ npcId,
262
+ request: {
263
+ agentIdRef: npcId,
264
+ persona: _soul.persona,
265
+ npcState: _soul.state
266
+ },
267
+ apiUrl
268
+ })).unwrap();
269
+ return {
270
+ txId: data.txId,
271
+ url: data.url,
272
+ soul: _soul
273
+ // Return the local soul data as context
274
+ };
275
+ } catch (e) {
276
+ throw new Error(`Soul export failed: ${e.message || "Network error"}`);
277
+ }
278
+ };
279
+ var importSoulFromArweave = async (txId, config = {}) => {
280
+ const apiUrl = config.apiUrl || "https://api.forboc.ai";
281
+ try {
282
+ const data = await dispatch(sdkApi.endpoints.getSoulImport.initiate({ txId, apiUrl })).unwrap();
283
+ return data;
284
+ } catch (e) {
285
+ throw new Error(`Import failed: ${e.message || "Network error"}`);
286
+ }
287
+ };
288
+ var getSoulList = async (limit = 50, apiUrl = "https://api.forboc.ai") => {
289
+ try {
290
+ const data = await dispatch(sdkApi.endpoints.getSouls.initiate({ limit, apiUrl })).unwrap();
291
+ return data.souls || [];
292
+ } catch {
293
+ return [];
294
+ }
295
+ };
296
+ var createSoulInstance = (id, name, persona, state, memories = []) => {
297
+ const soulData = createSoul(id, name, persona, state, memories);
298
+ return {
299
+ export: (config) => exportSoul(id, soulData, config),
300
+ toJSON: () => ({ ...soulData })
301
+ };
302
+ };
303
+ var validateSoul = (soul) => {
304
+ const errors = [
305
+ !soul.id && "Missing id",
306
+ !soul.persona && "Missing persona",
307
+ !soul.state && "Missing state"
308
+ ].filter((e) => !!e);
309
+ return { valid: errors.length === 0, errors };
310
+ };
311
+
312
+ export {
313
+ sdkApi,
314
+ npcSlice,
315
+ setNPCInfo,
316
+ setNPCState,
317
+ updateNPCState,
318
+ addToHistory,
319
+ setHistory,
320
+ setLastAction,
321
+ blockAction,
322
+ clearBlock,
323
+ cortexSlice,
324
+ cortexInitStart,
325
+ cortexInitSuccess,
326
+ cortexInitFailed,
327
+ setCortexStatus,
328
+ createSDKStore,
329
+ store,
330
+ dispatch,
331
+ createSoul,
332
+ serializeSoul,
333
+ deserializeSoul,
334
+ exportSoul,
335
+ importSoulFromArweave,
336
+ getSoulList,
337
+ createSoulInstance,
338
+ validateSoul
339
+ };
@@ -0,0 +1,86 @@
1
+ // src/soul.ts
2
+ var createSoul = (id, name, persona, state, memories = []) => ({
3
+ id,
4
+ version: "1.0.0",
5
+ name,
6
+ persona,
7
+ state: { ...state },
8
+ memories: [...memories]
9
+ });
10
+ var serializeSoul = (soul) => JSON.stringify(soul, null, 2);
11
+ var deserializeSoul = (json) => {
12
+ const parsed = JSON.parse(json);
13
+ if (!parsed.id || !parsed.persona || !parsed.state) {
14
+ throw new Error("Invalid Soul format: missing required fields");
15
+ }
16
+ return {
17
+ id: parsed.id,
18
+ version: parsed.version || "1.0.0",
19
+ name: parsed.name || "Unknown",
20
+ persona: parsed.persona,
21
+ state: parsed.state,
22
+ memories: parsed.memories || [],
23
+ signature: parsed.signature
24
+ };
25
+ };
26
+ var exportSoul = async (agentId, _soul, config = {}) => {
27
+ const apiUrl = config.apiUrl || "https://api.forboc.ai";
28
+ const response = await fetch(`${apiUrl}/agents/${agentId}/soul/export`, {
29
+ method: "POST",
30
+ headers: { "Content-Type": "application/json" },
31
+ body: JSON.stringify({
32
+ agentIdRef: agentId,
33
+ persona: _soul.persona,
34
+ agentState: _soul.state
35
+ })
36
+ });
37
+ if (!response.ok) {
38
+ throw new Error(`Soul export failed: ${response.statusText}`);
39
+ }
40
+ const data = await response.json();
41
+ return {
42
+ txId: data.txId,
43
+ url: data.url,
44
+ soul: _soul
45
+ // Return the local soul data as context
46
+ };
47
+ };
48
+ var importSoulFromArweave = async (txId, config = {}) => {
49
+ const apiUrl = config.apiUrl || "https://api.forboc.ai";
50
+ const response = await fetch(`${apiUrl}/souls/${txId}`);
51
+ if (!response.ok) throw new Error(`Import failed: ${response.statusText}`);
52
+ const data = await response.json();
53
+ return data;
54
+ };
55
+ var getSoulList = async (limit = 50, apiUrl = "https://api.forboc.ai") => {
56
+ const response = await fetch(`${apiUrl}/souls?limit=${limit}`);
57
+ if (!response.ok) return [];
58
+ const data = await response.json();
59
+ return data.souls || [];
60
+ };
61
+ var createSoulInstance = (id, name, persona, state, memories = []) => {
62
+ const soulData = createSoul(id, name, persona, state, memories);
63
+ return {
64
+ export: (config) => exportSoul(id, soulData, config),
65
+ toJSON: () => ({ ...soulData })
66
+ };
67
+ };
68
+ var validateSoul = (soul) => {
69
+ const errors = [
70
+ !soul.id && "Missing id",
71
+ !soul.persona && "Missing persona",
72
+ !soul.state && "Missing state"
73
+ ].filter((e) => !!e);
74
+ return { valid: errors.length === 0, errors };
75
+ };
76
+
77
+ export {
78
+ createSoul,
79
+ serializeSoul,
80
+ deserializeSoul,
81
+ exportSoul,
82
+ importSoulFromArweave,
83
+ getSoulList,
84
+ createSoulInstance,
85
+ validateSoul
86
+ };