@forbocai/core 0.6.1 → 0.6.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +592 -21
- package/dist/index.d.ts +592 -21
- package/dist/index.js +417 -113
- package/dist/index.mjs +415 -113
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -54,6 +54,8 @@ __export(index_exports, {
|
|
|
54
54
|
getGhostStatusThunk: () => getGhostStatusThunk,
|
|
55
55
|
getSoulListThunk: () => getSoulListThunk,
|
|
56
56
|
ghostSlice: () => ghostSlice,
|
|
57
|
+
handler_ArweaveDownload: () => handler_ArweaveDownload,
|
|
58
|
+
handler_ArweaveUpload: () => handler_ArweaveUpload,
|
|
57
59
|
importNpcFromSoulThunk: () => importNpcFromSoulThunk,
|
|
58
60
|
importSoulFromArweaveThunk: () => importSoulFromArweaveThunk,
|
|
59
61
|
initRemoteCortexThunk: () => initRemoteCortexThunk,
|
|
@@ -169,6 +171,21 @@ var sdkApi = (0, import_query.createApi)({
|
|
|
169
171
|
transformResponse: (response) => response
|
|
170
172
|
}),
|
|
171
173
|
// NPC Endpoints
|
|
174
|
+
/**
|
|
175
|
+
* User Story: As the SDK protocol loop, I need a single process endpoint
|
|
176
|
+
* that returns one atomic instruction per turn while echoing full tape state.
|
|
177
|
+
* ᚹ one hop in, one hop out, like passing a lit shard through vacuum.
|
|
178
|
+
*/
|
|
179
|
+
postNpcProcess: builder.mutation({
|
|
180
|
+
query: ({ npcId, request, apiUrl, apiKey }) => ({
|
|
181
|
+
url: `${apiUrl}/npcs/${npcId}/process`,
|
|
182
|
+
method: "POST",
|
|
183
|
+
headers: apiKey ? { "Authorization": `Bearer ${apiKey}` } : {},
|
|
184
|
+
body: request
|
|
185
|
+
}),
|
|
186
|
+
invalidatesTags: (result, error, { npcId }) => [{ type: "NPC", id: npcId }],
|
|
187
|
+
transformResponse: (response) => response
|
|
188
|
+
}),
|
|
172
189
|
postDirective: builder.mutation({
|
|
173
190
|
query: ({ npcId, request, apiUrl, apiKey }) => ({
|
|
174
191
|
url: `${apiUrl}/npcs/${npcId}/directive`,
|
|
@@ -310,6 +327,16 @@ var sdkApi = (0, import_query.createApi)({
|
|
|
310
327
|
invalidatesTags: ["Soul"],
|
|
311
328
|
transformResponse: (response) => response
|
|
312
329
|
}),
|
|
330
|
+
postSoulExportConfirm: builder.mutation({
|
|
331
|
+
query: ({ npcId, request, apiUrl, apiKey }) => ({
|
|
332
|
+
url: `${apiUrl}/npcs/${npcId}/soul/confirm`,
|
|
333
|
+
method: "POST",
|
|
334
|
+
headers: apiKey ? { "Authorization": `Bearer ${apiKey}` } : {},
|
|
335
|
+
body: request
|
|
336
|
+
}),
|
|
337
|
+
invalidatesTags: ["Soul"],
|
|
338
|
+
transformResponse: (response) => response
|
|
339
|
+
}),
|
|
313
340
|
getSoulImport: builder.query({
|
|
314
341
|
query: ({ txId, apiUrl, apiKey }) => ({
|
|
315
342
|
url: `${apiUrl}/souls/${txId}`,
|
|
@@ -418,6 +445,16 @@ var sdkApi = (0, import_query.createApi)({
|
|
|
418
445
|
invalidatesTags: ["NPC"],
|
|
419
446
|
transformResponse: (response) => response
|
|
420
447
|
}),
|
|
448
|
+
postNpcImportConfirm: builder.mutation({
|
|
449
|
+
query: ({ request, apiUrl, apiKey }) => ({
|
|
450
|
+
url: `${apiUrl}/npcs/import/confirm`,
|
|
451
|
+
method: "POST",
|
|
452
|
+
headers: apiKey ? { "Authorization": `Bearer ${apiKey}` } : {},
|
|
453
|
+
body: request
|
|
454
|
+
}),
|
|
455
|
+
invalidatesTags: ["NPC"],
|
|
456
|
+
transformResponse: (response) => response
|
|
457
|
+
}),
|
|
421
458
|
// Cortex Remote Endpoint
|
|
422
459
|
postCortexComplete: builder.mutation({
|
|
423
460
|
query: ({ cortexId, prompt, options, apiUrl, apiKey }) => ({
|
|
@@ -437,6 +474,25 @@ var sdkApi = (0, import_query.createApi)({
|
|
|
437
474
|
})
|
|
438
475
|
});
|
|
439
476
|
|
|
477
|
+
// src/errors.ts
|
|
478
|
+
var extractThunkErrorMessage = (error, fallback) => {
|
|
479
|
+
if (typeof error === "string") return error;
|
|
480
|
+
if (error && typeof error === "object") {
|
|
481
|
+
const e = error;
|
|
482
|
+
if (typeof e.data === "object" && e.data?.message) return String(e.data.message);
|
|
483
|
+
if (typeof e.data === "string") return e.data;
|
|
484
|
+
if (e.message) return e.message;
|
|
485
|
+
if (e.error) return e.error;
|
|
486
|
+
}
|
|
487
|
+
return fallback;
|
|
488
|
+
};
|
|
489
|
+
var requireApiKeyGuidance = (apiUrl, apiKey) => {
|
|
490
|
+
const normalized = apiUrl.toLowerCase();
|
|
491
|
+
if (normalized.includes("api.forboc.ai") && !apiKey) {
|
|
492
|
+
throw new Error("Missing API key. Set FORBOCAI_API_KEY (or run `forboc config set apiKey <key>`) for production API calls.");
|
|
493
|
+
}
|
|
494
|
+
};
|
|
495
|
+
|
|
440
496
|
// src/bridgeSlice.ts
|
|
441
497
|
var initialState = {
|
|
442
498
|
activePresets: [],
|
|
@@ -451,6 +507,7 @@ var validateBridgeThunk = (0, import_toolkit.createAsyncThunk)(
|
|
|
451
507
|
async ({ action, context, npcId, apiUrl, apiKey }, { dispatch: dispatch2, rejectWithValue }) => {
|
|
452
508
|
try {
|
|
453
509
|
const url = apiUrl || "https://api.forboc.ai";
|
|
510
|
+
requireApiKeyGuidance(url, apiKey);
|
|
454
511
|
const data = await dispatch2(sdkApi.endpoints.postBridgeValidate.initiate({
|
|
455
512
|
request: { action, context },
|
|
456
513
|
npcId,
|
|
@@ -458,8 +515,8 @@ var validateBridgeThunk = (0, import_toolkit.createAsyncThunk)(
|
|
|
458
515
|
apiKey
|
|
459
516
|
})).unwrap();
|
|
460
517
|
return data;
|
|
461
|
-
} catch (
|
|
462
|
-
return rejectWithValue(
|
|
518
|
+
} catch (error) {
|
|
519
|
+
return rejectWithValue(extractThunkErrorMessage(error, "Bridge validation failed"));
|
|
463
520
|
}
|
|
464
521
|
}
|
|
465
522
|
);
|
|
@@ -468,9 +525,10 @@ var loadBridgePresetThunk = (0, import_toolkit.createAsyncThunk)(
|
|
|
468
525
|
async ({ presetName, apiUrl, apiKey }, { dispatch: dispatch2, rejectWithValue }) => {
|
|
469
526
|
try {
|
|
470
527
|
const url = apiUrl || "https://api.forboc.ai";
|
|
528
|
+
requireApiKeyGuidance(url, apiKey);
|
|
471
529
|
return await dispatch2(sdkApi.endpoints.postBridgePreset.initiate({ presetName, apiUrl: url, apiKey })).unwrap();
|
|
472
|
-
} catch (
|
|
473
|
-
return rejectWithValue(
|
|
530
|
+
} catch (error) {
|
|
531
|
+
return rejectWithValue(extractThunkErrorMessage(error, "Failed to load preset"));
|
|
474
532
|
}
|
|
475
533
|
}
|
|
476
534
|
);
|
|
@@ -479,9 +537,10 @@ var getBridgeRulesThunk = (0, import_toolkit.createAsyncThunk)(
|
|
|
479
537
|
async ({ apiUrl, apiKey }, { dispatch: dispatch2, rejectWithValue }) => {
|
|
480
538
|
try {
|
|
481
539
|
const url = apiUrl || "https://api.forboc.ai";
|
|
540
|
+
requireApiKeyGuidance(url, apiKey);
|
|
482
541
|
return await dispatch2(sdkApi.endpoints.getBridgeRules.initiate({ apiUrl: url, apiKey })).unwrap();
|
|
483
|
-
} catch (
|
|
484
|
-
return rejectWithValue(
|
|
542
|
+
} catch (error) {
|
|
543
|
+
return rejectWithValue(extractThunkErrorMessage(error, "Failed to list bridge rules"));
|
|
485
544
|
}
|
|
486
545
|
}
|
|
487
546
|
);
|
|
@@ -490,9 +549,10 @@ var listRulesetsThunk = (0, import_toolkit.createAsyncThunk)(
|
|
|
490
549
|
async ({ apiUrl, apiKey }, { dispatch: dispatch2, rejectWithValue }) => {
|
|
491
550
|
try {
|
|
492
551
|
const url = apiUrl || "https://api.forboc.ai";
|
|
552
|
+
requireApiKeyGuidance(url, apiKey);
|
|
493
553
|
return await dispatch2(sdkApi.endpoints.getRulesets.initiate({ apiUrl: url, apiKey })).unwrap();
|
|
494
|
-
} catch (
|
|
495
|
-
return rejectWithValue(
|
|
554
|
+
} catch (error) {
|
|
555
|
+
return rejectWithValue(extractThunkErrorMessage(error, "Failed to list rulesets"));
|
|
496
556
|
}
|
|
497
557
|
}
|
|
498
558
|
);
|
|
@@ -501,9 +561,10 @@ var listRulePresetsThunk = (0, import_toolkit.createAsyncThunk)(
|
|
|
501
561
|
async ({ apiUrl, apiKey }, { dispatch: dispatch2, rejectWithValue }) => {
|
|
502
562
|
try {
|
|
503
563
|
const url = apiUrl || "https://api.forboc.ai";
|
|
564
|
+
requireApiKeyGuidance(url, apiKey);
|
|
504
565
|
return await dispatch2(sdkApi.endpoints.getRulePresets.initiate({ apiUrl: url, apiKey })).unwrap();
|
|
505
|
-
} catch (
|
|
506
|
-
return rejectWithValue(
|
|
566
|
+
} catch (error) {
|
|
567
|
+
return rejectWithValue(extractThunkErrorMessage(error, "Failed to list rule presets"));
|
|
507
568
|
}
|
|
508
569
|
}
|
|
509
570
|
);
|
|
@@ -512,9 +573,10 @@ var registerRulesetThunk = (0, import_toolkit.createAsyncThunk)(
|
|
|
512
573
|
async ({ ruleset, apiUrl, apiKey }, { dispatch: dispatch2, rejectWithValue }) => {
|
|
513
574
|
try {
|
|
514
575
|
const url = apiUrl || "https://api.forboc.ai";
|
|
576
|
+
requireApiKeyGuidance(url, apiKey);
|
|
515
577
|
return await dispatch2(sdkApi.endpoints.postRuleRegister.initiate({ request: ruleset, apiUrl: url, apiKey })).unwrap();
|
|
516
|
-
} catch (
|
|
517
|
-
return rejectWithValue(
|
|
578
|
+
} catch (error) {
|
|
579
|
+
return rejectWithValue(extractThunkErrorMessage(error, "Failed to register ruleset"));
|
|
518
580
|
}
|
|
519
581
|
}
|
|
520
582
|
);
|
|
@@ -523,9 +585,10 @@ var deleteRulesetThunk = (0, import_toolkit.createAsyncThunk)(
|
|
|
523
585
|
async ({ rulesetId, apiUrl, apiKey }, { dispatch: dispatch2, rejectWithValue }) => {
|
|
524
586
|
try {
|
|
525
587
|
const url = apiUrl || "https://api.forboc.ai";
|
|
588
|
+
requireApiKeyGuidance(url, apiKey);
|
|
526
589
|
return await dispatch2(sdkApi.endpoints.deleteRule.initiate({ rulesetId, apiUrl: url, apiKey })).unwrap();
|
|
527
|
-
} catch (
|
|
528
|
-
return rejectWithValue(
|
|
590
|
+
} catch (error) {
|
|
591
|
+
return rejectWithValue(extractThunkErrorMessage(error, "Failed to delete ruleset"));
|
|
529
592
|
}
|
|
530
593
|
}
|
|
531
594
|
);
|
|
@@ -574,6 +637,124 @@ var bridgeSlice_default = bridgeSlice.reducer;
|
|
|
574
637
|
|
|
575
638
|
// src/soulSlice.ts
|
|
576
639
|
var import_toolkit2 = require("@reduxjs/toolkit");
|
|
640
|
+
|
|
641
|
+
// src/handlers/arweave.ts
|
|
642
|
+
var sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
643
|
+
var getLocalWalletToken = () => {
|
|
644
|
+
const maybeEnv = globalThis.process?.env;
|
|
645
|
+
return maybeEnv?.ARWEAVE_WALLET_JWK ?? null;
|
|
646
|
+
};
|
|
647
|
+
var withTimeout = async (promiseFactory, timeoutMs = 6e4) => {
|
|
648
|
+
const controller = new AbortController();
|
|
649
|
+
const timeout = setTimeout(() => controller.abort(), timeoutMs);
|
|
650
|
+
try {
|
|
651
|
+
return await promiseFactory(controller.signal);
|
|
652
|
+
} finally {
|
|
653
|
+
clearTimeout(timeout);
|
|
654
|
+
}
|
|
655
|
+
};
|
|
656
|
+
async function handler_ArweaveUpload(instruction, maxRetries = 3) {
|
|
657
|
+
const headers = {
|
|
658
|
+
"Content-Type": instruction.auiContentType || "application/json"
|
|
659
|
+
};
|
|
660
|
+
const authToken = instruction.auiAuthHeader ?? (getLocalWalletToken() ? `Bearer ${getLocalWalletToken()}` : null);
|
|
661
|
+
if (authToken) {
|
|
662
|
+
headers.Authorization = authToken;
|
|
663
|
+
}
|
|
664
|
+
let attempt = 0;
|
|
665
|
+
while (attempt < maxRetries) {
|
|
666
|
+
attempt += 1;
|
|
667
|
+
try {
|
|
668
|
+
const response = await withTimeout(
|
|
669
|
+
(signal) => fetch(instruction.auiEndpoint, {
|
|
670
|
+
method: "POST",
|
|
671
|
+
headers,
|
|
672
|
+
body: JSON.stringify(instruction.auiPayload),
|
|
673
|
+
signal
|
|
674
|
+
})
|
|
675
|
+
);
|
|
676
|
+
let responseBody = null;
|
|
677
|
+
try {
|
|
678
|
+
responseBody = await response.json();
|
|
679
|
+
} catch {
|
|
680
|
+
responseBody = null;
|
|
681
|
+
}
|
|
682
|
+
const txId = responseBody?.id ?? `ar_tx_sdk_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;
|
|
683
|
+
const success = response.status >= 200 && response.status < 300;
|
|
684
|
+
if (!success && attempt < maxRetries) {
|
|
685
|
+
await sleep(250 * 2 ** (attempt - 1));
|
|
686
|
+
continue;
|
|
687
|
+
}
|
|
688
|
+
return {
|
|
689
|
+
aurTxId: txId,
|
|
690
|
+
aurStatus: response.status,
|
|
691
|
+
aurSuccess: success,
|
|
692
|
+
aurError: success ? null : `upload_failed_status_${response.status}`
|
|
693
|
+
};
|
|
694
|
+
} catch (error) {
|
|
695
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
696
|
+
if (attempt < maxRetries) {
|
|
697
|
+
await sleep(250 * 2 ** (attempt - 1));
|
|
698
|
+
continue;
|
|
699
|
+
}
|
|
700
|
+
return {
|
|
701
|
+
aurTxId: `ar_tx_failed_${Date.now()}`,
|
|
702
|
+
aurStatus: 0,
|
|
703
|
+
aurSuccess: false,
|
|
704
|
+
aurError: `upload_request_failed:${message}`
|
|
705
|
+
};
|
|
706
|
+
}
|
|
707
|
+
}
|
|
708
|
+
return {
|
|
709
|
+
aurTxId: `ar_tx_failed_${Date.now()}`,
|
|
710
|
+
aurStatus: 0,
|
|
711
|
+
aurSuccess: false,
|
|
712
|
+
aurError: "upload_retry_exhausted"
|
|
713
|
+
};
|
|
714
|
+
}
|
|
715
|
+
async function handler_ArweaveDownload(instruction) {
|
|
716
|
+
try {
|
|
717
|
+
const response = await withTimeout(
|
|
718
|
+
(signal) => fetch(instruction.adiGatewayUrl, {
|
|
719
|
+
method: "GET",
|
|
720
|
+
signal
|
|
721
|
+
})
|
|
722
|
+
);
|
|
723
|
+
if (response.status < 200 || response.status >= 300) {
|
|
724
|
+
return {
|
|
725
|
+
adrBody: null,
|
|
726
|
+
adrStatus: response.status,
|
|
727
|
+
adrSuccess: false,
|
|
728
|
+
adrError: `download_failed_status_${response.status}`
|
|
729
|
+
};
|
|
730
|
+
}
|
|
731
|
+
try {
|
|
732
|
+
const body = await response.json();
|
|
733
|
+
return {
|
|
734
|
+
adrBody: body,
|
|
735
|
+
adrStatus: response.status,
|
|
736
|
+
adrSuccess: true,
|
|
737
|
+
adrError: null
|
|
738
|
+
};
|
|
739
|
+
} catch {
|
|
740
|
+
return {
|
|
741
|
+
adrBody: null,
|
|
742
|
+
adrStatus: response.status,
|
|
743
|
+
adrSuccess: false,
|
|
744
|
+
adrError: "download_invalid_json"
|
|
745
|
+
};
|
|
746
|
+
}
|
|
747
|
+
} catch (error) {
|
|
748
|
+
return {
|
|
749
|
+
adrBody: null,
|
|
750
|
+
adrStatus: 0,
|
|
751
|
+
adrSuccess: false,
|
|
752
|
+
adrError: error instanceof Error ? error.message : String(error)
|
|
753
|
+
};
|
|
754
|
+
}
|
|
755
|
+
}
|
|
756
|
+
|
|
757
|
+
// src/soulSlice.ts
|
|
577
758
|
var initialState2 = {
|
|
578
759
|
exportStatus: "idle",
|
|
579
760
|
importStatus: "idle",
|
|
@@ -584,26 +765,45 @@ var initialState2 = {
|
|
|
584
765
|
};
|
|
585
766
|
var remoteExportSoulThunk = (0, import_toolkit2.createAsyncThunk)(
|
|
586
767
|
"soul/export",
|
|
587
|
-
async ({ npcId: argNpcId, apiUrl, apiKey
|
|
768
|
+
async ({ npcId: argNpcId, apiUrl, apiKey }, { getState, dispatch: dispatch2, rejectWithValue }) => {
|
|
588
769
|
try {
|
|
589
770
|
const state = getState().npc;
|
|
590
771
|
const npcId = argNpcId || state.activeNpcId;
|
|
591
772
|
const npc = state.entities[npcId];
|
|
592
773
|
if (!npc) throw new Error(`NPC ${npcId} not found`);
|
|
593
774
|
const url = apiUrl || "https://api.forboc.ai";
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
775
|
+
requireApiKeyGuidance(url, apiKey);
|
|
776
|
+
const phase1 = await dispatch2(
|
|
777
|
+
sdkApi.endpoints.postSoulExport.initiate({
|
|
778
|
+
npcId,
|
|
779
|
+
request: { npcIdRef: npcId, persona: npc.persona || "NPC", npcState: npc.state },
|
|
780
|
+
apiUrl: url,
|
|
781
|
+
apiKey
|
|
782
|
+
})
|
|
783
|
+
).unwrap();
|
|
784
|
+
const uploadResult = await handler_ArweaveUpload({
|
|
785
|
+
...phase1.se1Instruction,
|
|
786
|
+
auiAuthHeader: phase1.se1Instruction.auiAuthHeader ?? null
|
|
787
|
+
});
|
|
788
|
+
const final = await dispatch2(
|
|
789
|
+
sdkApi.endpoints.postSoulExportConfirm.initiate({
|
|
790
|
+
npcId,
|
|
791
|
+
request: {
|
|
792
|
+
secUploadResult: uploadResult,
|
|
793
|
+
secSignedPayload: phase1.se1SignedPayload,
|
|
794
|
+
secSignature: phase1.se1Signature
|
|
795
|
+
},
|
|
796
|
+
apiUrl: url,
|
|
797
|
+
apiKey
|
|
798
|
+
})
|
|
799
|
+
).unwrap();
|
|
600
800
|
return {
|
|
601
|
-
txId:
|
|
602
|
-
url:
|
|
603
|
-
soul:
|
|
801
|
+
txId: final.txId,
|
|
802
|
+
url: final.arweaveUrl,
|
|
803
|
+
soul: final.soul
|
|
604
804
|
};
|
|
605
|
-
} catch (
|
|
606
|
-
return rejectWithValue(
|
|
805
|
+
} catch (error) {
|
|
806
|
+
return rejectWithValue(extractThunkErrorMessage(error, "Soul export failed"));
|
|
607
807
|
}
|
|
608
808
|
}
|
|
609
809
|
);
|
|
@@ -612,10 +812,31 @@ var importSoulFromArweaveThunk = (0, import_toolkit2.createAsyncThunk)(
|
|
|
612
812
|
async ({ txId, apiUrl, apiKey }, { dispatch: dispatch2, rejectWithValue }) => {
|
|
613
813
|
try {
|
|
614
814
|
const url = apiUrl || "https://api.forboc.ai";
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
815
|
+
requireApiKeyGuidance(url, apiKey);
|
|
816
|
+
const phase1 = await dispatch2(
|
|
817
|
+
sdkApi.endpoints.postNpcImport.initiate({ request: { txIdRef: txId }, apiUrl: url, apiKey })
|
|
818
|
+
).unwrap();
|
|
819
|
+
const downloadResult = await handler_ArweaveDownload(phase1.si1Instruction);
|
|
820
|
+
const npc = await dispatch2(
|
|
821
|
+
sdkApi.endpoints.postNpcImportConfirm.initiate({
|
|
822
|
+
request: {
|
|
823
|
+
sicTxId: txId,
|
|
824
|
+
sicDownloadResult: downloadResult
|
|
825
|
+
},
|
|
826
|
+
apiUrl: url,
|
|
827
|
+
apiKey
|
|
828
|
+
})
|
|
829
|
+
).unwrap();
|
|
830
|
+
return {
|
|
831
|
+
id: txId,
|
|
832
|
+
version: "2.0.0",
|
|
833
|
+
name: npc.npcId,
|
|
834
|
+
persona: npc.persona,
|
|
835
|
+
memories: [],
|
|
836
|
+
state: npc.data || {}
|
|
837
|
+
};
|
|
838
|
+
} catch (error) {
|
|
839
|
+
return rejectWithValue(extractThunkErrorMessage(error, "Soul import failed"));
|
|
619
840
|
}
|
|
620
841
|
}
|
|
621
842
|
);
|
|
@@ -624,10 +845,11 @@ var getSoulListThunk = (0, import_toolkit2.createAsyncThunk)(
|
|
|
624
845
|
async ({ limit = 50, apiUrl, apiKey }, { dispatch: dispatch2, rejectWithValue }) => {
|
|
625
846
|
try {
|
|
626
847
|
const url = apiUrl || "https://api.forboc.ai";
|
|
848
|
+
requireApiKeyGuidance(url, apiKey);
|
|
627
849
|
const data = await dispatch2(sdkApi.endpoints.getSouls.initiate({ limit, apiUrl: url, apiKey })).unwrap();
|
|
628
850
|
return data.souls || [];
|
|
629
|
-
} catch (
|
|
630
|
-
return rejectWithValue(
|
|
851
|
+
} catch (error) {
|
|
852
|
+
return rejectWithValue(extractThunkErrorMessage(error, "Failed to list souls"));
|
|
631
853
|
}
|
|
632
854
|
}
|
|
633
855
|
);
|
|
@@ -636,9 +858,10 @@ var verifySoulThunk = (0, import_toolkit2.createAsyncThunk)(
|
|
|
636
858
|
async ({ txId, apiUrl, apiKey }, { dispatch: dispatch2, rejectWithValue }) => {
|
|
637
859
|
try {
|
|
638
860
|
const url = apiUrl || "https://api.forboc.ai";
|
|
861
|
+
requireApiKeyGuidance(url, apiKey);
|
|
639
862
|
return await dispatch2(sdkApi.endpoints.postSoulVerify.initiate({ txId, apiUrl: url, apiKey })).unwrap();
|
|
640
|
-
} catch (
|
|
641
|
-
return rejectWithValue(
|
|
863
|
+
} catch (error) {
|
|
864
|
+
return rejectWithValue(extractThunkErrorMessage(error, "Soul verify failed"));
|
|
642
865
|
}
|
|
643
866
|
}
|
|
644
867
|
);
|
|
@@ -647,13 +870,24 @@ var importNpcFromSoulThunk = (0, import_toolkit2.createAsyncThunk)(
|
|
|
647
870
|
async ({ txId, apiUrl, apiKey }, { dispatch: dispatch2, rejectWithValue }) => {
|
|
648
871
|
try {
|
|
649
872
|
const url = apiUrl || "https://api.forboc.ai";
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
873
|
+
requireApiKeyGuidance(url, apiKey);
|
|
874
|
+
const phase1 = await dispatch2(
|
|
875
|
+
sdkApi.endpoints.postNpcImport.initiate({
|
|
876
|
+
request: { txIdRef: txId },
|
|
877
|
+
apiUrl: url,
|
|
878
|
+
apiKey
|
|
879
|
+
})
|
|
880
|
+
).unwrap();
|
|
881
|
+
const downloadResult = await handler_ArweaveDownload(phase1.si1Instruction);
|
|
882
|
+
return await dispatch2(
|
|
883
|
+
sdkApi.endpoints.postNpcImportConfirm.initiate({
|
|
884
|
+
request: { sicTxId: txId, sicDownloadResult: downloadResult },
|
|
885
|
+
apiUrl: url,
|
|
886
|
+
apiKey
|
|
887
|
+
})
|
|
888
|
+
).unwrap();
|
|
889
|
+
} catch (error) {
|
|
890
|
+
return rejectWithValue(extractThunkErrorMessage(error, "NPC import from soul failed"));
|
|
657
891
|
}
|
|
658
892
|
}
|
|
659
893
|
);
|
|
@@ -712,6 +946,7 @@ var startGhostThunk = (0, import_toolkit3.createAsyncThunk)(
|
|
|
712
946
|
async (config, { dispatch: dispatch2, rejectWithValue }) => {
|
|
713
947
|
try {
|
|
714
948
|
const apiUrl = config.apiUrl || "https://api.forboc.ai";
|
|
949
|
+
requireApiKeyGuidance(apiUrl, config.apiKey);
|
|
715
950
|
const data = await dispatch2(sdkApi.endpoints.postGhostRun.initiate({
|
|
716
951
|
request: { testSuite: config.testSuite, duration: config.duration ?? 300 },
|
|
717
952
|
apiUrl,
|
|
@@ -721,8 +956,8 @@ var startGhostThunk = (0, import_toolkit3.createAsyncThunk)(
|
|
|
721
956
|
sessionId: data.sessionId,
|
|
722
957
|
status: data.runStatus
|
|
723
958
|
};
|
|
724
|
-
} catch (
|
|
725
|
-
return rejectWithValue(
|
|
959
|
+
} catch (error) {
|
|
960
|
+
return rejectWithValue(extractThunkErrorMessage(error, "Failed to start Ghost"));
|
|
726
961
|
}
|
|
727
962
|
}
|
|
728
963
|
);
|
|
@@ -734,6 +969,7 @@ var getGhostStatusThunk = (0, import_toolkit3.createAsyncThunk)(
|
|
|
734
969
|
const targetSession = sessionId || state.activeSessionId;
|
|
735
970
|
if (!targetSession) throw new Error("No active Ghost session");
|
|
736
971
|
const url = apiUrl || "https://api.forboc.ai";
|
|
972
|
+
requireApiKeyGuidance(url, apiKey);
|
|
737
973
|
const data = await dispatch2(sdkApi.endpoints.getGhostStatus.initiate({ sessionId: targetSession, apiUrl: url, apiKey })).unwrap();
|
|
738
974
|
return {
|
|
739
975
|
sessionId: data.ghostSessionId,
|
|
@@ -743,8 +979,8 @@ var getGhostStatusThunk = (0, import_toolkit3.createAsyncThunk)(
|
|
|
743
979
|
duration: data.ghostDuration || 0,
|
|
744
980
|
errors: data.ghostErrors
|
|
745
981
|
};
|
|
746
|
-
} catch (
|
|
747
|
-
return rejectWithValue(
|
|
982
|
+
} catch (error) {
|
|
983
|
+
return rejectWithValue(extractThunkErrorMessage(error, "Failed to get ghost status"));
|
|
748
984
|
}
|
|
749
985
|
}
|
|
750
986
|
);
|
|
@@ -756,6 +992,7 @@ var getGhostResultsThunk = (0, import_toolkit3.createAsyncThunk)(
|
|
|
756
992
|
const targetSession = sessionId || state.activeSessionId;
|
|
757
993
|
if (!targetSession) throw new Error("No active Ghost session");
|
|
758
994
|
const url = apiUrl || "https://api.forboc.ai";
|
|
995
|
+
requireApiKeyGuidance(url, apiKey);
|
|
759
996
|
const data = await dispatch2(sdkApi.endpoints.getGhostResults.initiate({ sessionId: targetSession, apiUrl: url, apiKey })).unwrap();
|
|
760
997
|
return {
|
|
761
998
|
sessionId: data.resultsSessionId,
|
|
@@ -774,8 +1011,8 @@ var getGhostResultsThunk = (0, import_toolkit3.createAsyncThunk)(
|
|
|
774
1011
|
coverage: data.resultsCoverage,
|
|
775
1012
|
metrics: Object.fromEntries(data.resultsMetrics || [])
|
|
776
1013
|
};
|
|
777
|
-
} catch (
|
|
778
|
-
return rejectWithValue(
|
|
1014
|
+
} catch (error) {
|
|
1015
|
+
return rejectWithValue(extractThunkErrorMessage(error, "Failed to get ghost results"));
|
|
779
1016
|
}
|
|
780
1017
|
}
|
|
781
1018
|
);
|
|
@@ -787,14 +1024,15 @@ var stopGhostThunk = (0, import_toolkit3.createAsyncThunk)(
|
|
|
787
1024
|
const targetSession = sessionId || state.activeSessionId;
|
|
788
1025
|
if (!targetSession) throw new Error("No active Ghost session");
|
|
789
1026
|
const url = apiUrl || "https://api.forboc.ai";
|
|
1027
|
+
requireApiKeyGuidance(url, apiKey);
|
|
790
1028
|
const data = await dispatch2(sdkApi.endpoints.postGhostStop.initiate({ sessionId: targetSession, apiUrl: url, apiKey })).unwrap();
|
|
791
1029
|
return {
|
|
792
1030
|
stopped: data.stopped,
|
|
793
1031
|
status: data.stopStatus,
|
|
794
1032
|
sessionId: data.stopSessionId
|
|
795
1033
|
};
|
|
796
|
-
} catch (
|
|
797
|
-
return rejectWithValue(
|
|
1034
|
+
} catch (error) {
|
|
1035
|
+
return rejectWithValue(extractThunkErrorMessage(error, "Failed to stop ghost session"));
|
|
798
1036
|
}
|
|
799
1037
|
}
|
|
800
1038
|
);
|
|
@@ -803,6 +1041,7 @@ var getGhostHistoryThunk = (0, import_toolkit3.createAsyncThunk)(
|
|
|
803
1041
|
async ({ limit = 10, apiUrl, apiKey }, { dispatch: dispatch2, rejectWithValue }) => {
|
|
804
1042
|
try {
|
|
805
1043
|
const url = apiUrl || "https://api.forboc.ai";
|
|
1044
|
+
requireApiKeyGuidance(url, apiKey);
|
|
806
1045
|
const data = await dispatch2(sdkApi.endpoints.getGhostHistory.initiate({ limit, apiUrl: url, apiKey })).unwrap();
|
|
807
1046
|
return (data.sessions || []).map((s) => ({
|
|
808
1047
|
sessionId: s.sessionId,
|
|
@@ -812,8 +1051,8 @@ var getGhostHistoryThunk = (0, import_toolkit3.createAsyncThunk)(
|
|
|
812
1051
|
status: s.status,
|
|
813
1052
|
passRate: s.passRate
|
|
814
1053
|
}));
|
|
815
|
-
} catch (
|
|
816
|
-
return rejectWithValue(
|
|
1054
|
+
} catch (error) {
|
|
1055
|
+
return rejectWithValue(extractThunkErrorMessage(error, "Failed to get ghost history"));
|
|
817
1056
|
}
|
|
818
1057
|
}
|
|
819
1058
|
);
|
|
@@ -848,7 +1087,7 @@ var ghostSlice = (0, import_toolkit3.createSlice)({
|
|
|
848
1087
|
state.status = "completed";
|
|
849
1088
|
}).addCase(stopGhostThunk.fulfilled, (state, action) => {
|
|
850
1089
|
if (action.payload.stopped) {
|
|
851
|
-
state.status = "
|
|
1090
|
+
state.status = "completed";
|
|
852
1091
|
} else {
|
|
853
1092
|
state.error = action.payload.status || "Ghost stop request did not stop a session";
|
|
854
1093
|
}
|
|
@@ -863,7 +1102,7 @@ var { clearGhostSession } = ghostSlice.actions;
|
|
|
863
1102
|
var ghostSlice_default = ghostSlice.reducer;
|
|
864
1103
|
|
|
865
1104
|
// src/utils/sdkVersion.ts
|
|
866
|
-
var SDK_VERSION = "0.6.
|
|
1105
|
+
var SDK_VERSION = "0.6.1";
|
|
867
1106
|
|
|
868
1107
|
// src/utils/generateNPCId.ts
|
|
869
1108
|
var generateNPCId = () => `ag_${Date.now().toString(36)}`;
|
|
@@ -944,7 +1183,8 @@ var npcSlice = (0, import_toolkit4.createSlice)({
|
|
|
944
1183
|
persona,
|
|
945
1184
|
state: initialState5 || {},
|
|
946
1185
|
history: [],
|
|
947
|
-
isBlocked: false
|
|
1186
|
+
isBlocked: false,
|
|
1187
|
+
stateLog: [{ timestamp: Date.now(), delta: initialState5 || {}, state: initialState5 || {} }]
|
|
948
1188
|
});
|
|
949
1189
|
state.activeNpcId = id;
|
|
950
1190
|
},
|
|
@@ -959,7 +1199,9 @@ var npcSlice = (0, import_toolkit4.createSlice)({
|
|
|
959
1199
|
const { id, delta } = action.payload;
|
|
960
1200
|
const npc = state.entities[id];
|
|
961
1201
|
if (npc) {
|
|
962
|
-
|
|
1202
|
+
const newState = { ...npc.state, ...delta };
|
|
1203
|
+
npc.state = newState;
|
|
1204
|
+
npc.stateLog.push({ timestamp: Date.now(), delta, state: newState });
|
|
963
1205
|
}
|
|
964
1206
|
},
|
|
965
1207
|
addToHistory: (state, action) => {
|
|
@@ -1029,6 +1271,7 @@ var initRemoteCortexThunk = (0, import_toolkit5.createAsyncThunk)(
|
|
|
1029
1271
|
async ({ model = "api-integrated", authKey, apiUrl, apiKey }, { dispatch: dispatch2, rejectWithValue }) => {
|
|
1030
1272
|
try {
|
|
1031
1273
|
const url = apiUrl || "https://api.forboc.ai";
|
|
1274
|
+
requireApiKeyGuidance(url, apiKey);
|
|
1032
1275
|
const data = await dispatch2(sdkApi.endpoints.postCortexInit.initiate({
|
|
1033
1276
|
request: { requestedModel: model, authKey },
|
|
1034
1277
|
apiUrl: url,
|
|
@@ -1040,8 +1283,8 @@ var initRemoteCortexThunk = (0, import_toolkit5.createAsyncThunk)(
|
|
|
1040
1283
|
ready: data.state?.toLowerCase() === "ready",
|
|
1041
1284
|
engine: "remote"
|
|
1042
1285
|
};
|
|
1043
|
-
} catch (
|
|
1044
|
-
return rejectWithValue(
|
|
1286
|
+
} catch (error) {
|
|
1287
|
+
return rejectWithValue(extractThunkErrorMessage(error, "Remote cortex init failed"));
|
|
1045
1288
|
}
|
|
1046
1289
|
}
|
|
1047
1290
|
);
|
|
@@ -1050,9 +1293,10 @@ var listCortexModelsThunk = (0, import_toolkit5.createAsyncThunk)(
|
|
|
1050
1293
|
async ({ apiUrl, apiKey }, { dispatch: dispatch2, rejectWithValue }) => {
|
|
1051
1294
|
try {
|
|
1052
1295
|
const url = apiUrl || "https://api.forboc.ai";
|
|
1296
|
+
requireApiKeyGuidance(url, apiKey);
|
|
1053
1297
|
return await dispatch2(sdkApi.endpoints.getCortexModels.initiate({ apiUrl: url, apiKey })).unwrap();
|
|
1054
|
-
} catch (
|
|
1055
|
-
return rejectWithValue(
|
|
1298
|
+
} catch (error) {
|
|
1299
|
+
return rejectWithValue(extractThunkErrorMessage(error, "Failed to list cortex models"));
|
|
1056
1300
|
}
|
|
1057
1301
|
}
|
|
1058
1302
|
);
|
|
@@ -1060,6 +1304,7 @@ var completeRemoteThunk = (0, import_toolkit5.createAsyncThunk)(
|
|
|
1060
1304
|
"cortex/completeRemote",
|
|
1061
1305
|
async ({ cortexId, prompt, options, apiUrl, apiKey }, { dispatch: dispatch2, rejectWithValue }) => {
|
|
1062
1306
|
try {
|
|
1307
|
+
requireApiKeyGuidance(apiUrl, apiKey);
|
|
1063
1308
|
const data = await dispatch2(sdkApi.endpoints.postCortexComplete.initiate({
|
|
1064
1309
|
cortexId,
|
|
1065
1310
|
prompt,
|
|
@@ -1068,8 +1313,8 @@ var completeRemoteThunk = (0, import_toolkit5.createAsyncThunk)(
|
|
|
1068
1313
|
apiKey
|
|
1069
1314
|
})).unwrap();
|
|
1070
1315
|
return data.text;
|
|
1071
|
-
} catch (
|
|
1072
|
-
return rejectWithValue(
|
|
1316
|
+
} catch (error) {
|
|
1317
|
+
return rejectWithValue(extractThunkErrorMessage(error, "Remote completing failed"));
|
|
1073
1318
|
}
|
|
1074
1319
|
}
|
|
1075
1320
|
);
|
|
@@ -1304,6 +1549,13 @@ var dispatch = store.dispatch;
|
|
|
1304
1549
|
|
|
1305
1550
|
// src/thunks.ts
|
|
1306
1551
|
var import_toolkit10 = require("@reduxjs/toolkit");
|
|
1552
|
+
var extractThunkErrorMessage2 = (e) => {
|
|
1553
|
+
if (typeof e === "string") return e;
|
|
1554
|
+
if (e?.data?.message) return String(e.data.message);
|
|
1555
|
+
if (e?.error) return String(e.error);
|
|
1556
|
+
if (e?.message) return String(e.message);
|
|
1557
|
+
return "Protocol processing failed";
|
|
1558
|
+
};
|
|
1307
1559
|
var processNPC = (0, import_toolkit10.createAsyncThunk)(
|
|
1308
1560
|
"npc/process",
|
|
1309
1561
|
async ({ npcId: argNpcId, text, context = {}, apiUrl, apiKey, memory, cortex, persona: argPersona }, { getState, dispatch: dispatch2, rejectWithValue }) => {
|
|
@@ -1327,61 +1579,111 @@ var processNPC = (0, import_toolkit10.createAsyncThunk)(
|
|
|
1327
1579
|
const directiveId = `${npcId}:${Date.now()}`;
|
|
1328
1580
|
dispatch2(directiveRunStarted({ id: directiveId, npcId, observation: text }));
|
|
1329
1581
|
try {
|
|
1330
|
-
const
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
const contextResult = await dispatch2(
|
|
1343
|
-
sdkApi.endpoints.postContext.initiate({ npcId, request: { memories: recalledMemories, observation: text, npcState: currentState, persona }, apiUrl, apiKey })
|
|
1344
|
-
).unwrap();
|
|
1345
|
-
dispatch2(contextComposed({ id: directiveId, prompt: contextResult.prompt, constraints: contextResult.constraints }));
|
|
1346
|
-
const generatedText = await cortex.complete(contextResult.prompt, {
|
|
1347
|
-
maxTokens: contextResult.constraints.maxTokens,
|
|
1348
|
-
temperature: contextResult.constraints.temperature,
|
|
1349
|
-
stop: contextResult.constraints.stop
|
|
1350
|
-
});
|
|
1351
|
-
const verdictResult = await dispatch2(
|
|
1352
|
-
sdkApi.endpoints.postVerdict.initiate({ npcId, request: { generatedOutput: generatedText, observation: text, npcState: currentState }, apiUrl, apiKey })
|
|
1353
|
-
).unwrap();
|
|
1354
|
-
dispatch2(verdictValidated({ id: directiveId, verdict: verdictResult }));
|
|
1355
|
-
if (!verdictResult.valid) {
|
|
1356
|
-
dispatch2(blockAction({ id: npcId, reason: verdictResult.dialogue || "Validation Failed" }));
|
|
1357
|
-
return {
|
|
1358
|
-
dialogue: verdictResult.dialogue,
|
|
1359
|
-
action: verdictResult.action,
|
|
1360
|
-
thought: verdictResult.dialogue
|
|
1361
|
-
};
|
|
1362
|
-
}
|
|
1363
|
-
if (verdictResult.memoryStore?.length && !memory) {
|
|
1364
|
-
return rejectWithValue("API returned memoryStore instructions, but no memory engine is configured");
|
|
1365
|
-
}
|
|
1366
|
-
if (memory && verdictResult.memoryStore) {
|
|
1367
|
-
for (const inst of verdictResult.memoryStore) {
|
|
1368
|
-
await memory.store(inst.text, inst.type, inst.importance);
|
|
1582
|
+
const initialTape = {
|
|
1583
|
+
observation: text,
|
|
1584
|
+
context,
|
|
1585
|
+
npcState: currentState,
|
|
1586
|
+
persona,
|
|
1587
|
+
memories: [],
|
|
1588
|
+
vectorQueried: false
|
|
1589
|
+
};
|
|
1590
|
+
const maxTurns = 12;
|
|
1591
|
+
const persistMemoryInstructionsRecursively = async (instructions, index = 0) => {
|
|
1592
|
+
if (!memory || index >= instructions.length) {
|
|
1593
|
+
return;
|
|
1369
1594
|
}
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
}
|
|
1374
|
-
const
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1595
|
+
const inst = instructions[index];
|
|
1596
|
+
await memory.store(inst.text, inst.type, inst.importance);
|
|
1597
|
+
await persistMemoryInstructionsRecursively(instructions, index + 1);
|
|
1598
|
+
};
|
|
1599
|
+
const runProtocolRecursively = async (tape, lastResult, turn) => {
|
|
1600
|
+
if (turn >= maxTurns) {
|
|
1601
|
+
return rejectWithValue(`Protocol loop exceeded max turns (${maxTurns})`);
|
|
1602
|
+
}
|
|
1603
|
+
const request = { tape, lastResult };
|
|
1604
|
+
const processResult = await dispatch2(
|
|
1605
|
+
sdkApi.endpoints.postNpcProcess.initiate({ npcId, request, apiUrl, apiKey })
|
|
1606
|
+
).unwrap();
|
|
1607
|
+
const nextTape = processResult.tape;
|
|
1608
|
+
const instruction = processResult.instruction;
|
|
1609
|
+
if (instruction.type === "IdentifyActor") {
|
|
1610
|
+
return runProtocolRecursively(nextTape, {
|
|
1611
|
+
type: "IdentifyActorResult",
|
|
1612
|
+
actor: {
|
|
1613
|
+
npcId,
|
|
1614
|
+
persona,
|
|
1615
|
+
data: nextTape.npcState
|
|
1616
|
+
}
|
|
1617
|
+
}, turn + 1);
|
|
1618
|
+
}
|
|
1619
|
+
if (instruction.type === "QueryVector") {
|
|
1620
|
+
dispatch2(directiveReceived({
|
|
1621
|
+
id: directiveId,
|
|
1622
|
+
response: { memoryRecall: { query: instruction.query, limit: instruction.limit, threshold: instruction.threshold } }
|
|
1623
|
+
}));
|
|
1624
|
+
if (!memory) {
|
|
1625
|
+
return rejectWithValue("API requested memory recall, but no memory engine is configured");
|
|
1626
|
+
}
|
|
1627
|
+
const recalled = await memory.recall(instruction.query, instruction.limit, instruction.threshold);
|
|
1628
|
+
return runProtocolRecursively(nextTape, {
|
|
1629
|
+
type: "QueryVectorResult",
|
|
1630
|
+
memories: recalled.map((m) => ({ text: m.text, type: m.type, importance: m.importance, similarity: m.similarity }))
|
|
1631
|
+
}, turn + 1);
|
|
1632
|
+
}
|
|
1633
|
+
if (instruction.type === "ExecuteInference") {
|
|
1634
|
+
dispatch2(contextComposed({ id: directiveId, prompt: instruction.prompt, constraints: instruction.constraints }));
|
|
1635
|
+
const generatedText = await cortex.complete(instruction.prompt, {
|
|
1636
|
+
maxTokens: instruction.constraints.maxTokens,
|
|
1637
|
+
temperature: instruction.constraints.temperature,
|
|
1638
|
+
stop: instruction.constraints.stop
|
|
1639
|
+
});
|
|
1640
|
+
return runProtocolRecursively(nextTape, {
|
|
1641
|
+
type: "ExecuteInferenceResult",
|
|
1642
|
+
generatedOutput: generatedText
|
|
1643
|
+
}, turn + 1);
|
|
1644
|
+
}
|
|
1645
|
+
if (instruction.type === "Finalize") {
|
|
1646
|
+
const finalize = instruction;
|
|
1647
|
+
dispatch2(verdictValidated({
|
|
1648
|
+
id: directiveId,
|
|
1649
|
+
verdict: {
|
|
1650
|
+
valid: finalize.valid,
|
|
1651
|
+
signature: finalize.signature,
|
|
1652
|
+
memoryStore: finalize.memoryStore,
|
|
1653
|
+
stateDelta: finalize.stateTransform,
|
|
1654
|
+
action: finalize.action,
|
|
1655
|
+
dialogue: finalize.dialogue
|
|
1656
|
+
}
|
|
1657
|
+
}));
|
|
1658
|
+
if (!finalize.valid) {
|
|
1659
|
+
dispatch2(blockAction({ id: npcId, reason: finalize.dialogue || "Validation Failed" }));
|
|
1660
|
+
return {
|
|
1661
|
+
dialogue: finalize.dialogue,
|
|
1662
|
+
action: finalize.action,
|
|
1663
|
+
thought: finalize.dialogue
|
|
1664
|
+
};
|
|
1665
|
+
}
|
|
1666
|
+
if (finalize.memoryStore?.length && !memory) {
|
|
1667
|
+
return rejectWithValue("API returned memoryStore instructions, but no memory engine is configured");
|
|
1668
|
+
}
|
|
1669
|
+
await persistMemoryInstructionsRecursively(finalize.memoryStore || []);
|
|
1670
|
+
if (finalize.stateTransform) {
|
|
1671
|
+
dispatch2(updateNPCState({ id: npcId, delta: finalize.stateTransform }));
|
|
1672
|
+
}
|
|
1673
|
+
dispatch2(setLastAction({ id: npcId, action: finalize.action }));
|
|
1674
|
+
dispatch2(addToHistory({ id: npcId, role: "user", content: text }));
|
|
1675
|
+
dispatch2(addToHistory({ id: npcId, role: "assistant", content: finalize.dialogue }));
|
|
1676
|
+
return {
|
|
1677
|
+
dialogue: finalize.dialogue,
|
|
1678
|
+
action: finalize.action,
|
|
1679
|
+
thought: finalize.dialogue
|
|
1680
|
+
};
|
|
1681
|
+
}
|
|
1682
|
+
return rejectWithValue("API returned unknown instruction type");
|
|
1382
1683
|
};
|
|
1684
|
+
return runProtocolRecursively(initialTape, void 0, 0);
|
|
1383
1685
|
} catch (e) {
|
|
1384
|
-
const message = e
|
|
1686
|
+
const message = extractThunkErrorMessage2(e);
|
|
1385
1687
|
dispatch2(directiveRunFailed({ id: directiveId, error: String(message) }));
|
|
1386
1688
|
return rejectWithValue(String(message));
|
|
1387
1689
|
}
|
|
@@ -1502,6 +1804,8 @@ var clearMemoryRemoteThunk = (0, import_toolkit10.createAsyncThunk)(
|
|
|
1502
1804
|
getGhostStatusThunk,
|
|
1503
1805
|
getSoulListThunk,
|
|
1504
1806
|
ghostSlice,
|
|
1807
|
+
handler_ArweaveDownload,
|
|
1808
|
+
handler_ArweaveUpload,
|
|
1505
1809
|
importNpcFromSoulThunk,
|
|
1506
1810
|
importSoulFromArweaveThunk,
|
|
1507
1811
|
initRemoteCortexThunk,
|