strapi-content-embeddings 0.1.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 +276 -0
- package/dist/_chunks/App-7LMg3lrX.mjs +1004 -0
- package/dist/_chunks/App-wC2qv6kC.js +1008 -0
- package/dist/_chunks/en-B4KWt_jN.js +4 -0
- package/dist/_chunks/en-Byx4XI2L.mjs +4 -0
- package/dist/_chunks/index-Cz9cEuvw.mjs +411 -0
- package/dist/_chunks/index-o-tbBpJG.js +413 -0
- package/dist/admin/index.js +4 -0
- package/dist/admin/index.mjs +5 -0
- package/dist/admin/src/components/Initializer.d.ts +5 -0
- package/dist/admin/src/components/PluginIcon.d.ts +2 -0
- package/dist/admin/src/components/custom/BackLink.d.ts +5 -0
- package/dist/admin/src/components/custom/ChatModal.d.ts +1 -0
- package/dist/admin/src/components/custom/EmbeddingsModal.d.ts +1 -0
- package/dist/admin/src/components/custom/EmbeddingsTable.d.ts +12 -0
- package/dist/admin/src/components/custom/EmbeddingsWidget.d.ts +1 -0
- package/dist/admin/src/components/custom/EmptyState.d.ts +1 -0
- package/dist/admin/src/components/custom/Illo.d.ts +1 -0
- package/dist/admin/src/components/custom/Markdown.d.ts +5 -0
- package/dist/admin/src/components/custom/MarkdownEditor.d.ts +9 -0
- package/dist/admin/src/components/custom/RobotIcon.d.ts +6 -0
- package/dist/admin/src/components/forms/CreateEmbeddingForm.d.ts +15 -0
- package/dist/admin/src/index.d.ts +12 -0
- package/dist/admin/src/pages/App.d.ts +2 -0
- package/dist/admin/src/pages/CreateEmbeddings.d.ts +1 -0
- package/dist/admin/src/pages/EmbeddingDetails.d.ts +1 -0
- package/dist/admin/src/pages/HomePage.d.ts +1 -0
- package/dist/admin/src/pluginId.d.ts +1 -0
- package/dist/admin/src/utils/api.d.ts +33 -0
- package/dist/admin/src/utils/getTranslation.d.ts +2 -0
- package/dist/server/index.js +1359 -0
- package/dist/server/index.mjs +1360 -0
- package/dist/server/src/bootstrap.d.ts +5 -0
- package/dist/server/src/config/index.d.ts +26 -0
- package/dist/server/src/content-types/embedding/index.d.ts +54 -0
- package/dist/server/src/content-types/index.d.ts +56 -0
- package/dist/server/src/controllers/controller.d.ts +12 -0
- package/dist/server/src/controllers/index.d.ts +18 -0
- package/dist/server/src/controllers/mcp.d.ts +18 -0
- package/dist/server/src/destroy.d.ts +5 -0
- package/dist/server/src/index.d.ts +154 -0
- package/dist/server/src/mcp/index.d.ts +6 -0
- package/dist/server/src/mcp/schemas/index.d.ts +65 -0
- package/dist/server/src/mcp/server.d.ts +8 -0
- package/dist/server/src/mcp/tools/create-embedding.d.ts +38 -0
- package/dist/server/src/mcp/tools/get-embedding.d.ts +34 -0
- package/dist/server/src/mcp/tools/index.d.ts +114 -0
- package/dist/server/src/mcp/tools/list-embeddings.d.ts +40 -0
- package/dist/server/src/mcp/tools/rag-query.d.ts +34 -0
- package/dist/server/src/mcp/tools/semantic-search.d.ts +34 -0
- package/dist/server/src/middlewares/index.d.ts +2 -0
- package/dist/server/src/plugin-manager.d.ts +45 -0
- package/dist/server/src/policies/index.d.ts +2 -0
- package/dist/server/src/register.d.ts +5 -0
- package/dist/server/src/routes/admin.d.ts +14 -0
- package/dist/server/src/routes/content-api.d.ts +15 -0
- package/dist/server/src/routes/index.d.ts +36 -0
- package/dist/server/src/services/embeddings.d.ts +45 -0
- package/dist/server/src/services/index.d.ts +26 -0
- package/dist/style.css +95 -0
- package/package.json +104 -0
|
@@ -0,0 +1,413 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
const jsxRuntime = require("react/jsx-runtime");
|
|
3
|
+
const react = require("react");
|
|
4
|
+
const designSystem = require("@strapi/design-system");
|
|
5
|
+
const reactRouterDom = require("react-router-dom");
|
|
6
|
+
const styled = require("styled-components");
|
|
7
|
+
const qs = require("qs");
|
|
8
|
+
const admin = require("@strapi/strapi/admin");
|
|
9
|
+
const icons = require("@strapi/icons");
|
|
10
|
+
require("@mdxeditor/editor/style.css");
|
|
11
|
+
const editor = require("@mdxeditor/editor");
|
|
12
|
+
const _interopDefault = (e) => e && e.__esModule ? e : { default: e };
|
|
13
|
+
const styled__default = /* @__PURE__ */ _interopDefault(styled);
|
|
14
|
+
const qs__default = /* @__PURE__ */ _interopDefault(qs);
|
|
15
|
+
const __variableDynamicImportRuntimeHelper = (glob, path, segs) => {
|
|
16
|
+
const v = glob[path];
|
|
17
|
+
if (v) {
|
|
18
|
+
return typeof v === "function" ? v() : Promise.resolve(v);
|
|
19
|
+
}
|
|
20
|
+
return new Promise((_, reject) => {
|
|
21
|
+
(typeof queueMicrotask === "function" ? queueMicrotask : setTimeout)(
|
|
22
|
+
reject.bind(
|
|
23
|
+
null,
|
|
24
|
+
new Error(
|
|
25
|
+
"Unknown variable dynamic import: " + path + (path.split("/").length !== segs ? ". Note that variables only represent file names one level deep." : "")
|
|
26
|
+
)
|
|
27
|
+
)
|
|
28
|
+
);
|
|
29
|
+
});
|
|
30
|
+
};
|
|
31
|
+
const PLUGIN_ID = "strapi-content-embeddings";
|
|
32
|
+
const getTranslation = (id) => `${PLUGIN_ID}.${id}`;
|
|
33
|
+
const Initializer = ({ setPlugin }) => {
|
|
34
|
+
const ref = react.useRef(setPlugin);
|
|
35
|
+
react.useEffect(() => {
|
|
36
|
+
ref.current(PLUGIN_ID);
|
|
37
|
+
}, []);
|
|
38
|
+
return null;
|
|
39
|
+
};
|
|
40
|
+
function RobotIcon({ height = 48, width = 48 }) {
|
|
41
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
42
|
+
"svg",
|
|
43
|
+
{
|
|
44
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
45
|
+
height,
|
|
46
|
+
viewBox: "0 -960 960 960",
|
|
47
|
+
width,
|
|
48
|
+
fill: "currentColor",
|
|
49
|
+
children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M160-120v-220q0-24.75 17.625-42.375T220-400h520q24.75 0 42.375 17.625T800-340v220H160Zm200-320q-83 0-141.5-58.5T160-640q0-83 58.5-141.5T360-840h240q83 0 141.5 58.5T800-640q0 83-58.5 141.5T600-440H360ZM220-180h520v-160H220v160Zm140-320h240q58.333 0 99.167-40.765 40.833-40.764 40.833-99Q740-698 699.167-739 658.333-780 600-780H360q-58.333 0-99.167 40.765-40.833 40.764-40.833 99Q220-582 260.833-541q40.834 41 99.167 41Zm.175-110q12.825 0 21.325-8.675 8.5-8.676 8.5-21.5 0-12.825-8.675-21.325-8.676-8.5-21.5-8.5-12.825 0-21.325 8.675-8.5 8.676-8.5 21.5 0 12.825 8.675 21.325 8.676 8.5 21.5 8.5Zm240 0q12.825 0 21.325-8.675 8.5-8.676 8.5-21.5 0-12.825-8.675-21.325-8.676-8.5-21.5-8.5-12.825 0-21.325 8.675-8.5 8.676-8.5 21.5 0 12.825 8.675 21.325 8.676 8.5 21.5 8.5ZM480-180Zm0-460Z" })
|
|
50
|
+
}
|
|
51
|
+
);
|
|
52
|
+
}
|
|
53
|
+
const PluginIcon = () => /* @__PURE__ */ jsxRuntime.jsx(RobotIcon, { height: 24, width: 24 });
|
|
54
|
+
const EditorWrapper = styled__default.default(designSystem.Box)`
|
|
55
|
+
border: 1px solid ${({ $isFocused }) => $isFocused ? "#4945ff" : "#dcdce4"};
|
|
56
|
+
border-radius: 4px;
|
|
57
|
+
overflow: hidden;
|
|
58
|
+
background: #fff;
|
|
59
|
+
transition: border-color 0.2s, box-shadow 0.2s;
|
|
60
|
+
box-shadow: ${({ $isFocused }) => $isFocused ? "0 0 0 2px rgba(73, 69, 255, 0.2)" : "none"};
|
|
61
|
+
`;
|
|
62
|
+
function MarkdownEditor({ content, onChange, height = 300 }) {
|
|
63
|
+
const [isFocused, setIsFocused] = react.useState(false);
|
|
64
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
65
|
+
EditorWrapper,
|
|
66
|
+
{
|
|
67
|
+
$isFocused: isFocused,
|
|
68
|
+
onFocus: () => setIsFocused(true),
|
|
69
|
+
onBlur: () => setIsFocused(false),
|
|
70
|
+
children: /* @__PURE__ */ jsxRuntime.jsx("div", { style: { minHeight: `${height}px` }, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
71
|
+
editor.MDXEditor,
|
|
72
|
+
{
|
|
73
|
+
markdown: content,
|
|
74
|
+
onChange,
|
|
75
|
+
placeholder: "Write your content here...",
|
|
76
|
+
contentEditableClassName: "mdx-editor-content",
|
|
77
|
+
plugins: [
|
|
78
|
+
editor.headingsPlugin(),
|
|
79
|
+
editor.listsPlugin(),
|
|
80
|
+
editor.quotePlugin(),
|
|
81
|
+
editor.thematicBreakPlugin(),
|
|
82
|
+
editor.linkPlugin(),
|
|
83
|
+
editor.linkDialogPlugin(),
|
|
84
|
+
editor.markdownShortcutPlugin(),
|
|
85
|
+
editor.toolbarPlugin({
|
|
86
|
+
toolbarContents: () => /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
87
|
+
/* @__PURE__ */ jsxRuntime.jsx(editor.UndoRedo, {}),
|
|
88
|
+
/* @__PURE__ */ jsxRuntime.jsx(editor.Separator, {}),
|
|
89
|
+
/* @__PURE__ */ jsxRuntime.jsx(editor.BlockTypeSelect, {}),
|
|
90
|
+
/* @__PURE__ */ jsxRuntime.jsx(editor.Separator, {}),
|
|
91
|
+
/* @__PURE__ */ jsxRuntime.jsx(editor.BoldItalicUnderlineToggles, {}),
|
|
92
|
+
/* @__PURE__ */ jsxRuntime.jsx(editor.Separator, {}),
|
|
93
|
+
/* @__PURE__ */ jsxRuntime.jsx(editor.CreateLink, {}),
|
|
94
|
+
/* @__PURE__ */ jsxRuntime.jsx(editor.Separator, {}),
|
|
95
|
+
/* @__PURE__ */ jsxRuntime.jsx(editor.ListsToggle, {})
|
|
96
|
+
] })
|
|
97
|
+
})
|
|
98
|
+
]
|
|
99
|
+
}
|
|
100
|
+
) })
|
|
101
|
+
}
|
|
102
|
+
);
|
|
103
|
+
}
|
|
104
|
+
const StyledTypography = styled__default.default(designSystem.Typography)`
|
|
105
|
+
display: block;
|
|
106
|
+
margin-top: 1rem;
|
|
107
|
+
margin-bottom: 0.5rem;
|
|
108
|
+
`;
|
|
109
|
+
const MAX_CONTENT_LENGTH = 4e3;
|
|
110
|
+
function EmbeddingsModal() {
|
|
111
|
+
const { post, get, put } = admin.useFetchClient();
|
|
112
|
+
const { toggleNotification } = admin.useNotification();
|
|
113
|
+
const navigate = reactRouterDom.useNavigate();
|
|
114
|
+
const context = admin.unstable_useContentManagerContext();
|
|
115
|
+
const { form, id, slug, collectionType } = context;
|
|
116
|
+
const modifiedValues = form?.values || {};
|
|
117
|
+
const [isVisible, setIsVisible] = react.useState(false);
|
|
118
|
+
const [isUpdateMode, setIsUpdateMode] = react.useState(false);
|
|
119
|
+
const [title, setTitle] = react.useState("");
|
|
120
|
+
const [content, setContent] = react.useState("");
|
|
121
|
+
const [fieldName, setFieldName] = react.useState("");
|
|
122
|
+
const [isLoading, setIsLoading] = react.useState(false);
|
|
123
|
+
const [isCheckingExisting, setIsCheckingExisting] = react.useState(true);
|
|
124
|
+
const [existingEmbedding, setExistingEmbedding] = react.useState(null);
|
|
125
|
+
react.useEffect(() => {
|
|
126
|
+
async function checkExistingEmbedding() {
|
|
127
|
+
if (!id || !slug) {
|
|
128
|
+
setIsCheckingExisting(false);
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
try {
|
|
132
|
+
const query = qs__default.default.stringify({
|
|
133
|
+
filters: {
|
|
134
|
+
$and: [
|
|
135
|
+
{ collectionType: { $eq: slug } },
|
|
136
|
+
{ metadata: { $containsi: id } }
|
|
137
|
+
]
|
|
138
|
+
}
|
|
139
|
+
});
|
|
140
|
+
const response = await get(`/${PLUGIN_ID}/embeddings/find?${query}`);
|
|
141
|
+
if (response.data?.data?.length > 0) {
|
|
142
|
+
setExistingEmbedding({
|
|
143
|
+
documentId: response.data.data[0].documentId,
|
|
144
|
+
title: response.data.data[0].title,
|
|
145
|
+
content: response.data.data[0].content
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
} catch (error) {
|
|
149
|
+
console.error("Failed to check for existing embedding:", error);
|
|
150
|
+
} finally {
|
|
151
|
+
setIsCheckingExisting(false);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
checkExistingEmbedding();
|
|
155
|
+
}, [id, slug, get]);
|
|
156
|
+
react.useEffect(() => {
|
|
157
|
+
if (!modifiedValues) return;
|
|
158
|
+
const textFieldNames = ["content", "description", "body", "text", "richtext", "markdown"];
|
|
159
|
+
for (const fieldName2 of textFieldNames) {
|
|
160
|
+
const value = modifiedValues[fieldName2];
|
|
161
|
+
if (value) {
|
|
162
|
+
setFieldName(fieldName2);
|
|
163
|
+
if (typeof value === "string" && value.trim()) {
|
|
164
|
+
setContent(value);
|
|
165
|
+
break;
|
|
166
|
+
} else if (Array.isArray(value)) {
|
|
167
|
+
const text = value.map((block) => {
|
|
168
|
+
if (block.children) {
|
|
169
|
+
return block.children.map((child) => child.text || "").join("");
|
|
170
|
+
}
|
|
171
|
+
return "";
|
|
172
|
+
}).join("\n\n");
|
|
173
|
+
if (text.trim()) {
|
|
174
|
+
setContent(text);
|
|
175
|
+
break;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
}, [modifiedValues]);
|
|
181
|
+
const contentLength = content.length;
|
|
182
|
+
const isOverLimit = contentLength > MAX_CONTENT_LENGTH;
|
|
183
|
+
const isSaved = !!id;
|
|
184
|
+
function generateMetadata() {
|
|
185
|
+
return {
|
|
186
|
+
source: "content-manager",
|
|
187
|
+
collectionType: slug || collectionType || "unknown",
|
|
188
|
+
fieldName: fieldName || "content",
|
|
189
|
+
documentId: id,
|
|
190
|
+
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
191
|
+
};
|
|
192
|
+
}
|
|
193
|
+
const isValid = title.trim() && content.trim() && !isOverLimit;
|
|
194
|
+
function handleOpenCreate() {
|
|
195
|
+
setIsUpdateMode(false);
|
|
196
|
+
setTitle("");
|
|
197
|
+
setIsVisible(true);
|
|
198
|
+
}
|
|
199
|
+
function handleOpenUpdate() {
|
|
200
|
+
if (existingEmbedding) {
|
|
201
|
+
setIsUpdateMode(true);
|
|
202
|
+
setTitle(existingEmbedding.title);
|
|
203
|
+
setIsVisible(true);
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
async function handleSubmit(e) {
|
|
207
|
+
e.preventDefault();
|
|
208
|
+
if (!title.trim()) {
|
|
209
|
+
toggleNotification({
|
|
210
|
+
type: "warning",
|
|
211
|
+
message: "Embeddings title is required"
|
|
212
|
+
});
|
|
213
|
+
return;
|
|
214
|
+
}
|
|
215
|
+
if (!content.trim()) {
|
|
216
|
+
toggleNotification({
|
|
217
|
+
type: "warning",
|
|
218
|
+
message: "Embeddings content is required"
|
|
219
|
+
});
|
|
220
|
+
return;
|
|
221
|
+
}
|
|
222
|
+
if (isOverLimit) {
|
|
223
|
+
toggleNotification({
|
|
224
|
+
type: "warning",
|
|
225
|
+
message: `Content exceeds ${MAX_CONTENT_LENGTH} character limit`
|
|
226
|
+
});
|
|
227
|
+
return;
|
|
228
|
+
}
|
|
229
|
+
setIsLoading(true);
|
|
230
|
+
try {
|
|
231
|
+
if (isUpdateMode && existingEmbedding) {
|
|
232
|
+
const result = await put(`/${PLUGIN_ID}/embeddings/update-embedding/${existingEmbedding.documentId}`, {
|
|
233
|
+
data: {
|
|
234
|
+
title: title.trim(),
|
|
235
|
+
content: content.trim(),
|
|
236
|
+
metadata: generateMetadata()
|
|
237
|
+
}
|
|
238
|
+
});
|
|
239
|
+
setExistingEmbedding({
|
|
240
|
+
documentId: result.data.documentId,
|
|
241
|
+
title: result.data.title,
|
|
242
|
+
content: result.data.content
|
|
243
|
+
});
|
|
244
|
+
setIsVisible(false);
|
|
245
|
+
toggleNotification({
|
|
246
|
+
type: "success",
|
|
247
|
+
message: "Embedding updated successfully"
|
|
248
|
+
});
|
|
249
|
+
} else {
|
|
250
|
+
const result = await post(`/${PLUGIN_ID}/embeddings/create-embedding`, {
|
|
251
|
+
data: {
|
|
252
|
+
title: title.trim(),
|
|
253
|
+
content: content.trim(),
|
|
254
|
+
collectionType: slug || collectionType,
|
|
255
|
+
fieldName,
|
|
256
|
+
metadata: generateMetadata()
|
|
257
|
+
}
|
|
258
|
+
});
|
|
259
|
+
setExistingEmbedding({
|
|
260
|
+
documentId: result.data.documentId,
|
|
261
|
+
title: result.data.title,
|
|
262
|
+
content: result.data.content
|
|
263
|
+
});
|
|
264
|
+
setIsVisible(false);
|
|
265
|
+
toggleNotification({
|
|
266
|
+
type: "success",
|
|
267
|
+
message: "Embedding created successfully"
|
|
268
|
+
});
|
|
269
|
+
}
|
|
270
|
+
} catch (error) {
|
|
271
|
+
console.error("Failed to save embedding:", error);
|
|
272
|
+
toggleNotification({
|
|
273
|
+
type: "danger",
|
|
274
|
+
message: error.message || "Failed to save embedding"
|
|
275
|
+
});
|
|
276
|
+
} finally {
|
|
277
|
+
setIsLoading(false);
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
function handleViewEmbedding() {
|
|
281
|
+
if (existingEmbedding?.documentId) {
|
|
282
|
+
navigate(`/plugins/${PLUGIN_ID}/embeddings/${existingEmbedding.documentId}`);
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
if (!form || !id) {
|
|
286
|
+
return null;
|
|
287
|
+
}
|
|
288
|
+
if (isCheckingExisting) {
|
|
289
|
+
return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { paddingTop: 2, children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Loader, { small: true, children: "Checking embeddings..." }) });
|
|
290
|
+
}
|
|
291
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Box, { paddingTop: 2, children: [
|
|
292
|
+
existingEmbedding ? /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", gap: 2, children: [
|
|
293
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { onClick: handleViewEmbedding, startIcon: /* @__PURE__ */ jsxRuntime.jsx(icons.Eye, {}), fullWidth: true, children: "View Embedding" }),
|
|
294
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { onClick: handleOpenUpdate, startIcon: /* @__PURE__ */ jsxRuntime.jsx(icons.Pencil, {}), variant: "secondary", fullWidth: true, children: "Update Embedding" })
|
|
295
|
+
] }) : /* @__PURE__ */ jsxRuntime.jsx(
|
|
296
|
+
designSystem.Button,
|
|
297
|
+
{
|
|
298
|
+
onClick: handleOpenCreate,
|
|
299
|
+
startIcon: /* @__PURE__ */ jsxRuntime.jsx(icons.Plus, {}),
|
|
300
|
+
disabled: !isSaved,
|
|
301
|
+
fullWidth: true,
|
|
302
|
+
children: "Create Embedding"
|
|
303
|
+
}
|
|
304
|
+
),
|
|
305
|
+
!isSaved && !existingEmbedding && /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "pi", textColor: "neutral600", style: { display: "block", marginTop: "0.5rem" }, children: "Save content first to create embedding" }),
|
|
306
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Modal.Root, { open: isVisible, onOpenChange: setIsVisible, children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Modal.Content, { children: [
|
|
307
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Modal.Header, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Modal.Title, { children: isUpdateMode ? "Update Embedding" : "Create Embedding from Content" }) }),
|
|
308
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Modal.Body, { children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Box, { children: [
|
|
309
|
+
/* @__PURE__ */ jsxRuntime.jsxs(StyledTypography, { variant: "omega", textColor: "neutral600", children: [
|
|
310
|
+
"Chunk Size: ",
|
|
311
|
+
contentLength,
|
|
312
|
+
"/",
|
|
313
|
+
MAX_CONTENT_LENGTH,
|
|
314
|
+
isOverLimit && /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textColor: "danger600", children: " (exceeds limit)" })
|
|
315
|
+
] }),
|
|
316
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { marginBottom: 4, children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Field.Root, { children: [
|
|
317
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Field.Label, { children: "Title" }),
|
|
318
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
319
|
+
designSystem.TextInput,
|
|
320
|
+
{
|
|
321
|
+
placeholder: "Enter embedding title",
|
|
322
|
+
value: title,
|
|
323
|
+
onChange: (e) => setTitle(e.target.value)
|
|
324
|
+
}
|
|
325
|
+
)
|
|
326
|
+
] }) }),
|
|
327
|
+
/* @__PURE__ */ jsxRuntime.jsxs(designSystem.Box, { marginBottom: 4, children: [
|
|
328
|
+
/* @__PURE__ */ jsxRuntime.jsxs(designSystem.Field.Root, { children: [
|
|
329
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Field.Label, { children: "Content" }),
|
|
330
|
+
/* @__PURE__ */ jsxRuntime.jsxs(designSystem.Field.Hint, { children: [
|
|
331
|
+
fieldName ? `From field: ${fieldName}` : "Enter content manually",
|
|
332
|
+
isUpdateMode && " - Changes will regenerate the embedding vector"
|
|
333
|
+
] })
|
|
334
|
+
] }),
|
|
335
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
336
|
+
MarkdownEditor,
|
|
337
|
+
{
|
|
338
|
+
content,
|
|
339
|
+
onChange: setContent,
|
|
340
|
+
height: 200
|
|
341
|
+
}
|
|
342
|
+
)
|
|
343
|
+
] })
|
|
344
|
+
] }) }),
|
|
345
|
+
/* @__PURE__ */ jsxRuntime.jsxs(designSystem.Modal.Footer, { children: [
|
|
346
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Modal.Close, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { variant: "tertiary", children: "Cancel" }) }),
|
|
347
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
348
|
+
designSystem.Button,
|
|
349
|
+
{
|
|
350
|
+
onClick: handleSubmit,
|
|
351
|
+
disabled: isLoading || !isValid,
|
|
352
|
+
loading: isLoading,
|
|
353
|
+
children: isLoading ? isUpdateMode ? "Updating..." : "Creating..." : isUpdateMode ? "Update Embedding" : "Create Embedding"
|
|
354
|
+
}
|
|
355
|
+
)
|
|
356
|
+
] })
|
|
357
|
+
] }) })
|
|
358
|
+
] });
|
|
359
|
+
}
|
|
360
|
+
function EmbeddingsWidget() {
|
|
361
|
+
return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { children: /* @__PURE__ */ jsxRuntime.jsx(EmbeddingsModal, {}) });
|
|
362
|
+
}
|
|
363
|
+
const index = {
|
|
364
|
+
register(app) {
|
|
365
|
+
app.addMenuLink({
|
|
366
|
+
to: `plugins/${PLUGIN_ID}`,
|
|
367
|
+
icon: PluginIcon,
|
|
368
|
+
intlLabel: {
|
|
369
|
+
id: `${PLUGIN_ID}.plugin.name`,
|
|
370
|
+
defaultMessage: PLUGIN_ID
|
|
371
|
+
},
|
|
372
|
+
Component: async () => {
|
|
373
|
+
const { App } = await Promise.resolve().then(() => require("./App-wC2qv6kC.js"));
|
|
374
|
+
return App;
|
|
375
|
+
}
|
|
376
|
+
});
|
|
377
|
+
app.registerPlugin({
|
|
378
|
+
id: PLUGIN_ID,
|
|
379
|
+
initializer: Initializer,
|
|
380
|
+
isReady: false,
|
|
381
|
+
name: PLUGIN_ID
|
|
382
|
+
});
|
|
383
|
+
},
|
|
384
|
+
bootstrap(app) {
|
|
385
|
+
app.getPlugin("content-manager").injectComponent("editView", "right-links", {
|
|
386
|
+
name: "open-ai-embeddings",
|
|
387
|
+
Component: () => /* @__PURE__ */ jsxRuntime.jsx(EmbeddingsWidget, {})
|
|
388
|
+
});
|
|
389
|
+
},
|
|
390
|
+
async registerTrads(app) {
|
|
391
|
+
const { locales } = app;
|
|
392
|
+
const importedTranslations = await Promise.all(
|
|
393
|
+
locales.map((locale) => {
|
|
394
|
+
return __variableDynamicImportRuntimeHelper(/* @__PURE__ */ Object.assign({ "./translations/en.json": () => Promise.resolve().then(() => require("./en-B4KWt_jN.js")) }), `./translations/${locale}.json`, 3).then(({ default: data }) => {
|
|
395
|
+
return {
|
|
396
|
+
data: getTranslation(data),
|
|
397
|
+
locale
|
|
398
|
+
};
|
|
399
|
+
}).catch(() => {
|
|
400
|
+
return {
|
|
401
|
+
data: {},
|
|
402
|
+
locale
|
|
403
|
+
};
|
|
404
|
+
});
|
|
405
|
+
})
|
|
406
|
+
);
|
|
407
|
+
return importedTranslations;
|
|
408
|
+
}
|
|
409
|
+
};
|
|
410
|
+
exports.MarkdownEditor = MarkdownEditor;
|
|
411
|
+
exports.PLUGIN_ID = PLUGIN_ID;
|
|
412
|
+
exports.RobotIcon = RobotIcon;
|
|
413
|
+
exports.index = index;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function ChatModal(): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function EmbeddingsModal(): import("react/jsx-runtime").JSX.Element | null;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
interface Embedding {
|
|
2
|
+
id: number;
|
|
3
|
+
documentId: string;
|
|
4
|
+
title: string;
|
|
5
|
+
content?: string;
|
|
6
|
+
embeddingId?: string;
|
|
7
|
+
}
|
|
8
|
+
interface EmbeddingsTableProps {
|
|
9
|
+
data: Embedding[];
|
|
10
|
+
}
|
|
11
|
+
export declare function EmbeddingsTable({ data }: EmbeddingsTableProps): import("react/jsx-runtime").JSX.Element;
|
|
12
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function EmbeddingsWidget(): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function EmptyState(): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const Illo: () => import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import '@mdxeditor/editor/style.css';
|
|
2
|
+
import './markdown-editor.css';
|
|
3
|
+
interface MarkdownEditorProps {
|
|
4
|
+
content: string;
|
|
5
|
+
onChange: (content: string) => void;
|
|
6
|
+
height?: number;
|
|
7
|
+
}
|
|
8
|
+
export declare function MarkdownEditor({ content, onChange, height }: MarkdownEditorProps): import("react/jsx-runtime").JSX.Element;
|
|
9
|
+
export {};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
interface CreateEmbeddingsFormProps {
|
|
3
|
+
onSubmit: (e: React.FormEvent<HTMLFormElement>) => void;
|
|
4
|
+
isLoading: boolean;
|
|
5
|
+
input: string;
|
|
6
|
+
setInput: (input: string) => void;
|
|
7
|
+
markdown: string;
|
|
8
|
+
handleMarkdownChange: React.Dispatch<React.SetStateAction<string>>;
|
|
9
|
+
metadata: string;
|
|
10
|
+
setMetadata: (metadata: string) => void;
|
|
11
|
+
height?: number;
|
|
12
|
+
children?: React.ReactNode;
|
|
13
|
+
}
|
|
14
|
+
export declare function CreateEmbeddingsForm({ onSubmit, isLoading, input, setInput, markdown, handleMarkdownChange, metadata, setMetadata, height, children, }: CreateEmbeddingsFormProps): import("react/jsx-runtime").JSX.Element;
|
|
15
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export default function CreateEmbeddings(): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export default function EmbeddingDetails(): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function HomePage(): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const PLUGIN_ID = "strapi-content-embeddings";
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
interface CreateEmbeddingData {
|
|
2
|
+
title: string;
|
|
3
|
+
content: string;
|
|
4
|
+
collectionType?: string;
|
|
5
|
+
fieldName?: string;
|
|
6
|
+
related?: {
|
|
7
|
+
__type: string;
|
|
8
|
+
id: number;
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
interface EmbeddingsListParams {
|
|
12
|
+
page?: number;
|
|
13
|
+
pageSize?: number;
|
|
14
|
+
filters?: Record<string, any>;
|
|
15
|
+
}
|
|
16
|
+
export declare const embeddingsApi: {
|
|
17
|
+
create: (fetchClient: {
|
|
18
|
+
post: Function;
|
|
19
|
+
}, data: CreateEmbeddingData) => Promise<any>;
|
|
20
|
+
delete: (fetchClient: {
|
|
21
|
+
del: Function;
|
|
22
|
+
}, id: string) => Promise<any>;
|
|
23
|
+
getOne: (fetchClient: {
|
|
24
|
+
get: Function;
|
|
25
|
+
}, id: string) => Promise<any>;
|
|
26
|
+
getAll: (fetchClient: {
|
|
27
|
+
get: Function;
|
|
28
|
+
}, params?: EmbeddingsListParams) => Promise<any>;
|
|
29
|
+
query: (fetchClient: {
|
|
30
|
+
get: Function;
|
|
31
|
+
}, query: string) => Promise<any>;
|
|
32
|
+
};
|
|
33
|
+
export {};
|