@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.mjs
CHANGED
|
@@ -205,6 +205,16 @@ var sdkApi = createApi({
|
|
|
205
205
|
invalidatesTags: ["Soul"],
|
|
206
206
|
transformResponse: (response) => response
|
|
207
207
|
}),
|
|
208
|
+
postSoulExportConfirm: builder.mutation({
|
|
209
|
+
query: ({ npcId, request, apiUrl, apiKey }) => ({
|
|
210
|
+
url: `${apiUrl}/npcs/${npcId}/soul/confirm`,
|
|
211
|
+
method: "POST",
|
|
212
|
+
headers: apiKey ? { "Authorization": `Bearer ${apiKey}` } : {},
|
|
213
|
+
body: request
|
|
214
|
+
}),
|
|
215
|
+
invalidatesTags: ["Soul"],
|
|
216
|
+
transformResponse: (response) => response
|
|
217
|
+
}),
|
|
208
218
|
getSoulImport: builder.query({
|
|
209
219
|
query: ({ txId, apiUrl, apiKey }) => ({
|
|
210
220
|
url: `${apiUrl}/souls/${txId}`,
|
|
@@ -313,6 +323,16 @@ var sdkApi = createApi({
|
|
|
313
323
|
invalidatesTags: ["NPC"],
|
|
314
324
|
transformResponse: (response) => response
|
|
315
325
|
}),
|
|
326
|
+
postNpcImportConfirm: builder.mutation({
|
|
327
|
+
query: ({ request, apiUrl, apiKey }) => ({
|
|
328
|
+
url: `${apiUrl}/npcs/import/confirm`,
|
|
329
|
+
method: "POST",
|
|
330
|
+
headers: apiKey ? { "Authorization": `Bearer ${apiKey}` } : {},
|
|
331
|
+
body: request
|
|
332
|
+
}),
|
|
333
|
+
invalidatesTags: ["NPC"],
|
|
334
|
+
transformResponse: (response) => response
|
|
335
|
+
}),
|
|
316
336
|
// Cortex Remote Endpoint
|
|
317
337
|
postCortexComplete: builder.mutation({
|
|
318
338
|
query: ({ cortexId, prompt, options, apiUrl, apiKey }) => ({
|
|
@@ -332,6 +352,25 @@ var sdkApi = createApi({
|
|
|
332
352
|
})
|
|
333
353
|
});
|
|
334
354
|
|
|
355
|
+
// src/errors.ts
|
|
356
|
+
var extractThunkErrorMessage = (error, fallback) => {
|
|
357
|
+
if (typeof error === "string") return error;
|
|
358
|
+
if (error && typeof error === "object") {
|
|
359
|
+
const e = error;
|
|
360
|
+
if (typeof e.data === "object" && e.data?.message) return String(e.data.message);
|
|
361
|
+
if (typeof e.data === "string") return e.data;
|
|
362
|
+
if (e.message) return e.message;
|
|
363
|
+
if (e.error) return e.error;
|
|
364
|
+
}
|
|
365
|
+
return fallback;
|
|
366
|
+
};
|
|
367
|
+
var requireApiKeyGuidance = (apiUrl, apiKey) => {
|
|
368
|
+
const normalized = apiUrl.toLowerCase();
|
|
369
|
+
if (normalized.includes("api.forboc.ai") && !apiKey) {
|
|
370
|
+
throw new Error("Missing API key. Set FORBOCAI_API_KEY (or run `forboc config set apiKey <key>`) for production API calls.");
|
|
371
|
+
}
|
|
372
|
+
};
|
|
373
|
+
|
|
335
374
|
// src/bridgeSlice.ts
|
|
336
375
|
var initialState = {
|
|
337
376
|
activePresets: [],
|
|
@@ -346,6 +385,7 @@ var validateBridgeThunk = createAsyncThunk(
|
|
|
346
385
|
async ({ action, context, npcId, apiUrl, apiKey }, { dispatch: dispatch2, rejectWithValue }) => {
|
|
347
386
|
try {
|
|
348
387
|
const url = apiUrl || "https://api.forboc.ai";
|
|
388
|
+
requireApiKeyGuidance(url, apiKey);
|
|
349
389
|
const data = await dispatch2(sdkApi.endpoints.postBridgeValidate.initiate({
|
|
350
390
|
request: { action, context },
|
|
351
391
|
npcId,
|
|
@@ -353,8 +393,8 @@ var validateBridgeThunk = createAsyncThunk(
|
|
|
353
393
|
apiKey
|
|
354
394
|
})).unwrap();
|
|
355
395
|
return data;
|
|
356
|
-
} catch (
|
|
357
|
-
return rejectWithValue(
|
|
396
|
+
} catch (error) {
|
|
397
|
+
return rejectWithValue(extractThunkErrorMessage(error, "Bridge validation failed"));
|
|
358
398
|
}
|
|
359
399
|
}
|
|
360
400
|
);
|
|
@@ -363,9 +403,10 @@ var loadBridgePresetThunk = createAsyncThunk(
|
|
|
363
403
|
async ({ presetName, apiUrl, apiKey }, { dispatch: dispatch2, rejectWithValue }) => {
|
|
364
404
|
try {
|
|
365
405
|
const url = apiUrl || "https://api.forboc.ai";
|
|
406
|
+
requireApiKeyGuidance(url, apiKey);
|
|
366
407
|
return await dispatch2(sdkApi.endpoints.postBridgePreset.initiate({ presetName, apiUrl: url, apiKey })).unwrap();
|
|
367
|
-
} catch (
|
|
368
|
-
return rejectWithValue(
|
|
408
|
+
} catch (error) {
|
|
409
|
+
return rejectWithValue(extractThunkErrorMessage(error, "Failed to load preset"));
|
|
369
410
|
}
|
|
370
411
|
}
|
|
371
412
|
);
|
|
@@ -374,9 +415,10 @@ var getBridgeRulesThunk = createAsyncThunk(
|
|
|
374
415
|
async ({ apiUrl, apiKey }, { dispatch: dispatch2, rejectWithValue }) => {
|
|
375
416
|
try {
|
|
376
417
|
const url = apiUrl || "https://api.forboc.ai";
|
|
418
|
+
requireApiKeyGuidance(url, apiKey);
|
|
377
419
|
return await dispatch2(sdkApi.endpoints.getBridgeRules.initiate({ apiUrl: url, apiKey })).unwrap();
|
|
378
|
-
} catch (
|
|
379
|
-
return rejectWithValue(
|
|
420
|
+
} catch (error) {
|
|
421
|
+
return rejectWithValue(extractThunkErrorMessage(error, "Failed to list bridge rules"));
|
|
380
422
|
}
|
|
381
423
|
}
|
|
382
424
|
);
|
|
@@ -385,9 +427,10 @@ var listRulesetsThunk = createAsyncThunk(
|
|
|
385
427
|
async ({ apiUrl, apiKey }, { dispatch: dispatch2, rejectWithValue }) => {
|
|
386
428
|
try {
|
|
387
429
|
const url = apiUrl || "https://api.forboc.ai";
|
|
430
|
+
requireApiKeyGuidance(url, apiKey);
|
|
388
431
|
return await dispatch2(sdkApi.endpoints.getRulesets.initiate({ apiUrl: url, apiKey })).unwrap();
|
|
389
|
-
} catch (
|
|
390
|
-
return rejectWithValue(
|
|
432
|
+
} catch (error) {
|
|
433
|
+
return rejectWithValue(extractThunkErrorMessage(error, "Failed to list rulesets"));
|
|
391
434
|
}
|
|
392
435
|
}
|
|
393
436
|
);
|
|
@@ -396,9 +439,10 @@ var listRulePresetsThunk = createAsyncThunk(
|
|
|
396
439
|
async ({ apiUrl, apiKey }, { dispatch: dispatch2, rejectWithValue }) => {
|
|
397
440
|
try {
|
|
398
441
|
const url = apiUrl || "https://api.forboc.ai";
|
|
442
|
+
requireApiKeyGuidance(url, apiKey);
|
|
399
443
|
return await dispatch2(sdkApi.endpoints.getRulePresets.initiate({ apiUrl: url, apiKey })).unwrap();
|
|
400
|
-
} catch (
|
|
401
|
-
return rejectWithValue(
|
|
444
|
+
} catch (error) {
|
|
445
|
+
return rejectWithValue(extractThunkErrorMessage(error, "Failed to list rule presets"));
|
|
402
446
|
}
|
|
403
447
|
}
|
|
404
448
|
);
|
|
@@ -407,9 +451,10 @@ var registerRulesetThunk = createAsyncThunk(
|
|
|
407
451
|
async ({ ruleset, apiUrl, apiKey }, { dispatch: dispatch2, rejectWithValue }) => {
|
|
408
452
|
try {
|
|
409
453
|
const url = apiUrl || "https://api.forboc.ai";
|
|
454
|
+
requireApiKeyGuidance(url, apiKey);
|
|
410
455
|
return await dispatch2(sdkApi.endpoints.postRuleRegister.initiate({ request: ruleset, apiUrl: url, apiKey })).unwrap();
|
|
411
|
-
} catch (
|
|
412
|
-
return rejectWithValue(
|
|
456
|
+
} catch (error) {
|
|
457
|
+
return rejectWithValue(extractThunkErrorMessage(error, "Failed to register ruleset"));
|
|
413
458
|
}
|
|
414
459
|
}
|
|
415
460
|
);
|
|
@@ -418,9 +463,10 @@ var deleteRulesetThunk = createAsyncThunk(
|
|
|
418
463
|
async ({ rulesetId, apiUrl, apiKey }, { dispatch: dispatch2, rejectWithValue }) => {
|
|
419
464
|
try {
|
|
420
465
|
const url = apiUrl || "https://api.forboc.ai";
|
|
466
|
+
requireApiKeyGuidance(url, apiKey);
|
|
421
467
|
return await dispatch2(sdkApi.endpoints.deleteRule.initiate({ rulesetId, apiUrl: url, apiKey })).unwrap();
|
|
422
|
-
} catch (
|
|
423
|
-
return rejectWithValue(
|
|
468
|
+
} catch (error) {
|
|
469
|
+
return rejectWithValue(extractThunkErrorMessage(error, "Failed to delete ruleset"));
|
|
424
470
|
}
|
|
425
471
|
}
|
|
426
472
|
);
|
|
@@ -469,6 +515,124 @@ var bridgeSlice_default = bridgeSlice.reducer;
|
|
|
469
515
|
|
|
470
516
|
// src/soulSlice.ts
|
|
471
517
|
import { createSlice as createSlice2, createAsyncThunk as createAsyncThunk2 } from "@reduxjs/toolkit";
|
|
518
|
+
|
|
519
|
+
// src/handlers/arweave.ts
|
|
520
|
+
var sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
521
|
+
var getLocalWalletToken = () => {
|
|
522
|
+
const maybeEnv = globalThis.process?.env;
|
|
523
|
+
return maybeEnv?.ARWEAVE_WALLET_JWK ?? null;
|
|
524
|
+
};
|
|
525
|
+
var withTimeout = async (promiseFactory, timeoutMs = 6e4) => {
|
|
526
|
+
const controller = new AbortController();
|
|
527
|
+
const timeout = setTimeout(() => controller.abort(), timeoutMs);
|
|
528
|
+
try {
|
|
529
|
+
return await promiseFactory(controller.signal);
|
|
530
|
+
} finally {
|
|
531
|
+
clearTimeout(timeout);
|
|
532
|
+
}
|
|
533
|
+
};
|
|
534
|
+
async function handler_ArweaveUpload(instruction, maxRetries = 3) {
|
|
535
|
+
const headers = {
|
|
536
|
+
"Content-Type": instruction.auiContentType || "application/json"
|
|
537
|
+
};
|
|
538
|
+
const authToken = instruction.auiAuthHeader ?? (getLocalWalletToken() ? `Bearer ${getLocalWalletToken()}` : null);
|
|
539
|
+
if (authToken) {
|
|
540
|
+
headers.Authorization = authToken;
|
|
541
|
+
}
|
|
542
|
+
let attempt = 0;
|
|
543
|
+
while (attempt < maxRetries) {
|
|
544
|
+
attempt += 1;
|
|
545
|
+
try {
|
|
546
|
+
const response = await withTimeout(
|
|
547
|
+
(signal) => fetch(instruction.auiEndpoint, {
|
|
548
|
+
method: "POST",
|
|
549
|
+
headers,
|
|
550
|
+
body: JSON.stringify(instruction.auiPayload),
|
|
551
|
+
signal
|
|
552
|
+
})
|
|
553
|
+
);
|
|
554
|
+
let responseBody = null;
|
|
555
|
+
try {
|
|
556
|
+
responseBody = await response.json();
|
|
557
|
+
} catch {
|
|
558
|
+
responseBody = null;
|
|
559
|
+
}
|
|
560
|
+
const txId = responseBody?.id ?? `ar_tx_sdk_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;
|
|
561
|
+
const success = response.status >= 200 && response.status < 300;
|
|
562
|
+
if (!success && attempt < maxRetries) {
|
|
563
|
+
await sleep(250 * 2 ** (attempt - 1));
|
|
564
|
+
continue;
|
|
565
|
+
}
|
|
566
|
+
return {
|
|
567
|
+
aurTxId: txId,
|
|
568
|
+
aurStatus: response.status,
|
|
569
|
+
aurSuccess: success,
|
|
570
|
+
aurError: success ? null : `upload_failed_status_${response.status}`
|
|
571
|
+
};
|
|
572
|
+
} catch (error) {
|
|
573
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
574
|
+
if (attempt < maxRetries) {
|
|
575
|
+
await sleep(250 * 2 ** (attempt - 1));
|
|
576
|
+
continue;
|
|
577
|
+
}
|
|
578
|
+
return {
|
|
579
|
+
aurTxId: `ar_tx_failed_${Date.now()}`,
|
|
580
|
+
aurStatus: 0,
|
|
581
|
+
aurSuccess: false,
|
|
582
|
+
aurError: `upload_request_failed:${message}`
|
|
583
|
+
};
|
|
584
|
+
}
|
|
585
|
+
}
|
|
586
|
+
return {
|
|
587
|
+
aurTxId: `ar_tx_failed_${Date.now()}`,
|
|
588
|
+
aurStatus: 0,
|
|
589
|
+
aurSuccess: false,
|
|
590
|
+
aurError: "upload_retry_exhausted"
|
|
591
|
+
};
|
|
592
|
+
}
|
|
593
|
+
async function handler_ArweaveDownload(instruction) {
|
|
594
|
+
try {
|
|
595
|
+
const response = await withTimeout(
|
|
596
|
+
(signal) => fetch(instruction.adiGatewayUrl, {
|
|
597
|
+
method: "GET",
|
|
598
|
+
signal
|
|
599
|
+
})
|
|
600
|
+
);
|
|
601
|
+
if (response.status < 200 || response.status >= 300) {
|
|
602
|
+
return {
|
|
603
|
+
adrBody: null,
|
|
604
|
+
adrStatus: response.status,
|
|
605
|
+
adrSuccess: false,
|
|
606
|
+
adrError: `download_failed_status_${response.status}`
|
|
607
|
+
};
|
|
608
|
+
}
|
|
609
|
+
try {
|
|
610
|
+
const body = await response.json();
|
|
611
|
+
return {
|
|
612
|
+
adrBody: body,
|
|
613
|
+
adrStatus: response.status,
|
|
614
|
+
adrSuccess: true,
|
|
615
|
+
adrError: null
|
|
616
|
+
};
|
|
617
|
+
} catch {
|
|
618
|
+
return {
|
|
619
|
+
adrBody: null,
|
|
620
|
+
adrStatus: response.status,
|
|
621
|
+
adrSuccess: false,
|
|
622
|
+
adrError: "download_invalid_json"
|
|
623
|
+
};
|
|
624
|
+
}
|
|
625
|
+
} catch (error) {
|
|
626
|
+
return {
|
|
627
|
+
adrBody: null,
|
|
628
|
+
adrStatus: 0,
|
|
629
|
+
adrSuccess: false,
|
|
630
|
+
adrError: error instanceof Error ? error.message : String(error)
|
|
631
|
+
};
|
|
632
|
+
}
|
|
633
|
+
}
|
|
634
|
+
|
|
635
|
+
// src/soulSlice.ts
|
|
472
636
|
var initialState2 = {
|
|
473
637
|
exportStatus: "idle",
|
|
474
638
|
importStatus: "idle",
|
|
@@ -479,26 +643,45 @@ var initialState2 = {
|
|
|
479
643
|
};
|
|
480
644
|
var remoteExportSoulThunk = createAsyncThunk2(
|
|
481
645
|
"soul/export",
|
|
482
|
-
async ({ npcId: argNpcId, apiUrl, apiKey
|
|
646
|
+
async ({ npcId: argNpcId, apiUrl, apiKey }, { getState, dispatch: dispatch2, rejectWithValue }) => {
|
|
483
647
|
try {
|
|
484
648
|
const state = getState().npc;
|
|
485
649
|
const npcId = argNpcId || state.activeNpcId;
|
|
486
650
|
const npc = state.entities[npcId];
|
|
487
651
|
if (!npc) throw new Error(`NPC ${npcId} not found`);
|
|
488
652
|
const url = apiUrl || "https://api.forboc.ai";
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
653
|
+
requireApiKeyGuidance(url, apiKey);
|
|
654
|
+
const phase1 = await dispatch2(
|
|
655
|
+
sdkApi.endpoints.postSoulExport.initiate({
|
|
656
|
+
npcId,
|
|
657
|
+
request: { npcIdRef: npcId, persona: npc.persona || "NPC", npcState: npc.state },
|
|
658
|
+
apiUrl: url,
|
|
659
|
+
apiKey
|
|
660
|
+
})
|
|
661
|
+
).unwrap();
|
|
662
|
+
const uploadResult = await handler_ArweaveUpload({
|
|
663
|
+
...phase1.se1Instruction,
|
|
664
|
+
auiAuthHeader: phase1.se1Instruction.auiAuthHeader ?? null
|
|
665
|
+
});
|
|
666
|
+
const final = await dispatch2(
|
|
667
|
+
sdkApi.endpoints.postSoulExportConfirm.initiate({
|
|
668
|
+
npcId,
|
|
669
|
+
request: {
|
|
670
|
+
secUploadResult: uploadResult,
|
|
671
|
+
secSignedPayload: phase1.se1SignedPayload,
|
|
672
|
+
secSignature: phase1.se1Signature
|
|
673
|
+
},
|
|
674
|
+
apiUrl: url,
|
|
675
|
+
apiKey
|
|
676
|
+
})
|
|
677
|
+
).unwrap();
|
|
495
678
|
return {
|
|
496
|
-
txId:
|
|
497
|
-
url:
|
|
498
|
-
soul:
|
|
679
|
+
txId: final.txId,
|
|
680
|
+
url: final.arweaveUrl,
|
|
681
|
+
soul: final.soul
|
|
499
682
|
};
|
|
500
|
-
} catch (
|
|
501
|
-
return rejectWithValue(
|
|
683
|
+
} catch (error) {
|
|
684
|
+
return rejectWithValue(extractThunkErrorMessage(error, "Soul export failed"));
|
|
502
685
|
}
|
|
503
686
|
}
|
|
504
687
|
);
|
|
@@ -507,10 +690,31 @@ var importSoulFromArweaveThunk = createAsyncThunk2(
|
|
|
507
690
|
async ({ txId, apiUrl, apiKey }, { dispatch: dispatch2, rejectWithValue }) => {
|
|
508
691
|
try {
|
|
509
692
|
const url = apiUrl || "https://api.forboc.ai";
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
693
|
+
requireApiKeyGuidance(url, apiKey);
|
|
694
|
+
const phase1 = await dispatch2(
|
|
695
|
+
sdkApi.endpoints.postNpcImport.initiate({ request: { txIdRef: txId }, apiUrl: url, apiKey })
|
|
696
|
+
).unwrap();
|
|
697
|
+
const downloadResult = await handler_ArweaveDownload(phase1.si1Instruction);
|
|
698
|
+
const npc = await dispatch2(
|
|
699
|
+
sdkApi.endpoints.postNpcImportConfirm.initiate({
|
|
700
|
+
request: {
|
|
701
|
+
sicTxId: txId,
|
|
702
|
+
sicDownloadResult: downloadResult
|
|
703
|
+
},
|
|
704
|
+
apiUrl: url,
|
|
705
|
+
apiKey
|
|
706
|
+
})
|
|
707
|
+
).unwrap();
|
|
708
|
+
return {
|
|
709
|
+
id: txId,
|
|
710
|
+
version: "2.0.0",
|
|
711
|
+
name: npc.npcId,
|
|
712
|
+
persona: npc.persona,
|
|
713
|
+
memories: [],
|
|
714
|
+
state: npc.data || {}
|
|
715
|
+
};
|
|
716
|
+
} catch (error) {
|
|
717
|
+
return rejectWithValue(extractThunkErrorMessage(error, "Soul import failed"));
|
|
514
718
|
}
|
|
515
719
|
}
|
|
516
720
|
);
|
|
@@ -519,10 +723,11 @@ var getSoulListThunk = createAsyncThunk2(
|
|
|
519
723
|
async ({ limit = 50, apiUrl, apiKey }, { dispatch: dispatch2, rejectWithValue }) => {
|
|
520
724
|
try {
|
|
521
725
|
const url = apiUrl || "https://api.forboc.ai";
|
|
726
|
+
requireApiKeyGuidance(url, apiKey);
|
|
522
727
|
const data = await dispatch2(sdkApi.endpoints.getSouls.initiate({ limit, apiUrl: url, apiKey })).unwrap();
|
|
523
728
|
return data.souls || [];
|
|
524
|
-
} catch (
|
|
525
|
-
return rejectWithValue(
|
|
729
|
+
} catch (error) {
|
|
730
|
+
return rejectWithValue(extractThunkErrorMessage(error, "Failed to list souls"));
|
|
526
731
|
}
|
|
527
732
|
}
|
|
528
733
|
);
|
|
@@ -531,9 +736,10 @@ var verifySoulThunk = createAsyncThunk2(
|
|
|
531
736
|
async ({ txId, apiUrl, apiKey }, { dispatch: dispatch2, rejectWithValue }) => {
|
|
532
737
|
try {
|
|
533
738
|
const url = apiUrl || "https://api.forboc.ai";
|
|
739
|
+
requireApiKeyGuidance(url, apiKey);
|
|
534
740
|
return await dispatch2(sdkApi.endpoints.postSoulVerify.initiate({ txId, apiUrl: url, apiKey })).unwrap();
|
|
535
|
-
} catch (
|
|
536
|
-
return rejectWithValue(
|
|
741
|
+
} catch (error) {
|
|
742
|
+
return rejectWithValue(extractThunkErrorMessage(error, "Soul verify failed"));
|
|
537
743
|
}
|
|
538
744
|
}
|
|
539
745
|
);
|
|
@@ -542,13 +748,24 @@ var importNpcFromSoulThunk = createAsyncThunk2(
|
|
|
542
748
|
async ({ txId, apiUrl, apiKey }, { dispatch: dispatch2, rejectWithValue }) => {
|
|
543
749
|
try {
|
|
544
750
|
const url = apiUrl || "https://api.forboc.ai";
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
751
|
+
requireApiKeyGuidance(url, apiKey);
|
|
752
|
+
const phase1 = await dispatch2(
|
|
753
|
+
sdkApi.endpoints.postNpcImport.initiate({
|
|
754
|
+
request: { txIdRef: txId },
|
|
755
|
+
apiUrl: url,
|
|
756
|
+
apiKey
|
|
757
|
+
})
|
|
758
|
+
).unwrap();
|
|
759
|
+
const downloadResult = await handler_ArweaveDownload(phase1.si1Instruction);
|
|
760
|
+
return await dispatch2(
|
|
761
|
+
sdkApi.endpoints.postNpcImportConfirm.initiate({
|
|
762
|
+
request: { sicTxId: txId, sicDownloadResult: downloadResult },
|
|
763
|
+
apiUrl: url,
|
|
764
|
+
apiKey
|
|
765
|
+
})
|
|
766
|
+
).unwrap();
|
|
767
|
+
} catch (error) {
|
|
768
|
+
return rejectWithValue(extractThunkErrorMessage(error, "NPC import from soul failed"));
|
|
552
769
|
}
|
|
553
770
|
}
|
|
554
771
|
);
|
|
@@ -607,6 +824,7 @@ var startGhostThunk = createAsyncThunk3(
|
|
|
607
824
|
async (config, { dispatch: dispatch2, rejectWithValue }) => {
|
|
608
825
|
try {
|
|
609
826
|
const apiUrl = config.apiUrl || "https://api.forboc.ai";
|
|
827
|
+
requireApiKeyGuidance(apiUrl, config.apiKey);
|
|
610
828
|
const data = await dispatch2(sdkApi.endpoints.postGhostRun.initiate({
|
|
611
829
|
request: { testSuite: config.testSuite, duration: config.duration ?? 300 },
|
|
612
830
|
apiUrl,
|
|
@@ -616,8 +834,8 @@ var startGhostThunk = createAsyncThunk3(
|
|
|
616
834
|
sessionId: data.sessionId,
|
|
617
835
|
status: data.runStatus
|
|
618
836
|
};
|
|
619
|
-
} catch (
|
|
620
|
-
return rejectWithValue(
|
|
837
|
+
} catch (error) {
|
|
838
|
+
return rejectWithValue(extractThunkErrorMessage(error, "Failed to start Ghost"));
|
|
621
839
|
}
|
|
622
840
|
}
|
|
623
841
|
);
|
|
@@ -629,6 +847,7 @@ var getGhostStatusThunk = createAsyncThunk3(
|
|
|
629
847
|
const targetSession = sessionId || state.activeSessionId;
|
|
630
848
|
if (!targetSession) throw new Error("No active Ghost session");
|
|
631
849
|
const url = apiUrl || "https://api.forboc.ai";
|
|
850
|
+
requireApiKeyGuidance(url, apiKey);
|
|
632
851
|
const data = await dispatch2(sdkApi.endpoints.getGhostStatus.initiate({ sessionId: targetSession, apiUrl: url, apiKey })).unwrap();
|
|
633
852
|
return {
|
|
634
853
|
sessionId: data.ghostSessionId,
|
|
@@ -638,8 +857,8 @@ var getGhostStatusThunk = createAsyncThunk3(
|
|
|
638
857
|
duration: data.ghostDuration || 0,
|
|
639
858
|
errors: data.ghostErrors
|
|
640
859
|
};
|
|
641
|
-
} catch (
|
|
642
|
-
return rejectWithValue(
|
|
860
|
+
} catch (error) {
|
|
861
|
+
return rejectWithValue(extractThunkErrorMessage(error, "Failed to get ghost status"));
|
|
643
862
|
}
|
|
644
863
|
}
|
|
645
864
|
);
|
|
@@ -651,6 +870,7 @@ var getGhostResultsThunk = createAsyncThunk3(
|
|
|
651
870
|
const targetSession = sessionId || state.activeSessionId;
|
|
652
871
|
if (!targetSession) throw new Error("No active Ghost session");
|
|
653
872
|
const url = apiUrl || "https://api.forboc.ai";
|
|
873
|
+
requireApiKeyGuidance(url, apiKey);
|
|
654
874
|
const data = await dispatch2(sdkApi.endpoints.getGhostResults.initiate({ sessionId: targetSession, apiUrl: url, apiKey })).unwrap();
|
|
655
875
|
return {
|
|
656
876
|
sessionId: data.resultsSessionId,
|
|
@@ -669,8 +889,8 @@ var getGhostResultsThunk = createAsyncThunk3(
|
|
|
669
889
|
coverage: data.resultsCoverage,
|
|
670
890
|
metrics: Object.fromEntries(data.resultsMetrics || [])
|
|
671
891
|
};
|
|
672
|
-
} catch (
|
|
673
|
-
return rejectWithValue(
|
|
892
|
+
} catch (error) {
|
|
893
|
+
return rejectWithValue(extractThunkErrorMessage(error, "Failed to get ghost results"));
|
|
674
894
|
}
|
|
675
895
|
}
|
|
676
896
|
);
|
|
@@ -682,14 +902,15 @@ var stopGhostThunk = createAsyncThunk3(
|
|
|
682
902
|
const targetSession = sessionId || state.activeSessionId;
|
|
683
903
|
if (!targetSession) throw new Error("No active Ghost session");
|
|
684
904
|
const url = apiUrl || "https://api.forboc.ai";
|
|
905
|
+
requireApiKeyGuidance(url, apiKey);
|
|
685
906
|
const data = await dispatch2(sdkApi.endpoints.postGhostStop.initiate({ sessionId: targetSession, apiUrl: url, apiKey })).unwrap();
|
|
686
907
|
return {
|
|
687
908
|
stopped: data.stopped,
|
|
688
909
|
status: data.stopStatus,
|
|
689
910
|
sessionId: data.stopSessionId
|
|
690
911
|
};
|
|
691
|
-
} catch (
|
|
692
|
-
return rejectWithValue(
|
|
912
|
+
} catch (error) {
|
|
913
|
+
return rejectWithValue(extractThunkErrorMessage(error, "Failed to stop ghost session"));
|
|
693
914
|
}
|
|
694
915
|
}
|
|
695
916
|
);
|
|
@@ -698,6 +919,7 @@ var getGhostHistoryThunk = createAsyncThunk3(
|
|
|
698
919
|
async ({ limit = 10, apiUrl, apiKey }, { dispatch: dispatch2, rejectWithValue }) => {
|
|
699
920
|
try {
|
|
700
921
|
const url = apiUrl || "https://api.forboc.ai";
|
|
922
|
+
requireApiKeyGuidance(url, apiKey);
|
|
701
923
|
const data = await dispatch2(sdkApi.endpoints.getGhostHistory.initiate({ limit, apiUrl: url, apiKey })).unwrap();
|
|
702
924
|
return (data.sessions || []).map((s) => ({
|
|
703
925
|
sessionId: s.sessionId,
|
|
@@ -707,8 +929,8 @@ var getGhostHistoryThunk = createAsyncThunk3(
|
|
|
707
929
|
status: s.status,
|
|
708
930
|
passRate: s.passRate
|
|
709
931
|
}));
|
|
710
|
-
} catch (
|
|
711
|
-
return rejectWithValue(
|
|
932
|
+
} catch (error) {
|
|
933
|
+
return rejectWithValue(extractThunkErrorMessage(error, "Failed to get ghost history"));
|
|
712
934
|
}
|
|
713
935
|
}
|
|
714
936
|
);
|
|
@@ -743,7 +965,7 @@ var ghostSlice = createSlice3({
|
|
|
743
965
|
state.status = "completed";
|
|
744
966
|
}).addCase(stopGhostThunk.fulfilled, (state, action) => {
|
|
745
967
|
if (action.payload.stopped) {
|
|
746
|
-
state.status = "
|
|
968
|
+
state.status = "completed";
|
|
747
969
|
} else {
|
|
748
970
|
state.error = action.payload.status || "Ghost stop request did not stop a session";
|
|
749
971
|
}
|
|
@@ -839,7 +1061,8 @@ var npcSlice = createSlice4({
|
|
|
839
1061
|
persona,
|
|
840
1062
|
state: initialState5 || {},
|
|
841
1063
|
history: [],
|
|
842
|
-
isBlocked: false
|
|
1064
|
+
isBlocked: false,
|
|
1065
|
+
stateLog: [{ timestamp: Date.now(), delta: initialState5 || {}, state: initialState5 || {} }]
|
|
843
1066
|
});
|
|
844
1067
|
state.activeNpcId = id;
|
|
845
1068
|
},
|
|
@@ -854,7 +1077,9 @@ var npcSlice = createSlice4({
|
|
|
854
1077
|
const { id, delta } = action.payload;
|
|
855
1078
|
const npc = state.entities[id];
|
|
856
1079
|
if (npc) {
|
|
857
|
-
|
|
1080
|
+
const newState = { ...npc.state, ...delta };
|
|
1081
|
+
npc.state = newState;
|
|
1082
|
+
npc.stateLog.push({ timestamp: Date.now(), delta, state: newState });
|
|
858
1083
|
}
|
|
859
1084
|
},
|
|
860
1085
|
addToHistory: (state, action) => {
|
|
@@ -924,6 +1149,7 @@ var initRemoteCortexThunk = createAsyncThunk4(
|
|
|
924
1149
|
async ({ model = "api-integrated", authKey, apiUrl, apiKey }, { dispatch: dispatch2, rejectWithValue }) => {
|
|
925
1150
|
try {
|
|
926
1151
|
const url = apiUrl || "https://api.forboc.ai";
|
|
1152
|
+
requireApiKeyGuidance(url, apiKey);
|
|
927
1153
|
const data = await dispatch2(sdkApi.endpoints.postCortexInit.initiate({
|
|
928
1154
|
request: { requestedModel: model, authKey },
|
|
929
1155
|
apiUrl: url,
|
|
@@ -935,8 +1161,8 @@ var initRemoteCortexThunk = createAsyncThunk4(
|
|
|
935
1161
|
ready: data.state?.toLowerCase() === "ready",
|
|
936
1162
|
engine: "remote"
|
|
937
1163
|
};
|
|
938
|
-
} catch (
|
|
939
|
-
return rejectWithValue(
|
|
1164
|
+
} catch (error) {
|
|
1165
|
+
return rejectWithValue(extractThunkErrorMessage(error, "Remote cortex init failed"));
|
|
940
1166
|
}
|
|
941
1167
|
}
|
|
942
1168
|
);
|
|
@@ -945,9 +1171,10 @@ var listCortexModelsThunk = createAsyncThunk4(
|
|
|
945
1171
|
async ({ apiUrl, apiKey }, { dispatch: dispatch2, rejectWithValue }) => {
|
|
946
1172
|
try {
|
|
947
1173
|
const url = apiUrl || "https://api.forboc.ai";
|
|
1174
|
+
requireApiKeyGuidance(url, apiKey);
|
|
948
1175
|
return await dispatch2(sdkApi.endpoints.getCortexModels.initiate({ apiUrl: url, apiKey })).unwrap();
|
|
949
|
-
} catch (
|
|
950
|
-
return rejectWithValue(
|
|
1176
|
+
} catch (error) {
|
|
1177
|
+
return rejectWithValue(extractThunkErrorMessage(error, "Failed to list cortex models"));
|
|
951
1178
|
}
|
|
952
1179
|
}
|
|
953
1180
|
);
|
|
@@ -955,6 +1182,7 @@ var completeRemoteThunk = createAsyncThunk4(
|
|
|
955
1182
|
"cortex/completeRemote",
|
|
956
1183
|
async ({ cortexId, prompt, options, apiUrl, apiKey }, { dispatch: dispatch2, rejectWithValue }) => {
|
|
957
1184
|
try {
|
|
1185
|
+
requireApiKeyGuidance(apiUrl, apiKey);
|
|
958
1186
|
const data = await dispatch2(sdkApi.endpoints.postCortexComplete.initiate({
|
|
959
1187
|
cortexId,
|
|
960
1188
|
prompt,
|
|
@@ -963,8 +1191,8 @@ var completeRemoteThunk = createAsyncThunk4(
|
|
|
963
1191
|
apiKey
|
|
964
1192
|
})).unwrap();
|
|
965
1193
|
return data.text;
|
|
966
|
-
} catch (
|
|
967
|
-
return rejectWithValue(
|
|
1194
|
+
} catch (error) {
|
|
1195
|
+
return rejectWithValue(extractThunkErrorMessage(error, "Remote completing failed"));
|
|
968
1196
|
}
|
|
969
1197
|
}
|
|
970
1198
|
);
|
|
@@ -1199,7 +1427,7 @@ var dispatch = store.dispatch;
|
|
|
1199
1427
|
|
|
1200
1428
|
// src/thunks.ts
|
|
1201
1429
|
import { createAsyncThunk as createAsyncThunk5 } from "@reduxjs/toolkit";
|
|
1202
|
-
var
|
|
1430
|
+
var extractThunkErrorMessage2 = (e) => {
|
|
1203
1431
|
if (typeof e === "string") return e;
|
|
1204
1432
|
if (e?.data?.message) return String(e.data.message);
|
|
1205
1433
|
if (e?.error) return String(e.error);
|
|
@@ -1333,7 +1561,7 @@ var processNPC = createAsyncThunk5(
|
|
|
1333
1561
|
};
|
|
1334
1562
|
return runProtocolRecursively(initialTape, void 0, 0);
|
|
1335
1563
|
} catch (e) {
|
|
1336
|
-
const message =
|
|
1564
|
+
const message = extractThunkErrorMessage2(e);
|
|
1337
1565
|
dispatch2(directiveRunFailed({ id: directiveId, error: String(message) }));
|
|
1338
1566
|
return rejectWithValue(String(message));
|
|
1339
1567
|
}
|
|
@@ -1453,6 +1681,8 @@ export {
|
|
|
1453
1681
|
getGhostStatusThunk,
|
|
1454
1682
|
getSoulListThunk,
|
|
1455
1683
|
ghostSlice,
|
|
1684
|
+
handler_ArweaveDownload,
|
|
1685
|
+
handler_ArweaveUpload,
|
|
1456
1686
|
importNpcFromSoulThunk,
|
|
1457
1687
|
importSoulFromArweaveThunk,
|
|
1458
1688
|
initRemoteCortexThunk,
|