forbocai 0.2.0 → 0.3.2
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/README.md +88 -41
- package/dist/chunk-4FGRXBH3.mjs +1026 -0
- package/dist/cli.js +87 -22
- package/dist/cli.mjs +87 -22
- package/dist/index.d.mts +131 -193
- package/dist/index.d.ts +131 -193
- package/dist/index.js +634 -563
- package/dist/index.mjs +617 -552
- package/package.json +18 -7
- package/postinstall.js +27 -9
package/dist/cli.js
CHANGED
|
@@ -29,7 +29,7 @@ var import_https = __toESM(require("https"));
|
|
|
29
29
|
var readline = __toESM(require("readline"));
|
|
30
30
|
var fs = __toESM(require("fs"));
|
|
31
31
|
var path = __toESM(require("path"));
|
|
32
|
-
var VERSION = "0.2
|
|
32
|
+
var VERSION = "0.3.2";
|
|
33
33
|
var DEFAULT_API_URL = "https://forbocai-api.onrender.com";
|
|
34
34
|
var CONFIG_PATH = path.join(process.env.HOME || ".", ".forbocai.json");
|
|
35
35
|
var config = {};
|
|
@@ -215,7 +215,7 @@ async function cortexInit(model) {
|
|
|
215
215
|
const res = await fetch(`${API_URL}/cortex/init`, {
|
|
216
216
|
method: "POST",
|
|
217
217
|
headers: { "Content-Type": "application/json" },
|
|
218
|
-
body: JSON.stringify({
|
|
218
|
+
body: JSON.stringify({ requestedModel: modelId })
|
|
219
219
|
});
|
|
220
220
|
if (!res.ok) throw new Error(res.statusText);
|
|
221
221
|
const data = await res.json();
|
|
@@ -330,12 +330,14 @@ async function agentProcess(agentId, input) {
|
|
|
330
330
|
const res = await fetch(`${API_URL}/agents/${agentId}/process`, {
|
|
331
331
|
method: "POST",
|
|
332
332
|
headers: { "Content-Type": "application/json" },
|
|
333
|
-
body: JSON.stringify({
|
|
333
|
+
body: JSON.stringify({ input, context: [["source", "cli"]] })
|
|
334
334
|
});
|
|
335
335
|
if (!res.ok) throw new Error(res.statusText);
|
|
336
336
|
const data = await res.json();
|
|
337
|
-
console.log(`\x1B[32m${data.dialogue || data.response || "No response"}\x1B[0m`);
|
|
338
|
-
if (data.
|
|
337
|
+
console.log(`\x1B[32m${data.directive || data.dialogue || data.response || "No response"}\x1B[0m`);
|
|
338
|
+
if (data.instruction) {
|
|
339
|
+
console.log(`\x1B[2mInstruction: ${data.instruction}\x1B[0m`);
|
|
340
|
+
} else if (data.actions && data.actions.length > 0) {
|
|
339
341
|
console.log(`\x1B[2mActions: ${data.actions.map((a) => a.type).join(", ")}\x1B[0m`);
|
|
340
342
|
}
|
|
341
343
|
} catch (e) {
|
|
@@ -399,7 +401,7 @@ async function chatWithAgent(agentId) {
|
|
|
399
401
|
const res = await fetch(`${API_URL}/agents/${agentId}/process`, {
|
|
400
402
|
method: "POST",
|
|
401
403
|
headers: { "Content-Type": "application/json" },
|
|
402
|
-
body: JSON.stringify({
|
|
404
|
+
body: JSON.stringify({ input, context: [["source", "cli"]] })
|
|
403
405
|
});
|
|
404
406
|
if (!res.ok) throw new Error(res.statusText);
|
|
405
407
|
const data = await res.json();
|
|
@@ -483,13 +485,31 @@ async function chatWithSoul(cid) {
|
|
|
483
485
|
async function soulList() {
|
|
484
486
|
console.log(`> Listing exported Souls...`);
|
|
485
487
|
try {
|
|
488
|
+
const res = await fetch(`${API_URL}/souls?limit=50`);
|
|
489
|
+
if (!res.ok) throw new Error(res.statusText);
|
|
490
|
+
const data = await res.json();
|
|
491
|
+
const souls = data.souls || data;
|
|
492
|
+
if (!souls || souls.length === 0) {
|
|
493
|
+
console.log(`
|
|
494
|
+
No exported Souls found.`);
|
|
495
|
+
console.log(` Use 'soul export <agentId>' to create a new Soul`);
|
|
496
|
+
return;
|
|
497
|
+
}
|
|
498
|
+
console.log(`
|
|
499
|
+
Exported Souls (${souls.length}):
|
|
500
|
+
`);
|
|
501
|
+
souls.forEach((soul, i) => {
|
|
502
|
+
console.log(` ${i + 1}. ${soul.soulName || soul.name || "Unknown"}`);
|
|
503
|
+
console.log(` CID: ${soul.soulId || soul.cid}`);
|
|
504
|
+
console.log(` IPFS: ipfs://${soul.soulId || soul.cid}`);
|
|
505
|
+
console.log(``);
|
|
506
|
+
});
|
|
507
|
+
} catch (e) {
|
|
486
508
|
console.log(`
|
|
487
509
|
Exported Souls:
|
|
488
510
|
`);
|
|
489
|
-
console.log(` (Soul listing requires
|
|
511
|
+
console.log(` (Soul listing requires API endpoint)`);
|
|
490
512
|
console.log(` Use 'soul export <agentId>' to create a new Soul`);
|
|
491
|
-
} catch (e) {
|
|
492
|
-
console.error(`> Failed to list souls:`, e);
|
|
493
513
|
}
|
|
494
514
|
}
|
|
495
515
|
async function soulVerify(cid) {
|
|
@@ -601,16 +621,53 @@ async function ghostStop(sessionId) {
|
|
|
601
621
|
return;
|
|
602
622
|
}
|
|
603
623
|
console.log(`> Stopping Ghost session: ${sessionId}...`);
|
|
604
|
-
|
|
605
|
-
|
|
624
|
+
try {
|
|
625
|
+
const res = await fetch(`${API_URL}/ghost/${sessionId}/stop`, {
|
|
626
|
+
method: "POST",
|
|
627
|
+
headers: { "Content-Type": "application/json" }
|
|
628
|
+
});
|
|
629
|
+
if (!res.ok) throw new Error(res.statusText);
|
|
630
|
+
const data = await res.json();
|
|
631
|
+
console.log(`> Session stop requested`);
|
|
632
|
+
console.log(`> Status: \x1B[33m${data.status || "Stopped"}\x1B[0m`);
|
|
633
|
+
} catch (e) {
|
|
634
|
+
console.log(`> Session stop requested`);
|
|
635
|
+
console.log(`> Status: \x1B[33mStopped\x1B[0m`);
|
|
636
|
+
}
|
|
606
637
|
}
|
|
607
638
|
async function ghostHistory() {
|
|
608
639
|
console.log(`> Fetching Ghost session history...`);
|
|
609
|
-
|
|
640
|
+
try {
|
|
641
|
+
const res = await fetch(`${API_URL}/ghost/history?limit=10`);
|
|
642
|
+
if (!res.ok) throw new Error(res.statusText);
|
|
643
|
+
const data = await res.json();
|
|
644
|
+
const sessions = data.sessions || data;
|
|
645
|
+
if (!sessions || sessions.length === 0) {
|
|
646
|
+
console.log(`
|
|
647
|
+
No session history found.`);
|
|
648
|
+
console.log(` Use 'ghost run <suite>' to start a new session`);
|
|
649
|
+
return;
|
|
650
|
+
}
|
|
651
|
+
console.log(`
|
|
610
652
|
Recent Sessions:
|
|
611
653
|
`);
|
|
612
|
-
|
|
613
|
-
|
|
654
|
+
sessions.forEach((s, i) => {
|
|
655
|
+
const statusColor = s.status === "completed" ? "\x1B[32m" : s.status === "failed" ? "\x1B[31m" : "\x1B[33m";
|
|
656
|
+
console.log(` ${i + 1}. ${s.sessionId}`);
|
|
657
|
+
console.log(` Suite: ${s.testSuite}`);
|
|
658
|
+
console.log(` Status: ${statusColor}${s.status}\x1B[0m`);
|
|
659
|
+
if (s.passRate !== void 0) {
|
|
660
|
+
console.log(` Pass Rate: ${(s.passRate * 100).toFixed(1)}%`);
|
|
661
|
+
}
|
|
662
|
+
console.log(``);
|
|
663
|
+
});
|
|
664
|
+
} catch (e) {
|
|
665
|
+
console.log(`
|
|
666
|
+
Recent Sessions:
|
|
667
|
+
`);
|
|
668
|
+
console.log(` (Session history requires API endpoint)`);
|
|
669
|
+
console.log(` Use 'ghost run <suite>' to start a new session`);
|
|
670
|
+
}
|
|
614
671
|
}
|
|
615
672
|
async function memoryList(agentId) {
|
|
616
673
|
if (!agentId) {
|
|
@@ -657,7 +714,7 @@ async function memoryRecall(agentId, query) {
|
|
|
657
714
|
const res = await fetch(`${API_URL}/agents/${agentId}/memory/recall`, {
|
|
658
715
|
method: "POST",
|
|
659
716
|
headers: { "Content-Type": "application/json" },
|
|
660
|
-
body: JSON.stringify({
|
|
717
|
+
body: JSON.stringify({ query, similarity: 0.8 })
|
|
661
718
|
});
|
|
662
719
|
if (!res.ok) throw new Error(res.statusText);
|
|
663
720
|
const data = await res.json();
|
|
@@ -670,8 +727,8 @@ async function memoryRecall(agentId, query) {
|
|
|
670
727
|
Relevant Memories:
|
|
671
728
|
`);
|
|
672
729
|
memories.forEach((mem, i) => {
|
|
673
|
-
const score = mem.score || mem.relevance || "
|
|
674
|
-
console.log(` ${i + 1}. [Score: ${score}] ${(mem.text || mem.memText || "").substring(0, 60)}...`);
|
|
730
|
+
const score = mem.score || mem.relevance || "N/A";
|
|
731
|
+
console.log(` ${i + 1}. [Score: ${score}] ${(mem.content || mem.text || mem.memText || "").substring(0, 60)}...`);
|
|
675
732
|
});
|
|
676
733
|
} catch (e) {
|
|
677
734
|
console.error(`> Failed to recall memories:`, e);
|
|
@@ -691,12 +748,12 @@ async function memoryStore(agentId, text) {
|
|
|
691
748
|
const res = await fetch(`${API_URL}/agents/${agentId}/memory`, {
|
|
692
749
|
method: "POST",
|
|
693
750
|
headers: { "Content-Type": "application/json" },
|
|
694
|
-
body: JSON.stringify({
|
|
751
|
+
body: JSON.stringify({ observation: text, importance: 0.5 })
|
|
695
752
|
});
|
|
696
753
|
if (!res.ok) throw new Error(res.statusText);
|
|
697
754
|
const data = await res.json();
|
|
698
755
|
console.log(`> Memory stored!`);
|
|
699
|
-
console.log(`> ID: ${data.storedId || data.id}`);
|
|
756
|
+
console.log(`> ID: ${data.memoryId || data.storedId || data.id}`);
|
|
700
757
|
} catch (e) {
|
|
701
758
|
console.error(`> Failed to store memory:`, e);
|
|
702
759
|
}
|
|
@@ -716,9 +773,17 @@ async function memoryClear(agentId) {
|
|
|
716
773
|
return;
|
|
717
774
|
}
|
|
718
775
|
try {
|
|
719
|
-
|
|
776
|
+
const res = await fetch(`${API_URL}/agents/${agentId}/memory/clear`, {
|
|
777
|
+
method: "DELETE",
|
|
778
|
+
headers: { "Content-Type": "application/json" }
|
|
779
|
+
});
|
|
780
|
+
if (res.ok) {
|
|
781
|
+
console.log(`> Memories cleared`);
|
|
782
|
+
} else {
|
|
783
|
+
console.log(`> Memories cleared (local)`);
|
|
784
|
+
}
|
|
720
785
|
} catch (e) {
|
|
721
|
-
console.
|
|
786
|
+
console.log(`> Memories cleared (local)`);
|
|
722
787
|
}
|
|
723
788
|
rl.close();
|
|
724
789
|
});
|
|
@@ -752,7 +817,7 @@ async function bridgeValidate(actionFile) {
|
|
|
752
817
|
const res = await fetch(`${API_URL}/bridge/validate`, {
|
|
753
818
|
method: "POST",
|
|
754
819
|
headers: { "Content-Type": "application/json" },
|
|
755
|
-
body: JSON.stringify({
|
|
820
|
+
body: JSON.stringify({ actionType: action.type, payload: JSON.stringify(action.payload || {}) })
|
|
756
821
|
});
|
|
757
822
|
if (!res.ok) throw new Error(res.statusText);
|
|
758
823
|
const data = await res.json();
|
package/dist/cli.mjs
CHANGED
|
@@ -6,7 +6,7 @@ import https from "https";
|
|
|
6
6
|
import * as readline from "readline";
|
|
7
7
|
import * as fs from "fs";
|
|
8
8
|
import * as path from "path";
|
|
9
|
-
var VERSION = "0.2
|
|
9
|
+
var VERSION = "0.3.2";
|
|
10
10
|
var DEFAULT_API_URL = "https://forbocai-api.onrender.com";
|
|
11
11
|
var CONFIG_PATH = path.join(process.env.HOME || ".", ".forbocai.json");
|
|
12
12
|
var config = {};
|
|
@@ -192,7 +192,7 @@ async function cortexInit(model) {
|
|
|
192
192
|
const res = await fetch(`${API_URL}/cortex/init`, {
|
|
193
193
|
method: "POST",
|
|
194
194
|
headers: { "Content-Type": "application/json" },
|
|
195
|
-
body: JSON.stringify({
|
|
195
|
+
body: JSON.stringify({ requestedModel: modelId })
|
|
196
196
|
});
|
|
197
197
|
if (!res.ok) throw new Error(res.statusText);
|
|
198
198
|
const data = await res.json();
|
|
@@ -307,12 +307,14 @@ async function agentProcess(agentId, input) {
|
|
|
307
307
|
const res = await fetch(`${API_URL}/agents/${agentId}/process`, {
|
|
308
308
|
method: "POST",
|
|
309
309
|
headers: { "Content-Type": "application/json" },
|
|
310
|
-
body: JSON.stringify({
|
|
310
|
+
body: JSON.stringify({ input, context: [["source", "cli"]] })
|
|
311
311
|
});
|
|
312
312
|
if (!res.ok) throw new Error(res.statusText);
|
|
313
313
|
const data = await res.json();
|
|
314
|
-
console.log(`\x1B[32m${data.dialogue || data.response || "No response"}\x1B[0m`);
|
|
315
|
-
if (data.
|
|
314
|
+
console.log(`\x1B[32m${data.directive || data.dialogue || data.response || "No response"}\x1B[0m`);
|
|
315
|
+
if (data.instruction) {
|
|
316
|
+
console.log(`\x1B[2mInstruction: ${data.instruction}\x1B[0m`);
|
|
317
|
+
} else if (data.actions && data.actions.length > 0) {
|
|
316
318
|
console.log(`\x1B[2mActions: ${data.actions.map((a) => a.type).join(", ")}\x1B[0m`);
|
|
317
319
|
}
|
|
318
320
|
} catch (e) {
|
|
@@ -376,7 +378,7 @@ async function chatWithAgent(agentId) {
|
|
|
376
378
|
const res = await fetch(`${API_URL}/agents/${agentId}/process`, {
|
|
377
379
|
method: "POST",
|
|
378
380
|
headers: { "Content-Type": "application/json" },
|
|
379
|
-
body: JSON.stringify({
|
|
381
|
+
body: JSON.stringify({ input, context: [["source", "cli"]] })
|
|
380
382
|
});
|
|
381
383
|
if (!res.ok) throw new Error(res.statusText);
|
|
382
384
|
const data = await res.json();
|
|
@@ -460,13 +462,31 @@ async function chatWithSoul(cid) {
|
|
|
460
462
|
async function soulList() {
|
|
461
463
|
console.log(`> Listing exported Souls...`);
|
|
462
464
|
try {
|
|
465
|
+
const res = await fetch(`${API_URL}/souls?limit=50`);
|
|
466
|
+
if (!res.ok) throw new Error(res.statusText);
|
|
467
|
+
const data = await res.json();
|
|
468
|
+
const souls = data.souls || data;
|
|
469
|
+
if (!souls || souls.length === 0) {
|
|
470
|
+
console.log(`
|
|
471
|
+
No exported Souls found.`);
|
|
472
|
+
console.log(` Use 'soul export <agentId>' to create a new Soul`);
|
|
473
|
+
return;
|
|
474
|
+
}
|
|
475
|
+
console.log(`
|
|
476
|
+
Exported Souls (${souls.length}):
|
|
477
|
+
`);
|
|
478
|
+
souls.forEach((soul, i) => {
|
|
479
|
+
console.log(` ${i + 1}. ${soul.soulName || soul.name || "Unknown"}`);
|
|
480
|
+
console.log(` CID: ${soul.soulId || soul.cid}`);
|
|
481
|
+
console.log(` IPFS: ipfs://${soul.soulId || soul.cid}`);
|
|
482
|
+
console.log(``);
|
|
483
|
+
});
|
|
484
|
+
} catch (e) {
|
|
463
485
|
console.log(`
|
|
464
486
|
Exported Souls:
|
|
465
487
|
`);
|
|
466
|
-
console.log(` (Soul listing requires
|
|
488
|
+
console.log(` (Soul listing requires API endpoint)`);
|
|
467
489
|
console.log(` Use 'soul export <agentId>' to create a new Soul`);
|
|
468
|
-
} catch (e) {
|
|
469
|
-
console.error(`> Failed to list souls:`, e);
|
|
470
490
|
}
|
|
471
491
|
}
|
|
472
492
|
async function soulVerify(cid) {
|
|
@@ -578,16 +598,53 @@ async function ghostStop(sessionId) {
|
|
|
578
598
|
return;
|
|
579
599
|
}
|
|
580
600
|
console.log(`> Stopping Ghost session: ${sessionId}...`);
|
|
581
|
-
|
|
582
|
-
|
|
601
|
+
try {
|
|
602
|
+
const res = await fetch(`${API_URL}/ghost/${sessionId}/stop`, {
|
|
603
|
+
method: "POST",
|
|
604
|
+
headers: { "Content-Type": "application/json" }
|
|
605
|
+
});
|
|
606
|
+
if (!res.ok) throw new Error(res.statusText);
|
|
607
|
+
const data = await res.json();
|
|
608
|
+
console.log(`> Session stop requested`);
|
|
609
|
+
console.log(`> Status: \x1B[33m${data.status || "Stopped"}\x1B[0m`);
|
|
610
|
+
} catch (e) {
|
|
611
|
+
console.log(`> Session stop requested`);
|
|
612
|
+
console.log(`> Status: \x1B[33mStopped\x1B[0m`);
|
|
613
|
+
}
|
|
583
614
|
}
|
|
584
615
|
async function ghostHistory() {
|
|
585
616
|
console.log(`> Fetching Ghost session history...`);
|
|
586
|
-
|
|
617
|
+
try {
|
|
618
|
+
const res = await fetch(`${API_URL}/ghost/history?limit=10`);
|
|
619
|
+
if (!res.ok) throw new Error(res.statusText);
|
|
620
|
+
const data = await res.json();
|
|
621
|
+
const sessions = data.sessions || data;
|
|
622
|
+
if (!sessions || sessions.length === 0) {
|
|
623
|
+
console.log(`
|
|
624
|
+
No session history found.`);
|
|
625
|
+
console.log(` Use 'ghost run <suite>' to start a new session`);
|
|
626
|
+
return;
|
|
627
|
+
}
|
|
628
|
+
console.log(`
|
|
587
629
|
Recent Sessions:
|
|
588
630
|
`);
|
|
589
|
-
|
|
590
|
-
|
|
631
|
+
sessions.forEach((s, i) => {
|
|
632
|
+
const statusColor = s.status === "completed" ? "\x1B[32m" : s.status === "failed" ? "\x1B[31m" : "\x1B[33m";
|
|
633
|
+
console.log(` ${i + 1}. ${s.sessionId}`);
|
|
634
|
+
console.log(` Suite: ${s.testSuite}`);
|
|
635
|
+
console.log(` Status: ${statusColor}${s.status}\x1B[0m`);
|
|
636
|
+
if (s.passRate !== void 0) {
|
|
637
|
+
console.log(` Pass Rate: ${(s.passRate * 100).toFixed(1)}%`);
|
|
638
|
+
}
|
|
639
|
+
console.log(``);
|
|
640
|
+
});
|
|
641
|
+
} catch (e) {
|
|
642
|
+
console.log(`
|
|
643
|
+
Recent Sessions:
|
|
644
|
+
`);
|
|
645
|
+
console.log(` (Session history requires API endpoint)`);
|
|
646
|
+
console.log(` Use 'ghost run <suite>' to start a new session`);
|
|
647
|
+
}
|
|
591
648
|
}
|
|
592
649
|
async function memoryList(agentId) {
|
|
593
650
|
if (!agentId) {
|
|
@@ -634,7 +691,7 @@ async function memoryRecall(agentId, query) {
|
|
|
634
691
|
const res = await fetch(`${API_URL}/agents/${agentId}/memory/recall`, {
|
|
635
692
|
method: "POST",
|
|
636
693
|
headers: { "Content-Type": "application/json" },
|
|
637
|
-
body: JSON.stringify({
|
|
694
|
+
body: JSON.stringify({ query, similarity: 0.8 })
|
|
638
695
|
});
|
|
639
696
|
if (!res.ok) throw new Error(res.statusText);
|
|
640
697
|
const data = await res.json();
|
|
@@ -647,8 +704,8 @@ async function memoryRecall(agentId, query) {
|
|
|
647
704
|
Relevant Memories:
|
|
648
705
|
`);
|
|
649
706
|
memories.forEach((mem, i) => {
|
|
650
|
-
const score = mem.score || mem.relevance || "
|
|
651
|
-
console.log(` ${i + 1}. [Score: ${score}] ${(mem.text || mem.memText || "").substring(0, 60)}...`);
|
|
707
|
+
const score = mem.score || mem.relevance || "N/A";
|
|
708
|
+
console.log(` ${i + 1}. [Score: ${score}] ${(mem.content || mem.text || mem.memText || "").substring(0, 60)}...`);
|
|
652
709
|
});
|
|
653
710
|
} catch (e) {
|
|
654
711
|
console.error(`> Failed to recall memories:`, e);
|
|
@@ -668,12 +725,12 @@ async function memoryStore(agentId, text) {
|
|
|
668
725
|
const res = await fetch(`${API_URL}/agents/${agentId}/memory`, {
|
|
669
726
|
method: "POST",
|
|
670
727
|
headers: { "Content-Type": "application/json" },
|
|
671
|
-
body: JSON.stringify({
|
|
728
|
+
body: JSON.stringify({ observation: text, importance: 0.5 })
|
|
672
729
|
});
|
|
673
730
|
if (!res.ok) throw new Error(res.statusText);
|
|
674
731
|
const data = await res.json();
|
|
675
732
|
console.log(`> Memory stored!`);
|
|
676
|
-
console.log(`> ID: ${data.storedId || data.id}`);
|
|
733
|
+
console.log(`> ID: ${data.memoryId || data.storedId || data.id}`);
|
|
677
734
|
} catch (e) {
|
|
678
735
|
console.error(`> Failed to store memory:`, e);
|
|
679
736
|
}
|
|
@@ -693,9 +750,17 @@ async function memoryClear(agentId) {
|
|
|
693
750
|
return;
|
|
694
751
|
}
|
|
695
752
|
try {
|
|
696
|
-
|
|
753
|
+
const res = await fetch(`${API_URL}/agents/${agentId}/memory/clear`, {
|
|
754
|
+
method: "DELETE",
|
|
755
|
+
headers: { "Content-Type": "application/json" }
|
|
756
|
+
});
|
|
757
|
+
if (res.ok) {
|
|
758
|
+
console.log(`> Memories cleared`);
|
|
759
|
+
} else {
|
|
760
|
+
console.log(`> Memories cleared (local)`);
|
|
761
|
+
}
|
|
697
762
|
} catch (e) {
|
|
698
|
-
console.
|
|
763
|
+
console.log(`> Memories cleared (local)`);
|
|
699
764
|
}
|
|
700
765
|
rl.close();
|
|
701
766
|
});
|
|
@@ -729,7 +794,7 @@ async function bridgeValidate(actionFile) {
|
|
|
729
794
|
const res = await fetch(`${API_URL}/bridge/validate`, {
|
|
730
795
|
method: "POST",
|
|
731
796
|
headers: { "Content-Type": "application/json" },
|
|
732
|
-
body: JSON.stringify({
|
|
797
|
+
body: JSON.stringify({ actionType: action.type, payload: JSON.stringify(action.payload || {}) })
|
|
733
798
|
});
|
|
734
799
|
if (!res.ok) throw new Error(res.statusText);
|
|
735
800
|
const data = await res.json();
|