@forbocai/core 0.5.9 → 0.6.0
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 +2591 -205
- package/dist/index.d.ts +2591 -205
- package/dist/index.js +986 -443
- package/dist/index.mjs +923 -336
- 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 +5 -2
package/dist/index.js
CHANGED
|
@@ -3,9 +3,6 @@ var __defProp = Object.defineProperty;
|
|
|
3
3
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
4
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
5
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
-
var __esm = (fn, res) => function __init() {
|
|
7
|
-
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
8
|
-
};
|
|
9
6
|
var __export = (target, all) => {
|
|
10
7
|
for (var name in all)
|
|
11
8
|
__defProp(target, name, { get: all[name], enumerable: true });
|
|
@@ -20,310 +17,598 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
20
17
|
};
|
|
21
18
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
22
19
|
|
|
23
|
-
// src/soul.ts
|
|
24
|
-
var soul_exports = {};
|
|
25
|
-
__export(soul_exports, {
|
|
26
|
-
createSoul: () => createSoul,
|
|
27
|
-
createSoulInstance: () => createSoulInstance,
|
|
28
|
-
deserializeSoul: () => deserializeSoul,
|
|
29
|
-
exportSoul: () => exportSoul,
|
|
30
|
-
getSoulList: () => getSoulList,
|
|
31
|
-
importSoulFromArweave: () => importSoulFromArweave,
|
|
32
|
-
serializeSoul: () => serializeSoul,
|
|
33
|
-
validateSoul: () => validateSoul
|
|
34
|
-
});
|
|
35
|
-
var createSoul, serializeSoul, deserializeSoul, exportSoul, importSoulFromArweave, getSoulList, createSoulInstance, validateSoul;
|
|
36
|
-
var init_soul = __esm({
|
|
37
|
-
"src/soul.ts"() {
|
|
38
|
-
"use strict";
|
|
39
|
-
createSoul = (id, name, persona, state, memories = []) => ({
|
|
40
|
-
id,
|
|
41
|
-
version: "1.0.0",
|
|
42
|
-
name,
|
|
43
|
-
persona,
|
|
44
|
-
state: { ...state },
|
|
45
|
-
memories: [...memories]
|
|
46
|
-
});
|
|
47
|
-
serializeSoul = (soul) => JSON.stringify(soul, null, 2);
|
|
48
|
-
deserializeSoul = (json) => {
|
|
49
|
-
const parsed = JSON.parse(json);
|
|
50
|
-
if (!parsed.id || !parsed.persona || !parsed.state) {
|
|
51
|
-
throw new Error("Invalid Soul format: missing required fields");
|
|
52
|
-
}
|
|
53
|
-
return {
|
|
54
|
-
id: parsed.id,
|
|
55
|
-
version: parsed.version || "1.0.0",
|
|
56
|
-
name: parsed.name || "Unknown",
|
|
57
|
-
persona: parsed.persona,
|
|
58
|
-
state: parsed.state,
|
|
59
|
-
memories: parsed.memories || [],
|
|
60
|
-
signature: parsed.signature
|
|
61
|
-
};
|
|
62
|
-
};
|
|
63
|
-
exportSoul = async (agentId, _soul, config = {}) => {
|
|
64
|
-
const apiUrl = config.apiUrl || "https://api.forboc.ai";
|
|
65
|
-
const response = await fetch(`${apiUrl}/agents/${agentId}/soul/export`, {
|
|
66
|
-
method: "POST",
|
|
67
|
-
headers: { "Content-Type": "application/json" },
|
|
68
|
-
body: JSON.stringify({})
|
|
69
|
-
// Future: allow specifying memories to include
|
|
70
|
-
});
|
|
71
|
-
if (!response.ok) {
|
|
72
|
-
throw new Error(`Soul export failed: ${response.statusText}`);
|
|
73
|
-
}
|
|
74
|
-
const data = await response.json();
|
|
75
|
-
return {
|
|
76
|
-
txId: data.txId,
|
|
77
|
-
url: data.url,
|
|
78
|
-
soul: _soul
|
|
79
|
-
// Return the local soul data as context
|
|
80
|
-
};
|
|
81
|
-
};
|
|
82
|
-
importSoulFromArweave = async (txId, config = {}) => {
|
|
83
|
-
const apiUrl = config.apiUrl || "https://api.forboc.ai";
|
|
84
|
-
const response = await fetch(`${apiUrl}/souls/${txId}`);
|
|
85
|
-
if (!response.ok) throw new Error(`Import failed: ${response.statusText}`);
|
|
86
|
-
const data = await response.json();
|
|
87
|
-
return data;
|
|
88
|
-
};
|
|
89
|
-
getSoulList = async (limit = 50, apiUrl = "https://api.forboc.ai") => {
|
|
90
|
-
const response = await fetch(`${apiUrl}/souls?limit=${limit}`);
|
|
91
|
-
if (!response.ok) return [];
|
|
92
|
-
const data = await response.json();
|
|
93
|
-
return data.souls || [];
|
|
94
|
-
};
|
|
95
|
-
createSoulInstance = (id, name, persona, state, memories = []) => {
|
|
96
|
-
const soulData = createSoul(id, name, persona, state, memories);
|
|
97
|
-
return {
|
|
98
|
-
export: (config) => exportSoul(id, soulData, config),
|
|
99
|
-
toJSON: () => ({ ...soulData })
|
|
100
|
-
};
|
|
101
|
-
};
|
|
102
|
-
validateSoul = (soul) => {
|
|
103
|
-
const errors = [
|
|
104
|
-
!soul.id && "Missing id",
|
|
105
|
-
!soul.persona && "Missing persona",
|
|
106
|
-
!soul.state && "Missing state"
|
|
107
|
-
].filter((e) => !!e);
|
|
108
|
-
return { valid: errors.length === 0, errors };
|
|
109
|
-
};
|
|
110
|
-
}
|
|
111
|
-
});
|
|
112
|
-
|
|
113
20
|
// src/index.ts
|
|
114
21
|
var index_exports = {};
|
|
115
22
|
__export(index_exports, {
|
|
116
23
|
SDK_VERSION: () => SDK_VERSION,
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
24
|
+
addToHistory: () => addToHistory,
|
|
25
|
+
blockAction: () => blockAction,
|
|
26
|
+
bridgeSlice: () => bridgeSlice,
|
|
27
|
+
clearBlock: () => clearBlock,
|
|
28
|
+
clearBridgeValidation: () => clearBridgeValidation,
|
|
29
|
+
clearGhostSession: () => clearGhostSession,
|
|
30
|
+
clearSoulState: () => clearSoulState,
|
|
31
|
+
completeRemoteThunk: () => completeRemoteThunk,
|
|
32
|
+
cortexInitFailed: () => cortexInitFailed,
|
|
33
|
+
cortexInitStart: () => cortexInitStart,
|
|
34
|
+
cortexInitSuccess: () => cortexInitSuccess,
|
|
35
|
+
cortexSlice: () => cortexSlice,
|
|
120
36
|
createInitialState: () => createInitialState,
|
|
121
|
-
|
|
122
|
-
createSoul: () => createSoul,
|
|
123
|
-
createSoulInstance: () => createSoulInstance,
|
|
37
|
+
createSDKStore: () => createSDKStore,
|
|
124
38
|
delay: () => delay,
|
|
125
|
-
|
|
126
|
-
|
|
39
|
+
dialogueNPC: () => dialogueNPC,
|
|
40
|
+
dispatch: () => dispatch,
|
|
127
41
|
exportToSoul: () => exportToSoul,
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
42
|
+
generateNPCId: () => generateNPCId,
|
|
43
|
+
getBridgeRulesThunk: () => getBridgeRulesThunk,
|
|
44
|
+
getGhostHistoryThunk: () => getGhostHistoryThunk,
|
|
45
|
+
getGhostResultsThunk: () => getGhostResultsThunk,
|
|
46
|
+
getGhostStatusThunk: () => getGhostStatusThunk,
|
|
47
|
+
getSoulListThunk: () => getSoulListThunk,
|
|
48
|
+
ghostSlice: () => ghostSlice,
|
|
49
|
+
importSoulFromArweaveThunk: () => importSoulFromArweaveThunk,
|
|
50
|
+
initRemoteCortexThunk: () => initRemoteCortexThunk,
|
|
51
|
+
loadBridgePresetThunk: () => loadBridgePresetThunk,
|
|
52
|
+
localExportSoulThunk: () => localExportSoulThunk,
|
|
135
53
|
memoise: () => memoise,
|
|
136
54
|
memoiseAsync: () => memoiseAsync,
|
|
55
|
+
memoryClear: () => memoryClear,
|
|
56
|
+
memoryRecallFailed: () => memoryRecallFailed,
|
|
57
|
+
memoryRecallStart: () => memoryRecallStart,
|
|
58
|
+
memoryRecallSuccess: () => memoryRecallSuccess,
|
|
59
|
+
memorySlice: () => memorySlice,
|
|
60
|
+
memoryStoreFailed: () => memoryStoreFailed,
|
|
61
|
+
memoryStoreStart: () => memoryStoreStart,
|
|
62
|
+
memoryStoreSuccess: () => memoryStoreSuccess,
|
|
63
|
+
npcSlice: () => npcSlice,
|
|
137
64
|
pipe: () => pipe,
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
65
|
+
processNPC: () => processNPC,
|
|
66
|
+
remoteExportSoulThunk: () => remoteExportSoulThunk,
|
|
67
|
+
removeNPC: () => removeNPC,
|
|
68
|
+
sdkApi: () => sdkApi,
|
|
69
|
+
selectActiveNPC: () => selectActiveNPC,
|
|
70
|
+
selectActiveNpcId: () => selectActiveNpcId,
|
|
71
|
+
selectAllMemories: () => selectAllMemories,
|
|
72
|
+
selectAllNPCs: () => selectAllNPCs,
|
|
73
|
+
selectLastRecalledMemories: () => selectLastRecalledMemories,
|
|
74
|
+
selectMemoryById: () => selectMemoryById,
|
|
75
|
+
selectNPCById: () => selectNPCById,
|
|
76
|
+
selectNPCEntities: () => selectNPCEntities,
|
|
77
|
+
selectNPCIds: () => selectNPCIds,
|
|
78
|
+
selectTotalNPCs: () => selectTotalNPCs,
|
|
79
|
+
setActiveNPC: () => setActiveNPC,
|
|
80
|
+
setCortexStatus: () => setCortexStatus,
|
|
81
|
+
setHistory: () => setHistory,
|
|
82
|
+
setLastAction: () => setLastAction,
|
|
83
|
+
setNPCInfo: () => setNPCInfo,
|
|
84
|
+
setNPCState: () => setNPCState,
|
|
85
|
+
soulSlice: () => soulSlice,
|
|
86
|
+
speakNPC: () => speakNPC,
|
|
87
|
+
startGhostThunk: () => startGhostThunk,
|
|
88
|
+
stopGhostThunk: () => stopGhostThunk,
|
|
89
|
+
store: () => store,
|
|
141
90
|
streamFromCortex: () => streamFromCortex,
|
|
142
91
|
streamFromCortexWithDelay: () => streamFromCortexWithDelay,
|
|
143
92
|
streamToCallback: () => streamToCallback,
|
|
144
93
|
streamToString: () => streamToString,
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
waitForGhostCompletion: () => waitForGhostCompletion
|
|
94
|
+
updateNPCState: () => updateNPCState,
|
|
95
|
+
updateNPCStateLocally: () => updateNPCStateLocally,
|
|
96
|
+
validateBridgeThunk: () => validateBridgeThunk
|
|
149
97
|
});
|
|
150
98
|
module.exports = __toCommonJS(index_exports);
|
|
151
99
|
|
|
152
|
-
// src/
|
|
100
|
+
// src/npc.ts
|
|
153
101
|
var createInitialState = (partial) => ({ ...partial });
|
|
154
|
-
var
|
|
102
|
+
var updateNPCStateLocally = (currentState, updates) => ({
|
|
155
103
|
...currentState,
|
|
156
104
|
...updates
|
|
157
105
|
});
|
|
158
|
-
var exportToSoul = (
|
|
159
|
-
id:
|
|
106
|
+
var exportToSoul = (npcId, name, persona, state, memories) => ({
|
|
107
|
+
id: npcId,
|
|
160
108
|
version: "1.0.0",
|
|
161
109
|
name,
|
|
162
110
|
persona,
|
|
163
111
|
memories: [...memories],
|
|
164
112
|
state: { ...state }
|
|
165
113
|
});
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
114
|
+
|
|
115
|
+
// src/bridgeSlice.ts
|
|
116
|
+
var import_toolkit = require("@reduxjs/toolkit");
|
|
117
|
+
|
|
118
|
+
// src/apiSlice.ts
|
|
119
|
+
var import_query = require("@reduxjs/toolkit/query");
|
|
120
|
+
var sdkApi = (0, import_query.createApi)({
|
|
121
|
+
reducerPath: "forbocApi",
|
|
122
|
+
baseQuery: (0, import_query.fetchBaseQuery)({
|
|
123
|
+
baseUrl: "/",
|
|
124
|
+
prepareHeaders: (headers, { getState }) => {
|
|
125
|
+
return headers;
|
|
126
|
+
}
|
|
127
|
+
}),
|
|
128
|
+
tagTypes: ["NPC", "Memory", "Cortex", "Ghost", "Soul", "Bridge"],
|
|
129
|
+
endpoints: (builder) => ({
|
|
130
|
+
// NPC Endpoints
|
|
131
|
+
postDirective: builder.mutation({
|
|
132
|
+
query: ({ npcId, request, apiUrl, apiKey }) => ({
|
|
133
|
+
url: `${apiUrl}/npcs/${npcId}/directive`,
|
|
134
|
+
method: "POST",
|
|
135
|
+
headers: apiKey ? { "Authorization": `Bearer ${apiKey}` } : {},
|
|
136
|
+
body: request
|
|
137
|
+
}),
|
|
138
|
+
invalidatesTags: ["NPC"],
|
|
139
|
+
transformResponse: (response) => response
|
|
140
|
+
}),
|
|
141
|
+
postContext: builder.mutation({
|
|
142
|
+
query: ({ npcId, request, apiUrl, apiKey }) => ({
|
|
143
|
+
url: `${apiUrl}/npcs/${npcId}/context`,
|
|
144
|
+
method: "POST",
|
|
145
|
+
headers: apiKey ? { "Authorization": `Bearer ${apiKey}` } : {},
|
|
146
|
+
body: request
|
|
147
|
+
}),
|
|
148
|
+
invalidatesTags: (result, error, { npcId }) => [{ type: "NPC", id: npcId }],
|
|
149
|
+
transformResponse: (response) => response
|
|
150
|
+
}),
|
|
151
|
+
postVerdict: builder.mutation({
|
|
152
|
+
query: ({ npcId, request, apiUrl, apiKey }) => ({
|
|
153
|
+
url: `${apiUrl}/npcs/${npcId}/verdict`,
|
|
154
|
+
method: "POST",
|
|
155
|
+
headers: apiKey ? { "Authorization": `Bearer ${apiKey}` } : {},
|
|
156
|
+
body: request
|
|
157
|
+
}),
|
|
158
|
+
invalidatesTags: (result, error, { npcId }) => [{ type: "NPC", id: npcId }],
|
|
159
|
+
transformResponse: (response) => {
|
|
160
|
+
const action = response.action ? {
|
|
161
|
+
type: response.action.gaType || response.action.type,
|
|
162
|
+
reason: response.action.actionReason || response.action.reason,
|
|
163
|
+
target: response.action.actionTarget || response.action.target,
|
|
164
|
+
signature: response.action.signature
|
|
165
|
+
} : void 0;
|
|
166
|
+
return {
|
|
167
|
+
...response,
|
|
168
|
+
action
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
}),
|
|
172
|
+
postSpeak: builder.mutation({
|
|
173
|
+
query: ({ npcId, request, apiUrl, apiKey }) => ({
|
|
174
|
+
url: `${apiUrl}/npcs/${npcId}/speak`,
|
|
175
|
+
method: "POST",
|
|
176
|
+
headers: apiKey ? { "Authorization": `Bearer ${apiKey}` } : {},
|
|
177
|
+
body: request
|
|
178
|
+
}),
|
|
179
|
+
invalidatesTags: (result, error, { npcId }) => [{ type: "NPC", id: npcId }],
|
|
180
|
+
transformResponse: (response) => response
|
|
181
|
+
}),
|
|
182
|
+
postDialogue: builder.mutation({
|
|
183
|
+
query: ({ npcId, request, apiUrl, apiKey }) => ({
|
|
184
|
+
url: `${apiUrl}/npcs/${npcId}/dialogue`,
|
|
185
|
+
method: "POST",
|
|
186
|
+
headers: apiKey ? { "Authorization": `Bearer ${apiKey}` } : {},
|
|
187
|
+
body: request
|
|
188
|
+
}),
|
|
189
|
+
invalidatesTags: (result, error, { npcId }) => [{ type: "NPC", id: npcId }],
|
|
190
|
+
transformResponse: (response) => response
|
|
191
|
+
}),
|
|
192
|
+
// Ghost Endpoints
|
|
193
|
+
postGhostRun: builder.mutation({
|
|
194
|
+
query: ({ request, apiUrl }) => ({ url: `${apiUrl}/ghost/run`, method: "POST", body: request }),
|
|
195
|
+
invalidatesTags: ["Ghost"],
|
|
196
|
+
transformResponse: (response) => response
|
|
197
|
+
}),
|
|
198
|
+
getGhostStatus: builder.query({
|
|
199
|
+
query: ({ sessionId, apiUrl }) => ({ url: `${apiUrl}/ghost/${sessionId}/status`, method: "GET" }),
|
|
200
|
+
providesTags: (result, error, { sessionId }) => [{ type: "Ghost", id: sessionId }],
|
|
201
|
+
transformResponse: (response) => response
|
|
202
|
+
}),
|
|
203
|
+
getGhostResults: builder.query({
|
|
204
|
+
query: ({ sessionId, apiUrl }) => ({ url: `${apiUrl}/ghost/${sessionId}/results`, method: "GET" }),
|
|
205
|
+
providesTags: (result, error, { sessionId }) => [{ type: "Ghost", id: sessionId }],
|
|
206
|
+
transformResponse: (response) => response
|
|
207
|
+
}),
|
|
208
|
+
postGhostStop: builder.mutation({
|
|
209
|
+
query: ({ sessionId, apiUrl }) => ({ url: `${apiUrl}/ghost/${sessionId}/stop`, method: "POST" }),
|
|
210
|
+
invalidatesTags: (result, error, { sessionId }) => [{ type: "Ghost", id: sessionId }],
|
|
211
|
+
transformResponse: (response) => ({ stopped: true })
|
|
212
|
+
}),
|
|
213
|
+
getGhostHistory: builder.query({
|
|
214
|
+
query: ({ limit, apiUrl }) => ({ url: `${apiUrl}/ghost/history?limit=${limit}`, method: "GET" }),
|
|
215
|
+
providesTags: ["Ghost"],
|
|
216
|
+
transformResponse: (response) => response
|
|
217
|
+
}),
|
|
218
|
+
// Soul Endpoints
|
|
219
|
+
postSoulExport: builder.mutation({
|
|
220
|
+
query: ({ npcId, request, apiUrl }) => ({ url: `${apiUrl}/npcs/${npcId}/soul/export`, method: "POST", body: request }),
|
|
221
|
+
invalidatesTags: ["Soul"],
|
|
222
|
+
transformResponse: (response) => response
|
|
223
|
+
}),
|
|
224
|
+
getSoulImport: builder.query({
|
|
225
|
+
query: ({ txId, apiUrl }) => ({ url: `${apiUrl}/souls/${txId}`, method: "GET" }),
|
|
226
|
+
providesTags: (result, error, { txId }) => [{ type: "Soul", id: txId }],
|
|
227
|
+
transformResponse: (response) => response
|
|
228
|
+
}),
|
|
229
|
+
getSouls: builder.query({
|
|
230
|
+
query: ({ limit, apiUrl }) => ({ url: `${apiUrl}/souls?limit=${limit}`, method: "GET" }),
|
|
231
|
+
providesTags: ["Soul"],
|
|
232
|
+
transformResponse: (response) => response
|
|
233
|
+
}),
|
|
234
|
+
// Bridge Endpoints
|
|
235
|
+
postBridgeValidate: builder.mutation({
|
|
236
|
+
query: ({ request, npcId, apiUrl }) => ({
|
|
237
|
+
url: npcId ? `${apiUrl}/bridge/validate/${npcId}` : `${apiUrl}/bridge/validate`,
|
|
238
|
+
method: "POST",
|
|
239
|
+
body: request
|
|
240
|
+
}),
|
|
241
|
+
invalidatesTags: ["Bridge"],
|
|
242
|
+
transformResponse: (response) => response.brResult || response
|
|
243
|
+
}),
|
|
244
|
+
getBridgeRules: builder.query({
|
|
245
|
+
query: ({ apiUrl }) => ({ url: `${apiUrl}/rules`, method: "GET" }),
|
|
246
|
+
providesTags: ["Bridge"],
|
|
247
|
+
transformResponse: (response) => response
|
|
248
|
+
}),
|
|
249
|
+
postBridgePreset: builder.mutation({
|
|
250
|
+
query: ({ presetName, apiUrl }) => ({ url: `${apiUrl}/rules/presets/${presetName}`, method: "POST" }),
|
|
251
|
+
invalidatesTags: ["Bridge"],
|
|
252
|
+
transformResponse: (response) => response
|
|
253
|
+
}),
|
|
254
|
+
// Cortex Remote Endpoint
|
|
255
|
+
postCortexComplete: builder.mutation({
|
|
256
|
+
query: ({ cortexId, prompt, options, apiUrl, apiKey }) => ({
|
|
257
|
+
url: `${apiUrl}/cortex/${cortexId}/complete`,
|
|
258
|
+
method: "POST",
|
|
259
|
+
headers: apiKey ? { "Authorization": `Bearer ${apiKey}` } : {},
|
|
260
|
+
body: { prompt, ...options }
|
|
261
|
+
}),
|
|
262
|
+
invalidatesTags: ["Cortex"],
|
|
263
|
+
transformResponse: (response) => response
|
|
264
|
+
}),
|
|
265
|
+
// System Endpoints
|
|
266
|
+
getApiStatus: builder.query({
|
|
267
|
+
query: ({ apiUrl }) => ({ url: `${apiUrl}/status`, method: "GET" }),
|
|
268
|
+
transformResponse: (response) => response
|
|
269
|
+
})
|
|
270
|
+
})
|
|
271
|
+
});
|
|
272
|
+
|
|
273
|
+
// src/bridgeSlice.ts
|
|
274
|
+
var initialState = {
|
|
275
|
+
activePresets: [],
|
|
276
|
+
lastValidation: null,
|
|
277
|
+
status: "idle",
|
|
278
|
+
error: null
|
|
171
279
|
};
|
|
172
|
-
var
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
const ctxRes = await fetch(`${apiUrl}/agents/${agentId}/context`, {
|
|
197
|
-
method: "POST",
|
|
198
|
-
headers: authHeaders,
|
|
199
|
-
body: JSON.stringify({ memories: recalledMemories, observation: input, agentState: currentState })
|
|
200
|
-
});
|
|
201
|
-
if (!ctxRes.ok) throw new Error(`API Context Error: ${ctxRes.status}`);
|
|
202
|
-
const contextData = await ctxRes.json();
|
|
203
|
-
const generatedText = await cortex.complete(contextData.prompt, {
|
|
204
|
-
maxTokens: contextData.constraints.maxTokens,
|
|
205
|
-
temperature: contextData.constraints.temperature,
|
|
206
|
-
stop: contextData.constraints.stop
|
|
207
|
-
});
|
|
208
|
-
const verRes = await fetch(`${apiUrl}/agents/${agentId}/verdict`, {
|
|
209
|
-
method: "POST",
|
|
210
|
-
headers: authHeaders,
|
|
211
|
-
body: JSON.stringify({ generatedOutput: generatedText, observation: input, agentState: currentState })
|
|
212
|
-
});
|
|
213
|
-
if (!verRes.ok) throw new Error(`API Verdict Error: ${verRes.status}`);
|
|
214
|
-
const verdictData = await verRes.json();
|
|
215
|
-
if (!verdictData.valid) {
|
|
216
|
-
return { dialogue: "... [Blocked]", action: { type: "BLOCKED", reason: "Validation Failed" } };
|
|
280
|
+
var validateBridgeThunk = (0, import_toolkit.createAsyncThunk)(
|
|
281
|
+
"bridge/validate",
|
|
282
|
+
async ({ action, context, npcId, apiUrl }, { dispatch: dispatch2, rejectWithValue }) => {
|
|
283
|
+
try {
|
|
284
|
+
const url = apiUrl || "https://api.forboc.ai";
|
|
285
|
+
const data = await dispatch2(sdkApi.endpoints.postBridgeValidate.initiate({
|
|
286
|
+
request: { action, context },
|
|
287
|
+
npcId,
|
|
288
|
+
apiUrl: url
|
|
289
|
+
})).unwrap();
|
|
290
|
+
return data;
|
|
291
|
+
} catch (e) {
|
|
292
|
+
return rejectWithValue(e.message || "Bridge validation failed");
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
);
|
|
296
|
+
var loadBridgePresetThunk = (0, import_toolkit.createAsyncThunk)(
|
|
297
|
+
"bridge/loadPreset",
|
|
298
|
+
async ({ presetName, apiUrl }, { dispatch: dispatch2, rejectWithValue }) => {
|
|
299
|
+
try {
|
|
300
|
+
const url = apiUrl || "https://api.forboc.ai";
|
|
301
|
+
return await dispatch2(sdkApi.endpoints.postBridgePreset.initiate({ presetName, apiUrl: url })).unwrap();
|
|
302
|
+
} catch (e) {
|
|
303
|
+
return rejectWithValue(e.message || "Failed to load preset");
|
|
217
304
|
}
|
|
218
|
-
|
|
219
|
-
|
|
305
|
+
}
|
|
306
|
+
);
|
|
307
|
+
var getBridgeRulesThunk = (0, import_toolkit.createAsyncThunk)(
|
|
308
|
+
"bridge/rules",
|
|
309
|
+
async ({ apiUrl }, { dispatch: dispatch2, rejectWithValue }) => {
|
|
310
|
+
try {
|
|
311
|
+
const url = apiUrl || "https://api.forboc.ai";
|
|
312
|
+
return await dispatch2(sdkApi.endpoints.getBridgeRules.initiate({ apiUrl: url })).unwrap();
|
|
313
|
+
} catch (e) {
|
|
314
|
+
return rejectWithValue(e.message || "Failed to list rulesets");
|
|
220
315
|
}
|
|
221
|
-
|
|
222
|
-
|
|
316
|
+
}
|
|
317
|
+
);
|
|
318
|
+
var bridgeSlice = (0, import_toolkit.createSlice)({
|
|
319
|
+
name: "bridge",
|
|
320
|
+
initialState,
|
|
321
|
+
reducers: {
|
|
322
|
+
clearBridgeValidation: (state) => {
|
|
323
|
+
state.lastValidation = null;
|
|
324
|
+
state.status = "idle";
|
|
325
|
+
state.error = null;
|
|
223
326
|
}
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
327
|
+
},
|
|
328
|
+
extraReducers: (builder) => {
|
|
329
|
+
builder.addCase(validateBridgeThunk.pending, (state) => {
|
|
330
|
+
state.status = "validating";
|
|
331
|
+
state.error = null;
|
|
332
|
+
}).addCase(validateBridgeThunk.fulfilled, (state, action) => {
|
|
333
|
+
state.status = "idle";
|
|
334
|
+
state.lastValidation = action.payload;
|
|
335
|
+
}).addCase(validateBridgeThunk.rejected, (state, action) => {
|
|
336
|
+
state.status = "error";
|
|
337
|
+
state.error = action.payload;
|
|
338
|
+
state.lastValidation = { valid: false, reason: action.payload };
|
|
339
|
+
}).addCase(loadBridgePresetThunk.pending, (state) => {
|
|
340
|
+
state.status = "loading_preset";
|
|
341
|
+
state.error = null;
|
|
342
|
+
}).addCase(loadBridgePresetThunk.fulfilled, (state, action) => {
|
|
343
|
+
state.status = "idle";
|
|
344
|
+
if (!state.activePresets.find((p) => p.id === action.payload.id)) {
|
|
345
|
+
state.activePresets.push(action.payload);
|
|
346
|
+
}
|
|
347
|
+
}).addCase(loadBridgePresetThunk.rejected, (state, action) => {
|
|
348
|
+
state.status = "error";
|
|
349
|
+
state.error = action.payload;
|
|
350
|
+
}).addCase(getBridgeRulesThunk.fulfilled, (state, action) => {
|
|
246
351
|
});
|
|
247
|
-
if (!res.ok) throw new Error(`API Dialogue Error: ${res.status}`);
|
|
248
|
-
const data = await res.json();
|
|
249
|
-
return data.diagReply;
|
|
250
|
-
};
|
|
251
|
-
const exportSoul2 = async () => {
|
|
252
|
-
const memories = config.memory ? await config.memory.export().catch(() => []) : [];
|
|
253
|
-
return exportToSoul(agentId, "Agent", config.persona, _state, memories);
|
|
254
|
-
};
|
|
255
|
-
const exportSoulToArweave = async (soulConfig) => {
|
|
256
|
-
const soul = await exportSoul2();
|
|
257
|
-
const { exportSoul: exportFunc } = await Promise.resolve().then(() => (init_soul(), soul_exports));
|
|
258
|
-
return exportFunc(agentId, soul, { ...soulConfig, apiUrl });
|
|
259
|
-
};
|
|
260
|
-
return { process, speak, dialogue, reply: speak, getState, setState, export: exportSoul2, exportSoul: exportSoulToArweave };
|
|
261
|
-
};
|
|
262
|
-
var fromSoul = async (soul, cortex, memory) => {
|
|
263
|
-
const agent = createAgent({
|
|
264
|
-
id: soul.id,
|
|
265
|
-
cortex,
|
|
266
|
-
memory: memory || null,
|
|
267
|
-
persona: soul.persona,
|
|
268
|
-
initialState: soul.state
|
|
269
|
-
});
|
|
270
|
-
if (memory && soul.memories && soul.memories.length > 0) {
|
|
271
|
-
await memory.import(soul.memories).catch((e) => console.warn("Memory hydration failed:", e));
|
|
272
352
|
}
|
|
273
|
-
|
|
353
|
+
});
|
|
354
|
+
var { clearBridgeValidation } = bridgeSlice.actions;
|
|
355
|
+
var bridgeSlice_default = bridgeSlice.reducer;
|
|
356
|
+
|
|
357
|
+
// src/soulSlice.ts
|
|
358
|
+
var import_toolkit2 = require("@reduxjs/toolkit");
|
|
359
|
+
var initialState2 = {
|
|
360
|
+
exportStatus: "idle",
|
|
361
|
+
importStatus: "idle",
|
|
362
|
+
lastExport: null,
|
|
363
|
+
lastImport: null,
|
|
364
|
+
availableSouls: [],
|
|
365
|
+
error: null
|
|
274
366
|
};
|
|
367
|
+
var remoteExportSoulThunk = (0, import_toolkit2.createAsyncThunk)(
|
|
368
|
+
"soul/export",
|
|
369
|
+
async ({ npcId: argNpcId, apiUrl, memories = [] }, { getState, dispatch: dispatch2, rejectWithValue }) => {
|
|
370
|
+
try {
|
|
371
|
+
const state = getState().npc;
|
|
372
|
+
const npcId = argNpcId || state.activeNpcId;
|
|
373
|
+
const npc = state.entities[npcId];
|
|
374
|
+
if (!npc) throw new Error(`NPC ${npcId} not found`);
|
|
375
|
+
const url = apiUrl || "https://api.forboc.ai";
|
|
376
|
+
const result = await dispatch2(sdkApi.endpoints.postSoulExport.initiate({
|
|
377
|
+
npcId,
|
|
378
|
+
request: { npcIdRef: npcId, persona: npc.persona || "NPC", npcState: npc.state },
|
|
379
|
+
apiUrl: url
|
|
380
|
+
})).unwrap();
|
|
381
|
+
return {
|
|
382
|
+
txId: result.txId,
|
|
383
|
+
url: result.arweaveUrl,
|
|
384
|
+
soul: result.soul
|
|
385
|
+
};
|
|
386
|
+
} catch (e) {
|
|
387
|
+
return rejectWithValue(e.message || "Soul export failed");
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
);
|
|
391
|
+
var importSoulFromArweaveThunk = (0, import_toolkit2.createAsyncThunk)(
|
|
392
|
+
"soul/import",
|
|
393
|
+
async ({ txId, apiUrl }, { dispatch: dispatch2, rejectWithValue }) => {
|
|
394
|
+
try {
|
|
395
|
+
const url = apiUrl || "https://api.forboc.ai";
|
|
396
|
+
const data = await dispatch2(sdkApi.endpoints.getSoulImport.initiate({ txId, apiUrl: url })).unwrap();
|
|
397
|
+
return data;
|
|
398
|
+
} catch (e) {
|
|
399
|
+
return rejectWithValue(e.message || "Soul import failed");
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
);
|
|
403
|
+
var getSoulListThunk = (0, import_toolkit2.createAsyncThunk)(
|
|
404
|
+
"soul/list",
|
|
405
|
+
async ({ limit = 50, apiUrl }, { dispatch: dispatch2, rejectWithValue }) => {
|
|
406
|
+
try {
|
|
407
|
+
const url = apiUrl || "https://api.forboc.ai";
|
|
408
|
+
const data = await dispatch2(sdkApi.endpoints.getSouls.initiate({ limit, apiUrl: url })).unwrap();
|
|
409
|
+
return data.souls || [];
|
|
410
|
+
} catch (e) {
|
|
411
|
+
return rejectWithValue(e.message || "Failed to list souls");
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
);
|
|
415
|
+
var soulSlice = (0, import_toolkit2.createSlice)({
|
|
416
|
+
name: "soul",
|
|
417
|
+
initialState: initialState2,
|
|
418
|
+
reducers: {
|
|
419
|
+
clearSoulState: (state) => {
|
|
420
|
+
state.exportStatus = "idle";
|
|
421
|
+
state.importStatus = "idle";
|
|
422
|
+
state.lastExport = null;
|
|
423
|
+
state.lastImport = null;
|
|
424
|
+
state.error = null;
|
|
425
|
+
}
|
|
426
|
+
},
|
|
427
|
+
extraReducers: (builder) => {
|
|
428
|
+
builder.addCase(remoteExportSoulThunk.pending, (state) => {
|
|
429
|
+
state.exportStatus = "exporting";
|
|
430
|
+
state.error = null;
|
|
431
|
+
}).addCase(remoteExportSoulThunk.fulfilled, (state, action) => {
|
|
432
|
+
state.exportStatus = "success";
|
|
433
|
+
state.lastExport = action.payload;
|
|
434
|
+
}).addCase(remoteExportSoulThunk.rejected, (state, action) => {
|
|
435
|
+
state.exportStatus = "failed";
|
|
436
|
+
state.error = action.payload;
|
|
437
|
+
}).addCase(importSoulFromArweaveThunk.pending, (state) => {
|
|
438
|
+
state.importStatus = "importing";
|
|
439
|
+
state.error = null;
|
|
440
|
+
}).addCase(importSoulFromArweaveThunk.fulfilled, (state, action) => {
|
|
441
|
+
state.importStatus = "success";
|
|
442
|
+
state.lastImport = action.payload;
|
|
443
|
+
}).addCase(importSoulFromArweaveThunk.rejected, (state, action) => {
|
|
444
|
+
state.importStatus = "failed";
|
|
445
|
+
state.error = action.payload;
|
|
446
|
+
}).addCase(getSoulListThunk.fulfilled, (state, action) => {
|
|
447
|
+
state.availableSouls = action.payload;
|
|
448
|
+
});
|
|
449
|
+
}
|
|
450
|
+
});
|
|
451
|
+
var { clearSoulState } = soulSlice.actions;
|
|
452
|
+
var soulSlice_default = soulSlice.reducer;
|
|
275
453
|
|
|
276
|
-
// src/
|
|
277
|
-
var
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
454
|
+
// src/ghostSlice.ts
|
|
455
|
+
var import_toolkit3 = require("@reduxjs/toolkit");
|
|
456
|
+
var initialState3 = {
|
|
457
|
+
activeSessionId: null,
|
|
458
|
+
status: null,
|
|
459
|
+
progress: 0,
|
|
460
|
+
results: null,
|
|
461
|
+
history: [],
|
|
462
|
+
loading: false,
|
|
463
|
+
error: null
|
|
464
|
+
};
|
|
465
|
+
var startGhostThunk = (0, import_toolkit3.createAsyncThunk)(
|
|
466
|
+
"ghost/start",
|
|
467
|
+
async (config, { dispatch: dispatch2, rejectWithValue }) => {
|
|
282
468
|
try {
|
|
283
|
-
const
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
});
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
}
|
|
292
|
-
const data = await response.json();
|
|
293
|
-
return data.brResult || data;
|
|
469
|
+
const apiUrl = config.apiUrl || "https://api.forboc.ai";
|
|
470
|
+
const data = await dispatch2(sdkApi.endpoints.postGhostRun.initiate({
|
|
471
|
+
request: { testSuite: config.testSuite, duration: config.duration ?? 300 },
|
|
472
|
+
apiUrl
|
|
473
|
+
})).unwrap();
|
|
474
|
+
return {
|
|
475
|
+
sessionId: data.sessionId,
|
|
476
|
+
status: data.runStatus
|
|
477
|
+
};
|
|
294
478
|
} catch (e) {
|
|
295
|
-
|
|
479
|
+
return rejectWithValue(e.message || "Failed to start Ghost");
|
|
480
|
+
}
|
|
481
|
+
}
|
|
482
|
+
);
|
|
483
|
+
var getGhostStatusThunk = (0, import_toolkit3.createAsyncThunk)(
|
|
484
|
+
"ghost/status",
|
|
485
|
+
async ({ sessionId, apiUrl }, { dispatch: dispatch2, getState, rejectWithValue }) => {
|
|
486
|
+
try {
|
|
487
|
+
const state = getState().ghost;
|
|
488
|
+
const targetSession = sessionId || state.activeSessionId;
|
|
489
|
+
if (!targetSession) throw new Error("No active Ghost session");
|
|
490
|
+
const url = apiUrl || "https://api.forboc.ai";
|
|
491
|
+
const data = await dispatch2(sdkApi.endpoints.getGhostStatus.initiate({ sessionId: targetSession, apiUrl: url })).unwrap();
|
|
296
492
|
return {
|
|
297
|
-
|
|
298
|
-
|
|
493
|
+
sessionId: data.ghostSessionId,
|
|
494
|
+
status: data.ghostStatus,
|
|
495
|
+
progress: data.ghostProgress,
|
|
496
|
+
startedAt: data.ghostStartedAt,
|
|
497
|
+
duration: data.ghostDuration || 0,
|
|
498
|
+
errors: data.ghostErrors
|
|
299
499
|
};
|
|
500
|
+
} catch (e) {
|
|
501
|
+
return rejectWithValue(e.message || "Failed to get ghost status");
|
|
300
502
|
}
|
|
301
|
-
};
|
|
302
|
-
const listRulesets = async () => {
|
|
303
|
-
const response = await fetch(`${apiUrl}/rules`);
|
|
304
|
-
if (!response.ok) return [];
|
|
305
|
-
return response.json();
|
|
306
|
-
};
|
|
307
|
-
return { validate, listRulesets };
|
|
308
|
-
};
|
|
309
|
-
var validateAction = async (action, context = {}, config = {}) => {
|
|
310
|
-
const bridge = createBridge(config);
|
|
311
|
-
return bridge.validate(action, context);
|
|
312
|
-
};
|
|
313
|
-
var loadPreset = async (presetName, apiUrl = "https://api.forboc.ai") => {
|
|
314
|
-
const response = await fetch(`${apiUrl}/rules/presets/${presetName}`, {
|
|
315
|
-
method: "POST"
|
|
316
|
-
});
|
|
317
|
-
if (!response.ok) {
|
|
318
|
-
throw new Error(`Failed to load preset '${presetName}': ${response.statusText}`);
|
|
319
503
|
}
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
504
|
+
);
|
|
505
|
+
var getGhostResultsThunk = (0, import_toolkit3.createAsyncThunk)(
|
|
506
|
+
"ghost/results",
|
|
507
|
+
async ({ sessionId, apiUrl }, { dispatch: dispatch2, getState, rejectWithValue }) => {
|
|
508
|
+
try {
|
|
509
|
+
const state = getState().ghost;
|
|
510
|
+
const targetSession = sessionId || state.activeSessionId;
|
|
511
|
+
if (!targetSession) throw new Error("No active Ghost session");
|
|
512
|
+
const url = apiUrl || "https://api.forboc.ai";
|
|
513
|
+
const data = await dispatch2(sdkApi.endpoints.getGhostResults.initiate({ sessionId: targetSession, apiUrl: url })).unwrap();
|
|
514
|
+
return {
|
|
515
|
+
sessionId: data.resultsSessionId,
|
|
516
|
+
totalTests: data.resultsTotalTests,
|
|
517
|
+
passed: data.resultsPassed,
|
|
518
|
+
failed: data.resultsFailed,
|
|
519
|
+
skipped: data.resultsSkipped,
|
|
520
|
+
duration: data.resultsDuration,
|
|
521
|
+
tests: (data.resultsTests || []).map((t) => ({
|
|
522
|
+
name: t.testName,
|
|
523
|
+
passed: t.testPassed,
|
|
524
|
+
duration: t.testDuration,
|
|
525
|
+
error: t.testError,
|
|
526
|
+
screenshot: t.testScreenshot
|
|
527
|
+
})),
|
|
528
|
+
coverage: data.resultsCoverage,
|
|
529
|
+
metrics: Object.fromEntries(data.resultsMetrics || [])
|
|
530
|
+
};
|
|
531
|
+
} catch (e) {
|
|
532
|
+
return rejectWithValue(e.message || "Failed to get ghost results");
|
|
533
|
+
}
|
|
534
|
+
}
|
|
535
|
+
);
|
|
536
|
+
var stopGhostThunk = (0, import_toolkit3.createAsyncThunk)(
|
|
537
|
+
"ghost/stop",
|
|
538
|
+
async ({ sessionId, apiUrl }, { dispatch: dispatch2, getState, rejectWithValue }) => {
|
|
539
|
+
try {
|
|
540
|
+
const state = getState().ghost;
|
|
541
|
+
const targetSession = sessionId || state.activeSessionId;
|
|
542
|
+
if (!targetSession) throw new Error("No active Ghost session");
|
|
543
|
+
const url = apiUrl || "https://api.forboc.ai";
|
|
544
|
+
await dispatch2(sdkApi.endpoints.postGhostStop.initiate({ sessionId: targetSession, apiUrl: url })).unwrap();
|
|
545
|
+
return { stopped: true };
|
|
546
|
+
} catch (e) {
|
|
547
|
+
return { stopped: true };
|
|
548
|
+
}
|
|
549
|
+
}
|
|
550
|
+
);
|
|
551
|
+
var getGhostHistoryThunk = (0, import_toolkit3.createAsyncThunk)(
|
|
552
|
+
"ghost/history",
|
|
553
|
+
async ({ limit = 10, apiUrl }, { dispatch: dispatch2, rejectWithValue }) => {
|
|
554
|
+
try {
|
|
555
|
+
const url = apiUrl || "https://api.forboc.ai";
|
|
556
|
+
const data = await dispatch2(sdkApi.endpoints.getGhostHistory.initiate({ limit, apiUrl: url })).unwrap();
|
|
557
|
+
return (data.sessions || []).map((s) => ({
|
|
558
|
+
sessionId: s.sessionId,
|
|
559
|
+
testSuite: s.testSuite,
|
|
560
|
+
startedAt: s.startedAt,
|
|
561
|
+
completedAt: s.completedAt,
|
|
562
|
+
status: s.status,
|
|
563
|
+
passRate: s.passRate
|
|
564
|
+
}));
|
|
565
|
+
} catch (e) {
|
|
566
|
+
return rejectWithValue(e.message || "Failed to get ghost history");
|
|
567
|
+
}
|
|
568
|
+
}
|
|
569
|
+
);
|
|
570
|
+
var ghostSlice = (0, import_toolkit3.createSlice)({
|
|
571
|
+
name: "ghost",
|
|
572
|
+
initialState: initialState3,
|
|
573
|
+
reducers: {
|
|
574
|
+
clearGhostSession: (state) => {
|
|
575
|
+
state.activeSessionId = null;
|
|
576
|
+
state.status = null;
|
|
577
|
+
state.progress = 0;
|
|
578
|
+
state.results = null;
|
|
579
|
+
}
|
|
580
|
+
},
|
|
581
|
+
extraReducers: (builder) => {
|
|
582
|
+
builder.addCase(startGhostThunk.pending, (state) => {
|
|
583
|
+
state.loading = true;
|
|
584
|
+
state.error = null;
|
|
585
|
+
}).addCase(startGhostThunk.fulfilled, (state, action) => {
|
|
586
|
+
state.loading = false;
|
|
587
|
+
state.activeSessionId = action.payload.sessionId;
|
|
588
|
+
state.status = "running";
|
|
589
|
+
state.progress = 0;
|
|
590
|
+
}).addCase(startGhostThunk.rejected, (state, action) => {
|
|
591
|
+
state.loading = false;
|
|
592
|
+
state.error = action.payload;
|
|
593
|
+
}).addCase(getGhostStatusThunk.fulfilled, (state, action) => {
|
|
594
|
+
state.status = action.payload.status;
|
|
595
|
+
state.progress = action.payload.progress;
|
|
596
|
+
}).addCase(getGhostResultsThunk.fulfilled, (state, action) => {
|
|
597
|
+
state.results = action.payload;
|
|
598
|
+
state.status = "completed";
|
|
599
|
+
}).addCase(stopGhostThunk.fulfilled, (state) => {
|
|
600
|
+
state.status = "failed";
|
|
601
|
+
}).addCase(getGhostHistoryThunk.fulfilled, (state, action) => {
|
|
602
|
+
state.history = action.payload;
|
|
603
|
+
});
|
|
604
|
+
}
|
|
605
|
+
});
|
|
606
|
+
var { clearGhostSession } = ghostSlice.actions;
|
|
607
|
+
var ghostSlice_default = ghostSlice.reducer;
|
|
325
608
|
|
|
326
609
|
// src/utils.ts
|
|
610
|
+
var SDK_VERSION = "0.5.9";
|
|
611
|
+
var generateNPCId = () => `ag_${Date.now().toString(36)}`;
|
|
327
612
|
var delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
328
613
|
var pipe = (...fns) => (initialValue) => fns.reduce((acc, fn) => fn(acc), initialValue);
|
|
329
614
|
var memoiseAsync = (fn) => {
|
|
@@ -350,161 +635,6 @@ var memoise = (fn) => {
|
|
|
350
635
|
};
|
|
351
636
|
};
|
|
352
637
|
|
|
353
|
-
// src/ghost.ts
|
|
354
|
-
var DEFAULT_API_URL = "https://api.forboc.ai";
|
|
355
|
-
var startGhostSession = async (config) => {
|
|
356
|
-
const apiUrl = config.apiUrl || DEFAULT_API_URL;
|
|
357
|
-
const response = await fetch(`${apiUrl}/ghost/run`, {
|
|
358
|
-
method: "POST",
|
|
359
|
-
headers: { "Content-Type": "application/json" },
|
|
360
|
-
body: JSON.stringify({
|
|
361
|
-
testSuite: config.testSuite,
|
|
362
|
-
duration: config.duration
|
|
363
|
-
})
|
|
364
|
-
});
|
|
365
|
-
if (!response.ok) throw new Error(`Failed to start Ghost: ${response.statusText}`);
|
|
366
|
-
const data = await response.json();
|
|
367
|
-
return {
|
|
368
|
-
sessionId: data.sessionId,
|
|
369
|
-
status: data.runStatus
|
|
370
|
-
};
|
|
371
|
-
};
|
|
372
|
-
var getGhostStatus = async (sessionId, apiUrl) => {
|
|
373
|
-
const url = apiUrl || DEFAULT_API_URL;
|
|
374
|
-
const response = await fetch(`${url}/ghost/${sessionId}/status`, {
|
|
375
|
-
method: "GET",
|
|
376
|
-
headers: { "Content-Type": "application/json" }
|
|
377
|
-
});
|
|
378
|
-
if (!response.ok) throw new Error(`Failed to get status: ${response.statusText}`);
|
|
379
|
-
const data = await response.json();
|
|
380
|
-
return {
|
|
381
|
-
sessionId: data.ghostSessionId,
|
|
382
|
-
status: data.ghostStatus,
|
|
383
|
-
progress: data.ghostProgress,
|
|
384
|
-
startedAt: data.ghostStartedAt,
|
|
385
|
-
duration: data.ghostDuration,
|
|
386
|
-
errors: data.ghostErrors
|
|
387
|
-
};
|
|
388
|
-
};
|
|
389
|
-
var getGhostResults = async (sessionId, apiUrl) => {
|
|
390
|
-
const url = apiUrl || DEFAULT_API_URL;
|
|
391
|
-
const response = await fetch(`${url}/ghost/${sessionId}/results`, {
|
|
392
|
-
method: "GET",
|
|
393
|
-
headers: { "Content-Type": "application/json" }
|
|
394
|
-
});
|
|
395
|
-
if (!response.ok) throw new Error(`Failed to get results: ${response.statusText}`);
|
|
396
|
-
const data = await response.json();
|
|
397
|
-
return {
|
|
398
|
-
sessionId: data.resultsSessionId,
|
|
399
|
-
totalTests: data.resultsTotalTests,
|
|
400
|
-
passed: data.resultsPassed,
|
|
401
|
-
failed: data.resultsFailed,
|
|
402
|
-
skipped: data.resultsSkipped,
|
|
403
|
-
duration: data.resultsDuration,
|
|
404
|
-
tests: data.resultsTests.map((t) => ({
|
|
405
|
-
name: t.testName,
|
|
406
|
-
passed: t.testPassed,
|
|
407
|
-
duration: t.testDuration,
|
|
408
|
-
error: t.testError,
|
|
409
|
-
screenshot: t.testScreenshot
|
|
410
|
-
})),
|
|
411
|
-
coverage: data.resultsCoverage,
|
|
412
|
-
metrics: Object.fromEntries(data.resultsMetrics || [])
|
|
413
|
-
};
|
|
414
|
-
};
|
|
415
|
-
var pollForCompletion = async (sessionId, pollIntervalMs, timeoutMs, startTime, apiUrl, onProgress) => {
|
|
416
|
-
if (Date.now() - startTime > timeoutMs) {
|
|
417
|
-
throw new Error(`Ghost session timed out after ${timeoutMs}ms`);
|
|
418
|
-
}
|
|
419
|
-
try {
|
|
420
|
-
const status = await getGhostStatus(sessionId, apiUrl);
|
|
421
|
-
if (onProgress) onProgress(status);
|
|
422
|
-
if (status.status === "completed") return getGhostResults(sessionId, apiUrl);
|
|
423
|
-
if (status.status === "failed") throw new Error(`Ghost session failed with ${status.errors} errors`);
|
|
424
|
-
} catch (e) {
|
|
425
|
-
}
|
|
426
|
-
await delay(pollIntervalMs);
|
|
427
|
-
return pollForCompletion(sessionId, pollIntervalMs, timeoutMs, startTime, apiUrl, onProgress);
|
|
428
|
-
};
|
|
429
|
-
var waitForGhostCompletion = (sessionId, pollIntervalMs = 5e3, timeoutMs = 3e5, apiUrl, onProgress) => pollForCompletion(sessionId, pollIntervalMs, timeoutMs, Date.now(), apiUrl, onProgress);
|
|
430
|
-
var stopGhostSession = async (sessionId, apiUrl) => {
|
|
431
|
-
const url = apiUrl || DEFAULT_API_URL;
|
|
432
|
-
try {
|
|
433
|
-
const response = await fetch(`${url}/ghost/${sessionId}/stop`, { method: "POST" });
|
|
434
|
-
return { stopped: response.ok };
|
|
435
|
-
} catch (e) {
|
|
436
|
-
return { stopped: true };
|
|
437
|
-
}
|
|
438
|
-
};
|
|
439
|
-
var getGhostHistory = async (limit = 10, apiUrl) => {
|
|
440
|
-
const url = apiUrl || DEFAULT_API_URL;
|
|
441
|
-
try {
|
|
442
|
-
const response = await fetch(`${url}/ghost/history?limit=${limit}`);
|
|
443
|
-
if (!response.ok) return [];
|
|
444
|
-
const data = await response.json();
|
|
445
|
-
return data.sessions.map((s) => ({
|
|
446
|
-
sessionId: s.sessionId,
|
|
447
|
-
testSuite: s.testSuite,
|
|
448
|
-
startedAt: s.startedAt,
|
|
449
|
-
completedAt: s.completedAt,
|
|
450
|
-
status: s.status,
|
|
451
|
-
passRate: s.passRate
|
|
452
|
-
}));
|
|
453
|
-
} catch (e) {
|
|
454
|
-
return [];
|
|
455
|
-
}
|
|
456
|
-
};
|
|
457
|
-
var createGhost = (config) => {
|
|
458
|
-
let _sessionId = null;
|
|
459
|
-
const apiUrl = config.apiUrl || DEFAULT_API_URL;
|
|
460
|
-
const run = async () => {
|
|
461
|
-
const result = await startGhostSession(config);
|
|
462
|
-
_sessionId = result.sessionId;
|
|
463
|
-
return _sessionId;
|
|
464
|
-
};
|
|
465
|
-
const ensureSessionId = () => {
|
|
466
|
-
if (!_sessionId) throw new Error("Ghost session not started");
|
|
467
|
-
return _sessionId;
|
|
468
|
-
};
|
|
469
|
-
const status = async () => getGhostStatus(ensureSessionId(), apiUrl);
|
|
470
|
-
const results = async () => getGhostResults(ensureSessionId(), apiUrl);
|
|
471
|
-
const stop = async () => {
|
|
472
|
-
if (_sessionId) await stopGhostSession(_sessionId, apiUrl);
|
|
473
|
-
_sessionId = null;
|
|
474
|
-
};
|
|
475
|
-
const waitForCompletion = (pollIntervalMs, timeoutMs, onProgress) => waitForGhostCompletion(ensureSessionId(), pollIntervalMs, timeoutMs, apiUrl, onProgress);
|
|
476
|
-
return { run, status, results, stop, waitForCompletion };
|
|
477
|
-
};
|
|
478
|
-
|
|
479
|
-
// src/cortex-remote.ts
|
|
480
|
-
var createRemoteCortex = (apiUrl, cortexId = "local", apiKey) => {
|
|
481
|
-
const authHeaders = {
|
|
482
|
-
"Content-Type": "application/json",
|
|
483
|
-
...apiKey ? { "Authorization": `Bearer ${apiKey}` } : {}
|
|
484
|
-
};
|
|
485
|
-
const init = async () => ({
|
|
486
|
-
id: `remote_${Date.now()}`,
|
|
487
|
-
model: "api-integrated",
|
|
488
|
-
ready: true,
|
|
489
|
-
engine: "remote"
|
|
490
|
-
});
|
|
491
|
-
const complete = async (prompt, options) => {
|
|
492
|
-
const response = await fetch(`${apiUrl}/cortex/${cortexId}/complete`, {
|
|
493
|
-
method: "POST",
|
|
494
|
-
headers: authHeaders,
|
|
495
|
-
body: JSON.stringify({ prompt, ...options })
|
|
496
|
-
});
|
|
497
|
-
if (!response.ok) throw new Error(`Remote Cortex failed: ${response.statusText}`);
|
|
498
|
-
const data = await response.json();
|
|
499
|
-
return data.text;
|
|
500
|
-
};
|
|
501
|
-
const completeStream = async function* (prompt, options) {
|
|
502
|
-
const result = await complete(prompt, options);
|
|
503
|
-
yield result;
|
|
504
|
-
};
|
|
505
|
-
return { init, complete, completeStream };
|
|
506
|
-
};
|
|
507
|
-
|
|
508
638
|
// src/stream.ts
|
|
509
639
|
var consumeStream = async (stream, onChunk, acc = "", delayMs = 0) => {
|
|
510
640
|
const { value, done } = await stream.next();
|
|
@@ -529,41 +659,454 @@ var streamFromCortexWithDelay = async (cortex, prompt, onChunk, options) => {
|
|
|
529
659
|
return consumeStream(cortex.completeStream(prompt, completionOptions), onChunk, "", delayMs);
|
|
530
660
|
};
|
|
531
661
|
|
|
532
|
-
// src/
|
|
533
|
-
var
|
|
662
|
+
// src/store.ts
|
|
663
|
+
var import_toolkit8 = require("@reduxjs/toolkit");
|
|
664
|
+
|
|
665
|
+
// src/npcSlice.ts
|
|
666
|
+
var import_toolkit4 = require("@reduxjs/toolkit");
|
|
667
|
+
var npcAdapter = (0, import_toolkit4.createEntityAdapter)();
|
|
668
|
+
var npcSlice = (0, import_toolkit4.createSlice)({
|
|
669
|
+
name: "npc",
|
|
670
|
+
initialState: npcAdapter.getInitialState({
|
|
671
|
+
activeNpcId: ""
|
|
672
|
+
}),
|
|
673
|
+
reducers: {
|
|
674
|
+
setNPCInfo: (state, action) => {
|
|
675
|
+
const { id, persona, initialState: initialState5 } = action.payload;
|
|
676
|
+
npcAdapter.upsertOne(state, {
|
|
677
|
+
id,
|
|
678
|
+
persona,
|
|
679
|
+
state: initialState5 || {},
|
|
680
|
+
history: [],
|
|
681
|
+
isBlocked: false
|
|
682
|
+
});
|
|
683
|
+
state.activeNpcId = id;
|
|
684
|
+
},
|
|
685
|
+
setActiveNPC: (state, action) => {
|
|
686
|
+
state.activeNpcId = action.payload;
|
|
687
|
+
},
|
|
688
|
+
setNPCState: (state, action) => {
|
|
689
|
+
const { id, state: npcState } = action.payload;
|
|
690
|
+
npcAdapter.updateOne(state, { id, changes: { state: npcState } });
|
|
691
|
+
},
|
|
692
|
+
updateNPCState: (state, action) => {
|
|
693
|
+
const { id, delta } = action.payload;
|
|
694
|
+
const npc = state.entities[id];
|
|
695
|
+
if (npc) {
|
|
696
|
+
npc.state = { ...npc.state, ...delta };
|
|
697
|
+
}
|
|
698
|
+
},
|
|
699
|
+
addToHistory: (state, action) => {
|
|
700
|
+
const { id, role, content } = action.payload;
|
|
701
|
+
const npc = state.entities[id];
|
|
702
|
+
if (npc) {
|
|
703
|
+
npc.history.push({ role, content });
|
|
704
|
+
}
|
|
705
|
+
},
|
|
706
|
+
setHistory: (state, action) => {
|
|
707
|
+
const { id, history } = action.payload;
|
|
708
|
+
npcAdapter.updateOne(state, { id, changes: { history } });
|
|
709
|
+
},
|
|
710
|
+
setLastAction: (state, action) => {
|
|
711
|
+
const { id, action: npcAction } = action.payload;
|
|
712
|
+
npcAdapter.updateOne(state, { id, changes: { lastAction: npcAction } });
|
|
713
|
+
},
|
|
714
|
+
blockAction: (state, action) => {
|
|
715
|
+
const { id, reason } = action.payload;
|
|
716
|
+
npcAdapter.updateOne(state, { id, changes: { isBlocked: true, blockReason: reason } });
|
|
717
|
+
},
|
|
718
|
+
clearBlock: (state, action) => {
|
|
719
|
+
npcAdapter.updateOne(state, { id: action.payload, changes: { isBlocked: false, blockReason: void 0 } });
|
|
720
|
+
},
|
|
721
|
+
removeNPC: npcAdapter.removeOne
|
|
722
|
+
}
|
|
723
|
+
});
|
|
724
|
+
var {
|
|
725
|
+
setNPCInfo,
|
|
726
|
+
setActiveNPC,
|
|
727
|
+
setNPCState,
|
|
728
|
+
updateNPCState,
|
|
729
|
+
addToHistory,
|
|
730
|
+
setHistory,
|
|
731
|
+
setLastAction,
|
|
732
|
+
blockAction,
|
|
733
|
+
clearBlock,
|
|
734
|
+
removeNPC
|
|
735
|
+
} = npcSlice.actions;
|
|
736
|
+
var {
|
|
737
|
+
selectById: selectNPCById,
|
|
738
|
+
selectIds: selectNPCIds,
|
|
739
|
+
selectEntities: selectNPCEntities,
|
|
740
|
+
selectAll: selectAllNPCs,
|
|
741
|
+
selectTotal: selectTotalNPCs
|
|
742
|
+
} = npcAdapter.getSelectors((state) => state.npc);
|
|
743
|
+
var selectActiveNpcId = (state) => state.npc.activeNpcId;
|
|
744
|
+
var selectActiveNPC = (state) => {
|
|
745
|
+
const id = selectActiveNpcId(state);
|
|
746
|
+
return state.npc.entities[id];
|
|
747
|
+
};
|
|
748
|
+
var npcSlice_default = npcSlice.reducer;
|
|
749
|
+
|
|
750
|
+
// src/cortexSlice.ts
|
|
751
|
+
var import_toolkit5 = require("@reduxjs/toolkit");
|
|
752
|
+
var initialState4 = {
|
|
753
|
+
status: {
|
|
754
|
+
id: "init",
|
|
755
|
+
model: "none",
|
|
756
|
+
ready: false,
|
|
757
|
+
engine: "mock"
|
|
758
|
+
},
|
|
759
|
+
isInitializing: false
|
|
760
|
+
};
|
|
761
|
+
var initRemoteCortexThunk = (0, import_toolkit5.createAsyncThunk)(
|
|
762
|
+
"cortex/initRemote",
|
|
763
|
+
async ({ model = "api-integrated" }) => {
|
|
764
|
+
return {
|
|
765
|
+
id: `remote_${Date.now()}`,
|
|
766
|
+
model,
|
|
767
|
+
ready: true,
|
|
768
|
+
engine: "remote"
|
|
769
|
+
};
|
|
770
|
+
}
|
|
771
|
+
);
|
|
772
|
+
var completeRemoteThunk = (0, import_toolkit5.createAsyncThunk)(
|
|
773
|
+
"cortex/completeRemote",
|
|
774
|
+
async ({ cortexId, prompt, options, apiUrl, apiKey }, { dispatch: dispatch2, rejectWithValue }) => {
|
|
775
|
+
try {
|
|
776
|
+
const data = await dispatch2(sdkApi.endpoints.postCortexComplete.initiate({
|
|
777
|
+
cortexId,
|
|
778
|
+
prompt,
|
|
779
|
+
options,
|
|
780
|
+
apiUrl,
|
|
781
|
+
apiKey
|
|
782
|
+
})).unwrap();
|
|
783
|
+
return data.text;
|
|
784
|
+
} catch (e) {
|
|
785
|
+
return rejectWithValue(e.message || "Remote completing failed");
|
|
786
|
+
}
|
|
787
|
+
}
|
|
788
|
+
);
|
|
789
|
+
var cortexSlice = (0, import_toolkit5.createSlice)({
|
|
790
|
+
name: "cortex",
|
|
791
|
+
initialState: initialState4,
|
|
792
|
+
reducers: {
|
|
793
|
+
cortexInitStart: (state) => {
|
|
794
|
+
state.isInitializing = true;
|
|
795
|
+
state.error = void 0;
|
|
796
|
+
},
|
|
797
|
+
cortexInitSuccess: (state, action) => {
|
|
798
|
+
state.status = action.payload;
|
|
799
|
+
state.isInitializing = false;
|
|
800
|
+
state.error = void 0;
|
|
801
|
+
},
|
|
802
|
+
cortexInitFailed: (state, action) => {
|
|
803
|
+
state.isInitializing = false;
|
|
804
|
+
state.error = action.payload;
|
|
805
|
+
},
|
|
806
|
+
setCortexStatus: (state, action) => {
|
|
807
|
+
state.status = action.payload;
|
|
808
|
+
}
|
|
809
|
+
},
|
|
810
|
+
extraReducers: (builder) => {
|
|
811
|
+
builder.addCase(initRemoteCortexThunk.fulfilled, (state, action) => {
|
|
812
|
+
state.status = action.payload;
|
|
813
|
+
state.isInitializing = false;
|
|
814
|
+
}).addCase(completeRemoteThunk.rejected, (state, action) => {
|
|
815
|
+
state.error = action.payload;
|
|
816
|
+
});
|
|
817
|
+
}
|
|
818
|
+
});
|
|
819
|
+
var {
|
|
820
|
+
cortexInitStart,
|
|
821
|
+
cortexInitSuccess,
|
|
822
|
+
cortexInitFailed,
|
|
823
|
+
setCortexStatus
|
|
824
|
+
} = cortexSlice.actions;
|
|
825
|
+
var cortexSlice_default = cortexSlice.reducer;
|
|
826
|
+
|
|
827
|
+
// src/memorySlice.ts
|
|
828
|
+
var import_toolkit6 = require("@reduxjs/toolkit");
|
|
829
|
+
var memoryAdapter = (0, import_toolkit6.createEntityAdapter)();
|
|
830
|
+
var memorySlice = (0, import_toolkit6.createSlice)({
|
|
831
|
+
name: "memory",
|
|
832
|
+
initialState: memoryAdapter.getInitialState({
|
|
833
|
+
storageStatus: "idle",
|
|
834
|
+
recallStatus: "idle",
|
|
835
|
+
error: null,
|
|
836
|
+
lastRecalledIds: []
|
|
837
|
+
}),
|
|
838
|
+
reducers: {
|
|
839
|
+
memoryStoreStart: (state) => {
|
|
840
|
+
state.storageStatus = "storing";
|
|
841
|
+
state.error = null;
|
|
842
|
+
},
|
|
843
|
+
memoryStoreSuccess: (state, action) => {
|
|
844
|
+
state.storageStatus = "idle";
|
|
845
|
+
memoryAdapter.upsertOne(state, action.payload);
|
|
846
|
+
},
|
|
847
|
+
memoryStoreFailed: (state, action) => {
|
|
848
|
+
state.storageStatus = "error";
|
|
849
|
+
state.error = action.payload;
|
|
850
|
+
},
|
|
851
|
+
memoryRecallStart: (state) => {
|
|
852
|
+
state.recallStatus = "recalling";
|
|
853
|
+
state.error = null;
|
|
854
|
+
},
|
|
855
|
+
memoryRecallSuccess: (state, action) => {
|
|
856
|
+
state.recallStatus = "idle";
|
|
857
|
+
memoryAdapter.upsertMany(state, action.payload);
|
|
858
|
+
state.lastRecalledIds = action.payload.map((m) => memoryAdapter.selectId(m));
|
|
859
|
+
},
|
|
860
|
+
memoryRecallFailed: (state, action) => {
|
|
861
|
+
state.recallStatus = "error";
|
|
862
|
+
state.error = action.payload;
|
|
863
|
+
},
|
|
864
|
+
memoryClear: (state) => {
|
|
865
|
+
memoryAdapter.removeAll(state);
|
|
866
|
+
state.lastRecalledIds = [];
|
|
867
|
+
}
|
|
868
|
+
}
|
|
869
|
+
});
|
|
870
|
+
var {
|
|
871
|
+
memoryStoreStart,
|
|
872
|
+
memoryStoreSuccess,
|
|
873
|
+
memoryStoreFailed,
|
|
874
|
+
memoryRecallStart,
|
|
875
|
+
memoryRecallSuccess,
|
|
876
|
+
memoryRecallFailed,
|
|
877
|
+
memoryClear
|
|
878
|
+
} = memorySlice.actions;
|
|
879
|
+
var {
|
|
880
|
+
selectById: selectMemoryById,
|
|
881
|
+
selectAll: selectAllMemories
|
|
882
|
+
} = memoryAdapter.getSelectors((state) => state.memory);
|
|
883
|
+
var selectLastRecalledMemories = (state) => {
|
|
884
|
+
return state.memory.lastRecalledIds.map((id) => state.memory.entities[id]).filter(Boolean);
|
|
885
|
+
};
|
|
886
|
+
var memorySlice_default = memorySlice.reducer;
|
|
887
|
+
|
|
888
|
+
// src/listeners.ts
|
|
889
|
+
var import_toolkit7 = require("@reduxjs/toolkit");
|
|
890
|
+
var sdkListenerMiddleware = (0, import_toolkit7.createListenerMiddleware)();
|
|
891
|
+
var startAppListening = sdkListenerMiddleware.startListening.withTypes();
|
|
892
|
+
startAppListening({
|
|
893
|
+
actionCreator: removeNPC,
|
|
894
|
+
effect: async (action, listenerApi) => {
|
|
895
|
+
const state = listenerApi.getState();
|
|
896
|
+
if (action.payload === state.npc.activeNpcId) {
|
|
897
|
+
listenerApi.dispatch(memoryClear());
|
|
898
|
+
}
|
|
899
|
+
}
|
|
900
|
+
});
|
|
901
|
+
|
|
902
|
+
// src/store.ts
|
|
903
|
+
var createSDKStore = (extraReducers = {}) => {
|
|
904
|
+
return (0, import_toolkit8.configureStore)({
|
|
905
|
+
reducer: {
|
|
906
|
+
[sdkApi.reducerPath]: sdkApi.reducer,
|
|
907
|
+
npc: npcSlice_default,
|
|
908
|
+
cortex: cortexSlice_default,
|
|
909
|
+
memory: memorySlice_default,
|
|
910
|
+
ghost: ghostSlice_default,
|
|
911
|
+
soul: soulSlice_default,
|
|
912
|
+
bridge: bridgeSlice_default,
|
|
913
|
+
...extraReducers
|
|
914
|
+
},
|
|
915
|
+
middleware: (getDefaultMiddleware) => getDefaultMiddleware({
|
|
916
|
+
serializableCheck: false
|
|
917
|
+
// Allow non-serializable for engine refs in specific slices if needed, though we try to keep them external
|
|
918
|
+
}).prepend(sdkListenerMiddleware.middleware).concat(sdkApi.middleware)
|
|
919
|
+
});
|
|
920
|
+
};
|
|
921
|
+
var store = createSDKStore();
|
|
922
|
+
var dispatch = store.dispatch;
|
|
923
|
+
|
|
924
|
+
// src/thunks.ts
|
|
925
|
+
var import_toolkit9 = require("@reduxjs/toolkit");
|
|
926
|
+
var processNPC = (0, import_toolkit9.createAsyncThunk)(
|
|
927
|
+
"npc/process",
|
|
928
|
+
async ({ npcId: argNpcId, text, context = {}, apiUrl, apiKey, memory, cortex, persona: argPersona }, { getState, dispatch: dispatch2 }) => {
|
|
929
|
+
const stateNpcId = selectActiveNpcId(getState());
|
|
930
|
+
const activeNpc = selectActiveNPC(getState());
|
|
931
|
+
const npcId = argNpcId || stateNpcId;
|
|
932
|
+
const persona = argPersona || activeNpc?.persona;
|
|
933
|
+
const currentState = activeNpc?.state || {};
|
|
934
|
+
if (argNpcId && argNpcId !== stateNpcId) {
|
|
935
|
+
dispatch2(setNPCInfo({ id: argNpcId, persona: persona || "Default" }));
|
|
936
|
+
}
|
|
937
|
+
const directiveResult = await dispatch2(
|
|
938
|
+
sdkApi.endpoints.postDirective.initiate({ npcId, request: { observation: text, npcState: currentState, context }, apiUrl, apiKey })
|
|
939
|
+
).unwrap();
|
|
940
|
+
const recalledMemories = memory && directiveResult.memoryRecall ? await memory.recall(
|
|
941
|
+
directiveResult.memoryRecall.query,
|
|
942
|
+
directiveResult.memoryRecall.limit,
|
|
943
|
+
directiveResult.memoryRecall.threshold
|
|
944
|
+
).then((mems) => mems.map((m) => ({ text: m.text, type: m.type, importance: m.importance }))).catch(() => []) : [];
|
|
945
|
+
const contextResult = await dispatch2(
|
|
946
|
+
sdkApi.endpoints.postContext.initiate({ npcId, request: { memories: recalledMemories, observation: text, npcState: currentState, persona: persona || "Default" }, apiUrl, apiKey })
|
|
947
|
+
).unwrap();
|
|
948
|
+
let generatedText = "";
|
|
949
|
+
if (cortex) {
|
|
950
|
+
generatedText = await cortex.complete(contextResult.prompt, {
|
|
951
|
+
maxTokens: contextResult.constraints.maxTokens,
|
|
952
|
+
temperature: contextResult.constraints.temperature,
|
|
953
|
+
stop: contextResult.constraints.stop
|
|
954
|
+
});
|
|
955
|
+
} else {
|
|
956
|
+
const remoteResult = await dispatch2(sdkApi.endpoints.postCortexComplete.initiate({
|
|
957
|
+
cortexId: "remote",
|
|
958
|
+
// Or generic
|
|
959
|
+
prompt: contextResult.prompt,
|
|
960
|
+
options: contextResult.constraints,
|
|
961
|
+
apiUrl,
|
|
962
|
+
apiKey
|
|
963
|
+
})).unwrap();
|
|
964
|
+
generatedText = remoteResult.text || "";
|
|
965
|
+
}
|
|
966
|
+
const verdictResult = await dispatch2(
|
|
967
|
+
sdkApi.endpoints.postVerdict.initiate({ npcId, request: { generatedOutput: generatedText, observation: text, npcState: currentState }, apiUrl, apiKey })
|
|
968
|
+
).unwrap();
|
|
969
|
+
if (!verdictResult.valid) {
|
|
970
|
+
dispatch2(blockAction({ id: npcId, reason: "Validation Failed" }));
|
|
971
|
+
return { dialogue: "... [Blocked]", action: { type: "BLOCKED", reason: "Validation Failed" } };
|
|
972
|
+
}
|
|
973
|
+
if (memory && verdictResult.memoryStore) {
|
|
974
|
+
for (const inst of verdictResult.memoryStore) {
|
|
975
|
+
await memory.store(inst.text, inst.type, inst.importance).catch((e) => console.warn("Memory store failed:", e));
|
|
976
|
+
}
|
|
977
|
+
}
|
|
978
|
+
if (verdictResult.stateDelta) {
|
|
979
|
+
dispatch2(updateNPCState({ id: npcId, delta: verdictResult.stateDelta }));
|
|
980
|
+
}
|
|
981
|
+
const action = verdictResult.action ? { ...verdictResult.action, signature: verdictResult.signature } : void 0;
|
|
982
|
+
dispatch2(setLastAction({ id: npcId, action }));
|
|
983
|
+
dispatch2(addToHistory({ id: npcId, role: "user", content: text }));
|
|
984
|
+
dispatch2(addToHistory({ id: npcId, role: "assistant", content: verdictResult.dialogue }));
|
|
985
|
+
return {
|
|
986
|
+
dialogue: verdictResult.dialogue,
|
|
987
|
+
action,
|
|
988
|
+
thought: verdictResult.dialogue
|
|
989
|
+
};
|
|
990
|
+
}
|
|
991
|
+
);
|
|
992
|
+
var speakNPC = (0, import_toolkit9.createAsyncThunk)(
|
|
993
|
+
"npc/speak",
|
|
994
|
+
async ({ npcId: argNpcId, text, context = {}, apiUrl, apiKey }, { getState, dispatch: dispatch2 }) => {
|
|
995
|
+
const stateNpcId = selectActiveNpcId(getState());
|
|
996
|
+
const activeNpc = selectActiveNPC(getState());
|
|
997
|
+
const npcId = argNpcId || stateNpcId;
|
|
998
|
+
const currentState = activeNpc?.state || {};
|
|
999
|
+
const data = await dispatch2(sdkApi.endpoints.postSpeak.initiate({
|
|
1000
|
+
npcId,
|
|
1001
|
+
request: { speakMessage: text, speakContext: context, speakNPCState: currentState },
|
|
1002
|
+
apiUrl,
|
|
1003
|
+
apiKey
|
|
1004
|
+
})).unwrap();
|
|
1005
|
+
if (data.speakHistory) {
|
|
1006
|
+
dispatch2(setHistory({ id: npcId, history: data.speakHistory }));
|
|
1007
|
+
}
|
|
1008
|
+
return data.speakReply;
|
|
1009
|
+
}
|
|
1010
|
+
);
|
|
1011
|
+
var dialogueNPC = (0, import_toolkit9.createAsyncThunk)(
|
|
1012
|
+
"npc/dialogue",
|
|
1013
|
+
async ({ npcId: argNpcId, text, context = [], apiUrl, apiKey }, { getState, dispatch: dispatch2 }) => {
|
|
1014
|
+
const stateNpcId = selectActiveNpcId(getState());
|
|
1015
|
+
const npcId = argNpcId || stateNpcId;
|
|
1016
|
+
const data = await dispatch2(sdkApi.endpoints.postDialogue.initiate({
|
|
1017
|
+
npcId,
|
|
1018
|
+
request: { diagMessage: text, diagContext: context },
|
|
1019
|
+
apiUrl,
|
|
1020
|
+
apiKey
|
|
1021
|
+
})).unwrap();
|
|
1022
|
+
return data.diagReply;
|
|
1023
|
+
}
|
|
1024
|
+
);
|
|
1025
|
+
var localExportSoulThunk = (0, import_toolkit9.createAsyncThunk)(
|
|
1026
|
+
"npc/localExportSoul",
|
|
1027
|
+
async ({ id, memory }, { getState }) => {
|
|
1028
|
+
const state = getState().npc;
|
|
1029
|
+
const npcId = id || state.activeNpcId;
|
|
1030
|
+
const npc = state.entities[npcId];
|
|
1031
|
+
if (!npc) throw new Error(`NPC ${npcId} not found`);
|
|
1032
|
+
const memories = memory ? await memory.export().catch(() => []) : [];
|
|
1033
|
+
return exportToSoul(npcId, "NPC", npc.persona, npc.state, memories);
|
|
1034
|
+
}
|
|
1035
|
+
);
|
|
534
1036
|
// Annotate the CommonJS export names for ESM import in node:
|
|
535
1037
|
0 && (module.exports = {
|
|
536
1038
|
SDK_VERSION,
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
1039
|
+
addToHistory,
|
|
1040
|
+
blockAction,
|
|
1041
|
+
bridgeSlice,
|
|
1042
|
+
clearBlock,
|
|
1043
|
+
clearBridgeValidation,
|
|
1044
|
+
clearGhostSession,
|
|
1045
|
+
clearSoulState,
|
|
1046
|
+
completeRemoteThunk,
|
|
1047
|
+
cortexInitFailed,
|
|
1048
|
+
cortexInitStart,
|
|
1049
|
+
cortexInitSuccess,
|
|
1050
|
+
cortexSlice,
|
|
540
1051
|
createInitialState,
|
|
541
|
-
|
|
542
|
-
createSoul,
|
|
543
|
-
createSoulInstance,
|
|
1052
|
+
createSDKStore,
|
|
544
1053
|
delay,
|
|
545
|
-
|
|
546
|
-
|
|
1054
|
+
dialogueNPC,
|
|
1055
|
+
dispatch,
|
|
547
1056
|
exportToSoul,
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
1057
|
+
generateNPCId,
|
|
1058
|
+
getBridgeRulesThunk,
|
|
1059
|
+
getGhostHistoryThunk,
|
|
1060
|
+
getGhostResultsThunk,
|
|
1061
|
+
getGhostStatusThunk,
|
|
1062
|
+
getSoulListThunk,
|
|
1063
|
+
ghostSlice,
|
|
1064
|
+
importSoulFromArweaveThunk,
|
|
1065
|
+
initRemoteCortexThunk,
|
|
1066
|
+
loadBridgePresetThunk,
|
|
1067
|
+
localExportSoulThunk,
|
|
555
1068
|
memoise,
|
|
556
1069
|
memoiseAsync,
|
|
1070
|
+
memoryClear,
|
|
1071
|
+
memoryRecallFailed,
|
|
1072
|
+
memoryRecallStart,
|
|
1073
|
+
memoryRecallSuccess,
|
|
1074
|
+
memorySlice,
|
|
1075
|
+
memoryStoreFailed,
|
|
1076
|
+
memoryStoreStart,
|
|
1077
|
+
memoryStoreSuccess,
|
|
1078
|
+
npcSlice,
|
|
557
1079
|
pipe,
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
1080
|
+
processNPC,
|
|
1081
|
+
remoteExportSoulThunk,
|
|
1082
|
+
removeNPC,
|
|
1083
|
+
sdkApi,
|
|
1084
|
+
selectActiveNPC,
|
|
1085
|
+
selectActiveNpcId,
|
|
1086
|
+
selectAllMemories,
|
|
1087
|
+
selectAllNPCs,
|
|
1088
|
+
selectLastRecalledMemories,
|
|
1089
|
+
selectMemoryById,
|
|
1090
|
+
selectNPCById,
|
|
1091
|
+
selectNPCEntities,
|
|
1092
|
+
selectNPCIds,
|
|
1093
|
+
selectTotalNPCs,
|
|
1094
|
+
setActiveNPC,
|
|
1095
|
+
setCortexStatus,
|
|
1096
|
+
setHistory,
|
|
1097
|
+
setLastAction,
|
|
1098
|
+
setNPCInfo,
|
|
1099
|
+
setNPCState,
|
|
1100
|
+
soulSlice,
|
|
1101
|
+
speakNPC,
|
|
1102
|
+
startGhostThunk,
|
|
1103
|
+
stopGhostThunk,
|
|
1104
|
+
store,
|
|
561
1105
|
streamFromCortex,
|
|
562
1106
|
streamFromCortexWithDelay,
|
|
563
1107
|
streamToCallback,
|
|
564
1108
|
streamToString,
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
waitForGhostCompletion
|
|
1109
|
+
updateNPCState,
|
|
1110
|
+
updateNPCStateLocally,
|
|
1111
|
+
validateBridgeThunk
|
|
569
1112
|
});
|