@forbocai/core 0.6.2 → 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 +396 -20
- package/dist/index.d.ts +396 -20
- package/dist/index.js +294 -62
- package/dist/index.mjs +292 -62
- 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,
|
|
@@ -325,6 +327,16 @@ var sdkApi = (0, import_query.createApi)({
|
|
|
325
327
|
invalidatesTags: ["Soul"],
|
|
326
328
|
transformResponse: (response) => response
|
|
327
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
|
+
}),
|
|
328
340
|
getSoulImport: builder.query({
|
|
329
341
|
query: ({ txId, apiUrl, apiKey }) => ({
|
|
330
342
|
url: `${apiUrl}/souls/${txId}`,
|
|
@@ -433,6 +445,16 @@ var sdkApi = (0, import_query.createApi)({
|
|
|
433
445
|
invalidatesTags: ["NPC"],
|
|
434
446
|
transformResponse: (response) => response
|
|
435
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
|
+
}),
|
|
436
458
|
// Cortex Remote Endpoint
|
|
437
459
|
postCortexComplete: builder.mutation({
|
|
438
460
|
query: ({ cortexId, prompt, options, apiUrl, apiKey }) => ({
|
|
@@ -452,6 +474,25 @@ var sdkApi = (0, import_query.createApi)({
|
|
|
452
474
|
})
|
|
453
475
|
});
|
|
454
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
|
+
|
|
455
496
|
// src/bridgeSlice.ts
|
|
456
497
|
var initialState = {
|
|
457
498
|
activePresets: [],
|
|
@@ -466,6 +507,7 @@ var validateBridgeThunk = (0, import_toolkit.createAsyncThunk)(
|
|
|
466
507
|
async ({ action, context, npcId, apiUrl, apiKey }, { dispatch: dispatch2, rejectWithValue }) => {
|
|
467
508
|
try {
|
|
468
509
|
const url = apiUrl || "https://api.forboc.ai";
|
|
510
|
+
requireApiKeyGuidance(url, apiKey);
|
|
469
511
|
const data = await dispatch2(sdkApi.endpoints.postBridgeValidate.initiate({
|
|
470
512
|
request: { action, context },
|
|
471
513
|
npcId,
|
|
@@ -473,8 +515,8 @@ var validateBridgeThunk = (0, import_toolkit.createAsyncThunk)(
|
|
|
473
515
|
apiKey
|
|
474
516
|
})).unwrap();
|
|
475
517
|
return data;
|
|
476
|
-
} catch (
|
|
477
|
-
return rejectWithValue(
|
|
518
|
+
} catch (error) {
|
|
519
|
+
return rejectWithValue(extractThunkErrorMessage(error, "Bridge validation failed"));
|
|
478
520
|
}
|
|
479
521
|
}
|
|
480
522
|
);
|
|
@@ -483,9 +525,10 @@ var loadBridgePresetThunk = (0, import_toolkit.createAsyncThunk)(
|
|
|
483
525
|
async ({ presetName, apiUrl, apiKey }, { dispatch: dispatch2, rejectWithValue }) => {
|
|
484
526
|
try {
|
|
485
527
|
const url = apiUrl || "https://api.forboc.ai";
|
|
528
|
+
requireApiKeyGuidance(url, apiKey);
|
|
486
529
|
return await dispatch2(sdkApi.endpoints.postBridgePreset.initiate({ presetName, apiUrl: url, apiKey })).unwrap();
|
|
487
|
-
} catch (
|
|
488
|
-
return rejectWithValue(
|
|
530
|
+
} catch (error) {
|
|
531
|
+
return rejectWithValue(extractThunkErrorMessage(error, "Failed to load preset"));
|
|
489
532
|
}
|
|
490
533
|
}
|
|
491
534
|
);
|
|
@@ -494,9 +537,10 @@ var getBridgeRulesThunk = (0, import_toolkit.createAsyncThunk)(
|
|
|
494
537
|
async ({ apiUrl, apiKey }, { dispatch: dispatch2, rejectWithValue }) => {
|
|
495
538
|
try {
|
|
496
539
|
const url = apiUrl || "https://api.forboc.ai";
|
|
540
|
+
requireApiKeyGuidance(url, apiKey);
|
|
497
541
|
return await dispatch2(sdkApi.endpoints.getBridgeRules.initiate({ apiUrl: url, apiKey })).unwrap();
|
|
498
|
-
} catch (
|
|
499
|
-
return rejectWithValue(
|
|
542
|
+
} catch (error) {
|
|
543
|
+
return rejectWithValue(extractThunkErrorMessage(error, "Failed to list bridge rules"));
|
|
500
544
|
}
|
|
501
545
|
}
|
|
502
546
|
);
|
|
@@ -505,9 +549,10 @@ var listRulesetsThunk = (0, import_toolkit.createAsyncThunk)(
|
|
|
505
549
|
async ({ apiUrl, apiKey }, { dispatch: dispatch2, rejectWithValue }) => {
|
|
506
550
|
try {
|
|
507
551
|
const url = apiUrl || "https://api.forboc.ai";
|
|
552
|
+
requireApiKeyGuidance(url, apiKey);
|
|
508
553
|
return await dispatch2(sdkApi.endpoints.getRulesets.initiate({ apiUrl: url, apiKey })).unwrap();
|
|
509
|
-
} catch (
|
|
510
|
-
return rejectWithValue(
|
|
554
|
+
} catch (error) {
|
|
555
|
+
return rejectWithValue(extractThunkErrorMessage(error, "Failed to list rulesets"));
|
|
511
556
|
}
|
|
512
557
|
}
|
|
513
558
|
);
|
|
@@ -516,9 +561,10 @@ var listRulePresetsThunk = (0, import_toolkit.createAsyncThunk)(
|
|
|
516
561
|
async ({ apiUrl, apiKey }, { dispatch: dispatch2, rejectWithValue }) => {
|
|
517
562
|
try {
|
|
518
563
|
const url = apiUrl || "https://api.forboc.ai";
|
|
564
|
+
requireApiKeyGuidance(url, apiKey);
|
|
519
565
|
return await dispatch2(sdkApi.endpoints.getRulePresets.initiate({ apiUrl: url, apiKey })).unwrap();
|
|
520
|
-
} catch (
|
|
521
|
-
return rejectWithValue(
|
|
566
|
+
} catch (error) {
|
|
567
|
+
return rejectWithValue(extractThunkErrorMessage(error, "Failed to list rule presets"));
|
|
522
568
|
}
|
|
523
569
|
}
|
|
524
570
|
);
|
|
@@ -527,9 +573,10 @@ var registerRulesetThunk = (0, import_toolkit.createAsyncThunk)(
|
|
|
527
573
|
async ({ ruleset, apiUrl, apiKey }, { dispatch: dispatch2, rejectWithValue }) => {
|
|
528
574
|
try {
|
|
529
575
|
const url = apiUrl || "https://api.forboc.ai";
|
|
576
|
+
requireApiKeyGuidance(url, apiKey);
|
|
530
577
|
return await dispatch2(sdkApi.endpoints.postRuleRegister.initiate({ request: ruleset, apiUrl: url, apiKey })).unwrap();
|
|
531
|
-
} catch (
|
|
532
|
-
return rejectWithValue(
|
|
578
|
+
} catch (error) {
|
|
579
|
+
return rejectWithValue(extractThunkErrorMessage(error, "Failed to register ruleset"));
|
|
533
580
|
}
|
|
534
581
|
}
|
|
535
582
|
);
|
|
@@ -538,9 +585,10 @@ var deleteRulesetThunk = (0, import_toolkit.createAsyncThunk)(
|
|
|
538
585
|
async ({ rulesetId, apiUrl, apiKey }, { dispatch: dispatch2, rejectWithValue }) => {
|
|
539
586
|
try {
|
|
540
587
|
const url = apiUrl || "https://api.forboc.ai";
|
|
588
|
+
requireApiKeyGuidance(url, apiKey);
|
|
541
589
|
return await dispatch2(sdkApi.endpoints.deleteRule.initiate({ rulesetId, apiUrl: url, apiKey })).unwrap();
|
|
542
|
-
} catch (
|
|
543
|
-
return rejectWithValue(
|
|
590
|
+
} catch (error) {
|
|
591
|
+
return rejectWithValue(extractThunkErrorMessage(error, "Failed to delete ruleset"));
|
|
544
592
|
}
|
|
545
593
|
}
|
|
546
594
|
);
|
|
@@ -589,6 +637,124 @@ var bridgeSlice_default = bridgeSlice.reducer;
|
|
|
589
637
|
|
|
590
638
|
// src/soulSlice.ts
|
|
591
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
|
|
592
758
|
var initialState2 = {
|
|
593
759
|
exportStatus: "idle",
|
|
594
760
|
importStatus: "idle",
|
|
@@ -599,26 +765,45 @@ var initialState2 = {
|
|
|
599
765
|
};
|
|
600
766
|
var remoteExportSoulThunk = (0, import_toolkit2.createAsyncThunk)(
|
|
601
767
|
"soul/export",
|
|
602
|
-
async ({ npcId: argNpcId, apiUrl, apiKey
|
|
768
|
+
async ({ npcId: argNpcId, apiUrl, apiKey }, { getState, dispatch: dispatch2, rejectWithValue }) => {
|
|
603
769
|
try {
|
|
604
770
|
const state = getState().npc;
|
|
605
771
|
const npcId = argNpcId || state.activeNpcId;
|
|
606
772
|
const npc = state.entities[npcId];
|
|
607
773
|
if (!npc) throw new Error(`NPC ${npcId} not found`);
|
|
608
774
|
const url = apiUrl || "https://api.forboc.ai";
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
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();
|
|
615
800
|
return {
|
|
616
|
-
txId:
|
|
617
|
-
url:
|
|
618
|
-
soul:
|
|
801
|
+
txId: final.txId,
|
|
802
|
+
url: final.arweaveUrl,
|
|
803
|
+
soul: final.soul
|
|
619
804
|
};
|
|
620
|
-
} catch (
|
|
621
|
-
return rejectWithValue(
|
|
805
|
+
} catch (error) {
|
|
806
|
+
return rejectWithValue(extractThunkErrorMessage(error, "Soul export failed"));
|
|
622
807
|
}
|
|
623
808
|
}
|
|
624
809
|
);
|
|
@@ -627,10 +812,31 @@ var importSoulFromArweaveThunk = (0, import_toolkit2.createAsyncThunk)(
|
|
|
627
812
|
async ({ txId, apiUrl, apiKey }, { dispatch: dispatch2, rejectWithValue }) => {
|
|
628
813
|
try {
|
|
629
814
|
const url = apiUrl || "https://api.forboc.ai";
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
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"));
|
|
634
840
|
}
|
|
635
841
|
}
|
|
636
842
|
);
|
|
@@ -639,10 +845,11 @@ var getSoulListThunk = (0, import_toolkit2.createAsyncThunk)(
|
|
|
639
845
|
async ({ limit = 50, apiUrl, apiKey }, { dispatch: dispatch2, rejectWithValue }) => {
|
|
640
846
|
try {
|
|
641
847
|
const url = apiUrl || "https://api.forboc.ai";
|
|
848
|
+
requireApiKeyGuidance(url, apiKey);
|
|
642
849
|
const data = await dispatch2(sdkApi.endpoints.getSouls.initiate({ limit, apiUrl: url, apiKey })).unwrap();
|
|
643
850
|
return data.souls || [];
|
|
644
|
-
} catch (
|
|
645
|
-
return rejectWithValue(
|
|
851
|
+
} catch (error) {
|
|
852
|
+
return rejectWithValue(extractThunkErrorMessage(error, "Failed to list souls"));
|
|
646
853
|
}
|
|
647
854
|
}
|
|
648
855
|
);
|
|
@@ -651,9 +858,10 @@ var verifySoulThunk = (0, import_toolkit2.createAsyncThunk)(
|
|
|
651
858
|
async ({ txId, apiUrl, apiKey }, { dispatch: dispatch2, rejectWithValue }) => {
|
|
652
859
|
try {
|
|
653
860
|
const url = apiUrl || "https://api.forboc.ai";
|
|
861
|
+
requireApiKeyGuidance(url, apiKey);
|
|
654
862
|
return await dispatch2(sdkApi.endpoints.postSoulVerify.initiate({ txId, apiUrl: url, apiKey })).unwrap();
|
|
655
|
-
} catch (
|
|
656
|
-
return rejectWithValue(
|
|
863
|
+
} catch (error) {
|
|
864
|
+
return rejectWithValue(extractThunkErrorMessage(error, "Soul verify failed"));
|
|
657
865
|
}
|
|
658
866
|
}
|
|
659
867
|
);
|
|
@@ -662,13 +870,24 @@ var importNpcFromSoulThunk = (0, import_toolkit2.createAsyncThunk)(
|
|
|
662
870
|
async ({ txId, apiUrl, apiKey }, { dispatch: dispatch2, rejectWithValue }) => {
|
|
663
871
|
try {
|
|
664
872
|
const url = apiUrl || "https://api.forboc.ai";
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
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"));
|
|
672
891
|
}
|
|
673
892
|
}
|
|
674
893
|
);
|
|
@@ -727,6 +946,7 @@ var startGhostThunk = (0, import_toolkit3.createAsyncThunk)(
|
|
|
727
946
|
async (config, { dispatch: dispatch2, rejectWithValue }) => {
|
|
728
947
|
try {
|
|
729
948
|
const apiUrl = config.apiUrl || "https://api.forboc.ai";
|
|
949
|
+
requireApiKeyGuidance(apiUrl, config.apiKey);
|
|
730
950
|
const data = await dispatch2(sdkApi.endpoints.postGhostRun.initiate({
|
|
731
951
|
request: { testSuite: config.testSuite, duration: config.duration ?? 300 },
|
|
732
952
|
apiUrl,
|
|
@@ -736,8 +956,8 @@ var startGhostThunk = (0, import_toolkit3.createAsyncThunk)(
|
|
|
736
956
|
sessionId: data.sessionId,
|
|
737
957
|
status: data.runStatus
|
|
738
958
|
};
|
|
739
|
-
} catch (
|
|
740
|
-
return rejectWithValue(
|
|
959
|
+
} catch (error) {
|
|
960
|
+
return rejectWithValue(extractThunkErrorMessage(error, "Failed to start Ghost"));
|
|
741
961
|
}
|
|
742
962
|
}
|
|
743
963
|
);
|
|
@@ -749,6 +969,7 @@ var getGhostStatusThunk = (0, import_toolkit3.createAsyncThunk)(
|
|
|
749
969
|
const targetSession = sessionId || state.activeSessionId;
|
|
750
970
|
if (!targetSession) throw new Error("No active Ghost session");
|
|
751
971
|
const url = apiUrl || "https://api.forboc.ai";
|
|
972
|
+
requireApiKeyGuidance(url, apiKey);
|
|
752
973
|
const data = await dispatch2(sdkApi.endpoints.getGhostStatus.initiate({ sessionId: targetSession, apiUrl: url, apiKey })).unwrap();
|
|
753
974
|
return {
|
|
754
975
|
sessionId: data.ghostSessionId,
|
|
@@ -758,8 +979,8 @@ var getGhostStatusThunk = (0, import_toolkit3.createAsyncThunk)(
|
|
|
758
979
|
duration: data.ghostDuration || 0,
|
|
759
980
|
errors: data.ghostErrors
|
|
760
981
|
};
|
|
761
|
-
} catch (
|
|
762
|
-
return rejectWithValue(
|
|
982
|
+
} catch (error) {
|
|
983
|
+
return rejectWithValue(extractThunkErrorMessage(error, "Failed to get ghost status"));
|
|
763
984
|
}
|
|
764
985
|
}
|
|
765
986
|
);
|
|
@@ -771,6 +992,7 @@ var getGhostResultsThunk = (0, import_toolkit3.createAsyncThunk)(
|
|
|
771
992
|
const targetSession = sessionId || state.activeSessionId;
|
|
772
993
|
if (!targetSession) throw new Error("No active Ghost session");
|
|
773
994
|
const url = apiUrl || "https://api.forboc.ai";
|
|
995
|
+
requireApiKeyGuidance(url, apiKey);
|
|
774
996
|
const data = await dispatch2(sdkApi.endpoints.getGhostResults.initiate({ sessionId: targetSession, apiUrl: url, apiKey })).unwrap();
|
|
775
997
|
return {
|
|
776
998
|
sessionId: data.resultsSessionId,
|
|
@@ -789,8 +1011,8 @@ var getGhostResultsThunk = (0, import_toolkit3.createAsyncThunk)(
|
|
|
789
1011
|
coverage: data.resultsCoverage,
|
|
790
1012
|
metrics: Object.fromEntries(data.resultsMetrics || [])
|
|
791
1013
|
};
|
|
792
|
-
} catch (
|
|
793
|
-
return rejectWithValue(
|
|
1014
|
+
} catch (error) {
|
|
1015
|
+
return rejectWithValue(extractThunkErrorMessage(error, "Failed to get ghost results"));
|
|
794
1016
|
}
|
|
795
1017
|
}
|
|
796
1018
|
);
|
|
@@ -802,14 +1024,15 @@ var stopGhostThunk = (0, import_toolkit3.createAsyncThunk)(
|
|
|
802
1024
|
const targetSession = sessionId || state.activeSessionId;
|
|
803
1025
|
if (!targetSession) throw new Error("No active Ghost session");
|
|
804
1026
|
const url = apiUrl || "https://api.forboc.ai";
|
|
1027
|
+
requireApiKeyGuidance(url, apiKey);
|
|
805
1028
|
const data = await dispatch2(sdkApi.endpoints.postGhostStop.initiate({ sessionId: targetSession, apiUrl: url, apiKey })).unwrap();
|
|
806
1029
|
return {
|
|
807
1030
|
stopped: data.stopped,
|
|
808
1031
|
status: data.stopStatus,
|
|
809
1032
|
sessionId: data.stopSessionId
|
|
810
1033
|
};
|
|
811
|
-
} catch (
|
|
812
|
-
return rejectWithValue(
|
|
1034
|
+
} catch (error) {
|
|
1035
|
+
return rejectWithValue(extractThunkErrorMessage(error, "Failed to stop ghost session"));
|
|
813
1036
|
}
|
|
814
1037
|
}
|
|
815
1038
|
);
|
|
@@ -818,6 +1041,7 @@ var getGhostHistoryThunk = (0, import_toolkit3.createAsyncThunk)(
|
|
|
818
1041
|
async ({ limit = 10, apiUrl, apiKey }, { dispatch: dispatch2, rejectWithValue }) => {
|
|
819
1042
|
try {
|
|
820
1043
|
const url = apiUrl || "https://api.forboc.ai";
|
|
1044
|
+
requireApiKeyGuidance(url, apiKey);
|
|
821
1045
|
const data = await dispatch2(sdkApi.endpoints.getGhostHistory.initiate({ limit, apiUrl: url, apiKey })).unwrap();
|
|
822
1046
|
return (data.sessions || []).map((s) => ({
|
|
823
1047
|
sessionId: s.sessionId,
|
|
@@ -827,8 +1051,8 @@ var getGhostHistoryThunk = (0, import_toolkit3.createAsyncThunk)(
|
|
|
827
1051
|
status: s.status,
|
|
828
1052
|
passRate: s.passRate
|
|
829
1053
|
}));
|
|
830
|
-
} catch (
|
|
831
|
-
return rejectWithValue(
|
|
1054
|
+
} catch (error) {
|
|
1055
|
+
return rejectWithValue(extractThunkErrorMessage(error, "Failed to get ghost history"));
|
|
832
1056
|
}
|
|
833
1057
|
}
|
|
834
1058
|
);
|
|
@@ -863,7 +1087,7 @@ var ghostSlice = (0, import_toolkit3.createSlice)({
|
|
|
863
1087
|
state.status = "completed";
|
|
864
1088
|
}).addCase(stopGhostThunk.fulfilled, (state, action) => {
|
|
865
1089
|
if (action.payload.stopped) {
|
|
866
|
-
state.status = "
|
|
1090
|
+
state.status = "completed";
|
|
867
1091
|
} else {
|
|
868
1092
|
state.error = action.payload.status || "Ghost stop request did not stop a session";
|
|
869
1093
|
}
|
|
@@ -959,7 +1183,8 @@ var npcSlice = (0, import_toolkit4.createSlice)({
|
|
|
959
1183
|
persona,
|
|
960
1184
|
state: initialState5 || {},
|
|
961
1185
|
history: [],
|
|
962
|
-
isBlocked: false
|
|
1186
|
+
isBlocked: false,
|
|
1187
|
+
stateLog: [{ timestamp: Date.now(), delta: initialState5 || {}, state: initialState5 || {} }]
|
|
963
1188
|
});
|
|
964
1189
|
state.activeNpcId = id;
|
|
965
1190
|
},
|
|
@@ -974,7 +1199,9 @@ var npcSlice = (0, import_toolkit4.createSlice)({
|
|
|
974
1199
|
const { id, delta } = action.payload;
|
|
975
1200
|
const npc = state.entities[id];
|
|
976
1201
|
if (npc) {
|
|
977
|
-
|
|
1202
|
+
const newState = { ...npc.state, ...delta };
|
|
1203
|
+
npc.state = newState;
|
|
1204
|
+
npc.stateLog.push({ timestamp: Date.now(), delta, state: newState });
|
|
978
1205
|
}
|
|
979
1206
|
},
|
|
980
1207
|
addToHistory: (state, action) => {
|
|
@@ -1044,6 +1271,7 @@ var initRemoteCortexThunk = (0, import_toolkit5.createAsyncThunk)(
|
|
|
1044
1271
|
async ({ model = "api-integrated", authKey, apiUrl, apiKey }, { dispatch: dispatch2, rejectWithValue }) => {
|
|
1045
1272
|
try {
|
|
1046
1273
|
const url = apiUrl || "https://api.forboc.ai";
|
|
1274
|
+
requireApiKeyGuidance(url, apiKey);
|
|
1047
1275
|
const data = await dispatch2(sdkApi.endpoints.postCortexInit.initiate({
|
|
1048
1276
|
request: { requestedModel: model, authKey },
|
|
1049
1277
|
apiUrl: url,
|
|
@@ -1055,8 +1283,8 @@ var initRemoteCortexThunk = (0, import_toolkit5.createAsyncThunk)(
|
|
|
1055
1283
|
ready: data.state?.toLowerCase() === "ready",
|
|
1056
1284
|
engine: "remote"
|
|
1057
1285
|
};
|
|
1058
|
-
} catch (
|
|
1059
|
-
return rejectWithValue(
|
|
1286
|
+
} catch (error) {
|
|
1287
|
+
return rejectWithValue(extractThunkErrorMessage(error, "Remote cortex init failed"));
|
|
1060
1288
|
}
|
|
1061
1289
|
}
|
|
1062
1290
|
);
|
|
@@ -1065,9 +1293,10 @@ var listCortexModelsThunk = (0, import_toolkit5.createAsyncThunk)(
|
|
|
1065
1293
|
async ({ apiUrl, apiKey }, { dispatch: dispatch2, rejectWithValue }) => {
|
|
1066
1294
|
try {
|
|
1067
1295
|
const url = apiUrl || "https://api.forboc.ai";
|
|
1296
|
+
requireApiKeyGuidance(url, apiKey);
|
|
1068
1297
|
return await dispatch2(sdkApi.endpoints.getCortexModels.initiate({ apiUrl: url, apiKey })).unwrap();
|
|
1069
|
-
} catch (
|
|
1070
|
-
return rejectWithValue(
|
|
1298
|
+
} catch (error) {
|
|
1299
|
+
return rejectWithValue(extractThunkErrorMessage(error, "Failed to list cortex models"));
|
|
1071
1300
|
}
|
|
1072
1301
|
}
|
|
1073
1302
|
);
|
|
@@ -1075,6 +1304,7 @@ var completeRemoteThunk = (0, import_toolkit5.createAsyncThunk)(
|
|
|
1075
1304
|
"cortex/completeRemote",
|
|
1076
1305
|
async ({ cortexId, prompt, options, apiUrl, apiKey }, { dispatch: dispatch2, rejectWithValue }) => {
|
|
1077
1306
|
try {
|
|
1307
|
+
requireApiKeyGuidance(apiUrl, apiKey);
|
|
1078
1308
|
const data = await dispatch2(sdkApi.endpoints.postCortexComplete.initiate({
|
|
1079
1309
|
cortexId,
|
|
1080
1310
|
prompt,
|
|
@@ -1083,8 +1313,8 @@ var completeRemoteThunk = (0, import_toolkit5.createAsyncThunk)(
|
|
|
1083
1313
|
apiKey
|
|
1084
1314
|
})).unwrap();
|
|
1085
1315
|
return data.text;
|
|
1086
|
-
} catch (
|
|
1087
|
-
return rejectWithValue(
|
|
1316
|
+
} catch (error) {
|
|
1317
|
+
return rejectWithValue(extractThunkErrorMessage(error, "Remote completing failed"));
|
|
1088
1318
|
}
|
|
1089
1319
|
}
|
|
1090
1320
|
);
|
|
@@ -1319,7 +1549,7 @@ var dispatch = store.dispatch;
|
|
|
1319
1549
|
|
|
1320
1550
|
// src/thunks.ts
|
|
1321
1551
|
var import_toolkit10 = require("@reduxjs/toolkit");
|
|
1322
|
-
var
|
|
1552
|
+
var extractThunkErrorMessage2 = (e) => {
|
|
1323
1553
|
if (typeof e === "string") return e;
|
|
1324
1554
|
if (e?.data?.message) return String(e.data.message);
|
|
1325
1555
|
if (e?.error) return String(e.error);
|
|
@@ -1453,7 +1683,7 @@ var processNPC = (0, import_toolkit10.createAsyncThunk)(
|
|
|
1453
1683
|
};
|
|
1454
1684
|
return runProtocolRecursively(initialTape, void 0, 0);
|
|
1455
1685
|
} catch (e) {
|
|
1456
|
-
const message =
|
|
1686
|
+
const message = extractThunkErrorMessage2(e);
|
|
1457
1687
|
dispatch2(directiveRunFailed({ id: directiveId, error: String(message) }));
|
|
1458
1688
|
return rejectWithValue(String(message));
|
|
1459
1689
|
}
|
|
@@ -1574,6 +1804,8 @@ var clearMemoryRemoteThunk = (0, import_toolkit10.createAsyncThunk)(
|
|
|
1574
1804
|
getGhostStatusThunk,
|
|
1575
1805
|
getSoulListThunk,
|
|
1576
1806
|
ghostSlice,
|
|
1807
|
+
handler_ArweaveDownload,
|
|
1808
|
+
handler_ArweaveUpload,
|
|
1577
1809
|
importNpcFromSoulThunk,
|
|
1578
1810
|
importSoulFromArweaveThunk,
|
|
1579
1811
|
initRemoteCortexThunk,
|