strapi-plugin-ai-sdk 0.6.2 → 0.6.4
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-BhTbl60k.mjs +2755 -0
- package/dist/_chunks/App-CdOD0qmW.js +2776 -0
- package/dist/_chunks/{index-DNcK7AKT.mjs → index-5GDOg82N.mjs} +1 -1
- package/dist/_chunks/{index-BCq8Gjnl.js → index-HDnO9h6E.js} +1 -1
- package/dist/admin/index.js +1 -1
- package/dist/admin/index.mjs +1 -1
- package/dist/server/index.js +39 -19
- package/dist/server/index.mjs +39 -19
- package/dist/server/src/config/index.d.ts +7 -0
- package/dist/server/src/index.d.ts +4 -0
- package/dist/server/src/lib/ai-provider.d.ts +1 -1
- package/dist/server/src/lib/types.d.ts +17 -1
- package/dist/server/src/tool-logic/list-content-types.d.ts +1 -0
- package/dist/server/src/tool-logic/search-content.d.ts +1 -1
- package/dist/widget/widget.js +1 -1
- package/package.json +1 -1
- package/dist/_chunks/App-BcZSDAZc.js +0 -2775
- package/dist/_chunks/App-tiKFYaQx.mjs +0 -2754
|
@@ -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-CdOD0qmW.js"));
|
|
41
41
|
return App;
|
|
42
42
|
}
|
|
43
43
|
});
|
package/dist/admin/index.js
CHANGED
package/dist/admin/index.mjs
CHANGED
package/dist/server/index.js
CHANGED
|
@@ -169,7 +169,11 @@ function createTTSRegistry() {
|
|
|
169
169
|
const DEFAULT_MODEL = "claude-sonnet-4-20250514";
|
|
170
170
|
const DEFAULT_TEMPERATURE = 0.7;
|
|
171
171
|
const DEFAULT_MAX_OUTPUT_TOKENS = 8192;
|
|
172
|
-
const DEFAULT_MAX_CONVERSATION_MESSAGES =
|
|
172
|
+
const DEFAULT_MAX_CONVERSATION_MESSAGES = 15;
|
|
173
|
+
const DEFAULT_PUBLIC_MAX_CONVERSATION_MESSAGES = 10;
|
|
174
|
+
const DEFAULT_MAX_STEPS = 10;
|
|
175
|
+
const DEFAULT_PUBLIC_MAX_STEPS = 5;
|
|
176
|
+
const DEFAULT_PUBLIC_CHAT_MODEL = "claude-haiku-4-5-20251001";
|
|
173
177
|
function isPromptInput(input) {
|
|
174
178
|
return "prompt" in input;
|
|
175
179
|
}
|
|
@@ -210,15 +214,15 @@ class AIProvider {
|
|
|
210
214
|
}
|
|
211
215
|
return true;
|
|
212
216
|
}
|
|
213
|
-
getLanguageModel() {
|
|
217
|
+
getLanguageModel(modelId) {
|
|
214
218
|
if (!this.modelFactory) {
|
|
215
219
|
throw new Error("AIProvider not initialized");
|
|
216
220
|
}
|
|
217
|
-
return this.modelFactory(this.model);
|
|
221
|
+
return this.modelFactory(modelId ?? this.model);
|
|
218
222
|
}
|
|
219
223
|
buildParams(input) {
|
|
220
224
|
const base = {
|
|
221
|
-
model: this.getLanguageModel(),
|
|
225
|
+
model: this.getLanguageModel(input.modelId),
|
|
222
226
|
system: input.system,
|
|
223
227
|
temperature: input.temperature ?? DEFAULT_TEMPERATURE,
|
|
224
228
|
maxOutputTokens: input.maxOutputTokens,
|
|
@@ -367,13 +371,16 @@ function parseComponent(uid, component) {
|
|
|
367
371
|
fieldCount: Object.keys(comp.attributes || {}).length
|
|
368
372
|
};
|
|
369
373
|
}
|
|
374
|
+
let cachedResult = null;
|
|
370
375
|
async function listContentTypes(strapi) {
|
|
376
|
+
if (cachedResult) return cachedResult;
|
|
371
377
|
const contentTypes2 = Object.entries(strapi.contentTypes).filter(([uid]) => isApiContentType(uid)).map(([uid, ct]) => parseContentType(uid, ct, strapi.contentTypes)).sort((a, b) => a.displayName.localeCompare(b.displayName));
|
|
372
378
|
const components = Object.entries(strapi.components).map(([uid, comp]) => parseComponent(uid, comp)).sort((a, b) => a.category.localeCompare(b.category) || a.displayName.localeCompare(b.displayName));
|
|
373
|
-
|
|
379
|
+
cachedResult = { contentTypes: contentTypes2, components };
|
|
380
|
+
return cachedResult;
|
|
374
381
|
}
|
|
375
382
|
const MAX_PAGE_SIZE = 50;
|
|
376
|
-
const LARGE_CONTENT_FIELDS = ["content", "blocks", "body", "richText", "markdown", "html"];
|
|
383
|
+
const LARGE_CONTENT_FIELDS = /* @__PURE__ */ new Set(["content", "blocks", "body", "richText", "markdown", "html"]);
|
|
377
384
|
const searchContentSchema = zod.z.object({
|
|
378
385
|
contentType: zod.z.string().describe(
|
|
379
386
|
'The content type UID to search, e.g. "api::article.article" or "plugin::users-permissions.user"'
|
|
@@ -389,13 +396,14 @@ const searchContentSchema = zod.z.object({
|
|
|
389
396
|
populate: zod.z.union([zod.z.string(), zod.z.array(zod.z.string()), zod.z.record(zod.z.string(), zod.z.unknown())]).optional().describe('Relations to populate. Defaults to "*" (all). Can be a string, array, or object.'),
|
|
390
397
|
includeContent: zod.z.boolean().optional().default(false).describe("When true, includes large content fields (content, blocks, body, etc.) in results. Default false to reduce context size.")
|
|
391
398
|
});
|
|
392
|
-
const searchContentDescription =
|
|
399
|
+
const searchContentDescription = 'Search and query any Strapi content type. Use listContentTypes first to discover available content types and their fields, then use this tool to query specific collections. Use sort (e.g. "createdAt:desc") and pageSize: 1 to get the latest entry. By default, large content fields are stripped from results — set includeContent to true or use fields to get full content.';
|
|
393
400
|
function stripLargeFields(obj) {
|
|
394
401
|
const stripped = {};
|
|
395
402
|
for (const [key, value] of Object.entries(obj)) {
|
|
396
|
-
if (
|
|
397
|
-
|
|
403
|
+
if (LARGE_CONTENT_FIELDS.has(key)) {
|
|
404
|
+
continue;
|
|
398
405
|
}
|
|
406
|
+
stripped[key] = value;
|
|
399
407
|
}
|
|
400
408
|
return stripped;
|
|
401
409
|
}
|
|
@@ -921,7 +929,8 @@ const config = {
|
|
|
921
929
|
baseURL: void 0,
|
|
922
930
|
systemPrompt: "",
|
|
923
931
|
maxOutputTokens: 8192,
|
|
924
|
-
maxConversationMessages:
|
|
932
|
+
maxConversationMessages: 15,
|
|
933
|
+
maxSteps: 10,
|
|
925
934
|
mcp: {
|
|
926
935
|
sessionTimeoutMs: 4 * 60 * 60 * 1e3,
|
|
927
936
|
maxSessions: 100,
|
|
@@ -933,7 +942,13 @@ const config = {
|
|
|
933
942
|
},
|
|
934
943
|
publicChat: {
|
|
935
944
|
/** Content type UIDs the public chat is allowed to query (e.g. ['api::article.article']) */
|
|
936
|
-
allowedContentTypes: []
|
|
945
|
+
allowedContentTypes: [],
|
|
946
|
+
/** Model for public chat — defaults to Haiku for lower cost & higher rate limits */
|
|
947
|
+
chatModel: "claude-haiku-4-5-20251001",
|
|
948
|
+
/** Max conversation messages for public chat */
|
|
949
|
+
maxConversationMessages: 10,
|
|
950
|
+
/** Max tool call steps for public chat */
|
|
951
|
+
maxSteps: 5
|
|
937
952
|
}
|
|
938
953
|
},
|
|
939
954
|
validator(config2) {
|
|
@@ -2029,18 +2044,18 @@ function createPublicTools(strapi, allowedContentTypes) {
|
|
|
2029
2044
|
const allowed = new Set(allowedContentTypes);
|
|
2030
2045
|
const tools = {};
|
|
2031
2046
|
for (const [name, def] of registry.getPublicSafe()) {
|
|
2032
|
-
if (CONTENT_TOOLS.has(name)
|
|
2047
|
+
if (CONTENT_TOOLS.has(name)) {
|
|
2033
2048
|
tools[name] = ai.tool({
|
|
2034
2049
|
description: def.description,
|
|
2035
2050
|
inputSchema: ai.zodSchema(def.schema),
|
|
2036
2051
|
execute: async (args) => {
|
|
2037
|
-
if (args.contentType
|
|
2052
|
+
if (!args.contentType || !allowed.has(args.contentType)) {
|
|
2038
2053
|
return { error: `Content type "${args.contentType}" is not available in public chat.` };
|
|
2039
2054
|
}
|
|
2040
2055
|
return def.execute(args, strapi);
|
|
2041
2056
|
}
|
|
2042
2057
|
});
|
|
2043
|
-
} else if (name === "listContentTypes"
|
|
2058
|
+
} else if (name === "listContentTypes") {
|
|
2044
2059
|
tools[name] = ai.tool({
|
|
2045
2060
|
description: def.description,
|
|
2046
2061
|
inputSchema: ai.zodSchema(def.schema),
|
|
@@ -2069,7 +2084,7 @@ function describeTools(tools) {
|
|
|
2069
2084
|
return `Available tools:
|
|
2070
2085
|
${lines.join("\n")}`;
|
|
2071
2086
|
}
|
|
2072
|
-
const DEFAULT_PREAMBLE = "You are a Strapi CMS assistant. Use your tools to fulfill user requests. When asked to create or update content, use the appropriate tool — do not tell the user you cannot.";
|
|
2087
|
+
const DEFAULT_PREAMBLE = "You are a Strapi CMS assistant. Use your tools to fulfill user requests. When asked to create or update content, use the appropriate tool — do not tell the user you cannot. When performing bulk operations (e.g. publish multiple items), call multiple tools in parallel in a single step rather than one at a time.";
|
|
2073
2088
|
const DEFAULT_PUBLIC_PREAMBLE = "You are a helpful public assistant for this website. Use your tools to answer questions about the site content. You cannot modify any content or perform administrative actions.";
|
|
2074
2089
|
function composeSystemPrompt(config2, toolsDescription, override) {
|
|
2075
2090
|
const base = override || config2?.systemPrompt || DEFAULT_PREAMBLE;
|
|
@@ -2103,6 +2118,7 @@ const service = ({ strapi }) => {
|
|
|
2103
2118
|
const config2 = strapi.config.get("plugin::ai-sdk");
|
|
2104
2119
|
const maxMessages = config2?.maxConversationMessages ?? DEFAULT_MAX_CONVERSATION_MESSAGES;
|
|
2105
2120
|
const maxOutputTokens = config2?.maxOutputTokens ?? DEFAULT_MAX_OUTPUT_TOKENS;
|
|
2121
|
+
const maxSteps = config2?.maxSteps ?? DEFAULT_MAX_STEPS;
|
|
2106
2122
|
const trimmedMessages = messages.length > maxMessages ? messages.slice(-maxMessages) : messages;
|
|
2107
2123
|
const modelMessages = await ai.convertToModelMessages(trimmedMessages);
|
|
2108
2124
|
const tools = createTools(strapi, { adminUserId: options2?.adminUserId });
|
|
@@ -2130,7 +2146,7 @@ ${lines.join("\n")}`;
|
|
|
2130
2146
|
system,
|
|
2131
2147
|
tools,
|
|
2132
2148
|
maxOutputTokens,
|
|
2133
|
-
stopWhen: ai.stepCountIs(
|
|
2149
|
+
stopWhen: ai.stepCountIs(maxSteps)
|
|
2134
2150
|
});
|
|
2135
2151
|
},
|
|
2136
2152
|
/**
|
|
@@ -2138,9 +2154,12 @@ ${lines.join("\n")}`;
|
|
|
2138
2154
|
*/
|
|
2139
2155
|
async publicChat(messages, options2) {
|
|
2140
2156
|
const config2 = strapi.config.get("plugin::ai-sdk");
|
|
2141
|
-
const
|
|
2157
|
+
const publicConfig = config2?.publicChat;
|
|
2158
|
+
const maxMessages = publicConfig?.maxConversationMessages ?? DEFAULT_PUBLIC_MAX_CONVERSATION_MESSAGES;
|
|
2142
2159
|
const maxOutputTokens = config2?.maxOutputTokens ?? DEFAULT_MAX_OUTPUT_TOKENS;
|
|
2143
|
-
const
|
|
2160
|
+
const maxSteps = publicConfig?.maxSteps ?? DEFAULT_PUBLIC_MAX_STEPS;
|
|
2161
|
+
const publicModel = publicConfig?.chatModel ?? DEFAULT_PUBLIC_CHAT_MODEL;
|
|
2162
|
+
const allowedContentTypes = publicConfig?.allowedContentTypes ?? [];
|
|
2144
2163
|
const trimmedMessages = messages.length > maxMessages ? messages.slice(-maxMessages) : messages;
|
|
2145
2164
|
const modelMessages = await ai.convertToModelMessages(trimmedMessages);
|
|
2146
2165
|
const tools = createPublicTools(strapi, allowedContentTypes);
|
|
@@ -2166,7 +2185,8 @@ ${lines.join("\n")}`;
|
|
|
2166
2185
|
system,
|
|
2167
2186
|
tools,
|
|
2168
2187
|
maxOutputTokens,
|
|
2169
|
-
|
|
2188
|
+
modelId: publicModel,
|
|
2189
|
+
stopWhen: ai.stepCountIs(maxSteps)
|
|
2170
2190
|
});
|
|
2171
2191
|
},
|
|
2172
2192
|
isInitialized() {
|
package/dist/server/index.mjs
CHANGED
|
@@ -149,7 +149,11 @@ function createTTSRegistry() {
|
|
|
149
149
|
const DEFAULT_MODEL = "claude-sonnet-4-20250514";
|
|
150
150
|
const DEFAULT_TEMPERATURE = 0.7;
|
|
151
151
|
const DEFAULT_MAX_OUTPUT_TOKENS = 8192;
|
|
152
|
-
const DEFAULT_MAX_CONVERSATION_MESSAGES =
|
|
152
|
+
const DEFAULT_MAX_CONVERSATION_MESSAGES = 15;
|
|
153
|
+
const DEFAULT_PUBLIC_MAX_CONVERSATION_MESSAGES = 10;
|
|
154
|
+
const DEFAULT_MAX_STEPS = 10;
|
|
155
|
+
const DEFAULT_PUBLIC_MAX_STEPS = 5;
|
|
156
|
+
const DEFAULT_PUBLIC_CHAT_MODEL = "claude-haiku-4-5-20251001";
|
|
153
157
|
function isPromptInput(input) {
|
|
154
158
|
return "prompt" in input;
|
|
155
159
|
}
|
|
@@ -190,15 +194,15 @@ class AIProvider {
|
|
|
190
194
|
}
|
|
191
195
|
return true;
|
|
192
196
|
}
|
|
193
|
-
getLanguageModel() {
|
|
197
|
+
getLanguageModel(modelId) {
|
|
194
198
|
if (!this.modelFactory) {
|
|
195
199
|
throw new Error("AIProvider not initialized");
|
|
196
200
|
}
|
|
197
|
-
return this.modelFactory(this.model);
|
|
201
|
+
return this.modelFactory(modelId ?? this.model);
|
|
198
202
|
}
|
|
199
203
|
buildParams(input) {
|
|
200
204
|
const base = {
|
|
201
|
-
model: this.getLanguageModel(),
|
|
205
|
+
model: this.getLanguageModel(input.modelId),
|
|
202
206
|
system: input.system,
|
|
203
207
|
temperature: input.temperature ?? DEFAULT_TEMPERATURE,
|
|
204
208
|
maxOutputTokens: input.maxOutputTokens,
|
|
@@ -347,13 +351,16 @@ function parseComponent(uid, component) {
|
|
|
347
351
|
fieldCount: Object.keys(comp.attributes || {}).length
|
|
348
352
|
};
|
|
349
353
|
}
|
|
354
|
+
let cachedResult = null;
|
|
350
355
|
async function listContentTypes(strapi) {
|
|
356
|
+
if (cachedResult) return cachedResult;
|
|
351
357
|
const contentTypes2 = Object.entries(strapi.contentTypes).filter(([uid]) => isApiContentType(uid)).map(([uid, ct]) => parseContentType(uid, ct, strapi.contentTypes)).sort((a, b) => a.displayName.localeCompare(b.displayName));
|
|
352
358
|
const components = Object.entries(strapi.components).map(([uid, comp]) => parseComponent(uid, comp)).sort((a, b) => a.category.localeCompare(b.category) || a.displayName.localeCompare(b.displayName));
|
|
353
|
-
|
|
359
|
+
cachedResult = { contentTypes: contentTypes2, components };
|
|
360
|
+
return cachedResult;
|
|
354
361
|
}
|
|
355
362
|
const MAX_PAGE_SIZE = 50;
|
|
356
|
-
const LARGE_CONTENT_FIELDS = ["content", "blocks", "body", "richText", "markdown", "html"];
|
|
363
|
+
const LARGE_CONTENT_FIELDS = /* @__PURE__ */ new Set(["content", "blocks", "body", "richText", "markdown", "html"]);
|
|
357
364
|
const searchContentSchema = z.object({
|
|
358
365
|
contentType: z.string().describe(
|
|
359
366
|
'The content type UID to search, e.g. "api::article.article" or "plugin::users-permissions.user"'
|
|
@@ -369,13 +376,14 @@ const searchContentSchema = z.object({
|
|
|
369
376
|
populate: z.union([z.string(), z.array(z.string()), z.record(z.string(), z.unknown())]).optional().describe('Relations to populate. Defaults to "*" (all). Can be a string, array, or object.'),
|
|
370
377
|
includeContent: z.boolean().optional().default(false).describe("When true, includes large content fields (content, blocks, body, etc.) in results. Default false to reduce context size.")
|
|
371
378
|
});
|
|
372
|
-
const searchContentDescription =
|
|
379
|
+
const searchContentDescription = 'Search and query any Strapi content type. Use listContentTypes first to discover available content types and their fields, then use this tool to query specific collections. Use sort (e.g. "createdAt:desc") and pageSize: 1 to get the latest entry. By default, large content fields are stripped from results — set includeContent to true or use fields to get full content.';
|
|
373
380
|
function stripLargeFields(obj) {
|
|
374
381
|
const stripped = {};
|
|
375
382
|
for (const [key, value] of Object.entries(obj)) {
|
|
376
|
-
if (
|
|
377
|
-
|
|
383
|
+
if (LARGE_CONTENT_FIELDS.has(key)) {
|
|
384
|
+
continue;
|
|
378
385
|
}
|
|
386
|
+
stripped[key] = value;
|
|
379
387
|
}
|
|
380
388
|
return stripped;
|
|
381
389
|
}
|
|
@@ -901,7 +909,8 @@ const config = {
|
|
|
901
909
|
baseURL: void 0,
|
|
902
910
|
systemPrompt: "",
|
|
903
911
|
maxOutputTokens: 8192,
|
|
904
|
-
maxConversationMessages:
|
|
912
|
+
maxConversationMessages: 15,
|
|
913
|
+
maxSteps: 10,
|
|
905
914
|
mcp: {
|
|
906
915
|
sessionTimeoutMs: 4 * 60 * 60 * 1e3,
|
|
907
916
|
maxSessions: 100,
|
|
@@ -913,7 +922,13 @@ const config = {
|
|
|
913
922
|
},
|
|
914
923
|
publicChat: {
|
|
915
924
|
/** Content type UIDs the public chat is allowed to query (e.g. ['api::article.article']) */
|
|
916
|
-
allowedContentTypes: []
|
|
925
|
+
allowedContentTypes: [],
|
|
926
|
+
/** Model for public chat — defaults to Haiku for lower cost & higher rate limits */
|
|
927
|
+
chatModel: "claude-haiku-4-5-20251001",
|
|
928
|
+
/** Max conversation messages for public chat */
|
|
929
|
+
maxConversationMessages: 10,
|
|
930
|
+
/** Max tool call steps for public chat */
|
|
931
|
+
maxSteps: 5
|
|
917
932
|
}
|
|
918
933
|
},
|
|
919
934
|
validator(config2) {
|
|
@@ -2009,18 +2024,18 @@ function createPublicTools(strapi, allowedContentTypes) {
|
|
|
2009
2024
|
const allowed = new Set(allowedContentTypes);
|
|
2010
2025
|
const tools = {};
|
|
2011
2026
|
for (const [name, def] of registry.getPublicSafe()) {
|
|
2012
|
-
if (CONTENT_TOOLS.has(name)
|
|
2027
|
+
if (CONTENT_TOOLS.has(name)) {
|
|
2013
2028
|
tools[name] = tool({
|
|
2014
2029
|
description: def.description,
|
|
2015
2030
|
inputSchema: zodSchema(def.schema),
|
|
2016
2031
|
execute: async (args) => {
|
|
2017
|
-
if (args.contentType
|
|
2032
|
+
if (!args.contentType || !allowed.has(args.contentType)) {
|
|
2018
2033
|
return { error: `Content type "${args.contentType}" is not available in public chat.` };
|
|
2019
2034
|
}
|
|
2020
2035
|
return def.execute(args, strapi);
|
|
2021
2036
|
}
|
|
2022
2037
|
});
|
|
2023
|
-
} else if (name === "listContentTypes"
|
|
2038
|
+
} else if (name === "listContentTypes") {
|
|
2024
2039
|
tools[name] = tool({
|
|
2025
2040
|
description: def.description,
|
|
2026
2041
|
inputSchema: zodSchema(def.schema),
|
|
@@ -2049,7 +2064,7 @@ function describeTools(tools) {
|
|
|
2049
2064
|
return `Available tools:
|
|
2050
2065
|
${lines.join("\n")}`;
|
|
2051
2066
|
}
|
|
2052
|
-
const DEFAULT_PREAMBLE = "You are a Strapi CMS assistant. Use your tools to fulfill user requests. When asked to create or update content, use the appropriate tool — do not tell the user you cannot.";
|
|
2067
|
+
const DEFAULT_PREAMBLE = "You are a Strapi CMS assistant. Use your tools to fulfill user requests. When asked to create or update content, use the appropriate tool — do not tell the user you cannot. When performing bulk operations (e.g. publish multiple items), call multiple tools in parallel in a single step rather than one at a time.";
|
|
2053
2068
|
const DEFAULT_PUBLIC_PREAMBLE = "You are a helpful public assistant for this website. Use your tools to answer questions about the site content. You cannot modify any content or perform administrative actions.";
|
|
2054
2069
|
function composeSystemPrompt(config2, toolsDescription, override) {
|
|
2055
2070
|
const base = override || config2?.systemPrompt || DEFAULT_PREAMBLE;
|
|
@@ -2083,6 +2098,7 @@ const service = ({ strapi }) => {
|
|
|
2083
2098
|
const config2 = strapi.config.get("plugin::ai-sdk");
|
|
2084
2099
|
const maxMessages = config2?.maxConversationMessages ?? DEFAULT_MAX_CONVERSATION_MESSAGES;
|
|
2085
2100
|
const maxOutputTokens = config2?.maxOutputTokens ?? DEFAULT_MAX_OUTPUT_TOKENS;
|
|
2101
|
+
const maxSteps = config2?.maxSteps ?? DEFAULT_MAX_STEPS;
|
|
2086
2102
|
const trimmedMessages = messages.length > maxMessages ? messages.slice(-maxMessages) : messages;
|
|
2087
2103
|
const modelMessages = await convertToModelMessages(trimmedMessages);
|
|
2088
2104
|
const tools = createTools(strapi, { adminUserId: options2?.adminUserId });
|
|
@@ -2110,7 +2126,7 @@ ${lines.join("\n")}`;
|
|
|
2110
2126
|
system,
|
|
2111
2127
|
tools,
|
|
2112
2128
|
maxOutputTokens,
|
|
2113
|
-
stopWhen: stepCountIs(
|
|
2129
|
+
stopWhen: stepCountIs(maxSteps)
|
|
2114
2130
|
});
|
|
2115
2131
|
},
|
|
2116
2132
|
/**
|
|
@@ -2118,9 +2134,12 @@ ${lines.join("\n")}`;
|
|
|
2118
2134
|
*/
|
|
2119
2135
|
async publicChat(messages, options2) {
|
|
2120
2136
|
const config2 = strapi.config.get("plugin::ai-sdk");
|
|
2121
|
-
const
|
|
2137
|
+
const publicConfig = config2?.publicChat;
|
|
2138
|
+
const maxMessages = publicConfig?.maxConversationMessages ?? DEFAULT_PUBLIC_MAX_CONVERSATION_MESSAGES;
|
|
2122
2139
|
const maxOutputTokens = config2?.maxOutputTokens ?? DEFAULT_MAX_OUTPUT_TOKENS;
|
|
2123
|
-
const
|
|
2140
|
+
const maxSteps = publicConfig?.maxSteps ?? DEFAULT_PUBLIC_MAX_STEPS;
|
|
2141
|
+
const publicModel = publicConfig?.chatModel ?? DEFAULT_PUBLIC_CHAT_MODEL;
|
|
2142
|
+
const allowedContentTypes = publicConfig?.allowedContentTypes ?? [];
|
|
2124
2143
|
const trimmedMessages = messages.length > maxMessages ? messages.slice(-maxMessages) : messages;
|
|
2125
2144
|
const modelMessages = await convertToModelMessages(trimmedMessages);
|
|
2126
2145
|
const tools = createPublicTools(strapi, allowedContentTypes);
|
|
@@ -2146,7 +2165,8 @@ ${lines.join("\n")}`;
|
|
|
2146
2165
|
system,
|
|
2147
2166
|
tools,
|
|
2148
2167
|
maxOutputTokens,
|
|
2149
|
-
|
|
2168
|
+
modelId: publicModel,
|
|
2169
|
+
stopWhen: stepCountIs(maxSteps)
|
|
2150
2170
|
});
|
|
2151
2171
|
},
|
|
2152
2172
|
isInitialized() {
|
|
@@ -7,6 +7,7 @@ declare const _default: {
|
|
|
7
7
|
systemPrompt: string;
|
|
8
8
|
maxOutputTokens: number;
|
|
9
9
|
maxConversationMessages: number;
|
|
10
|
+
maxSteps: number;
|
|
10
11
|
mcp: {
|
|
11
12
|
sessionTimeoutMs: number;
|
|
12
13
|
maxSessions: number;
|
|
@@ -19,6 +20,12 @@ declare const _default: {
|
|
|
19
20
|
publicChat: {
|
|
20
21
|
/** Content type UIDs the public chat is allowed to query (e.g. ['api::article.article']) */
|
|
21
22
|
allowedContentTypes: string[];
|
|
23
|
+
/** Model for public chat — defaults to Haiku for lower cost & higher rate limits */
|
|
24
|
+
chatModel: string;
|
|
25
|
+
/** Max conversation messages for public chat */
|
|
26
|
+
maxConversationMessages: number;
|
|
27
|
+
/** Max tool call steps for public chat */
|
|
28
|
+
maxSteps: number;
|
|
22
29
|
};
|
|
23
30
|
};
|
|
24
31
|
validator(config: unknown): void;
|
|
@@ -18,6 +18,7 @@ declare const _default: {
|
|
|
18
18
|
systemPrompt: string;
|
|
19
19
|
maxOutputTokens: number;
|
|
20
20
|
maxConversationMessages: number;
|
|
21
|
+
maxSteps: number;
|
|
21
22
|
mcp: {
|
|
22
23
|
sessionTimeoutMs: number;
|
|
23
24
|
maxSessions: number;
|
|
@@ -29,6 +30,9 @@ declare const _default: {
|
|
|
29
30
|
};
|
|
30
31
|
publicChat: {
|
|
31
32
|
allowedContentTypes: string[];
|
|
33
|
+
chatModel: string;
|
|
34
|
+
maxConversationMessages: number;
|
|
35
|
+
maxSteps: number;
|
|
32
36
|
};
|
|
33
37
|
};
|
|
34
38
|
validator(config: unknown): void;
|
|
@@ -20,7 +20,7 @@ type ProviderCreator = (config: {
|
|
|
20
20
|
baseURL?: string;
|
|
21
21
|
}) => (modelId: string) => LanguageModel;
|
|
22
22
|
export declare class AIProvider {
|
|
23
|
-
private static providerRegistry;
|
|
23
|
+
private static readonly providerRegistry;
|
|
24
24
|
private modelFactory;
|
|
25
25
|
private model;
|
|
26
26
|
/**
|
|
@@ -17,10 +17,20 @@ export interface MCPConfig {
|
|
|
17
17
|
cleanupInterval?: number;
|
|
18
18
|
}
|
|
19
19
|
export declare const DEFAULT_MAX_OUTPUT_TOKENS = 8192;
|
|
20
|
-
export declare const DEFAULT_MAX_CONVERSATION_MESSAGES =
|
|
20
|
+
export declare const DEFAULT_MAX_CONVERSATION_MESSAGES = 15;
|
|
21
|
+
export declare const DEFAULT_PUBLIC_MAX_CONVERSATION_MESSAGES = 10;
|
|
22
|
+
export declare const DEFAULT_MAX_STEPS = 10;
|
|
23
|
+
export declare const DEFAULT_PUBLIC_MAX_STEPS = 5;
|
|
24
|
+
export declare const DEFAULT_PUBLIC_CHAT_MODEL = "claude-haiku-4-5-20251001";
|
|
21
25
|
export interface PublicChatConfig {
|
|
22
26
|
/** Content type UIDs the public chat is allowed to query (e.g. ['api::article.article']) */
|
|
23
27
|
allowedContentTypes?: string[];
|
|
28
|
+
/** Model to use for public chat (defaults to Haiku for lower cost & higher rate limits) */
|
|
29
|
+
chatModel?: string;
|
|
30
|
+
/** Max conversation messages for public chat (defaults to 10) */
|
|
31
|
+
maxConversationMessages?: number;
|
|
32
|
+
/** Max tool call steps for public chat (defaults to 2) */
|
|
33
|
+
maxSteps?: number;
|
|
24
34
|
}
|
|
25
35
|
export interface PluginConfig {
|
|
26
36
|
anthropicApiKey: string;
|
|
@@ -30,6 +40,8 @@ export interface PluginConfig {
|
|
|
30
40
|
systemPrompt?: string;
|
|
31
41
|
maxOutputTokens?: number;
|
|
32
42
|
maxConversationMessages?: number;
|
|
43
|
+
/** Max tool call steps for admin chat (defaults to 3) */
|
|
44
|
+
maxSteps?: number;
|
|
33
45
|
typecastApiKey?: string;
|
|
34
46
|
typecastActorId?: string;
|
|
35
47
|
mcp?: MCPConfig;
|
|
@@ -42,6 +54,10 @@ export interface GenerateOptions {
|
|
|
42
54
|
maxOutputTokens?: number;
|
|
43
55
|
tools?: ToolSet;
|
|
44
56
|
stopWhen?: AnyStopCondition;
|
|
57
|
+
/** Max tool call round-trips before stopping */
|
|
58
|
+
maxSteps?: number;
|
|
59
|
+
/** Override model for this request (e.g. use Haiku for public chat) */
|
|
60
|
+
modelId?: string;
|
|
45
61
|
}
|
|
46
62
|
export interface PromptInput extends GenerateOptions {
|
|
47
63
|
prompt: string;
|
|
@@ -29,5 +29,6 @@ export interface ListContentTypesResult {
|
|
|
29
29
|
/**
|
|
30
30
|
* Core logic for listing content types and components.
|
|
31
31
|
* Shared between AI SDK tool and MCP tool.
|
|
32
|
+
* Results are cached since content types are static after server startup.
|
|
32
33
|
*/
|
|
33
34
|
export declare function listContentTypes(strapi: Core.Strapi): Promise<ListContentTypesResult>;
|
|
@@ -16,7 +16,7 @@ export declare const searchContentSchema: z.ZodObject<{
|
|
|
16
16
|
populate: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>, z.ZodRecord<z.ZodString, z.ZodUnknown>]>>;
|
|
17
17
|
includeContent: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
|
|
18
18
|
}, z.core.$strip>;
|
|
19
|
-
export declare const searchContentDescription = "Search and query any Strapi content type. Use listContentTypes first to discover available content types and their fields, then use this tool to query specific collections. By default, large content fields are stripped from results \u2014 set includeContent to true or use fields to get full content.";
|
|
19
|
+
export declare const searchContentDescription = "Search and query any Strapi content type. Use listContentTypes first to discover available content types and their fields, then use this tool to query specific collections. Use sort (e.g. \"createdAt:desc\") and pageSize: 1 to get the latest entry. By default, large content fields are stripped from results \u2014 set includeContent to true or use fields to get full content.";
|
|
20
20
|
export interface SearchContentParams {
|
|
21
21
|
contentType: string;
|
|
22
22
|
query?: string;
|