strapi-plugin-ai-sdk 0.7.4 → 0.7.9
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/_chunks/{App-CEEsJsKL.js → App-DTbAnq7K.js} +712 -53
- package/dist/_chunks/{App-DCV7o6Hc.mjs → App-DZVBmpvs.mjs} +714 -55
- package/dist/_chunks/{index-Cw2aiQ8K.js → index-C3xn2IND.js} +1 -1
- package/dist/_chunks/{index-BMrDQVQl.mjs → index-Ca2F2wBp.mjs} +1 -1
- package/dist/admin/index.js +1 -1
- package/dist/admin/index.mjs +1 -1
- package/dist/admin/src/components/NotePanel.d.ts +15 -0
- package/dist/admin/src/hooks/useNotes.d.ts +22 -0
- package/dist/admin/src/pages/NoteStorePage.d.ts +2 -0
- package/dist/admin/src/utils/notes-api.d.ts +28 -0
- package/dist/server/index.js +603 -171
- package/dist/server/index.mjs +603 -171
- package/dist/server/src/content-types/index.d.ts +46 -0
- package/dist/server/src/content-types/note/index.d.ts +47 -0
- package/dist/server/src/controllers/index.d.ts +9 -0
- package/dist/server/src/controllers/note.d.ts +12 -0
- package/dist/server/src/index.d.ts +55 -0
- package/dist/server/src/mcp/resources/tool-guide.d.ts +5 -0
- package/dist/server/src/tool-logic/aggregate-content.d.ts +1 -1
- package/dist/server/src/tool-logic/create-content.d.ts +27 -0
- package/dist/server/src/tool-logic/find-one-content.d.ts +1 -1
- package/dist/server/src/tool-logic/index.d.ts +8 -2
- package/dist/server/src/tool-logic/list-content-types.d.ts +1 -1
- package/dist/server/src/tool-logic/manage-task.d.ts +1 -1
- package/dist/server/src/tool-logic/recall-notes.d.ts +22 -0
- package/dist/server/src/tool-logic/save-note.d.ts +17 -0
- package/dist/server/src/tool-logic/update-content.d.ts +29 -0
- package/dist/server/src/tool-logic/upload-media.d.ts +1 -1
- package/dist/server/src/tools/definitions/create-content.d.ts +2 -0
- package/dist/server/src/tools/definitions/{write-content.d.ts → recall-notes.d.ts} +1 -1
- package/dist/server/src/tools/definitions/save-note.d.ts +2 -0
- package/dist/server/src/tools/definitions/update-content.d.ts +2 -0
- package/package.json +1 -1
- package/dist/server/src/tool-logic/write-content.d.ts +0 -34
package/dist/server/index.js
CHANGED
|
@@ -30,6 +30,90 @@ function _interopNamespace(e) {
|
|
|
30
30
|
}
|
|
31
31
|
const fs__namespace = /* @__PURE__ */ _interopNamespace(fs$1);
|
|
32
32
|
const path__namespace = /* @__PURE__ */ _interopNamespace(path$1);
|
|
33
|
+
function toSnakeCase$1(str) {
|
|
34
|
+
return str.replace(/:/g, "__").replace(/-/g, "_").replace(/[A-Z]/g, (letter) => `_${letter.toLowerCase()}`);
|
|
35
|
+
}
|
|
36
|
+
function extractType(field) {
|
|
37
|
+
const def = field?._zod?.def;
|
|
38
|
+
if (!def) return "unknown";
|
|
39
|
+
switch (def.type) {
|
|
40
|
+
case "string":
|
|
41
|
+
return "string";
|
|
42
|
+
case "number":
|
|
43
|
+
return "number";
|
|
44
|
+
case "boolean":
|
|
45
|
+
return "boolean";
|
|
46
|
+
case "enum":
|
|
47
|
+
return Object.keys(def.entries).join(" | ");
|
|
48
|
+
case "optional":
|
|
49
|
+
return extractType({ _zod: { def: def.innerType } });
|
|
50
|
+
case "default":
|
|
51
|
+
return extractType({ _zod: { def: def.innerType } });
|
|
52
|
+
case "record":
|
|
53
|
+
return "object";
|
|
54
|
+
case "array":
|
|
55
|
+
return "array";
|
|
56
|
+
case "union":
|
|
57
|
+
return "string | array | object";
|
|
58
|
+
default:
|
|
59
|
+
return def.type || "unknown";
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
function formatParams(schema2) {
|
|
63
|
+
const shape = schema2.shape;
|
|
64
|
+
if (!shape || Object.keys(shape).length === 0) {
|
|
65
|
+
return "_No parameters._\n";
|
|
66
|
+
}
|
|
67
|
+
const rows = [];
|
|
68
|
+
rows.push("| Parameter | Type | Required | Description |");
|
|
69
|
+
rows.push("|-----------|------|----------|-------------|");
|
|
70
|
+
for (const [name, field] of Object.entries(shape)) {
|
|
71
|
+
const required = !field.isOptional?.();
|
|
72
|
+
const type = extractType(field);
|
|
73
|
+
const desc = (field.description || "").replace(/\|/g, "\\|");
|
|
74
|
+
rows.push(`| ${name} | ${type} | ${required ? "Yes" : "No"} | ${desc} |`);
|
|
75
|
+
}
|
|
76
|
+
return rows.join("\n") + "\n";
|
|
77
|
+
}
|
|
78
|
+
function generateToolGuide(registry) {
|
|
79
|
+
const tools = registry.getPublic();
|
|
80
|
+
const sources = registry.getToolSources();
|
|
81
|
+
const sections = [];
|
|
82
|
+
sections.push("# Strapi AI Tools Guide\n");
|
|
83
|
+
sections.push("## Getting Started\n");
|
|
84
|
+
sections.push(
|
|
85
|
+
"Start with `list_content_types` to discover your content types and their fields, then use `search_content` to query them.\n"
|
|
86
|
+
);
|
|
87
|
+
for (const source of sources) {
|
|
88
|
+
const heading = source.id === "built-in" ? "Built-in Tools" : source.label;
|
|
89
|
+
sections.push(`## ${heading}
|
|
90
|
+
`);
|
|
91
|
+
for (const toolName of source.tools) {
|
|
92
|
+
const def = tools.get(toolName);
|
|
93
|
+
if (!def) continue;
|
|
94
|
+
const mcpName = toSnakeCase$1(toolName);
|
|
95
|
+
sections.push(`### ${mcpName}
|
|
96
|
+
`);
|
|
97
|
+
sections.push(`${def.description}
|
|
98
|
+
`);
|
|
99
|
+
sections.push(formatParams(def.schema));
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
sections.push("## Common Workflows\n");
|
|
103
|
+
sections.push("### Create a blog post\n");
|
|
104
|
+
sections.push(
|
|
105
|
+
"1. Call `list_content_types` to discover the article/blog content type and its fields\n2. (Optional) Call `upload_media` with a URL to upload a cover image\n3. Call `create_content` with the content type UID and field data\n"
|
|
106
|
+
);
|
|
107
|
+
sections.push("### Find and update content\n");
|
|
108
|
+
sections.push(
|
|
109
|
+
"1. Call `search_content` with filters or a query to find the document\n2. Note the `documentId` from the results\n3. Call `update_content` with the content type, documentId, and fields to change\n"
|
|
110
|
+
);
|
|
111
|
+
sections.push("### Content analytics\n");
|
|
112
|
+
sections.push(
|
|
113
|
+
"1. Call `aggregate_content` with operation `count` for totals\n2. Use `countByField` with `groupByField` to see distribution (e.g. articles per category)\n3. Use `countByDateRange` with `granularity` to see trends over time\n"
|
|
114
|
+
);
|
|
115
|
+
return sections.join("\n");
|
|
116
|
+
}
|
|
33
117
|
function toSnakeCase(str) {
|
|
34
118
|
return str.replace(/:/g, "__").replace(/-/g, "_").replace(/[A-Z]/g, (letter) => `_${letter.toLowerCase()}`);
|
|
35
119
|
}
|
|
@@ -46,7 +130,8 @@ function createMcpServer(strapi) {
|
|
|
46
130
|
},
|
|
47
131
|
{
|
|
48
132
|
capabilities: {
|
|
49
|
-
tools: {}
|
|
133
|
+
tools: {},
|
|
134
|
+
resources: {}
|
|
50
135
|
}
|
|
51
136
|
}
|
|
52
137
|
);
|
|
@@ -74,6 +159,24 @@ function createMcpServer(strapi) {
|
|
|
74
159
|
}
|
|
75
160
|
);
|
|
76
161
|
}
|
|
162
|
+
const guideMarkdown = generateToolGuide(registry);
|
|
163
|
+
server.registerResource(
|
|
164
|
+
"Tool Guide",
|
|
165
|
+
"strapi://tools/guide",
|
|
166
|
+
{
|
|
167
|
+
description: "Complete guide to all available Strapi AI tools with parameters and usage examples",
|
|
168
|
+
mimeType: "text/markdown"
|
|
169
|
+
},
|
|
170
|
+
async () => ({
|
|
171
|
+
contents: [
|
|
172
|
+
{
|
|
173
|
+
uri: "strapi://tools/guide",
|
|
174
|
+
mimeType: "text/markdown",
|
|
175
|
+
text: guideMarkdown
|
|
176
|
+
}
|
|
177
|
+
]
|
|
178
|
+
})
|
|
179
|
+
);
|
|
77
180
|
strapi.log.info("[ai-sdk:mcp] MCP server created with tools:", { tools: toolNames });
|
|
78
181
|
return server;
|
|
79
182
|
}
|
|
@@ -239,7 +342,7 @@ class ToolRegistry {
|
|
|
239
342
|
}
|
|
240
343
|
}
|
|
241
344
|
const listContentTypesSchema = zod.z.object({});
|
|
242
|
-
const listContentTypesDescription =
|
|
345
|
+
const listContentTypesDescription = 'List all Strapi content types and components with their fields, relations, and structure. This is the starting point for any content operation — call it first to discover content type UIDs (e.g. "api::article.article"), field names, relation targets, and components. No parameters required. Results are cached.';
|
|
243
346
|
const INTERNAL_FIELDS = /* @__PURE__ */ new Set([
|
|
244
347
|
"createdAt",
|
|
245
348
|
"updatedAt",
|
|
@@ -387,33 +490,41 @@ async function searchContent(strapi, params) {
|
|
|
387
490
|
}
|
|
388
491
|
};
|
|
389
492
|
}
|
|
390
|
-
const
|
|
493
|
+
const createContentSchema = zod.z.object({
|
|
391
494
|
contentType: zod.z.string().describe('Content type UID, e.g. "api::article.article"'),
|
|
392
|
-
action: zod.z.enum(["create", "update"]).describe("Whether to create a new document or update an existing one"),
|
|
393
|
-
documentId: zod.z.string().optional().describe("Required for update — the document ID to update"),
|
|
394
495
|
data: zod.z.record(zod.z.string(), zod.z.unknown()).describe("The field values to set. Must match the content type schema."),
|
|
395
496
|
status: zod.z.enum(["draft", "published"]).optional().describe("Document status. Defaults to draft."),
|
|
396
497
|
locale: zod.z.string().optional().describe('Locale code for i18n content, e.g. "en" or "fr"')
|
|
397
498
|
});
|
|
398
|
-
const
|
|
399
|
-
async function
|
|
400
|
-
const { contentType,
|
|
499
|
+
const createContentDescription = "Create a new document in any Strapi content type. Requires contentType (UID) and data (field values). Call listContentTypes first to discover UIDs and required fields. To attach media, upload it first with uploadMedia, then pass the file ID in data. Returns the created document with all fields populated.";
|
|
500
|
+
async function createContent(strapi, params) {
|
|
501
|
+
const { contentType, data, status, locale } = params;
|
|
401
502
|
if (!strapi.contentTypes[contentType]) {
|
|
402
503
|
throw new Error(`Content type "${contentType}" does not exist.`);
|
|
403
504
|
}
|
|
404
|
-
if (action === "update" && !documentId) {
|
|
405
|
-
throw new Error("documentId is required for update actions.");
|
|
406
|
-
}
|
|
407
505
|
const docs = strapi.documents(contentType);
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
506
|
+
const document = await docs.create({
|
|
507
|
+
data,
|
|
508
|
+
...status ? { status } : {},
|
|
509
|
+
...locale ? { locale } : {},
|
|
510
|
+
populate: "*"
|
|
511
|
+
});
|
|
512
|
+
return { action: "create", document };
|
|
513
|
+
}
|
|
514
|
+
const updateContentSchema = zod.z.object({
|
|
515
|
+
contentType: zod.z.string().describe('Content type UID, e.g. "api::article.article"'),
|
|
516
|
+
documentId: zod.z.string().describe("The document ID to update"),
|
|
517
|
+
data: zod.z.record(zod.z.string(), zod.z.unknown()).describe("The field values to set. Must match the content type schema."),
|
|
518
|
+
status: zod.z.enum(["draft", "published"]).optional().describe("Document status. Defaults to draft."),
|
|
519
|
+
locale: zod.z.string().optional().describe('Locale code for i18n content, e.g. "en" or "fr"')
|
|
520
|
+
});
|
|
521
|
+
const updateContentDescription = "Update an existing document in any Strapi content type. Requires contentType, documentId, and data (fields to change — only include fields you want to modify). Typical workflow: searchContent to find the documentId, then updateContent to modify it. Returns the updated document.";
|
|
522
|
+
async function updateContent(strapi, params) {
|
|
523
|
+
const { contentType, documentId, data, status, locale } = params;
|
|
524
|
+
if (!strapi.contentTypes[contentType]) {
|
|
525
|
+
throw new Error(`Content type "${contentType}" does not exist.`);
|
|
416
526
|
}
|
|
527
|
+
const docs = strapi.documents(contentType);
|
|
417
528
|
const existing = await docs.findOne({
|
|
418
529
|
documentId,
|
|
419
530
|
...locale ? { locale } : {}
|
|
@@ -480,7 +591,7 @@ async function sendEmail(strapi, params) {
|
|
|
480
591
|
subject: params.subject
|
|
481
592
|
};
|
|
482
593
|
}
|
|
483
|
-
const CONTENT_TYPE$
|
|
594
|
+
const CONTENT_TYPE$a = "plugin::ai-sdk.memory";
|
|
484
595
|
const saveMemorySchema = zod.z.object({
|
|
485
596
|
content: zod.z.string().describe('A short, factual statement to remember about the user (e.g. "User prefers dark mode", "Company name is Acme Corp")'),
|
|
486
597
|
category: zod.z.string().optional().describe('Category for the memory (e.g. "preference", "project", "personal", "general"). Defaults to "general".')
|
|
@@ -491,7 +602,7 @@ async function saveMemory(strapi, params, context) {
|
|
|
491
602
|
return { success: false, message: "Cannot save memory: user context not available." };
|
|
492
603
|
}
|
|
493
604
|
try {
|
|
494
|
-
await strapi.documents(CONTENT_TYPE$
|
|
605
|
+
await strapi.documents(CONTENT_TYPE$a).create({
|
|
495
606
|
data: {
|
|
496
607
|
content: params.content,
|
|
497
608
|
category: params.category || "general",
|
|
@@ -504,7 +615,7 @@ async function saveMemory(strapi, params, context) {
|
|
|
504
615
|
return { success: false, message: `Failed to save memory: ${detail}` };
|
|
505
616
|
}
|
|
506
617
|
}
|
|
507
|
-
const CONTENT_TYPE$
|
|
618
|
+
const CONTENT_TYPE$9 = "plugin::ai-sdk.memory";
|
|
508
619
|
const recallMemoriesSchema = zod.z.object({
|
|
509
620
|
query: zod.z.string().optional().describe("Optional search term to filter memories by content"),
|
|
510
621
|
category: zod.z.string().optional().describe('Optional category to filter by (e.g. "preference", "project", "personal")')
|
|
@@ -522,7 +633,7 @@ async function recallMemories(strapi, params, context) {
|
|
|
522
633
|
if (params.query) {
|
|
523
634
|
filters.content = { $containsi: params.query };
|
|
524
635
|
}
|
|
525
|
-
const memories = await strapi.documents(CONTENT_TYPE$
|
|
636
|
+
const memories = await strapi.documents(CONTENT_TYPE$9).findMany({
|
|
526
637
|
filters,
|
|
527
638
|
fields: ["content", "category"],
|
|
528
639
|
sort: { createdAt: "desc" }
|
|
@@ -548,7 +659,7 @@ const findOneContentSchema = zod.z.object({
|
|
|
548
659
|
status: zod.z.enum(["draft", "published"]).optional().describe("Document status filter."),
|
|
549
660
|
locale: zod.z.string().optional().describe('Locale code for i18n content, e.g. "en" or "fr"')
|
|
550
661
|
});
|
|
551
|
-
const findOneContentDescription = "Fetch a single document by its documentId
|
|
662
|
+
const findOneContentDescription = "Fetch a single document by its exact documentId. Use this when you already have a documentId and need full details with populated relations. If you need to find documents by title, field values, or full-text search, use searchContent instead. Requires contentType and documentId.";
|
|
552
663
|
async function findOneContent(strapi, params) {
|
|
553
664
|
const { contentType, documentId, populate = "*", fields, status, locale } = params;
|
|
554
665
|
if (!strapi.contentTypes[contentType]) {
|
|
@@ -574,7 +685,7 @@ const uploadMediaSchema = zod.z.object({
|
|
|
574
685
|
caption: zod.z.string().optional().describe("Caption for the media file"),
|
|
575
686
|
alternativeText: zod.z.string().optional().describe("Alternative text for accessibility")
|
|
576
687
|
});
|
|
577
|
-
const uploadMediaDescription = "Upload a media file from a URL to the Strapi media library.
|
|
688
|
+
const uploadMediaDescription = "Upload a media file from a URL to the Strapi media library. This is step 1 of a two-step process: (1) upload the file with this tool to get a file ID, then (2) link it to a content entry using createContent or updateContent with { fieldName: fileId }. Requires url. Optional: name, caption, alternativeText.";
|
|
578
689
|
async function uploadMedia(strapi, params) {
|
|
579
690
|
const { url, name, caption, alternativeText } = params;
|
|
580
691
|
let parsedUrl;
|
|
@@ -642,10 +753,10 @@ async function uploadMedia(strapi, params) {
|
|
|
642
753
|
return {
|
|
643
754
|
file: uploadedFile,
|
|
644
755
|
message: `File "${uploadedFile.name}" uploaded successfully (ID: ${uploadedFile.id}).`,
|
|
645
|
-
usage: `To link this file to a content type field, use
|
|
756
|
+
usage: `To link this file to a content type field, use createContent or updateContent with: { "fieldName": ${uploadedFile.id} }`
|
|
646
757
|
};
|
|
647
758
|
}
|
|
648
|
-
const CONTENT_TYPE$
|
|
759
|
+
const CONTENT_TYPE$8 = "plugin::ai-sdk.public-memory";
|
|
649
760
|
const recallPublicMemoriesSchema = zod.z.object({
|
|
650
761
|
query: zod.z.string().optional().describe("Optional search term to filter public memories by content"),
|
|
651
762
|
category: zod.z.string().optional().describe('Optional category to filter by (e.g. "faq", "product", "policy")')
|
|
@@ -656,7 +767,7 @@ async function recallPublicMemories(strapi, params) {
|
|
|
656
767
|
const filters = {};
|
|
657
768
|
if (params.category) filters.category = params.category;
|
|
658
769
|
if (params.query) filters.content = { $containsi: params.query };
|
|
659
|
-
const memories = await strapi.documents(CONTENT_TYPE$
|
|
770
|
+
const memories = await strapi.documents(CONTENT_TYPE$8).findMany({
|
|
660
771
|
filters,
|
|
661
772
|
fields: ["content", "category"],
|
|
662
773
|
sort: { createdAt: "desc" }
|
|
@@ -738,7 +849,7 @@ const aggregateContentSchema = zod.z.object({
|
|
|
738
849
|
status: zod.z.enum(["draft", "published"]).optional().describe("Filter by document status"),
|
|
739
850
|
locale: zod.z.string().optional().describe("Locale code for i18n content")
|
|
740
851
|
});
|
|
741
|
-
const aggregateContentDescription = '
|
|
852
|
+
const aggregateContentDescription = 'Count and group content entries for analytics. Answers questions like "how many articles?", "posts per category", "content published by month". Three operations: count (total), countByField (group by a field), countByDateRange (bucket by day/week/month). Prefer this over searchContent when you need counts or distributions, not the documents themselves.';
|
|
742
853
|
function buildBaseQuery(params) {
|
|
743
854
|
const { filters, status, locale, dateFrom, dateTo, dateField = "createdAt" } = params;
|
|
744
855
|
const query = {};
|
|
@@ -890,7 +1001,7 @@ async function aggregateContent(strapi, params) {
|
|
|
890
1001
|
throw new Error(`Unknown operation: ${operation}`);
|
|
891
1002
|
}
|
|
892
1003
|
}
|
|
893
|
-
const CONTENT_TYPE$
|
|
1004
|
+
const CONTENT_TYPE$7 = "plugin::ai-sdk.task";
|
|
894
1005
|
const manageTaskSchema = zod.z.object({
|
|
895
1006
|
action: zod.z.enum(["create", "update", "complete", "list", "summary"]).describe(
|
|
896
1007
|
"Action to perform: create a new task, update an existing task, complete (mark done), list open tasks, or get a summary."
|
|
@@ -906,14 +1017,14 @@ const manageTaskSchema = zod.z.object({
|
|
|
906
1017
|
done: zod.z.boolean().optional().describe("Set done status explicitly (for update action)."),
|
|
907
1018
|
filters: zod.z.record(zod.z.string(), zod.z.unknown()).optional().describe("Additional Strapi filters for list action.")
|
|
908
1019
|
});
|
|
909
|
-
const manageTaskDescription = "Manage the user's task list.
|
|
1020
|
+
const manageTaskDescription = "Manage the user's task list. Actions: create (new task), update (modify fields), complete (mark done), list (open tasks sorted by priority score), summary (overview with overdue/urgent counts). Tasks are scored by consequence × impact to prioritize what matters most. For create: title is required; consequence and impact are collected via UI form if omitted.";
|
|
910
1021
|
async function resolveTask(strapi, adminUserId, documentId, title) {
|
|
911
1022
|
if (documentId) {
|
|
912
|
-
const task2 = await strapi.documents(CONTENT_TYPE$
|
|
1023
|
+
const task2 = await strapi.documents(CONTENT_TYPE$7).findOne({ documentId });
|
|
913
1024
|
if (task2 && task2.adminUserId === adminUserId) return task2;
|
|
914
1025
|
}
|
|
915
1026
|
if (title) {
|
|
916
|
-
const tasks = await strapi.documents(CONTENT_TYPE$
|
|
1027
|
+
const tasks = await strapi.documents(CONTENT_TYPE$7).findMany({
|
|
917
1028
|
filters: {
|
|
918
1029
|
adminUserId,
|
|
919
1030
|
title: { $containsi: title }
|
|
@@ -966,7 +1077,7 @@ async function manageTask(strapi, params, context) {
|
|
|
966
1077
|
if (params.consequence !== void 0) data.consequence = params.consequence;
|
|
967
1078
|
if (params.impact !== void 0) data.impact = params.impact;
|
|
968
1079
|
if (params.dueDate !== void 0) data.dueDate = params.dueDate;
|
|
969
|
-
const updated = await strapi.documents(CONTENT_TYPE$
|
|
1080
|
+
const updated = await strapi.documents(CONTENT_TYPE$7).update({
|
|
970
1081
|
documentId: duplicate.documentId,
|
|
971
1082
|
data
|
|
972
1083
|
});
|
|
@@ -977,7 +1088,7 @@ async function manageTask(strapi, params, context) {
|
|
|
977
1088
|
data: updated
|
|
978
1089
|
};
|
|
979
1090
|
}
|
|
980
|
-
const task2 = await strapi.documents(CONTENT_TYPE$
|
|
1091
|
+
const task2 = await strapi.documents(CONTENT_TYPE$7).create({
|
|
981
1092
|
data: {
|
|
982
1093
|
title: params.title,
|
|
983
1094
|
description: params.description,
|
|
@@ -1006,7 +1117,7 @@ async function manageTask(strapi, params, context) {
|
|
|
1006
1117
|
for (const key of ["title", "description", "content", "priority", "consequence", "impact", "dueDate", "done"]) {
|
|
1007
1118
|
if (params[key] !== void 0) data[key] = params[key];
|
|
1008
1119
|
}
|
|
1009
|
-
const updated = await strapi.documents(CONTENT_TYPE$
|
|
1120
|
+
const updated = await strapi.documents(CONTENT_TYPE$7).update({
|
|
1010
1121
|
documentId: existing.documentId,
|
|
1011
1122
|
data
|
|
1012
1123
|
});
|
|
@@ -1017,7 +1128,7 @@ async function manageTask(strapi, params, context) {
|
|
|
1017
1128
|
if (!toComplete) {
|
|
1018
1129
|
return { success: false, message: "Task not found. Provide a documentId or a title to search by." };
|
|
1019
1130
|
}
|
|
1020
|
-
await strapi.documents(CONTENT_TYPE$
|
|
1131
|
+
await strapi.documents(CONTENT_TYPE$7).update({
|
|
1021
1132
|
documentId: toComplete.documentId,
|
|
1022
1133
|
data: { done: true }
|
|
1023
1134
|
});
|
|
@@ -1029,7 +1140,7 @@ async function manageTask(strapi, params, context) {
|
|
|
1029
1140
|
done: false,
|
|
1030
1141
|
...params.filters
|
|
1031
1142
|
};
|
|
1032
|
-
const tasks = await strapi.documents(CONTENT_TYPE$
|
|
1143
|
+
const tasks = await strapi.documents(CONTENT_TYPE$7).findMany({
|
|
1033
1144
|
filters
|
|
1034
1145
|
});
|
|
1035
1146
|
const sorted = tasks.sort((a, b) => {
|
|
@@ -1058,7 +1169,7 @@ async function manageTask(strapi, params, context) {
|
|
|
1058
1169
|
};
|
|
1059
1170
|
}
|
|
1060
1171
|
case "summary": {
|
|
1061
|
-
const allOpen = await strapi.documents(CONTENT_TYPE$
|
|
1172
|
+
const allOpen = await strapi.documents(CONTENT_TYPE$7).findMany({
|
|
1062
1173
|
filters: { adminUserId, done: false }
|
|
1063
1174
|
});
|
|
1064
1175
|
const today = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
|
|
@@ -1095,6 +1206,82 @@ async function manageTask(strapi, params, context) {
|
|
|
1095
1206
|
return { success: false, message: `Task operation failed: ${detail}` };
|
|
1096
1207
|
}
|
|
1097
1208
|
}
|
|
1209
|
+
const CONTENT_TYPE$6 = "plugin::ai-sdk.note";
|
|
1210
|
+
const saveNoteSchema = zod.z.object({
|
|
1211
|
+
title: zod.z.string().optional().describe("A short title or label for the note"),
|
|
1212
|
+
content: zod.z.string().describe("The note content in markdown format. Can include code blocks, lists, links, etc."),
|
|
1213
|
+
category: zod.z.string().optional().describe('Category for the note: "research", "snippet", "idea", or "reference". Defaults to "research".'),
|
|
1214
|
+
tags: zod.z.string().optional().describe('Comma-separated tags for filtering (e.g. "strapi, api, tutorial")'),
|
|
1215
|
+
source: zod.z.string().optional().describe('Where this note came from (e.g. "conversation", "web research", a URL)')
|
|
1216
|
+
});
|
|
1217
|
+
const saveNoteDescription = "Save a research note, code snippet, idea, or reference for the user. Use this when the user wants to save part of a conversation, research findings, code examples, or any content they may want to use later for writing blog posts or articles. Content is saved as markdown.";
|
|
1218
|
+
async function saveNote(strapi, params, context) {
|
|
1219
|
+
if (!context?.adminUserId) {
|
|
1220
|
+
return { success: false, message: "Cannot save note: user context not available." };
|
|
1221
|
+
}
|
|
1222
|
+
try {
|
|
1223
|
+
await strapi.documents(CONTENT_TYPE$6).create({
|
|
1224
|
+
data: {
|
|
1225
|
+
title: params.title || "",
|
|
1226
|
+
content: params.content,
|
|
1227
|
+
category: params.category || "research",
|
|
1228
|
+
tags: params.tags || "",
|
|
1229
|
+
source: params.source || "conversation",
|
|
1230
|
+
adminUserId: context.adminUserId
|
|
1231
|
+
}
|
|
1232
|
+
});
|
|
1233
|
+
const label = params.title ? `"${params.title}"` : "Note";
|
|
1234
|
+
return { success: true, message: `${label} saved to research notes.` };
|
|
1235
|
+
} catch (error) {
|
|
1236
|
+
const detail = error instanceof Error ? error.message : String(error);
|
|
1237
|
+
return { success: false, message: `Failed to save note: ${detail}` };
|
|
1238
|
+
}
|
|
1239
|
+
}
|
|
1240
|
+
const CONTENT_TYPE$5 = "plugin::ai-sdk.note";
|
|
1241
|
+
const recallNotesSchema = zod.z.object({
|
|
1242
|
+
query: zod.z.string().optional().describe("Optional search term to filter notes by title or content"),
|
|
1243
|
+
category: zod.z.string().optional().describe('Optional category to filter by: "research", "snippet", "idea", "reference"'),
|
|
1244
|
+
tag: zod.z.string().optional().describe("Optional tag to filter by (matches within comma-separated tags)")
|
|
1245
|
+
});
|
|
1246
|
+
const recallNotesDescription = "Recall saved research notes, snippets, ideas, and references. Use this to look up previously saved notes. Without parameters, returns all notes.";
|
|
1247
|
+
async function recallNotes(strapi, params, context) {
|
|
1248
|
+
if (!context?.adminUserId) {
|
|
1249
|
+
return { success: false, notes: [], count: 0 };
|
|
1250
|
+
}
|
|
1251
|
+
try {
|
|
1252
|
+
const filters = { adminUserId: context.adminUserId };
|
|
1253
|
+
if (params.category) {
|
|
1254
|
+
filters.category = params.category;
|
|
1255
|
+
}
|
|
1256
|
+
if (params.query) {
|
|
1257
|
+
filters.$or = [
|
|
1258
|
+
{ title: { $containsi: params.query } },
|
|
1259
|
+
{ content: { $containsi: params.query } }
|
|
1260
|
+
];
|
|
1261
|
+
}
|
|
1262
|
+
if (params.tag) {
|
|
1263
|
+
filters.tags = { $containsi: params.tag };
|
|
1264
|
+
}
|
|
1265
|
+
const notes = await strapi.documents(CONTENT_TYPE$5).findMany({
|
|
1266
|
+
filters,
|
|
1267
|
+
fields: ["title", "content", "category", "tags", "source"],
|
|
1268
|
+
sort: { createdAt: "desc" }
|
|
1269
|
+
});
|
|
1270
|
+
return {
|
|
1271
|
+
success: true,
|
|
1272
|
+
notes: notes.map((n) => ({
|
|
1273
|
+
title: n.title || "",
|
|
1274
|
+
content: n.content,
|
|
1275
|
+
category: n.category,
|
|
1276
|
+
tags: n.tags || "",
|
|
1277
|
+
source: n.source || ""
|
|
1278
|
+
})),
|
|
1279
|
+
count: notes.length
|
|
1280
|
+
};
|
|
1281
|
+
} catch (error) {
|
|
1282
|
+
return { success: false, notes: [], count: 0 };
|
|
1283
|
+
}
|
|
1284
|
+
}
|
|
1098
1285
|
const listContentTypesTool = {
|
|
1099
1286
|
name: "listContentTypes",
|
|
1100
1287
|
description: listContentTypesDescription,
|
|
@@ -1143,13 +1330,24 @@ async function sanitizeInput(strapi, uid, data, auth) {
|
|
|
1143
1330
|
throw error;
|
|
1144
1331
|
}
|
|
1145
1332
|
}
|
|
1146
|
-
const
|
|
1147
|
-
name: "
|
|
1148
|
-
description:
|
|
1149
|
-
schema:
|
|
1333
|
+
const createContentTool = {
|
|
1334
|
+
name: "createContent",
|
|
1335
|
+
description: createContentDescription,
|
|
1336
|
+
schema: createContentSchema,
|
|
1337
|
+
execute: async (args, strapi) => {
|
|
1338
|
+
const sanitizedData = await sanitizeInput(strapi, args.contentType, args.data);
|
|
1339
|
+
const result = await createContent(strapi, { ...args, data: sanitizedData });
|
|
1340
|
+
const sanitizedDoc = await sanitizeOutput(strapi, args.contentType, result.document);
|
|
1341
|
+
return { ...result, document: sanitizedDoc };
|
|
1342
|
+
}
|
|
1343
|
+
};
|
|
1344
|
+
const updateContentTool = {
|
|
1345
|
+
name: "updateContent",
|
|
1346
|
+
description: updateContentDescription,
|
|
1347
|
+
schema: updateContentSchema,
|
|
1150
1348
|
execute: async (args, strapi) => {
|
|
1151
1349
|
const sanitizedData = await sanitizeInput(strapi, args.contentType, args.data);
|
|
1152
|
-
const result = await
|
|
1350
|
+
const result = await updateContent(strapi, { ...args, data: sanitizedData });
|
|
1153
1351
|
const sanitizedDoc = await sanitizeOutput(strapi, args.contentType, result.document);
|
|
1154
1352
|
return { ...result, document: sanitizedDoc };
|
|
1155
1353
|
}
|
|
@@ -1214,10 +1412,25 @@ const manageTaskTool = {
|
|
|
1214
1412
|
execute: async (args, strapi, context) => manageTask(strapi, args, context),
|
|
1215
1413
|
internal: true
|
|
1216
1414
|
};
|
|
1415
|
+
const saveNoteTool = {
|
|
1416
|
+
name: "saveNote",
|
|
1417
|
+
description: saveNoteDescription,
|
|
1418
|
+
schema: saveNoteSchema,
|
|
1419
|
+
execute: async (args, strapi, context) => saveNote(strapi, args, context),
|
|
1420
|
+
internal: true
|
|
1421
|
+
};
|
|
1422
|
+
const recallNotesTool = {
|
|
1423
|
+
name: "recallNotes",
|
|
1424
|
+
description: recallNotesDescription,
|
|
1425
|
+
schema: recallNotesSchema,
|
|
1426
|
+
execute: async (args, strapi, context) => recallNotes(strapi, args, context),
|
|
1427
|
+
internal: true
|
|
1428
|
+
};
|
|
1217
1429
|
const builtInTools = [
|
|
1218
1430
|
listContentTypesTool,
|
|
1219
1431
|
searchContentTool,
|
|
1220
|
-
|
|
1432
|
+
createContentTool,
|
|
1433
|
+
updateContentTool,
|
|
1221
1434
|
findOneContentTool,
|
|
1222
1435
|
uploadMediaTool,
|
|
1223
1436
|
sendEmailTool,
|
|
@@ -1225,12 +1438,22 @@ const builtInTools = [
|
|
|
1225
1438
|
recallMemoriesTool,
|
|
1226
1439
|
recallPublicMemoriesTool,
|
|
1227
1440
|
aggregateContentTool,
|
|
1228
|
-
manageTaskTool
|
|
1441
|
+
manageTaskTool,
|
|
1442
|
+
saveNoteTool,
|
|
1443
|
+
recallNotesTool
|
|
1229
1444
|
];
|
|
1230
1445
|
const PLUGIN_ID$2 = "ai-sdk";
|
|
1231
1446
|
const bootstrap = ({ strapi }) => {
|
|
1232
1447
|
const plugin = strapi.plugin(PLUGIN_ID$2);
|
|
1233
1448
|
const config2 = strapi.config.get(`plugin::${PLUGIN_ID$2}`);
|
|
1449
|
+
initializeProvider(strapi, plugin, config2);
|
|
1450
|
+
const registry = initializeToolRegistry(plugin);
|
|
1451
|
+
discoverPluginTools(strapi, registry);
|
|
1452
|
+
plugin.createMcpServer = () => createMcpServer(strapi);
|
|
1453
|
+
plugin.mcpSessions = /* @__PURE__ */ new Map();
|
|
1454
|
+
strapi.log.info(`[${PLUGIN_ID$2}] MCP endpoint available at: /api/${PLUGIN_ID$2}/mcp`);
|
|
1455
|
+
};
|
|
1456
|
+
function initializeProvider(strapi, plugin, config2) {
|
|
1234
1457
|
AIProvider.registerProvider("anthropic", ({ apiKey, baseURL }) => {
|
|
1235
1458
|
const provider = anthropic.createAnthropic({ apiKey, baseURL });
|
|
1236
1459
|
return (modelId) => provider(modelId);
|
|
@@ -1243,27 +1466,22 @@ const bootstrap = ({ strapi }) => {
|
|
|
1243
1466
|
} else {
|
|
1244
1467
|
strapi.log.warn(`[${PLUGIN_ID$2}] anthropicApiKey not configured, AI provider will not be available`);
|
|
1245
1468
|
}
|
|
1469
|
+
}
|
|
1470
|
+
function initializeToolRegistry(plugin) {
|
|
1246
1471
|
const toolRegistry = new ToolRegistry();
|
|
1247
1472
|
for (const tool of builtInTools) {
|
|
1248
1473
|
toolRegistry.register(tool);
|
|
1249
1474
|
}
|
|
1250
1475
|
plugin.toolRegistry = toolRegistry;
|
|
1476
|
+
return toolRegistry;
|
|
1477
|
+
}
|
|
1478
|
+
function discoverPluginTools(strapi, registry) {
|
|
1251
1479
|
const pluginNames = Object.keys(strapi.plugins).filter((n) => n !== PLUGIN_ID$2);
|
|
1252
1480
|
strapi.log.info(`[${PLUGIN_ID$2}] Scanning ${pluginNames.length} plugins for ai-tools: [${pluginNames.join(", ")}]`);
|
|
1253
1481
|
for (const [pluginName, pluginInstance] of Object.entries(strapi.plugins)) {
|
|
1254
1482
|
if (pluginName === PLUGIN_ID$2) continue;
|
|
1255
1483
|
try {
|
|
1256
|
-
|
|
1257
|
-
try {
|
|
1258
|
-
aiToolsService = strapi.plugin(pluginName)?.service?.("ai-tools");
|
|
1259
|
-
} catch {
|
|
1260
|
-
}
|
|
1261
|
-
if (!aiToolsService) {
|
|
1262
|
-
try {
|
|
1263
|
-
aiToolsService = pluginInstance.service?.("ai-tools");
|
|
1264
|
-
} catch {
|
|
1265
|
-
}
|
|
1266
|
-
}
|
|
1484
|
+
const aiToolsService = resolveAiToolsService(strapi, pluginName, pluginInstance);
|
|
1267
1485
|
if (!aiToolsService?.getTools) {
|
|
1268
1486
|
strapi.log.debug(`[${PLUGIN_ID$2}] No ai-tools service on plugin: ${pluginName}`);
|
|
1269
1487
|
continue;
|
|
@@ -1271,21 +1489,7 @@ const bootstrap = ({ strapi }) => {
|
|
|
1271
1489
|
strapi.log.info(`[${PLUGIN_ID$2}] Found ai-tools service on plugin: ${pluginName}`);
|
|
1272
1490
|
const contributed = aiToolsService.getTools();
|
|
1273
1491
|
if (!Array.isArray(contributed)) continue;
|
|
1274
|
-
|
|
1275
|
-
for (const tool of contributed) {
|
|
1276
|
-
if (!tool.name || !tool.execute || !tool.schema) {
|
|
1277
|
-
strapi.log.warn(`[${PLUGIN_ID$2}] Invalid tool from ${pluginName}: ${tool.name || "unnamed"}`);
|
|
1278
|
-
continue;
|
|
1279
|
-
}
|
|
1280
|
-
const safeName = pluginName.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
1281
|
-
const namespacedName = `${safeName}__${tool.name}`;
|
|
1282
|
-
if (toolRegistry.has(namespacedName)) {
|
|
1283
|
-
strapi.log.warn(`[${PLUGIN_ID$2}] Duplicate tool: ${namespacedName}`);
|
|
1284
|
-
continue;
|
|
1285
|
-
}
|
|
1286
|
-
toolRegistry.register({ ...tool, name: namespacedName });
|
|
1287
|
-
count++;
|
|
1288
|
-
}
|
|
1492
|
+
const count = registerContributedTools(strapi, registry, pluginName, contributed);
|
|
1289
1493
|
if (count > 0) {
|
|
1290
1494
|
strapi.log.info(`[${PLUGIN_ID$2}] Registered ${count} tools from plugin: ${pluginName}`);
|
|
1291
1495
|
}
|
|
@@ -1293,10 +1497,38 @@ const bootstrap = ({ strapi }) => {
|
|
|
1293
1497
|
strapi.log.warn(`[${PLUGIN_ID$2}] Tool discovery failed for ${pluginName}: ${err}`);
|
|
1294
1498
|
}
|
|
1295
1499
|
}
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1500
|
+
}
|
|
1501
|
+
function registerContributedTools(strapi, registry, pluginName, tools) {
|
|
1502
|
+
const safeName = pluginName.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
1503
|
+
let count = 0;
|
|
1504
|
+
for (const tool of tools) {
|
|
1505
|
+
if (!tool.name || !tool.execute || !tool.schema) {
|
|
1506
|
+
strapi.log.warn(`[${PLUGIN_ID$2}] Invalid tool from ${pluginName}: ${tool.name || "unnamed"}`);
|
|
1507
|
+
continue;
|
|
1508
|
+
}
|
|
1509
|
+
const namespacedName = `${safeName}__${tool.name}`;
|
|
1510
|
+
if (registry.has(namespacedName)) {
|
|
1511
|
+
strapi.log.warn(`[${PLUGIN_ID$2}] Duplicate tool: ${namespacedName}`);
|
|
1512
|
+
continue;
|
|
1513
|
+
}
|
|
1514
|
+
registry.register({ ...tool, name: namespacedName });
|
|
1515
|
+
count++;
|
|
1516
|
+
}
|
|
1517
|
+
return count;
|
|
1518
|
+
}
|
|
1519
|
+
function resolveAiToolsService(strapi, pluginName, pluginInstance) {
|
|
1520
|
+
try {
|
|
1521
|
+
const svc = strapi.plugin(pluginName)?.service?.("ai-tools");
|
|
1522
|
+
if (svc) return svc;
|
|
1523
|
+
} catch {
|
|
1524
|
+
}
|
|
1525
|
+
try {
|
|
1526
|
+
const svc = pluginInstance.service?.("ai-tools");
|
|
1527
|
+
if (svc) return svc;
|
|
1528
|
+
} catch {
|
|
1529
|
+
}
|
|
1530
|
+
return null;
|
|
1531
|
+
}
|
|
1300
1532
|
const PLUGIN_ID$1 = "ai-sdk";
|
|
1301
1533
|
async function closeSession(strapi, sessionId, session) {
|
|
1302
1534
|
try {
|
|
@@ -1379,17 +1611,17 @@ const config = {
|
|
|
1379
1611
|
}
|
|
1380
1612
|
}
|
|
1381
1613
|
};
|
|
1382
|
-
const kind$
|
|
1383
|
-
const collectionName$
|
|
1384
|
-
const info$
|
|
1614
|
+
const kind$4 = "collectionType";
|
|
1615
|
+
const collectionName$4 = "ai_sdk_conversations";
|
|
1616
|
+
const info$4 = {
|
|
1385
1617
|
singularName: "conversation",
|
|
1386
1618
|
pluralName: "conversations",
|
|
1387
1619
|
displayName: "AI Conversation"
|
|
1388
1620
|
};
|
|
1389
|
-
const options$
|
|
1621
|
+
const options$4 = {
|
|
1390
1622
|
draftAndPublish: false
|
|
1391
1623
|
};
|
|
1392
|
-
const pluginOptions$
|
|
1624
|
+
const pluginOptions$4 = {
|
|
1393
1625
|
"content-manager": {
|
|
1394
1626
|
visible: false
|
|
1395
1627
|
},
|
|
@@ -1397,7 +1629,7 @@ const pluginOptions$3 = {
|
|
|
1397
1629
|
visible: false
|
|
1398
1630
|
}
|
|
1399
1631
|
};
|
|
1400
|
-
const attributes$
|
|
1632
|
+
const attributes$4 = {
|
|
1401
1633
|
title: {
|
|
1402
1634
|
type: "string",
|
|
1403
1635
|
required: true,
|
|
@@ -1412,26 +1644,26 @@ const attributes$3 = {
|
|
|
1412
1644
|
required: true
|
|
1413
1645
|
}
|
|
1414
1646
|
};
|
|
1415
|
-
const schema$
|
|
1416
|
-
kind: kind$
|
|
1417
|
-
collectionName: collectionName$
|
|
1418
|
-
info: info$
|
|
1419
|
-
options: options$
|
|
1420
|
-
pluginOptions: pluginOptions$
|
|
1421
|
-
attributes: attributes$
|
|
1647
|
+
const schema$4 = {
|
|
1648
|
+
kind: kind$4,
|
|
1649
|
+
collectionName: collectionName$4,
|
|
1650
|
+
info: info$4,
|
|
1651
|
+
options: options$4,
|
|
1652
|
+
pluginOptions: pluginOptions$4,
|
|
1653
|
+
attributes: attributes$4
|
|
1422
1654
|
};
|
|
1423
|
-
const conversation = { schema: schema$
|
|
1424
|
-
const kind$
|
|
1425
|
-
const collectionName$
|
|
1426
|
-
const info$
|
|
1655
|
+
const conversation = { schema: schema$4 };
|
|
1656
|
+
const kind$3 = "collectionType";
|
|
1657
|
+
const collectionName$3 = "ai_sdk_memories";
|
|
1658
|
+
const info$3 = {
|
|
1427
1659
|
singularName: "memory",
|
|
1428
1660
|
pluralName: "memories",
|
|
1429
1661
|
displayName: "AI Memory"
|
|
1430
1662
|
};
|
|
1431
|
-
const options$
|
|
1663
|
+
const options$3 = {
|
|
1432
1664
|
draftAndPublish: false
|
|
1433
1665
|
};
|
|
1434
|
-
const pluginOptions$
|
|
1666
|
+
const pluginOptions$3 = {
|
|
1435
1667
|
"content-manager": {
|
|
1436
1668
|
visible: false
|
|
1437
1669
|
},
|
|
@@ -1439,9 +1671,9 @@ const pluginOptions$2 = {
|
|
|
1439
1671
|
visible: false
|
|
1440
1672
|
}
|
|
1441
1673
|
};
|
|
1442
|
-
const attributes$
|
|
1674
|
+
const attributes$3 = {
|
|
1443
1675
|
content: {
|
|
1444
|
-
type: "
|
|
1676
|
+
type: "richtext",
|
|
1445
1677
|
required: true
|
|
1446
1678
|
},
|
|
1447
1679
|
category: {
|
|
@@ -1459,26 +1691,26 @@ const attributes$2 = {
|
|
|
1459
1691
|
required: true
|
|
1460
1692
|
}
|
|
1461
1693
|
};
|
|
1462
|
-
const schema$
|
|
1463
|
-
kind: kind$
|
|
1464
|
-
collectionName: collectionName$
|
|
1465
|
-
info: info$
|
|
1466
|
-
options: options$
|
|
1467
|
-
pluginOptions: pluginOptions$
|
|
1468
|
-
attributes: attributes$
|
|
1694
|
+
const schema$3 = {
|
|
1695
|
+
kind: kind$3,
|
|
1696
|
+
collectionName: collectionName$3,
|
|
1697
|
+
info: info$3,
|
|
1698
|
+
options: options$3,
|
|
1699
|
+
pluginOptions: pluginOptions$3,
|
|
1700
|
+
attributes: attributes$3
|
|
1469
1701
|
};
|
|
1470
|
-
const memory = { schema: schema$
|
|
1471
|
-
const kind$
|
|
1472
|
-
const collectionName$
|
|
1473
|
-
const info$
|
|
1702
|
+
const memory = { schema: schema$3 };
|
|
1703
|
+
const kind$2 = "collectionType";
|
|
1704
|
+
const collectionName$2 = "ai_sdk_public_memories";
|
|
1705
|
+
const info$2 = {
|
|
1474
1706
|
singularName: "public-memory",
|
|
1475
1707
|
pluralName: "public-memories",
|
|
1476
1708
|
displayName: "AI Public Memory"
|
|
1477
1709
|
};
|
|
1478
|
-
const options$
|
|
1710
|
+
const options$2 = {
|
|
1479
1711
|
draftAndPublish: false
|
|
1480
1712
|
};
|
|
1481
|
-
const pluginOptions$
|
|
1713
|
+
const pluginOptions$2 = {
|
|
1482
1714
|
"content-manager": {
|
|
1483
1715
|
visible: false
|
|
1484
1716
|
},
|
|
@@ -1486,7 +1718,7 @@ const pluginOptions$1 = {
|
|
|
1486
1718
|
visible: false
|
|
1487
1719
|
}
|
|
1488
1720
|
};
|
|
1489
|
-
const attributes$
|
|
1721
|
+
const attributes$2 = {
|
|
1490
1722
|
content: {
|
|
1491
1723
|
type: "text",
|
|
1492
1724
|
required: true
|
|
@@ -1502,26 +1734,26 @@ const attributes$1 = {
|
|
|
1502
1734
|
"default": "general"
|
|
1503
1735
|
}
|
|
1504
1736
|
};
|
|
1505
|
-
const schema$
|
|
1506
|
-
kind: kind$
|
|
1507
|
-
collectionName: collectionName$
|
|
1508
|
-
info: info$
|
|
1509
|
-
options: options$
|
|
1510
|
-
pluginOptions: pluginOptions$
|
|
1511
|
-
attributes: attributes$
|
|
1737
|
+
const schema$2 = {
|
|
1738
|
+
kind: kind$2,
|
|
1739
|
+
collectionName: collectionName$2,
|
|
1740
|
+
info: info$2,
|
|
1741
|
+
options: options$2,
|
|
1742
|
+
pluginOptions: pluginOptions$2,
|
|
1743
|
+
attributes: attributes$2
|
|
1512
1744
|
};
|
|
1513
|
-
const publicMemory = { schema: schema$
|
|
1514
|
-
const kind = "collectionType";
|
|
1515
|
-
const collectionName = "ai_sdk_tasks";
|
|
1516
|
-
const info = {
|
|
1745
|
+
const publicMemory = { schema: schema$2 };
|
|
1746
|
+
const kind$1 = "collectionType";
|
|
1747
|
+
const collectionName$1 = "ai_sdk_tasks";
|
|
1748
|
+
const info$1 = {
|
|
1517
1749
|
singularName: "task",
|
|
1518
1750
|
pluralName: "tasks",
|
|
1519
1751
|
displayName: "AI Task"
|
|
1520
1752
|
};
|
|
1521
|
-
const options = {
|
|
1753
|
+
const options$1 = {
|
|
1522
1754
|
draftAndPublish: false
|
|
1523
1755
|
};
|
|
1524
|
-
const pluginOptions = {
|
|
1756
|
+
const pluginOptions$1 = {
|
|
1525
1757
|
"content-manager": {
|
|
1526
1758
|
visible: true
|
|
1527
1759
|
},
|
|
@@ -1529,7 +1761,7 @@ const pluginOptions = {
|
|
|
1529
1761
|
visible: false
|
|
1530
1762
|
}
|
|
1531
1763
|
};
|
|
1532
|
-
const attributes = {
|
|
1764
|
+
const attributes$1 = {
|
|
1533
1765
|
title: {
|
|
1534
1766
|
type: "string",
|
|
1535
1767
|
required: true
|
|
@@ -1574,6 +1806,62 @@ const attributes = {
|
|
|
1574
1806
|
required: true
|
|
1575
1807
|
}
|
|
1576
1808
|
};
|
|
1809
|
+
const schema$1 = {
|
|
1810
|
+
kind: kind$1,
|
|
1811
|
+
collectionName: collectionName$1,
|
|
1812
|
+
info: info$1,
|
|
1813
|
+
options: options$1,
|
|
1814
|
+
pluginOptions: pluginOptions$1,
|
|
1815
|
+
attributes: attributes$1
|
|
1816
|
+
};
|
|
1817
|
+
const task = { schema: schema$1 };
|
|
1818
|
+
const kind = "collectionType";
|
|
1819
|
+
const collectionName = "ai_sdk_notes";
|
|
1820
|
+
const info = {
|
|
1821
|
+
singularName: "note",
|
|
1822
|
+
pluralName: "notes",
|
|
1823
|
+
displayName: "AI Note"
|
|
1824
|
+
};
|
|
1825
|
+
const options = {
|
|
1826
|
+
draftAndPublish: false
|
|
1827
|
+
};
|
|
1828
|
+
const pluginOptions = {
|
|
1829
|
+
"content-manager": {
|
|
1830
|
+
visible: false
|
|
1831
|
+
},
|
|
1832
|
+
"content-type-builder": {
|
|
1833
|
+
visible: false
|
|
1834
|
+
}
|
|
1835
|
+
};
|
|
1836
|
+
const attributes = {
|
|
1837
|
+
title: {
|
|
1838
|
+
type: "string"
|
|
1839
|
+
},
|
|
1840
|
+
content: {
|
|
1841
|
+
type: "richtext",
|
|
1842
|
+
required: true
|
|
1843
|
+
},
|
|
1844
|
+
category: {
|
|
1845
|
+
type: "enumeration",
|
|
1846
|
+
"enum": [
|
|
1847
|
+
"research",
|
|
1848
|
+
"snippet",
|
|
1849
|
+
"idea",
|
|
1850
|
+
"reference"
|
|
1851
|
+
],
|
|
1852
|
+
"default": "research"
|
|
1853
|
+
},
|
|
1854
|
+
tags: {
|
|
1855
|
+
type: "text"
|
|
1856
|
+
},
|
|
1857
|
+
source: {
|
|
1858
|
+
type: "string"
|
|
1859
|
+
},
|
|
1860
|
+
adminUserId: {
|
|
1861
|
+
type: "integer",
|
|
1862
|
+
required: true
|
|
1863
|
+
}
|
|
1864
|
+
};
|
|
1577
1865
|
const schema = {
|
|
1578
1866
|
kind,
|
|
1579
1867
|
collectionName,
|
|
@@ -1582,8 +1870,8 @@ const schema = {
|
|
|
1582
1870
|
pluginOptions,
|
|
1583
1871
|
attributes
|
|
1584
1872
|
};
|
|
1585
|
-
const
|
|
1586
|
-
const contentTypes = { conversation, memory, "public-memory": publicMemory, task };
|
|
1873
|
+
const note = { schema };
|
|
1874
|
+
const contentTypes = { conversation, memory, "public-memory": publicMemory, task, note };
|
|
1587
1875
|
function getService(strapi, ctx) {
|
|
1588
1876
|
const service2 = strapi.plugin("ai-sdk").service("service");
|
|
1589
1877
|
if (!service2.isInitialized()) {
|
|
@@ -1899,20 +2187,20 @@ const mcpController = ({ strapi }) => {
|
|
|
1899
2187
|
}
|
|
1900
2188
|
};
|
|
1901
2189
|
};
|
|
1902
|
-
const CONTENT_TYPE$
|
|
1903
|
-
function getAdminUserId$
|
|
2190
|
+
const CONTENT_TYPE$4 = "plugin::ai-sdk.conversation";
|
|
2191
|
+
function getAdminUserId$3(ctx) {
|
|
1904
2192
|
const id = ctx.state?.user?.id;
|
|
1905
2193
|
return typeof id === "number" ? id : null;
|
|
1906
2194
|
}
|
|
1907
2195
|
const conversationController = ({ strapi }) => ({
|
|
1908
2196
|
async find(ctx) {
|
|
1909
|
-
const adminUserId = getAdminUserId$
|
|
2197
|
+
const adminUserId = getAdminUserId$3(ctx);
|
|
1910
2198
|
if (!adminUserId) {
|
|
1911
2199
|
ctx.status = 401;
|
|
1912
2200
|
ctx.body = { error: "Unauthorized" };
|
|
1913
2201
|
return;
|
|
1914
2202
|
}
|
|
1915
|
-
const conversations = await strapi.documents(CONTENT_TYPE$
|
|
2203
|
+
const conversations = await strapi.documents(CONTENT_TYPE$4).findMany({
|
|
1916
2204
|
filters: { adminUserId },
|
|
1917
2205
|
fields: ["title", "createdAt", "updatedAt"],
|
|
1918
2206
|
sort: { updatedAt: "desc" }
|
|
@@ -1920,14 +2208,14 @@ const conversationController = ({ strapi }) => ({
|
|
|
1920
2208
|
ctx.body = { data: conversations };
|
|
1921
2209
|
},
|
|
1922
2210
|
async findOne(ctx) {
|
|
1923
|
-
const adminUserId = getAdminUserId$
|
|
2211
|
+
const adminUserId = getAdminUserId$3(ctx);
|
|
1924
2212
|
if (!adminUserId) {
|
|
1925
2213
|
ctx.status = 401;
|
|
1926
2214
|
ctx.body = { error: "Unauthorized" };
|
|
1927
2215
|
return;
|
|
1928
2216
|
}
|
|
1929
2217
|
const { id } = ctx.params;
|
|
1930
|
-
const conversation2 = await strapi.documents(CONTENT_TYPE$
|
|
2218
|
+
const conversation2 = await strapi.documents(CONTENT_TYPE$4).findOne({
|
|
1931
2219
|
documentId: id
|
|
1932
2220
|
});
|
|
1933
2221
|
if (!conversation2 || conversation2.adminUserId !== adminUserId) {
|
|
@@ -1938,14 +2226,14 @@ const conversationController = ({ strapi }) => ({
|
|
|
1938
2226
|
ctx.body = { data: conversation2 };
|
|
1939
2227
|
},
|
|
1940
2228
|
async create(ctx) {
|
|
1941
|
-
const adminUserId = getAdminUserId$
|
|
2229
|
+
const adminUserId = getAdminUserId$3(ctx);
|
|
1942
2230
|
if (!adminUserId) {
|
|
1943
2231
|
ctx.status = 401;
|
|
1944
2232
|
ctx.body = { error: "Unauthorized" };
|
|
1945
2233
|
return;
|
|
1946
2234
|
}
|
|
1947
2235
|
const { title, messages } = ctx.request.body;
|
|
1948
|
-
const conversation2 = await strapi.documents(CONTENT_TYPE$
|
|
2236
|
+
const conversation2 = await strapi.documents(CONTENT_TYPE$4).create({
|
|
1949
2237
|
data: {
|
|
1950
2238
|
title: title || "New conversation",
|
|
1951
2239
|
messages: messages || [],
|
|
@@ -1956,14 +2244,14 @@ const conversationController = ({ strapi }) => ({
|
|
|
1956
2244
|
ctx.body = { data: conversation2 };
|
|
1957
2245
|
},
|
|
1958
2246
|
async update(ctx) {
|
|
1959
|
-
const adminUserId = getAdminUserId$
|
|
2247
|
+
const adminUserId = getAdminUserId$3(ctx);
|
|
1960
2248
|
if (!adminUserId) {
|
|
1961
2249
|
ctx.status = 401;
|
|
1962
2250
|
ctx.body = { error: "Unauthorized" };
|
|
1963
2251
|
return;
|
|
1964
2252
|
}
|
|
1965
2253
|
const { id } = ctx.params;
|
|
1966
|
-
const existing = await strapi.documents(CONTENT_TYPE$
|
|
2254
|
+
const existing = await strapi.documents(CONTENT_TYPE$4).findOne({
|
|
1967
2255
|
documentId: id
|
|
1968
2256
|
});
|
|
1969
2257
|
if (!existing || existing.adminUserId !== adminUserId) {
|
|
@@ -1975,21 +2263,21 @@ const conversationController = ({ strapi }) => ({
|
|
|
1975
2263
|
const data = {};
|
|
1976
2264
|
if (title !== void 0) data.title = title;
|
|
1977
2265
|
if (messages !== void 0) data.messages = messages;
|
|
1978
|
-
const conversation2 = await strapi.documents(CONTENT_TYPE$
|
|
2266
|
+
const conversation2 = await strapi.documents(CONTENT_TYPE$4).update({
|
|
1979
2267
|
documentId: id,
|
|
1980
2268
|
data
|
|
1981
2269
|
});
|
|
1982
2270
|
ctx.body = { data: conversation2 };
|
|
1983
2271
|
},
|
|
1984
2272
|
async delete(ctx) {
|
|
1985
|
-
const adminUserId = getAdminUserId$
|
|
2273
|
+
const adminUserId = getAdminUserId$3(ctx);
|
|
1986
2274
|
if (!adminUserId) {
|
|
1987
2275
|
ctx.status = 401;
|
|
1988
2276
|
ctx.body = { error: "Unauthorized" };
|
|
1989
2277
|
return;
|
|
1990
2278
|
}
|
|
1991
2279
|
const { id } = ctx.params;
|
|
1992
|
-
const existing = await strapi.documents(CONTENT_TYPE$
|
|
2280
|
+
const existing = await strapi.documents(CONTENT_TYPE$4).findOne({
|
|
1993
2281
|
documentId: id
|
|
1994
2282
|
});
|
|
1995
2283
|
if (!existing || existing.adminUserId !== adminUserId) {
|
|
@@ -1997,25 +2285,25 @@ const conversationController = ({ strapi }) => ({
|
|
|
1997
2285
|
ctx.body = { error: "Conversation not found" };
|
|
1998
2286
|
return;
|
|
1999
2287
|
}
|
|
2000
|
-
await strapi.documents(CONTENT_TYPE$
|
|
2288
|
+
await strapi.documents(CONTENT_TYPE$4).delete({ documentId: id });
|
|
2001
2289
|
ctx.status = 200;
|
|
2002
2290
|
ctx.body = { data: { documentId: id } };
|
|
2003
2291
|
}
|
|
2004
2292
|
});
|
|
2005
|
-
const CONTENT_TYPE$
|
|
2006
|
-
function getAdminUserId$
|
|
2293
|
+
const CONTENT_TYPE$3 = "plugin::ai-sdk.memory";
|
|
2294
|
+
function getAdminUserId$2(ctx) {
|
|
2007
2295
|
const id = ctx.state?.user?.id;
|
|
2008
2296
|
return typeof id === "number" ? id : null;
|
|
2009
2297
|
}
|
|
2010
2298
|
const memoryController = ({ strapi }) => ({
|
|
2011
2299
|
async find(ctx) {
|
|
2012
|
-
const adminUserId = getAdminUserId$
|
|
2300
|
+
const adminUserId = getAdminUserId$2(ctx);
|
|
2013
2301
|
if (!adminUserId) {
|
|
2014
2302
|
ctx.status = 401;
|
|
2015
2303
|
ctx.body = { error: "Unauthorized" };
|
|
2016
2304
|
return;
|
|
2017
2305
|
}
|
|
2018
|
-
const memories = await strapi.documents(CONTENT_TYPE$
|
|
2306
|
+
const memories = await strapi.documents(CONTENT_TYPE$3).findMany({
|
|
2019
2307
|
filters: { adminUserId },
|
|
2020
2308
|
fields: ["content", "category", "createdAt"],
|
|
2021
2309
|
sort: { createdAt: "desc" }
|
|
@@ -2023,7 +2311,7 @@ const memoryController = ({ strapi }) => ({
|
|
|
2023
2311
|
ctx.body = { data: memories };
|
|
2024
2312
|
},
|
|
2025
2313
|
async create(ctx) {
|
|
2026
|
-
const adminUserId = getAdminUserId$
|
|
2314
|
+
const adminUserId = getAdminUserId$2(ctx);
|
|
2027
2315
|
if (!adminUserId) {
|
|
2028
2316
|
ctx.status = 401;
|
|
2029
2317
|
ctx.body = { error: "Unauthorized" };
|
|
@@ -2035,7 +2323,7 @@ const memoryController = ({ strapi }) => ({
|
|
|
2035
2323
|
ctx.body = { error: "content is required" };
|
|
2036
2324
|
return;
|
|
2037
2325
|
}
|
|
2038
|
-
const memory2 = await strapi.documents(CONTENT_TYPE$
|
|
2326
|
+
const memory2 = await strapi.documents(CONTENT_TYPE$3).create({
|
|
2039
2327
|
data: {
|
|
2040
2328
|
content,
|
|
2041
2329
|
category: category || "general",
|
|
@@ -2046,14 +2334,14 @@ const memoryController = ({ strapi }) => ({
|
|
|
2046
2334
|
ctx.body = { data: memory2 };
|
|
2047
2335
|
},
|
|
2048
2336
|
async update(ctx) {
|
|
2049
|
-
const adminUserId = getAdminUserId$
|
|
2337
|
+
const adminUserId = getAdminUserId$2(ctx);
|
|
2050
2338
|
if (!adminUserId) {
|
|
2051
2339
|
ctx.status = 401;
|
|
2052
2340
|
ctx.body = { error: "Unauthorized" };
|
|
2053
2341
|
return;
|
|
2054
2342
|
}
|
|
2055
2343
|
const { id } = ctx.params;
|
|
2056
|
-
const existing = await strapi.documents(CONTENT_TYPE$
|
|
2344
|
+
const existing = await strapi.documents(CONTENT_TYPE$3).findOne({
|
|
2057
2345
|
documentId: id
|
|
2058
2346
|
});
|
|
2059
2347
|
if (!existing || existing.adminUserId !== adminUserId) {
|
|
@@ -2065,21 +2353,21 @@ const memoryController = ({ strapi }) => ({
|
|
|
2065
2353
|
const data = {};
|
|
2066
2354
|
if (content !== void 0) data.content = content;
|
|
2067
2355
|
if (category !== void 0) data.category = category;
|
|
2068
|
-
const memory2 = await strapi.documents(CONTENT_TYPE$
|
|
2356
|
+
const memory2 = await strapi.documents(CONTENT_TYPE$3).update({
|
|
2069
2357
|
documentId: id,
|
|
2070
2358
|
data
|
|
2071
2359
|
});
|
|
2072
2360
|
ctx.body = { data: memory2 };
|
|
2073
2361
|
},
|
|
2074
2362
|
async delete(ctx) {
|
|
2075
|
-
const adminUserId = getAdminUserId$
|
|
2363
|
+
const adminUserId = getAdminUserId$2(ctx);
|
|
2076
2364
|
if (!adminUserId) {
|
|
2077
2365
|
ctx.status = 401;
|
|
2078
2366
|
ctx.body = { error: "Unauthorized" };
|
|
2079
2367
|
return;
|
|
2080
2368
|
}
|
|
2081
2369
|
const { id } = ctx.params;
|
|
2082
|
-
const existing = await strapi.documents(CONTENT_TYPE$
|
|
2370
|
+
const existing = await strapi.documents(CONTENT_TYPE$3).findOne({
|
|
2083
2371
|
documentId: id
|
|
2084
2372
|
});
|
|
2085
2373
|
if (!existing || existing.adminUserId !== adminUserId) {
|
|
@@ -2087,15 +2375,15 @@ const memoryController = ({ strapi }) => ({
|
|
|
2087
2375
|
ctx.body = { error: "Memory not found" };
|
|
2088
2376
|
return;
|
|
2089
2377
|
}
|
|
2090
|
-
await strapi.documents(CONTENT_TYPE$
|
|
2378
|
+
await strapi.documents(CONTENT_TYPE$3).delete({ documentId: id });
|
|
2091
2379
|
ctx.status = 200;
|
|
2092
2380
|
ctx.body = { data: { documentId: id } };
|
|
2093
2381
|
}
|
|
2094
2382
|
});
|
|
2095
|
-
const CONTENT_TYPE$
|
|
2383
|
+
const CONTENT_TYPE$2 = "plugin::ai-sdk.public-memory";
|
|
2096
2384
|
const publicMemoryController = ({ strapi }) => ({
|
|
2097
2385
|
async find(ctx) {
|
|
2098
|
-
const memories = await strapi.documents(CONTENT_TYPE$
|
|
2386
|
+
const memories = await strapi.documents(CONTENT_TYPE$2).findMany({
|
|
2099
2387
|
fields: ["content", "category", "createdAt"],
|
|
2100
2388
|
sort: { createdAt: "desc" }
|
|
2101
2389
|
});
|
|
@@ -2108,7 +2396,7 @@ const publicMemoryController = ({ strapi }) => ({
|
|
|
2108
2396
|
ctx.body = { error: "content is required" };
|
|
2109
2397
|
return;
|
|
2110
2398
|
}
|
|
2111
|
-
const memory2 = await strapi.documents(CONTENT_TYPE$
|
|
2399
|
+
const memory2 = await strapi.documents(CONTENT_TYPE$2).create({
|
|
2112
2400
|
data: { content, category: category || "general" }
|
|
2113
2401
|
});
|
|
2114
2402
|
ctx.status = 201;
|
|
@@ -2116,7 +2404,7 @@ const publicMemoryController = ({ strapi }) => ({
|
|
|
2116
2404
|
},
|
|
2117
2405
|
async update(ctx) {
|
|
2118
2406
|
const { id } = ctx.params;
|
|
2119
|
-
const existing = await strapi.documents(CONTENT_TYPE$
|
|
2407
|
+
const existing = await strapi.documents(CONTENT_TYPE$2).findOne({ documentId: id });
|
|
2120
2408
|
if (!existing) {
|
|
2121
2409
|
ctx.status = 404;
|
|
2122
2410
|
ctx.body = { error: "Public memory not found" };
|
|
@@ -2126,7 +2414,7 @@ const publicMemoryController = ({ strapi }) => ({
|
|
|
2126
2414
|
const data = {};
|
|
2127
2415
|
if (content !== void 0) data.content = content;
|
|
2128
2416
|
if (category !== void 0) data.category = category;
|
|
2129
|
-
const memory2 = await strapi.documents(CONTENT_TYPE$
|
|
2417
|
+
const memory2 = await strapi.documents(CONTENT_TYPE$2).update({
|
|
2130
2418
|
documentId: id,
|
|
2131
2419
|
data
|
|
2132
2420
|
});
|
|
@@ -2134,45 +2422,45 @@ const publicMemoryController = ({ strapi }) => ({
|
|
|
2134
2422
|
},
|
|
2135
2423
|
async delete(ctx) {
|
|
2136
2424
|
const { id } = ctx.params;
|
|
2137
|
-
const existing = await strapi.documents(CONTENT_TYPE$
|
|
2425
|
+
const existing = await strapi.documents(CONTENT_TYPE$2).findOne({ documentId: id });
|
|
2138
2426
|
if (!existing) {
|
|
2139
2427
|
ctx.status = 404;
|
|
2140
2428
|
ctx.body = { error: "Public memory not found" };
|
|
2141
2429
|
return;
|
|
2142
2430
|
}
|
|
2143
|
-
await strapi.documents(CONTENT_TYPE$
|
|
2431
|
+
await strapi.documents(CONTENT_TYPE$2).delete({ documentId: id });
|
|
2144
2432
|
ctx.status = 200;
|
|
2145
2433
|
ctx.body = { data: { documentId: id } };
|
|
2146
2434
|
}
|
|
2147
2435
|
});
|
|
2148
|
-
const CONTENT_TYPE = "plugin::ai-sdk.task";
|
|
2149
|
-
function getAdminUserId(ctx) {
|
|
2436
|
+
const CONTENT_TYPE$1 = "plugin::ai-sdk.task";
|
|
2437
|
+
function getAdminUserId$1(ctx) {
|
|
2150
2438
|
const id = ctx.state?.user?.id;
|
|
2151
2439
|
return typeof id === "number" ? id : null;
|
|
2152
2440
|
}
|
|
2153
2441
|
const taskController = ({ strapi }) => ({
|
|
2154
2442
|
async find(ctx) {
|
|
2155
|
-
const adminUserId = getAdminUserId(ctx);
|
|
2443
|
+
const adminUserId = getAdminUserId$1(ctx);
|
|
2156
2444
|
if (!adminUserId) {
|
|
2157
2445
|
ctx.status = 401;
|
|
2158
2446
|
ctx.body = { error: "Unauthorized" };
|
|
2159
2447
|
return;
|
|
2160
2448
|
}
|
|
2161
|
-
const tasks = await strapi.documents(CONTENT_TYPE).findMany({
|
|
2449
|
+
const tasks = await strapi.documents(CONTENT_TYPE$1).findMany({
|
|
2162
2450
|
filters: { adminUserId },
|
|
2163
2451
|
sort: { createdAt: "desc" }
|
|
2164
2452
|
});
|
|
2165
2453
|
ctx.body = { data: tasks };
|
|
2166
2454
|
},
|
|
2167
2455
|
async create(ctx) {
|
|
2168
|
-
const adminUserId = getAdminUserId(ctx);
|
|
2456
|
+
const adminUserId = getAdminUserId$1(ctx);
|
|
2169
2457
|
if (!adminUserId) {
|
|
2170
2458
|
ctx.status = 401;
|
|
2171
2459
|
ctx.body = { error: "Unauthorized" };
|
|
2172
2460
|
return;
|
|
2173
2461
|
}
|
|
2174
2462
|
const body = ctx.request.body;
|
|
2175
|
-
const task2 = await strapi.documents(CONTENT_TYPE).create({
|
|
2463
|
+
const task2 = await strapi.documents(CONTENT_TYPE$1).create({
|
|
2176
2464
|
data: {
|
|
2177
2465
|
title: body.title,
|
|
2178
2466
|
description: body.description,
|
|
@@ -2189,14 +2477,14 @@ const taskController = ({ strapi }) => ({
|
|
|
2189
2477
|
ctx.body = { data: task2 };
|
|
2190
2478
|
},
|
|
2191
2479
|
async update(ctx) {
|
|
2192
|
-
const adminUserId = getAdminUserId(ctx);
|
|
2480
|
+
const adminUserId = getAdminUserId$1(ctx);
|
|
2193
2481
|
if (!adminUserId) {
|
|
2194
2482
|
ctx.status = 401;
|
|
2195
2483
|
ctx.body = { error: "Unauthorized" };
|
|
2196
2484
|
return;
|
|
2197
2485
|
}
|
|
2198
2486
|
const { id } = ctx.params;
|
|
2199
|
-
const existing = await strapi.documents(CONTENT_TYPE).findOne({
|
|
2487
|
+
const existing = await strapi.documents(CONTENT_TYPE$1).findOne({
|
|
2200
2488
|
documentId: id
|
|
2201
2489
|
});
|
|
2202
2490
|
if (!existing || existing.adminUserId !== adminUserId) {
|
|
@@ -2209,13 +2497,80 @@ const taskController = ({ strapi }) => ({
|
|
|
2209
2497
|
for (const key of ["title", "description", "content", "done", "priority", "consequence", "impact", "dueDate"]) {
|
|
2210
2498
|
if (body[key] !== void 0) data[key] = body[key];
|
|
2211
2499
|
}
|
|
2212
|
-
const task2 = await strapi.documents(CONTENT_TYPE).update({
|
|
2500
|
+
const task2 = await strapi.documents(CONTENT_TYPE$1).update({
|
|
2213
2501
|
documentId: id,
|
|
2214
2502
|
data
|
|
2215
2503
|
});
|
|
2216
2504
|
ctx.body = { data: task2 };
|
|
2217
2505
|
},
|
|
2218
2506
|
async delete(ctx) {
|
|
2507
|
+
const adminUserId = getAdminUserId$1(ctx);
|
|
2508
|
+
if (!adminUserId) {
|
|
2509
|
+
ctx.status = 401;
|
|
2510
|
+
ctx.body = { error: "Unauthorized" };
|
|
2511
|
+
return;
|
|
2512
|
+
}
|
|
2513
|
+
const { id } = ctx.params;
|
|
2514
|
+
const existing = await strapi.documents(CONTENT_TYPE$1).findOne({
|
|
2515
|
+
documentId: id
|
|
2516
|
+
});
|
|
2517
|
+
if (!existing || existing.adminUserId !== adminUserId) {
|
|
2518
|
+
ctx.status = 404;
|
|
2519
|
+
ctx.body = { error: "Task not found" };
|
|
2520
|
+
return;
|
|
2521
|
+
}
|
|
2522
|
+
await strapi.documents(CONTENT_TYPE$1).delete({ documentId: id });
|
|
2523
|
+
ctx.status = 200;
|
|
2524
|
+
ctx.body = { data: { documentId: id } };
|
|
2525
|
+
}
|
|
2526
|
+
});
|
|
2527
|
+
const CONTENT_TYPE = "plugin::ai-sdk.note";
|
|
2528
|
+
function getAdminUserId(ctx) {
|
|
2529
|
+
const id = ctx.state?.user?.id;
|
|
2530
|
+
return typeof id === "number" ? id : null;
|
|
2531
|
+
}
|
|
2532
|
+
const noteController = ({ strapi }) => ({
|
|
2533
|
+
async find(ctx) {
|
|
2534
|
+
const adminUserId = getAdminUserId(ctx);
|
|
2535
|
+
if (!adminUserId) {
|
|
2536
|
+
ctx.status = 401;
|
|
2537
|
+
ctx.body = { error: "Unauthorized" };
|
|
2538
|
+
return;
|
|
2539
|
+
}
|
|
2540
|
+
const notes = await strapi.documents(CONTENT_TYPE).findMany({
|
|
2541
|
+
filters: { adminUserId },
|
|
2542
|
+
fields: ["title", "content", "category", "tags", "source", "createdAt"],
|
|
2543
|
+
sort: { createdAt: "desc" }
|
|
2544
|
+
});
|
|
2545
|
+
ctx.body = { data: notes };
|
|
2546
|
+
},
|
|
2547
|
+
async create(ctx) {
|
|
2548
|
+
const adminUserId = getAdminUserId(ctx);
|
|
2549
|
+
if (!adminUserId) {
|
|
2550
|
+
ctx.status = 401;
|
|
2551
|
+
ctx.body = { error: "Unauthorized" };
|
|
2552
|
+
return;
|
|
2553
|
+
}
|
|
2554
|
+
const { title, content, category, tags, source } = ctx.request.body;
|
|
2555
|
+
if (!content || typeof content !== "string") {
|
|
2556
|
+
ctx.status = 400;
|
|
2557
|
+
ctx.body = { error: "content is required" };
|
|
2558
|
+
return;
|
|
2559
|
+
}
|
|
2560
|
+
const note2 = await strapi.documents(CONTENT_TYPE).create({
|
|
2561
|
+
data: {
|
|
2562
|
+
title: title || "",
|
|
2563
|
+
content,
|
|
2564
|
+
category: category || "research",
|
|
2565
|
+
tags: tags || "",
|
|
2566
|
+
source: source || "",
|
|
2567
|
+
adminUserId
|
|
2568
|
+
}
|
|
2569
|
+
});
|
|
2570
|
+
ctx.status = 201;
|
|
2571
|
+
ctx.body = { data: note2 };
|
|
2572
|
+
},
|
|
2573
|
+
async update(ctx) {
|
|
2219
2574
|
const adminUserId = getAdminUserId(ctx);
|
|
2220
2575
|
if (!adminUserId) {
|
|
2221
2576
|
ctx.status = 401;
|
|
@@ -2228,12 +2583,58 @@ const taskController = ({ strapi }) => ({
|
|
|
2228
2583
|
});
|
|
2229
2584
|
if (!existing || existing.adminUserId !== adminUserId) {
|
|
2230
2585
|
ctx.status = 404;
|
|
2231
|
-
ctx.body = { error: "
|
|
2586
|
+
ctx.body = { error: "Note not found" };
|
|
2587
|
+
return;
|
|
2588
|
+
}
|
|
2589
|
+
const { title, content, category, tags, source } = ctx.request.body;
|
|
2590
|
+
const data = {};
|
|
2591
|
+
if (title !== void 0) data.title = title;
|
|
2592
|
+
if (content !== void 0) data.content = content;
|
|
2593
|
+
if (category !== void 0) data.category = category;
|
|
2594
|
+
if (tags !== void 0) data.tags = tags;
|
|
2595
|
+
if (source !== void 0) data.source = source;
|
|
2596
|
+
const note2 = await strapi.documents(CONTENT_TYPE).update({
|
|
2597
|
+
documentId: id,
|
|
2598
|
+
data
|
|
2599
|
+
});
|
|
2600
|
+
ctx.body = { data: note2 };
|
|
2601
|
+
},
|
|
2602
|
+
async delete(ctx) {
|
|
2603
|
+
const adminUserId = getAdminUserId(ctx);
|
|
2604
|
+
if (!adminUserId) {
|
|
2605
|
+
ctx.status = 401;
|
|
2606
|
+
ctx.body = { error: "Unauthorized" };
|
|
2607
|
+
return;
|
|
2608
|
+
}
|
|
2609
|
+
const { id } = ctx.params;
|
|
2610
|
+
const existing = await strapi.documents(CONTENT_TYPE).findOne({
|
|
2611
|
+
documentId: id
|
|
2612
|
+
});
|
|
2613
|
+
if (!existing || existing.adminUserId !== adminUserId) {
|
|
2614
|
+
ctx.status = 404;
|
|
2615
|
+
ctx.body = { error: "Note not found" };
|
|
2232
2616
|
return;
|
|
2233
2617
|
}
|
|
2234
2618
|
await strapi.documents(CONTENT_TYPE).delete({ documentId: id });
|
|
2235
2619
|
ctx.status = 200;
|
|
2236
2620
|
ctx.body = { data: { documentId: id } };
|
|
2621
|
+
},
|
|
2622
|
+
async clearAll(ctx) {
|
|
2623
|
+
const adminUserId = getAdminUserId(ctx);
|
|
2624
|
+
if (!adminUserId) {
|
|
2625
|
+
ctx.status = 401;
|
|
2626
|
+
ctx.body = { error: "Unauthorized" };
|
|
2627
|
+
return;
|
|
2628
|
+
}
|
|
2629
|
+
const notes = await strapi.documents(CONTENT_TYPE).findMany({
|
|
2630
|
+
filters: { adminUserId },
|
|
2631
|
+
fields: ["documentId"]
|
|
2632
|
+
});
|
|
2633
|
+
for (const note2 of notes) {
|
|
2634
|
+
await strapi.documents(CONTENT_TYPE).delete({ documentId: note2.documentId });
|
|
2635
|
+
}
|
|
2636
|
+
ctx.status = 200;
|
|
2637
|
+
ctx.body = { data: { deleted: notes.length } };
|
|
2237
2638
|
}
|
|
2238
2639
|
});
|
|
2239
2640
|
const controllers = {
|
|
@@ -2242,7 +2643,8 @@ const controllers = {
|
|
|
2242
2643
|
conversation: conversationController,
|
|
2243
2644
|
memory: memoryController,
|
|
2244
2645
|
"public-memory": publicMemoryController,
|
|
2245
|
-
task: taskController
|
|
2646
|
+
task: taskController,
|
|
2647
|
+
note: noteController
|
|
2246
2648
|
};
|
|
2247
2649
|
const promptInjection = [
|
|
2248
2650
|
"ignore (all |any )?(previous|prior|above) (instructions|prompts|rules)",
|
|
@@ -2612,6 +3014,36 @@ const adminAPIRoutes = {
|
|
|
2612
3014
|
path: "/tasks/:id",
|
|
2613
3015
|
handler: "task.delete",
|
|
2614
3016
|
config: { policies: [] }
|
|
3017
|
+
},
|
|
3018
|
+
{
|
|
3019
|
+
method: "GET",
|
|
3020
|
+
path: "/notes",
|
|
3021
|
+
handler: "note.find",
|
|
3022
|
+
config: { policies: [] }
|
|
3023
|
+
},
|
|
3024
|
+
{
|
|
3025
|
+
method: "POST",
|
|
3026
|
+
path: "/notes",
|
|
3027
|
+
handler: "note.create",
|
|
3028
|
+
config: { policies: [] }
|
|
3029
|
+
},
|
|
3030
|
+
{
|
|
3031
|
+
method: "PUT",
|
|
3032
|
+
path: "/notes/:id",
|
|
3033
|
+
handler: "note.update",
|
|
3034
|
+
config: { policies: [] }
|
|
3035
|
+
},
|
|
3036
|
+
{
|
|
3037
|
+
method: "DELETE",
|
|
3038
|
+
path: "/notes/clear",
|
|
3039
|
+
handler: "note.clearAll",
|
|
3040
|
+
config: { policies: [] }
|
|
3041
|
+
},
|
|
3042
|
+
{
|
|
3043
|
+
method: "DELETE",
|
|
3044
|
+
path: "/notes/:id",
|
|
3045
|
+
handler: "note.delete",
|
|
3046
|
+
config: { policies: [] }
|
|
2615
3047
|
}
|
|
2616
3048
|
]
|
|
2617
3049
|
};
|