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