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.
@@ -36,7 +36,7 @@ const index = {
36
36
  defaultMessage: PLUGIN_ID
37
37
  },
38
38
  Component: async () => {
39
- const { App } = await import("./App-tiKFYaQx.mjs");
39
+ const { App } = await import("./App-BhTbl60k.mjs");
40
40
  return App;
41
41
  }
42
42
  });
@@ -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-BcZSDAZc.js"));
40
+ const { App } = await Promise.resolve().then(() => require("./App-CdOD0qmW.js"));
41
41
  return App;
42
42
  }
43
43
  });
@@ -1,3 +1,3 @@
1
1
  "use strict";
2
- const index = require("../_chunks/index-BCq8Gjnl.js");
2
+ const index = require("../_chunks/index-HDnO9h6E.js");
3
3
  module.exports = index.index;
@@ -1,4 +1,4 @@
1
- import { i } from "../_chunks/index-DNcK7AKT.mjs";
1
+ import { i } from "../_chunks/index-5GDOg82N.mjs";
2
2
  export {
3
3
  i as default
4
4
  };
@@ -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 = 40;
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
- return { contentTypes: contentTypes2, components };
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 = "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 — set includeContent to true or use fields to get full content.";
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 (!LARGE_CONTENT_FIELDS.includes(key)) {
397
- stripped[key] = value;
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: 40,
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) && allowed.size > 0) {
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 && !allowed.has(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" && allowed.size > 0) {
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(6)
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 maxMessages = config2?.maxConversationMessages ?? DEFAULT_MAX_CONVERSATION_MESSAGES;
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 allowedContentTypes = config2?.publicChat?.allowedContentTypes ?? [];
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
- stopWhen: ai.stepCountIs(6)
2188
+ modelId: publicModel,
2189
+ stopWhen: ai.stepCountIs(maxSteps)
2170
2190
  });
2171
2191
  },
2172
2192
  isInitialized() {
@@ -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 = 40;
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
- return { contentTypes: contentTypes2, components };
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 = "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 — set includeContent to true or use fields to get full content.";
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 (!LARGE_CONTENT_FIELDS.includes(key)) {
377
- stripped[key] = value;
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: 40,
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) && allowed.size > 0) {
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 && !allowed.has(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" && allowed.size > 0) {
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(6)
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 maxMessages = config2?.maxConversationMessages ?? DEFAULT_MAX_CONVERSATION_MESSAGES;
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 allowedContentTypes = config2?.publicChat?.allowedContentTypes ?? [];
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
- stopWhen: stepCountIs(6)
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 = 40;
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;