strapi-plugin-ai-sdk 0.6.9 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +151 -2
- package/dist/_chunks/{App-C_BH5Ir4.js → App-BGIUzHMh.js} +298 -2
- package/dist/_chunks/{App-DKyCb0BY.mjs → App-v0CobEGM.mjs} +298 -2
- package/dist/_chunks/{index-DCEjJ0as.js → index-BNk29VRc.js} +1 -1
- package/dist/_chunks/{index-BV9DET_M.mjs → index-CFO5UshL.mjs} +1 -1
- package/dist/admin/index.js +1 -1
- package/dist/admin/index.mjs +1 -1
- package/dist/admin/src/components/TaskConfirmCard.d.ts +11 -0
- package/dist/server/index.js +526 -76
- package/dist/server/index.mjs +526 -76
- package/dist/server/src/content-types/index.d.ts +62 -0
- package/dist/server/src/content-types/task/index.d.ts +63 -0
- package/dist/server/src/controllers/index.d.ts +8 -0
- package/dist/server/src/controllers/task.d.ts +11 -0
- package/dist/server/src/index.d.ts +70 -3
- package/dist/server/src/lib/tool-registry.d.ts +2 -0
- package/dist/server/src/tool-logic/index.d.ts +2 -0
- package/dist/server/src/tool-logic/manage-task.d.ts +43 -0
- package/dist/server/src/tools/definitions/manage-task.d.ts +2 -0
- package/package.json +1 -1
|
@@ -4,7 +4,7 @@ import { Link, useNavigate, Routes, Route } from "react-router-dom";
|
|
|
4
4
|
import { Box, Typography, TextInput, Button, Main, SearchForm, Searchbar, Table, Thead, Tr, Th, Tbody, Td, Flex, Pagination, Modal, Field, Textarea, SingleSelect, SingleSelectOption } from "@strapi/design-system";
|
|
5
5
|
import { useState, useEffect, useCallback, forwardRef, useRef, useMemo } from "react";
|
|
6
6
|
import styled from "styled-components";
|
|
7
|
-
import { P as PLUGIN_ID } from "./index-
|
|
7
|
+
import { P as PLUGIN_ID } from "./index-CFO5UshL.mjs";
|
|
8
8
|
import { Plus, Trash, Sparkle, ArrowLeft, Pencil } from "@strapi/icons";
|
|
9
9
|
import Markdown from "react-markdown";
|
|
10
10
|
import remarkGfm from "remark-gfm";
|
|
@@ -612,6 +612,267 @@ function MemoryPanel({ memories, open, onDelete }) {
|
|
|
612
612
|
] })
|
|
613
613
|
] });
|
|
614
614
|
}
|
|
615
|
+
const SCORE_LABELS = {
|
|
616
|
+
1: "Negligible",
|
|
617
|
+
2: "Minor",
|
|
618
|
+
3: "Moderate",
|
|
619
|
+
4: "Significant",
|
|
620
|
+
5: "Critical"
|
|
621
|
+
};
|
|
622
|
+
const Card = styled.div`
|
|
623
|
+
margin-top: 8px;
|
|
624
|
+
border: 1px solid #dcdce4;
|
|
625
|
+
border-radius: 8px;
|
|
626
|
+
padding: 14px 16px;
|
|
627
|
+
background: #fff;
|
|
628
|
+
font-size: 13px;
|
|
629
|
+
`;
|
|
630
|
+
const Title = styled.div`
|
|
631
|
+
font-weight: 700;
|
|
632
|
+
font-size: 14px;
|
|
633
|
+
color: #32324d;
|
|
634
|
+
margin-bottom: 2px;
|
|
635
|
+
`;
|
|
636
|
+
const Description = styled.div`
|
|
637
|
+
color: #8e8ea9;
|
|
638
|
+
font-size: 12px;
|
|
639
|
+
margin-bottom: 10px;
|
|
640
|
+
`;
|
|
641
|
+
const Row = styled.div`
|
|
642
|
+
display: flex;
|
|
643
|
+
align-items: center;
|
|
644
|
+
gap: 10px;
|
|
645
|
+
margin-bottom: 8px;
|
|
646
|
+
flex-wrap: wrap;
|
|
647
|
+
`;
|
|
648
|
+
const Label = styled.label`
|
|
649
|
+
font-size: 12px;
|
|
650
|
+
font-weight: 600;
|
|
651
|
+
color: #666687;
|
|
652
|
+
min-width: 80px;
|
|
653
|
+
`;
|
|
654
|
+
const Select = styled.select`
|
|
655
|
+
padding: 4px 8px;
|
|
656
|
+
border: 1px solid #dcdce4;
|
|
657
|
+
border-radius: 4px;
|
|
658
|
+
font-size: 12px;
|
|
659
|
+
background: #fff;
|
|
660
|
+
color: #32324d;
|
|
661
|
+
`;
|
|
662
|
+
const DateInput = styled.input`
|
|
663
|
+
padding: 4px 8px;
|
|
664
|
+
border: 1px solid #dcdce4;
|
|
665
|
+
border-radius: 4px;
|
|
666
|
+
font-size: 12px;
|
|
667
|
+
color: #32324d;
|
|
668
|
+
`;
|
|
669
|
+
const AsapButton = styled.button`
|
|
670
|
+
padding: 4px 10px;
|
|
671
|
+
border: none;
|
|
672
|
+
border-radius: 4px;
|
|
673
|
+
background: #4945ff;
|
|
674
|
+
color: #fff;
|
|
675
|
+
font-size: 11px;
|
|
676
|
+
font-weight: 600;
|
|
677
|
+
cursor: pointer;
|
|
678
|
+
|
|
679
|
+
&:hover {
|
|
680
|
+
background: #3b38e0;
|
|
681
|
+
}
|
|
682
|
+
`;
|
|
683
|
+
const ScorePreview = styled.div`
|
|
684
|
+
font-size: 12px;
|
|
685
|
+
color: #666687;
|
|
686
|
+
margin-bottom: 10px;
|
|
687
|
+
font-weight: 500;
|
|
688
|
+
`;
|
|
689
|
+
const CreateButton = styled.button`
|
|
690
|
+
padding: 8px 18px;
|
|
691
|
+
border: none;
|
|
692
|
+
border-radius: 4px;
|
|
693
|
+
background: #4945ff;
|
|
694
|
+
color: #fff;
|
|
695
|
+
font-size: 13px;
|
|
696
|
+
font-weight: 600;
|
|
697
|
+
cursor: pointer;
|
|
698
|
+
|
|
699
|
+
&:disabled {
|
|
700
|
+
background: #a5a5ba;
|
|
701
|
+
cursor: not-allowed;
|
|
702
|
+
}
|
|
703
|
+
|
|
704
|
+
&:not(:disabled):hover {
|
|
705
|
+
background: #3b38e0;
|
|
706
|
+
}
|
|
707
|
+
`;
|
|
708
|
+
const SuccessBanner = styled.div`
|
|
709
|
+
margin-top: 8px;
|
|
710
|
+
border: 1px solid #c6f0c2;
|
|
711
|
+
border-radius: 8px;
|
|
712
|
+
padding: 14px 16px;
|
|
713
|
+
background: #eafbe7;
|
|
714
|
+
font-size: 13px;
|
|
715
|
+
color: #2f6846;
|
|
716
|
+
`;
|
|
717
|
+
const SuccessTitle = styled.div`
|
|
718
|
+
font-weight: 700;
|
|
719
|
+
margin-bottom: 4px;
|
|
720
|
+
`;
|
|
721
|
+
const TaskLink = styled(Link)`
|
|
722
|
+
color: #4945ff;
|
|
723
|
+
font-weight: 600;
|
|
724
|
+
text-decoration: none;
|
|
725
|
+
font-size: 12px;
|
|
726
|
+
|
|
727
|
+
&:hover {
|
|
728
|
+
text-decoration: underline;
|
|
729
|
+
}
|
|
730
|
+
`;
|
|
731
|
+
const ErrorText = styled.div`
|
|
732
|
+
color: #d02b20;
|
|
733
|
+
font-size: 12px;
|
|
734
|
+
margin-top: 4px;
|
|
735
|
+
`;
|
|
736
|
+
function TaskConfirmCard({ proposed }) {
|
|
737
|
+
const [consequence, setConsequence] = useState(null);
|
|
738
|
+
const [impact, setImpact] = useState(null);
|
|
739
|
+
const [dueDate, setDueDate] = useState(proposed.dueDate ?? "");
|
|
740
|
+
const [submitting, setSubmitting] = useState(false);
|
|
741
|
+
const [created, setCreated] = useState(null);
|
|
742
|
+
const [error, setError] = useState(null);
|
|
743
|
+
const score = consequence != null && impact != null ? consequence * impact : null;
|
|
744
|
+
async function handleCreate() {
|
|
745
|
+
if (consequence == null || impact == null) return;
|
|
746
|
+
setSubmitting(true);
|
|
747
|
+
setError(null);
|
|
748
|
+
try {
|
|
749
|
+
const token = getToken();
|
|
750
|
+
const backend = getBackendURL();
|
|
751
|
+
const res = await fetch(`${backend}/ai-sdk/tasks`, {
|
|
752
|
+
method: "POST",
|
|
753
|
+
headers: {
|
|
754
|
+
"Content-Type": "application/json",
|
|
755
|
+
...token ? { Authorization: `Bearer ${token}` } : {}
|
|
756
|
+
},
|
|
757
|
+
body: JSON.stringify({
|
|
758
|
+
title: proposed.title,
|
|
759
|
+
description: proposed.description,
|
|
760
|
+
content: proposed.content,
|
|
761
|
+
priority: proposed.priority,
|
|
762
|
+
consequence,
|
|
763
|
+
impact,
|
|
764
|
+
dueDate: dueDate || void 0
|
|
765
|
+
})
|
|
766
|
+
});
|
|
767
|
+
if (!res.ok) {
|
|
768
|
+
const body = await res.json().catch(() => ({}));
|
|
769
|
+
throw new Error(body.error ?? `HTTP ${res.status}`);
|
|
770
|
+
}
|
|
771
|
+
const { data } = await res.json();
|
|
772
|
+
setCreated({
|
|
773
|
+
documentId: data.documentId,
|
|
774
|
+
title: data.title,
|
|
775
|
+
consequence: data.consequence,
|
|
776
|
+
impact: data.impact,
|
|
777
|
+
priority: data.priority
|
|
778
|
+
});
|
|
779
|
+
} catch (err) {
|
|
780
|
+
setError(err instanceof Error ? err.message : String(err));
|
|
781
|
+
} finally {
|
|
782
|
+
setSubmitting(false);
|
|
783
|
+
}
|
|
784
|
+
}
|
|
785
|
+
if (created) {
|
|
786
|
+
const s = created.consequence * created.impact;
|
|
787
|
+
return /* @__PURE__ */ jsxs(SuccessBanner, { children: [
|
|
788
|
+
/* @__PURE__ */ jsxs(SuccessTitle, { children: [
|
|
789
|
+
"Task created: ",
|
|
790
|
+
created.title
|
|
791
|
+
] }),
|
|
792
|
+
/* @__PURE__ */ jsxs("span", { children: [
|
|
793
|
+
"Score: ",
|
|
794
|
+
created.consequence,
|
|
795
|
+
" x ",
|
|
796
|
+
created.impact,
|
|
797
|
+
" = ",
|
|
798
|
+
s,
|
|
799
|
+
" · Priority: ",
|
|
800
|
+
created.priority
|
|
801
|
+
] }),
|
|
802
|
+
/* @__PURE__ */ jsx("div", { style: { marginTop: 6 }, children: /* @__PURE__ */ jsx(TaskLink, { to: `/content-manager/collection-types/plugin::ai-sdk.task/${created.documentId}`, children: "Open in Content Manager" }) })
|
|
803
|
+
] });
|
|
804
|
+
}
|
|
805
|
+
const today = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
|
|
806
|
+
return /* @__PURE__ */ jsxs(Card, { children: [
|
|
807
|
+
/* @__PURE__ */ jsx(Title, { children: proposed.title }),
|
|
808
|
+
proposed.description && /* @__PURE__ */ jsx(Description, { children: proposed.description }),
|
|
809
|
+
/* @__PURE__ */ jsxs(Row, { children: [
|
|
810
|
+
/* @__PURE__ */ jsx(Label, { children: "Consequence" }),
|
|
811
|
+
/* @__PURE__ */ jsxs(
|
|
812
|
+
Select,
|
|
813
|
+
{
|
|
814
|
+
value: consequence ?? "",
|
|
815
|
+
onChange: (e) => setConsequence(e.target.value ? Number(e.target.value) : null),
|
|
816
|
+
children: [
|
|
817
|
+
/* @__PURE__ */ jsx("option", { value: "", children: "Select…" }),
|
|
818
|
+
[1, 2, 3, 4, 5].map((n) => /* @__PURE__ */ jsxs("option", { value: n, children: [
|
|
819
|
+
n,
|
|
820
|
+
" — ",
|
|
821
|
+
SCORE_LABELS[n]
|
|
822
|
+
] }, n))
|
|
823
|
+
]
|
|
824
|
+
}
|
|
825
|
+
)
|
|
826
|
+
] }),
|
|
827
|
+
/* @__PURE__ */ jsxs(Row, { children: [
|
|
828
|
+
/* @__PURE__ */ jsx(Label, { children: "Impact" }),
|
|
829
|
+
/* @__PURE__ */ jsxs(
|
|
830
|
+
Select,
|
|
831
|
+
{
|
|
832
|
+
value: impact ?? "",
|
|
833
|
+
onChange: (e) => setImpact(e.target.value ? Number(e.target.value) : null),
|
|
834
|
+
children: [
|
|
835
|
+
/* @__PURE__ */ jsx("option", { value: "", children: "Select…" }),
|
|
836
|
+
[1, 2, 3, 4, 5].map((n) => /* @__PURE__ */ jsxs("option", { value: n, children: [
|
|
837
|
+
n,
|
|
838
|
+
" — ",
|
|
839
|
+
SCORE_LABELS[n]
|
|
840
|
+
] }, n))
|
|
841
|
+
]
|
|
842
|
+
}
|
|
843
|
+
)
|
|
844
|
+
] }),
|
|
845
|
+
/* @__PURE__ */ jsxs(Row, { children: [
|
|
846
|
+
/* @__PURE__ */ jsx(Label, { children: "Due date" }),
|
|
847
|
+
/* @__PURE__ */ jsx(
|
|
848
|
+
DateInput,
|
|
849
|
+
{
|
|
850
|
+
type: "date",
|
|
851
|
+
value: dueDate,
|
|
852
|
+
onChange: (e) => setDueDate(e.target.value)
|
|
853
|
+
}
|
|
854
|
+
),
|
|
855
|
+
/* @__PURE__ */ jsx(AsapButton, { type: "button", onClick: () => setDueDate(today), children: "ASAP" })
|
|
856
|
+
] }),
|
|
857
|
+
score != null && /* @__PURE__ */ jsxs(ScorePreview, { children: [
|
|
858
|
+
"Score: ",
|
|
859
|
+
consequence,
|
|
860
|
+
" x ",
|
|
861
|
+
impact,
|
|
862
|
+
" = ",
|
|
863
|
+
score
|
|
864
|
+
] }),
|
|
865
|
+
/* @__PURE__ */ jsx(
|
|
866
|
+
CreateButton,
|
|
867
|
+
{
|
|
868
|
+
disabled: consequence == null || impact == null || submitting,
|
|
869
|
+
onClick: handleCreate,
|
|
870
|
+
children: submitting ? "Creating…" : "Create Task"
|
|
871
|
+
}
|
|
872
|
+
),
|
|
873
|
+
error && /* @__PURE__ */ jsx(ErrorText, { children: error })
|
|
874
|
+
] });
|
|
875
|
+
}
|
|
615
876
|
function buildContentManagerUrl(contentType, documentId) {
|
|
616
877
|
const base = `/content-manager/collection-types/${contentType}`;
|
|
617
878
|
return documentId ? `${base}/${documentId}` : base;
|
|
@@ -657,6 +918,31 @@ function extractContentLinks(toolCall) {
|
|
|
657
918
|
}
|
|
658
919
|
return [];
|
|
659
920
|
}
|
|
921
|
+
const TASK_CONTENT_TYPE = "plugin::ai-sdk.task";
|
|
922
|
+
function extractTaskLinks(toolCall) {
|
|
923
|
+
if (toolCall.toolName !== "manageTask" || toolCall.output == null) return [];
|
|
924
|
+
const output = toolCall.output;
|
|
925
|
+
if (!output.success) return [];
|
|
926
|
+
const data = output.data;
|
|
927
|
+
if (!data) return [];
|
|
928
|
+
if (!Array.isArray(data)) {
|
|
929
|
+
const docId = data.documentId;
|
|
930
|
+
const title = data.title || docId;
|
|
931
|
+
if (docId && title) {
|
|
932
|
+
return [{ label: title, to: buildContentManagerUrl(TASK_CONTENT_TYPE, docId) }];
|
|
933
|
+
}
|
|
934
|
+
return [];
|
|
935
|
+
}
|
|
936
|
+
const links = [];
|
|
937
|
+
for (const task of data.slice(0, 5)) {
|
|
938
|
+
const docId = task.documentId;
|
|
939
|
+
const title = task.title || docId;
|
|
940
|
+
if (docId && title) {
|
|
941
|
+
links.push({ label: title, to: buildContentManagerUrl(TASK_CONTENT_TYPE, docId) });
|
|
942
|
+
}
|
|
943
|
+
}
|
|
944
|
+
return links;
|
|
945
|
+
}
|
|
660
946
|
const ToolCallBox = styled.div`
|
|
661
947
|
margin-top: 8px;
|
|
662
948
|
border: 1px solid #dcdce4;
|
|
@@ -741,6 +1027,13 @@ const HIDDEN_TOOLS = /* @__PURE__ */ new Set();
|
|
|
741
1027
|
function ToolCallDisplay({ toolCall }) {
|
|
742
1028
|
const [expanded, setExpanded] = useState(false);
|
|
743
1029
|
const contentLinks = extractContentLinks(toolCall);
|
|
1030
|
+
const taskLinks = extractTaskLinks(toolCall);
|
|
1031
|
+
if (toolCall.toolName === "manageTask" && toolCall.output != null) {
|
|
1032
|
+
const output = toolCall.output;
|
|
1033
|
+
if (output.status === "pending_confirmation" && output.proposed) {
|
|
1034
|
+
return /* @__PURE__ */ jsx(TaskConfirmCard, { proposed: output.proposed });
|
|
1035
|
+
}
|
|
1036
|
+
}
|
|
744
1037
|
return /* @__PURE__ */ jsxs(ToolCallBox, { children: [
|
|
745
1038
|
/* @__PURE__ */ jsxs(ToolCallHeader, { onClick: () => setExpanded(!expanded), children: [
|
|
746
1039
|
/* @__PURE__ */ jsx("span", { children: expanded ? "▼" : "▶" }),
|
|
@@ -750,7 +1043,10 @@ function ToolCallDisplay({ toolCall }) {
|
|
|
750
1043
|
] }),
|
|
751
1044
|
toolCall.output === void 0 ? /* @__PURE__ */ jsx(Spinner, {}) : /* @__PURE__ */ jsx("span", { style: { marginLeft: "auto", fontWeight: 400, opacity: 0.6 }, children: "completed" })
|
|
752
1045
|
] }),
|
|
753
|
-
contentLinks.length > 0
|
|
1046
|
+
(contentLinks.length > 0 || taskLinks.length > 0) && /* @__PURE__ */ jsxs(ContentLinksRow, { children: [
|
|
1047
|
+
contentLinks.map((link) => /* @__PURE__ */ jsx(ContentLinkChip, { to: link.to, children: link.label }, link.to)),
|
|
1048
|
+
taskLinks.map((link) => /* @__PURE__ */ jsx(ContentLinkChip, { to: link.to, children: link.label }, link.to))
|
|
1049
|
+
] }),
|
|
754
1050
|
expanded && /* @__PURE__ */ jsx(ToolCallContent, { children: toolCall.output === void 0 ? "Waiting for result..." : JSON.stringify(toolCall.output, null, 2) })
|
|
755
1051
|
] });
|
|
756
1052
|
}
|
|
@@ -37,7 +37,7 @@ const index = {
|
|
|
37
37
|
defaultMessage: PLUGIN_ID
|
|
38
38
|
},
|
|
39
39
|
Component: async () => {
|
|
40
|
-
const { App } = await Promise.resolve().then(() => require("./App-
|
|
40
|
+
const { App } = await Promise.resolve().then(() => require("./App-BGIUzHMh.js"));
|
|
41
41
|
return App;
|
|
42
42
|
}
|
|
43
43
|
});
|
package/dist/admin/index.js
CHANGED
package/dist/admin/index.mjs
CHANGED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
interface Proposed {
|
|
2
|
+
title: string;
|
|
3
|
+
description?: string;
|
|
4
|
+
content?: string;
|
|
5
|
+
priority: string;
|
|
6
|
+
dueDate: string | null;
|
|
7
|
+
}
|
|
8
|
+
export declare function TaskConfirmCard({ proposed }: Readonly<{
|
|
9
|
+
proposed: Proposed;
|
|
10
|
+
}>): import("react/jsx-runtime").JSX.Element;
|
|
11
|
+
export {};
|