@forbocai/core 0.6.3 → 0.6.4

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
@@ -18,341 +18,443 @@ import { createSlice, createAsyncThunk } from "@reduxjs/toolkit";
18
18
 
19
19
  // src/apiSlice.ts
20
20
  import { createApi, fetchBaseQuery } from "@reduxjs/toolkit/query";
21
- var sdkApi = createApi({
22
- reducerPath: "forbocApi",
23
- baseQuery: fetchBaseQuery({
24
- baseUrl: "/",
25
- prepareHeaders: (headers, { getState }) => {
26
- return headers;
27
- }
21
+
22
+ // src/api/endpoints/arweave.ts
23
+ var buildArweaveEndpoints = (builder) => ({
24
+ postArweaveUpload: builder.mutation({
25
+ queryFn: async (instruction) => {
26
+ const maxRetries = instruction.maxRetries ?? 3;
27
+ const headers = {
28
+ "Content-Type": instruction.auiContentType || "application/json"
29
+ };
30
+ const walletToken = typeof globalThis !== "undefined" ? globalThis.process?.env?.ARWEAVE_WALLET_JWK ?? null : null;
31
+ const authToken = instruction.auiAuthHeader ?? (walletToken ? `Bearer ${walletToken}` : null);
32
+ if (authToken) headers.Authorization = authToken;
33
+ const attempt = async (n) => {
34
+ try {
35
+ const controller = new AbortController();
36
+ const timeout = setTimeout(() => controller.abort(), 6e4);
37
+ const response = await fetch(instruction.auiEndpoint, {
38
+ method: "POST",
39
+ headers,
40
+ body: JSON.stringify(instruction.auiPayload),
41
+ signal: controller.signal
42
+ });
43
+ clearTimeout(timeout);
44
+ const responseBody = await response.json().catch(() => null);
45
+ const txId = responseBody?.id ?? `ar_tx_sdk_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;
46
+ const success = response.status >= 200 && response.status < 300;
47
+ return !success && n + 1 < maxRetries ? new Promise((resolve) => setTimeout(() => resolve(attempt(n + 1)), 250 * 2 ** n)) : {
48
+ data: {
49
+ aurTxId: txId,
50
+ aurStatus: response.status,
51
+ aurSuccess: success,
52
+ aurError: success ? null : `upload_failed_status_${response.status}`
53
+ }
54
+ };
55
+ } catch (error) {
56
+ const message = error instanceof Error ? error.message : String(error);
57
+ return n + 1 < maxRetries ? new Promise((resolve) => setTimeout(() => resolve(attempt(n + 1)), 250 * 2 ** n)) : {
58
+ data: {
59
+ aurTxId: `ar_tx_failed_${Date.now()}`,
60
+ aurStatus: 0,
61
+ aurSuccess: false,
62
+ aurError: `upload_request_failed:${message}`
63
+ }
64
+ };
65
+ }
66
+ };
67
+ return attempt(0);
68
+ },
69
+ invalidatesTags: ["Soul"]
28
70
  }),
29
- tagTypes: ["NPC", "Memory", "Cortex", "Ghost", "Soul", "Bridge", "Rule"],
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 || []
71
+ postArweaveDownload: builder.mutation({
72
+ queryFn: async (instruction) => {
73
+ try {
74
+ const controller = new AbortController();
75
+ const timeout = setTimeout(() => controller.abort(), 6e4);
76
+ const response = await fetch(instruction.adiGatewayUrl, { method: "GET", signal: controller.signal });
77
+ clearTimeout(timeout);
78
+ return response.status < 200 || response.status >= 300 ? { data: { adrBody: null, adrStatus: response.status, adrSuccess: false, adrError: `download_failed_status_${response.status}` } } : response.json().then((body) => ({ data: { adrBody: body, adrStatus: response.status, adrSuccess: true, adrError: null } })).catch(() => ({ data: { adrBody: null, adrStatus: response.status, adrSuccess: false, adrError: "download_invalid_json" } }));
79
+ } catch (error) {
80
+ return {
81
+ data: {
82
+ adrBody: null,
83
+ adrStatus: 0,
84
+ adrSuccess: false,
85
+ adrError: error instanceof Error ? error.message : String(error)
86
+ }
87
+ };
88
+ }
89
+ },
90
+ invalidatesTags: ["Soul"]
91
+ })
92
+ });
93
+
94
+ // src/api/endpoints/builder.ts
95
+ var authHeaders = (apiKey) => apiKey ? { Authorization: `Bearer ${apiKey}` } : {};
96
+
97
+ // src/api/endpoints/cortex.ts
98
+ var buildCortexEndpoints = (builder) => ({
99
+ getCortexModels: builder.query({
100
+ query: ({ apiUrl, apiKey }) => ({
101
+ url: `${apiUrl}/cortex/models`,
102
+ method: "GET",
103
+ headers: authHeaders(apiKey)
40
104
  }),
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
105
+ providesTags: ["Cortex"],
106
+ transformResponse: (response) => response || []
107
+ }),
108
+ postCortexInit: builder.mutation({
109
+ query: ({ request, apiUrl, apiKey }) => ({
110
+ url: `${apiUrl}/cortex/init`,
111
+ method: "POST",
112
+ headers: authHeaders(apiKey),
113
+ body: request
50
114
  }),
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
115
+ invalidatesTags: ["Cortex"],
116
+ transformResponse: (response) => response
117
+ }),
118
+ postCortexComplete: builder.mutation({
119
+ query: ({ cortexId, prompt, options, apiUrl, apiKey }) => ({
120
+ url: `${apiUrl}/cortex/${cortexId}/complete`,
121
+ method: "POST",
122
+ headers: authHeaders(apiKey),
123
+ body: { prompt, ...options }
66
124
  }),
67
- postDirective: builder.mutation({
68
- query: ({ npcId, request, apiUrl, apiKey }) => ({
69
- url: `${apiUrl}/npcs/${npcId}/directive`,
70
- method: "POST",
71
- headers: apiKey ? { "Authorization": `Bearer ${apiKey}` } : {},
72
- body: request
73
- }),
74
- invalidatesTags: ["NPC"],
75
- transformResponse: (response) => response
125
+ invalidatesTags: ["Cortex"],
126
+ transformResponse: (response) => response
127
+ })
128
+ });
129
+
130
+ // src/api/endpoints/ghost.ts
131
+ var ghostTag = (sessionId) => [{ type: "Ghost", id: sessionId }];
132
+ var buildGhostEndpoints = (builder) => ({
133
+ postGhostRun: builder.mutation({
134
+ query: ({ request, apiUrl, apiKey }) => ({
135
+ url: `${apiUrl}/ghost/run`,
136
+ method: "POST",
137
+ headers: authHeaders(apiKey),
138
+ body: request
76
139
  }),
77
- postContext: builder.mutation({
78
- query: ({ npcId, request, apiUrl, apiKey }) => ({
79
- url: `${apiUrl}/npcs/${npcId}/context`,
80
- method: "POST",
81
- headers: apiKey ? { "Authorization": `Bearer ${apiKey}` } : {},
82
- body: request
83
- }),
84
- invalidatesTags: (result, error, { npcId }) => [{ type: "NPC", id: npcId }],
85
- transformResponse: (response) => response
140
+ invalidatesTags: ["Ghost"],
141
+ transformResponse: (response) => response
142
+ }),
143
+ getGhostStatus: builder.query({
144
+ query: ({ sessionId, apiUrl, apiKey }) => ({
145
+ url: `${apiUrl}/ghost/${sessionId}/status`,
146
+ method: "GET",
147
+ headers: authHeaders(apiKey)
86
148
  }),
87
- postVerdict: builder.mutation({
88
- query: ({ npcId, request, apiUrl, apiKey }) => ({
89
- url: `${apiUrl}/npcs/${npcId}/verdict`,
90
- method: "POST",
91
- headers: apiKey ? { "Authorization": `Bearer ${apiKey}` } : {},
92
- body: request
93
- }),
94
- invalidatesTags: (result, error, { npcId }) => [{ type: "NPC", id: npcId }],
95
- transformResponse: (response) => {
96
- const action = response.action ? {
97
- type: response.action.gaType || response.action.type,
98
- reason: response.action.actionReason || response.action.reason,
99
- target: response.action.actionTarget || response.action.target,
100
- signature: response.action.signature
101
- } : void 0;
102
- return {
103
- ...response,
104
- action
105
- };
106
- }
149
+ providesTags: (_result, _error, { sessionId }) => ghostTag(sessionId),
150
+ transformResponse: (response) => response
151
+ }),
152
+ getGhostResults: builder.query({
153
+ query: ({ sessionId, apiUrl, apiKey }) => ({
154
+ url: `${apiUrl}/ghost/${sessionId}/results`,
155
+ method: "GET",
156
+ headers: authHeaders(apiKey)
107
157
  }),
108
- postMemoryStore: builder.mutation({
109
- query: ({ npcId, request, apiUrl, apiKey }) => ({
110
- url: `${apiUrl}/npcs/${npcId}/memory`,
111
- method: "POST",
112
- headers: apiKey ? { "Authorization": `Bearer ${apiKey}` } : {},
113
- body: request
114
- }),
115
- invalidatesTags: (result, error, { npcId }) => [{ type: "Memory", id: npcId }],
116
- transformResponse: (response) => response
158
+ providesTags: (_result, _error, { sessionId }) => ghostTag(sessionId),
159
+ transformResponse: (response) => response
160
+ }),
161
+ postGhostStop: builder.mutation({
162
+ query: ({ sessionId, apiUrl, apiKey }) => ({
163
+ url: `${apiUrl}/ghost/${sessionId}/stop`,
164
+ method: "POST",
165
+ headers: authHeaders(apiKey)
117
166
  }),
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 || []
167
+ invalidatesTags: (_result, _error, { sessionId }) => ghostTag(sessionId),
168
+ transformResponse: (response) => ({
169
+ stopped: response?.stopStatus === "stopped",
170
+ stopStatus: response?.stopStatus,
171
+ stopSessionId: response?.stopSessionId
172
+ })
173
+ }),
174
+ getGhostHistory: builder.query({
175
+ query: ({ limit, apiUrl, apiKey }) => ({
176
+ url: `${apiUrl}/ghost/history?limit=${limit}`,
177
+ method: "GET",
178
+ headers: authHeaders(apiKey)
126
179
  }),
127
- postMemoryRecall: builder.mutation({
128
- query: ({ npcId, request, apiUrl, apiKey }) => ({
129
- url: `${apiUrl}/npcs/${npcId}/memory/recall`,
130
- method: "POST",
131
- headers: apiKey ? { "Authorization": `Bearer ${apiKey}` } : {},
132
- body: request
133
- }),
134
- invalidatesTags: (result, error, { npcId }) => [{ type: "Memory", id: npcId }],
135
- transformResponse: (response) => response || []
180
+ providesTags: ["Ghost"],
181
+ transformResponse: (response) => response
182
+ })
183
+ });
184
+
185
+ // src/api/endpoints/npc.ts
186
+ var memoryTag = (npcId) => [{ type: "Memory", id: npcId }];
187
+ var npcTag = (npcId) => [{ type: "NPC", id: npcId }];
188
+ var buildNpcEndpoints = (builder) => ({
189
+ postNpcProcess: builder.mutation({
190
+ query: ({ npcId, request, apiUrl, apiKey }) => ({
191
+ url: `${apiUrl}/npcs/${npcId}/process`,
192
+ method: "POST",
193
+ headers: authHeaders(apiKey),
194
+ body: request
136
195
  }),
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 }],
144
- transformResponse: (response) => response
196
+ invalidatesTags: (_result, _error, { npcId }) => npcTag(npcId),
197
+ transformResponse: (response) => response
198
+ }),
199
+ postDirective: builder.mutation({
200
+ query: ({ npcId, request, apiUrl, apiKey }) => ({
201
+ url: `${apiUrl}/npcs/${npcId}/directive`,
202
+ method: "POST",
203
+ headers: authHeaders(apiKey),
204
+ body: request
145
205
  }),
146
- // Ghost Endpoints
147
- postGhostRun: builder.mutation({
148
- query: ({ request, apiUrl, apiKey }) => ({
149
- url: `${apiUrl}/ghost/run`,
150
- method: "POST",
151
- headers: apiKey ? { "Authorization": `Bearer ${apiKey}` } : {},
152
- body: request
153
- }),
154
- invalidatesTags: ["Ghost"],
155
- transformResponse: (response) => response
206
+ invalidatesTags: ["NPC"],
207
+ transformResponse: (response) => response
208
+ }),
209
+ postContext: builder.mutation({
210
+ query: ({ npcId, request, apiUrl, apiKey }) => ({
211
+ url: `${apiUrl}/npcs/${npcId}/context`,
212
+ method: "POST",
213
+ headers: authHeaders(apiKey),
214
+ body: request
156
215
  }),
157
- getGhostStatus: builder.query({
158
- query: ({ sessionId, apiUrl, apiKey }) => ({
159
- url: `${apiUrl}/ghost/${sessionId}/status`,
160
- method: "GET",
161
- headers: apiKey ? { "Authorization": `Bearer ${apiKey}` } : {}
162
- }),
163
- providesTags: (result, error, { sessionId }) => [{ type: "Ghost", id: sessionId }],
164
- transformResponse: (response) => response
216
+ invalidatesTags: (_result, _error, { npcId }) => npcTag(npcId),
217
+ transformResponse: (response) => response
218
+ }),
219
+ postVerdict: builder.mutation({
220
+ query: ({ npcId, request, apiUrl, apiKey }) => ({
221
+ url: `${apiUrl}/npcs/${npcId}/verdict`,
222
+ method: "POST",
223
+ headers: authHeaders(apiKey),
224
+ body: request
165
225
  }),
166
- getGhostResults: builder.query({
167
- query: ({ sessionId, apiUrl, apiKey }) => ({
168
- url: `${apiUrl}/ghost/${sessionId}/results`,
169
- method: "GET",
170
- headers: apiKey ? { "Authorization": `Bearer ${apiKey}` } : {}
171
- }),
172
- providesTags: (result, error, { sessionId }) => [{ type: "Ghost", id: sessionId }],
173
- transformResponse: (response) => response
226
+ invalidatesTags: (_result, _error, { npcId }) => npcTag(npcId),
227
+ transformResponse: (response) => {
228
+ const action = response.action ? {
229
+ type: response.action.gaType || response.action.type,
230
+ reason: response.action.actionReason || response.action.reason,
231
+ target: response.action.actionTarget || response.action.target,
232
+ signature: response.action.signature
233
+ } : void 0;
234
+ return {
235
+ ...response,
236
+ action
237
+ };
238
+ }
239
+ }),
240
+ postMemoryStore: builder.mutation({
241
+ query: ({ npcId, request, apiUrl, apiKey }) => ({
242
+ url: `${apiUrl}/npcs/${npcId}/memory`,
243
+ method: "POST",
244
+ headers: authHeaders(apiKey),
245
+ body: request
174
246
  }),
175
- postGhostStop: builder.mutation({
176
- query: ({ sessionId, apiUrl, apiKey }) => ({
177
- url: `${apiUrl}/ghost/${sessionId}/stop`,
178
- method: "POST",
179
- headers: apiKey ? { "Authorization": `Bearer ${apiKey}` } : {}
180
- }),
181
- invalidatesTags: (result, error, { sessionId }) => [{ type: "Ghost", id: sessionId }],
182
- transformResponse: (response) => ({
183
- stopped: response?.stopStatus === "stopped",
184
- stopStatus: response?.stopStatus,
185
- stopSessionId: response?.stopSessionId
186
- })
247
+ invalidatesTags: (_result, _error, { npcId }) => memoryTag(npcId),
248
+ transformResponse: (response) => response
249
+ }),
250
+ getMemoryList: builder.query({
251
+ query: ({ npcId, apiUrl, apiKey }) => ({
252
+ url: `${apiUrl}/npcs/${npcId}/memory`,
253
+ method: "GET",
254
+ headers: authHeaders(apiKey)
187
255
  }),
188
- getGhostHistory: builder.query({
189
- query: ({ limit, apiUrl, apiKey }) => ({
190
- url: `${apiUrl}/ghost/history?limit=${limit}`,
191
- method: "GET",
192
- headers: apiKey ? { "Authorization": `Bearer ${apiKey}` } : {}
193
- }),
194
- providesTags: ["Ghost"],
195
- transformResponse: (response) => response
256
+ providesTags: (_result, _error, { npcId }) => memoryTag(npcId),
257
+ transformResponse: (response) => response || []
258
+ }),
259
+ postMemoryRecall: builder.mutation({
260
+ query: ({ npcId, request, apiUrl, apiKey }) => ({
261
+ url: `${apiUrl}/npcs/${npcId}/memory/recall`,
262
+ method: "POST",
263
+ headers: authHeaders(apiKey),
264
+ body: request
196
265
  }),
197
- // Soul Endpoints
198
- postSoulExport: builder.mutation({
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
- }),
205
- invalidatesTags: ["Soul"],
206
- transformResponse: (response) => response
266
+ invalidatesTags: (_result, _error, { npcId }) => memoryTag(npcId),
267
+ transformResponse: (response) => response || []
268
+ }),
269
+ deleteMemoryClear: builder.mutation({
270
+ query: ({ npcId, apiUrl, apiKey }) => ({
271
+ url: `${apiUrl}/npcs/${npcId}/memory/clear`,
272
+ method: "DELETE",
273
+ headers: authHeaders(apiKey)
207
274
  }),
208
- postSoulExportConfirm: builder.mutation({
209
- query: ({ npcId, request, apiUrl, apiKey }) => ({
210
- url: `${apiUrl}/npcs/${npcId}/soul/confirm`,
211
- method: "POST",
212
- headers: apiKey ? { "Authorization": `Bearer ${apiKey}` } : {},
213
- body: request
214
- }),
215
- invalidatesTags: ["Soul"],
216
- transformResponse: (response) => response
275
+ invalidatesTags: (_result, _error, { npcId }) => memoryTag(npcId),
276
+ transformResponse: (response) => response
277
+ })
278
+ });
279
+
280
+ // src/api/endpoints/rules.ts
281
+ var buildBridgeAndRuleEndpoints = (builder) => ({
282
+ postBridgeValidate: builder.mutation({
283
+ query: ({ request, npcId, apiUrl, apiKey }) => ({
284
+ url: npcId ? `${apiUrl}/bridge/validate/${npcId}` : `${apiUrl}/bridge/validate`,
285
+ method: "POST",
286
+ headers: authHeaders(apiKey),
287
+ body: request
217
288
  }),
218
- getSoulImport: builder.query({
219
- query: ({ txId, apiUrl, apiKey }) => ({
220
- url: `${apiUrl}/souls/${txId}`,
221
- method: "GET",
222
- headers: apiKey ? { "Authorization": `Bearer ${apiKey}` } : {}
223
- }),
224
- providesTags: (result, error, { txId }) => [{ type: "Soul", id: txId }],
225
- transformResponse: (response) => response
289
+ invalidatesTags: ["Bridge"],
290
+ transformResponse: (response) => response.brResult || response
291
+ }),
292
+ getBridgeRules: builder.query({
293
+ query: ({ apiUrl, apiKey }) => ({
294
+ url: `${apiUrl}/bridge/rules`,
295
+ method: "GET",
296
+ headers: authHeaders(apiKey)
226
297
  }),
227
- getSouls: builder.query({
228
- query: ({ limit, apiUrl, apiKey }) => ({
229
- url: `${apiUrl}/souls?limit=${limit}`,
230
- method: "GET",
231
- headers: apiKey ? { "Authorization": `Bearer ${apiKey}` } : {}
232
- }),
233
- providesTags: ["Soul"],
234
- transformResponse: (response) => response
298
+ providesTags: ["Bridge"],
299
+ transformResponse: (response) => response
300
+ }),
301
+ postBridgePreset: builder.mutation({
302
+ query: ({ presetName, apiUrl, apiKey }) => ({
303
+ url: `${apiUrl}/rules/presets/${presetName}`,
304
+ method: "POST",
305
+ headers: authHeaders(apiKey)
235
306
  }),
236
- // Bridge Endpoints
237
- postBridgeValidate: builder.mutation({
238
- query: ({ request, npcId, apiUrl, apiKey }) => ({
239
- url: npcId ? `${apiUrl}/bridge/validate/${npcId}` : `${apiUrl}/bridge/validate`,
240
- method: "POST",
241
- headers: apiKey ? { "Authorization": `Bearer ${apiKey}` } : {},
242
- body: request
243
- }),
244
- invalidatesTags: ["Bridge"],
245
- transformResponse: (response) => response.brResult || response
307
+ invalidatesTags: ["Bridge"],
308
+ transformResponse: (response) => response
309
+ }),
310
+ getRulesets: builder.query({
311
+ query: ({ apiUrl, apiKey }) => ({
312
+ url: `${apiUrl}/rules`,
313
+ method: "GET",
314
+ headers: authHeaders(apiKey)
246
315
  }),
247
- getBridgeRules: builder.query({
248
- query: ({ apiUrl, apiKey }) => ({
249
- url: `${apiUrl}/bridge/rules`,
250
- method: "GET",
251
- headers: apiKey ? { "Authorization": `Bearer ${apiKey}` } : {}
252
- }),
253
- providesTags: ["Bridge"],
254
- transformResponse: (response) => response
316
+ providesTags: ["Rule"],
317
+ transformResponse: (response) => response || []
318
+ }),
319
+ getRulePresets: builder.query({
320
+ query: ({ apiUrl, apiKey }) => ({
321
+ url: `${apiUrl}/rules/presets`,
322
+ method: "GET",
323
+ headers: authHeaders(apiKey)
255
324
  }),
256
- postBridgePreset: builder.mutation({
257
- query: ({ presetName, apiUrl, apiKey }) => ({
258
- url: `${apiUrl}/rules/presets/${presetName}`,
259
- method: "POST",
260
- headers: apiKey ? { "Authorization": `Bearer ${apiKey}` } : {}
261
- }),
262
- invalidatesTags: ["Bridge"],
263
- transformResponse: (response) => response
325
+ providesTags: ["Rule"],
326
+ transformResponse: (response) => response || []
327
+ }),
328
+ postRuleRegister: builder.mutation({
329
+ query: ({ request, apiUrl, apiKey }) => ({
330
+ url: `${apiUrl}/rules`,
331
+ method: "POST",
332
+ headers: authHeaders(apiKey),
333
+ body: request
264
334
  }),
265
- // Rules Endpoints
266
- getRulesets: builder.query({
267
- query: ({ apiUrl, apiKey }) => ({
268
- url: `${apiUrl}/rules`,
269
- method: "GET",
270
- headers: apiKey ? { "Authorization": `Bearer ${apiKey}` } : {}
271
- }),
272
- providesTags: ["Rule"],
273
- transformResponse: (response) => response || []
335
+ invalidatesTags: ["Rule"],
336
+ transformResponse: (response) => response
337
+ }),
338
+ deleteRule: builder.mutation({
339
+ query: ({ rulesetId, apiUrl, apiKey }) => ({
340
+ url: `${apiUrl}/rules/${rulesetId}`,
341
+ method: "DELETE",
342
+ headers: authHeaders(apiKey)
274
343
  }),
275
- getRulePresets: builder.query({
276
- query: ({ apiUrl, apiKey }) => ({
277
- url: `${apiUrl}/rules/presets`,
278
- method: "GET",
279
- headers: apiKey ? { "Authorization": `Bearer ${apiKey}` } : {}
280
- }),
281
- providesTags: ["Rule"],
282
- transformResponse: (response) => response || []
344
+ invalidatesTags: ["Rule"],
345
+ transformResponse: (_response) => ({ deleted: true })
346
+ })
347
+ });
348
+
349
+ // src/api/endpoints/soul.ts
350
+ var soulTag = (id) => [{ type: "Soul", id }];
351
+ var buildSoulEndpoints = (builder) => ({
352
+ postSoulExport: builder.mutation({
353
+ query: ({ npcId, request, apiUrl, apiKey }) => ({
354
+ url: `${apiUrl}/npcs/${npcId}/soul/export`,
355
+ method: "POST",
356
+ headers: authHeaders(apiKey),
357
+ body: request
283
358
  }),
284
- postRuleRegister: builder.mutation({
285
- query: ({ request, apiUrl, apiKey }) => ({
286
- url: `${apiUrl}/rules`,
287
- method: "POST",
288
- headers: apiKey ? { "Authorization": `Bearer ${apiKey}` } : {},
289
- body: request
290
- }),
291
- invalidatesTags: ["Rule"],
292
- transformResponse: (response) => response
359
+ invalidatesTags: ["Soul"],
360
+ transformResponse: (response) => response
361
+ }),
362
+ postSoulExportConfirm: builder.mutation({
363
+ query: ({ npcId, request, apiUrl, apiKey }) => ({
364
+ url: `${apiUrl}/npcs/${npcId}/soul/confirm`,
365
+ method: "POST",
366
+ headers: authHeaders(apiKey),
367
+ body: request
293
368
  }),
294
- deleteRule: builder.mutation({
295
- query: ({ rulesetId, apiUrl, apiKey }) => ({
296
- url: `${apiUrl}/rules/${rulesetId}`,
297
- method: "DELETE",
298
- headers: apiKey ? { "Authorization": `Bearer ${apiKey}` } : {}
299
- }),
300
- invalidatesTags: ["Rule"],
301
- transformResponse: (_response) => ({ deleted: true })
369
+ invalidatesTags: ["Soul"],
370
+ transformResponse: (response) => response
371
+ }),
372
+ getSoulImport: builder.query({
373
+ query: ({ txId, apiUrl, apiKey }) => ({
374
+ url: `${apiUrl}/souls/${txId}`,
375
+ method: "GET",
376
+ headers: authHeaders(apiKey)
302
377
  }),
303
- // Additional Soul/NPC Endpoints
304
- postSoulVerify: builder.mutation({
305
- query: ({ txId, apiUrl, apiKey }) => ({
306
- url: `${apiUrl}/souls/${txId}/verify`,
307
- method: "POST",
308
- headers: apiKey ? { "Authorization": `Bearer ${apiKey}` } : {}
309
- }),
310
- invalidatesTags: ["Soul"],
311
- transformResponse: (response) => ({
312
- valid: response.verifyValid ?? response.valid ?? false,
313
- reason: response.verifyReason ?? response.reason
314
- })
378
+ providesTags: (_result, _error, { txId }) => soulTag(txId),
379
+ transformResponse: (response) => response
380
+ }),
381
+ getSouls: builder.query({
382
+ query: ({ limit, apiUrl, apiKey }) => ({
383
+ url: `${apiUrl}/souls?limit=${limit}`,
384
+ method: "GET",
385
+ headers: authHeaders(apiKey)
315
386
  }),
316
- postNpcImport: builder.mutation({
317
- query: ({ request, apiUrl, apiKey }) => ({
318
- url: `${apiUrl}/npcs/import`,
319
- method: "POST",
320
- headers: apiKey ? { "Authorization": `Bearer ${apiKey}` } : {},
321
- body: request
322
- }),
323
- invalidatesTags: ["NPC"],
324
- transformResponse: (response) => response
387
+ providesTags: ["Soul"],
388
+ transformResponse: (response) => response
389
+ }),
390
+ postSoulVerify: builder.mutation({
391
+ query: ({ txId, apiUrl, apiKey }) => ({
392
+ url: `${apiUrl}/souls/${txId}/verify`,
393
+ method: "POST",
394
+ headers: authHeaders(apiKey)
325
395
  }),
326
- postNpcImportConfirm: builder.mutation({
327
- query: ({ request, apiUrl, apiKey }) => ({
328
- url: `${apiUrl}/npcs/import/confirm`,
329
- method: "POST",
330
- headers: apiKey ? { "Authorization": `Bearer ${apiKey}` } : {},
331
- body: request
332
- }),
333
- invalidatesTags: ["NPC"],
334
- transformResponse: (response) => response
396
+ invalidatesTags: ["Soul"],
397
+ transformResponse: (response) => ({
398
+ valid: response.verifyValid ?? response.valid ?? false,
399
+ reason: response.verifyReason ?? response.reason
400
+ })
401
+ }),
402
+ postNpcImport: builder.mutation({
403
+ query: ({ request, apiUrl, apiKey }) => ({
404
+ url: `${apiUrl}/npcs/import`,
405
+ method: "POST",
406
+ headers: authHeaders(apiKey),
407
+ body: request
335
408
  }),
336
- // Cortex Remote Endpoint
337
- postCortexComplete: builder.mutation({
338
- query: ({ cortexId, prompt, options, apiUrl, apiKey }) => ({
339
- url: `${apiUrl}/cortex/${cortexId}/complete`,
340
- method: "POST",
341
- headers: apiKey ? { "Authorization": `Bearer ${apiKey}` } : {},
342
- body: { prompt, ...options }
343
- }),
344
- invalidatesTags: ["Cortex"],
345
- transformResponse: (response) => response
409
+ invalidatesTags: ["NPC"],
410
+ transformResponse: (response) => response
411
+ }),
412
+ postNpcImportConfirm: builder.mutation({
413
+ query: ({ request, apiUrl, apiKey }) => ({
414
+ url: `${apiUrl}/npcs/import/confirm`,
415
+ method: "POST",
416
+ headers: authHeaders(apiKey),
417
+ body: request
346
418
  }),
347
- // System Endpoints
348
- getApiStatus: builder.query({
349
- query: ({ apiUrl }) => ({ url: `${apiUrl}/status`, method: "GET" }),
350
- transformResponse: (response) => response
351
- })
419
+ invalidatesTags: ["NPC"],
420
+ transformResponse: (response) => response
421
+ })
422
+ });
423
+
424
+ // src/api/endpoints/system.ts
425
+ var buildSystemEndpoints = (builder) => ({
426
+ getApiStatus: builder.query({
427
+ query: ({ apiUrl }) => ({ url: `${apiUrl}/status`, method: "GET" }),
428
+ providesTags: ["NPC"],
429
+ transformResponse: (response) => response
430
+ })
431
+ });
432
+
433
+ // src/apiSlice.ts
434
+ var api = createApi({
435
+ reducerPath: "api",
436
+ baseQuery: fetchBaseQuery({
437
+ baseUrl: "/",
438
+ prepareHeaders: (headers, { getState }) => {
439
+ return headers;
440
+ }
441
+ }),
442
+ tagTypes: ["NPC", "Memory", "Cortex", "Ghost", "Soul", "Bridge", "Rule"],
443
+ endpoints: (builder) => ({
444
+ ...buildCortexEndpoints(builder),
445
+ ...buildNpcEndpoints(builder),
446
+ ...buildGhostEndpoints(builder),
447
+ ...buildSoulEndpoints(builder),
448
+ ...buildBridgeAndRuleEndpoints(builder),
449
+ ...buildArweaveEndpoints(builder),
450
+ ...buildSystemEndpoints(builder)
352
451
  })
353
452
  });
354
453
 
355
454
  // src/errors.ts
455
+ var DEFAULT_API_URL = "http://localhost:8080";
456
+ var PRODUCTION_API_URL = "https://api.forboc.ai";
457
+ var resolveApiUrl = (apiUrl) => apiUrl || DEFAULT_API_URL;
356
458
  var extractThunkErrorMessage = (error, fallback) => {
357
459
  if (typeof error === "string") return error;
358
460
  if (error && typeof error === "object") {
@@ -384,9 +486,9 @@ var validateBridgeThunk = createAsyncThunk(
384
486
  "bridge/validate",
385
487
  async ({ action, context, npcId, apiUrl, apiKey }, { dispatch: dispatch2, rejectWithValue }) => {
386
488
  try {
387
- const url = apiUrl || "https://api.forboc.ai";
489
+ const url = resolveApiUrl(apiUrl);
388
490
  requireApiKeyGuidance(url, apiKey);
389
- const data = await dispatch2(sdkApi.endpoints.postBridgeValidate.initiate({
491
+ const data = await dispatch2(api.endpoints.postBridgeValidate.initiate({
390
492
  request: { action, context },
391
493
  npcId,
392
494
  apiUrl: url,
@@ -402,9 +504,9 @@ var loadBridgePresetThunk = createAsyncThunk(
402
504
  "bridge/loadPreset",
403
505
  async ({ presetName, apiUrl, apiKey }, { dispatch: dispatch2, rejectWithValue }) => {
404
506
  try {
405
- const url = apiUrl || "https://api.forboc.ai";
507
+ const url = resolveApiUrl(apiUrl);
406
508
  requireApiKeyGuidance(url, apiKey);
407
- return await dispatch2(sdkApi.endpoints.postBridgePreset.initiate({ presetName, apiUrl: url, apiKey })).unwrap();
509
+ return await dispatch2(api.endpoints.postBridgePreset.initiate({ presetName, apiUrl: url, apiKey })).unwrap();
408
510
  } catch (error) {
409
511
  return rejectWithValue(extractThunkErrorMessage(error, "Failed to load preset"));
410
512
  }
@@ -414,9 +516,9 @@ var getBridgeRulesThunk = createAsyncThunk(
414
516
  "bridge/rules",
415
517
  async ({ apiUrl, apiKey }, { dispatch: dispatch2, rejectWithValue }) => {
416
518
  try {
417
- const url = apiUrl || "https://api.forboc.ai";
519
+ const url = resolveApiUrl(apiUrl);
418
520
  requireApiKeyGuidance(url, apiKey);
419
- return await dispatch2(sdkApi.endpoints.getBridgeRules.initiate({ apiUrl: url, apiKey })).unwrap();
521
+ return await dispatch2(api.endpoints.getBridgeRules.initiate({ apiUrl: url, apiKey })).unwrap();
420
522
  } catch (error) {
421
523
  return rejectWithValue(extractThunkErrorMessage(error, "Failed to list bridge rules"));
422
524
  }
@@ -426,9 +528,9 @@ var listRulesetsThunk = createAsyncThunk(
426
528
  "bridge/listRulesets",
427
529
  async ({ apiUrl, apiKey }, { dispatch: dispatch2, rejectWithValue }) => {
428
530
  try {
429
- const url = apiUrl || "https://api.forboc.ai";
531
+ const url = resolveApiUrl(apiUrl);
430
532
  requireApiKeyGuidance(url, apiKey);
431
- return await dispatch2(sdkApi.endpoints.getRulesets.initiate({ apiUrl: url, apiKey })).unwrap();
533
+ return await dispatch2(api.endpoints.getRulesets.initiate({ apiUrl: url, apiKey })).unwrap();
432
534
  } catch (error) {
433
535
  return rejectWithValue(extractThunkErrorMessage(error, "Failed to list rulesets"));
434
536
  }
@@ -438,9 +540,9 @@ var listRulePresetsThunk = createAsyncThunk(
438
540
  "bridge/listRulePresets",
439
541
  async ({ apiUrl, apiKey }, { dispatch: dispatch2, rejectWithValue }) => {
440
542
  try {
441
- const url = apiUrl || "https://api.forboc.ai";
543
+ const url = resolveApiUrl(apiUrl);
442
544
  requireApiKeyGuidance(url, apiKey);
443
- return await dispatch2(sdkApi.endpoints.getRulePresets.initiate({ apiUrl: url, apiKey })).unwrap();
545
+ return await dispatch2(api.endpoints.getRulePresets.initiate({ apiUrl: url, apiKey })).unwrap();
444
546
  } catch (error) {
445
547
  return rejectWithValue(extractThunkErrorMessage(error, "Failed to list rule presets"));
446
548
  }
@@ -450,9 +552,9 @@ var registerRulesetThunk = createAsyncThunk(
450
552
  "bridge/registerRuleset",
451
553
  async ({ ruleset, apiUrl, apiKey }, { dispatch: dispatch2, rejectWithValue }) => {
452
554
  try {
453
- const url = apiUrl || "https://api.forboc.ai";
555
+ const url = resolveApiUrl(apiUrl);
454
556
  requireApiKeyGuidance(url, apiKey);
455
- return await dispatch2(sdkApi.endpoints.postRuleRegister.initiate({ request: ruleset, apiUrl: url, apiKey })).unwrap();
557
+ return await dispatch2(api.endpoints.postRuleRegister.initiate({ request: ruleset, apiUrl: url, apiKey })).unwrap();
456
558
  } catch (error) {
457
559
  return rejectWithValue(extractThunkErrorMessage(error, "Failed to register ruleset"));
458
560
  }
@@ -462,9 +564,9 @@ var deleteRulesetThunk = createAsyncThunk(
462
564
  "bridge/deleteRuleset",
463
565
  async ({ rulesetId, apiUrl, apiKey }, { dispatch: dispatch2, rejectWithValue }) => {
464
566
  try {
465
- const url = apiUrl || "https://api.forboc.ai";
567
+ const url = resolveApiUrl(apiUrl);
466
568
  requireApiKeyGuidance(url, apiKey);
467
- return await dispatch2(sdkApi.endpoints.deleteRule.initiate({ rulesetId, apiUrl: url, apiKey })).unwrap();
569
+ return await dispatch2(api.endpoints.deleteRule.initiate({ rulesetId, apiUrl: url, apiKey })).unwrap();
468
570
  } catch (error) {
469
571
  return rejectWithValue(extractThunkErrorMessage(error, "Failed to delete ruleset"));
470
572
  }
@@ -516,121 +618,82 @@ var bridgeSlice_default = bridgeSlice.reducer;
516
618
  // src/soulSlice.ts
517
619
  import { createSlice as createSlice2, createAsyncThunk as createAsyncThunk2 } from "@reduxjs/toolkit";
518
620
 
519
- // src/handlers/arweave.ts
520
- var sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
521
- var getLocalWalletToken = () => {
522
- const maybeEnv = globalThis.process?.env;
523
- return maybeEnv?.ARWEAVE_WALLET_JWK ?? null;
524
- };
525
- var withTimeout = async (promiseFactory, timeoutMs = 6e4) => {
526
- const controller = new AbortController();
527
- const timeout = setTimeout(() => controller.abort(), timeoutMs);
528
- try {
529
- return await promiseFactory(controller.signal);
530
- } finally {
531
- clearTimeout(timeout);
532
- }
533
- };
534
- async function handler_ArweaveUpload(instruction, maxRetries = 3) {
535
- const headers = {
536
- "Content-Type": instruction.auiContentType || "application/json"
537
- };
538
- const authToken = instruction.auiAuthHeader ?? (getLocalWalletToken() ? `Bearer ${getLocalWalletToken()}` : null);
539
- if (authToken) {
540
- headers.Authorization = authToken;
541
- }
542
- let attempt = 0;
543
- while (attempt < maxRetries) {
544
- attempt += 1;
545
- try {
546
- const response = await withTimeout(
547
- (signal) => fetch(instruction.auiEndpoint, {
548
- method: "POST",
549
- headers,
550
- body: JSON.stringify(instruction.auiPayload),
551
- signal
552
- })
553
- );
554
- let responseBody = null;
555
- try {
556
- responseBody = await response.json();
557
- } catch {
558
- responseBody = null;
559
- }
560
- const txId = responseBody?.id ?? `ar_tx_sdk_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;
561
- const success = response.status >= 200 && response.status < 300;
562
- if (!success && attempt < maxRetries) {
563
- await sleep(250 * 2 ** (attempt - 1));
564
- continue;
565
- }
566
- return {
567
- aurTxId: txId,
568
- aurStatus: response.status,
569
- aurSuccess: success,
570
- aurError: success ? null : `upload_failed_status_${response.status}`
571
- };
572
- } catch (error) {
573
- const message = error instanceof Error ? error.message : String(error);
574
- if (attempt < maxRetries) {
575
- await sleep(250 * 2 ** (attempt - 1));
576
- continue;
577
- }
578
- return {
579
- aurTxId: `ar_tx_failed_${Date.now()}`,
580
- aurStatus: 0,
581
- aurSuccess: false,
582
- aurError: `upload_request_failed:${message}`
583
- };
584
- }
621
+ // src/functional_core.ts
622
+ var just = (value) => ({
623
+ _tag: "Just",
624
+ map: (f) => just(f(value)),
625
+ chain: (f) => f(value),
626
+ getOrElse: (_defaultValue) => value,
627
+ match: (cases) => cases.just(value)
628
+ });
629
+ var nothing = () => ({
630
+ _tag: "Nothing",
631
+ map: (_f) => nothing(),
632
+ chain: (_f) => nothing(),
633
+ getOrElse: (defaultValue) => defaultValue,
634
+ match: (cases) => cases.nothing()
635
+ });
636
+ var fmap = (m, f) => m.map(f);
637
+ var mbind = (m, f) => m.chain(f);
638
+ var orElse = (m, defaultValue) => m.getOrElse(defaultValue);
639
+ var match = (m, onJust, onNothing) => m.match({ just: onJust, nothing: onNothing });
640
+ var isJust = (m) => m._tag === "Just";
641
+ var isNothing = (m) => m._tag === "Nothing";
642
+ var fromNullable = (value) => value != null ? just(value) : nothing();
643
+ var requireJust = (m, errorMsg) => m.match({
644
+ just: (v) => v,
645
+ nothing: () => {
646
+ throw new Error(errorMsg);
585
647
  }
586
- return {
587
- aurTxId: `ar_tx_failed_${Date.now()}`,
588
- aurStatus: 0,
589
- aurSuccess: false,
590
- aurError: "upload_retry_exhausted"
648
+ });
649
+ var left = (error) => ({
650
+ _tag: "Left",
651
+ map: (_f) => left(error),
652
+ chain: (_f) => left(error),
653
+ getOrElse: (defaultValue) => defaultValue,
654
+ match: (cases) => cases.left(error)
655
+ });
656
+ var right = (value) => ({
657
+ _tag: "Right",
658
+ map: (f) => right(f(value)),
659
+ chain: (f) => f(value),
660
+ getOrElse: (_defaultValue) => value,
661
+ match: (cases) => cases.right(value)
662
+ });
663
+ var efmap = (e, f) => e.map(f);
664
+ var ebind = (e, f) => e.chain(f);
665
+ var ematch = (e, onLeft, onRight) => e.match({ left: onLeft, right: onRight });
666
+ var isLeft = (e) => e._tag === "Left";
667
+ var isRight = (e) => e._tag === "Right";
668
+ function compose(...fns) {
669
+ return (...args) => {
670
+ const last = fns[fns.length - 1];
671
+ const rest = fns.slice(0, -1);
672
+ return rest.reduceRight((acc, fn) => fn(acc), last(...args));
591
673
  };
592
674
  }
593
- async function handler_ArweaveDownload(instruction) {
594
- try {
595
- const response = await withTimeout(
596
- (signal) => fetch(instruction.adiGatewayUrl, {
597
- method: "GET",
598
- signal
599
- })
600
- );
601
- if (response.status < 200 || response.status >= 300) {
602
- return {
603
- adrBody: null,
604
- adrStatus: response.status,
605
- adrSuccess: false,
606
- adrError: `download_failed_status_${response.status}`
607
- };
608
- }
609
- try {
610
- const body = await response.json();
611
- return {
612
- adrBody: body,
613
- adrStatus: response.status,
614
- adrSuccess: true,
615
- adrError: null
616
- };
617
- } catch {
618
- return {
619
- adrBody: null,
620
- adrStatus: response.status,
621
- adrSuccess: false,
622
- adrError: "download_invalid_json"
623
- };
624
- }
625
- } catch (error) {
626
- return {
627
- adrBody: null,
628
- adrStatus: 0,
629
- adrSuccess: false,
630
- adrError: error instanceof Error ? error.message : String(error)
631
- };
632
- }
675
+ function curry(fn) {
676
+ const arity = fn.length;
677
+ const curried = (...args) => args.length >= arity ? fn(...args) : (...moreArgs) => curried(...args, ...moreArgs);
678
+ return curried;
633
679
  }
680
+ var createDispatcher = (entries) => {
681
+ const table = new Map(entries);
682
+ return {
683
+ dispatch: (key, ...args) => {
684
+ const handler = table.get(key);
685
+ return handler ? just(handler(...args)) : nothing();
686
+ },
687
+ has: (key) => table.has(key),
688
+ keys: () => [...table.keys()]
689
+ };
690
+ };
691
+ var _ = /* @__PURE__ */ Symbol.for("forbocai_wildcard");
692
+ var testCase = (value, predicate, handler) => predicate === _ ? just(handler(value)) : typeof predicate === "function" ? predicate(value) ? just(handler(value)) : nothing() : predicate === value ? just(handler(value)) : nothing();
693
+ var multiMatch = (value, cases) => cases.length === 0 ? nothing() : testCase(value, cases[0][0], cases[0][1]).match({
694
+ just: (v) => just(v),
695
+ nothing: () => multiMatch(value, cases.slice(1))
696
+ });
634
697
 
635
698
  // src/soulSlice.ts
636
699
  var initialState2 = {
@@ -647,24 +710,25 @@ var remoteExportSoulThunk = createAsyncThunk2(
647
710
  try {
648
711
  const state = getState().npc;
649
712
  const npcId = argNpcId || state.activeNpcId;
650
- const npc = state.entities[npcId];
651
- if (!npc) throw new Error(`NPC ${npcId} not found`);
652
- const url = apiUrl || "https://api.forboc.ai";
713
+ const npc = requireJust(fromNullable(state.entities[npcId]), `NPC ${npcId} not found`);
714
+ const url = resolveApiUrl(apiUrl);
653
715
  requireApiKeyGuidance(url, apiKey);
654
716
  const phase1 = await dispatch2(
655
- sdkApi.endpoints.postSoulExport.initiate({
717
+ api.endpoints.postSoulExport.initiate({
656
718
  npcId,
657
719
  request: { npcIdRef: npcId, persona: npc.persona || "NPC", npcState: npc.state },
658
720
  apiUrl: url,
659
721
  apiKey
660
722
  })
661
723
  ).unwrap();
662
- const uploadResult = await handler_ArweaveUpload({
663
- ...phase1.se1Instruction,
664
- auiAuthHeader: phase1.se1Instruction.auiAuthHeader ?? null
665
- });
724
+ const uploadResult = await dispatch2(
725
+ api.endpoints.postArweaveUpload.initiate({
726
+ ...phase1.se1Instruction,
727
+ auiAuthHeader: phase1.se1Instruction.auiAuthHeader ?? null
728
+ })
729
+ ).unwrap();
666
730
  const final = await dispatch2(
667
- sdkApi.endpoints.postSoulExportConfirm.initiate({
731
+ api.endpoints.postSoulExportConfirm.initiate({
668
732
  npcId,
669
733
  request: {
670
734
  secUploadResult: uploadResult,
@@ -689,14 +753,16 @@ var importSoulFromArweaveThunk = createAsyncThunk2(
689
753
  "soul/import",
690
754
  async ({ txId, apiUrl, apiKey }, { dispatch: dispatch2, rejectWithValue }) => {
691
755
  try {
692
- const url = apiUrl || "https://api.forboc.ai";
756
+ const url = resolveApiUrl(apiUrl);
693
757
  requireApiKeyGuidance(url, apiKey);
694
758
  const phase1 = await dispatch2(
695
- sdkApi.endpoints.postNpcImport.initiate({ request: { txIdRef: txId }, apiUrl: url, apiKey })
759
+ api.endpoints.postNpcImport.initiate({ request: { txIdRef: txId }, apiUrl: url, apiKey })
760
+ ).unwrap();
761
+ const downloadResult = await dispatch2(
762
+ api.endpoints.postArweaveDownload.initiate(phase1.si1Instruction)
696
763
  ).unwrap();
697
- const downloadResult = await handler_ArweaveDownload(phase1.si1Instruction);
698
764
  const npc = await dispatch2(
699
- sdkApi.endpoints.postNpcImportConfirm.initiate({
765
+ api.endpoints.postNpcImportConfirm.initiate({
700
766
  request: {
701
767
  sicTxId: txId,
702
768
  sicDownloadResult: downloadResult
@@ -722,9 +788,9 @@ var getSoulListThunk = createAsyncThunk2(
722
788
  "soul/list",
723
789
  async ({ limit = 50, apiUrl, apiKey }, { dispatch: dispatch2, rejectWithValue }) => {
724
790
  try {
725
- const url = apiUrl || "https://api.forboc.ai";
791
+ const url = resolveApiUrl(apiUrl);
726
792
  requireApiKeyGuidance(url, apiKey);
727
- const data = await dispatch2(sdkApi.endpoints.getSouls.initiate({ limit, apiUrl: url, apiKey })).unwrap();
793
+ const data = await dispatch2(api.endpoints.getSouls.initiate({ limit, apiUrl: url, apiKey })).unwrap();
728
794
  return data.souls || [];
729
795
  } catch (error) {
730
796
  return rejectWithValue(extractThunkErrorMessage(error, "Failed to list souls"));
@@ -735,9 +801,9 @@ var verifySoulThunk = createAsyncThunk2(
735
801
  "soul/verify",
736
802
  async ({ txId, apiUrl, apiKey }, { dispatch: dispatch2, rejectWithValue }) => {
737
803
  try {
738
- const url = apiUrl || "https://api.forboc.ai";
804
+ const url = resolveApiUrl(apiUrl);
739
805
  requireApiKeyGuidance(url, apiKey);
740
- return await dispatch2(sdkApi.endpoints.postSoulVerify.initiate({ txId, apiUrl: url, apiKey })).unwrap();
806
+ return await dispatch2(api.endpoints.postSoulVerify.initiate({ txId, apiUrl: url, apiKey })).unwrap();
741
807
  } catch (error) {
742
808
  return rejectWithValue(extractThunkErrorMessage(error, "Soul verify failed"));
743
809
  }
@@ -747,18 +813,20 @@ var importNpcFromSoulThunk = createAsyncThunk2(
747
813
  "soul/importNpc",
748
814
  async ({ txId, apiUrl, apiKey }, { dispatch: dispatch2, rejectWithValue }) => {
749
815
  try {
750
- const url = apiUrl || "https://api.forboc.ai";
816
+ const url = resolveApiUrl(apiUrl);
751
817
  requireApiKeyGuidance(url, apiKey);
752
818
  const phase1 = await dispatch2(
753
- sdkApi.endpoints.postNpcImport.initiate({
819
+ api.endpoints.postNpcImport.initiate({
754
820
  request: { txIdRef: txId },
755
821
  apiUrl: url,
756
822
  apiKey
757
823
  })
758
824
  ).unwrap();
759
- const downloadResult = await handler_ArweaveDownload(phase1.si1Instruction);
825
+ const downloadResult = await dispatch2(
826
+ api.endpoints.postArweaveDownload.initiate(phase1.si1Instruction)
827
+ ).unwrap();
760
828
  return await dispatch2(
761
- sdkApi.endpoints.postNpcImportConfirm.initiate({
829
+ api.endpoints.postNpcImportConfirm.initiate({
762
830
  request: { sicTxId: txId, sicDownloadResult: downloadResult },
763
831
  apiUrl: url,
764
832
  apiKey
@@ -823,9 +891,9 @@ var startGhostThunk = createAsyncThunk3(
823
891
  "ghost/start",
824
892
  async (config, { dispatch: dispatch2, rejectWithValue }) => {
825
893
  try {
826
- const apiUrl = config.apiUrl || "https://api.forboc.ai";
894
+ const apiUrl = resolveApiUrl(config.apiUrl);
827
895
  requireApiKeyGuidance(apiUrl, config.apiKey);
828
- const data = await dispatch2(sdkApi.endpoints.postGhostRun.initiate({
896
+ const data = await dispatch2(api.endpoints.postGhostRun.initiate({
829
897
  request: { testSuite: config.testSuite, duration: config.duration ?? 300 },
830
898
  apiUrl,
831
899
  apiKey: config.apiKey
@@ -844,11 +912,10 @@ var getGhostStatusThunk = createAsyncThunk3(
844
912
  async ({ sessionId, apiUrl, apiKey }, { dispatch: dispatch2, getState, rejectWithValue }) => {
845
913
  try {
846
914
  const state = getState().ghost;
847
- const targetSession = sessionId || state.activeSessionId;
848
- if (!targetSession) throw new Error("No active Ghost session");
849
- const url = apiUrl || "https://api.forboc.ai";
915
+ const targetSession = requireJust(fromNullable(sessionId || state.activeSessionId), "No active Ghost session");
916
+ const url = resolveApiUrl(apiUrl);
850
917
  requireApiKeyGuidance(url, apiKey);
851
- const data = await dispatch2(sdkApi.endpoints.getGhostStatus.initiate({ sessionId: targetSession, apiUrl: url, apiKey })).unwrap();
918
+ const data = await dispatch2(api.endpoints.getGhostStatus.initiate({ sessionId: targetSession, apiUrl: url, apiKey })).unwrap();
852
919
  return {
853
920
  sessionId: data.ghostSessionId,
854
921
  status: data.ghostStatus,
@@ -867,11 +934,10 @@ var getGhostResultsThunk = createAsyncThunk3(
867
934
  async ({ sessionId, apiUrl, apiKey }, { dispatch: dispatch2, getState, rejectWithValue }) => {
868
935
  try {
869
936
  const state = getState().ghost;
870
- const targetSession = sessionId || state.activeSessionId;
871
- if (!targetSession) throw new Error("No active Ghost session");
872
- const url = apiUrl || "https://api.forboc.ai";
937
+ const targetSession = requireJust(fromNullable(sessionId || state.activeSessionId), "No active Ghost session");
938
+ const url = resolveApiUrl(apiUrl);
873
939
  requireApiKeyGuidance(url, apiKey);
874
- const data = await dispatch2(sdkApi.endpoints.getGhostResults.initiate({ sessionId: targetSession, apiUrl: url, apiKey })).unwrap();
940
+ const data = await dispatch2(api.endpoints.getGhostResults.initiate({ sessionId: targetSession, apiUrl: url, apiKey })).unwrap();
875
941
  return {
876
942
  sessionId: data.resultsSessionId,
877
943
  totalTests: data.resultsTotalTests,
@@ -899,11 +965,10 @@ var stopGhostThunk = createAsyncThunk3(
899
965
  async ({ sessionId, apiUrl, apiKey }, { dispatch: dispatch2, getState, rejectWithValue }) => {
900
966
  try {
901
967
  const state = getState().ghost;
902
- const targetSession = sessionId || state.activeSessionId;
903
- if (!targetSession) throw new Error("No active Ghost session");
904
- const url = apiUrl || "https://api.forboc.ai";
968
+ const targetSession = requireJust(fromNullable(sessionId || state.activeSessionId), "No active Ghost session");
969
+ const url = resolveApiUrl(apiUrl);
905
970
  requireApiKeyGuidance(url, apiKey);
906
- const data = await dispatch2(sdkApi.endpoints.postGhostStop.initiate({ sessionId: targetSession, apiUrl: url, apiKey })).unwrap();
971
+ const data = await dispatch2(api.endpoints.postGhostStop.initiate({ sessionId: targetSession, apiUrl: url, apiKey })).unwrap();
907
972
  return {
908
973
  stopped: data.stopped,
909
974
  status: data.stopStatus,
@@ -918,9 +983,9 @@ var getGhostHistoryThunk = createAsyncThunk3(
918
983
  "ghost/history",
919
984
  async ({ limit = 10, apiUrl, apiKey }, { dispatch: dispatch2, rejectWithValue }) => {
920
985
  try {
921
- const url = apiUrl || "https://api.forboc.ai";
986
+ const url = resolveApiUrl(apiUrl);
922
987
  requireApiKeyGuidance(url, apiKey);
923
- const data = await dispatch2(sdkApi.endpoints.getGhostHistory.initiate({ limit, apiUrl: url, apiKey })).unwrap();
988
+ const data = await dispatch2(api.endpoints.getGhostHistory.initiate({ limit, apiUrl: url, apiKey })).unwrap();
924
989
  return (data.sessions || []).map((s) => ({
925
990
  sessionId: s.sessionId,
926
991
  testSuite: s.testSuite,
@@ -979,8 +1044,8 @@ var ghostSlice = createSlice3({
979
1044
  var { clearGhostSession } = ghostSlice.actions;
980
1045
  var ghostSlice_default = ghostSlice.reducer;
981
1046
 
982
- // src/utils/sdkVersion.ts
983
- var SDK_VERSION = "0.6.1";
1047
+ // src/utils/version.ts
1048
+ var VERSION = "0.6.4";
984
1049
 
985
1050
  // src/utils/generateNPCId.ts
986
1051
  var generateNPCId = () => `ag_${Date.now().toString(36)}`;
@@ -1148,9 +1213,9 @@ var initRemoteCortexThunk = createAsyncThunk4(
1148
1213
  "cortex/initRemote",
1149
1214
  async ({ model = "api-integrated", authKey, apiUrl, apiKey }, { dispatch: dispatch2, rejectWithValue }) => {
1150
1215
  try {
1151
- const url = apiUrl || "https://api.forboc.ai";
1216
+ const url = resolveApiUrl(apiUrl);
1152
1217
  requireApiKeyGuidance(url, apiKey);
1153
- const data = await dispatch2(sdkApi.endpoints.postCortexInit.initiate({
1218
+ const data = await dispatch2(api.endpoints.postCortexInit.initiate({
1154
1219
  request: { requestedModel: model, authKey },
1155
1220
  apiUrl: url,
1156
1221
  apiKey
@@ -1170,9 +1235,9 @@ var listCortexModelsThunk = createAsyncThunk4(
1170
1235
  "cortex/listModels",
1171
1236
  async ({ apiUrl, apiKey }, { dispatch: dispatch2, rejectWithValue }) => {
1172
1237
  try {
1173
- const url = apiUrl || "https://api.forboc.ai";
1238
+ const url = resolveApiUrl(apiUrl);
1174
1239
  requireApiKeyGuidance(url, apiKey);
1175
- return await dispatch2(sdkApi.endpoints.getCortexModels.initiate({ apiUrl: url, apiKey })).unwrap();
1240
+ return await dispatch2(api.endpoints.getCortexModels.initiate({ apiUrl: url, apiKey })).unwrap();
1176
1241
  } catch (error) {
1177
1242
  return rejectWithValue(extractThunkErrorMessage(error, "Failed to list cortex models"));
1178
1243
  }
@@ -1183,7 +1248,7 @@ var completeRemoteThunk = createAsyncThunk4(
1183
1248
  async ({ cortexId, prompt, options, apiUrl, apiKey }, { dispatch: dispatch2, rejectWithValue }) => {
1184
1249
  try {
1185
1250
  requireApiKeyGuidance(apiUrl, apiKey);
1186
- const data = await dispatch2(sdkApi.endpoints.postCortexComplete.initiate({
1251
+ const data = await dispatch2(api.endpoints.postCortexComplete.initiate({
1187
1252
  cortexId,
1188
1253
  prompt,
1189
1254
  options,
@@ -1384,8 +1449,8 @@ var directiveSlice_default = directiveSlice.reducer;
1384
1449
 
1385
1450
  // src/listeners.ts
1386
1451
  import { createListenerMiddleware } from "@reduxjs/toolkit";
1387
- var sdkListenerMiddleware = createListenerMiddleware();
1388
- var startAppListening = sdkListenerMiddleware.startListening.withTypes();
1452
+ var listenerMiddleware = createListenerMiddleware();
1453
+ var startAppListening = listenerMiddleware.startListening.withTypes();
1389
1454
  startAppListening({
1390
1455
  actionCreator: removeNPC,
1391
1456
  effect: async (action, listenerApi) => {
@@ -1402,11 +1467,38 @@ startAppListening({
1402
1467
  }
1403
1468
  });
1404
1469
 
1470
+ // src/runtimeRegistry.ts
1471
+ var createRuntimeRegistry = () => {
1472
+ const _store = {};
1473
+ return {
1474
+ get: (ns, key) => _store[ns]?.[key],
1475
+ set: (ns, key, value) => {
1476
+ if (!_store[ns]) _store[ns] = {};
1477
+ _store[ns][key] = value;
1478
+ },
1479
+ delete: (ns, key) => {
1480
+ if (_store[ns]) {
1481
+ delete _store[ns][key];
1482
+ return true;
1483
+ }
1484
+ return false;
1485
+ },
1486
+ has: (ns, key) => !!(_store[ns]?.[key] !== void 0),
1487
+ clear: (ns) => {
1488
+ if (ns) {
1489
+ delete _store[ns];
1490
+ } else {
1491
+ Object.keys(_store).forEach((k) => delete _store[k]);
1492
+ }
1493
+ }
1494
+ };
1495
+ };
1496
+
1405
1497
  // src/store.ts
1406
- var createSDKStore = (extraReducers = {}) => {
1498
+ var createRuntimeStore = (extraReducers = {}, registry = createRuntimeRegistry()) => {
1407
1499
  return configureStore({
1408
1500
  reducer: {
1409
- [sdkApi.reducerPath]: sdkApi.reducer,
1501
+ [api.reducerPath]: api.reducer,
1410
1502
  npc: npcSlice_default,
1411
1503
  cortex: cortexSlice_default,
1412
1504
  memory: memorySlice_default,
@@ -1417,46 +1509,120 @@ var createSDKStore = (extraReducers = {}) => {
1417
1509
  ...extraReducers
1418
1510
  },
1419
1511
  middleware: (getDefaultMiddleware) => getDefaultMiddleware({
1420
- serializableCheck: false
1421
- // Allow non-serializable for engine refs in specific slices if needed, though we try to keep them external
1422
- }).prepend(sdkListenerMiddleware.middleware).concat(sdkApi.middleware)
1512
+ thunk: { extraArgument: registry },
1513
+ serializableCheck: {
1514
+ ignoredActionPaths: [
1515
+ "meta.arg.cortex",
1516
+ "meta.arg.memory",
1517
+ "meta.arg.onProgress",
1518
+ "meta.baseQueryMeta.request",
1519
+ "meta.baseQueryMeta.response"
1520
+ ]
1521
+ }
1522
+ }).prepend(listenerMiddleware.middleware).concat(api.middleware)
1423
1523
  });
1424
1524
  };
1425
- var store = createSDKStore();
1525
+ var store = createRuntimeStore();
1426
1526
  var dispatch = store.dispatch;
1427
1527
 
1428
1528
  // src/thunks.ts
1429
1529
  import { createAsyncThunk as createAsyncThunk5 } from "@reduxjs/toolkit";
1430
- var extractThunkErrorMessage2 = (e) => {
1431
- if (typeof e === "string") return e;
1432
- if (e?.data?.message) return String(e.data.message);
1433
- if (e?.error) return String(e.error);
1434
- if (e?.message) return String(e.message);
1435
- return "Protocol processing failed";
1530
+
1531
+ // src/protocolHandlers.ts
1532
+ var persistMemoryRecursively = async (memory, instructions, index = 0) => !memory || index >= instructions.length ? void 0 : memory.store(instructions[index].text, instructions[index].type, instructions[index].importance).then(() => persistMemoryRecursively(memory, instructions, index + 1));
1533
+ var handleIdentifyActor = (ctx, nextTape, turn) => ctx.recurse(nextTape, {
1534
+ type: "IdentifyActorResult",
1535
+ actor: { npcId: ctx.npcId, persona: ctx.persona, data: nextTape.npcState }
1536
+ }, turn + 1);
1537
+ var handleQueryVector = async (ctx, instruction, nextTape, turn) => {
1538
+ ctx.dispatch(directiveReceived({
1539
+ id: ctx.directiveId,
1540
+ response: { memoryRecall: { query: instruction.query, limit: instruction.limit, threshold: instruction.threshold } }
1541
+ }));
1542
+ return ctx.memory ? ctx.memory.recall(instruction.query, instruction.limit, instruction.threshold).then((recalled) => ctx.recurse(nextTape, {
1543
+ type: "QueryVectorResult",
1544
+ memories: recalled.map((m) => ({ text: m.text, type: m.type, importance: m.importance, similarity: m.similarity }))
1545
+ }, turn + 1)) : ctx.rejectWithValue("API requested memory recall, but no memory engine is configured");
1546
+ };
1547
+ var handleExecuteInference = async (ctx, instruction, nextTape, turn) => {
1548
+ ctx.dispatch(contextComposed({ id: ctx.directiveId, prompt: instruction.prompt, constraints: instruction.constraints }));
1549
+ const generatedText = await ctx.cortex.complete(instruction.prompt, {
1550
+ maxTokens: instruction.constraints.maxTokens,
1551
+ temperature: instruction.constraints.temperature,
1552
+ stop: instruction.constraints.stop
1553
+ });
1554
+ return ctx.recurse(nextTape, {
1555
+ type: "ExecuteInferenceResult",
1556
+ generatedOutput: generatedText
1557
+ }, turn + 1);
1436
1558
  };
1559
+ var handleFinalize = async (ctx, finalize) => {
1560
+ ctx.dispatch(verdictValidated({
1561
+ id: ctx.directiveId,
1562
+ verdict: {
1563
+ valid: finalize.valid,
1564
+ signature: finalize.signature,
1565
+ memoryStore: finalize.memoryStore,
1566
+ stateDelta: finalize.stateTransform,
1567
+ action: finalize.action,
1568
+ dialogue: finalize.dialogue
1569
+ }
1570
+ }));
1571
+ return finalize.valid ? applyFinalizeSuccess(ctx, finalize) : applyFinalizeBlocked(ctx, finalize);
1572
+ };
1573
+ var applyFinalizeBlocked = (ctx, finalize) => {
1574
+ ctx.dispatch(blockAction({ id: ctx.npcId, reason: finalize.dialogue || "Validation Failed" }));
1575
+ return { dialogue: finalize.dialogue, action: finalize.action, thought: finalize.dialogue };
1576
+ };
1577
+ var applyFinalizeSuccess = async (ctx, finalize) => {
1578
+ if (finalize.memoryStore?.length && !ctx.memory) {
1579
+ return ctx.rejectWithValue("API returned memoryStore instructions, but no memory engine is configured");
1580
+ }
1581
+ await persistMemoryRecursively(ctx.memory, finalize.memoryStore || []);
1582
+ if (finalize.stateTransform) {
1583
+ ctx.dispatch(updateNPCState({ id: ctx.npcId, delta: finalize.stateTransform }));
1584
+ }
1585
+ ctx.dispatch(setLastAction({ id: ctx.npcId, action: finalize.action }));
1586
+ ctx.dispatch(addToHistory({ id: ctx.npcId, role: "user", content: ctx.text }));
1587
+ ctx.dispatch(addToHistory({ id: ctx.npcId, role: "assistant", content: finalize.dialogue }));
1588
+ return { dialogue: finalize.dialogue, action: finalize.action, thought: finalize.dialogue };
1589
+ };
1590
+ var dispatchInstruction = (ctx, instruction, nextTape, turn) => {
1591
+ const handlers = {
1592
+ "IdentifyActor": () => handleIdentifyActor(ctx, nextTape, turn),
1593
+ "QueryVector": () => handleQueryVector(ctx, instruction, nextTape, turn),
1594
+ "ExecuteInference": () => handleExecuteInference(ctx, instruction, nextTape, turn),
1595
+ "Finalize": () => handleFinalize(ctx, instruction)
1596
+ };
1597
+ const handler = handlers[instruction.type];
1598
+ return handler ? handler() : Promise.resolve(ctx.rejectWithValue("API returned unknown instruction type"));
1599
+ };
1600
+
1601
+ // src/thunks.ts
1602
+ var extractThunkErrorMessage2 = (e) => multiMatch(e, [
1603
+ [(e2) => typeof e2 === "string", (e2) => e2],
1604
+ [(e2) => !!e2?.data?.message, (e2) => String(e2.data.message)],
1605
+ [(e2) => !!e2?.error, (e2) => String(e2.error)],
1606
+ [(e2) => !!e2?.message, (e2) => String(e2.message)],
1607
+ [_, () => "Protocol processing failed"]
1608
+ ]).getOrElse("Protocol processing failed");
1609
+ var safeDispatch = async (promise) => promise.then((v) => right(v)).catch((e) => left(extractThunkErrorMessage2(e)));
1437
1610
  var processNPC = createAsyncThunk5(
1438
1611
  "npc/process",
1439
1612
  async ({ npcId: argNpcId, text, context = {}, apiUrl, apiKey, memory, cortex, persona: argPersona }, { getState, dispatch: dispatch2, rejectWithValue }) => {
1440
1613
  const stateNpcId = selectActiveNpcId(getState());
1441
1614
  const activeNpc = selectActiveNPC(getState());
1442
- const npcId = argNpcId || stateNpcId;
1443
- const persona = argPersona || activeNpc?.persona;
1444
1615
  const currentState = activeNpc?.state || {};
1445
- if (!npcId) {
1446
- return rejectWithValue("No npcId provided and no active NPC selected");
1447
- }
1448
- if (!persona) {
1449
- return rejectWithValue("No persona provided and no active NPC persona available");
1450
- }
1451
- if (!cortex) {
1452
- return rejectWithValue("No local cortex provided. SDK remote cortex fallback is disabled.");
1453
- }
1454
- if (argNpcId && argNpcId !== stateNpcId) {
1455
- dispatch2(setNPCInfo({ id: argNpcId, persona }));
1456
- }
1457
- const directiveId = `${npcId}:${Date.now()}`;
1458
- dispatch2(directiveRunStarted({ id: directiveId, npcId, observation: text }));
1616
+ let directiveId;
1459
1617
  try {
1618
+ const npcId = requireJust(fromNullable(argNpcId || stateNpcId), "No npcId provided and no active NPC selected");
1619
+ const persona = requireJust(fromNullable(argPersona || activeNpc?.persona), "No persona provided and no active NPC persona available");
1620
+ requireJust(fromNullable(cortex), "No local cortex provided. SDK remote cortex fallback is disabled.");
1621
+ if (argNpcId && argNpcId !== stateNpcId) {
1622
+ dispatch2(setNPCInfo({ id: argNpcId, persona }));
1623
+ }
1624
+ directiveId = `${npcId}:${Date.now()}`;
1625
+ dispatch2(directiveRunStarted({ id: directiveId, npcId, observation: text }));
1460
1626
  const initialTape = {
1461
1627
  observation: text,
1462
1628
  context,
@@ -1465,104 +1631,33 @@ var processNPC = createAsyncThunk5(
1465
1631
  memories: [],
1466
1632
  vectorQueried: false
1467
1633
  };
1468
- const maxTurns = 12;
1469
- const persistMemoryInstructionsRecursively = async (instructions, index = 0) => {
1470
- if (!memory || index >= instructions.length) {
1471
- return;
1472
- }
1473
- const inst = instructions[index];
1474
- await memory.store(inst.text, inst.type, inst.importance);
1475
- await persistMemoryInstructionsRecursively(instructions, index + 1);
1476
- };
1477
- const runProtocolRecursively = async (tape, lastResult, turn) => {
1478
- if (turn >= maxTurns) {
1479
- return rejectWithValue(`Protocol loop exceeded max turns (${maxTurns})`);
1634
+ const runProtocol = async (tape, lastResult, turn) => {
1635
+ if (turn >= 12) {
1636
+ return rejectWithValue("Protocol loop exceeded max turns (12)");
1480
1637
  }
1481
1638
  const request = { tape, lastResult };
1482
1639
  const processResult = await dispatch2(
1483
- sdkApi.endpoints.postNpcProcess.initiate({ npcId, request, apiUrl, apiKey })
1640
+ api.endpoints.postNpcProcess.initiate({ npcId, request, apiUrl, apiKey })
1484
1641
  ).unwrap();
1485
- const nextTape = processResult.tape;
1486
- const instruction = processResult.instruction;
1487
- if (instruction.type === "IdentifyActor") {
1488
- return runProtocolRecursively(nextTape, {
1489
- type: "IdentifyActorResult",
1490
- actor: {
1491
- npcId,
1492
- persona,
1493
- data: nextTape.npcState
1494
- }
1495
- }, turn + 1);
1496
- }
1497
- if (instruction.type === "QueryVector") {
1498
- dispatch2(directiveReceived({
1499
- id: directiveId,
1500
- response: { memoryRecall: { query: instruction.query, limit: instruction.limit, threshold: instruction.threshold } }
1501
- }));
1502
- if (!memory) {
1503
- return rejectWithValue("API requested memory recall, but no memory engine is configured");
1504
- }
1505
- const recalled = await memory.recall(instruction.query, instruction.limit, instruction.threshold);
1506
- return runProtocolRecursively(nextTape, {
1507
- type: "QueryVectorResult",
1508
- memories: recalled.map((m) => ({ text: m.text, type: m.type, importance: m.importance, similarity: m.similarity }))
1509
- }, turn + 1);
1510
- }
1511
- if (instruction.type === "ExecuteInference") {
1512
- dispatch2(contextComposed({ id: directiveId, prompt: instruction.prompt, constraints: instruction.constraints }));
1513
- const generatedText = await cortex.complete(instruction.prompt, {
1514
- maxTokens: instruction.constraints.maxTokens,
1515
- temperature: instruction.constraints.temperature,
1516
- stop: instruction.constraints.stop
1517
- });
1518
- return runProtocolRecursively(nextTape, {
1519
- type: "ExecuteInferenceResult",
1520
- generatedOutput: generatedText
1521
- }, turn + 1);
1522
- }
1523
- if (instruction.type === "Finalize") {
1524
- const finalize = instruction;
1525
- dispatch2(verdictValidated({
1526
- id: directiveId,
1527
- verdict: {
1528
- valid: finalize.valid,
1529
- signature: finalize.signature,
1530
- memoryStore: finalize.memoryStore,
1531
- stateDelta: finalize.stateTransform,
1532
- action: finalize.action,
1533
- dialogue: finalize.dialogue
1534
- }
1535
- }));
1536
- if (!finalize.valid) {
1537
- dispatch2(blockAction({ id: npcId, reason: finalize.dialogue || "Validation Failed" }));
1538
- return {
1539
- dialogue: finalize.dialogue,
1540
- action: finalize.action,
1541
- thought: finalize.dialogue
1542
- };
1543
- }
1544
- if (finalize.memoryStore?.length && !memory) {
1545
- return rejectWithValue("API returned memoryStore instructions, but no memory engine is configured");
1546
- }
1547
- await persistMemoryInstructionsRecursively(finalize.memoryStore || []);
1548
- if (finalize.stateTransform) {
1549
- dispatch2(updateNPCState({ id: npcId, delta: finalize.stateTransform }));
1550
- }
1551
- dispatch2(setLastAction({ id: npcId, action: finalize.action }));
1552
- dispatch2(addToHistory({ id: npcId, role: "user", content: text }));
1553
- dispatch2(addToHistory({ id: npcId, role: "assistant", content: finalize.dialogue }));
1554
- return {
1555
- dialogue: finalize.dialogue,
1556
- action: finalize.action,
1557
- thought: finalize.dialogue
1558
- };
1559
- }
1560
- return rejectWithValue("API returned unknown instruction type");
1642
+ const ctx = {
1643
+ npcId,
1644
+ persona,
1645
+ text,
1646
+ directiveId,
1647
+ memory,
1648
+ cortex,
1649
+ dispatch: dispatch2,
1650
+ rejectWithValue,
1651
+ recurse: runProtocol
1652
+ };
1653
+ return dispatchInstruction(ctx, processResult.instruction, processResult.tape, turn);
1561
1654
  };
1562
- return runProtocolRecursively(initialTape, void 0, 0);
1655
+ return runProtocol(initialTape, void 0, 0);
1563
1656
  } catch (e) {
1564
1657
  const message = extractThunkErrorMessage2(e);
1565
- dispatch2(directiveRunFailed({ id: directiveId, error: String(message) }));
1658
+ if (directiveId) {
1659
+ dispatch2(directiveRunFailed({ id: directiveId, error: String(message) }));
1660
+ }
1566
1661
  return rejectWithValue(String(message));
1567
1662
  }
1568
1663
  }
@@ -1572,8 +1667,7 @@ var localExportSoulThunk = createAsyncThunk5(
1572
1667
  async ({ id, memory }, { getState }) => {
1573
1668
  const state = getState().npc;
1574
1669
  const npcId = id || state.activeNpcId;
1575
- const npc = state.entities[npcId];
1576
- if (!npc) throw new Error(`NPC ${npcId} not found`);
1670
+ const npc = requireJust(fromNullable(state.entities[npcId]), `NPC ${npcId} not found`);
1577
1671
  const memories = memory ? await memory.export() : [];
1578
1672
  return exportToSoul(npcId, "NPC", npc.persona, npc.state, memories);
1579
1673
  }
@@ -1581,76 +1675,98 @@ var localExportSoulThunk = createAsyncThunk5(
1581
1675
  var checkApiStatusThunk = createAsyncThunk5(
1582
1676
  "system/checkApiStatus",
1583
1677
  async ({ apiUrl }, { dispatch: dispatch2, rejectWithValue }) => {
1584
- try {
1585
- return await dispatch2(sdkApi.endpoints.getApiStatus.initiate({ apiUrl })).unwrap();
1586
- } catch (e) {
1587
- return rejectWithValue(e?.message || "Connection failed");
1588
- }
1678
+ const result = await safeDispatch(dispatch2(api.endpoints.getApiStatus.initiate({ apiUrl })).unwrap());
1679
+ return result.match({
1680
+ left: (e) => rejectWithValue(e),
1681
+ right: (v) => v
1682
+ });
1589
1683
  }
1590
1684
  );
1591
1685
  var listMemoryRemoteThunk = createAsyncThunk5(
1592
1686
  "memory/listRemote",
1593
1687
  async ({ npcId, apiUrl, apiKey }, { dispatch: dispatch2, rejectWithValue }) => {
1594
- try {
1595
- const data = await dispatch2(sdkApi.endpoints.getMemoryList.initiate({ npcId, apiUrl, apiKey })).unwrap();
1596
- return data || [];
1597
- } catch (e) {
1598
- return rejectWithValue(e?.message || "Failed to list memories");
1599
- }
1688
+ const result = await safeDispatch(dispatch2(api.endpoints.getMemoryList.initiate({ npcId, apiUrl, apiKey })).unwrap());
1689
+ return result.match({
1690
+ left: (e) => rejectWithValue(e),
1691
+ right: (v) => v || []
1692
+ });
1600
1693
  }
1601
1694
  );
1602
1695
  var recallMemoryRemoteThunk = createAsyncThunk5(
1603
1696
  "memory/recallRemote",
1604
1697
  async ({ npcId, query, apiUrl, apiKey }, { dispatch: dispatch2, rejectWithValue }) => {
1605
- try {
1606
- const data = await dispatch2(
1607
- sdkApi.endpoints.postMemoryRecall.initiate({
1608
- npcId,
1609
- request: { query },
1610
- apiUrl,
1611
- apiKey
1612
- })
1613
- ).unwrap();
1614
- return data || [];
1615
- } catch (e) {
1616
- return rejectWithValue(e?.message || "Failed to recall memories");
1617
- }
1698
+ const result = await safeDispatch(dispatch2(
1699
+ api.endpoints.postMemoryRecall.initiate({ npcId, request: { query }, apiUrl, apiKey })
1700
+ ).unwrap());
1701
+ return result.match({
1702
+ left: (e) => rejectWithValue(e),
1703
+ right: (v) => v || []
1704
+ });
1618
1705
  }
1619
1706
  );
1620
1707
  var storeMemoryRemoteThunk = createAsyncThunk5(
1621
1708
  "memory/storeRemote",
1622
1709
  async ({ npcId, observation, importance = 0.8, apiUrl, apiKey }, { dispatch: dispatch2, rejectWithValue }) => {
1623
- try {
1624
- return await dispatch2(
1625
- sdkApi.endpoints.postMemoryStore.initiate({
1626
- npcId,
1627
- request: { observation, importance },
1628
- apiUrl,
1629
- apiKey
1630
- })
1631
- ).unwrap();
1632
- } catch (e) {
1633
- return rejectWithValue(e?.message || "Failed to store memory");
1634
- }
1710
+ const result = await safeDispatch(dispatch2(
1711
+ api.endpoints.postMemoryStore.initiate({ npcId, request: { observation, importance }, apiUrl, apiKey })
1712
+ ).unwrap());
1713
+ return result.match({
1714
+ left: (e) => rejectWithValue(e),
1715
+ right: (v) => v
1716
+ });
1635
1717
  }
1636
1718
  );
1637
1719
  var clearMemoryRemoteThunk = createAsyncThunk5(
1638
1720
  "memory/clearRemote",
1639
1721
  async ({ npcId, apiUrl, apiKey }, { dispatch: dispatch2, rejectWithValue }) => {
1640
- try {
1641
- return await dispatch2(
1642
- sdkApi.endpoints.deleteMemoryClear.initiate({ npcId, apiUrl, apiKey })
1643
- ).unwrap();
1644
- } catch (e) {
1645
- return rejectWithValue(e?.message || "Failed to clear memories");
1646
- }
1722
+ const result = await safeDispatch(dispatch2(
1723
+ api.endpoints.deleteMemoryClear.initiate({ npcId, apiUrl, apiKey })
1724
+ ).unwrap());
1725
+ return result.match({
1726
+ left: (e) => rejectWithValue(e),
1727
+ right: (v) => v
1728
+ });
1647
1729
  }
1648
1730
  );
1731
+
1732
+ // src/handlers/arweave.ts
1733
+ var handler_ArweaveUpload = async (instruction, maxRetries = 3) => store.dispatch(
1734
+ api.endpoints.postArweaveUpload.initiate({ ...instruction, maxRetries })
1735
+ ).unwrap();
1736
+ var handler_ArweaveDownload = async (instruction) => store.dispatch(
1737
+ api.endpoints.postArweaveDownload.initiate(instruction)
1738
+ ).unwrap();
1739
+
1740
+ // src/configOps.ts
1741
+ var normalizeStatusUrl = (apiUrl) => apiUrl.endsWith("/status") ? apiUrl : `${apiUrl.replace(/\/+$/, "")}/status`;
1742
+ var checkApiConnectivity = async (apiUrl = DEFAULT_API_URL) => {
1743
+ try {
1744
+ const res = await fetch(normalizeStatusUrl(apiUrl), { signal: AbortSignal.timeout(1500) });
1745
+ return res.ok;
1746
+ } catch {
1747
+ return false;
1748
+ }
1749
+ };
1750
+ var resolveReachableApiUrl = async (apiUrl) => {
1751
+ if (apiUrl) return await checkApiConnectivity(apiUrl) ? apiUrl : null;
1752
+ if (await checkApiConnectivity(DEFAULT_API_URL)) return DEFAULT_API_URL;
1753
+ if (await checkApiConnectivity(PRODUCTION_API_URL)) return PRODUCTION_API_URL;
1754
+ return null;
1755
+ };
1756
+ var resolveApiUrlWithFallback = async (apiUrl) => {
1757
+ if (apiUrl) return apiUrl;
1758
+ return await resolveReachableApiUrl() || PRODUCTION_API_URL;
1759
+ };
1649
1760
  export {
1650
- SDK_VERSION,
1761
+ DEFAULT_API_URL,
1762
+ PRODUCTION_API_URL,
1763
+ VERSION,
1764
+ _,
1651
1765
  addToHistory,
1766
+ api,
1652
1767
  blockAction,
1653
1768
  bridgeSlice,
1769
+ checkApiConnectivity,
1654
1770
  checkApiStatusThunk,
1655
1771
  clearBlock,
1656
1772
  clearBridgeValidation,
@@ -1659,13 +1775,17 @@ export {
1659
1775
  clearMemoryRemoteThunk,
1660
1776
  clearSoulState,
1661
1777
  completeRemoteThunk,
1778
+ compose,
1662
1779
  contextComposed,
1663
1780
  cortexInitFailed,
1664
1781
  cortexInitStart,
1665
1782
  cortexInitSuccess,
1666
1783
  cortexSlice,
1784
+ createDispatcher,
1667
1785
  createInitialState,
1668
- createSDKStore,
1786
+ createRuntimeRegistry,
1787
+ createRuntimeStore,
1788
+ curry,
1669
1789
  delay,
1670
1790
  deleteRulesetThunk,
1671
1791
  directiveReceived,
@@ -1673,7 +1793,12 @@ export {
1673
1793
  directiveRunStarted,
1674
1794
  directiveSlice,
1675
1795
  dispatch,
1796
+ ebind,
1797
+ efmap,
1798
+ ematch,
1676
1799
  exportToSoul,
1800
+ fmap,
1801
+ fromNullable,
1677
1802
  generateNPCId,
1678
1803
  getBridgeRulesThunk,
1679
1804
  getGhostHistoryThunk,
@@ -1686,12 +1811,20 @@ export {
1686
1811
  importNpcFromSoulThunk,
1687
1812
  importSoulFromArweaveThunk,
1688
1813
  initRemoteCortexThunk,
1814
+ isJust,
1815
+ isLeft,
1816
+ isNothing,
1817
+ isRight,
1818
+ just,
1819
+ left,
1689
1820
  listCortexModelsThunk,
1690
1821
  listMemoryRemoteThunk,
1691
1822
  listRulePresetsThunk,
1692
1823
  listRulesetsThunk,
1693
1824
  loadBridgePresetThunk,
1694
1825
  localExportSoulThunk,
1826
+ match,
1827
+ mbind,
1695
1828
  memoise,
1696
1829
  memoiseAsync,
1697
1830
  memoryClear,
@@ -1702,14 +1835,21 @@ export {
1702
1835
  memoryStoreFailed,
1703
1836
  memoryStoreStart,
1704
1837
  memoryStoreSuccess,
1838
+ multiMatch,
1839
+ nothing,
1705
1840
  npcSlice,
1841
+ orElse,
1706
1842
  pipe,
1707
1843
  processNPC,
1708
1844
  recallMemoryRemoteThunk,
1709
1845
  registerRulesetThunk,
1710
1846
  remoteExportSoulThunk,
1711
1847
  removeNPC,
1712
- sdkApi,
1848
+ requireJust,
1849
+ resolveApiUrl,
1850
+ resolveApiUrlWithFallback,
1851
+ resolveReachableApiUrl,
1852
+ right,
1713
1853
  selectActiveDirective,
1714
1854
  selectActiveDirectiveId,
1715
1855
  selectActiveNPC,