@nocobase/plugin-ai 2.1.0-beta.5 → 2.1.0-beta.7

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.
Files changed (43) hide show
  1. package/dist/client/{1907d8fc160052b4.js → 05bb46e182de283c.js} +1 -1
  2. package/dist/client/{888db19c1c5dd1c9.js → 35156dfea5f288fa.js} +1 -1
  3. package/dist/client/ai-employees/chatbox/model.d.ts +3 -4
  4. package/dist/client/c49179ef6fcbc972.js +10 -0
  5. package/dist/client/f36cbdd2680ceeba.js +10 -0
  6. package/dist/client/index.d.ts +2 -2
  7. package/dist/client/index.js +3 -3
  8. package/dist/client/llm-services/hooks/useLLMServiceCatalog.d.ts +2 -2
  9. package/dist/client/llm-services/utils.d.ts +1 -1
  10. package/dist/client/repositories/AIConfigRepository.d.ts +52 -0
  11. package/dist/client/{ai-employees/flow/context/index.d.ts → repositories/hooks/useAIConfigRepository.d.ts} +2 -1
  12. package/dist/externalVersion.js +14 -13
  13. package/dist/node_modules/@langchain/anthropic/package.json +1 -1
  14. package/dist/node_modules/@langchain/core/package.json +1 -1
  15. package/dist/node_modules/@langchain/deepseek/package.json +1 -1
  16. package/dist/node_modules/@langchain/google-genai/package.json +1 -1
  17. package/dist/node_modules/@langchain/langgraph/package.json +1 -1
  18. package/dist/node_modules/@langchain/langgraph-checkpoint/package.json +1 -1
  19. package/dist/node_modules/@langchain/ollama/package.json +1 -1
  20. package/dist/node_modules/@langchain/openai/package.json +1 -1
  21. package/dist/node_modules/fast-glob/package.json +1 -1
  22. package/dist/node_modules/flexsearch/package.json +1 -1
  23. package/dist/node_modules/fs-extra/package.json +1 -1
  24. package/dist/node_modules/langchain/package.json +1 -1
  25. package/dist/node_modules/nodejs-snowflake/package.json +1 -1
  26. package/dist/node_modules/zod/package.json +1 -1
  27. package/dist/server/ai-employees/ai-employee.d.ts +3 -3
  28. package/dist/server/ai-employees/ai-employee.js +13 -11
  29. package/dist/server/llm-providers/anthropic.d.ts +1 -0
  30. package/dist/server/llm-providers/anthropic.js +11 -0
  31. package/dist/server/manager/ai-chat-conversation.js +1 -1
  32. package/dist/server/manager/ai-context-datasource-manager.js +4 -3
  33. package/dist/server/plugin.js +1 -5
  34. package/dist/server/tools/docs.d.ts +3 -4
  35. package/dist/server/tools/docs.js +104 -43
  36. package/dist/server/types/ai-chat-conversation.type.d.ts +1 -1
  37. package/package.json +3 -2
  38. package/dist/client/2793ab2b95a86390.js +0 -10
  39. package/dist/client/ai-employees/flow/context/ai-employees-data.d.ts +0 -10
  40. package/dist/client/ai-employees/hooks/useAIEmployeesData.d.ts +0 -17
  41. package/dist/client/f52e5acb1a4b991c.js +0 -10
  42. package/dist/client/llm-services/LLMServicesRepository.d.ts +0 -30
  43. package/dist/client/llm-services/hooks/useLLMServicesRepository.d.ts +0 -10
@@ -1 +1 @@
1
- {"name":"langchain","version":"1.2.24","description":"Typescript bindings for langchain","author":"LangChain","license":"MIT","type":"module","engines":{"node":">=20"},"files":["dist/","CHANGELOG.md","README.md","LICENSE","storage","load","load.d.cts","load.cjs","load.d.ts","load.js","hub","chat_models","hub.d.cts","hub.cjs","hub.d.ts","hub.js"],"repository":{"type":"git","url":"git+ssh://git@github.com/langchain-ai/langchainjs.git"},"homepage":"https://github.com/langchain-ai/langchainjs/tree/main/libs/langchain/","devDependencies":{"@tsconfig/recommended":"^1.0.2","@types/js-yaml":"^4","@types/jsdom":"^21.1.1","@types/uuid":"^9","@types/ws":"^8","@vitest/coverage-v8":"^3.2.4","cheerio":"1.0.0-rc.12","dotenv":"^16.0.3","dpdm":"^3.14.0","eslint":"^9.34.0","openai":"^5.1.0","peggy":"^3.0.2","prettier":"^3.5.0","reflect-metadata":"^0.2.2","rimraf":"^5.0.1","tinybench":"^6.0.0","typeorm":"^0.3.28","typescript":"~5.8.3","vitest":"^3.2.4","yaml":"^2.8.1","@langchain/anthropic":"1.3.17","@langchain/core":"^1.1.24","@langchain/cohere":"1.0.2","@langchain/eslint":"0.1.1","@langchain/openai":"1.2.7","@langchain/tsconfig":"0.0.1"},"peerDependencies":{"@langchain/core":"^1.1.24"},"dependencies":{"@langchain/langgraph":"^1.1.2","@langchain/langgraph-checkpoint":"^1.0.0","langsmith":">=0.5.0 <1.0.0","uuid":"^10.0.0","zod":"^3.25.76 || ^4"},"publishConfig":{"access":"public"},"keywords":["llm","ai","gpt3","chain","prompt","prompt engineering","chatgpt","machine learning","ml","openai","embeddings","vectorstores"],"main":"./dist/index.cjs","types":"./dist/index.d.cts","exports":{".":{"input":"./src/index.ts","require":{"types":"./dist/index.d.cts","default":"./dist/index.cjs"},"import":{"types":"./dist/index.d.ts","default":"./dist/index.js"}},"./chat_models/universal":{"input":"./src/chat_models/universal.ts","require":{"types":"./dist/chat_models/universal.d.cts","default":"./dist/chat_models/universal.cjs"},"import":{"types":"./dist/chat_models/universal.d.ts","default":"./dist/chat_models/universal.js"}},"./hub":{"input":"./src/hub/index.ts","require":{"types":"./dist/hub/index.d.cts","default":"./dist/hub/index.cjs"},"import":{"types":"./dist/hub/index.d.ts","default":"./dist/hub/index.js"}},"./hub/node":{"input":"./src/hub/node.ts","require":{"types":"./dist/hub/node.d.cts","default":"./dist/hub/node.cjs"},"import":{"types":"./dist/hub/node.d.ts","default":"./dist/hub/node.js"}},"./load":{"input":"./src/load/index.ts","require":{"types":"./dist/load/index.d.cts","default":"./dist/load/index.cjs"},"import":{"types":"./dist/load/index.d.ts","default":"./dist/load/index.js"}},"./load/serializable":{"input":"./src/load/serializable.ts","require":{"types":"./dist/load/serializable.d.cts","default":"./dist/load/serializable.cjs"},"import":{"types":"./dist/load/serializable.d.ts","default":"./dist/load/serializable.js"}},"./storage/encoder_backed":{"input":"./src/storage/encoder_backed.ts","require":{"types":"./dist/storage/encoder_backed.d.cts","default":"./dist/storage/encoder_backed.cjs"},"import":{"types":"./dist/storage/encoder_backed.d.ts","default":"./dist/storage/encoder_backed.js"}},"./storage/file_system":{"input":"./src/storage/file_system.ts","require":{"types":"./dist/storage/file_system.d.cts","default":"./dist/storage/file_system.cjs"},"import":{"types":"./dist/storage/file_system.d.ts","default":"./dist/storage/file_system.js"}},"./storage/in_memory":{"input":"./src/storage/in_memory.ts","require":{"types":"./dist/storage/in_memory.d.cts","default":"./dist/storage/in_memory.cjs"},"import":{"types":"./dist/storage/in_memory.d.ts","default":"./dist/storage/in_memory.js"}},"./package.json":"./package.json"},"module":"./dist/index.js","scripts":{"build":"turbo build:compile --filter langchain --output-logs new-only","build:compile":"tsdown","lint:eslint":"eslint --cache src/","lint:dpdm":"dpdm --skip-dynamic-imports circular --exit-code circular:1 --no-warning --no-tree src/*.ts src/**/*.ts","lint":"pnpm lint:eslint && pnpm lint:dpdm","lint:fix":"pnpm lint:eslint --fix && pnpm lint:dpdm","precommit":"lint-staged","clean":"rm -rf .turbo dist/","test":"vitest run","test:watch":"vitest --watch","test:bench":"vitest --mode bench --run","test:integration":"vitest --mode int","format":"prettier --write \"src\"","format:check":"prettier --check \"src\""},"_lastModified":"2026-02-26T08:44:43.472Z"}
1
+ {"name":"langchain","version":"1.2.24","description":"Typescript bindings for langchain","author":"LangChain","license":"MIT","type":"module","engines":{"node":">=20"},"files":["dist/","CHANGELOG.md","README.md","LICENSE","storage","load","load.d.cts","load.cjs","load.d.ts","load.js","hub","chat_models","hub.d.cts","hub.cjs","hub.d.ts","hub.js"],"repository":{"type":"git","url":"git+ssh://git@github.com/langchain-ai/langchainjs.git"},"homepage":"https://github.com/langchain-ai/langchainjs/tree/main/libs/langchain/","devDependencies":{"@tsconfig/recommended":"^1.0.2","@types/js-yaml":"^4","@types/jsdom":"^21.1.1","@types/uuid":"^9","@types/ws":"^8","@vitest/coverage-v8":"^3.2.4","cheerio":"1.0.0-rc.12","dotenv":"^16.0.3","dpdm":"^3.14.0","eslint":"^9.34.0","openai":"^5.1.0","peggy":"^3.0.2","prettier":"^3.5.0","reflect-metadata":"^0.2.2","rimraf":"^5.0.1","tinybench":"^6.0.0","typeorm":"^0.3.28","typescript":"~5.8.3","vitest":"^3.2.4","yaml":"^2.8.1","@langchain/anthropic":"1.3.17","@langchain/core":"^1.1.24","@langchain/cohere":"1.0.2","@langchain/eslint":"0.1.1","@langchain/openai":"1.2.7","@langchain/tsconfig":"0.0.1"},"peerDependencies":{"@langchain/core":"^1.1.24"},"dependencies":{"@langchain/langgraph":"^1.1.2","@langchain/langgraph-checkpoint":"^1.0.0","langsmith":">=0.5.0 <1.0.0","uuid":"^10.0.0","zod":"^3.25.76 || ^4"},"publishConfig":{"access":"public"},"keywords":["llm","ai","gpt3","chain","prompt","prompt engineering","chatgpt","machine learning","ml","openai","embeddings","vectorstores"],"main":"./dist/index.cjs","types":"./dist/index.d.cts","exports":{".":{"input":"./src/index.ts","require":{"types":"./dist/index.d.cts","default":"./dist/index.cjs"},"import":{"types":"./dist/index.d.ts","default":"./dist/index.js"}},"./chat_models/universal":{"input":"./src/chat_models/universal.ts","require":{"types":"./dist/chat_models/universal.d.cts","default":"./dist/chat_models/universal.cjs"},"import":{"types":"./dist/chat_models/universal.d.ts","default":"./dist/chat_models/universal.js"}},"./hub":{"input":"./src/hub/index.ts","require":{"types":"./dist/hub/index.d.cts","default":"./dist/hub/index.cjs"},"import":{"types":"./dist/hub/index.d.ts","default":"./dist/hub/index.js"}},"./hub/node":{"input":"./src/hub/node.ts","require":{"types":"./dist/hub/node.d.cts","default":"./dist/hub/node.cjs"},"import":{"types":"./dist/hub/node.d.ts","default":"./dist/hub/node.js"}},"./load":{"input":"./src/load/index.ts","require":{"types":"./dist/load/index.d.cts","default":"./dist/load/index.cjs"},"import":{"types":"./dist/load/index.d.ts","default":"./dist/load/index.js"}},"./load/serializable":{"input":"./src/load/serializable.ts","require":{"types":"./dist/load/serializable.d.cts","default":"./dist/load/serializable.cjs"},"import":{"types":"./dist/load/serializable.d.ts","default":"./dist/load/serializable.js"}},"./storage/encoder_backed":{"input":"./src/storage/encoder_backed.ts","require":{"types":"./dist/storage/encoder_backed.d.cts","default":"./dist/storage/encoder_backed.cjs"},"import":{"types":"./dist/storage/encoder_backed.d.ts","default":"./dist/storage/encoder_backed.js"}},"./storage/file_system":{"input":"./src/storage/file_system.ts","require":{"types":"./dist/storage/file_system.d.cts","default":"./dist/storage/file_system.cjs"},"import":{"types":"./dist/storage/file_system.d.ts","default":"./dist/storage/file_system.js"}},"./storage/in_memory":{"input":"./src/storage/in_memory.ts","require":{"types":"./dist/storage/in_memory.d.cts","default":"./dist/storage/in_memory.cjs"},"import":{"types":"./dist/storage/in_memory.d.ts","default":"./dist/storage/in_memory.js"}},"./package.json":"./package.json"},"module":"./dist/index.js","scripts":{"build":"turbo build:compile --filter langchain --output-logs new-only","build:compile":"tsdown","lint:eslint":"eslint --cache src/","lint:dpdm":"dpdm --skip-dynamic-imports circular --exit-code circular:1 --no-warning --no-tree src/*.ts src/**/*.ts","lint":"pnpm lint:eslint && pnpm lint:dpdm","lint:fix":"pnpm lint:eslint --fix && pnpm lint:dpdm","precommit":"lint-staged","clean":"rm -rf .turbo dist/","test":"vitest run","test:watch":"vitest --watch","test:bench":"vitest --mode bench --run","test:integration":"vitest --mode int","format":"prettier --write \"src\"","format:check":"prettier --check \"src\""},"_lastModified":"2026-03-04T03:18:33.820Z"}
@@ -1 +1 @@
1
- {"name":"nodejs-snowflake","collaborators":["Utkarsh Srivastava <utkarsh@sagacious.dev>"],"description":"Generate time sortable 64 bits unique ids for distributed systems (inspired from twitter snowflake)","version":"2.0.1","license":"Apache 2.0","repository":{"type":"git","url":"https://github.com/utkarsh-pro/nodejs-snowflake.git"},"files":["nodejs_snowflake_bg.wasm","nodejs_snowflake.js","nodejs_snowflake.d.ts"],"main":"nodejs_snowflake.js","types":"nodejs_snowflake.d.ts","_lastModified":"2026-02-26T08:44:35.786Z"}
1
+ {"name":"nodejs-snowflake","collaborators":["Utkarsh Srivastava <utkarsh@sagacious.dev>"],"description":"Generate time sortable 64 bits unique ids for distributed systems (inspired from twitter snowflake)","version":"2.0.1","license":"Apache 2.0","repository":{"type":"git","url":"https://github.com/utkarsh-pro/nodejs-snowflake.git"},"files":["nodejs_snowflake_bg.wasm","nodejs_snowflake.js","nodejs_snowflake.d.ts"],"main":"nodejs_snowflake.js","types":"nodejs_snowflake.d.ts","_lastModified":"2026-03-04T03:18:26.040Z"}
@@ -1 +1 @@
1
- {"name":"zod","version":"4.3.5","type":"module","license":"MIT","author":"Colin McDonnell <zod@colinhacks.com>","description":"TypeScript-first schema declaration and validation library with static type inference","homepage":"https://zod.dev","llms":"https://zod.dev/llms.txt","llmsFull":"https://zod.dev/llms-full.txt","mcpServer":"https://mcp.inkeep.com/zod/mcp","funding":"https://github.com/sponsors/colinhacks","sideEffects":false,"files":["src","**/*.js","**/*.mjs","**/*.cjs","**/*.d.ts","**/*.d.mts","**/*.d.cts","**/package.json"],"keywords":["typescript","schema","validation","type","inference"],"main":"./index.cjs","types":"./index.d.cts","module":"./index.js","zshy":{"exports":{"./package.json":"./package.json",".":"./src/index.ts","./mini":"./src/mini/index.ts","./locales":"./src/locales/index.ts","./v3":"./src/v3/index.ts","./v4":"./src/v4/index.ts","./v4-mini":"./src/v4-mini/index.ts","./v4/mini":"./src/v4/mini/index.ts","./v4/core":"./src/v4/core/index.ts","./v4/locales":"./src/v4/locales/index.ts","./v4/locales/*":"./src/v4/locales/*"},"conditions":{"@zod/source":"src"}},"exports":{"./package.json":"./package.json",".":{"@zod/source":"./src/index.ts","types":"./index.d.cts","import":"./index.js","require":"./index.cjs"},"./mini":{"@zod/source":"./src/mini/index.ts","types":"./mini/index.d.cts","import":"./mini/index.js","require":"./mini/index.cjs"},"./locales":{"@zod/source":"./src/locales/index.ts","types":"./locales/index.d.cts","import":"./locales/index.js","require":"./locales/index.cjs"},"./v3":{"@zod/source":"./src/v3/index.ts","types":"./v3/index.d.cts","import":"./v3/index.js","require":"./v3/index.cjs"},"./v4":{"@zod/source":"./src/v4/index.ts","types":"./v4/index.d.cts","import":"./v4/index.js","require":"./v4/index.cjs"},"./v4-mini":{"@zod/source":"./src/v4-mini/index.ts","types":"./v4-mini/index.d.cts","import":"./v4-mini/index.js","require":"./v4-mini/index.cjs"},"./v4/mini":{"@zod/source":"./src/v4/mini/index.ts","types":"./v4/mini/index.d.cts","import":"./v4/mini/index.js","require":"./v4/mini/index.cjs"},"./v4/core":{"@zod/source":"./src/v4/core/index.ts","types":"./v4/core/index.d.cts","import":"./v4/core/index.js","require":"./v4/core/index.cjs"},"./v4/locales":{"@zod/source":"./src/v4/locales/index.ts","types":"./v4/locales/index.d.cts","import":"./v4/locales/index.js","require":"./v4/locales/index.cjs"},"./v4/locales/*":{"@zod/source":"./src/v4/locales/*","types":"./v4/locales/*","import":"./v4/locales/*","require":"./v4/locales/*"}},"repository":{"type":"git","url":"git+https://github.com/colinhacks/zod.git"},"bugs":{"url":"https://github.com/colinhacks/zod/issues"},"support":{"backing":{"npm-funding":true}},"scripts":{"clean":"git clean -xdf . -e node_modules","build":"zshy --project tsconfig.build.json","postbuild":"tsx ../../scripts/write-stub-package-jsons.ts && pnpm biome check --write .","test:watch":"pnpm vitest","test":"pnpm vitest run","prepublishOnly":"tsx ../../scripts/check-versions.ts"},"_lastModified":"2026-02-26T08:44:37.120Z"}
1
+ {"name":"zod","version":"4.3.5","type":"module","license":"MIT","author":"Colin McDonnell <zod@colinhacks.com>","description":"TypeScript-first schema declaration and validation library with static type inference","homepage":"https://zod.dev","llms":"https://zod.dev/llms.txt","llmsFull":"https://zod.dev/llms-full.txt","mcpServer":"https://mcp.inkeep.com/zod/mcp","funding":"https://github.com/sponsors/colinhacks","sideEffects":false,"files":["src","**/*.js","**/*.mjs","**/*.cjs","**/*.d.ts","**/*.d.mts","**/*.d.cts","**/package.json"],"keywords":["typescript","schema","validation","type","inference"],"main":"./index.cjs","types":"./index.d.cts","module":"./index.js","zshy":{"exports":{"./package.json":"./package.json",".":"./src/index.ts","./mini":"./src/mini/index.ts","./locales":"./src/locales/index.ts","./v3":"./src/v3/index.ts","./v4":"./src/v4/index.ts","./v4-mini":"./src/v4-mini/index.ts","./v4/mini":"./src/v4/mini/index.ts","./v4/core":"./src/v4/core/index.ts","./v4/locales":"./src/v4/locales/index.ts","./v4/locales/*":"./src/v4/locales/*"},"conditions":{"@zod/source":"src"}},"exports":{"./package.json":"./package.json",".":{"@zod/source":"./src/index.ts","types":"./index.d.cts","import":"./index.js","require":"./index.cjs"},"./mini":{"@zod/source":"./src/mini/index.ts","types":"./mini/index.d.cts","import":"./mini/index.js","require":"./mini/index.cjs"},"./locales":{"@zod/source":"./src/locales/index.ts","types":"./locales/index.d.cts","import":"./locales/index.js","require":"./locales/index.cjs"},"./v3":{"@zod/source":"./src/v3/index.ts","types":"./v3/index.d.cts","import":"./v3/index.js","require":"./v3/index.cjs"},"./v4":{"@zod/source":"./src/v4/index.ts","types":"./v4/index.d.cts","import":"./v4/index.js","require":"./v4/index.cjs"},"./v4-mini":{"@zod/source":"./src/v4-mini/index.ts","types":"./v4-mini/index.d.cts","import":"./v4-mini/index.js","require":"./v4-mini/index.cjs"},"./v4/mini":{"@zod/source":"./src/v4/mini/index.ts","types":"./v4/mini/index.d.cts","import":"./v4/mini/index.js","require":"./v4/mini/index.cjs"},"./v4/core":{"@zod/source":"./src/v4/core/index.ts","types":"./v4/core/index.d.cts","import":"./v4/core/index.js","require":"./v4/core/index.cjs"},"./v4/locales":{"@zod/source":"./src/v4/locales/index.ts","types":"./v4/locales/index.d.cts","import":"./v4/locales/index.js","require":"./v4/locales/index.cjs"},"./v4/locales/*":{"@zod/source":"./src/v4/locales/*","types":"./v4/locales/*","import":"./v4/locales/*","require":"./v4/locales/*"}},"repository":{"type":"git","url":"git+https://github.com/colinhacks/zod.git"},"bugs":{"url":"https://github.com/colinhacks/zod/issues"},"support":{"backing":{"npm-funding":true}},"scripts":{"clean":"git clean -xdf . -e node_modules","build":"zshy --project tsconfig.build.json","postbuild":"tsx ../../scripts/write-stub-package-jsons.ts && pnpm biome check --write .","test:watch":"pnpm vitest","test":"pnpm vitest run","prepublishOnly":"tsx ../../scripts/check-versions.ts"},"_lastModified":"2026-03-04T03:18:27.240Z"}
@@ -9,7 +9,7 @@
9
9
  import { Model, Transaction } from '@nocobase/database';
10
10
  import { Context } from '@nocobase/actions';
11
11
  import { LLMProvider } from '../llm-providers/provider';
12
- import { AIChatContext, AIChatConversation, AIMessage, AIMessageInput, UserDecision } from '../types';
12
+ import { AIChatContext, AIChatConversation, AIMessageInput, UserDecision } from '../types';
13
13
  import { DocumentSegmentedWithScore } from '../features';
14
14
  import { KnowledgeBaseGroup } from '../types';
15
15
  import { ToolsEntry } from '@nocobase/ai';
@@ -80,8 +80,8 @@ export declare class AIEmployee {
80
80
  responseMetadata: Map<string, any>;
81
81
  }): Promise<void>;
82
82
  getEmployeeDataSourceContext(): string;
83
- getSystemPrompt(): Promise<string>;
84
- retrieveKnowledgeBase(userMessage: AIMessage): Promise<DocumentSegmentedWithScore[]>;
83
+ getSystemPrompt(userMessages: AIMessageInput[]): Promise<string>;
84
+ retrieveKnowledgeBase(userMessage: AIMessageInput): Promise<DocumentSegmentedWithScore[]>;
85
85
  isEnabledKnowledgeBase(): boolean;
86
86
  getAIEmployeeKnowledgeBaseConfig(): {
87
87
  topK: number;
@@ -145,7 +145,7 @@ class AIEmployee {
145
145
  userDecisions,
146
146
  tools,
147
147
  middleware,
148
- getSystemPrompt: () => this.getSystemPrompt(),
148
+ getSystemPrompt: (userMessages2) => this.getSystemPrompt(userMessages2),
149
149
  formatMessages: (messages) => this.formatMessages({ messages, provider })
150
150
  });
151
151
  return { providerName: service.provider, model, provider, chatContext, config, state };
@@ -519,7 +519,7 @@ Field: ${field.name}, Title: ${(_a = field.options.uiSchema) == null ? void 0 :
519
519
  }
520
520
  return message;
521
521
  }
522
- async getSystemPrompt() {
522
+ async getSystemPrompt(userMessages) {
523
523
  var _a;
524
524
  const userConfig = await this.db.getRepository("usersAiEmployees").findOne({
525
525
  filter: {
@@ -527,7 +527,7 @@ Field: ${field.name}, Title: ${(_a = field.options.uiSchema) == null ? void 0 :
527
527
  aiEmployee: this.employee.username
528
528
  }
529
529
  });
530
- let systemMessage = await (0, import_utils.parseVariables)(this.ctx, this.employee.about ?? this.employee.defaultPrompt);
530
+ let systemMessage = await (0, import_utils.parseVariables)(this.ctx, this.employee.about ?? this.employee.defaultPrompt ?? "");
531
531
  const dataSourceMessage = this.getEmployeeDataSourceContext();
532
532
  if (dataSourceMessage) {
533
533
  systemMessage = `${systemMessage}
@@ -544,14 +544,16 @@ ${dataSourceMessage}`;
544
544
  ${workContextBackground.join("\n")}`;
545
545
  }
546
546
  let knowledgeBase;
547
- if (this.isEnabledKnowledgeBase() && this.employee.knowledgeBasePrompt) {
548
- const lastUserMessage = await this.aiChatConversation.lastUserMessage();
549
- const docs = await this.retrieveKnowledgeBase(lastUserMessage);
550
- const knowledgeBaseData = docs.map((x) => x.content).join("\n");
551
- const promptTemplate = import_prompts2.ChatPromptTemplate.fromTemplate(this.employee.knowledgeBasePrompt);
552
- knowledgeBase = import_lodash.default.isEmpty(knowledgeBaseData) ? void 0 : await promptTemplate.format({
553
- knowledgeBaseData
554
- });
547
+ if (this.isEnabledKnowledgeBase() && this.employee.knowledgeBasePrompt && (userMessages == null ? void 0 : userMessages.length)) {
548
+ const lastUserMessage = userMessages.filter((x) => x.role === "user").at(-1);
549
+ if (lastUserMessage) {
550
+ const docs = await this.retrieveKnowledgeBase(lastUserMessage);
551
+ const knowledgeBaseData = docs.map((x) => x.content).join("\n");
552
+ const promptTemplate = import_prompts2.ChatPromptTemplate.fromTemplate(this.employee.knowledgeBasePrompt);
553
+ knowledgeBase = import_lodash.default.isEmpty(knowledgeBaseData) ? void 0 : await promptTemplate.format({
554
+ knowledgeBaseData
555
+ });
556
+ }
555
557
  }
556
558
  const systemPrompt = (0, import_prompts.getSystemPrompt)({
557
559
  aiEmployee: {
@@ -36,5 +36,6 @@ export declare class AnthropicProvider extends LLMProvider {
36
36
  query: string;
37
37
  }[];
38
38
  parseAttachment(ctx: Context, attachment: any): Promise<any>;
39
+ private setMaxTokens;
39
40
  }
40
41
  export declare const anthropicProviderOptions: LLMProviderMeta;
@@ -45,6 +45,9 @@ var import_anthropic = require("@langchain/anthropic");
45
45
  var import_axios = __toESM(require("axios"));
46
46
  var import_utils = require("../utils");
47
47
  var import_ai_manager = require("../manager/ai-manager");
48
+ const MAX_TOKENS_PRESET = {
49
+ "kimi-for-coding": 128 * 1024
50
+ };
48
51
  class AnthropicProvider extends import_provider.LLMProvider {
49
52
  get baseURL() {
50
53
  return "https://api.anthropic.com";
@@ -73,6 +76,7 @@ class AnthropicProvider extends import_provider.LLMProvider {
73
76
  delete sanitizedModelOptions[key];
74
77
  }
75
78
  }
79
+ this.setMaxTokens(sanitizedModelOptions);
76
80
  return new import_anthropic.ChatAnthropic({
77
81
  apiKey,
78
82
  ...sanitizedModelOptions,
@@ -208,6 +212,13 @@ class AnthropicProvider extends import_provider.LLMProvider {
208
212
  };
209
213
  }
210
214
  }
215
+ setMaxTokens(options = {}) {
216
+ var _a;
217
+ if (!options.model || options.maxTokens) {
218
+ return;
219
+ }
220
+ options.maxTokens = (_a = Object.entries(MAX_TOKENS_PRESET).find(([key]) => options.model.startsWith(key))) == null ? void 0 : _a[1];
221
+ }
211
222
  }
212
223
  const anthropicProviderOptions = {
213
224
  title: "Anthropic",
@@ -138,7 +138,7 @@ class AIChatConversationImpl {
138
138
  formatMessages
139
139
  } = options ?? {};
140
140
  const messages = userMessages ? await (formatMessages == null ? void 0 : formatMessages(userMessages)) ?? [] : void 0;
141
- const systemPrompt = await (getSystemPrompt == null ? void 0 : getSystemPrompt()) ?? "";
141
+ const systemPrompt = await (getSystemPrompt == null ? void 0 : getSystemPrompt(userMessages)) ?? "";
142
142
  const chatContext = {
143
143
  systemPrompt,
144
144
  messages,
@@ -30,6 +30,7 @@ __export(ai_context_datasource_manager_exports, {
30
30
  });
31
31
  module.exports = __toCommonJS(ai_context_datasource_manager_exports);
32
32
  var import_utils = require("@nocobase/utils");
33
+ var import_acl = require("@nocobase/acl");
33
34
  class AIContextDatasourceManager {
34
35
  constructor(plugin) {
35
36
  this.plugin = plugin;
@@ -51,7 +52,7 @@ class AIContextDatasourceManager {
51
52
  };
52
53
  }
53
54
  async innerQuery(ctx, options) {
54
- var _a;
55
+ var _a, _b;
55
56
  const { datasource, collectionName } = options;
56
57
  const resource = collectionName;
57
58
  const action = "list";
@@ -87,8 +88,8 @@ class AIContextDatasourceManager {
87
88
  records: []
88
89
  };
89
90
  }
90
- const filteredParams = ds.acl.filterParams(ctx, collectionName, can.params);
91
- const parsedParams = filteredParams ? await ds.acl.parseJsonTemplate(filteredParams, ctx) : {};
91
+ (0, import_acl.checkFilterParams)(collection, (_b = can.params) == null ? void 0 : _b.filter);
92
+ const parsedParams = can.params ? await (0, import_acl.parseJsonTemplate)(can.params, ctx) : {};
92
93
  if (parsedParams.appends && options.fields) {
93
94
  for (const queryField of options.fields) {
94
95
  if (parsedParams.appends.indexOf(queryField) !== -1) {
@@ -117,11 +117,7 @@ class PluginAIServer extends import_server.Plugin {
117
117
  }
118
118
  registerTools() {
119
119
  const toolsManager = this.ai.toolsManager;
120
- const docsModulesDescription = (0, import_tools.describeDocModules)("Docs modules unavailable. Run ai:create-docs-index first.");
121
- toolsManager.registerTools([
122
- (0, import_tools.createDocsSearchTool)({ description: docsModulesDescription }),
123
- (0, import_tools.createReadDocEntryTool)()
124
- ]);
120
+ toolsManager.registerTools([(0, import_tools.createDocsSearchTool)(), (0, import_tools.createReadDocEntryTool)()]);
125
121
  toolsManager.registerDynamicTools((0, import_tools.getWorkflowCallers)(this, "workflowCaller"));
126
122
  }
127
123
  defineResources() {
@@ -23,12 +23,11 @@ export type DocEntryResult = {
23
23
  export declare function loadDocsIndexes(baseDir?: string): Promise<void>;
24
24
  export declare function getDocModuleKeys(): string[];
25
25
  export declare function describeDocModules(emptyMessage?: string): string;
26
- export declare function searchDocsModule(moduleKey: string, query: string, limit?: number): Promise<{
26
+ export declare function searchDocsModule(moduleKey: string, keywords: string[], limit?: number): Promise<{
27
27
  key: string;
28
+ keywords: string[];
28
29
  matches: string[];
29
30
  }>;
30
31
  export declare function readDocEntry(docPath: string): Promise<DocEntryResult>;
31
- export declare function createDocsSearchTool(options?: {
32
- description?: string;
33
- }): ToolsOptions;
32
+ export declare function createDocsSearchTool(): ToolsOptions;
34
33
  export declare function createReadDocEntryTool(): ToolsOptions;
@@ -56,6 +56,8 @@ let docsBaseDir = DEFAULT_DOCS_DIR;
56
56
  let docsMeta = {};
57
57
  const DOCS_INDEX_TTL_MS = 5 * 60 * 1e3;
58
58
  const DOCS_INDEX_MAX_CACHE = 5;
59
+ const DOCS_SEARCH_MAX_KEYWORDS = 5;
60
+ const DOCS_READ_MAX_PATHS = 3;
59
61
  const docsIndexCache = /* @__PURE__ */ new Map();
60
62
  const docsIndexLoading = /* @__PURE__ */ new Map();
61
63
  async function loadDocsIndexes(baseDir = DEFAULT_DOCS_DIR) {
@@ -122,26 +124,55 @@ function describeDocModules(emptyMessage = "No document modules available.") {
122
124
  });
123
125
  return `Available modules: ${items.join(", ")}`;
124
126
  }
125
- async function searchDocsModule(moduleKey, query, limit = 5) {
127
+ async function searchDocsModule(moduleKey, keywords, limit = 5) {
126
128
  const key = normalizeModuleKey(moduleKey);
127
129
  const entry = docsModules.get(key);
128
130
  if (!entry) {
129
131
  throw new Error(`Document module "${key}" not found.`);
130
132
  }
131
133
  const { index: flexIndex, fileMap } = await getOrLoadDocsIndex(entry);
134
+ const searchTerms = buildSearchTerms(keywords);
135
+ if (!searchTerms.length) {
136
+ throw new Error("At least one valid keyword is required.");
137
+ }
132
138
  const boundedLimit = Math.min(Math.max(limit ?? 5, 1), 20);
133
- const hits = await flexIndex.searchAsync(query, { limit: boundedLimit }) || [];
134
- const seen = /* @__PURE__ */ new Set();
135
- const matches = [];
136
- for (const hit of hits) {
137
- const filePath = fileMap[String(hit)];
138
- if (filePath && !seen.has(filePath)) {
139
- seen.add(filePath);
140
- matches.push(filePath);
139
+ const perKeywordLimit = Math.min(Math.max(boundedLimit * 2, 4), 20);
140
+ const keywordHits = await Promise.all(
141
+ searchTerms.map(
142
+ async (keyword) => (await flexIndex.searchAsync(keyword, { limit: perKeywordLimit }) || []).map(
143
+ (id) => String(id)
144
+ )
145
+ )
146
+ );
147
+ const aggregate = /* @__PURE__ */ new Map();
148
+ for (const hits of keywordHits) {
149
+ for (let i = 0; i < hits.length; i++) {
150
+ const filePath = fileMap[hits[i]];
151
+ if (!filePath) {
152
+ continue;
153
+ }
154
+ const rankScore = perKeywordLimit - i;
155
+ const record = aggregate.get(filePath);
156
+ if (record) {
157
+ record.score += rankScore;
158
+ record.bestRank = Math.min(record.bestRank, i);
159
+ } else {
160
+ aggregate.set(filePath, { score: rankScore, bestRank: i });
161
+ }
141
162
  }
142
163
  }
164
+ const matches = Array.from(aggregate.entries()).sort((a, b) => {
165
+ if (b[1].score !== a[1].score) {
166
+ return b[1].score - a[1].score;
167
+ }
168
+ if (a[1].bestRank !== b[1].bestRank) {
169
+ return a[1].bestRank - b[1].bestRank;
170
+ }
171
+ return a[0].localeCompare(b[0]);
172
+ }).slice(0, boundedLimit).map(([filePath]) => filePath);
143
173
  return {
144
174
  key,
175
+ keywords: searchTerms,
145
176
  matches
146
177
  };
147
178
  }
@@ -183,7 +214,8 @@ async function readDocEntry(docPath) {
183
214
  content
184
215
  };
185
216
  }
186
- function createDocsSearchTool(options) {
217
+ function createDocsSearchTool() {
218
+ const docsModulesDescription = describeDocModules("Docs modules unavailable. Run ai:create-docs-index first.");
187
219
  return {
188
220
  scope: "GENERAL",
189
221
  defaultPermission: "ALLOW",
@@ -194,17 +226,16 @@ function createDocsSearchTool(options) {
194
226
  definition: {
195
227
  name: "searchDocs",
196
228
  description: `Search indexed documentation using a FlexSearch-based keyword index.
197
- The index is built from module identifiers (e.g. "runjs") and English technical terms.
198
- Use concise, exact keywords (module names, API names, identifiers). Avoid natural language queries or vague wording.
199
- Return matching document paths only. ${options.description}`,
229
+ Provide a small keyword list (identifiers, API names, module terms). The tool will search them concurrently with limited parallelism.
230
+ Return matching document paths only. ${docsModulesDescription}`,
200
231
  schema: import_zod.z.object({
201
232
  module: import_zod.z.string().min(1, "module is required").describe("Module key, e.g. runjs"),
202
- query: import_zod.z.string().min(1, "query is required").describe("Search keyword or phrase in English"),
233
+ keywords: import_zod.z.array(import_zod.z.string().min(1)).min(1, "keywords is required").max(DOCS_SEARCH_MAX_KEYWORDS, `keywords can contain up to ${DOCS_SEARCH_MAX_KEYWORDS} items`).describe('Keywords to search, e.g. ["router", "ctx.state", "runjs"]'),
203
234
  limit: import_zod.z.number().int().min(1).max(20).optional().describe("Maximum number of hits (default 5, max 20)")
204
235
  })
205
236
  },
206
237
  invoke: async (ctx, args) => {
207
- var _a, _b, _c, _d;
238
+ var _a, _b, _c;
208
239
  const available = getDocModuleKeys();
209
240
  if (!available.length) {
210
241
  return {
@@ -213,26 +244,27 @@ Return matching document paths only. ${options.description}`,
213
244
  };
214
245
  }
215
246
  const moduleKey = (_a = args == null ? void 0 : args.module) == null ? void 0 : _a.trim();
216
- const query = (_b = args == null ? void 0 : args.query) == null ? void 0 : _b.trim();
247
+ const keywords = Array.isArray(args == null ? void 0 : args.keywords) ? args.keywords : [];
217
248
  const limit = typeof (args == null ? void 0 : args.limit) === "number" ? args.limit : void 0;
218
- if (!moduleKey || !query) {
249
+ if (!moduleKey || !keywords.length) {
219
250
  return {
220
251
  status: "error",
221
- content: `Both module and query are required. Available modules: ${available.join(", ")}`
252
+ content: `Both module and keywords are required. Available modules: ${available.join(", ")}`
222
253
  };
223
254
  }
224
255
  try {
225
- const result = await searchDocsModule(moduleKey, query, limit);
256
+ const result = await searchDocsModule(moduleKey, keywords, limit);
226
257
  return {
227
258
  status: "success",
228
259
  content: JSON.stringify({
229
260
  module: result.key,
261
+ keywords: result.keywords,
230
262
  matches: result.matches,
231
263
  availableModules: available
232
264
  })
233
265
  };
234
266
  } catch (error) {
235
- (_d = (_c = ctx.log) == null ? void 0 : _c.error) == null ? void 0 : _d.call(_c, error, {
267
+ (_c = (_b = ctx.log) == null ? void 0 : _b.error) == null ? void 0 : _c.call(_b, error, {
236
268
  module: "ai",
237
269
  subModule: "toolCalling",
238
270
  toolName: "searchDocs"
@@ -255,43 +287,56 @@ function createReadDocEntryTool() {
255
287
  },
256
288
  definition: {
257
289
  name: "readDocEntry",
258
- description: "Read files or list directories inside storage/ai/docs using canonical module-based paths.",
290
+ description: "Read files or list directories inside storage/ai/docs using canonical module-based paths. Supports up to 3 paths per call.",
259
291
  schema: import_zod.z.object({
260
- path: import_zod.z.string().min(1, "path is required").describe(
261
- "Canonical path like runjs/context/router/index.md or /runjs/context/router/index.md. No wildcards, relative segments, or globbing."
262
- )
292
+ paths: import_zod.z.array(
293
+ import_zod.z.string().min(1, "path is required").describe(
294
+ "Canonical path like runjs/context/router/index.md or /runjs/context/router/index.md. No wildcards, relative segments, or globbing."
295
+ )
296
+ ).min(1, "paths is required").max(DOCS_READ_MAX_PATHS, `paths can contain up to ${DOCS_READ_MAX_PATHS} items`)
263
297
  })
264
298
  },
265
299
  invoke: async (ctx, args) => {
266
- var _a, _b, _c;
300
+ var _a, _b;
267
301
  const available = getDocModuleKeys();
268
- const targetPath = (_a = args == null ? void 0 : args.path) == null ? void 0 : _a.trim();
269
- if (!targetPath) {
302
+ if (!available.length) {
270
303
  return {
271
304
  status: "error",
272
- content: `Path is required. Available indexes: ${available.join(", ")}`
305
+ content: "No document indexes available."
273
306
  };
274
307
  }
275
- try {
276
- const entry = await readDocEntry(targetPath);
277
- if (entry.type === "directory") {
278
- const listing = entry.entries.map((item) => `${item.type === "directory" ? "DIR " : "FILE"} ${item.path}`).join("\n");
279
- return {
280
- status: "success",
281
- content: `DIRECTORY ${entry.path}
282
- ${listing}`
283
- };
284
- }
285
- const clean = entry.content.replace(/\r\n/g, "\n");
308
+ const rawPaths = Array.isArray(args == null ? void 0 : args.paths) ? args.paths : [];
309
+ const paths = Array.from(
310
+ new Set(
311
+ rawPaths.map((p) => String(p ?? "").trim()).filter((p) => !!p).slice(0, DOCS_READ_MAX_PATHS)
312
+ )
313
+ );
314
+ if (!paths.length) {
286
315
  return {
287
- status: "success",
288
- content: `FILE ${entry.path}
316
+ status: "error",
317
+ content: `Paths are required. Available indexes: ${available.join(", ")}`
318
+ };
319
+ }
320
+ try {
321
+ const entries = await Promise.all(paths.map((targetPath) => readDocEntry(targetPath)));
322
+ const blocks = entries.map((entry) => {
323
+ if (entry.type === "directory") {
324
+ const listing = entry.entries.map((item) => `${item.type === "directory" ? "DIR " : "FILE"} ${item.path}`).join("\n");
325
+ return `DIRECTORY ${entry.path}
326
+ ${listing}`;
327
+ }
328
+ const clean = entry.content.replace(/\r\n/g, "\n");
329
+ return `FILE ${entry.path}
289
330
  \`\`\`
290
331
  ${clean}
291
- \`\`\``
332
+ \`\`\``;
333
+ });
334
+ return {
335
+ status: "success",
336
+ content: blocks.join("\n\n")
292
337
  };
293
338
  } catch (error) {
294
- (_c = (_b = ctx.log) == null ? void 0 : _b.error) == null ? void 0 : _c.call(_b, error, {
339
+ (_b = (_a = ctx.log) == null ? void 0 : _a.error) == null ? void 0 : _b.call(_a, error, {
295
340
  module: "ai",
296
341
  subModule: "toolCalling",
297
342
  toolName: "readDocEntry"
@@ -427,6 +472,22 @@ function enforceDocsIndexCacheLimit() {
427
472
  docsIndexCache.delete(entries[i][0]);
428
473
  }
429
474
  }
475
+ function buildSearchTerms(keywords) {
476
+ const seen = /* @__PURE__ */ new Set();
477
+ const terms = [];
478
+ for (const raw of keywords) {
479
+ const keyword = String(raw ?? "").trim().replace(/\s+/g, " ");
480
+ if (!keyword || seen.has(keyword)) {
481
+ continue;
482
+ }
483
+ seen.add(keyword);
484
+ terms.push(keyword);
485
+ if (terms.length >= DOCS_SEARCH_MAX_KEYWORDS) {
486
+ break;
487
+ }
488
+ }
489
+ return terms;
490
+ }
430
491
  // Annotate the CommonJS export names for ESM import in node:
431
492
  0 && (module.exports = {
432
493
  createDocsSearchTool,
@@ -51,6 +51,6 @@ export type AIChatContextOptions = {
51
51
  userDecisions?: UserDecision[];
52
52
  tools?: any[];
53
53
  middleware?: any[];
54
- getSystemPrompt?: () => Promise<string>;
54
+ getSystemPrompt?: (userMessages: AIMessageInput[]) => Promise<string>;
55
55
  formatMessages?: (messages: AIMessageInput[]) => Promise<any[]>;
56
56
  } & AIMessageQuery;
package/package.json CHANGED
@@ -6,12 +6,13 @@
6
6
  "description": "Create AI employees with diverse skills to collaborate with humans, build systems, and handle business operations.",
7
7
  "description.ru-RU": "Поддержка интеграции с AI-сервисами: предоставляются AI-узлы для рабочих процессов, расширяя возможности бизнес-обработки.",
8
8
  "description.zh-CN": "创建各种技能的 AI 员工,与人类协同,搭建系统,处理业务。",
9
- "version": "2.1.0-beta.5",
9
+ "version": "2.1.0-beta.7",
10
10
  "main": "dist/server/index.js",
11
11
  "homepage": "https://docs.nocobase.com/handbook/action-ai",
12
12
  "homepage.ru-RU": "https://docs-ru.nocobase.com/handbook/action-ai",
13
13
  "homepage.zh-CN": "https://docs-cn.nocobase.com/handbook/action-ai",
14
14
  "peerDependencies": {
15
+ "@nocobase/acl": "2.x",
15
16
  "@nocobase/ai": "2.x",
16
17
  "@nocobase/client": "2.x",
17
18
  "@nocobase/flow-engine": "2.x",
@@ -51,5 +52,5 @@
51
52
  "keywords": [
52
53
  "AI"
53
54
  ],
54
- "gitHead": "9c70818fb54a8fbd36378192bc4bbe45c2634905"
55
+ "gitHead": "da7dfef2b6d6854988a56119463c8c38e3221e79"
55
56
  }